ntdll: Support loading a PE-format ntdll.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4fcf20d1d1
commit
f89f7a54c2
|
@ -1956,12 +1956,12 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
|
||||
|
||||
/*************************************************************************
|
||||
* build_so_dll_module
|
||||
* build_builtin_module
|
||||
*
|
||||
* Build the module for a .so builtin library.
|
||||
* Build the module for a builtin library.
|
||||
*/
|
||||
static NTSTATUS build_so_dll_module( const WCHAR *load_path, const UNICODE_STRING *nt_name,
|
||||
void *module, DWORD flags, WINE_MODREF **pwm )
|
||||
static NTSTATUS build_builtin_module( const WCHAR *load_path, const UNICODE_STRING *nt_name,
|
||||
void *module, DWORD flags, WINE_MODREF **pwm )
|
||||
{
|
||||
NTSTATUS status;
|
||||
pe_image_info_t image_info = { 0 };
|
||||
|
@ -2337,7 +2337,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((status = build_so_dll_module( load_path, &win_name, module, flags, &wm ))) return status;
|
||||
if ((status = build_builtin_module( load_path, &win_name, module, flags, &wm ))) return status;
|
||||
TRACE_(loaddll)( "Loaded %s at %p: builtin\n", debugstr_us(nt_name), module );
|
||||
}
|
||||
*pwm = wm;
|
||||
|
@ -3919,7 +3919,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
|
|||
*/
|
||||
void __wine_process_init(void)
|
||||
{
|
||||
extern IMAGE_NT_HEADERS __wine_spec_nt_header;
|
||||
static const WCHAR ntdllW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','t','e','m','3','2','\\',
|
||||
'n','t','d','l','l','.','d','l','l',0};
|
||||
|
@ -3932,7 +3931,7 @@ void __wine_process_init(void)
|
|||
NTSTATUS status;
|
||||
ANSI_STRING func_name;
|
||||
UNICODE_STRING nt_name;
|
||||
HMODULE ntdll_module = (HMODULE)((__wine_spec_nt_header.OptionalHeader.ImageBase + 0xffff) & ~0xffff);
|
||||
MEMORY_BASIC_INFORMATION meminfo;
|
||||
INITIAL_TEB stack;
|
||||
ULONG_PTR val;
|
||||
TEB *teb = NtCurrentTeb();
|
||||
|
@ -3976,7 +3975,9 @@ void __wine_process_init(void)
|
|||
|
||||
/* setup the load callback and create ntdll modref */
|
||||
RtlInitUnicodeString( &nt_name, ntdllW );
|
||||
status = build_so_dll_module( params->DllPath.Buffer, &nt_name, ntdll_module, 0, &wm );
|
||||
NtQueryVirtualMemory( GetCurrentProcess(), __wine_process_init, MemoryBasicInformation,
|
||||
&meminfo, sizeof(meminfo), NULL );
|
||||
status = build_builtin_module( params->DllPath.Buffer, &nt_name, meminfo.AllocationBase, 0, &wm );
|
||||
assert( !status );
|
||||
|
||||
RtlInitUnicodeString( &nt_name, kernel32W );
|
||||
|
|
|
@ -124,7 +124,7 @@ const char *build_dir = NULL;
|
|||
const char *config_dir = NULL;
|
||||
const char **dll_paths = NULL;
|
||||
const char *user_name = NULL;
|
||||
HMODULE ntdll_module = NULL;
|
||||
static HMODULE ntdll_module;
|
||||
|
||||
struct file_id
|
||||
{
|
||||
|
@ -1295,10 +1295,22 @@ found:
|
|||
*/
|
||||
static HMODULE load_ntdll(void)
|
||||
{
|
||||
NTSTATUS status;
|
||||
void *module;
|
||||
char *name = build_path( dll_dir, "ntdll.dll.so" );
|
||||
NTSTATUS status = dlopen_dll( name, &module );
|
||||
int fd;
|
||||
char *name = build_path( dll_dir, "ntdll.dll" );
|
||||
|
||||
if ((fd = open( name, O_RDONLY )) != -1)
|
||||
{
|
||||
status = virtual_map_ntdll( fd, &module );
|
||||
close( fd );
|
||||
}
|
||||
else
|
||||
{
|
||||
free( name );
|
||||
name = build_path( dll_dir, "ntdll.dll.so" );
|
||||
status = dlopen_dll( name, &module );
|
||||
}
|
||||
if (status) fatal_error( "failed to load %s error %x\n", name, status );
|
||||
free( name );
|
||||
return module;
|
||||
|
|
|
@ -134,7 +134,6 @@ extern const char *build_dir DECLSPEC_HIDDEN;
|
|||
extern const char *config_dir DECLSPEC_HIDDEN;
|
||||
extern const char *user_name DECLSPEC_HIDDEN;
|
||||
extern const char **dll_paths DECLSPEC_HIDDEN;
|
||||
extern HMODULE ntdll_module DECLSPEC_HIDDEN;
|
||||
extern USHORT *uctable DECLSPEC_HIDDEN;
|
||||
extern USHORT *lctable DECLSPEC_HIDDEN;
|
||||
extern SIZE_T startup_info_size DECLSPEC_HIDDEN;
|
||||
|
@ -190,6 +189,7 @@ extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct o
|
|||
data_size_t *ret_len ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_map_ntdll( int fd, void **module ) DECLSPEC_HIDDEN;
|
||||
extern ULONG_PTR get_system_affinity_mask(void) DECLSPEC_HIDDEN;
|
||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_create_builtin_view( void *module ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -2413,6 +2413,59 @@ void virtual_init(void)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* virtual_map_ntdll
|
||||
*
|
||||
* Map ntdll, used instead of virtual_map_section() because some things are not initialized yet.
|
||||
*/
|
||||
NTSTATUS virtual_map_ntdll( int fd, void **module )
|
||||
{
|
||||
IMAGE_DOS_HEADER dos;
|
||||
IMAGE_NT_HEADERS nt;
|
||||
NTSTATUS status;
|
||||
SIZE_T size;
|
||||
void *base;
|
||||
unsigned int vprot;
|
||||
struct file_view *view;
|
||||
|
||||
/* load the headers */
|
||||
|
||||
size = pread( fd, &dos, sizeof(dos), 0 );
|
||||
if (size < sizeof(dos)) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (dos.e_magic != IMAGE_DOS_SIGNATURE) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
|
||||
size = pread( fd, &nt, sizeof(nt), dos.e_lfanew );
|
||||
if (size < sizeof(nt)) return STATUS_INVALID_IMAGE_PROTECT;
|
||||
if (nt.Signature != IMAGE_NT_SIGNATURE) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
if (nt.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
#ifdef __i386__
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_I386) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
#elif defined(__x86_64__)
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
#elif defined(__arm__)
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARM &&
|
||||
nt.FileHeader.Machine != IMAGE_FILE_MACHINE_THUMB &&
|
||||
nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARMNT) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
#elif defined(__aarch64__)
|
||||
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARM64) return STATUS_INVALID_IMAGE_FORMAT;
|
||||
#endif
|
||||
|
||||
base = (void *)nt.OptionalHeader.ImageBase;
|
||||
size = ROUND_SIZE( 0, nt.OptionalHeader.SizeOfImage );
|
||||
vprot = SEC_IMAGE | SEC_FILE | VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY;
|
||||
|
||||
status = map_view( &view, base, size, FALSE, vprot, 0 );
|
||||
if (status == STATUS_CONFLICTING_ADDRESSES)
|
||||
ERR( "couldn't load ntdll at preferred address %p\n", base );
|
||||
if (status) return status;
|
||||
*module = view->base;
|
||||
return map_image_into_view( view, fd, base, nt.OptionalHeader.SizeOfHeaders, 0, -1, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_system_affinity_mask
|
||||
*/
|
||||
ULONG_PTR get_system_affinity_mask(void)
|
||||
{
|
||||
ULONG num_cpus = NtCurrentTeb()->Peb->NumberOfProcessors;
|
||||
|
|
Loading…
Reference in New Issue