From: Paul Gofman pgofman@codeweavers.com
--- dlls/wow64/struct32.h | 7 +++++++ dlls/wow64/virtual.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h index 91acc26436f..071bdf092e0 100644 --- a/dlls/wow64/struct32.h +++ b/dlls/wow64/struct32.h @@ -674,4 +674,11 @@ struct __server_request_info32 struct __server_iovec32 data[__SERVER_MAX_DATA]; };
+typedef struct +{ + ULONG LowestStartingAddress; + ULONG HighestEndingAddress; + ULONG Alignment; +} MEM_ADDRESS_REQUIREMENTS32; + #endif /* __WOW64_STRUCT32_H */ diff --git a/dlls/wow64/virtual.c b/dlls/wow64/virtual.c index 8b7d022301f..8cccf40b2c6 100644 --- a/dlls/wow64/virtual.c +++ b/dlls/wow64/virtual.c @@ -91,10 +91,48 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) void *addr; SIZE_T size; NTSTATUS status; + SIZE_T alloc_size = count * sizeof(*params); + MEM_EXTENDED_PARAMETER *params64; + MEM_ADDRESS_REQUIREMENTS *buf; + unsigned int i; + + if (count && !params) return STATUS_INVALID_PARAMETER; + + for (i = 0; i < count; ++i) + { + if (params[i].Type == MemExtendedParameterAddressRequirements) + alloc_size += sizeof(MEM_ADDRESS_REQUIREMENTS); + else if (params[i].Type && params[i].Type < MemExtendedParameterMax) + FIXME( "Unsupported parameter type %d.\n", params[i].Type); + } + + params64 = Wow64AllocateTemp( alloc_size ); + memcpy( params64, params, count * sizeof(*params64) ); + buf = (MEM_ADDRESS_REQUIREMENTS *)((char *)params64 + count * sizeof(*params64)); + for (i = 0; i < count; ++i) + { + if (params64[i].Type == MemExtendedParameterAddressRequirements) + { + MEM_ADDRESS_REQUIREMENTS32 *p = (MEM_ADDRESS_REQUIREMENTS32 *)params[i].Pointer; + + buf->LowestStartingAddress = (void *)(ULONG_PTR)p->LowestStartingAddress; + if (p->HighestEndingAddress) + { + if (p->HighestEndingAddress > highest_user_address) return STATUS_INVALID_PARAMETER; + buf->HighestEndingAddress = (void *)(ULONG_PTR)p->HighestEndingAddress; + } + else + { + buf->HighestEndingAddress = *addr32 ? NULL : highest_user_address; + } + buf->Alignment = p->Alignment; + params64[i].Pointer = buf; + ++buf; + } + }
- if (count) FIXME( "%ld extended parameters %p\n", count, params ); status = NtAllocateVirtualMemoryEx( process, addr_32to64( &addr, addr32 ), size_32to64( &size, size32 ), - type, protect, params, count ); + type, protect, params64, count ); if (!status) { put_addr( addr32, addr );