Beispiel #1
0
        private void CreateNewDisk()
        {
            string[] typeAndVariant = Type.Split('-');
            if (typeAndVariant.Length < 1 || typeAndVariant.Length > 2)
            {
                WriteError(new ErrorRecord(
                               new ArgumentException("Invalid Type of disk"),
                               "BadDiskType",
                               ErrorCategory.InvalidArgument,
                               null));
                return;
            }

            long size;

            if (!DiscUtils.Common.Utilities.TryParseDiskSize(Size, out size))
            {
                WriteError(new ErrorRecord(
                               new ArgumentException("Unable to parse the disk size"),
                               "BadDiskSize",
                               ErrorCategory.InvalidArgument,
                               null));
                return;
            }


            string type    = typeAndVariant[0];
            string variant = typeAndVariant.Length > 1 ? typeAndVariant[1] : null;

            string   child;
            PSObject parentObj = ResolveNewDiskPath(out child);

            VirtualDisk disk = null;

            if (parentObj.BaseObject is DirectoryInfo)
            {
                string path = Path.Combine(((DirectoryInfo)parentObj.BaseObject).FullName, child);
                using (VirtualDisk realDisk = VirtualDisk.CreateDisk(type, variant, path, size, null, null)) { }
                disk = new OnDemandVirtualDisk(path, FileAccess.ReadWrite);
            }
            else if (parentObj.BaseObject is DiscDirectoryInfo)
            {
                DiscDirectoryInfo ddi  = (DiscDirectoryInfo)parentObj.BaseObject;
                string            path = Path.Combine(ddi.FullName, child);
                using (VirtualDisk realDisk = VirtualDisk.CreateDisk(ddi.FileSystem, type, variant, path, size, null, null)) { }
                disk = new OnDemandVirtualDisk(ddi.FileSystem, path, FileAccess.ReadWrite);
            }
            else
            {
                WriteError(new ErrorRecord(
                               new DirectoryNotFoundException("Cannot create a virtual disk in that location"),
                               "BadDiskLocation",
                               ErrorCategory.InvalidArgument,
                               null));
                return;
            }

            WriteObject(disk, false);
        }
Beispiel #2
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 #3
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();
                }
            }
        }
Beispiel #4
0
        protected override void DoRun()
        {
            if (DiskSize <= 0)
            {
                DisplayHelp();
                return;
            }

            using (VirtualDisk sourceDisk = VirtualDisk.OpenDisk(_sourceFile.Value, FileAccess.Read, UserName, Password))
                using (VirtualDisk destDisk = VirtualDisk.CreateDisk(OutputDiskType, OutputDiskVariant, _destFile.Value, DiskParameters, UserName, Password))
                {
                    if (destDisk is DiscUtils.Vhd.Disk)
                    {
                        ((DiscUtils.Vhd.Disk)destDisk).AutoCommitFooter = false;
                    }

                    // Copy the MBR from the source disk, and invent a new signature for this new disk
                    destDisk.SetMasterBootRecord(sourceDisk.GetMasterBootRecord());
                    destDisk.Signature = new Random().Next();

                    SparseStream   sourcePartStream = SparseStream.FromStream(sourceDisk.Partitions[0].Open(), Ownership.None);
                    NtfsFileSystem sourceNtfs       = new NtfsFileSystem(sourcePartStream);

                    // Copy the OS boot code into memory, so we can apply it when formatting the new disk
                    byte[] bootCode;
                    using (Stream bootStream = sourceNtfs.OpenFile("$Boot", FileMode.Open, FileAccess.Read))
                    {
                        bootCode = new byte[bootStream.Length];
                        int totalRead = 0;
                        while (totalRead < bootCode.Length)
                        {
                            totalRead += bootStream.Read(bootCode, totalRead, bootCode.Length - totalRead);
                        }
                    }

                    // Partition the new disk with a single NTFS partition
                    BiosPartitionTable.Initialize(destDisk, WellKnownPartitionType.WindowsNtfs);
                    VolumeManager volMgr = new VolumeManager(destDisk);

                    string label = _labelSwitch.IsPresent ? _labelSwitch.Value : sourceNtfs.VolumeLabel;
                    using (NtfsFileSystem destNtfs = NtfsFileSystem.Format(volMgr.GetLogicalVolumes()[0], label, bootCode))
                    {
                        destNtfs.SetSecurity(@"\", sourceNtfs.GetSecurity(@"\"));
                        destNtfs.NtfsOptions.ShortNameCreation = ShortFileNameOption.Disabled;

                        sourceNtfs.NtfsOptions.HideHiddenFiles = false;
                        sourceNtfs.NtfsOptions.HideSystemFiles = false;
                        CopyFiles(sourceNtfs, destNtfs, @"\", true);

                        if (destNtfs.FileExists(@"\boot\BCD"))
                        {
                            // Force all boot entries in the BCD to point to the newly created NTFS partition - does _not_ cope with
                            // complex multi-volume / multi-boot scenarios at all.
                            using (Stream bcdStream = destNtfs.OpenFile(@"\boot\BCD", FileMode.Open, FileAccess.ReadWrite))
                            {
                                using (RegistryHive hive = new RegistryHive(bcdStream))
                                {
                                    Store store = new Store(hive.Root);
                                    foreach (var obj in store.Objects)
                                    {
                                        foreach (var elem in obj.Elements)
                                        {
                                            if (elem.Format == DiscUtils.BootConfig.ElementFormat.Device)
                                            {
                                                elem.Value = DiscUtils.BootConfig.ElementValue.ForDevice(elem.Value.ParentObject, volMgr.GetPhysicalVolumes()[0]);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }