Alexandre Julliard : kernelbase: Reimplement EnumUILanguages() using the locale.nls data.

Alexandre Julliard julliard at winehq.org
Thu Mar 24 17:46:43 CDT 2022


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Mar 24 16:57:15 2022 +0100

kernelbase: Reimplement EnumUILanguages() using the locale.nls data.

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

---

 dlls/kernel32/tests/locale.c |  4 ++++
 dlls/kernelbase/locale.c     | 54 ++++++++++++++++++++++++++++++--------------
 2 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 2bc368c8bc1..d30a771c2c2 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -3849,6 +3849,10 @@ static void test_EnumUILanguageA(void)
   }
   ok(ret, "Expected ret != 0, got %d, error %ld\n", ret, GetLastError());
 
+  SetLastError(0xdeadbeef);
+  ret = pEnumUILanguagesA(luilocale_proc1A, MUI_LANGUAGE_NAME, 0);
+  ok(ret, "Expected ret != 0, got %d, error %ld\n", ret, GetLastError());
+
   enumCount = 0;
   SetLastError(ERROR_SUCCESS);
   ret = pEnumUILanguagesA(luilocale_proc2A, 0, 0);
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index faa7b657adc..0fd6d393eba 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -3111,38 +3111,58 @@ BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumTimeFormats( TIMEFMT_ENUMPROCW proc,
 BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumUILanguages( UILANGUAGE_ENUMPROCW proc, DWORD flags,
                                                         LONG_PTR param, BOOL unicode )
 {
-    WCHAR name[10];
-    DWORD name_len, type, index = 0;
-    HKEY key;
+    WCHAR nameW[LOCALE_NAME_MAX_LENGTH];
+    char nameA[LOCALE_NAME_MAX_LENGTH];
+    DWORD i;
 
     if (!proc)
     {
 	SetLastError( ERROR_INVALID_PARAMETER );
 	return FALSE;
     }
-    if (flags & ~MUI_LANGUAGE_ID)
+    if (flags & ~(MUI_LANGUAGE_ID | MUI_LANGUAGE_NAME))
     {
 	SetLastError( ERROR_INVALID_FLAGS );
 	return FALSE;
     }
 
-    if (RegOpenKeyExW( nls_key, L"Locale", 0, KEY_READ, &key )) return FALSE;
-
-    for (;;)
+    for (i = 0; i < locale_table->nb_lcnames; i++)
     {
-        name_len = ARRAY_SIZE(name);
-        if (RegEnumValueW( key, index++, name, &name_len, NULL, &type, NULL, NULL )) break;
-        if (type != REG_SZ) continue;
-        if (!wcstoul( name, NULL, 16 )) continue;
-        if (!unicode)
+        if (!lcnames_index[i].name) continue;  /* skip invariant locale */
+        if (lcnames_index[i].id & 0x80000000) continue;  /* skip aliases */
+        if (!get_locale_data( lcnames_index[i].idx )->inotneutral) continue;  /* skip neutral locales */
+        if (!SORTIDFROMLCID( lcnames_index[i].id ) != !(flags & LCID_ALTERNATE_SORTS))
+            continue;  /* skip alternate sorts */
+        if (flags & MUI_LANGUAGE_NAME)
         {
-            char nameA[10];
-            WideCharToMultiByte( CP_ACP, 0, name, -1, nameA, sizeof(nameA), NULL, NULL );
-            if (!((UILANGUAGE_ENUMPROCA)proc)( nameA, param )) break;
+            const WCHAR *str = locale_strings + lcnames_index[i].name;
+
+            if (unicode)
+            {
+                memcpy( nameW, str + 1, (*str + 1) * sizeof(WCHAR) );
+                if (!proc( nameW, param )) break;
+            }
+            else
+            {
+                WideCharToMultiByte( CP_ACP, 0, str + 1, -1, nameA, sizeof(nameA), NULL, NULL );
+                if (!((UILANGUAGE_ENUMPROCA)proc)( nameA, param )) break;
+            }
+        }
+        else
+        {
+            if (lcnames_index[i].id == LOCALE_CUSTOM_UNSPECIFIED) continue;  /* skip locales with no lcid */
+            if (unicode)
+            {
+                swprintf( nameW, ARRAY_SIZE(nameW), L"%04lx", lcnames_index[i].id );
+                if (!proc( nameW, param )) break;
+            }
+            else
+            {
+                sprintf( nameA, "%04x", lcnames_index[i].id );
+                if (!((UILANGUAGE_ENUMPROCA)proc)( nameA, param )) break;
+            }
         }
-        else if (!proc( name, param )) break;
     }
-    RegCloseKey( key );
     return TRUE;
 }
 




More information about the wine-cvs mailing list