mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 13:33:42 +00:00
ntdll: Support specified alignment in NtAllocateVirtualMemoryEx().
This commit is contained in:
parent
bf9dc3ff1f
commit
17328f4f5c
|
@ -584,6 +584,48 @@ static void test_NtAllocateVirtualMemoryEx_address_requirements(void)
|
||||||
size = 0;
|
size = 0;
|
||||||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE);
|
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE);
|
||||||
ok(!status, "Unexpected status %08lx.\n", status);
|
ok(!status, "Unexpected status %08lx.\n", status);
|
||||||
|
|
||||||
|
a.HighestEndingAddress = (void *)(0x20001000 - 1);
|
||||||
|
a.Alignment = 0x20000000;
|
||||||
|
size = 0x2000;
|
||||||
|
addr = NULL;
|
||||||
|
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr, &size, MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE, ext, 1);
|
||||||
|
ok(status == STATUS_NO_MEMORY, "Unexpected status %08lx.\n", status);
|
||||||
|
|
||||||
|
a.HighestEndingAddress = NULL;
|
||||||
|
a.Alignment = 0x8000;
|
||||||
|
size = 0x1000;
|
||||||
|
addr = NULL;
|
||||||
|
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr, &size, MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE, ext, 1);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
|
||||||
|
|
||||||
|
a.Alignment = 0x30000;
|
||||||
|
size = 0x1000;
|
||||||
|
addr = NULL;
|
||||||
|
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr, &size, MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE, ext, 1);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
|
||||||
|
|
||||||
|
a.Alignment = 0x40000;
|
||||||
|
size = 0x1000;
|
||||||
|
addr = NULL;
|
||||||
|
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr, &size, MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE, ext, 1);
|
||||||
|
ok(!status, "Unexpected status %08lx.\n", status);
|
||||||
|
ok(!((ULONG_PTR)addr & 0x3ffff), "Unexpected addr %p.\n", addr);
|
||||||
|
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr, &size, MEM_COMMIT,
|
||||||
|
PAGE_EXECUTE_READWRITE, ext, 1);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE);
|
||||||
|
ok(!status, "Unexpected status %08lx.\n", status);
|
||||||
|
|
||||||
|
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr, &size, MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE, ext, 1);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct test_stack_size_thread_args
|
struct test_stack_size_thread_args
|
||||||
|
|
|
@ -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, limit;
|
SIZE_T size, bits, limit, align;
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
memset( result, 0, sizeof(*result) );
|
memset( result, 0, sizeof(*result) );
|
||||||
|
@ -416,9 +416,12 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
||||||
addr = wine_server_get_ptr( call->virtual_alloc_ex.addr );
|
addr = wine_server_get_ptr( call->virtual_alloc_ex.addr );
|
||||||
size = call->virtual_alloc_ex.size;
|
size = call->virtual_alloc_ex.size;
|
||||||
limit = min( (ULONG_PTR)sbi.HighestUserAddress, call->virtual_alloc_ex.limit );
|
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)
|
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)
|
||||||
{
|
{
|
||||||
r.HighestEndingAddress = (void *)limit;
|
r.HighestEndingAddress = (void *)limit;
|
||||||
|
r.Alignment = align;
|
||||||
result->virtual_alloc_ex.status = NtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr, &size,
|
result->virtual_alloc_ex.status = NtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr, &size,
|
||||||
call->virtual_alloc_ex.op_type,
|
call->virtual_alloc_ex.op_type,
|
||||||
call->virtual_alloc_ex.prot, &ext, 1 );
|
call->virtual_alloc_ex.prot, &ext, 1 );
|
||||||
|
|
|
@ -3738,7 +3738,7 @@ void virtual_set_large_address_space(void)
|
||||||
* NtAllocateVirtualMemory[Ex] implementation.
|
* NtAllocateVirtualMemory[Ex] implementation.
|
||||||
*/
|
*/
|
||||||
static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG type, ULONG protect,
|
static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG type, ULONG protect,
|
||||||
ULONG_PTR limit )
|
ULONG_PTR limit, ULONG_PTR align )
|
||||||
{
|
{
|
||||||
void *base;
|
void *base;
|
||||||
unsigned int vprot;
|
unsigned int vprot;
|
||||||
|
@ -3800,7 +3800,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
|
||||||
if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION;
|
if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION;
|
||||||
else if (is_dos_memory) status = allocate_dos_memory( &view, vprot );
|
else if (is_dos_memory) status = allocate_dos_memory( &view, vprot );
|
||||||
else status = map_view( &view, base, size, type & MEM_TOP_DOWN, vprot, limit,
|
else status = map_view( &view, base, size, type & MEM_TOP_DOWN, vprot, limit,
|
||||||
granularity_mask );
|
align ? align - 1 : granularity_mask );
|
||||||
|
|
||||||
if (status == STATUS_SUCCESS) base = view->base;
|
if (status == STATUS_SUCCESS) base = view->base;
|
||||||
}
|
}
|
||||||
|
@ -3888,7 +3888,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
|
||||||
else
|
else
|
||||||
limit = 0;
|
limit = 0;
|
||||||
|
|
||||||
return allocate_virtual_memory( ret, size_ptr, type, protect, limit );
|
return allocate_virtual_memory( ret, size_ptr, type, protect, limit, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3901,6 +3901,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||||
ULONG count )
|
ULONG count )
|
||||||
{
|
{
|
||||||
ULONG_PTR limit = 0;
|
ULONG_PTR limit = 0;
|
||||||
|
ULONG_PTR align = 0;
|
||||||
|
|
||||||
TRACE("%p %p %08lx %x %08x %p %u\n", process, *ret, *size_ptr, type, protect, parameters, count );
|
TRACE("%p %p %08lx %x %08x %p %u\n", process, *ret, *size_ptr, type, protect, parameters, count );
|
||||||
|
|
||||||
|
@ -3930,17 +3931,27 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||||
}
|
}
|
||||||
r = (MEM_ADDRESS_REQUIREMENTS *)parameters[i].Pointer;
|
r = (MEM_ADDRESS_REQUIREMENTS *)parameters[i].Pointer;
|
||||||
|
|
||||||
if (r->LowestStartingAddress || r->Alignment)
|
if (r->LowestStartingAddress)
|
||||||
FIXME( "Not supported requirements LowestStartingAddress %p, Alignment %p.\n",
|
FIXME( "Not supported requirements LowestStartingAddress %p, Alignment %p.\n",
|
||||||
r->LowestStartingAddress, (void *)r->Alignment );
|
r->LowestStartingAddress, (void *)r->Alignment );
|
||||||
|
|
||||||
|
if (r->Alignment)
|
||||||
|
{
|
||||||
|
if (*ret || (r->Alignment & (r->Alignment - 1)) || r->Alignment - 1 < granularity_mask)
|
||||||
|
{
|
||||||
|
WARN( "Invalid alignment %lu.\n", r->Alignment );
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
align = r->Alignment;
|
||||||
|
}
|
||||||
|
|
||||||
limit = (ULONG_PTR)r->HighestEndingAddress;
|
limit = (ULONG_PTR)r->HighestEndingAddress;
|
||||||
if (limit && (*ret || limit > (ULONG_PTR)user_space_limit || ((limit + 1) & (page_mask - 1))))
|
if (limit && (*ret || limit > (ULONG_PTR)user_space_limit || ((limit + 1) & (page_mask - 1))))
|
||||||
{
|
{
|
||||||
WARN( "Invalid limit %p.\n", r->HighestEndingAddress);
|
WARN( "Invalid limit %p.\n", r->HighestEndingAddress);
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
TRACE( "limit %p.\n", (void *)limit );
|
TRACE( "limit %p, align %p.\n", (void *)limit, (void *)align );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3958,6 +3969,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||||
call.virtual_alloc_ex.addr = wine_server_client_ptr( *ret );
|
call.virtual_alloc_ex.addr = wine_server_client_ptr( *ret );
|
||||||
call.virtual_alloc_ex.size = *size_ptr;
|
call.virtual_alloc_ex.size = *size_ptr;
|
||||||
call.virtual_alloc_ex.limit = limit;
|
call.virtual_alloc_ex.limit = limit;
|
||||||
|
call.virtual_alloc_ex.align = align;
|
||||||
call.virtual_alloc_ex.op_type = type;
|
call.virtual_alloc_ex.op_type = type;
|
||||||
call.virtual_alloc_ex.prot = protect;
|
call.virtual_alloc_ex.prot = protect;
|
||||||
status = server_queue_process_apc( process, &call, &result );
|
status = server_queue_process_apc( process, &call, &result );
|
||||||
|
@ -3971,7 +3983,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||||
return result.virtual_alloc_ex.status;
|
return result.virtual_alloc_ex.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return allocate_virtual_memory( ret, size_ptr, type, protect, limit );
|
return allocate_virtual_memory( ret, size_ptr, type, protect, limit, align );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -526,6 +526,7 @@ typedef union
|
||||||
client_ptr_t addr;
|
client_ptr_t addr;
|
||||||
mem_size_t size;
|
mem_size_t size;
|
||||||
mem_size_t limit;
|
mem_size_t limit;
|
||||||
|
mem_size_t align;
|
||||||
unsigned int prot;
|
unsigned int prot;
|
||||||
} virtual_alloc_ex;
|
} virtual_alloc_ex;
|
||||||
struct
|
struct
|
||||||
|
@ -6355,7 +6356,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 757
|
#define SERVER_PROTOCOL_VERSION 758
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -542,6 +542,7 @@ typedef union
|
||||||
client_ptr_t addr; /* requested address */
|
client_ptr_t addr; /* requested address */
|
||||||
mem_size_t size; /* allocation size */
|
mem_size_t size; /* allocation size */
|
||||||
mem_size_t limit; /* allocation address limit */
|
mem_size_t limit; /* allocation address limit */
|
||||||
|
mem_size_t align; /* allocation alignment */
|
||||||
unsigned int prot; /* memory protection flags */
|
unsigned int prot; /* memory protection flags */
|
||||||
} virtual_alloc_ex;
|
} virtual_alloc_ex;
|
||||||
struct
|
struct
|
||||||
|
|
|
@ -193,6 +193,7 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call )
|
||||||
dump_uint64( "APC_VIRTUAL_ALLOC,addr==", &call->virtual_alloc_ex.addr );
|
dump_uint64( "APC_VIRTUAL_ALLOC,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 );
|
||||||
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", call->virtual_alloc_ex.op_type, call->virtual_alloc_ex.prot );
|
||||||
break;
|
break;
|
||||||
case APC_VIRTUAL_FREE:
|
case APC_VIRTUAL_FREE:
|
||||||
|
|
Loading…
Reference in a new issue