Abstraction for VirtualAlloc/VirtualFree.
This commit is contained in:
@@ -24,26 +24,69 @@ size_t page_size() {
|
||||
return value;
|
||||
}
|
||||
|
||||
DWORD ToWin32ProtectFlags(PageAccess access) {
|
||||
switch (access) {
|
||||
case PageAccess::kNoAccess:
|
||||
return PAGE_NOACCESS;
|
||||
case PageAccess::kReadOnly:
|
||||
return PAGE_READONLY;
|
||||
case PageAccess::kReadWrite:
|
||||
return PAGE_READWRITE;
|
||||
case PageAccess::kExecuteReadWrite:
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
default:
|
||||
assert_unhandled_case(access);
|
||||
return PAGE_NOACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void* AllocFixed(void* base_address, size_t length,
|
||||
AllocationType allocation_type, PageAccess access) {
|
||||
DWORD alloc_type = 0;
|
||||
switch (allocation_type) {
|
||||
case AllocationType::kReserve:
|
||||
alloc_type = MEM_RESERVE;
|
||||
break;
|
||||
case AllocationType::kCommit:
|
||||
alloc_type = MEM_COMMIT;
|
||||
break;
|
||||
case AllocationType::kReserveCommit:
|
||||
alloc_type = MEM_RESERVE | MEM_COMMIT;
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(allocation_type);
|
||||
break;
|
||||
}
|
||||
DWORD protect = ToWin32ProtectFlags(access);
|
||||
return VirtualAlloc(base_address, length, alloc_type, protect);
|
||||
}
|
||||
|
||||
bool DeallocFixed(void* base_address, size_t length,
|
||||
DeallocationType deallocation_type) {
|
||||
DWORD free_type = 0;
|
||||
switch (deallocation_type) {
|
||||
case DeallocationType::kRelease:
|
||||
free_type = MEM_RELEASE;
|
||||
break;
|
||||
case DeallocationType::kDecommit:
|
||||
free_type = MEM_DECOMMIT;
|
||||
break;
|
||||
case DeallocationType::kDecommitRelease:
|
||||
free_type = MEM_RELEASE | MEM_DECOMMIT;
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(deallocation_type);
|
||||
break;
|
||||
}
|
||||
return VirtualFree(base_address, length, free_type) ? true : false;
|
||||
}
|
||||
|
||||
bool Protect(void* base_address, size_t length, PageAccess access,
|
||||
PageAccess* out_old_access) {
|
||||
if (out_old_access) {
|
||||
*out_old_access = PageAccess::kNoAccess;
|
||||
}
|
||||
DWORD new_protect;
|
||||
switch (access) {
|
||||
case PageAccess::kNoAccess:
|
||||
new_protect = PAGE_NOACCESS;
|
||||
break;
|
||||
case PageAccess::kReadOnly:
|
||||
new_protect = PAGE_READONLY;
|
||||
break;
|
||||
case PageAccess::kReadWrite:
|
||||
new_protect = PAGE_READWRITE;
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(access);
|
||||
break;
|
||||
}
|
||||
DWORD new_protect = ToWin32ProtectFlags(access);
|
||||
DWORD old_protect = 0;
|
||||
BOOL result = VirtualProtect(base_address, length, new_protect, &old_protect);
|
||||
if (result) {
|
||||
@@ -58,6 +101,8 @@ bool Protect(void* base_address, size_t length, PageAccess access,
|
||||
case PAGE_READWRITE:
|
||||
*out_old_access = PageAccess::kReadWrite;
|
||||
break;
|
||||
case PAGE_EXECUTE_READWRITE:
|
||||
*out_old_access = PageAccess::kExecuteReadWrite;
|
||||
default:
|
||||
assert_unhandled_case(access);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user