/* */ #include #include #include #define MAP_TO_LOCAL_FILE 1 // set to 1 to map against a local "mappingFile" NON-paging file, set to 0 for map against paging file, specified on value of INVALID_HANDLE_VALUE #define MAP_USE_LARGE_PAGES 0 // set to 1 to include LARGE page support, set to 0 exclude such // so my local testing has success on MAP_TO_LOCAL_FILE 1 and 0 // the use of enabling large page (MAP_USE_LARGE_PAGES 1) always result in not success // seems like according to https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga // that if you intend to use SEC_LARGE_PAGES then you must map thru INVALID_HANDLE_VALUE (NOT a local file, must be case where MAP_TO_LOCAL_FILE is value NOT 1 // #define BUF_SIZE 65536 #define FILE_MAP_START 0 // starting point within the file of // the data to examine (135K) TCHAR szName[] = TEXT("LARGEPAGE"); TCHAR mappingFile[] = TEXT("mapping.txt"); typedef int(*GETLARGEPAGEMINIMUM)(void); void DisplayError(const wchar_t* 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(const wchar_t* 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()); } int _tmain(void) { SYSTEM_INFO SysInfo; // system information; used to get granularity DWORD dwFileSize; // temporary storage for file sizes DWORD dwSysGran; // system allocation granularity DWORD dwFileMapStart; // where to start the file map view DWORD dwMapViewSize; // the size of the view DWORD dwFileMapSize; // size of the file mapping DWORD dBytesWritten; // number of bytes written int i; // loop counter int iData; // on success contains the first int of data int iViewDelta; // the offset into the view where the data shows up HANDLE hMapFile; HANDLE hFileHandle; TCHAR * lpcTheFile; 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 = (6 * (*pGetLargePageMinimum)()); // multiply by 6 _tprintf(TEXT("Page Size: %u\n"), size); lpcTheFile = mappingFile; #if MAP_TO_LOCAL_FILE != 0 // here where local mapping file is created hFileHandle = CreateFile(lpcTheFile, GENERIC_READ | GENERIC_WRITE, // must create with GENERIC_READ and GENERIC_WRITE 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFileHandle == INVALID_HANDLE_VALUE) { _tprintf(TEXT("hFile is NULL\n")); _tprintf(TEXT("Target file is %s\n"), lpcTheFile); return 4; } #endif // Get the system allocation granularity. GetSystemInfo(&SysInfo); dwSysGran = SysInfo.dwAllocationGranularity; // Now calculate a few variables. Calculate the file offsets as // 64-bit values, and then get the low-order 32 bits for the // function calls. // To calculate where to start the file mapping, round down the // offset of the data into the file to the nearest multiple of the // system allocation granularity. dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran; _tprintf(TEXT("The file map view starts at %ld bytes into the file.\n"), dwFileMapStart); // Calculate the size of the file mapping view. dwMapViewSize = (FILE_MAP_START % dwSysGran) + size; // BUFFSIZE; _tprintf(TEXT("The file map view is %ld bytes large.\n"), dwMapViewSize); // How large will the file mapping object be? dwFileMapSize = FILE_MAP_START + size; // BUFFSIZE; _tprintf(TEXT("The file mapping object is %ld bytes large.\n"), dwFileMapSize); // The data of interest isn't at the beginning of the // view, so determine how far into the view to set the pointer. iViewDelta = FILE_MAP_START - dwFileMapStart; _tprintf(TEXT("The data is %d bytes into the view.\n"), iViewDelta); // Now write a file with data suitable for experimentation. This // provides unique int (4-byte) offsets in the file for easy visual // inspection. Note that this code does not check for storage // medium overflow or other errors, which production code should // do. Because an int is 4 bytes, the value at the pointer to the // data should be one quarter of the desired offset into the file // you need to calc number of dwSysGran in dwMapViewSize and then spin a loop for that count // so there is an outer loop. the loop for dwSysGran stays int writeCount = (dwMapViewSize / dwSysGran); #if MAP_TO_LOCAL_FILE != 0 for (int granularityCount = 0; granularityCount < writeCount; granularityCount++) { for (i = 0; i < (int)dwSysGran; i++) { WriteFile(hFileHandle, &i, sizeof(i), &dBytesWritten, NULL); } } // Verify that the correct file size was written. dwFileSize = GetFileSize(hFileHandle, NULL); _tprintf(TEXT("hFile size: %10d\n"), dwFileSize); #endif Privilege(TEXT("SeLockMemoryPrivilege"), TRUE); #if MAP_TO_LOCAL_FILE == 0 #if MAP_USE_LARGE_PAGES == 1 hMapFile = CreateFileMapping( /* hFileHandle */ INVALID_HANDLE_VALUE, // use paging file NULL, // default security PAGE_READWRITE | SEC_COMMIT | SEC_LARGE_PAGES , 0, // max. object size dwFileMapSize /* size */, // buffer size /* NULL */ szName ); // name of mapping object #else hMapFile = CreateFileMapping( /* hFileHandle */ INVALID_HANDLE_VALUE, // use paging file NULL, // default security PAGE_READWRITE , // seems inclusion of any business with respect to _LARGE_PAGES result in handle of 0x0 and or not success 0, // max. object size dwFileMapSize /* size */, // buffer size /* NULL */ szName ); // name of mapping object #endif #else // mapping via local mapping handle - do not specify any LARGE_PAGE business.... hMapFile = CreateFileMapping( hFileHandle , // use local file file NULL, // default security PAGE_READWRITE /* | SEC_COMMIT | SEC_LARGE_PAGES */ , // <--- any inclusion of these result in 0x0 handle // NOTE NOTE NOTE NOTE // Enables large pages to be used for file mapping objects that are backed by the operating system paging file (the hfile parameter is INVALID_HANDLE_VALUE). // This attribute is not supported for file mapping objects that are backed by executable image files or data files (the hFile parameter is a handle to an executable image or data file). // NOTE NOTE NOTE NOTE // reference: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga 0, // size high max. object size dwFileMapSize /* size */, // size low NULL /* szName */ ); // name of mapping object #endif if (hMapFile == NULL) DisplayError(TEXT("CreateFileMapping"), GetLastError()); else _tprintf(TEXT("File mapping object successfully created.\n")); Privilege(TEXT("SeLockMemoryPrivilege"), FALSE); long whatisme = FILE_MAP_ALL_ACCESS; #if MAP_USE_LARGE_PAGES == 1 pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS | FILE_MAP_LARGE_PAGES, // read/write permission // <--- any inclusion of these result in 0x0 handle 0, dwFileMapStart /* 0 */, dwMapViewSize /* BUF_SIZE */ ); #else pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS , // read/write permission 0, dwFileMapStart /* 0 */, dwMapViewSize /* BUF_SIZE */); #endif FreeLibrary(hDll); 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); }