From 4a9553bf6df683b9f2995e5d7c485bf3034502e1 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 14 Feb 2022 21:54:21 +0100 Subject: [PATCH] MemArena: Load UnmapViewOfFileEx dynamically to restore Windows 7 support. --- Source/Core/Common/MemArena.h | 2 ++ Source/Core/Common/MemArenaWin.cpp | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index 5aebeccc23..7a0a683579 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -107,7 +107,9 @@ private: std::vector m_regions; void* m_reserved_region = nullptr; void* m_memory_handle = nullptr; + Common::DynamicLibrary m_kernel32_handle; Common::DynamicLibrary m_api_ms_win_core_memory_l1_1_6_handle; + void* m_address_UnmapViewOfFileEx = nullptr; void* m_address_VirtualAlloc2 = nullptr; void* m_address_MapViewOfFile3 = nullptr; #else diff --git a/Source/Core/Common/MemArenaWin.cpp b/Source/Core/Common/MemArenaWin.cpp index d94eb7c9d8..1e2de701c5 100644 --- a/Source/Core/Common/MemArenaWin.cpp +++ b/Source/Core/Common/MemArenaWin.cpp @@ -29,6 +29,8 @@ using PMapViewOfFile3 = PVOID(WINAPI*)(HANDLE FileMapping, HANDLE Process, PVOID MEM_EXTENDED_PARAMETER* ExtendedParameters, ULONG ParameterCount); +using PUnmapViewOfFileEx = BOOL(WINAPI*)(PVOID BaseAddress, ULONG UnmapFlags); + using PIsApiSetImplemented = BOOL(APIENTRY*)(PCSTR Contract); namespace Common @@ -62,22 +64,30 @@ MemArena::MemArena() return; m_api_ms_win_core_memory_l1_1_6_handle.Open("api-ms-win-core-memory-l1-1-6.dll"); - if (!m_api_ms_win_core_memory_l1_1_6_handle.IsOpen()) + m_kernel32_handle.Open("Kernel32.dll"); + if (!m_api_ms_win_core_memory_l1_1_6_handle.IsOpen() || !m_kernel32_handle.IsOpen()) + { + m_api_ms_win_core_memory_l1_1_6_handle.Close(); + m_kernel32_handle.Close(); return; + } void* const address_VirtualAlloc2 = m_api_ms_win_core_memory_l1_1_6_handle.GetSymbolAddress("VirtualAlloc2FromApp"); void* const address_MapViewOfFile3 = m_api_ms_win_core_memory_l1_1_6_handle.GetSymbolAddress("MapViewOfFile3FromApp"); - if (address_VirtualAlloc2 && address_MapViewOfFile3) + void* const address_UnmapViewOfFileEx = m_kernel32_handle.GetSymbolAddress("UnmapViewOfFileEx"); + if (address_VirtualAlloc2 && address_MapViewOfFile3 && address_UnmapViewOfFileEx) { m_address_VirtualAlloc2 = address_VirtualAlloc2; m_address_MapViewOfFile3 = address_MapViewOfFile3; + m_address_UnmapViewOfFileEx = address_UnmapViewOfFileEx; } else { // at least one function is not available, use legacy logic m_api_ms_win_core_memory_l1_1_6_handle.Close(); + m_kernel32_handle.Close(); } } @@ -394,7 +404,8 @@ void MemArena::UnmapFromMemoryRegion(void* view, size_t size) { if (m_api_ms_win_core_memory_l1_1_6_handle.IsOpen()) { - if (UnmapViewOfFileEx(view, MEM_PRESERVE_PLACEHOLDER)) + if (static_cast(m_address_UnmapViewOfFileEx)(view, + MEM_PRESERVE_PLACEHOLDER)) { if (!JoinRegionsAfterUnmap(view, size)) PanicAlertFmt("Joining memory region failed.");