/// <summary> /// Coverts a raw DD image into a VHD file suitable for FFU imaging. /// </summary> /// <param name="ddfile">The path to the DD file.</param> /// <param name="vhdfile">The path to the output VHD file.</param> /// <returns></returns> public static void ConvertDD2VHD(string ddfile, string vhdfile, string[] partitions, bool Recovery, int SectorSize) { SetupHelper.SetupContainers(); Stream strm; if (ddfile.ToLower().Contains(@"\\.\physicaldrive")) { strm = new DeviceStream(ddfile); } else { strm = new FileStream(ddfile, FileMode.Open); } Stream fstream; if (!Recovery) { fstream = new EPartitionStream(strm, partitions); } else { fstream = strm; } using (var inDisk = new Disk(fstream, Ownership.Dispose)) { var diskParams = inDisk.Parameters; using (var outDisk = VirtualDisk.CreateDisk("VHD", "dynamic", vhdfile, diskParams, "", "")) { var contentStream = inDisk.Content; var pump = new StreamPump { InputStream = contentStream, OutputStream = outDisk.Content, SparseCopy = true, SparseChunkSize = SectorSize, BufferSize = SectorSize * 1024 }; var totalBytes = contentStream.Length; var now = DateTime.Now; pump.ProgressEvent += (o, e) => { ShowProgress(totalBytes, now, o, e); }; Logging.Log("Converting RAW to VHD"); pump.Run(); Console.WriteLine(); } } }
void InitializeVhdViaPump(DiscUtils.Vhd.Disk vhdDisk) { if (SectorSize != XvdFile.LEGACY_SECTOR_SIZE) { throw new InvalidOperationException( "Initializing VHD via pump is only supported for 512 byte sectors"); } var pump = new StreamPump(_fs, vhdDisk.Content, (int)XvdFile.LEGACY_SECTOR_SIZE); pump.Run(); }
private void CopyFile(FileInfo infile, FileInfo outfile, int blocksize = (UInt16.MaxValue + 1) * 2) { FileStream inStream = infile.OpenRead(); FileStream outStream = outfile.OpenWrite(); length = inStream.Length; StreamPump streamPump = new StreamPump(inStream, outStream, 0); streamPump.SparseCopy = false; streamPump.BufferSize = blocksize; streamPump.SparseChunkSize = blocksize * 2; streamPump.ProgressEvent += StreamPump_ProgressEvent; streamPump.Run(); inStream.Close(); outStream.Flush(true); outStream.Close(); }
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 override void Run() { long x; string id; IFile destTemp; ITempIdentityFileService destTempService; IFile dest; Stream srcStream = null, destStream = null; IFileHashingService hasher; string sourceHash, destTempHash; try { lock (this.SyncLock) { m_TaskThread = Thread.CurrentThread; if (m_TransferState != TransferState.NotStarted) { throw new InvalidOperationException(); } SetTransferState(TransferState.Preparing); ProcessTaskStateRequest(); } id = m_Source.Address.Uri + m_Source.Length.ToString() + (m_Source.Attributes.CreationTime ?? DateTime.MinValue).ToBinary().ToString(); destTempService = (ITempIdentityFileService)m_Destination.GetService(new TempIdentityFileServiceType(id)); destTemp = destTempService.GetTempFile(); for (;;) { try { x = destTemp.Length; } catch (FileNotFoundException) { x = 0; } dest = m_Destination.ParentDirectory.ResolveFile("$TMP_" + m_Destination.Address.Name + "_" + Guid.NewGuid().ToString("N")); try { if (x == m_Source.Length) { try { if (m_Source.IdenticalTo(destTemp, FileComparingFlags.CompareContents)) { SetTransferState(TransferState.Copying); ProcessTaskStateRequest(); m_Progress.RaiseValueChanged(m_Progress.CurrentValue, 0); destTemp.MoveTo(dest, true); if (!m_Source.IdenticalTo(dest, FileComparingFlags.CompareContents)) { continue; } dest.RenameTo(m_Destination.Address.NameAndQuery, true); m_BytesTransferred = m_Destination.Length; m_Progress.RaiseValueChanged(m_Progress.CurrentValue, m_BytesTransferred); SetTransferState(TransferState.Finished); ProcessTaskStateRequest(); return; } } catch (IOException) { } } srcStream = m_Source.GetContent().GetInputStream(FileShare.Read); if (!srcStream.CanSeek) { destStream = destTemp.GetContent().GetOutputStream(FileMode.Create, FileShare.Read); } else { destStream = destTemp.GetContent().GetOutputStream(FileMode.Append, FileShare.Read); SetTransferState(TransferState.Comparing); ProcessTaskStateRequest(); hasher = (IFileHashingService)m_Source.GetService(new FileHashingServiceType("md5")); sourceHash = hasher.ComputeHash(0, destStream.Length).TextValue; hasher = (IFileHashingService)destTemp.GetService(new FileHashingServiceType("md5")); destTempHash = hasher.ComputeHash().TextValue; if (sourceHash != destTempHash) { destStream.Close(); destStream = destTemp.GetContent().GetOutputStream(FileMode.Create, FileShare.Read); } else { m_Offset = destStream.Length; if (m_Offset > 0) { srcStream = new PartialStream(srcStream, m_Offset); } } } m_Progress.RaiseValueChanged(0, m_Offset); ProcessTaskStateRequest(); m_Pump = new StreamPump(srcStream, destStream, true, false, m_ServiceType.BufferSize); m_Pump.TaskStateChanged += new TaskEventHandler(Pump_TaskStateChanged); SetTransferState(TransferState.Transferring); ProcessTaskStateRequest(); m_Pump.Run(); if (m_Pump.TaskState == TaskState.Stopped) { throw new StopRequestedException(); } SetTransferState(TransferState.Copying); ProcessTaskStateRequest(); } finally { if (srcStream != null) { Routines.IgnoreExceptions(delegate { srcStream.Close(); }); } if (destStream != null) { Routines.IgnoreExceptions(delegate { destStream.Close(); }); } } break; } SetTransferState(TransferState.Tidying); destTemp.MoveTo(dest, true); /// /// Aquire an UpdateContext for the attributes /// so that all updates to the attributes are /// commited in a single operation /// using (dest.Attributes.AquireUpdateContext()) { foreach (string s in this.m_ServiceType.AttributesToTransfer) { dest.Attributes[s] = m_Source.Attributes[s]; } } dest.RenameTo(m_Destination.Address.Name, true); SetTransferState(TransferState.Finished); } finally { if (m_TransferState != TransferState.Stopped) { SetTransferState(TransferState.Finished); } } }