示例#1
0
        private static void InitializeDifferencingInternal(Stream stream, DiskImageFile parent, string parentAbsolutePath, string parentRelativePath, DateTime parentModificationTimeUtc)
        {
            Footer footer = new Footer(parent.Geometry, parent._footer.CurrentSize, FileType.Differencing);

            footer.DataOffset   = 512; // Offset of Dynamic Header
            footer.OriginalSize = parent._footer.OriginalSize;
            footer.UpdateChecksum();
            byte[] footerBlock = new byte[512];
            footer.ToBytes(footerBlock, 0);

            long tableOffset = 512 + 1024; // Footer + Header

            uint blockSize = (parent._dynamicHeader == null) ? DynamicHeader.DefaultBlockSize : parent._dynamicHeader.BlockSize;

            DynamicHeader dynamicHeader = new DynamicHeader(-1, tableOffset, blockSize, footer.CurrentSize);
            int           batSize       = (((dynamicHeader.MaxTableEntries * 4) + Utilities.SectorSize - 1) / Utilities.SectorSize) * Utilities.SectorSize;

            dynamicHeader.ParentUniqueId    = parent.UniqueId;
            dynamicHeader.ParentTimestamp   = parentModificationTimeUtc;
            dynamicHeader.ParentUnicodeName = Utilities.GetFileFromPath(parentAbsolutePath);
            dynamicHeader.ParentLocators[7].PlatformCode       = ParentLocator.PlatformCodeWindowsAbsoluteUnicode;
            dynamicHeader.ParentLocators[7].PlatformDataSpace  = 512;
            dynamicHeader.ParentLocators[7].PlatformDataLength = parentAbsolutePath.Length * 2;
            dynamicHeader.ParentLocators[7].PlatformDataOffset = tableOffset + batSize;
            dynamicHeader.ParentLocators[6].PlatformCode       = ParentLocator.PlatformCodeWindowsRelativeUnicode;
            dynamicHeader.ParentLocators[6].PlatformDataSpace  = 512;
            dynamicHeader.ParentLocators[6].PlatformDataLength = parentRelativePath.Length * 2;
            dynamicHeader.ParentLocators[6].PlatformDataOffset = tableOffset + batSize + 512;
            dynamicHeader.UpdateChecksum();
            byte[] dynamicHeaderBlock = new byte[1024];
            dynamicHeader.ToBytes(dynamicHeaderBlock, 0);

            byte[] platformLocator1 = new byte[512];
            Encoding.Unicode.GetBytes(parentAbsolutePath, 0, parentAbsolutePath.Length, platformLocator1, 0);
            byte[] platformLocator2 = new byte[512];
            Encoding.Unicode.GetBytes(parentRelativePath, 0, parentRelativePath.Length, platformLocator2, 0);

            byte[] bat = new byte[batSize];
            for (int i = 0; i < bat.Length; ++i)
            {
                bat[i] = 0xFF;
            }

            stream.Position = 0;
            stream.Write(footerBlock, 0, 512);
            stream.Write(dynamicHeaderBlock, 0, 1024);
            stream.Write(bat, 0, batSize);
            stream.Write(platformLocator1, 0, 512);
            stream.Write(platformLocator2, 0, 512);
            stream.Write(footerBlock, 0, 512);
        }
        internal override List<BuilderExtent> FixExtents(out long totalLength)
        {
            const int FooterSize = 512;
            const int DynHeaderSize = 1024;

            List<BuilderExtent> extents = new List<BuilderExtent>();

            _footer.DataOffset = FooterSize;

            DynamicHeader dynHeader = new DynamicHeader(-1, FooterSize + DynHeaderSize, _blockSize, _footer.CurrentSize);

            BlockAllocationTableExtent batExtent = new BlockAllocationTableExtent(FooterSize + DynHeaderSize, dynHeader.MaxTableEntries);

            long streamPos = batExtent.Start + batExtent.Length;

            foreach (var blockRange in StreamExtent.Blocks(_content.Extents, _blockSize))
            {
                for (int i = 0; i < blockRange.Count; ++i)
                {
                    long block = blockRange.Offset + i;
                    long blockStart = block * _blockSize;
                    DataBlockExtent dataExtent = new DataBlockExtent(streamPos, new SubStream(_content, blockStart, Math.Min(_blockSize, _content.Length - blockStart)));
                    extents.Add(dataExtent);

                    batExtent.SetEntry((int)block, (uint)(streamPos / Sizes.Sector));

                    streamPos += dataExtent.Length;
                }
            }

            _footer.UpdateChecksum();
            dynHeader.UpdateChecksum();

            byte[] footerBuffer = new byte[FooterSize];
            _footer.ToBytes(footerBuffer, 0);

            byte[] dynHeaderBuffer = new byte[DynHeaderSize];
            dynHeader.ToBytes(dynHeaderBuffer, 0);

            // Add footer (to end)
            extents.Add(new BuilderBufferExtent(streamPos, footerBuffer));
            totalLength = streamPos + FooterSize;

            extents.Insert(0, batExtent);
            extents.Insert(0, new BuilderBufferExtent(FooterSize, dynHeaderBuffer));
            extents.Insert(0, new BuilderBufferExtent(0, footerBuffer));

            return extents;
        }
示例#3
0
        internal override List <BuilderExtent> FixExtents(out long totalLength)
        {
            const int FooterSize    = 512;
            const int DynHeaderSize = 1024;

            List <BuilderExtent> extents = new List <BuilderExtent>();

            _footer.DataOffset = FooterSize;

            DynamicHeader dynHeader = new DynamicHeader(-1, FooterSize + DynHeaderSize, _blockSize, _footer.CurrentSize);

            BlockAllocationTableExtent batExtent = new BlockAllocationTableExtent(FooterSize + DynHeaderSize, dynHeader.MaxTableEntries);

            long streamPos = batExtent.Start + batExtent.Length;

            foreach (var blockRange in StreamExtent.Blocks(_content.Extents, _blockSize))
            {
                for (int i = 0; i < blockRange.Count; ++i)
                {
                    long            block      = blockRange.Offset + i;
                    long            blockStart = block * _blockSize;
                    DataBlockExtent dataExtent = new DataBlockExtent(streamPos, new SubStream(_content, blockStart, Math.Min(_blockSize, _content.Length - blockStart)));
                    extents.Add(dataExtent);

                    batExtent.SetEntry((int)block, (uint)(streamPos / Sizes.Sector));

                    streamPos += dataExtent.Length;
                }
            }

            _footer.UpdateChecksum();
            dynHeader.UpdateChecksum();

            byte[] footerBuffer = new byte[FooterSize];
            _footer.ToBytes(footerBuffer, 0);

            byte[] dynHeaderBuffer = new byte[DynHeaderSize];
            dynHeader.ToBytes(dynHeaderBuffer, 0);

            // Add footer (to end)
            extents.Add(new BuilderBufferExtent(streamPos, footerBuffer));
            totalLength = streamPos + FooterSize;

            extents.Insert(0, batExtent);
            extents.Insert(0, new BuilderBufferExtent(FooterSize, dynHeaderBuffer));
            extents.Insert(0, new BuilderBufferExtent(0, footerBuffer));

            return(extents);
        }
示例#4
0
 public DynamicHeader(DynamicHeader toCopy)
 {
     Cookie = toCopy.Cookie;
     DataOffset = toCopy.DataOffset;
     TableOffset = toCopy.TableOffset;
     HeaderVersion = toCopy.HeaderVersion;
     MaxTableEntries = toCopy.MaxTableEntries;
     BlockSize = toCopy.BlockSize;
     Checksum = toCopy.Checksum;
     ParentUniqueId = toCopy.ParentUniqueId;
     ParentTimestamp = toCopy.ParentTimestamp;
     ParentUnicodeName = toCopy.ParentUnicodeName;
     ParentLocators = new ParentLocator[toCopy.ParentLocators.Length];
     for (int i = 0; i < ParentLocators.Length; ++i)
     {
         ParentLocators[i] = new ParentLocator(toCopy.ParentLocators[i]);
     }
 }
示例#5
0
 public DynamicHeader(DynamicHeader toCopy)
 {
     Cookie            = toCopy.Cookie;
     DataOffset        = toCopy.DataOffset;
     TableOffset       = toCopy.TableOffset;
     HeaderVersion     = toCopy.HeaderVersion;
     MaxTableEntries   = toCopy.MaxTableEntries;
     BlockSize         = toCopy.BlockSize;
     Checksum          = toCopy.Checksum;
     ParentUniqueId    = toCopy.ParentUniqueId;
     ParentTimestamp   = toCopy.ParentTimestamp;
     ParentUnicodeName = toCopy.ParentUnicodeName;
     ParentLocators    = new ParentLocator[toCopy.ParentLocators.Length];
     for (int i = 0; i < ParentLocators.Length; ++i)
     {
         ParentLocators[i] = new ParentLocator(toCopy.ParentLocators[i]);
     }
 }
示例#6
0
        private uint CalculateChecksum()
        {
            DynamicHeader copy = new DynamicHeader(this);

            copy.Checksum = 0;

            byte[] asBytes = new byte[1024];
            copy.ToBytes(asBytes, 0);
            uint checksum = 0;

            foreach (uint value in asBytes)
            {
                checksum += value;
            }

            checksum = ~checksum;

            return(checksum);
        }
示例#7
0
        private void ReadHeaders()
        {
            long pos = _footer.DataOffset;

            while (pos != -1)
            {
                _fileStream.Position = pos;
                Header hdr = Header.FromStream(_fileStream);
                if (hdr.Cookie == DynamicHeader.HeaderCookie)
                {
                    _fileStream.Position = pos;
                    _dynamicHeader       = DynamicHeader.FromStream(_fileStream);
                    if (!_dynamicHeader.IsValid())
                    {
                        throw new IOException("Invalid Dynamic Disc Header");
                    }
                }

                pos = hdr.DataOffset;
            }
        }
示例#8
0
        public DynamicStream(Stream fileStream, DynamicHeader dynamicHeader, long length, SparseStream parentStream, Ownership ownsParentStream)
        {
            if (fileStream == null)
            {
                throw new ArgumentNullException("fileStream");
            }

            if (dynamicHeader == null)
            {
                throw new ArgumentNullException("dynamicHeader");
            }

            if (parentStream == null)
            {
                throw new ArgumentNullException("parentStream");
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", length, "Negative lengths not allowed");
            }

            _fileStream       = fileStream;
            _dynamicHeader    = dynamicHeader;
            _length           = length;
            _parentStream     = parentStream;
            _ownsParentStream = ownsParentStream;

            _blockBitmaps    = new byte[_dynamicHeader.MaxTableEntries][];
            _blockBitmapSize = (int)Utilities.RoundUp((_dynamicHeader.BlockSize / Utilities.SectorSize) / 8, Utilities.SectorSize);

            ReadBlockAllocationTable();

            // Detect where next block should go (cope if the footer is missing)
            _fileStream.Position = Utilities.RoundDown(_fileStream.Length, Utilities.SectorSize) - Utilities.SectorSize;
            byte[] footerBytes = Utilities.ReadFully(_fileStream, Utilities.SectorSize);
            Footer footer      = Footer.FromBytes(footerBytes, 0);

            _nextBlockStart = _fileStream.Position - (footer.IsValid() ? Utilities.SectorSize : 0);
        }
示例#9
0
        public DynamicStream(Stream fileStream, DynamicHeader dynamicHeader, long length, SparseStream parentStream, Ownership ownsParentStream)
        {
            if (fileStream == null)
            {
                throw new ArgumentNullException("fileStream");
            }

            if (dynamicHeader == null)
            {
                throw new ArgumentNullException("dynamicHeader");
            }

            if (parentStream == null)
            {
                throw new ArgumentNullException("parentStream");
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", length, "Negative lengths not allowed");
            }

            _fileStream = fileStream;
            _dynamicHeader = dynamicHeader;
            _length = length;
            _parentStream = parentStream;
            _ownsParentStream = ownsParentStream;

            _blockBitmaps = new byte[_dynamicHeader.MaxTableEntries][];
            _blockBitmapSize = (int)Utilities.RoundUp((_dynamicHeader.BlockSize / Utilities.SectorSize) / 8, Utilities.SectorSize);

            ReadBlockAllocationTable();

            // Detect where next block should go (cope if the footer is missing)
            _fileStream.Position = Utilities.RoundDown(_fileStream.Length, Utilities.SectorSize) - Utilities.SectorSize;
            byte[] footerBytes = Utilities.ReadFully(_fileStream, Utilities.SectorSize);
            Footer footer = Footer.FromBytes(footerBytes, 0);
            _nextBlockStart = _fileStream.Position - (footer.IsValid() ? Utilities.SectorSize : 0);
        }
示例#10
0
        private static void InitializeDynamicInternal(Stream stream, long capacity, Geometry geometry, long blockSize)
        {
            if (blockSize > uint.MaxValue || blockSize < 0)
            {
                throw new ArgumentOutOfRangeException("blockSize", "Must be in the range 0 to uint.MaxValue");
            }

            if (geometry == null)
            {
                geometry = Geometry.FromCapacity(capacity);
            }

            Footer footer = new Footer(geometry, capacity, FileType.Dynamic);

            footer.DataOffset = 512; // Offset of Dynamic Header
            footer.UpdateChecksum();
            byte[] footerBlock = new byte[512];
            footer.ToBytes(footerBlock, 0);

            DynamicHeader dynamicHeader = new DynamicHeader(-1, 1024 + 512, (uint)blockSize, capacity);

            dynamicHeader.UpdateChecksum();
            byte[] dynamicHeaderBlock = new byte[1024];
            dynamicHeader.ToBytes(dynamicHeaderBlock, 0);

            int batSize = (((dynamicHeader.MaxTableEntries * 4) + Utilities.SectorSize - 1) / Utilities.SectorSize) * Utilities.SectorSize;

            byte[] bat = new byte[batSize];
            for (int i = 0; i < bat.Length; ++i)
            {
                bat[i] = 0xFF;
            }

            stream.Position = 0;
            stream.Write(footerBlock, 0, 512);
            stream.Write(dynamicHeaderBlock, 0, 1024);
            stream.Write(bat, 0, batSize);
            stream.Write(footerBlock, 0, 512);
        }
示例#11
0
        public static DynamicHeader FromBytes(byte[] data, int offset)
        {
            DynamicHeader result = new DynamicHeader();

            result.Cookie            = Utilities.BytesToString(data, offset, 8);
            result.DataOffset        = Utilities.ToInt64BigEndian(data, offset + 8);
            result.TableOffset       = Utilities.ToInt64BigEndian(data, offset + 16);
            result.HeaderVersion     = Utilities.ToUInt32BigEndian(data, offset + 24);
            result.MaxTableEntries   = Utilities.ToInt32BigEndian(data, offset + 28);
            result.BlockSize         = Utilities.ToUInt32BigEndian(data, offset + 32);
            result.Checksum          = Utilities.ToUInt32BigEndian(data, offset + 36);
            result.ParentUniqueId    = Utilities.ToGuidBigEndian(data, offset + 40);
            result.ParentTimestamp   = Footer.EpochUtc.AddSeconds(Utilities.ToUInt32BigEndian(data, offset + 56));
            result.ParentUnicodeName = Encoding.BigEndianUnicode.GetString(data, offset + 64, 512).TrimEnd('\0');

            result.ParentLocators = new ParentLocator[8];
            for (int i = 0; i < 8; ++i)
            {
                result.ParentLocators[i] = ParentLocator.FromBytes(data, offset + 576 + (i * 24));
            }

            return(result);
        }
示例#12
0
        private void CheckDynamicHeader()
        {
            long lastHeaderEnd = _footer.DataOffset + 512;
            long pos           = _footer.DataOffset;

            while (pos != -1)
            {
                if ((pos % 512) != 0)
                {
                    ReportError("DynHeader: Unaligned header @{0}", pos);
                }

                _fileStream.Position = pos;
                Header hdr = Header.FromStream(_fileStream);

                if (hdr.Cookie == DynamicHeader.HeaderCookie)
                {
                    if (_dynamicHeader != null)
                    {
                        ReportError("DynHeader: Duplicate dynamic header found");
                    }

                    _fileStream.Position = pos;
                    _dynamicHeader       = DynamicHeader.FromStream(_fileStream);

                    if (pos + 1024 > lastHeaderEnd)
                    {
                        lastHeaderEnd = pos + 1024;
                    }
                }
                else
                {
                    ReportWarning("DynHeader: Undocumented header found, with cookie '" + hdr.Cookie + "'");

                    if (pos + 512 > lastHeaderEnd)
                    {
                        lastHeaderEnd = pos + 1024;
                    }
                }

                pos = hdr.DataOffset;
            }

            if (_dynamicHeader == null)
            {
                ReportError("DynHeader: No dynamic header found");
                return;
            }

            if (_dynamicHeader.TableOffset < lastHeaderEnd)
            {
                ReportError("DynHeader: BAT offset is before last header");
            }

            if ((_dynamicHeader.TableOffset % 512) != 0)
            {
                ReportError("DynHeader: BAT offset is not sector aligned");
            }

            if (_dynamicHeader.HeaderVersion != 0x00010000)
            {
                ReportError("DynHeader: Unrecognized header version");
            }

            if (_dynamicHeader.MaxTableEntries != Utilities.Ceil(_footer.CurrentSize, _dynamicHeader.BlockSize))
            {
                ReportError("DynHeader: Max table entries is invalid");
            }

            if ((_dynamicHeader.BlockSize != Sizes.OneMiB * 2) && (_dynamicHeader.BlockSize != Sizes.OneKiB * 512))
            {
                ReportWarning("DynHeader: Using non-standard block size '" + _dynamicHeader.BlockSize + "'");
            }

            if (!Utilities.IsPowerOfTwo(_dynamicHeader.BlockSize))
            {
                ReportError("DynHeader: Block size is not a power of 2");
            }

            if (!_dynamicHeader.IsChecksumValid())
            {
                ReportError("DynHeader: Invalid checksum");
            }

            if (_footer.DiskType == FileType.Dynamic && _dynamicHeader.ParentUniqueId != Guid.Empty)
            {
                ReportWarning("DynHeader: Parent Id is not null for dynamic disk");
            }
            else if (_footer.DiskType == FileType.Differencing && _dynamicHeader.ParentUniqueId == Guid.Empty)
            {
                ReportError("DynHeader: Parent Id is null for differencing disk");
            }

            if (_footer.DiskType == FileType.Differencing && _dynamicHeader.ParentTimestamp > DateTime.UtcNow)
            {
                ReportWarning("DynHeader: Parent timestamp is greater than current time");
            }
        }
示例#13
0
        private void CheckDynamicHeader()
        {
            long lastHeaderEnd = _footer.DataOffset + 512;
            long pos = _footer.DataOffset;
            while (pos != -1)
            {
                if ((pos % 512) != 0)
                {
                    ReportError("DynHeader: Unaligned header @{0}", pos);
                }

                _fileStream.Position = pos;
                Header hdr = Header.FromStream(_fileStream);

                if (hdr.Cookie == DynamicHeader.HeaderCookie)
                {
                    if (_dynamicHeader != null)
                    {
                        ReportError("DynHeader: Duplicate dynamic header found");
                    }

                    _fileStream.Position = pos;
                    _dynamicHeader = DynamicHeader.FromStream(_fileStream);

                    if (pos + 1024 > lastHeaderEnd)
                    {
                        lastHeaderEnd = pos + 1024;
                    }
                }
                else
                {
                    ReportWarning("DynHeader: Undocumented header found, with cookie '" + hdr.Cookie + "'");

                    if (pos + 512 > lastHeaderEnd)
                    {
                        lastHeaderEnd = pos + 1024;
                    }
                }

                pos = hdr.DataOffset;
            }

            if (_dynamicHeader == null)
            {
                ReportError("DynHeader: No dynamic header found");
                return;
            }

            if (_dynamicHeader.TableOffset < lastHeaderEnd)
            {
                ReportError("DynHeader: BAT offset is before last header");
            }

            if ((_dynamicHeader.TableOffset % 512) != 0)
            {
                ReportError("DynHeader: BAT offset is not sector aligned");
            }

            if (_dynamicHeader.HeaderVersion != 0x00010000)
            {
                ReportError("DynHeader: Unrecognized header version");
            }

            if (_dynamicHeader.MaxTableEntries != Utilities.Ceil(_footer.CurrentSize, _dynamicHeader.BlockSize))
            {
                ReportError("DynHeader: Max table entries is invalid");
            }

            if ((_dynamicHeader.BlockSize != Sizes.OneMiB * 2) && (_dynamicHeader.BlockSize != Sizes.OneKiB * 512))
            {
                ReportWarning("DynHeader: Using non-standard block size '" + _dynamicHeader.BlockSize + "'");
            }

            if (!Utilities.IsPowerOfTwo(_dynamicHeader.BlockSize))
            {
                ReportError("DynHeader: Block size is not a power of 2");
            }

            if (!_dynamicHeader.IsChecksumValid())
            {
                ReportError("DynHeader: Invalid checksum");
            }

            if (_footer.DiskType == FileType.Dynamic && _dynamicHeader.ParentUniqueId != Guid.Empty)
            {
                ReportWarning("DynHeader: Parent Id is not null for dynamic disk");
            }
            else if (_footer.DiskType == FileType.Differencing && _dynamicHeader.ParentUniqueId == Guid.Empty)
            {
                ReportError("DynHeader: Parent Id is null for differencing disk");
            }

            if (_footer.DiskType == FileType.Differencing && _dynamicHeader.ParentTimestamp > DateTime.UtcNow)
            {
                ReportWarning("DynHeader: Parent timestamp is greater than current time");
            }
        }
示例#14
0
 internal DiskImageFileInfo(Footer footer, DynamicHeader header, Stream vhdStream)
 {
     _footer    = footer;
     _header    = header;
     _vhdStream = vhdStream;
 }
示例#15
0
        private void ReadHeaders()
        {
            long pos = _footer.DataOffset;
            while (pos != -1)
            {
                _fileStream.Position = pos;
                Header hdr = Header.FromStream(_fileStream);
                if (hdr.Cookie == DynamicHeader.HeaderCookie)
                {
                    _fileStream.Position = pos;
                    _dynamicHeader = DynamicHeader.FromStream(_fileStream);
                    if (!_dynamicHeader.IsValid())
                    {
                        throw new IOException("Invalid Dynamic Disc Header");
                    }
                }

                pos = hdr.DataOffset;
            }
        }
示例#16
0
        private static void InitializeDifferencingInternal(Stream stream, DiskImageFile parent, string parentAbsolutePath, string parentRelativePath, DateTime parentModificationTimeUtc)
        {
            Footer footer = new Footer(parent.Geometry, parent._footer.CurrentSize, FileType.Differencing);
            footer.DataOffset = 512; // Offset of Dynamic Header
            footer.OriginalSize = parent._footer.OriginalSize;
            footer.UpdateChecksum();
            byte[] footerBlock = new byte[512];
            footer.ToBytes(footerBlock, 0);

            long tableOffset = 512 + 1024; // Footer + Header

            uint blockSize = (parent._dynamicHeader == null) ? DynamicHeader.DefaultBlockSize : parent._dynamicHeader.BlockSize;

            DynamicHeader dynamicHeader = new DynamicHeader(-1, tableOffset, blockSize, footer.CurrentSize);
            int batSize = (((dynamicHeader.MaxTableEntries * 4) + Utilities.SectorSize - 1) / Utilities.SectorSize) * Utilities.SectorSize;
            dynamicHeader.ParentUniqueId = parent.UniqueId;
            dynamicHeader.ParentTimestamp = parentModificationTimeUtc;
            dynamicHeader.ParentUnicodeName = Utilities.GetFileFromPath(parentAbsolutePath);
            dynamicHeader.ParentLocators[7].PlatformCode = ParentLocator.PlatformCodeWindowsAbsoluteUnicode;
            dynamicHeader.ParentLocators[7].PlatformDataSpace = 512;
            dynamicHeader.ParentLocators[7].PlatformDataLength = parentAbsolutePath.Length * 2;
            dynamicHeader.ParentLocators[7].PlatformDataOffset = tableOffset + batSize;
            dynamicHeader.ParentLocators[6].PlatformCode = ParentLocator.PlatformCodeWindowsRelativeUnicode;
            dynamicHeader.ParentLocators[6].PlatformDataSpace = 512;
            dynamicHeader.ParentLocators[6].PlatformDataLength = parentRelativePath.Length * 2;
            dynamicHeader.ParentLocators[6].PlatformDataOffset = tableOffset + batSize + 512;
            dynamicHeader.UpdateChecksum();
            byte[] dynamicHeaderBlock = new byte[1024];
            dynamicHeader.ToBytes(dynamicHeaderBlock, 0);

            byte[] platformLocator1 = new byte[512];
            Encoding.Unicode.GetBytes(parentAbsolutePath, 0, parentAbsolutePath.Length, platformLocator1, 0);
            byte[] platformLocator2 = new byte[512];
            Encoding.Unicode.GetBytes(parentRelativePath, 0, parentRelativePath.Length, platformLocator2, 0);

            byte[] bat = new byte[batSize];
            for (int i = 0; i < bat.Length; ++i)
            {
                bat[i] = 0xFF;
            }

            stream.Position = 0;
            stream.Write(footerBlock, 0, 512);
            stream.Write(dynamicHeaderBlock, 0, 1024);
            stream.Write(bat, 0, batSize);
            stream.Write(platformLocator1, 0, 512);
            stream.Write(platformLocator2, 0, 512);
            stream.Write(footerBlock, 0, 512);
        }
示例#17
0
        private static void InitializeDynamicInternal(Stream stream, long capacity, Geometry geometry, long blockSize)
        {
            if (blockSize > uint.MaxValue || blockSize < 0)
            {
                throw new ArgumentOutOfRangeException("blockSize", "Must be in the range 0 to uint.MaxValue");
            }

            if (geometry == null)
            {
                geometry = Geometry.FromCapacity(capacity);
            }

            Footer footer = new Footer(geometry, capacity, FileType.Dynamic);
            footer.DataOffset = 512; // Offset of Dynamic Header
            footer.UpdateChecksum();
            byte[] footerBlock = new byte[512];
            footer.ToBytes(footerBlock, 0);

            DynamicHeader dynamicHeader = new DynamicHeader(-1, 1024 + 512, (uint)blockSize, capacity);
            dynamicHeader.UpdateChecksum();
            byte[] dynamicHeaderBlock = new byte[1024];
            dynamicHeader.ToBytes(dynamicHeaderBlock, 0);

            int batSize = (((dynamicHeader.MaxTableEntries * 4) + Utilities.SectorSize - 1) / Utilities.SectorSize) * Utilities.SectorSize;
            byte[] bat = new byte[batSize];
            for (int i = 0; i < bat.Length; ++i)
            {
                bat[i] = 0xFF;
            }

            stream.Position = 0;
            stream.Write(footerBlock, 0, 512);
            stream.Write(dynamicHeaderBlock, 0, 1024);
            stream.Write(bat, 0, batSize);
            stream.Write(footerBlock, 0, 512);
        }
 internal DiskImageFileInfo(Footer footer, DynamicHeader header, Stream vhdStream)
 {
     _footer = footer;
     _header = header;
     _vhdStream = vhdStream;
 }
示例#19
0
        private uint CalculateChecksum()
        {
            DynamicHeader copy = new DynamicHeader(this);
            copy.Checksum = 0;

            byte[] asBytes = new byte[1024];
            copy.ToBytes(asBytes, 0);
            uint checksum = 0;
            foreach (uint value in asBytes)
            {
                checksum += value;
            }

            checksum = ~checksum;

            return checksum;
        }
示例#20
0
        public static DynamicHeader FromBytes(byte[] data, int offset)
        {
            DynamicHeader result = new DynamicHeader();
            result.Cookie = Utilities.BytesToString(data, offset, 8);
            result.DataOffset = Utilities.ToInt64BigEndian(data, offset + 8);
            result.TableOffset = Utilities.ToInt64BigEndian(data, offset + 16);
            result.HeaderVersion = Utilities.ToUInt32BigEndian(data, offset + 24);
            result.MaxTableEntries = Utilities.ToInt32BigEndian(data, offset + 28);
            result.BlockSize = Utilities.ToUInt32BigEndian(data, offset + 32);
            result.Checksum = Utilities.ToUInt32BigEndian(data, offset + 36);
            result.ParentUniqueId = Utilities.ToGuidBigEndian(data, offset + 40);
            result.ParentTimestamp = Footer.EpochUtc.AddSeconds(Utilities.ToUInt32BigEndian(data, offset + 56));
            result.ParentUnicodeName = Encoding.BigEndianUnicode.GetString(data, offset + 64, 512).TrimEnd('\0');

            result.ParentLocators = new ParentLocator[8];
            for (int i = 0; i < 8; ++i)
            {
                result.ParentLocators[i] = ParentLocator.FromBytes(data, offset + 576 + (i * 24));
            }

            return result;
        }