From 46b28fd25b5992fe654966452d71d69f7bb07143 Mon Sep 17 00:00:00 2001 From: "Daniel R." <47796739+polybiusproxy@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:16:10 +0200 Subject: [PATCH] Fix bug where files were always mapped as read only. --- src/common/io_file.cpp | 13 +++++++++++-- src/core/address_space.cpp | 17 +++++++++++++++-- src/core/address_space.h | 2 +- src/core/memory.cpp | 2 +- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/common/io_file.cpp b/src/common/io_file.cpp index 3d60d5b4f..63b036574 100644 --- a/src/common/io_file.cpp +++ b/src/common/io_file.cpp @@ -246,9 +246,18 @@ uintptr_t IOFile::GetFileMapping() { } #ifdef _WIN64 const int fd = fileno(file); + HANDLE hfile = reinterpret_cast(_get_osfhandle(fd)); - HANDLE mapping = - CreateFileMapping2(hfile, NULL, FILE_MAP_READ, PAGE_READONLY, SEC_COMMIT, 0, NULL, NULL, 0); + HANDLE mapping = nullptr; + + if (file_access_mode == FileAccessMode::ReadWrite) { + mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_WRITE, PAGE_READWRITE, SEC_COMMIT, + 0, NULL, NULL, 0); + } else { + mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_READ, PAGE_READONLY, SEC_COMMIT, + 0, NULL, NULL, 0); + } + file_mapping = std::bit_cast(mapping); ASSERT_MSG(file_mapping, "{}", Common::GetLastErrorMsg()); return file_mapping; diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 7749ec2dd..8a07edcfc 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "common/error.h" #include "core/address_space.h" +#include "core/memory.h" #include "core/libraries/kernel/memory_management.h" #ifdef _WIN32 @@ -18,6 +19,18 @@ namespace Core { static constexpr size_t BackingSize = SCE_KERNEL_MAIN_DMEM_SIZE; +[[nodiscard]] constexpr u64 ToWindowsProt(Core::MemoryProt prot) { + switch (prot) { + case Core::MemoryProt::NoAccess: + default: + return PAGE_NOACCESS; + case Core::MemoryProt::CpuRead: + return PAGE_READONLY; + case Core::MemoryProt::CpuReadWrite: + return PAGE_READWRITE; + } +} + #ifdef _WIN32 struct AddressSpace::Impl { Impl() : process{GetCurrentProcess()} { @@ -325,8 +338,8 @@ void* AddressSpace::Map(VAddr virtual_addr, size_t size, u64 alignment, PAddr ph is_exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); } -void* AddressSpace::MapFile(VAddr virtual_addr, size_t size, size_t offset, uintptr_t fd) { - return impl->Map(virtual_addr, offset, size, fd ? PAGE_READONLY : PAGE_READWRITE, fd); +void* AddressSpace::MapFile(VAddr virtual_addr, size_t size, size_t offset, u32 prot, uintptr_t fd) { + return impl->Map(virtual_addr, offset, size, ToWindowsProt(std::bit_cast(prot)), fd); } void AddressSpace::Unmap(VAddr virtual_addr, size_t size, bool has_backing) { diff --git a/src/core/address_space.h b/src/core/address_space.h index b979481f7..5b68839c0 100644 --- a/src/core/address_space.h +++ b/src/core/address_space.h @@ -63,7 +63,7 @@ public: bool exec = false); /// Memory maps a specified file descriptor. - void* MapFile(VAddr virtual_addr, size_t size, size_t offset, uintptr_t fd); + void* MapFile(VAddr virtual_addr, size_t size, size_t offset, u32 prot, uintptr_t fd); /// Unmaps specified virtual memory area. void Unmap(VAddr virtual_addr, size_t size, bool has_backing); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 2f1f99d35..98628ee40 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -195,7 +195,7 @@ int MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, size_t size, Mem } // Map the file. - impl.MapFile(mapped_addr, size, offset, fd); + impl.MapFile(mapped_addr, size, offset, std::bit_cast(prot), fd); // Add virtual memory area auto& new_vma = AddMapping(mapped_addr, size_aligned);