예제 #1
0
        /// <param name="size">In bytes</param>
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="System.UnauthorizedAccessException"></exception>
        public static VirtualHardDisk Create(string path, long size)
        {
            VHDFooter footer = new VHDFooter();

            footer.OriginalSize = (ulong)size;
            footer.CurrentSize  = (ulong)size;
            footer.SetCurrentTimeStamp();
            footer.SetDiskGeometry((ulong)size / BytesPerDiskSector);

            RawDiskImage diskImage = RawDiskImage.Create(path, size + VHDFooter.Length, BytesPerDiskSector);

            diskImage.WriteSectors(size / BytesPerDiskSector, footer.GetBytes());

            return(new VirtualHardDisk(path));
        }
예제 #2
0
        /// <param name="diskSize">In bytes</param>
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="System.UnauthorizedAccessException"></exception>
        public static VirtualHardDisk CreateFixedDisk(string path, long diskSize)
        {
            if (diskSize % BytesPerDiskSector > 0)
            {
                throw new ArgumentException("diskSize must be a multiple of sector size");
            }

            VHDFooter footer = new VHDFooter();

            footer.OriginalSize = (ulong)diskSize;
            footer.CurrentSize  = (ulong)diskSize;
            footer.SetCurrentTimeStamp();
            footer.SetDiskGeometry((ulong)diskSize / BytesPerDiskSector);

            RawDiskImage diskImage = RawDiskImage.Create(path, diskSize + VHDFooter.Length, BytesPerDiskSector);

            diskImage.WriteSectors(diskSize / BytesPerDiskSector, footer.GetBytes());

            return(new VirtualHardDisk(path));
        }
예제 #3
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));
        }
예제 #4
0
        /// <param name="length">In bytes</param>
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="System.UnauthorizedAccessException"></exception>
        public static VirtualHardDisk Create(string path, long length)
        {
            bool       hasManageVolumePrivilege = SecurityUtils.ObtainManageVolumePrivilege();
            FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);

            try
            {
                stream.SetLength(length + 512); // VHD footer is 512 bytes
                if (hasManageVolumePrivilege)
                {
                    FileStreamUtils.SetValidLength(stream, length + 512);
                }
            }
            catch (IOException)
            {
                stream.Close();
                try
                {
                    // Delete the incomplete file
                    File.Delete(path);
                }
                catch (IOException)
                {
                }
                throw;
            }

            VHDFooter footer = new VHDFooter();

            footer.OriginalSize = (ulong)length;
            footer.CurrentSize  = (ulong)length;
            footer.SetCurrentTimeStamp();
            footer.SetDiskGeometry((ulong)length / DiskImage.DEFAULT_BYTES_PER_SECTOR);
            stream.Seek(length, SeekOrigin.Begin);
            stream.Write(footer.GetBytes(), 0, VHDFooter.Length);
            stream.Close();
            return(new VirtualHardDisk(path));
        }