protected virtual void Dispose(bool disposing) { if (IsOpen) { Win32MapApis.CloseHandle(_hMap); } _hMap = NULL_HANDLE; if (disposing) { GC.SuppressFinalize(this); } }
public static MemoryMappedFile Open(FileMapAccessType access, String name) { MemoryMappedFile map = new MemoryMappedFile { _hMap = Win32MapApis.OpenFileMapping((int)access, false, name) }; if (map._hMap == NULL_HANDLE) { throw new MMException(Marshal.GetLastWin32Error()); } map._maxSize = -1; return(map); }
public void Flush(IntPtr viewBaseAddr) { IntPtr flushLength = new IntPtr(MaxSize); Win32MapApis.FlushViewOfFile(viewBaseAddr, flushLength); }
public void UnMapView(IntPtr mapBaseAddr) { Win32MapApis.UnmapViewOfFile(mapBaseAddr); }
public IntPtr MapView(FileMapAccessType access, ref long offset, ref long mapSize) { if (!IsOpen) { throw new ObjectDisposedException("Memory file already closed"); } // Grab system info to get the allocation granularity. SYSTEM_INFO pSI = new SYSTEM_INFO(); Win32MapApis.GetSystemInfo(ref pSI); // Make sure the offset is aligned. offset -= offset % pSI.dwAllocationGranularity; // Find the largest contiguous virtual address space. MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION(); long address = 0; const uint MEM_FREE = 0x10000; long freestart = 0, largestFreestart = 0; long free = 0, largestFree = 0; bool recording = false; while (true) { int numBytes = Win32MapApis.VirtualQueryEx(System.Diagnostics.Process.GetCurrentProcess().Handle, (IntPtr)address, out mbi, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); if (numBytes != Marshal.SizeOf(mbi)) { break; } if (mbi.State == MEM_FREE) { if (!recording) { freestart = address; } free += mbi.RegionSize.ToInt64(); recording = true; } else { if (recording) { if (free > largestFree) { largestFree = free; largestFreestart = freestart; } } free = 0; recording = false; } address += mbi.RegionSize.ToInt64(); } // Make sure the address is aligned if (largestFreestart % pSI.dwAllocationGranularity != 0) { long diff = pSI.dwAllocationGranularity - (largestFreestart % pSI.dwAllocationGranularity); largestFreestart += diff; largestFree -= diff; } // Cap map size if (mapSize > largestFree) { mapSize = largestFree; } // Edge case if (offset + mapSize > _fileSize) { long diff = offset + mapSize - _fileSize; if (diff % pSI.dwAllocationGranularity != 0) { diff -= diff % pSI.dwAllocationGranularity; diff += pSI.dwAllocationGranularity; } offset -= diff; } IntPtr baseAddress = Win32MapApis.MapViewOfFileEx( _hMap, (int)access, (int)((offset >> 32) & 0xFFFFFFFF), (int)(offset & 0xFFFFFFFF), (IntPtr)mapSize, (IntPtr)largestFreestart); if (baseAddress == IntPtr.Zero) { throw new MMException(Marshal.GetLastWin32Error()); } return(baseAddress); }
Create(string fileName, MapProtection protection, long maxSize, String name) { MemoryMappedFile map = new MemoryMappedFile(); if (!map.Is64bit && maxSize > uint.MaxValue) { throw new ConstraintException("32bit systems support max size of 4gb."); } // open file first IntPtr hFile = INVALID_HANDLE_VALUE; if (!string.IsNullOrEmpty(fileName)) { if (!File.Exists(fileName)) { throw new MMException(string.Format("MemoryMappedFile.Create - \"{0}\" does not exist ==> Unable to map file", fileName)); } FileInfo backingFileInfo = new FileInfo(fileName); // Get the file size and store it for later use. map._fileSize = backingFileInfo.Length; // Set max size if not set. Otherwise cap it. if (maxSize == 0) { maxSize = backingFileInfo.Length; } else { maxSize = Math.Min(maxSize, backingFileInfo.Length); } if (maxSize == 0) { throw new MMException(string.Format("Create - \"{0}\" is zero bytes ==> Unable to map file", fileName)); } int desiredAccess = GENERIC_READ; int desiredShareMode = FILE_SHARE_READ; if ((protection == MapProtection.PageReadWrite) || (protection == MapProtection.PageWriteCopy)) { desiredAccess |= GENERIC_WRITE; desiredShareMode |= FILE_SHARE_WRITE; } hFile = Win32MapApis.CreateFile( fileName, desiredAccess, desiredShareMode, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero ); if (hFile == INVALID_HANDLE_VALUE) { throw new MMException(Marshal.GetLastWin32Error()); } map._fileName = fileName; } // Map the file. map._hMap = Win32MapApis.CreateFileMapping( hFile, IntPtr.Zero, (int)protection, (int)((maxSize >> 32) & 0xFFFFFFFF), (int)(maxSize & 0xFFFFFFFF), name ); if (hFile != INVALID_HANDLE_VALUE) { Win32MapApis.CloseHandle(hFile); } if (map._hMap == NULL_HANDLE) { throw new MMException(Marshal.GetLastWin32Error()); } map._protection = protection; map._maxSize = maxSize; return(map); }