internal MapViewStream(MemoryMappedFile backingFile, long mapSize, bool isWriteable) { if (backingFile == null) { throw new MMException("MapViewStream.MapViewStream - backingFile is null"); } if (!backingFile.IsOpen) { throw new MMException("MapViewStream.MapViewStream - backingFile is not open"); } if ((mapSize < 1) || (mapSize > backingFile.MaxSize)) { throw new MMException(string.Format("MapViewStream.MapViewStream - mapSize is invalid. mapSize == {0}, backingFile.MaxSize == {1}", mapSize, backingFile.MaxSize)); } _backingFile = backingFile; _isWriteable = isWriteable; _access = isWriteable ? FileMapAccessType.Write : FileMapAccessType.Read; _mapSize = mapSize; _isOpen = true; Seek(0, SeekOrigin.Begin); }
public static extern IntPtr MapViewOfFileEx( IntPtr hFileMappingObject, FileMapAccessType dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap, IntPtr lpBaseAddress);
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 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); }
public static extern IntPtr MapViewOfFileEx(IntPtr hFileMappingObject, FileMapAccessType dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap, IntPtr lpBaseAddress);
public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, FileMapAccessType dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);