- #else
-
- HANDLE hProcessToken { };
- LUID luid { };
- void* mem = nullptr;
-
- const size_t largePageSize = GetLargePageMinimum();
- if (!largePageSize)
- return nullptr;
-
- // We need SeLockMemoryPrivilege, so try to enable it for the process
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcessToken))
- return nullptr;
-
- if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &luid))
- {
- TOKEN_PRIVILEGES tp { };
- TOKEN_PRIVILEGES prevTp { };
- DWORD prevTpLen = 0;
-
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-
- // Try to enable SeLockMemoryPrivilege. Note that even if AdjustTokenPrivileges() succeeds,
- // we still need to query GetLastError() to ensure that the privileges were actually obtained.
- if (AdjustTokenPrivileges(
- hProcessToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &prevTp, &prevTpLen) &&
- GetLastError() == ERROR_SUCCESS)
- {
- // Round up size to full pages and allocate
- allocSize = (allocSize + largePageSize - 1) & ~size_t(largePageSize - 1);
- mem = VirtualAlloc(
- nullptr, allocSize, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
-
- // Privilege no longer needed, restore previous state
- AdjustTokenPrivileges(hProcessToken, FALSE, &prevTp, 0, nullptr, nullptr);
- }
- }
-
- CloseHandle(hProcessToken);
-
- return mem;
-
- #endif
+ #else
+
+ HANDLE hProcessToken{};
+ LUID luid{};
+ void* mem = nullptr;
+
+ const size_t largePageSize = GetLargePageMinimum();
+ if (!largePageSize)
+ return nullptr;
+
+ // Dynamically link OpenProcessToken, LookupPrivilegeValue and AdjustTokenPrivileges
+
+ HMODULE hAdvapi32 = GetModuleHandle(TEXT("advapi32.dll"));
+
+ if (!hAdvapi32)
+ hAdvapi32 = LoadLibrary(TEXT("advapi32.dll"));
+
+ auto fun6 = fun6_t((void (*)()) GetProcAddress(hAdvapi32, "OpenProcessToken"));
+ if (!fun6)
+ return nullptr;
+ auto fun7 = fun7_t((void (*)()) GetProcAddress(hAdvapi32, "LookupPrivilegeValueA"));
+ if (!fun7)
+ return nullptr;
+ auto fun8 = fun8_t((void (*)()) GetProcAddress(hAdvapi32, "AdjustTokenPrivileges"));
+ if (!fun8)
+ return nullptr;
+
+ // We need SeLockMemoryPrivilege, so try to enable it for the process
+ if (!fun6( // OpenProcessToken()
+ GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcessToken))
+ return nullptr;
+
+ if (fun7( // LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &luid)
+ nullptr, "SeLockMemoryPrivilege", &luid))
+ {
+ TOKEN_PRIVILEGES tp{};
+ TOKEN_PRIVILEGES prevTp{};
+ DWORD prevTpLen = 0;
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ // Try to enable SeLockMemoryPrivilege. Note that even if AdjustTokenPrivileges() succeeds,
+ // we still need to query GetLastError() to ensure that the privileges were actually obtained.
+ if (fun8( // AdjustTokenPrivileges()
+ hProcessToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &prevTp, &prevTpLen)
+ && GetLastError() == ERROR_SUCCESS)
+ {
+ // Round up size to full pages and allocate
+ allocSize = (allocSize + largePageSize - 1) & ~size_t(largePageSize - 1);
+ mem = VirtualAlloc(nullptr, allocSize, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
+ PAGE_READWRITE);
+
+ // Privilege no longer needed, restore previous state
+ fun8( // AdjustTokenPrivileges ()
+ hProcessToken, FALSE, &prevTp, 0, nullptr, nullptr);
+ }
+ }
+
+ CloseHandle(hProcessToken);
+
+ return mem;
+
+ #endif