Commit 4b8f3dd9 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Support extended address requirements in NtMapViewOfSectionEx().

parent 185e168a
...@@ -566,6 +566,45 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO ...@@ -566,6 +566,45 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
else result->map_view.status = STATUS_INVALID_PARAMETER; else result->map_view.status = STATUS_INVALID_PARAMETER;
if (!self) NtClose( wine_server_ptr_handle(call->map_view.handle) ); if (!self) NtClose( wine_server_ptr_handle(call->map_view.handle) );
break; break;
case APC_MAP_VIEW_EX:
{
MEM_ADDRESS_REQUIREMENTS addr_req;
MEM_EXTENDED_PARAMETER ext[1];
ULONG count = 0;
LARGE_INTEGER offset;
result->type = call->type;
addr = wine_server_get_ptr( call->map_view_ex.addr );
size = call->map_view_ex.size;
offset.QuadPart = call->map_view_ex.offset;
if ((ULONG_PTR)addr != call->map_view_ex.addr || size != call->map_view_ex.size)
{
result->map_view_ex.status = STATUS_WORKING_SET_LIMIT_RANGE;
break;
}
if (call->map_view_ex.limit)
{
SYSTEM_BASIC_INFORMATION sbi;
ULONG_PTR limit;
virtual_get_system_info( &sbi, is_wow64() );
limit = min( (ULONG_PTR)sbi.HighestUserAddress, call->map_view_ex.limit );
addr_req.LowestStartingAddress = NULL;
addr_req.HighestEndingAddress = (void *)limit;
addr_req.Alignment = 0;
ext[count].Type = MemExtendedParameterAddressRequirements;
ext[count].Pointer = &addr_req;
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,
call->map_view_ex.prot, ext, count );
result->map_view_ex.addr = wine_server_client_ptr( addr );
result->map_view_ex.size = size;
if (!self) NtClose( wine_server_ptr_handle(call->map_view_ex.handle) );
break;
}
case APC_UNMAP_VIEW: case APC_UNMAP_VIEW:
result->type = call->type; result->type = call->type;
addr = wine_server_get_ptr( call->unmap_view.addr ); addr = wine_server_get_ptr( call->unmap_view.addr );
......
...@@ -4868,13 +4868,66 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -4868,13 +4868,66 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
* NtMapViewOfSectionEx (NTDLL.@) * NtMapViewOfSectionEx (NTDLL.@)
* ZwMapViewOfSectionEx (NTDLL.@) * ZwMapViewOfSectionEx (NTDLL.@)
*/ */
NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr_ptr, const LARGE_INTEGER *offset_ptr, NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr_ptr,
SIZE_T *size_ptr, ULONG alloc_type, ULONG protect, MEM_EXTENDED_PARAMETER *params, ULONG params_count ) const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
ULONG alloc_type, ULONG protect,
MEM_EXTENDED_PARAMETER *parameters, ULONG count )
{ {
if (params) ULONG_PTR limit = 0, align = 0;
FIXME("Ignoring extended parameters.\n"); ULONG attributes = 0;
unsigned int status;
SIZE_T mask = granularity_mask;
LARGE_INTEGER offset;
offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
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 );
if (status) return status;
if (align) return STATUS_INVALID_PARAMETER;
if (*addr_ptr && limit) return STATUS_INVALID_PARAMETER;
#ifndef _WIN64
if (!is_old_wow64() && (alloc_type & AT_ROUND_TO_PAGE))
{
*addr_ptr = ROUND_ADDR( *addr_ptr, page_mask );
mask = page_mask;
}
#endif
if ((offset.u.LowPart & mask) || (*addr_ptr && ((UINT_PTR)*addr_ptr & mask)))
return STATUS_MAPPED_ALIGNMENT;
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
memset( &call, 0, sizeof(call) );
call.map_view_ex.type = APC_MAP_VIEW_EX;
call.map_view_ex.handle = wine_server_obj_handle( handle );
call.map_view_ex.addr = wine_server_client_ptr( *addr_ptr );
call.map_view_ex.size = *size_ptr;
call.map_view_ex.offset = offset.QuadPart;
call.map_view_ex.limit = limit;
call.map_view_ex.alloc_type = alloc_type;
call.map_view_ex.prot = protect;
status = server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (NT_SUCCESS(result.map_view_ex.status))
{
*addr_ptr = wine_server_get_ptr( result.map_view_ex.addr );
*size_ptr = result.map_view_ex.size;
}
return result.map_view_ex.status;
}
return NtMapViewOfSection( handle, process, addr_ptr, 0, 0, offset_ptr, size_ptr, ViewShare, alloc_type, protect ); return virtual_map_section( handle, addr_ptr, limit, 0, offset_ptr, size_ptr, alloc_type, protect );
} }
/*********************************************************************** /***********************************************************************
......
...@@ -485,6 +485,7 @@ enum apc_type ...@@ -485,6 +485,7 @@ enum apc_type
APC_VIRTUAL_LOCK, APC_VIRTUAL_LOCK,
APC_VIRTUAL_UNLOCK, APC_VIRTUAL_UNLOCK,
APC_MAP_VIEW, APC_MAP_VIEW,
APC_MAP_VIEW_EX,
APC_UNMAP_VIEW, APC_UNMAP_VIEW,
APC_CREATE_THREAD, APC_CREATE_THREAD,
APC_DUP_HANDLE APC_DUP_HANDLE
...@@ -585,6 +586,17 @@ typedef union ...@@ -585,6 +586,17 @@ typedef union
struct struct
{ {
enum apc_type type; enum apc_type type;
obj_handle_t handle;
client_ptr_t addr;
mem_size_t size;
file_pos_t offset;
mem_size_t limit;
unsigned int alloc_type;
unsigned int prot;
} map_view_ex;
struct
{
enum apc_type type;
int __pad; int __pad;
client_ptr_t addr; client_ptr_t addr;
} unmap_view; } unmap_view;
...@@ -691,6 +703,13 @@ typedef union ...@@ -691,6 +703,13 @@ typedef union
{ {
enum apc_type type; enum apc_type type;
unsigned int status; unsigned int status;
client_ptr_t addr;
mem_size_t size;
} map_view_ex;
struct
{
enum apc_type type;
unsigned int status;
} unmap_view; } unmap_view;
struct struct
{ {
...@@ -6359,7 +6378,7 @@ union generic_reply ...@@ -6359,7 +6378,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 763 #define SERVER_PROTOCOL_VERSION 764
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -501,6 +501,7 @@ enum apc_type ...@@ -501,6 +501,7 @@ enum apc_type
APC_VIRTUAL_LOCK, APC_VIRTUAL_LOCK,
APC_VIRTUAL_UNLOCK, APC_VIRTUAL_UNLOCK,
APC_MAP_VIEW, APC_MAP_VIEW,
APC_MAP_VIEW_EX,
APC_UNMAP_VIEW, APC_UNMAP_VIEW,
APC_CREATE_THREAD, APC_CREATE_THREAD,
APC_DUP_HANDLE APC_DUP_HANDLE
...@@ -600,6 +601,17 @@ typedef union ...@@ -600,6 +601,17 @@ typedef union
} map_view; } map_view;
struct struct
{ {
enum apc_type type; /* APC_MAP_VIEW_EX */
obj_handle_t handle; /* mapping handle */
client_ptr_t addr; /* requested address */
mem_size_t size; /* allocation size */
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 */
} map_view_ex;
struct
{
enum apc_type type; /* APC_UNMAP_VIEW */ enum apc_type type; /* APC_UNMAP_VIEW */
int __pad; int __pad;
client_ptr_t addr; /* view address */ client_ptr_t addr; /* view address */
...@@ -643,7 +655,7 @@ typedef union ...@@ -643,7 +655,7 @@ typedef union
} virtual_alloc; } virtual_alloc;
struct struct
{ {
enum apc_type type; /* APC_VIRTUAL_ALLOC */ enum apc_type type; /* APC_VIRTUAL_ALLOC_EX */
unsigned int status; /* status returned by call */ unsigned int status; /* status returned by call */
client_ptr_t addr; /* resulting address */ client_ptr_t addr; /* resulting address */
mem_size_t size; /* resulting size */ mem_size_t size; /* resulting size */
...@@ -705,6 +717,13 @@ typedef union ...@@ -705,6 +717,13 @@ typedef union
} map_view; } map_view;
struct struct
{ {
enum apc_type type; /* APC_MAP_VIEW_EX */
unsigned int status; /* status returned by call */
client_ptr_t addr; /* resulting address */
mem_size_t size; /* resulting size */
} map_view_ex;
struct
{
enum apc_type type; /* APC_UNMAP_VIEW */ enum apc_type type; /* APC_UNMAP_VIEW */
unsigned int status; /* status returned by call */ unsigned int status; /* status returned by call */
} unmap_view; } unmap_view;
......
...@@ -1724,6 +1724,7 @@ DECL_HANDLER(queue_apc) ...@@ -1724,6 +1724,7 @@ DECL_HANDLER(queue_apc)
process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION ); process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION );
break; break;
case APC_MAP_VIEW: case APC_MAP_VIEW:
case APC_MAP_VIEW_EX:
process = get_process_from_handle( req->handle, PROCESS_VM_OPERATION ); process = get_process_from_handle( req->handle, PROCESS_VM_OPERATION );
if (process && process != current->process) if (process && process != current->process)
{ {
......
...@@ -184,13 +184,13 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call ) ...@@ -184,13 +184,13 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
fprintf( stderr, ",status=%s,result=%u", get_status_name(call->async_io.status), call->async_io.result ); fprintf( stderr, ",status=%s,result=%u", get_status_name(call->async_io.status), call->async_io.result );
break; break;
case APC_VIRTUAL_ALLOC: case APC_VIRTUAL_ALLOC:
dump_uint64( "APC_VIRTUAL_ALLOC,addr==", &call->virtual_alloc.addr ); dump_uint64( "APC_VIRTUAL_ALLOC,addr=", &call->virtual_alloc.addr );
dump_uint64( ",size=", &call->virtual_alloc.size ); dump_uint64( ",size=", &call->virtual_alloc.size );
dump_uint64( ",zero_bits=", &call->virtual_alloc.zero_bits ); dump_uint64( ",zero_bits=", &call->virtual_alloc.zero_bits );
fprintf( stderr, ",op_type=%x,prot=%x", call->virtual_alloc.op_type, call->virtual_alloc.prot ); fprintf( stderr, ",op_type=%x,prot=%x", call->virtual_alloc.op_type, call->virtual_alloc.prot );
break; break;
case APC_VIRTUAL_ALLOC_EX: case APC_VIRTUAL_ALLOC_EX:
dump_uint64( "APC_VIRTUAL_ALLOC,addr==", &call->virtual_alloc_ex.addr ); dump_uint64( "APC_VIRTUAL_ALLOC_EX,addr=", &call->virtual_alloc_ex.addr );
dump_uint64( ",size=", &call->virtual_alloc_ex.size ); dump_uint64( ",size=", &call->virtual_alloc_ex.size );
dump_uint64( ",limit=", &call->virtual_alloc_ex.limit ); dump_uint64( ",limit=", &call->virtual_alloc_ex.limit );
dump_uint64( ",align=", &call->virtual_alloc_ex.align ); dump_uint64( ",align=", &call->virtual_alloc_ex.align );
...@@ -231,6 +231,14 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call ) ...@@ -231,6 +231,14 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
dump_uint64( ",zero_bits=", &call->map_view.zero_bits ); dump_uint64( ",zero_bits=", &call->map_view.zero_bits );
fprintf( stderr, ",alloc_type=%x,prot=%x", call->map_view.alloc_type, call->map_view.prot ); fprintf( stderr, ",alloc_type=%x,prot=%x", call->map_view.alloc_type, call->map_view.prot );
break; break;
case APC_MAP_VIEW_EX:
fprintf( stderr, "APC_MAP_VIEW_EX,handle=%04x", call->map_view_ex.handle );
dump_uint64( ",addr=", &call->map_view_ex.addr );
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 );
break;
case APC_UNMAP_VIEW: case APC_UNMAP_VIEW:
dump_uint64( "APC_UNMAP_VIEW,addr=", &call->unmap_view.addr ); dump_uint64( "APC_UNMAP_VIEW,addr=", &call->unmap_view.addr );
break; break;
......
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