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>
This commit is contained in:
parent
4a10f3a188
commit
bb065801a6
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue