From 0e937af7ff78415a0d803f4b46b7c8c87acc249e Mon Sep 17 00:00:00 2001 From: Echelon9 Date: Mon, 8 Apr 2013 23:22:30 +1000 Subject: [PATCH] Added special case to NtQueryVirtualMemory to handle Forza Motorsport bug -- backported from Dxbx, where issue was resolved by PatrickvL --- src/CxbxKrnl/EmuKrnl.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/CxbxKrnl/EmuKrnl.cpp b/src/CxbxKrnl/EmuKrnl.cpp index 02fefbed5..e95057ccb 100644 --- a/src/CxbxKrnl/EmuKrnl.cpp +++ b/src/CxbxKrnl/EmuKrnl.cpp @@ -3457,8 +3457,29 @@ XBSYSAPI EXPORTNUM(217) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryVirtualMemory 0 ); - if(FAILED(ret)) - EmuWarning("NtQueryVirtualMemory failed!"); + if(FAILED(ret)) { + EmuWarning("NtQueryVirtualMemory failed (%s)!", NtStatusToString(ret)); + + // Bugfix for "Forza Motorsport", which iterates over 2 Gb of memory in 64kb chunks, + // but fails on this last query. It's not done though, as after this Forza tries to + // NtAllocateVirtualMemory at address 0x00000000 (3 times, actually) which fails too... + // + // Ported back from dxbx, translator PatrickvL + + if (BaseAddress == (PVOID)0x7FFF0000) { + Buffer->BaseAddress = BaseAddress; + Buffer->AllocationBase = BaseAddress; + Buffer->AllocationProtect = PAGE_READONLY; + Buffer->RegionSize = 64 * 1024; // size, in bytes, of the region beginning at the base address in which all pages have identical attributes + Buffer->State = 4096; // MEM_DECOMMIT | PAGE_EXECUTE_WRITECOPY etc + Buffer->Protect = PAGE_READONLY; // One of the flags listed for the AllocationProtect member is specified + Buffer->Type = 262144; // Specifies the type of pages in the region. (MEM_IMAGE, MEM_MAPPED or MEM_PRIVATE) + + ret = STATUS_SUCCESS; + + DbgPrintf("EmuKrnl (0x%X): NtQueryVirtualMemory: Applied fix for Forza Motorsport!\n", GetCurrentThreadId()); + } + } EmuSwapFS(); // Xbox FS