VirtualProtect platform abstraction.

This commit is contained in:
Ben Vanik
2015-07-15 18:20:05 -07:00
parent 99104a25a8
commit 58c3a1ba79
11 changed files with 155 additions and 56 deletions

View File

@@ -18,6 +18,21 @@
#include "xenia/base/byte_order.h"
namespace xe {
namespace memory {
// Returns the native page size of the system, in bytes.
size_t page_size();
enum class PageAccess {
kNoAccess = 0,
kReadOnly,
kReadWrite,
};
// Sets the access rights for the given block of memory and returns the previous
// access rights. Both base_address and length will be adjusted to page_size().
bool Protect(void* base_address, size_t length, PageAccess access,
PageAccess* out_old_access);
inline size_t hash_combine(size_t seed) { return seed; }
@@ -28,6 +43,10 @@ size_t hash_combine(size_t seed, const T& v, const Ts&... vs) {
return hash_combine(seed, vs...);
}
} // namespace memory
// TODO(benvanik): move into xe::memory::
constexpr void* low_address(void* address) {
return (void*)(uint64_t(address) & 0xFFFFFFFF);
}

View File

@@ -0,0 +1,73 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/memory.h"
#include "xenia/base/platform_win.h"
namespace xe {
namespace memory {
size_t page_size() {
static size_t value = 0;
if (!value) {
SYSTEM_INFO si;
GetSystemInfo(&si);
value = si.dwAllocationGranularity;
}
return value;
}
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 old_protect = 0;
BOOL result = VirtualProtect(base_address, length, new_protect, &old_protect);
if (result) {
if (out_old_access) {
switch (old_protect) {
case PAGE_NOACCESS:
*out_old_access = PageAccess::kNoAccess;
break;
case PAGE_READONLY:
*out_old_access = PageAccess::kReadOnly;
break;
case PAGE_READWRITE:
*out_old_access = PageAccess::kReadWrite;
break;
default:
assert_unhandled_case(access);
break;
}
}
return true;
} else {
return false;
}
}
} // namespace memory
} // namespace xe

View File

@@ -76,9 +76,6 @@ const size_t max_path = 1024; // PATH_MAX
// Launches a web browser to the given URL.
void LaunchBrowser(const char* url);
// Returns the native page size of the system, in bytes.
size_t page_size();
} // namespace xe
#endif // XENIA_BASE_PLATFORM_H_

View File

@@ -11,16 +11,6 @@
namespace xe {
size_t page_size() {
static size_t value = 0;
if (!value) {
SYSTEM_INFO si;
GetSystemInfo(&si);
value = si.dwAllocationGranularity;
}
return value;
}
void LaunchBrowser(const char* url) {
ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}