OSDN Git Service

Add support for retaining time stamps on uploading files.
[ffftp/ffftp.git] / mbswrapper.c
1 // mbswrapper.c\r
2 // Copyright (C) 2011 Suguru Kawamoto\r
3 // マルチバイト文字ワイド文字APIラッパー\r
4 // マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする\r
5 // 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要\r
6 \r
7 #define UNICODE\r
8 #define _UNICODE\r
9 \r
10 #include <stdio.h>\r
11 #include <tchar.h>\r
12 #include <direct.h>\r
13 #include <windows.h>\r
14 #include <commctrl.h>\r
15 #include <shlobj.h>\r
16 #include <htmlhelp.h>\r
17 \r
18 #define DO_NOT_REPLACE\r
19 #include "mbswrapper.h"\r
20 \r
21 // マルチバイト文字列からワイド文字列へ変換\r
22 int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
23 {\r
24         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
25                 return 0;\r
26         if(pDst)\r
27                 return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);\r
28         return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);\r
29 }\r
30 \r
31 // ワイド文字列からマルチバイト文字列へ変換\r
32 int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
33 {\r
34         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
35                 return 0;\r
36         if(pDst)\r
37                 return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);\r
38         return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);\r
39 }\r
40 \r
41 // Shift_JIS文字列からワイド文字列へ変換\r
42 int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
43 {\r
44         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
45                 return 0;\r
46         if(pDst)\r
47                 return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);\r
48         return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);\r
49 }\r
50 \r
51 // ワイド文字列からShift_JIS文字列へ変換\r
52 int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
53 {\r
54         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
55                 return 0;\r
56         if(pDst)\r
57                 return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);\r
58         return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);\r
59 }\r
60 \r
61 // マルチバイト文字列バッファ終端を強制的にNULLで置換\r
62 int TerminateStringM(LPSTR lpString, int size)\r
63 {\r
64         int i;\r
65         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
66                 return 0;\r
67         for(i = 0; i < size; i++)\r
68         {\r
69                 if(lpString[i] == '\0')\r
70                         return i;\r
71         }\r
72         i--;\r
73         lpString[i] = '\0';\r
74         return i;\r
75 }\r
76 \r
77 // ワイド文字列バッファ終端を強制的にNULLで置換\r
78 int TerminateStringW(LPWSTR lpString, int size)\r
79 {\r
80         int i;\r
81         if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)\r
82                 return 0;\r
83         for(i = 0; i < size; i++)\r
84         {\r
85                 if(lpString[i] == L'\0')\r
86                         return i;\r
87         }\r
88         i--;\r
89         lpString[i] = L'\0';\r
90         return i;\r
91 }\r
92 \r
93 // Shift_JIS文字列バッファ終端を強制的にNULLで置換\r
94 int TerminateStringA(LPSTR lpString, int size)\r
95 {\r
96         int i;\r
97         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
98                 return 0;\r
99         for(i = 0; i < size; i++)\r
100         {\r
101                 if(lpString[i] == '\0')\r
102                         return i;\r
103         }\r
104         i--;\r
105         lpString[i] = '\0';\r
106         return i;\r
107 }\r
108 \r
109 // NULL区切り複数マルチバイト文字列の長さを取得\r
110 size_t GetMultiStringLengthM(LPCSTR lpString)\r
111 {\r
112         size_t i;\r
113         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
114                 return 0;\r
115         i = 0;\r
116         while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
117         {\r
118                 i++;\r
119         }\r
120         i++;\r
121         return i;\r
122 }\r
123 \r
124 // NULL区切り複数ワイド文字列の長さを取得\r
125 size_t GetMultiStringLengthW(LPCWSTR lpString)\r
126 {\r
127         size_t i;\r
128         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
129                 return 0;\r
130         i = 0;\r
131         while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')\r
132         {\r
133                 i++;\r
134         }\r
135         i++;\r
136         return i;\r
137 }\r
138 \r
139 // NULL区切り複数Shift_JIS文字列の長さを取得\r
140 size_t GetMultiStringLengthA(LPCSTR lpString)\r
141 {\r
142         size_t i;\r
143         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
144                 return 0;\r
145         i = 0;\r
146         while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
147         {\r
148                 i++;\r
149         }\r
150         i++;\r
151         return i;\r
152 }\r
153 \r
154 // NULL区切りマルチバイト文字列からワイド文字列へ変換\r
155 int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
156 {\r
157         int i;\r
158         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
159                 return 0;\r
160         if(!pDst)\r
161                 return GetMultiStringLengthM(pSrc);\r
162         i = 0;\r
163         while(*pSrc != '\0')\r
164         {\r
165                 i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);\r
166                 pSrc += strlen(pSrc) + 1;\r
167         }\r
168         pDst[i] = L'\0';\r
169         return i;\r
170 }\r
171 \r
172 // NULL区切りワイド文字列からマルチバイト文字列へ変換\r
173 int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
174 {\r
175         int i;\r
176         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
177                 return 0;\r
178         if(!pDst)\r
179                 return GetMultiStringLengthW(pSrc);\r
180         i = 0;\r
181         while(*pSrc != L'\0')\r
182         {\r
183                 i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
184                 pSrc += wcslen(pSrc) + 1;\r
185         }\r
186         pDst[i] = '\0';\r
187         return i;\r
188 }\r
189 \r
190 // NULL区切りShift_JIS文字列からワイド文字列へ変換\r
191 int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
192 {\r
193         int i;\r
194         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
195                 return 0;\r
196         if(!pDst)\r
197                 return GetMultiStringLengthA(pSrc);\r
198         i = 0;\r
199         while(*pSrc != '\0')\r
200         {\r
201                 i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);\r
202                 pSrc += strlen(pSrc) + 1;\r
203         }\r
204         pDst[i] = L'\0';\r
205         return i;\r
206 }\r
207 \r
208 // NULL区切りワイド文字列からShift_JIS文字列へ変換\r
209 int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
210 {\r
211         int i;\r
212         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
213                 return 0;\r
214         if(!pDst)\r
215                 return GetMultiStringLengthW(pSrc);\r
216         i = 0;\r
217         while(*pSrc != L'\0')\r
218         {\r
219                 i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
220                 pSrc += wcslen(pSrc) + 1;\r
221         }\r
222         pDst[i] = '\0';\r
223         return i;\r
224 }\r
225 \r
226 // マルチバイト文字列用のメモリを確保\r
227 char* AllocateStringM(int size)\r
228 {\r
229         char* p;\r
230         // 0が指定される場合があるため1文字分追加\r
231         p = (char*)malloc(sizeof(char) * (size + 1));\r
232         // 念のため先頭にNULL文字を代入\r
233         if(p)\r
234                 *p = '\0';\r
235         return p;\r
236 }\r
237 \r
238 // ワイド文字列用のメモリを確保\r
239 wchar_t* AllocateStringW(int size)\r
240 {\r
241         wchar_t* p;\r
242         // 0が指定される場合があるため1文字分追加\r
243         p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));\r
244         // 念のため先頭にNULL文字を代入\r
245         if(p)\r
246                 *p = L'\0';\r
247         return p;\r
248 }\r
249 \r
250 // Shift_JIS文字列用のメモリを確保\r
251 char* AllocateStringA(int size)\r
252 {\r
253         char* p;\r
254         // 0が指定される場合があるため1文字分追加\r
255         p = (char*)malloc(sizeof(char) * (size + 1));\r
256         // 念のため先頭にNULL文字を代入\r
257         if(p)\r
258                 *p = '\0';\r
259         return p;\r
260 }\r
261 \r
262 // メモリを確保してマルチバイト文字列からワイド文字列へ変換\r
263 // リソースIDならば元の値を返す\r
264 wchar_t* DuplicateMtoW(LPCSTR lpString, int c)\r
265 {\r
266         wchar_t* p;\r
267         int i;\r
268         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
269                 return (wchar_t*)lpString;\r
270         if(c < 0)\r
271                 c = strlen(lpString);\r
272         p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);\r
273         if(p)\r
274         {\r
275                 i = MtoW(p, 65535, lpString, c);\r
276                 p[i] = L'\0';\r
277         }\r
278         return p;\r
279 }\r
280 \r
281 // 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換\r
282 // リソースIDならば元の値を返す\r
283 wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)\r
284 {\r
285         wchar_t* p;\r
286         int i;\r
287         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
288                 return (wchar_t*)lpString;\r
289         if(c < 0)\r
290                 c = strlen(lpString);\r
291         p = AllocateStringW(size);\r
292         if(p)\r
293         {\r
294                 i = MtoW(p, size, lpString, c);\r
295                 p[i] = L'\0';\r
296         }\r
297         return p;\r
298 }\r
299 \r
300 // メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
301 // リソースIDならば元の値を返す\r
302 wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)\r
303 {\r
304         int count;\r
305         wchar_t* p;\r
306         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
307                 return (wchar_t*)lpString;\r
308         count = GetMultiStringLengthM(lpString) + 1;\r
309         p = AllocateStringW(count);\r
310         if(p)\r
311                 MtoW(p, count, lpString, count);\r
312         return p;\r
313 }\r
314 \r
315 // 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
316 // リソースIDならば元の値を返す\r
317 wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)\r
318 {\r
319         int count;\r
320         wchar_t* p;\r
321         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
322                 return (wchar_t*)lpString;\r
323         count = GetMultiStringLengthM(lpString) + 1;\r
324         p = AllocateStringW(size);\r
325         if(p)\r
326         {\r
327                 MtoW(p, size, lpString, count);\r
328                 p[size - 2] = L'\0';\r
329                 p[size - 1] = L'\0';\r
330         }\r
331         return p;\r
332 }\r
333 \r
334 // メモリを確保してワイド文字列からマルチバイト文字列へ変換\r
335 // リソースIDならば元の値を返す\r
336 char* DuplicateWtoM(LPCWSTR lpString, int c)\r
337 {\r
338         char* p;\r
339         int i;\r
340         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
341                 return (char*)lpString;\r
342         if(c < 0)\r
343                 c = wcslen(lpString);\r
344         p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);\r
345         if(p)\r
346         {\r
347                 i = WtoM(p, 65535, lpString, c);\r
348                 p[i] = L'\0';\r
349         }\r
350         return p;\r
351 }\r
352 \r
353 // メモリを確保してShift_JIS文字列からワイド文字列へ変換\r
354 // リソースIDならば元の値を返す\r
355 wchar_t* DuplicateAtoW(LPCSTR lpString, int c)\r
356 {\r
357         wchar_t* p;\r
358         int i;\r
359         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
360                 return (wchar_t*)lpString;\r
361         if(c < 0)\r
362                 c = strlen(lpString);\r
363         p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);\r
364         if(p)\r
365         {\r
366                 i = AtoW(p, 65535, lpString, c);\r
367                 p[i] = L'\0';\r
368         }\r
369         return p;\r
370 }\r
371 \r
372 // メモリを確保してワイド文字列からShift_JIS文字列へ変換\r
373 // リソースIDならば元の値を返す\r
374 char* DuplicateWtoA(LPCWSTR lpString, int c)\r
375 {\r
376         char* p;\r
377         int i;\r
378         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
379                 return (char*)lpString;\r
380         if(c < 0)\r
381                 c = wcslen(lpString);\r
382         p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);\r
383         if(p)\r
384         {\r
385                 i = WtoA(p, 65535, lpString, c);\r
386                 p[i] = L'\0';\r
387         }\r
388         return p;\r
389 }\r
390 \r
391 // マルチバイト文字列からコードポイントと次のポインタを取得\r
392 // エンコードが不正な場合は0x80000000を返す\r
393 DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
394 {\r
395         DWORD Code;\r
396         int i;\r
397         Code = 0;\r
398         if((*lpString & 0xfe) == 0xfc)\r
399         {\r
400                 i = 5;\r
401                 Code |= (DWORD)*lpString & 0x01;\r
402         }\r
403         else if((*lpString & 0xfc) == 0xf8)\r
404         {\r
405                 i = 4;\r
406                 Code |= (DWORD)*lpString & 0x03;\r
407         }\r
408         else if((*lpString & 0xf8) == 0xf0)\r
409         {\r
410                 i = 3;\r
411                 Code |= (DWORD)*lpString & 0x07;\r
412         }\r
413         else if((*lpString & 0xf0) == 0xe0)\r
414         {\r
415                 i = 2;\r
416                 Code |= (DWORD)*lpString & 0x0f;\r
417         }\r
418         else if((*lpString & 0xe0) == 0xc0)\r
419         {\r
420                 i = 1;\r
421                 Code |= (DWORD)*lpString & 0x1f;\r
422         }\r
423         else if((*lpString & 0x80) == 0x00)\r
424         {\r
425                 i = 0;\r
426                 Code |= (DWORD)*lpString & 0x7f;\r
427         }\r
428         else\r
429                 i = -1;\r
430         if(*lpString != 0x00)\r
431         {\r
432                 lpString++;\r
433                 while((*lpString & 0xc0) == 0x80)\r
434                 {\r
435                         i--;\r
436                         Code = Code << 6;\r
437                         Code |= (DWORD)*lpString & 0x3f;\r
438                         lpString++;\r
439                 }\r
440         }\r
441         else\r
442                 lpString++;\r
443         if(i != 0)\r
444                 Code = 0x80000000;\r
445         if(ppNext)\r
446                 *ppNext = lpString;\r
447         return Code;\r
448 }\r
449 \r
450 // マルチバイト文字列の冗長表現を修正\r
451 // 修正があればTRUEを返す\r
452 // 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
453 BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)\r
454 {\r
455         BOOL bResult;\r
456         char* p;\r
457         DWORD Code;\r
458         int i;\r
459         char c;\r
460         bResult = FALSE;\r
461         p = (char*)pSrc;\r
462         while(*pSrc != '\0')\r
463         {\r
464                 Code = GetNextCharM(pSrc, &pSrc);\r
465                 if(Code & 0x80000000)\r
466                         continue;\r
467                 else if(Code & 0x7c000000)\r
468                 {\r
469                         i = 5;\r
470                         c = (char)(0xfc | (Code >> (6 * i)));\r
471                 }\r
472                 else if(Code & 0x03e00000)\r
473                 {\r
474                         i = 4;\r
475                         c = (char)(0xf8 | (Code >> (6 * i)));\r
476                 }\r
477                 else if(Code & 0x001f0000)\r
478                 {\r
479                         i = 3;\r
480                         c = (char)(0xf0 | (Code >> (6 * i)));\r
481                 }\r
482                 else if(Code & 0x0000f800)\r
483                 {\r
484                         i = 2;\r
485                         c = (char)(0xe0 | (Code >> (6 * i)));\r
486                 }\r
487                 else if(Code & 0x00000780)\r
488                 {\r
489                         i = 1;\r
490                         c = (char)(0xc0 | (Code >> (6 * i)));\r
491                 }\r
492                 else\r
493                 {\r
494                         i = 0;\r
495                         c = (char)Code;\r
496                 }\r
497                 if(c != *p)\r
498                         bResult = TRUE;\r
499                 p++;\r
500                 *pDst = c;\r
501                 pDst++;\r
502                 while(i > 0)\r
503                 {\r
504                         i--;\r
505                         c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f));\r
506                         if(c != *p)\r
507                                 bResult = TRUE;\r
508                         p++;\r
509                         *pDst = c;\r
510                         pDst++;\r
511                 }\r
512         }\r
513         if(*p != '\0')\r
514                 bResult = TRUE;\r
515         *pDst = '\0';\r
516         return bResult;\r
517 }\r
518 \r
519 // NULL区切りマルチバイト文字列の冗長表現を修正\r
520 // 修正があればTRUEを返す\r
521 // 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
522 BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc)\r
523 {\r
524         BOOL bResult;\r
525         int Length;\r
526         bResult = FALSE;\r
527         while(*pSrc != '\0')\r
528         {\r
529                 Length = strlen(pSrc) + 1;\r
530                 bResult = bResult | FixStringM(pDst, pSrc);\r
531                 pSrc += Length;\r
532                 pDst += strlen(pDst) + 1;\r
533         }\r
534         *pDst = '\0';\r
535         return bResult;\r
536 }\r
537 \r
538 // マルチバイト文字列の冗長表現を確認\r
539 // 冗長表現があればTRUEを返す\r
540 BOOL CheckStringM(LPCSTR lpString)\r
541 {\r
542         BOOL bResult;\r
543         char* p;\r
544         bResult = FALSE;\r
545         p = AllocateStringM(strlen(lpString) + 1);\r
546         if(p)\r
547         {\r
548                 bResult = FixStringM(p, lpString);\r
549                 FreeDuplicatedString(p);\r
550         }\r
551         return bResult;\r
552 }\r
553 \r
554 // NULL区切りマルチバイト文字列の冗長表現を確認\r
555 // 冗長表現があればTRUEを返す\r
556 BOOL CheckMultiStringM(LPCSTR lpString)\r
557 {\r
558         BOOL bResult;\r
559         char* p;\r
560         bResult = FALSE;\r
561         p = AllocateStringM(GetMultiStringLengthM(lpString) + 1);\r
562         if(p)\r
563         {\r
564                 bResult = FixMultiStringM(p, lpString);\r
565                 FreeDuplicatedString(p);\r
566         }\r
567         return bResult;\r
568 }\r
569 \r
570 // 文字列用に確保したメモリを開放\r
571 // リソースIDならば何もしない\r
572 void FreeDuplicatedString(void* p)\r
573 {\r
574         if(p < (void*)0x00010000 || p == (void*)~0)\r
575                 return;\r
576         free(p);\r
577 }\r
578 \r
579 // 以下ラッパー\r
580 // 戻り値バッファ r\r
581 // ワイド文字バッファ pw%d\r
582 // マルチバイト文字バッファ pm%d\r
583 // 引数バッファ a%d\r
584 \r
585 #pragma warning(disable:4102)\r
586 #define START_ROUTINE                                   do{\r
587 #define END_ROUTINE                                             }while(0);end_of_routine:\r
588 #define QUIT_ROUTINE                                    goto end_of_routine;\r
589 \r
590 int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)\r
591 {\r
592         int r = 0;\r
593         char* pm0 = NULL;\r
594 START_ROUTINE\r
595         pm0 = DuplicateWtoM(lpCmdLine, -1);\r
596         r = WinMainM(hInstance, hPrevInstance, pm0, nCmdShow);\r
597 END_ROUTINE\r
598         FreeDuplicatedString(pm0);\r
599         return r;\r
600 }\r
601 \r
602 HMODULE LoadLibraryM(LPCSTR lpLibFileName)\r
603 {\r
604         HMODULE r = NULL;\r
605         wchar_t* pw0 = NULL;\r
606 START_ROUTINE\r
607         pw0 = DuplicateMtoW(lpLibFileName, -1);\r
608         r = LoadLibraryW(pw0);\r
609 END_ROUTINE\r
610         FreeDuplicatedString(pw0);\r
611         return r;\r
612 }\r
613 \r
614 HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)\r
615 {\r
616         HANDLE r = INVALID_HANDLE_VALUE;\r
617         wchar_t* pw0 = NULL;\r
618 START_ROUTINE\r
619         pw0 = DuplicateMtoW(lpFileName, -1);\r
620         r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);\r
621 END_ROUTINE\r
622         FreeDuplicatedString(pw0);\r
623         return r;\r
624 }\r
625 \r
626 int MessageBoxM(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)\r
627 {\r
628         int r = IDOK;\r
629         wchar_t* pw0 = NULL;\r
630         wchar_t* pw1 = NULL;\r
631 START_ROUTINE\r
632         pw0 = DuplicateMtoW(lpText, -1);\r
633         pw1 = DuplicateMtoW(lpCaption, -1);\r
634         r = MessageBoxW(hWnd, pw0, pw1, uType);\r
635 END_ROUTINE\r
636         FreeDuplicatedString(pw0);\r
637         FreeDuplicatedString(pw1);\r
638         return r;\r
639 }\r
640 \r
641 HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)\r
642 {\r
643         HANDLE r = INVALID_HANDLE_VALUE;\r
644         wchar_t* pw0 = NULL;\r
645         WIN32_FIND_DATAW a0;\r
646 START_ROUTINE\r
647         pw0 = DuplicateMtoW(lpFileName, -1);\r
648         r = FindFirstFileW(pw0, &a0);\r
649         if(r != INVALID_HANDLE_VALUE)\r
650         {\r
651                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
652                 lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
653                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
654                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
655                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
656                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
657                 lpFindFileData->dwReserved0 = a0.dwReserved0;\r
658                 lpFindFileData->dwReserved1 = a0.dwReserved1;\r
659                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
660                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
661         }\r
662 END_ROUTINE\r
663         FreeDuplicatedString(pw0);\r
664         return r;\r
665 }\r
666 \r
667 BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)\r
668 {\r
669         BOOL r = FALSE;\r
670         WIN32_FIND_DATAW a0;\r
671 START_ROUTINE\r
672         r = FindNextFileW(hFindFile, &a0);\r
673         if(r)\r
674         {\r
675                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
676                 lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
677                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
678                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
679                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
680                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
681                 lpFindFileData->dwReserved0 = a0.dwReserved0;\r
682                 lpFindFileData->dwReserved1 = a0.dwReserved1;\r
683                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
684                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
685         }\r
686 END_ROUTINE\r
687         return r;\r
688 }\r
689 \r
690 DWORD GetLogicalDriveStringsM(DWORD nBufferLength, LPSTR lpBuffer)\r
691 {\r
692         DWORD r = 0;\r
693         wchar_t* pw0 = NULL;\r
694 START_ROUTINE\r
695         pw0 = AllocateStringW(nBufferLength * 4);\r
696         GetLogicalDriveStringsW(nBufferLength * 4, pw0);\r
697         WtoMMultiString(lpBuffer, nBufferLength, pw0);\r
698         r = TerminateStringM(lpBuffer, nBufferLength);\r
699 END_ROUTINE\r
700         FreeDuplicatedString(pw0);\r
701         return r;\r
702 }\r
703 \r
704 ATOM RegisterClassExM(CONST WNDCLASSEXA * v0)\r
705 {\r
706         ATOM r = 0;\r
707         wchar_t* pw0 = NULL;\r
708         wchar_t* pw1 = NULL;\r
709         WNDCLASSEXW a0;\r
710 START_ROUTINE\r
711         a0.cbSize = sizeof(WNDCLASSEXW);\r
712         a0.style = v0->style;\r
713         a0.lpfnWndProc = v0->lpfnWndProc;\r
714         a0.cbClsExtra = v0->cbClsExtra;\r
715         a0.cbWndExtra = v0->cbWndExtra;\r
716         a0.hInstance = v0->hInstance;\r
717         a0.hIcon = v0->hIcon;\r
718         a0.hCursor = v0->hCursor;\r
719         a0.hbrBackground = v0->hbrBackground;\r
720         pw0 = DuplicateMtoW(v0->lpszMenuName, -1);\r
721         a0.lpszMenuName = pw0;\r
722         pw1 = DuplicateMtoW(v0->lpszClassName, -1);\r
723         a0.lpszClassName = pw1;\r
724         a0.hIconSm = v0->hIconSm;\r
725         r = RegisterClassExW(&a0);\r
726 END_ROUTINE\r
727         FreeDuplicatedString(pw0);\r
728         FreeDuplicatedString(pw1);\r
729         return r;\r
730 }\r
731 \r
732 HWND CreateWindowExM(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)\r
733 {\r
734         HWND r = NULL;\r
735         wchar_t* pw0 = NULL;\r
736         wchar_t* pw1 = NULL;\r
737 START_ROUTINE\r
738         pw0 = DuplicateMtoW(lpClassName, -1);\r
739         pw1 = DuplicateMtoW(lpWindowName, -1);\r
740         r = CreateWindowExW(dwExStyle, pw0, pw1, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);\r
741 END_ROUTINE\r
742         FreeDuplicatedString(pw0);\r
743         FreeDuplicatedString(pw1);\r
744         return r;\r
745 }\r
746 \r
747 LONG GetWindowLongM(HWND hWnd, int nIndex)\r
748 {\r
749         LONG r = 0;\r
750 START_ROUTINE\r
751         if(IsWindowUnicode(hWnd))\r
752                 r = GetWindowLongW(hWnd, nIndex);\r
753         else\r
754                 r = GetWindowLongA(hWnd, nIndex);\r
755 END_ROUTINE\r
756         return r;\r
757 }\r
758 \r
759 LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)\r
760 {\r
761         LONG r = 0;\r
762 START_ROUTINE\r
763         if(IsWindowUnicode(hWnd))\r
764                 r = SetWindowLongW(hWnd, nIndex, dwNewLong);\r
765         else\r
766                 r = SetWindowLongA(hWnd, nIndex, dwNewLong);\r
767 END_ROUTINE\r
768         return r;\r
769 }\r
770 \r
771 LONG_PTR GetWindowLongPtrM(HWND hWnd, int nIndex)\r
772 {\r
773         LONG_PTR r = 0;\r
774 START_ROUTINE\r
775         if(IsWindowUnicode(hWnd))\r
776                 r = GetWindowLongPtrW(hWnd, nIndex);\r
777         else\r
778                 r = GetWindowLongPtrA(hWnd, nIndex);\r
779 END_ROUTINE\r
780         return r;\r
781 }\r
782 \r
783 LONG_PTR SetWindowLongPtrM(HWND hWnd, int nIndex, LONG_PTR dwNewLong)\r
784 {\r
785         LONG_PTR r = 0;\r
786 START_ROUTINE\r
787         if(IsWindowUnicode(hWnd))\r
788                 r = SetWindowLongPtrW(hWnd, nIndex, dwNewLong);\r
789         else\r
790                 r = SetWindowLongPtrA(hWnd, nIndex, dwNewLong);\r
791 END_ROUTINE\r
792         return r;\r
793 }\r
794 \r
795 LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
796 {\r
797         LRESULT r = 0;\r
798 START_ROUTINE\r
799         if(IsWindowUnicode(hWnd))\r
800                 r = DefWindowProcW(hWnd, Msg, wParam, lParam);\r
801         else\r
802                 r = DefWindowProcA(hWnd, Msg, wParam, lParam);\r
803 END_ROUTINE\r
804         return r;\r
805 }\r
806 \r
807 LRESULT CallWindowProcM(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
808 {\r
809         LRESULT r = 0;\r
810 START_ROUTINE\r
811         if(IsWindowUnicode(hWnd))\r
812                 r = CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
813         else\r
814                 r = CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
815 END_ROUTINE\r
816         return r;\r
817 }\r
818 \r
819 LRESULT SendMessageM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
820 {\r
821         LRESULT r = 0;\r
822         wchar_t* pw0 = NULL;\r
823         wchar_t* pw1 = NULL;\r
824         int Size;\r
825         LVITEMA* pmLVItem;\r
826         LVITEMW wLVItem;\r
827         LVFINDINFOA* pmLVFindInfo;\r
828         LVFINDINFOW wLVFindInfo;\r
829         LVCOLUMNA* pmLVColumn;\r
830         LVCOLUMNW wLVColumn;\r
831         TVITEMEXA* pmTVItem;\r
832         TVITEMEXW wTVItem;\r
833         TVINSERTSTRUCTA* pmTVInsert;\r
834         TVINSERTSTRUCTW wTVInsert;\r
835         wchar_t ClassName[MAX_PATH];\r
836 START_ROUTINE\r
837         switch(Msg)\r
838         {\r
839         case WM_SETTEXT:\r
840                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
841                 r = SendMessageW(hWnd, WM_SETTEXT, wParam, (LPARAM)pw0);\r
842                 break;\r
843         case WM_GETTEXT:\r
844                 pw0 = AllocateStringW(wParam * 4);\r
845                 SendMessageW(hWnd, WM_GETTEXT, wParam * 4, (LPARAM)pw0);\r
846                 WtoM((LPSTR)lParam, wParam, pw0, -1);\r
847                 r = TerminateStringM((LPSTR)lParam, wParam);\r
848                 break;\r
849         case WM_GETTEXTLENGTH:\r
850                 Size = SendMessageW(hWnd, WM_GETTEXTLENGTH, wParam, lParam) + 1;\r
851                 pw0 = AllocateStringW(Size);\r
852                 SendMessageW(hWnd, WM_GETTEXT, (WPARAM)Size, (LPARAM)pw0);\r
853                 r = WtoM(NULL, 0, pw0, -1) - 1;\r
854                 break;\r
855         default:\r
856                 GetClassNameW(hWnd, ClassName, sizeof(ClassName) / sizeof(wchar_t));\r
857                 if(_wcsicmp(ClassName, WC_EDITW) == 0)\r
858                 {\r
859                         switch(Msg)\r
860                         {\r
861                         case EM_REPLACESEL:\r
862                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
863                                 r = SendMessageW(hWnd, EM_REPLACESEL, wParam, (LPARAM)pw0);\r
864                                 break;\r
865                         default:\r
866                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
867                                 break;\r
868                         }\r
869                 }\r
870                 else if(_wcsicmp(ClassName, WC_COMBOBOXW) == 0)\r
871                 {\r
872                         switch(Msg)\r
873                         {\r
874                         case CB_ADDSTRING:\r
875                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
876                                 r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0);\r
877                                 break;\r
878                         case CB_GETLBTEXT:\r
879                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;\r
880                                 pw0 = AllocateStringW(Size);\r
881                                 SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0);\r
882                                 // バッファ長不明のためオーバーランの可能性あり\r
883                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);\r
884                                 r = TerminateStringM((LPSTR)lParam, Size * 4);\r
885                                 break;\r
886                         case CB_GETLBTEXTLEN:\r
887                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;\r
888                                 pw0 = AllocateStringW(Size);\r
889                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);\r
890                                 r = WtoM(NULL, 0, pw0, -1) - 1;\r
891                                 break;\r
892                         case CB_INSERTSTRING:\r
893                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
894                                 r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0);\r
895                                 break;\r
896                         case CB_FINDSTRINGEXACT:\r
897                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
898                                 r = SendMessageW(hWnd, CB_FINDSTRINGEXACT, wParam, (LPARAM)pw0);\r
899                                 break;\r
900                         default:\r
901                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
902                                 break;\r
903                         }\r
904                 }\r
905                 else if(_wcsicmp(ClassName, WC_LISTBOXW) == 0)\r
906                 {\r
907                         switch(Msg)\r
908                         {\r
909                         case LB_ADDSTRING:\r
910                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
911                                 r = SendMessageW(hWnd, LB_ADDSTRING, wParam, (LPARAM)pw0);\r
912                                 break;\r
913                         case LB_INSERTSTRING:\r
914                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
915                                 r = SendMessageW(hWnd, LB_INSERTSTRING, wParam, (LPARAM)pw0);\r
916                                 break;\r
917                         case LB_GETTEXT:\r
918                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;\r
919                                 pw0 = AllocateStringW(Size);\r
920                                 SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0);\r
921                                 // バッファ長不明のためオーバーランの可能性あり\r
922                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);\r
923                                 r = TerminateStringM((LPSTR)lParam, Size * 4);\r
924                                 break;\r
925                         case LB_GETTEXTLEN:\r
926                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;\r
927                                 pw0 = AllocateStringW(Size);\r
928                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);\r
929                                 r = WtoM(NULL, 0, pw0, -1) - 1;\r
930                                 break;\r
931                         default:\r
932                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
933                                 break;\r
934                         }\r
935                 }\r
936                 else if(_wcsicmp(ClassName, WC_LISTVIEWW) == 0)\r
937                 {\r
938                         switch(Msg)\r
939                         {\r
940                         case LVM_GETITEMA:\r
941                                 pmLVItem = (LVITEMA*)lParam;\r
942                                 wLVItem.mask = pmLVItem->mask;\r
943                                 wLVItem.iItem = pmLVItem->iItem;\r
944                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
945                                 wLVItem.state = pmLVItem->state;\r
946                                 wLVItem.stateMask = pmLVItem->stateMask;\r
947                                 if(pmLVItem->mask & LVIF_TEXT)\r
948                                 {\r
949                                         Size = pmLVItem->cchTextMax * 4;\r
950                                         pw0 = AllocateStringW(Size);\r
951                                         wLVItem.pszText = pw0;\r
952                                         wLVItem.cchTextMax = Size;\r
953                                 }\r
954                                 wLVItem.iImage = pmLVItem->iImage;\r
955                                 wLVItem.lParam = pmLVItem->lParam;\r
956                                 wLVItem.iIndent = pmLVItem->iIndent;\r
957                                 r = SendMessageW(hWnd, LVM_GETITEMW, wParam, (LPARAM)&wLVItem);\r
958                                 pmLVItem->mask = wLVItem.mask;\r
959                                 pmLVItem->iItem = wLVItem.iItem;\r
960                                 pmLVItem->iSubItem = wLVItem.iSubItem;\r
961                                 pmLVItem->state = wLVItem.state;\r
962                                 pmLVItem->stateMask = wLVItem.stateMask;\r
963                                 if(pmLVItem->mask & LVIF_TEXT)\r
964                                 {\r
965                                         WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);\r
966                                         TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);\r
967                                 }\r
968                                 pmLVItem->iImage = wLVItem.iImage;\r
969                                 pmLVItem->lParam = wLVItem.lParam;\r
970                                 pmLVItem->iIndent = wLVItem.iIndent;\r
971                                 break;\r
972                         case LVM_SETITEMA:\r
973                                 pmLVItem = (LVITEMA*)lParam;\r
974                                 wLVItem.mask = pmLVItem->mask;\r
975                                 wLVItem.iItem = pmLVItem->iItem;\r
976                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
977                                 wLVItem.state = pmLVItem->state;\r
978                                 wLVItem.stateMask = pmLVItem->stateMask;\r
979                                 if(pmLVItem->mask & LVIF_TEXT)\r
980                                 {\r
981                                         pw0 = DuplicateMtoW(pmLVItem->pszText, -1);\r
982                                         wLVItem.pszText = pw0;\r
983                                         // TODO: cchTextMaxの確認\r
984                                         wLVItem.cchTextMax = pmLVItem->cchTextMax;\r
985                                 }\r
986                                 wLVItem.iImage = pmLVItem->iImage;\r
987                                 wLVItem.lParam = pmLVItem->lParam;\r
988                                 wLVItem.iIndent = pmLVItem->iIndent;\r
989                                 r = SendMessageW(hWnd, LVM_SETITEMW, wParam, (LPARAM)&wLVItem);\r
990                                 break;\r
991                         case LVM_INSERTITEMA:\r
992                                 pmLVItem = (LVITEMA*)lParam;\r
993                                 wLVItem.mask = pmLVItem->mask;\r
994                                 wLVItem.iItem = pmLVItem->iItem;\r
995                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
996                                 wLVItem.state = pmLVItem->state;\r
997                                 wLVItem.stateMask = pmLVItem->stateMask;\r
998                                 if(pmLVItem->mask & LVIF_TEXT)\r
999                                 {\r
1000                                         pw0 = DuplicateMtoW(pmLVItem->pszText, -1);\r
1001                                         wLVItem.pszText = pw0;\r
1002                                         // TODO: cchTextMaxの確認\r
1003                                         wLVItem.cchTextMax = pmLVItem->cchTextMax;\r
1004                                 }\r
1005                                 wLVItem.iImage = pmLVItem->iImage;\r
1006                                 wLVItem.lParam = pmLVItem->lParam;\r
1007                                 wLVItem.iIndent = pmLVItem->iIndent;\r
1008                                 r = SendMessageW(hWnd, LVM_INSERTITEMW, wParam, (LPARAM)&wLVItem);\r
1009                                 break;\r
1010                         case LVM_FINDITEMA:\r
1011                                 pmLVFindInfo = (LVFINDINFOA*)lParam;\r
1012                                 wLVFindInfo.flags = pmLVFindInfo->flags;\r
1013                                 if(pmLVFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL))\r
1014                                 {\r
1015                                         pw0 = DuplicateMtoW(pmLVFindInfo->psz, -1);\r
1016                                         wLVFindInfo.psz = pw0;\r
1017                                 }\r
1018                                 wLVFindInfo.lParam = pmLVFindInfo->lParam;\r
1019                                 wLVFindInfo.pt = pmLVFindInfo->pt;\r
1020                                 wLVFindInfo.vkDirection = pmLVFindInfo->vkDirection;\r
1021                                 r = SendMessageW(hWnd, LVM_FINDITEMW, wParam, (LPARAM)&wLVItem);\r
1022                                 break;\r
1023                         case LVM_GETCOLUMNA:\r
1024                                 pmLVColumn = (LVCOLUMNA*)lParam;\r
1025                                 wLVColumn.mask = pmLVColumn->mask;\r
1026                                 wLVColumn.fmt = pmLVColumn->fmt;\r
1027                                 wLVColumn.cx = pmLVColumn->cx;\r
1028                                 Size = pmLVColumn->cchTextMax * 4;\r
1029                                 if(pmLVColumn->mask & LVCF_TEXT)\r
1030                                 {\r
1031                                         pw0 = AllocateStringW(Size);\r
1032                                         wLVColumn.pszText = pw0;\r
1033                                         wLVColumn.cchTextMax = Size;\r
1034                                 }\r
1035                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;\r
1036                                 wLVColumn.iImage = pmLVColumn->iImage;\r
1037                                 wLVColumn.iOrder = pmLVColumn->iOrder;\r
1038                                 r = SendMessageW(hWnd, LVM_GETCOLUMNW, wParam, (LPARAM)&wLVColumn);\r
1039                                 pmLVColumn->mask = wLVColumn.mask;\r
1040                                 pmLVColumn->fmt = wLVColumn.fmt;\r
1041                                 pmLVColumn->cx = wLVColumn.cx;\r
1042                                 if(pmLVColumn->mask & LVCF_TEXT)\r
1043                                 {\r
1044                                         WtoM(pmLVColumn->pszText, pmLVColumn->cchTextMax, wLVColumn.pszText, -1);\r
1045                                         TerminateStringM(pmLVColumn->pszText, pmLVColumn->cchTextMax);\r
1046                                 }\r
1047                                 pmLVColumn->iSubItem = wLVColumn.iSubItem;\r
1048                                 pmLVColumn->iImage = wLVColumn.iImage;\r
1049                                 pmLVColumn->iOrder = wLVColumn.iOrder;\r
1050                                 break;\r
1051                         case LVM_INSERTCOLUMNA:\r
1052                                 pmLVColumn = (LVCOLUMNA*)lParam;\r
1053                                 wLVColumn.mask = pmLVColumn->mask;\r
1054                                 wLVColumn.fmt = pmLVColumn->fmt;\r
1055                                 wLVColumn.cx = pmLVColumn->cx;\r
1056                                 if(pmLVColumn->mask & LVCF_TEXT)\r
1057                                 {\r
1058                                         pw0 = DuplicateMtoW(pmLVColumn->pszText, -1);\r
1059                                         wLVColumn.pszText = pw0;\r
1060                                         // TODO: cchTextMaxの確認\r
1061                                         wLVColumn.cchTextMax = pmLVColumn->cchTextMax;\r
1062                                 }\r
1063                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;\r
1064                                 wLVColumn.iImage = pmLVColumn->iImage;\r
1065                                 wLVColumn.iOrder = pmLVColumn->iOrder;\r
1066                                 r = SendMessageW(hWnd, LVM_INSERTCOLUMNW, wParam, (LPARAM)&wLVColumn);\r
1067                                 break;\r
1068                         case LVM_GETITEMTEXTA:\r
1069                                 pmLVItem = (LVITEMA*)lParam;\r
1070                                 wLVItem.mask = pmLVItem->mask;\r
1071                                 wLVItem.iItem = pmLVItem->iItem;\r
1072                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
1073                                 wLVItem.state = pmLVItem->state;\r
1074                                 wLVItem.stateMask = pmLVItem->stateMask;\r
1075                                 Size = pmLVItem->cchTextMax * 4;\r
1076                                 pw0 = AllocateStringW(Size);\r
1077                                 wLVItem.pszText = pw0;\r
1078                                 wLVItem.cchTextMax = Size;\r
1079                                 wLVItem.iImage = pmLVItem->iImage;\r
1080                                 wLVItem.lParam = pmLVItem->lParam;\r
1081                                 wLVItem.iIndent = pmLVItem->iIndent;\r
1082                                 r = SendMessageW(hWnd, LVM_GETITEMTEXTW, wParam, (LPARAM)&wLVItem);\r
1083                                 pmLVItem->mask = wLVItem.mask;\r
1084                                 pmLVItem->iItem = wLVItem.iItem;\r
1085                                 pmLVItem->iSubItem = wLVItem.iSubItem;\r
1086                                 pmLVItem->state = wLVItem.state;\r
1087                                 pmLVItem->stateMask = wLVItem.stateMask;\r
1088                                 WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);\r
1089                                 TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);\r
1090                                 pmLVItem->iImage = wLVItem.iImage;\r
1091                                 pmLVItem->lParam = wLVItem.lParam;\r
1092                                 pmLVItem->iIndent = wLVItem.iIndent;\r
1093                                 break;\r
1094                         default:\r
1095                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
1096                                 break;\r
1097                         }\r
1098                 }\r
1099                 else if(_wcsicmp(ClassName, STATUSCLASSNAMEW) == 0)\r
1100                 {\r
1101                         switch(Msg)\r
1102                         {\r
1103                         case SB_SETTEXTA:\r
1104                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
1105                                 r = SendMessageW(hWnd, SB_SETTEXTW, wParam, (LPARAM)pw0);\r
1106                                 break;\r
1107                         default:\r
1108                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
1109                                 break;\r
1110                         }\r
1111                 }\r
1112                 else if(_wcsicmp(ClassName, WC_TREEVIEWW) == 0)\r
1113                 {\r
1114                         switch(Msg)\r
1115                         {\r
1116                         case TVM_GETITEMA:\r
1117                                 pmTVItem = (TVITEMEXA*)lParam;\r
1118                                 wTVItem.mask = pmTVItem->mask;\r
1119                                 wTVItem.hItem = pmTVItem->hItem;\r
1120                                 wTVItem.state = pmTVItem->state;\r
1121                                 wTVItem.stateMask = pmTVItem->stateMask;\r
1122                                 if(pmTVItem->mask & TVIF_TEXT)\r
1123                                 {\r
1124                                         Size = pmTVItem->cchTextMax * 4;\r
1125                                         pw0 = AllocateStringW(Size);\r
1126                                         wTVItem.pszText = pw0;\r
1127                                         wTVItem.cchTextMax = Size;\r
1128                                 }\r
1129                                 wTVItem.iImage = pmTVItem->iImage;\r
1130                                 wTVItem.iSelectedImage = pmTVItem->iSelectedImage;\r
1131                                 wTVItem.cChildren = pmTVItem->cChildren;\r
1132                                 wTVItem.lParam = pmTVItem->lParam;\r
1133                                 wTVItem.iIntegral = pmTVItem->iIntegral;\r
1134 //                              wTVItem.uStateEx = pmTVItem->uStateEx;\r
1135 //                              wTVItem.hwnd = pmTVItem->hwnd;\r
1136 //                              wTVItem.iExpandedImage = pmTVItem->iExpandedImage;\r
1137 //                              wTVItem.iReserved = pmTVItem->iReserved;\r
1138                                 r = SendMessageW(hWnd, TVM_GETITEMW, wParam, (LPARAM)&wTVItem);\r
1139                                 pmTVItem->mask = wTVItem.mask;\r
1140                                 pmTVItem->hItem = wTVItem.hItem;\r
1141                                 pmTVItem->state = wTVItem.state;\r
1142                                 pmTVItem->stateMask = wTVItem.stateMask;\r
1143                                 if(pmTVItem->mask & TVIF_TEXT)\r
1144                                 {\r
1145                                         WtoM(pmTVItem->pszText, pmTVItem->cchTextMax, wTVItem.pszText, -1);\r
1146                                         TerminateStringM(pmTVItem->pszText, pmTVItem->cchTextMax);\r
1147                                 }\r
1148                                 pmTVItem->iImage = wTVItem.iImage;\r
1149                                 pmTVItem->iSelectedImage = wTVItem.iSelectedImage;\r
1150                                 pmTVItem->cChildren = wTVItem.cChildren;\r
1151                                 pmTVItem->lParam = wTVItem.lParam;\r
1152                                 pmTVItem->iIntegral = wTVItem.iIntegral;\r
1153 //                              pmTVItem->uStateEx = wTVItem.uStateEx;\r
1154 //                              pmTVItem->hwnd = wTVItem.hwnd;\r
1155 //                              pmTVItem->iExpandedImage = wTVItem.iExpandedImage;\r
1156 //                              pmTVItem->iReserved = wTVItem.iReserved;\r
1157                                 break;\r
1158                         case TVM_INSERTITEMA:\r
1159                                 pmTVInsert = (TVINSERTSTRUCTA*)lParam;\r
1160                                 wTVInsert.hParent = pmTVInsert->hParent;\r
1161                                 wTVInsert.hInsertAfter = pmTVInsert->hInsertAfter;\r
1162                                 wTVInsert.itemex.mask = pmTVInsert->itemex.mask;\r
1163                                 wTVInsert.itemex.hItem = pmTVInsert->itemex.hItem;\r
1164                                 wTVInsert.itemex.state = pmTVInsert->itemex.state;\r
1165                                 wTVInsert.itemex.stateMask = pmTVInsert->itemex.stateMask;\r
1166                                 if(pmTVInsert->itemex.mask & TVIF_TEXT)\r
1167                                 {\r
1168                                         pw0 = DuplicateMtoW(pmTVInsert->itemex.pszText, -1);\r
1169                                         wTVInsert.itemex.pszText = pw0;\r
1170                                         // TODO: cchTextMaxの確認\r
1171                                         wTVInsert.itemex.cchTextMax = pmTVInsert->itemex.cchTextMax;\r
1172                                 }\r
1173                                 wTVInsert.itemex.iImage = pmTVInsert->itemex.iImage;\r
1174                                 wTVInsert.itemex.iSelectedImage = pmTVInsert->itemex.iSelectedImage;\r
1175                                 wTVInsert.itemex.cChildren = pmTVInsert->itemex.cChildren;\r
1176                                 wTVInsert.itemex.lParam = pmTVInsert->itemex.lParam;\r
1177                                 wTVInsert.itemex.iIntegral = pmTVInsert->itemex.iIntegral;\r
1178 //                              wTVInsert.itemex.uStateEx = pmTVInsert->itemex.uStateEx;\r
1179 //                              wTVInsert.itemex.hwnd = pmTVInsert->itemex.hwnd;\r
1180 //                              wTVInsert.itemex.iExpandedImage = pmTVInsert->itemex.iExpandedImage;\r
1181 //                              wTVInsert.itemex.iReserved = pmTVInsert->itemex.iReserved;\r
1182                                 r = SendMessageW(hWnd, TVM_INSERTITEMW, wParam, (LPARAM)&wTVInsert);\r
1183                                 break;\r
1184                         default:\r
1185                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
1186                                 break;\r
1187                         }\r
1188                 }\r
1189                 else\r
1190                         r = SendMessageW(hWnd, Msg, wParam, lParam);\r
1191                 break;\r
1192         }\r
1193 END_ROUTINE\r
1194         FreeDuplicatedString(pw0);\r
1195         FreeDuplicatedString(pw1);\r
1196         return r;\r
1197 }\r
1198 \r
1199 LRESULT DefDlgProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
1200 {\r
1201         LRESULT r = 0;\r
1202 START_ROUTINE\r
1203         // WNDPROCがShift_JIS用であるため\r
1204         if(IsWindowUnicode(hWnd))\r
1205                 r = DefDlgProcW(hWnd, Msg, wParam, lParam);\r
1206         else\r
1207                 r = DefDlgProcA(hWnd, Msg, wParam, lParam);\r
1208 END_ROUTINE\r
1209         return r;\r
1210 }\r
1211 \r
1212 LRESULT SendDlgItemMessageM(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)\r
1213 {\r
1214         LRESULT r = 0;\r
1215 START_ROUTINE\r
1216         r = SendMessageM(GetDlgItem(hDlg, nIDDlgItem), Msg, wParam, lParam);\r
1217 END_ROUTINE\r
1218         return r;\r
1219 }\r
1220 \r
1221 BOOL SetWindowTextM(HWND hWnd, LPCSTR lpString)\r
1222 {\r
1223         BOOL r = FALSE;\r
1224         wchar_t* pw0 = NULL;\r
1225 START_ROUTINE\r
1226         pw0 = DuplicateMtoW(lpString, -1);\r
1227         r = SetWindowTextW(hWnd, pw0);\r
1228 END_ROUTINE\r
1229         FreeDuplicatedString(pw0);\r
1230         return r;\r
1231 }\r
1232 \r
1233 UINT DragQueryFileM(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch)\r
1234 {\r
1235         UINT r = 0;\r
1236         wchar_t* pw0 = NULL;\r
1237 START_ROUTINE\r
1238         if(iFile == (UINT)-1)\r
1239                 r = DragQueryFileW(hDrop, iFile, (LPWSTR)lpszFile, cch);\r
1240         else\r
1241         {\r
1242                 pw0 = AllocateStringW(cch * 4);\r
1243                 DragQueryFileW(hDrop, iFile, pw0, cch * 4);\r
1244                 WtoM(lpszFile, cch, pw0, -1);\r
1245                 r = TerminateStringM(lpszFile, cch);\r
1246         }\r
1247 END_ROUTINE\r
1248         FreeDuplicatedString(pw0);\r
1249         return r;\r
1250 }\r
1251 \r
1252 LPSTR GetCommandLineM()\r
1253 {\r
1254         LPSTR r = 0;\r
1255         static char* pm0 = NULL;\r
1256 START_ROUTINE\r
1257         if(!pm0)\r
1258                 pm0 = DuplicateWtoM(GetCommandLineW(), -1);\r
1259         r = pm0;\r
1260 END_ROUTINE\r
1261         return r;\r
1262 }\r
1263 \r
1264 DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)\r
1265 {\r
1266         DWORD r = 0;\r
1267         wchar_t* pw0 = NULL;\r
1268 START_ROUTINE\r
1269         // TODO: バッファが不十分な場合に必要なサイズを返す\r
1270         pw0 = AllocateStringW(nBufferLength * 4);\r
1271         GetCurrentDirectoryW(nBufferLength * 4, pw0);\r
1272         WtoM(lpBuffer, nBufferLength, pw0, -1);\r
1273         r = TerminateStringM(lpBuffer, nBufferLength);\r
1274 END_ROUTINE\r
1275         FreeDuplicatedString(pw0);\r
1276         return r;\r
1277 }\r
1278 \r
1279 BOOL SetCurrentDirectoryM(LPCSTR lpPathName)\r
1280 {\r
1281         BOOL r = FALSE;\r
1282         wchar_t* pw0 = NULL;\r
1283 START_ROUTINE\r
1284         pw0 = DuplicateMtoW(lpPathName, -1);\r
1285         r = SetCurrentDirectoryW(pw0);\r
1286 END_ROUTINE\r
1287         FreeDuplicatedString(pw0);\r
1288         return r;\r
1289 }\r
1290 \r
1291 DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)\r
1292 {\r
1293         DWORD r = 0;\r
1294         wchar_t* pw0 = NULL;\r
1295 START_ROUTINE\r
1296         pw0 = AllocateStringW(nBufferLength * 4);\r
1297         GetTempPathW(nBufferLength * 4, pw0);\r
1298         WtoM(lpBuffer, nBufferLength, pw0, -1);\r
1299         r = TerminateStringM(lpBuffer, nBufferLength);\r
1300 END_ROUTINE\r
1301         FreeDuplicatedString(pw0);\r
1302         return r;\r
1303 }\r
1304 \r
1305 DWORD GetFileAttributesM(LPCSTR lpFileName)\r
1306 {\r
1307         DWORD r = FALSE;\r
1308         wchar_t* pw0 = NULL;\r
1309 START_ROUTINE\r
1310         pw0 = DuplicateMtoW(lpFileName, -1);\r
1311         r = GetFileAttributesW(pw0);\r
1312 END_ROUTINE\r
1313         FreeDuplicatedString(pw0);\r
1314         return r;\r
1315 }\r
1316 \r
1317 DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)\r
1318 {\r
1319         DWORD r = 0;\r
1320         wchar_t* pw0 = NULL;\r
1321 START_ROUTINE\r
1322         pw0 = AllocateStringW(nSize * 4);\r
1323         GetModuleFileNameW(hModule, pw0, nSize * 4);\r
1324         WtoM(lpFilename, nSize, pw0, -1);\r
1325         r = TerminateStringM(lpFilename, nSize);\r
1326 END_ROUTINE\r
1327         FreeDuplicatedString(pw0);\r
1328         return r;\r
1329 }\r
1330 \r
1331 LSTATUS RegOpenKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)\r
1332 {\r
1333         LSTATUS r = 0;\r
1334         wchar_t* pw0 = NULL;\r
1335 START_ROUTINE\r
1336         pw0 = DuplicateMtoW(lpSubKey, -1);\r
1337         r = RegOpenKeyExW(hKey, pw0, ulOptions, samDesired, phkResult);\r
1338 END_ROUTINE\r
1339         FreeDuplicatedString(pw0);\r
1340         return r;\r
1341 }\r
1342 \r
1343 LSTATUS RegCreateKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)\r
1344 {\r
1345         LSTATUS r = 0;\r
1346         wchar_t* pw0 = NULL;\r
1347         wchar_t* pw1 = NULL;\r
1348 START_ROUTINE\r
1349         pw0 = DuplicateMtoW(lpSubKey, -1);\r
1350         pw1 = DuplicateMtoW(lpClass, -1);\r
1351         r = RegCreateKeyExW(hKey, pw0, Reserved, pw1, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);\r
1352 END_ROUTINE\r
1353         FreeDuplicatedString(pw0);\r
1354         FreeDuplicatedString(pw1);\r
1355         return r;\r
1356 }\r
1357 \r
1358 LSTATUS RegDeleteValueM(HKEY hKey, LPCSTR lpValueName)\r
1359 {\r
1360         LSTATUS r = 0;\r
1361         wchar_t* pw0 = NULL;\r
1362 START_ROUTINE\r
1363         pw0 = DuplicateMtoW(lpValueName, -1);\r
1364         r = RegDeleteValueW(hKey, pw0);\r
1365 END_ROUTINE\r
1366         FreeDuplicatedString(pw0);\r
1367         return r;\r
1368 }\r
1369 \r
1370 LSTATUS RegQueryValueExM(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)\r
1371 {\r
1372         LSTATUS r = 0;\r
1373         wchar_t* pw0 = NULL;\r
1374         wchar_t* pw1 = NULL;\r
1375         DWORD dwType;\r
1376         DWORD wcbData;\r
1377 START_ROUTINE\r
1378         pw0 = DuplicateMtoW(lpValueName, -1);\r
1379         if(RegQueryValueExW(hKey, pw0, NULL, &dwType, NULL, 0) == ERROR_SUCCESS)\r
1380         {\r
1381                 switch(dwType)\r
1382                 {\r
1383                 case REG_SZ:\r
1384                 case REG_EXPAND_SZ:\r
1385                 case REG_MULTI_SZ:\r
1386                         if(lpcbData)\r
1387                         {\r
1388                                 pw1 = AllocateStringW(*lpcbData / sizeof(char) * 4);\r
1389                                 wcbData = *lpcbData / sizeof(char) * 4;\r
1390                                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, (LPBYTE)pw1, &wcbData);\r
1391                                 if(lpData)\r
1392                                         *lpcbData = sizeof(char) * WtoM((char*)lpData, *lpcbData / sizeof(char), pw1, wcbData / sizeof(wchar_t));\r
1393                                 else\r
1394                                         *lpcbData = sizeof(char) * WtoM(NULL, 0, pw1, wcbData / sizeof(wchar_t));\r
1395                         }\r
1396                         break;\r
1397                 default:\r
1398                         r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);\r
1399                         break;\r
1400                 }\r
1401         }\r
1402         else\r
1403                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);\r
1404 END_ROUTINE\r
1405         FreeDuplicatedString(pw0);\r
1406         FreeDuplicatedString(pw1);\r
1407         return r;\r
1408 }\r
1409 \r
1410 LSTATUS RegSetValueExM(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData)\r
1411 {\r
1412         LSTATUS r = 0;\r
1413         wchar_t* pw0 = NULL;\r
1414         wchar_t* pw1 = NULL;\r
1415         DWORD wcbData;\r
1416 START_ROUTINE\r
1417         pw0 = DuplicateMtoW(lpValueName, -1);\r
1418         switch(dwType)\r
1419         {\r
1420         case REG_SZ:\r
1421         case REG_EXPAND_SZ:\r
1422         case REG_MULTI_SZ:\r
1423                 wcbData = MtoW(NULL, 0, (char*)lpData, cbData / sizeof(char));\r
1424                 pw1 = AllocateStringW(wcbData);\r
1425                 MtoW(pw1, wcbData, (char*)lpData, cbData / sizeof(char));\r
1426                 wcbData = sizeof(wchar_t) * wcbData;\r
1427                 lpData = (BYTE*)pw1;\r
1428                 cbData = wcbData;\r
1429                 break;\r
1430         }\r
1431         r = RegSetValueExW(hKey, pw0, Reserved, dwType, lpData, cbData);\r
1432 END_ROUTINE\r
1433         FreeDuplicatedString(pw0);\r
1434         FreeDuplicatedString(pw1);\r
1435         return r;\r
1436 }\r
1437 \r
1438 BOOL TextOutM(HDC hdc, int x, int y, LPCSTR lpString, int c)\r
1439 {\r
1440         BOOL r = FALSE;\r
1441         wchar_t* pw0 = NULL;\r
1442 START_ROUTINE\r
1443         pw0 = DuplicateMtoW(lpString, c);\r
1444         r = TextOutW(hdc, x, y, pw0, wcslen(pw0));\r
1445 END_ROUTINE\r
1446         FreeDuplicatedString(pw0);\r
1447         return r;\r
1448 }\r
1449 \r
1450 BOOL GetTextExtentPoint32M(HDC hdc, LPCSTR lpString, int c, LPSIZE psizl)\r
1451 {\r
1452         BOOL r = FALSE;\r
1453         wchar_t* pw0 = NULL;\r
1454 START_ROUTINE\r
1455         pw0 = DuplicateMtoW(lpString, c);\r
1456         r = GetTextExtentPoint32W(hdc, pw0, wcslen(pw0), psizl);\r
1457 END_ROUTINE\r
1458         FreeDuplicatedString(pw0);\r
1459         return r;\r
1460 }\r
1461 \r
1462 INT_PTR PropertySheetM(LPCPROPSHEETHEADERA v0)\r
1463 {\r
1464         INT_PTR r = 0;\r
1465         PROPSHEETHEADERW a0;\r
1466         PROPSHEETPAGEW* pwPage;\r
1467         UINT i;\r
1468 START_ROUTINE\r
1469         a0.dwSize = sizeof(PROPSHEETHEADERW);\r
1470         a0.dwFlags = v0->dwFlags;\r
1471         a0.hwndParent = v0->hwndParent;\r
1472         a0.hInstance = v0->hInstance;\r
1473         if(v0->dwFlags & PSH_USEICONID)\r
1474                 a0.pszIcon = DuplicateMtoW(v0->pszIcon, -1);\r
1475         else\r
1476                 a0.hIcon = v0->hIcon;\r
1477         a0.pszCaption = DuplicateMtoW(v0->pszCaption, -1);\r
1478         a0.nPages = v0->nPages;\r
1479         if(v0->dwFlags & PSH_USEPSTARTPAGE)\r
1480                 a0.pStartPage = DuplicateMtoW(v0->pStartPage, -1);\r
1481         else\r
1482                 a0.nStartPage = v0->nStartPage;\r
1483         if(v0->dwFlags & PSH_PROPSHEETPAGE)\r
1484         {\r
1485                 if(v0->ppsp && (pwPage = (PROPSHEETPAGEW*)malloc(sizeof(PROPSHEETPAGEW) * v0->nPages)))\r
1486                 {\r
1487                         for(i = 0; i < v0->nPages; i++)\r
1488                         {\r
1489                                 pwPage[i].dwSize = sizeof(PROPSHEETPAGEW);\r
1490                                 pwPage[i].dwFlags = v0->ppsp[i].dwFlags;\r
1491                                 pwPage[i].hInstance = v0->ppsp[i].hInstance;\r
1492                                 if(v0->ppsp[i].dwFlags & PSP_DLGINDIRECT)\r
1493                                         pwPage[i].pResource = v0->ppsp[i].pResource;\r
1494                                 else\r
1495                                         pwPage[i].pszTemplate = DuplicateMtoW(v0->ppsp[i].pszTemplate, -1);\r
1496                                 if(v0->ppsp[i].dwFlags & PSP_USEICONID)\r
1497                                         pwPage[i].pszIcon = DuplicateMtoW(v0->ppsp[i].pszIcon, -1);\r
1498                                 else\r
1499                                         pwPage[i].hIcon = v0->ppsp[i].hIcon;\r
1500                                 if(v0->ppsp[i].dwFlags & PSP_USETITLE)\r
1501                                         pwPage[i].pszTitle = DuplicateMtoW(v0->ppsp[i].pszTitle, -1);\r
1502                                 pwPage[i].pfnDlgProc = v0->ppsp[i].pfnDlgProc;\r
1503                                 pwPage[i].lParam = v0->ppsp[i].lParam;\r
1504                                 // TODO: pfnCallback\r
1505                                 pwPage[i].pfnCallback = (LPFNPSPCALLBACKW)v0->ppsp[i].pfnCallback;\r
1506                                 pwPage[i].pcRefParent = v0->ppsp[i].pcRefParent;\r
1507                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERTITLE)\r
1508                                         pwPage[i].pszHeaderTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderTitle, -1);\r
1509                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERSUBTITLE)\r
1510                                         pwPage[i].pszHeaderSubTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderSubTitle, -1);\r
1511                         }\r
1512                 }\r
1513                 else\r
1514                         pwPage = NULL;\r
1515                 a0.ppsp = pwPage;\r
1516         }\r
1517         else\r
1518                 a0.phpage = v0->phpage;\r
1519         a0.pfnCallback = v0->pfnCallback;\r
1520         if(v0->dwFlags & PSH_USEHBMWATERMARK)\r
1521                 a0.hbmWatermark = v0->hbmWatermark;\r
1522         else\r
1523                 a0.pszbmWatermark = DuplicateMtoW(v0->pszbmWatermark, -1);\r
1524         r = PropertySheetW(&a0);\r
1525         if(a0.dwFlags & PSH_USEICONID)\r
1526                 FreeDuplicatedString((void*)a0.pszIcon);\r
1527         FreeDuplicatedString((void*)a0.pszCaption);\r
1528         if(v0->dwFlags & PSH_USEPSTARTPAGE)\r
1529                 FreeDuplicatedString((void*)a0.pStartPage);\r
1530         if(v0->dwFlags & PSH_PROPSHEETPAGE)\r
1531         {\r
1532                 if(pwPage)\r
1533                 {\r
1534                         for(i = 0; i < v0->nPages; i++)\r
1535                         {\r
1536                                 if(!(v0->ppsp[i].dwFlags & PSP_DLGINDIRECT))\r
1537                                         FreeDuplicatedString((void*)pwPage[i].pszTemplate);\r
1538                                 if(v0->ppsp[i].dwFlags & PSP_USEICONID)\r
1539                                         FreeDuplicatedString((void*)pwPage[i].pszIcon);\r
1540                                 if(v0->ppsp[i].dwFlags & PSP_USETITLE)\r
1541                                         FreeDuplicatedString((void*)pwPage[i].pszTitle);\r
1542                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERTITLE)\r
1543                                         FreeDuplicatedString((void*)pwPage[i].pszHeaderTitle);\r
1544                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERSUBTITLE)\r
1545                                         FreeDuplicatedString((void*)pwPage[i].pszHeaderSubTitle);\r
1546                         }\r
1547                         free(pwPage);\r
1548                 }\r
1549         }\r
1550         if(!(v0->dwFlags & PSH_USEHBMWATERMARK))\r
1551                 FreeDuplicatedString((void*)a0.pszbmWatermark);\r
1552 END_ROUTINE\r
1553         return r;\r
1554 }\r
1555 \r
1556 BOOL GetOpenFileNameM(LPOPENFILENAMEA v0)\r
1557 {\r
1558         BOOL r = FALSE;\r
1559         wchar_t* pw0 = NULL;\r
1560         wchar_t* pw1 = NULL;\r
1561         wchar_t* pw2 = NULL;\r
1562         wchar_t* pw3 = NULL;\r
1563         wchar_t* pw4 = NULL;\r
1564         wchar_t* pw5 = NULL;\r
1565         wchar_t* pw6 = NULL;\r
1566         wchar_t* pw7 = NULL;\r
1567         wchar_t* pw8 = NULL;\r
1568         wchar_t* pw9 = NULL;\r
1569         OPENFILENAMEW wofn;\r
1570 START_ROUTINE\r
1571         wofn.lStructSize = sizeof(OPENFILENAMEW);\r
1572         wofn.hwndOwner = v0->hwndOwner;\r
1573         wofn.hInstance = v0->hInstance;\r
1574         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);\r
1575         wofn.lpstrFilter = pw0;\r
1576         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);\r
1577         wofn.lpstrCustomFilter = pw1;\r
1578         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;\r
1579         wofn.nFilterIndex = v0->nFilterIndex;\r
1580         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);\r
1581         wofn.lpstrFile = pw2;\r
1582         wofn.nMaxFile = v0->nMaxFile * 4;\r
1583         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);\r
1584         wofn.lpstrFileTitle = pw3;\r
1585         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;\r
1586         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);\r
1587         wofn.lpstrInitialDir = pw4;\r
1588         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);\r
1589         wofn.lpstrTitle = pw5;\r
1590         wofn.Flags = v0->Flags;\r
1591         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);\r
1592         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);\r
1593         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);\r
1594         wofn.lpstrDefExt = pw6;\r
1595         wofn.lCustData = v0->lCustData;\r
1596         wofn.lpfnHook = v0->lpfnHook;\r
1597         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
1598         wofn.pvReserved = v0->pvReserved;\r
1599         wofn.FlagsEx = v0->FlagsEx;\r
1600         r = GetOpenFileNameW(&wofn);\r
1601         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);\r
1602         TerminateStringM(v0->lpstrFile, v0->nMaxFile);\r
1603         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);\r
1604         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);\r
1605 END_ROUTINE\r
1606         FreeDuplicatedString(pw0);\r
1607         FreeDuplicatedString(pw1);\r
1608         FreeDuplicatedString(pw2);\r
1609         FreeDuplicatedString(pw3);\r
1610         FreeDuplicatedString(pw4);\r
1611         FreeDuplicatedString(pw5);\r
1612         FreeDuplicatedString(pw6);\r
1613         return r;\r
1614 }\r
1615 \r
1616 BOOL GetSaveFileNameM(LPOPENFILENAMEA v0)\r
1617 {\r
1618         BOOL r = FALSE;\r
1619         wchar_t* pw0 = NULL;\r
1620         wchar_t* pw1 = NULL;\r
1621         wchar_t* pw2 = NULL;\r
1622         wchar_t* pw3 = NULL;\r
1623         wchar_t* pw4 = NULL;\r
1624         wchar_t* pw5 = NULL;\r
1625         wchar_t* pw6 = NULL;\r
1626         wchar_t* pw7 = NULL;\r
1627         wchar_t* pw8 = NULL;\r
1628         wchar_t* pw9 = NULL;\r
1629         OPENFILENAMEW wofn;\r
1630 START_ROUTINE\r
1631         wofn.lStructSize = sizeof(OPENFILENAMEW);\r
1632         wofn.hwndOwner = v0->hwndOwner;\r
1633         wofn.hInstance = v0->hInstance;\r
1634         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);\r
1635         wofn.lpstrFilter = pw0;\r
1636         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);\r
1637         wofn.lpstrCustomFilter = pw1;\r
1638         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;\r
1639         wofn.nFilterIndex = v0->nFilterIndex;\r
1640         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);\r
1641         wofn.lpstrFile = pw2;\r
1642         wofn.nMaxFile = v0->nMaxFile * 4;\r
1643         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);\r
1644         wofn.lpstrFileTitle = pw3;\r
1645         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;\r
1646         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);\r
1647         wofn.lpstrInitialDir = pw4;\r
1648         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);\r
1649         wofn.lpstrTitle = pw5;\r
1650         wofn.Flags = v0->Flags;\r
1651         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);\r
1652         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);\r
1653         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);\r
1654         wofn.lpstrDefExt = pw6;\r
1655         wofn.lCustData = v0->lCustData;\r
1656         wofn.lpfnHook = v0->lpfnHook;\r
1657         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
1658         wofn.pvReserved = v0->pvReserved;\r
1659         wofn.FlagsEx = v0->FlagsEx;\r
1660         r = GetSaveFileNameW(&wofn);\r
1661         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);\r
1662         TerminateStringM(v0->lpstrFile, v0->nMaxFile);\r
1663         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);\r
1664         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);\r
1665 END_ROUTINE\r
1666         FreeDuplicatedString(pw0);\r
1667         FreeDuplicatedString(pw1);\r
1668         FreeDuplicatedString(pw2);\r
1669         FreeDuplicatedString(pw3);\r
1670         FreeDuplicatedString(pw4);\r
1671         FreeDuplicatedString(pw5);\r
1672         FreeDuplicatedString(pw6);\r
1673         return r;\r
1674 }\r
1675 \r
1676 HWND HtmlHelpM(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData)\r
1677 {\r
1678         HWND r = NULL;\r
1679         wchar_t* pw0 = NULL;\r
1680 START_ROUTINE\r
1681         pw0 = DuplicateMtoW(pszFile, -1);\r
1682         r = HtmlHelpW(hwndCaller, pw0, uCommand, dwData);\r
1683 END_ROUTINE\r
1684         FreeDuplicatedString(pw0);\r
1685         return r;\r
1686 }\r
1687 \r
1688 BOOL CreateProcessM(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)\r
1689 {\r
1690         BOOL r = FALSE;\r
1691         wchar_t* pw0 = NULL;\r
1692         wchar_t* pw1 = NULL;\r
1693         wchar_t* pw2 = NULL;\r
1694         wchar_t* pw3 = NULL;\r
1695         wchar_t* pw4 = NULL;\r
1696         wchar_t* pw5 = NULL;\r
1697         STARTUPINFOW wStartupInfo;\r
1698 START_ROUTINE\r
1699         pw0 = DuplicateMtoW(lpApplicationName, -1);\r
1700         pw1 = DuplicateMtoWBuffer(lpCommandLine, -1, (strlen(lpCommandLine) + 1) * 4);\r
1701         pw2 = DuplicateMtoW(lpCurrentDirectory, -1);\r
1702         wStartupInfo.cb = sizeof(LPSTARTUPINFOW);\r
1703         pw3 = DuplicateMtoW(lpStartupInfo->lpReserved, -1);\r
1704         wStartupInfo.lpReserved = pw3;\r
1705         pw4 = DuplicateMtoW(lpStartupInfo->lpDesktop, -1);\r
1706         wStartupInfo.lpDesktop = pw4;\r
1707         pw5 = DuplicateMtoW(lpStartupInfo->lpTitle, -1);\r
1708         wStartupInfo.lpTitle = pw5;\r
1709         wStartupInfo.dwX = lpStartupInfo->dwX;\r
1710         wStartupInfo.dwY = lpStartupInfo->dwY;\r
1711         wStartupInfo.dwXSize = lpStartupInfo->dwXSize;\r
1712         wStartupInfo.dwYSize = lpStartupInfo->dwYSize;\r
1713         wStartupInfo.dwXCountChars = lpStartupInfo->dwXCountChars;\r
1714         wStartupInfo.dwYCountChars = lpStartupInfo->dwYCountChars;\r
1715         wStartupInfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;\r
1716         wStartupInfo.dwFlags = lpStartupInfo->dwFlags;\r
1717         wStartupInfo.wShowWindow = lpStartupInfo->wShowWindow;\r
1718         wStartupInfo.cbReserved2 = lpStartupInfo->cbReserved2;\r
1719         wStartupInfo.lpReserved2 = lpStartupInfo->lpReserved2;\r
1720         wStartupInfo.hStdInput = lpStartupInfo->hStdInput;\r
1721         wStartupInfo.hStdOutput = lpStartupInfo->hStdOutput;\r
1722         wStartupInfo.hStdError = lpStartupInfo->hStdError;\r
1723         r = CreateProcessW(pw0, pw1, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pw2, &wStartupInfo, lpProcessInformation);\r
1724         WtoM(lpCommandLine, strlen(lpCommandLine) + 1, pw1, -1);\r
1725 END_ROUTINE\r
1726         FreeDuplicatedString(pw0);\r
1727         FreeDuplicatedString(pw1);\r
1728         FreeDuplicatedString(pw2);\r
1729         FreeDuplicatedString(pw3);\r
1730         FreeDuplicatedString(pw4);\r
1731         FreeDuplicatedString(pw5);\r
1732         return r;\r
1733 }\r
1734 \r
1735 HINSTANCE FindExecutableM(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)\r
1736 {\r
1737         HINSTANCE r = NULL;\r
1738         wchar_t* pw0 = NULL;\r
1739         wchar_t* pw1 = NULL;\r
1740         wchar_t* pw2 = NULL;\r
1741         wchar_t* pw3 = NULL;\r
1742 START_ROUTINE\r
1743         pw0 = DuplicateMtoW(lpFile, -1);\r
1744         pw1 = DuplicateMtoW(lpDirectory, -1);\r
1745         pw2 = AllocateStringW(MAX_PATH * 4);\r
1746         r = FindExecutableW(pw0, pw1, pw2);\r
1747         // バッファ長不明のためオーバーランの可能性あり\r
1748         WtoM(lpResult, MAX_PATH, pw2, -1);\r
1749         TerminateStringM(lpResult, MAX_PATH);\r
1750 END_ROUTINE\r
1751         FreeDuplicatedString(pw0);\r
1752         FreeDuplicatedString(pw1);\r
1753         FreeDuplicatedString(pw2);\r
1754         FreeDuplicatedString(pw3);\r
1755         return r;\r
1756 }\r
1757 \r
1758 HINSTANCE ShellExecuteM(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)\r
1759 {\r
1760         HINSTANCE r = NULL;\r
1761         wchar_t* pw0 = NULL;\r
1762         wchar_t* pw1 = NULL;\r
1763         wchar_t* pw2 = NULL;\r
1764         wchar_t* pw3 = NULL;\r
1765 START_ROUTINE\r
1766         pw0 = DuplicateMtoW(lpOperation, -1);\r
1767         pw1 = DuplicateMtoW(lpFile, -1);\r
1768         pw2 = DuplicateMtoW(lpParameters, -1);\r
1769         pw3 = DuplicateMtoW(lpDirectory, -1);\r
1770         r = ShellExecuteW(hwnd, pw0, pw1, pw2, pw3, nShowCmd);\r
1771 END_ROUTINE\r
1772         FreeDuplicatedString(pw0);\r
1773         FreeDuplicatedString(pw1);\r
1774         FreeDuplicatedString(pw2);\r
1775         FreeDuplicatedString(pw3);\r
1776         return r;\r
1777 }\r
1778 \r
1779 BOOL ShellExecuteExM(LPSHELLEXECUTEINFOA lpExecInfo)\r
1780 {\r
1781         BOOL r = FALSE;\r
1782         wchar_t* pw0 = NULL;\r
1783         wchar_t* pw1 = NULL;\r
1784         wchar_t* pw2 = NULL;\r
1785         wchar_t* pw3 = NULL;\r
1786         wchar_t* pw4 = NULL;\r
1787         SHELLEXECUTEINFOW wExecInfo;\r
1788 START_ROUTINE\r
1789         wExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);\r
1790         wExecInfo.fMask = lpExecInfo->fMask;\r
1791         wExecInfo.hwnd = lpExecInfo->hwnd;\r
1792         pw0 = DuplicateMtoW(lpExecInfo->lpVerb, -1);\r
1793         wExecInfo.lpVerb = pw0;\r
1794         pw1 = DuplicateMtoW(lpExecInfo->lpFile, -1);\r
1795         wExecInfo.lpFile = pw1;\r
1796         pw2 = DuplicateMtoW(lpExecInfo->lpParameters, -1);\r
1797         wExecInfo.lpParameters = pw2;\r
1798         pw3 = DuplicateMtoW(lpExecInfo->lpDirectory, -1);\r
1799         wExecInfo.lpDirectory = pw3;\r
1800         wExecInfo.nShow = lpExecInfo->nShow;\r
1801         wExecInfo.hInstApp = lpExecInfo->hInstApp;\r
1802         wExecInfo.lpIDList = lpExecInfo->lpIDList;\r
1803         if(lpExecInfo->fMask & SEE_MASK_CLASSNAME)\r
1804         {\r
1805                 pw4 = DuplicateMtoW(lpExecInfo->lpClass, -1);\r
1806                 wExecInfo.lpClass = pw4;\r
1807         }\r
1808         wExecInfo.hkeyClass = lpExecInfo->hkeyClass;\r
1809         wExecInfo.dwHotKey = lpExecInfo->dwHotKey;\r
1810         wExecInfo.hIcon = lpExecInfo->hIcon;\r
1811         wExecInfo.hProcess = lpExecInfo->hProcess;\r
1812         r = ShellExecuteExW(&wExecInfo);\r
1813         lpExecInfo->hInstApp = wExecInfo.hInstApp;\r
1814         lpExecInfo->hProcess = wExecInfo.hProcess;\r
1815 END_ROUTINE\r
1816         FreeDuplicatedString(pw0);\r
1817         FreeDuplicatedString(pw1);\r
1818         FreeDuplicatedString(pw2);\r
1819         FreeDuplicatedString(pw3);\r
1820         FreeDuplicatedString(pw4);\r
1821         return r;\r
1822 }\r
1823 \r
1824 PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)\r
1825 {\r
1826         PIDLIST_ABSOLUTE r = NULL;\r
1827         wchar_t* pw0 = NULL;\r
1828         wchar_t* pw1 = NULL;\r
1829         BROWSEINFOW wbi;\r
1830 START_ROUTINE\r
1831         wbi.hwndOwner = lpbi->hwndOwner;\r
1832         wbi.pidlRoot = lpbi->pidlRoot;\r
1833         pw0 = DuplicateMtoWBuffer(lpbi->pszDisplayName, -1, MAX_PATH * 4);\r
1834         wbi.pszDisplayName = pw0;\r
1835         pw1 = DuplicateMtoW(lpbi->lpszTitle, -1);\r
1836         wbi.lpszTitle = pw1;\r
1837         wbi.ulFlags = lpbi->ulFlags;\r
1838         // TODO: lpfn\r
1839         wbi.lpfn = lpbi->lpfn;\r
1840         wbi.lParam = lpbi->lParam;\r
1841         wbi.iImage = lpbi->iImage;\r
1842         r = SHBrowseForFolderW(&wbi);\r
1843         // バッファ長不明のためオーバーランの可能性あり\r
1844         WtoM(lpbi->pszDisplayName, MAX_PATH, wbi.pszDisplayName, -1);\r
1845         lpbi->iImage = wbi.iImage;\r
1846 END_ROUTINE\r
1847         FreeDuplicatedString(pw0);\r
1848         FreeDuplicatedString(pw1);\r
1849         return r;\r
1850 }\r
1851 \r
1852 BOOL SHGetPathFromIDListM(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath)\r
1853 {\r
1854         BOOL r = FALSE;\r
1855         wchar_t* pw0 = NULL;\r
1856 START_ROUTINE\r
1857         pw0 = AllocateStringW(MAX_PATH * 4);\r
1858         r = SHGetPathFromIDListW(pidl, pw0);\r
1859         // バッファ長不明のためオーバーランの可能性あり\r
1860         WtoM(pszPath, MAX_PATH, pw0, -1);\r
1861         TerminateStringM(pszPath, MAX_PATH);\r
1862 END_ROUTINE\r
1863         FreeDuplicatedString(pw0);\r
1864         return r;\r
1865 }\r
1866 \r
1867 int SHFileOperationM(LPSHFILEOPSTRUCTA lpFileOp)\r
1868 {\r
1869         int r = 0;\r
1870         wchar_t* pw0 = NULL;\r
1871         wchar_t* pw1 = NULL;\r
1872         wchar_t* pw2 = NULL;\r
1873         SHFILEOPSTRUCTW wFileOp;\r
1874 START_ROUTINE\r
1875         wFileOp.hwnd = lpFileOp->hwnd;\r
1876         wFileOp.wFunc = lpFileOp->wFunc;\r
1877         pw0 = DuplicateMtoWMultiString(lpFileOp->pFrom);\r
1878         wFileOp.pFrom = pw0;\r
1879         pw1 = DuplicateMtoWMultiString(lpFileOp->pTo);\r
1880         wFileOp.pTo = pw1;\r
1881         wFileOp.fFlags = lpFileOp->fFlags;\r
1882         wFileOp.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;\r
1883         wFileOp.hNameMappings = lpFileOp->hNameMappings;\r
1884         if(lpFileOp->fFlags & FOF_SIMPLEPROGRESS)\r
1885                 pw2 = DuplicateMtoW(lpFileOp->lpszProgressTitle, -1);\r
1886         r = SHFileOperationW(&wFileOp);\r
1887         lpFileOp->fAnyOperationsAborted = wFileOp.fAnyOperationsAborted;\r
1888 END_ROUTINE\r
1889         FreeDuplicatedString(pw0);\r
1890         FreeDuplicatedString(pw1);\r
1891         FreeDuplicatedString(pw2);\r
1892         return r;\r
1893 }\r
1894 \r
1895 DWORD_PTR SHGetFileInfoM(LPCSTR pszPath, DWORD dwFileAttributes, SHFILEINFOA *psfi, UINT cbFileInfo, UINT uFlags)\r
1896 {\r
1897         DWORD_PTR r = 0;\r
1898         wchar_t* pw0 = NULL;\r
1899         SHFILEINFOW wsfi;\r
1900 START_ROUTINE\r
1901         pw0 = DuplicateMtoWMultiString(pszPath);\r
1902         if((r = SHGetFileInfoW(pw0, dwFileAttributes, &wsfi, cbFileInfo, uFlags)) != 0)\r
1903         {\r
1904                 psfi->hIcon = wsfi.hIcon;\r
1905                 psfi->iIcon = wsfi.iIcon;\r
1906                 psfi->dwAttributes = wsfi.dwAttributes;\r
1907                 WtoM(psfi->szDisplayName, MAX_PATH, wsfi.szDisplayName, -1);\r
1908                 WtoM(psfi->szTypeName, 80, wsfi.szTypeName, -1);\r
1909         }\r
1910 END_ROUTINE\r
1911         FreeDuplicatedString(pw0);\r
1912         return r;\r
1913 }\r
1914 \r
1915 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)\r
1916 {\r
1917         int r = 0;\r
1918         wchar_t* pw0 = NULL;\r
1919 START_ROUTINE\r
1920         if(uFlags & (MF_BITMAP | MF_OWNERDRAW))\r
1921                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, (LPCWSTR)lpNewItem);\r
1922         else\r
1923         {\r
1924                 pw0 = DuplicateMtoW(lpNewItem, -1);\r
1925                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, pw0);\r
1926         }\r
1927 END_ROUTINE\r
1928         FreeDuplicatedString(pw0);\r
1929         return r;\r
1930 }\r
1931 \r
1932 BOOL GetMenuItemInfoM(HMENU hmenu, UINT item, BOOL fByPosition, LPMENUITEMINFOA lpmii)\r
1933 {\r
1934         BOOL r = FALSE;\r
1935         wchar_t* pw0 = NULL;\r
1936         MENUITEMINFOW wmii;\r
1937 START_ROUTINE\r
1938         wmii.cbSize = sizeof(MENUITEMINFOW);\r
1939         wmii.fMask = lpmii->fMask;\r
1940         wmii.fType = lpmii->fType;\r
1941         wmii.fState = lpmii->fState;\r
1942         wmii.wID = lpmii->wID;\r
1943         wmii.hSubMenu = lpmii->hSubMenu;\r
1944         wmii.hbmpChecked = lpmii->hbmpChecked;\r
1945         wmii.hbmpUnchecked = lpmii->hbmpUnchecked;\r
1946         wmii.dwItemData = lpmii->dwItemData;\r
1947         if(lpmii->fMask & MIIM_TYPE)\r
1948         {\r
1949                 pw0 = DuplicateMtoWBuffer(lpmii->dwTypeData, -1, lpmii->cch * 4);\r
1950                 wmii.dwTypeData = pw0;\r
1951                 wmii.cch = lpmii->cch * 4;\r
1952         }\r
1953         wmii.hbmpItem = lpmii->hbmpItem;\r
1954         r = GetMenuItemInfoW(hmenu, item, fByPosition, &wmii);\r
1955         lpmii->fType = wmii.fType;\r
1956         lpmii->fState = wmii.fState;\r
1957         lpmii->wID = wmii.wID;\r
1958         lpmii->hSubMenu = wmii.hSubMenu;\r
1959         lpmii->hbmpChecked = wmii.hbmpChecked;\r
1960         lpmii->hbmpUnchecked = wmii.hbmpUnchecked;\r
1961         lpmii->dwItemData = wmii.dwItemData;\r
1962         WtoM(lpmii->dwTypeData, lpmii->cch, wmii.dwTypeData, -1);\r
1963         TerminateStringM(lpmii->dwTypeData, lpmii->cch);\r
1964 END_ROUTINE\r
1965         FreeDuplicatedString(pw0);\r
1966         return r;\r
1967 }\r
1968 \r
1969 HFONT CreateFontIndirectM(CONST LOGFONTA *lplf)\r
1970 {\r
1971         HFONT r = NULL;\r
1972         LOGFONTW wlf;\r
1973 START_ROUTINE\r
1974         wlf.lfHeight = lplf->lfHeight;\r
1975         wlf.lfWidth = lplf->lfWidth;\r
1976         wlf.lfEscapement = lplf->lfEscapement;\r
1977         wlf.lfOrientation = lplf->lfOrientation;\r
1978         wlf.lfWeight = lplf->lfWeight;\r
1979         wlf.lfItalic = lplf->lfItalic;\r
1980         wlf.lfUnderline = lplf->lfUnderline;\r
1981         wlf.lfStrikeOut = lplf->lfStrikeOut;\r
1982         wlf.lfCharSet = lplf->lfCharSet;\r
1983         wlf.lfOutPrecision = lplf->lfOutPrecision;\r
1984         wlf.lfClipPrecision = lplf->lfClipPrecision;\r
1985         wlf.lfQuality = lplf->lfQuality;\r
1986         wlf.lfPitchAndFamily = lplf->lfPitchAndFamily;\r
1987         MtoW(wlf.lfFaceName, LF_FACESIZE, lplf->lfFaceName, -1);\r
1988         TerminateStringW(wlf.lfFaceName, LF_FACESIZE);\r
1989         r = CreateFontIndirect(&wlf);\r
1990 END_ROUTINE\r
1991         return r;\r
1992 }\r
1993 \r
1994 BOOL ChooseFontM(LPCHOOSEFONTA v0)\r
1995 {\r
1996         BOOL r = FALSE;\r
1997         wchar_t* pw0 = NULL;\r
1998         wchar_t* pw1 = NULL;\r
1999         CHOOSEFONTW a0;\r
2000         LOGFONTW* pwlf;\r
2001 START_ROUTINE\r
2002         a0.lStructSize = sizeof(CHOOSEFONTW);\r
2003         a0.hwndOwner = v0->hwndOwner;\r
2004         a0.hDC = v0->hDC;\r
2005         if(v0->lpLogFont && (pwlf = (LOGFONTW*)malloc(sizeof(LOGFONTW))))\r
2006         {\r
2007                 pwlf->lfHeight = v0->lpLogFont->lfHeight;\r
2008                 pwlf->lfWidth = v0->lpLogFont->lfWidth;\r
2009                 pwlf->lfEscapement = v0->lpLogFont->lfEscapement;\r
2010                 pwlf->lfOrientation = v0->lpLogFont->lfOrientation;\r
2011                 pwlf->lfWeight = v0->lpLogFont->lfWeight;\r
2012                 pwlf->lfItalic = v0->lpLogFont->lfItalic;\r
2013                 pwlf->lfUnderline = v0->lpLogFont->lfUnderline;\r
2014                 pwlf->lfStrikeOut = v0->lpLogFont->lfStrikeOut;\r
2015                 pwlf->lfCharSet = v0->lpLogFont->lfCharSet;\r
2016                 pwlf->lfOutPrecision = v0->lpLogFont->lfOutPrecision;\r
2017                 pwlf->lfClipPrecision = v0->lpLogFont->lfClipPrecision;\r
2018                 pwlf->lfQuality = v0->lpLogFont->lfQuality;\r
2019                 pwlf->lfPitchAndFamily = v0->lpLogFont->lfPitchAndFamily;\r
2020                 MtoW(pwlf->lfFaceName, LF_FACESIZE, v0->lpLogFont->lfFaceName, -1);\r
2021                 TerminateStringW(pwlf->lfFaceName, LF_FACESIZE);\r
2022         }\r
2023         else\r
2024                 pwlf = NULL;\r
2025         a0.lpLogFont = pwlf;\r
2026         a0.iPointSize = v0->iPointSize;\r
2027         a0.Flags = v0->Flags;\r
2028         a0.rgbColors = v0->rgbColors;\r
2029         a0.lCustData = v0->lCustData;\r
2030         a0.lpfnHook = v0->lpfnHook;\r
2031         pw0 = DuplicateMtoW(v0->lpTemplateName, -1);\r
2032         a0.lpTemplateName = pw0;\r
2033         a0.hInstance = v0->hInstance;\r
2034         pw1 = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);\r
2035         a0.lpszStyle = pw1;\r
2036         a0.nFontType = v0->nFontType;\r
2037         a0.nSizeMin = v0->nSizeMin;\r
2038         a0.nSizeMax = v0->nSizeMax;\r
2039         r = ChooseFontW(&a0);\r
2040         if(v0->lpLogFont)\r
2041         {\r
2042                 v0->lpLogFont->lfHeight = pwlf->lfHeight;\r
2043                 v0->lpLogFont->lfWidth = pwlf->lfWidth;\r
2044                 v0->lpLogFont->lfEscapement = pwlf->lfEscapement;\r
2045                 v0->lpLogFont->lfOrientation = pwlf->lfOrientation;\r
2046                 v0->lpLogFont->lfWeight = pwlf->lfWeight;\r
2047                 v0->lpLogFont->lfItalic = pwlf->lfItalic;\r
2048                 v0->lpLogFont->lfUnderline = pwlf->lfUnderline;\r
2049                 v0->lpLogFont->lfStrikeOut = pwlf->lfStrikeOut;\r
2050                 v0->lpLogFont->lfCharSet = pwlf->lfCharSet;\r
2051                 v0->lpLogFont->lfOutPrecision = pwlf->lfOutPrecision;\r
2052                 v0->lpLogFont->lfClipPrecision = pwlf->lfClipPrecision;\r
2053                 v0->lpLogFont->lfQuality = pwlf->lfQuality;\r
2054                 v0->lpLogFont->lfPitchAndFamily = pwlf->lfPitchAndFamily;\r
2055                 WtoM(v0->lpLogFont->lfFaceName, LF_FACESIZE, pwlf->lfFaceName, -1);\r
2056                 TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);\r
2057         }\r
2058         v0->rgbColors = a0.rgbColors;\r
2059         WtoM(v0->lpszStyle, LF_FACESIZE, pw1, -1);\r
2060         TerminateStringM(v0->lpszStyle, LF_FACESIZE);\r
2061         v0->nFontType = a0.nFontType;\r
2062         if(pwlf)\r
2063                 free(pwlf);\r
2064 END_ROUTINE\r
2065         FreeDuplicatedString(pw0);\r
2066         FreeDuplicatedString(pw1);\r
2067         return r;\r
2068 }\r
2069 \r
2070 INT_PTR DialogBoxParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)\r
2071 {\r
2072         INT_PTR r = 0;\r
2073         wchar_t* pw0 = NULL;\r
2074 START_ROUTINE\r
2075         pw0 = DuplicateMtoW(lpTemplateName, -1);\r
2076         r = DialogBoxParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);\r
2077 END_ROUTINE\r
2078         FreeDuplicatedString(pw0);\r
2079         return r;\r
2080 }\r
2081 \r
2082 HWND CreateDialogParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)\r
2083 {\r
2084         HWND r = NULL;\r
2085         wchar_t* pw0 = NULL;\r
2086 START_ROUTINE\r
2087         pw0 = DuplicateMtoW(lpTemplateName, -1);\r
2088         r = CreateDialogParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);\r
2089 END_ROUTINE\r
2090         FreeDuplicatedString(pw0);\r
2091         return r;\r
2092 }\r
2093 \r
2094 BOOL sndPlaySoundM(LPCSTR pszSound, UINT fuSound)\r
2095 {\r
2096         BOOL r = FALSE;\r
2097         wchar_t* pw0 = NULL;\r
2098 START_ROUTINE\r
2099         pw0 = DuplicateMtoW(pszSound, -1);\r
2100         r = sndPlaySoundW(pw0, fuSound);\r
2101 END_ROUTINE\r
2102         FreeDuplicatedString(pw0);\r
2103         return r;\r
2104 }\r
2105 \r
2106 HANDLE SetClipboardDataM(UINT uFormat, HANDLE hMem)\r
2107 {\r
2108         HANDLE r = NULL;\r
2109         char* p;\r
2110         int Length;\r
2111         int BufferLength;\r
2112         HGLOBAL hBufferMem;\r
2113 START_ROUTINE\r
2114         if(uFormat == CF_TEXT)\r
2115         {\r
2116                 p = (char*)GlobalLock(hMem);\r
2117                 Length = (int)GlobalSize(hMem);\r
2118                 BufferLength = MtoW(NULL, 0, p, Length);\r
2119                 if(hBufferMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * BufferLength))\r
2120                 {\r
2121                         MtoW((LPWSTR)GlobalLock(hBufferMem), BufferLength, p, Length);\r
2122                         GlobalUnlock(hBufferMem);\r
2123                         r = SetClipboardData(CF_UNICODETEXT, hBufferMem);\r
2124                 }\r
2125                 GlobalUnlock(hMem);\r
2126                 GlobalFree(hMem);\r
2127         }\r
2128         else\r
2129                 r = SetClipboardData(uFormat, hMem);\r
2130 END_ROUTINE\r
2131         return r;\r
2132 }\r
2133 \r
2134 BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)\r
2135 {\r
2136         BOOL r = FALSE;\r
2137         wchar_t* pw0 = NULL;\r
2138         wchar_t* pw1 = NULL;\r
2139 START_ROUTINE\r
2140         pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
2141         pw1 = DuplicateMtoW(lpNewFileName, -1);\r
2142         r = CopyFileW(pw0, pw1, bFailIfExists);\r
2143 END_ROUTINE\r
2144         FreeDuplicatedString(pw0);\r
2145         FreeDuplicatedString(pw1);\r
2146         return r;\r
2147 }\r
2148 \r
2149 BOOL MoveFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)\r
2150 {\r
2151         BOOL r = FALSE;\r
2152         wchar_t* pw0 = NULL;\r
2153         wchar_t* pw1 = NULL;\r
2154 START_ROUTINE\r
2155         pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
2156         pw1 = DuplicateMtoW(lpNewFileName, -1);\r
2157         r = MoveFileW(pw0, pw1);\r
2158 END_ROUTINE\r
2159         FreeDuplicatedString(pw0);\r
2160         FreeDuplicatedString(pw1);\r
2161         return r;\r
2162 }\r
2163 \r
2164 BOOL DeleteFileM(LPCSTR lpFileName)\r
2165 {\r
2166         BOOL r = FALSE;\r
2167         wchar_t* pw0 = NULL;\r
2168 START_ROUTINE\r
2169         pw0 = DuplicateMtoW(lpFileName, -1);\r
2170         r = DeleteFileW(pw0);\r
2171 END_ROUTINE\r
2172         FreeDuplicatedString(pw0);\r
2173         return r;\r
2174 }\r
2175 \r
2176 int mkdirM(const char * _Path)\r
2177 {\r
2178         int r = -1;\r
2179         wchar_t* pw0 = NULL;\r
2180 START_ROUTINE\r
2181         pw0 = DuplicateMtoW(_Path, -1);\r
2182         r = _wmkdir(pw0);\r
2183 END_ROUTINE\r
2184         FreeDuplicatedString(pw0);\r
2185         return r;\r
2186 }\r
2187 \r
2188 int _mkdirM(const char * _Path)\r
2189 {\r
2190         int r = -1;\r
2191         wchar_t* pw0 = NULL;\r
2192 START_ROUTINE\r
2193         pw0 = DuplicateMtoW(_Path, -1);\r
2194         r = _wmkdir(pw0);\r
2195 END_ROUTINE\r
2196         FreeDuplicatedString(pw0);\r
2197         return r;\r
2198 }\r
2199 \r
2200 int rmdirM(const char * _Path)\r
2201 {\r
2202         int r = -1;\r
2203         wchar_t* pw0 = NULL;\r
2204 START_ROUTINE\r
2205         pw0 = DuplicateMtoW(_Path, -1);\r
2206         r = _wrmdir(pw0);\r
2207 END_ROUTINE\r
2208         FreeDuplicatedString(pw0);\r
2209         return r;\r
2210 }\r
2211 \r
2212 int _rmdirM(const char * _Path)\r
2213 {\r
2214         int r = -1;\r
2215         wchar_t* pw0 = NULL;\r
2216 START_ROUTINE\r
2217         pw0 = DuplicateMtoW(_Path, -1);\r
2218         r = _wrmdir(pw0);\r
2219 END_ROUTINE\r
2220         FreeDuplicatedString(pw0);\r
2221         return r;\r
2222 }\r
2223 \r
2224 int removeM(const char * _Filename)\r
2225 {\r
2226         int r = -1;\r
2227         wchar_t* pw0 = NULL;\r
2228 START_ROUTINE\r
2229         pw0 = DuplicateMtoW(_Filename, -1);\r
2230         r = _wremove(pw0);\r
2231 END_ROUTINE\r
2232         FreeDuplicatedString(pw0);\r
2233         return r;\r
2234 }\r
2235 \r
2236 int _removeM(const char * _Filename)\r
2237 {\r
2238         int r = -1;\r
2239         wchar_t* pw0 = NULL;\r
2240 START_ROUTINE\r
2241         pw0 = DuplicateMtoW(_Filename, -1);\r
2242         r = _wremove(pw0);\r
2243 END_ROUTINE\r
2244         FreeDuplicatedString(pw0);\r
2245         return r;\r
2246 }\r
2247 \r
2248 int _unlinkM(const char * _Filename)\r
2249 {\r
2250         int r = -1;\r
2251         wchar_t* pw0 = NULL;\r
2252 START_ROUTINE\r
2253         pw0 = DuplicateMtoW(_Filename, -1);\r
2254         r = _wunlink(pw0);\r
2255 END_ROUTINE\r
2256         FreeDuplicatedString(pw0);\r
2257         return r;\r
2258 }\r
2259 \r
2260 size_t _mbslenM(const unsigned char * _Str)\r
2261 {\r
2262         size_t r = 0;\r
2263 START_ROUTINE\r
2264         while(GetNextCharM(_Str, &_Str) > 0)\r
2265         {\r
2266                 r++;\r
2267         }\r
2268 END_ROUTINE\r
2269         return r;\r
2270 }\r
2271 \r
2272 unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
2273 {\r
2274         unsigned char* r = NULL;\r
2275         unsigned int c;\r
2276         unsigned char* p;\r
2277 START_ROUTINE\r
2278         while((c = GetNextCharM(_Str, &p)) > 0)\r
2279         {\r
2280                 if(c == _Ch)\r
2281                         break;\r
2282                 _Str = p;\r
2283         }\r
2284         if(c == _Ch)\r
2285                 r = (unsigned char*)_Str;\r
2286 END_ROUTINE\r
2287         return r;\r
2288 }\r
2289 \r
2290 unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
2291 {\r
2292         unsigned char* r = NULL;\r
2293         unsigned int c;\r
2294         unsigned char* p;\r
2295 START_ROUTINE\r
2296         while((c = GetNextCharM(_Str, &p)) > 0)\r
2297         {\r
2298                 if(c == _Ch)\r
2299                         r = (unsigned char*)_Str;\r
2300                 _Str = p;\r
2301         }\r
2302         if(c == _Ch)\r
2303                 r = (unsigned char*)_Str;\r
2304 END_ROUTINE\r
2305         return r;\r
2306 }\r
2307 \r
2308 unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
2309 {\r
2310         unsigned char* r = NULL;\r
2311 START_ROUTINE\r
2312         r = strstr(_Str, _Substr);\r
2313 END_ROUTINE\r
2314         return r;\r
2315 }\r
2316 \r
2317 int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
2318 {\r
2319         int r = 0;\r
2320 START_ROUTINE\r
2321         r = strcmp(_Str1, _Str2);\r
2322 END_ROUTINE\r
2323         return r;\r
2324 }\r
2325 \r
2326 int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
2327 {\r
2328         int r = 0;\r
2329 START_ROUTINE\r
2330         r = _stricmp(_Str1, _Str2);\r
2331 END_ROUTINE\r
2332         return r;\r
2333 }\r
2334 \r
2335 int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
2336 {\r
2337         int r = 0;\r
2338         DWORD c1;\r
2339         DWORD c2;\r
2340 START_ROUTINE\r
2341         c1 = 0;\r
2342         c2 = 0;\r
2343         while(_MaxCount > 0)\r
2344         {\r
2345                 c1 = GetNextCharM(_Str1, &_Str1);\r
2346                 c2 = GetNextCharM(_Str2, &_Str2);\r
2347                 if(c1 != c2)\r
2348                         break;\r
2349                 _MaxCount--;\r
2350                 if(c1 == 0 || c2 == 0)\r
2351                         break;\r
2352         }\r
2353         r = c1 - c2;\r
2354 END_ROUTINE\r
2355         return r;\r
2356 }\r
2357 \r
2358 unsigned char * _mbslwrM(unsigned char * _String)\r
2359 {\r
2360         unsigned char* r = NULL;\r
2361 START_ROUTINE\r
2362         r = _strlwr(_String);\r
2363 END_ROUTINE\r
2364         return r;\r
2365 }\r
2366 \r
2367 unsigned char * _mbsuprM(unsigned char * _String)\r
2368 {\r
2369         unsigned char* r = NULL;\r
2370 START_ROUTINE\r
2371         r = _strupr(_String);\r
2372 END_ROUTINE\r
2373         return r;\r
2374 }\r
2375 \r
2376 unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
2377 {\r
2378         unsigned char* r = NULL;\r
2379 START_ROUTINE\r
2380         while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
2381         {\r
2382                 _Count--;\r
2383         }\r
2384         r = (unsigned char*)_Str;\r
2385 END_ROUTINE\r
2386         return r;\r
2387 }\r
2388 \r
2389 FILE * fopenM(const char * _Filename, const char * _Mode)\r
2390 {\r
2391         FILE* r = NULL;\r
2392         wchar_t* pw0 = NULL;\r
2393         wchar_t* pw1 = NULL;\r
2394 START_ROUTINE\r
2395         pw0 = DuplicateMtoW(_Filename, -1);\r
2396         pw1 = DuplicateMtoW(_Mode, -1);\r
2397         r = _wfopen(pw0, pw1);\r
2398 END_ROUTINE\r
2399         FreeDuplicatedString(pw0);\r
2400         FreeDuplicatedString(pw1);\r
2401         return r;\r
2402 }\r
2403 \r