/// <summary> /// Initializes a new instance of the NtfsFileSystemChecker class. /// </summary> /// <param name="diskData">The file system to check</param> public NtfsFileSystemChecker(Stream diskData) { SnapshotStream protectiveStream = new SnapshotStream(diskData, Ownership.None); protectiveStream.Snapshot(); protectiveStream.Freeze(); _target = protectiveStream; }
/// <summary> /// Initializes a new instance of the NtfsFileSystemChecker class. /// </summary> /// <param name="diskData">The file system to check.</param> public NtfsFileSystemChecker(Stream diskData) { SnapshotStream protectiveStream = new SnapshotStream(diskData, Ownership.None); protectiveStream.Snapshot(); protectiveStream.Freeze(); _target = protectiveStream; }
/// <summary> /// Saves or updates the current snapshot for a given aggregate /// </summary> /// <typeparam name="T">Type of snapshot</typeparam> /// <param name="snapshot">Snapshot instance</param> public void SaveSnapshot <T>(Snapshot <T> snapshot) { var snapshotStream = new SnapshotStream { AggregateRootId = snapshot.AggregateRootId.AsGuid, Version = snapshot.Version, DateCreated = DateTime.UtcNow, SnapshotType = typeof(T).Name, SnapshotData = JsonConvert.SerializeObject(snapshot.Data, SerializerSettings) }; GetRepository().InsertSnapshot(snapshotStream); }
private void ReplayLog() { _freeSpace.Reserve((long)_header.LogOffset, _header.LogLength); _logicalStream = _fileStream; // If log is empty, skip. if (_header.LogGuid == Guid.Empty) { return; } LogSequence activeLogSequence = FindActiveLogSequence(); if (activeLogSequence == null || activeLogSequence.Count == 0) { throw new IOException("Unable to replay VHDX log, suspected corrupt VHDX file"); } if (activeLogSequence.Head.FlushedFileOffset > (ulong)_logicalStream.Length) { throw new IOException("truncated VHDX file found while replaying log"); } if (activeLogSequence.Count > 1 || !activeLogSequence.Head.IsEmpty) { // However, have seen VHDX with a non-empty log with no data to replay. These are // 'safe' to open. if (!_fileStream.CanWrite) { SnapshotStream replayStream = new SnapshotStream(_fileStream, Ownership.None); replayStream.Snapshot(); _logicalStream = replayStream; } foreach (LogEntry logEntry in activeLogSequence) { if (logEntry.LogGuid != _header.LogGuid) { throw new IOException("Invalid log entry in VHDX log, suspected currupt VHDX file"); } if (logEntry.IsEmpty) { continue; } logEntry.Replay(_logicalStream); } _logicalStream.Seek((long)activeLogSequence.Head.LastFileOffset, SeekOrigin.Begin); } }
public DdrPs2FileDataTableChunk GetBound(Stream stream) { var cache = new CachedStream(stream); var cacheReader = new BinaryReader(cache); var entryCount = cacheReader.ReadInt32(); var offsets = Enumerable.Range(0, entryCount).Select(x => cacheReader.ReadInt32()).ToArray(); var lengths = Enumerable.Range(0, entryCount).Select(x => cacheReader.ReadInt32()).ToArray(); var entries = offsets.Select((e, i) => (Offset: e, Length: lengths[i])).OrderBy(x => x.Offset).ToArray(); var max = entries.Last().Use(x => x.Length + x.Offset); cache.Rewind(); var snapshot = new SnapshotStream(cache); snapshot.TryRead(new byte[max], 0, max); return(new DdrPs2FileDataTableChunk { Data = snapshot.ToArray(), HasHeaders = false }); }
protected override void DoRun() { using (VirtualDisk inDisk = VirtualDisk.OpenDisk(_inFile.Value, FileAccess.Read, UserName, Password)) { VirtualDiskParameters diskParams = inDisk.Parameters; diskParams.AdapterType = AdapterType; VirtualDiskTypeInfo diskTypeInfo = VirtualDisk.GetDiskType(OutputDiskType, OutputDiskVariant); if (diskTypeInfo.DeterministicGeometry) { diskParams.Geometry = diskTypeInfo.CalcGeometry(diskParams.Capacity); } if (_translation.IsPresent && _translation.EnumValue != GeometryTranslation.None) { diskParams.BiosGeometry = diskParams.Geometry.TranslateToBios(diskParams.Capacity, _translation.EnumValue); } else if (!inDisk.DiskTypeInfo.PreservesBiosGeometry) { // In case the BIOS geometry was just a default, it's better to override based on the physical geometry // of the new disk. diskParams.BiosGeometry = Geometry.MakeBiosSafe(diskParams.Geometry, diskParams.Capacity); } using (VirtualDisk outDisk = VirtualDisk.CreateDisk(OutputDiskType, OutputDiskVariant, _outFile.Value, diskParams, UserName, Password)) { if (outDisk.Capacity < inDisk.Capacity) { Console.WriteLine("ERROR: The output disk is smaller than the input disk, conversion aborted"); } SparseStream contentStream = inDisk.Content; if (_translation.IsPresent && _translation.EnumValue != GeometryTranslation.None) { SnapshotStream ssStream = new SnapshotStream(contentStream, Ownership.None); ssStream.Snapshot(); UpdateBiosGeometry(ssStream, inDisk.BiosGeometry, diskParams.BiosGeometry); contentStream = ssStream; } StreamPump pump = new StreamPump() { InputStream = contentStream, OutputStream = outDisk.Content, SparseCopy = !_wipe.IsPresent }; if (!Quiet) { long totalBytes = contentStream.Length; if (!_wipe.IsPresent) { totalBytes = 0; foreach (var se in contentStream.Extents) { totalBytes += se.Length; } } DateTime now = DateTime.Now; pump.ProgressEvent += (o, e) => { ShowProgress("Progress", totalBytes, now, o, e); }; } pump.Run(); } } }
protected override void DoRun() { if (!IsAdministrator()) { Console.WriteLine("\nThis utility must be run as an administrator!\n"); Environment.Exit(1); } DiskImageBuilder builder = DiskImageBuilder.GetBuilder(OutputDiskType, OutputDiskVariant); builder.GenericAdapterType = AdapterType; string[] sourceVolume = _volumes.Values; uint diskNumber; List <CloneVolume> cloneVolumes = GatherVolumes(sourceVolume, out diskNumber); if (!Quiet) { Console.WriteLine("Inspecting Disk..."); } // Construct a stream representing the contents of the cloned disk. BiosPartitionedDiskBuilder contentBuilder; Geometry biosGeometry; Geometry ideGeometry; long capacity; using (Disk disk = new Disk(diskNumber)) { contentBuilder = new BiosPartitionedDiskBuilder(disk); biosGeometry = disk.BiosGeometry; ideGeometry = disk.Geometry; capacity = disk.Capacity; } // Preserve the IDE (aka Physical) geometry builder.Geometry = ideGeometry; // Translate the BIOS (aka Logical) geometry GeometryTranslation translation = _translation.EnumValue; if (builder.PreservesBiosGeometry && translation == GeometryTranslation.Auto) { // If the new format preserves BIOS geometry, then take no action if asked for 'auto' builder.BiosGeometry = biosGeometry; translation = GeometryTranslation.None; } else { builder.BiosGeometry = ideGeometry.TranslateToBios(0, translation); } if (translation != GeometryTranslation.None) { contentBuilder.UpdateBiosGeometry(builder.BiosGeometry); } IVssBackupComponents backupCmpnts; int status; if (Marshal.SizeOf(typeof(IntPtr)) == 4) { status = NativeMethods.CreateVssBackupComponents(out backupCmpnts); } else { status = NativeMethods.CreateVssBackupComponents64(out backupCmpnts); } Guid snapshotSetId = CreateSnapshotSet(cloneVolumes, backupCmpnts); if (!Quiet) { Console.Write("Copying Disk..."); } foreach (var sv in cloneVolumes) { Volume sourceVol = new Volume(sv.SnapshotProperties.SnapshotDeviceObject, sv.SourceExtent.ExtentLength); SnapshotStream rawVolStream = new SnapshotStream(sourceVol.Content, Ownership.None); rawVolStream.Snapshot(); byte[] volBitmap; int clusterSize; using (NtfsFileSystem ntfs = new NtfsFileSystem(rawVolStream)) { ntfs.NtfsOptions.HideSystemFiles = false; ntfs.NtfsOptions.HideHiddenFiles = false; ntfs.NtfsOptions.HideMetafiles = false; // Remove VSS snapshot files (can be very large) foreach (string filePath in ntfs.GetFiles(@"\System Volume Information", "*{3808876B-C176-4e48-B7AE-04046E6CC752}")) { ntfs.DeleteFile(filePath); } // Remove the page file if (ntfs.FileExists(@"\Pagefile.sys")) { ntfs.DeleteFile(@"\Pagefile.sys"); } // Remove the hibernation file if (ntfs.FileExists(@"\hiberfil.sys")) { ntfs.DeleteFile(@"\hiberfil.sys"); } using (Stream bitmapStream = ntfs.OpenFile(@"$Bitmap", FileMode.Open)) { volBitmap = new byte[bitmapStream.Length]; int totalRead = 0; int numRead = bitmapStream.Read(volBitmap, 0, volBitmap.Length - totalRead); while (numRead > 0) { totalRead += numRead; numRead = bitmapStream.Read(volBitmap, totalRead, volBitmap.Length - totalRead); } } clusterSize = (int)ntfs.ClusterSize; if (translation != GeometryTranslation.None) { ntfs.UpdateBiosGeometry(builder.BiosGeometry); } } List <StreamExtent> extents = new List <StreamExtent>(BitmapToRanges(volBitmap, clusterSize)); SparseStream partSourceStream = SparseStream.FromStream(rawVolStream, Ownership.None, extents); for (int i = 0; i < contentBuilder.PartitionTable.Partitions.Count; ++i) { var part = contentBuilder.PartitionTable.Partitions[i]; if (part.FirstSector * 512 == sv.SourceExtent.StartingOffset) { contentBuilder.SetPartitionContent(i, partSourceStream); } } } SparseStream contentStream = contentBuilder.Build(); // Write out the disk images string dir = Path.GetDirectoryName(_destDisk.Value); string file = Path.GetFileNameWithoutExtension(_destDisk.Value); builder.Content = contentStream; DiskImageFileSpecification[] fileSpecs = builder.Build(file); for (int i = 0; i < fileSpecs.Length; ++i) { // Construct the destination file path from the directory of the primary file. string outputPath = Path.Combine(dir, fileSpecs[i].Name); // Force the primary file to the be one from the command-line. if (i == 0) { outputPath = _destDisk.Value; } using (SparseStream vhdStream = fileSpecs[i].OpenStream()) using (FileStream fs = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite)) { StreamPump pump = new StreamPump() { InputStream = vhdStream, OutputStream = fs, }; long totalBytes = 0; foreach (var se in vhdStream.Extents) { totalBytes += se.Length; } if (!Quiet) { Console.WriteLine(); DateTime now = DateTime.Now; pump.ProgressEvent += (o, e) => { ShowProgress(fileSpecs[i].Name, totalBytes, now, o, e); }; } pump.Run(); if (!Quiet) { Console.WriteLine(); } } } // Complete - tidy up CallAsyncMethod(backupCmpnts.BackupComplete); long numDeleteFailed; Guid deleteFailed; backupCmpnts.DeleteSnapshots(snapshotSetId, 2 /*VSS_OBJECT_SNAPSHOT_SET*/, true, out numDeleteFailed, out deleteFailed); Marshal.ReleaseComObject(backupCmpnts); }
public void InsertSnapshot(SnapshotStream snapshot) { EnsureContext(); _context.SnapshotStreams.Add(snapshot); _context.SaveChanges(); }
public DdrPs2FileDataTableChunk GetUnbound(Stream stream) { var cache = new CachedStream(stream); var cacheReader = new BinaryReader(cache); using var snapshot = new SnapshotStream(cache); var snapshotReader = new BinaryReader(snapshot); var firstFile = snapshotReader.ReadInt32(); var tableSize = firstFile / 4 * 4; var table = Enumerable.Range(0, firstFile / 4).Select(_ => snapshotReader.ReadInt32()).ToArray(); var skip = firstFile - tableSize; int index; if (skip > 0) { snapshotReader.ReadBytes(skip); } for (index = 1; index < table.Length; index++) { if (table[index] < table[index - 1]) { break; } } // Warning: big heckin' hack. // We're looking for a TCB table, which puts headers on all the file entries. // There's no way to tell easily outside of this function, so... var prevPosition = cache.Position; cache.Position = table[0]; var headTest0 = cacheReader.ReadInt32(); var headTest1 = cacheReader.ReadInt32(); var headTest2 = cacheReader.ReadInt32(); var hasHeaders = headTest0 > 0 && headTest1 > 0 && headTest2 > 0 && headTest2 > headTest1 && headTest1 > headTest0 && (headTest0 & 0x3) == 0 && ((headTest0 | headTest1 | headTest2) >> 24) == 0; cache.Position = prevPosition; var desiredPosition = table[index - 1]; snapshotReader.ReadBytes((int)(desiredPosition - prevPosition)); if (hasHeaders) { snapshotReader.ReadBytes(0xC); } try { _bemaniLzDecoder.Decode(snapshot); } catch (Exception) { return(null); } return(new DdrPs2FileDataTableChunk { Data = snapshot.ToArray(), HasHeaders = hasHeaders }); }