X-Git-Url: http://git.sourceforge.jp/view?p=ffftp%2Fffftp.git;a=blobdiff_plain;f=mbswrapper.c;h=62b21127b8d23fc84dfec5cac59a91fbeb93afa2;hp=771bcc9cc441f48eb9de1a92a0fa44d1b7ac419a;hb=619b82a7a7f0c24da339c76ef9a102960ce928b0;hpb=93f66de680facd0f7ef9c9b0c1383e1d5c0b5dac diff --git a/mbswrapper.c b/mbswrapper.c index 771bcc9..62b2112 100644 --- a/mbswrapper.c +++ b/mbswrapper.c @@ -7,6 +7,7 @@ #define UNICODE #define _UNICODE +#include #include #include #include @@ -387,6 +388,180 @@ char* DuplicateWtoA(LPCWSTR lpString, int c) return p; } +// マルチバイト文字列からコードポイントと次のポインタを取得 +// エンコードが不正な場合は0x80000000を返す +DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext) +{ + DWORD Code; + int i; + Code = 0; + if((*lpString & 0xfe) == 0xfc) + { + i = 5; + Code |= (DWORD)*lpString & 0x01; + } + else if((*lpString & 0xfc) == 0xf8) + { + i = 4; + Code |= (DWORD)*lpString & 0x03; + } + else if((*lpString & 0xf8) == 0xf0) + { + i = 3; + Code |= (DWORD)*lpString & 0x07; + } + else if((*lpString & 0xf0) == 0xe0) + { + i = 2; + Code |= (DWORD)*lpString & 0x0f; + } + else if((*lpString & 0xe0) == 0xc0) + { + i = 1; + Code |= (DWORD)*lpString & 0x1f; + } + else if((*lpString & 0x80) == 0x00) + { + i = 0; + Code |= (DWORD)*lpString & 0x7f; + } + else + i = -1; + lpString++; + while((*lpString & 0xc0) == 0x80) + { + i--; + Code = Code << 6; + Code |= (DWORD)*lpString & 0x3f; + lpString++; + } + if(i != 0) + Code = 0x80000000; + if(ppNext) + *ppNext = lpString; + return Code; +} + +// マルチバイト文字列の冗長表現を修正 +// 修正があればTRUEを返す +// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能 +BOOL FixStringM(LPSTR pDst, LPCSTR pSrc) +{ + BOOL bResult; + char* p; + DWORD Code; + int i; + char c; + bResult = FALSE; + p = (char*)pSrc; + while(*pSrc != '\0') + { + Code = GetNextCharM(pSrc, &pSrc); + if(Code & 0x80000000) + continue; + else if(Code & 0x7c000000) + { + i = 5; + c = (char)(0xfc | (Code >> (6 * i))); + } + else if(Code & 0x03e00000) + { + i = 4; + c = (char)(0xf8 | (Code >> (6 * i))); + } + else if(Code & 0x001f0000) + { + i = 3; + c = (char)(0xf0 | (Code >> (6 * i))); + } + else if(Code & 0x0000f800) + { + i = 2; + c = (char)(0xe0 | (Code >> (6 * i))); + } + else if(Code & 0x00000780) + { + i = 1; + c = (char)(0xc0 | (Code >> (6 * i))); + } + else + { + i = 0; + c = (char)Code; + } + if(c != *p) + bResult = TRUE; + p++; + *pDst = c; + pDst++; + while(i > 0) + { + i--; + c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f)); + if(c != *p) + bResult = TRUE; + p++; + *pDst = c; + pDst++; + } + } + if(*p != '\0') + bResult = TRUE; + *pDst = '\0'; + return bResult; +} + +// NULL区切りマルチバイト文字列の冗長表現を修正 +// 修正があればTRUEを返す +// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能 +BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc) +{ + BOOL bResult; + int Length; + bResult = FALSE; + while(*pSrc != '\0') + { + Length = strlen(pSrc) + 1; + bResult = bResult | FixStringM(pDst, pSrc); + pSrc += Length; + pDst += strlen(pDst) + 1; + } + *pDst = '\0'; + return bResult; +} + +// マルチバイト文字列の冗長表現を確認 +// 冗長表現があればTRUEを返す +BOOL CheckStringM(LPCSTR lpString) +{ + BOOL bResult; + char* p; + bResult = FALSE; + p = AllocateStringM(strlen(lpString) + 1); + if(p) + { + bResult = FixStringM(p, lpString); + FreeDuplicatedString(p); + } + return bResult; +} + +// NULL区切りマルチバイト文字列の冗長表現を確認 +// 冗長表現があればTRUEを返す +BOOL CheckMultiStringM(LPCSTR lpString) +{ + BOOL bResult; + char* p; + bResult = FALSE; + p = AllocateStringM(GetMultiStringLengthM(lpString) + 1); + if(p) + { + bResult = FixMultiStringM(p, lpString); + FreeDuplicatedString(p); + } + return bResult; +} + // 文字列用に確保したメモリを開放 // リソースIDならば何もしない void FreeDuplicatedString(void* p) @@ -548,7 +723,7 @@ END_ROUTINE LONG GetWindowLongM(HWND hWnd, int nIndex) { - LRESULT r = 0; + LONG r = 0; START_ROUTINE // WNDPROCがShift_JIS用であるため if(IsWindowUnicode(hWnd)) @@ -561,7 +736,7 @@ END_ROUTINE LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong) { - LRESULT r = 0; + LONG r = 0; START_ROUTINE // WNDPROCがShift_JIS用であるため if(IsWindowUnicode(hWnd)) @@ -572,6 +747,32 @@ END_ROUTINE return r; } +LONG_PTR GetWindowLongPtrM(HWND hWnd, int nIndex) +{ + LONG_PTR r = 0; +START_ROUTINE + // WNDPROCがShift_JIS用であるため + if(IsWindowUnicode(hWnd)) + r = GetWindowLongPtrW(hWnd, nIndex); + else + r = GetWindowLongPtrA(hWnd, nIndex); +END_ROUTINE + return r; +} + +LONG_PTR SetWindowLongPtrM(HWND hWnd, int nIndex, LONG_PTR dwNewLong) +{ + LONG_PTR r = 0; +START_ROUTINE + // WNDPROCがShift_JIS用であるため + if(IsWindowUnicode(hWnd)) + r = SetWindowLongPtrW(hWnd, nIndex, dwNewLong); + else + r = SetWindowLongPtrA(hWnd, nIndex, dwNewLong); +END_ROUTINE + return r; +} + LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT r = 0; @@ -1558,6 +1759,51 @@ END_ROUTINE return r; } +BOOL ShellExecuteExM(LPSHELLEXECUTEINFOA lpExecInfo) +{ + BOOL r = FALSE; + wchar_t* pw0 = NULL; + wchar_t* pw1 = NULL; + wchar_t* pw2 = NULL; + wchar_t* pw3 = NULL; + wchar_t* pw4 = NULL; + SHELLEXECUTEINFOW wExecInfo; +START_ROUTINE + wExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW); + wExecInfo.fMask = lpExecInfo->fMask; + wExecInfo.hwnd = lpExecInfo->hwnd; + pw0 = DuplicateMtoW(lpExecInfo->lpVerb, -1); + wExecInfo.lpVerb = pw0; + pw1 = DuplicateMtoW(lpExecInfo->lpFile, -1); + wExecInfo.lpFile = pw1; + pw2 = DuplicateMtoW(lpExecInfo->lpParameters, -1); + wExecInfo.lpParameters = pw2; + pw3 = DuplicateMtoW(lpExecInfo->lpDirectory, -1); + wExecInfo.lpDirectory = pw3; + wExecInfo.nShow = lpExecInfo->nShow; + wExecInfo.hInstApp = lpExecInfo->hInstApp; + wExecInfo.lpIDList = lpExecInfo->lpIDList; + if(lpExecInfo->fMask & SEE_MASK_CLASSNAME) + { + pw4 = DuplicateMtoW(lpExecInfo->lpClass, -1); + wExecInfo.lpClass = pw4; + } + wExecInfo.hkeyClass = lpExecInfo->hkeyClass; + wExecInfo.dwHotKey = lpExecInfo->dwHotKey; + wExecInfo.hIcon = lpExecInfo->hIcon; + wExecInfo.hProcess = lpExecInfo->hProcess; + r = ShellExecuteExW(&wExecInfo); + lpExecInfo->hInstApp = wExecInfo.hInstApp; + lpExecInfo->hProcess = wExecInfo.hProcess; +END_ROUTINE + FreeDuplicatedString(pw0); + FreeDuplicatedString(pw1); + FreeDuplicatedString(pw2); + FreeDuplicatedString(pw3); + FreeDuplicatedString(pw4); + return r; +} + PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi) { PIDLIST_ABSOLUTE r = NULL; @@ -1808,7 +2054,7 @@ END_ROUTINE BOOL sndPlaySoundM(LPCSTR pszSound, UINT fuSound) { - HWND r = NULL; + BOOL r = FALSE; wchar_t* pw0 = NULL; START_ROUTINE pw0 = DuplicateMtoW(pszSound, -1); @@ -1818,6 +2064,49 @@ END_ROUTINE return r; } +HANDLE SetClipboardDataM(UINT uFormat, HANDLE hMem) +{ + HANDLE r = NULL; + char* p; + int Length; + int BufferLength; + HGLOBAL hBufferMem; +START_ROUTINE + if(uFormat == CF_TEXT) + { + p = (char*)GlobalLock(hMem); + Length = (int)GlobalSize(hMem); + BufferLength = MtoW(NULL, 0, p, Length); + if(hBufferMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * BufferLength)) + { + MtoW((LPWSTR)GlobalLock(hBufferMem), BufferLength, p, Length); + GlobalUnlock(hBufferMem); + r = SetClipboardData(CF_UNICODETEXT, hBufferMem); + } + GlobalUnlock(hMem); + GlobalFree(hMem); + } + else + r = SetClipboardData(uFormat, hMem); +END_ROUTINE + return r; +} + +BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists) +{ + BOOL r = FALSE; + wchar_t* pw0 = NULL; + wchar_t* pw1 = NULL; +START_ROUTINE + pw0 = DuplicateMtoW(lpExistingFileName, -1); + pw1 = DuplicateMtoW(lpNewFileName, -1); + r = CopyFileW(pw0, pw1, bFailIfExists); +END_ROUTINE + FreeDuplicatedString(pw0); + FreeDuplicatedString(pw1); + return r; +} + int mkdirM(const char * _Path) { int r = 0; @@ -1869,162 +2158,129 @@ END_ROUTINE size_t _mbslenM(const unsigned char * _Str) { size_t r = 0; - wchar_t* pw0 = NULL; START_ROUTINE - pw0 = DuplicateMtoW(_Str, -1); - r = wcslen(pw0); + while(GetNextCharM(_Str, &_Str) > 0) + { + r++; + } END_ROUTINE - FreeDuplicatedString(pw0); return r; } unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch) { unsigned char* r = NULL; - wchar_t* pw0 = NULL; - wchar_t* wr; + unsigned int c; + unsigned char* p; START_ROUTINE - pw0 = DuplicateMtoW(_Str, -1); - // TODO: 非ASCII文字の対応 - wr = wcschr(pw0, _Ch); - if(wr) + while((c = GetNextCharM(_Str, &p)) > 0) { - *wr = L'\0'; - r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1; + if(c == _Ch) + break; + _Str = p; } + if(c == _Ch) + r = (unsigned char*)_Str; END_ROUTINE - FreeDuplicatedString(pw0); return r; } unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch) { unsigned char* r = NULL; - wchar_t* pw0 = NULL; - wchar_t* wr; + unsigned int c; + unsigned char* p; START_ROUTINE - pw0 = DuplicateMtoW(_Str, -1); - // TODO: 非ASCII文字の対応 - wr = wcsrchr(pw0, _Ch); - if(wr) + while((c = GetNextCharM(_Str, &p)) > 0) { - *wr = L'\0'; - r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1; + if(c == _Ch) + r = (unsigned char*)_Str; + _Str = p; } + if(c == _Ch) + r = (unsigned char*)_Str; END_ROUTINE - FreeDuplicatedString(pw0); return r; } unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr) { unsigned char* r = NULL; - wchar_t* pw0 = NULL; - wchar_t* pw1 = NULL; - wchar_t* wr; START_ROUTINE - pw0 = DuplicateMtoW(_Str, -1); - pw1 = DuplicateMtoW(_Substr, -1); - wr = wcsstr(pw0, pw1); - if(wr) - { - *wr = L'\0'; - r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1; - } + r = strstr(_Str, _Substr); END_ROUTINE - FreeDuplicatedString(pw0); - FreeDuplicatedString(pw1); return r; } int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2) { int r = 0; - wchar_t* pw0 = NULL; - wchar_t* pw1 = NULL; START_ROUTINE - pw0 = DuplicateMtoW(_Str1, -1); - pw1 = DuplicateMtoW(_Str2, -1); - r = wcscmp(pw0, pw1); + r = strcmp(_Str1, _Str2); END_ROUTINE - FreeDuplicatedString(pw0); - FreeDuplicatedString(pw1); return r; } int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2) { int r = 0; - wchar_t* pw0 = NULL; - wchar_t* pw1 = NULL; START_ROUTINE - pw0 = DuplicateMtoW(_Str1, -1); - pw1 = DuplicateMtoW(_Str2, -1); - r = _wcsicmp(pw0, pw1); + r = _stricmp(_Str1, _Str2); END_ROUTINE - FreeDuplicatedString(pw0); - FreeDuplicatedString(pw1); return r; } int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount) { int r = 0; - wchar_t* pw0 = NULL; - wchar_t* pw1 = NULL; + DWORD c1; + DWORD c2; START_ROUTINE - pw0 = DuplicateMtoW(_Str1, -1); - pw1 = DuplicateMtoW(_Str2, -1); - r = wcsncmp(pw0, pw1, _MaxCount); + c1 = 0; + c2 = 0; + while(_MaxCount > 0) + { + c1 = GetNextCharM(_Str1, &_Str1); + c2 = GetNextCharM(_Str2, &_Str2); + if(c1 != c2) + break; + _MaxCount--; + if(c1 == 0 || c2 == 0) + break; + } + r = c1 - c2; END_ROUTINE - FreeDuplicatedString(pw0); - FreeDuplicatedString(pw1); return r; } unsigned char * _mbslwrM(unsigned char * _String) { unsigned char* r = NULL; - wchar_t* pw0 = NULL; START_ROUTINE - pw0 = DuplicateMtoW(_String, -1); - _wcslwr(pw0); - r = _String; - WtoM(_String, strlen(_String) + 1, pw0, -1); + r = _strlwr(_String); END_ROUTINE - FreeDuplicatedString(pw0); return r; } unsigned char * _mbsuprM(unsigned char * _String) { unsigned char* r = NULL; - wchar_t* pw0 = NULL; START_ROUTINE - pw0 = DuplicateMtoW(_String, -1); - _wcsupr(pw0); - r = _String; - WtoM(_String, strlen(_String) + 1, pw0, -1); + r = _strupr(_String); END_ROUTINE - FreeDuplicatedString(pw0); return r; } unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count) { unsigned char* r = NULL; - wchar_t* pw0 = NULL; - wchar_t* wr; START_ROUTINE - pw0 = DuplicateMtoW(_Str, -1); - wr = _wcsninc(pw0, _Count); - if(wr) + while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0) { - *wr = L'\0'; - r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1; + _Count--; } + r = (unsigned char*)_Str; END_ROUTINE - FreeDuplicatedString(pw0); return r; }