Пример #1
0
        /// <summary>
        /// Opens connection to file.
        /// </summary>
        /// <param name="fileAccess">Defines required access.</param>
        /// <param name="type">Disk type.</param>
        /// <exception cref="System.ComponentModel.Win32Exception">Native error.</exception>
        /// <exception cref="System.IO.FileNotFoundException">File not found.</exception>
        /// <exception cref="System.IO.InvalidDataException">File type not recognized.</exception>
        private void Open(VirtualDiskAccessMask fileAccess, VirtualDiskType type)
        {
            var parameters = new NativeMethods.OPEN_VIRTUAL_DISK_PARAMETERS();
            parameters.Version = NativeMethods.OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_1;
            parameters.Version1.RWDepth = NativeMethods.OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT;

            var storageType = new NativeMethods.VIRTUAL_STORAGE_TYPE();
            switch (type) {
                case VirtualDiskType.AutoDetect:
                    if (this.FileName.EndsWith(".iso", StringComparison.OrdinalIgnoreCase)) {
                        storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_ISO;
                        fileAccess = ((fileAccess & VirtualDiskAccessMask.GetInfo) == VirtualDiskAccessMask.GetInfo) ? VirtualDiskAccessMask.GetInfo : 0;
                        fileAccess |= VirtualDiskAccessMask.AttachReadOnly;
                        this.DiskType = VirtualDiskType.Iso;
                    } else if (this.FileName.EndsWith(".vhdx", StringComparison.OrdinalIgnoreCase)) {
                        storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
                        this.DiskType = VirtualDiskType.Vhdx;
                    } else {
                        storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHD;
                        this.DiskType = VirtualDiskType.Vhd;
                    }
                    break;

                case VirtualDiskType.Iso: storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_ISO;
                    fileAccess = ((fileAccess & VirtualDiskAccessMask.GetInfo) == VirtualDiskAccessMask.GetInfo) ? VirtualDiskAccessMask.GetInfo : 0;
                    fileAccess |= VirtualDiskAccessMask.AttachReadOnly;
                    this.DiskType = VirtualDiskType.Iso;
                    break;

                case VirtualDiskType.Vhd:
                    storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHD;
                    this.DiskType = VirtualDiskType.Vhd;
                    break;

                case VirtualDiskType.Vhdx:
                    storageType.DeviceId = NativeMethods.VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
                    this.DiskType = VirtualDiskType.Vhdx;
                    break;
            }
            storageType.VendorId = NativeMethods.VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT;

            int res = NativeMethods.OpenVirtualDisk(ref storageType, this.FileName, (NativeMethods.VIRTUAL_DISK_ACCESS_MASK)fileAccess, NativeMethods.OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NONE, ref parameters, ref _handle);
            if (res == NativeMethods.ERROR_SUCCESS) {
            } 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_ACCESS_DENIED) {
                    throw new IOException("Access is denied.");
                } else if (res == NativeMethods.ERROR_FILE_CORRUPT) {
                    throw new InvalidDataException("File type not recognized.");
                } else {
                    throw new Win32Exception(res);
                }
            }
        }
Пример #2
0
        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));
                }
            }
        }
Пример #3
0
        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);
                }
            }
        }
Пример #4
0
        public void Open()
        {
            var parameters = new NativeMethods.OPEN_VIRTUAL_DISK_PARAMETERS();
            parameters.Version = NativeMethods.OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_1;
            parameters.Version1.RWDepth = NativeMethods.OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT;

            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 = NativeMethods.OpenVirtualDisk(ref storageType, this.FileName, NativeMethods.VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ALL, NativeMethods.OPEN_VIRTUAL_DISK_FLAG.OPEN_VIRTUAL_DISK_FLAG_NONE, ref parameters, ref _handle);
            if (res == NativeMethods.ERROR_SUCCESS)
            {
            }
            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
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Native error {0}.", res));
                }
            }
        }