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