Module: wine Branch: master Commit: 6ac357667ee3f4739fff45d03f88e1bc19bd079a URL: https://source.winehq.org/git/wine.git/?a=commit;h=6ac357667ee3f4739fff45d03...
Author: Alexandre Julliard julliard@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@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; }