예제 #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");
            }
        }
        public VhdHeader CreateHeader()
        {
            if (footer.DiskType != DiskType.Dynamic && footer.DiskType != DiskType.Differencing)
            {
                return(null);
            }

            try
            {
                var attributeHelper = new AttributeHelper <VhdHeader>();
                var header          = new VhdHeader();
                header.Cookie          = ReadHeaderCookie(attributeHelper.GetAttribute(() => header.Cookie));
                header.DataOffset      = ReadDataOffset(attributeHelper.GetAttribute(() => header.DataOffset));
                header.TableOffset     = ReadBATOffset(attributeHelper.GetAttribute(() => header.TableOffset));
                header.HeaderVersion   = ReaderHeaderVersion(attributeHelper.GetAttribute(() => header.HeaderVersion));
                header.MaxTableEntries = ReadMaxTableEntries(attributeHelper.GetAttribute(() => header.MaxTableEntries));
                header.BlockSize       = ReadBlockSize(attributeHelper.GetAttribute(() => header.BlockSize));
                header.CheckSum        = ReadCheckSum(attributeHelper.GetAttribute(() => header.CheckSum));
                header.ParentUniqueId  = ReadParentUniqueId(attributeHelper.GetAttribute(() => header.ParentUniqueId));
                header.ParentTimeStamp = ReadParentTimeStamp(attributeHelper.GetAttribute(() => header.ParentTimeStamp));
                header.Reserverd1      = ReadReserved1(attributeHelper.GetAttribute(() => header.Reserverd1));
                header.ParentPath      = ReadParentPath(attributeHelper.GetAttribute(() => header.ParentPath));
                header.ParentLocators  = ReadParentLocators(attributeHelper.GetAttribute(() => header.ParentLocators));
                header.RawData         = ReadRawData(attributeHelper.GetAttribute(() => header.RawData));
                return(header);
            }
            catch (EndOfStreamException e)
            {
                throw new VhdParsingException("unsupported format", e);
            }
        }
예제 #3
0
        public static HardDisk Create(HardDisk hdd)
        {
            byte[]    headBytes = hdd.ReadBytes(hdd.Length - 512, 512);
            VhdHeader head      = Program.ToStructFromBigEndian <VhdHeader>(headBytes);

            if (head.CookieStr != "conectix")
            {
                throw new Exception("missing magic string");
            }
            if (head.FileFormatVersion != 0x00010000)
            {
                throw new Exception("upsupported version");
            }
            //TODO: validate checksum

            if (head.DiskType == DiskType.Fixed)
            {
                return(new FixedVhd(hdd, in head));
            }
            else if (head.DiskType == DiskType.Dynamic)
            {
                return(new DynamicVhd(hdd, in head));
            }
            else
            {
                throw new Exception("Only fixed size VHDs are supported.");
            }
        }
예제 #4
0
        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);
        }
예제 #5
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();
                }
            }
        }
예제 #6
0
        private string GetParentPath(string vhdDirectory, VhdHeader header)
        {
            string parentPath;

            if (vhdDirectory == null)
            {
                parentPath = vhdDirectory;
            }
            else
            {
                string relativeParentPath = header.GetRelativeParentPath();
                if (relativeParentPath != null)
                {
                    parentPath = Path.Combine(vhdDirectory, relativeParentPath);
                }
                else
                {
                    parentPath = header.GetAbsoluteParentPath();
                }
            }
            return(parentPath);
        }
 public BlockAllocationTableFactory(VhdDataReader dataReader, VhdHeader header)
 {
     this.dataReader = dataReader;
     this.header = header;
 }
 public BlockAllocationTableFactory(VhdDataReader dataReader, VhdHeader header)
 {
     this.dataReader = dataReader;
     this.header     = header;
 }
        private IEnumerable <CompletionPort> CreateVhdHeader(AsyncMachine <VhdHeader> machine)
        {
            if (footer.DiskType != DiskType.Dynamic && footer.DiskType != DiskType.Differencing)
            {
                machine.ParameterValue = null;
                yield break;
            }

            var attributeHelper = new AttributeHelper <VhdHeader>();
            var header          = new VhdHeader();

            BeginReadHeaderCookie(attributeHelper.GetAttribute(() => header.Cookie), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.Cookie = TryCatch <VhdCookie>(EndReadHeaderCookie, machine.CompletionResult);

            BeginReadDataOffset(attributeHelper.GetAttribute(() => header.DataOffset), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.DataOffset = TryCatch <long>(EndReadDataOffset, machine.CompletionResult);

            BeginReadBATOffset(attributeHelper.GetAttribute(() => header.TableOffset), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.TableOffset = TryCatch <long>(EndReadBATOffset, machine.CompletionResult);

            BeginReadHeaderVersion(attributeHelper.GetAttribute(() => header.HeaderVersion), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.HeaderVersion = TryCatch <VhdHeaderVersion>(EndReadHeaderVersion, machine.CompletionResult);

            BeginReadMaxTableEntries(attributeHelper.GetAttribute(() => header.MaxTableEntries), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.MaxTableEntries = TryCatch <uint>(EndReadMaxTableEntries, machine.CompletionResult);

            BeginReadBlockSize(attributeHelper.GetAttribute(() => header.BlockSize), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.BlockSize = TryCatch <uint>(EndReadBlockSize, machine.CompletionResult);

            BeginReadCheckSum(attributeHelper.GetAttribute(() => header.CheckSum), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.CheckSum = TryCatch <uint>(EndReadCheckSum, machine.CompletionResult);

            BeginReadParentUniqueId(attributeHelper.GetAttribute(() => header.ParentUniqueId), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.ParentUniqueId = TryCatch <Guid>(EndReadParentUniqueId, machine.CompletionResult);

            BeginReadParentTimeStamp(attributeHelper.GetAttribute(() => header.ParentTimeStamp), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.ParentTimeStamp = TryCatch <DateTime>(EndReadParentTimeStamp, machine.CompletionResult);

            BeginReadReserved1(attributeHelper.GetAttribute(() => header.Reserverd1), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.Reserverd1 = TryCatch <uint>(EndReadReserved1, machine.CompletionResult);

            BeginReadParentPath(attributeHelper.GetAttribute(() => header.ParentPath), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.ParentPath = TryCatch <string>(EndReadParentPath, machine.CompletionResult);

            BeginReadParentLocators(attributeHelper.GetAttribute(() => header.ParentLocators), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.ParentLocators = TryCatch <IList <ParentLocator> >(EndReadParentLocators, machine.CompletionResult);

            BeginReadRawData(attributeHelper.GetAttribute(() => header.RawData), machine.CompletionCallback, null);
            yield return(CompletionPort.SingleOperation);

            header.RawData = TryCatch <byte[]>(EndReadRawData, machine.CompletionResult);

            machine.ParameterValue = header;
        }