I'm working with file mappings on Windows but having some troubles with them. First off, I have the necessity to partially map a file and setting the start and the end of it dynamically.
My code is the following:
long fiveMB = 5 * pow(2, 20);
for(int i=0;i<parts;i++){
long start = (i)*fiveMB;
long end = (i + 1)*fiveMB;
long realEnd = end;
if (roundedDim<realEnd)
realEnd = dim;
long chunkDim = realEnd - start;
LARGE_INTEGER fileMapStart.QuadPart = (start/granularity)*granularity;
LARGE_INTEGER mapViewSize.QuadPart = (start%granularity) + chunkDim;
LARGE_INTEGER fileMapSize.QuadPart = start + chunkDim;
long offset = start - fileMapStart.QuadPart;
HANDLE fileMappingH= CreateFileMapping(fileH, NULL, PAGE_READONLY, fileMapSize.HighPart, fileMapSize.LowPart, NULL);
if(fileMappingH == INVALID_HANDLE_VALUE || fileMappingH == NULL){
printf("Error mapping file: %d\n",GetLastError());
CloseHandle(fileH);
return 1;
}
char *mapView = (char *)MapViewOfFile(fileMappingH, FILE_MAP_READ, fileMapStart.HighPart, fileMapStart.LowPart, mapViewSize.QuadPart);
if ((LPVOID)mapView == NULL) {
printf("Error mapView: %d\n", GetLastError());
CloseHandle(fileMappingH);
CloseHandle(file);
return 1;
}
mapView += offset;
/* doing all the stuff */
UnmapViewOfFile((LPVOID)mapView);
CloseHandle(fileMappingH);
}
As far as I know, only MapViewOfFile requires the starting byte to be aligned with the system granularity, so I didn't bother to fix the maximum file mapping size for that.
I tried this code on a 1448 KB file (printing out dim I get 1482159 bytes) while calculating the available memory via GlobalMemoryStatusEx(&memstatus) and memstatus.ullAvailVirtual I get 2092208128 bytes but still stuck on having the CreateFileMapping call failed and with error code 8, ERROR_NOT_ENOUGH_MEMORY.
I also tried calling CreateFileMapping(fileH, NULL, PAGE_READONLY, 0, 0, NULL) to memory map the whole file, but instead there were problems on MapViewOfFile, error 5, ERROR_ACCESS_DENIED.
I don't understand what I'm doing wrong here, since I successfully did it with mmap on a Linux version of the same project.
Thanks anyone who may help.
EDITS:
c was a leftover, I actually meant i
added UnmapViewOfFile and CloseHandle calls
CreateFileMappingin loop - this is design error. you need call this only once. at second on errorCreateFileMappingreturn 0 but notINVALID_HANDLE_VALUE- no sense check it forINVALID_HANDLE_VALUE- RbMmERROR_NOT_ENOUGH_MEMORY- several ntstatus codes is converted to this error. so here lost on win32 layer. need callRtlGetLastNtStatus()- may be you got for exampleSTATUS_SECTION_TOO_BIG- this mean that you set size for section more than file size and because you usePAGE_READONLYfile can not be extended - RbMmMapViewOfFilecall; so if you know which is the right file offset and how many bytes you want to check from there on, you simply do that by correctly specifying the last parameter forMapViewOfFile, which in my code ismapViewSize.QuadPart. Here you can see the whole code, link to the peculiarMapViewOfFilefunction call - Emanuele GionaCreateFileMappingyou have to put the whole file size; in order to examine your 3 bytes at a given offset has to be specified throughMapViewOfFile: be aware that each size involved in such calls has to be aligned with the filesystem granularity! So if you want to read those 3 bytes, you have to map the a chunk of file which correctly starts at the expected granularity, with 3 bytes size and then take the offset into account to localize such bytes - Emanuele Giona