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