diff --git a/src/alloy/memory.h b/src/alloy/memory.h index a29d12170..0a1f861ad 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -55,6 +55,7 @@ class Memory { uint32_t alignment = 0x20) = 0; virtual int HeapFree(uint64_t address, size_t size) = 0; + virtual size_t QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) = 0; virtual size_t QuerySize(uint64_t base_address) = 0; virtual int Protect(uint64_t address, size_t size, uint32_t access) = 0; diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 37bac9c61..c04bb7083 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -415,6 +415,12 @@ int XenonMemory::HeapFree(uint64_t address, size_t size) { } } +size_t XenonMemory::QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) { + uint8_t* p = Translate(base_address); + + return VirtualQuery(p, &mem_info, sizeof(mem_info)); +} + size_t XenonMemory::QuerySize(uint64_t base_address) { if (base_address >= XENON_MEMORY_VIRTUAL_HEAP_LOW && base_address < XENON_MEMORY_VIRTUAL_HEAP_HIGH) { diff --git a/src/xenia/cpu/xenon_memory.h b/src/xenia/cpu/xenon_memory.h index dc5ff9354..4015dd08f 100644 --- a/src/xenia/cpu/xenon_memory.h +++ b/src/xenia/cpu/xenon_memory.h @@ -54,6 +54,7 @@ public: uint32_t alignment = 0x20) override; int HeapFree(uint64_t address, size_t size) override; + size_t QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) override; size_t QuerySize(uint64_t base_address) override; int Protect(uint64_t address, size_t size, uint32_t access) override; diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 487d4757a..9a9b8b258 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -191,15 +191,23 @@ SHIM_CALL NtFreeVirtualMemory_shim( X_STATUS xeNtQueryVirtualMemory( uint32_t base_address, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { + KernelState* state = shared_kernel_state_; + assert_not_null(state); - // Just pretend that there is no virtual address allocated at given base address - memory_basic_information->base_address = XEROUNDUP(base_address, 4096); - memory_basic_information->allocation_base = NULL; - memory_basic_information->allocation_protect = 0; - memory_basic_information->region_size = 0; - memory_basic_information->state = X_MEM_FREE; - memory_basic_information->protect = X_PAGE_NOACCESS; - memory_basic_information->type = 0; + MEMORY_BASIC_INFORMATION mem_info; + size_t result = state->memory()->QueryInformation(base_address, mem_info); + + if (!result) { + return STATUS_INVALID_PARAMETER; + } + + memory_basic_information->base_address = (uint32_t) mem_info.BaseAddress; + memory_basic_information->allocation_base = (uint32_t) mem_info.AllocationBase; + memory_basic_information->allocation_protect = mem_info.AllocationProtect; + memory_basic_information->region_size = mem_info.RegionSize; + memory_basic_information->state = mem_info.State; + memory_basic_information->protect = mem_info.Protect; + memory_basic_information->type = mem_info.Type; if (swap) { memory_basic_information->base_address = poly::byte_swap(memory_basic_information->base_address);