private VhdFile Create(Stream stream, string vhdDirectory) { var reader = new BinaryReader(stream, Encoding.Unicode); try { var dataReader = new VhdDataReader(reader); var footer = new VhdFooterFactory(dataReader).CreateFooter(); VhdHeader header = null; BlockAllocationTable blockAllocationTable = null; VhdFile parent = null; if (footer.DiskType != DiskType.Fixed) { header = new VhdHeaderFactory(dataReader, footer).CreateHeader(); blockAllocationTable = new BlockAllocationTableFactory(dataReader, header).Create(); if (footer.DiskType == DiskType.Differencing) { var parentPath = vhdDirectory == null ? header.ParentPath : Path.Combine(vhdDirectory, header.GetRelativeParentPath()); parent = Create(parentPath); } } return(new VhdFile(footer, header, blockAllocationTable, parent, stream)); } catch (EndOfStreamException) { throw new VhdParsingException("unsupported format"); } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="System.IO.InvalidDataException"></exception> /// <exception cref="System.NotImplementedException"></exception> /// <exception cref="System.UnauthorizedAccessException"></exception> public VirtualHardDisk(string virtualHardDiskPath) : base(virtualHardDiskPath) { // We can't read the VHD footer using this.ReadSector() because it's out of the disk boundaries m_file = new RawDiskImage(virtualHardDiskPath, BytesPerDiskSector); byte[] buffer = m_file.ReadSector(m_file.Size / BytesPerDiskSector - 1); m_vhdFooter = new VHDFooter(buffer); if (!m_vhdFooter.IsValid) { // check to see if a header is present (dynamic VHD) and use it instead buffer = m_file.ReadSector(0); m_vhdFooter = new VHDFooter(buffer); if (!m_vhdFooter.IsValid) { throw new InvalidDataException("Invalid VHD footer"); } } if (m_vhdFooter.DiskType == VirtualHardDiskType.Fixed) { } else if (m_vhdFooter.DiskType == VirtualHardDiskType.Dynamic) { buffer = m_file.ReadSectors(1, 2); m_dynamicHeader = new DynamicDiskHeader(buffer); m_blockAllocationTable = BlockAllocationTable.ReadBlockAllocationTable(virtualHardDiskPath, m_dynamicHeader); } else { throw new NotImplementedException("Differencing VHD is not supported"); } SetGeometry(); }
public void LoadHeaders(string filename) { try { this.Filename = filename; footer = new Footer(); footer.FromFile(filename); if (footer.DataOffset > 0) { dynamicHeader = new DynamicHeader(); dynamicHeader.FromFile(filename, (int)footer.DataOffset); blockAllocationTable = new BlockAllocationTable(dynamicHeader.TableOffset, dynamicHeader.BlockSize, dynamicHeader.MaxTableEntries); blockAllocationTable.FromFile(filename); masterBootRecord = new MasterBootRecord(blockAllocationTable); // ShowUsage(); // ShowDetailedUsage(); } else { masterBootRecord = new MasterBootRecord(filename, 0); // MessageBox.Show("So far all the good stuff involves Dynamic VHDs, so all you get is this pretty box really.", "Fixed VHD", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (VhdReadException ex) { this.vhdReadException = ex; } }
public DiskModel(Footer footer, DynamicHeader dynamicHeader, BlockAllocationTable blockAllocationTable, MasterBootRecord masterBootRecord) { // TODO: Complete member initialization this.footer = footer; this.dynamicHeader = dynamicHeader; this.blockAllocationTable = blockAllocationTable; this.masterBootRecord = masterBootRecord; }
private IEnumerable <CompletionPort> CreateAsync(AsyncMachine <VhdFile> machine, StreamSource streamSource) { var disposer = new Action(() => { if (streamSource.DisposeOnException) { streamSource.Stream.Dispose(); } }); var reader = TryCatch(() => new BinaryReader(streamSource.Stream, Encoding.Unicode), disposer); var dataReader = TryCatch(() => new VhdDataReader(reader), disposer); var footerFactory = TryCatch(() => new VhdFooterFactory(dataReader), disposer); footerFactory.BeginCreateFooter(machine.CompletionCallback, null); yield return(CompletionPort.SingleOperation); var footer = TryCatch <VhdFooter>(footerFactory.EndCreateFooter, disposer, machine.CompletionResult); VhdHeader header = null; BlockAllocationTable blockAllocationTable = null; VhdFile parent = null; if (footer.DiskType != DiskType.Fixed) { var headerFactory = new VhdHeaderFactory(dataReader, footer); headerFactory.BeginCreateHeader(machine.CompletionCallback, null); yield return(CompletionPort.SingleOperation); header = TryCatch <VhdHeader>(headerFactory.EndCreateHeader, disposer, machine.CompletionResult); var tableFactory = new BlockAllocationTableFactory(dataReader, header); tableFactory.BeginCreate(machine.CompletionCallback, null); yield return(CompletionPort.SingleOperation); blockAllocationTable = TryCatch <BlockAllocationTable>(tableFactory.EndCreate, disposer, machine.CompletionResult); if (footer.DiskType == DiskType.Differencing) { var parentPath = streamSource.VhdDirectory == null ? header.ParentPath : Path.Combine(streamSource.VhdDirectory, header.GetRelativeParentPath()); BeginCreate(parentPath, machine.CompletionCallback, null); yield return(CompletionPort.SingleOperation); parent = TryCatch <VhdFile>(EndCreate, disposer, machine.CompletionResult); } } machine.ParameterValue = new VhdFile(footer, header, blockAllocationTable, parent, streamSource.Stream); }
private VhdFile Create(StreamSource streamSource) { var disposer = new Action(() => { if (streamSource.DisposeOnException) { streamSource.Stream.Dispose(); } }); bool throwing = false; try { var reader = new BinaryReader(streamSource.Stream, Encoding.Unicode); var dataReader = new VhdDataReader(reader); var footer = new VhdFooterFactory(dataReader).CreateFooter(); VhdHeader header = null; BlockAllocationTable blockAllocationTable = null; VhdFile parent = null; if (footer.DiskType != DiskType.Fixed) { header = new VhdHeaderFactory(dataReader, footer).CreateHeader(); blockAllocationTable = new BlockAllocationTableFactory(dataReader, header).Create(); if (footer.DiskType == DiskType.Differencing) { string parentPath = GetParentPath(streamSource.VhdDirectory, header); parent = Create(parentPath); } } return(new VhdFile(footer, header, blockAllocationTable, parent, streamSource.Stream)); } catch (Exception e) { throwing = true; throw new VhdParsingException("unsupported format", e); } finally { if (throwing) { disposer(); } } }
/// <param name="diskSize">In bytes</param> /// <exception cref="System.IO.IOException"></exception> /// <exception cref="System.UnauthorizedAccessException"></exception> public static VirtualHardDisk CreateDynamicDisk(string path, long diskSize) { const int BlockSizeInBytes = 4096 * BytesPerDiskSector; if (diskSize % BlockSizeInBytes > 0) { // All blocks within a given image must be the same size throw new ArgumentException("Dynamic VHD disk size must be a multiple of 2MiB"); } VHDFooter footer = new VHDFooter(); footer.OriginalSize = (ulong)diskSize; footer.CurrentSize = (ulong)diskSize; footer.SetCurrentTimeStamp(); footer.SetDiskGeometry((ulong)diskSize / BytesPerDiskSector); footer.DiskType = VirtualHardDiskType.Dynamic; DynamicDiskHeader header = new DynamicDiskHeader(); header.TableOffset = VHDFooter.Length + DynamicDiskHeader.Length; header.BlockSize = BlockSizeInBytes; header.MaxTableEntries = (uint)Math.Ceiling((double)diskSize / BlockSizeInBytes); BlockAllocationTable blockAllocationTable = new BlockAllocationTable(header.MaxTableEntries); byte[] footerBytes = footer.GetBytes(); byte[] headerBytes = header.GetBytes(); byte[] blockAllocationTableBytes = blockAllocationTable.GetBytes(); int fileSize = VHDFooter.Length + DynamicDiskHeader.Length + blockAllocationTableBytes.Length + VHDFooter.Length; RawDiskImage diskImage = RawDiskImage.Create(path, fileSize, BytesPerDiskSector); diskImage.WriteSectors(0, footerBytes); diskImage.WriteSectors(1, headerBytes); diskImage.WriteSectors(3, blockAllocationTableBytes); diskImage.WriteSectors(fileSize / BytesPerDiskSector - 1, footerBytes); return(new VirtualHardDisk(path)); }