Commit 5b6e82f0 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Handle the extended memory attributes in NtAllocateVirtualMemoryEx().

parent f2623cca
......@@ -366,7 +366,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 )
{
SIZE_T size, bits, limit, align;
SIZE_T size, bits;
void *addr;
memset( result, 0, sizeof(*result) );
......@@ -411,32 +411,50 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
break;
case APC_VIRTUAL_ALLOC_EX:
{
MEM_ADDRESS_REQUIREMENTS r = { NULL };
MEM_EXTENDED_PARAMETER ext =
{
.Type = MemExtendedParameterAddressRequirements,
.Pointer = &r
};
SYSTEM_BASIC_INFORMATION sbi;
MEM_ADDRESS_REQUIREMENTS r;
MEM_EXTENDED_PARAMETER ext[2];
ULONG count = 0;
virtual_get_system_info( &sbi, is_wow64() );
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 );
align = call->virtual_alloc_ex.align;
if ((ULONG_PTR)addr == call->virtual_alloc_ex.addr && size == call->virtual_alloc_ex.size
&& align == call->virtual_alloc_ex.align)
if ((ULONG_PTR)addr != call->virtual_alloc_ex.addr || size != call->virtual_alloc_ex.size)
{
result->virtual_alloc_ex.status = STATUS_WORKING_SET_LIMIT_RANGE;
break;
}
if (call->virtual_alloc_ex.limit || call->virtual_alloc_ex.align)
{
SYSTEM_BASIC_INFORMATION sbi;
SIZE_T limit, align;
virtual_get_system_info( &sbi, is_wow64() );
limit = min( (ULONG_PTR)sbi.HighestUserAddress, call->virtual_alloc_ex.limit );
align = call->virtual_alloc_ex.align;
if (align != call->virtual_alloc_ex.align)
{
result->virtual_alloc_ex.status = STATUS_WORKING_SET_LIMIT_RANGE;
break;
}
r.LowestStartingAddress = NULL;
r.HighestEndingAddress = (void *)limit;
r.Alignment = align;
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;
ext[count].Type = MemExtendedParameterAddressRequirements;
ext[count].Pointer = &r;
count++;
}
if (call->virtual_alloc_ex.attributes)
{
ext[count].Type = MemExtendedParameterAttributeFlags;
ext[count].ULong64 = call->virtual_alloc_ex.attributes;
count++;
}
else result->virtual_alloc_ex.status = STATUS_WORKING_SET_LIMIT_RANGE;
result->virtual_alloc_ex.status = NtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr, &size,
call->virtual_alloc_ex.op_type,
call->virtual_alloc_ex.prot,
ext, count );
result->virtual_alloc_ex.addr = wine_server_client_ptr( addr );
result->virtual_alloc_ex.size = size;
break;
}
case APC_VIRTUAL_FREE:
......
......@@ -3911,7 +3911,7 @@ void virtual_set_large_address_space(void)
* NtAllocateVirtualMemory[Ex] implementation.
*/
static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG type, ULONG protect,
ULONG_PTR limit, ULONG_PTR align )
ULONG_PTR limit, ULONG_PTR align, ULONG attributes )
{
void *base;
unsigned int vprot;
......@@ -4061,7 +4061,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
else
limit = 0;
return allocate_virtual_memory( ret, size_ptr, type, protect, limit, 0 );
return allocate_virtual_memory( ret, size_ptr, type, protect, limit, 0, 0 );
}
......@@ -4075,35 +4075,22 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
{
ULONG_PTR limit = 0;
ULONG_PTR align = 0;
ULONG attributes = 0;
MEM_ADDRESS_REQUIREMENTS *r = NULL;
unsigned int i;
TRACE("%p %p %08lx %x %08x %p %u\n",
TRACE( "%p %p %08lx %x %08x %p %u\n",
process, *ret, *size_ptr, (int)type, (int)protect, parameters, (int)count );
if (count && !parameters) return STATUS_INVALID_PARAMETER;
if (count)
for (i = 0; i < count; ++i)
{
MEM_ADDRESS_REQUIREMENTS *r = NULL;
unsigned int i;
for (i = 0; i < count; ++i)
switch (parameters[i].Type)
{
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;
case MemExtendedParameterAddressRequirements:
if (r) return STATUS_INVALID_PARAMETER;
r = parameters[i].Pointer;
if (r->LowestStartingAddress)
FIXME( "Not supported requirements LowestStartingAddress %p, Alignment %p.\n",
......@@ -4126,6 +4113,22 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
return STATUS_INVALID_PARAMETER;
}
TRACE( "limit %p, align %p.\n", (void *)limit, (void *)align );
break;
case MemExtendedParameterAttributeFlags:
attributes = parameters[i].ULong;
break;
case MemExtendedParameterNumaNode:
case MemExtendedParameterPartitionHandle:
case MemExtendedParameterUserPhysicalHandle:
case MemExtendedParameterImageMachine:
FIXME( "Parameter type %d is not supported.\n", parameters[i].Type );
break;
default:
WARN( "Invalid parameter type %u\n", parameters[i].Type );
return STATUS_INVALID_PARAMETER;
}
}
......@@ -4146,6 +4149,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
call.virtual_alloc_ex.align = align;
call.virtual_alloc_ex.op_type = type;
call.virtual_alloc_ex.prot = protect;
call.virtual_alloc_ex.attributes = attributes;
status = server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
......@@ -4157,7 +4161,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
return result.virtual_alloc_ex.status;
}
return allocate_virtual_memory( ret, size_ptr, type, protect, limit, align );
return allocate_virtual_memory( ret, size_ptr, type, protect, limit, align, attributes );
}
......
......@@ -528,6 +528,7 @@ typedef union
mem_size_t limit;
mem_size_t align;
unsigned int prot;
unsigned int attributes;
} virtual_alloc_ex;
struct
{
......@@ -6358,7 +6359,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 762
#define SERVER_PROTOCOL_VERSION 763
/* ### protocol_version end ### */
......
......@@ -777,6 +777,7 @@ typedef enum MEM_EXTENDED_PARAMETER_TYPE {
MemExtendedParameterPartitionHandle,
MemExtendedParameterUserPhysicalHandle,
MemExtendedParameterAttributeFlags,
MemExtendedParameterImageMachine,
MemExtendedParameterMax
} MEM_EXTENDED_PARAMETER_TYPE, *PMEM_EXTENDED_PARAMETER_TYPE;
......@@ -797,6 +798,15 @@ typedef struct DECLSPEC_ALIGN(8) MEM_EXTENDED_PARAMETER {
} DUMMYUNIONNAME;
} MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER;
#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001
#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002
#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004
#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008
#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010
#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
#define MEM_EXTENDED_PARAMETER_IMAGE_NO_HPAT 0x00000080
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
......
......@@ -544,6 +544,7 @@ typedef union
mem_size_t limit; /* allocation address limit */
mem_size_t align; /* allocation alignment */
unsigned int prot; /* memory protection flags */
unsigned int attributes; /* memory extended attributes */
} virtual_alloc_ex;
struct
{
......
......@@ -194,7 +194,9 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
dump_uint64( ",size=", &call->virtual_alloc_ex.size );
dump_uint64( ",limit=", &call->virtual_alloc_ex.limit );
dump_uint64( ",align=", &call->virtual_alloc_ex.align );
fprintf( stderr, ",op_type=%x,prot=%x", call->virtual_alloc_ex.op_type, call->virtual_alloc_ex.prot );
fprintf( stderr, ",op_type=%x,prot=%x,attributes=%x",
call->virtual_alloc_ex.op_type, call->virtual_alloc_ex.prot,
call->virtual_alloc_ex.attributes );
break;
case APC_VIRTUAL_FREE:
dump_uint64( "APC_VIRTUAL_FREE,addr=", &call->virtual_free.addr );
......
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