Module: wine Branch: master Commit: b8845e61be25d1cd174901f4d4cf5ec54539ceb4 URL: https://gitlab.winehq.org/wine/wine/-/commit/b8845e61be25d1cd174901f4d4cf5ec...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Nov 16 10:44:36 2022 +0100
ntdll: Use the unique id of the user locale for resource lookup.
---
dlls/ntdll/locale.c | 40 ++++++++++++++++++++++++++++++++++++---- dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/resource.c | 18 ++++++++---------- 3 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index b4bfdf48f0c..105de1feec4 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -39,9 +39,13 @@ UINT NlsAnsiCodePage = 0; BYTE NlsMbCodePageTag = 0; BYTE NlsMbOemCodePageTag = 0;
+static LCID user_resource_lcid; +static LCID user_resource_neutral_lcid; +static LCID system_lcid; static NLSTABLEINFO nls_info = { { CP_UTF8 }, { CP_UTF8 } }; static struct norm_table *norm_tables[16]; static const NLS_LOCALE_HEADER *locale_table; +static const WCHAR *locale_strings;
static WCHAR casemap( USHORT *table, WCHAR ch ) @@ -94,7 +98,6 @@ void locale_init(void) WCHAR locale[LOCALE_NAME_MAX_LENGTH]; LARGE_INTEGER unused; SIZE_T size; - LCID system_lcid; UINT ansi_cp = 1252, oem_cp = 437; void *ansi_ptr = utf8, *oem_ptr = utf8, *case_ptr; NTSTATUS status; @@ -107,6 +110,7 @@ void locale_init(void) return; } locale_table = (const NLS_LOCALE_HEADER *)((char *)header + header->locales); + locale_strings = (const WCHAR *)((char *)locale_table + locale_table->strings_offset);
if (system_lcid == LOCALE_CUSTOM_UNSPECIFIED) { @@ -119,6 +123,26 @@ void locale_init(void) oem_cp = get_locale_data( locale_table, entry->idx )->idefaultcodepage; }
+ NtQueryDefaultLocale( TRUE, &user_resource_lcid ); + user_resource_neutral_lcid = PRIMARYLANGID( user_resource_lcid ); + if (user_resource_lcid == LOCALE_CUSTOM_UNSPECIFIED) + { + const NLS_LOCALE_LCNAME_INDEX *entry; + const WCHAR *parent; + WCHAR bufferW[LOCALE_NAME_MAX_LENGTH]; + SIZE_T len; + + if (!RtlQueryEnvironmentVariable( NULL, L"WINEUSERLOCALE", 14, bufferW, ARRAY_SIZE(bufferW), &len ) + && (entry = find_lcname_entry( locale_table, bufferW ))) + { + user_resource_lcid = get_locale_data( locale_table, entry->idx )->unique_lcid; + parent = locale_strings + get_locale_data( locale_table, entry->idx )->sparent; + if (*parent && (entry = find_lcname_entry( locale_table, parent + 1 ))) + user_resource_neutral_lcid = get_locale_data( locale_table, entry->idx )->unique_lcid; + } + } + TRACE( "resources: %04x/%04x/%04x\n", user_resource_lcid, user_resource_neutral_lcid, system_lcid ); + if (!RtlQueryActivationContextApplicationSettings( 0, NULL, L"http://schemas.microsoft.com/SMI/2019/WindowsSettings", L"activeCodePage", locale, ARRAY_SIZE(locale), NULL )) { @@ -159,6 +183,15 @@ void locale_init(void) }
+/* return LCIDs to use for resource lookup */ +void get_resource_lcids( LANGID *user, LANGID *user_neutral, LANGID *system ) +{ + *user = LANGIDFROMLCID( user_resource_lcid ); + *user_neutral = LANGIDFROMLCID( user_resource_neutral_lcid ); + *system = LANGIDFROMLCID( system_lcid ); +} + + static NTSTATUS get_dummy_preferred_ui_language( DWORD flags, LANGID lang, ULONG *count, WCHAR *buffer, ULONG *size ) { @@ -841,7 +874,6 @@ BOOLEAN WINAPI RtlIsValidLocaleName( const WCHAR *name, ULONG flags ) */ NTSTATUS WINAPI RtlLcidToLocaleName( LCID lcid, UNICODE_STRING *str, ULONG flags, BOOLEAN alloc ) { - const WCHAR *strings = (const WCHAR *)((char *)locale_table + locale_table->strings_offset); const NLS_LOCALE_LCID_INDEX *entry; const WCHAR *name; ULONG len; @@ -855,7 +887,7 @@ NTSTATUS WINAPI RtlLcidToLocaleName( LCID lcid, UNICODE_STRING *str, ULONG flags break; case LOCALE_SYSTEM_DEFAULT: case LOCALE_CUSTOM_DEFAULT: - NtQueryDefaultLocale( FALSE, &lcid ); + lcid = system_lcid; break; case LOCALE_CUSTOM_UI_DEFAULT: return STATUS_UNSUCCESSFUL; @@ -868,7 +900,7 @@ NTSTATUS WINAPI RtlLcidToLocaleName( LCID lcid, UNICODE_STRING *str, ULONG flags if (!(flags & 2) && !get_locale_data( locale_table, entry->idx )->inotneutral) return STATUS_INVALID_PARAMETER_1;
- name = strings + entry->name; + name = locale_strings + entry->name; len = *name++;
if (alloc) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 36972a966f1..d1a7790991b 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -72,6 +72,7 @@ extern void actctx_init(void) DECLSPEC_HIDDEN; extern void locale_init(void) DECLSPEC_HIDDEN; extern void init_user_process_params(void) DECLSPEC_HIDDEN; extern void CDECL DECLSPEC_NORETURN signal_start_thread( CONTEXT *ctx ) DECLSPEC_HIDDEN; +extern void get_resource_lcids( LANGID *user, LANGID *user_neutral, LANGID *system ) DECLSPEC_HIDDEN;
/* module handling */ extern LIST_ENTRY tls_links DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/resource.c b/dlls/ntdll/resource.c index 58a0fc7d2e2..2d32aafe1c9 100644 --- a/dlls/ntdll/resource.c +++ b/dlls/ntdll/resource.c @@ -175,7 +175,6 @@ static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( const IMAGE_RESOURCE_ static NTSTATUS find_entry( HMODULE hmod, const LDR_RESOURCE_INFO *info, ULONG level, const void **ret, int want_dir ) { - static LCID user_lcid, system_lcid; ULONG size; const void *root; const IMAGE_RESOURCE_DIRECTORY *resdirptr; @@ -210,29 +209,28 @@ static NTSTATUS find_entry( HMODULE hmod, const LDR_RESOURCE_INFO *info, /* if no explicitly specified language, try some defaults */ if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL) { + LANGID user_lang, user_neutral_lang, system_lang; + + get_resource_lcids( &user_lang, &user_neutral_lang, &system_lang ); + /* user defaults, unless SYS_DEFAULT sublanguage specified */ if (SUBLANGID(info->Language) != SUBLANG_SYS_DEFAULT) { - if (!user_lcid) NtQueryDefaultLocale( TRUE, &user_lcid ); - /* 4. current thread locale language */ pos = push_language( list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale) );
/* 5. user locale language */ - pos = push_language( list, pos, LANGIDFROMLCID(user_lcid) ); + pos = push_language( list, pos, user_lang );
/* 6. user locale language with neutral sublanguage */ - pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(user_lcid), SUBLANG_NEUTRAL ) ); + pos = push_language( list, pos, user_neutral_lang ); }
- /* now system defaults */ - if (!system_lcid) NtQueryDefaultLocale( FALSE, &system_lcid ); - /* 7. system locale language */ - pos = push_language( list, pos, LANGIDFROMLCID( system_lcid ) ); + pos = push_language( list, pos, system_lang );
/* 8. system locale language with neutral sublanguage */ - pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(system_lcid), SUBLANG_NEUTRAL ) ); + pos = push_language( list, pos, PRIMARYLANGID( system_lang ));
/* 9. English */ pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) );