#pragma region OS
#pragma warning(push)
#pragma warning(disable: 4820)
#pragma comment(lib, "Kernel32.lib")
#pragma comment(lib, "Advapi32.lib")
#define MS_INVALID_HANDLE_VALUE            ((MS_HANDLE)(S8)-1)
#define MS_ANYSIZE_ARRAY                   1
#define MS_MEM_COMMIT                      0x00001000
#define MS_MEM_RESERVE                     0x00002000
#define MS_MEM_RELEASE                     0x00008000
#define MS_MEM_LARGE_PAGES                 0x20000000
#define MS_PAGE_READWRITE                  0x04
#define MS_TOKEN_ADJUST_PRIVILEGES         (0x0020)
#define MS_SE_PRIVILEGE_ENABLED            (0x00000002L)
#define MS_TOKEN_QUERY                     (0x0008)
#define MS__TEXT(quote)                    L ## quote      // r_winnt
#define MS_TEXT(quote)                     MS__TEXT(quote)   // r_winnt
#define MS_SE_LOCK_MEMORY_NAME             MS_TEXT("SeLockMemoryPrivilege")
typedef int              MS_BOOL;
typedef unsigned long    MS_DWORD;
typedef MS_DWORD*        MS_PDWORD;
typedef void*            MS_HANDLE;
typedef MS_HANDLE*       MS_PHANDLE;
typedef long             MS_LONG;
typedef S8               MS_LONGLONG;
typedef char const*      MS_LPCSTR;
typedef unsigned short*  MS_LPWSTR, *MS_PWSTR;
typedef void*            MS_LPVOID;
typedef MS_DWORD*        MS_LPDWORD;
typedef U8               MS_ULONG_PTR, *MS_PULONG_PTR;
typedef void const*      MS_LPCVOID;
typedef struct MS_SECURITY_ATTRIBUTES *MS_PSECURITY_ATTRIBUTES, *MS_LPSECURITY_ATTRIBUTES;
typedef struct MS_OVERLAPPED          *MS_LPOVERLAPPED;
typedef def_union(MS_LARGE_INTEGER)        { struct { MS_DWORD LowPart; MS_LONG HighPart; } _; struct { MS_DWORD LowPart; MS_LONG HighPart; } u; MS_LONGLONG QuadPart; };
typedef def_struct(MS_FILE)                { void* _Placeholder; };
typedef def_struct(MS_SECURITY_ATTRIBUTES) { MS_DWORD  nLength; A4_B1 _PAD_; MS_LPVOID lpSecurityDescriptor; MS_BOOL bInheritHandle; };
typedef def_struct(MS_OVERLAPPED)          { MS_ULONG_PTR Internal; MS_ULONG_PTR InternalHigh; union { struct { MS_DWORD Offset; MS_DWORD OffsetHigh; } _; void* Pointer; } _; MS_HANDLE  hEvent; };
typedef struct MS_LUID*                    MS_PLUID;
typedef struct MS_LUID_AND_ATTRIBUTES*     MS_PLUID_AND_ATTRIBUTES;
typedef struct MS_TOKEN_PRIVILEGES*        MS_PTOKEN_PRIVILEGES;
typedef def_struct(MS_LUID)                { MS_DWORD LowPart;        MS_LONG HighPart; };
typedef def_struct(MS_LUID_AND_ATTRIBUTES) { MS_LUID  Luid;           MS_DWORD Attributes; };
typedef def_struct(MS_TOKEN_PRIVILEGES)    { MS_DWORD PrivilegeCount; MS_LUID_AND_ATTRIBUTES Privileges[MS_ANYSIZE_ARRAY]; };
WinAPI MS_BOOL   CloseHandle(MS_HANDLE hObject);
WinAPI MS_BOOL   AdjustTokenPrivileges(MS_HANDLE TokenHandle, MS_BOOL DisableAllPrivileges, MS_PTOKEN_PRIVILEGES NewState, MS_DWORD BufferLength, MS_PTOKEN_PRIVILEGES PreviousState, MS_PDWORD ReturnLength);
WinAPI MS_HANDLE GetCurrentProcess(void);
WinAPI U8        GetLargePageMinimum(void);
WinAPI MS_BOOL   LookupPrivilegeValueW(MS_LPWSTR lpSystemName, MS_LPWSTR lpName, MS_PLUID lpLuid);
WinAPI MS_BOOL   OpenProcessToken(MS_HANDLE ProcessHandle, MS_DWORD DesiredAccess, MS_PHANDLE TokenHandle);
WinAPI MS_LPVOID VirtualAlloc(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD flAllocationType, MS_DWORD flProtect);
WinAPI MS_BOOL   VirtualFree (MS_LPVOID lpAddress, U8 dwSize, MS_DWORD dwFreeType);
#pragma warning(pop)

typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; };
global OS_Windows_State os__windows_info;

IA_ OS_SystemInfo* os_system_info(void) { return & os__windows_info.system_info; }
I_
void os__enable_large_pages(void) {
	MS_HANDLE token;
	if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
	{
		MS_LUID luid;
		if (LookupPrivilegeValueW(0, MS_SE_LOCK_MEMORY_NAME, &luid))
		{
			MS_TOKEN_PRIVILEGES priv;
			priv.PrivilegeCount           = 1;
			priv.Privileges[0].Luid       = luid;
			priv.Privileges[0].Attributes = MS_SE_PRIVILEGE_ENABLED;
			AdjustTokenPrivileges(token, 0, & priv, size_of(priv), 0, 0);
		}
		CloseHandle(token);
	}
}
I_
void os_init(void) {
	os__enable_large_pages();
	OS_SystemInfo*R_ info = & os__windows_info.system_info;
	info->target_page_size = (U8)GetLargePageMinimum();
}
// TODO(Ed): Large pages disabled for now... (not failing gracefully)
IA_ U8 os__vmem_reserve(U8 size, Opts_vmem*R_ opts) {
	assert(opts != nullptr);
	void*R_ result = VirtualAlloc(cast(void*R_, opts->base_addr), size
		,	MS_MEM_RESERVE
		// |MS_MEM_COMMIT|(opts->no_large_pages == false ? MS_MEM_LARGE_PAGES : 0)
		,	MS_PAGE_READWRITE
	);
	return u8_(result);
}
IA_ B4 os__vmem_commit(U8 vm, U8 size, Opts_vmem*R_ opts) {
	assert(opts != nullptr);
	// if (opts->no_large_pages == false ) { return 1; }
	B4 result = (VirtualAlloc(cast(MS_LPVOID, vm), size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
	return result;
}
I_ void  os_vmem_release(U8 vm, U8 size) { VirtualFree(cast(MS_LPVOID, vm), 0, MS_MEM_RELEASE); }
#pragma endregion OS
