OSDN Git Service

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