+// mbswrapper.c\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// マルチバイト文字ワイド文字APIラッパー\r
+// マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする\r
+// 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要\r
+\r
+#define UNICODE\r
+#define _UNICODE\r
+\r
+#include <stdio.h>\r
+#include <tchar.h>\r
+#include <direct.h>\r
+#include <windows.h>\r
+#include <commctrl.h>\r
+#include <shlobj.h>\r
+#include <htmlhelp.h>\r
+\r
+#define DO_NOT_REPLACE\r
+#include "mbswrapper.h"\r
+\r
+// マルチバイト文字列からワイド文字列へ変換\r
+int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
+{\r
+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+ return 0;\r
+ if(pDst)\r
+ return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);\r
+ return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);\r
+}\r
+\r
+// ワイド文字列からマルチバイト文字列へ変換\r
+int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
+{\r
+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+ return 0;\r
+ if(pDst)\r
+ return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);\r
+ return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);\r
+}\r
+\r
+// Shift_JIS文字列からワイド文字列へ変換\r
+int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
+{\r
+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+ return 0;\r
+ if(pDst)\r
+ return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);\r
+ return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);\r
+}\r
+\r
+// ワイド文字列からShift_JIS文字列へ変換\r
+int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
+{\r
+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+ return 0;\r
+ if(pDst)\r
+ return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);\r
+ return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);\r
+}\r
+\r
+// マルチバイト文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringM(LPSTR lpString, int size)\r
+{\r
+ int i;\r
+ if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
+ return 0;\r
+ for(i = 0; i < size; i++)\r
+ {\r
+ if(lpString[i] == '\0')\r
+ return i;\r
+ }\r
+ i--;\r
+ lpString[i] = '\0';\r
+ return i;\r
+}\r
+\r
+// ワイド文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringW(LPWSTR lpString, int size)\r
+{\r
+ int i;\r
+ if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)\r
+ return 0;\r
+ for(i = 0; i < size; i++)\r
+ {\r
+ if(lpString[i] == L'\0')\r
+ return i;\r
+ }\r
+ i--;\r
+ lpString[i] = L'\0';\r
+ return i;\r
+}\r
+\r
+// Shift_JIS文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringA(LPSTR lpString, int size)\r
+{\r
+ int i;\r
+ if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
+ return 0;\r
+ for(i = 0; i < size; i++)\r
+ {\r
+ if(lpString[i] == '\0')\r
+ return i;\r
+ }\r
+ i--;\r
+ lpString[i] = '\0';\r
+ return i;\r
+}\r
+\r
+// NULL区切り複数マルチバイト文字列の長さを取得\r
+size_t GetMultiStringLengthM(LPCSTR lpString)\r
+{\r
+ size_t i;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return 0;\r
+ i = 0;\r
+ while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
+ {\r
+ i++;\r
+ }\r
+ i++;\r
+ return i;\r
+}\r
+\r
+// NULL区切り複数ワイド文字列の長さを取得\r
+size_t GetMultiStringLengthW(LPCWSTR lpString)\r
+{\r
+ size_t i;\r
+ if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+ return 0;\r
+ i = 0;\r
+ while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')\r
+ {\r
+ i++;\r
+ }\r
+ i++;\r
+ return i;\r
+}\r
+\r
+// NULL区切り複数Shift_JIS文字列の長さを取得\r
+size_t GetMultiStringLengthA(LPCSTR lpString)\r
+{\r
+ size_t i;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return 0;\r
+ i = 0;\r
+ while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
+ {\r
+ i++;\r
+ }\r
+ i++;\r
+ return i;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列からワイド文字列へ変換\r
+int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
+{\r
+ int i;\r
+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+ return 0;\r
+ if(!pDst)\r
+ return GetMultiStringLengthM(pSrc);\r
+ i = 0;\r
+ while(*pSrc != '\0')\r
+ {\r
+ i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);\r
+ pSrc += strlen(pSrc) + 1;\r
+ }\r
+ pDst[i] = L'\0';\r
+ return i;\r
+}\r
+\r
+// NULL区切りワイド文字列からマルチバイト文字列へ変換\r
+int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
+{\r
+ int i;\r
+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+ return 0;\r
+ if(!pDst)\r
+ return GetMultiStringLengthW(pSrc);\r
+ i = 0;\r
+ while(*pSrc != L'\0')\r
+ {\r
+ i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
+ pSrc += wcslen(pSrc) + 1;\r
+ }\r
+ pDst[i] = '\0';\r
+ return i;\r
+}\r
+\r
+// NULL区切りShift_JIS文字列からワイド文字列へ変換\r
+int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
+{\r
+ int i;\r
+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+ return 0;\r
+ if(!pDst)\r
+ return GetMultiStringLengthA(pSrc);\r
+ i = 0;\r
+ while(*pSrc != '\0')\r
+ {\r
+ i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);\r
+ pSrc += strlen(pSrc) + 1;\r
+ }\r
+ pDst[i] = L'\0';\r
+ return i;\r
+}\r
+\r
+// NULL区切りワイド文字列からShift_JIS文字列へ変換\r
+int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
+{\r
+ int i;\r
+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+ return 0;\r
+ if(!pDst)\r
+ return GetMultiStringLengthW(pSrc);\r
+ i = 0;\r
+ while(*pSrc != L'\0')\r
+ {\r
+ i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
+ pSrc += wcslen(pSrc) + 1;\r
+ }\r
+ pDst[i] = '\0';\r
+ return i;\r
+}\r
+\r
+// マルチバイト文字列用のメモリを確保\r
+char* AllocateStringM(int size)\r
+{\r
+ char* p;\r
+ // 0が指定される場合があるため1文字分追加\r
+ p = (char*)malloc(sizeof(char) * (size + 1));\r
+ // 念のため先頭にNULL文字を代入\r
+ if(p)\r
+ *p = '\0';\r
+ return p;\r
+}\r
+\r
+// ワイド文字列用のメモリを確保\r
+wchar_t* AllocateStringW(int size)\r
+{\r
+ wchar_t* p;\r
+ // 0が指定される場合があるため1文字分追加\r
+ p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));\r
+ // 念のため先頭にNULL文字を代入\r
+ if(p)\r
+ *p = L'\0';\r
+ return p;\r
+}\r
+\r
+// Shift_JIS文字列用のメモリを確保\r
+char* AllocateStringA(int size)\r
+{\r
+ char* p;\r
+ // 0が指定される場合があるため1文字分追加\r
+ p = (char*)malloc(sizeof(char) * (size + 1));\r
+ // 念のため先頭にNULL文字を代入\r
+ if(p)\r
+ *p = '\0';\r
+ return p;\r
+}\r
+\r
+// メモリを確保してマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoW(LPCSTR lpString, int c)\r
+{\r
+ wchar_t* p;\r
+ int i;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return (wchar_t*)lpString;\r
+ if(c < 0)\r
+ c = strlen(lpString);\r
+ p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);\r
+ if(p)\r
+ {\r
+ i = MtoW(p, 65535, lpString, c);\r
+ p[i] = L'\0';\r
+ }\r
+ return p;\r
+}\r
+\r
+// 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)\r
+{\r
+ wchar_t* p;\r
+ int i;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return (wchar_t*)lpString;\r
+ if(c < 0)\r
+ c = strlen(lpString);\r
+ p = AllocateStringW(size);\r
+ if(p)\r
+ {\r
+ i = MtoW(p, size, lpString, c);\r
+ p[i] = L'\0';\r
+ }\r
+ return p;\r
+}\r
+\r
+// メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)\r
+{\r
+ int count;\r
+ wchar_t* p;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return (wchar_t*)lpString;\r
+ count = GetMultiStringLengthM(lpString) + 1;\r
+ p = AllocateStringW(count);\r
+ if(p)\r
+ MtoW(p, count, lpString, count);\r
+ return p;\r
+}\r
+\r
+// 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)\r
+{\r
+ int count;\r
+ wchar_t* p;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return (wchar_t*)lpString;\r
+ count = GetMultiStringLengthM(lpString) + 1;\r
+ p = AllocateStringW(size);\r
+ if(p)\r
+ {\r
+ MtoW(p, size, lpString, count);\r
+ p[size - 2] = L'\0';\r
+ p[size - 1] = L'\0';\r
+ }\r
+ return p;\r
+}\r
+\r
+// メモリを確保してワイド文字列からマルチバイト文字列へ変換\r
+// リソースIDならば元の値を返す\r
+char* DuplicateWtoM(LPCWSTR lpString, int c)\r
+{\r
+ char* p;\r
+ int i;\r
+ if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+ return (char*)lpString;\r
+ if(c < 0)\r
+ c = wcslen(lpString);\r
+ p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);\r
+ if(p)\r
+ {\r
+ i = WtoM(p, 65535, lpString, c);\r
+ p[i] = L'\0';\r
+ }\r
+ return p;\r
+}\r
+\r
+// メモリを確保してShift_JIS文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateAtoW(LPCSTR lpString, int c)\r
+{\r
+ wchar_t* p;\r
+ int i;\r
+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+ return (wchar_t*)lpString;\r
+ if(c < 0)\r
+ c = strlen(lpString);\r
+ p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);\r
+ if(p)\r
+ {\r
+ i = AtoW(p, 65535, lpString, c);\r
+ p[i] = L'\0';\r
+ }\r
+ return p;\r
+}\r
+\r
+// メモリを確保してワイド文字列からShift_JIS文字列へ変換\r
+// リソースIDならば元の値を返す\r
+char* DuplicateWtoA(LPCWSTR lpString, int c)\r
+{\r
+ char* p;\r
+ int i;\r
+ if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+ return (char*)lpString;\r
+ if(c < 0)\r
+ c = wcslen(lpString);\r
+ p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);\r
+ if(p)\r
+ {\r
+ i = WtoA(p, 65535, lpString, c);\r
+ p[i] = L'\0';\r
+ }\r
+ return p;\r
+}\r
+\r
+// マルチバイト文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
+{\r
+ DWORD Code;\r
+ int i;\r
+ Code = 0;\r
+ if((*lpString & 0xfe) == 0xfc)\r
+ {\r
+ i = 5;\r
+ Code |= (DWORD)*lpString & 0x01;\r
+ }\r
+ else if((*lpString & 0xfc) == 0xf8)\r
+ {\r
+ i = 4;\r
+ Code |= (DWORD)*lpString & 0x03;\r
+ }\r
+ else if((*lpString & 0xf8) == 0xf0)\r
+ {\r
+ i = 3;\r
+ Code |= (DWORD)*lpString & 0x07;\r
+ }\r
+ else if((*lpString & 0xf0) == 0xe0)\r
+ {\r
+ i = 2;\r
+ Code |= (DWORD)*lpString & 0x0f;\r
+ }\r
+ else if((*lpString & 0xe0) == 0xc0)\r
+ {\r
+ i = 1;\r
+ Code |= (DWORD)*lpString & 0x1f;\r
+ }\r
+ else if((*lpString & 0x80) == 0x00)\r
+ {\r
+ i = 0;\r
+ Code |= (DWORD)*lpString & 0x7f;\r
+ }\r
+ else\r
+ i = -1;\r
+ lpString++;\r
+ while((*lpString & 0xc0) == 0x80)\r
+ {\r
+ i--;\r
+ Code = Code << 6;\r
+ Code |= (DWORD)*lpString & 0x3f;\r
+ lpString++;\r
+ }\r
+ if(i != 0)\r
+ Code = 0x80000000;\r
+ if(ppNext)\r
+ *ppNext = lpString;\r
+ return Code;\r
+}\r
+\r
+// マルチバイト文字列の冗長表現を修正\r
+// 修正があればTRUEを返す\r
+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
+BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)\r
+{\r
+ BOOL bResult;\r
+ char* p;\r
+ DWORD Code;\r
+ int i;\r
+ char c;\r
+ bResult = FALSE;\r
+ p = (char*)pSrc;\r
+ while(*pSrc != '\0')\r
+ {\r
+ Code = GetNextCharM(pSrc, &pSrc);\r
+ if(Code & 0x80000000)\r
+ continue;\r
+ else if(Code & 0x7c000000)\r
+ {\r
+ i = 5;\r
+ c = (char)(0xfc | (Code >> (6 * i)));\r
+ }\r
+ else if(Code & 0x03e00000)\r
+ {\r
+ i = 4;\r
+ c = (char)(0xf8 | (Code >> (6 * i)));\r
+ }\r
+ else if(Code & 0x001f0000)\r
+ {\r
+ i = 3;\r
+ c = (char)(0xf0 | (Code >> (6 * i)));\r
+ }\r
+ else if(Code & 0x0000f800)\r
+ {\r
+ i = 2;\r
+ c = (char)(0xe0 | (Code >> (6 * i)));\r
+ }\r
+ else if(Code & 0x00000780)\r
+ {\r
+ i = 1;\r
+ c = (char)(0xc0 | (Code >> (6 * i)));\r
+ }\r
+ else\r
+ {\r
+ i = 0;\r
+ c = (char)Code;\r
+ }\r
+ if(c != *p)\r
+ bResult = TRUE;\r
+ p++;\r
+ *pDst = c;\r
+ pDst++;\r
+ while(i > 0)\r
+ {\r
+ i--;\r
+ c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f));\r
+ if(c != *p)\r
+ bResult = TRUE;\r
+ p++;\r
+ *pDst = c;\r
+ pDst++;\r
+ }\r
+ }\r
+ if(*p != '\0')\r
+ bResult = TRUE;\r
+ *pDst = '\0';\r
+ return bResult;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列の冗長表現を修正\r
+// 修正があればTRUEを返す\r
+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
+BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc)\r
+{\r
+ BOOL bResult;\r
+ int Length;\r
+ bResult = FALSE;\r
+ while(*pSrc != '\0')\r
+ {\r
+ Length = strlen(pSrc) + 1;\r
+ bResult = bResult | FixStringM(pDst, pSrc);\r
+ pSrc += Length;\r
+ pDst += strlen(pDst) + 1;\r
+ }\r
+ *pDst = '\0';\r
+ return bResult;\r
+}\r
+\r
+// マルチバイト文字列の冗長表現を確認\r
+// 冗長表現があればTRUEを返す\r
+BOOL CheckStringM(LPCSTR lpString)\r
+{\r
+ BOOL bResult;\r
+ char* p;\r
+ bResult = FALSE;\r
+ p = AllocateStringM(strlen(lpString) + 1);\r
+ if(p)\r
+ {\r
+ bResult = FixStringM(p, lpString);\r
+ FreeDuplicatedString(p);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列の冗長表現を確認\r
+// 冗長表現があればTRUEを返す\r
+BOOL CheckMultiStringM(LPCSTR lpString)\r
+{\r
+ BOOL bResult;\r
+ char* p;\r
+ bResult = FALSE;\r
+ p = AllocateStringM(GetMultiStringLengthM(lpString) + 1);\r
+ if(p)\r
+ {\r
+ bResult = FixMultiStringM(p, lpString);\r
+ FreeDuplicatedString(p);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// 文字列用に確保したメモリを開放\r
+// リソースIDならば何もしない\r
+void FreeDuplicatedString(void* p)\r
+{\r
+ if(p < (void*)0x00010000 || p == (void*)~0)\r
+ return;\r
+ free(p);\r
+}\r
+\r
+// 以下ラッパー\r
+// 戻り値バッファ r\r
+// ワイド文字バッファ pw%d\r
+// マルチバイト文字バッファ pm%d\r
+// 引数バッファ a%d\r
+\r
+#pragma warning(disable:4102)\r
+#define START_ROUTINE do{\r
+#define END_ROUTINE }while(0);end_of_routine:\r
+#define QUIT_ROUTINE goto end_of_routine;\r
+\r
+HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)\r
+{\r
+ HANDLE r = INVALID_HANDLE_VALUE;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(lpFileName, -1);\r
+ r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)\r
+{\r
+ HANDLE r = INVALID_HANDLE_VALUE;\r
+ wchar_t* pw0 = NULL;\r
+ WIN32_FIND_DATAW a0;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(lpFileName, -1);\r
+ r = FindFirstFileW(pw0, &a0);\r
+ if(r != INVALID_HANDLE_VALUE)\r
+ {\r
+ lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
+ lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
+ lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
+ lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
+ lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
+ lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
+ lpFindFileData->dwReserved0 = a0.dwReserved0;\r
+ lpFindFileData->dwReserved1 = a0.dwReserved1;\r
+ WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
+ WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
+ }\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)\r
+{\r
+ BOOL r = FALSE;\r
+ WIN32_FIND_DATAW a0;\r
+START_ROUTINE\r
+ r = FindNextFileW(hFindFile, &a0);\r
+ if(r)\r
+ {\r
+ lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
+ lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
+ lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
+ lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
+ lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
+ lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
+ lpFindFileData->dwReserved0 = a0.dwReserved0;\r
+ lpFindFileData->dwReserved1 = a0.dwReserved1;\r
+ WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
+ WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
+ }\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+ DWORD r = 0;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ // TODO: バッファが不十分な場合に必要なサイズを返す\r
+ pw0 = AllocateStringW(nBufferLength * 4);\r
+ GetCurrentDirectoryW(nBufferLength * 4, pw0);\r
+ WtoM(lpBuffer, nBufferLength, pw0, -1);\r
+ r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+BOOL SetCurrentDirectoryM(LPCSTR lpPathName)\r
+{\r
+ BOOL r = FALSE;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(lpPathName, -1);\r
+ r = SetCurrentDirectoryW(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+ DWORD r = 0;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = AllocateStringW(nBufferLength * 4);\r
+ GetTempPathW(nBufferLength * 4, pw0);\r
+ WtoM(lpBuffer, nBufferLength, pw0, -1);\r
+ r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+DWORD GetFileAttributesM(LPCSTR lpFileName)\r
+{\r
+ DWORD r = FALSE;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(lpFileName, -1);\r
+ r = GetFileAttributesW(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)\r
+{\r
+ DWORD r = 0;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = AllocateStringW(nSize * 4);\r
+ GetModuleFileNameW(hModule, pw0, nSize * 4);\r
+ WtoM(lpFilename, nSize, pw0, -1);\r
+ r = TerminateStringM(lpFilename, nSize);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)\r
+{\r
+ BOOL r = FALSE;\r
+ wchar_t* pw0 = NULL;\r
+ wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
+ pw1 = DuplicateMtoW(lpNewFileName, -1);\r
+ r = CopyFileW(pw0, pw1, bFailIfExists);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ FreeDuplicatedString(pw1);\r
+ return r;\r
+}\r
+\r
+int mkdirM(const char * _Path)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Path, -1);\r
+ r = _wmkdir(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+int _mkdirM(const char * _Path)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Path, -1);\r
+ r = _wmkdir(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+int rmdirM(const char * _Path)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Path, -1);\r
+ r = _wrmdir(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+int _rmdirM(const char * _Path)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Path, -1);\r
+ r = _wrmdir(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+int removeM(const char * _Filename)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Filename, -1);\r
+ r = _wremove(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+int _removeM(const char * _Filename)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Filename, -1);\r
+ r = _wremove(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+int _unlinkM(const char * _Filename)\r
+{\r
+ int r = -1;\r
+ wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Filename, -1);\r
+ r = _wunlink(pw0);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+size_t _mbslenM(const unsigned char * _Str)\r
+{\r
+ size_t r = 0;\r
+START_ROUTINE\r
+ while(GetNextCharM(_Str, &_Str) > 0)\r
+ {\r
+ r++;\r
+ }\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
+{\r
+ unsigned char* r = NULL;\r
+ unsigned int c;\r
+ unsigned char* p;\r
+START_ROUTINE\r
+ while((c = GetNextCharM(_Str, &p)) > 0)\r
+ {\r
+ if(c == _Ch)\r
+ break;\r
+ _Str = p;\r
+ }\r
+ if(c == _Ch)\r
+ r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
+{\r
+ unsigned char* r = NULL;\r
+ unsigned int c;\r
+ unsigned char* p;\r
+START_ROUTINE\r
+ while((c = GetNextCharM(_Str, &p)) > 0)\r
+ {\r
+ if(c == _Ch)\r
+ r = (unsigned char*)_Str;\r
+ _Str = p;\r
+ }\r
+ if(c == _Ch)\r
+ r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
+{\r
+ unsigned char* r = NULL;\r
+START_ROUTINE\r
+ r = strstr(_Str, _Substr);\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
+{\r
+ int r = 0;\r
+START_ROUTINE\r
+ r = strcmp(_Str1, _Str2);\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
+{\r
+ int r = 0;\r
+START_ROUTINE\r
+ r = _stricmp(_Str1, _Str2);\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
+{\r
+ int r = 0;\r
+ DWORD c1;\r
+ DWORD c2;\r
+START_ROUTINE\r
+ c1 = 0;\r
+ c2 = 0;\r
+ while(_MaxCount > 0)\r
+ {\r
+ c1 = GetNextCharM(_Str1, &_Str1);\r
+ c2 = GetNextCharM(_Str2, &_Str2);\r
+ if(c1 != c2)\r
+ break;\r
+ _MaxCount--;\r
+ if(c1 == 0 || c2 == 0)\r
+ break;\r
+ }\r
+ r = c1 - c2;\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+unsigned char * _mbslwrM(unsigned char * _String)\r
+{\r
+ unsigned char* r = NULL;\r
+START_ROUTINE\r
+ r = _strlwr(_String);\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+unsigned char * _mbsuprM(unsigned char * _String)\r
+{\r
+ unsigned char* r = NULL;\r
+START_ROUTINE\r
+ r = _strupr(_String);\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
+{\r
+ unsigned char* r = NULL;\r
+START_ROUTINE\r
+ while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
+ {\r
+ _Count--;\r
+ }\r
+ r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+ return r;\r
+}\r
+\r
+FILE * fopenM(const char * _Filename, const char * _Mode)\r
+{\r
+ FILE* r = NULL;\r
+ wchar_t* pw0 = NULL;\r
+ wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+ pw0 = DuplicateMtoW(_Filename, -1);\r
+ pw1 = DuplicateMtoW(_Mode, -1);\r
+ r = _wfopen(pw0, pw1);\r
+END_ROUTINE\r
+ FreeDuplicatedString(pw0);\r
+ FreeDuplicatedString(pw1);\r
+ return r;\r
+}\r
+\r