diff --git a/ThunksList.md b/ThunksList.md index 34f7f82..44734d9 100644 --- a/ThunksList.md +++ b/ThunksList.md @@ -530,6 +530,7 @@ | GetCalendarInfoEx | 不存在时,调用GetCalendarInfoW。 | GetNLSVersionEx | 不存在时,返回一个假版本。 | IsNLSDefinedString | 不存在时,调用GetStringTypeW。 +| FindNLSStringEx | 调用 CompareStringW。 | SetProcessWorkingSetSizeEx | 不存在时,调用SetProcessWorkingSetSize。 | GetProcessWorkingSetSizeEx | 不存在时,调用GetProcessWorkingSetSize。 | GetTimeZoneInformationForYear | 不存在时,直接读取`Time Zones`注册表。 diff --git a/src/Thunks/api-ms-win-core-localization.hpp b/src/Thunks/api-ms-win-core-localization.hpp index 3fe00b9..db2266a 100644 --- a/src/Thunks/api-ms-win-core-localization.hpp +++ b/src/Thunks/api-ms-win-core-localization.hpp @@ -2537,4 +2537,138 @@ } #endif + + +#if (YY_Thunks_Target < __WindowsNT6) + + // 最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用] + // 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 40, + int, + WINAPI, + FindNLSStringEx, + _In_opt_ LPCWSTR _szLocaleName, + _In_ DWORD _fFindNLSStringFlags, + _In_reads_(_cchSource) LPCWSTR _szStringSource, + _In_ int _cchSource, + _In_reads_(_cchValue) LPCWSTR _szStringValue, + _In_ int _cchValue, + _Out_opt_ LPINT _pcchFound, + _In_opt_ LPNLSVERSIONINFO _pVersionInformation, + _In_opt_ LPVOID _pReserved, + _In_opt_ LPARAM _hSortHandle + ) + { + if (auto const _pfnFindNLSStringEx = try_get_FindNLSStringEx()) + { + return _pfnFindNLSStringEx(_szLocaleName, _fFindNLSStringFlags, _szStringSource, _cchSource, _szStringValue, _cchValue, _pcchFound, _pVersionInformation, _pReserved, _hSortHandle); + } + + __WarningMessage__("FindNLSStringEx 暂时只支持搜索 _cchValue 的子字符串。"); + + if (_pVersionInformation || _pReserved|| _hSortHandle + || _szStringSource == nullptr || _cchSource == 0 || _cchSource < -1 + || _szStringValue == nullptr || _cchValue == 0 || _cchValue < -1) + { + SetLastError(ERROR_INVALID_PARAMETER); + return -1; + } + + const auto _Locale = LocaleNameToLCID(_szLocaleName, 0); + if (_Locale == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return -1; + } + + if (_cchSource == -1) + { + _cchSource = wcslen(_szStringSource); + } + + if (_cchValue == -1) + { + _cchValue = wcslen(_szStringValue); + } + + if (_cchSource < _cchValue) + return -1; + + const DWORD _fCmpFlags = _fFindNLSStringFlags & ~(FIND_STARTSWITH | FIND_ENDSWITH | FIND_FROMSTART | FIND_FROMEND); + if (_fFindNLSStringFlags & (FIND_FROMSTART | FIND_STARTSWITH)) + { + // 从头开始搜索 + if (_fFindNLSStringFlags & FIND_STARTSWITH) + { + const auto _nResult = CompareStringW(_Locale, _fCmpFlags, _szStringSource, _cchValue, _szStringValue, _cchValue); + if (_nResult == CSTR_EQUAL) + { + if (_pcchFound) + *_pcchFound = _cchValue; + + return 0; + } + } + else + { + auto _szStr = _szStringSource; + auto _szStrEnd = _szStringSource + _cchSource - _cchValue + 1; + for (; _szStr != _szStrEnd;++_szStr) + { + const auto _nResult = CompareStringW(_Locale, _fCmpFlags, _szStr, _cchValue, _szStringValue, _cchValue); + if (_nResult == 0) + return -1; + + if (_nResult == CSTR_EQUAL) + { + if (_pcchFound) + *_pcchFound = _cchValue; + + return _szStr - _szStringSource; + } + } + } + } + else + { + // 反向搜索 + auto _szStr = _szStringSource + _cchSource - _cchValue; + if (_fFindNLSStringFlags & FIND_ENDSWITH) + { + const auto _nResult = CompareStringW(_Locale, _fCmpFlags, _szStr, _cchValue, _szStringValue, _cchValue); + if (_nResult == CSTR_EQUAL) + { + if (_pcchFound) + *_pcchFound = _cchValue; + + return _szStr - _szStringSource; + } + } + else + { + for(;; --_szStr) + { + const auto _nResult = CompareStringW(_Locale, _fCmpFlags, _szStr, _cchValue, _szStringValue, _cchValue); + if (_nResult == 0) + return -1; + + if (_nResult == CSTR_EQUAL) + { + if (_pcchFound) + *_pcchFound = _cchValue; + + return _szStr - _szStringSource; + } + + if (_szStr == _szStringSource) + break; + } + } + } + + return -1; + } +#endif } //namespace YY diff --git a/src/YY-Thunks.UnitTest/api-ms-win-core-localization.UnitTest.cpp b/src/YY-Thunks.UnitTest/api-ms-win-core-localization.UnitTest.cpp index d5f9aea..8469d8b 100644 --- a/src/YY-Thunks.UnitTest/api-ms-win-core-localization.UnitTest.cpp +++ b/src/YY-Thunks.UnitTest/api-ms-win-core-localization.UnitTest.cpp @@ -411,369 +411,455 @@ namespace api_ms_win_core_localization } }; - TEST_CLASS(GetThreadPreferredUILanguages) - { + TEST_CLASS(GetThreadPreferredUILanguages) + { AwaysNullGuard Guard; - public: - GetThreadPreferredUILanguages() - { + public: + GetThreadPreferredUILanguages() + { Guard |= YY::Thunks::aways_null_try_get_GetThreadPreferredUILanguages; - } + } - TEST_METHOD(无效参数验证) - { - wchar_t szLanguagesBuffer[512]; - ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); - ULONG ulNumLanguages = 0; + TEST_METHOD(无效参数验证) + { + wchar_t szLanguagesBuffer[512]; + ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); + ULONG ulNumLanguages = 0; - //pulNumLanguages 不能为 nullptr - auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, nullptr, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsFalse(bRet); + //pulNumLanguages 不能为 nullptr + auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, nullptr, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsFalse(bRet); - cchLanguagesBuffer = _countof(szLanguagesBuffer); - //pwszLanguagesBuffer 为nullptr 时, pcchLanguagesBuffer 必须为 0 - bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, nullptr, &cchLanguagesBuffer); - Assert::IsFalse(bRet); + cchLanguagesBuffer = _countof(szLanguagesBuffer); + //pwszLanguagesBuffer 为nullptr 时, pcchLanguagesBuffer 必须为 0 + bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, nullptr, &cchLanguagesBuffer); + Assert::IsFalse(bRet); - //pcchLanguagesBuffer不能为 nullptr - bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, szLanguagesBuffer, nullptr); - Assert::IsFalse(bRet); + //pcchLanguagesBuffer不能为 nullptr + bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, szLanguagesBuffer, nullptr); + Assert::IsFalse(bRet); - //MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID不能同时使用 - cchLanguagesBuffer = _countof(szLanguagesBuffer); - bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsFalse(bRet); + //MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID不能同时使用 + cchLanguagesBuffer = _countof(szLanguagesBuffer); + bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsFalse(bRet); - //MUI_MERGE_SYSTEM_FALLBACK | MUI_THREAD_LANGUAGES不能同时使用 - cchLanguagesBuffer = _countof(szLanguagesBuffer); - bRet = ::GetThreadPreferredUILanguages(MUI_MERGE_SYSTEM_FALLBACK | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsFalse(bRet); + //MUI_MERGE_SYSTEM_FALLBACK | MUI_THREAD_LANGUAGES不能同时使用 + cchLanguagesBuffer = _countof(szLanguagesBuffer); + bRet = ::GetThreadPreferredUILanguages(MUI_MERGE_SYSTEM_FALLBACK | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsFalse(bRet); - //MUI_MERGE_USER_FALLBACK | MUI_THREAD_LANGUAGES不能同时使用 - cchLanguagesBuffer = _countof(szLanguagesBuffer); - bRet = ::GetThreadPreferredUILanguages(MUI_MERGE_USER_FALLBACK | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsFalse(bRet); + //MUI_MERGE_USER_FALLBACK | MUI_THREAD_LANGUAGES不能同时使用 + cchLanguagesBuffer = _countof(szLanguagesBuffer); + bRet = ::GetThreadPreferredUILanguages(MUI_MERGE_USER_FALLBACK | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsFalse(bRet); - //不允许使用MUI_CONSOLE_FILTER - cchLanguagesBuffer = _countof(szLanguagesBuffer); - bRet = ::GetThreadPreferredUILanguages(MUI_CONSOLE_FILTER, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsFalse(bRet); + //不允许使用MUI_CONSOLE_FILTER + cchLanguagesBuffer = _countof(szLanguagesBuffer); + bRet = ::GetThreadPreferredUILanguages(MUI_CONSOLE_FILTER, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsFalse(bRet); - //不允许使用MUI_COMPLEX_SCRIPT_FILTER - cchLanguagesBuffer = _countof(szLanguagesBuffer); - bRet = ::GetThreadPreferredUILanguages(MUI_COMPLEX_SCRIPT_FILTER, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsFalse(bRet); - } + //不允许使用MUI_COMPLEX_SCRIPT_FILTER + cchLanguagesBuffer = _countof(szLanguagesBuffer); + bRet = ::GetThreadPreferredUILanguages(MUI_COMPLEX_SCRIPT_FILTER, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsFalse(bRet); + } - TEST_METHOD(MUI_LANGUAGE_ID验证) - { - wchar_t szLanguagesBuffer[512]; - ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); - ULONG ulNumLanguages = 0; + TEST_METHOD(MUI_LANGUAGE_ID验证) + { + wchar_t szLanguagesBuffer[512]; + ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); + ULONG ulNumLanguages = 0; - //pulNumLanguages 不能为 nullptr - auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_ID | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsTrue(bRet); + //pulNumLanguages 不能为 nullptr + auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_ID | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsTrue(bRet); - Assert::AreEqual(ulNumLanguages, 1ul); - Assert::AreEqual(cchLanguagesBuffer, 6ul); + Assert::AreEqual(ulNumLanguages, 1ul); + Assert::AreEqual(cchLanguagesBuffer, 6ul); - Assert::AreEqual(szLanguagesBuffer[4], L'\0'); - Assert::AreEqual(szLanguagesBuffer[5], L'\0'); + Assert::AreEqual(szLanguagesBuffer[4], L'\0'); + Assert::AreEqual(szLanguagesBuffer[5], L'\0'); - CStringW ThreadHex; - ThreadHex.Format(L"%.4x", GetThreadLocale()); + CStringW ThreadHex; + ThreadHex.Format(L"%.4x", GetThreadLocale()); - Assert::AreEqual(ThreadHex.GetString(), szLanguagesBuffer, true); - } + Assert::AreEqual(ThreadHex.GetString(), szLanguagesBuffer, true); + } - TEST_METHOD(MUI_LANGUAGE_NAME验证) - { + TEST_METHOD(MUI_LANGUAGE_NAME验证) + { - //zh-cn\0\0 - SetThreadLocale(0x0804); + //zh-cn\0\0 + SetThreadLocale(0x0804); - { - wchar_t szLanguagesBuffer[512]; - ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); - ULONG ulNumLanguages = 0; + { + wchar_t szLanguagesBuffer[512]; + ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); + ULONG ulNumLanguages = 0; - //pulNumLanguages 不能为 nullptr - auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsTrue(bRet); + //pulNumLanguages 不能为 nullptr + auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME | MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsTrue(bRet); - Assert::AreEqual(ulNumLanguages, 1ul); - Assert::AreEqual(cchLanguagesBuffer, 7ul); + Assert::AreEqual(ulNumLanguages, 1ul); + Assert::AreEqual(cchLanguagesBuffer, 7ul); - Assert::AreEqual(szLanguagesBuffer[5], L'\0'); - Assert::AreEqual(szLanguagesBuffer[6], L'\0'); + Assert::AreEqual(szLanguagesBuffer[5], L'\0'); + Assert::AreEqual(szLanguagesBuffer[6], L'\0'); - Assert::AreEqual(L"zh-cn", szLanguagesBuffer, true); - } + Assert::AreEqual(L"zh-cn", szLanguagesBuffer, true); + } - //默认为 MUI_LANGUAGE_NAME - { - wchar_t szLanguagesBuffer[512]; - ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); - ULONG ulNumLanguages = 0; + //默认为 MUI_LANGUAGE_NAME + { + wchar_t szLanguagesBuffer[512]; + ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); + ULONG ulNumLanguages = 0; - //pulNumLanguages 不能为 nullptr - auto bRet = ::GetThreadPreferredUILanguages(MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsTrue(bRet); + //pulNumLanguages 不能为 nullptr + auto bRet = ::GetThreadPreferredUILanguages(MUI_THREAD_LANGUAGES, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsTrue(bRet); - Assert::AreEqual(ulNumLanguages, 1ul); - Assert::AreEqual(cchLanguagesBuffer, 7ul); + Assert::AreEqual(ulNumLanguages, 1ul); + Assert::AreEqual(cchLanguagesBuffer, 7ul); - Assert::AreEqual(szLanguagesBuffer[5], L'\0'); - Assert::AreEqual(szLanguagesBuffer[6], L'\0'); + Assert::AreEqual(szLanguagesBuffer[5], L'\0'); + Assert::AreEqual(szLanguagesBuffer[6], L'\0'); - Assert::AreEqual(L"zh-cn", szLanguagesBuffer, true); - } + Assert::AreEqual(L"zh-cn", szLanguagesBuffer, true); + } - } + } - TEST_METHOD(Languages消重验证) - { + TEST_METHOD(Languages消重验证) + { - //zh-cn\0\0 - SetThreadLocale(GetUserDefaultLangID()); + //zh-cn\0\0 + SetThreadLocale(GetUserDefaultLangID()); - { - wchar_t szLanguagesBuffer[512]; - ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); - ULONG ulNumLanguages = 0; + { + wchar_t szLanguagesBuffer[512]; + ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); + ULONG ulNumLanguages = 0; - //pulNumLanguages 不能为 nullptr - auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_ID | MUI_MERGE_USER_FALLBACK, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsTrue(bRet); + //pulNumLanguages 不能为 nullptr + auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_ID | MUI_MERGE_USER_FALLBACK, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsTrue(bRet); - std::set Map; + std::set Map; - for (auto Str = szLanguagesBuffer; *Str; Str = Str + wcslen(Str) + 1) - { - Assert::IsTrue(Map.insert(CStringW(Str).MakeLower()).second); - } + for (auto Str = szLanguagesBuffer; *Str; Str = Str + wcslen(Str) + 1) + { + Assert::IsTrue(Map.insert(CStringW(Str).MakeLower()).second); + } - Assert::IsTrue(Map.size() >= 1); - } + Assert::IsTrue(Map.size() >= 1); + } - // - { - auto UserId = GetUserDefaultLangID(); - LANGID ThreadId; + // + { + auto UserId = GetUserDefaultLangID(); + LANGID ThreadId; - if (UserId == 0x0804) - { - //en-us - ThreadId = 0x0409; - } - else - { - ThreadId = 0x0804; - } + if (UserId == 0x0804) + { + //en-us + ThreadId = 0x0409; + } + else + { + ThreadId = 0x0804; + } - SetThreadLocale(ThreadId); + SetThreadLocale(ThreadId); - wchar_t szLanguagesBuffer[512]; - ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); - ULONG ulNumLanguages = 0; + wchar_t szLanguagesBuffer[512]; + ULONG cchLanguagesBuffer = _countof(szLanguagesBuffer); + ULONG ulNumLanguages = 0; - //pulNumLanguages 不能为 nullptr - auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_ID | MUI_MERGE_USER_FALLBACK, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); - Assert::IsTrue(bRet); + //pulNumLanguages 不能为 nullptr + auto bRet = ::GetThreadPreferredUILanguages(MUI_LANGUAGE_ID | MUI_MERGE_USER_FALLBACK, &ulNumLanguages, szLanguagesBuffer, &cchLanguagesBuffer); + Assert::IsTrue(bRet); - std::set Map; + std::set Map; - for (auto Str = szLanguagesBuffer; *Str; Str = Str + wcslen(Str) + 1) - { - Assert::IsTrue(Map.insert(CStringW(Str).MakeLower()).second); - } + for (auto Str = szLanguagesBuffer; *Str; Str = Str + wcslen(Str) + 1) + { + Assert::IsTrue(Map.insert(CStringW(Str).MakeLower()).second); + } - Assert::IsTrue(Map.size() >= 1); - } + Assert::IsTrue(Map.size() >= 1); + } - } + } - }; + }; - TEST_CLASS(ResolveLocaleName) - { + TEST_CLASS(ResolveLocaleName) + { AwaysNullGuard Guard; - public: - ResolveLocaleName() - { + public: + ResolveLocaleName() + { Guard |= YY::Thunks::aways_null_try_get_ResolveLocaleName; - } + } + + TEST_METHOD(中性语言验证) + { + wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + + auto result = ::ResolveLocaleName(L"zh", Buffer, _countof(Buffer)); + + Assert::AreEqual(result, (int)_countof(L"zh-CN")); + + Assert::AreEqual(Buffer, L"zh-CN", true); + + + result = ::ResolveLocaleName(L"zh-Hant", Buffer, _countof(Buffer)); + + Assert::AreEqual(result, (int)_countof(L"zh-HK")); + + Assert::AreEqual(Buffer, L"zh-HK", true); + + - TEST_METHOD(中性语言验证) - { - wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + result = ::ResolveLocaleName(L"mn-Mong", Buffer, _countof(Buffer)); - auto result = ::ResolveLocaleName(L"zh", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"mn-Mong-CN")); - Assert::AreEqual(result, (int)_countof(L"zh-CN")); + Assert::AreEqual(Buffer, L"mn-Mong-CN", true); + } + + TEST_METHOD(特定区域语言验证) + { + wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + + auto result = ::ResolveLocaleName(L"zh-TW", Buffer, _countof(Buffer)); + + Assert::AreEqual(result, (int)_countof(L"zh-TW")); + + Assert::AreEqual(Buffer, L"zh-TW", true); + + + result = ::ResolveLocaleName(L"es-ES_tradnl", Buffer, _countof(Buffer)); + + Assert::AreEqual(result, (int)_countof(L"es-ES_tradnl")); - Assert::AreEqual(Buffer, L"zh-CN", true); + Assert::AreEqual(Buffer, L"es-ES_tradnl", true); + } + TEST_METHOD(特定区域排序语言验证) + { + wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; - result = ::ResolveLocaleName(L"zh-Hant", Buffer, _countof(Buffer)); + auto result = ::ResolveLocaleName(L"x-IV-mathan", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"")); + Assert::AreEqual(Buffer, L"", true); - Assert::AreEqual(result, (int)_countof(L"zh-HK")); + result = ::ResolveLocaleName(L"de-DE_phoneb", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"de-DE")); + Assert::AreEqual(Buffer, L"de-DE", true); - Assert::AreEqual(Buffer, L"zh-HK", true); + result = ::ResolveLocaleName(L"hu-HU_technl", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"hu-HU")); + Assert::AreEqual(Buffer, L"hu-HU", true); - result = ::ResolveLocaleName(L"mn-Mong", Buffer, _countof(Buffer)); + result = ::ResolveLocaleName(L"ka-GE_modern", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"ka-GE")); + Assert::AreEqual(Buffer, L"ka-GE", true); - Assert::AreEqual(result, (int)_countof(L"mn-Mong-CN")); - Assert::AreEqual(Buffer, L"mn-Mong-CN", true); - } + result = ::ResolveLocaleName(L"zh-CN_stroke", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-CN")); + Assert::AreEqual(Buffer, L"zh-CN", true); - TEST_METHOD(特定区域语言验证) - { - wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + result = ::ResolveLocaleName(L"zh-SG_stroke", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-SG")); + Assert::AreEqual(Buffer, L"zh-SG", true); - auto result = ::ResolveLocaleName(L"zh-TW", Buffer, _countof(Buffer)); + result = ::ResolveLocaleName(L"zh-MO_stroke", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-MO")); + Assert::AreEqual(Buffer, L"zh-MO", true); - Assert::AreEqual(result, (int)_countof(L"zh-TW")); - Assert::AreEqual(Buffer, L"zh-TW", true); + result = ::ResolveLocaleName(L"zh-TW_pronun", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-TW")); + Assert::AreEqual(Buffer, L"zh-TW", true); - result = ::ResolveLocaleName(L"es-ES_tradnl", Buffer, _countof(Buffer)); + result = ::ResolveLocaleName(L"zh-TW_radstr", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-TW")); + Assert::AreEqual(Buffer, L"zh-TW", true); - Assert::AreEqual(result, (int)_countof(L"es-ES_tradnl")); + result = ::ResolveLocaleName(L"ja-JP_radstr", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"ja-JP")); + Assert::AreEqual(Buffer, L"ja-JP", true); - Assert::AreEqual(Buffer, L"es-ES_tradnl", true); - } + result = ::ResolveLocaleName(L"zh-HK_radstr", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-HK")); + Assert::AreEqual(Buffer, L"zh-HK", true); - TEST_METHOD(特定区域排序语言验证) - { - wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; - auto result = ::ResolveLocaleName(L"x-IV-mathan", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"")); - Assert::AreEqual(Buffer, L"", true); + result = ::ResolveLocaleName(L"zh-MO_radstr", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-MO")); + Assert::AreEqual(Buffer, L"zh-MO", true); - result = ::ResolveLocaleName(L"de-DE_phoneb", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"de-DE")); - Assert::AreEqual(Buffer, L"de-DE", true); + } + + TEST_METHOD(自动回退验证) + { + wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; - result = ::ResolveLocaleName(L"hu-HU_technl", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"hu-HU")); - Assert::AreEqual(Buffer, L"hu-HU", true); + auto result = ::ResolveLocaleName(L"zh-TW-XXXXXX", Buffer, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-TW")); - result = ::ResolveLocaleName(L"ka-GE_modern", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"ka-GE")); - Assert::AreEqual(Buffer, L"ka-GE", true); + Assert::AreEqual(Buffer, L"zh-TW", true); - result = ::ResolveLocaleName(L"zh-CN_stroke", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-CN")); - Assert::AreEqual(Buffer, L"zh-CN", true); - result = ::ResolveLocaleName(L"zh-SG_stroke", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-SG")); - Assert::AreEqual(Buffer, L"zh-SG", true); + result = ::ResolveLocaleName(L"zh-Hant-XXXXXX", Buffer, _countof(Buffer)); - result = ::ResolveLocaleName(L"zh-MO_stroke", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-MO")); - Assert::AreEqual(Buffer, L"zh-MO", true); + Assert::AreEqual(result, (int)_countof(L"zh-HK")); + Assert::AreEqual(Buffer, L"zh-HK", true); + } + + + TEST_METHOD(默认值验证) + { + wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; - result = ::ResolveLocaleName(L"zh-TW_pronun", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-TW")); - Assert::AreEqual(Buffer, L"zh-TW", true); + auto result = ::ResolveLocaleName(nullptr, Buffer, _countof(Buffer)); + Assert::AreNotEqual(result, 0); - result = ::ResolveLocaleName(L"zh-TW_radstr", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-TW")); - Assert::AreEqual(Buffer, L"zh-TW", true); + Assert::AreEqual(::LocaleNameToLCID(Buffer, 0), ::GetUserDefaultLCID()); - result = ::ResolveLocaleName(L"ja-JP_radstr", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"ja-JP")); - Assert::AreEqual(Buffer, L"ja-JP", true); + + ::ResolveLocaleName(LOCALE_NAME_SYSTEM_DEFAULT, Buffer, _countof(Buffer)); - result = ::ResolveLocaleName(L"zh-HK_radstr", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-HK")); - Assert::AreEqual(Buffer, L"zh-HK", true); + Assert::AreNotEqual(result, 0); + Assert::AreEqual(::LocaleNameToLCID(Buffer, 0), ::GetSystemDefaultLCID()); - result = ::ResolveLocaleName(L"zh-MO_radstr", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-MO")); - Assert::AreEqual(Buffer, L"zh-MO", true); + result = ::ResolveLocaleName(L"wrwrwrwr", Buffer, _countof(Buffer)); + Assert::AreEqual(result, 1); + Assert::AreEqual(Buffer, L"", true); + } - } + TEST_METHOD(仅返回长度验证) + { + wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; - TEST_METHOD(自动回退验证) - { - wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + auto result = ::ResolveLocaleName(L"zh-CN", Buffer, 0); + Assert::AreEqual(result, (int)_countof(L"zh-CN")); - auto result = ::ResolveLocaleName(L"zh-TW-XXXXXX", Buffer, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-TW")); - Assert::AreEqual(Buffer, L"zh-TW", true); + result = ::ResolveLocaleName(L"zh-CN", 0, _countof(Buffer)); + Assert::AreEqual(result, (int)_countof(L"zh-CN")); + result = ::ResolveLocaleName(L"zh-CN", 0, 0); + Assert::AreEqual(result, (int)_countof(L"zh-CN")); + } + }; - result = ::ResolveLocaleName(L"zh-Hant-XXXXXX", Buffer, _countof(Buffer)); + TEST_CLASS(FindNLSStringEx) + { + AwaysNullGuard Guard; - Assert::AreEqual(result, (int)_countof(L"zh-HK")); + public: + FindNLSStringEx() + { + Guard |= YY::Thunks::aways_null_try_get_FindNLSStringEx; + } - Assert::AreEqual(Buffer, L"zh-HK", true); - } + TEST_METHOD(FIND_STARTSWITH验证) + { + INT _nFound; + int _nIndex; + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_STARTSWITH, L"0123456789", -1, L"0123", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 0); + Assert::AreEqual(_nFound, 4); - TEST_METHOD(默认值验证) - { - wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_STARTSWITH, L"0123456789", -1, L"1234", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, -1); - auto result = ::ResolveLocaleName(nullptr, Buffer, _countof(Buffer)); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_STARTSWITH, L"0123456789", -1, L"6789", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, -1); + } - Assert::AreNotEqual(result, 0); + TEST_METHOD(FIND_FROMSTART验证) + { + INT _nFound; + int _nIndex; - Assert::AreEqual(::LocaleNameToLCID(Buffer, 0), ::GetUserDefaultLCID()); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMSTART, L"0123456789", -1, L"0123", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 0); + Assert::AreEqual(_nFound, 4); - - ::ResolveLocaleName(LOCALE_NAME_SYSTEM_DEFAULT, Buffer, _countof(Buffer)); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMSTART, L"0123450123", -1, L"0123", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 0); + Assert::AreEqual(_nFound, 4); - Assert::AreNotEqual(result, 0); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMSTART, L"0123456789", -1, L"1234", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 1); + Assert::AreEqual(_nFound, 4); - Assert::AreEqual(::LocaleNameToLCID(Buffer, 0), ::GetSystemDefaultLCID()); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMSTART, L"0123456789", -1, L"6789", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 6); + Assert::AreEqual(_nFound, 4); - result = ::ResolveLocaleName(L"wrwrwrwr", Buffer, _countof(Buffer)); - Assert::AreEqual(result, 1); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMSTART, L"0123456789", -1, L"3210", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, -1); + } - Assert::AreEqual(Buffer, L"", true); - } + TEST_METHOD(FIND_ENDSWITH验证) + { + INT _nFound; + int _nIndex; - TEST_METHOD(仅返回长度验证) - { - wchar_t Buffer[LOCALE_NAME_MAX_LENGTH] = {}; + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_ENDSWITH, L"0123456789", -1, L"0123", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, -1); - auto result = ::ResolveLocaleName(L"zh-CN", Buffer, 0); - Assert::AreEqual(result, (int)_countof(L"zh-CN")); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_ENDSWITH, L"0123456789", -1, L"6789", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 6); + Assert::AreEqual(_nFound, 4); + } + TEST_METHOD(FIND_FROMEND验证) + { + INT _nFound; + int _nIndex; + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMEND, L"0123456789", -1, L"0123", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 0); + Assert::AreEqual(_nFound, 4); - result = ::ResolveLocaleName(L"zh-CN", 0, _countof(Buffer)); - Assert::AreEqual(result, (int)_countof(L"zh-CN")); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMEND, L"0123456789", -1, L"6789", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 6); + Assert::AreEqual(_nFound, 4); + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMEND, L"6789456789", -1, L"6789", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, 6); + Assert::AreEqual(_nFound, 4); - result = ::ResolveLocaleName(L"zh-CN", 0, 0); - Assert::AreEqual(result, (int)_countof(L"zh-CN")); - } - }; + _nIndex = ::FindNLSStringEx(LOCALE_NAME_SYSTEM_DEFAULT, FIND_FROMEND, L"0123456789", -1, L"9876", -1, &_nFound, nullptr, nullptr, 0); + Assert::AreEqual(_nIndex, -1); + } + }; }