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