This is a temporary workaround until we have a correct apisets implementation.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- Previously builtin DLLs could always be loaded regardless of the dll search path options provided by the applications. That has changed and now, e. g., with LOAD_LIBRARY_SEARCH_APPLICATION_DIR flag the DLLs residing in the system paths won't be loaded. Which is correct for normal system DLLs but not for apisets pseudo dlls.
The full solution would be to implement apisets properly but we should probably workaround that for now to fix 7.0 regressions.
dlls/kernel32/tests/module.c | 23 +++++++++++++++++++++++ dlls/ntdll/loader.c | 12 ++++++++++++ 2 files changed, 35 insertions(+)
diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c index 2ee23595f55..8ec3a5433ee 100644 --- a/dlls/kernel32/tests/module.c +++ b/dlls/kernel32/tests/module.c @@ -466,6 +466,7 @@ static void testLoadLibraryEx(void)
static void test_LoadLibraryEx_search_flags(void) { + static const char apiset_dll[] = "api-ms-win-shcore-obsolete-l1-1-0.dll"; static const struct { int add_dirs[4]; @@ -684,6 +685,28 @@ static void test_LoadLibraryEx_search_flags(void) for (k = 0; tests[j].add_dirs[k]; k++) pRemoveDllDirectory( cookies[k] ); }
+ mod = GetModuleHandleA( apiset_dll ); + if (mod) + { + win_skip( "%s already referenced, skipping test.\n", apiset_dll ); + } + else + { + mod = LoadLibraryA( apiset_dll ); + if (mod) + { + FreeLibrary(mod); + mod = LoadLibraryExA( apiset_dll, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); + ok( !!mod, "Got NULL module, error %u.\n", GetLastError() ); + ok( !!GetModuleHandleA( apiset_dll ), "Got NULL handle.\n" ); + ret = FreeLibrary( mod ); + ok( ret, "FreeLibrary failed, error %u.\n", GetLastError() ); + } + else + { + win_skip( "%s not found, skipping test.\n", apiset_dll ); + } + } done: for (i = 1; i <= 6; i++) { diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index d11f3f0f79d..8a4a7258eac 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -2905,6 +2905,16 @@ done: return status; }
+/*********************************************************************** + * is_apiset_dll_name + * + */ +static BOOL is_apiset_dll_name( const WCHAR *name ) +{ + static const WCHAR name_prefix[] = L"api-ms-win-"; + + return !wcsnicmp( name, name_prefix, ARRAY_SIZE(name_prefix) - 1 ); +}
/*********************************************************************** * find_dll_file @@ -2948,6 +2958,8 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, UNI if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH) { status = search_dll_file( load_path, libname, nt_name, pwm, mapping, image_info, id ); + if (status == STATUS_DLL_NOT_FOUND && load_path && is_apiset_dll_name( libname )) + status = search_dll_file( NULL, libname, nt_name, pwm, mapping, image_info, id ); if (status == STATUS_DLL_NOT_FOUND) status = find_builtin_without_file( libname, nt_name, pwm, mapping, image_info, id ); }