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;

    // 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
    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
        DisplayError(TEXT("AdjustTokenPrivileges"), GetLastError());

    // close the handle
    if (!CloseHandle(hToken))
        DisplayError(TEXT("CloseHandle"), GetLastError());
}

void main(void)
{
    HANDLE hMapFile;
    LPCTSTR pBuf;
    SIZE_T 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);

    printf("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
        printf("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
        printf("View of file successfully mapped.\n");
	
    // do nothing, clean up an exit
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);
}

See Also

Creating a File Mapping Object
Large Page Support

Send comments about this topic to Microsoft

Build date: 11/19/2009

Tags : largepage


Community Content

Alexey Kamenev
Error handling and other issues in the example

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.

Tags :

Page view tracker