From: Paul Gofman pgofman@codeweavers.com
To prevent 64 bit NtAllocateVirtualMemoryEx() allocating from above 32 bit user space limit. --- dlls/wow64/virtual.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/dlls/wow64/virtual.c b/dlls/wow64/virtual.c index 8cccf40b2c6..373a07a2236 100644 --- a/dlls/wow64/virtual.c +++ b/dlls/wow64/virtual.c @@ -93,6 +93,7 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) NTSTATUS status; SIZE_T alloc_size = count * sizeof(*params); MEM_EXTENDED_PARAMETER *params64; + BOOL need_highest_address = !*addr32; MEM_ADDRESS_REQUIREMENTS *buf; unsigned int i;
@@ -101,14 +102,33 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) for (i = 0; i < count; ++i) { if (params[i].Type == MemExtendedParameterAddressRequirements) + { alloc_size += sizeof(MEM_ADDRESS_REQUIREMENTS); + need_highest_address = FALSE; + } else if (params[i].Type && params[i].Type < MemExtendedParameterMax) + { FIXME( "Unsupported parameter type %d.\n", params[i].Type); + } }
+ if (need_highest_address) + alloc_size += sizeof(*params) + sizeof(MEM_ADDRESS_REQUIREMENTS); params64 = Wow64AllocateTemp( alloc_size ); memcpy( params64, params, count * sizeof(*params64) ); - buf = (MEM_ADDRESS_REQUIREMENTS *)((char *)params64 + count * sizeof(*params64)); + if (need_highest_address) + { + buf = (MEM_ADDRESS_REQUIREMENTS *)((char *)params64 + (count + 1) * sizeof(*params64)); + params64[count].Type = MemExtendedParameterAddressRequirements; + params64[count].Pointer = buf; + memset(buf, 0, sizeof(*buf)); + buf->HighestEndingAddress = (void *)(ULONG_PTR)highest_user_address; + ++buf; + } + else + { + buf = (MEM_ADDRESS_REQUIREMENTS *)((char *)params64 + count * sizeof(*params64)); + } for (i = 0; i < count; ++i) { if (params64[i].Type == MemExtendedParameterAddressRequirements) @@ -123,7 +143,7 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) } else { - buf->HighestEndingAddress = *addr32 ? NULL : highest_user_address; + buf->HighestEndingAddress = *addr32 ? NULL : (void *)(ULONG_PTR)highest_user_address; } buf->Alignment = p->Alignment; params64[i].Pointer = buf; @@ -132,7 +152,7 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) }
status = NtAllocateVirtualMemoryEx( process, addr_32to64( &addr, addr32 ), size_32to64( &size, size32 ), - type, protect, params64, count ); + type, protect, params64, count + need_highest_address ); if (!status) { put_addr( addr32, addr );