예제 #1
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();
                }
            }
        }