From c7686e33a80472390e8f25ac73051a4730b59100 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Sun, 17 May 2026 14:29:13 -0500 Subject: [PATCH] Core: Fix file position after read-only file mmaps (#4442) * Fix file position after file mmaps * Oops --- src/core/address_space.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index be9e0c62e..360c05583 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -241,19 +241,28 @@ struct AddressSpace::Impl { if (phys_addr != -1) { HANDLE backing = fd != -1 ? reinterpret_cast(fd) : backing_handle; if (fd != -1 && prot == PAGE_READONLY) { + // Allocate the memory for the mapping DWORD resultvar; ptr = VirtualAlloc2(process, reinterpret_cast(virtual_addr), size, MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0); - // phys_addr serves as an offset for file mmaps. - // Create an OVERLAPPED with the offset, then supply that to ReadFile + // Use ReadFile to read file contents into the memory area. + // Create an OVERLAPPED with the file offset, then supply that to ReadFile OVERLAPPED param{}; // Offset is the least-significant 32 bits, OffsetHigh is the most-significant. param.Offset = phys_addr & 0xffffffffull; param.OffsetHigh = (phys_addr & 0xffffffff00000000ull) >> 32; bool ret = ReadFile(backing, ptr, size, &resultvar, ¶m); ASSERT_MSG(ret, "ReadFile failed. {}", Common::GetLastErrorMsg()); + + // ReadFile moves the file pointer, restore it with SetFilePointer + s64 size_to_move = -size; + LONG size_low = size_to_move & 0xffffffffull; + LONG size_high = (size_to_move & 0xffffffff00000000ull) >> 32; + ret = SetFilePointer(backing, size_low, &size_high, FILE_CURRENT); + + // Protect the memory area appropriately ret = VirtualProtect(ptr, size, prot, &resultvar); ASSERT_MSG(ret, "VirtualProtect failed. {}", Common::GetLastErrorMsg()); } else {