Пример #1
0
 /// <summary>
 /// Initializes a new instance of the Disk class.  Differencing disks are supported.
 /// </summary>
 /// <param name="file">The file containing the disk</param>
 /// <param name="ownsFile">Indicates if the new instance should control the lifetime of the file.</param>
 /// <param name="parentLocator">Object used to locate the parent disk</param>
 /// <param name="parentPath">Path to the parent disk (if required)</param>
 private Disk(DiskImageFile file, Ownership ownsFile, FileLocator parentLocator, string parentPath)
 {
     _files = new List <KDM.Tuple <DiskImageFile, Ownership> >();
     _files.Add(new KDM.Tuple <DiskImageFile, Ownership>(file, ownsFile));
     if (file.NeedsParent)
     {
         _files.Add(
             new KDM.Tuple <DiskImageFile, Ownership>(
                 new DiskImageFile(parentLocator, parentPath, FileAccess.Read),
                 Ownership.Dispose));
         ResolveFileChain();
     }
 }
Пример #2
0
        /// <summary>
        /// Initializes a stream as a differencing disk VHD file.
        /// </summary>
        /// <param name="stream">The stream to initialize.</param>
        /// <param name="ownsStream">Indicates if the new instance controls the lifetime of the <paramref name="stream"/>.</param>
        /// <param name="parent">The disk this file is a different from.</param>
        /// <param name="ownsParent">Indicates if the new instance controls the lifetime of the <paramref name="parent"/> file.</param>
        /// <param name="parentAbsolutePath">The full path to the parent disk.</param>
        /// <param name="parentRelativePath">The relative path from the new disk to the parent disk.</param>
        /// <param name="parentModificationTime">The time the parent disk's file was last modified (from file system).</param>
        /// <returns>An object that accesses the stream as a VHD file</returns>
        public static Disk InitializeDifferencing(
            Stream stream,
            Ownership ownsStream,
            DiskImageFile parent,
            Ownership ownsParent,
            string parentAbsolutePath,
            string parentRelativePath,
            DateTime parentModificationTime)
        {
            DiskImageFile file = DiskImageFile.InitializeDifferencing(stream, ownsStream, parent, parentAbsolutePath, parentRelativePath, parentModificationTime);

            return(new Disk(file, Ownership.Dispose, parent, ownsParent));
        }
Пример #3
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);
        }
Пример #4
0
        /// <summary>
        /// Creates a new VHD differencing disk file.
        /// </summary>
        /// <param name="path">The path to the new disk file</param>
        /// <param name="parentPath">The path to the parent disk file</param>
        /// <returns>An object that accesses the new file as a Disk</returns>
        public static Disk InitializeDifferencing(string path, string parentPath)
        {
            LocalFileLocator parentLocator  = new LocalFileLocator(Path.GetDirectoryName(parentPath));
            string           parentFileName = Path.GetFileName(parentPath);

            DiskImageFile newFile;

            using (DiskImageFile parent = new DiskImageFile(parentLocator, parentFileName, FileAccess.Read))
            {
                LocalFileLocator locator = new LocalFileLocator(Path.GetDirectoryName(path));
                newFile = parent.CreateDifferencing(locator, Path.GetFileName(path));
            }

            return(new Disk(newFile, Ownership.Dispose, parentLocator, parentFileName));
        }
Пример #5
0
 /// <summary>
 /// Initializes a new instance of the Disk class.  Differencing disks are supported.
 /// </summary>
 /// <param name="file">The file containing the disk</param>
 /// <param name="ownsFile">Indicates if the new instance should control the lifetime of the file.</param>
 /// <param name="parentFile">The file containing the disk's parent</param>
 /// <param name="ownsParent">Indicates if the new instance should control the lifetime of the parentFile</param>
 private Disk(DiskImageFile file, Ownership ownsFile, DiskImageFile parentFile, Ownership ownsParent)
 {
     _files = new List <KDM.Tuple <DiskImageFile, Ownership> >();
     _files.Add(new KDM.Tuple <DiskImageFile, Ownership>(file, ownsFile));
     if (file.NeedsParent)
     {
         _files.Add(new KDM.Tuple <DiskImageFile, Ownership>(parentFile, ownsParent));
         ResolveFileChain();
     }
     else
     {
         if (parentFile != null && ownsParent == Ownership.Dispose)
         {
             parentFile.Dispose();
         }
     }
 }
Пример #6
0
        internal static DiskImageFile InitializeDynamic(FileLocator locator, string path, long capacity, Geometry geometry, long blockSize)
        {
            DiskImageFile result = null;
            Stream        stream = locator.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None);

            try
            {
                InitializeDynamicInternal(stream, capacity, geometry, blockSize);
                result = new DiskImageFile(locator, path, stream, Ownership.Dispose);
                stream = null;
            }
            finally
            {
                if (stream != null)
                {
                    stream.Dispose();
                }
            }

            return(result);
        }
Пример #7
0
 internal static Disk InitializeDynamic(FileLocator fileLocator, string path, long capacity, Geometry geometry, long blockSize)
 {
     return(new Disk(DiskImageFile.InitializeDynamic(fileLocator, path, capacity, geometry, blockSize), Ownership.Dispose));
 }
Пример #8
0
 internal static Disk InitializeFixed(FileLocator fileLocator, string path, long capacity, Geometry geometry)
 {
     return(new Disk(DiskImageFile.InitializeFixed(fileLocator, path, capacity, geometry), Ownership.Dispose));
 }
Пример #9
0
 /// <summary>
 /// Initializes a stream as a dynamically-sized VHD file.
 /// </summary>
 /// <param name="stream">The stream to initialize.</param>
 /// <param name="ownsStream">Indicates if the new instance controls the lifetime of the stream.</param>
 /// <param name="capacity">The desired capacity of the new disk</param>
 /// <param name="blockSize">The size of each block (unit of allocation)</param>
 /// <returns>An object that accesses the stream as a VHD file</returns>
 public static Disk InitializeDynamic(Stream stream, Ownership ownsStream, long capacity, long blockSize)
 {
     return(new Disk(DiskImageFile.InitializeDynamic(stream, ownsStream, capacity, blockSize), Ownership.Dispose));
 }
Пример #10
0
 /// <summary>
 /// Initializes a stream as a dynamically-sized VHD file.
 /// </summary>
 /// <param name="stream">The stream to initialize.</param>
 /// <param name="ownsStream">Indicates if the new instance controls the lifetime of the stream.</param>
 /// <param name="capacity">The desired capacity of the new disk</param>
 /// <param name="geometry">The desired geometry of the new disk, or <c>null</c> for default</param>
 /// <returns>An object that accesses the stream as a VHD file</returns>
 public static Disk InitializeDynamic(Stream stream, Ownership ownsStream, long capacity, Geometry geometry)
 {
     return(new Disk(DiskImageFile.InitializeDynamic(stream, ownsStream, capacity, geometry), Ownership.Dispose));
 }
Пример #11
0
 /// <summary>
 /// Initializes a new instance of the Disk class.  Differencing disks are not supported.
 /// </summary>
 /// <param name="file">The file containing the disk</param>
 /// <param name="ownsFile">Indicates if the new instance should control the lifetime of the file.</param>
 private Disk(DiskImageFile file, Ownership ownsFile)
 {
     _files = new List <KDM.Tuple <DiskImageFile, Ownership> >();
     _files.Add(new KDM.Tuple <DiskImageFile, Ownership>(file, ownsFile));
     ResolveFileChain();
 }