Alexandre Julliard : ntdll: Store the locales in Wine-specific environment variables.

Alexandre Julliard julliard at winehq.org
Mon Mar 1 15:54:03 CST 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Sun Feb 28 11:30:37 2021 +0100

ntdll: Store the locales in Wine-specific environment variables.

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

---

 dlls/kernelbase/locale.c       | 43 ++++++++++++++++++++++++++++++++++++------
 dlls/ntdll/locale.c            | 36 -----------------------------------
 dlls/ntdll/unix/env.c          | 19 ++++++-------------
 dlls/ntdll/unix/loader.c       |  1 -
 dlls/ntdll/unix/unix_private.h |  1 -
 dlls/ntdll/unixlib.h           |  5 +----
 6 files changed, 44 insertions(+), 61 deletions(-)

diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index ac473ccd63a..b746feca639 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -696,6 +696,27 @@ done:
 }
 
 
+static LCID locale_to_lcid( WCHAR *win_name )
+{
+    WCHAR *p;
+    LCID lcid;
+
+    if (!RtlLocaleNameToLcid( win_name, &lcid, 0 )) return lcid;
+
+    /* try neutral name */
+    if ((p = wcsrchr( win_name, '-' )))
+    {
+        *p = 0;
+        if (!RtlLocaleNameToLcid( win_name, &lcid, 2 ))
+        {
+            if (SUBLANGID(lcid) == SUBLANG_NEUTRAL)
+                lcid = MAKELANGID( PRIMARYLANGID(lcid), SUBLANG_DEFAULT );
+            return lcid;
+        }
+    }
+    return 0;
+}
+
 /***********************************************************************
  *		init_locale
  */
@@ -704,8 +725,8 @@ void init_locale(void)
     UINT ansi_cp = 0, oem_cp = 0;
     USHORT *ansi_ptr, *oem_ptr;
     void *sort_ptr;
-    LCID lcid = GetUserDefaultLCID();
-    WCHAR bufferW[80];
+    LCID user_lcid = 0, system_lcid = 0;
+    WCHAR bufferW[LOCALE_NAME_MAX_LENGTH];
     DYNAMIC_TIME_ZONE_INFORMATION timezone;
     GEOID geoid = GEOID_NOT_AVAILABLE;
     DWORD count, dispos, i;
@@ -714,6 +735,16 @@ void init_locale(void)
 
     if (GetEnvironmentVariableW( L"WINEUNIXCP", bufferW, ARRAY_SIZE(bufferW) ))
         unix_cp = wcstoul( bufferW, NULL, 10 );
+    if (GetEnvironmentVariableW( L"WINELOCALE", bufferW, ARRAY_SIZE(bufferW) ))
+        system_lcid = locale_to_lcid( bufferW );
+    if (GetEnvironmentVariableW( L"WINEUSERLOCALE", bufferW, ARRAY_SIZE(bufferW) ))
+        user_lcid = locale_to_lcid( bufferW );
+    if (!system_lcid) system_lcid = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT );
+    if (!user_lcid) user_lcid = system_lcid;
+
+    NtSetDefaultUILanguage( LANGIDFROMLCID(user_lcid) );
+    NtSetDefaultLocale( TRUE, user_lcid );
+    NtSetDefaultLocale( FALSE, system_lcid );
 
     kernel32_handle = GetModuleHandleW( L"kernel32.dll" );
 
@@ -775,11 +806,11 @@ void init_locale(void)
     count = sizeof(bufferW);
     if (!RegQueryValueExW( intl_key, L"Locale", NULL, NULL, (BYTE *)bufferW, &count ))
     {
-        if (wcstoul( bufferW, NULL, 16 ) == lcid) return;  /* already set correctly */
-        TRACE( "updating registry, locale changed %s -> %08x\n", debugstr_w(bufferW), lcid );
+        if (wcstoul( bufferW, NULL, 16 ) == user_lcid) return;  /* already set correctly */
+        TRACE( "updating registry, locale changed %s -> %08x\n", debugstr_w(bufferW), user_lcid );
     }
-    else TRACE( "updating registry, locale changed none -> %08x\n", lcid );
-    swprintf( bufferW, ARRAY_SIZE(bufferW), L"%08x", lcid );
+    else TRACE( "updating registry, locale changed none -> %08x\n", user_lcid );
+    swprintf( bufferW, ARRAY_SIZE(bufferW), L"%08x", user_lcid );
     RegSetValueExW( intl_key, L"Locale", 0, REG_SZ,
                     (BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR) );
 
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c
index 758789a533c..19626a48b72 100644
--- a/dlls/ntdll/locale.c
+++ b/dlls/ntdll/locale.c
@@ -533,48 +533,12 @@ static unsigned int compose_string( const struct norm_table *info, WCHAR *str, u
 }
 
 
-static LCID locale_to_lcid( WCHAR *win_name )
-{
-    WCHAR *p;
-    LCID lcid;
-
-    if (!RtlLocaleNameToLcid( win_name, &lcid, 0 )) return lcid;
-
-    /* try neutral name */
-    if ((p = wcsrchr( win_name, '-' )))
-    {
-        *p = 0;
-        if (!RtlLocaleNameToLcid( win_name, &lcid, 2 ))
-        {
-            if (SUBLANGID(lcid) == SUBLANG_NEUTRAL)
-                lcid = MAKELANGID( PRIMARYLANGID(lcid), SUBLANG_DEFAULT );
-            return lcid;
-        }
-    }
-    return 0;
-}
-
-
 /******************************************************************
  *		init_locale
  */
 void init_locale( HMODULE module )
 {
-    WCHAR system_locale[LOCALE_NAME_MAX_LENGTH];
-    WCHAR user_locale[LOCALE_NAME_MAX_LENGTH];
-
     kernel32_handle = module;
-
-    unix_funcs->get_locales( system_locale, user_locale );
-    system_lcid = locale_to_lcid( system_locale );
-    user_lcid = locale_to_lcid( user_locale );
-    if (!system_lcid) system_lcid = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT );
-    if (!user_lcid) user_lcid = system_lcid;
-
-    NtSetDefaultUILanguage( LANGIDFROMLCID(user_lcid) );
-    NtSetDefaultLocale( TRUE, user_lcid );
-    NtSetDefaultLocale( FALSE, system_lcid );
-    TRACE( "system=%04x user=%04x\n", system_lcid, user_lcid );
 }
 
 
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 84d5ab298a4..cca334865e4 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -545,6 +545,8 @@ static BOOL is_dynamic_env_var( const char *var )
             STARTS_WITH( var, "WINECONFIGDIR=" ) ||
             STARTS_WITH( var, "WINEDLLDIR" ) ||
             STARTS_WITH( var, "WINEUNIXCP=" ) ||
+            STARTS_WITH( var, "WINELOCALE=" ) ||
+            STARTS_WITH( var, "WINEUSERLOCALE=" ) ||
             STARTS_WITH( var, "WINEUSERNAME=" ) ||
             STARTS_WITH( var, "WINEPRELOADRESERVE=" ) ||
             STARTS_WITH( var, "WINELOADERNOEXEC=" ) ||
@@ -1197,13 +1199,14 @@ static WCHAR *get_dynamic_environment( SIZE_T *size )
     DWORD i;
     char str[22];
 
-    alloc = 20 * 8;  /* 8 variable names */
+    alloc = 20 * 10;  /* 10 variable names */
     if (data_dir) alloc += strlen( data_dir ) + 9;
     if (home_dir) alloc += strlen( home_dir ) + 9;
     if (build_dir) alloc += strlen( build_dir ) + 9;
     if (config_dir) alloc += strlen( config_dir ) + 9;
     if (user_name) alloc += strlen( user_name );
     if (overrides) alloc += strlen( overrides );
+    alloc += strlen(system_locale) + strlen(user_locale);
     for (i = 0; dll_paths[i]; i++) alloc += 20 + strlen( dll_paths[i] ) + 9;
 
     if (!(buffer = malloc( alloc * sizeof(WCHAR) ))) return NULL;
@@ -1223,6 +1226,8 @@ static WCHAR *get_dynamic_environment( SIZE_T *size )
         sprintf( str, "%u", unix_cp.data[1] );
         append_envA( buffer, &pos, "WINEUNIXCP", str );
     }
+    append_envA( buffer, &pos, "WINELOCALE", system_locale );
+    if (strcmp( user_locale, system_locale )) append_envA( buffer, &pos, "WINEUSERLOCALE", user_locale );
     assert( pos <= alloc );
     *size = pos * sizeof(WCHAR);
     return buffer;
@@ -1355,18 +1360,6 @@ static void get_initial_directory( UNICODE_STRING *dir )
 }
 
 
-/*************************************************************************
- *		get_locales
- *
- * Return the system and user locales. Buffers must be at least LOCALE_NAME_MAX_LENGTH chars long.
- */
-void CDECL get_locales( WCHAR *sys, WCHAR *user )
-{
-    ntdll_umbstowcs( system_locale, strlen(system_locale) + 1, sys, LOCALE_NAME_MAX_LENGTH );
-    ntdll_umbstowcs( user_locale, strlen(user_locale) + 1, user, LOCALE_NAME_MAX_LENGTH );
-}
-
-
 /***********************************************************************
  *           build_command_line
  *
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 21e1e1893c0..b7e1432535d 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1715,7 +1715,6 @@ static struct unix_funcs unix_funcs =
     ntdll_sin,
     ntdll_sqrt,
     ntdll_tan,
-    get_locales,
     virtual_release_address_space,
     load_so_dll,
     load_builtin_dll,
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index d56fc9b0f19..031f9ed3d33 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -100,7 +100,6 @@ extern LONGLONG CDECL fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN;
 extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value,
                                     const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
 
-extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
 extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
 
 extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
index 6a7f008ed9c..290379a9310 100644
--- a/dlls/ntdll/unixlib.h
+++ b/dlls/ntdll/unixlib.h
@@ -26,7 +26,7 @@
 struct _DISPATCHER_CONTEXT;
 
 /* increment this when you change the function table */
-#define NTDLL_UNIXLIB_VERSION 114
+#define NTDLL_UNIXLIB_VERSION 115
 
 struct unix_funcs
 {
@@ -69,9 +69,6 @@ struct unix_funcs
     double        (CDECL *sqrt)( double d );
     double        (CDECL *tan)( double d );
 
-    /* environment functions */
-    void          (CDECL *get_locales)( WCHAR *sys, WCHAR *user );
-
     /* virtual memory functions */
     void          (CDECL *virtual_release_address_space)(void);
 




More information about the wine-cvs mailing list