Creating a File Mapping Object
The first step in mapping a file is to open the file by calling the CreateFile function. To ensure that other processes cannot write to the portion of the file that is mapped, you should open the file with exclusive access. In addition, the file handle should remain open until the process no longer needs the file mapping object. An easy way to obtain exclusive access is to specify zero in the fdwShareMode parameter of CreateFile. The handle returned by CreateFile is used by the CreateFileMapping function to create a file mapping object.
The CreateFileMapping function returns a handle to the file mapping object. This handle will be used when creating a file view so that you can access the shared memory. When you call CreateFileMapping, you specify an object name, the number of bytes to be mapped from the file, and the read/write permission for the mapped memory. The first process that calls CreateFileMapping creates the file mapping object. Processes calling CreateFileMapping for an existing object receive a handle to the existing object. You can tell whether or not a successful call to CreateFileMapping created or opened the file mapping object by calling the GetLastError function. GetLastError returns NO_ERROR to the creating process and ERROR_ALREADY_EXISTS to subsequent processes.
- Specify the GENERIC_READ and GENERIC_WRITE values in the fdwAccess parameter of CreateFile.
- Specify the PAGE_READWRITE value in the fdwProtect parameter of CreateFileMapping.
Creating a file mapping object does not commit physical memory, it only reserves it.
File Mapping Size
The size of the file mapping object is independent of the size of the file being mapped. However, if the file mapping object is larger than the file, the system expands the file before CreateFileMapping returns. If the file mapping object is smaller than the file, the system maps only the specified number of bytes from the file.
The dwMaximumSizeHigh and dwMaximumSizeLow parameters of CreateFileMapping allow you to specify the number of bytes to be mapped from the file:
When you do not want the size of the file to change (for example, when mapping read-only files), call CreateFileMapping and specify zero for both dwMaximumSizeHigh and dwMaximumSizeLow. Doing this creates a file mapping object that is exactly the same size as the file. Otherwise, you must calculate or estimate the size of the finished file because file mapping objects are static in size; once created, their size cannot be increased or decreased. An attempt to map a file with a length of zero in this manner fails with an error code of ERROR_FILE_INVALID. Programs should test for files with a length of zero and reject such files.
The size of a file mapping object that is backed by a named file is limited by disk space. The size of a file view is limited to the largest available contiguous block of unreserved virtual memory. This is at most 2 GB minus the virtual memory already reserved by the process.
The size of the file mapping object that you select controls how far into the file you can "see" with memory mapping. If you create a file mapping object that is 500 Kb in size, you have access only to the first 500 Kb of the file, regardless of the size of the file. Since it does not cost you any system resources to create a larger file mapping object, create a file mapping object that is the size of the file (set the dwMaximumSizeHigh and dwMaximumSizeLow parameters of CreateFileMapping both to zero) even if you do not expect to view the entire file. The cost in system resources comes in creating the views and accessing them.
If you want to view a portion of the file that does not start at the beginning of the file, you must create a file mapping object. This object is the size of the portion of the file that you want to view plus the offset into the file.