Beispiel #1
0
        /// <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();
                }
            }
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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);
				}
			}
		}
Beispiel #7
0
        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);
                }
            }
        }