OSDN Git Service

Change the character code of windows into UTF-16 completely.
[ffftp/ffftp.git] / mbswrapper.c
index 25e603d..62b2112 100644 (file)
@@ -7,6 +7,7 @@
 #define UNICODE\r
 #define _UNICODE\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 <tchar.h>\r
 #include <direct.h>\r
 #include <windows.h>\r
@@ -387,6 +388,180 @@ char* DuplicateWtoA(LPCWSTR lpString, int c)
        return p;\r
 }\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
 // リソースIDならば何もしない\r
 void FreeDuplicatedString(void* p)\r
@@ -548,7 +723,7 @@ END_ROUTINE
 \r
 LONG GetWindowLongM(HWND hWnd, int nIndex)\r
 {\r
 \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
 START_ROUTINE\r
        // WNDPROCがShift_JIS用であるため\r
        if(IsWindowUnicode(hWnd))\r
@@ -561,7 +736,7 @@ END_ROUTINE
 \r
 LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)\r
 {\r
 \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
 START_ROUTINE\r
        // WNDPROCがShift_JIS用であるため\r
        if(IsWindowUnicode(hWnd))\r
@@ -572,6 +747,32 @@ END_ROUTINE
        return r;\r
 }\r
 \r
        return r;\r
 }\r
 \r
+LONG_PTR GetWindowLongPtrM(HWND hWnd, int nIndex)\r
+{\r
+       LONG_PTR r = 0;\r
+START_ROUTINE\r
+       // WNDPROCがShift_JIS用であるため\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
+       // WNDPROCがShift_JIS用であるため\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
 LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
 {\r
        LRESULT r = 0;\r
@@ -1558,6 +1759,51 @@ END_ROUTINE
        return r;\r
 }\r
 \r
        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
 PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)\r
 {\r
        PIDLIST_ABSOLUTE r = NULL;\r
@@ -1806,6 +2052,61 @@ END_ROUTINE
        return r;\r
 }\r
 \r
        return r;\r
 }\r
 \r
+BOOL sndPlaySoundM(LPCSTR pszSound, UINT fuSound)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(pszSound, -1);\r
+       r = sndPlaySoundW(pw0, fuSound);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+HANDLE SetClipboardDataM(UINT uFormat, HANDLE hMem)\r
+{\r
+       HANDLE r = NULL;\r
+       char* p;\r
+       int Length;\r
+       int BufferLength;\r
+       HGLOBAL hBufferMem;\r
+START_ROUTINE\r
+       if(uFormat == CF_TEXT)\r
+       {\r
+               p = (char*)GlobalLock(hMem);\r
+               Length = (int)GlobalSize(hMem);\r
+               BufferLength = MtoW(NULL, 0, p, Length);\r
+               if(hBufferMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * BufferLength))\r
+               {\r
+                       MtoW((LPWSTR)GlobalLock(hBufferMem), BufferLength, p, Length);\r
+                       GlobalUnlock(hBufferMem);\r
+                       r = SetClipboardData(CF_UNICODETEXT, hBufferMem);\r
+               }\r
+               GlobalUnlock(hMem);\r
+               GlobalFree(hMem);\r
+       }\r
+       else\r
+               r = SetClipboardData(uFormat, hMem);\r
+END_ROUTINE\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 = 0;\r
 int mkdirM(const char * _Path)\r
 {\r
        int r = 0;\r
@@ -1857,162 +2158,129 @@ END_ROUTINE
 size_t _mbslenM(const unsigned char * _Str)\r
 {\r
        size_t r = 0;\r
 size_t _mbslenM(const unsigned char * _Str)\r
 {\r
        size_t r = 0;\r
-       wchar_t* pw0 = NULL;\r
 START_ROUTINE\r
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       r = wcslen(pw0);\r
+       while(GetNextCharM(_Str, &_Str) > 0)\r
+       {\r
+               r++;\r
+       }\r
 END_ROUTINE\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
 {\r
        unsigned char* r = NULL;\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
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       // TODO: 非ASCII文字の対応\r
-       wr = wcschr(pw0, _Ch);\r
-       if(wr)\r
+       while((c = GetNextCharM(_Str, &p)) > 0)\r
        {\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
        }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
 END_ROUTINE\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
        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
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       // TODO: 非ASCII文字の対応\r
-       wr = wcsrchr(pw0, _Ch);\r
-       if(wr)\r
+       while((c = GetNextCharM(_Str, &p)) > 0)\r
        {\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
        }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
 END_ROUTINE\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
        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
 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
 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
        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
 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
 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
        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
 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
 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
        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
 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, &_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
 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
        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
 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
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
 unsigned char * _mbsuprM(unsigned char * _String)\r
 {\r
        unsigned char* r = NULL;\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
 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
 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
        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
 START_ROUTINE\r
-       pw0 = DuplicateMtoW(_Str, -1);\r
-       wr = _wcsninc(pw0, _Count);\r
-       if(wr)\r
+       while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
        {\r
        {\r
-               *wr = L'\0';\r
-               r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
+               _Count--;\r
        }\r
        }\r
+       r = (unsigned char*)_Str;\r
 END_ROUTINE\r
 END_ROUTINE\r
-       FreeDuplicatedString(pw0);\r
        return r;\r
 }\r
 \r
        return r;\r
 }\r
 \r