Memory Mapped File Problem

From: Nicolas (info_at_-REMOVE-.chsoft.ch)
Date: 03/16/04


Date: Tue, 16 Mar 2004 10:15:28 +0100

Hi

I want to read a portion of a large file (50Mb+) into a memory mapped
file for fast access. Since I don't need the full file in the memory,
I'm trying to read only a portion into memory by using
MapViewOfFile(...). This doesn't work somehow, I always get an error
(GetLastError()) of 5 (ACCESS_DENIED) whenever I set the starting
offset (dwStartOffset) for MapViewOfFile to something other than 0.

Btw: Reading the whole file into memory (last two parameters of
MapViewOfFile set to zero) works without any problems, but slows down
the system a lot if the file to map is larger than the available
physical memory.

Here's the de-classified portion that does the file mapping. Maybe
someone can tell me what to do to make it work....

thanks in advance
Nicolas

--- code start ---
const BOOL CMemMapTestDlg::ReadFile()
{
  CString sFilename = "mytestfile.bin"; // file is about 50 MB

  HANDLE hFile = INVALID_HANDLE_VALUE;
  HANDLE hMapping = NULL;
  BOOL bReadOnly = TRUE;
  LPVOID lpData = NULL;
  CString sMappingName = "";
  BOOL bOpen = FALSE;
  HANDLE hMutex = NULL;
  DWORD dwLength = 0;
  LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;

  SYSTEM_INFO SysInfo;
  ZeroMemory( &SysInfo, sizeof( SYSTEM_INFO ) );
  GetSystemInfo( &SysInfo );
  const unsigned long lMaxBytesToRead =
SysInfo.dwAllocationGranularity;

  DWORD dwDesiredFileAccess = GENERIC_READ;
  if (!bReadOnly)
  {
    dwDesiredFileAccess |= GENERIC_WRITE;
  }

  DWORD dwShareMode = 0;
  //Open the real file on the file system
  hFile = CreateFile(sFilename, dwDesiredFileAccess, dwShareMode,
NULL,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
  {
    TRACE(_T("Failed in call to CreateFile, GetLastError returned
%d\n"), GetLastError());
    //UnMap();
    return FALSE;
  }

  DWORD dwFileSizeHigh=0;
  DWORD dwLength_ = GetFileSize(hFile, &dwFileSizeHigh);
  if (dwLength_ == 0xFFFFFFFF)
  {
    //There was an error calling GetFileSize
    TRACE(_T("Failed in call to GetFileSize, GetLastError returned
%d\n"), GetLastError());
    //UnMap();
    return FALSE;
  }

  //Fail if file is greater than 4GB in size
  if (dwFileSizeHigh)
  {
    //There was an error calling GetFileSize
    TRACE(_T("File size is greater than 4GB, Memory mapping this file
size will not work until CMemMapFile supports Win64 !!\n"));
    // UnMap();
    return FALSE;
  }

  //Fail if file is 0 length in size, calling CreateFileMapping on a
  //zero length file on 95/98 can cause problems
  if (dwFileSizeHigh == 0 && dwLength_ == 0)
  {
    TRACE(_T("File size is 0, not attempting to memory map the
file\n"));
    //UnMap();
    return FALSE;
  }

  //Now work out the size of the mapping we will be performing
  if (lMaxBytesToRead)
    dwLength = lMaxBytesToRead;
  else
    dwLength = dwLength_;

  //Create the file mapping object
  DWORD flProtect = (!bReadOnly) ? PAGE_READWRITE : PAGE_READONLY;

  //work out the length of the file mapping to create
  //DWORD dwLength = m_dwLength;

  hMapping = ::CreateFileMapping(hFile, lpSecurityAttributes,
flProtect, 0, dwLength, sMappingName);
  if (hMapping == NULL)
  {
    TRACE(_T("Failed in call to CreateFileMapping, GetLastError
returned %d\n"), GetLastError());
    // UnMap();
    return FALSE;
  }

  // start reading from here:
  DWORD dwStartOffset = 1 * SysInfo.dwAllocationGranularity;

  //Map the view
        DWORD dwDesiredAccess = (!bReadOnly) ? FILE_MAP_WRITE :
FILE_MAP_READ;
  lpData = MapViewOfFile(hMapping, dwDesiredAccess, 0, dwStartOffset,
dwLength);
  DWORD dwErr = GetLastError();
  //ASSERT( 0 == dwErr );

  // Create the mutex to sync access
  // hMutex = CreateMutex(lpSecurityAttributes, FALSE,
CreateMutexName());

  // data ready??
  if( NULL != lpData )
  {
    MessageBox( "success" );
    LPVOID x = lpData;
    //.... do some processing here...
  }

  

  // clean up...
  if (lpData != NULL)
        {
                FlushViewOfFile(lpData, 0);
                UnmapViewOfFile(lpData);
                lpData = NULL;
        }

  //remove the file mapping
        if (hMapping != NULL)
        {
                CloseHandle(hMapping);
                hMapping = NULL;
        }

  //close the file system file if its open
        if (hFile != INVALID_HANDLE_VALUE)
        {
                CloseHandle(hFile);
                hFile = INVALID_HANDLE_VALUE;
        }

  //Close the mutex we have been using
        if (hMutex != NULL)
        {
                CloseHandle(hMutex);
                hMutex = NULL;
        }

  //Reset the remaining member variables
  bReadOnly = TRUE;
  sMappingName.Empty();
  dwLength = 0;

  return TRUE;
}

--- code end ---



Relevant Pages

  • Re: Memory Mapped File Problem
    ... You appear to have created a file mapping that is one granual long, ... > I want to read a portion of a large file into a memory mapped ... Since I don't need the full file in the memory, ... > flProtect, 0, dwLength, sMappingName); ...
    (microsoft.public.vc.mfc)
  • Re: Memory Mapped File Problem
    ... You appear to have created a file mapping that is one granual long, ... > I want to read a portion of a large file into a memory mapped ... Since I don't need the full file in the memory, ... > flProtect, 0, dwLength, sMappingName); ...
    (microsoft.public.vc.language)
  • [9fans] segfree() - more details?
    ... ory within the span [va, va+len), but leaves that portion of ... any memory outside that span, and may not free all or even ... any of the specified memory. ... For example data and text segments will be read ...
    (comp.os.plan9)
  • Re: Email storing - Need urgent help
    ... > What happens to the discarded email? ... Should I free any portion of memory? ... No you can't do this via the Exchange Administration Console ...
    (microsoft.public.exchange2000.development)
  • Improved file handling mechanisms for 64-bit architectures
    ... in the new kernel version for 64-bit architectures. ... there is not enough physical memory, save the contents of the file to disk ... exception would occur and read a missing page (a missing portion of file). ... a remapping of virtual memory and the cooperation of file system is needed. ...
    (Linux-Kernel)

Loading