Creating a File Mapping Using Large Pages
The following example uses the CreateFileMapping function with the SEC_LARGE_PAGES flag to use large pages. It requires Windows Server 2003 with Service Pack 1 (SP1) or later.
The buffer must be large enough to contain the minimum size of a large page. This value is obtained using the GetLargePageMinimum function. This feature also requires the "SeLockMemoryPrivilege" privilege.
#include <windows.h> #include <tchar.h> #include <stdio.h> #define BUF_SIZE 65536 TCHAR szName[]=TEXT("LARGEPAGE"); typedef int (*GETLARGEPAGEMINIMUM)(void); void DisplayError(TCHAR* pszAPI, DWORD dwError) { LPVOID lpvMessageBuffer; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpvMessageBuffer, 0, NULL); //... now display this string _tprintf(TEXT("ERROR: API = %s\n"), pszAPI); _tprintf(TEXT(" error code = %d\n"), dwError); _tprintf(TEXT(" message = %s\n"), lpvMessageBuffer); // Free the buffer allocated by the system LocalFree(lpvMessageBuffer); ExitProcess(GetLastError()); } void Privilege(TCHAR* pszPrivilege, BOOL bEnable) { HANDLE hToken; TOKEN_PRIVILEGES tp; BOOL status; DWORD error; // open process token if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) DisplayError(TEXT("OpenProcessToken"), GetLastError()); // get the luid if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid)) DisplayError(TEXT("LookupPrivilegeValue"), GetLastError()); tp.PrivilegeCount = 1; // enable or disable privilege if (bEnable) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // enable or disable privilege status = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); // It is possible for AdjustTokenPrivileges to return TRUE and still not succeed. // So always check for the last error value. error = GetLastError(); if (!status || (error != ERROR_SUCCESS)) DisplayError(TEXT("AdjustTokenPrivileges"), GetLastError()); // close the handle if (!CloseHandle(hToken)) DisplayError(TEXT("CloseHandle"), GetLastError()); } void _tmain(void) { HANDLE hMapFile; LPCTSTR pBuf; DWORD size; GETLARGEPAGEMINIMUM pGetLargePageMinimum; HINSTANCE hDll; // call succeeds only on Windows Server 2003 SP1 or later hDll = LoadLibrary(TEXT("kernel32.dll")); if (hDll == NULL) DisplayError(TEXT("LoadLibrary"), GetLastError()); pGetLargePageMinimum = (GETLARGEPAGEMINIMUM)GetProcAddress(hDll, "GetLargePageMinimum"); if (pGetLargePageMinimum == NULL) DisplayError(TEXT("GetProcAddress"), GetLastError()); size = (*pGetLargePageMinimum)(); FreeLibrary(hDll); _tprintf(TEXT("Page Size: %u\n"), size); Privilege(TEXT("SeLockMemoryPrivilege"), TRUE); hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security PAGE_READWRITE | SEC_COMMIT | SEC_LARGE_PAGES, 0, // max. object size size, // buffer size szName); // name of mapping object if (hMapFile == NULL) DisplayError(TEXT("CreateFileMapping"), GetLastError()); else _tprintf(TEXT("File mapping object successfulyl created.\n")); Privilege(TEXT("SeLockMemoryPrivilege"), FALSE); pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) DisplayError(TEXT("MapViewOfFile"), GetLastError()); else _tprintf(TEXT("View of file successfully mapped.\n")); // do nothing, clean up an exit UnmapViewOfFile(pBuf); CloseHandle(hMapFile); }
Related topics
Send comments about this topic to Microsoft
Build date: 2/7/2012
The example given here contains, at least, incorrect error handling code. Following code:
// enable or disable privilege
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
DisplayError(TEXT("AdjustTokenPrivileges"), GetLastError());
should be replaced with something like:
// enable or disable privilege
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
DisplayError(TEXT("AdjustTokenPrivileges"), GetLastError());
DWORD dwLasError = GetLastError();
if (dwLasError != ERROR_SUCCESS)
DisplayError(TEXT("AdjustTokenPrivileges"), dwLasError);
Also, note that AdjustTokenPrivileges does not grant new privileges to a user, it just enables/disables already granted ones. So, in order to grant the user SeLockMemoryPrivilege, you would have to use either gpedit.msc or programmatically something like that: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q132958
By default, SeLockMemoryPrivilege is not granted to any user, don't forget that you will have either to reboot your server after granting the privilege if your application is running under system account (Local Service or Network Service) or logoff/logon if your app is running under dedicated account.
- 8/27/2008
- Alexey Kamenev
- 1/15/2009
- Alexey Kamenev