Alexandre Julliard : ntdll: Implement RtlIsValidLocaleName().

Alexandre Julliard julliard at winehq.org
Tue Mar 22 16:46:29 CDT 2022


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar 22 10:32:13 2022 +0100

ntdll: Implement RtlIsValidLocaleName().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/locale.c | 78 +++++++++++++++++++++++++++++++++++++-------
 dlls/ntdll/locale.c          | 14 ++++++++
 dlls/ntdll/ntdll.spec        |  1 +
 include/winternl.h           |  1 +
 4 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 68bab2094e5..06b3d84c97a 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -63,6 +63,7 @@ static BOOL (WINAPI *pEnumSystemLocalesEx)(LOCALE_ENUMPROCEX, DWORD, LPARAM, LPV
 static INT (WINAPI *pLCMapStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM);
 static LCID (WINAPI *pLocaleNameToLCID)(LPCWSTR, DWORD);
 static NTSTATUS (WINAPI *pRtlLocaleNameToLcid)(LPCWSTR, LCID *, DWORD);
+static BOOLEAN (WINAPI *pRtlIsValidLocaleName)(const WCHAR *,ULONG);
 static INT  (WINAPI *pLCIDToLocaleName)(LCID, LPWSTR, INT, DWORD);
 static BOOL (WINAPI *pIsValidLanguageGroup)(LGRPID, DWORD);
 static INT (WINAPI *pIdnToNameprepUnicode)(DWORD, LPCWSTR, INT, LPWSTR, INT);
@@ -145,6 +146,7 @@ static void InitFunctionPointers(void)
   mod = GetModuleHandleA("ntdll");
   X(RtlUpcaseUnicodeChar);
   X(RtlLocaleNameToLcid);
+  X(RtlIsValidLocaleName);
   X(RtlNormalizeString);
   X(RtlIsNormalizedString);
   X(NtGetNlsSectionPtr);
@@ -4734,11 +4736,6 @@ static void test_GetLocaleInfoEx(void)
 
 static void test_IsValidLocaleName(void)
 {
-    static const WCHAR enusW[] = {'e','n','-','U','S',0};
-    static const WCHAR enW[] = {'e','n',0};
-    static const WCHAR zzW[] = {'z','z',0};
-    static const WCHAR zz_zzW[] = {'z','z','-','Z','Z',0};
-    static const WCHAR zzzzW[] = {'z','z','z','z',0};
     BOOL ret;
 
     if (!pIsValidLocaleName)
@@ -4747,20 +4744,79 @@ static void test_IsValidLocaleName(void)
         return;
     }
 
-    ret = pIsValidLocaleName(enusW);
+    ret = pIsValidLocaleName(L"en-US");
+    ok(ret, "IsValidLocaleName failed\n");
+    ret = pIsValidLocaleName(L"en");
+    ok(ret, "IsValidLocaleName failed\n");
+    ret = pIsValidLocaleName(L"es-es");
+    ok(ret, "IsValidLocaleName failed\n");
+    ret = pIsValidLocaleName(L"de-DE_phoneb");
     ok(ret, "IsValidLocaleName failed\n");
-    ret = pIsValidLocaleName(enW);
+    ret = pIsValidLocaleName(L"DE_de-phoneb");
     ok(ret || broken(!ret), "IsValidLocaleName failed\n");
-    ret = pIsValidLocaleName(zzW);
+    ret = pIsValidLocaleName(L"DE_de_PHONEB");
+    ok(ret || broken(!ret), "IsValidLocaleName failed\n");
+    ret = pIsValidLocaleName(L"DE_de+phoneb");
+    ok(!ret, "IsValidLocaleName should have failed\n");
+    ret = pIsValidLocaleName(L"zz");
+    ok(!ret || broken(ret), "IsValidLocaleName should have failed\n");
+    ret = pIsValidLocaleName(L"zz-ZZ");
     ok(!ret || broken(ret), "IsValidLocaleName should have failed\n");
-    ret = pIsValidLocaleName(zz_zzW);
+    ret = pIsValidLocaleName(L"zzz");
     ok(!ret || broken(ret), "IsValidLocaleName should have failed\n");
-    ret = pIsValidLocaleName(zzzzW);
+    ret = pIsValidLocaleName(L"zzz-ZZZ");
+    ok(!ret, "IsValidLocaleName should have failed\n");
+    ret = pIsValidLocaleName(L"zzzz");
     ok(!ret, "IsValidLocaleName should have failed\n");
     ret = pIsValidLocaleName(LOCALE_NAME_INVARIANT);
     ok(ret, "IsValidLocaleName failed\n");
-    ret = pIsValidLocaleName(NULL);
+    ret = pIsValidLocaleName(LOCALE_NAME_USER_DEFAULT);
+    ok(!ret, "IsValidLocaleName should have failed\n");
+    ret = pIsValidLocaleName(LOCALE_NAME_SYSTEM_DEFAULT);
     ok(!ret, "IsValidLocaleName should have failed\n");
+
+    if (!pRtlIsValidLocaleName)
+    {
+        win_skip( "RtlIsValidLocaleName not available\n" );
+        return;
+    }
+
+    ret = pRtlIsValidLocaleName( L"en-US", 0 );
+    ok(ret, "RtlIsValidLocaleName failed\n");
+    ret = pRtlIsValidLocaleName( L"en", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"en", 1 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"en", 2 );
+    ok(ret, "RtlIsValidLocaleName failed\n");
+    ret = pRtlIsValidLocaleName( L"en-RR", 2 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"es-es", 0 );
+    ok(ret, "RtlIsValidLocaleName failed\n");
+    ret = pRtlIsValidLocaleName( L"de-DE_phoneb", 0 );
+    ok(ret, "RtlIsValidLocaleName failed\n");
+    ret = pRtlIsValidLocaleName( L"DE_de_PHONEB", 0 );
+    ok(ret || broken(!ret), "RtlIsValidLocaleName failed\n");
+    ret = pRtlIsValidLocaleName( L"DE_de+phoneb", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"zz", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"zz", 2 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"zz-ZZ", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"zzz", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"zzz-ZZZ", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( L"zzzz", 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( LOCALE_NAME_INVARIANT, 0 );
+    ok(ret, "RtlIsValidLocaleName failed\n");
+    ret = pRtlIsValidLocaleName( LOCALE_NAME_USER_DEFAULT, 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
+    ret = pRtlIsValidLocaleName( LOCALE_NAME_SYSTEM_DEFAULT, 0 );
+    ok(!ret, "RtlIsValidLocaleName should have failed\n");
 }
 
 static void test_CompareStringOrdinal(void)
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c
index b266bc0af3d..695524decb7 100644
--- a/dlls/ntdll/locale.c
+++ b/dlls/ntdll/locale.c
@@ -1224,6 +1224,20 @@ WCHAR __cdecl towupper( WCHAR ch )
 }
 
 
+/******************************************************************
+ *      RtlIsValidLocaleName   (NTDLL.@)
+ */
+BOOLEAN WINAPI RtlIsValidLocaleName( const WCHAR *name, ULONG flags )
+{
+    const NLS_LOCALE_LCNAME_INDEX *entry = find_lcname_entry( name );
+
+    if (!entry) return FALSE;
+    /* reject neutral locale unless flag 2 is set */
+    if (!(flags & 2) && !get_locale_data( entry->idx )->inotneutral) return FALSE;
+    return TRUE;
+}
+
+
 /******************************************************************
  *      RtlLocaleNameToLcid   (NTDLL.@)
  */
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 4c7b9be1d9f..14a828d7d0c 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -834,6 +834,7 @@
 # @ stub RtlIsThreadWithinLoaderCallout
 @ stdcall RtlIsValidHandle(ptr ptr)
 @ stdcall RtlIsValidIndexHandle(ptr long ptr)
+@ stdcall RtlIsValidLocaleName(wstr long)
 @ stdcall -arch=win32 -ret64 RtlLargeIntegerAdd(int64 int64)
 @ stdcall -arch=win32 -ret64 RtlLargeIntegerArithmeticShift(int64 long)
 @ stdcall -arch=win32 -ret64 RtlLargeIntegerDivide(int64 int64 ptr)
diff --git a/include/winternl.h b/include/winternl.h
index d4f360bd2a7..07a8755dc87 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -4402,6 +4402,7 @@ NTSYSAPI BOOLEAN   WINAPI RtlIsProcessorFeaturePresent(UINT);
 NTSYSAPI BOOLEAN   WINAPI RtlIsTextUnicode(LPCVOID,INT,INT *);
 NTSYSAPI BOOLEAN   WINAPI RtlIsValidHandle(const RTL_HANDLE_TABLE *, const RTL_HANDLE *);
 NTSYSAPI BOOLEAN   WINAPI RtlIsValidIndexHandle(const RTL_HANDLE_TABLE *, ULONG Index, RTL_HANDLE **);
+NTSYSAPI BOOLEAN   WINAPI RtlIsValidLocaleName(const WCHAR*,ULONG);
 NTSYSAPI NTSTATUS  WINAPI RtlLeaveCriticalSection(RTL_CRITICAL_SECTION *);
 NTSYSAPI DWORD     WINAPI RtlLengthRequiredSid(DWORD);
 NTSYSAPI ULONG     WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR);




More information about the wine-cvs mailing list