Alexandre Julliard : kernelbase: Implement IsValidNLSVersion().

Alexandre Julliard julliard at winehq.org
Fri Mar 20 17:08:21 CDT 2020


Module: wine
Branch: master
Commit: 84cca2baae23c6afa0c8070f5009fdcfa218e039
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=84cca2baae23c6afa0c8070f5009fdcfa218e039

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Mar 20 14:43:45 2020 +0100

kernelbase: Implement IsValidNLSVersion().

Signed-off-by: Alexandre Julliard <julliard at 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);




More information about the wine-cvs mailing list