OSDN Git Service

Add test code for SFTP (still useless).
[ffftp/ffftp.git] / putty / mbswrapper.c
1 // mbswrapper.c\r
2 // Copyright (C) 2011 Suguru Kawamoto\r
3 // マルチバイト文字ワイド文字APIラッパー\r
4 // マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする\r
5 // 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要\r
6 \r
7 #define UNICODE\r
8 #define _UNICODE\r
9 \r
10 #include <stdio.h>\r
11 #include <tchar.h>\r
12 #include <direct.h>\r
13 #include <windows.h>\r
14 #include <commctrl.h>\r
15 #include <shlobj.h>\r
16 #include <htmlhelp.h>\r
17 \r
18 #define DO_NOT_REPLACE\r
19 #include "mbswrapper.h"\r
20 \r
21 // マルチバイト文字列からワイド文字列へ変換\r
22 int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
23 {\r
24         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
25                 return 0;\r
26         if(pDst)\r
27                 return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);\r
28         return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);\r
29 }\r
30 \r
31 // ワイド文字列からマルチバイト文字列へ変換\r
32 int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
33 {\r
34         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
35                 return 0;\r
36         if(pDst)\r
37                 return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);\r
38         return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);\r
39 }\r
40 \r
41 // Shift_JIS文字列からワイド文字列へ変換\r
42 int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
43 {\r
44         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
45                 return 0;\r
46         if(pDst)\r
47                 return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);\r
48         return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);\r
49 }\r
50 \r
51 // ワイド文字列からShift_JIS文字列へ変換\r
52 int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
53 {\r
54         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
55                 return 0;\r
56         if(pDst)\r
57                 return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);\r
58         return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);\r
59 }\r
60 \r
61 // マルチバイト文字列バッファ終端を強制的にNULLで置換\r
62 int TerminateStringM(LPSTR lpString, int size)\r
63 {\r
64         int i;\r
65         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
66                 return 0;\r
67         for(i = 0; i < size; i++)\r
68         {\r
69                 if(lpString[i] == '\0')\r
70                         return i;\r
71         }\r
72         i--;\r
73         lpString[i] = '\0';\r
74         return i;\r
75 }\r
76 \r
77 // ワイド文字列バッファ終端を強制的にNULLで置換\r
78 int TerminateStringW(LPWSTR lpString, int size)\r
79 {\r
80         int i;\r
81         if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)\r
82                 return 0;\r
83         for(i = 0; i < size; i++)\r
84         {\r
85                 if(lpString[i] == L'\0')\r
86                         return i;\r
87         }\r
88         i--;\r
89         lpString[i] = L'\0';\r
90         return i;\r
91 }\r
92 \r
93 // Shift_JIS文字列バッファ終端を強制的にNULLで置換\r
94 int TerminateStringA(LPSTR lpString, int size)\r
95 {\r
96         int i;\r
97         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
98                 return 0;\r
99         for(i = 0; i < size; i++)\r
100         {\r
101                 if(lpString[i] == '\0')\r
102                         return i;\r
103         }\r
104         i--;\r
105         lpString[i] = '\0';\r
106         return i;\r
107 }\r
108 \r
109 // NULL区切り複数マルチバイト文字列の長さを取得\r
110 size_t GetMultiStringLengthM(LPCSTR lpString)\r
111 {\r
112         size_t i;\r
113         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
114                 return 0;\r
115         i = 0;\r
116         while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
117         {\r
118                 i++;\r
119         }\r
120         i++;\r
121         return i;\r
122 }\r
123 \r
124 // NULL区切り複数ワイド文字列の長さを取得\r
125 size_t GetMultiStringLengthW(LPCWSTR lpString)\r
126 {\r
127         size_t i;\r
128         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
129                 return 0;\r
130         i = 0;\r
131         while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')\r
132         {\r
133                 i++;\r
134         }\r
135         i++;\r
136         return i;\r
137 }\r
138 \r
139 // NULL区切り複数Shift_JIS文字列の長さを取得\r
140 size_t GetMultiStringLengthA(LPCSTR lpString)\r
141 {\r
142         size_t i;\r
143         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
144                 return 0;\r
145         i = 0;\r
146         while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
147         {\r
148                 i++;\r
149         }\r
150         i++;\r
151         return i;\r
152 }\r
153 \r
154 // NULL区切りマルチバイト文字列からワイド文字列へ変換\r
155 int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
156 {\r
157         int i;\r
158         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
159                 return 0;\r
160         if(!pDst)\r
161                 return GetMultiStringLengthM(pSrc);\r
162         i = 0;\r
163         while(*pSrc != '\0')\r
164         {\r
165                 i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);\r
166                 pSrc += strlen(pSrc) + 1;\r
167         }\r
168         pDst[i] = L'\0';\r
169         return i;\r
170 }\r
171 \r
172 // NULL区切りワイド文字列からマルチバイト文字列へ変換\r
173 int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
174 {\r
175         int i;\r
176         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
177                 return 0;\r
178         if(!pDst)\r
179                 return GetMultiStringLengthW(pSrc);\r
180         i = 0;\r
181         while(*pSrc != L'\0')\r
182         {\r
183                 i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
184                 pSrc += wcslen(pSrc) + 1;\r
185         }\r
186         pDst[i] = '\0';\r
187         return i;\r
188 }\r
189 \r
190 // NULL区切りShift_JIS文字列からワイド文字列へ変換\r
191 int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
192 {\r
193         int i;\r
194         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
195                 return 0;\r
196         if(!pDst)\r
197                 return GetMultiStringLengthA(pSrc);\r
198         i = 0;\r
199         while(*pSrc != '\0')\r
200         {\r
201                 i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);\r
202                 pSrc += strlen(pSrc) + 1;\r
203         }\r
204         pDst[i] = L'\0';\r
205         return i;\r
206 }\r
207 \r
208 // NULL区切りワイド文字列からShift_JIS文字列へ変換\r
209 int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
210 {\r
211         int i;\r
212         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
213                 return 0;\r
214         if(!pDst)\r
215                 return GetMultiStringLengthW(pSrc);\r
216         i = 0;\r
217         while(*pSrc != L'\0')\r
218         {\r
219                 i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
220                 pSrc += wcslen(pSrc) + 1;\r
221         }\r
222         pDst[i] = '\0';\r
223         return i;\r
224 }\r
225 \r
226 // マルチバイト文字列用のメモリを確保\r
227 char* AllocateStringM(int size)\r
228 {\r
229         char* p;\r
230         // 0が指定される場合があるため1文字分追加\r
231         p = (char*)malloc(sizeof(char) * (size + 1));\r
232         // 念のため先頭にNULL文字を代入\r
233         if(p)\r
234                 *p = '\0';\r
235         return p;\r
236 }\r
237 \r
238 // ワイド文字列用のメモリを確保\r
239 wchar_t* AllocateStringW(int size)\r
240 {\r
241         wchar_t* p;\r
242         // 0が指定される場合があるため1文字分追加\r
243         p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));\r
244         // 念のため先頭にNULL文字を代入\r
245         if(p)\r
246                 *p = L'\0';\r
247         return p;\r
248 }\r
249 \r
250 // Shift_JIS文字列用のメモリを確保\r
251 char* AllocateStringA(int size)\r
252 {\r
253         char* p;\r
254         // 0が指定される場合があるため1文字分追加\r
255         p = (char*)malloc(sizeof(char) * (size + 1));\r
256         // 念のため先頭にNULL文字を代入\r
257         if(p)\r
258                 *p = '\0';\r
259         return p;\r
260 }\r
261 \r
262 // メモリを確保してマルチバイト文字列からワイド文字列へ変換\r
263 // リソースIDならば元の値を返す\r
264 wchar_t* DuplicateMtoW(LPCSTR lpString, int c)\r
265 {\r
266         wchar_t* p;\r
267         int i;\r
268         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
269                 return (wchar_t*)lpString;\r
270         if(c < 0)\r
271                 c = strlen(lpString);\r
272         p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);\r
273         if(p)\r
274         {\r
275                 i = MtoW(p, 65535, lpString, c);\r
276                 p[i] = L'\0';\r
277         }\r
278         return p;\r
279 }\r
280 \r
281 // 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換\r
282 // リソースIDならば元の値を返す\r
283 wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)\r
284 {\r
285         wchar_t* p;\r
286         int i;\r
287         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
288                 return (wchar_t*)lpString;\r
289         if(c < 0)\r
290                 c = strlen(lpString);\r
291         p = AllocateStringW(size);\r
292         if(p)\r
293         {\r
294                 i = MtoW(p, size, lpString, c);\r
295                 p[i] = L'\0';\r
296         }\r
297         return p;\r
298 }\r
299 \r
300 // メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
301 // リソースIDならば元の値を返す\r
302 wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)\r
303 {\r
304         int count;\r
305         wchar_t* p;\r
306         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
307                 return (wchar_t*)lpString;\r
308         count = GetMultiStringLengthM(lpString) + 1;\r
309         p = AllocateStringW(count);\r
310         if(p)\r
311                 MtoW(p, count, lpString, count);\r
312         return p;\r
313 }\r
314 \r
315 // 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
316 // リソースIDならば元の値を返す\r
317 wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)\r
318 {\r
319         int count;\r
320         wchar_t* p;\r
321         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
322                 return (wchar_t*)lpString;\r
323         count = GetMultiStringLengthM(lpString) + 1;\r
324         p = AllocateStringW(size);\r
325         if(p)\r
326         {\r
327                 MtoW(p, size, lpString, count);\r
328                 p[size - 2] = L'\0';\r
329                 p[size - 1] = L'\0';\r
330         }\r
331         return p;\r
332 }\r
333 \r
334 // メモリを確保してワイド文字列からマルチバイト文字列へ変換\r
335 // リソースIDならば元の値を返す\r
336 char* DuplicateWtoM(LPCWSTR lpString, int c)\r
337 {\r
338         char* p;\r
339         int i;\r
340         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
341                 return (char*)lpString;\r
342         if(c < 0)\r
343                 c = wcslen(lpString);\r
344         p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);\r
345         if(p)\r
346         {\r
347                 i = WtoM(p, 65535, lpString, c);\r
348                 p[i] = L'\0';\r
349         }\r
350         return p;\r
351 }\r
352 \r
353 // メモリを確保してShift_JIS文字列からワイド文字列へ変換\r
354 // リソースIDならば元の値を返す\r
355 wchar_t* DuplicateAtoW(LPCSTR lpString, int c)\r
356 {\r
357         wchar_t* p;\r
358         int i;\r
359         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
360                 return (wchar_t*)lpString;\r
361         if(c < 0)\r
362                 c = strlen(lpString);\r
363         p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);\r
364         if(p)\r
365         {\r
366                 i = AtoW(p, 65535, lpString, c);\r
367                 p[i] = L'\0';\r
368         }\r
369         return p;\r
370 }\r
371 \r
372 // メモリを確保してワイド文字列からShift_JIS文字列へ変換\r
373 // リソースIDならば元の値を返す\r
374 char* DuplicateWtoA(LPCWSTR lpString, int c)\r
375 {\r
376         char* p;\r
377         int i;\r
378         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
379                 return (char*)lpString;\r
380         if(c < 0)\r
381                 c = wcslen(lpString);\r
382         p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);\r
383         if(p)\r
384         {\r
385                 i = WtoA(p, 65535, lpString, c);\r
386                 p[i] = L'\0';\r
387         }\r
388         return p;\r
389 }\r
390 \r
391 // マルチバイト文字列からコードポイントと次のポインタを取得\r
392 // エンコードが不正な場合は0x80000000を返す\r
393 DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
394 {\r
395         DWORD Code;\r
396         int i;\r
397         Code = 0;\r
398         if((*lpString & 0xfe) == 0xfc)\r
399         {\r
400                 i = 5;\r
401                 Code |= (DWORD)*lpString & 0x01;\r
402         }\r
403         else if((*lpString & 0xfc) == 0xf8)\r
404         {\r
405                 i = 4;\r
406                 Code |= (DWORD)*lpString & 0x03;\r
407         }\r
408         else if((*lpString & 0xf8) == 0xf0)\r
409         {\r
410                 i = 3;\r
411                 Code |= (DWORD)*lpString & 0x07;\r
412         }\r
413         else if((*lpString & 0xf0) == 0xe0)\r
414         {\r
415                 i = 2;\r
416                 Code |= (DWORD)*lpString & 0x0f;\r
417         }\r
418         else if((*lpString & 0xe0) == 0xc0)\r
419         {\r
420                 i = 1;\r
421                 Code |= (DWORD)*lpString & 0x1f;\r
422         }\r
423         else if((*lpString & 0x80) == 0x00)\r
424         {\r
425                 i = 0;\r
426                 Code |= (DWORD)*lpString & 0x7f;\r
427         }\r
428         else\r
429                 i = -1;\r
430         lpString++;\r
431         while((*lpString & 0xc0) == 0x80)\r
432         {\r
433                 i--;\r
434                 Code = Code << 6;\r
435                 Code |= (DWORD)*lpString & 0x3f;\r
436                 lpString++;\r
437         }\r
438         if(i != 0)\r
439                 Code = 0x80000000;\r
440         if(ppNext)\r
441                 *ppNext = lpString;\r
442         return Code;\r
443 }\r
444 \r
445 // マルチバイト文字列の冗長表現を修正\r
446 // 修正があればTRUEを返す\r
447 // 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
448 BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)\r
449 {\r
450         BOOL bResult;\r
451         char* p;\r
452         DWORD Code;\r
453         int i;\r
454         char c;\r
455         bResult = FALSE;\r
456         p = (char*)pSrc;\r
457         while(*pSrc != '\0')\r
458         {\r
459                 Code = GetNextCharM(pSrc, &pSrc);\r
460                 if(Code & 0x80000000)\r
461                         continue;\r
462                 else if(Code & 0x7c000000)\r
463                 {\r
464                         i = 5;\r
465                         c = (char)(0xfc | (Code >> (6 * i)));\r
466                 }\r
467                 else if(Code & 0x03e00000)\r
468                 {\r
469                         i = 4;\r
470                         c = (char)(0xf8 | (Code >> (6 * i)));\r
471                 }\r
472                 else if(Code & 0x001f0000)\r
473                 {\r
474                         i = 3;\r
475                         c = (char)(0xf0 | (Code >> (6 * i)));\r
476                 }\r
477                 else if(Code & 0x0000f800)\r
478                 {\r
479                         i = 2;\r
480                         c = (char)(0xe0 | (Code >> (6 * i)));\r
481                 }\r
482                 else if(Code & 0x00000780)\r
483                 {\r
484                         i = 1;\r
485                         c = (char)(0xc0 | (Code >> (6 * i)));\r
486                 }\r
487                 else\r
488                 {\r
489                         i = 0;\r
490                         c = (char)Code;\r
491                 }\r
492                 if(c != *p)\r
493                         bResult = TRUE;\r
494                 p++;\r
495                 *pDst = c;\r
496                 pDst++;\r
497                 while(i > 0)\r
498                 {\r
499                         i--;\r
500                         c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f));\r
501                         if(c != *p)\r
502                                 bResult = TRUE;\r
503                         p++;\r
504                         *pDst = c;\r
505                         pDst++;\r
506                 }\r
507         }\r
508         if(*p != '\0')\r
509                 bResult = TRUE;\r
510         *pDst = '\0';\r
511         return bResult;\r
512 }\r
513 \r
514 // NULL区切りマルチバイト文字列の冗長表現を修正\r
515 // 修正があればTRUEを返す\r
516 // 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
517 BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc)\r
518 {\r
519         BOOL bResult;\r
520         int Length;\r
521         bResult = FALSE;\r
522         while(*pSrc != '\0')\r
523         {\r
524                 Length = strlen(pSrc) + 1;\r
525                 bResult = bResult | FixStringM(pDst, pSrc);\r
526                 pSrc += Length;\r
527                 pDst += strlen(pDst) + 1;\r
528         }\r
529         *pDst = '\0';\r
530         return bResult;\r
531 }\r
532 \r
533 // マルチバイト文字列の冗長表現を確認\r
534 // 冗長表現があればTRUEを返す\r
535 BOOL CheckStringM(LPCSTR lpString)\r
536 {\r
537         BOOL bResult;\r
538         char* p;\r
539         bResult = FALSE;\r
540         p = AllocateStringM(strlen(lpString) + 1);\r
541         if(p)\r
542         {\r
543                 bResult = FixStringM(p, lpString);\r
544                 FreeDuplicatedString(p);\r
545         }\r
546         return bResult;\r
547 }\r
548 \r
549 // NULL区切りマルチバイト文字列の冗長表現を確認\r
550 // 冗長表現があればTRUEを返す\r
551 BOOL CheckMultiStringM(LPCSTR lpString)\r
552 {\r
553         BOOL bResult;\r
554         char* p;\r
555         bResult = FALSE;\r
556         p = AllocateStringM(GetMultiStringLengthM(lpString) + 1);\r
557         if(p)\r
558         {\r
559                 bResult = FixMultiStringM(p, lpString);\r
560                 FreeDuplicatedString(p);\r
561         }\r
562         return bResult;\r
563 }\r
564 \r
565 // 文字列用に確保したメモリを開放\r
566 // リソースIDならば何もしない\r
567 void FreeDuplicatedString(void* p)\r
568 {\r
569         if(p < (void*)0x00010000 || p == (void*)~0)\r
570                 return;\r
571         free(p);\r
572 }\r
573 \r
574 // 以下ラッパー\r
575 // 戻り値バッファ r\r
576 // ワイド文字バッファ pw%d\r
577 // マルチバイト文字バッファ pm%d\r
578 // 引数バッファ a%d\r
579 \r
580 #pragma warning(disable:4102)\r
581 #define START_ROUTINE                                   do{\r
582 #define END_ROUTINE                                             }while(0);end_of_routine:\r
583 #define QUIT_ROUTINE                                    goto end_of_routine;\r
584 \r
585 HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)\r
586 {\r
587         HANDLE r = INVALID_HANDLE_VALUE;\r
588         wchar_t* pw0 = NULL;\r
589 START_ROUTINE\r
590         pw0 = DuplicateMtoW(lpFileName, -1);\r
591         r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);\r
592 END_ROUTINE\r
593         FreeDuplicatedString(pw0);\r
594         return r;\r
595 }\r
596 \r
597 HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)\r
598 {\r
599         HANDLE r = INVALID_HANDLE_VALUE;\r
600         wchar_t* pw0 = NULL;\r
601         WIN32_FIND_DATAW a0;\r
602 START_ROUTINE\r
603         pw0 = DuplicateMtoW(lpFileName, -1);\r
604         r = FindFirstFileW(pw0, &a0);\r
605         if(r != INVALID_HANDLE_VALUE)\r
606         {\r
607                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
608                 lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
609                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
610                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
611                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
612                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
613                 lpFindFileData->dwReserved0 = a0.dwReserved0;\r
614                 lpFindFileData->dwReserved1 = a0.dwReserved1;\r
615                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
616                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
617         }\r
618 END_ROUTINE\r
619         FreeDuplicatedString(pw0);\r
620         return r;\r
621 }\r
622 \r
623 BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)\r
624 {\r
625         BOOL r = FALSE;\r
626         WIN32_FIND_DATAW a0;\r
627 START_ROUTINE\r
628         r = FindNextFileW(hFindFile, &a0);\r
629         if(r)\r
630         {\r
631                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
632                 lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
633                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
634                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
635                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
636                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
637                 lpFindFileData->dwReserved0 = a0.dwReserved0;\r
638                 lpFindFileData->dwReserved1 = a0.dwReserved1;\r
639                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
640                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
641         }\r
642 END_ROUTINE\r
643         return r;\r
644 }\r
645 \r
646 DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)\r
647 {\r
648         DWORD r = 0;\r
649         wchar_t* pw0 = NULL;\r
650 START_ROUTINE\r
651         // TODO: バッファが不十分な場合に必要なサイズを返す\r
652         pw0 = AllocateStringW(nBufferLength * 4);\r
653         GetCurrentDirectoryW(nBufferLength * 4, pw0);\r
654         WtoM(lpBuffer, nBufferLength, pw0, -1);\r
655         r = TerminateStringM(lpBuffer, nBufferLength);\r
656 END_ROUTINE\r
657         FreeDuplicatedString(pw0);\r
658         return r;\r
659 }\r
660 \r
661 BOOL SetCurrentDirectoryM(LPCSTR lpPathName)\r
662 {\r
663         BOOL r = FALSE;\r
664         wchar_t* pw0 = NULL;\r
665 START_ROUTINE\r
666         pw0 = DuplicateMtoW(lpPathName, -1);\r
667         r = SetCurrentDirectoryW(pw0);\r
668 END_ROUTINE\r
669         FreeDuplicatedString(pw0);\r
670         return r;\r
671 }\r
672 \r
673 DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)\r
674 {\r
675         DWORD r = 0;\r
676         wchar_t* pw0 = NULL;\r
677 START_ROUTINE\r
678         pw0 = AllocateStringW(nBufferLength * 4);\r
679         GetTempPathW(nBufferLength * 4, pw0);\r
680         WtoM(lpBuffer, nBufferLength, pw0, -1);\r
681         r = TerminateStringM(lpBuffer, nBufferLength);\r
682 END_ROUTINE\r
683         FreeDuplicatedString(pw0);\r
684         return r;\r
685 }\r
686 \r
687 DWORD GetFileAttributesM(LPCSTR lpFileName)\r
688 {\r
689         DWORD r = FALSE;\r
690         wchar_t* pw0 = NULL;\r
691 START_ROUTINE\r
692         pw0 = DuplicateMtoW(lpFileName, -1);\r
693         r = GetFileAttributesW(pw0);\r
694 END_ROUTINE\r
695         FreeDuplicatedString(pw0);\r
696         return r;\r
697 }\r
698 \r
699 DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)\r
700 {\r
701         DWORD r = 0;\r
702         wchar_t* pw0 = NULL;\r
703 START_ROUTINE\r
704         pw0 = AllocateStringW(nSize * 4);\r
705         GetModuleFileNameW(hModule, pw0, nSize * 4);\r
706         WtoM(lpFilename, nSize, pw0, -1);\r
707         r = TerminateStringM(lpFilename, nSize);\r
708 END_ROUTINE\r
709         FreeDuplicatedString(pw0);\r
710         return r;\r
711 }\r
712 \r
713 BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)\r
714 {\r
715         BOOL r = FALSE;\r
716         wchar_t* pw0 = NULL;\r
717         wchar_t* pw1 = NULL;\r
718 START_ROUTINE\r
719         pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
720         pw1 = DuplicateMtoW(lpNewFileName, -1);\r
721         r = CopyFileW(pw0, pw1, bFailIfExists);\r
722 END_ROUTINE\r
723         FreeDuplicatedString(pw0);\r
724         FreeDuplicatedString(pw1);\r
725         return r;\r
726 }\r
727 \r
728 int mkdirM(const char * _Path)\r
729 {\r
730         int r = -1;\r
731         wchar_t* pw0 = NULL;\r
732 START_ROUTINE\r
733         pw0 = DuplicateMtoW(_Path, -1);\r
734         r = _wmkdir(pw0);\r
735 END_ROUTINE\r
736         FreeDuplicatedString(pw0);\r
737         return r;\r
738 }\r
739 \r
740 int _mkdirM(const char * _Path)\r
741 {\r
742         int r = -1;\r
743         wchar_t* pw0 = NULL;\r
744 START_ROUTINE\r
745         pw0 = DuplicateMtoW(_Path, -1);\r
746         r = _wmkdir(pw0);\r
747 END_ROUTINE\r
748         FreeDuplicatedString(pw0);\r
749         return r;\r
750 }\r
751 \r
752 int rmdirM(const char * _Path)\r
753 {\r
754         int r = -1;\r
755         wchar_t* pw0 = NULL;\r
756 START_ROUTINE\r
757         pw0 = DuplicateMtoW(_Path, -1);\r
758         r = _wrmdir(pw0);\r
759 END_ROUTINE\r
760         FreeDuplicatedString(pw0);\r
761         return r;\r
762 }\r
763 \r
764 int _rmdirM(const char * _Path)\r
765 {\r
766         int r = -1;\r
767         wchar_t* pw0 = NULL;\r
768 START_ROUTINE\r
769         pw0 = DuplicateMtoW(_Path, -1);\r
770         r = _wrmdir(pw0);\r
771 END_ROUTINE\r
772         FreeDuplicatedString(pw0);\r
773         return r;\r
774 }\r
775 \r
776 int removeM(const char * _Filename)\r
777 {\r
778         int r = -1;\r
779         wchar_t* pw0 = NULL;\r
780 START_ROUTINE\r
781         pw0 = DuplicateMtoW(_Filename, -1);\r
782         r = _wremove(pw0);\r
783 END_ROUTINE\r
784         FreeDuplicatedString(pw0);\r
785         return r;\r
786 }\r
787 \r
788 int _removeM(const char * _Filename)\r
789 {\r
790         int r = -1;\r
791         wchar_t* pw0 = NULL;\r
792 START_ROUTINE\r
793         pw0 = DuplicateMtoW(_Filename, -1);\r
794         r = _wremove(pw0);\r
795 END_ROUTINE\r
796         FreeDuplicatedString(pw0);\r
797         return r;\r
798 }\r
799 \r
800 int _unlinkM(const char * _Filename)\r
801 {\r
802         int r = -1;\r
803         wchar_t* pw0 = NULL;\r
804 START_ROUTINE\r
805         pw0 = DuplicateMtoW(_Filename, -1);\r
806         r = _wunlink(pw0);\r
807 END_ROUTINE\r
808         FreeDuplicatedString(pw0);\r
809         return r;\r
810 }\r
811 \r
812 size_t _mbslenM(const unsigned char * _Str)\r
813 {\r
814         size_t r = 0;\r
815 START_ROUTINE\r
816         while(GetNextCharM(_Str, &_Str) > 0)\r
817         {\r
818                 r++;\r
819         }\r
820 END_ROUTINE\r
821         return r;\r
822 }\r
823 \r
824 unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
825 {\r
826         unsigned char* r = NULL;\r
827         unsigned int c;\r
828         unsigned char* p;\r
829 START_ROUTINE\r
830         while((c = GetNextCharM(_Str, &p)) > 0)\r
831         {\r
832                 if(c == _Ch)\r
833                         break;\r
834                 _Str = p;\r
835         }\r
836         if(c == _Ch)\r
837                 r = (unsigned char*)_Str;\r
838 END_ROUTINE\r
839         return r;\r
840 }\r
841 \r
842 unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
843 {\r
844         unsigned char* r = NULL;\r
845         unsigned int c;\r
846         unsigned char* p;\r
847 START_ROUTINE\r
848         while((c = GetNextCharM(_Str, &p)) > 0)\r
849         {\r
850                 if(c == _Ch)\r
851                         r = (unsigned char*)_Str;\r
852                 _Str = p;\r
853         }\r
854         if(c == _Ch)\r
855                 r = (unsigned char*)_Str;\r
856 END_ROUTINE\r
857         return r;\r
858 }\r
859 \r
860 unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
861 {\r
862         unsigned char* r = NULL;\r
863 START_ROUTINE\r
864         r = strstr(_Str, _Substr);\r
865 END_ROUTINE\r
866         return r;\r
867 }\r
868 \r
869 int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
870 {\r
871         int r = 0;\r
872 START_ROUTINE\r
873         r = strcmp(_Str1, _Str2);\r
874 END_ROUTINE\r
875         return r;\r
876 }\r
877 \r
878 int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
879 {\r
880         int r = 0;\r
881 START_ROUTINE\r
882         r = _stricmp(_Str1, _Str2);\r
883 END_ROUTINE\r
884         return r;\r
885 }\r
886 \r
887 int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
888 {\r
889         int r = 0;\r
890         DWORD c1;\r
891         DWORD c2;\r
892 START_ROUTINE\r
893         c1 = 0;\r
894         c2 = 0;\r
895         while(_MaxCount > 0)\r
896         {\r
897                 c1 = GetNextCharM(_Str1, &_Str1);\r
898                 c2 = GetNextCharM(_Str2, &_Str2);\r
899                 if(c1 != c2)\r
900                         break;\r
901                 _MaxCount--;\r
902                 if(c1 == 0 || c2 == 0)\r
903                         break;\r
904         }\r
905         r = c1 - c2;\r
906 END_ROUTINE\r
907         return r;\r
908 }\r
909 \r
910 unsigned char * _mbslwrM(unsigned char * _String)\r
911 {\r
912         unsigned char* r = NULL;\r
913 START_ROUTINE\r
914         r = _strlwr(_String);\r
915 END_ROUTINE\r
916         return r;\r
917 }\r
918 \r
919 unsigned char * _mbsuprM(unsigned char * _String)\r
920 {\r
921         unsigned char* r = NULL;\r
922 START_ROUTINE\r
923         r = _strupr(_String);\r
924 END_ROUTINE\r
925         return r;\r
926 }\r
927 \r
928 unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
929 {\r
930         unsigned char* r = NULL;\r
931 START_ROUTINE\r
932         while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
933         {\r
934                 _Count--;\r
935         }\r
936         r = (unsigned char*)_Str;\r
937 END_ROUTINE\r
938         return r;\r
939 }\r
940 \r
941 FILE * fopenM(const char * _Filename, const char * _Mode)\r
942 {\r
943         FILE* r = NULL;\r
944         wchar_t* pw0 = NULL;\r
945         wchar_t* pw1 = NULL;\r
946 START_ROUTINE\r
947         pw0 = DuplicateMtoW(_Filename, -1);\r
948         pw1 = DuplicateMtoW(_Mode, -1);\r
949         r = _wfopen(pw0, pw1);\r
950 END_ROUTINE\r
951         FreeDuplicatedString(pw0);\r
952         FreeDuplicatedString(pw1);\r
953         return r;\r
954 }\r
955 \r