Activer les grandes pages dans Windows par programmation

Je veux utiliser de grandes pages dans mon application comme ceci:

VirtualAlloc(NULL, n_bytes, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE, PAGE_READWRITE); 

Je prévois d’activer les grandes pages pour l’ utilisateur actuel lors de l’installation, tout en disposant de droits d’administrateur élevés . Quelqu’un at-il un code pour activer de grandes pages par programme?

Je poste ce que j’ai rassemblé.

L’idée générale:

  1. Activer les grandes pages pour le compte d’utilisateur actuel. (Nécessite des droits d’administrateur).
  2. Activer les grandes pages pour le jeton de processus actuel. (Nécessite des droits d’administrateur).
  3. Allouez la mémoire (granulaire à grande page, 2 Mo, en fait).

Si vous avez correctement désactivé le contrôle de compte d’utilisateur , vous devez exécuter l’ étape 1 une seule fois avec les droits d’administrateur. Si vous avez activé le contrôle de compte d’utilisateur, vous devez toujours tout exécuter avec des droits d’administrateur.

 #define UNICODE #define _UNICODE #include  #include  #include  #include  void InitLsaSsortingng(PLSA_UNICODE_STRING LsaSsortingng, LPWSTR Ssortingng) { DWORD SsortingngLength; if (Ssortingng == NULL) { LsaSsortingng->Buffer = NULL; LsaSsortingng->Length = 0; LsaSsortingng->MaximumLength = 0; return; } SsortingngLength = wcslen(Ssortingng); LsaSsortingng->Buffer = Ssortingng; LsaSsortingng->Length = (USHORT)SsortingngLength * sizeof(WCHAR); LsaSsortingng->MaximumLength = (USHORT)(SsortingngLength + 1) * sizeof(WCHAR); } NTSTATUS OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle) { LSA_OBJECT_ATTRIBUTES ObjectAtsortingbutes; LSA_UNICODE_STRING ServerSsortingng; PLSA_UNICODE_STRING Server = NULL; // // Always initialize the object atsortingbutes to all zeroes. // ZeroMemory(&ObjectAtsortingbutes, sizeof(ObjectAtsortingbutes)); if (ServerName != NULL) { // // Make a LSA_UNICODE_STRING out of the LPWSTR passed in // InitLsaSsortingng(&ServerSsortingng, ServerName); Server = &ServerSsortingng; } // // Attempt to open the policy. // return LsaOpenPolicy( Server, &ObjectAtsortingbutes, DesiredAccess, PolicyHandle ); } NTSTATUS SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName, BOOL bEnable) { LSA_UNICODE_STRING PrivilegeSsortingng; // // Create a LSA_UNICODE_STRING for the privilege name. // InitLsaSsortingng(&PrivilegeSsortingng, PrivilegeName); // // grant or revoke the privilege, accordingly // if (bEnable) { return LsaAddAccountRights( PolicyHandle, // open policy handle AccountSid, // target SID &PrivilegeSsortingng, // privileges 1 // privilege count ); } else { return LsaRemoveAccountRights( PolicyHandle, // open policy handle AccountSid, // target SID FALSE, // do not disable all rights &PrivilegeSsortingng, // privileges 1 // privilege count ); } } void main() { HANDLE hToken = NULL; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { applog(LOG_INFO, "OpenProcessToken failed. GetLastError returned: %d\n", GetLastError()); return -1; } DWORD dwBufferSize = 0; // Probe the buffer size reqired for PTOKEN_USER structure if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwBufferSize) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { applog(LOG_INFO, "GetTokenInformation failed. GetLastError returned: %d\n", GetLastError()); // Cleanup CloseHandle(hToken); hToken = NULL; return -1; } PTOKEN_USER pTokenUser = (PTOKEN_USER) malloc(dwBufferSize); // Resortingeve the token information in a TOKEN_USER structure if (!GetTokenInformation( hToken, TokenUser, pTokenUser, dwBufferSize, &dwBufferSize)) { applog(LOG_INFO, "GetTokenInformation failed. GetLastError returned: %d\n", GetLastError()); // Cleanup CloseHandle(hToken); hToken = NULL; return -1; } // Print SID ssortingng LPWSTR strsid; ConvertSidToSsortingngSid(pTokenUser->User.Sid, &strsid); applog(LOG_INFO, "User SID: %S\n", strsid); // Cleanup CloseHandle(hToken); hToken = NULL; NTSTATUS status; LSA_HANDLE policyHandle; if (status = OpenPolicy(NULL, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &policyHandle)) { applog(LOG_INFO, "OpenPolicy %d", status); } // Add new privelege to the account if (status = SetPrivilegeOnAccount(policyHandle, pTokenUser->User.Sid, SE_LOCK_MEMORY_NAME, TRUE)) { applog(LOG_INFO, "OpenPSetPrivilegeOnAccountolicy %d", status); } // Enable this priveledge for the current process hToken = NULL; TOKEN_PRIVILEGES tp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { applog(LOG_INFO, "OpenProcessToken #2 failed. GetLastError returned: %d\n", GetLastError()); return -1; } tp.PrivilegeCount = 1; tp.Privileges[0].Atsortingbutes = SE_PRIVILEGE_ENABLED; if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &tp.Privileges[0].Luid)) { applog(LOG_INFO, "LookupPrivilegeValue failed. GetLastError returned: %d\n", GetLastError()); return -1; } BOOL result = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); DWORD error = GetLastError(); if (!result || (error != ERROR_SUCCESS)) { applog(LOG_INFO, "AdjustTokenPrivileges failed. GetLastError returned: %d\n", error); return -1; } // Cleanup CloseHandle(hToken); hToken = NULL; SIZE_T pageSize = GetLargePageMinimum(); // Finally allocate the memory char *largeBuffer = VirtualAlloc(NULL, pageSize * N_PAGES_TO_ALLOC, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); if (largeBuffer) { applog(LOG_INFO, "VirtualAlloc failed, error 0x%x", GetLastError()); } }