Module: wine Branch: master Commit: 84cca2baae23c6afa0c8070f5009fdcfa218e039 URL: https://source.winehq.org/git/wine.git/?a=commit;h=84cca2baae23c6afa0c8070f5...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Mar 20 14:43:45 2020 +0100
kernelbase: Implement IsValidNLSVersion().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/tests/locale.c | 80 +++++++++++++++++++++++++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/locale.c | 33 +++++++++++++++++ include/winnls.h | 1 + 5 files changed, 116 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 1cccaf2209..2e2f7c9a84 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -995,6 +995,7 @@ @ stdcall -import IsValidLanguageGroup(long long) @ stdcall -import IsValidLocale(long long) @ stdcall -import IsValidLocaleName(wstr) +@ stdcall -import IsValidNLSVersion(long wstr ptr) # @ stub IsValidUILanguage @ stdcall -import IsWow64Process(ptr ptr) @ stdcall K32EmptyWorkingSet(long) diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 3f755aa2b9..4c1e1b4d73 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -87,6 +87,7 @@ static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT); static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL); static BOOL (WINAPI *pGetNLSVersion)(NLS_FUNCTION,LCID,NLSVERSIONINFO*); static BOOL (WINAPI *pGetNLSVersionEx)(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*); +static DWORD (WINAPI *pIsValidNLSVersion)(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*); static NTSTATUS (WINAPI *pRtlNormalizeString)(ULONG, LPCWSTR, INT, LPWSTR, INT*); static NTSTATUS (WINAPI *pRtlIsNormalizedString)(ULONG, LPCWSTR, INT, BOOLEAN*); static NTSTATUS (WINAPI *pNtGetNlsSectionPtr)(ULONG,ULONG,void*,void**,SIZE_T*); @@ -129,6 +130,7 @@ static void InitFunctionPointers(void) X(FindStringOrdinal); X(GetNLSVersion); X(GetNLSVersionEx); + X(IsValidNLSVersion);
mod = GetModuleHandleA("ntdll"); X(RtlUpcaseUnicodeChar); @@ -6763,6 +6765,84 @@ static void test_NLSVersion(void) else ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); } else win_skip( "GetNLSVersionEx not available\n" ); + + if (pIsValidNLSVersion) + { + info.dwNLSVersionInfoSize = sizeof(info); + pGetNLSVersion( COMPARE_STRING, LOCALE_USER_DEFAULT, (NLSVERSIONINFO *)&info ); + + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = sizeof(info); + ret = pIsValidNLSVersion( COMPARE_STRING, L"ja-JP", &info ); + ok( ret, "IsValidNLSVersion failed err %u\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = offsetof( NLSVERSIONINFO, dwEffectiveId ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( ret, "IsValidNLSVersion failed err %u\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = sizeof(info); + ret = pIsValidNLSVersion( 2, L"en-US", &info ); + ok( !ret, "IsValidNLSVersion succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = sizeof(info); + ret = pIsValidNLSVersion( COMPARE_STRING, L"foobar", &info ); + ok( !ret, "IsValidNLSVersion succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + memset( &info, 0xcc, sizeof(info) ); + info.dwNLSVersionInfoSize = sizeof(info); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( !ret, "IsValidNLSVersion succeeded\n" ); + ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); + + info.dwNLSVersionInfoSize = sizeof(info); + pGetNLSVersion( COMPARE_STRING, LOCALE_USER_DEFAULT, (NLSVERSIONINFO *)&info ); + info.dwNLSVersion++; + SetLastError( 0xdeadbeef ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( ret, "IsValidNLSVersion failed err %u\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); + + info.dwNLSVersion += 0x100; + SetLastError( 0xdeadbeef ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( !ret, "IsValidNLSVersion succeeded\n" ); + ok( GetLastError() == 0, "wrong error %u\n", GetLastError() ); + + info.dwNLSVersion -= 0x200; + SetLastError( 0xdeadbeef ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( !ret, "IsValidNLSVersion succeeded\n" ); + ok( GetLastError() == 0, "wrong error %u\n", GetLastError() ); + + info.dwNLSVersion += 0x100; + info.dwDefinedVersion += 0x100; + SetLastError( 0xdeadbeef ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( ret, "IsValidNLSVersion failed err %u\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); + + info.dwDefinedVersion -= 0x100; + info.guidCustomVersion.Data1 = 0x123; + SetLastError( 0xdeadbeef ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( !ret, "IsValidNLSVersion succeeded\n" ); + ok( GetLastError() == 0, "wrong error %u\n", GetLastError() ); + + info.guidCustomVersion = guid_null; + SetLastError( 0xdeadbeef ); + ret = pIsValidNLSVersion( COMPARE_STRING, L"en-US", &info ); + ok( ret, "IsValidNLSVersion failed err %u\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); + } + else win_skip( "IsValidNLSVersion not available\n" ); }
START_TEST(locale) diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index fbcae55e98..d74f65c8f1 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -878,7 +878,7 @@ @ stdcall IsValidLanguageGroup(long long) @ stdcall IsValidLocale(long long) @ stdcall IsValidLocaleName(wstr) -# @ stub IsValidNLSVersion +@ stdcall IsValidNLSVersion(long wstr ptr) @ stub IsValidRelativeSecurityDescriptor @ stdcall IsValidSecurityDescriptor(ptr) @ stdcall IsValidSid(ptr) diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index b9a53b0ef3..623cb01280 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -4860,6 +4860,39 @@ BOOL WINAPI DECLSPEC_HOTPATCH IsValidLocaleName( const WCHAR *locale ) }
+/****************************************************************************** + * IsValidNLSVersion (kernelbase.@) + */ +DWORD WINAPI DECLSPEC_HOTPATCH IsValidNLSVersion( NLS_FUNCTION func, const WCHAR *locale, + NLSVERSIONINFOEX *info ) +{ + static const GUID GUID_NULL; + NLSVERSIONINFOEX infoex; + DWORD ret; + + if (func != COMPARE_STRING) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (info->dwNLSVersionInfoSize < sizeof(*info) && + (info->dwNLSVersionInfoSize != offsetof( NLSVERSIONINFO, dwEffectiveId ))) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + infoex.dwNLSVersionInfoSize = sizeof(infoex); + if (!GetNLSVersionEx( func, locale, &infoex )) return FALSE; + + ret = (infoex.dwNLSVersion & ~0xff) == (info->dwNLSVersion & ~0xff); + if (ret && !IsEqualGUID( &info->guidCustomVersion, &GUID_NULL )) + ret = find_sortguid( &info->guidCustomVersion ) != NULL; + + if (!ret) SetLastError( ERROR_SUCCESS ); + return ret; +} + + /*********************************************************************** * LCIDToLocaleName (kernelbase.@) */ diff --git a/include/winnls.h b/include/winnls.h index e563968cf9..e7b478b1c6 100644 --- a/include/winnls.h +++ b/include/winnls.h @@ -957,6 +957,7 @@ WINBASEAPI BOOL WINAPI IsValidCodePage(UINT); WINBASEAPI BOOL WINAPI IsValidLanguageGroup(LGRPID,DWORD); WINBASEAPI BOOL WINAPI IsValidLocale(LCID,DWORD); WINBASEAPI BOOL WINAPI IsValidLocaleName(LPCWSTR); +WINBASEAPI DWORD WINAPI IsValidNLSVersion(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*); WINBASEAPI INT WINAPI LCIDToLocaleName(LCID,LPWSTR,INT,DWORD); WINBASEAPI INT WINAPI LCMapStringA(LCID,DWORD,LPCSTR,INT,LPSTR,INT); WINBASEAPI INT WINAPI LCMapStringW(LCID,DWORD,LPCWSTR,INT,LPWSTR,INT);