mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:50:49 +00:00
ntdll: Support the machine extended parameter in NtMapViewOfSectionEx().
This commit is contained in:
parent
af01944a8c
commit
ebc1b09915
|
@ -1655,7 +1655,6 @@ static void test_NtMapViewOfSectionEx(void)
|
|||
ptr = NULL;
|
||||
size = 0;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, ext, 1 );
|
||||
todo_wine
|
||||
ok(status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status);
|
||||
}
|
||||
else win_skip( "MemExtendedParameterImageMachine not supported\n" );
|
||||
|
|
|
@ -30,6 +30,7 @@ static USHORT (WINAPI *pRtlWow64GetCurrentMachine)(void);
|
|||
static NTSTATUS (WINAPI *pRtlWow64GetProcessMachines)(HANDLE,WORD*,WORD*);
|
||||
static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE,WOW64_CONTEXT*);
|
||||
static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*);
|
||||
static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE,HANDLE,PVOID*,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG);
|
||||
#ifdef _WIN64
|
||||
static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
|
||||
static NTSTATUS (WINAPI *pRtlWow64GetThreadSelectorEntry)(HANDLE,THREAD_DESCRIPTOR_INFORMATION*,ULONG,ULONG*);
|
||||
|
@ -80,6 +81,7 @@ static void init(void)
|
|||
}
|
||||
|
||||
#define GET_PROC(func) p##func = (void *)GetProcAddress( ntdll, #func )
|
||||
GET_PROC( NtMapViewOfSectionEx );
|
||||
GET_PROC( NtQuerySystemInformation );
|
||||
GET_PROC( NtQuerySystemInformationEx );
|
||||
GET_PROC( RtlGetNativeSystemInformation );
|
||||
|
@ -99,7 +101,7 @@ static void init(void)
|
|||
#endif
|
||||
#undef GET_PROC
|
||||
|
||||
if (is_wow64)
|
||||
if (pRtlGetNativeSystemInformation)
|
||||
{
|
||||
SYSTEM_CPU_INFORMATION info;
|
||||
ULONG len;
|
||||
|
@ -595,6 +597,153 @@ static void test_selectors(void)
|
|||
#undef GET_ENTRY
|
||||
}
|
||||
|
||||
static void test_image_mappings(void)
|
||||
{
|
||||
MEM_EXTENDED_PARAMETER ext = { .Type = MemExtendedParameterImageMachine };
|
||||
HANDLE file, mapping, process = GetCurrentProcess();
|
||||
NTSTATUS status;
|
||||
SIZE_T size;
|
||||
LARGE_INTEGER offset;
|
||||
void *ptr;
|
||||
|
||||
if (!pNtMapViewOfSectionEx)
|
||||
{
|
||||
win_skip( "NtMapViewOfSectionEx() not supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
offset.QuadPart = 0;
|
||||
file = CreateFileA( "c:\\windows\\system32\\version.dll", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
|
||||
mapping = CreateFileMappingA( file, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
|
||||
ok( mapping != 0, "CreateFileMapping failed\n" );
|
||||
CloseHandle( file );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = IMAGE_FILE_MACHINE_AMD64;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
if (status == STATUS_INVALID_PARAMETER)
|
||||
{
|
||||
win_skip( "MemExtendedParameterImageMachine not supported\n" );
|
||||
NtClose( mapping );
|
||||
return;
|
||||
}
|
||||
if (current_machine == IMAGE_FILE_MACHINE_AMD64)
|
||||
{
|
||||
ok( status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE,
|
||||
"NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
}
|
||||
else if (current_machine == IMAGE_FILE_MACHINE_ARM64)
|
||||
{
|
||||
ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
}
|
||||
else ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = IMAGE_FILE_MACHINE_I386;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
if (current_machine == IMAGE_FILE_MACHINE_I386)
|
||||
{
|
||||
ok( status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE,
|
||||
"NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
}
|
||||
else ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = IMAGE_FILE_MACHINE_ARM64;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
if (native_machine == IMAGE_FILE_MACHINE_ARM64)
|
||||
{
|
||||
switch (current_machine)
|
||||
{
|
||||
case IMAGE_FILE_MACHINE_ARM64:
|
||||
ok( status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE,
|
||||
"NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
break;
|
||||
case IMAGE_FILE_MACHINE_AMD64:
|
||||
ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
break;
|
||||
default:
|
||||
ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = IMAGE_FILE_MACHINE_R3000;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = 0;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
ok( status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE,
|
||||
"NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
|
||||
NtClose( mapping );
|
||||
|
||||
if (is_wow64)
|
||||
{
|
||||
file = CreateFileA( "c:\\windows\\sysnative\\version.dll", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
|
||||
|
||||
mapping = CreateFileMappingA( file, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
|
||||
ok( mapping != 0, "CreateFileMapping failed\n" );
|
||||
CloseHandle( file );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = native_machine;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
ok( status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE,
|
||||
"NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = IMAGE_FILE_MACHINE_I386;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
NtClose( mapping );
|
||||
}
|
||||
else if (native_machine == IMAGE_FILE_MACHINE_AMD64 || native_machine == IMAGE_FILE_MACHINE_ARM64)
|
||||
{
|
||||
file = CreateFileA( "c:\\windows\\syswow64\\version.dll", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
|
||||
|
||||
mapping = CreateFileMappingA( file, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
|
||||
ok( mapping != 0, "CreateFileMapping failed\n" );
|
||||
CloseHandle( file );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = native_machine;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
ext.ULong = IMAGE_FILE_MACHINE_I386;
|
||||
status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
|
||||
todo_wine
|
||||
ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status );
|
||||
NtUnmapViewOfSection( process, ptr );
|
||||
NtClose( mapping );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
static void test_cpu_area(void)
|
||||
|
@ -1396,6 +1545,7 @@ START_TEST(wow64)
|
|||
test_query_architectures();
|
||||
test_peb_teb();
|
||||
test_selectors();
|
||||
test_image_mappings();
|
||||
#ifndef _WIN64
|
||||
test_nt_wow64();
|
||||
test_modules();
|
||||
|
|
|
@ -1451,13 +1451,13 @@ static NTSTATUS open_builtin_so_file( const char *name, OBJECT_ATTRIBUTES *attr,
|
|||
* find_builtin_dll
|
||||
*/
|
||||
static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T *size_ptr,
|
||||
SECTION_IMAGE_INFORMATION *image_info,
|
||||
ULONG_PTR limit, WORD machine, BOOL prefer_native )
|
||||
SECTION_IMAGE_INFORMATION *image_info, ULONG_PTR limit,
|
||||
USHORT search_machine, USHORT load_machine, BOOL prefer_native )
|
||||
{
|
||||
unsigned int i, pos, namepos, maxlen = 0;
|
||||
unsigned int len = nt_name->Length / sizeof(WCHAR);
|
||||
char *ptr = NULL, *file, *ext = NULL;
|
||||
const char *pe_dir = get_pe_dir( machine );
|
||||
const char *pe_dir = get_pe_dir( search_machine );
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||
BOOL found_image = FALSE;
|
||||
|
@ -1489,21 +1489,23 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
|
|||
/* try as a dll */
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend_build_dir_path( file + pos, ".dll", pe_dir, "/dlls" );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit, machine, prefer_native );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info,
|
||||
limit, load_machine, prefer_native );
|
||||
ptr = prepend_build_dir_path( file + pos, ".dll", "", "/dlls" );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
strcpy( file + pos + len + 1, ".so" );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, load_machine, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
|
||||
/* now as a program */
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend_build_dir_path( file + pos, ".exe", pe_dir, "/programs" );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit, machine, prefer_native );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info,
|
||||
limit, load_machine, prefer_native );
|
||||
ptr = prepend_build_dir_path( file + pos, ".exe", "", "/programs" );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
strcpy( file + pos + len + 1, ".so" );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, load_machine, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
||||
|
@ -1513,18 +1515,20 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
|
|||
file[pos + len + 1] = 0;
|
||||
ptr = prepend( ptr, pe_dir, strlen(pe_dir) );
|
||||
ptr = prepend( ptr, dll_paths[i], strlen(dll_paths[i]) );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit, machine, prefer_native );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit,
|
||||
load_machine, prefer_native );
|
||||
/* use so dir for unix lib */
|
||||
ptr = file + pos;
|
||||
ptr = prepend( ptr, so_dir, strlen(so_dir) );
|
||||
ptr = prepend( ptr, dll_paths[i], strlen(dll_paths[i]) );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
strcpy( file + pos + len + 1, ".so" );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, load_machine, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit, machine, prefer_native );
|
||||
status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, limit,
|
||||
load_machine, prefer_native );
|
||||
if (status == STATUS_NOT_SUPPORTED)
|
||||
{
|
||||
found_image = TRUE;
|
||||
|
@ -1532,7 +1536,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
|
|||
}
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
strcpy( file + pos + len + 1, ".so" );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native );
|
||||
status = open_builtin_so_file( ptr, &attr, module, image_info, load_machine, prefer_native );
|
||||
if (status == STATUS_NOT_SUPPORTED) found_image = TRUE;
|
||||
else if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
@ -1556,10 +1560,9 @@ done:
|
|||
* Load the builtin dll if specified by load order configuration.
|
||||
* Return STATUS_IMAGE_ALREADY_LOADED if we should keep the native one that we have found.
|
||||
*/
|
||||
NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename,
|
||||
NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename, USHORT machine,
|
||||
void **module, SIZE_T *size, ULONG_PTR limit )
|
||||
{
|
||||
WORD machine = image_info->machine; /* request same machine as the native one */
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING nt_name;
|
||||
SECTION_IMAGE_INFORMATION info;
|
||||
|
@ -1588,9 +1591,11 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename,
|
|||
case LO_NATIVE_BUILTIN:
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
case LO_BUILTIN:
|
||||
return find_builtin_dll( &nt_name, module, size, &info, limit, machine, FALSE );
|
||||
return find_builtin_dll( &nt_name, module, size, &info, limit,
|
||||
image_info->machine, machine, FALSE );
|
||||
default:
|
||||
status = find_builtin_dll( &nt_name, module, size, &info, limit, machine, (loadorder == LO_DEFAULT) );
|
||||
status = find_builtin_dll( &nt_name, module, size, &info, limit,
|
||||
image_info->machine, machine, (loadorder == LO_DEFAULT) );
|
||||
if (status == STATUS_DLL_NOT_FOUND || status == STATUS_NOT_SUPPORTED)
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
return status;
|
||||
|
@ -1753,7 +1758,7 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA
|
|||
/* if path is in system dir, we can load the builtin even if the file itself doesn't exist */
|
||||
if (loadorder != LO_NATIVE && is_builtin_path( &nt_name, &machine ))
|
||||
{
|
||||
status = find_builtin_dll( &nt_name, module, &size, &main_image_info, 0, machine, FALSE );
|
||||
status = find_builtin_dll( &nt_name, module, &size, &main_image_info, 0, machine, 0, FALSE );
|
||||
if (status != STATUS_DLL_NOT_FOUND) return status;
|
||||
}
|
||||
if (!contains_path) return STATUS_DLL_NOT_FOUND;
|
||||
|
@ -1782,7 +1787,7 @@ NTSTATUS load_start_exe( WCHAR **image, void **module )
|
|||
wcscpy( *image, get_machine_wow64_dir( current_machine ));
|
||||
wcscat( *image, startW );
|
||||
init_unicode_string( &nt_name, *image );
|
||||
status = find_builtin_dll( &nt_name, module, &size, &main_image_info, 0, current_machine, FALSE );
|
||||
status = find_builtin_dll( &nt_name, module, &size, &main_image_info, 0, current_machine, 0, FALSE );
|
||||
if (status)
|
||||
{
|
||||
MESSAGE( "wine: failed to load start.exe: %x\n", status );
|
||||
|
@ -1993,7 +1998,7 @@ static void load_wow64_ntdll( USHORT machine )
|
|||
wcscpy( path, get_machine_wow64_dir( machine ));
|
||||
wcscat( path, ntdllW );
|
||||
init_unicode_string( &nt_name, path );
|
||||
status = find_builtin_dll( &nt_name, &module, &size, &info, 0, machine, FALSE );
|
||||
status = find_builtin_dll( &nt_name, &module, &size, &info, 0, machine, 0, FALSE );
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_IMAGE_NOT_AT_BASE:
|
||||
|
|
|
@ -569,7 +569,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
|||
case APC_MAP_VIEW_EX:
|
||||
{
|
||||
MEM_ADDRESS_REQUIREMENTS addr_req;
|
||||
MEM_EXTENDED_PARAMETER ext[1];
|
||||
MEM_EXTENDED_PARAMETER ext[2];
|
||||
ULONG count = 0;
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
|
@ -596,6 +596,12 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
|||
ext[count].Pointer = &addr_req;
|
||||
count++;
|
||||
}
|
||||
if (call->map_view_ex.machine)
|
||||
{
|
||||
ext[count].Type = MemExtendedParameterImageMachine;
|
||||
ext[count].ULong = call->map_view_ex.machine;
|
||||
count++;
|
||||
}
|
||||
result->map_view_ex.status = NtMapViewOfSectionEx( wine_server_ptr_handle(call->map_view_ex.handle),
|
||||
NtCurrentProcess(), &addr, &offset, &size,
|
||||
call->map_view_ex.alloc_type,
|
||||
|
|
|
@ -174,7 +174,7 @@ extern void *create_startup_info( const UNICODE_STRING *nt_image, const RTL_USER
|
|||
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
|
||||
extern char *get_alternate_wineloader( WORD machine ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS exec_wineloader( char **argv, int socketfd, const pe_image_info_t *pe_info ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename,
|
||||
extern NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename, USHORT machine,
|
||||
void **addr_ptr, SIZE_T *size_ptr, ULONG_PTR limit ) DECLSPEC_HIDDEN;
|
||||
extern BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *curdir, WCHAR **image,
|
||||
|
|
|
@ -2366,6 +2366,7 @@ static void update_arm64x_mapping( char *base, IMAGE_NT_HEADERS *nt, IMAGE_SECTI
|
|||
|
||||
/* retrieve config directory */
|
||||
|
||||
if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_ARM64) return;
|
||||
if (nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return;
|
||||
dir = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
|
||||
if (!dir->VirtualAddress || !dir->Size) return;
|
||||
|
@ -2375,6 +2376,7 @@ static void update_arm64x_mapping( char *base, IMAGE_NT_HEADERS *nt, IMAGE_SECTI
|
|||
/* update code ranges */
|
||||
|
||||
if (size <= offsetof( IMAGE_LOAD_CONFIG_DIRECTORY, CHPEMetadataPointer )) return;
|
||||
if (!cfg->CHPEMetadataPointer) return;
|
||||
metadata = (void *)(base + (cfg->CHPEMetadataPointer - nt->OptionalHeader.ImageBase));
|
||||
if (metadata->CodeMap && arm64ec_map)
|
||||
{
|
||||
|
@ -2440,7 +2442,8 @@ static void update_arm64x_mapping( char *base, IMAGE_NT_HEADERS *nt, IMAGE_SECTI
|
|||
* virtual_mutex must be held by caller.
|
||||
*/
|
||||
static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filename, int fd, void *orig_base,
|
||||
SIZE_T header_size, ULONG image_flags, int shared_fd, BOOL removable )
|
||||
pe_image_info_t *image_info, USHORT machine,
|
||||
int shared_fd, BOOL removable )
|
||||
{
|
||||
IMAGE_DOS_HEADER *dos;
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
|
@ -2453,14 +2456,14 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena
|
|||
struct stat st;
|
||||
char *header_end, *header_start;
|
||||
char *ptr = view->base;
|
||||
SIZE_T total_size = view->size;
|
||||
SIZE_T header_size, total_size = view->size;
|
||||
|
||||
TRACE_(module)( "mapping PE file %s at %p-%p\n", debugstr_w(filename), ptr, ptr + total_size );
|
||||
|
||||
/* map the header */
|
||||
|
||||
fstat( fd, &st );
|
||||
header_size = min( header_size, st.st_size );
|
||||
header_size = min( image_info->header_size, st.st_size );
|
||||
if ((status = map_pe_header( view->base, header_size, fd, &removable ))) return status;
|
||||
|
||||
status = STATUS_INVALID_IMAGE_FORMAT; /* generic error */
|
||||
|
@ -2482,7 +2485,7 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena
|
|||
|
||||
/* check for non page-aligned binary */
|
||||
|
||||
if (image_flags & IMAGE_FLAGS_ImageMappedFlat)
|
||||
if (image_info->image_flags & IMAGE_FLAGS_ImageMappedFlat)
|
||||
{
|
||||
/* unaligned sections, this happens for native subsystem binaries */
|
||||
/* in that case Windows simply maps in the whole file */
|
||||
|
@ -2598,10 +2601,14 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena
|
|||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
if (main_image_info.Machine == IMAGE_FILE_MACHINE_AMD64 &&
|
||||
nt->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64)
|
||||
if (machine == IMAGE_FILE_MACHINE_AMD64 ||
|
||||
(!machine && main_image_info.Machine == IMAGE_FILE_MACHINE_AMD64))
|
||||
{
|
||||
update_arm64x_mapping( ptr, nt, sections );
|
||||
image_info->machine = nt->FileHeader.Machine; /* reload changed machine from NT header */
|
||||
}
|
||||
#endif
|
||||
if (machine && machine != nt->FileHeader.Machine) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* set the image protections */
|
||||
|
||||
|
@ -2687,8 +2694,8 @@ static unsigned int get_mapping_info( HANDLE handle, ACCESS_MASK access, unsigne
|
|||
*
|
||||
* Map a PE image section into memory.
|
||||
*/
|
||||
static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **addr_ptr, SIZE_T *size_ptr,
|
||||
ULONG_PTR limit, HANDLE shared_file, ULONG alloc_type,
|
||||
static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **addr_ptr, SIZE_T *size_ptr, HANDLE shared_file,
|
||||
ULONG_PTR limit, ULONG alloc_type, USHORT machine,
|
||||
pe_image_info_t *image_info, WCHAR *filename, BOOL is_builtin )
|
||||
{
|
||||
unsigned int vprot = SEC_IMAGE | SEC_FILE | VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY;
|
||||
|
@ -2722,8 +2729,8 @@ static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **ad
|
|||
if (status) status = map_view( &view, NULL, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 );
|
||||
if (status) goto done;
|
||||
|
||||
status = map_image_into_view( view, filename, unix_fd, base, image_info->header_size,
|
||||
image_info->image_flags, shared_fd, needs_close );
|
||||
status = map_image_into_view( view, filename, unix_fd, base, image_info,
|
||||
machine, shared_fd, needs_close );
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
SERVER_START_REQ( map_view )
|
||||
|
@ -2759,8 +2766,9 @@ done:
|
|||
* Map a file section into memory.
|
||||
*/
|
||||
static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_PTR limit,
|
||||
SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
|
||||
ULONG alloc_type, ULONG protect )
|
||||
SIZE_T commit_size, const LARGE_INTEGER *offset_ptr,
|
||||
SIZE_T *size_ptr, ULONG alloc_type, ULONG protect,
|
||||
USHORT machine )
|
||||
{
|
||||
unsigned int res;
|
||||
mem_size_t full_size;
|
||||
|
@ -2805,10 +2813,10 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P
|
|||
{
|
||||
filename = (WCHAR *)(image_info + 1);
|
||||
/* check if we can replace that mapping with the builtin */
|
||||
res = load_builtin( image_info, filename, addr_ptr, size_ptr, limit );
|
||||
res = load_builtin( image_info, filename, machine, addr_ptr, size_ptr, limit );
|
||||
if (res == STATUS_IMAGE_ALREADY_LOADED)
|
||||
res = virtual_map_image( handle, access, addr_ptr, size_ptr, limit, shared_file,
|
||||
alloc_type, image_info, filename, FALSE );
|
||||
res = virtual_map_image( handle, access, addr_ptr, size_ptr, shared_file, limit,
|
||||
alloc_type, machine, image_info, filename, FALSE );
|
||||
if (shared_file) NtClose( shared_file );
|
||||
free( image_info );
|
||||
return res;
|
||||
|
@ -3047,11 +3055,6 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size
|
|||
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_w(filename) );
|
||||
status = STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
else if (machine && image_info->machine != machine)
|
||||
{
|
||||
TRACE( "%s is for arch %04x, continuing search\n", debugstr_w(filename), image_info->machine );
|
||||
status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (prefer_native && (image_info->dll_charact & IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE))
|
||||
{
|
||||
TRACE( "%s has prefer-native flag, ignoring builtin\n", debugstr_w(filename) );
|
||||
|
@ -3059,8 +3062,8 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size
|
|||
}
|
||||
else
|
||||
{
|
||||
status = virtual_map_image( mapping, SECTION_MAP_READ | SECTION_MAP_EXECUTE,
|
||||
module, size, limit, shared_file, 0, image_info, filename, TRUE );
|
||||
status = virtual_map_image( mapping, access, module, size, shared_file, limit, 0,
|
||||
machine, image_info, filename, TRUE );
|
||||
virtual_fill_image_information( image_info, info );
|
||||
}
|
||||
|
||||
|
@ -4150,7 +4153,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
|
|||
|
||||
|
||||
static NTSTATUS get_extended_params( const MEM_EXTENDED_PARAMETER *parameters, ULONG count,
|
||||
ULONG_PTR *limit, ULONG_PTR *align, ULONG *attributes )
|
||||
ULONG_PTR *limit, ULONG_PTR *align, ULONG *attributes,
|
||||
USHORT *machine )
|
||||
{
|
||||
ULONG i, present = 0;
|
||||
|
||||
|
@ -4197,10 +4201,13 @@ static NTSTATUS get_extended_params( const MEM_EXTENDED_PARAMETER *parameters, U
|
|||
*attributes = parameters[i].ULong;
|
||||
break;
|
||||
|
||||
case MemExtendedParameterImageMachine:
|
||||
*machine = parameters[i].ULong;
|
||||
break;
|
||||
|
||||
case MemExtendedParameterNumaNode:
|
||||
case MemExtendedParameterPartitionHandle:
|
||||
case MemExtendedParameterUserPhysicalHandle:
|
||||
case MemExtendedParameterImageMachine:
|
||||
FIXME( "Parameter type %d is not supported.\n", parameters[i].Type );
|
||||
break;
|
||||
|
||||
|
@ -4224,12 +4231,13 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
|||
ULONG_PTR limit = 0;
|
||||
ULONG_PTR align = 0;
|
||||
ULONG attributes = 0;
|
||||
USHORT machine = 0;
|
||||
unsigned int status;
|
||||
|
||||
TRACE( "%p %p %08lx %x %08x %p %u\n",
|
||||
process, *ret, *size_ptr, (int)type, (int)protect, parameters, (int)count );
|
||||
|
||||
status = get_extended_params( parameters, count, &limit, &align, &attributes );
|
||||
status = get_extended_params( parameters, count, &limit, &align, &attributes, &machine );
|
||||
if (status) return status;
|
||||
|
||||
if (*ret && (align || limit)) return STATUS_INVALID_PARAMETER;
|
||||
|
@ -4957,7 +4965,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
}
|
||||
|
||||
return virtual_map_section( handle, addr_ptr, get_zero_bits_limit( zero_bits ), commit_size,
|
||||
offset_ptr, size_ptr, alloc_type, protect );
|
||||
offset_ptr, size_ptr, alloc_type, protect, 0 );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -4971,6 +4979,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
{
|
||||
ULONG_PTR limit = 0, align = 0;
|
||||
ULONG attributes = 0;
|
||||
USHORT machine = 0;
|
||||
unsigned int status;
|
||||
SIZE_T mask = granularity_mask;
|
||||
LARGE_INTEGER offset;
|
||||
|
@ -4980,7 +4989,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
TRACE( "handle=%p process=%p addr=%p off=%s size=%lx access=%x\n",
|
||||
handle, process, *addr_ptr, wine_dbgstr_longlong(offset.QuadPart), *size_ptr, (int)protect );
|
||||
|
||||
status = get_extended_params( parameters, count, &limit, &align, &attributes );
|
||||
status = get_extended_params( parameters, count, &limit, &align, &attributes, &machine );
|
||||
if (status) return status;
|
||||
|
||||
if (align) return STATUS_INVALID_PARAMETER;
|
||||
|
@ -5012,6 +5021,8 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
call.map_view_ex.limit = limit;
|
||||
call.map_view_ex.alloc_type = alloc_type;
|
||||
call.map_view_ex.prot = protect;
|
||||
call.map_view_ex.machine = machine;
|
||||
if (call.map_view_ex.prot != protect) return STATUS_INVALID_PARAMETER;
|
||||
status = server_queue_process_apc( process, &call, &result );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
|
||||
|
@ -5023,7 +5034,8 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
return result.map_view_ex.status;
|
||||
}
|
||||
|
||||
return virtual_map_section( handle, addr_ptr, limit, 0, offset_ptr, size_ptr, alloc_type, protect );
|
||||
return virtual_map_section( handle, addr_ptr, limit, 0, offset_ptr, size_ptr,
|
||||
alloc_type, protect, machine );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -592,7 +592,8 @@ typedef union
|
|||
file_pos_t offset;
|
||||
mem_size_t limit;
|
||||
unsigned int alloc_type;
|
||||
unsigned int prot;
|
||||
unsigned short prot;
|
||||
unsigned short machine;
|
||||
} map_view_ex;
|
||||
struct
|
||||
{
|
||||
|
@ -6393,7 +6394,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 766
|
||||
#define SERVER_PROTOCOL_VERSION 767
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -608,7 +608,8 @@ typedef union
|
|||
file_pos_t offset; /* file offset */
|
||||
mem_size_t limit; /* allocation address limit */
|
||||
unsigned int alloc_type; /* allocation type */
|
||||
unsigned int prot; /* memory protection flags */
|
||||
unsigned short prot; /* memory protection flags */
|
||||
unsigned short machine; /* requested machine for image mappings */
|
||||
} map_view_ex;
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -237,7 +237,8 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
|
|||
dump_uint64( ",size=", &call->map_view_ex.size );
|
||||
dump_uint64( ",offset=", &call->map_view_ex.offset );
|
||||
dump_uint64( ",limit=", &call->map_view_ex.limit );
|
||||
fprintf( stderr, ",alloc_type=%x,prot=%x", call->map_view_ex.alloc_type, call->map_view_ex.prot );
|
||||
fprintf( stderr, ",alloc_type=%x,prot=%x,machine=%04x",
|
||||
call->map_view_ex.alloc_type, call->map_view_ex.prot, call->map_view_ex.machine );
|
||||
break;
|
||||
case APC_UNMAP_VIEW:
|
||||
dump_uint64( "APC_UNMAP_VIEW,addr=", &call->unmap_view.addr );
|
||||
|
|
Loading…
Reference in a new issue