OSDN Git Service

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