1// Windows/MemoryLock.cpp 2 3#include "StdAfx.h" 4 5#include "../../C/CpuArch.h" 6 7#include "MemoryLock.h" 8 9namespace NWindows { 10namespace NSecurity { 11 12#ifndef UNDER_CE 13 14#ifdef _UNICODE 15#define MY_FUNC_SELECT(f) :: f 16#else 17#define MY_FUNC_SELECT(f) my_ ## f 18extern "C" { 19typedef BOOL (WINAPI * Func_OpenProcessToken)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle); 20typedef BOOL (WINAPI * Func_LookupPrivilegeValue)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid); 21typedef BOOL (WINAPI * Func_AdjustTokenPrivileges)(HANDLE TokenHandle, BOOL DisableAllPrivileges, 22 PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength); 23} 24 25#define GET_PROC_ADDR(fff, name) \ 26 const Func_ ## fff my_ ## fff = Z7_GET_PROC_ADDRESS( \ 27 Func_ ## fff, hModule, name); 28#endif 29 30bool EnablePrivilege(LPCTSTR privilegeName, bool enable) 31{ 32 bool res = false; 33 34 #ifndef _UNICODE 35 36 const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); 37 if (!hModule) 38 return false; 39 40 GET_PROC_ADDR( 41 OpenProcessToken, 42 "OpenProcessToken") 43 GET_PROC_ADDR( 44 LookupPrivilegeValue, 45 "LookupPrivilegeValueA") 46 GET_PROC_ADDR( 47 AdjustTokenPrivileges, 48 "AdjustTokenPrivileges") 49 50 if (my_OpenProcessToken && 51 my_AdjustTokenPrivileges && 52 my_LookupPrivilegeValue) 53 54 #endif 55 56 { 57 HANDLE token; 58 if (MY_FUNC_SELECT(OpenProcessToken)(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) 59 { 60 TOKEN_PRIVILEGES tp; 61 if (MY_FUNC_SELECT(LookupPrivilegeValue)(NULL, privilegeName, &(tp.Privileges[0].Luid))) 62 { 63 tp.PrivilegeCount = 1; 64 tp.Privileges[0].Attributes = (enable ? SE_PRIVILEGE_ENABLED : 0); 65 if (MY_FUNC_SELECT(AdjustTokenPrivileges)(token, FALSE, &tp, 0, NULL, NULL)) 66 res = (GetLastError() == ERROR_SUCCESS); 67 } 68 ::CloseHandle(token); 69 } 70 } 71 72 #ifndef _UNICODE 73 74 ::FreeLibrary(hModule); 75 76 #endif 77 78 return res; 79} 80 81 82 83typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *); 84 85/* 86 We suppose that Window 10 works incorrectly with "Large Pages" at: 87 - Windows 10 1703 (15063) : incorrect allocating after VirtualFree() 88 - Windows 10 1709 (16299) : incorrect allocating after VirtualFree() 89 - Windows 10 1809 (17763) : the failures for blocks of 1 GiB and larger, 90 if CPU doesn't support 1 GB pages. 91 Windows 10 1903 (18362) probably works correctly. 92*/ 93 94unsigned Get_LargePages_RiskLevel() 95{ 96 OSVERSIONINFOEXW vi; 97 const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); 98 if (!ntdll) 99 return 0; 100 const 101 Func_RtlGetVersion func = Z7_GET_PROC_ADDRESS( 102 Func_RtlGetVersion, ntdll, 103 "RtlGetVersion"); 104 if (!func) 105 return 0; 106 func(&vi); 107 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) 108 return 0; 109 if (vi.dwMajorVersion + vi.dwMinorVersion != 10) 110 return 0; 111 if (vi.dwBuildNumber <= 16299) 112 return 1; 113 114 #ifdef MY_CPU_X86_OR_AMD64 115 if (vi.dwBuildNumber < 18362 && !CPU_IsSupported_PageGB()) 116 return 1; 117 #endif 118 119 return 0; 120} 121 122#endif 123 124}} 125