mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 07:06:52 +00:00
ntdll: Support HighestEndingAddress in NtAllocateVirtualMemoryEx().
This commit is contained in:
parent
5d583498e8
commit
7e8bb68f95
|
@ -358,7 +358,7 @@ static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTAT
|
||||||
*/
|
*/
|
||||||
static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self )
|
static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self )
|
||||||
{
|
{
|
||||||
SIZE_T size, bits;
|
SIZE_T size, bits, limit;
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
memset( result, 0, sizeof(*result) );
|
memset( result, 0, sizeof(*result) );
|
||||||
|
@ -401,6 +401,33 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
||||||
}
|
}
|
||||||
else result->virtual_alloc.status = STATUS_WORKING_SET_LIMIT_RANGE;
|
else result->virtual_alloc.status = STATUS_WORKING_SET_LIMIT_RANGE;
|
||||||
break;
|
break;
|
||||||
|
case APC_VIRTUAL_ALLOC_EX:
|
||||||
|
{
|
||||||
|
MEM_ADDRESS_REQUIREMENTS r = { NULL };
|
||||||
|
MEM_EXTENDED_PARAMETER ext =
|
||||||
|
{
|
||||||
|
.Type = MemExtendedParameterAddressRequirements,
|
||||||
|
.Pointer = &r
|
||||||
|
};
|
||||||
|
SYSTEM_BASIC_INFORMATION sbi;
|
||||||
|
|
||||||
|
virtual_get_system_info( &sbi, !!NtCurrentTeb()->WowTebOffset );
|
||||||
|
result->type = call->type;
|
||||||
|
addr = wine_server_get_ptr( call->virtual_alloc_ex.addr );
|
||||||
|
size = call->virtual_alloc_ex.size;
|
||||||
|
limit = min( (ULONG_PTR)sbi.HighestUserAddress, call->virtual_alloc_ex.limit );
|
||||||
|
if ((ULONG_PTR)addr == call->virtual_alloc_ex.addr && size == call->virtual_alloc_ex.size)
|
||||||
|
{
|
||||||
|
r.HighestEndingAddress = (void *)limit;
|
||||||
|
result->virtual_alloc_ex.status = NtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr, &size,
|
||||||
|
call->virtual_alloc_ex.op_type,
|
||||||
|
call->virtual_alloc_ex.prot, &ext, 1 );
|
||||||
|
result->virtual_alloc_ex.addr = wine_server_client_ptr( addr );
|
||||||
|
result->virtual_alloc_ex.size = size;
|
||||||
|
}
|
||||||
|
else result->virtual_alloc_ex.status = STATUS_WORKING_SET_LIMIT_RANGE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case APC_VIRTUAL_FREE:
|
case APC_VIRTUAL_FREE:
|
||||||
result->type = call->type;
|
result->type = call->type;
|
||||||
addr = wine_server_get_ptr( call->virtual_free.addr );
|
addr = wine_server_get_ptr( call->virtual_free.addr );
|
||||||
|
|
|
@ -1921,7 +1921,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||||
|
|
||||||
alloc.size = size;
|
alloc.size = size;
|
||||||
alloc.top_down = top_down;
|
alloc.top_down = top_down;
|
||||||
alloc.limit = limit ? (void*)(limit & (UINT_PTR)user_space_limit) : user_space_limit;
|
alloc.limit = limit ? min( (void *)(limit + 1), user_space_limit ) : user_space_limit;
|
||||||
|
|
||||||
if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
|
if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
|
||||||
{
|
{
|
||||||
|
@ -3894,11 +3894,78 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||||
ULONG protect, MEM_EXTENDED_PARAMETER *parameters,
|
ULONG protect, MEM_EXTENDED_PARAMETER *parameters,
|
||||||
ULONG count )
|
ULONG count )
|
||||||
{
|
{
|
||||||
|
ULONG_PTR limit = 0;
|
||||||
|
|
||||||
|
TRACE("%p %p %08lx %x %08x %p %u\n", process, *ret, *size_ptr, type, protect, parameters, count );
|
||||||
|
|
||||||
if (count && !parameters) return STATUS_INVALID_PARAMETER;
|
if (count && !parameters) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (count) FIXME( "Ignoring %d extended parameters %p\n", count, parameters );
|
if (count)
|
||||||
|
{
|
||||||
|
MEM_ADDRESS_REQUIREMENTS *r = NULL;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
return NtAllocateVirtualMemory( process, ret, 0, size_ptr, type, protect );
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (parameters[i].Type == MemExtendedParameterInvalidType || parameters[i].Type >= MemExtendedParameterMax)
|
||||||
|
{
|
||||||
|
WARN( "Invalid parameter type %d.\n", parameters[i].Type );
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (parameters[i].Type != MemExtendedParameterAddressRequirements)
|
||||||
|
{
|
||||||
|
FIXME( "Parameter type %d is not supported.\n", parameters[i].Type );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
WARN( "Duplicate parameter.\n" );
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
r = (MEM_ADDRESS_REQUIREMENTS *)parameters[i].Pointer;
|
||||||
|
|
||||||
|
if (r->LowestStartingAddress || r->Alignment)
|
||||||
|
FIXME( "Not supported requirements LowestStartingAddress %p, Alignment %p.\n",
|
||||||
|
r->LowestStartingAddress, (void *)r->Alignment );
|
||||||
|
|
||||||
|
limit = (ULONG_PTR)r->HighestEndingAddress;
|
||||||
|
if (limit && (*ret || limit > (ULONG_PTR)user_space_limit || ((limit + 1) & (page_mask - 1))))
|
||||||
|
{
|
||||||
|
WARN( "Invalid limit %p.\n", r->HighestEndingAddress);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
TRACE( "limit %p.\n", (void *)limit );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*size_ptr) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (process != NtCurrentProcess())
|
||||||
|
{
|
||||||
|
apc_call_t call;
|
||||||
|
apc_result_t result;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
memset( &call, 0, sizeof(call) );
|
||||||
|
|
||||||
|
call.virtual_alloc_ex.type = APC_VIRTUAL_ALLOC_EX;
|
||||||
|
call.virtual_alloc_ex.addr = wine_server_client_ptr( *ret );
|
||||||
|
call.virtual_alloc_ex.size = *size_ptr;
|
||||||
|
call.virtual_alloc_ex.limit = limit;
|
||||||
|
call.virtual_alloc_ex.op_type = type;
|
||||||
|
call.virtual_alloc_ex.prot = protect;
|
||||||
|
status = server_queue_process_apc( process, &call, &result );
|
||||||
|
if (status != STATUS_SUCCESS) return status;
|
||||||
|
|
||||||
|
if (result.virtual_alloc_ex.status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
*ret = wine_server_get_ptr( result.virtual_alloc_ex.addr );
|
||||||
|
*size_ptr = result.virtual_alloc_ex.size;
|
||||||
|
}
|
||||||
|
return result.virtual_alloc_ex.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocate_virtual_memory( ret, size_ptr, type, protect, limit );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -477,6 +477,7 @@ enum apc_type
|
||||||
APC_USER,
|
APC_USER,
|
||||||
APC_ASYNC_IO,
|
APC_ASYNC_IO,
|
||||||
APC_VIRTUAL_ALLOC,
|
APC_VIRTUAL_ALLOC,
|
||||||
|
APC_VIRTUAL_ALLOC_EX,
|
||||||
APC_VIRTUAL_FREE,
|
APC_VIRTUAL_FREE,
|
||||||
APC_VIRTUAL_QUERY,
|
APC_VIRTUAL_QUERY,
|
||||||
APC_VIRTUAL_PROTECT,
|
APC_VIRTUAL_PROTECT,
|
||||||
|
@ -519,6 +520,15 @@ typedef union
|
||||||
unsigned int prot;
|
unsigned int prot;
|
||||||
} virtual_alloc;
|
} virtual_alloc;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
enum apc_type type;
|
||||||
|
unsigned int op_type;
|
||||||
|
client_ptr_t addr;
|
||||||
|
mem_size_t size;
|
||||||
|
mem_size_t limit;
|
||||||
|
unsigned int prot;
|
||||||
|
} virtual_alloc_ex;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
enum apc_type type;
|
enum apc_type type;
|
||||||
unsigned int op_type;
|
unsigned int op_type;
|
||||||
|
@ -614,6 +624,13 @@ typedef union
|
||||||
mem_size_t size;
|
mem_size_t size;
|
||||||
} virtual_alloc;
|
} virtual_alloc;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
enum apc_type type;
|
||||||
|
unsigned int status;
|
||||||
|
client_ptr_t addr;
|
||||||
|
mem_size_t size;
|
||||||
|
} virtual_alloc_ex;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
enum apc_type type;
|
enum apc_type type;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
@ -6338,7 +6355,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 756
|
#define SERVER_PROTOCOL_VERSION 757
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -759,6 +759,13 @@ typedef struct _MEMORY_BASIC_INFORMATION
|
||||||
DWORD Type;
|
DWORD Type;
|
||||||
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
|
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _MEM_ADDRESS_REQUIREMENTS
|
||||||
|
{
|
||||||
|
void *LowestStartingAddress;
|
||||||
|
void *HighestEndingAddress;
|
||||||
|
SIZE_T Alignment;
|
||||||
|
} MEM_ADDRESS_REQUIREMENTS, *PMEM_ADDRESS_REQUIREMENTS;
|
||||||
|
|
||||||
#define MEM_EXTENDED_PARAMETER_TYPE_BITS 8
|
#define MEM_EXTENDED_PARAMETER_TYPE_BITS 8
|
||||||
|
|
||||||
typedef enum MEM_EXTENDED_PARAMETER_TYPE {
|
typedef enum MEM_EXTENDED_PARAMETER_TYPE {
|
||||||
|
|
|
@ -493,6 +493,7 @@ enum apc_type
|
||||||
APC_USER,
|
APC_USER,
|
||||||
APC_ASYNC_IO,
|
APC_ASYNC_IO,
|
||||||
APC_VIRTUAL_ALLOC,
|
APC_VIRTUAL_ALLOC,
|
||||||
|
APC_VIRTUAL_ALLOC_EX,
|
||||||
APC_VIRTUAL_FREE,
|
APC_VIRTUAL_FREE,
|
||||||
APC_VIRTUAL_QUERY,
|
APC_VIRTUAL_QUERY,
|
||||||
APC_VIRTUAL_PROTECT,
|
APC_VIRTUAL_PROTECT,
|
||||||
|
@ -535,6 +536,15 @@ typedef union
|
||||||
unsigned int prot; /* memory protection flags */
|
unsigned int prot; /* memory protection flags */
|
||||||
} virtual_alloc;
|
} virtual_alloc;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
enum apc_type type; /* APC_VIRTUAL_ALLOC */
|
||||||
|
unsigned int op_type; /* type of operation */
|
||||||
|
client_ptr_t addr; /* requested address */
|
||||||
|
mem_size_t size; /* allocation size */
|
||||||
|
mem_size_t limit; /* allocation address limit */
|
||||||
|
unsigned int prot; /* memory protection flags */
|
||||||
|
} virtual_alloc_ex;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
enum apc_type type; /* APC_VIRTUAL_FREE */
|
enum apc_type type; /* APC_VIRTUAL_FREE */
|
||||||
unsigned int op_type; /* type of operation */
|
unsigned int op_type; /* type of operation */
|
||||||
|
@ -630,6 +640,13 @@ typedef union
|
||||||
mem_size_t size; /* resulting size */
|
mem_size_t size; /* resulting size */
|
||||||
} virtual_alloc;
|
} virtual_alloc;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
enum apc_type type; /* APC_VIRTUAL_ALLOC */
|
||||||
|
unsigned int status; /* status returned by call */
|
||||||
|
client_ptr_t addr; /* resulting address */
|
||||||
|
mem_size_t size; /* resulting size */
|
||||||
|
} virtual_alloc_ex;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
enum apc_type type; /* APC_VIRTUAL_FREE */
|
enum apc_type type; /* APC_VIRTUAL_FREE */
|
||||||
unsigned int status; /* status returned by call */
|
unsigned int status; /* status returned by call */
|
||||||
|
|
|
@ -1713,6 +1713,7 @@ DECL_HANDLER(queue_apc)
|
||||||
thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT );
|
thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT );
|
||||||
break;
|
break;
|
||||||
case APC_VIRTUAL_ALLOC:
|
case APC_VIRTUAL_ALLOC:
|
||||||
|
case APC_VIRTUAL_ALLOC_EX:
|
||||||
case APC_VIRTUAL_FREE:
|
case APC_VIRTUAL_FREE:
|
||||||
case APC_VIRTUAL_PROTECT:
|
case APC_VIRTUAL_PROTECT:
|
||||||
case APC_VIRTUAL_FLUSH:
|
case APC_VIRTUAL_FLUSH:
|
||||||
|
|
|
@ -189,6 +189,12 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
|
||||||
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:
|
||||||
|
dump_uint64( "APC_VIRTUAL_ALLOC,addr==", &call->virtual_alloc_ex.addr );
|
||||||
|
dump_uint64( ",size=", &call->virtual_alloc_ex.size );
|
||||||
|
dump_uint64( ",limit=", &call->virtual_alloc_ex.limit );
|
||||||
|
fprintf( stderr, ",op_type=%x,prot=%x", call->virtual_alloc_ex.op_type, call->virtual_alloc_ex.prot );
|
||||||
|
break;
|
||||||
case APC_VIRTUAL_FREE:
|
case APC_VIRTUAL_FREE:
|
||||||
dump_uint64( "APC_VIRTUAL_FREE,addr=", &call->virtual_free.addr );
|
dump_uint64( "APC_VIRTUAL_FREE,addr=", &call->virtual_free.addr );
|
||||||
dump_uint64( ",size=", &call->virtual_free.size );
|
dump_uint64( ",size=", &call->virtual_free.size );
|
||||||
|
|
Loading…
Reference in a new issue