Alexandre Julliard : ntdll: Support loading builtin modules that don't use a constructor.

Alexandre Julliard julliard at winehq.org
Wed Apr 15 15:55:42 CDT 2020


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Apr 15 19:37:44 2020 +0200

ntdll: Support loading builtin modules that don't use a constructor.

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

---

 dlls/ntdll/loader.c | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 9329dd2a9b..1e50e2b663 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1780,6 +1780,7 @@ static void load_builtin_callback( void *module, const char *filename )
     if (!module)
     {
         ERR("could not map image for %s\n", debugstr_us(builtin_load_info->filename) );
+        builtin_load_info->status = STATUS_NO_MEMORY;
         return;
     }
     if (!(nt = RtlImageNtHeader( module )))
@@ -2555,6 +2556,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
     static const WCHAR soW[] = {'.','s','o',0};
     DWORD len;
     void *handle;
+    const IMAGE_NT_HEADERS *nt;
     struct builtin_load_info info, *prev_info;
     ANSI_STRING unix_name;
     UNICODE_STRING win_name = *nt_name;
@@ -2581,7 +2583,6 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
     prev_info = builtin_load_info;
     builtin_load_info = &info;
     handle = dlopen( so_name ? so_name : unix_name.Buffer, RTLD_NOW );
-    builtin_load_info = prev_info;
     RtlFreeHeap( GetProcessHeap(), 0, unix_name.Buffer );
 
     if (!handle)
@@ -2589,15 +2590,39 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
         if (so_name)
         {
             ERR("failed to load .so lib %s: %s\n", debugstr_a(so_name), dlerror() );
-            return STATUS_PROCEDURE_NOT_FOUND;
+            info.status = STATUS_PROCEDURE_NOT_FOUND;
+        }
+        else
+        {
+            WARN( "failed to load .so lib %s: %s\n", debugstr_us(nt_name), dlerror() );
+            info.status = STATUS_INVALID_IMAGE_FORMAT;
         }
-        WARN( "failed to load .so lib %s: %s\n", debugstr_us(nt_name), dlerror() );
-        return STATUS_INVALID_IMAGE_FORMAT;
     }
 
     if (info.status != STATUS_SUCCESS) goto failed;
 
-    if (!info.wm)
+    if (!info.wm && (nt = dlsym( handle, "__wine_spec_nt_header" )))
+    {
+        HMODULE module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
+        if ((info.wm = get_modref( module )))  /* already loaded */
+        {
+            TRACE( "Found %s at %p for builtin %s\n",
+                   debugstr_w(info.wm->ldr.FullDllName.Buffer), info.wm->ldr.BaseAddress,
+                   debugstr_us(nt_name) );
+            if (info.wm->ldr.LoadCount != -1) info.wm->ldr.LoadCount++;
+            dlclose( handle );
+        }
+        else
+        {
+            __wine_dll_register( nt, NULL );
+            if (!info.wm) goto failed;
+            TRACE_(loaddll)( "Loaded %s at %p: builtin\n",
+                             debugstr_w(info.wm->ldr.FullDllName.Buffer), info.wm->ldr.BaseAddress );
+            info.wm->ldr.LoadCount = 1;
+            info.wm->ldr.SectionHandle = handle;
+        }
+    }
+    else if (!info.wm)
     {
         /* The constructor wasn't called, this means the .so is already
          * loaded under a different name. Try to find the wm for it. */
@@ -2620,11 +2645,13 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
         info.wm->ldr.SectionHandle = handle;
     }
 
+    builtin_load_info = prev_info;
     *pwm = info.wm;
     return STATUS_SUCCESS;
 
 failed:
-    dlclose( handle );
+    builtin_load_info = prev_info;
+    if (handle) dlclose( handle );
     return info.status;
 }
 




More information about the wine-cvs mailing list