OSDN Git Service

Modify documents.
[ffftp/ffftp.git] / mbswrapper.c
index 242837c..a051543 100644 (file)
@@ -7,6 +7,7 @@
 #define UNICODE\r
 #define _UNICODE\r
 \r
+#include <stdio.h>\r
 #include <tchar.h>\r
 #include <direct.h>\r
 #include <windows.h>\r
@@ -387,62 +388,212 @@ char* DuplicateWtoA(LPCWSTR lpString, int c)
        return p;\r
 }\r
 \r
-// マルチバイト文字列の冗長表現を修正\r
-// 修正があればTRUEを返す\r
-// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
-BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)\r
+// マルチバイト文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR pLimit, LPCSTR* ppNext)\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
+       Code = 0;\r
+       i = -1;\r
+       if(!pLimit)\r
+               pLimit = (LPCSTR)(~0);\r
+       if(lpString < pLimit)\r
        {\r
-               Code = 0;\r
-               if((*pSrc & 0xfe) == 0xfc)\r
+               if((*lpString & 0xfe) == 0xfc)\r
                {\r
                        i = 5;\r
-                       Code |= (DWORD)*pSrc & 0x01;\r
+                       Code |= (DWORD)*lpString & 0x01;\r
                }\r
-               else if((*pSrc & 0xfc) == 0xf8)\r
+               else if((*lpString & 0xfc) == 0xf8)\r
                {\r
                        i = 4;\r
-                       Code |= (DWORD)*pSrc & 0x03;\r
+                       Code |= (DWORD)*lpString & 0x03;\r
                }\r
-               else if((*pSrc & 0xf8) == 0xf0)\r
+               else if((*lpString & 0xf8) == 0xf0)\r
                {\r
                        i = 3;\r
-                       Code |= (DWORD)*pSrc & 0x07;\r
+                       Code |= (DWORD)*lpString & 0x07;\r
                }\r
-               else if((*pSrc & 0xf0) == 0xe0)\r
+               else if((*lpString & 0xf0) == 0xe0)\r
                {\r
                        i = 2;\r
-                       Code |= (DWORD)*pSrc & 0x0f;\r
+                       Code |= (DWORD)*lpString & 0x0f;\r
                }\r
-               else if((*pSrc & 0xe0) == 0xc0)\r
+               else if((*lpString & 0xe0) == 0xc0)\r
                {\r
                        i = 1;\r
-                       Code |= (DWORD)*pSrc & 0x1f;\r
+                       Code |= (DWORD)*lpString & 0x1f;\r
                }\r
-               else if((*pSrc & 0x80) == 0x00)\r
+               else if((*lpString & 0x80) == 0x00)\r
                {\r
                        i = 0;\r
-                       Code |= (DWORD)*pSrc & 0x7f;\r
+                       Code |= (DWORD)*lpString & 0x7f;\r
                }\r
-               else\r
-                       i = -1;\r
-               pSrc++;\r
-               while((*pSrc & 0xc0) == 0x80)\r
+               lpString++;\r
+               while(lpString < pLimit && i > 0 && (*lpString & 0xc0) == 0x80)\r
                {\r
                        i--;\r
                        Code = Code << 6;\r
-                       Code |= (DWORD)*pSrc & 0x3f;\r
-                       pSrc++;\r
+                       Code |= (DWORD)*lpString & 0x3f;\r
+                       lpString++;\r
+               }\r
+       }\r
+       if(i != 0)\r
+               Code = 0x80000000;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// マルチバイト文字列へコードポイントの文字を追加して次のポインタを取得\r
+// 文字の長さを返す\r
+int PutNextCharM(LPSTR lpString, LPSTR pLimit, LPSTR* ppNext, DWORD Code)\r
+{\r
+       int Count;\r
+       int i;\r
+       Count = 0;\r
+       i = -1;\r
+       if(!pLimit)\r
+               pLimit = (LPSTR)(~0);\r
+       if(lpString < pLimit)\r
+       {\r
+               if(Code & 0x7c000000)\r
+               {\r
+                       i = 5;\r
+                       *lpString = 0xfc | ((CHAR)(Code >> 30) & 0x01);\r
+               }\r
+               else if(Code & 0x03e00000)\r
+               {\r
+                       i = 4;\r
+                       *lpString = 0xf8 | ((CHAR)(Code >> 24) & 0x03);\r
+               }\r
+               else if(Code & 0x001f0000)\r
+               {\r
+                       i = 3;\r
+                       *lpString = 0xf0 | ((CHAR)(Code >> 18) & 0x07);\r
+               }\r
+               else if(Code & 0x0000f800)\r
+               {\r
+                       i = 2;\r
+                       *lpString = 0xe0 | ((CHAR)(Code >> 12) & 0x0f);\r
+               }\r
+               else if(Code & 0x00000780)\r
+               {\r
+                       i = 1;\r
+                       *lpString = 0xc0 | ((CHAR)(Code >> 6) & 0x1f);\r
+               }\r
+               else\r
+               {\r
+                       i = 0;\r
+                       *lpString = (CHAR)Code & 0x7f;\r
+               }\r
+               Count = i + 1;\r
+               lpString++;\r
+               while(lpString < pLimit && i > 0)\r
+               {\r
+                       i--;\r
+                       *lpString = 0x80 | ((CHAR)(Code >> (i * 6)) & 0x3f);\r
+                       lpString++;\r
+               }\r
+       }\r
+       if(i != 0)\r
+               Count = 0;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Count;\r
+}\r
+\r
+// ワイド文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharW(LPCWSTR lpString, LPCWSTR pLimit, LPCWSTR* ppNext)\r
+{\r
+       DWORD Code;\r
+       Code = 0x80000000;\r
+       if(!pLimit)\r
+               pLimit = (LPCWSTR)(~0);\r
+       if(lpString < pLimit)\r
+       {\r
+               if((*lpString & 0xf800) == 0xd800)\r
+               {\r
+                       if((*lpString & 0x0400) == 0x0400)\r
+                       {\r
+                               Code = (DWORD)*lpString & 0x03ff;\r
+                               lpString++;\r
+                               if(lpString < pLimit)\r
+                               {\r
+                                       if((*lpString & 0x0400) == 0x0000)\r
+                                       {\r
+                                               Code |= ((DWORD)*lpString & 0x03ff) << 10;\r
+                                               lpString++;\r
+                                       }\r
+                                       else\r
+                                               Code = 0x80000000;\r
+                               }\r
+                               else\r
+                                       Code = 0x80000000;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       Code = (DWORD)*lpString;\r
+                       lpString++;\r
+               }\r
+       }\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// ワイド文字列へコードポイントの文字を追加して次のポインタを取得\r
+// 文字の長さを返す\r
+int PutNextCharW(LPWSTR lpString, LPWSTR pLimit, LPWSTR* ppNext, DWORD Code)\r
+{\r
+       int Count;\r
+       Count = 0;\r
+       if(!pLimit)\r
+               pLimit = (LPWSTR)(~0);\r
+       if(lpString < pLimit)\r
+       {\r
+               if((Code & 0x7fff0000) || (Code & 0x0000f800) == 0x0000d800)\r
+               {\r
+                       *lpString = 0xdc00 | ((WCHAR)Code & 0x03ff);\r
+                       lpString++;\r
+                       if(lpString < pLimit)\r
+                       {\r
+                               *lpString = 0xd800 | ((WCHAR)(Code >> 10) & 0x03ff);\r
+                               lpString++;\r
+                               Count = 2;\r
+                       }\r
                }\r
-               if(i != 0)\r
+               else\r
+               {\r
+                       *lpString = (WCHAR)Code;\r
+                       lpString++;\r
+                       Count = 1;\r
+               }\r
+       }\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Count;\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, NULL, &pSrc);\r
+               if(Code & 0x80000000)\r
                        continue;\r
                else if(Code & 0x7c000000)\r
                {\r
@@ -556,6 +707,82 @@ void FreeDuplicatedString(void* p)
        free(p);\r
 }\r
 \r
+// マルチバイト文字列からワイド文字列へ変換\r
+// UTF-8からUTF-16 LEへの変換専用\r
+int MultiByteToWideCharAlternative(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)\r
+{\r
+       int WideCount;\r
+       LPCSTR pMultiLimit;\r
+       LPWSTR pWideLimit;\r
+       DWORD Code;\r
+       WCHAR Temp[8];\r
+       if(CodePage != CP_UTF8 || dwFlags != 0)\r
+               return MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar);\r
+       WideCount = 0;\r
+       if(cbMultiByte == -1)\r
+               pMultiLimit = lpMultiByteStr + strlen(lpMultiByteStr) + 1;\r
+       else\r
+               pMultiLimit = lpMultiByteStr + cbMultiByte;\r
+       pWideLimit = lpWideCharStr + cchWideChar;\r
+       while(lpMultiByteStr < pMultiLimit)\r
+       {\r
+               Code = GetNextCharM(lpMultiByteStr, pMultiLimit, &lpMultiByteStr);\r
+               if(Code == 0x80000000)\r
+                       continue;\r
+               if(lpWideCharStr)\r
+               {\r
+                       WideCount += PutNextCharW(lpWideCharStr, pWideLimit, &lpWideCharStr, Code);\r
+                       if(lpWideCharStr >= pWideLimit)\r
+                       {\r
+                               WideCount = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       WideCount += PutNextCharW(Temp, NULL, NULL, Code);\r
+       }\r
+       return WideCount;\r
+}\r
+\r
+// ワイド文字列からマルチバイト文字列へ変換\r
+// UTF-16 LEからUTF-8への変換専用\r
+int WideCharToMultiByteAlternative(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)\r
+{\r
+       int MultiCount;\r
+       LPCWSTR pWideLimit;\r
+       LPSTR pMultiLimit;\r
+       DWORD Code;\r
+       CHAR Temp[8];\r
+       if(CodePage != CP_UTF8 || dwFlags != 0)\r
+               return WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);\r
+       MultiCount = 0;\r
+       if(cchWideChar == -1)\r
+               pWideLimit = lpWideCharStr + wcslen(lpWideCharStr) + 1;\r
+       else\r
+               pWideLimit = lpWideCharStr + cchWideChar;\r
+       pMultiLimit = lpMultiByteStr + cbMultiByte;\r
+       while(lpWideCharStr < pWideLimit)\r
+       {\r
+               Code = GetNextCharW(lpWideCharStr, pWideLimit, &lpWideCharStr);\r
+               if(Code == 0x80000000)\r
+                       continue;\r
+               if(lpMultiByteStr)\r
+               {\r
+                       MultiCount += PutNextCharM(lpMultiByteStr, pMultiLimit, &lpMultiByteStr, Code);\r
+                       if(lpMultiByteStr >= pMultiLimit)\r
+                       {\r
+                               MultiCount = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       MultiCount += PutNextCharM(Temp, NULL, NULL, Code);\r
+       }\r
+       if(lpUsedDefaultChar)\r
+               *lpUsedDefaultChar = FALSE;\r
+       return MultiCount;\r
+}\r
+\r
 // 以下ラッパー\r
 // 戻り値バッファ r\r
 // ワイド文字バッファ pw%d\r
@@ -684,10 +911,28 @@ END_ROUTINE
 ATOM RegisterClassExM(CONST WNDCLASSEXA * v0)\r
 {\r
        ATOM r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       WNDCLASSEXW a0;\r
 START_ROUTINE\r
-       // WNDPROCがShift_JIS用であるため\r
-       r = RegisterClassExA(v0);\r
+       a0.cbSize = sizeof(WNDCLASSEXW);\r
+       a0.style = v0->style;\r
+       a0.lpfnWndProc = v0->lpfnWndProc;\r
+       a0.cbClsExtra = v0->cbClsExtra;\r
+       a0.cbWndExtra = v0->cbWndExtra;\r
+       a0.hInstance = v0->hInstance;\r
+       a0.hIcon = v0->hIcon;\r
+       a0.hCursor = v0->hCursor;\r
+       a0.hbrBackground = v0->hbrBackground;\r
+       pw0 = DuplicateMtoW(v0->lpszMenuName, -1);\r
+       a0.lpszMenuName = pw0;\r
+       pw1 = DuplicateMtoW(v0->lpszClassName, -1);\r
+       a0.lpszClassName = pw1;\r
+       a0.hIconSm = v0->hIconSm;\r
+       r = RegisterClassExW(&a0);\r
 END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
        return r;\r
 }\r
 \r
@@ -708,9 +953,8 @@ END_ROUTINE
 \r
 LONG GetWindowLongM(HWND hWnd, int nIndex)\r
 {\r
-       LRESULT r = 0;\r
+       LONG r = 0;\r
 START_ROUTINE\r
-       // WNDPROCがShift_JIS用であるため\r
        if(IsWindowUnicode(hWnd))\r
                r = GetWindowLongW(hWnd, nIndex);\r
        else\r
@@ -721,9 +965,8 @@ END_ROUTINE
 \r
 LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)\r
 {\r
-       LRESULT r = 0;\r
+       LONG r = 0;\r
 START_ROUTINE\r
-       // WNDPROCがShift_JIS用であるため\r
        if(IsWindowUnicode(hWnd))\r
                r = SetWindowLongW(hWnd, nIndex, dwNewLong);\r
        else\r
@@ -732,11 +975,34 @@ END_ROUTINE
        return r;\r
 }\r
 \r
+LONG_PTR GetWindowLongPtrM(HWND hWnd, int nIndex)\r
+{\r
+       LONG_PTR r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = GetWindowLongPtrW(hWnd, nIndex);\r
+       else\r
+               r = GetWindowLongPtrA(hWnd, nIndex);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LONG_PTR SetWindowLongPtrM(HWND hWnd, int nIndex, LONG_PTR dwNewLong)\r
+{\r
+       LONG_PTR r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = SetWindowLongPtrW(hWnd, nIndex, dwNewLong);\r
+       else\r
+               r = SetWindowLongPtrA(hWnd, nIndex, dwNewLong);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
 LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
 {\r
        LRESULT r = 0;\r
 START_ROUTINE\r
-       // WNDPROCがShift_JIS用であるため\r
        if(IsWindowUnicode(hWnd))\r
                r = DefWindowProcW(hWnd, Msg, wParam, lParam);\r
        else\r
@@ -749,7 +1015,6 @@ LRESULT CallWindowProcM(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wPara
 {\r
        LRESULT r = 0;\r
 START_ROUTINE\r
-       // WNDPROCがShift_JIS用であるため\r
        if(IsWindowUnicode(hWnd))\r
                r = CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
        else\r
@@ -1718,6 +1983,51 @@ END_ROUTINE
        return r;\r
 }\r
 \r
+BOOL ShellExecuteExM(LPSHELLEXECUTEINFOA lpExecInfo)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+       wchar_t* pw4 = NULL;\r
+       SHELLEXECUTEINFOW wExecInfo;\r
+START_ROUTINE\r
+       wExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);\r
+       wExecInfo.fMask = lpExecInfo->fMask;\r
+       wExecInfo.hwnd = lpExecInfo->hwnd;\r
+       pw0 = DuplicateMtoW(lpExecInfo->lpVerb, -1);\r
+       wExecInfo.lpVerb = pw0;\r
+       pw1 = DuplicateMtoW(lpExecInfo->lpFile, -1);\r
+       wExecInfo.lpFile = pw1;\r
+       pw2 = DuplicateMtoW(lpExecInfo->lpParameters, -1);\r
+       wExecInfo.lpParameters = pw2;\r
+       pw3 = DuplicateMtoW(lpExecInfo->lpDirectory, -1);\r
+       wExecInfo.lpDirectory = pw3;\r
+       wExecInfo.nShow = lpExecInfo->nShow;\r
+       wExecInfo.hInstApp = lpExecInfo->hInstApp;\r
+       wExecInfo.lpIDList = lpExecInfo->lpIDList;\r
+       if(lpExecInfo->fMask & SEE_MASK_CLASSNAME)\r
+       {\r
+               pw4 = DuplicateMtoW(lpExecInfo->lpClass, -1);\r
+               wExecInfo.lpClass = pw4;\r
+       }\r
+       wExecInfo.hkeyClass = lpExecInfo->hkeyClass;\r
+       wExecInfo.dwHotKey = lpExecInfo->dwHotKey;\r
+       wExecInfo.hIcon = lpExecInfo->hIcon;\r
+       wExecInfo.hProcess = lpExecInfo->hProcess;\r
+       r = ShellExecuteExW(&wExecInfo);\r
+       lpExecInfo->hInstApp = wExecInfo.hInstApp;\r
+       lpExecInfo->hProcess = wExecInfo.hProcess;\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       FreeDuplicatedString(pw4);\r
+       return r;\r
+}\r
+\r
 PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)\r
 {\r
        PIDLIST_ABSOLUTE r = NULL;\r
@@ -1789,6 +2099,26 @@ END_ROUTINE
        return r;\r
 }\r
 \r
+DWORD_PTR SHGetFileInfoM(LPCSTR pszPath, DWORD dwFileAttributes, SHFILEINFOA *psfi, UINT cbFileInfo, UINT uFlags)\r
+{\r
+       DWORD_PTR r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       SHFILEINFOW wsfi;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoWMultiString(pszPath);\r
+       if((r = SHGetFileInfoW(pw0, dwFileAttributes, &wsfi, cbFileInfo, uFlags)) != 0)\r
+       {\r
+               psfi->hIcon = wsfi.hIcon;\r
+               psfi->iIcon = wsfi.iIcon;\r
+               psfi->dwAttributes = wsfi.dwAttributes;\r
+               WtoM(psfi->szDisplayName, MAX_PATH, wsfi.szDisplayName, -1);\r
+               WtoM(psfi->szTypeName, 80, wsfi.szTypeName, -1);\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)\r
 {\r
        int r = 0;\r
@@ -1872,6 +2202,7 @@ BOOL ChooseFontM(LPCHOOSEFONTA v0)
 {\r
        BOOL r = FALSE;\r
        wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
        CHOOSEFONTW a0;\r
        LOGFONTW* pwlf;\r
 START_ROUTINE\r
@@ -1904,9 +2235,11 @@ START_ROUTINE
        a0.rgbColors = v0->rgbColors;\r
        a0.lCustData = v0->lCustData;\r
        a0.lpfnHook = v0->lpfnHook;\r
-       a0.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
+       pw0 = DuplicateMtoW(v0->lpTemplateName, -1);\r
+       a0.lpTemplateName = pw0;\r
        a0.hInstance = v0->hInstance;\r
-       a0.lpszStyle = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);\r
+       pw1 = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);\r
+       a0.lpszStyle = pw1;\r
        a0.nFontType = v0->nFontType;\r
        a0.nSizeMin = v0->nSizeMin;\r
        a0.nSizeMax = v0->nSizeMax;\r
@@ -1930,15 +2263,14 @@ START_ROUTINE
                TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);\r
        }\r
        v0->rgbColors = a0.rgbColors;\r
-       WtoM(v0->lpszStyle, LF_FACESIZE, a0.lpszStyle, -1);\r
+       WtoM(v0->lpszStyle, LF_FACESIZE, pw1, -1);\r
        TerminateStringM(v0->lpszStyle, LF_FACESIZE);\r
        v0->nFontType = a0.nFontType;\r
        if(pwlf)\r
                free(pwlf);\r
-       FreeDuplicatedString((void*)a0.lpTemplateName);\r
-       FreeDuplicatedString(a0.lpszStyle);\r
 END_ROUTINE\r
        FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
        return r;\r
 }\r
 \r
@@ -2021,9 +2353,36 @@ END_ROUTINE
        return r;\r
 }\r
 \r
+BOOL MoveFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)\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 = MoveFileW(pw0, pw1);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+BOOL DeleteFileM(LPCSTR lpFileName)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = DeleteFileW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
 int mkdirM(const char * _Path)\r
 {\r
-       int r = 0;\r
+       int r = -1;\r
        wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
        pw0 = DuplicateMtoW(_Path, -1);\r
@@ -2035,7 +2394,7 @@ END_ROUTINE
 \r
 int _mkdirM(const char * _Path)\r
 {\r
-       int r = 0;\r
+       int r = -1;\r
        wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
        pw0 = DuplicateMtoW(_Path, -1);\r
@@ -2047,7 +2406,7 @@ END_ROUTINE
 \r
 int rmdirM(const char * _Path)\r
 {\r
-       int r = 0;\r
+       int r = -1;\r
        wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
        pw0 = DuplicateMtoW(_Path, -1);\r
@@ -2059,7 +2418,7 @@ END_ROUTINE
 \r
 int _rmdirM(const char * _Path)\r
 {\r
-       int r = 0;\r
+       int r = -1;\r
        wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
        pw0 = DuplicateMtoW(_Path, -1);\r
@@ -2069,165 +2428,168 @@ END_ROUTINE
        return r;\r
 }\r
 \r
-size_t _mbslenM(const unsigned char * _Str)\r
+int removeM(const char * _Filename)\r
 {\r
-       size_t r = 0;\r
+       int r = -1;\r
        wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       r = wcslen(pw0);\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, NULL, &_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
-       wchar_t* pw0 = NULL;\r
-       wchar_t* wr;\r
+       unsigned int c;\r
+       unsigned char* p;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       // TODO: 非ASCII文字の対応\r
-       wr = wcschr(pw0, _Ch);\r
-       if(wr)\r
+       while((c = GetNextCharM(_Str, NULL, &p)) > 0)\r
        {\r
-               *wr = L'\0';\r
-               r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
+               if(c == _Ch)\r
+                       break;\r
+               _Str = p;\r
        }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
 {\r
        unsigned char* r = NULL;\r
-       wchar_t* pw0 = NULL;\r
-       wchar_t* wr;\r
+       unsigned int c;\r
+       unsigned char* p;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       // TODO: 非ASCII文字の対応\r
-       wr = wcsrchr(pw0, _Ch);\r
-       if(wr)\r
+       while((c = GetNextCharM(_Str, NULL, &p)) > 0)\r
        {\r
-               *wr = L'\0';\r
-               r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\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
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
 {\r
        unsigned char* r = NULL;\r
-       wchar_t* pw0 = NULL;\r
-       wchar_t* pw1 = NULL;\r
-       wchar_t* wr;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       pw1 = DuplicateMtoW(_Substr, -1);\r
-       wr = wcsstr(pw0, pw1);\r
-       if(wr)\r
-       {\r
-               *wr = L'\0';\r
-               r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
-       }\r
+       r = strstr(_Str, _Substr);\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
-       FreeDuplicatedString(pw1);\r
        return r;\r
 }\r
 \r
 int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
 {\r
        int r = 0;\r
-       wchar_t* pw0 = NULL;\r
-       wchar_t* pw1 = NULL;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str1, -1);\r
-       pw1 = DuplicateMtoW(_Str2, -1);\r
-       r = wcscmp(pw0, pw1);\r
+       r = strcmp(_Str1, _Str2);\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
-       FreeDuplicatedString(pw1);\r
        return r;\r
 }\r
 \r
 int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
 {\r
        int r = 0;\r
-       wchar_t* pw0 = NULL;\r
-       wchar_t* pw1 = NULL;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str1, -1);\r
-       pw1 = DuplicateMtoW(_Str2, -1);\r
-       r = _wcsicmp(pw0, pw1);\r
+       r = _stricmp(_Str1, _Str2);\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
-       FreeDuplicatedString(pw1);\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
-       wchar_t* pw0 = NULL;\r
-       wchar_t* pw1 = NULL;\r
+       DWORD c1;\r
+       DWORD c2;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str1, -1);\r
-       pw1 = DuplicateMtoW(_Str2, -1);\r
-       r = wcsncmp(pw0, pw1, _MaxCount);\r
+       c1 = 0;\r
+       c2 = 0;\r
+       while(_MaxCount > 0)\r
+       {\r
+               c1 = GetNextCharM(_Str1, NULL, &_Str1);\r
+               c2 = GetNextCharM(_Str2, NULL, &_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
-       FreeDuplicatedString(pw0);\r
-       FreeDuplicatedString(pw1);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbslwrM(unsigned char * _String)\r
 {\r
        unsigned char* r = NULL;\r
-       wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_String, -1);\r
-       _wcslwr(pw0);\r
-       r = _String;\r
-       WtoM(_String, strlen(_String) + 1, pw0, -1);\r
+       r = _strlwr(_String);\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbsuprM(unsigned char * _String)\r
 {\r
        unsigned char* r = NULL;\r
-       wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_String, -1);\r
-       _wcsupr(pw0);\r
-       r = _String;\r
-       WtoM(_String, strlen(_String) + 1, pw0, -1);\r
+       r = _strupr(_String);\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
 {\r
        unsigned char* r = NULL;\r
-       wchar_t* pw0 = NULL;\r
-       wchar_t* wr;\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       wr = _wcsninc(pw0, _Count);\r
-       if(wr)\r
+       while(_Count > 0 && GetNextCharM(_Str, NULL, &_Str) > 0)\r
        {\r
-               *wr = L'\0';\r
-               r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
+               _Count--;\r
        }\r
+       r = (unsigned char*)_Str;\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r