ntdll: Support the machine extended parameter in NtMapViewOfSectionEx().

This commit is contained in:
Alexandre Julliard 2023-05-23 10:40:46 +02:00
parent af01944a8c
commit ebc1b09915
9 changed files with 229 additions and 54 deletions

View file

@ -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" );

View file

@ -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();

View file

@ -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:

View file

@ -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,

View file

@ -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,

View file

@ -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 );
}
/***********************************************************************

View file

@ -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 ### */

View file

@ -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
{

View file

@ -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 );