geode/loader/dobby/source/UserMode/UnifiedInterface/platform-windows.cc
2022-07-30 19:24:03 +03:00

88 lines
2.2 KiB
C++

#include <stdio.h>
#include <windows.h>
#include "logging/logging.h"
#include "logging/check_logging.h"
#include "UnifiedInterface/platform.h"
int GetProtectionFromMemoryPermission(MemoryPermission access) {
if (kReadWriteExecute == access)
return PAGE_EXECUTE_READWRITE;
else if (kReadExecute == access)
return PAGE_EXECUTE_READ;
return 0;
}
int OSMemory::AllocPageSize() {
static int lastRet = -1;
if (lastRet == -1) {
SYSTEM_INFO si;
GetSystemInfo(&si);
lastRet = si.dwAllocationGranularity; // should be used with VirtualAlloc(MEM_RESERVE)
}
return lastRet;
}
int OSMemory::PageSize() {
static int lastRet = -1;
if (lastRet == -1) {
SYSTEM_INFO si;
GetSystemInfo(&si);
lastRet = si.dwPageSize; // should be used with VirtualAlloc(MEM_RESERVE)
}
return lastRet;
}
void *OSMemory::Allocate(void *address, int size, MemoryPermission access) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % AllocPageSize());
DCHECK_EQ(0, size % PageSize());
void *result = VirtualAlloc(address, size, MEM_COMMIT | MEM_RESERVE, PAGE_NOACCESS);
OSMemory::SetPermission(result, size, kReadWriteExecute);
if (result == nullptr)
return nullptr;
// TODO: if need align
void *aligned_base = result;
return static_cast<void *>(aligned_base);
}
// static
bool OSMemory::Free(void *address, const int size) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % PageSize());
DCHECK_EQ(0, size % PageSize());
return VirtualFree(address, size, MEM_RELEASE);
}
bool OSMemory::Release(void *address, int size) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % PageSize());
DCHECK_EQ(0, size % PageSize());
return OSMemory::Free(address, size);
}
bool OSMemory::SetPermission(void *address, int size, MemoryPermission access) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % PageSize());
DCHECK_EQ(0, size % PageSize());
int prot = GetProtectionFromMemoryPermission(access);
DWORD oldProtect;
return VirtualProtect(address, size, prot, &oldProtect);
}
// =====
void OSPrint::Print(const char *format, ...) {
va_list args;
va_start(args, format);
VPrint(format, args);
va_end(args);
}
void OSPrint::VPrint(const char *format, va_list args) {
vprintf(format, args);
}