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); }
/// <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(); } } }
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 (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]); } } } } } } } } }