OSDN Git Service

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