public DumpFileMemoryReader(string dumpFilePath)
{
bool dispose = true;
FileStream fileStream = null;
MemoryMappedFile memoryMappedFile = null;
MemoryMappedViewStream stream = null;
try
{
fileStream = new FileStream(dumpFilePath, FileMode.Open, FileAccess.Read);
memoryMappedFile = MemoryMappedFile.CreateFromFile(fileStream, Guid.NewGuid().ToString(), fileStream.Length, MemoryMappedFileAccess.Read, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, false);
stream = memoryMappedFile.CreateViewStream(0, fileStream.Length, MemoryMappedFileAccess.Read);
stream.SafeMemoryMappedViewHandle.AcquirePointer(ref basePointer);
IntPtr streamPointer = IntPtr.Zero;
uint streamSize = 0;
MINIDUMP_DIRECTORY directory = new MINIDUMP_DIRECTORY();
if (!MiniDumpReadDumpStream((IntPtr)basePointer, MINIDUMP_STREAM_TYPE.Memory64ListStream, ref directory, ref streamPointer, ref streamSize))
throw new Exception("Unable to read mini dump stream");
var data = (MINIDUMP_MEMORY64_LIST)Marshal.PtrToStructure(streamPointer, typeof(MINIDUMP_MEMORY64_LIST));
ulong lastEnd = data.BaseRva;
ranges = new MemoryLocation[data.NumberOfMemoryRanges];
for (int i = 0; i < ranges.Length; i++)
{
var descriptor = (MINIDUMP_MEMORY_DESCRIPTOR64)Marshal.PtrToStructure(streamPointer + sizeof(MINIDUMP_MEMORY64_LIST) + i * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64), typeof(MINIDUMP_MEMORY_DESCRIPTOR64));
ranges[i] = new MemoryLocation()
{
MemoryStart = descriptor.StartOfMemoryRange,
MemoryEnd = descriptor.StartOfMemoryRange + descriptor.DataSize,
FilePosition = lastEnd,
};
lastEnd += descriptor.DataSize;
}
int newEnd = 0;
for (int i = 1; i < ranges.Length; i++)
if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd)
ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd;
else
ranges[++newEnd] = ranges[i];
newEnd++;
Array.Resize(ref ranges, newEnd);
finder = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion { BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd }).ToArray());
dispose = false;
}
finally
{
if (dispose)
{
stream.SafeMemoryMappedViewHandle.ReleasePointer();
if (stream != null)
{
stream.Dispose();
}
if (memoryMappedFile != null)
{
memoryMappedFile.Dispose();
}
if (fileStream != null)
{
fileStream.Dispose();
}
}
else
{
this.fileStream = fileStream;
this.stream = stream;
this.memoryMappedFile = memoryMappedFile;
}
}
}