Commit 5fef775d authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Delay mapping a module until we have found the final one to load.

parent 63b62953
......@@ -1140,15 +1140,14 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
*
* Open a file for a new dll. Helper for open_builtin_file.
*/
static NTSTATUS open_dll_file( const char *name, void **module, SECTION_IMAGE_INFORMATION *image_info )
static NTSTATUS open_dll_file( const char *name, HANDLE *mapping, void **module,
SECTION_IMAGE_INFORMATION *image_info, struct stat *st )
{
struct builtin_module *builtin;
OBJECT_ATTRIBUTES attr = { sizeof(attr) };
LARGE_INTEGER size;
struct stat st;
SIZE_T len = 0;
NTSTATUS status;
HANDLE handle, mapping;
HANDLE handle;
if ((status = open_unix_file( &handle, name, GENERIC_READ | SYNCHRONIZE, &attr, 0,
FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN,
......@@ -1157,70 +1156,50 @@ static NTSTATUS open_dll_file( const char *name, void **module, SECTION_IMAGE_IN
if (status != STATUS_OBJECT_PATH_NOT_FOUND && status != STATUS_OBJECT_NAME_NOT_FOUND)
{
/* if the file exists but failed to open, report the error */
if (!stat( name, &st )) return status;
if (!stat( name, st )) return status;
}
/* otherwise continue searching */
return STATUS_DLL_NOT_FOUND;
}
if (!stat( name, &st ))
if (!stat( name, st ))
{
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
{
if (builtin->id.dev == st.st_dev && builtin->id.ino == st.st_ino)
if (builtin->id.dev == st->st_dev && builtin->id.ino == st->st_ino)
{
TRACE( "%s is the same file as existing module %p\n", debugstr_a(name),
builtin->module );
NtClose( handle );
NtUnmapViewOfSection( NtCurrentProcess(), *module );
*module = builtin->module;
return STATUS_SUCCESS;
}
}
}
else memset( &st, 0, sizeof(st) );
else memset( st, 0, sizeof(*st) );
*module = NULL;
size.QuadPart = 0;
status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
status = NtCreateSection( mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
SECTION_MAP_READ | SECTION_MAP_EXECUTE,
NULL, &size, PAGE_EXECUTE_READ, SEC_IMAGE, handle );
NtClose( handle );
if (status) return status;
NtQuerySection( mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL );
NtQuerySection( *mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL );
/* ignore non-builtins */
if (!(image_info->u.ImageFlags & IMAGE_FLAGS_WineBuiltin))
{
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_a(name) );
status = STATUS_DLL_NOT_FOUND;
NtClose( *mapping );
}
else if (!is_valid_binary( image_info ))
{
TRACE( "%s is for arch %x, continuing search\n", debugstr_a(name), image_info->Machine );
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
NtClose( *mapping );
}
else
{
if (*module)
{
NtUnmapViewOfSection( NtCurrentProcess(), *module );
*module = NULL;
}
status = NtMapViewOfSection( mapping, NtCurrentProcess(), module, 0, 0, NULL, &len,
ViewShare, 0, PAGE_EXECUTE_READ );
if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS;
if (!status)
{
status = add_builtin_module( *module, NULL, &st );
if (status)
{
NtUnmapViewOfSection( NtCurrentProcess(), *module );
*module = NULL;
}
}
}
NtClose( mapping );
return status;
}
......@@ -1228,12 +1207,13 @@ static NTSTATUS open_dll_file( const char *name, void **module, SECTION_IMAGE_IN
/***********************************************************************
* open_builtin_file
*/
static NTSTATUS open_builtin_file( char *name, void **module, SECTION_IMAGE_INFORMATION *image_info )
static NTSTATUS open_builtin_file( char *name, HANDLE *mapping, void **module,
SECTION_IMAGE_INFORMATION *image_info, struct stat *st )
{
NTSTATUS status;
int fd;
status = open_dll_file( name, module, image_info );
status = open_dll_file( name, mapping, module, image_info, st );
if (status != STATUS_DLL_NOT_FOUND) return status;
/* try .so file */
......@@ -1243,8 +1223,6 @@ static NTSTATUS open_builtin_file( char *name, void **module, SECTION_IMAGE_INFO
{
if (check_library_arch( fd ))
{
NtUnmapViewOfSection( NtCurrentProcess(), *module );
*module = NULL;
if (!dlopen_dll( name, module ))
{
memset( image_info, 0, sizeof(*image_info) );
......@@ -1265,6 +1243,28 @@ static NTSTATUS open_builtin_file( char *name, void **module, SECTION_IMAGE_INFO
/***********************************************************************
* map_builtin_module
*/
static NTSTATUS map_builtin_module( HANDLE mapping, void **module, struct stat *st )
{
NTSTATUS status;
SIZE_T len = 0;
*module = NULL;
status = NtMapViewOfSection( mapping, NtCurrentProcess(), module, 0, 0, NULL, &len,
ViewShare, 0, PAGE_EXECUTE_READ );
if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS;
if (!status)
{
status = add_builtin_module( *module, NULL, st );
if (status) NtUnmapViewOfSection( NtCurrentProcess(), *module );
}
return status;
}
/***********************************************************************
* load_builtin_dll
*/
static NTSTATUS CDECL load_builtin_dll( const WCHAR *name, void **module, void **unix_entry,
......@@ -1274,6 +1274,8 @@ static NTSTATUS CDECL load_builtin_dll( const WCHAR *name, void **module, void *
char *ptr = NULL, *file, *ext = NULL;
NTSTATUS status = STATUS_DLL_NOT_FOUND;
BOOL found_image = FALSE;
HANDLE mapping;
struct stat st;
len = wcslen( name );
if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/") + len;
......@@ -1302,7 +1304,7 @@ static NTSTATUS CDECL load_builtin_dll( const WCHAR *name, void **module, void *
ptr = prepend( ptr, ptr, namelen );
ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 );
ptr = prepend( ptr, build_dir, strlen(build_dir) );
status = open_builtin_file( ptr, module, image_info );
status = open_builtin_file( ptr, &mapping, module, image_info, &st );
if (status != STATUS_DLL_NOT_FOUND) goto done;
/* now as a program */
......@@ -1313,7 +1315,7 @@ static NTSTATUS CDECL load_builtin_dll( const WCHAR *name, void **module, void *
ptr = prepend( ptr, ptr, namelen );
ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 );
ptr = prepend( ptr, build_dir, strlen(build_dir) );
status = open_builtin_file( ptr, module, image_info );
status = open_builtin_file( ptr, &mapping, module, image_info, &st );
if (status != STATUS_DLL_NOT_FOUND) goto done;
}
......@@ -1321,7 +1323,7 @@ static NTSTATUS CDECL load_builtin_dll( const WCHAR *name, void **module, void *
{
file[pos + len + 1] = 0;
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
status = open_builtin_file( ptr, module, image_info );
status = open_builtin_file( ptr, &mapping, module, image_info, &st );
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
else if (status != STATUS_DLL_NOT_FOUND) goto done;
}
......@@ -1330,6 +1332,11 @@ static NTSTATUS CDECL load_builtin_dll( const WCHAR *name, void **module, void *
WARN( "cannot find builtin library for %s\n", debugstr_w(name) );
done:
if (!status && !*module)
{
status = map_builtin_module( mapping, module, &st );
NtClose( mapping );
}
if (!status && ext)
{
strcpy( ext, ".so" );
......@@ -1452,11 +1459,18 @@ static void load_ntdll(void)
{
NTSTATUS status;
SECTION_IMAGE_INFORMATION info;
void *module = NULL;
HANDLE mapping;
struct stat st;
void *module;
char *name = build_path( dll_dir, "ntdll.dll.so" );
name[strlen(name) - 3] = 0; /* remove .so */
status = open_builtin_file( name, &module, &info );
status = open_builtin_file( name, &mapping, &module, &info, &st );
if (!status && !module)
{
status = map_builtin_module( mapping, &module, &st );
NtClose( mapping );
}
if (status) fatal_error( "failed to load %s error %x\n", name, status );
free( name );
load_ntdll_functions( module );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment