Alexandre Julliard : ntdll: Map the builtin or fake dll from the Wine dirs if it's missing from the prefix.

Alexandre Julliard julliard at winehq.org
Tue Mar 30 15:19:49 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar 30 10:12:07 2021 +0200

ntdll: Map the builtin or fake dll from the Wine dirs if it's missing from the prefix.

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

---

 dlls/kernel32/tests/module.c |   4 +-
 dlls/mscoree/tests/mscoree.c |   4 +-
 dlls/ntdll/loader.c          | 141 ++++++++++++++++++++++++++-----------------
 3 files changed, 88 insertions(+), 61 deletions(-)

diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c
index 6eb2fc804d1..46f5c43b54e 100644
--- a/dlls/kernel32/tests/module.c
+++ b/dlls/kernel32/tests/module.c
@@ -422,10 +422,8 @@ static void testLoadLibraryEx(void)
     /* load kernel32.dll with an absolute path that does not exist */
     SetLastError(0xdeadbeef);
     hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
+    ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
     todo_wine
-    {
-        ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
-    }
     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
 
diff --git a/dlls/mscoree/tests/mscoree.c b/dlls/mscoree/tests/mscoree.c
index 9974eff6335..92126339ef0 100644
--- a/dlls/mscoree/tests/mscoree.c
+++ b/dlls/mscoree/tests/mscoree.c
@@ -368,7 +368,7 @@ static void test_loadlibraryshim(void)
     }
 
     hr = pLoadLibraryShim(fusion, vbogus, NULL, &hdll);
-    todo_wine ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr);
+    ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr);
     if (SUCCEEDED(hr))
         FreeLibrary(hdll);
 
@@ -406,7 +406,7 @@ static void test_loadlibraryshim(void)
         FreeLibrary(hdll);
 
     hr = pLoadLibraryShim(gdidll, latest, NULL, &hdll);
-    todo_wine ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr);
+    ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr);
     if (SUCCEEDED(hr))
         FreeLibrary(hdll);
 }
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 7dada146044..e8b53778284 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2378,38 +2378,6 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
 }
 
 
-/***********************************************************************
- *           load_builtin_dll
- */
-static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name,
-                                  DWORD flags, WINE_MODREF** pwm, BOOL prefer_native )
-{
-    NTSTATUS status;
-    void *module;
-    SECTION_IMAGE_INFORMATION image_info;
-
-    TRACE("Trying built-in %s\n", debugstr_us(nt_name));
-
-    status = unix_funcs->load_builtin_dll( nt_name, &module, &image_info, prefer_native );
-    if (status) return status;
-
-    if ((*pwm = find_existing_module( module )))  /* already loaded */
-    {
-        if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++;
-        TRACE( "Found %s for %s at %p, count=%d\n",
-               debugstr_us(&(*pwm)->ldr.FullDllName), debugstr_us(nt_name),
-               (*pwm)->ldr.DllBase, (*pwm)->ldr.LoadCount);
-        if (module != (*pwm)->ldr.DllBase) NtUnmapViewOfSection( NtCurrentProcess(), module );
-        return STATUS_SUCCESS;
-    }
-
-    TRACE( "loading %s\n", debugstr_us(nt_name) );
-    status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
-    if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module );
-    return status;
-}
-
-
 /*************************************************************************
  *		build_main_module
  *
@@ -2553,6 +2521,86 @@ done:
 }
 
 
+/***********************************************************************
+ *	get_env_var
+ */
+static NTSTATUS get_env_var( const WCHAR *name, SIZE_T extra, UNICODE_STRING *ret )
+{
+    NTSTATUS status;
+    SIZE_T len, size = 1024 + extra;
+
+    for (;;)
+    {
+        ret->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, size );
+        status = RtlQueryEnvironmentVariable( NULL, name, wcslen(name),
+                                              ret->Buffer, size - extra - 1, &len );
+        if (!status)
+        {
+            ret->Buffer[len] = 0;
+            ret->Length = len * sizeof(WCHAR);
+            ret->MaximumLength = size * sizeof(WCHAR);
+            return status;
+        }
+        RtlFreeHeap( GetProcessHeap(), 0, ret->Buffer );
+        if (status != STATUS_BUFFER_TOO_SMALL) return status;
+        size = len + 1 + extra;
+    }
+}
+
+
+/***********************************************************************
+ *	find_builtin_without_file
+ *
+ * Find a builtin dll when the corresponding file cannot be found in the prefix.
+ * This is used during prefix bootstrap.
+ */
+static NTSTATUS find_builtin_without_file( const WCHAR *name, UNICODE_STRING *new_name,
+                                           WINE_MODREF **pwm, HANDLE *mapping,
+                                           SECTION_IMAGE_INFORMATION *image_info, struct file_id *id )
+{
+    const WCHAR *ext;
+    WCHAR dllpath[32];
+    DWORD i, len;
+    NTSTATUS status = STATUS_DLL_NOT_FOUND;
+    BOOL found_image = FALSE;
+
+    if (!get_env_var( L"WINEBUILDDIR", 20 + 2 * wcslen(name), new_name ))
+    {
+        RtlAppendUnicodeToString( new_name, L"\\dlls\\" );
+        RtlAppendUnicodeToString( new_name, name );
+        if ((ext = wcsrchr( name, '.' )) && !wcscmp( ext, L".dll" )) new_name->Length -= 4 * sizeof(WCHAR);
+        RtlAppendUnicodeToString( new_name, L"\\" );
+        RtlAppendUnicodeToString( new_name, name );
+        status = open_dll_file( new_name, pwm, mapping, image_info, id );
+        if (status != STATUS_DLL_NOT_FOUND) return status;
+        RtlAppendUnicodeToString( new_name, L".fake" );
+        status = open_dll_file( new_name, pwm, mapping, image_info, id );
+        if (status != STATUS_DLL_NOT_FOUND) return status;
+        RtlFreeUnicodeString( new_name );
+    }
+    for (i = 0; ; i++)
+    {
+        swprintf( dllpath, ARRAY_SIZE(dllpath), L"WINEDLLDIR%u", i );
+        if (get_env_var( dllpath, 20 + wcslen(name), new_name )) break;
+        len = new_name->Length;
+        RtlAppendUnicodeToString( new_name, L"\\" );
+        RtlAppendUnicodeToString( new_name, name );
+        status = open_dll_file( new_name, pwm, mapping, image_info, id );
+        if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
+        else if (status != STATUS_DLL_NOT_FOUND) return status;
+        new_name->Length = len;
+        RtlAppendUnicodeToString( new_name, L"\\fakedlls\\" );
+        RtlAppendUnicodeToString( new_name, name );
+        status = open_dll_file( new_name, pwm, mapping, image_info, id );
+        if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
+        else if (status != STATUS_DLL_NOT_FOUND) return status;
+        RtlFreeUnicodeString( new_name );
+    }
+    if (found_image) status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
+    return status;
+}
+
+
 /***********************************************************************
  *	search_dll_file
  *
@@ -2597,14 +2645,10 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *
         paths = ptr;
     }
 
-    if (!found_image)
-    {
-        /* not found, return file in the system dir to be loaded as builtin */
-        wcscpy( name, system_dir );
-        wcscat( name, search );
-        if (!RtlDosPathNameToNtPathName_U( name, nt_name, NULL, NULL )) status = STATUS_NO_MEMORY;
-    }
-    else status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
+    if (found_image)
+        status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
+    else if (!wcspbrk( search, L":/\\" ))
+        status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id );
 
 done:
     RtlFreeHeap( GetProcessHeap(), 0, name );
@@ -2713,7 +2757,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
         return STATUS_SUCCESS;
     }
 
-    if (nts && nts != STATUS_DLL_NOT_FOUND && nts != STATUS_INVALID_IMAGE_NOT_MZ) goto done;
+    if (nts && nts != STATUS_INVALID_IMAGE_NOT_MZ) goto done;
 
     prev = NtCurrentTeb()->Tib.ArbitraryUserPointer;
     NtCurrentTeb()->Tib.ArbitraryUserPointer = nt_name.Buffer + 4;
@@ -2727,21 +2771,6 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
     case STATUS_SUCCESS:  /* valid PE file */
         nts = load_native_dll( load_path, &nt_name, mapping, &image_info, &id, flags, pwm );
         break;
-
-    case STATUS_DLL_NOT_FOUND:  /* no file found, try builtin */
-        switch (unix_funcs->get_load_order( &nt_name ))
-        {
-        case LO_NATIVE_BUILTIN:
-        case LO_BUILTIN:
-        case LO_BUILTIN_NATIVE:
-        case LO_DEFAULT:
-            nts = load_builtin_dll( load_path, &nt_name, flags, pwm, FALSE );
-            break;
-        default:
-            nts = STATUS_DLL_NOT_FOUND;
-            break;
-        }
-        break;
     }
     NtCurrentTeb()->Tib.ArbitraryUserPointer = prev;
 




More information about the wine-cvs mailing list