private void Create(VirtualDiskType type, long size, VirtualDiskCreateOptions options, int blockSize, int sectorSize, bool createAsync) { var parameters = new NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS(); parameters.Version = NativeMethods.CREATE_VIRTUAL_DISK_VERSION.CREATE_VIRTUAL_DISK_VERSION_1; if (blockSize == 0) { //parameters.Version1.BlockSizeInBytes = NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE; //blocks if you set it parameters.Version1.BlockSizeInBytes = 0; } else { parameters.Version1.BlockSizeInBytes = blockSize; } parameters.Version1.MaximumSize = size; parameters.Version1.ParentPath = IntPtr.Zero; if (sectorSize == 0) { parameters.Version1.SectorSizeInBytes = NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_SECTOR_SIZE; } else { parameters.Version1.SectorSizeInBytes = sectorSize; } parameters.Version1.SourcePath = IntPtr.Zero; parameters.Version1.UniqueId = Guid.Empty; var storageType = new NativeMethods.VIRTUAL_STORAGE_TYPE(); switch (type) { case VirtualDiskType.AutoDetect: if (this.FileName.EndsWith(".iso", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Cannot create iso file."); } else if (this.FileName.EndsWith(".vhdx", StringComparison.OrdinalIgnoreCase)) { storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHDX; } else { storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHD; } break; case VirtualDiskType.Vhd: storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHD; break; case VirtualDiskType.Vhdx: storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHDX; break; case VirtualDiskType.Iso: throw new InvalidOperationException("Cannot create iso file."); } storageType.VendorId = NativeMethods.VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT; int res; if (createAsync) { this._createOverlapEvent = new ManualResetEvent(false); this._createOverlap = new NativeOverlapped(); this._createOverlap.OffsetLow = 0; this._createOverlap.OffsetHigh = 0; #pragma warning disable 0618 this._createOverlap.EventHandle = this._createOverlapEvent.Handle; #pragma warning restore 0618 res = NativeMethods.CreateVirtualDisk(ref storageType, this.FileName, NativeMethods.VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ALL, IntPtr.Zero, (NativeMethods.CREATE_VIRTUAL_DISK_FLAG)options, 0, ref parameters, ref _createOverlap, ref _handle); } else { res = NativeMethods.CreateVirtualDisk(ref storageType, this.FileName, NativeMethods.VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ALL, IntPtr.Zero, (NativeMethods.CREATE_VIRTUAL_DISK_FLAG)options, 0, ref parameters, IntPtr.Zero, ref _handle); } if (res == NativeMethods.ERROR_SUCCESS) { } else if (res == NativeMethods.ERROR_IO_PENDING) { } else { _handle.SetHandleAsInvalid(); if ((res == NativeMethods.ERROR_FILE_NOT_FOUND) || (res == NativeMethods.ERROR_PATH_NOT_FOUND)) { throw new FileNotFoundException("File not found."); } else if (res == NativeMethods.ERROR_FILE_CORRUPT) { throw new InvalidDataException("File type not recognized."); } else if (res == NativeMethods.ERROR_FILE_EXISTS) { throw new IOException("File already exists."); } else if (res == NativeMethods.ERROR_FILE_SYSTEM_LIMITATION) { throw new IOException("Virtual disk creation could not be completed due to a file system limitation."); } else if (res == NativeMethods.ERROR_INVALID_PARAMETER) { throw new ArgumentException("Invalid parameter.", "size"); } else { throw new Win32Exception(res); } } }
private void Create(long size, VirtualDiskCreateOptions options, int blockSize, int sectorSize, bool createAsync) { var parameters = new NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS(); parameters.Version = NativeMethods.CREATE_VIRTUAL_DISK_VERSION.CREATE_VIRTUAL_DISK_VERSION_1; if (blockSize == 0) { //parameters.Version1.BlockSizeInBytes = NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE; //blocks if you set it parameters.Version1.BlockSizeInBytes = 0; } else { parameters.Version1.BlockSizeInBytes = blockSize; } parameters.Version1.MaximumSize = size; parameters.Version1.ParentPath = IntPtr.Zero; if (sectorSize == 0) { parameters.Version1.SectorSizeInBytes = NativeMethods.CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_SECTOR_SIZE; } else { parameters.Version1.SectorSizeInBytes = sectorSize; } parameters.Version1.SourcePath = IntPtr.Zero; parameters.Version1.UniqueId = Guid.Empty; var storageType = new NativeMethods.VIRTUAL_STORAGE_TYPE(); storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHD; storageType.VendorId = NativeMethods.VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT; int res; if (createAsync) { this._createOverlapEvent = new ManualResetEvent(false); this._createOverlap = new NativeOverlapped(); this._createOverlap.OffsetLow = 0; this._createOverlap.OffsetHigh = 0; this._createOverlap.EventHandle = this._createOverlapEvent.Handle; res = NativeMethods.CreateVirtualDisk(ref storageType, this.FileName, NativeMethods.VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ALL, IntPtr.Zero, (NativeMethods.CREATE_VIRTUAL_DISK_FLAG)options, 0, ref parameters, ref _createOverlap, ref _handle); } else { res = NativeMethods.CreateVirtualDisk(ref storageType, this.FileName, NativeMethods.VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ALL, IntPtr.Zero, (NativeMethods.CREATE_VIRTUAL_DISK_FLAG)options, 0, ref parameters, IntPtr.Zero, ref _handle); } if (res == NativeMethods.ERROR_SUCCESS) { } else if (res == NativeMethods.ERROR_IO_PENDING) { } else { _handle.SetHandleAsInvalid(); if ((res == NativeMethods.ERROR_FILE_NOT_FOUND) || (res == NativeMethods.ERROR_PATH_NOT_FOUND)) { throw new System.IO.FileNotFoundException("File not found."); } else if (res == NativeMethods.ERROR_FILE_CORRUPT) { throw new System.IO.InvalidDataException("File format not recognized."); } else if (res == NativeMethods.ERROR_FILE_EXISTS) { throw new System.IO.IOException("File already exists."); } else if (res == NativeMethods.ERROR_INVALID_PARAMETER) { throw new System.ArgumentException("Invalid parameter.", "size"); } else { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Native error {0}.", res)); } } }