MemArena: Load UnmapViewOfFileEx dynamically to restore Windows 7 support.

This commit is contained in:
Admiral H. Curtiss 2022-02-14 21:54:21 +01:00
parent 3a4de2b306
commit 4a9553bf6d
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 16 additions and 3 deletions

View File

@ -107,7 +107,9 @@ private:
std::vector<WindowsMemoryRegion> m_regions; std::vector<WindowsMemoryRegion> m_regions;
void* m_reserved_region = nullptr; void* m_reserved_region = nullptr;
void* m_memory_handle = nullptr; void* m_memory_handle = nullptr;
Common::DynamicLibrary m_kernel32_handle;
Common::DynamicLibrary m_api_ms_win_core_memory_l1_1_6_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_VirtualAlloc2 = nullptr;
void* m_address_MapViewOfFile3 = nullptr; void* m_address_MapViewOfFile3 = nullptr;
#else #else

View File

@ -29,6 +29,8 @@ using PMapViewOfFile3 = PVOID(WINAPI*)(HANDLE FileMapping, HANDLE Process, PVOID
MEM_EXTENDED_PARAMETER* ExtendedParameters, MEM_EXTENDED_PARAMETER* ExtendedParameters,
ULONG ParameterCount); ULONG ParameterCount);
using PUnmapViewOfFileEx = BOOL(WINAPI*)(PVOID BaseAddress, ULONG UnmapFlags);
using PIsApiSetImplemented = BOOL(APIENTRY*)(PCSTR Contract); using PIsApiSetImplemented = BOOL(APIENTRY*)(PCSTR Contract);
namespace Common namespace Common
@ -62,22 +64,30 @@ MemArena::MemArena()
return; return;
m_api_ms_win_core_memory_l1_1_6_handle.Open("api-ms-win-core-memory-l1-1-6.dll"); 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; return;
}
void* const address_VirtualAlloc2 = void* const address_VirtualAlloc2 =
m_api_ms_win_core_memory_l1_1_6_handle.GetSymbolAddress("VirtualAlloc2FromApp"); m_api_ms_win_core_memory_l1_1_6_handle.GetSymbolAddress("VirtualAlloc2FromApp");
void* const address_MapViewOfFile3 = void* const address_MapViewOfFile3 =
m_api_ms_win_core_memory_l1_1_6_handle.GetSymbolAddress("MapViewOfFile3FromApp"); 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_VirtualAlloc2 = address_VirtualAlloc2;
m_address_MapViewOfFile3 = address_MapViewOfFile3; m_address_MapViewOfFile3 = address_MapViewOfFile3;
m_address_UnmapViewOfFileEx = address_UnmapViewOfFileEx;
} }
else else
{ {
// at least one function is not available, use legacy logic // at least one function is not available, use legacy logic
m_api_ms_win_core_memory_l1_1_6_handle.Close(); 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 (m_api_ms_win_core_memory_l1_1_6_handle.IsOpen())
{ {
if (UnmapViewOfFileEx(view, MEM_PRESERVE_PLACEHOLDER)) if (static_cast<PUnmapViewOfFileEx>(m_address_UnmapViewOfFileEx)(view,
MEM_PRESERVE_PLACEHOLDER))
{ {
if (!JoinRegionsAfterUnmap(view, size)) if (!JoinRegionsAfterUnmap(view, size))
PanicAlertFmt("Joining memory region failed."); PanicAlertFmt("Joining memory region failed.");