Some time ago, I wrote a class that encapsulates a file mapping view, you can use it if you like:
static class NativeMethods
{
[Flags]
public enum FileAccess : uint
{
DeviceAttributes = 0,
GenericRead = 0x80000000,
GenericWrite = 0x40000000
}
public enum CreationDisposition
{
CreateNew = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5
}
[Flags]
public enum FileShareMode
{
Read = 1,
Write = 2,
Delete = 4
}
[Flags]
public enum FileFlagsAndAttributes : uint
{
ReadOnly = 0x1,
Hidden = 0x2,
System = 0x4,
Archive = 0x20,
Normal = 0x80,
FlagWriteThrough = 0x80000000,
FlagRandomAccess = 0x10000000
}
public enum PageProtect
{
ReadOnly = 0x2,
ReadWrite = 0x4,
}
[Flags]
public enum MapAccess
{
Write = 0x2,
Read = 0x4,
AllAccess = Write | Read
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern SafeFileHandle CreateFile(
string lpFileName,
FileAccess dwDesiredAccess,
FileShareMode dwShareMode,
IntPtr lpSecurityAttributes,
CreationDisposition dwCreationDisposition,
FileFlagsAndAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern SafeFileMappingHandle CreateFileMapping(SafeFileHandle hFile, IntPtr lpFileMappingAttributes, PageProtect flProtect,
uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr MapViewOfFile(SafeFileMappingHandle hFileMappingObject, MapAccess dwDesiredAccess, uint dwFileOffsetHigh,
uint dwFileOffsetLow, IntPtr dwNumberOfBytesToMap);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("kernel32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
sealed class SafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeFileMappingHandle()
: base(true)
{
}
public SafeFileMappingHandle(IntPtr handle, bool ownsHandle)
: base(ownsHandle)
{
SetHandle(handle);
}
protected override bool ReleaseHandle()
{
return NativeMethods.CloseHandle(handle);
}
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)]
public sealed class FileMapping : IDisposable
{
private readonly SafeFileHandle _file;
private readonly SafeFileMappingHandle _mapping;
private readonly IntPtr _view;
private readonly long _size;
private bool _disposed;
public FileMapping(string fileName)
{
if( fileName == null )
throw new ArgumentNullException("fileName");
_size = new FileInfo(fileName).Length;
try
{
_file = NativeMethods.CreateFile(fileName, NativeMethods.FileAccess.GenericRead, NativeMethods.FileShareMode.Read, IntPtr.Zero, NativeMethods.CreationDisposition.OpenExisting, NativeMethods.FileFlagsAndAttributes.Normal | NativeMethods.FileFlagsAndAttributes.FlagRandomAccess, IntPtr.Zero);
if( _file.IsInvalid )
throw new Win32Exception();
_mapping = NativeMethods.CreateFileMapping(_file, IntPtr.Zero, NativeMethods.PageProtect.ReadOnly, 0, 0, null);
if( _mapping.IsInvalid )
throw new Win32Exception();
_view = NativeMethods.MapViewOfFile(_mapping, NativeMethods.MapAccess.Read, 0, 0, IntPtr.Zero);
if( _view == IntPtr.Zero )
throw new Win32Exception();
}
catch
{
if( _view != IntPtr.Zero )
NativeMethods.UnmapViewOfFile(_view);
if( _mapping != null )
_mapping.Dispose();
if( _file != null )
_file.Dispose();
throw;
}
}
~FileMapping()
{
Dispose(false);
}
public IntPtr View
{
get
{
CheckDisposed();
return _view;
}
}
public long Size
{
get
{
CheckDisposed();
return _size;
}
}
private void Dispose(bool disposing)
{
if( !_disposed )
{
if( _view != IntPtr.Zero )
NativeMethods.UnmapViewOfFile(_view);
if( disposing )
{
if( _mapping != null )
_mapping.Dispose();
if( _file != null )
_file.Dispose();
}
_disposed = true;
}
}
private void CheckDisposed()
{
if( _disposed )
throw new ObjectDisposedException(typeof(FileMapping).FullName);
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}