OSDN Git Service

Fix small bugs (they usually do not occur).
[ffftp/ffftp.git] / mbswrapper.c
1 // mbswrapper.cpp
2 // Copyright (C) 2011 Suguru Kawamoto
3 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\83\8f\83C\83h\95\8e\9aAPI\83\89\83b\83p\81[
4 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\82ÍUTF-8\81A\83\8f\83C\83h\95\8e\9a\82ÍUTF-16\82Å\82 \82é\82à\82Ì\82Æ\82·\82é
5 // \91S\82Ä\82Ì\90§\8cä\97p\82Ì\95\8e\9a\82ÍASCII\82Ì\94Í\88Í\82Å\82 \82é\82½\82ß\81AShift_JIS\82ÆUTF-8\8aÔ\82Ì\95Ï\8a·\82Í\95s\97v
6
7 #define UNICODE
8 #define _UNICODE
9 #define _WIN32_WINNT 0x0600
10 #undef _WIN32_IE
11 #define _WIN32_IE 0x0400
12
13 #include <tchar.h>
14 #include <direct.h>
15 #include <windows.h>
16 #include <commctrl.h>
17 #include <shlobj.h>
18 #include <htmlhelp.h>
19
20 #define DO_NOT_REPLACE
21 #include "mbswrapper.h"
22
23 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
24 int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)
25 {
26         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
27                 return 0;
28         if(pDst)
29                 return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);
30         return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);
31 }
32
33 // \83\8f\83C\83h\95\8e\9a\97ñ\82©\82ç\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82Ö\95Ï\8a·
34 int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)
35 {
36         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
37                 return 0;
38         if(pDst)
39                 return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);
40         return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);
41 }
42
43 // \83\8f\83C\83h\95\8e\9a\97ñ\82©\82çShift_JIS\95\8e\9a\97ñ\82Ö\95Ï\8a·
44 int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)
45 {
46         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
47                 return 0;
48         if(pDst)
49                 return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);
50         return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);
51 }
52
53 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\83o\83b\83t\83@\8fI\92[\82ð\8b­\90§\93I\82ÉNULL\82Å\92u\8a·
54 int TerminateStringM(LPSTR lpString, int size)
55 {
56         int i;
57         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)
58                 return 0;
59         for(i = 0; i < size; i++)
60         {
61                 if(lpString[i] == '\0')
62                         return i;
63         }
64         i--;
65         lpString[i] = '\0';
66         return i;
67 }
68
69 // \83\8f\83C\83h\95\8e\9a\97ñ\83o\83b\83t\83@\8fI\92[\82ð\8b­\90§\93I\82ÉNULL\82Å\92u\8a·
70 int TerminateStringW(LPWSTR lpString, int size)
71 {
72         int i;
73         if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)
74                 return 0;
75         for(i = 0; i < size; i++)
76         {
77                 if(lpString[i] == L'\0')
78                         return i;
79         }
80         i--;
81         lpString[i] = L'\0';
82         return i;
83 }
84
85 // Shift_JIS\95\8e\9a\97ñ\83o\83b\83t\83@\8fI\92[\82ð\8b­\90§\93I\82ÉNULL\82Å\92u\8a·
86 int TerminateStringA(LPSTR lpString, int size)
87 {
88         int i;
89         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)
90                 return 0;
91         for(i = 0; i < size; i++)
92         {
93                 if(lpString[i] == '\0')
94                         return i;
95         }
96         i--;
97         lpString[i] = '\0';
98         return i;
99 }
100
101 // NULL\8bæ\90Ø\82è\95¡\90\94\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82Ì\92·\82³\82ð\8eæ\93¾
102 size_t GetMultiStringLengthM(LPCSTR lpString)
103 {
104         size_t i;
105         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
106                 return 0;
107         i = 0;
108         while(lpString[i] != '\0' || lpString[i + 1] != '\0')
109         {
110                 i++;
111         }
112         i++;
113         return i;
114 }
115
116 // NULL\8bæ\90Ø\82è\95¡\90\94\83\8f\83C\83h\95\8e\9a\97ñ\82Ì\92·\82³\82ð\8eæ\93¾
117 size_t GetMultiStringLengthW(LPCWSTR lpString)
118 {
119         size_t i;
120         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
121                 return 0;
122         i = 0;
123         while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')
124         {
125                 i++;
126         }
127         i++;
128         return i;
129 }
130
131 // NULL\8bæ\90Ø\82è\95¡\90\94Shift_JIS\95\8e\9a\97ñ\82Ì\92·\82³\82ð\8eæ\93¾
132 size_t GetMultiStringLengthA(LPCSTR lpString)
133 {
134         size_t i;
135         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
136                 return 0;
137         i = 0;
138         while(lpString[i] != '\0' || lpString[i + 1] != '\0')
139         {
140                 i++;
141         }
142         i++;
143         return i;
144 }
145
146 // NULL\8bæ\90Ø\82è\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
147 int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)
148 {
149         int i;
150         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
151                 return 0;
152         if(!pDst)
153                 return GetMultiStringLengthM(pSrc);
154         i = 0;
155         while(*pSrc != '\0')
156         {
157                 i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);
158                 pSrc += strlen(pSrc) + 1;
159         }
160         pDst[i] = L'\0';
161         return i;
162 }
163
164 // NULL\8bæ\90Ø\82è\83\8f\83C\83h\95\8e\9a\97ñ\82©\82ç\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82Ö\95Ï\8a·
165 int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)
166 {
167         int i;
168         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
169                 return 0;
170         if(!pDst)
171                 return GetMultiStringLengthW(pSrc);
172         i = 0;
173         while(*pSrc != L'\0')
174         {
175                 i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);
176                 pSrc += wcslen(pSrc) + 1;
177         }
178         pDst[i] = '\0';
179         return i;
180 }
181
182 // NULL\8bæ\90Ø\82è\83\8f\83C\83h\95\8e\9a\97ñ\82©\82çShift_JIS\95\8e\9a\97ñ\82Ö\95Ï\8a·
183 int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)
184 {
185         int i;
186         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
187                 return 0;
188         if(!pDst)
189                 return GetMultiStringLengthW(pSrc);
190         i = 0;
191         while(*pSrc != L'\0')
192         {
193                 i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);
194                 pSrc += wcslen(pSrc) + 1;
195         }
196         pDst[i] = '\0';
197         return i;
198 }
199
200 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\97p\82Ì\83\81\83\82\83\8a\82ð\8am\95Û
201 char* AllocateStringM(int size)
202 {
203         char* p;
204         // 0\82ª\8ew\92è\82³\82ê\82é\8fê\8d\87\82ª\82 \82é\82½\82ß1\95\8e\9a\95ª\92Ç\89Á
205         p = (char*)malloc(sizeof(char) * (size + 1));
206         // \94O\82Ì\82½\82ß\90æ\93ª\82ÉNULL\95\8e\9a\82ð\91ã\93ü
207         if(p)
208                 *p = '\0';
209         return p;
210 }
211
212 // \83\8f\83C\83h\95\8e\9a\97ñ\97p\82Ì\83\81\83\82\83\8a\82ð\8am\95Û
213 wchar_t* AllocateStringW(int size)
214 {
215         wchar_t* p;
216         // 0\82ª\8ew\92è\82³\82ê\82é\8fê\8d\87\82ª\82 \82é\82½\82ß1\95\8e\9a\95ª\92Ç\89Á
217         p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));
218         // \94O\82Ì\82½\82ß\90æ\93ª\82ÉNULL\95\8e\9a\82ð\91ã\93ü
219         if(p)
220                 *p = L'\0';
221         return p;
222 }
223
224 // Shift_JIS\95\8e\9a\97ñ\97p\82Ì\83\81\83\82\83\8a\82ð\8am\95Û
225 char* AllocateStringA(int size)
226 {
227         char* p;
228         // 0\82ª\8ew\92è\82³\82ê\82é\8fê\8d\87\82ª\82 \82é\82½\82ß1\95\8e\9a\95ª\92Ç\89Á
229         p = (char*)malloc(sizeof(char) * (size + 1));
230         // \94O\82Ì\82½\82ß\90æ\93ª\82ÉNULL\95\8e\9a\82ð\91ã\93ü
231         if(p)
232                 *p = '\0';
233         return p;
234 }
235
236 // \83\81\83\82\83\8a\82ð\8am\95Û\82µ\82Ä\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
237 wchar_t* DuplicateMtoW(LPCSTR lpString, int c)
238 {
239         wchar_t* p;
240         int i;
241         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
242                 return (wchar_t*)lpString;
243         if(c < 0)
244                 c = strlen(lpString);
245         p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);
246         if(p)
247         {
248                 i = MtoW(p, 65535, lpString, c);
249                 p[i] = L'\0';
250         }
251         return p;
252 }
253
254 // \8ew\92è\82µ\82½\83T\83C\83Y\82Ì\83\81\83\82\83\8a\82ð\8am\95Û\82µ\82Ä\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
255 wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)
256 {
257         wchar_t* p;
258         int i;
259         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
260                 return (wchar_t*)lpString;
261         if(c < 0)
262                 c = strlen(lpString);
263         p = AllocateStringW(size);
264         if(p)
265         {
266                 i = MtoW(p, size, lpString, c);
267                 p[i] = L'\0';
268         }
269         return p;
270 }
271
272 // \83\81\83\82\83\8a\82ð\8am\95Û\82µ\82ÄNULL\8bæ\90Ø\82è\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
273 wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)
274 {
275         int count;
276         wchar_t* p;
277         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
278                 return (wchar_t*)lpString;
279         count = GetMultiStringLengthM(lpString) + 1;
280         p = AllocateStringW(count);
281         if(p)
282                 MtoW(p, count, lpString, count);
283         return p;
284 }
285
286 // \8ew\92è\82µ\82½\83T\83C\83Y\82Ì\83\81\83\82\83\8a\82ð\8am\95Û\82µ\82ÄNULL\8bæ\90Ø\82è\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
287 wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)
288 {
289         int count;
290         wchar_t* p;
291         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
292                 return (wchar_t*)lpString;
293         count = GetMultiStringLengthM(lpString) + 1;
294         p = AllocateStringW(size);
295         if(p)
296         {
297                 MtoW(p, size, lpString, count);
298                 p[size - 2] = L'\0';
299                 p[size - 1] = L'\0';
300         }
301         return p;
302 }
303
304 // \83\81\83\82\83\8a\82ð\8am\95Û\82µ\82Ä\83\8f\83C\83h\95\8e\9a\97ñ\82©\82ç\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82Ö\95Ï\8a·
305 char* DuplicateWtoM(LPCWSTR lpString, int c)
306 {
307         char* p;
308         int i;
309         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
310                 return (char*)lpString;
311         if(c < 0)
312                 c = wcslen(lpString);
313         p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);
314         if(p)
315         {
316                 i = WtoM(p, 65535, lpString, c);
317                 p[i] = L'\0';
318         }
319         return p;
320 }
321
322 // \83\81\83\82\83\8a\82ð\8am\95Û\82µ\82Ä\83\8f\83C\83h\95\8e\9a\97ñ\82©\82çShift_JIS\95\8e\9a\97ñ\82Ö\95Ï\8a·
323 char* DuplicateWtoA(LPCWSTR lpString, int c)
324 {
325         char* p;
326         int i;
327         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
328                 return (char*)lpString;
329         if(c < 0)
330                 c = wcslen(lpString);
331         p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);
332         if(p)
333         {
334                 i = WtoA(p, 65535, lpString, c);
335                 p[i] = L'\0';
336         }
337         return p;
338 }
339
340 // \95\8e\9a\97ñ\97p\82É\8am\95Û\82µ\82½\83\81\83\82\83\8a\82ð\8aJ\95ú
341 void FreeDuplicatedString(void* p)
342 {
343         if(p < (void*)0x00010000 || p == (void*)~0)
344                 return;
345         free(p);
346 }
347
348 // \88È\89º\83\89\83b\83p\81[
349 // \96ß\82è\92l\83o\83b\83t\83@ r
350 // \83\8f\83C\83h\95\8e\9a\83o\83b\83t\83@ pw%d
351 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\83o\83b\83t\83@ pm%d
352 // \88ø\90\94\83o\83b\83t\83@ a%d
353
354 #define START_ROUTINE                                   do{
355 #define END_ROUTINE                                             }while(0);end_of_routine:
356 #define QUIT_ROUTINE                                    goto end_of_routine;
357
358 HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
359 {
360         HANDLE r = INVALID_HANDLE_VALUE;
361         wchar_t* pw0 = NULL;
362 START_ROUTINE
363         pw0 = DuplicateMtoW(lpFileName, -1);
364         r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
365 END_ROUTINE
366         FreeDuplicatedString(pw0);
367         return r;
368 }
369
370 int MessageBoxM(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
371 {
372         int r = IDOK;
373         wchar_t* pw0 = NULL;
374         wchar_t* pw1 = NULL;
375 START_ROUTINE
376         pw0 = DuplicateMtoW(lpText, -1);
377         pw1 = DuplicateMtoW(lpCaption, -1);
378         r = MessageBoxW(hWnd, pw0, pw1, uType);
379 END_ROUTINE
380         FreeDuplicatedString(pw0);
381         FreeDuplicatedString(pw1);
382         return r;
383 }
384
385 HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
386 {
387         HANDLE r = INVALID_HANDLE_VALUE;
388         wchar_t* pw0 = NULL;
389         WIN32_FIND_DATAW a0;
390 START_ROUTINE
391         pw0 = DuplicateMtoW(lpFileName, -1);
392         r = FindFirstFileW(pw0, &a0);
393         if(r != INVALID_HANDLE_VALUE)
394         {
395                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
396                 lpFindFileData->ftCreationTime = a0.ftCreationTime;
397                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
398                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
399                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
400                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
401                 lpFindFileData->dwReserved0 = a0.dwReserved0;
402                 lpFindFileData->dwReserved1 = a0.dwReserved1;
403                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
404                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
405         }
406 END_ROUTINE
407         FreeDuplicatedString(pw0);
408         return r;
409 }
410
411 BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
412 {
413         BOOL r = FALSE;
414         WIN32_FIND_DATAW a0;
415 START_ROUTINE
416         r = FindNextFileW(hFindFile, &a0);
417         if(r)
418         {
419                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
420                 lpFindFileData->ftCreationTime = a0.ftCreationTime;
421                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
422                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
423                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
424                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
425                 lpFindFileData->dwReserved0 = a0.dwReserved0;
426                 lpFindFileData->dwReserved1 = a0.dwReserved1;
427                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
428                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
429         }
430 END_ROUTINE
431         return r;
432 }
433
434 DWORD GetLogicalDriveStringsM(DWORD nBufferLength, LPSTR lpBuffer)
435 {
436         DWORD r = 0;
437         wchar_t* pw0 = NULL;
438 START_ROUTINE
439         pw0 = AllocateStringW(nBufferLength * 4);
440         GetLogicalDriveStringsW(nBufferLength * 4, pw0);
441         WtoMMultiString(lpBuffer, nBufferLength, pw0);
442         r = TerminateStringM(lpBuffer, nBufferLength);
443 END_ROUTINE
444         FreeDuplicatedString(pw0);
445         return r;
446 }
447
448 ATOM RegisterClassExM(CONST WNDCLASSEXA * v0)
449 {
450         ATOM r = 0;
451 START_ROUTINE
452         // WNDPROC\82ªShift_JIS\97p\82Å\82 \82é\82½\82ß
453         r = RegisterClassExA(v0);
454 END_ROUTINE
455         return r;
456 }
457
458 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)
459 {
460         HWND r = NULL;
461         wchar_t* pw0 = NULL;
462         wchar_t* pw1 = NULL;
463 START_ROUTINE
464         pw0 = DuplicateMtoW(lpClassName, -1);
465         pw1 = DuplicateMtoW(lpWindowName, -1);
466         r = CreateWindowExW(dwExStyle, pw0, pw1, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
467 END_ROUTINE
468         FreeDuplicatedString(pw0);
469         FreeDuplicatedString(pw1);
470         return r;
471 }
472
473 LONG GetWindowLongM(HWND hWnd, int nIndex)
474 {
475         LRESULT r = 0;
476 START_ROUTINE
477         // WNDPROC\82ªShift_JIS\97p\82Å\82 \82é\82½\82ß
478         if(IsWindowUnicode(hWnd))
479                 r = GetWindowLongW(hWnd, nIndex);
480         else
481                 r = GetWindowLongA(hWnd, nIndex);
482 END_ROUTINE
483         return r;
484 }
485
486 LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)
487 {
488         LRESULT r = 0;
489 START_ROUTINE
490         // WNDPROC\82ªShift_JIS\97p\82Å\82 \82é\82½\82ß
491         if(IsWindowUnicode(hWnd))
492                 r = SetWindowLongW(hWnd, nIndex, dwNewLong);
493         else
494                 r = SetWindowLongA(hWnd, nIndex, dwNewLong);
495 END_ROUTINE
496         return r;
497 }
498
499 LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
500 {
501         LRESULT r = 0;
502 START_ROUTINE
503         // WNDPROC\82ªShift_JIS\97p\82Å\82 \82é\82½\82ß
504         if(IsWindowUnicode(hWnd))
505                 r = DefWindowProcW(hWnd, Msg, wParam, lParam);
506         else
507                 r = DefWindowProcA(hWnd, Msg, wParam, lParam);
508 END_ROUTINE
509         return r;
510 }
511
512 LRESULT CallWindowProcM(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
513 {
514         LRESULT r = 0;
515 START_ROUTINE
516         // WNDPROC\82ªShift_JIS\97p\82Å\82 \82é\82½\82ß
517         if(IsWindowUnicode(hWnd))
518                 r = CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
519         else
520                 r = CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
521 END_ROUTINE
522         return r;
523 }
524
525 LRESULT SendMessageM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
526 {
527         LRESULT r = 0;
528         wchar_t* pw0 = NULL;
529         wchar_t* pw1 = NULL;
530         int Size;
531         LVITEMA* pmLVItem;
532         LVITEMW wLVItem;
533         LVFINDINFOA* pmLVFindInfo;
534         LVFINDINFOW wLVFindInfo;
535         LVCOLUMNA* pmLVColumn;
536         LVCOLUMNW wLVColumn;
537         wchar_t ClassName[MAX_PATH];
538 START_ROUTINE
539         switch(Msg)
540         {
541         case WM_SETTEXT:
542                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
543                 r = SendMessageW(hWnd, WM_SETTEXT, wParam, (LPARAM)pw0);
544                 break;
545         case WM_GETTEXT:
546                 pw0 = AllocateStringW(wParam * 4);
547                 SendMessageW(hWnd, WM_GETTEXT, wParam * 4, (LPARAM)pw0);
548                 WtoM((LPSTR)lParam, wParam, pw0, -1);
549                 r = TerminateStringM((LPSTR)lParam, wParam);
550                 break;
551         case WM_GETTEXTLENGTH:
552                 Size = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1;
553                 pw0 = AllocateStringW(Size);
554                 SendMessageW(hWnd, WM_GETTEXT, (WPARAM)Size, (LPARAM)pw0);
555                 r = WtoM(NULL, 0, pw0, -1) - 1;
556                 break;
557         default:
558                 GetClassNameW(hWnd, ClassName, sizeof(ClassName) / sizeof(wchar_t));
559                 if(_wcsicmp(ClassName, WC_EDITW) == 0)
560                 {
561                         switch(Msg)
562                         {
563                         case EM_REPLACESEL:
564                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
565                                 r = SendMessageW(hWnd, EM_REPLACESEL, wParam, (LPARAM)pw0);
566                                 break;
567                         default:
568                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
569                                 break;
570                         }
571                 }
572                 else if(_wcsicmp(ClassName, WC_COMBOBOXW) == 0)
573                 {
574                         switch(Msg)
575                         {
576                         case CB_ADDSTRING:
577                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
578                                 r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0);
579                                 break;
580                         case CB_GETLBTEXT:
581                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;
582                                 pw0 = AllocateStringW(Size);
583                                 SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0);
584                                 // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
585                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);
586                                 r = TerminateStringM((LPSTR)lParam, Size * 4);
587                                 break;
588                         case CB_GETLBTEXTLEN:
589                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;
590                                 pw0 = AllocateStringW(Size);
591                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);
592                                 r = WtoM(NULL, 0, pw0, -1) - 1;
593                                 break;
594                         case CB_INSERTSTRING:
595                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
596                                 r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0);
597                                 break;
598                         case CB_FINDSTRINGEXACT:
599                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
600                                 r = SendMessageW(hWnd, CB_FINDSTRINGEXACT, wParam, (LPARAM)pw0);
601                                 break;
602                         default:
603                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
604                                 break;
605                         }
606                 }
607                 else if(_wcsicmp(ClassName, WC_LISTBOXW) == 0)
608                 {
609                         switch(Msg)
610                         {
611                         case LB_ADDSTRING:
612                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
613                                 r = SendMessageW(hWnd, LB_ADDSTRING, wParam, (LPARAM)pw0);
614                                 break;
615                         case LB_INSERTSTRING:
616                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
617                                 r = SendMessageW(hWnd, LB_INSERTSTRING, wParam, (LPARAM)pw0);
618                                 break;
619                         case LB_GETTEXT:
620                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;
621                                 pw0 = AllocateStringW(Size);
622                                 SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0);
623                                 // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
624                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);
625                                 r = TerminateStringM((LPSTR)lParam, Size * 4);
626                                 break;
627                         case LB_GETTEXTLEN:
628                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;
629                                 pw0 = AllocateStringW(Size);
630                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);
631                                 r = WtoM(NULL, 0, pw0, -1) - 1;
632                                 break;
633                         default:
634                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
635                                 break;
636                         }
637                 }
638                 else if(_wcsicmp(ClassName, WC_LISTVIEWW) == 0)
639                 {
640                         switch(Msg)
641                         {
642                         case LVM_GETITEMA:
643                                 pmLVItem = (LVITEMA*)lParam;
644                                 wLVItem.mask = pmLVItem->mask;
645                                 wLVItem.iItem = pmLVItem->iItem;
646                                 wLVItem.iSubItem = pmLVItem->iSubItem;
647                                 wLVItem.state = pmLVItem->state;
648                                 wLVItem.stateMask = pmLVItem->stateMask;
649                                 if(pmLVItem->mask & LVIF_TEXT)
650                                 {
651                                         Size = pmLVItem->cchTextMax * 4;
652                                         pw0 = AllocateStringW(Size);
653                                         wLVItem.pszText = pw0;
654                                         wLVItem.cchTextMax = Size;
655                                 }
656                                 wLVItem.iImage = pmLVItem->iImage;
657                                 wLVItem.lParam = pmLVItem->lParam;
658                                 wLVItem.iIndent = pmLVItem->iIndent;
659                                 r = SendMessageW(hWnd, LVM_GETITEMW, wParam, (LPARAM)&wLVItem);
660                                 pmLVItem->mask = wLVItem.mask;
661                                 pmLVItem->iItem = wLVItem.iItem;
662                                 pmLVItem->iSubItem = wLVItem.iSubItem;
663                                 pmLVItem->state = wLVItem.state;
664                                 pmLVItem->stateMask = wLVItem.stateMask;
665                                 if(pmLVItem->mask & LVIF_TEXT)
666                                 {
667                                         WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);
668                                         TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);
669                                 }
670                                 pmLVItem->iImage = wLVItem.iImage;
671                                 pmLVItem->lParam = wLVItem.lParam;
672                                 pmLVItem->iIndent = wLVItem.iIndent;
673                                 break;
674                         case LVM_SETITEMA:
675                                 pmLVItem = (LVITEMA*)lParam;
676                                 wLVItem.mask = pmLVItem->mask;
677                                 wLVItem.iItem = pmLVItem->iItem;
678                                 wLVItem.iSubItem = pmLVItem->iSubItem;
679                                 wLVItem.state = pmLVItem->state;
680                                 wLVItem.stateMask = pmLVItem->stateMask;
681                                 if(pmLVItem->mask & LVIF_TEXT)
682                                 {
683                                         pw0 = DuplicateMtoW(pmLVItem->pszText, -1);
684                                         wLVItem.pszText = pw0;
685                                         // TODO: cchTextMax\82Ì\8am\94F
686                                         wLVItem.cchTextMax = pmLVItem->cchTextMax;
687                                 }
688                                 wLVItem.iImage = pmLVItem->iImage;
689                                 wLVItem.lParam = pmLVItem->lParam;
690                                 wLVItem.iIndent = pmLVItem->iIndent;
691                                 r = SendMessageW(hWnd, LVM_SETITEMW, wParam, (LPARAM)&wLVItem);
692                                 break;
693                         case LVM_INSERTITEMA:
694                                 pmLVItem = (LVITEMA*)lParam;
695                                 wLVItem.mask = pmLVItem->mask;
696                                 wLVItem.iItem = pmLVItem->iItem;
697                                 wLVItem.iSubItem = pmLVItem->iSubItem;
698                                 wLVItem.state = pmLVItem->state;
699                                 wLVItem.stateMask = pmLVItem->stateMask;
700                                 if(pmLVItem->mask & LVIF_TEXT)
701                                 {
702                                         pw0 = DuplicateMtoW(pmLVItem->pszText, -1);
703                                         wLVItem.pszText = pw0;
704                                         // TODO: cchTextMax\82Ì\8am\94F
705                                         wLVItem.cchTextMax = pmLVItem->cchTextMax;
706                                 }
707                                 wLVItem.iImage = pmLVItem->iImage;
708                                 wLVItem.lParam = pmLVItem->lParam;
709                                 wLVItem.iIndent = pmLVItem->iIndent;
710                                 r = SendMessageW(hWnd, LVM_INSERTITEMW, wParam, (LPARAM)&wLVItem);
711                                 break;
712                         case LVM_FINDITEMA:
713                                 pmLVFindInfo = (LVFINDINFOA*)lParam;
714                                 wLVFindInfo.flags = pmLVFindInfo->flags;
715                                 if(pmLVFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL))
716                                 {
717                                         pw0 = DuplicateMtoW(pmLVFindInfo->psz, -1);
718                                         wLVFindInfo.psz = pw0;
719                                 }
720                                 wLVFindInfo.lParam = pmLVFindInfo->lParam;
721                                 wLVFindInfo.pt = pmLVFindInfo->pt;
722                                 wLVFindInfo.vkDirection = pmLVFindInfo->vkDirection;
723                                 r = SendMessageW(hWnd, LVM_FINDITEMW, wParam, (LPARAM)&wLVItem);
724                                 break;
725                         case LVM_GETCOLUMNA:
726                                 pmLVColumn = (LVCOLUMNA*)lParam;
727                                 wLVColumn.mask = pmLVColumn->mask;
728                                 wLVColumn.fmt = pmLVColumn->fmt;
729                                 wLVColumn.cx = pmLVColumn->cx;
730                                 Size = pmLVColumn->cchTextMax * 4;
731                                 if(pmLVColumn->mask & LVCF_TEXT)
732                                 {
733                                         pw0 = AllocateStringW(Size);
734                                         wLVColumn.pszText = pw0;
735                                         wLVColumn.cchTextMax = Size;
736                                 }
737                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;
738                                 wLVColumn.iImage = pmLVColumn->iImage;
739                                 wLVColumn.iOrder = pmLVColumn->iOrder;
740                                 r = SendMessageW(hWnd, LVM_GETCOLUMNW, wParam, (LPARAM)&wLVColumn);
741                                 pmLVColumn->mask = wLVColumn.mask;
742                                 pmLVColumn->fmt = wLVColumn.fmt;
743                                 pmLVColumn->cx = wLVColumn.cx;
744                                 if(pmLVColumn->mask & LVCF_TEXT)
745                                 {
746                                         WtoM(pmLVColumn->pszText, pmLVColumn->cchTextMax, wLVColumn.pszText, -1);
747                                         TerminateStringM(pmLVColumn->pszText, pmLVColumn->cchTextMax);
748                                 }
749                                 pmLVColumn->iSubItem = wLVColumn.iSubItem;
750                                 pmLVColumn->iImage = wLVColumn.iImage;
751                                 pmLVColumn->iOrder = wLVColumn.iOrder;
752                                 break;
753                         case LVM_INSERTCOLUMNA:
754                                 pmLVColumn = (LVCOLUMNA*)lParam;
755                                 wLVColumn.mask = pmLVColumn->mask;
756                                 wLVColumn.fmt = pmLVColumn->fmt;
757                                 wLVColumn.cx = pmLVColumn->cx;
758                                 if(pmLVColumn->mask & LVCF_TEXT)
759                                 {
760                                         pw0 = DuplicateMtoW(pmLVColumn->pszText, -1);
761                                         wLVColumn.pszText = pw0;
762                                         // TODO: cchTextMax\82Ì\8am\94F
763                                         wLVColumn.cchTextMax = pmLVColumn->cchTextMax;
764                                 }
765                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;
766                                 wLVColumn.iImage = pmLVColumn->iImage;
767                                 wLVColumn.iOrder = pmLVColumn->iOrder;
768                                 r = SendMessageW(hWnd, LVM_INSERTCOLUMNW, wParam, (LPARAM)&wLVColumn);
769                                 break;
770                         case LVM_GETITEMTEXTA:
771                                 pmLVItem = (LVITEMA*)lParam;
772                                 wLVItem.mask = pmLVItem->mask;
773                                 wLVItem.iItem = pmLVItem->iItem;
774                                 wLVItem.iSubItem = pmLVItem->iSubItem;
775                                 wLVItem.state = pmLVItem->state;
776                                 wLVItem.stateMask = pmLVItem->stateMask;
777                                 Size = pmLVItem->cchTextMax * 4;
778                                 pw0 = AllocateStringW(Size);
779                                 wLVItem.pszText = pw0;
780                                 wLVItem.cchTextMax = Size;
781                                 wLVItem.iImage = pmLVItem->iImage;
782                                 wLVItem.lParam = pmLVItem->lParam;
783                                 wLVItem.iIndent = pmLVItem->iIndent;
784                                 r = SendMessageW(hWnd, LVM_GETITEMTEXTW, wParam, (LPARAM)&wLVItem);
785                                 pmLVItem->mask = wLVItem.mask;
786                                 pmLVItem->iItem = wLVItem.iItem;
787                                 pmLVItem->iSubItem = wLVItem.iSubItem;
788                                 pmLVItem->state = wLVItem.state;
789                                 pmLVItem->stateMask = wLVItem.stateMask;
790                                 WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);
791                                 TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);
792                                 pmLVItem->iImage = wLVItem.iImage;
793                                 pmLVItem->lParam = wLVItem.lParam;
794                                 pmLVItem->iIndent = wLVItem.iIndent;
795                                 break;
796                         default:
797                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
798                                 break;
799                         }
800                 }
801                 else if(_wcsicmp(ClassName, STATUSCLASSNAMEW) == 0)
802                 {
803                         switch(Msg)
804                         {
805                         case SB_SETTEXTA:
806                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
807                                 r = SendMessageW(hWnd, SB_SETTEXTW, wParam, (LPARAM)pw0);
808                                 break;
809                         default:
810                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
811                                 break;
812                         }
813                 }
814                 else
815                         r = SendMessageW(hWnd, Msg, wParam, lParam);
816                 break;
817         }
818 END_ROUTINE
819         FreeDuplicatedString(pw0);
820         FreeDuplicatedString(pw1);
821         return r;
822 }
823
824 LRESULT DefDlgProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
825 {
826         LRESULT r = 0;
827 START_ROUTINE
828         // WNDPROC\82ªShift_JIS\97p\82Å\82 \82é\82½\82ß
829         if(IsWindowUnicode(hWnd))
830                 r = DefDlgProcW(hWnd, Msg, wParam, lParam);
831         else
832                 r = DefDlgProcA(hWnd, Msg, wParam, lParam);
833 END_ROUTINE
834         return r;
835 }
836
837 LRESULT SendDlgItemMessageM(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
838 {
839         LRESULT r = 0;
840 START_ROUTINE
841         r = SendMessageM(GetDlgItem(hDlg, nIDDlgItem), Msg, wParam, lParam);
842 END_ROUTINE
843         return r;
844 }
845
846 BOOL SetWindowTextM(HWND hWnd, LPCSTR lpString)
847 {
848         BOOL r = FALSE;
849         wchar_t* pw0 = NULL;
850 START_ROUTINE
851         pw0 = DuplicateMtoW(lpString, -1);
852         r = SetWindowTextW(hWnd, pw0);
853 END_ROUTINE
854         FreeDuplicatedString(pw0);
855         return r;
856 }
857
858 UINT DragQueryFileM(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch)
859 {
860         UINT r = 0;
861         wchar_t* pw0 = NULL;
862 START_ROUTINE
863         if(iFile == (UINT)-1)
864                 r = DragQueryFileW(hDrop, iFile, (LPWSTR)lpszFile, cch);
865         else
866         {
867                 pw0 = AllocateStringW(cch * 4);
868                 DragQueryFileW(hDrop, iFile, pw0, cch * 4);
869                 WtoM(lpszFile, cch, pw0, -1);
870                 r = TerminateStringM(lpszFile, cch);
871         }
872 END_ROUTINE
873         FreeDuplicatedString(pw0);
874         return r;
875 }
876
877 DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)
878 {
879         DWORD r = 0;
880         wchar_t* pw0 = NULL;
881 START_ROUTINE
882         pw0 = AllocateStringW(nBufferLength * 4);
883         GetCurrentDirectoryW(nBufferLength * 4, pw0);
884         WtoM(lpBuffer, nBufferLength, pw0, -1);
885         r = TerminateStringM(lpBuffer, nBufferLength);
886 END_ROUTINE
887         FreeDuplicatedString(pw0);
888         return r;
889 }
890
891 BOOL SetCurrentDirectoryM(LPCSTR lpPathName)
892 {
893         BOOL r = FALSE;
894         wchar_t* pw0 = NULL;
895 START_ROUTINE
896         pw0 = DuplicateMtoW(lpPathName, -1);
897         r = SetCurrentDirectoryW(pw0);
898 END_ROUTINE
899         FreeDuplicatedString(pw0);
900         return r;
901 }
902
903 BOOL SetDllDirectoryM(LPCSTR lpPathName)
904 {
905         BOOL r = FALSE;
906         wchar_t* pw0 = NULL;
907 START_ROUTINE
908         pw0 = DuplicateMtoW(lpPathName, -1);
909         r = SetDllDirectoryW(pw0);
910 END_ROUTINE
911         FreeDuplicatedString(pw0);
912         return r;
913 }
914
915 DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)
916 {
917         DWORD r = 0;
918         wchar_t* pw0 = NULL;
919 START_ROUTINE
920         pw0 = AllocateStringW(nBufferLength * 4);
921         GetTempPathW(nBufferLength * 4, pw0);
922         WtoM(lpBuffer, nBufferLength, pw0, -1);
923         r = TerminateStringM(lpBuffer, nBufferLength);
924 END_ROUTINE
925         FreeDuplicatedString(pw0);
926         return r;
927 }
928
929 DWORD GetFileAttributesM(LPCSTR lpFileName)
930 {
931         DWORD r = FALSE;
932         wchar_t* pw0 = NULL;
933 START_ROUTINE
934         pw0 = DuplicateMtoW(lpFileName, -1);
935         r = GetFileAttributesW(pw0);
936 END_ROUTINE
937         FreeDuplicatedString(pw0);
938         return r;
939 }
940
941 DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)
942 {
943         DWORD r = 0;
944         wchar_t* pw0 = NULL;
945 START_ROUTINE
946         pw0 = AllocateStringW(nSize * 4);
947         GetModuleFileNameW(hModule, pw0, nSize * 4);
948         WtoM(lpFilename, nSize, pw0, -1);
949         r = TerminateStringM(lpFilename, nSize);
950 END_ROUTINE
951         FreeDuplicatedString(pw0);
952         return r;
953 }
954
955 LSTATUS RegOpenKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
956 {
957         LSTATUS r = 0;
958         wchar_t* pw0 = NULL;
959 START_ROUTINE
960         pw0 = DuplicateMtoW(lpSubKey, -1);
961         r = RegOpenKeyExW(hKey, pw0, ulOptions, samDesired, phkResult);
962 END_ROUTINE
963         FreeDuplicatedString(pw0);
964         return r;
965 }
966
967 LSTATUS RegCreateKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
968 {
969         LSTATUS r = 0;
970         wchar_t* pw0 = NULL;
971         wchar_t* pw1 = NULL;
972 START_ROUTINE
973         pw0 = DuplicateMtoW(lpSubKey, -1);
974         pw1 = DuplicateMtoW(lpClass, -1);
975         r = RegCreateKeyExW(hKey, pw0, Reserved, pw1, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
976 END_ROUTINE
977         FreeDuplicatedString(pw0);
978         FreeDuplicatedString(pw1);
979         return r;
980 }
981
982 LSTATUS RegDeleteValueM(HKEY hKey, LPCSTR lpValueName)
983 {
984         LSTATUS r = 0;
985         wchar_t* pw0 = NULL;
986 START_ROUTINE
987         pw0 = DuplicateMtoW(lpValueName, -1);
988         r = RegDeleteValueW(hKey, pw0);
989 END_ROUTINE
990         FreeDuplicatedString(pw0);
991         return r;
992 }
993
994 LSTATUS RegQueryValueExM(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
995 {
996         LSTATUS r = 0;
997         wchar_t* pw0 = NULL;
998         wchar_t* pw1 = NULL;
999         DWORD dwType;
1000         DWORD wcbData;
1001 START_ROUTINE
1002         pw0 = DuplicateMtoW(lpValueName, -1);
1003         if(RegQueryValueExW(hKey, pw0, NULL, &dwType, NULL, 0) == ERROR_SUCCESS)
1004         {
1005                 switch(dwType)
1006                 {
1007                 case REG_SZ:
1008                 case REG_EXPAND_SZ:
1009                 case REG_MULTI_SZ:
1010                         if(lpData && lpcbData)
1011                         {
1012                                 pw1 = AllocateStringW(*lpcbData / sizeof(char) * 4);
1013                                 wcbData = *lpcbData / sizeof(char) * 4;
1014                                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, (LPBYTE)pw1, &wcbData);
1015                                 *lpcbData = sizeof(char) * WtoM((char*)lpData, *lpcbData / sizeof(char), pw1, wcbData / sizeof(wchar_t));
1016                         }
1017                         break;
1018                 default:
1019                         r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);
1020                         break;
1021                 }
1022         }
1023         else
1024                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);
1025 END_ROUTINE
1026         FreeDuplicatedString(pw0);
1027         FreeDuplicatedString(pw1);
1028         return r;
1029 }
1030
1031 LSTATUS RegSetValueExM(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData)
1032 {
1033         LSTATUS r = 0;
1034         wchar_t* pw0 = NULL;
1035         wchar_t* pw1 = NULL;
1036         DWORD wcbData;
1037 START_ROUTINE
1038         pw0 = DuplicateMtoW(lpValueName, -1);
1039         switch(dwType)
1040         {
1041         case REG_SZ:
1042         case REG_EXPAND_SZ:
1043         case REG_MULTI_SZ:
1044                 wcbData = MtoW(NULL, 0, (char*)lpData, cbData / sizeof(char));
1045                 pw1 = AllocateStringW(wcbData);
1046                 MtoW(pw1, wcbData, (char*)lpData, cbData / sizeof(char));
1047                 wcbData = sizeof(wchar_t) * wcbData;
1048                 lpData = (BYTE*)pw1;
1049                 cbData = wcbData;
1050                 break;
1051         }
1052         r = RegSetValueExW(hKey, pw0, Reserved, dwType, lpData, cbData);
1053 END_ROUTINE
1054         FreeDuplicatedString(pw0);
1055         FreeDuplicatedString(pw1);
1056         return r;
1057 }
1058
1059 BOOL TextOutM(HDC hdc, int x, int y, LPCSTR lpString, int c)
1060 {
1061         BOOL r = FALSE;
1062         wchar_t* pw0 = NULL;
1063 START_ROUTINE
1064         pw0 = DuplicateMtoW(lpString, c);
1065         r = TextOutW(hdc, x, y, pw0, wcslen(pw0));
1066 END_ROUTINE
1067         FreeDuplicatedString(pw0);
1068         return r;
1069 }
1070
1071 BOOL GetTextExtentPoint32M(HDC hdc, LPCSTR lpString, int c, LPSIZE psizl)
1072 {
1073         BOOL r = FALSE;
1074         wchar_t* pw0 = NULL;
1075 START_ROUTINE
1076         pw0 = DuplicateMtoW(lpString, c);
1077         r = GetTextExtentPoint32W(hdc, pw0, wcslen(pw0), psizl);
1078 END_ROUTINE
1079         FreeDuplicatedString(pw0);
1080         return r;
1081 }
1082
1083 INT_PTR PropertySheetM(LPCPROPSHEETHEADERA v0)
1084 {
1085         INT_PTR r = 0;
1086         PROPSHEETHEADERW a0;
1087         PROPSHEETPAGEW* pwPage;
1088         UINT i;
1089 START_ROUTINE
1090         a0.dwSize = sizeof(PROPSHEETHEADERW);
1091         a0.dwFlags = v0->dwFlags;
1092         a0.hwndParent = v0->hwndParent;
1093         a0.hInstance = v0->hInstance;
1094         if(v0->dwFlags & PSH_USEICONID)
1095                 a0.pszIcon = DuplicateMtoW(v0->pszIcon, -1);
1096         else
1097                 a0.hIcon = v0->hIcon;
1098         a0.pszCaption = DuplicateMtoW(v0->pszCaption, -1);
1099         a0.nPages = v0->nPages;
1100         a0.pStartPage = DuplicateMtoW(v0->pStartPage, -1);
1101         if(v0->ppsp && (pwPage = (PROPSHEETPAGEW*)malloc(sizeof(PROPSHEETPAGEW) * v0->nPages)))
1102         {
1103                 for(i = 0; i < v0->nPages; i++)
1104                 {
1105                         pwPage[i].dwSize = sizeof(PROPSHEETPAGEW);
1106                         pwPage[i].dwFlags = v0->ppsp[i].dwFlags;
1107                         pwPage[i].hInstance = v0->ppsp[i].hInstance;
1108                         pwPage[i].pszTemplate = DuplicateMtoW(v0->ppsp[i].pszTemplate, -1);
1109                         if(v0->ppsp[i].dwFlags & PSP_USEICONID)
1110                                 pwPage[i].pszIcon = DuplicateMtoW(v0->ppsp[i].pszIcon, -1);
1111                         else
1112                                 pwPage[i].hIcon = v0->ppsp[i].hIcon;
1113                         if(v0->ppsp[i].dwFlags & PSP_USETITLE)
1114                                 pwPage[i].pszTitle = DuplicateMtoW(v0->ppsp[i].pszTitle, -1);
1115                         pwPage[i].pfnDlgProc = v0->ppsp[i].pfnDlgProc;
1116                         pwPage[i].lParam = v0->ppsp[i].lParam;
1117                         // TODO: pfnCallback
1118                         pwPage[i].pfnCallback = v0->ppsp[i].pfnCallback;
1119                         pwPage[i].pcRefParent = v0->ppsp[i].pcRefParent;
1120 //                      pwPage[i].pszHeaderTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderTitle, -1);
1121 //                      pwPage[i].pszHeaderSubTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderSubTitle, -1);
1122                         pwPage[i].hActCtx = v0->ppsp[i].hActCtx;
1123 //                      pwPage[i].pszbmHeader = DuplicateMtoW(v0->ppsp[i].pszbmHeader, -1);
1124                 }
1125         }
1126         else
1127                 pwPage = NULL;
1128         a0.ppsp = pwPage;
1129         a0.pfnCallback = v0->pfnCallback;
1130         r = PropertySheetW(&a0);
1131         if(a0.dwFlags & PSH_USEICONID)
1132                 FreeDuplicatedString(a0.pszIcon);
1133         FreeDuplicatedString(a0.pszCaption);
1134         FreeDuplicatedString(a0.pStartPage);
1135         if(pwPage)
1136         {
1137                 for(i = 0; i < v0->nPages; i++)
1138                 {
1139                         FreeDuplicatedString(pwPage[i].pszTemplate);
1140                         if(pwPage[i].dwFlags & PSP_USEICONID)
1141                                 FreeDuplicatedString(pwPage[i].pszIcon);
1142                         if(pwPage[i].dwFlags & PSP_USETITLE)
1143                                 FreeDuplicatedString(pwPage[i].pszTitle);
1144 //                      FreeDuplicatedString(pwPage[i].pszHeaderTitle);
1145 //                      FreeDuplicatedString(pwPage[i].pszHeaderSubTitle);
1146 //                      FreeDuplicatedString(pwPage[i].pszbmHeader);
1147                 }
1148                 free(pwPage);
1149         }
1150 END_ROUTINE
1151         return r;
1152 }
1153
1154 BOOL GetOpenFileNameM(LPOPENFILENAMEA v0)
1155 {
1156         BOOL r = FALSE;
1157         wchar_t* pw0 = NULL;
1158         wchar_t* pw1 = NULL;
1159         wchar_t* pw2 = NULL;
1160         wchar_t* pw3 = NULL;
1161         wchar_t* pw4 = NULL;
1162         wchar_t* pw5 = NULL;
1163         wchar_t* pw6 = NULL;
1164         wchar_t* pw7 = NULL;
1165         wchar_t* pw8 = NULL;
1166         wchar_t* pw9 = NULL;
1167         OPENFILENAMEW wofn;
1168 START_ROUTINE
1169         wofn.lStructSize = sizeof(OPENFILENAMEW);
1170         wofn.hwndOwner = v0->hwndOwner;
1171         wofn.hInstance = v0->hInstance;
1172         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);
1173         wofn.lpstrFilter = pw0;
1174         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);
1175         wofn.lpstrCustomFilter = pw1;
1176         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;
1177         wofn.nFilterIndex = v0->nFilterIndex;
1178         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);
1179         wofn.lpstrFile = pw2;
1180         wofn.nMaxFile = v0->nMaxFile * 4;
1181         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);
1182         wofn.lpstrFileTitle = pw3;
1183         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;
1184         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);
1185         wofn.lpstrInitialDir = pw4;
1186         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);
1187         wofn.lpstrTitle = pw5;
1188         wofn.Flags = v0->Flags;
1189         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);
1190         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);
1191         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);
1192         wofn.lpstrDefExt = pw6;
1193         wofn.lCustData = v0->lCustData;
1194         wofn.lpfnHook = v0->lpfnHook;
1195         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
1196         wofn.pvReserved = v0->pvReserved;
1197         wofn.FlagsEx = v0->FlagsEx;
1198         r = GetOpenFileNameW(&wofn);
1199         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);
1200         TerminateStringM(v0->lpstrFile, v0->nMaxFile);
1201         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);
1202         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);
1203 END_ROUTINE
1204         FreeDuplicatedString(pw0);
1205         FreeDuplicatedString(pw1);
1206         FreeDuplicatedString(pw2);
1207         FreeDuplicatedString(pw3);
1208         FreeDuplicatedString(pw4);
1209         FreeDuplicatedString(pw5);
1210         FreeDuplicatedString(pw6);
1211         return r;
1212 }
1213
1214 BOOL GetSaveFileNameM(LPOPENFILENAMEA v0)
1215 {
1216         BOOL r = FALSE;
1217         wchar_t* pw0 = NULL;
1218         wchar_t* pw1 = NULL;
1219         wchar_t* pw2 = NULL;
1220         wchar_t* pw3 = NULL;
1221         wchar_t* pw4 = NULL;
1222         wchar_t* pw5 = NULL;
1223         wchar_t* pw6 = NULL;
1224         wchar_t* pw7 = NULL;
1225         wchar_t* pw8 = NULL;
1226         wchar_t* pw9 = NULL;
1227         OPENFILENAMEW wofn;
1228 START_ROUTINE
1229         wofn.lStructSize = sizeof(OPENFILENAMEW);
1230         wofn.hwndOwner = v0->hwndOwner;
1231         wofn.hInstance = v0->hInstance;
1232         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);
1233         wofn.lpstrFilter = pw0;
1234         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);
1235         wofn.lpstrCustomFilter = pw1;
1236         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;
1237         wofn.nFilterIndex = v0->nFilterIndex;
1238         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);
1239         wofn.lpstrFile = pw2;
1240         wofn.nMaxFile = v0->nMaxFile * 4;
1241         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);
1242         wofn.lpstrFileTitle = pw3;
1243         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;
1244         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);
1245         wofn.lpstrInitialDir = pw4;
1246         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);
1247         wofn.lpstrTitle = pw5;
1248         wofn.Flags = v0->Flags;
1249         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);
1250         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);
1251         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);
1252         wofn.lpstrDefExt = pw6;
1253         wofn.lCustData = v0->lCustData;
1254         wofn.lpfnHook = v0->lpfnHook;
1255         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
1256         wofn.pvReserved = v0->pvReserved;
1257         wofn.FlagsEx = v0->FlagsEx;
1258         r = GetSaveFileNameW(&wofn);
1259         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);
1260         TerminateStringM(v0->lpstrFile, v0->nMaxFile);
1261         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);
1262         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);
1263 END_ROUTINE
1264         FreeDuplicatedString(pw0);
1265         FreeDuplicatedString(pw1);
1266         FreeDuplicatedString(pw2);
1267         FreeDuplicatedString(pw3);
1268         FreeDuplicatedString(pw4);
1269         FreeDuplicatedString(pw5);
1270         FreeDuplicatedString(pw6);
1271         return r;
1272 }
1273
1274 HWND HtmlHelpM(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData)
1275 {
1276         HWND r = NULL;
1277         wchar_t* pw0 = NULL;
1278 START_ROUTINE
1279         pw0 = DuplicateMtoW(pszFile, -1);
1280         r = HtmlHelpW(hwndCaller, pw0, uCommand, dwData);
1281 END_ROUTINE
1282         FreeDuplicatedString(pw0);
1283         return r;
1284 }
1285
1286 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)
1287 {
1288         BOOL r = FALSE;
1289         wchar_t* pw0 = NULL;
1290         wchar_t* pw1 = NULL;
1291         wchar_t* pw2 = NULL;
1292         wchar_t* pw3 = NULL;
1293         wchar_t* pw4 = NULL;
1294         wchar_t* pw5 = NULL;
1295         STARTUPINFOW wStartupInfo;
1296 START_ROUTINE
1297         pw0 = DuplicateMtoW(lpApplicationName, -1);
1298         pw1 = DuplicateMtoWBuffer(lpCommandLine, -1, (strlen(lpCommandLine) + 1) * 4);
1299         pw2 = DuplicateMtoW(lpCurrentDirectory, -1);
1300         wStartupInfo.cb = sizeof(LPSTARTUPINFOW);
1301         pw3 = DuplicateMtoW(lpStartupInfo->lpReserved, -1);
1302         wStartupInfo.lpReserved = pw3;
1303         pw4 = DuplicateMtoW(lpStartupInfo->lpDesktop, -1);
1304         wStartupInfo.lpDesktop = pw4;
1305         pw5 = DuplicateMtoW(lpStartupInfo->lpTitle, -1);
1306         wStartupInfo.lpTitle = pw5;
1307         wStartupInfo.dwX = lpStartupInfo->dwX;
1308         wStartupInfo.dwY = lpStartupInfo->dwY;
1309         wStartupInfo.dwXSize = lpStartupInfo->dwXSize;
1310         wStartupInfo.dwYSize = lpStartupInfo->dwYSize;
1311         wStartupInfo.dwXCountChars = lpStartupInfo->dwXCountChars;
1312         wStartupInfo.dwYCountChars = lpStartupInfo->dwYCountChars;
1313         wStartupInfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
1314         wStartupInfo.dwFlags = lpStartupInfo->dwFlags;
1315         wStartupInfo.wShowWindow = lpStartupInfo->wShowWindow;
1316         wStartupInfo.cbReserved2 = lpStartupInfo->cbReserved2;
1317         wStartupInfo.lpReserved2 = lpStartupInfo->lpReserved2;
1318         wStartupInfo.hStdInput = lpStartupInfo->hStdInput;
1319         wStartupInfo.hStdOutput = lpStartupInfo->hStdOutput;
1320         wStartupInfo.hStdError = lpStartupInfo->hStdError;
1321         r = CreateProcessW(pw0, pw1, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pw2, &wStartupInfo, lpProcessInformation);
1322         WtoM(lpCommandLine, strlen(lpCommandLine) + 1, pw1, -1);
1323 END_ROUTINE
1324         FreeDuplicatedString(pw0);
1325         FreeDuplicatedString(pw1);
1326         FreeDuplicatedString(pw2);
1327         FreeDuplicatedString(pw3);
1328         FreeDuplicatedString(pw4);
1329         FreeDuplicatedString(pw5);
1330         return r;
1331 }
1332
1333 HINSTANCE FindExecutableM(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
1334 {
1335         HINSTANCE r = NULL;
1336         wchar_t* pw0 = NULL;
1337         wchar_t* pw1 = NULL;
1338         wchar_t* pw2 = NULL;
1339         wchar_t* pw3 = NULL;
1340 START_ROUTINE
1341         pw0 = DuplicateMtoW(lpFile, -1);
1342         pw1 = DuplicateMtoW(lpDirectory, -1);
1343         pw2 = AllocateStringW(MAX_PATH * 4);
1344         r = FindExecutableW(pw0, pw1, pw2);
1345         // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
1346         WtoM(lpResult, MAX_PATH, pw2, -1);
1347         TerminateStringM(lpResult, MAX_PATH);
1348 END_ROUTINE
1349         FreeDuplicatedString(pw0);
1350         FreeDuplicatedString(pw1);
1351         FreeDuplicatedString(pw2);
1352         FreeDuplicatedString(pw3);
1353         return r;
1354 }
1355
1356 HINSTANCE ShellExecuteM(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)
1357 {
1358         HINSTANCE r = NULL;
1359         wchar_t* pw0 = NULL;
1360         wchar_t* pw1 = NULL;
1361         wchar_t* pw2 = NULL;
1362         wchar_t* pw3 = NULL;
1363 START_ROUTINE
1364         pw0 = DuplicateMtoW(lpOperation, -1);
1365         pw1 = DuplicateMtoW(lpFile, -1);
1366         pw2 = DuplicateMtoW(lpParameters, -1);
1367         pw3 = DuplicateMtoW(lpDirectory, -1);
1368         r = ShellExecuteW(hwnd, pw0, pw1, pw2, pw3, nShowCmd);
1369 END_ROUTINE
1370         FreeDuplicatedString(pw0);
1371         FreeDuplicatedString(pw1);
1372         FreeDuplicatedString(pw2);
1373         FreeDuplicatedString(pw3);
1374         return r;
1375 }
1376
1377 PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)
1378 {
1379         PIDLIST_ABSOLUTE r = NULL;
1380         wchar_t* pw0 = NULL;
1381         wchar_t* pw1 = NULL;
1382         BROWSEINFOW wbi;
1383 START_ROUTINE
1384         wbi.hwndOwner = lpbi->hwndOwner;
1385         wbi.pidlRoot = lpbi->pidlRoot;
1386         pw0 = DuplicateMtoWBuffer(lpbi->pszDisplayName, -1, MAX_PATH * 4);
1387         wbi.pszDisplayName = pw0;
1388         pw1 = DuplicateMtoW(lpbi->lpszTitle, -1);
1389         wbi.lpszTitle = pw1;
1390         wbi.ulFlags = lpbi->ulFlags;
1391         // TODO: lpfn
1392         wbi.lpfn = lpbi->lpfn;
1393         wbi.lParam = lpbi->lParam;
1394         wbi.iImage = lpbi->iImage;
1395         r = SHBrowseForFolderW(&wbi);
1396         // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
1397         WtoM(lpbi->pszDisplayName, MAX_PATH, wbi.pszDisplayName, -1);
1398         lpbi->iImage = wbi.iImage;
1399 END_ROUTINE
1400         FreeDuplicatedString(pw0);
1401         FreeDuplicatedString(pw1);
1402         return r;
1403 }
1404
1405 BOOL SHGetPathFromIDListM(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath)
1406 {
1407         BOOL r = FALSE;
1408         wchar_t* pw0 = NULL;
1409 START_ROUTINE
1410         pw0 = AllocateStringW(MAX_PATH * 4);
1411         r = SHGetPathFromIDListW(pidl, pw0);
1412         // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
1413         WtoM(pszPath, MAX_PATH, pw0, -1);
1414         TerminateStringM(pszPath, MAX_PATH);
1415 END_ROUTINE
1416         FreeDuplicatedString(pw0);
1417         return r;
1418 }
1419
1420 int SHFileOperationM(LPSHFILEOPSTRUCTA lpFileOp)
1421 {
1422         int r = 0;
1423         wchar_t* pw0 = NULL;
1424         wchar_t* pw1 = NULL;
1425         wchar_t* pw2 = NULL;
1426         SHFILEOPSTRUCTW wFileOp;
1427 START_ROUTINE
1428         wFileOp.hwnd = lpFileOp->hwnd;
1429         wFileOp.wFunc = lpFileOp->wFunc;
1430         pw0 = DuplicateMtoWMultiString(lpFileOp->pFrom);
1431         wFileOp.pFrom = pw0;
1432         pw1 = DuplicateMtoWMultiString(lpFileOp->pTo);
1433         wFileOp.pTo = pw1;
1434         wFileOp.fFlags = lpFileOp->fFlags;
1435         wFileOp.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;
1436         wFileOp.hNameMappings = lpFileOp->hNameMappings;
1437         pw2 = DuplicateMtoW(lpFileOp->lpszProgressTitle, -1);
1438         r = SHFileOperationW(&wFileOp);
1439         lpFileOp->fAnyOperationsAborted = wFileOp.fAnyOperationsAborted;
1440 END_ROUTINE
1441         FreeDuplicatedString(pw0);
1442         FreeDuplicatedString(pw1);
1443         FreeDuplicatedString(pw2);
1444         return r;
1445 }
1446
1447 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)
1448 {
1449         int r = 0;
1450         wchar_t* pw0 = NULL;
1451 START_ROUTINE
1452         if(uFlags & (MF_BITMAP | MF_OWNERDRAW))
1453                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, (LPCWSTR)lpNewItem);
1454         else
1455         {
1456                 pw0 = DuplicateMtoW(lpNewItem, -1);
1457                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, pw0);
1458         }
1459 END_ROUTINE
1460         FreeDuplicatedString(pw0);
1461         return r;
1462 }
1463
1464 BOOL GetMenuItemInfoM(HMENU hmenu, UINT item, BOOL fByPosition, LPMENUITEMINFOA lpmii)
1465 {
1466         BOOL r = FALSE;
1467         wchar_t* pw0 = NULL;
1468         MENUITEMINFOW wmii;
1469 START_ROUTINE
1470         wmii.cbSize = sizeof(MENUITEMINFOW);
1471         wmii.fMask = lpmii->fMask;
1472         wmii.fType = lpmii->fType;
1473         wmii.fState = lpmii->fState;
1474         wmii.wID = lpmii->wID;
1475         wmii.hSubMenu = lpmii->hSubMenu;
1476         wmii.hbmpChecked = lpmii->hbmpChecked;
1477         wmii.hbmpUnchecked = lpmii->hbmpUnchecked;
1478         wmii.dwItemData = lpmii->dwItemData;
1479         pw0 = DuplicateMtoWBuffer(lpmii->dwTypeData, -1, lpmii->cch * 4);
1480         wmii.dwTypeData = pw0;
1481         wmii.cch = lpmii->cch * 4;
1482         r = GetMenuItemInfoW(hmenu, item, fByPosition, &wmii);
1483         lpmii->fType = wmii.fType;
1484         lpmii->fState = wmii.fState;
1485         lpmii->wID = wmii.wID;
1486         lpmii->hSubMenu = wmii.hSubMenu;
1487         lpmii->hbmpChecked = wmii.hbmpChecked;
1488         lpmii->hbmpUnchecked = wmii.hbmpUnchecked;
1489         lpmii->dwItemData = wmii.dwItemData;
1490         WtoM(lpmii->dwTypeData, lpmii->cch, wmii.dwTypeData, -1);
1491         TerminateStringM(lpmii->dwTypeData, lpmii->cch);
1492 END_ROUTINE
1493         FreeDuplicatedString(pw0);
1494         return r;
1495 }
1496
1497 HFONT CreateFontIndirectM(CONST LOGFONTA *lplf)
1498 {
1499         HFONT r = NULL;
1500         LOGFONTW wlf;
1501 START_ROUTINE
1502         wlf.lfHeight = lplf->lfHeight;
1503         wlf.lfWidth = lplf->lfWidth;
1504         wlf.lfEscapement = lplf->lfEscapement;
1505         wlf.lfOrientation = lplf->lfOrientation;
1506         wlf.lfWeight = lplf->lfWeight;
1507         wlf.lfItalic = lplf->lfItalic;
1508         wlf.lfUnderline = lplf->lfUnderline;
1509         wlf.lfStrikeOut = lplf->lfStrikeOut;
1510         wlf.lfCharSet = lplf->lfCharSet;
1511         wlf.lfOutPrecision = lplf->lfOutPrecision;
1512         wlf.lfClipPrecision = lplf->lfClipPrecision;
1513         wlf.lfQuality = lplf->lfQuality;
1514         wlf.lfPitchAndFamily = lplf->lfPitchAndFamily;
1515         MtoW(wlf.lfFaceName, LF_FACESIZE, lplf->lfFaceName, -1);
1516         TerminateStringW(wlf.lfFaceName, LF_FACESIZE);
1517         r = CreateFontIndirect(&wlf);
1518 END_ROUTINE
1519         return r;
1520 }
1521
1522 BOOL ChooseFontM(LPCHOOSEFONTA v0)
1523 {
1524         BOOL r = FALSE;
1525         wchar_t* pw0 = NULL;
1526         CHOOSEFONTW a0;
1527         LOGFONTW* pwlf;
1528 START_ROUTINE
1529         a0.lStructSize = sizeof(CHOOSEFONTW);
1530         a0.hwndOwner = v0->hwndOwner;
1531         a0.hDC = v0->hDC;
1532         if(v0->lpLogFont && (pwlf = (LOGFONTW*)malloc(sizeof(LOGFONTW))))
1533         {
1534                 pwlf->lfHeight = v0->lpLogFont->lfHeight;
1535                 pwlf->lfWidth = v0->lpLogFont->lfWidth;
1536                 pwlf->lfEscapement = v0->lpLogFont->lfEscapement;
1537                 pwlf->lfOrientation = v0->lpLogFont->lfOrientation;
1538                 pwlf->lfWeight = v0->lpLogFont->lfWeight;
1539                 pwlf->lfItalic = v0->lpLogFont->lfItalic;
1540                 pwlf->lfUnderline = v0->lpLogFont->lfUnderline;
1541                 pwlf->lfStrikeOut = v0->lpLogFont->lfStrikeOut;
1542                 pwlf->lfCharSet = v0->lpLogFont->lfCharSet;
1543                 pwlf->lfOutPrecision = v0->lpLogFont->lfOutPrecision;
1544                 pwlf->lfClipPrecision = v0->lpLogFont->lfClipPrecision;
1545                 pwlf->lfQuality = v0->lpLogFont->lfQuality;
1546                 pwlf->lfPitchAndFamily = v0->lpLogFont->lfPitchAndFamily;
1547                 MtoW(pwlf->lfFaceName, LF_FACESIZE, v0->lpLogFont->lfFaceName, -1);
1548                 TerminateStringW(pwlf->lfFaceName, LF_FACESIZE);
1549         }
1550         else
1551                 pwlf = NULL;
1552         a0.lpLogFont = pwlf;
1553         a0.iPointSize = v0->iPointSize;
1554         a0.Flags = v0->Flags;
1555         a0.rgbColors = v0->rgbColors;
1556         a0.lCustData = v0->lCustData;
1557         a0.lpfnHook = v0->lpfnHook;
1558         a0.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
1559         a0.hInstance = v0->hInstance;
1560         a0.lpszStyle = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);
1561         a0.nFontType = v0->nFontType;
1562         a0.nSizeMin = v0->nSizeMin;
1563         a0.nSizeMax = v0->nSizeMax;
1564         r = ChooseFontW(&a0);
1565         if(v0->lpLogFont)
1566         {
1567                 v0->lpLogFont->lfHeight = pwlf->lfHeight;
1568                 v0->lpLogFont->lfWidth = pwlf->lfWidth;
1569                 v0->lpLogFont->lfEscapement = pwlf->lfEscapement;
1570                 v0->lpLogFont->lfOrientation = pwlf->lfOrientation;
1571                 v0->lpLogFont->lfWeight = pwlf->lfWeight;
1572                 v0->lpLogFont->lfItalic = pwlf->lfItalic;
1573                 v0->lpLogFont->lfUnderline = pwlf->lfUnderline;
1574                 v0->lpLogFont->lfStrikeOut = pwlf->lfStrikeOut;
1575                 v0->lpLogFont->lfCharSet = pwlf->lfCharSet;
1576                 v0->lpLogFont->lfOutPrecision = pwlf->lfOutPrecision;
1577                 v0->lpLogFont->lfClipPrecision = pwlf->lfClipPrecision;
1578                 v0->lpLogFont->lfQuality = pwlf->lfQuality;
1579                 v0->lpLogFont->lfPitchAndFamily = pwlf->lfPitchAndFamily;
1580                 WtoM(v0->lpLogFont->lfFaceName, LF_FACESIZE, pwlf->lfFaceName, -1);
1581                 TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);
1582         }
1583         v0->rgbColors = a0.rgbColors;
1584         WtoM(v0->lpszStyle, LF_FACESIZE, a0.lpszStyle, -1);
1585         TerminateStringM(v0->lpszStyle, LF_FACESIZE);
1586         v0->nFontType = a0.nFontType;
1587         if(pwlf)
1588                 free(pwlf);
1589         FreeDuplicatedString(a0.lpTemplateName);
1590         FreeDuplicatedString(a0.lpszStyle);
1591 END_ROUTINE
1592         FreeDuplicatedString(pw0);
1593         return r;
1594 }
1595
1596 INT_PTR DialogBoxParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
1597 {
1598         INT_PTR r = 0;
1599         wchar_t* pw0 = NULL;
1600 START_ROUTINE
1601         pw0 = DuplicateMtoW(lpTemplateName, -1);
1602         r = DialogBoxParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);
1603 END_ROUTINE
1604         FreeDuplicatedString(pw0);
1605         return r;
1606 }
1607
1608 HWND CreateDialogParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
1609 {
1610         HWND r = NULL;
1611         wchar_t* pw0 = NULL;
1612 START_ROUTINE
1613         pw0 = DuplicateMtoW(lpTemplateName, -1);
1614         r = CreateDialogParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);
1615 END_ROUTINE
1616         FreeDuplicatedString(pw0);
1617         return r;
1618 }
1619
1620 int mkdirM(const char * _Path)
1621 {
1622         int r = 0;
1623         wchar_t* pw0 = NULL;
1624 START_ROUTINE
1625         pw0 = DuplicateMtoW(_Path, -1);
1626         r = _wmkdir(pw0);
1627 END_ROUTINE
1628         FreeDuplicatedString(pw0);
1629         return r;
1630 }
1631
1632 int _mkdirM(const char * _Path)
1633 {
1634         int r = 0;
1635         wchar_t* pw0 = NULL;
1636 START_ROUTINE
1637         pw0 = DuplicateMtoW(_Path, -1);
1638         r = _wmkdir(pw0);
1639 END_ROUTINE
1640         FreeDuplicatedString(pw0);
1641         return r;
1642 }
1643
1644 int rmdirM(const char * _Path)
1645 {
1646         int r = 0;
1647         wchar_t* pw0 = NULL;
1648 START_ROUTINE
1649         pw0 = DuplicateMtoW(_Path, -1);
1650         r = _wrmdir(pw0);
1651 END_ROUTINE
1652         FreeDuplicatedString(pw0);
1653         return r;
1654 }
1655
1656 int _rmdirM(const char * _Path)
1657 {
1658         int r = 0;
1659         wchar_t* pw0 = NULL;
1660 START_ROUTINE
1661         pw0 = DuplicateMtoW(_Path, -1);
1662         r = _wrmdir(pw0);
1663 END_ROUTINE
1664         FreeDuplicatedString(pw0);
1665         return r;
1666 }
1667
1668 size_t _mbslenM(const unsigned char * _Str)
1669 {
1670         size_t r = 0;
1671         wchar_t* pw0 = NULL;
1672 START_ROUTINE
1673         pw0 = DuplicateMtoW(_Str, -1);
1674         r = wcslen(pw0);
1675 END_ROUTINE
1676         FreeDuplicatedString(pw0);
1677         return r;
1678 }
1679
1680 unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)
1681 {
1682         unsigned char* r = NULL;
1683         wchar_t* pw0 = NULL;
1684         wchar_t* wr;
1685 START_ROUTINE
1686         pw0 = DuplicateMtoW(_Str, -1);
1687         // TODO: \94ñASCII\95\8e\9a\82Ì\91Î\89\9e
1688         wr = wcschr(pw0, _Ch);
1689         if(wr)
1690         {
1691                 *wr = L'\0';
1692                 r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
1693         }
1694 END_ROUTINE
1695         FreeDuplicatedString(pw0);
1696         return r;
1697 }
1698
1699 unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)
1700 {
1701         unsigned char* r = NULL;
1702         wchar_t* pw0 = NULL;
1703         wchar_t* wr;
1704 START_ROUTINE
1705         pw0 = DuplicateMtoW(_Str, -1);
1706         // TODO: \94ñASCII\95\8e\9a\82Ì\91Î\89\9e
1707         wr = wcsrchr(pw0, _Ch);
1708         if(wr)
1709         {
1710                 *wr = L'\0';
1711                 r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
1712         }
1713 END_ROUTINE
1714         FreeDuplicatedString(pw0);
1715         return r;
1716 }
1717
1718 unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)
1719 {
1720         unsigned char* r = NULL;
1721         wchar_t* pw0 = NULL;
1722         wchar_t* pw1 = NULL;
1723         wchar_t* wr;
1724 START_ROUTINE
1725         pw0 = DuplicateMtoW(_Str, -1);
1726         pw1 = DuplicateMtoW(_Substr, -1);
1727         wr = wcsstr(pw0, pw1);
1728         if(wr)
1729         {
1730                 *wr = L'\0';
1731                 r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
1732         }
1733 END_ROUTINE
1734         FreeDuplicatedString(pw0);
1735         FreeDuplicatedString(pw1);
1736         return r;
1737 }
1738
1739 int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)
1740 {
1741         int r = 0;
1742         wchar_t* pw0 = NULL;
1743         wchar_t* pw1 = NULL;
1744 START_ROUTINE
1745         pw0 = DuplicateMtoW(_Str1, -1);
1746         pw1 = DuplicateMtoW(_Str2, -1);
1747         r = wcscmp(pw0, pw1);
1748 END_ROUTINE
1749         FreeDuplicatedString(pw0);
1750         FreeDuplicatedString(pw1);
1751         return r;
1752 }
1753
1754 int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)
1755 {
1756         int r = 0;
1757         wchar_t* pw0 = NULL;
1758         wchar_t* pw1 = NULL;
1759 START_ROUTINE
1760         pw0 = DuplicateMtoW(_Str1, -1);
1761         pw1 = DuplicateMtoW(_Str2, -1);
1762         r = _wcsicmp(pw0, pw1);
1763 END_ROUTINE
1764         FreeDuplicatedString(pw0);
1765         FreeDuplicatedString(pw1);
1766         return r;
1767 }
1768
1769 int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)
1770 {
1771         int r = 0;
1772         wchar_t* pw0 = NULL;
1773         wchar_t* pw1 = NULL;
1774 START_ROUTINE
1775         pw0 = DuplicateMtoW(_Str1, -1);
1776         pw1 = DuplicateMtoW(_Str2, -1);
1777         r = wcsncmp(pw0, pw1, _MaxCount);
1778 END_ROUTINE
1779         FreeDuplicatedString(pw0);
1780         FreeDuplicatedString(pw1);
1781         return r;
1782 }
1783
1784 unsigned char * _mbslwrM(unsigned char * _String)
1785 {
1786         unsigned char* r = NULL;
1787         wchar_t* pw0 = NULL;
1788 START_ROUTINE
1789         pw0 = DuplicateMtoW(_String, -1);
1790         _wcslwr(pw0);
1791         r = _String;
1792         WtoM(_String, strlen(_String) + 1, pw0, -1);
1793 END_ROUTINE
1794         FreeDuplicatedString(pw0);
1795         return r;
1796 }
1797
1798 unsigned char * _mbsuprM(unsigned char * _String)
1799 {
1800         unsigned char* r = NULL;
1801         wchar_t* pw0 = NULL;
1802 START_ROUTINE
1803         pw0 = DuplicateMtoW(_String, -1);
1804         _wcsupr(pw0);
1805         r = _String;
1806         WtoM(_String, strlen(_String) + 1, pw0, -1);
1807 END_ROUTINE
1808         FreeDuplicatedString(pw0);
1809         return r;
1810 }
1811
1812 unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)
1813 {
1814         unsigned char* r = NULL;
1815         wchar_t* pw0 = NULL;
1816         wchar_t* wr;
1817 START_ROUTINE
1818         pw0 = DuplicateMtoW(_Str, -1);
1819         wr = _wcsninc(pw0, _Count);
1820         if(wr)
1821         {
1822                 *wr = L'\0';
1823                 r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
1824         }
1825 END_ROUTINE
1826         FreeDuplicatedString(pw0);
1827         return r;
1828 }
1829