OSDN Git Service

fc4841a8ec7e3efc1169449e621211288255e4b2
[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 _WIN32_WINNT 0x0600
9 #undef _WIN32_IE
10 #define _WIN32_IE 0x0400
11
12 #include <tchar.h>
13 #include <windows.h>
14 #include <commctrl.h>
15 #include <shlobj.h>
16 #include <htmlhelp.h>
17
18 #define DO_NOT_REPLACE
19 #include "mbswrapper.h"
20
21 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82©\82ç\83\8f\83C\83h\95\8e\9a\97ñ\82Ö\95Ï\8a·
22 int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)
23 {
24         if(pSrc < (LPCSTR)0x00010000 || !((char*)pSrc + 1))
25                 return 0;
26         if(pDst)
27                 return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);
28         return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);
29 }
30
31 // \83\8f\83C\83h\95\8e\9a\97ñ\82©\82ç\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82Ö\95Ï\8a·
32 int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)
33 {
34         if(pSrc < (LPCWSTR)0x00010000 || !((char*)pSrc + 1))
35                 return 0;
36         if(pDst)
37                 return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);
38         return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);
39 }
40
41 // \83\8f\83C\83h\95\8e\9a\97ñ\82©\82çShift_JIS\95\8e\9a\97ñ\82Ö\95Ï\8a·
42 int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)
43 {
44         if(pSrc < (LPCWSTR)0x00010000 || !((char*)pSrc + 1))
45                 return 0;
46         if(pDst)
47                 return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);
48         return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);
49 }
50
51 // \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·
52 int TerminateStringM(LPSTR lpString, int size)
53 {
54         int i;
55         if(lpString < (LPSTR)0x00010000 || !((char*)lpString + 1))
56                 return 0;
57         for(i = 0; i < size; i++)
58         {
59                 if(lpString[i] == '\0')
60                         return i;
61         }
62         i--;
63         lpString[i] = '\0';
64         return i;
65 }
66
67 // \83\8f\83C\83h\95\8e\9a\97ñ\83o\83b\83t\83@\8fI\92[\82ð\8b­\90§\93I\82ÉNULL\82Å\92u\8a·
68 int TerminateStringW(LPWSTR lpString, int size)
69 {
70         int i;
71         if(lpString < (LPWSTR)0x00010000 || !((char*)lpString + 1))
72                 return 0;
73         for(i = 0; i < size; i++)
74         {
75                 if(lpString[i] == L'\0')
76                         return i;
77         }
78         i--;
79         lpString[i] = L'\0';
80         return i;
81 }
82
83 // NULL\8bæ\90Ø\82è\95¡\90\94\83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\82Ì\92·\82³\82ð\8eæ\93¾
84 size_t GetMultiStringLengthM(LPCSTR lpString)
85 {
86         size_t i;
87         if(lpString < (LPCSTR)0x00010000 || !((char*)lpString + 1))
88                 return 0;
89         i = 0;
90         while(lpString[i] != '\0' || lpString[i + 1] != '\0')
91         {
92                 i++;
93         }
94         i++;
95         return i;
96 }
97
98 // NULL\8bæ\90Ø\82è\95¡\90\94\83\8f\83C\83h\95\8e\9a\97ñ\82Ì\92·\82³\82ð\8eæ\93¾
99 size_t GetMultiStringLengthW(LPCWSTR lpString)
100 {
101         size_t i;
102         if(lpString < (LPCWSTR)0x00010000 || !((char*)lpString + 1))
103                 return 0;
104         i = 0;
105         while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')
106         {
107                 i++;
108         }
109         i++;
110         return i;
111 }
112
113 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\97ñ\97p\82Ì\83\81\83\82\83\8a\82ð\8am\95Û
114 char* AllocateStringM(int size)
115 {
116         char* p;
117         p = (char*)malloc(sizeof(char) * size);
118         if(p)
119                 *p = '\0';
120         return p;
121 }
122
123 // \83\8f\83C\83h\95\8e\9a\97ñ\97p\82Ì\83\81\83\82\83\8a\82ð\8am\95Û
124 wchar_t* AllocateStringW(int size)
125 {
126         wchar_t* p;
127         p = (wchar_t*)malloc(sizeof(wchar_t) * size);
128         if(p)
129                 *p = L'\0';
130         return p;
131 }
132
133 // Shift_JIS\95\8e\9a\97ñ\97p\82Ì\83\81\83\82\83\8a\82ð\8am\95Û
134 char* AllocateStringA(int size)
135 {
136         char* p;
137         p = (char*)malloc(sizeof(char) * size);
138         if(p)
139                 *p = '\0';
140         return p;
141 }
142
143 // \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·
144 wchar_t* DuplicateMtoW(LPCSTR lpString, int c)
145 {
146         wchar_t* p;
147         int i;
148         if(lpString < (LPCSTR)0x00010000 || !((char*)lpString + 1))
149                 return (wchar_t*)lpString;
150         if(c < 0)
151                 c = strlen(lpString);
152         p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);
153         if(p)
154         {
155                 i = MtoW(p, 65535, lpString, c);
156                 p[i] = L'\0';
157         }
158         return p;
159 }
160
161 // \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·
162 wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)
163 {
164         wchar_t* p;
165         int i;
166         if(lpString < (LPCSTR)0x00010000 || !((char*)lpString + 1))
167                 return (wchar_t*)lpString;
168         if(c < 0)
169                 c = strlen(lpString);
170         p = AllocateStringW(size);
171         if(p)
172         {
173                 i = MtoW(p, size, lpString, c);
174                 p[i] = L'\0';
175         }
176         return p;
177 }
178
179 // \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·
180 wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)
181 {
182         int count;
183         wchar_t* p;
184         if(lpString < (LPCSTR)0x00010000 || !((char*)lpString + 1))
185                 return (wchar_t*)lpString;
186         count = GetMultiStringLengthM(lpString) + 1;
187         p = AllocateStringW(count);
188         if(p)
189                 MtoW(p, count, lpString, count);
190         return p;
191 }
192
193 // \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·
194 wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)
195 {
196         int count;
197         wchar_t* p;
198         if(lpString < (LPCSTR)0x00010000 || !((char*)lpString + 1))
199                 return (wchar_t*)lpString;
200         count = GetMultiStringLengthM(lpString) + 1;
201         p = AllocateStringW(size);
202         if(p)
203         {
204                 MtoW(p, size, lpString, count);
205                 p[size - 2] = L'\0';
206                 p[size - 1] = L'\0';
207         }
208         return p;
209 }
210
211 // \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·
212 char* DuplicateWtoM(LPCWSTR lpString, int c)
213 {
214         char* p;
215         int i;
216         if(lpString < (LPCWSTR)0x00010000 || !((char*)lpString + 1))
217                 return (char*)lpString;
218         if(c < 0)
219                 c = wcslen(lpString);
220         p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);
221         if(p)
222         {
223                 i = WtoM(p, 65535, lpString, c);
224                 p[i] = L'\0';
225         }
226         return p;
227 }
228
229 // \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·
230 char* DuplicateWtoA(LPCWSTR lpString, int c)
231 {
232         char* p;
233         int i;
234         if(lpString < (LPCWSTR)0x00010000 || !((char*)lpString + 1))
235                 return (char*)lpString;
236         if(c < 0)
237                 c = wcslen(lpString);
238         p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);
239         if(p)
240         {
241                 i = WtoA(p, 65535, lpString, c);
242                 p[i] = L'\0';
243         }
244         return p;
245 }
246
247 // \95\8e\9a\97ñ\97p\82É\8am\95Û\82µ\82½\83\81\83\82\83\8a\82ð\8aJ\95ú
248 void FreeDuplicatedString(void* p)
249 {
250         if(p < (void*)0x00010000 || !((char*)p + 1))
251                 return;
252         free(p);
253 }
254
255 // \88È\89º\83\89\83b\83p\81[
256 // \96ß\82è\92l\83o\83b\83t\83@ r
257 // \83\8f\83C\83h\95\8e\9a\83o\83b\83t\83@ pw%d
258 // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\83o\83b\83t\83@ pm%d
259 // \88ø\90\94\83o\83b\83t\83@ a%d
260
261 #define START_ROUTINE                                   do{
262 #define END_ROUTINE                                             }while(0);end_of_routine:
263 #define QUIT_ROUTINE                                    goto end_of_routine;
264
265 HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
266 {
267         HANDLE r = INVALID_HANDLE_VALUE;
268         wchar_t* pw0 = NULL;
269 START_ROUTINE
270         pw0 = DuplicateMtoW(lpFileName, -1);
271         r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
272 END_ROUTINE
273         FreeDuplicatedString(pw0);
274         return r;
275 }
276
277 int MessageBoxM(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
278 {
279         int r = IDOK;
280         wchar_t* pw0 = NULL;
281         wchar_t* pw1 = NULL;
282 START_ROUTINE
283         pw0 = DuplicateMtoW(lpText, -1);
284         pw1 = DuplicateMtoW(lpCaption, -1);
285         r = MessageBoxW(hWnd, pw0, pw1, uType);
286 END_ROUTINE
287         FreeDuplicatedString(pw0);
288         FreeDuplicatedString(pw1);
289         return r;
290 }
291
292 HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
293 {
294         HANDLE r = INVALID_HANDLE_VALUE;
295         wchar_t* pw0 = NULL;
296         WIN32_FIND_DATAW a0;
297 START_ROUTINE
298         pw0 = DuplicateMtoW(lpFileName, -1);
299         r = FindFirstFileW(pw0, &a0);
300         if(r != INVALID_HANDLE_VALUE)
301         {
302                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
303                 lpFindFileData->ftCreationTime = a0.ftCreationTime;
304                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
305                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
306                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
307                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
308                 lpFindFileData->dwReserved0 = a0.dwReserved0;
309                 lpFindFileData->dwReserved1 = a0.dwReserved1;
310                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
311                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
312         }
313 END_ROUTINE
314         FreeDuplicatedString(pw0);
315         return r;
316 }
317
318 BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
319 {
320         BOOL r = FALSE;
321         WIN32_FIND_DATAW a0;
322 START_ROUTINE
323         r = FindNextFileW(hFindFile, &a0);
324         if(r)
325         {
326                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
327                 lpFindFileData->ftCreationTime = a0.ftCreationTime;
328                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
329                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
330                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
331                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
332                 lpFindFileData->dwReserved0 = a0.dwReserved0;
333                 lpFindFileData->dwReserved1 = a0.dwReserved1;
334                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
335                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
336         }
337 END_ROUTINE
338         return r;
339 }
340
341 DWORD GetLogicalDriveStringsM(DWORD nBufferLength, LPSTR lpBuffer)
342 {
343         // TODO: \96{\97\88\82Í\95Ï\8a·\82ª\95K\97v\82¾\82ª\94¼\8ap\89p\90\94\82Ì\82Ý\82Æ\8ev\82í\82ê\82é\82Ì\82Å\8fÈ\97ª
344         return GetLogicalDriveStringsA(nBufferLength, lpBuffer);
345 }
346
347 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)
348 {
349         HWND r = NULL;
350         wchar_t* pw0 = NULL;
351         wchar_t* pw1 = NULL;
352 START_ROUTINE
353         pw0 = DuplicateMtoW(lpClassName, -1);
354         pw1 = DuplicateMtoW(lpWindowName, -1);
355         r = CreateWindowExW(dwExStyle, pw0, pw1, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
356 END_ROUTINE
357         FreeDuplicatedString(pw0);
358         FreeDuplicatedString(pw1);
359         return r;
360 }
361
362 LRESULT SendMessageM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
363 {
364         LRESULT r = 0;
365         wchar_t* pw0 = NULL;
366         wchar_t* pw1 = NULL;
367         int Size;
368         LVITEMA* pmLVItem;
369         LVITEMW wLVItem;
370         LVFINDINFOA* pmLVFindInfo;
371         LVFINDINFOW wLVFindInfo;
372         LVCOLUMNA* pmLVColumn;
373         LVCOLUMNW wLVColumn;
374         wchar_t ClassName[MAX_PATH];
375 START_ROUTINE
376         switch(Msg)
377         {
378         case WM_SETTEXT:
379                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
380                 r = SendMessageW(hWnd, WM_SETTEXT, wParam, (LPARAM)pw0);
381                 break;
382         case WM_GETTEXT:
383                 pw0 = AllocateStringW(wParam * 4);
384                 SendMessageW(hWnd, WM_GETTEXT, wParam * 4, (LPARAM)pw0);
385                 WtoM((LPSTR)lParam, wParam, pw0, -1);
386                 r = TerminateStringM((LPSTR)lParam, wParam);
387                 break;
388         case WM_GETTEXTLENGTH:
389                 Size = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1;
390                 pw0 = AllocateStringW(Size);
391                 SendMessageW(hWnd, WM_GETTEXT, (WPARAM)Size, (LPARAM)pw0);
392                 r = WtoM(NULL, 0, pw0, -1) - 1;
393                 break;
394         default:
395                 GetClassNameW(hWnd, ClassName, sizeof(ClassName) / sizeof(wchar_t));
396                 if(_wcsicmp(ClassName, WC_EDITW) == 0)
397                 {
398                         switch(Msg)
399                         {
400                         case EM_REPLACESEL:
401                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
402                                 r = SendMessageW(hWnd, EM_REPLACESEL, wParam, (LPARAM)pw0);
403                                 break;
404                         default:
405                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
406                                 break;
407                         }
408                 }
409                 else if(_wcsicmp(ClassName, WC_COMBOBOXW) == 0)
410                 {
411                         switch(Msg)
412                         {
413                         case CB_ADDSTRING:
414                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
415                                 r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0);
416                                 break;
417                         case CB_GETLBTEXT:
418                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;
419                                 pw0 = AllocateStringW(Size);
420                                 SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0);
421                                 // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
422                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);
423                                 r = TerminateStringM((LPSTR)lParam, Size * 4);
424                                 break;
425                         case CB_GETLBTEXTLEN:
426                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;
427                                 pw0 = AllocateStringW(Size);
428                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);
429                                 r = WtoM(NULL, 0, pw0, -1) - 1;
430                                 break;
431                         case CB_INSERTSTRING:
432                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
433                                 r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0);
434                                 break;
435                         case CB_FINDSTRINGEXACT:
436                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
437                                 r = SendMessageW(hWnd, CB_FINDSTRINGEXACT, wParam, (LPARAM)pw0);
438                                 break;
439                         default:
440                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
441                                 break;
442                         }
443                 }
444                 else if(_wcsicmp(ClassName, WC_LISTBOXW) == 0)
445                 {
446                         switch(Msg)
447                         {
448                         case LB_ADDSTRING:
449                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
450                                 r = SendMessageW(hWnd, LB_ADDSTRING, wParam, (LPARAM)pw0);
451                                 break;
452                         case LB_INSERTSTRING:
453                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
454                                 r = SendMessageW(hWnd, LB_INSERTSTRING, wParam, (LPARAM)pw0);
455                                 break;
456                         case LB_GETTEXT:
457                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;
458                                 pw0 = AllocateStringW(Size);
459                                 SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0);
460                                 // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
461                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);
462                                 r = TerminateStringM((LPSTR)lParam, Size * 4);
463                                 break;
464                         case LB_GETTEXTLEN:
465                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;
466                                 pw0 = AllocateStringW(Size);
467                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);
468                                 r = WtoM(NULL, 0, pw0, -1) - 1;
469                                 break;
470                         default:
471                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
472                                 break;
473                         }
474                 }
475                 else if(_wcsicmp(ClassName, WC_LISTVIEWW) == 0)
476                 {
477                         switch(Msg)
478                         {
479                         case LVM_GETITEMA:
480                                 pmLVItem = (LVITEMA*)lParam;
481                                 wLVItem.mask = pmLVItem->mask;
482                                 wLVItem.iItem = pmLVItem->iItem;
483                                 wLVItem.iSubItem = pmLVItem->iSubItem;
484                                 wLVItem.state = pmLVItem->state;
485                                 wLVItem.stateMask = pmLVItem->stateMask;
486                                 Size = pmLVItem->cchTextMax * 4;
487                                 pw0 = AllocateStringW(Size);
488                                 wLVItem.pszText = pw0;
489                                 wLVItem.cchTextMax = Size;
490                                 wLVItem.iImage = pmLVItem->iImage;
491                                 wLVItem.lParam = pmLVItem->lParam;
492                                 wLVItem.iIndent = pmLVItem->iIndent;
493                                 r = SendMessageW(hWnd, LVM_GETITEMW, wParam, (LPARAM)&wLVItem);
494                                 pmLVItem->mask = wLVItem.mask;
495                                 pmLVItem->iItem = wLVItem.iItem;
496                                 pmLVItem->iSubItem = wLVItem.iSubItem;
497                                 pmLVItem->state = wLVItem.state;
498                                 pmLVItem->stateMask = wLVItem.stateMask;
499                                 WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);
500                                 TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);
501                                 pmLVItem->iImage = wLVItem.iImage;
502                                 pmLVItem->lParam = wLVItem.lParam;
503                                 pmLVItem->iIndent = wLVItem.iIndent;
504                                 break;
505                         case LVM_SETITEMA:
506                                 pmLVItem = (LVITEMA*)lParam;
507                                 wLVItem.mask = pmLVItem->mask;
508                                 wLVItem.iItem = pmLVItem->iItem;
509                                 wLVItem.iSubItem = pmLVItem->iSubItem;
510                                 wLVItem.state = pmLVItem->state;
511                                 wLVItem.stateMask = pmLVItem->stateMask;
512                                 pw0 = DuplicateMtoW(pmLVItem->pszText, -1);
513                                 wLVItem.pszText = pw0;
514                                 // TODO: cchTextMax\82Ì\8am\94F
515                                 wLVItem.cchTextMax = pmLVItem->cchTextMax;
516                                 wLVItem.iImage = pmLVItem->iImage;
517                                 wLVItem.lParam = pmLVItem->lParam;
518                                 wLVItem.iIndent = pmLVItem->iIndent;
519                                 r = SendMessageW(hWnd, LVM_SETITEMW, wParam, (LPARAM)&wLVItem);
520                                 break;
521                         case LVM_INSERTITEMA:
522                                 pmLVItem = (LVITEMA*)lParam;
523                                 wLVItem.mask = pmLVItem->mask;
524                                 wLVItem.iItem = pmLVItem->iItem;
525                                 wLVItem.iSubItem = pmLVItem->iSubItem;
526                                 wLVItem.state = pmLVItem->state;
527                                 wLVItem.stateMask = pmLVItem->stateMask;
528                                 pw0 = DuplicateMtoW(pmLVItem->pszText, -1);
529                                 wLVItem.pszText = pw0;
530                                 // TODO: cchTextMax\82Ì\8am\94F
531                                 wLVItem.cchTextMax = pmLVItem->cchTextMax;
532                                 wLVItem.iImage = pmLVItem->iImage;
533                                 wLVItem.lParam = pmLVItem->lParam;
534                                 wLVItem.iIndent = pmLVItem->iIndent;
535                                 r = SendMessageW(hWnd, LVM_INSERTITEMW, wParam, (LPARAM)&wLVItem);
536                                 break;
537                         case LVM_FINDITEMA:
538                                 pmLVFindInfo = (LVFINDINFOA*)lParam;
539                                 wLVFindInfo.flags = pmLVFindInfo->flags;
540                                 pw0 = DuplicateMtoW(pmLVFindInfo->psz, -1);
541                                 wLVFindInfo.psz = pw0;
542                                 wLVFindInfo.lParam = pmLVFindInfo->lParam;
543                                 wLVFindInfo.pt = pmLVFindInfo->pt;
544                                 wLVFindInfo.vkDirection = pmLVFindInfo->vkDirection;
545                                 r = SendMessageW(hWnd, LVM_FINDITEMW, wParam, (LPARAM)&wLVItem);
546                                 break;
547                         case LVM_INSERTCOLUMNA:
548                                 pmLVColumn = (LVCOLUMNA*)lParam;
549                                 wLVColumn.mask = pmLVColumn->mask;
550                                 wLVColumn.fmt = pmLVColumn->fmt;
551                                 wLVColumn.cx = pmLVColumn->cx;
552                                 pw0 = DuplicateMtoW(pmLVColumn->pszText, -1);
553                                 wLVColumn.pszText = pw0;
554                                 wLVColumn.cchTextMax = pmLVColumn->cchTextMax;
555                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;
556                                 wLVColumn.iImage = pmLVColumn->iImage;
557                                 wLVColumn.iOrder = pmLVColumn->iOrder;
558                                 r = SendMessageW(hWnd, LVM_INSERTCOLUMNW, wParam, (LPARAM)&wLVColumn);
559                                 break;
560                         case LVM_GETITEMTEXTA:
561                                 pmLVItem = (LVITEMA*)lParam;
562                                 wLVItem.mask = pmLVItem->mask;
563                                 wLVItem.iItem = pmLVItem->iItem;
564                                 wLVItem.iSubItem = pmLVItem->iSubItem;
565                                 wLVItem.state = pmLVItem->state;
566                                 wLVItem.stateMask = pmLVItem->stateMask;
567                                 Size = pmLVItem->cchTextMax * 4;
568                                 pw0 = AllocateStringW(Size);
569                                 wLVItem.pszText = pw0;
570                                 wLVItem.cchTextMax = Size;
571                                 wLVItem.iImage = pmLVItem->iImage;
572                                 wLVItem.lParam = pmLVItem->lParam;
573                                 wLVItem.iIndent = pmLVItem->iIndent;
574                                 r = SendMessageW(hWnd, LVM_GETITEMTEXTW, wParam, (LPARAM)&wLVItem);
575                                 pmLVItem->mask = wLVItem.mask;
576                                 pmLVItem->iItem = wLVItem.iItem;
577                                 pmLVItem->iSubItem = wLVItem.iSubItem;
578                                 pmLVItem->state = wLVItem.state;
579                                 pmLVItem->stateMask = wLVItem.stateMask;
580                                 WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);
581                                 TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);
582                                 pmLVItem->iImage = wLVItem.iImage;
583                                 pmLVItem->lParam = wLVItem.lParam;
584                                 pmLVItem->iIndent = wLVItem.iIndent;
585                                 break;
586                         default:
587                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
588                                 break;
589                         }
590                 }
591                 else if(_wcsicmp(ClassName, STATUSCLASSNAMEW) == 0)
592                 {
593                         switch(Msg)
594                         {
595                         case SB_SETTEXTA:
596                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
597                                 r = SendMessageW(hWnd, SB_SETTEXTW, wParam, (LPARAM)pw0);
598                                 break;
599                         default:
600                                 r = SendMessageW(hWnd, Msg, wParam, lParam);
601                                 break;
602                         }
603                 }
604                 else
605                         r = SendMessageW(hWnd, Msg, wParam, lParam);
606                 break;
607         }
608 END_ROUTINE
609         FreeDuplicatedString(pw0);
610         FreeDuplicatedString(pw1);
611         return r;
612 }
613
614 LRESULT SendDlgItemMessageM(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
615 {
616         LRESULT r = 0;
617 START_ROUTINE
618         r = SendMessageM(GetDlgItem(hDlg, nIDDlgItem), Msg, wParam, lParam);
619 END_ROUTINE
620         return r;
621 }
622
623 BOOL SetWindowTextM(HWND hWnd, LPCSTR lpString)
624 {
625         BOOL r = FALSE;
626         wchar_t* pw0 = NULL;
627 START_ROUTINE
628         pw0 = DuplicateMtoW(lpString, -1);
629         r = SetWindowTextW(hWnd, pw0);
630 END_ROUTINE
631         FreeDuplicatedString(pw0);
632         return r;
633 }
634
635 UINT DragQueryFileM(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch)
636 {
637         UINT r = 0;
638         wchar_t* pw0 = NULL;
639 START_ROUTINE
640         pw0 = AllocateStringW(cch * 4);
641         DragQueryFileW(hDrop, iFile, pw0, cch * 4);
642         WtoM(lpszFile, cch, pw0, -1);
643         r = TerminateStringM(lpszFile, cch);
644 END_ROUTINE
645         FreeDuplicatedString(pw0);
646         return r;
647 }
648
649 DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)
650 {
651         DWORD r = 0;
652         wchar_t* pw0 = NULL;
653 START_ROUTINE
654         pw0 = AllocateStringW(nBufferLength * 4);
655         GetCurrentDirectoryW(nBufferLength * 4, pw0);
656         WtoM(lpBuffer, nBufferLength, pw0, -1);
657         r = TerminateStringM(lpBuffer, nBufferLength);
658 END_ROUTINE
659         FreeDuplicatedString(pw0);
660         return r;
661 }
662
663 BOOL SetCurrentDirectoryM(LPCSTR lpPathName)
664 {
665         BOOL r = FALSE;
666         wchar_t* pw0 = NULL;
667 START_ROUTINE
668         pw0 = DuplicateMtoW(lpPathName, -1);
669         r = SetCurrentDirectoryW(pw0);
670 END_ROUTINE
671         FreeDuplicatedString(pw0);
672         return r;
673 }
674
675 BOOL SetDllDirectoryM(LPCSTR lpPathName)
676 {
677         BOOL r = FALSE;
678         wchar_t* pw0 = NULL;
679 START_ROUTINE
680         pw0 = DuplicateMtoW(lpPathName, -1);
681         r = SetDllDirectoryW(pw0);
682 END_ROUTINE
683         FreeDuplicatedString(pw0);
684         return r;
685 }
686
687 DWORD GetFileAttributesM(LPCSTR lpFileName)
688 {
689         DWORD r = FALSE;
690         wchar_t* pw0 = NULL;
691 START_ROUTINE
692         pw0 = DuplicateMtoW(lpFileName, -1);
693         r = GetFileAttributesW(pw0);
694 END_ROUTINE
695         FreeDuplicatedString(pw0);
696         return r;
697 }
698
699 DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)
700 {
701         DWORD r = 0;
702         wchar_t* pw0 = NULL;
703 START_ROUTINE
704         pw0 = AllocateStringW(nSize * 4);
705         GetModuleFileNameW(hModule, pw0, nSize * 4);
706         WtoM(lpFilename, nSize, pw0, -1);
707         r = TerminateStringM(lpFilename, nSize);
708 END_ROUTINE
709         FreeDuplicatedString(pw0);
710         return r;
711 }
712
713 LSTATUS RegOpenKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
714 {
715         LSTATUS r = 0;
716         wchar_t* pw0 = NULL;
717 START_ROUTINE
718         pw0 = DuplicateMtoW(lpSubKey, -1);
719         r = RegOpenKeyExW(hKey, pw0, ulOptions, samDesired, phkResult);
720 END_ROUTINE
721         FreeDuplicatedString(pw0);
722         return r;
723 }
724
725 LSTATUS RegCreateKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
726 {
727         LSTATUS r = 0;
728         wchar_t* pw0 = NULL;
729         wchar_t* pw1 = NULL;
730 START_ROUTINE
731         pw0 = DuplicateMtoW(lpSubKey, -1);
732         pw1 = DuplicateMtoW(lpClass, -1);
733         r = RegCreateKeyExW(hKey, pw0, Reserved, pw1, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
734 END_ROUTINE
735         FreeDuplicatedString(pw0);
736         FreeDuplicatedString(pw1);
737         return r;
738 }
739
740 LSTATUS RegDeleteValueM(HKEY hKey, LPCSTR lpValueName)
741 {
742         LSTATUS r = 0;
743         wchar_t* pw0 = NULL;
744 START_ROUTINE
745         pw0 = DuplicateMtoW(lpValueName, -1);
746         r = RegDeleteValueW(hKey, pw0);
747 END_ROUTINE
748         FreeDuplicatedString(pw0);
749         return r;
750 }
751
752 LSTATUS RegQueryValueExM(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
753 {
754         LSTATUS r = 0;
755         wchar_t* pw0 = NULL;
756         wchar_t* pw1 = NULL;
757         DWORD dwType;
758         DWORD wcbData;
759 START_ROUTINE
760         pw0 = DuplicateMtoW(lpValueName, -1);
761         if(RegQueryValueExW(hKey, pw0, NULL, &dwType, NULL, 0) == ERROR_SUCCESS)
762         {
763                 switch(dwType)
764                 {
765                 case REG_SZ:
766                 case REG_EXPAND_SZ:
767                 case REG_MULTI_SZ:
768                         if(lpData && lpcbData)
769                         {
770                                 pw1 = AllocateStringW(*lpcbData / sizeof(char) * 4);
771                                 wcbData = *lpcbData / sizeof(char) * 4;
772                                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, (LPBYTE)pw1, &wcbData);
773                                 *lpcbData = sizeof(char) * WtoM((char*)lpData, *lpcbData / sizeof(char), pw1, wcbData / sizeof(wchar_t));
774                         }
775                         break;
776                 default:
777                         r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);
778                         break;
779                 }
780         }
781         else
782                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);
783 END_ROUTINE
784         FreeDuplicatedString(pw0);
785         FreeDuplicatedString(pw1);
786         return r;
787 }
788
789 LSTATUS RegSetValueExM(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData)
790 {
791         LSTATUS r = 0;
792         wchar_t* pw0 = NULL;
793         wchar_t* pw1 = NULL;
794         DWORD wcbData;
795 START_ROUTINE
796         pw0 = DuplicateMtoW(lpValueName, -1);
797         switch(dwType)
798         {
799         case REG_SZ:
800         case REG_EXPAND_SZ:
801         case REG_MULTI_SZ:
802                 wcbData = MtoW(NULL, 0, (char*)lpData, cbData / sizeof(char));
803                 pw1 = AllocateStringW(wcbData);
804                 MtoW(pw1, wcbData, (char*)lpData, cbData / sizeof(char));
805                 wcbData = sizeof(wchar_t) * wcbData;
806                 lpData = (BYTE*)pw1;
807                 cbData = wcbData;
808                 break;
809         }
810         r = RegSetValueExW(hKey, pw0, Reserved, dwType, lpData, cbData);
811 END_ROUTINE
812         FreeDuplicatedString(pw0);
813         FreeDuplicatedString(pw1);
814         return r;
815 }
816
817 BOOL TextOutM(HDC hdc, int x, int y, LPCSTR lpString, int c)
818 {
819         BOOL r = FALSE;
820         wchar_t* pw0 = NULL;
821 START_ROUTINE
822         pw0 = DuplicateMtoW(lpString, c);
823         r = TextOutW(hdc, x, y, pw0, wcslen(pw0));
824 END_ROUTINE
825         FreeDuplicatedString(pw0);
826         return r;
827 }
828
829 BOOL GetTextExtentPoint32M(HDC hdc, LPCSTR lpString, int c, LPSIZE psizl)
830 {
831         BOOL r = FALSE;
832         wchar_t* pw0 = NULL;
833 START_ROUTINE
834         pw0 = DuplicateMtoW(lpString, c);
835         r = GetTextExtentPoint32W(hdc, pw0, wcslen(pw0), psizl);
836 END_ROUTINE
837         FreeDuplicatedString(pw0);
838         return r;
839 }
840
841 INT_PTR PropertySheetM(LPCPROPSHEETHEADERA v0)
842 {
843         INT_PTR r = 0;
844         PROPSHEETHEADERW a0;
845         PROPSHEETPAGEW* pwPage;
846         UINT i;
847 START_ROUTINE
848         a0.dwSize = sizeof(PROPSHEETHEADERW);
849         a0.dwFlags = v0->dwFlags;
850         a0.hwndParent = v0->hwndParent;
851         a0.hInstance = v0->hInstance;
852         if(v0->dwFlags & PSH_USEICONID)
853                 a0.pszIcon = DuplicateMtoW(v0->pszIcon, -1);
854         else
855                 a0.hIcon = v0->hIcon;
856         a0.pszCaption = DuplicateMtoW(v0->pszCaption, -1);
857         a0.nPages = v0->nPages;
858         a0.pStartPage = DuplicateMtoW(v0->pStartPage, -1);
859         if(v0->ppsp && (pwPage = (PROPSHEETPAGEW*)malloc(sizeof(PROPSHEETPAGEW) * v0->nPages)))
860         {
861                 for(i = 0; i < v0->nPages; i++)
862                 {
863                         pwPage[i].dwSize = sizeof(PROPSHEETPAGEW);
864                         pwPage[i].dwFlags = v0->ppsp[i].dwFlags;
865                         pwPage[i].hInstance = v0->ppsp[i].hInstance;
866                         pwPage[i].pszTemplate = DuplicateMtoW(v0->ppsp[i].pszTemplate, -1);
867                         if(v0->ppsp[i].dwFlags & PSP_USEICONID)
868                                 pwPage[i].pszIcon = DuplicateMtoW(v0->ppsp[i].pszIcon, -1);
869                         else
870                                 pwPage[i].hIcon = v0->ppsp[i].hIcon;
871                         if(v0->ppsp[i].dwFlags & PSP_USETITLE)
872                                 pwPage[i].pszTitle = DuplicateMtoW(v0->ppsp[i].pszTitle, -1);
873                         pwPage[i].pfnDlgProc = v0->ppsp[i].pfnDlgProc;
874                         pwPage[i].lParam = v0->ppsp[i].lParam;
875                         // TODO: pfnCallback
876                         pwPage[i].pfnCallback = v0->ppsp[i].pfnCallback;
877                         pwPage[i].pcRefParent = v0->ppsp[i].pcRefParent;
878 //                      pwPage[i].pszHeaderTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderTitle, -1);
879 //                      pwPage[i].pszHeaderSubTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderSubTitle, -1);
880                         pwPage[i].hActCtx = v0->ppsp[i].hActCtx;
881 //                      pwPage[i].pszbmHeader = DuplicateMtoW(v0->ppsp[i].pszbmHeader, -1);
882                 }
883         }
884         else
885                 pwPage = NULL;
886         a0.ppsp = pwPage;
887         a0.pfnCallback = v0->pfnCallback;
888         r = PropertySheetW(&a0);
889         if(a0.dwFlags & PSH_USEICONID)
890                 FreeDuplicatedString(a0.pszIcon);
891         FreeDuplicatedString(a0.pszCaption);
892         FreeDuplicatedString(a0.pStartPage);
893         if(pwPage)
894         {
895                 for(i = 0; i < v0->nPages; i++)
896                 {
897                         FreeDuplicatedString(pwPage[i].pszTemplate);
898                         if(pwPage[i].dwFlags & PSP_USEICONID)
899                                 FreeDuplicatedString(pwPage[i].pszIcon);
900                         if(pwPage[i].dwFlags & PSP_USETITLE)
901                                 FreeDuplicatedString(pwPage[i].pszTitle);
902 //                      FreeDuplicatedString(pwPage[i].pszHeaderTitle);
903 //                      FreeDuplicatedString(pwPage[i].pszHeaderSubTitle);
904 //                      FreeDuplicatedString(pwPage[i].pszbmHeader);
905                 }
906                 free(pwPage);
907         }
908 END_ROUTINE
909         return r;
910 }
911
912 BOOL GetOpenFileNameM(LPOPENFILENAMEA v0)
913 {
914         BOOL r = FALSE;
915         wchar_t* pw0 = NULL;
916         wchar_t* pw1 = NULL;
917         wchar_t* pw2 = NULL;
918         wchar_t* pw3 = NULL;
919         wchar_t* pw4 = NULL;
920         wchar_t* pw5 = NULL;
921         wchar_t* pw6 = NULL;
922         wchar_t* pw7 = NULL;
923         wchar_t* pw8 = NULL;
924         wchar_t* pw9 = NULL;
925         OPENFILENAMEW wofn;
926 START_ROUTINE
927         wofn.lStructSize = sizeof(OPENFILENAMEW);
928         wofn.hwndOwner = v0->hwndOwner;
929         wofn.hInstance = v0->hInstance;
930         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);
931         wofn.lpstrFilter = pw0;
932         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);
933         wofn.lpstrCustomFilter = pw1;
934         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;
935         wofn.nFilterIndex = v0->nFilterIndex;
936         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);
937         wofn.lpstrFile = pw2;
938         wofn.nMaxFile = v0->nMaxFile * 4;
939         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);
940         wofn.lpstrFileTitle = pw3;
941         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;
942         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);
943         wofn.lpstrInitialDir = pw4;
944         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);
945         wofn.lpstrTitle = pw5;
946         wofn.Flags = v0->Flags;
947         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);
948         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);
949         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);
950         wofn.lpstrDefExt = pw6;
951         wofn.lCustData = v0->lCustData;
952         wofn.lpfnHook = v0->lpfnHook;
953         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
954         wofn.pvReserved = v0->pvReserved;
955         wofn.FlagsEx = v0->FlagsEx;
956         r = GetOpenFileNameW(&wofn);
957         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);
958         TerminateStringM(v0->lpstrFile, v0->nMaxFile);
959         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);
960         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);
961 END_ROUTINE
962         FreeDuplicatedString(pw0);
963         FreeDuplicatedString(pw1);
964         FreeDuplicatedString(pw2);
965         FreeDuplicatedString(pw3);
966         FreeDuplicatedString(pw4);
967         FreeDuplicatedString(pw5);
968         FreeDuplicatedString(pw6);
969         return r;
970 }
971
972 BOOL GetSaveFileNameM(LPOPENFILENAMEA v0)
973 {
974         BOOL r = FALSE;
975         wchar_t* pw0 = NULL;
976         wchar_t* pw1 = NULL;
977         wchar_t* pw2 = NULL;
978         wchar_t* pw3 = NULL;
979         wchar_t* pw4 = NULL;
980         wchar_t* pw5 = NULL;
981         wchar_t* pw6 = NULL;
982         wchar_t* pw7 = NULL;
983         wchar_t* pw8 = NULL;
984         wchar_t* pw9 = NULL;
985         OPENFILENAMEW wofn;
986 START_ROUTINE
987         wofn.lStructSize = sizeof(OPENFILENAMEW);
988         wofn.hwndOwner = v0->hwndOwner;
989         wofn.hInstance = v0->hInstance;
990         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);
991         wofn.lpstrFilter = pw0;
992         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);
993         wofn.lpstrCustomFilter = pw1;
994         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;
995         wofn.nFilterIndex = v0->nFilterIndex;
996         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);
997         wofn.lpstrFile = pw2;
998         wofn.nMaxFile = v0->nMaxFile * 4;
999         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);
1000         wofn.lpstrFileTitle = pw3;
1001         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;
1002         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);
1003         wofn.lpstrInitialDir = pw4;
1004         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);
1005         wofn.lpstrTitle = pw5;
1006         wofn.Flags = v0->Flags;
1007         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);
1008         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);
1009         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);
1010         wofn.lpstrDefExt = pw6;
1011         wofn.lCustData = v0->lCustData;
1012         wofn.lpfnHook = v0->lpfnHook;
1013         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
1014         wofn.pvReserved = v0->pvReserved;
1015         wofn.FlagsEx = v0->FlagsEx;
1016         r = GetSaveFileNameW(&wofn);
1017         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);
1018         TerminateStringM(v0->lpstrFile, v0->nMaxFile);
1019         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);
1020         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);
1021 END_ROUTINE
1022         FreeDuplicatedString(pw0);
1023         FreeDuplicatedString(pw1);
1024         FreeDuplicatedString(pw2);
1025         FreeDuplicatedString(pw3);
1026         FreeDuplicatedString(pw4);
1027         FreeDuplicatedString(pw5);
1028         FreeDuplicatedString(pw6);
1029         return r;
1030 }
1031
1032 HWND HtmlHelpM(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData)
1033 {
1034         HWND r = NULL;
1035         wchar_t* pw0 = NULL;
1036 START_ROUTINE
1037         pw0 = DuplicateMtoW(pszFile, -1);
1038         r = HtmlHelpW(hwndCaller, pw0, uCommand, dwData);
1039 END_ROUTINE
1040         FreeDuplicatedString(pw0);
1041         return r;
1042 }
1043
1044 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)
1045 {
1046         BOOL r = FALSE;
1047         wchar_t* pw0 = NULL;
1048         wchar_t* pw1 = NULL;
1049         wchar_t* pw2 = NULL;
1050         wchar_t* pw3 = NULL;
1051         wchar_t* pw4 = NULL;
1052         wchar_t* pw5 = NULL;
1053         STARTUPINFOW wStartupInfo;
1054 START_ROUTINE
1055         pw0 = DuplicateMtoW(lpApplicationName, -1);
1056         pw1 = DuplicateMtoWBuffer(lpCommandLine, -1, (strlen(lpCommandLine) + 1) * 4);
1057         pw2 = DuplicateMtoW(lpCurrentDirectory, -1);
1058         wStartupInfo.cb = sizeof(LPSTARTUPINFOW);
1059         pw3 = DuplicateMtoW(lpStartupInfo->lpReserved, -1);
1060         wStartupInfo.lpReserved = pw3;
1061         pw4 = DuplicateMtoW(lpStartupInfo->lpDesktop, -1);
1062         wStartupInfo.lpDesktop = pw4;
1063         pw5 = DuplicateMtoW(lpStartupInfo->lpTitle, -1);
1064         wStartupInfo.lpTitle = pw5;
1065         wStartupInfo.dwX = lpStartupInfo->dwX;
1066         wStartupInfo.dwY = lpStartupInfo->dwY;
1067         wStartupInfo.dwXSize = lpStartupInfo->dwXSize;
1068         wStartupInfo.dwYSize = lpStartupInfo->dwYSize;
1069         wStartupInfo.dwXCountChars = lpStartupInfo->dwXCountChars;
1070         wStartupInfo.dwYCountChars = lpStartupInfo->dwYCountChars;
1071         wStartupInfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
1072         wStartupInfo.dwFlags = lpStartupInfo->dwFlags;
1073         wStartupInfo.wShowWindow = lpStartupInfo->wShowWindow;
1074         wStartupInfo.cbReserved2 = lpStartupInfo->cbReserved2;
1075         wStartupInfo.lpReserved2 = lpStartupInfo->lpReserved2;
1076         wStartupInfo.hStdInput = lpStartupInfo->hStdInput;
1077         wStartupInfo.hStdOutput = lpStartupInfo->hStdOutput;
1078         wStartupInfo.hStdError = lpStartupInfo->hStdError;
1079         r = CreateProcessW(pw0, pw1, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pw2, &wStartupInfo, lpProcessInformation);
1080         WtoM(lpCommandLine, strlen(lpCommandLine) + 1, pw1, -1);
1081 END_ROUTINE
1082         FreeDuplicatedString(pw0);
1083         FreeDuplicatedString(pw1);
1084         FreeDuplicatedString(pw2);
1085         FreeDuplicatedString(pw3);
1086         FreeDuplicatedString(pw4);
1087         FreeDuplicatedString(pw5);
1088         return r;
1089 }
1090
1091 HINSTANCE FindExecutableM(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
1092 {
1093         HINSTANCE r = NULL;
1094         wchar_t* pw0 = NULL;
1095         wchar_t* pw1 = NULL;
1096         wchar_t* pw2 = NULL;
1097         wchar_t* pw3 = NULL;
1098 START_ROUTINE
1099         pw0 = DuplicateMtoW(lpFile, -1);
1100         pw1 = DuplicateMtoW(lpDirectory, -1);
1101         pw2 = AllocateStringW(MAX_PATH * 4);
1102         r = FindExecutableW(pw0, pw1, pw2);
1103         // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
1104         WtoM(lpResult, MAX_PATH, pw2, -1);
1105         TerminateStringM(lpResult, MAX_PATH);
1106 END_ROUTINE
1107         FreeDuplicatedString(pw0);
1108         FreeDuplicatedString(pw1);
1109         FreeDuplicatedString(pw2);
1110         FreeDuplicatedString(pw3);
1111         return r;
1112 }
1113
1114 HINSTANCE ShellExecuteM(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)
1115 {
1116         HINSTANCE r = NULL;
1117         wchar_t* pw0 = NULL;
1118         wchar_t* pw1 = NULL;
1119         wchar_t* pw2 = NULL;
1120         wchar_t* pw3 = NULL;
1121 START_ROUTINE
1122         pw0 = DuplicateMtoW(lpOperation, -1);
1123         pw1 = DuplicateMtoW(lpFile, -1);
1124         pw2 = DuplicateMtoW(lpParameters, -1);
1125         pw3 = DuplicateMtoW(lpDirectory, -1);
1126         r = ShellExecuteW(hwnd, pw0, pw1, pw2, pw3, nShowCmd);
1127 END_ROUTINE
1128         FreeDuplicatedString(pw0);
1129         FreeDuplicatedString(pw1);
1130         FreeDuplicatedString(pw2);
1131         FreeDuplicatedString(pw3);
1132         return r;
1133 }
1134
1135 PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)
1136 {
1137         PIDLIST_ABSOLUTE r = NULL;
1138         wchar_t* pw0 = NULL;
1139         wchar_t* pw1 = NULL;
1140         BROWSEINFOW wbi;
1141 START_ROUTINE
1142         wbi.hwndOwner = lpbi->hwndOwner;
1143         wbi.pidlRoot = lpbi->pidlRoot;
1144         pw0 = DuplicateMtoWBuffer(lpbi->pszDisplayName, -1, MAX_PATH * 4);
1145         wbi.pszDisplayName = pw0;
1146         pw1 = DuplicateMtoW(lpbi->lpszTitle, -1);
1147         wbi.lpszTitle = pw1;
1148         wbi.ulFlags = lpbi->ulFlags;
1149         // TODO: lpfn
1150         wbi.lpfn = lpbi->lpfn;
1151         wbi.lParam = lpbi->lParam;
1152         wbi.iImage = lpbi->iImage;
1153         r = SHBrowseForFolderW(&wbi);
1154         // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
1155         WtoM(lpbi->pszDisplayName, MAX_PATH, wbi.pszDisplayName, -1);
1156         lpbi->iImage = wbi.iImage;
1157 END_ROUTINE
1158         FreeDuplicatedString(pw0);
1159         FreeDuplicatedString(pw1);
1160         return r;
1161 }
1162
1163 BOOL SHGetPathFromIDListM(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath)
1164 {
1165         BOOL r = FALSE;
1166         wchar_t* pw0 = NULL;
1167 START_ROUTINE
1168         pw0 = AllocateStringW(MAX_PATH * 4);
1169         r = SHGetPathFromIDListW(pidl, pw0);
1170         // \83o\83b\83t\83@\92·\95s\96¾\82Ì\82½\82ß\83I\81[\83o\81[\83\89\83\93\82Ì\89Â\94\\90«\82 \82è
1171         WtoM(pszPath, MAX_PATH, pw0, -1);
1172         TerminateStringM(pszPath, MAX_PATH);
1173 END_ROUTINE
1174         FreeDuplicatedString(pw0);
1175         return r;
1176 }
1177
1178 int SHFileOperationM(LPSHFILEOPSTRUCTA lpFileOp)
1179 {
1180         int r = 0;
1181         wchar_t* pw0 = NULL;
1182         wchar_t* pw1 = NULL;
1183         wchar_t* pw2 = NULL;
1184         SHFILEOPSTRUCTW wFileOp;
1185 START_ROUTINE
1186         wFileOp.hwnd = lpFileOp->hwnd;
1187         wFileOp.wFunc = lpFileOp->wFunc;
1188         pw0 = DuplicateMtoWMultiString(lpFileOp->pFrom);
1189         wFileOp.pFrom = pw0;
1190         pw1 = DuplicateMtoWMultiString(lpFileOp->pTo);
1191         wFileOp.pTo = pw1;
1192         wFileOp.fFlags = lpFileOp->fFlags;
1193         wFileOp.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;
1194         wFileOp.hNameMappings = lpFileOp->hNameMappings;
1195         pw2 = DuplicateMtoW(lpFileOp->lpszProgressTitle, -1);
1196         r = SHFileOperationW(&wFileOp);
1197         lpFileOp->fAnyOperationsAborted = wFileOp.fAnyOperationsAborted;
1198 END_ROUTINE
1199         FreeDuplicatedString(pw0);
1200         FreeDuplicatedString(pw1);
1201         FreeDuplicatedString(pw2);
1202         return r;
1203 }
1204
1205 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)
1206 {
1207         int r = 0;
1208         wchar_t* pw0 = NULL;
1209 START_ROUTINE
1210         if(uFlags & (MF_BITMAP | MF_OWNERDRAW))
1211                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, (LPCWSTR)lpNewItem);
1212         else
1213         {
1214                 pw0 = DuplicateMtoW(lpNewItem, -1);
1215                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, pw0);
1216         }
1217 END_ROUTINE
1218         FreeDuplicatedString(pw0);
1219         return r;
1220 }
1221
1222 BOOL GetMenuItemInfoM(HMENU hmenu, UINT item, BOOL fByPosition, LPMENUITEMINFOA lpmii)
1223 {
1224         BOOL r = FALSE;
1225         wchar_t* pw0 = NULL;
1226         MENUITEMINFOW wmii;
1227 START_ROUTINE
1228         wmii.cbSize = sizeof(MENUITEMINFOW);
1229         wmii.fMask = lpmii->fMask;
1230         wmii.fType = lpmii->fType;
1231         wmii.fState = lpmii->fState;
1232         wmii.wID = lpmii->wID;
1233         wmii.hSubMenu = lpmii->hSubMenu;
1234         wmii.hbmpChecked = lpmii->hbmpChecked;
1235         wmii.hbmpUnchecked = lpmii->hbmpUnchecked;
1236         wmii.dwItemData = lpmii->dwItemData;
1237         pw0 = DuplicateMtoWBuffer(lpmii->dwTypeData, -1, lpmii->cch * 4);
1238         wmii.dwTypeData = pw0;
1239         wmii.cch = lpmii->cch * 4;
1240         r = GetMenuItemInfoW(hmenu, item, fByPosition, &wmii);
1241         lpmii->fType = wmii.fType;
1242         lpmii->fState = wmii.fState;
1243         lpmii->wID = wmii.wID;
1244         lpmii->hSubMenu = wmii.hSubMenu;
1245         lpmii->hbmpChecked = wmii.hbmpChecked;
1246         lpmii->hbmpUnchecked = wmii.hbmpUnchecked;
1247         lpmii->dwItemData = wmii.dwItemData;
1248         WtoM(lpmii->dwTypeData, lpmii->cch, wmii.dwTypeData, -1);
1249         TerminateStringM(lpmii->dwTypeData, lpmii->cch);
1250 END_ROUTINE
1251         FreeDuplicatedString(pw0);
1252         return r;
1253 }
1254
1255 HFONT CreateFontIndirectM(CONST LOGFONTA *lplf)
1256 {
1257         HFONT r = NULL;
1258         LOGFONTW wlf;
1259 START_ROUTINE
1260         wlf.lfHeight = lplf->lfHeight;
1261         wlf.lfWidth = lplf->lfWidth;
1262         wlf.lfEscapement = lplf->lfEscapement;
1263         wlf.lfOrientation = lplf->lfOrientation;
1264         wlf.lfWeight = lplf->lfWeight;
1265         wlf.lfItalic = lplf->lfItalic;
1266         wlf.lfUnderline = lplf->lfUnderline;
1267         wlf.lfStrikeOut = lplf->lfStrikeOut;
1268         wlf.lfCharSet = lplf->lfCharSet;
1269         wlf.lfOutPrecision = lplf->lfOutPrecision;
1270         wlf.lfClipPrecision = lplf->lfClipPrecision;
1271         wlf.lfQuality = lplf->lfQuality;
1272         wlf.lfPitchAndFamily = lplf->lfPitchAndFamily;
1273         MtoW(wlf.lfFaceName, LF_FACESIZE, lplf->lfFaceName, -1);
1274         TerminateStringW(wlf.lfFaceName, LF_FACESIZE);
1275         r = CreateFontIndirect(&wlf);
1276 END_ROUTINE
1277         return r;
1278 }
1279
1280 BOOL ChooseFontM(LPCHOOSEFONTA v0)
1281 {
1282         BOOL r = FALSE;
1283         wchar_t* pw0 = NULL;
1284         CHOOSEFONTW a0;
1285         LOGFONTW* pwlf;
1286 START_ROUTINE
1287         a0.lStructSize = sizeof(CHOOSEFONTW);
1288         a0.hwndOwner = v0->hwndOwner;
1289         a0.hDC = v0->hDC;
1290         if(v0->lpLogFont && (pwlf = (LOGFONTW*)malloc(sizeof(LOGFONTW))))
1291         {
1292                 pwlf->lfHeight = v0->lpLogFont->lfHeight;
1293                 pwlf->lfWidth = v0->lpLogFont->lfWidth;
1294                 pwlf->lfEscapement = v0->lpLogFont->lfEscapement;
1295                 pwlf->lfOrientation = v0->lpLogFont->lfOrientation;
1296                 pwlf->lfWeight = v0->lpLogFont->lfWeight;
1297                 pwlf->lfItalic = v0->lpLogFont->lfItalic;
1298                 pwlf->lfUnderline = v0->lpLogFont->lfUnderline;
1299                 pwlf->lfStrikeOut = v0->lpLogFont->lfStrikeOut;
1300                 pwlf->lfCharSet = v0->lpLogFont->lfCharSet;
1301                 pwlf->lfOutPrecision = v0->lpLogFont->lfOutPrecision;
1302                 pwlf->lfClipPrecision = v0->lpLogFont->lfClipPrecision;
1303                 pwlf->lfQuality = v0->lpLogFont->lfQuality;
1304                 pwlf->lfPitchAndFamily = v0->lpLogFont->lfPitchAndFamily;
1305                 MtoW(pwlf->lfFaceName, LF_FACESIZE, v0->lpLogFont->lfFaceName, -1);
1306                 TerminateStringW(pwlf->lfFaceName, LF_FACESIZE);
1307         }
1308         else
1309                 pwlf = NULL;
1310         a0.lpLogFont = pwlf;
1311         a0.iPointSize = v0->iPointSize;
1312         a0.Flags = v0->Flags;
1313         a0.rgbColors = v0->rgbColors;
1314         a0.lCustData = v0->lCustData;
1315         a0.lpfnHook = v0->lpfnHook;
1316         a0.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
1317         a0.hInstance = v0->hInstance;
1318         a0.lpszStyle = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);
1319         a0.nFontType = v0->nFontType;
1320         a0.nSizeMin = v0->nSizeMin;
1321         a0.nSizeMax = v0->nSizeMax;
1322         r = ChooseFontW(&a0);
1323         if(v0->lpLogFont)
1324         {
1325                 v0->lpLogFont->lfHeight = pwlf->lfHeight;
1326                 v0->lpLogFont->lfWidth = pwlf->lfWidth;
1327                 v0->lpLogFont->lfEscapement = pwlf->lfEscapement;
1328                 v0->lpLogFont->lfOrientation = pwlf->lfOrientation;
1329                 v0->lpLogFont->lfWeight = pwlf->lfWeight;
1330                 v0->lpLogFont->lfItalic = pwlf->lfItalic;
1331                 v0->lpLogFont->lfUnderline = pwlf->lfUnderline;
1332                 v0->lpLogFont->lfStrikeOut = pwlf->lfStrikeOut;
1333                 v0->lpLogFont->lfCharSet = pwlf->lfCharSet;
1334                 v0->lpLogFont->lfOutPrecision = pwlf->lfOutPrecision;
1335                 v0->lpLogFont->lfClipPrecision = pwlf->lfClipPrecision;
1336                 v0->lpLogFont->lfQuality = pwlf->lfQuality;
1337                 v0->lpLogFont->lfPitchAndFamily = pwlf->lfPitchAndFamily;
1338                 WtoM(v0->lpLogFont->lfFaceName, LF_FACESIZE, pwlf->lfFaceName, -1);
1339                 TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);
1340         }
1341         v0->rgbColors = a0.rgbColors;
1342         WtoM(v0->lpszStyle, LF_FACESIZE, a0.lpszStyle, -1);
1343         TerminateStringM(v0->lpszStyle, LF_FACESIZE);
1344         v0->nFontType = a0.nFontType;
1345         if(pwlf)
1346                 free(pwlf);
1347         FreeDuplicatedString(a0.lpTemplateName);
1348         FreeDuplicatedString(a0.lpszStyle);
1349 END_ROUTINE
1350         FreeDuplicatedString(pw0);
1351         return r;
1352 }
1353
1354 INT_PTR DialogBoxParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
1355 {
1356         INT_PTR r = 0;
1357         wchar_t* pw0 = NULL;
1358 START_ROUTINE
1359         pw0 = DuplicateMtoW(lpTemplateName, -1);
1360         r = DialogBoxParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);
1361 END_ROUTINE
1362         FreeDuplicatedString(pw0);
1363         return r;
1364 }
1365