From: Craig Schulstad <craigaschulstad@gmail.com> Before attempting to find a resource, determine if there is an associated multi-language resource file base upon the user language and if such a file is found, also search the file for resource data such as menu items, dialog boxes, and so forth. --- dlls/kernelbase/loader.c | 92 +++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c index 9bcf315c103..3d2b179c071 100755 --- a/dlls/kernelbase/loader.c +++ b/dlls/kernelbase/loader.c @@ -60,6 +60,7 @@ static CRITICAL_SECTION exclusive_datafile_list_section = { &critsect_debug, -1, static WCHAR mui_locale[LOCALE_NAME_MAX_LENGTH]; static BOOL locale_found = FALSE; static BOOL recursion_flag = FALSE; +static HMODULE module_mui = NULL; /*********************************************************************** * Modules @@ -1069,9 +1070,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExW( HMODULE module, ENUMRESTYPEP HMODULE get_mui(HMODULE module) { WCHAR module_name[MAX_PATH], mui_name[MAX_PATH]; - HMODULE mui_module; - - INT i, j, k, l; + HMODULE mui_module = NULL; + INT i, j = 0, k = 0, l = 0; /* Initialize the work strings */ @@ -1082,13 +1082,20 @@ HMODULE get_mui(HMODULE module) /* Acquire the base resource file name */ - if (!(GetModuleFileNameW(module, module_name, MAX_PATH))) - return module; + if (!(GetModuleFileNameW(module, module_name, MAX_PATH))) { + TRACE ("Module file name was not found - returning with source module\n"); + return module; + } + + /* Stay with the original module reference if this file is not an executable file. */ + + if (!(wcsstr(module_name, L".exe"))) + return module; if (!(locale_found)) { if (recursion_flag) - return module; + return module; recursion_flag = TRUE; @@ -1102,8 +1109,6 @@ HMODULE get_mui(HMODULE module) /* Locate the position of the final backslash in the retrieved executable file. */ - j = 0; - for (i = 0; i < MAX_PATH; i++) { if (module_name[i] == 0) break; @@ -1113,8 +1118,6 @@ HMODULE get_mui(HMODULE module) /* Set up the work index that will be used to extract just the executable file from the fully qualified file name. */ - k = 0; - for (i = 0; i < MAX_PATH; i++) { if (module_name[i] == 0) break; @@ -1149,13 +1152,13 @@ HMODULE get_mui(HMODULE module) mui_module = LoadLibraryExW(mui_name, 0, 0); - if (mui_module != NULL) - TRACE("MUI module found: %s Address: %p\n", debugstr_w(module_name), mui_module); - - if (mui_module != NULL) + if (mui_module != NULL) { + module_mui = mui_module; return mui_module; - else + } else { + module_mui = NULL; return module; + } } @@ -1184,7 +1187,8 @@ HRSRC get_res_handle(HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang) info.Language = lang; status = LdrFindResource_U( module, &info, 3, &entry ); done: - if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + if (status != STATUS_SUCCESS) + SetLastError( RtlNtStatusToDosError(status) ); } __EXCEPT_PAGE_FAULT { @@ -1198,31 +1202,40 @@ HRSRC get_res_handle(HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang) return (HRSRC)entry; } + /********************************************************************** * FindResourceExW (kernelbase.@) */ HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang ) { - HRSRC rsrc; - HMODULE work_module = NULL; - - TRACE( "FindResourceW: %p %s %s %04x\n", module, debugstr_w(type), debugstr_w(name), lang ); + HRSRC rsrc; + HMODULE work_module = NULL, test_module = NULL; if (!module) module = GetModuleHandleW( 0 ); - work_module = GetModuleHandleW( 0 ); + work_module = GetModuleHandleW( 0 ); - if (module != work_module) { + if (module != work_module) { rsrc = get_res_handle(module, type, name, lang); - } else { - rsrc = get_res_handle(get_mui(module), type, name, lang); - - if (!rsrc) - TRACE("Resource not found from MUI\n"); + module_mui = NULL; + } else { + test_module = get_mui(module); + if (test_module == module) { + rsrc = get_res_handle(module, type, name, lang); + module_mui = NULL; + } else { + rsrc = get_res_handle(test_module, type, name, lang); + + if (!rsrc) { + TRACE("Fallback from MUI to base module: %p %p %s %s\n", test_module, module, debugstr_w(type), debugstr_w(name)); + rsrc = get_res_handle(module, type, name, lang); + module_mui = NULL; + } + } } - return rsrc; + return rsrc; } @@ -1250,26 +1263,25 @@ BOOL WINAPI DECLSPEC_HOTPATCH FreeResource( HGLOBAL handle ) HGLOBAL WINAPI DECLSPEC_HOTPATCH LoadResource( HINSTANCE module, HRSRC rsrc ) { void *ret; - - HMODULE work_module = NULL; - - TRACE( "LoadResource: %p %p\n", module, rsrc ); + HMODULE work_module = NULL; if (!rsrc) return 0; if (!module) module = GetModuleHandleW( 0 ); + work_module = module; - work_module = GetModuleHandleW( 0 ); + /* Check for and use a MUI module */ - if (module != work_module) { - if (!set_ntstatus( LdrAccessResource( module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL ))) - return 0; - return ret; + if (module_mui != NULL) { + if (((HMODULE)rsrc < module) || ((module_mui > module) && ((HMODULE)rsrc > module_mui))) + work_module = module_mui; } - if (!set_ntstatus( LdrAccessResource( get_mui(module), (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL ))) { - TRACE("Resource was not loaded\n"); + /* Ready this handle for next resource retrieval */ + + module_mui= NULL; + + if (!set_ntstatus( LdrAccessResource( work_module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL ))) return 0; - } return ret; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10209