[PATCH] ntdll: Always try searching apiset DLLs in the default directories.

Paul Gofman pgofman at codeweavers.com
Mon Dec 20 09:07:33 CST 2021


This is a temporary workaround until we have a correct apisets
implementation.

Signed-off-by: Paul Gofman <pgofman at 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 );
     }
-- 
2.33.1




More information about the wine-devel mailing list