/// <summary> /// Opens a virtual hard disk (VHD) using the V2 of OpenVirtualDisk Win32 API for use, allowing you to explicitly specify OpenVirtualDiskFlags, /// Read/Write depth, and Access Mask information. /// </summary> /// <param name="filePath">The path and name of the Virtual Hard Disk file to open.</param> /// <param name="accessMask">Contains the bit mask for specifying access rights to a virtual hard disk (VHD). Default is All.</param> /// <param name="flags">An OpenVirtualDiskFlags object to modify the way the Virtual Hard Disk is opened. Default is Unknown.</param> /// <param name="virtualStorageDeviceType">VHD Format Version (VHD1 or VHD2)</param> /// <returns>VirtualHardDisk object</returns> public static VirtualHardDisk Open( string filePath, VIRTUAL_STORAGE_TYPE_DEVICE virtualStorageDeviceType, VIRTUAL_DISK_ACCESS_MASK accessMask = VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ALL, OPEN_VIRTUAL_DISK_FLAG flags = OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NONE) { if (filePath == null) { throw new ArgumentNullException(nameof(filePath)); } if (!File.Exists(filePath)) { throw new FileNotFoundException("The specified VHD was not found. Please check your path and try again.", filePath); } var openParams = new NativeMethods.OPEN_VIRTUAL_DISK_PARAMETERS(); openParams.Version = virtualStorageDeviceType == VIRTUAL_STORAGE_TYPE_DEVICE.VIRTUAL_STORAGE_TYPE_DEVICE_VHD ? NativeMethods.OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_1 : NativeMethods.OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_2; openParams.GetInfoOnly = false; var virtualStorageType = new NativeMethods.VIRTUAL_STORAGE_TYPE(); virtualStorageType.DeviceId = virtualStorageDeviceType; virtualStorageType.VendorId = virtualStorageDeviceType == VIRTUAL_STORAGE_TYPE_DEVICE.VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN ? NativeMethods.VirtualStorageTypeVendorUnknown : NativeMethods.VirtualStorageTypeVendorMicrosoft; int ret = NativeMethods.OpenVirtualDisk(ref virtualStorageType, filePath, accessMask, flags, ref openParams, out var handle); if (NativeMethods.ERROR_SUCCESS != ret) { throw new Win32Exception(ret); } return(new VirtualHardDisk(handle, filePath)); }
// // CREATE_VIRTUAL_DISK_VERSION_2 allows specifying a richer set a values and returns // a V2 handle. // // VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens. // // Valid BlockSize values are as follows (use 0 to indicate default value): // Fixed VHD: 0 // Dynamic VHD: 512kb, 2mb (default) // Differencing VHD: 512kb, 2mb (if parent is fixed, default is 2mb; if parent is dynamic or differencing, default is parent blocksize) // Fixed VHDX: 0 // Dynamic VHDX: 1mb, 2mb, 4mb, 8mb, 16mb, 32mb (default), 64mb, 128mb, 256mb // Differencing VHDX: 1mb, 2mb (default), 4mb, 8mb, 16mb, 32mb, 64mb, 128mb, 256mb // // Valid LogicalSectorSize values are as follows (use 0 to indicate default value): // VHD: 512 (default) // VHDX: 512 (for fixed or dynamic, default is 512; for differencing, default is parent logicalsectorsize), 4096 // // Valid PhysicalSectorSize values are as follows (use 0 to indicate default value): // VHD: 512 (default) // VHDX: 512, 4096 (for fixed or dynamic, default is 4096; for differencing, default is parent physicalsectorsize) // public static VirtualHardDisk CreateDisk( string filePath, ulong maximumSize, IntPtr overlapped, bool overwrite = false, string source = null, int blockSizeInBytes = 0, int sectorSizeInBytes = 0, int physicalSectorSizeInBytes = 0, CREATE_VIRTUAL_DISK_FLAG flags = CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE) { if (overwrite && File.Exists(filePath)) { File.Delete(filePath); } var createParams = new NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS_VERSION2(); createParams.Version = NativeMethods.CREATE_VIRTUAL_DISK_VERSION.CREATE_VIRTUAL_DISK_VERSION_2; //createParams.UniqueId = Guid.NewGuid(); createParams.MaximumSize = maximumSize; createParams.BlockSizeInBytes = blockSizeInBytes; createParams.SectorSizeInBytes = sectorSizeInBytes; createParams.PhysicalSectorSizeInBytes = physicalSectorSizeInBytes; createParams.ParentPath = null; createParams.SourcePath = source; createParams.OpenFlags = OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NONE; //createParams.ParentVirtualStorageType = new NativeMethods.VIRTUAL_STORAGE_TYPE(); //createParams.SourceVirtualStorageType = new NativeMethods.VIRTUAL_STORAGE_TYPE(); if (!NativeMethods.InitializeSecurityDescriptor(out var securityDescriptor, 1)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var virtualStorageType = new NativeMethods.VIRTUAL_STORAGE_TYPE(); virtualStorageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE.VIRTUAL_STORAGE_TYPE_DEVICE_VHDX; int ret = NativeMethods.CreateVirtualDisk( ref virtualStorageType, filePath, VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE, ref securityDescriptor, flags, 0, ref createParams, overlapped, out var handle); if (NativeMethods.ERROR_SUCCESS != ret && NativeMethods.ERROR_IO_PENDING != ret) { throw new Win32Exception(ret); } return(new VirtualHardDisk(handle, filePath)); }