private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string devid = (string)e.Argument; string devnum = new String(devid.Where(Char.IsDigit).ToArray()); RawDisk disk = new RawDisk(DiskNumberType.PhysicalDisk, Convert.ToInt32(devnum), FileAccess.Read); long diskReadLength = disk.SizeBytes; long totalRead = 0; int increment = (int)(((16f * 1024f * 1024f) / disk.SectorSize) * disk.SectorSize); byte[] input = new byte[increment]; Stopwatch sw = new Stopwatch(); FileStream fs = new FileStream(textBox1.Text, FileMode.Create); using (RawDiskStream diskFs = disk.CreateDiskStream()) { sw.Start(); while (true) { if (backgroundWorker1.CancellationPending) { e.Cancel = true; diskFs.Close(); fs.Close(); break; } int read = (int)Math.Min(increment, disk.SizeBytes - totalRead); int actualRead = diskFs.Read(input, 0, read); if (actualRead == 0) { diskFs.Close(); fs.Close(); if (totalRead == diskReadLength) { readCompleteOK = true; } else { readCompleteOK = false; } break; } totalRead += actualRead; fs.Write(input, 0, input.Length); imageState imst = new imageState(); imst.progress = fsToHuman(Convert.ToUInt64(totalRead)) + " / " + fsToHuman(Convert.ToUInt64(diskReadLength)); int perc = (int)(0.5f + ((100f * totalRead) / disk.SizeBytes)); //imst.disksize = disk.SizeBytes; //imst.diskposition = totalRead; imst.percent = perc.ToString() + "% complete"; imst.speed = Math.Round(((diskFs.Position / 1048576f) / sw.Elapsed.TotalSeconds), 2).ToString() + "MB/s"; backgroundWorker1.ReportProgress(perc, imst); } } }
static void Main(string[] args) { char driveLetter = 'C'; if (args.Length == 1) { driveLetter = args[0][0]; } using (RawDisk disk = new RawDisk(driveLetter)) { MftDiskExtents res = new MftDiskExtents(); byte[] ntfsBoot = disk.ReadSectors(0, 1); BootSector boot = BootSector.ParseData(ntfsBoot, ntfsBoot.Length, 0); Console.WriteLine("MFT is at LCN " + boot.MFTCluster); MftDetails mft = GetMftDetails(disk, boot); Console.WriteLine("MFT is in " + mft.MftExtents.Length + " extents"); res.Extents.AddRange(mft.MftExtents); using (RawDiskStream diskStream = disk.CreateDiskStream()) using (NtfsDiskStream mftStream = new NtfsDiskStream(diskStream, false, mft.MftExtents, (uint)disk.ClusterSize, 0, (long)mft.MftSize)) { uint sectorsPrRecord = (uint)(boot.MFTRecordSizeBytes / disk.SectorSize); ushort bytesPrSector = (ushort)disk.SectorSize; int records = (int)(mftStream.Length / boot.MFTRecordSizeBytes); byte[] tmp = new byte[boot.MFTRecordSizeBytes]; while (true) { int read = mftStream.Read(tmp, 0, tmp.Length); if (read < boot.MFTRecordSizeBytes) { Console.WriteLine("Stopped reading as we got " + read + " bytes instead of " + tmp.Length + " bytes"); break; } FileRecord rec = FileRecord.Parse(tmp, 0, bytesPrSector, sectorsPrRecord); // Keep track of all external extents to the MFT RecordExternalDiskExtents(rec, res); //// Special case for LIST attributes, since they can further reference more extents outside the MFT //ProcessNonResidentListAttributes(disk, rec); } } long clustersTotal = res.Extents.Sum(x => x.Clusters); Console.WriteLine("To copy: {0:N0} extents", res.Extents.Count); Console.WriteLine("{0:N0} clusters, {1:N0} bytes", clustersTotal, clustersTotal * disk.ClusterSize); } Console.ReadLine(); }
internal override void ParseAttributeNonResidentBody(RawDisk disk) { base.ParseAttributeNonResidentBody(disk); // Read clusters from disk Data = new byte[NonResidentHeader.ContentSize]; using (RawDiskStream diskStream = disk.CreateDiskStream()) using (NtfsDiskStream attribStream = new NtfsDiskStream(diskStream, false, NonResidentHeader.Fragments, (uint)disk.ClusterSize, 0, Data.LongLength)) attribStream.Read(Data, 0, Data.Length); }
public override void Execute() { // 512 MB const long lengthTodo = 512L * 1024 * 1024; IEnumerable <char> volumeDrives = Utils.GetAllAvailableVolumes(); foreach (char drive in volumeDrives) { Console.WriteLine("Hashing " + drive + ":"); try { using (RawDisk disk = new RawDisk(drive)) { long diskReadLength = Math.Min(disk.SizeBytes, lengthTodo); long totalRead = 0; // Read in ~16M chunks int increment = (int)(((16f * 1024f * 1024f) / disk.SectorSize) * disk.SectorSize); Console.WriteLine("Reading {0:N0} B in {1:N0} B chunks. Chunks: {2:N0}", diskReadLength, increment, diskReadLength / increment); byte[] input = new byte[increment]; byte[] output = new byte[increment]; MD5 md5 = MD5.Create(); Stopwatch sw = new Stopwatch(); using (RawDiskStream diskFs = disk.CreateDiskStream()) { sw.Start(); while (true) { int read = (int)Math.Min(increment, diskReadLength - diskFs.Position); int actualRead = diskFs.Read(input, 0, read); if (actualRead == 0) { Console.CursorTop++; if (totalRead == diskReadLength) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Done! Read {0:N0} in total", totalRead); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Done! Read {0:N0} in total (not expected)", totalRead); } Console.ForegroundColor = ExampleUtilities.DefaultColor; break; } md5.TransformBlock(input, 0, actualRead, output, 0); totalRead += actualRead; Console.WriteLine("Position: {0:N0} B, Progress: {1:#0.000%}, AvgSpeed: {2:N2} MB/s", diskFs.Position, diskFs.Position * 1f / diskReadLength, (diskFs.Position / 1048576f) / sw.Elapsed.TotalSeconds); Console.CursorTop--; } sw.Stop(); } md5.TransformFinalBlock(new byte[0], 0, 0); Console.Write("Computed MD5: "); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(BitConverter.ToString(md5.Hash).Replace("-", "")); Console.ForegroundColor = ExampleUtilities.DefaultColor; } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Error: " + ex.Message); Console.ForegroundColor = ExampleUtilities.DefaultColor; } Console.WriteLine(); } }