Beispiel #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 + Sizes.Sector - 1) / Sizes.Sector *
                                          Sizes.Sector;

            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);
        }
Beispiel #2
0
        private uint CalculateChecksum()
        {
            Footer copy = new Footer(this);

            copy.Checksum = 0;

            byte[] asBytes = new byte[512];
            copy.ToBytes(asBytes, 0);
            uint Checksum = 0;

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

            return(Checksum);
        }
Beispiel #3
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);

                // Backwards compatibility - if the geometry isn't specified, make the actual capacity a
                // multiple of the disk geometry's cylinder capacity.
                long cylinderSize = geometry.BytesPerSector * (long)geometry.SectorsPerTrack * geometry.HeadsPerCylinder;
                capacity = (capacity / cylinderSize) * cylinderSize;
            }

            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);
        }
        private static void InitializeFixedInternal(Stream stream, long capacity, Geometry geometry)
        {
            if (geometry == null)
            {
                geometry = Geometry.FromCapacity(capacity);
            }

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

            footer.UpdateChecksum();

            byte[] sector = new byte[Utilities.SectorSize];
            footer.ToBytes(sector, 0);
            stream.Position = Utilities.RoundUp(capacity, Utilities.SectorSize);
            stream.Write(sector, 0, sector.Length);
            stream.SetLength(stream.Position);

            stream.Position = 0;
        }
Beispiel #5
0
        /// <summary>
        /// Initiates the build process.
        /// </summary>
        /// <param name="baseName">The base name for the VHD, for example 'foo' to create 'foo.vhd'.</param>
        /// <returns>A set of one or more logical files that constitute the VHD.  The first file is
        /// the 'primary' file that is normally attached to VMs.</returns>
        public override DiskImageFileSpecification[] Build(string baseName)
        {
            if (string.IsNullOrEmpty(baseName))
            {
                throw new ArgumentException("Invalid base file name", nameof(baseName));
            }

            if (Content == null)
            {
                throw new InvalidOperationException("No content stream specified");
            }

            List <DiskImageFileSpecification> fileSpecs = new List <DiskImageFileSpecification>();

            Geometry geometry = Geometry ?? Geometry.FromCapacity(Content.Length);

            Footer footer = new Footer(geometry, Content.Length, DiskType);

            if (DiskType == FileType.Fixed)
            {
                footer.UpdateChecksum();

                byte[] footerSector = new byte[Sizes.Sector];
                footer.ToBytes(footerSector, 0);

                SparseStream footerStream = SparseStream.FromStream(new MemoryStream(footerSector, false),
                                                                    Ownership.None);
                Stream imageStream = new ConcatStream(Ownership.None, Content, footerStream);
                fileSpecs.Add(new DiskImageFileSpecification(baseName + ".vhd",
                                                             new PassthroughStreamBuilder(imageStream)));
            }
            else if (DiskType == FileType.Dynamic)
            {
                fileSpecs.Add(new DiskImageFileSpecification(baseName + ".vhd",
                                                             new DynamicDiskBuilder(Content, footer, (uint)Sizes.OneMiB * 2)));
            }
            else
            {
                throw new InvalidOperationException("Only Fixed and Dynamic disk types supported");
            }

            return(fileSpecs.ToArray());
        }
Beispiel #6
0
        /// <summary>
        /// Initiates the build process.
        /// </summary>
        /// <param name="baseName">The base name for the VHD, for example 'foo' to create 'foo.vhd'.</param>
        /// <returns>A set of one or more logical files that constitute the VHD.  The first file is
        /// the 'primary' file that is normally attached to VMs.</returns>
        public override DiskImageFileSpecification[] Build(string baseName)
        {
            if (string.IsNullOrEmpty(baseName))
            {
                throw new ArgumentException("Invalid base file name", "baseName");
            }

            if (Content == null)
            {
                throw new InvalidOperationException("No content stream specified");
            }

            List<DiskImageFileSpecification> fileSpecs = new List<DiskImageFileSpecification>();

            Geometry geometry = Geometry ?? Geometry.FromCapacity(Content.Length);

            Footer footer = new Footer(geometry, Content.Length, DiskType);

            if (_diskType == FileType.Fixed)
            {
                footer.UpdateChecksum();

                byte[] footerSector = new byte[Sizes.Sector];
                footer.ToBytes(footerSector, 0);

                SparseStream footerStream = SparseStream.FromStream(new MemoryStream(footerSector, false), Ownership.None);
                Stream imageStream = new ConcatStream(Ownership.None, Content, footerStream);
                fileSpecs.Add(new DiskImageFileSpecification(baseName + ".vhd", new PassthroughStreamBuilder(imageStream)));
            }
            else if (_diskType == FileType.Dynamic)
            {
                fileSpecs.Add(new DiskImageFileSpecification(baseName + ".vhd",  new DynamicDiskBuilder(Content, footer, (uint)Sizes.OneMiB * 2)));
            }
            else
            {
                throw new InvalidOperationException("Only Fixed and Dynamic disk types supported");
            }

            return fileSpecs.ToArray();
        }
Beispiel #7
0
        private static void InitializeDynamicInternal(Stream stream, long capacity, Geometry geometry, long blockSize)
        {
            if (blockSize > uint.MaxValue || blockSize < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(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 + Sizes.Sector - 1) / Sizes.Sector *
                          Sizes.Sector;

            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);
        }
Beispiel #8
0
        private static void InitializeFixedInternal(Stream stream, long capacity, Geometry geometry)
        {
            if (geometry == null)
            {
                geometry = Geometry.FromCapacity(capacity);

                // This is to maintain legacy behaviour - if no geometry specified, we make the actual capacity exactly
                // fit the disk geometry, rather than allowing it to be different.
                capacity = geometry.Capacity;
            }

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

            footer.UpdateChecksum();

            byte[] sector = new byte[Utilities.SectorSize];
            footer.ToBytes(sector, 0);
            stream.Position = Utilities.RoundUp(capacity, Utilities.SectorSize);
            stream.Write(sector, 0, sector.Length);
            stream.SetLength(stream.Position);

            stream.Position = 0;
        }
Beispiel #9
0
        private static void InitializeFixedInternal(Stream stream, long capacity, Geometry geometry)
        {
            if (geometry == null)
            {
                geometry = Geometry.FromCapacity(capacity);
            }

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

            byte[] sector = new byte[Utilities.SectorSize];
            footer.ToBytes(sector, 0);
            stream.Position = Utilities.RoundUp(capacity, Utilities.SectorSize);
            stream.Write(sector, 0, sector.Length);
            stream.SetLength(stream.Position);

            stream.Position = 0;
        }
Beispiel #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);
        }
Beispiel #11
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);
        }
Beispiel #12
0
        private uint CalculateChecksum()
        {
            Footer copy = new Footer(this);
            copy.Checksum = 0;

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

            checksum = ~checksum;

            return checksum;
        }
Beispiel #13
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);

                // Backwards compatibility - if the geometry isn't specified, make the actual capacity a
                // multiple of the disk geometry's cylinder capacity.
                long cylinderSize = geometry.BytesPerSector * (long)geometry.SectorsPerTrack * geometry.HeadsPerCylinder;
                capacity = (capacity / cylinderSize) * cylinderSize;
            }

            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);
        }
Beispiel #14
0
        private static void InitializeFixedInternal(Stream stream, long capacity, Geometry geometry)
        {
            if (geometry == null)
            {
                geometry = Geometry.FromCapacity(capacity);

                // This is to maintain legacy behaviour - if no geometry specified, we make the actual capacity exactly
                // fit the disk geometry, rather than allowing it to be different.
                capacity = geometry.Capacity;
            }

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

            byte[] sector = new byte[Utilities.SectorSize];
            footer.ToBytes(sector, 0);
            stream.Position = Utilities.RoundUp(capacity, Utilities.SectorSize);
            stream.Write(sector, 0, sector.Length);
            stream.SetLength(stream.Position);

            stream.Position = 0;
        }