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