diff --git a/PInvoke/Kernel32/IoApiSet.cs b/PInvoke/Kernel32/IoApiSet.cs index af5caf81..c167726c 100644 --- a/PInvoke/Kernel32/IoApiSet.cs +++ b/PInvoke/Kernel32/IoApiSet.cs @@ -612,15 +612,18 @@ namespace Vanara.PInvoke /// /// The data returned by the operation. The format of this data depends on the value of the dwIoControlCode parameter. /// + /// + /// The amount of memory to allocate for retrieval. If this value is 0, then initialize the default structure. + /// /// true if successful. [PInvokeData("Winbase.h", MSDNShortId = "aa363216")] - public static bool DeviceIoControl(HFILE hDev, uint ioControlCode, TIn inVal, out TOut outVal) where TIn : struct where TOut : struct + public static bool DeviceIoControl(HFILE hDev, uint ioControlCode, TIn inVal, out TOut outVal, SizeT outSz = default) where TIn : struct where TOut : struct { - using SafeHGlobalHandle ptrIn = SafeHGlobalHandle.CreateFromStructure(inVal), ptrOut = SafeHGlobalHandle.CreateFromStructure(); + using SafeHGlobalHandle ptrIn = SafeHGlobalHandle.CreateFromStructure(inVal), ptrOut = outSz == 0 ? SafeHGlobalHandle.CreateFromStructure() : new(outSz); var ret = DeviceIoControl(hDev, ioControlCode, ptrIn, ptrIn.Size, ptrOut, ptrOut.Size, out var bRet, IntPtr.Zero); if (!ret && Win32Error.GetLastError() == Win32Error.ERROR_INSUFFICIENT_BUFFER) { - ptrOut.Size = bRet; + ptrOut.Size = bRet == 0 ? ptrOut.Size * 16 : bRet; ret = DeviceIoControl(hDev, ioControlCode, ptrIn, ptrIn.Size, ptrOut, ptrOut.Size, out bRet, IntPtr.Zero); } outVal = ret ? ptrOut.ToStructure() : default; @@ -642,11 +645,14 @@ namespace Vanara.PInvoke /// /// The data returned by the operation. The format of this data depends on the value of the dwIoControlCode parameter. /// + /// + /// The amount of memory to allocate for retrieval. If this value is 0, then initialize the default structure. + /// /// true if successful. [PInvokeData("Winbase.h", MSDNShortId = "aa363216")] - public static bool DeviceIoControl(HFILE hDev, uint ioControlCode, out TOut outVal) where TOut : struct + public static bool DeviceIoControl(HFILE hDev, uint ioControlCode, out TOut outVal, SizeT outSz = default) where TOut : struct { - using var ptrOut = SafeHGlobalHandle.CreateFromStructure(); + using var ptrOut = outSz == 0 ? SafeHGlobalHandle.CreateFromStructure() : new(outSz); var ret = DeviceIoControl(hDev, ioControlCode, IntPtr.Zero, 0, ptrOut, ptrOut.Size, out var bRet, IntPtr.Zero); var err = Win32Error.GetLastError(); if (!ret && err == Win32Error.ERROR_INSUFFICIENT_BUFFER) diff --git a/PInvoke/Kernel32/WinIOCtl.Enums.cs b/PInvoke/Kernel32/WinIOCtl.Enums.cs index 3a69a151..0adcbc70 100644 --- a/PInvoke/Kernel32/WinIOCtl.Enums.cs +++ b/PInvoke/Kernel32/WinIOCtl.Enums.cs @@ -2120,7 +2120,7 @@ namespace Vanara.PInvoke public enum STORAGE_PROPERTY_ID { /// Indicates that the caller is querying for the device descriptor, STORAGE_DEVICE_DESCRIPTOR. - [CorrespondingType(typeof(STORAGE_DEVICE_DESCRIPTOR))] + [CorrespondingType(typeof(STORAGE_DEVICE_DESCRIPTOR_MGD))] StorageDeviceProperty = 0, /// Indicates that the caller is querying for the adapter descriptor, STORAGE_ADAPTER_DESCRIPTOR. @@ -2139,7 +2139,7 @@ namespace Vanara.PInvoke /// the STORAGE_DEVICE_UNIQUE_IDENTIFIER structure (see the storduid.h header in the DDK). Windows Server 2003 and Windows XP: /// This value is not supported before Windows Vista and Windows Server 2008. /// - [CorrespondingType(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER))] + [CorrespondingType(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD))] StorageDeviceUniqueIdProperty, /// diff --git a/PInvoke/Kernel32/WinIOCtl.STORAGE_DEVICE_MANAGEMENT_STATUS.cs b/PInvoke/Kernel32/WinIOCtl.STORAGE_DEVICE_MANAGEMENT_STATUS.cs index 8f908540..172064b3 100644 --- a/PInvoke/Kernel32/WinIOCtl.STORAGE_DEVICE_MANAGEMENT_STATUS.cs +++ b/PInvoke/Kernel32/WinIOCtl.STORAGE_DEVICE_MANAGEMENT_STATUS.cs @@ -1,9 +1,10 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; +using Vanara.Extensions; using Vanara.InteropServices; namespace Vanara.PInvoke; -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public static partial class Kernel32 { private const int STORAGE_ADAPTER_SERIAL_NUMBER_V1_MAX_LENGTH = 128; @@ -84,6 +85,40 @@ public static partial class Kernel32 public string SerialNumber; } + /// The STORAGE_DEVICE_LAYOUT_SIGNATURE structure defines a device layout structure. + [PInvokeData("storduid.h", MSDNShortId = "NS:storduid._STORAGE_DEVICE_LAYOUT_SIGNATURE")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_LAYOUT_SIGNATURE + { + /// The version of the DUID. + public uint Version; + + /// The size, in bytes, of this STORAGE_DEVICE_LAYOUT_SIGNATURE structure. + public uint Size; + + /// + /// A Boolean value that indicates whether the partition table of the disk is formatted with a master boot record (MBR). If TRUE, the + /// partition table of the disk is formatted with a master boot record (MBR). If FALSE, the disk has a GUID partition table (GPT). + /// + public bool Mbr; + + /// The device specific info. + public DEVICESPECIFIC DeviceSpecific; + + /// The device specific info. + [StructLayout(LayoutKind.Explicit)] + public struct DEVICESPECIFIC + { + /// The signature value, which uniquely identifies the disk. + [FieldOffset(0)] + public uint MbrSignature; + + /// The GUID that uniquely identifies the disk. + [FieldOffset(0)] + public Guid GptDiskId; + } + } + /// Structure for STORAGE_PROPERTY_ID.StorageDeviceManagementStatus [PInvokeData("winioctl.h")] [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfAdditionalReasons))] @@ -125,29 +160,27 @@ public static partial class Kernel32 // _STORAGE_DEVICE_UNIQUE_IDENTIFIER { ULONG Version; ULONG Size; ULONG StorageDeviceIdOffset; ULONG StorageDeviceOffset; ULONG // DriveLayoutSignatureOffset; } STORAGE_DEVICE_UNIQUE_IDENTIFIER, *PSTORAGE_DEVICE_UNIQUE_IDENTIFIER; [PInvokeData("storduid.h", MSDNShortId = "NS:storduid._STORAGE_DEVICE_UNIQUE_IDENTIFIER")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct STORAGE_DEVICE_UNIQUE_IDENTIFIER + [VanaraMarshaler(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER_Marshaler))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD { /// The version of the DUID. public uint Version; - /// The size, in bytes, of the identifier header and the identifiers (IDs) that follow the header. - public uint Size; + /// + /// The offset, in bytes, from the beginning of the header to the device ID descriptor ( ). + /// The device ID descriptor contains the IDs that are extracted from page 0x83 of the device's vital product data (VPD). + /// + public STORAGE_DEVICE_ID_DESCRIPTOR StorageDeviceId; /// - /// The offset, in bytes, from the beginning of the header to the device ID descriptor (STORAGE_DEVICE_ID_DESCRIPTOR). The device ID - /// descriptor contains the IDs that are extracted from page 0x83 of the device's vital product data (VPD). + /// The offset, in bytes, from the beginning of the header to the device descriptor ( ). The + /// device descriptor contains IDs that are extracted from non-VPD inquiry data. /// - public uint StorageDeviceIdOffset; + public STORAGE_DEVICE_DESCRIPTOR_MGD StorageDevice; - /// - /// The offset, in bytes, from the beginning of the header to the device descriptor (STORAGE_DEVICE_DESCRIPTOR). The device - /// descriptor contains IDs that are extracted from non-VPD inquiry data. - /// - public uint StorageDeviceOffset; - - /// The offset, in bytes, to the drive layout signature (STORAGE_DEVICE_LAYOUT_SIGNATURE). - public uint DriveLayoutSignatureOffset; + /// The offset, in bytes, to the drive layout signature ( ). + public STORAGE_DEVICE_LAYOUT_SIGNATURE DriveLayoutSignature; } /// Additional reasons. @@ -201,4 +234,38 @@ public static partial class Kernel32 public uint AsUlong; } } + + [StructLayout(LayoutKind.Sequential)] + private struct STORAGE_DEVICE_UNIQUE_IDENTIFIER + { + public uint Version; + + public uint Size; + + public uint StorageDeviceIdOffset; + + public uint StorageDeviceOffset; + + public uint DriveLayoutSignatureOffset; + } + + private class STORAGE_DEVICE_UNIQUE_IDENTIFIER_Marshaler : IVanaraMarshaler + { + SizeT IVanaraMarshaler.GetNativeSize() => Marshal.SizeOf(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER)); + + SafeAllocatedMemoryHandle IVanaraMarshaler.MarshalManagedToNative(object managedObject) => new SafeCoTaskMemHandle(1024); + + object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes) + { + if (pNativeData == IntPtr.Zero) return null; + STORAGE_DEVICE_UNIQUE_IDENTIFIER sdd = (STORAGE_DEVICE_UNIQUE_IDENTIFIER)Marshal.PtrToStructure(pNativeData, typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER))!; + return new STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD + { + Version = sdd.Version, + StorageDeviceId = sdd.StorageDeviceIdOffset == 0 ? default : pNativeData.ToStructure(allocatedBytes, (int)sdd.StorageDeviceIdOffset), + StorageDevice = sdd.StorageDeviceOffset == 0 ? default : pNativeData.ToStructure(allocatedBytes, (int)sdd.StorageDeviceOffset), + DriveLayoutSignature = sdd.DriveLayoutSignatureOffset == 0 ? default : pNativeData.ToStructure(allocatedBytes, (int)sdd.DriveLayoutSignatureOffset), + }; + } + } } \ No newline at end of file diff --git a/PInvoke/Kernel32/WinIOCtl.Structs2.cs b/PInvoke/Kernel32/WinIOCtl.Structs2.cs index c6ae97be..2c0a9d52 100644 --- a/PInvoke/Kernel32/WinIOCtl.Structs2.cs +++ b/PInvoke/Kernel32/WinIOCtl.Structs2.cs @@ -1,6982 +1,7035 @@ -using System; +#nullable enable +using System; using System.Linq; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; -using static Vanara.PInvoke.Kernel32; -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +public static partial class Kernel32 { - public static partial class Kernel32 + /* + https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ + */ + + /// + public const uint CSV_NAMESPACE_INFO_V1 = 24; + + /// + public const int FILE_STORAGE_TIER_DESCRIPTION_LENGTH = 512; + + /// + public const int FILE_STORAGE_TIER_NAME_LENGTH = 256; + + /// + public const int MAX_VOLUME_ID_SIZE = 36; + + /// + public const int MAX_VOLUME_TEMPLATE_SIZE = 40; + + /// + public const int PRODUCT_ID_LENGTH = 16; + + /// + public const ushort REQUEST_OPLOCK_CURRENT_VERSION = 1; + + /// + public const int REVISION_LENGTH = 4; + + /// + public const int SERIAL_NUMBER_LENGTH = 32; + + /// + public const int STORAGE_OFFLOAD_TOKEN_ID_LENGTH = 0x1f8; + + /// + /// The Token member uses a well-known format. The first two bytes of the Token member are a 16-bit unsigned integer + /// that describes the region. The possible values are either STORAGE_OFFLOAD_PATTERN_ZERO or + /// STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO. STORAGE_OFFLOAD_PATTERN_ZERO (0x0001) is a well-known token + /// that indicates that the region represented has all bits set to zero. STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO is + /// a well-known token that indicates that the data in the region represented has all bits set to zero and the corresponding + /// protection information is valid. + /// + public const uint STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN = 0xFFFFFFFF; + + /// + public const uint STORAGE_PROTOCOL_STRUCTURE_VERSION = 0x1; + + /// + public const uint STORAGE_RPMB_DESCRIPTOR_VERSION_1 = 1; + + /// The file is not a transacted file. + public const uint TXFS_TRANSACTED_VERSION_NONTRANSACTED = 0xFFFFFFFE; + + /// The file has been opened as a transacted writer. + public const uint TXFS_TRANSACTED_VERSION_UNCOMMITTED = 0xFFFFFFFF; + + /// + public const int VENDOR_ID_LENGTH = 8; + + /// Represents the status of the specified element. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_element_status typedef struct + // _CHANGER_ELEMENT_STATUS { CHANGER_ELEMENT Element; CHANGER_ELEMENT SrcElementAddress; DWORD Flags; DWORD ExceptionCode; BYTE + // TargetId; BYTE Lun; WORD Reserved; BYTE PrimaryVolumeID[MAX_VOLUME_ID_SIZE]; BYTE AlternateVolumeID[MAX_VOLUME_ID_SIZE]; } + // CHANGER_ELEMENT_STATUS, *PCHANGER_ELEMENT_STATUS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_ELEMENT_STATUS")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct CHANGER_ELEMENT_STATUS { - /* - https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ - */ - - /// - public const uint CSV_NAMESPACE_INFO_V1 = 24; - - /// - public const int FILE_STORAGE_TIER_DESCRIPTION_LENGTH = 512; - - /// - public const int FILE_STORAGE_TIER_NAME_LENGTH = 256; - - /// - public const int MAX_VOLUME_ID_SIZE = 36; - - /// - public const int MAX_VOLUME_TEMPLATE_SIZE = 40; - - /// - public const int PRODUCT_ID_LENGTH = 16; - - /// - public const ushort REQUEST_OPLOCK_CURRENT_VERSION = 1; - - /// - public const int REVISION_LENGTH = 4; - - /// - public const int SERIAL_NUMBER_LENGTH = 32; - - /// - public const int STORAGE_OFFLOAD_TOKEN_ID_LENGTH = 0x1f8; + /// A CHANGER_ELEMENT structure that represents the element. + public CHANGER_ELEMENT Element; /// - /// The Token member uses a well-known format. The first two bytes of the Token member are a 16-bit unsigned integer - /// that describes the region. The possible values are either STORAGE_OFFLOAD_PATTERN_ZERO or - /// STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO. STORAGE_OFFLOAD_PATTERN_ZERO (0x0001) is a well-known token - /// that indicates that the region represented has all bits set to zero. STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO is - /// a well-known token that indicates that the data in the region represented has all bits set to zero and the corresponding - /// protection information is valid. - /// - public const uint STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN = 0xFFFFFFFF; - - /// - public const uint STORAGE_PROTOCOL_STRUCTURE_VERSION = 0x1; - - /// - public const uint STORAGE_RPMB_DESCRIPTOR_VERSION_1 = 1; - - /// The file is not a transacted file. - public const uint TXFS_TRANSACTED_VERSION_NONTRANSACTED = 0xFFFFFFFE; - - /// The file has been opened as a transacted writer. - public const uint TXFS_TRANSACTED_VERSION_UNCOMMITTED = 0xFFFFFFFF; - - /// - public const int VENDOR_ID_LENGTH = 8; - - /// Represents the status of the specified element. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_element_status typedef struct - // _CHANGER_ELEMENT_STATUS { CHANGER_ELEMENT Element; CHANGER_ELEMENT SrcElementAddress; DWORD Flags; DWORD ExceptionCode; BYTE - // TargetId; BYTE Lun; WORD Reserved; BYTE PrimaryVolumeID[MAX_VOLUME_ID_SIZE]; BYTE AlternateVolumeID[MAX_VOLUME_ID_SIZE]; } - // CHANGER_ELEMENT_STATUS, *PCHANGER_ELEMENT_STATUS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_ELEMENT_STATUS")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct CHANGER_ELEMENT_STATUS - { - /// A CHANGER_ELEMENT structure that represents the element. - public CHANGER_ELEMENT Element; - - /// - /// - /// A CHANGER_ELEMENT structure that represents the element from which the media currently in this element was most recently moved. - /// - /// This member is valid only if the Flags member includes ELEMENT_STATUS_SVALID. - /// - public CHANGER_ELEMENT SrcElementAddress; - - /// - /// The element status. This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// ELEMENT_STATUS_ACCESS 0x00000008 - /// - /// The changer's transport element can access the piece of media in this element. The media is not accessible in the following - /// circumstances: (1) If the element type is ChangerSlot, the slot is not present in the changer (for example, the magazine - /// containing the slot has been physically removed). (2) If the element type is ChangerDrive, the drive is broken or has been - /// removed. (3) If the element type is ChangerIEPort, the changer's insert/eject port is extended. - /// - /// - /// - /// ELEMENT_STATUS_AVOLTAG 0x20000000 - /// Alternate volume information in the AlternateVolumeID member is valid. - /// - /// - /// ELEMENT_STATUS_EXCEPT 0x00000004 - /// The element is in an abnormal state. Check the ExceptionCode member for more information. - /// - /// - /// ELEMENT_STATUS_EXENAB 0x00000010 - /// The element supports export of media through the changer's insert/eject port. - /// - /// - /// ELEMENT_STATUS_FULL 0x00000001 - /// - /// The element contains a piece of media. Note that this value is valid only if the element type is ChangerDrive, ChangerSlot, - /// or ChangerTransport. If ElementType is ChangerIEPort, this value is valid only if the Features0 member of - /// GET_CHANGER_PARAMETERS includes CHANGER_REPORT_IEPORT_STATE. - /// - /// - /// - /// ELEMENT_STATUS_ID_VALID 0x00002000 - /// The SCSI target ID in the TargetID member is valid. This value is valid only if the element type is ChangerDrive. - /// - /// - /// ELEMENT_STATUS_IMPEXP 0x00000002 - /// The media in this element was placed there by an operator. This value is valid only if the element type is ChangerIEPort. - /// - /// - /// ELEMENT_STATUS_INENAB 0x00000020 - /// The element supports import of media through the changer's insert/eject port. - /// - /// - /// ELEMENT_STATUS_INVERT 0x00400000 - /// The media in the element was flipped. This value is valid only if ELEMENT_STATUS_SVALID is also included. - /// - /// - /// ELEMENT_STATUS_LUN_VALID 0x00001000 - /// The logical unit number in the Lun member is valid. This value is valid only if the element type is ChangerDrive. - /// - /// - /// ELEMENT_STATUS_NOT_BUS 0x00008000 - /// The drive at the address indicated by Lun and TargetID is on a different SCSI bus than the changer itself. - /// - /// - /// ELEMENT_STATUS_PVOLTAG 0x10000000 - /// Primary volume information in the PrimaryVolumeID member is valid. - /// - /// - /// ELEMENT_STATUS_SVALID 0x00800000 - /// The SourceElement member and ELEMENT_STATUS_INVERT are both valid. - /// - /// - /// - public ELEMENT_STATUS Flags; - - /// - /// - /// An exception code that indicates that the element is in an abnormal state. This member is valid only if the Flags - /// member includes ELEMENT_STATUS_EXCEPT. This member can be one of the following values. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// ERROR_DRIVE_NOT_INSTALLED 0x00000008 - /// The drive at this element address is absent. - /// - /// - /// ERROR_LABEL_QUESTIONABLE 0x00000002 - /// The label might be invalid due to a unit attention condition. - /// - /// - /// ERROR_LABEL_UNREADABLE 0x00000001 - /// - /// The changer's barcode reader could not read the bar code label on the piece of media in this element, because the media is - /// missing, damaged, improperly positioned, or upside down. - /// - /// - /// - /// ERROR_SLOT_NOT_PRESENT 0x00000004 - /// - /// The slot at this element address is currently not installed in the changer. Each slot in a removable magazine is reported - /// not present to indicate that the magazine has been removed. - /// - /// - /// - /// ERROR_TRAY_MALFUNCTION 0x00000010 - /// - /// The drive at this element address has a tray that must be extended to load or remove media, and the tray is not extending as required. - /// - /// - /// - /// ERROR_UNHANDLED_ERROR 0xFFFFFFFF - /// Unknown error condition. - /// - /// - /// - public ELEMENT_ERROR ExceptionCode; - - /// - /// For a SCSI changer, specifies the SCSI target ID of the drive at this element address. This member is valid only if the - /// ElementType member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_ID_VALID. - /// - public byte TargetId; - - /// - /// The SCSI logical unit number of the drive at this element address. This member is valid only if the ElementType - /// member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_LUN_VALID. - /// - public byte Lun; - - /// Reserved for future use. The value of this member must be zero. - public ushort Reserved; - - /// - /// - /// The primary volume identifier for the media. If the changer supports a barcode reader and the reader is installed (as - /// indicated by CHANGER_BAR_CODE_SCANNER_INSTALLED in the Features0 member of GET_CHANGER_PARAMETERS), - /// PrimaryVolumeID is the bar code of the media. If the changer does not support a barcode reader, - /// PrimaryVolumeID is the value previously assigned to the media. - /// - /// This member is valid only if the Flags member includes ELEMENT_STATUS_PVOLTAG. - /// If the volume identifier is missing or unreadable, this member is cleared. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] - public string PrimaryVolumeID; - - /// - /// - /// An alternate volume identification for the media. This member is valid only for two-sided media, and pertains to the ID of - /// the inverted side. It never represents a bar code. - /// - /// This member is valid only if the Flags member includes ELEMENT_STATUS_AVOLTAG. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] - public string AlternateVolumeID; - } - - /// Represents the status of the specified element. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_element_status_ex typedef struct - // _CHANGER_ELEMENT_STATUS_EX { CHANGER_ELEMENT Element; CHANGER_ELEMENT SrcElementAddress; DWORD Flags; DWORD ExceptionCode; BYTE - // TargetId; BYTE Lun; WORD Reserved; BYTE PrimaryVolumeID[MAX_VOLUME_ID_SIZE]; BYTE AlternateVolumeID[MAX_VOLUME_ID_SIZE]; BYTE - // VendorIdentification[VENDOR_ID_LENGTH]; BYTE ProductIdentification[PRODUCT_ID_LENGTH]; BYTE SerialNumber[SERIAL_NUMBER_LENGTH]; } - // CHANGER_ELEMENT_STATUS_EX, *PCHANGER_ELEMENT_STATUS_EX; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_ELEMENT_STATUS_EX")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct CHANGER_ELEMENT_STATUS_EX - { - /// A CHANGER_ELEMENT structure that represents the element to which this structure refers. - public CHANGER_ELEMENT Element; - - /// - /// - /// A CHANGER_ELEMENT structure that represents the element from which the media currently in this element was most recently moved. - /// - /// This member is valid only if the Flags member includes ELEMENT_STATUS_SVALID. - /// - public CHANGER_ELEMENT SrcElementAddress; - - /// - /// The element status. This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// ELEMENT_STATUS_ACCESS 0x00000008 - /// - /// The changer's transport element can access the piece of media in this element. The media is not accessible in the following - /// circumstances: (1) If the element type is ChangerSlot, the slot is not present in the changer (for example, the magazine - /// containing the slot has been physically removed). (2) If the element type is ChangerDrive, the drive is broken or has been - /// removed. (3) If the element type is ChangerIEPort, the changer's insert/eject port is extended. - /// - /// - /// - /// ELEMENT_STATUS_AVOLTAG 0x20000000 - /// Alternate volume information in the AlternateVolumeID member is valid. - /// - /// - /// ELEMENT_STATUS_EXCEPT 0x00000004 - /// The element is in an abnormal state. Check the ExceptionCode member for more information. - /// - /// - /// ELEMENT_STATUS_EXENAB 0x00000010 - /// The element supports export of media through the changer's insert/eject port. - /// - /// - /// ELEMENT_STATUS_FULL 0x00000001 - /// - /// The element contains a piece of media. Note that this value is valid only if the element type is ChangerDrive, ChangerSlot, - /// or ChangerTransport. If the element type is ChangerIEPort, this value is valid only if the Features0 member of - /// GET_CHANGER_PARAMETERS includes CHANGER_REPORT_IEPORT_STATE. - /// - /// - /// - /// ELEMENT_STATUS_ID_VALID 0x00002000 - /// The SCSI target ID in the TargetID member is valid. This value is valid only if the element type is ChangerDrive. - /// - /// - /// ELEMENT_STATUS_IMPEXP 0x00000002 - /// The media in this element was placed there by an operator. This value is valid only if the element type is ChangerIEPort. - /// - /// - /// ELEMENT_STATUS_INENAB 0x00000020 - /// The element supports import of media through the changer's insert/eject port. - /// - /// - /// ELEMENT_STATUS_INVERT 0x00400000 - /// The media in the element was flipped. This value is valid only if ELEMENT_STATUS_SVALID is also included. - /// - /// - /// ELEMENT_STATUS_LUN_VALID 0x00001000 - /// The logical unit number in the Lun member is valid. This value is valid only if the element type is ChangerDrive. - /// - /// - /// ELEMENT_STATUS_NOT_BUS 0x00008000 - /// The drive at the address indicated by Lun and TargetID is on a different SCSI bus than the changer itself. - /// - /// - /// ELEMENT_STATUS_PRODUCT_DATA 0x00000040 - /// The serial number in the SerialNumber member is valid. - /// - /// - /// ELEMENT_STATUS_PVOLTAG 0x10000000 - /// Primary volume information in the PrimaryVolumeID member is valid. - /// - /// - /// ELEMENT_STATUS_SVALID 0x00800000 - /// The SourceElement member and ELEMENT_STATUS_INVERT are both valid. - /// - /// - /// - public ELEMENT_STATUS Flags; - - /// - /// - /// An exception code that indicates that the element is in an abnormal state. This member is valid only if the Flags - /// member includes ELEMENT_STATUS_EXCEPT. This member can be one of the following values. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// ERROR_DRIVE_NOT_INSTALLED 0x00000008 - /// The drive at this element address is absent. - /// - /// - /// ERROR_INIT_STATUS_NEEDED 0x00000011 - /// An Initialize Element Status command is needed. - /// - /// - /// ERROR_LABEL_QUESTIONABLE 0x00000002 - /// The label might be invalid due to a unit attention condition. - /// - /// - /// ERROR_LABEL_UNREADABLE 0x00000001 - /// - /// The changer's barcode reader could not read the bar code label on the piece of media in this element, because the media is - /// missing, damaged, improperly positioned, or upside down. - /// - /// - /// - /// ERROR_SLOT_NOT_PRESENT 0x00000004 - /// - /// The slot at this element address is currently not installed in the changer. Each slot in a removable magazine is reported - /// not present to indicate that the magazine has been removed. - /// - /// - /// - /// ERROR_TRAY_MALFUNCTION 0x00000010 - /// - /// The drive at this element address has a tray that must be extended to load or remove media, and the tray is not extending as required. - /// - /// - /// - /// ERROR_UNHANDLED_ERROR 0xFFFFFFFF - /// Unknown error condition. - /// - /// - /// - public ELEMENT_ERROR ExceptionCode; - - /// - /// For a SCSI changer, specifies the SCSI target ID of the drive at this element address. This member is valid only if the - /// ElementType member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_ID_VALID. - /// - public byte TargetId; - - /// - /// The SCSI logical unit number of the drive at this element address. This member is valid only if the ElementType - /// member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_LUN_VALID. - /// - public byte Lun; - - /// Reserved for future use. The value of this member must be zero. - public ushort Reserved; - - /// - /// - /// The primary volume identifier for the media. If the changer supports a barcode reader and the reader is installed (as - /// indicated by CHANGER_BAR_CODE_SCANNER_INSTALLED in the Features0 member of GET_CHANGER_PARAMETERS), - /// PrimaryVolumeID is the bar code of the media. If the changer does not support a barcode reader, - /// PrimaryVolumeID is the value previously assigned to the media. - /// - /// This member is valid only if the Flags member includes ELEMENT_STATUS_PVOLTAG. - /// If the volume identifier is missing or unreadable, this member is cleared. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] - public string PrimaryVolumeID; - - /// - /// - /// An alternate volume identification for the media. This member is valid for two-sided media only, and pertains to the ID of - /// the inverted side. It never represents a bar code. - /// - /// This member is valid only if the Flags member includes ELEMENT_STATUS_AVOLTAG. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] - public string AlternateVolumeID; - - /// The vendor identifier. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = VENDOR_ID_LENGTH)] - public string VendorIdentification; - - /// The product identifier. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PRODUCT_ID_LENGTH)] - public string ProductIdentification; - - /// The serial number for the drive. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SERIAL_NUMBER_LENGTH)] - public string SerialNumber; - } - - /// - /// Contains information the IOCTL_CHANGER_EXCHANGE_MEDIUM control code uses to move a piece of media to a destination, and the - /// piece of media originally in the first destination to a second destination. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_exchange_medium typedef struct - // _CHANGER_EXCHANGE_MEDIUM { CHANGER_ELEMENT Transport; CHANGER_ELEMENT Source; CHANGER_ELEMENT Destination1; CHANGER_ELEMENT - // Destination2; BOOLEAN Flip1; BOOLEAN Flip2; } CHANGER_EXCHANGE_MEDIUM, *PCHANGER_EXCHANGE_MEDIUM; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_EXCHANGE_MEDIUM")] - [StructLayout(LayoutKind.Sequential)] - public struct CHANGER_EXCHANGE_MEDIUM - { - /// - /// A CHANGER_ELEMENT structure that indicates which transport element to use for the exchange operation. The ElementType - /// member of this structure must be ChangerTransport. - /// - public CHANGER_ELEMENT Transport; - - /// A CHANGER_ELEMENT structure that indicates the element that contains the media that is to be moved. - public CHANGER_ELEMENT Source; - - /// A CHANGER_ELEMENT structure that indicates the element that is the destination of the media originally at Source. - public CHANGER_ELEMENT Destination1; - - /// A CHANGER_ELEMENT structure that indicates the element that is the destination of the media originally at Destination1. - public CHANGER_ELEMENT Destination2; - - /// - /// If this member is TRUE, the medium at Destination1 should be flipped. Otherwise, it should not. This member is - /// valid only if the Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. - /// - [MarshalAs(UnmanagedType.U1)] - public bool Flip1; - - /// - /// If this member is TRUE, the medium at Destination2 should be flipped. Otherwise, it should not. This member is - /// valid only if the Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. - /// - [MarshalAs(UnmanagedType.U1)] - public bool Flip2; - } - - /// Represents the status of all media changer elements or the specified elements of a particular type. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_initialize_element_status typedef struct - // _CHANGER_INITIALIZE_ELEMENT_STATUS { CHANGER_ELEMENT_LIST ElementList; BOOLEAN BarCodeScan; } CHANGER_INITIALIZE_ELEMENT_STATUS, *PCHANGER_INITIALIZE_ELEMENT_STATUS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_INITIALIZE_ELEMENT_STATUS")] - [StructLayout(LayoutKind.Sequential)] - public struct CHANGER_INITIALIZE_ELEMENT_STATUS - { - /// - /// A CHANGER_ELEMENT_LIST structure that lists the elements and range on which to initialize. - /// - /// If CHANGER_INIT_ELEM_STAT_WITH_RANGE is set in the Features0 member of GET_CHANGER_PARAMETERS, the changer supports - /// initializing a range of elements. In this case, the ElementType member can be one of the following: ChangerTransport, - /// ChangerSlot, ChangerDrive, or ChangerIEPort. Otherwise, the element type must be AllElements and the NumberOfElements - /// member is ignored. - /// - /// - public CHANGER_ELEMENT_LIST ElementList; - - /// - /// - /// If this member is TRUE, a bar-code scan should be used. Otherwise, it should not. If the changer has nonvolatile RAM, - /// using a bar-code scan is an optimization. - /// - /// This member is applicable only if CHANGER_BAR_CODE_SCANNER_INSTALLED is set in the Features0 member of GET_CHANGER_PARAMETERS. - /// - [MarshalAs(UnmanagedType.U1)] - public bool BarCodeScan; - } - - /// Contains information that the IOCTL_CHANGER_MOVE_MEDIUM control code uses to move a piece of media to a destination. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_move_medium typedef struct _CHANGER_MOVE_MEDIUM { - // CHANGER_ELEMENT Transport; CHANGER_ELEMENT Source; CHANGER_ELEMENT Destination; BOOLEAN Flip; } CHANGER_MOVE_MEDIUM, *PCHANGER_MOVE_MEDIUM; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_MOVE_MEDIUM")] - [StructLayout(LayoutKind.Sequential)] - public struct CHANGER_MOVE_MEDIUM - { - /// A CHANGER_ELEMENT structure that indicates which transport element to use for the move operation. - public CHANGER_ELEMENT Transport; - - /// A CHANGER_ELEMENT structure that indicates the element that contains the media that is to be moved. - public CHANGER_ELEMENT Source; - - /// A CHANGER_ELEMENT structure that indicates the element that is the destination of the media originally at Source. - public CHANGER_ELEMENT Destination; - - /// - /// If this member is TRUE, the media should be flipped. Otherwise, it should not. This member is valid only if the - /// Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. - /// - [MarshalAs(UnmanagedType.U1)] - public bool Flip; - } - - /// Represents product data for a changer device. It is used by the IOCTL_CHANGER_GET_PRODUCT_DATA control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_product_data typedef struct _CHANGER_PRODUCT_DATA - // { BYTE VendorId[VENDOR_ID_LENGTH]; BYTE ProductId[PRODUCT_ID_LENGTH]; BYTE Revision[REVISION_LENGTH]; BYTE - // SerialNumber[SERIAL_NUMBER_LENGTH]; BYTE DeviceType; } CHANGER_PRODUCT_DATA, *PCHANGER_PRODUCT_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_PRODUCT_DATA")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct CHANGER_PRODUCT_DATA - { - /// The device manufacturer's name. This is acquired directly from the device inquiry data. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = VENDOR_ID_LENGTH)] - public string VendorId; - - /// The product identification, as defined by the vendor. This is acquired directly from the device inquiry data. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PRODUCT_ID_LENGTH)] - public string ProductId; - - /// The product revision, as defined by the vendor. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = REVISION_LENGTH)] - public string Revision; - - /// A unique value used to globally identify this device, as defined by the vendor. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SERIAL_NUMBER_LENGTH)] - public string SerialNumber; - - /// The device type of data transports, as defined by SCSI-2. This member must be FILE_DEVICE_CHANGER. - public byte DeviceType; - } - - /// - /// Contains information that the IOCTL_CHANGER_GET_ELEMENT_STATUS control code needs to determine the elements whose status is to - /// be retrieved. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_read_element_status typedef struct - // _CHANGER_READ_ELEMENT_STATUS { CHANGER_ELEMENT_LIST ElementList; BOOLEAN VolumeTagInfo; } CHANGER_READ_ELEMENT_STATUS, *PCHANGER_READ_ELEMENT_STATUS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_READ_ELEMENT_STATUS")] - [StructLayout(LayoutKind.Sequential)] - public struct CHANGER_READ_ELEMENT_STATUS - { - /// - /// A CHANGER_ELEMENT_LIST structure that contains an array of structures that represents the range of elements for which - /// information is to be retrieved. The ElementType member of each structure can be one of the following values: - /// ChangerDrive, ChangerSlot, ChangerTransport, ChangerIEPort, or AllElements. - /// - public CHANGER_ELEMENT_LIST ElementList; - - /// - /// If this member is TRUE, volume tag information is to be retrieved. Otherwise, no volume information is retrieved. A - /// volume tag can be a bar code or an application-defined value. This member is valid only if the Features0 member of - /// the GET_CHANGER_PARAMETERS structure is CHANGER_BAR_CODE_SCANNER_INSTALLED or CHANGER_VOLUME_IDENTIFICATION. - /// - [MarshalAs(UnmanagedType.U1)] - public bool VolumeTagInfo; - } - - /// - /// Contains information that the IOCTL_CHANGER_QUERY_VOLUME_TAGS control code uses to determine the volume information to be retrieved. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_send_volume_tag_information typedef struct - // _CHANGER_SEND_VOLUME_TAG_INFORMATION { CHANGER_ELEMENT StartingElement; DWORD ActionCode; BYTE - // VolumeIDTemplate[MAX_VOLUME_TEMPLATE_SIZE]; } CHANGER_SEND_VOLUME_TAG_INFORMATION, *PCHANGER_SEND_VOLUME_TAG_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_SEND_VOLUME_TAG_INFORMATION")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct CHANGER_SEND_VOLUME_TAG_INFORMATION - { - /// A CHANGER_ELEMENT structure that represents the starting element for which information is to be retrieved. - public CHANGER_ELEMENT StartingElement; - - /// - /// The action to be performed. - /// - /// - /// Value - /// Meaning - /// - /// - /// ASSERT_ALTERNATE 0x9 - /// Define the alternate volume tag of a volume that currently has none defined. Requires that Features0 is CHANGER_VOLUME_ASSERT. - /// - /// - /// ASSERT_PRIMARY 0x8 - /// Define the primary volume tag of a volume that currently has none defined. Requires that Features0 is CHANGER_VOLUME_ASSERT. - /// - /// - /// REPLACE_ALTERNATE 0xB - /// Replace the alternate volume tag with a new tag. Requires that Features0 is CHANGER_VOLUME_REPLACE. - /// - /// - /// REPLACE_PRIMARY 0xA - /// Replace the primary volume tag with a new tag. Requires that Features0 is CHANGER_VOLUME_REPLACE. - /// - /// - /// SEARCH_ALL 0x0 - /// Search all defined volume tags. Requires that Features0 is CHANGER_VOLUME_SEARCH. - /// - /// - /// SEARCH_ALL_NO_SEQ 0x4 - /// Search all defined volume tags, but ignore sequence numbers. Requires that Features0 is CHANGER_VOLUME_SEARCH. - /// - /// - /// SEARCH_ALT_NO_SEQ 0x6 - /// Search only alternate volume tags, but ignore sequence numbers. Requires that Features0 is CHANGER_VOLUME_SEARCH. - /// - /// - /// SEARCH_ALTERNATE 02 - /// Search only alternate volume tags. Requires that Features0 is CHANGER_VOLUME_SEARCH. - /// - /// - /// SEARCH_PRI_NO_SEQ 05 - /// Search only primary volume tags but ignore sequence numbers. Requires that Features0 is CHANGER_VOLUME_SEARCH. - /// - /// - /// SEARCH_PRIMARY 0x1 - /// Search only primary volume tags. Requires that Features0 is CHANGER_VOLUME_SEARCH. - /// - /// - /// UNDEFINE_ALTERNATE 0xD - /// Clear the alternate volume tag. Requires that Features0 is CHANGER_VOLUME_UNDEFINE. - /// - /// - /// UNDEFINE_PRIMARY 0xC - /// Clear the primary volume tag. Requires that Features0 is CHANGER_VOLUME_UNDEFINE. - /// - /// - /// - public ChangerActionCode ActionCode; - - /// - /// The template that the device uses to search for volume IDs. For search operations, the template can include wildcard - /// characters to search for volumes that match the template. Supported wildcard characters include the asterisk (*) and - /// question mark (?). For other operations, the template must specify a single volume. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_TEMPLATE_SIZE)] - public string VolumeIDTemplate; - } - - /// - /// Contains information that the IOCTL_CHANGER_SET_ACCESS control code needs to set the state of the device's insert/eject port, - /// door, or keypad. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_set_access typedef struct _CHANGER_SET_ACCESS { - // CHANGER_ELEMENT Element; DWORD Control; } CHANGER_SET_ACCESS, *PCHANGER_SET_ACCESS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_SET_ACCESS")] - [StructLayout(LayoutKind.Sequential)] - public struct CHANGER_SET_ACCESS - { - /// - /// A CHANGER_ELEMENT structure that represents the changer element. The ElementType member can be one of the following - /// values: ChangerDoor, ChangerIEPort, or ChangerKeypad. - /// - public CHANGER_ELEMENT Element; - - /// - /// The operation to be performed. - /// - /// - /// Value - /// Meaning - /// - /// - /// EXTEND_IEPORT 2 - /// The element is to be extended. Requires that Features0 is CHANGER_OPEN_IEPORT. - /// - /// - /// LOCK_ELEMENT 0 - /// The element is to be locked. Requires that Features0 is CHANGER_LOCK_UNLOCK. - /// - /// - /// RETRACT_IEPORT 3 - /// The element is to be retracted. Requires that Features0 is CHANGER_CLOSE_IEPORT. - /// - /// - /// UNLOCK_ELEMENT 1 - /// The element is to be unlocked. Requires that Features0 is CHANGER_LOCK_UNLOCK. - /// - /// - /// - public CHANGER_SET_ACCESS_OP Control; - } - - /// - /// Contains information needed by the IOCTL_CHANGER_SET_POSITION control code to set the changer's robotic transport mechanism to - /// the specified element address. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_set_position typedef struct _CHANGER_SET_POSITION - // { CHANGER_ELEMENT Transport; CHANGER_ELEMENT Destination; BOOLEAN Flip; } CHANGER_SET_POSITION, *PCHANGER_SET_POSITION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_SET_POSITION")] - [StructLayout(LayoutKind.Sequential)] - public struct CHANGER_SET_POSITION - { - /// - /// A CHANGER_ELEMENT structure that indicates the transport to be moved. The ElementType member must be ChangerTransport. - /// - public CHANGER_ELEMENT Transport; - - /// - /// A CHANGER_ELEMENT structure that indicates the final destination of the transport. The ElementType member must be one - /// of the following values: ChangerSlot, ChangerDrive, or ChangerIEPort. - /// - public CHANGER_ELEMENT Destination; - - /// - /// If this member is TRUE, the media currently carried by Transport should be flipped. Otherwise, it should not. - /// This member is valid only if the Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. - /// - [MarshalAs(UnmanagedType.U1)] - public bool Flip; - } - - /// Contains information associated with a media change event. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-class_media_change_context typedef struct - // _CLASS_MEDIA_CHANGE_CONTEXT { DWORD MediaChangeCount; DWORD NewState; } CLASS_MEDIA_CHANGE_CONTEXT, *PCLASS_MEDIA_CHANGE_CONTEXT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CLASS_MEDIA_CHANGE_CONTEXT")] - [StructLayout(LayoutKind.Sequential)] - public struct CLASS_MEDIA_CHANGE_CONTEXT - { - /// The number of times that media has been changed since system startup. - public uint MediaChangeCount; - - /// - /// - /// The state information. This member can be one of the following values from the MEDIA_CHANGE_DETECTION_STATE - /// enumeration type. - /// - /// MediaUnknown (0) - /// MediaPresent (1) - /// MediaNotPresent (2) - /// MediaUnavailable (3) - /// - public MEDIA_CHANGE_DETECTION_STATE NewState; - } - - /// Represents a type of CSV control operation. - /// - /// This structure is used with the FSCTL_CSV_CONTROL control code to indicate what kind of CSV control operation is being - /// undertaken. It is an alternative to calling that control code by just passing a CSV_CONTROL_OP enumeration value, as the - /// structure encapsulates an enumeration value of that type. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_control_param typedef struct _CSV_CONTROL_PARAM { - // CSV_CONTROL_OP Operation; LONGLONG Unused; } CSV_CONTROL_PARAM, *PCSV_CONTROL_PARAM; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_CONTROL_PARAM")] - [StructLayout(LayoutKind.Sequential)] - public struct CSV_CONTROL_PARAM - { - /// The type of CSV control operation to undertake. - public CSV_CONTROL_OP Operation; - - /// Unused. - public long Unused; - } - - /// - /// Contains the output for the FSCTL_IS_VOLUME_OWNED_BYCSVFS control code that determines whether a volume is owned by CSVFS. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_is_owned_by_csvfs typedef struct - // _CSV_IS_OWNED_BY_CSVFS { BOOLEAN OwnedByCSVFS; } CSV_IS_OWNED_BY_CSVFS, *PCSV_IS_OWNED_BY_CSVFS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_IS_OWNED_BY_CSVFS")] - [StructLayout(LayoutKind.Sequential)] - public struct CSV_IS_OWNED_BY_CSVFS - { - /// TRUE if a volume is owned by CSVFS; otherwise, FALSE. - [MarshalAs(UnmanagedType.U1)] - public bool OwnedByCSVFS; - } - - /// Contains the output for the FSCTL_IS_CSV_FILE control code that retrieves namespace information for a file. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_namespace_info typedef struct _CSV_NAMESPACE_INFO { - // DWORD Version; DWORD DeviceNumber; LARGE_INTEGER StartingOffset; DWORD SectorSize; } CSV_NAMESPACE_INFO, *PCSV_NAMESPACE_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_NAMESPACE_INFO")] - [StructLayout(LayoutKind.Sequential)] - public struct CSV_NAMESPACE_INFO - { - /// - /// The version number. This value must be set to CSV_NAMESPACE_INFO_V1. - /// - /// - /// Value - /// Meaning - /// - /// - /// CSV_NAMESPACE_INFO_V1 - /// Version 1. - /// - /// - /// - public uint Version; - - /// The device number of the disk. - public uint DeviceNumber; - - /// The starting offset of the volume. - public long StartingOffset; - - /// The sector size of the disk. - public uint SectorSize; - } - - /// Contains information about whether files in a stream have been modified. - /// /// - /// This structure is used if the FSCTL_CSV_CONTROL control code is called with a CSV_CONTROL_OP enumeration value of - /// CsvControlQueryFileRevision, or if the control code is used with an CSV_CONTROL_PARAM structure containing that - /// enumeration value. + /// A CHANGER_ELEMENT structure that represents the element from which the media currently in this element was most recently moved. /// - /// Revision tracking is per file, not per stream, so the output changes whenever the stream changes. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_file_revision typedef struct - // _CSV_QUERY_FILE_REVISION { LONGLONG FileId; LONGLONG FileRevision[3]; } CSV_QUERY_FILE_REVISION, *PCSV_QUERY_FILE_REVISION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_FILE_REVISION")] - [StructLayout(LayoutKind.Sequential)] - public struct CSV_QUERY_FILE_REVISION - { - /// The identifier of an NTFS file. - public long FileId; - - /// - /// FileRevision[0] increases every time the CSV MDS stack is rebuilt and CSVFLT loses its state. - /// If any of the numbers are 0, the function caller should assume that the file was modified. - /// - public long FileRevision0; - - /// FileRevision[1] increases every time the CSV MDS stack purges the cached revision number for the file. - public long FileRevision1; - - /// - /// FileRevision[2] increases every time the CSV MDS observes that file sizes might have changed or the file might have - /// been written to. The element is also incremented whenever one of the nodes performs the first direct input/output operation - /// on a stream that is associated with this file after opening this stream. - /// - public long FileRevision2; - } - - /// Contains the path that is used by CSV to communicate to the MDS. - /// - /// This structure is used if the FSCTL_CSV_CONTROL control code is called with a CSV_CONTROL_OP enumeration value of - /// CsvControlQueryMdsPath, or if the control code is used with an CSV_CONTROL_PARAM structure containing that enumeration value. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_mds_path typedef struct _CSV_QUERY_MDS_PATH { - // DWORD MdsNodeId; DWORD DsNodeId; DWORD PathLength; WCHAR Path[1]; } CSV_QUERY_MDS_PATH, *PCSV_QUERY_MDS_PATH; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_MDS_PATH")] - [VanaraMarshaler(typeof(AnySizeStringMarshaler), nameof(PathLength) + ":cn")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct CSV_QUERY_MDS_PATH - { - /// The identifier of an MDS node. - public uint MdsNodeId; - - /// The identifier of a DS node. - public uint DsNodeId; - - /// The length of the path. - public uint PathLength; - - /// The path. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] - public string Path; - } - - /// Contains information about whether files in a stream have been redirected. - /// - /// This structure is used if the FSCTL_CSV_CONTROL control code is called with a CSV_CONTROL_OP enumeration value of - /// CsvControlQueryRedirectState, or if the control code is used with an CSV_CONTROL_PARAM structure containing that - /// enumeration value. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_redirect_state typedef struct - // _CSV_QUERY_REDIRECT_STATE { DWORD MdsNodeId; DWORD DsNodeId; BOOLEAN FileRedirected; } CSV_QUERY_REDIRECT_STATE, *PCSV_QUERY_REDIRECT_STATE; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_REDIRECT_STATE")] - [StructLayout(LayoutKind.Sequential)] - public struct CSV_QUERY_REDIRECT_STATE - { - /// The identifier of an MDS node. - public uint MdsNodeId; - - /// The identifier of a DS node. - public uint DsNodeId; - - /// TRUE if the file has been redirected; otherwise, FALSE. - [MarshalAs(UnmanagedType.U1)] - public bool FileRedirected; - } - - /// Contains troubleshooting information about why a volume is in redirected mode. - /// - /// CSV writes the troubleshooting strings to a diagnostic log that, when filtered, can provide hints as to why a volume is in a - /// redirected mode. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_veto_file_direct_io_output typedef struct - // _CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT { DWORDLONG VetoedFromAltitudeIntegral; DWORDLONG VetoedFromAltitudeDecimal; WCHAR - // Reason[256]; } CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT, *PCSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT - { - /// The integer portion of VetoedFromAltitude. - public ulong VetoedFromAltitudeIntegral; - - /// The decimal portion of VetoedFromAltitude. - public ulong VetoedFromAltitudeDecimal; - - /// The reason why volume is in a redirected mode. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] - public string Reason; - } + /// This member is valid only if the Flags member includes ELEMENT_STATUS_SVALID. + /// + public CHANGER_ELEMENT SrcElementAddress; /// - /// The DEVICE_COPY_OFFLOAD_DESCRIPTOR structure is one of the query result structures returned from an - /// IOCTL_STORAGE_QUERY_PROPERTY request. This structure contains the copy offload capabilities for a storage device. - /// - /// - /// This structure is returned from a IOCTL_STORAGE_QUERY_PROPERTY request when the PropertyId member of - /// STORAGE_PROPERTY_QUERY is set to StorageDeviceCopyOffloadProperty. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_copy_offload_descriptor typedef struct - // _DEVICE_COPY_OFFLOAD_DESCRIPTOR { DWORD Version; DWORD Size; DWORD MaximumTokenLifetime; DWORD DefaultTokenLifetime; DWORDLONG - // MaximumTransferSize; DWORDLONG OptimalTransferCount; DWORD MaximumDataDescriptors; DWORD MaximumTransferLengthPerDescriptor; - // DWORD OptimalTransferLengthPerDescriptor; WORD OptimalTransferLengthGranularity; BYTE Reserved[2]; } - // DEVICE_COPY_OFFLOAD_DESCRIPTOR, *PDEVICE_COPY_OFFLOAD_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_COPY_OFFLOAD_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_COPY_OFFLOAD_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// The maximum lifetime of the token, in seconds. - public uint MaximumTokenLifetime; - - /// The default lifetime of the token, in seconds. - public uint DefaultTokenLifetime; - - /// The maximum transfer size, in bytes. - public ulong MaximumTransferSize; - - /// The optimal transfer size, in bytes. - public ulong OptimalTransferCount; - - /// The maximum number of data descriptors. - public uint MaximumDataDescriptors; - - /// The maximum transfer length, in blocks, per descriptor. - public uint MaximumTransferLengthPerDescriptor; - - /// The optimal transfer length per descriptor. - public uint OptimalTransferLengthPerDescriptor; - - /// - /// The granularity of the optimal transfer length, in blocks. Transfer lengths that are not an even multiple of this length may - /// be delayed. - /// - public ushort OptimalTransferLengthGranularity; - - /// Reserved. - public ushort Reserved; - } - - /// - /// Output structure for the DeviceDsmAction_Allocation action of the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - /// - /// - /// - /// Provisioning state information is returned when the Action member of the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure is - /// set to DeviceDsmAction_Allocation. The caller should include only one data set range in the system buffer at DataSetRangesOffset. - /// - /// - /// On return, the system buffer contains a DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT structure followed by the - /// DEVICE_DATA_SET_LB_PROVISIONING_STATE structure. The DEVICE_DATA_SET_LB_PROVISIONING_STATE structure begins at an - /// offset from the beginning of the system buffer specified by OutputBlockOffset in DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT. - /// - /// - /// Each bit in the allocation bitmap represents a slab mapping within the data set range requested. The bits correspond directly to - /// the slabs in the data set range. This means that bit 0 in the bitmap marks the first slab in the range. A slab is mapped if the - /// bit value = 1 and unmapped if the bit value = 0. - /// - /// - /// Space for SlabAllocationBitMap should be allocated based on the number of possible slabs in the requested data set range. - /// The SlabAllocationBitMapLength of the bitmap returned is - /// (number_of_slabs / 32) + ((number_of_slabs MOD 32) > 0 ? 1 : 0) - /// . - /// - /// - /// Slab size is determined by the OptimalUnmapGranularity member of the DEVICE_LB_PROVISIONING_DESCRIPTOR structure returned - /// from an IOCTL_STORAGE_QUERY_PROPERTY control code. The length of the data set range provided should be a multiple of - /// OptimalUnmapGranularity. When the range length is not a multiple of OptimalUnmapGranularity, it is reduced to be a multiple. - /// - /// - /// If the starting offset in the data set range is not aligned on a slab boundary, a multiple of OptimalUnmapGranularity, - /// the offset will be adjusted to the next boundary. The difference between the requested offset and the adjusted offset is - /// returned in SlabOffsetDeltaInBytes. - /// - /// - /// If the slab allocation total returned in SlabAllocationBitMapBitCount is not as expected because of data set range - /// alignment or length adjustments, an additional request may be submitted with a data set range modified according to the values - /// in both SlabAllocationBitMapBitCount and SlabOffsetDeltaInBytes. The new range will properly select the slabs left - /// out of the bitmap returned by the previous request. - /// - /// - /// If the requested slab size is too large (for example if it is larger than the maximum transfer length of the HBA) then the - /// IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES can fail with ERROR_INVALID_PARAMETER. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_data_set_lb_provisioning_state typedef struct - // _DEVICE_DATA_SET_LB_PROVISIONING_STATE { DWORD Size; DWORD Version; DWORDLONG SlabSizeInBytes; DWORD SlabOffsetDeltaInBytes; - // DWORD SlabAllocationBitMapBitCount; DWORD SlabAllocationBitMapLength; DWORD SlabAllocationBitMap[ANYSIZE_ARRAY]; } - // DEVICE_DATA_SET_LB_PROVISIONING_STATE, *PDEVICE_DATA_SET_LB_PROVISIONING_STATE, DEVICE_DSM_ALLOCATION_OUTPUT, *PDEVICE_DSM_ALLOCATION_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DATA_SET_LB_PROVISIONING_STATE")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(SlabAllocationBitMapLength))] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_DATA_SET_LB_PROVISIONING_STATE - { - /// The size of this structure, including the bitmap, in bytes. - public uint Size; - - /// The version of this structure. - public uint Version; - - /// The size of a slab, in bytes. - public ulong SlabSizeInBytes; - - /// - /// If the range specified is not aligned to the OptimalUnmapGranularity as returned in DEVICE_LB_PROVISIONING_DESCRIPTOR - /// structure then the data represented in the SlabAllocationBitMap is offset from the specified range by this amount. - /// - public uint SlabOffsetDeltaInBytes; - - /// The number of relevant bits in the bitmap. - public uint SlabAllocationBitMapBitCount; - - /// The number of DWORD s in the bitmap array. - public uint SlabAllocationBitMapLength; - - /// - /// The allocation bitmap containing one bit for each slab. If a bit is set then the corresponding slab is allocated. Otherwise, - /// if a bit is clear, the corresponding slab is unallocated. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public uint[] SlabAllocationBitMap; - } - - /// Provides data set range information for use with the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_data_set_range typedef struct - // _DEVICE_DATA_SET_RANGE { LONGLONG StartingOffset; DWORDLONG LengthInBytes; } DEVICE_DATA_SET_RANGE, *PDEVICE_DATA_SET_RANGE, - // DEVICE_DSM_RANGE, *PDEVICE_DSM_RANGE; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DATA_SET_RANGE")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_DATA_SET_RANGE - { - /// - /// Starting offset of the data set range in bytes, relative to the start of the volume. Must align to disk logical sector size. - /// - public long StartingOffset; - - /// Length of the data set range, in bytes. Must be a multiple of disk logical sector size. - public ulong LengthInBytes; - } - - /// - /// Specifies parameters for the repair operation. A repair operation is initiated by specifying DeviceDsmAction_Repair in - /// the Action member of the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure passed in a IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - /// control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_data_set_repair_parameters typedef struct - // _DEVICE_DATA_SET_REPAIR_PARAMETERS { DWORD NumberOfRepairCopies; DWORD SourceCopy; DWORD RepairCopies[ANYSIZE_ARRAY]; } - // DEVICE_DATA_SET_REPAIR_PARAMETERS, *PDEVICE_DATA_SET_REPAIR_PARAMETERS, DEVICE_DSM_REPAIR_PARAMETERS, *PDEVICE_DSM_REPAIR_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DATA_SET_REPAIR_PARAMETERS")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfRepairCopies))] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_DATA_SET_REPAIR_PARAMETERS - { - /// The number of copies that will be repaired. - public uint NumberOfRepairCopies; - - /// The copy number of the source copy. - public uint SourceCopy; - - /// The copy numbers of all the copies that will be repaired. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public uint[] RepairCopies; - } - - /// - /// Contains parameters for the DeviceDsmAction_Notification action for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_dsm_notification_parameters typedef struct - // _DEVICE_DSM_NOTIFICATION_PARAMETERS { DWORD Size; DWORD Flags; DWORD NumFileTypeIDs; GUID FileTypeID[ANYSIZE_ARRAY]; } - // DEVICE_DSM_NOTIFICATION_PARAMETERS, *PDEVICE_DSM_NOTIFICATION_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DSM_NOTIFICATION_PARAMETERS")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumFileTypeIDs))] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_DSM_NOTIFICATION_PARAMETERS - { - /// - /// Specifies the total size, in bytes, of this structure. The value of this member must include the total size, in bytes, of - /// the FileTypeIDs member. - /// - public uint Size; - - /// - /// Flags specific to the notify operation - /// - /// - /// Value - /// Meaning - /// - /// - /// DEVICE_DSM_NOTIFY_FLAG_BEGIN 0x00000001 - /// - /// The ranges specified in the DEVICE_DATA_SET_RANGE structures following the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure are - /// currently being used by the file types that are specified in the FileTypeIDs member. - /// - /// - /// - /// DEVICE_DSM_NOTIFY_FLAG_END 0x00000002 - /// The ranges are no longer being used by the file types that are specified in the FileTypeIDs member. - /// - /// - /// - public DEVICE_DSM_NOTIFY_FLAG Flags; - - /// The number of entries in the FileTypeIDs member. - public uint NumFileTypeIDs; - - /// - /// One or more GUID values that specify the file type for the notification operation. - /// - /// - /// Value - /// Meaning - /// - /// - /// FILE_TYPE_NOTIFICATION_GUID_PAGE_FILE 0d0a64a1-38fc-4db8-9fe7-3f4352cd7c5c - /// Specifies a notification operation for a page file. - /// - /// - /// FILE_TYPE_NOTIFICATION_GUID_HIBERNATION_FILE b7624d64-b9a3-4cf8-8011-5b86c940e7b7 - /// Specifies a notification operation for the system hibernation file. - /// - /// - /// FILE_TYPE_NOTIFICATION_GUID_CRASHDUMP_FILE 9d453eb7-d2a6-4dbd-a2e3-fbd0ed9109a9 - /// Specifies a notification operation for a system crash dump file. - /// - /// - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public Guid[] FileTypeID; - - /// - /// Initializes a new instance of the struct setting all values appropriately - /// based on parameters. - /// - /// One or more GUID values that specify the file type for the notification operation. - /// Flags specific to the notify operation. - public DEVICE_DSM_NOTIFICATION_PARAMETERS(Guid[] fileTypeID, DEVICE_DSM_NOTIFY_FLAG flags) - { - FileTypeID = fileTypeID; - NumFileTypeIDs = (uint)fileTypeID.Length; - Flags = flags; - Size = (uint)(Marshal.SizeOf(typeof(DEVICE_DSM_NOTIFICATION_PARAMETERS)) + Marshal.SizeOf(typeof(Guid)) * (NumFileTypeIDs - 1)); - } - } - - /// - /// Contains parameters for the DeviceDsmAction_OffloadRead action for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_dsm_offload_read_parameters typedef struct - // _DEVICE_DSM_OFFLOAD_READ_PARAMETERS { DWORD Flags; DWORD TimeToLive; DWORD Reserved[2]; } DEVICE_DSM_OFFLOAD_READ_PARAMETERS, *PDEVICE_DSM_OFFLOAD_READ_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DSM_OFFLOAD_READ_PARAMETERS")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_DSM_OFFLOAD_READ_PARAMETERS - { - /// Set to 0. - public uint Flags; - - /// The time to live (TTL) for the token, in milliseconds. - public uint TimeToLive; - - /// Set to 0. - public ulong Reserved; - } - - /// - /// Specifies parameters for the offload write operation. An offload write operation is initiated by specifying - /// DeviceDsmAction_OffloadWrite in the Action member of the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure passed in a - /// IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_dsm_offload_write_parameters typedef struct - // _DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS { DWORD Flags; DWORD Reserved; DWORDLONG TokenOffset; STORAGE_OFFLOAD_TOKEN Token; } - // DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS, *PDEVICE_DSM_OFFLOAD_WRITE_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS - { - /// Set to 0. - public uint Flags; - - /// Reserved. - public uint Reserved; - - /// The starting offset to copy from the range bound to the token - public ulong TokenOffset; - - /// STORAGE_OFFLOAD_TOKEN structure containing the token returned from the offload read operation. - public STORAGE_OFFLOAD_TOKEN Token; - } - - /// - /// The DEVICE_LB_PROVISIONING_DESCRIPTOR structure is one of the query result structures returned from an - /// IOCTL_STORAGE_QUERY_PROPERTY request. This structure contains the thin provisioning capabilities for a storage device. - /// - /// - /// - /// This structure is returned from a IOCTL_STORAGE_QUERY_PROPERTY request when the PropertyId member of - /// STORAGE_PROPERTY_QUERY is set to StorageDeviceLBProvisioningProperty. - /// - /// - /// If UnmapGranularityAlignmentValid = 0, then any code using UnmapGranularityAlignment should assume it has a value - /// of 0. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_lb_provisioning_descriptor typedef struct - // _DEVICE_LB_PROVISIONING_DESCRIPTOR { DWORD Version; DWORD Size; BYTE ThinProvisioningEnabled : 1; BYTE ThinProvisioningReadZeros - // : 1; BYTE AnchorSupported : 3; BYTE UnmapGranularityAlignmentValid : 1; BYTE Reserved0 : 2; BYTE Reserved1[7]; DWORDLONG - // OptimalUnmapGranularity; DWORDLONG UnmapGranularityAlignment; DWORD MaxUnmapLbaCount; DWORD MaxUnmapBlockDescriptorCount; } - // DEVICE_LB_PROVISIONING_DESCRIPTOR, *PDEVICE_LB_PROVISIONING_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_LB_PROVISIONING_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_LB_PROVISIONING_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - private byte flags; - - /// - /// The thin provisioning–enabled status. - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// Thin provisioning is disabled. - /// - /// - /// 1 - /// Thin provisioning is enabled. - /// - /// - /// - public bool ThinProvisioningEnabled { get => BitHelper.GetBit(flags, 0); set => BitHelper.SetBit(ref flags, 0, value); } - - /// - /// Reads to unmapped regions return zeros. - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// Data read from unmapped regions is undefined. - /// - /// - /// 1 - /// Reads return zeros. - /// - /// - /// - public bool ThinProvisioningReadZeros { get => BitHelper.GetBit(flags, 1); set => BitHelper.SetBit(ref flags, 1, value); } - - /// - /// Deterministic read after trim support. - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// Deterministic read after trim is not supported. - /// - /// - /// 1 - /// Deterministic read after trim is supported. - /// - /// - /// - public byte AnchorSupported { get => BitHelper.GetBits(flags, 2, 3); set => BitHelper.SetBits(ref flags, 2, 3, value); } - - /// - /// The validity of unmap granularity alignment for the device. - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// Unmap granularity alignment is not valid. - /// - /// - /// 1 - /// Unmap granularity alignment is valid. - /// - /// - /// - public bool UnmapGranularityAlignmentValid { get => BitHelper.GetBit(flags, 5); set => BitHelper.SetBit(ref flags, 5, value); } - - /// Reserved. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] - public byte[] Reserved1; - - /// The optimal number of logical sectors for unmap granularity for the device. - public ulong OptimalUnmapGranularity; - - /// The current value, in logical sectors, set for unmap granularity alignment on the device. - public ulong UnmapGranularityAlignment; - - /// - /// Starting in Windows 10: The maximum number of LBAs that can be unmapped in a single unmap command, in logical blocks. - /// - public uint MaxUnmapLbaCount; - - /// Starting in Windows 10: The maximum number of descriptors allowed in a single unmap command. - public uint MaxUnmapBlockDescriptorCount; - } - - /// Input structure for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - /// - /// The total length of the buffer that contains this structure must be at least - /// (sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + ParameterBlockLength + DataSetRangesLength) - /// . - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_manage_data_set_attributes typedef struct - // _DEVICE_MANAGE_DATA_SET_ATTRIBUTES { DWORD Size; DEVICE_DSM_ACTION Action; DWORD Flags; DWORD ParameterBlockOffset; DWORD - // ParameterBlockLength; DWORD DataSetRangesOffset; DWORD DataSetRangesLength; } DEVICE_MANAGE_DATA_SET_ATTRIBUTES, - // *PDEVICE_MANAGE_DATA_SET_ATTRIBUTES, DEVICE_DSM_INPUT, *PDEVICE_DSM_INPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_MANAGE_DATA_SET_ATTRIBUTES")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_MANAGE_DATA_SET_ATTRIBUTES - { - /// - /// Size of this data structure. Must be set to - /// sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) - /// . - /// - public uint Size; - - /// - /// A valid value of type DEVICE_DATA_MANAGEMENT_SET_ACTION. - /// - /// - /// Value - /// Meaning - /// - /// - /// DeviceDsmAction_Trim 1 - /// A trim action is performed. This value is not supported for user-mode applications. - /// - /// - /// DeviceDsmAction_Notification 2 | DeviceDsmActionFlag_NonDestructive (0x80000002) - /// - /// A notification action is performed. The additional parameters are in a DEVICE_DSM_NOTIFICATION_PARAMETERS structure. The - /// DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver stack that this operation is non-destructive. - /// - /// - /// - /// DeviceDsmAction_OffloadRead 3 | DeviceDsmActionFlag_NonDestructive (0x80000003) - /// - /// An offload read action is performed. The additional parameters are in a DEVICE_DSM_OFFLOAD_READ_PARAMETERS structure. The - /// DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver stack that this operation is - /// non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_OffloadWrite 4 - /// - /// An offload write action is performed. The additional parameters are in a DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS structure. - /// Windows 7 and Windows Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_Allocation 5 | DeviceDsmActionFlag_NonDestructive (0x80000005) - /// - /// An allocation bitmap is retrieved for the first data set range specified. The DeviceDsmActionFlag_NonDestructive - /// (0x80000000) is a bit flag to indicate to the driver stack that this operation is non-destructive. Windows 7 and Windows - /// Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_Repair 6 | DeviceDsmActionFlag_NonDestructive (0x80000006) - /// - /// A repair action is performed. The additional parameters are in a DEVICE_DATA_SET_REPAIR_PARAMETERS structure. The - /// DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver stack that this operation is - /// non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_Scrub 7 | DeviceDsmActionFlag_NonDestructive (0x80000007) - /// - /// A scrub action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver - /// stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before - /// Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_Resiliency 8 | DeviceDsmActionFlag_NonDestructive (0x80000008) - /// - /// A resiliency action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the - /// driver stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported - /// before Windows 8 and Windows Server 2012. - /// - /// - /// - /// - public DEVICE_DSM_ACTION Action; - - /// - /// Flags for the actions. - /// - /// - /// Value - /// Meaning - /// - /// - /// DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED 0x80000000 - /// - /// If set then the described ranges are not allocated by a file system. This flag is specific to the DeviceDsmAction_Trim action. - /// - /// - /// - /// DEVICE_DSM_FLAG_RESILIENCY_START_RESYNC 0x10000000 - /// Starts a resync operation on the storage device. This flag is specific to the DeviceDsmAction_Resiliency action. - /// - /// - /// DEVICE_DSM_FLAG_RESILIENCY_START_LOAD_BALANCING 0x20000000 - /// Starts a load balancing operation on the storage device. This flag is specific to the DeviceDsmAction_Resiliency action. - /// - /// - /// - public uint Flags; - - /// - /// Byte offset to the start of the parameter block stored in the buffer contiguous to this structure. Must be aligned to the - /// corresponding structure alignment. A value of zero indicates there is no parameter block and the ParameterBlockLength - /// member must also be zero. - /// - public uint ParameterBlockOffset; - - /// - /// Length of the parameter block, in bytes. A value of zero indicates there is no parameter block and the - /// ParameterBlockOffset member must also be zero. - /// - public uint ParameterBlockLength; - - /// - /// Byte offset to the start of the data set ranges block made up of an array of DEVICE_DATA_SET_RANGE structures stored in the - /// buffer contiguous to this structure. Must be aligned to the DEVICE_DATA_SET_RANGE structure alignment. A value of - /// zero indicates there is no data set ranges block and the DataSetRangesLength member must also be zero. - /// - public uint DataSetRangesOffset; - - /// - /// Length of the data set ranges block, in bytes. A value of zero indicates there is no data set ranges block and the - /// DataSetRangesOffset member must also be zero. - /// - public uint DataSetRangesLength; - } - - /// Output structure for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_manage_data_set_attributes_output typedef struct - // _DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT { DWORD Size; DEVICE_DSM_ACTION Action; DWORD Flags; DWORD OperationStatus; DWORD - // ExtendedError; DWORD TargetDetailedError; DWORD ReservedStatus; DWORD OutputBlockOffset; DWORD OutputBlockLength; } - // DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT, *PDEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT, DEVICE_DSM_OUTPUT, *PDEVICE_DSM_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT - { - /// - /// Size of the structure. This is set to - /// sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT) - /// . - /// - public uint Size; - - /// - /// - /// The action related to the instance of this structure. This is a value for the DEVICE_DATA_MANAGEMENT_SET_ACTION data type. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// DeviceDsmAction_Trim 1 - /// A trim action is performed. This value is not supported for user-mode applications. - /// - /// - /// DeviceDsmAction_Notification 2 | DeviceDsmActionFlag_NonDestructive (0x80000002) - /// - /// A notification action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the - /// driver stack that this operation is non-destructive. - /// - /// - /// - /// DeviceDsmAction_OffloadRead 3 | DeviceDsmActionFlag_NonDestructive (0x80000003) - /// - /// An offload read action is performed. The output described by the OutputBlockOffset and OutputBlockLength members is a - /// STORAGE_OFFLOAD_READ_OUTPUT structure. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the - /// driver stack that this operation is non-destructive. - /// - /// - /// - /// DeviceDsmAction_OffloadWrite 4 - /// - /// An offload write action is performed. The output described by the OutputBlockOffset and OutputBlockLength members is a - /// STORAGE_OFFLOAD_WRITE_OUTPUT structure. - /// - /// - /// - /// DeviceDsmAction_Allocation 5 | DeviceDsmActionFlag_NonDestructive (0x80000005) - /// - /// An allocation bitmap is returned for the first data set range passed in. The output is in a - /// DEVICE_DATA_SET_LB_PROVISIONING_STATE structure. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to - /// indicate to the driver stack that this operation is non-destructive. - /// - /// - /// - /// DeviceDsmAction_Repair 6 | DeviceDsmActionFlag_NonDestructive (0x80000006) - /// - /// A repair action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver - /// stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before - /// Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_Scrub 7 | DeviceDsmActionFlag_NonDestructive (0x80000007) - /// - /// A scrub action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver - /// stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before - /// Windows 8 and Windows Server 2012. - /// - /// - /// - /// DeviceDsmAction_Resiliency 8 | DeviceDsmActionFlag_NonDestructive (0x80000008) - /// - /// A resiliency action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the - /// driver stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported - /// before Windows 8 and Windows Server 2012. - /// - /// - /// - /// - public DEVICE_DSM_ACTION Action; - - /// Not used. - public uint Flags; - - /// Not used. - public uint OperationStatus; - - /// Extended error information. - public uint ExtendedError; - - /// Target specific error. - public uint TargetDetailedError; - - /// Reserved. - public uint ReservedStatus; - - /// The offset, in bytes, from the beginning of this structure to where any action-specific data is located. - public uint OutputBlockOffset; - - /// The length, in bytes, of the action-specific data. - public uint OutputBlockLength; - } - - /// Provides information about the media supported by a device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_media_info typedef struct _DEVICE_MEDIA_INFO { - // union { struct { LARGE_INTEGER Cylinders; STORAGE_MEDIA_TYPE MediaType; DWORD TracksPerCylinder; DWORD SectorsPerTrack; DWORD - // BytesPerSector; DWORD NumberMediaSides; DWORD MediaCharacteristics; } DiskInfo; struct { LARGE_INTEGER Cylinders; - // STORAGE_MEDIA_TYPE MediaType; DWORD TracksPerCylinder; DWORD SectorsPerTrack; DWORD BytesPerSector; DWORD NumberMediaSides; DWORD - // MediaCharacteristics; } RemovableDiskInfo; struct { STORAGE_MEDIA_TYPE MediaType; DWORD MediaCharacteristics; DWORD - // CurrentBlockSize; STORAGE_BUS_TYPE BusType; union { struct { BYTE MediumType; BYTE DensityCode; } ScsiInformation; } - // BusSpecificData; } TapeInfo; } DeviceSpecific; } DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_MEDIA_INFO")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_MEDIA_INFO - { - /// A union that contains the following members. - public DEVICESPECIFIC DeviceSpecific; - - /// A union that contains the following members. - [StructLayout(LayoutKind.Explicit)] - public struct DEVICESPECIFIC - { - /// A structure that contains the following members. - [FieldOffset(0)] - public DISKINFO DiskInfo; - - /// A structure that contains the following members. - [FieldOffset(0)] - public DISKINFO RemovableDiskInfo; - - /// A structure that contains the following members. - [FieldOffset(0)] - public TAPEINFO TapeInfo; - - /// A structure that contains the following members. - [StructLayout(LayoutKind.Sequential)] - public struct DISKINFO - { - /// The number of cylinders on this disk. - public long Cylinders; - - /// - /// The media type. This member can be one of the values from the STORAGE_MEDIA_TYPE or MEDIA_TYPE enumeration types. - /// - public STORAGE_MEDIA_TYPE MediaType; - - /// The number of tracks per cylinder. - public uint TracksPerCylinder; - - /// The number of sectors per track. - public uint SectorsPerTrack; - - /// The number of bytes per sector. - public uint BytesPerSector; - - /// - /// The number of sides of the disk that can contain data. This member is 1 for one-sided media or 2 for two-sided media. - /// - public uint NumberMediaSides; - - /// - /// The characteristics of the media. This member can be one or more of the following values. - /// DiskInfo.MediaCharacteristics.MEDIA_CURRENTLY_MOUNTED (0x80000000) - /// DiskInfo.MediaCharacteristics.MEDIA_ERASEABLE (0x00000001) - /// DiskInfo.MediaCharacteristics.MEDIA_READ_ONLY (0x00000004) - /// DiskInfo.MediaCharacteristics.MEDIA_READ_WRITE (0x00000008) - /// DiskInfo.MediaCharacteristics.MEDIA_WRITE_ONCE (0x00000002) - /// DiskInfo.MediaCharacteristics.MEDIA_WRITE_PROTECTED (0x00000100) - /// - public MEDIA_CHARACTER MediaCharacteristics; - } - - /// A structure that contains the following members. - [StructLayout(LayoutKind.Sequential)] - public struct TAPEINFO - { - /// - /// The media type. This member can be one of the values from the STORAGE_MEDIA_TYPE or MEDIA_TYPE enumeration types. - /// - public STORAGE_MEDIA_TYPE MediaType; - - /// - /// The characteristics of the media. This member can be one or more of the following values. - /// TapeInfo.MediaCharacteristics.MEDIA_CURRENTLY_MOUNTED (0x80000000) - /// TapeInfo.MediaCharacteristics.MEDIA_ERASEABLE (0x00000001) - /// TapeInfo.MediaCharacteristics.MEDIA_READ_ONLY (0x00000004) - /// TapeInfo.MediaCharacteristics.MEDIA_READ_WRITE (0x00000008) - /// TapeInfo.MediaCharacteristics.MEDIA_WRITE_ONCE (0x00000002) - /// TapeInfo.MediaCharacteristics.MEDIA_WRITE_PROTECTED (0x00000100) - /// - public MEDIA_CHARACTER MediaCharacteristics; // Bitmask of MEDIA_XXX values. - - /// The current block size, in bytes. - public uint CurrentBlockSize; - - /// - /// The type of bus to which the tape drive is connected. This members can be one of the STORAGE_BUS_TYPE enumeration values. - /// - public STORAGE_BUS_TYPE BusType; - - /// A union that contains the following members. - public BUSSPECIFICDATA BusSpecificData; - - /// A union that contains the following members. - [StructLayout(LayoutKind.Explicit)] - public struct BUSSPECIFICDATA - { - /// - [FieldOffset(0)] - public SCSIINFORMATION ScsiInformation; - - /// - [StructLayout(LayoutKind.Sequential)] - public struct SCSIINFORMATION - { - /// The SCSI-specific medium type. - public byte MediumType; - - /// The SCSI-specific current operating density for read/write operations. - public byte DensityCode; - } - } - } - } - } - - /// The DEVICE_POWER_DESCRIPTOR structure describes the power capabilities of a storage device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_power_descriptor typedef struct - // _DEVICE_POWER_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN DeviceAttentionSupported; BOOLEAN - // AsynchronousNotificationSupported; BOOLEAN IdlePowerManagementEnabled; BOOLEAN D3ColdEnabled; BOOLEAN D3ColdSupported; BOOLEAN - // NoVerifyDuringIdlePower; BYTE Reserved[2]; DWORD IdleTimeoutInMS; } DEVICE_POWER_DESCRIPTOR, *PDEVICE_POWER_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_POWER_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_POWER_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// True if device attention is supported. Otherwise, false. - [MarshalAs(UnmanagedType.U1)] - public bool DeviceAttentionSupported; - - /// - /// True if the device supports asynchronous notifications, delivered via IOCTL_STORAGE_EVENT_NOTIFICATION. Otherwise, false. - /// - [MarshalAs(UnmanagedType.U1)] - public bool AsynchronousNotificationSupported; - - /// True if the device has been registered for runtime idle power management. Otherwise, false. - [MarshalAs(UnmanagedType.U1)] - public bool IdlePowerManagementEnabled; - - /// True if the device will be powered off when put into D3 power state. Otherwise, false. - [MarshalAs(UnmanagedType.U1)] - public bool D3ColdEnabled; - - /// True if the platform supports D3ColdEnabled for this device. Otherwise, false. - [MarshalAs(UnmanagedType.U1)] - public bool D3ColdSupported; - - /// - [MarshalAs(UnmanagedType.U1)] - public bool NoVerifyDuringIdlePower; - - /// Reserved. - public ushort Reserved; - - /// The idle timeout value in milliseconds. This member is ignored unless IdlePowerManagementEnabled is true. - public uint IdleTimeoutInMS; - } - - /// - /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY request to retrieve the seek penalty descriptor data for a device. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_seek_penalty_descriptor typedef struct - // _DEVICE_SEEK_PENALTY_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN IncursSeekPenalty; } DEVICE_SEEK_PENALTY_DESCRIPTOR, *PDEVICE_SEEK_PENALTY_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_SEEK_PENALTY_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_SEEK_PENALTY_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// Specifies whether the device incurs a seek penalty. - [MarshalAs(UnmanagedType.U1)] - public bool IncursSeekPenalty; - } - - /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY request to retrieve the trim descriptor data for a device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_trim_descriptor typedef struct - // _DEVICE_TRIM_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN TrimEnabled; } DEVICE_TRIM_DESCRIPTOR, *PDEVICE_TRIM_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_TRIM_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_TRIM_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// Specifies whether trim is enabled for the device. - [MarshalAs(UnmanagedType.U1)] - public bool TrimEnabled; - } - - /// Reserved for system use. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_write_aggregation_descriptor typedef struct - // _DEVICE_WRITE_AGGREGATION_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN BenefitsFromWriteAggregation; } - // DEVICE_WRITE_AGGREGATION_DESCRIPTOR, *PDEVICE_WRITE_AGGREGATION_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_WRITE_AGGREGATION_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct DEVICE_WRITE_AGGREGATION_DESCRIPTOR - { - /// - /// Contains the size, in bytes, of this structure. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the descriptor, in bytes. - public uint Size; - - /// TRUE if the device benefits from write aggregation. - [MarshalAs(UnmanagedType.U1)] - public bool BenefitsFromWriteAggregation; - } - - /// Contains parameters for the FSCTL_DUPLICATE_EXTENTS control code that performs the Block Cloning operation. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-duplicate_extents_data typedef struct - // _DUPLICATE_EXTENTS_DATA { HANDLE FileHandle; LARGE_INTEGER SourceFileOffset; LARGE_INTEGER TargetFileOffset; LARGE_INTEGER - // ByteCount; } DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DUPLICATE_EXTENTS_DATA")] - [StructLayout(LayoutKind.Sequential)] - public struct DUPLICATE_EXTENTS_DATA - { - /// - /// A handle to the source file from which the byte range is to be copied. To retrieve a file handle, use the CreateFile function. - /// - public HFILE FileHandle; - - /// The offset, in bytes, to the beginning of the range to copy from the source file. - public long SourceFileOffset; - - /// The offset, in bytes, to place the copied byte range in the destination file. - public long TargetFileOffset; - - /// The length, in bytes, of the range to copy. - public long ByteCount; - } - - /// - /// Indicates a range of bytes in a file. This structure is used with the FSCTL_QUERY_ALLOCATED_RANGES control code. On input, the - /// structure indicates the range of the file to search. On output, the operation retrieves an array of - /// FILE_ALLOCATED_RANGE_BUFFER structures to indicate the allocated ranges within the search range. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_allocated_range_buffer typedef struct - // _FILE_ALLOCATED_RANGE_BUFFER { LARGE_INTEGER FileOffset; LARGE_INTEGER Length; } FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_ALLOCATED_RANGE_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_ALLOCATED_RANGE_BUFFER - { - /// The file offset of the start of a range of bytes in a file, in bytes. - public long FileOffset; - - /// The size of the range, in bytes. - public long Length; - } - - /// Used as input to the FSCTL_FILE_LEVEL_TRIM control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_level_trim typedef struct _FILE_LEVEL_TRIM { DWORD - // Key; DWORD NumRanges; FILE_LEVEL_TRIM_RANGE Ranges[1]; } FILE_LEVEL_TRIM, *PFILE_LEVEL_TRIM; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_LEVEL_TRIM")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumRanges))] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_LEVEL_TRIM - { - /// Reserved. Set to zero (0). - public uint Key; - - /// - /// Number of FILE_LEVEL_TRIM_RANGE entries in the Ranges member. On return should be compared with the - /// NumRangesProcessed member of the FILE_LEVEL_TRIM_OUTPUT structure. - /// - public uint NumRanges; - - /// Array of ranges that describe the portions of the file that are to be trimmed. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public FILE_LEVEL_TRIM_RANGE[] Ranges; - } - - /// Used as output to the FSCTL_FILE_LEVEL_TRIM control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_level_trim_output typedef struct - // _FILE_LEVEL_TRIM_OUTPUT { DWORD NumRangesProcessed; } FILE_LEVEL_TRIM_OUTPUT, *PFILE_LEVEL_TRIM_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_LEVEL_TRIM_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_LEVEL_TRIM_OUTPUT - { - /// - /// Contains the number of ranges that were successfully processed. This may be less than the value passed in the - /// NumRanges member of the FILE_LEVEL_TRIM structure. If it is then the last ranges in the array were not processed. - /// - public uint NumRangesProcessed; - } - - /// Specifies a range of a file that is to be trimmed. - /// - /// Before the trim operation is passed to the underlying storage system the input ranges are reduced to be aligned to page - /// boundaries (4,096 bytes on 32-bit and x64-based editions of Windows, 8,192 bytes on Itanium-Based editions of Windows). - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_level_trim_range typedef struct - // _FILE_LEVEL_TRIM_RANGE { DWORDLONG Offset; DWORDLONG Length; } FILE_LEVEL_TRIM_RANGE, *PFILE_LEVEL_TRIM_RANGE; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_LEVEL_TRIM_RANGE")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_LEVEL_TRIM_RANGE - { - /// Offset, in bytes, from the start of the file for the range to be trimmed. - public ulong Offset; - - /// Length, in bytes, for the range to be trimmed. - public ulong Length; - } - - /// - /// Specifies the disc to close the current session for. This control code is used for UDF file systems. This structure is used for - /// input when calling FSCTL_MAKE_MEDIA_COMPATIBLE. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_make_compatible_buffer typedef struct - // _FILE_MAKE_COMPATIBLE_BUFFER { BOOLEAN CloseDisc; } FILE_MAKE_COMPATIBLE_BUFFER, *PFILE_MAKE_COMPATIBLE_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_MAKE_COMPATIBLE_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_MAKE_COMPATIBLE_BUFFER - { - /// If TRUE, indicates the media should be finalized. No new data can be appended to the media. - [MarshalAs(UnmanagedType.U1)] - public bool CloseDisc; - } - - /// Contains an object identifier and user-defined metadata associated with the object identifier. - /// - /// Object identifiers are used to track files and directories. They are invisible to most applications and should never be modified - /// by applications. Modifying an object identifier can result in the loss of data from portions of a file, up to and including - /// entire volumes of data. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_objectid_buffer typedef struct _FILE_OBJECTID_BUFFER - // { BYTE ObjectId[16]; union { struct { BYTE BirthVolumeId[16]; BYTE BirthObjectId[16]; BYTE DomainId[16]; } DUMMYSTRUCTNAME; BYTE - // ExtendedInfo[48]; } DUMMYUNIONNAME; } FILE_OBJECTID_BUFFER, *PFILE_OBJECTID_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_OBJECTID_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_OBJECTID_BUFFER - { - /// The identifier that uniquely identifies the file or directory within the volume on which it resides. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] ObjectId; - - /// - /// User-defined extended data to be set with FSCTL_SET_OBJECT_ID_EXTENDED. Use this data as an alternative to the - /// BirthVolumeId, BirthObjectId, and DomainId members. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] - public byte[] ExtendedInfo; - - /// - /// The identifier of the volume on which the object resided when the object identifier was created, or zero if the volume had - /// no object identifier at that time. After copy operations, move operations, or other file operations, this may not be the - /// same as the object identifier of the volume on which the object presently resides. - /// - public byte[] BirthVolumeId { get => ExtendedInfo.Take(16).ToArray(); set => Buffer.BlockCopy(value, 0, ExtendedInfo, 0, 16); } - - /// - /// The object identifier of the object at the time it was created. After copy operations, move operations, or other file - /// operations, this may not be the same as the ObjectId member at present. - /// - public byte[] BirthObjectId { get => ExtendedInfo.Skip(16).Take(16).ToArray(); set => Buffer.BlockCopy(value, 0, ExtendedInfo, 16, 16); } - - /// Reserved; must be zero. - public byte[] DomainId { get => ExtendedInfo.Skip(32).Take(16).ToArray(); set => Buffer.BlockCopy(value, 0, ExtendedInfo, 32, 16); } - } - - /// Receives the volume information from a call to FSCTL_QUERY_ON_DISK_VOLUME_INFO. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_query_on_disk_vol_info_buffer typedef struct - // _FILE_QUERY_ON_DISK_VOL_INFO_BUFFER { LARGE_INTEGER DirectoryCount; LARGE_INTEGER FileCount; WORD FsFormatMajVersion; WORD - // FsFormatMinVersion; WCHAR FsFormatName[12]; LARGE_INTEGER FormatTime; LARGE_INTEGER LastUpdateTime; WCHAR CopyrightInfo[34]; - // WCHAR AbstractInfo[34]; WCHAR FormattingImplementationInfo[34]; WCHAR LastModifyingImplementationInfo[34]; } - // FILE_QUERY_ON_DISK_VOL_INFO_BUFFER, *PFILE_QUERY_ON_DISK_VOL_INFO_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_QUERY_ON_DISK_VOL_INFO_BUFFER")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct FILE_QUERY_ON_DISK_VOL_INFO_BUFFER - { - /// - /// The number of directories on the specified disk. This member is -1 if the number is unknown. - /// - /// For UDF file systems with a virtual allocation table, this information is available only if the UDF revision is greater than 1.50. - /// - /// - public long DirectoryCount; - - /// - /// The number of files on the specified disk. Returns -1 if the number is unknown. - /// - /// For UDF file systems with a virtual allocation table, this information is available only if the UDF revision is greater than 1.50. - /// - /// - public long FileCount; - - /// - /// The major version number of the file system. Returns -1 if the number is unknown or not applicable. On UDF 1.02 file - /// systems, 1 is returned. - /// - public ushort FsFormatMajVersion; - - /// - /// The minor version number of the file system. Returns -1 if the number is unknown or not applicable. On UDF 1.02 file - /// systems, 02 is returned. - /// - public ushort FsFormatMinVersion; - - /// Always returns UDF. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)] - public string FsFormatName; - - /// The time the media was formatted. - public long FormatTime; - - /// The time the media was last updated. - public long LastUpdateTime; - - /// Any copyright information associated with the volume. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] - public string CopyrightInfo; - - /// Any abstract information written on the media. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] - public string AbstractInfo; - - /// - /// Implementation-specific information; in some cases, it is the operating system version that the media was formatted by. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] - public string FormattingImplementationInfo; - - /// - /// The last implementation that modified the disk. This information is implementation specific; in some cases, it is the - /// operating system version that the media was last modified by. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] - public string LastModifyingImplementationInfo; - } - - /// Contains defect management properties. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_query_sparing_buffer typedef struct - // _FILE_QUERY_SPARING_BUFFER { DWORD SparingUnitBytes; BOOLEAN SoftwareSparing; DWORD TotalSpareBlocks; DWORD FreeSpareBlocks; } - // FILE_QUERY_SPARING_BUFFER, *PFILE_QUERY_SPARING_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_QUERY_SPARING_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_QUERY_SPARING_BUFFER - { - /// The size of a sparing packet and the underlying error check and correction (ECC) block size of the volume. - public uint SparingUnitBytes; - - /// If TRUE, indicates that sparing behavior is software-based; if FALSE, it is hardware-based. - [MarshalAs(UnmanagedType.U1)] - public bool SoftwareSparing; - - /// The total number of blocks allocated for sparing. - public uint TotalSpareBlocks; - - /// The number of blocks available for sparing. - public uint FreeSpareBlocks; - } - - /// Specifies the defect management state to be set. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_set_defect_mgmt_buffer typedef struct - // _FILE_SET_DEFECT_MGMT_BUFFER { BOOLEAN Disable; } FILE_SET_DEFECT_MGMT_BUFFER, *PFILE_SET_DEFECT_MGMT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_SET_DEFECT_MGMT_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_SET_DEFECT_MGMT_BUFFER - { - /// If TRUE, indicates that defect management is disabled. - [MarshalAs(UnmanagedType.U1)] - public bool Disable; - } - - /// - /// Specifies the sparse state to be set. Windows Server 2003 and Windows XP: This structure is optional. For more - /// information, see FSCTL_SET_SPARSE. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_set_sparse_buffer typedef struct - // _FILE_SET_SPARSE_BUFFER { BOOLEAN SetSparse; } FILE_SET_SPARSE_BUFFER, *PFILE_SET_SPARSE_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_SET_SPARSE_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_SET_SPARSE_BUFFER - { - /// - /// If TRUE, makes the file sparse. - /// If FALSE, makes the file not sparse. - /// - /// Windows Server 2008 R2, Windows 7, Windows Server 2008 and Windows Vista: A value of FALSE for this member is - /// valid only on files that no longer have any sparse regions. For more information, see FSCTL_SET_SPARSE. - /// - /// - /// Windows Server 2003 and Windows XP: A value of FALSE for this member is not supported. Specifying FALSE - /// will cause the FSCTL_SET_SPARSE call to fail. - /// - /// - [MarshalAs(UnmanagedType.U1)] - public bool SetSparse; - } - - /// Represents an identifier for the storage tier relative to the volume. - /// - /// The storage tier ID for a particular volume has no relationship to the storage tier ID with the same value on a different volume. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_storage_tier typedef struct _FILE_STORAGE_TIER { - // GUID Id; WCHAR Name[FILE_STORAGE_TIER_NAME_LENGTH]; WCHAR Description[FILE_STORAGE_TIER_NAME_LENGTH]; DWORDLONG Flags; DWORDLONG - // ProvisionedCapacity; FILE_STORAGE_TIER_MEDIA_TYPE MediaType; FILE_STORAGE_TIER_CLASS Class; } FILE_STORAGE_TIER, *PFILE_STORAGE_TIER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_STORAGE_TIER")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_STORAGE_TIER - { - /// Tier ID. - public Guid Id; - - /// Name for the tier. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FILE_STORAGE_TIER_NAME_LENGTH)] - public string Name; - - /// Note for the tier. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FILE_STORAGE_TIER_NAME_LENGTH)] - public string Description; - - /// - /// The file storage tier flags. This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// FILE_STORAGE_TIER_FLAG_NO_SEEK_PENALTY 0x00020000 - /// Tier does not suffer a seek penalty on IO operations, which indicates that is an SSD (solid state drive). - /// - /// - /// - public FILE_STORAGE_TIER_FLAG Flags; - - /// Provisioned capacity of the tier. - public ulong ProvisionedCapacity; - - /// Media type of the tier. - public FILE_STORAGE_TIER_MEDIA_TYPE MediaType; - - /// - public FILE_STORAGE_TIER_CLASS Class; - } - - /// Describes a single storage tier region. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_storage_tier_region typedef struct - // _FILE_STORAGE_TIER_REGION { GUID TierId; DWORDLONG Offset; DWORDLONG Length; } FILE_STORAGE_TIER_REGION, *PFILE_STORAGE_TIER_REGION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_STORAGE_TIER_REGION")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_STORAGE_TIER_REGION - { - /// Tier ID. - public Guid TierId; - - /// Offset from the beginning of the volume of this region, in bytes. - public ulong Offset; - - /// Length of region in bytes. - public ulong Length; - } - - /// Describes a single storage tier region. - /// Contains file system recognition information retrieved by the FSCTL_QUERY_FILE_SYSTEM_RECOGNITION control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_system_recognition_information typedef struct - // _FILE_SYSTEM_RECOGNITION_INFORMATION { CHAR FileSystem[9]; } FILE_SYSTEM_RECOGNITION_INFORMATION, *PFILE_SYSTEM_RECOGNITION_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_SYSTEM_RECOGNITION_INFORMATION")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct FILE_SYSTEM_RECOGNITION_INFORMATION - { - /// - /// The file system name stored on the disk. This is a null-terminated string of 8 ASCII characters that represents the - /// nonlocalizable human-readable name of the file system the volume is formatted with. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)] - public string FileSystem; - } - - /// Contains a range of a file to set to zeros. This structure is used by the FSCTL_SET_ZERO_DATA control code - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_zero_data_information typedef struct - // _FILE_ZERO_DATA_INFORMATION { LARGE_INTEGER FileOffset; LARGE_INTEGER BeyondFinalZero; } FILE_ZERO_DATA_INFORMATION, *PFILE_ZERO_DATA_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_ZERO_DATA_INFORMATION")] - [StructLayout(LayoutKind.Sequential)] - public struct FILE_ZERO_DATA_INFORMATION - { - /// The file offset of the start of the range to set to zeros, in bytes. - public long FileOffset; - - /// The byte offset of the first byte beyond the last zeroed byte. - public long BeyondFinalZero; - } - - /// Contains data for the FSCTL_FIND_FILES_BY_SID control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-find_by_sid_data typedef struct { DWORD Restart; SID Sid; - // } FIND_BY_SID_DATA, *PFIND_BY_SID_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_12")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(SubAuthorityCount))] - [StructLayout(LayoutKind.Sequential)] - public struct FIND_BY_SID_DATA - { - /// - /// Indicates whether to restart the search. This member should be 1 on first call, so the search will start from the root. For - /// subsequent calls, this member should be zero so the search will resume at the point where it stopped. - /// - public uint Restart; - - private byte Revision; - private byte SubAuthorityCount; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - private byte[] IdentifierAuthority; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - private uint[] SubAuthority; - - /// A SID structure that specifies the desired creator owner. - public byte[] Sid - { - get - { - var value = new byte[8 + SubAuthorityCount * 4]; - value[0] = Revision; - value[1] = SubAuthorityCount; - for (int i = 0; i < 6; i++) - value[i + 2] = IdentifierAuthority[i]; - for (int i = 0; i < SubAuthorityCount; i++) - { - var sa = BitConverter.GetBytes(SubAuthority[i]); - for (int j = 0; j < 4; j++) - value[8 + (i * 4) + j] = sa[j]; - } - return value; - } - set - { - if (value is null || value.Length < 12) throw new ArgumentException(); - Revision = value[0]; - SubAuthorityCount = value[1]; - if (value.Length < 8 + 4 * SubAuthorityCount) throw new ArgumentException(); - for (int i = 0; i < 6; i++) - IdentifierAuthority[i] = value[i + 2]; - for (int i = 0; i < SubAuthorityCount; i++) - SubAuthority[i] = BitConverter.ToUInt32(value, 8 + (i * 4)); - } - } - } - - /// Represents a file name. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-find_by_sid_output typedef struct { DWORD - // NextEntryOffset; DWORD FileIndex; DWORD FileNameLength; WCHAR FileName[1]; } FIND_BY_SID_OUTPUT, *PFIND_BY_SID_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_13")] - [VanaraMarshaler(typeof(AnySizeStringMarshaler), nameof(FileNameLength) + ":br")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct FIND_BY_SID_OUTPUT - { - /// - public uint NextEntryOffset; - - /// - public uint FileIndex; - - /// The size of the file name, in bytes. This size does not include the NULL character. - public uint FileNameLength; - - /// A pointer to a null-terminated string that specifies the file name. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] - public string FileName; - } - - /// - /// Contains information used in formatting a contiguous set of disk tracks. It is used by the IOCTL_DISK_FORMAT_TRACKS_EX control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-format_ex_parameters typedef struct _FORMAT_EX_PARAMETERS - // { MEDIA_TYPE MediaType; DWORD StartCylinderNumber; DWORD EndCylinderNumber; DWORD StartHeadNumber; DWORD EndHeadNumber; WORD - // FormatGapLength; WORD SectorsPerTrack; WORD SectorNumber[1]; } FORMAT_EX_PARAMETERS, *PFORMAT_EX_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FORMAT_EX_PARAMETERS")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(SectorsPerTrack))] - [StructLayout(LayoutKind.Sequential)] - public struct FORMAT_EX_PARAMETERS - { - /// The media type. For a list of values, see MEDIA_TYPE. - public MEDIA_TYPE MediaType; - - /// The cylinder number at which to begin the format. - public uint StartCylinderNumber; - - /// The cylinder number at which to end the format. - public uint EndCylinderNumber; - - /// The beginning head location. - public uint StartHeadNumber; - - /// The ending head location. - public uint EndHeadNumber; - - /// The length of the gap between two successive sectors on a track. - public ushort FormatGapLength; - - /// The number of sectors in each track. - public ushort SectorsPerTrack; - - /// An array of values specifying the sector numbers of the sectors to be included in the track to be formatted. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public ushort[] SectorNumber; - } - - /// - /// Contains information used in formatting a contiguous set of disk tracks. It is used by the IOCTL_DISK_FORMAT_TRACKS control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-format_parameters typedef struct _FORMAT_PARAMETERS { - // MEDIA_TYPE MediaType; DWORD StartCylinderNumber; DWORD EndCylinderNumber; DWORD StartHeadNumber; DWORD EndHeadNumber; } - // FORMAT_PARAMETERS, *PFORMAT_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FORMAT_PARAMETERS")] - [StructLayout(LayoutKind.Sequential)] - public struct FORMAT_PARAMETERS - { - /// The media type. For a list of values, see MEDIA_TYPE. - public MEDIA_TYPE MediaType; - - /// The cylinder number at which to begin the format. - public uint StartCylinderNumber; - - /// The cylinder number at which to end the format. - public uint EndCylinderNumber; - - /// The beginning head location. - public uint StartHeadNumber; - - /// The ending head location. - public uint EndHeadNumber; - } - - /// - /// Contains the integrity information for a file or directory. Returned from the FSCTL_GET_INTEGRITY_INFORMATION control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_get_integrity_information_buffer typedef struct - // _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER { WORD ChecksumAlgorithm; WORD Reserved; DWORD Flags; DWORD ChecksumChunkSizeInBytes; - // DWORD ClusterSizeInBytes; } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_GET_INTEGRITY_INFORMATION_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FSCTL_GET_INTEGRITY_INFORMATION_BUFFER - { - /// - /// The checksum algorithm used. - /// - /// - /// Value - /// Meaning - /// - /// - /// CHECKSUM_TYPE_NONE 0x0000 - /// The file or directory is not configured to use integrity. - /// - /// - /// CHECKSUM_TYPE_CRC64 0x0002 - /// The file or directory uses a CRC64 checksum to provide integrity. - /// - /// - /// 3–0xffff - /// Reserved for future use. - /// - /// - /// - public CHECKSUM_TYPE ChecksumAlgorithm; - - /// Reserved for future use. Set to 0. - public ushort Reserved; - - /// - /// Contains one or more flags. - /// - /// - /// Value - /// Meaning - /// - /// - /// FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 - /// If set, the checksum enforcement is disabled. - /// - /// - /// - public FSCTL_INTEGRITY_FLAG Flags; - - /// Size in bytes of the chunks used to calculate checksums. - public uint ChecksumChunkSizeInBytes; - - /// - /// Size in bytes of a cluster for this volume. This value must be a power of 2, must be greater than or equal to the sector - /// size of the underlying hardware and must be a power of 2 multiple of the sector size. - /// - public uint ClusterSizeInBytes; - } - - /// Contains the storage tier regions from the storage stack for a particular volume. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_query_region_info_input typedef struct - // _FSCTL_QUERY_REGION_INFO_INPUT { DWORD Version; DWORD Size; DWORD Flags; DWORD NumberOfTierIds; GUID TierIds[ANYSIZE_ARRAY]; } - // FSCTL_QUERY_REGION_INFO_INPUT, *PFSCTL_QUERY_REGION_INFO_INPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_QUERY_REGION_INFO_INPUT")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfTierIds))] - [StructLayout(LayoutKind.Sequential)] - public struct FSCTL_QUERY_REGION_INFO_INPUT - { - /// The size of this structure serves as the version. Set it to sizeof( FSCTL_QUERY_REGION_INFO_INPUT). - public uint Version; - - /// The size of this structure in bytes. - public uint Size; - - /// Reserved for future use. - public uint Flags; - - /// Number of entries in TierIds, 0 to request IDs for the entire volume. - public uint NumberOfTierIds; - - /// Array of storage tiers (represented by GUID values) for which to return information. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public Guid[] TierIds; - } - - /// Contains information for one or more regions. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_query_region_info_output typedef struct - // _FSCTL_QUERY_REGION_INFO_OUTPUT { DWORD Version; DWORD Size; DWORD Flags; DWORD Reserved; DWORDLONG Alignment; DWORD - // TotalNumberOfRegions; DWORD NumberOfRegionsReturned; FILE_STORAGE_TIER_REGION Regions[ANYSIZE_ARRAY]; } - // FSCTL_QUERY_REGION_INFO_OUTPUT, *PFSCTL_QUERY_REGION_INFO_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_QUERY_REGION_INFO_OUTPUT")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfRegionsReturned))] - [StructLayout(LayoutKind.Sequential)] - public struct FSCTL_QUERY_REGION_INFO_OUTPUT - { - /// The size of this structure serves as the version. Set it to sizeof( FSCTL_QUERY_REGION_INFO_OUTPUT). - public uint Version; - - /// The size of this structure in bytes. - public uint Size; - - /// Reserved for future use. - public uint Flags; - - /// Reserved for future use. - public uint Reserved; - - /// - /// Offset from the beginning of the volume to the first slab of the tiered volume. If the logical disk is made up of multiple - /// tiers and each tier maps to a set of regions then the first tier for the volume contained on the logical disk has a certain - /// offset within the tier that represents the offset of the volume on the logical disk. The Alignment member contains - /// this value. - /// - public ulong Alignment; - - /// Total number of available regions. - public uint TotalNumberOfRegions; - - /// Number of regions that fit in the output. - public uint NumberOfRegionsReturned; - - /// FILE_STORAGE_TIER_REGION struct that contains detailed information for each region. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public FILE_STORAGE_TIER_REGION[] Regions; - } - - /// Contains information for all tiers of a specific volume. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_query_storage_classes_output typedef struct - // _FSCTL_QUERY_STORAGE_CLASSES_OUTPUT { DWORD Version; DWORD Size; DWORD Flags; DWORD TotalNumberOfTiers; DWORD - // NumberOfTiersReturned; FILE_STORAGE_TIER Tiers[ANYSIZE_ARRAY]; } FSCTL_QUERY_STORAGE_CLASSES_OUTPUT, *PFSCTL_QUERY_STORAGE_CLASSES_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_QUERY_STORAGE_CLASSES_OUTPUT")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfTiersReturned))] - [StructLayout(LayoutKind.Sequential)] - public struct FSCTL_QUERY_STORAGE_CLASSES_OUTPUT - { - /// The size of this structure serves as the version. Set it to sizeof( FSCTL_QUERY_STORAGE_CLASSES_OUTPUT). - public uint Version; - - /// Size of this structure plus all the variable sized fields. - public uint Size; - - /// - /// The element status. This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// FILE_STORAGE_TIER_FLAG_NO_SEEK_PENALTY 0x00020000 - /// Tier does not suffer a seek penalty on IO operations, which indicates that is an SSD (solid state drive). - /// - /// - /// - public FILE_STORAGE_TIER_FLAG Flags; - - /// Total number of available tiers for this disk. - public uint TotalNumberOfTiers; - - /// Number of tiers that fit in the output. - public uint NumberOfTiersReturned; - - /// FILE_STORAGE_TIER structure that contains detailed info on the storage tiers. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public FILE_STORAGE_TIER[] Tiers; - } - - /// Input buffer passed with the FSCTL_SET_INTEGRITY_INFORMATION control code. - /// - /// If FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF is specified and the file is opened with sharing permissions such that - /// subsequent opens can succeed, it's possible for corrupt data to be read by an application that did not specify FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_set_integrity_information_buffer typedef struct - // _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { WORD ChecksumAlgorithm; WORD Reserved; DWORD Flags; } - // FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_SET_INTEGRITY_INFORMATION_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct FSCTL_SET_INTEGRITY_INFORMATION_BUFFER - { - /// - /// Specifies the checksum algorithm. - /// - /// - /// Value - /// Meaning - /// - /// - /// CHECKSUM_TYPE_NONE 0x0000 - /// The file or directory is not configured to use integrity. - /// - /// - /// CHECKSUM_TYPE_CRC64 0x0002 - /// The file or directory uses a CRC64 checksum to provide integrity. - /// - /// - /// 3–0xfffe - /// Reserved for future use. Must not be used. - /// - /// - /// CHECKSUM_TYPE_UNCHANGED 0xffff - /// The checksum algorithm is to remain the same. - /// - /// - /// - public CHECKSUM_TYPE ChecksumAlgorithm; - - /// Must be 0 - public ushort Reserved; - - /// - /// Contains zero or more flags. - /// - /// - /// Value - /// Meaning - /// - /// - /// FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 - /// - /// If set, the checksum enforcement is disabled and reads will succeed even if the checksums do not match. This flag is valid - /// only if the file has an integrity algorithm set. If there is no algorithm set or the CheckSum member is set to - /// CHECKSUM_TYPE_NONE, then the operation fails with ERROR_INVALID_PARAMETER. - /// - /// - /// - /// - public FSCTL_INTEGRITY_FLAG Flags; - } - - /// Represents the parameters of a changer. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_changer_parameters typedef struct - // _GET_CHANGER_PARAMETERS { DWORD Size; WORD NumberTransportElements; WORD NumberStorageElements; WORD NumberCleanerSlots; WORD - // NumberIEElements; WORD NumberDataTransferElements; WORD NumberOfDoors; WORD FirstSlotNumber; WORD FirstDriveNumber; WORD - // FirstTransportNumber; WORD FirstIEPortNumber; WORD FirstCleanerSlotAddress; WORD MagazineSize; DWORD DriveCleanTimeout; DWORD - // Features0; DWORD Features1; BYTE MoveFromTransport; BYTE MoveFromSlot; BYTE MoveFromIePort; BYTE MoveFromDrive; BYTE - // ExchangeFromTransport; BYTE ExchangeFromSlot; BYTE ExchangeFromIePort; BYTE ExchangeFromDrive; BYTE LockUnlockCapabilities; BYTE - // PositionCapabilities; BYTE Reserved1[2]; DWORD Reserved2[2]; } GET_CHANGER_PARAMETERS, *PGET_CHANGER_PARAMETERS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_CHANGER_PARAMETERS")] - [StructLayout(LayoutKind.Sequential)] - public struct GET_CHANGER_PARAMETERS - { - /// - /// The size of this structure, in bytes. The caller must set this member to - /// sizeof(GET_CHANGER_PARAMETERS) - /// . - /// - public uint Size; - - /// - /// The number of transport elements in the changer. For a SCSI changer, this is defined in the element address page. This value - /// is almost always 1, because most changers have a single transport element with one or two picker mechanisms. A changer that - /// has two picker mechanisms on its transport must not be represented as having two transports, because pickers are not - /// individually addressable. High-end media libraries can have dual and multiple transport elements for fault tolerance. - /// - public ushort NumberTransportElements; - - /// - /// The number of storage elements (slots) in the changer. For a SCSI changer, this is defined in the element address page. This - /// value represents the maximum number of slots available for this changer including those in removable magazines, whether or - /// not the magazines are installed. If NumberCleanerSlots is 1, then NumberStorageElements is 1 less than the - /// maximum number of slots in the changer. - /// - public ushort NumberStorageElements; - - /// - /// The number of storage elements (slots) for cleaner cartridges in the changer. If NumberCleanerSlots is 1, then - /// FirstCleanerSlotAddress indicates the zero-based address of the slot in which a drive cleaner should be inserted. If - /// the changer does not support drive cleaning by programmatically moving the cleaner cartridge from its slot to a drive, - /// NumberCleanerSlots is 0. NumberCleanerSlots cannot be greater than 1. - /// - public ushort NumberCleanerSlots; - - /// - /// The number of import/export elements (insert/eject ports) the changer has for inserting and ejecting media. For a SCSI - /// changer, this is defined in the element address page. An import/export element must not be part of the storage element - /// (slot) space, and it must be possible to transport media between the import/export element and a slot using a MOVE MEDIUM - /// command. If the changer has a door and not a true import/export element, NumberIEElements is 0. - /// - public ushort NumberIEElements; - - /// - /// The number of data transfer elements (drives) in the changer. For a SCSI changer, this is defined in the element address - /// page. Unlike NumberStorageElements, which indicates the total number of possible slots whether or not the slots are - /// actually present, NumberDataTransferElements indicates the number of drives that are actually present in the changer. - /// - public ushort NumberDataTransferElements; - - /// - /// The number of doors in the changer. A door provides access to all media in the changer at once, unlike an insert/eject port, - /// which provides access to one or more, but not all, media. A changer's door can be a physical front door or a single magazine - /// that contains all media. If a changer supports only an insert/eject port for inserting and ejecting media, - /// NumberOfDoors is 0. - /// - public ushort NumberOfDoors; - - /// - /// The number used by the changer vendor to identify the first storage element (slot) in the changer to the end user, either by - /// marking a magazine or by defining a slot numbering scheme in the changer's operators guide. FirstSlotNumber is - /// typically 0 or 1, but it can be the first address in a consecutive range of slot addresses defined by the vendor. - /// - public ushort FirstSlotNumber; - - /// - /// The number used by the changer vendor to identify the first data transfer element (drive) in the changer to the end user. - /// FirstDriveNumber is typically 0 or 1, but it can be the first address in a consecutive range of drive addresses - /// defined by the vendor. - /// - public ushort FirstDriveNumber; - - /// - /// The number used by the changer vendor to identify the first (and usually only) transport element in the changer to the end - /// user. FirstTransportNumber is typically 0 or 1, but it can be the first address in a consecutive range of transport - /// addresses defined by the vendor. - /// - public ushort FirstTransportNumber; - - /// - /// The number used by the changer vendor to identify the first (and usually only) insert/eject port in the changer to the end - /// user. FirstIEPortNumber is typically 0 or 1, but it can be the first address in a consecutive range of insert/eject - /// port addresses defined by the vendor. If NumberIEElements is 0, FirstIEPortNumber must also be 0. - /// - public ushort FirstIEPortNumber; - - /// - /// The number used by the changer vendor to identify the first (and only) slot address assigned to a drive cleaner cartridge to - /// the end user. This must be the value defined by the vendor in the changer's operators guide. For example, if a changer has 8 - /// slots numbered 1 through 8 and its operator's guide designates slot 8 as the drive cleaner slot, FirstSlotNumber - /// would be 1 and FirstCleanerSlotAddress would be 8. If the same 8 slots were numbered 0 through 7, - /// FirstSlotNumber would be 0 and FirstCleanerSlotAddress would be 7. If NumberCleanerSlots is 0, - /// FirstCleanerSlotAddress must be 0. - /// - public ushort FirstCleanerSlotAddress; - - /// - /// The number of slots in the removable magazines in the changer. This member is valid only if CHANGER_CARTRIDGE_MAGAZINE is - /// set in Features0. - /// - public ushort MagazineSize; - - /// - /// Twice the maximum number of seconds a cleaning is expected to take. The changer's drives should be cleaned by its cleaner - /// cartridge in half the time specified by DriveCleanTimeout. For example, if a drive is typically cleaned in 300 - /// seconds (5 minutes), DriveCleanTimeout should be set to 600. - /// - public uint DriveCleanTimeout; - - /// - /// The features supported by the changer. This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// CHANGER_BAR_CODE_SCANNER_INSTALLED 0x00000001 - /// The changer supports a bar-code reader and the reader is installed. - /// - /// - /// CHANGER_CARTRIDGE_MAGAZINE 0x00000100 - /// The changer uses removable cartridge magazines for some or all storage slots. - /// - /// - /// CHANGER_CLEANER_ACCESS_NOT_VALID 0x00040000 - /// - /// The ELEMENT_STATUS_ACCESS flag in a CHANGER_ELEMENT_STATUS structure for a data transport element is invalid when the - /// transport element contains a cleaning cartridge. - /// - /// - /// - /// CHANGER_CLEANER_SLOT 0x00000040 - /// - /// The changer has a slot designated for a cleaner cartridge. If this flag is set, NumberCleanerSlots must be 1 and - /// FirstCleanerSlotAddress must specify the address of the cleaner slot. - /// - /// - /// - /// CHANGER_CLOSE_IEPORT 0x00000004 - /// The changer has an insert/eject port and can retract the insert/eject port programmatically. - /// - /// - /// CHANGER_DEVICE_REINITIALIZE_CAPABLE 0x08000000 - /// The changer can recalibrate its transport element in response to an explicit command. - /// - /// - /// CHANGER_DRIVE_CLEANING_REQUIRED 0x00010000 - /// - /// The changer's drives require periodic cleaning, which must be initiated by either the user or an application, and the - /// changer can use its transport element to mount a cleaner cartridge in a drive. - /// - /// - /// - /// CHANGER_DRIVE_EMPTY_ON_DOOR_ACCESS 0x20000000 - /// The changer requires all drives to be empty (dismounted) before they can be accessed through its door. - /// - /// - /// CHANGER_EXCHANGE_MEDIA 0x00000020 - /// - /// The changer can exchange media between elements. For a SCSI changer, this flag indicates whether the changer supports the - /// EXCHANGE MEDIUM command. - /// - /// - /// - /// CHANGER_INIT_ELEM_STAT_WITH_RANGE 0x00000002 - /// - /// The changer can initialize elements within a specified range. For a SCSI changer, this flag indicates whether the changer - /// supports the INITIALIZE ELEMENT STATUS WITH RANGE command. - /// - /// - /// - /// CHANGER_KEYPAD_ENABLE_DISABLE 0x10000000 - /// The changer keypad can be enabled and disabled programmatically. - /// - /// - /// CHANGER_LOCK_UNLOCK 0x00000080 - /// - /// The changer's door, insert/eject port, or keypad can be locked or unlocked programmatically. If this flag is set, - /// LockUnlockCapabilities indicates which elements can be locked or unlocked. - /// - /// - /// - /// CHANGER_MEDIUM_FLIP 0x00000200 - /// - /// The changer's transport element supports flipping (rotating) media. For a SCSI changer, this flag reflects the rotate bit in - /// the transport geometry parameters page. - /// - /// - /// - /// CHANGER_OPEN_IEPORT 0x00000008 - /// The changer has an insert/eject port and can extend the insert/eject port programmatically. - /// - /// - /// CHANGER_POSITION_TO_ELEMENT 0x00000400 - /// - /// The changer can position the transport to a particular destination. For a SCSI changer, this flag indicates whether the - /// changer supports the POSITION TO ELEMENT command. If this flag is set, PositionCapabilities indicates the elements to which - /// the transport can be positioned. - /// - /// - /// - /// CHANGER_PREDISMOUNT_EJECT_REQUIRED 0x00020000 - /// - /// The changer requires an explicit command issued through a mass-storage driver (tape, disk, or CDROM, for example) to eject - /// media from a drive before the changer can move the media from a drive to a slot. - /// - /// - /// - /// CHANGER_PREMOUNT_EJECT_REQUIRED 0x00080000 - /// - /// The changer requires an explicit command issued through a mass storage driver to eject a drive mechanism before the changer - /// can move media from a slot to the drive. For example, a changer with CD-ROM drives might require the tray to be presented to - /// the robotic transport so that a piece of media could be loaded onto the tray during a mount operation. - /// - /// - /// - /// CHANGER_REPORT_IEPORT_STATE 0x00000800 - /// - /// The changer can report whether media is present in the insert/eject port. Such a changer must have a sensor in the - /// insert/eject port to detect the presence or absence of media. - /// - /// - /// - /// CHANGER_SERIAL_NUMBER_VALID 0x04000000 - /// - /// The serial number is valid and unique for all changers of this type. Serial numbers are not guaranteed to be unique across - /// vendor and product lines. - /// - /// - /// - /// CHANGER_STATUS_NON_VOLATILE 0x00000010 - /// The changer uses nonvolatile memory for element status information. - /// - /// - /// CHANGER_STORAGE_DRIVE 0x00001000 - /// - /// The changer can use a drive as an independent storage element; that is, it can store media in the drive without reading it. - /// For a SCSI changer, this flag reflects the state of the DT bit in the device capabilities page. - /// - /// - /// - /// CHANGER_STORAGE_IEPORT 0x00002000 - /// - /// The changer can use an insert/eject port as an independent storage element. For a SCSI changer, this flag reflects the state - /// of the I/E bit in the device capabilities page. - /// - /// - /// - /// CHANGER_STORAGE_SLOT 0x00004000 - /// - /// The changer can use a slot as an independent storage element for media. For a SCSI changer, this flag reflects the state of - /// the ST bit in the device capabilities page. Slots are the normal storage location for media, so the changer must support - /// this functionality. - /// - /// - /// - /// CHANGER_STORAGE_TRANSPORT 0x00008000 - /// - /// The changer can use a transport as an independent storage element. For a SCSI changer, this flag reflects the state of the - /// MT bit in the device capabilities page. - /// - /// - /// - /// CHANGER_VOLUME_ASSERT 0x00400000 - /// - /// The changer can verify volume information. For a SCSI changer, this flag indicates whether the changer supports the SEND - /// VOLUME TAG command with a send action code of ASSERT. - /// - /// - /// - /// CHANGER_VOLUME_IDENTIFICATION 0x00100000 - /// - /// The changer supports volume identification. For a SCSI changer, this flag indicates whether the changer supports the SEND - /// VOLUME TAG and REQUEST VOLUME ELEMENT ADDRESS commands. - /// - /// - /// - /// CHANGER_VOLUME_REPLACE 0x00800000 - /// - /// The changer can replace volume information. For a SCSI changer, this flag indicates whether the changer supports the SEND - /// VOLUME TAG command with a send action code of REPLACE. - /// - /// - /// - /// CHANGER_VOLUME_SEARCH 0x00200000 - /// - /// The changer can search for volume information. For a SCSI changer, this flag indicates whether the changer supports the - /// supports the SEND VOLUME TAG command with a send action code of TRANSLATE. - /// - /// - /// - /// CHANGER_VOLUME_UNDEFINE 0x01000000 - /// - /// The changer can clear existing volume information. For a SCSI changer, this flag indicates whether the changer supports the - /// SEND VOLUME TAG command with a send action code of UNDEFINE. - /// - /// - /// - /// - public CHANGER_FEATURES0 Features0; - - /// - /// Any additional features supported by the changer. This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// CHANGER_CLEANER_AUTODISMOUNT 0x80000004 - /// The changer will move the cleaning cartridge back to its original slot automatically after cleaning is finished. - /// - /// - /// CHANGER_CLEANER_OPS_NOT_SUPPORTED 0x80000040 - /// The changer does not support automatic cleaning of its elements. - /// - /// - /// CHANGER_IEPORT_USER_CONTROL_CLOSE 0x80000100 - /// The changer requires the user to manually close an open insert/eject port. - /// - /// - /// CHANGER_IEPORT_USER_CONTROL_OPEN 0x80000080 - /// The changer requires the user to manually open a closed insert/eject port. - /// - /// - /// CHANGER_MOVE_EXTENDS_IEPORT 0x80000200 - /// The changer will extend the tray automatically whenever a command is issued to move media to an insert/eject port. - /// - /// - /// CHANGER_MOVE_RETRACTS_IEPORT 0x80000400 - /// The changer will retract the tray automatically whenever a command is issued to move media from an insert/eject port. - /// - /// - /// CHANGER_PREDISMOUNT_ALIGN_TO_DRIVE 0x80000002 - /// - /// The changer requires an explicit command to position the transport element to a drive before it can eject media from the drive. - /// - /// - /// - /// CHANGER_PREDISMOUNT_ALIGN_TO_SLOT 0x80000001 - /// - /// The changer requires an explicit command to position the transport element to a slot before it can eject media from the slot. - /// - /// - /// - /// CHANGER_RTN_MEDIA_TO_ORIGINAL_ADDR 0x80000020 - /// The changer requires media to be returned to its original slot after it has been moved. - /// - /// - /// CHANGER_SLOTS_USE_TRAYS 0x80000010 - /// - /// The changer uses removable trays in its slots, which require the media to be placed in a tray and the tray moved to the - /// desired position. - /// - /// - /// - /// CHANGER_TRUE_EXCHANGE_CAPABLE 0x80000008 - /// - /// The changer can exchange media between a source and a destination in a single operation. This flag is valid only if - /// CHANGER_EXCHANGE_MEDIA is also set in Features0. - /// - /// - /// - /// - public CHANGER_FEATURES1 Features1; - - /// - /// - /// Indicates whether the changer supports moving a piece of media from a transport element to another transport element, a - /// storage slot, an insert/eject port, or a drive. For a SCSI changer, this is defined in the device capabilities page. The - /// transport is not typically the source or destination for moving or exchanging media. - /// - /// To determine whether the changer can move media to a given element, use the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// CHANGER_TO_DRIVE 0x08 - /// The changer can carry out the operation from the specified element to a drive. - /// - /// - /// CHANGER_TO_IEPORT 0x04 - /// The changer can carry out the operation from the specified element to an insert/eject port. - /// - /// - /// CHANGER_TO_SLOT 0x02 - /// The changer can carry out the operation from the specified element to a storage slot. - /// - /// - /// CHANGER_TO_TRANSPORT 0x01 - /// The changer can carry out the operation from the specified element to a transport. - /// - /// - /// - public CHANGER_MOVE MoveFromTransport; - - /// - /// Indicates whether the changer supports moving medium from a storage slot to a transport element, another storage slot, an - /// insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether the changer - /// supports the move. - /// - public byte MoveFromSlot; - - /// - /// Indicates whether the changer supports moving medium from an insert/eject port to a transport element, a storage slot, - /// another insert/eject port, or a drive. For a SCSI changer, this is defined in the device capabilities page. Use the flags - /// described under MoveFromTransport to determine whether the changer supports the move. - /// - public byte MoveFromIePort; - - /// - /// Indicates whether the changer supports moving medium from a drive to a transport element, a storage slot, an insert/eject - /// port, or another drive. Use the flags described under MoveFromTransport to determine whether the changer supports the move. - /// - public byte MoveFromDrive; - - /// - /// Indicates whether the changer supports exchanging medium between a transport element and another transport element, a - /// storage slot, an insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether - /// the changer supports the exchange. - /// - public byte ExchangeFromTransport; - - /// - /// Indicates whether the changer supports exchanging medium between a storage slot and a transport element, another storage - /// slot, an insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether the - /// changer supports the exchange. - /// - public byte ExchangeFromSlot; - - /// - /// Indicates whether the changer supports exchanging medium between an insert/eject port and a transport element, a storage - /// slot, another insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether the - /// changer supports the exchange. - /// - public byte ExchangeFromIePort; - - /// - /// Indicates whether the changer supports exchanging medium between a drive and a transport element, a storage slot, an - /// insert/eject port, or another drive. Use the flags described under MoveFromTransport to determine whether the changer - /// supports the exchange. - /// - public byte ExchangeFromDrive; - - /// - /// - /// The elements of a changer that can be locked or unlocked programmatically. This member is valid only if CHANGER_LOCK_UNLOCK - /// is set in Features0. - /// - /// To determine whether the changer can lock or unlock a particular element, use one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// LOCK_UNLOCK_DOOR 0x02 - /// The changer can lock or unlock its door. - /// - /// - /// LOCK_UNLOCK_IEPORT 0x01 - /// The changer can lock or unlock its insert/eject port. - /// - /// - /// LOCK_UNLOCK_KEYPAD 0x04 - /// The changer can lock or unlock its keypad. - /// - /// - /// - public CHANGER_LOCK LockUnlockCapabilities; - - /// - /// The elements to which a changer can position its transport. Use the flags described under MoveFromTransport to - /// determine whether the changer supports positioning the transport to a particular element. This member is valid only if - /// CHANGER_POSITION_TO_ELEMENT is set in Features0. - /// - public byte PositionCapabilities; - - /// Reserved for future use. - public ushort Reserved1; - - /// Reserved for future use. - public ulong Reserved2; - } - - /// - /// Contains the attributes of a disk device. Returned as the output buffer from the IOCTL_DISK_GET_DISK_ATTRIBUTES control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_disk_attributes typedef struct _GET_DISK_ATTRIBUTES { - // DWORD Version; DWORD Reserved1; DWORDLONG Attributes; } GET_DISK_ATTRIBUTES, *PGET_DISK_ATTRIBUTES; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_DISK_ATTRIBUTES")] - [StructLayout(LayoutKind.Sequential)] - public struct GET_DISK_ATTRIBUTES - { - /// - /// Set to - /// sizeof(GET_DISK_ATTRIBUTES) - /// . - /// - public uint Version; - - /// Reserved. - public uint Reserved1; - - /// - /// Contains attributes. - /// - /// - /// Value - /// Meaning - /// - /// - /// DISK_ATTRIBUTE_OFFLINE 0x0000000000000001 - /// The disk is offline. - /// - /// - /// DISK_ATTRIBUTE_READ_ONLY 0x0000000000000002 - /// The disk is read-only. - /// - /// - /// - public DISK_ATTRIBUTE Attributes; - } - - /// Contains disk, volume, or partition length information used by the IOCTL_DISK_GET_LENGTH_INFO control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_length_information typedef struct - // _GET_LENGTH_INFORMATION { LARGE_INTEGER Length; } GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_LENGTH_INFORMATION")] - [StructLayout(LayoutKind.Sequential)] - public struct GET_LENGTH_INFORMATION - { - /// The length of the disk, volume, or partition, in bytes. - public long Length; - } - - /// Contains information about the media types supported by a device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_media_types typedef struct _GET_MEDIA_TYPES { DWORD - // DeviceType; DWORD MediaInfoCount; DEVICE_MEDIA_INFO MediaInfo[1]; } GET_MEDIA_TYPES, *PGET_MEDIA_TYPES; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_MEDIA_TYPES")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(MediaInfoCount))] - [StructLayout(LayoutKind.Sequential)] - public struct GET_MEDIA_TYPES - { - /// - /// - /// The type of device. Values from 0 through 32,767 are reserved for use by Microsoft Corporation. Values from 32,768 through - /// 65,535 are reserved for use by other vendors. The following values are defined by Microsoft: - /// - /// FILE_DEVICE_8042_PORT - /// FILE_DEVICE_ACPI - /// FILE_DEVICE_BATTERY - /// FILE_DEVICE_BEEP - /// FILE_DEVICE_BLUETOOTH - /// FILE_DEVICE_BUS_EXTENDER - /// FILE_DEVICE_CD_ROM - /// FILE_DEVICE_CD_ROM_FILE_SYSTEM - /// FILE_DEVICE_CHANGER - /// FILE_DEVICE_CONTROLLER - /// FILE_DEVICE_CRYPT_PROVIDER - /// FILE_DEVICE_DATALINK - /// FILE_DEVICE_DFS - /// FILE_DEVICE_DFS_FILE_SYSTEM - /// FILE_DEVICE_DFS_VOLUME - /// FILE_DEVICE_DISK - /// FILE_DEVICE_DISK_FILE_SYSTEM - /// FILE_DEVICE_DVD - /// FILE_DEVICE_FILE_SYSTEM - /// FILE_DEVICE_FIPS - /// FILE_DEVICE_FULLSCREEN_VIDEO - /// FILE_DEVICE_INFINIBAND - /// FILE_DEVICE_INPORT_PORT - /// FILE_DEVICE_KEYBOARD - /// FILE_DEVICE_KS - /// FILE_DEVICE_KSEC - /// FILE_DEVICE_MAILSLOT - /// FILE_DEVICE_MASS_STORAGE - /// FILE_DEVICE_MIDI_IN - /// FILE_DEVICE_MIDI_OUT - /// FILE_DEVICE_MODEM - /// FILE_DEVICE_MOUSE - /// FILE_DEVICE_MULTI_UNC_PROVIDER - /// FILE_DEVICE_NAMED_PIPE - /// FILE_DEVICE_NETWORK - /// FILE_DEVICE_NETWORK_BROWSER - /// FILE_DEVICE_NETWORK_FILE_SYSTEM - /// FILE_DEVICE_NETWORK_REDIRECTOR - /// FILE_DEVICE_NULL - /// FILE_DEVICE_PARALLEL_PORT - /// FILE_DEVICE_PHYSICAL_NETCARD - /// FILE_DEVICE_PRINTER - /// FILE_DEVICE_SCANNER - /// FILE_DEVICE_SCREEN - /// FILE_DEVICE_SERENUM - /// FILE_DEVICE_SERIAL_MOUSE_PORT - /// FILE_DEVICE_SERIAL_PORT - /// FILE_DEVICE_SMARTCARD - /// FILE_DEVICE_SMB - /// FILE_DEVICE_SOUND - /// FILE_DEVICE_STREAMS - /// FILE_DEVICE_TAPE - /// FILE_DEVICE_TAPE_FILE_SYSTEM - /// FILE_DEVICE_TERMSRV - /// FILE_DEVICE_TRANSPORT - /// FILE_DEVICE_UNKNOWN - /// FILE_DEVICE_VDM - /// FILE_DEVICE_VIDEO - /// FILE_DEVICE_VIRTUAL_DISK - /// FILE_DEVICE_VMBUS - /// FILE_DEVICE_WAVE_IN - /// FILE_DEVICE_WAVE_OUT - /// FILE_DEVICE_WPD - /// - public DEVICE_TYPE DeviceType; - - private ushort Reserved; - - /// The number of elements in the MediaInfo array. - public uint MediaInfoCount; - - /// - /// A pointer to the first DEVICE_MEDIA_INFO structure in the array. There is one structure for each media type supported by the device. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public DEVICE_MEDIA_INFO[] MediaInfo; - } - - /// - /// Returned from the FSCTL_LOOKUP_STREAM_FROM_CLUSTER control code. Zero or more of these structures follow the - /// LOOKUP_STREAM_FROM_CLUSTER_OUTPUT structure in the output buffer returned. - /// - /// - /// The name in the FileName member can be very long and in a format not recognized by a customer with the stream name and - /// attribute type name following the filename. While it's appropriate to log the entire filename for diagnostic purposes, if it is - /// to be presented to an end-user it should be reformatted to be more understandable (for example, remove the attribute type name - /// and if the Flags member has any flag other than LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_DATA set then an - /// appropriate message should be displayed. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-lookup_stream_from_cluster_entry typedef struct - // _LOOKUP_STREAM_FROM_CLUSTER_ENTRY { DWORD OffsetToNext; DWORD Flags; LARGE_INTEGER Reserved; LARGE_INTEGER Cluster; WCHAR - // FileName[1]; } LOOKUP_STREAM_FROM_CLUSTER_ENTRY, *PLOOKUP_STREAM_FROM_CLUSTER_ENTRY; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._LOOKUP_STREAM_FROM_CLUSTER_ENTRY")] - [VanaraMarshaler(typeof(AnySizeStringMarshaler), "*")] - [StructLayout(LayoutKind.Sequential)] - public struct LOOKUP_STREAM_FROM_CLUSTER_ENTRY - { - /// - /// Offset in bytes from the beginning of this structure to the next LOOKUP_STREAM_FROM_CLUSTER_ENTRY structure returned. - /// If there are no more entries, this value is zero. - /// - public uint OffsetToNext; - - /// - /// - /// Flags describing characteristics about this stream. The value will consist of one or more of these values. At least one of - /// the LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_* values that fall within the - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_MASK (0xff000000) will be set; one or more of the other flag values may be set. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_PAGE_FILE 0x00000001 - /// The stream is part of the system pagefile. - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_DENY_DEFRAG_SET 0x00000002 - /// - /// The stream is locked from defragmentation. The HandleInfo member of the MARK_HANDLE_INFO structure for this stream has the - /// MARK_HANDLE_PROTECT_CLUSTERS flag set. - /// - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_FS_SYSTEM_FILE 0x00000004 - /// The stream is part of a file that is internal to the filesystem. - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_TXF_SYSTEM_FILE 0x00000008 - /// The stream is part of a file that is internal to TxF. - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_DATA 0x01000000 - /// The stream is part of a $DATA attribute for the file (data stream). - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_INDEX 0x02000000 - /// The stream is part of the $INDEX_ALLOCATION attribute for the file. - /// - /// - /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_SYSTEM 0x03000000 - /// The stream is part of another attribute for the file. - /// - /// - /// - public LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG Flags; - - /// This value is reserved and is currently zero. - public long Reserved; - - /// This is the cluster that this entry refers to. It will be one of the clusters passed in the input structure. - public long Cluster; - - /// - /// A NULL-terminated Unicode string containing the path of the object relative to the root of the volume. This string - /// will refer to the attribute or stream represented by the cluster. This string is not limited by MAX_PATH and may be - /// up to 32,768 characters (65,536 bytes) in length. Not all of the filenames returned can be opened; some are internal to NTFS - /// and always opened exclusively. The string returned includes the full path including filename, stream name, and attribute - /// type name in the form "full\path\to\file\filename.ext:streamname:typename". - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] - public string FileName; - } - - /// Passed as input to the FSCTL_LOOKUP_STREAM_FROM_CLUSTER control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-lookup_stream_from_cluster_input typedef struct - // _LOOKUP_STREAM_FROM_CLUSTER_INPUT { DWORD Flags; DWORD NumberOfClusters; LARGE_INTEGER Cluster[1]; } - // LOOKUP_STREAM_FROM_CLUSTER_INPUT, *PLOOKUP_STREAM_FROM_CLUSTER_INPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._LOOKUP_STREAM_FROM_CLUSTER_INPUT")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfClusters))] - [StructLayout(LayoutKind.Sequential)] - public struct LOOKUP_STREAM_FROM_CLUSTER_INPUT - { - /// Flags for the operation. Currently no flags are defined. - public uint Flags; - - /// - /// Number of clusters in the following array of clusters. The input buffer must be large enough to contain this number or the - /// operation will fail. - /// - public uint NumberOfClusters; - - /// An array of one or more clusters to look up. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public long[] Cluster; - } - - /// Received as output from the FSCTL_LOOKUP_STREAM_FROM_CLUSTER control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-lookup_stream_from_cluster_output typedef struct - // _LOOKUP_STREAM_FROM_CLUSTER_OUTPUT { DWORD Offset; DWORD NumberOfMatches; DWORD BufferSizeRequired; } - // LOOKUP_STREAM_FROM_CLUSTER_OUTPUT, *PLOOKUP_STREAM_FROM_CLUSTER_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._LOOKUP_STREAM_FROM_CLUSTER_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct LOOKUP_STREAM_FROM_CLUSTER_OUTPUT - { - /// - /// Offset from the beginning of this structure to the first entry returned. If no entries are returned, this value is zero. - /// - public uint Offset; - - /// - /// Number of matches to the input criteria. Note that more matches may be found than entries returned if the buffer provided is - /// not large enough. - /// - public uint NumberOfMatches; - - /// Minimum size of the buffer, in bytes, which would be needed to contain all matching entries to the input criteria. - public uint BufferSizeRequired; - } - - /// - /// Contains information that is used to mark a specified file or directory, and its update sequence number (USN) change journal - /// record with data about changes. It is used by the FSCTL_MARK_HANDLE control code. - /// - /// - /// To retrieve a handle to a volume, call CreateFile with the lpFileName parameter set to a string in the following form: - /// "\.\X:" - /// In the preceding string, X is the letter identifying the drive on which the volume appears. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-mark_handle_info typedef struct { union { DWORD - // UsnSourceInfo; DWORD CopyNumber; } DUMMYUNIONNAME; DWORD UsnSourceInfo; HANDLE VolumeHandle; DWORD HandleInfo; } - // MARK_HANDLE_INFO, *PMARK_HANDLE_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "ns-winioctl-mark_handle_info")] - [StructLayout(LayoutKind.Sequential)] - public struct MARK_HANDLE_INFO - { - /// - /// The type of changes being made. - /// - /// The operation does not modify the file or directory externally from the point of view of the application that created it. - /// - /// - /// When a thread writes a new USN record, the source information flags in the prior record continues to be present only if the - /// thread also sets those flags. Therefore, the source information structure allows applications to filter out USN records that - /// are set only by a known source, such as an antivirus filter. - /// - /// The following values are defined. - /// - /// - /// Value - /// Meaning - /// - /// - /// USN_SOURCE_DATA_MANAGEMENT 0x00000001 - /// - /// The operation provides information about a change to the file or directory made by the operating system. A typical use is - /// when Remote Storage moves data from external to local storage. Remote Storage is the hierarchical storage management - /// software. Such a move usually at a minimum adds the USN_REASON_DATA_OVERWRITE flag to a USN record. However, the data has - /// not changed from the user point of view. By noting USN_SOURCE_DATA_MANAGEMENT in the SourceInfo member of the USN_RECORD - /// structure that holds the record, you can determine that although a write operation is performed on the item, data has not changed. - /// - /// - /// - /// USN_SOURCE_AUXILIARY_DATA 0x00000002 - /// - /// The operation adds a private data stream to a file or directory. An example might be a virus detector adding checksum - /// information. As the virus detector modifies the item, the system generates USN records. USN_SOURCE_AUXILIARY_DATA indicates - /// that the modifications did not change the application data. - /// - /// - /// - /// USN_SOURCE_REPLICATION_MANAGEMENT 0x00000004 - /// - /// The operation creates or updates the contents of a replicated file. For example, the file replication service sets this flag - /// when it creates or updates a file in a replicated directory. - /// - /// - /// - /// - /// USN_SOURCE_CLIENT_REPLICATION_MANAGEMENT 0x00000008 - /// Replication is being performed on client systems either from the cloud or servers. - /// - /// - /// - public USN_SOURCE UsnSourceInfo { get => (USN_SOURCE)CopyNumber; set => CopyNumber = (uint)value; } - - - /// - public uint CopyNumber; - - /// - /// - /// The volume handle to the volume where the file or directory resides. For more information on obtaining a volume handle, see - /// the Remarks section. - /// - /// This handle is required to check the privileges for this operation. - /// The caller must have the SE_MANAGE_VOLUME_NAME privilege. For more information, see Privileges. - /// - public HFILE VolumeHandle; - - /// - /// - /// The flag that specifies additional information about the file or directory identified by the handle value in the - /// VolumeHandle member. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// MARK_HANDLE_PROTECT_CLUSTERS 0x00000001 - /// - /// The file is marked as unable to be defragmented until the handle is closed. Once a handle marked - /// MARK_HANDLE_PROTECT_CLUSTERS is closed, there is no guarantee that the file's clusters won't move. - /// - /// - /// - /// MARK_HANDLE_TXF_SYSTEM_LOG 0x00000004 - /// - /// The file is marked as unable to be defragmented until the handle is closed. Windows Server 2003: This flag is not supported - /// until Windows Server 2003 with SP1. Windows XP: This flag is not supported. - /// - /// - /// - /// MARK_HANDLE_NOT_TXF_SYSTEM_LOG 0x00000008 - /// - /// The file is marked as unable to be defragmented until the handle is closed. Windows Server 2003: This flag is not supported - /// until Windows Server 2003 with SP1. Windows XP: This flag is not supported. - /// - /// - /// - /// MARK_HANDLE_REALTIME 0x00000020 - /// - /// The file is marked for real-time read behavior regardless of the actual file type. Files marked with this flag must be - /// opened for unbuffered I/O. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported. - /// - /// - /// - /// MARK_HANDLE_NOT_REALTIME 0x00000040 - /// - /// The file previously marked for real-time read behavior using the MARK_HANDLE_REALTIME flag can be unmarked using this flag, - /// removing the real-time behavior. Files marked with this flag must be opened for unbuffered I/O. Windows Server 2008, Windows - /// Vista, Windows Server 2003 and Windows XP: This flag is not supported. - /// - /// - /// - /// MARK_HANDLE_READ_COPY 0x00000080 - /// - /// Indicates the copy number specified in the CopyNumber member should be used for reads. Files marked with this flag must be - /// opened for unbuffered I/O. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and - /// Windows XP: This flag is not supported until Windows 8 and Windows Server 2012. - /// - /// - /// - /// MARK_HANDLE_NOT_READ_COPY 0x00000100 - /// - /// The file previously marked for read-copy behavior using the MARK_HANDLE_READ_COPY flag can be unmarked using this flag, - /// removing the read-copy behavior. Files marked with this flag must be opened for unbuffered I/O. Windows Server 2008 R2, - /// Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported until Windows - /// 8 and Windows Server 2012. - /// - /// - /// - /// - /// - /// - /// MARK_HANDLE_DISABLE_FILE_METADATA_OPTIMIZATION 0x00001000 - /// - /// A highly fragmented file in NTFS uses multiple MFT records to describe all of the extents for a file. This list of child MFT - /// records (also known as FRS records) are controlled by a structure known as an attribute list. An attribute list is limited - /// to 128K in size. When the size of an attribute list hits a certain threshold NTFS will trigger a background compaction on - /// the extents so the minimum number of child FRS records will be used. This flag disables this FRS compaction feature for the - /// given file. This flag is not supported until Windows 10. - /// - /// - /// - /// - /// - /// - /// MARK_HANDLE_SKIP_COHERENCY_SYNC_DISALLOW_WRITES 0x00004000 - /// - /// Setting this flag tells the system that writes are not allowed on this file. If an application tries to open the file for - /// write access, the operation is failed with STATUS_ACCESS_DENIED. If a write is seen the operation is failed with - /// STATUS_MARKED_TO_DISALLOW_WRITES This flag is not supported until Windows 10. - /// - /// - /// - /// - public MARK_HANDLE_INFO_FLAG HandleInfo; - } - - /// Contains input data for the FSCTL_MOVE_FILE control code. - /// - /// - /// To retrieve data to fill in this structure, use the DeviceIoControl function with the FSCTL_GET_RETRIEVAL_POINTERS control code. - /// - /// The first cluster of a directory on a FAT file system volume cannot be moved. - /// - /// When possible, move data in blocks aligned relative to each other in 16-kilobyte (KB) increments. This reduces copy-on-write - /// overhead when shadow copies are enabled, because shadow copy space is increased and performance is reduced when the following - /// conditions occur: - /// - /// + /// The element status. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// /// - /// The move request block size is less than or equal to 16 KB. + /// ELEMENT_STATUS_ACCESS 0x00000008 + /// + /// The changer's transport element can access the piece of media in this element. The media is not accessible in the following + /// circumstances: (1) If the element type is ChangerSlot, the slot is not present in the changer (for example, the magazine + /// containing the slot has been physically removed). (2) If the element type is ChangerDrive, the drive is broken or has been + /// removed. (3) If the element type is ChangerIEPort, the changer's insert/eject port is extended. + /// /// /// - /// The move delta is not in increments of 16 KB. + /// ELEMENT_STATUS_AVOLTAG 0x20000000 + /// Alternate volume information in the AlternateVolumeID member is valid. + /// + /// + /// ELEMENT_STATUS_EXCEPT 0x00000004 + /// The element is in an abnormal state. Check the ExceptionCode member for more information. + /// + /// + /// ELEMENT_STATUS_EXENAB 0x00000010 + /// The element supports export of media through the changer's insert/eject port. + /// + /// + /// ELEMENT_STATUS_FULL 0x00000001 + /// + /// The element contains a piece of media. Note that this value is valid only if the element type is ChangerDrive, ChangerSlot, + /// or ChangerTransport. If ElementType is ChangerIEPort, this value is valid only if the Features0 member of + /// GET_CHANGER_PARAMETERS includes CHANGER_REPORT_IEPORT_STATE. + /// + /// + /// + /// ELEMENT_STATUS_ID_VALID 0x00002000 + /// The SCSI target ID in the TargetID member is valid. This value is valid only if the element type is ChangerDrive. + /// + /// + /// ELEMENT_STATUS_IMPEXP 0x00000002 + /// The media in this element was placed there by an operator. This value is valid only if the element type is ChangerIEPort. + /// + /// + /// ELEMENT_STATUS_INENAB 0x00000020 + /// The element supports import of media through the changer's insert/eject port. + /// + /// + /// ELEMENT_STATUS_INVERT 0x00400000 + /// The media in the element was flipped. This value is valid only if ELEMENT_STATUS_SVALID is also included. + /// + /// + /// ELEMENT_STATUS_LUN_VALID 0x00001000 + /// The logical unit number in the Lun member is valid. This value is valid only if the element type is ChangerDrive. + /// + /// + /// ELEMENT_STATUS_NOT_BUS 0x00008000 + /// The drive at the address indicated by Lun and TargetID is on a different SCSI bus than the changer itself. + /// + /// + /// ELEMENT_STATUS_PVOLTAG 0x10000000 + /// Primary volume information in the PrimaryVolumeID member is valid. + /// + /// + /// ELEMENT_STATUS_SVALID 0x00800000 + /// The SourceElement member and ELEMENT_STATUS_INVERT are both valid. /// /// + /// + public ELEMENT_STATUS Flags; + + /// /// - /// The move delta is the number of bytes between the start of the source block and the start of the target block. In other words, a - /// block starting at offset X (on-disk) can be moved to a starting offset Y if the absolute value of X minus Y is an even multiple - /// of 16 KB. So, assuming 4-KB clusters, a move from cluster 3 to cluster 27 will be optimized, but a move from cluster 18 to - /// cluster 24 will not. Note that mod(3,4) = 3 = mod(27,4). Mod 4 is chosen because four clusters at 4 KB each is equivalent to 16 - /// KB. Therefore, a volume formatted to a 16-KB cluster size will result in all move files being optimized. + /// An exception code that indicates that the element is in an abnormal state. This member is valid only if the Flags + /// member includes ELEMENT_STATUS_EXCEPT. This member can be one of the following values. /// - /// For more information about shadow copies, see Volume Shadow Copy Service. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-move_file_data typedef struct { HANDLE FileHandle; - // LARGE_INTEGER StartingVcn; LARGE_INTEGER StartingLcn; DWORD ClusterCount; } MOVE_FILE_DATA, *PMOVE_FILE_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_10")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct MOVE_FILE_DATA + /// + /// + /// Value + /// Meaning + /// + /// + /// ERROR_DRIVE_NOT_INSTALLED 0x00000008 + /// The drive at this element address is absent. + /// + /// + /// ERROR_LABEL_QUESTIONABLE 0x00000002 + /// The label might be invalid due to a unit attention condition. + /// + /// + /// ERROR_LABEL_UNREADABLE 0x00000001 + /// + /// The changer's barcode reader could not read the bar code label on the piece of media in this element, because the media is + /// missing, damaged, improperly positioned, or upside down. + /// + /// + /// + /// ERROR_SLOT_NOT_PRESENT 0x00000004 + /// + /// The slot at this element address is currently not installed in the changer. Each slot in a removable magazine is reported + /// not present to indicate that the magazine has been removed. + /// + /// + /// + /// ERROR_TRAY_MALFUNCTION 0x00000010 + /// + /// The drive at this element address has a tray that must be extended to load or remove media, and the tray is not extending as required. + /// + /// + /// + /// ERROR_UNHANDLED_ERROR 0xFFFFFFFF + /// Unknown error condition. + /// + /// + /// + public ELEMENT_ERROR ExceptionCode; + + /// + /// For a SCSI changer, specifies the SCSI target ID of the drive at this element address. This member is valid only if the + /// ElementType member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_ID_VALID. + /// + public byte TargetId; + + /// + /// The SCSI logical unit number of the drive at this element address. This member is valid only if the ElementType + /// member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_LUN_VALID. + /// + public byte Lun; + + /// Reserved for future use. The value of this member must be zero. + public ushort Reserved; + + /// + /// + /// The primary volume identifier for the media. If the changer supports a barcode reader and the reader is installed (as + /// indicated by CHANGER_BAR_CODE_SCANNER_INSTALLED in the Features0 member of GET_CHANGER_PARAMETERS), + /// PrimaryVolumeID is the bar code of the media. If the changer does not support a barcode reader, + /// PrimaryVolumeID is the value previously assigned to the media. + /// + /// This member is valid only if the Flags member includes ELEMENT_STATUS_PVOLTAG. + /// If the volume identifier is missing or unreadable, this member is cleared. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] + public string PrimaryVolumeID; + + /// + /// + /// An alternate volume identification for the media. This member is valid only for two-sided media, and pertains to the ID of + /// the inverted side. It never represents a bar code. + /// + /// This member is valid only if the Flags member includes ELEMENT_STATUS_AVOLTAG. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] + public string AlternateVolumeID; + } + + /// Represents the status of the specified element. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_element_status_ex typedef struct + // _CHANGER_ELEMENT_STATUS_EX { CHANGER_ELEMENT Element; CHANGER_ELEMENT SrcElementAddress; DWORD Flags; DWORD ExceptionCode; BYTE + // TargetId; BYTE Lun; WORD Reserved; BYTE PrimaryVolumeID[MAX_VOLUME_ID_SIZE]; BYTE AlternateVolumeID[MAX_VOLUME_ID_SIZE]; BYTE + // VendorIdentification[VENDOR_ID_LENGTH]; BYTE ProductIdentification[PRODUCT_ID_LENGTH]; BYTE SerialNumber[SERIAL_NUMBER_LENGTH]; } + // CHANGER_ELEMENT_STATUS_EX, *PCHANGER_ELEMENT_STATUS_EX; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_ELEMENT_STATUS_EX")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct CHANGER_ELEMENT_STATUS_EX + { + /// A CHANGER_ELEMENT structure that represents the element to which this structure refers. + public CHANGER_ELEMENT Element; + + /// + /// + /// A CHANGER_ELEMENT structure that represents the element from which the media currently in this element was most recently moved. + /// + /// This member is valid only if the Flags member includes ELEMENT_STATUS_SVALID. + /// + public CHANGER_ELEMENT SrcElementAddress; + + /// + /// The element status. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// ELEMENT_STATUS_ACCESS 0x00000008 + /// + /// The changer's transport element can access the piece of media in this element. The media is not accessible in the following + /// circumstances: (1) If the element type is ChangerSlot, the slot is not present in the changer (for example, the magazine + /// containing the slot has been physically removed). (2) If the element type is ChangerDrive, the drive is broken or has been + /// removed. (3) If the element type is ChangerIEPort, the changer's insert/eject port is extended. + /// + /// + /// + /// ELEMENT_STATUS_AVOLTAG 0x20000000 + /// Alternate volume information in the AlternateVolumeID member is valid. + /// + /// + /// ELEMENT_STATUS_EXCEPT 0x00000004 + /// The element is in an abnormal state. Check the ExceptionCode member for more information. + /// + /// + /// ELEMENT_STATUS_EXENAB 0x00000010 + /// The element supports export of media through the changer's insert/eject port. + /// + /// + /// ELEMENT_STATUS_FULL 0x00000001 + /// + /// The element contains a piece of media. Note that this value is valid only if the element type is ChangerDrive, ChangerSlot, + /// or ChangerTransport. If the element type is ChangerIEPort, this value is valid only if the Features0 member of + /// GET_CHANGER_PARAMETERS includes CHANGER_REPORT_IEPORT_STATE. + /// + /// + /// + /// ELEMENT_STATUS_ID_VALID 0x00002000 + /// The SCSI target ID in the TargetID member is valid. This value is valid only if the element type is ChangerDrive. + /// + /// + /// ELEMENT_STATUS_IMPEXP 0x00000002 + /// The media in this element was placed there by an operator. This value is valid only if the element type is ChangerIEPort. + /// + /// + /// ELEMENT_STATUS_INENAB 0x00000020 + /// The element supports import of media through the changer's insert/eject port. + /// + /// + /// ELEMENT_STATUS_INVERT 0x00400000 + /// The media in the element was flipped. This value is valid only if ELEMENT_STATUS_SVALID is also included. + /// + /// + /// ELEMENT_STATUS_LUN_VALID 0x00001000 + /// The logical unit number in the Lun member is valid. This value is valid only if the element type is ChangerDrive. + /// + /// + /// ELEMENT_STATUS_NOT_BUS 0x00008000 + /// The drive at the address indicated by Lun and TargetID is on a different SCSI bus than the changer itself. + /// + /// + /// ELEMENT_STATUS_PRODUCT_DATA 0x00000040 + /// The serial number in the SerialNumber member is valid. + /// + /// + /// ELEMENT_STATUS_PVOLTAG 0x10000000 + /// Primary volume information in the PrimaryVolumeID member is valid. + /// + /// + /// ELEMENT_STATUS_SVALID 0x00800000 + /// The SourceElement member and ELEMENT_STATUS_INVERT are both valid. + /// + /// + /// + public ELEMENT_STATUS Flags; + + /// + /// + /// An exception code that indicates that the element is in an abnormal state. This member is valid only if the Flags + /// member includes ELEMENT_STATUS_EXCEPT. This member can be one of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// ERROR_DRIVE_NOT_INSTALLED 0x00000008 + /// The drive at this element address is absent. + /// + /// + /// ERROR_INIT_STATUS_NEEDED 0x00000011 + /// An Initialize Element Status command is needed. + /// + /// + /// ERROR_LABEL_QUESTIONABLE 0x00000002 + /// The label might be invalid due to a unit attention condition. + /// + /// + /// ERROR_LABEL_UNREADABLE 0x00000001 + /// + /// The changer's barcode reader could not read the bar code label on the piece of media in this element, because the media is + /// missing, damaged, improperly positioned, or upside down. + /// + /// + /// + /// ERROR_SLOT_NOT_PRESENT 0x00000004 + /// + /// The slot at this element address is currently not installed in the changer. Each slot in a removable magazine is reported + /// not present to indicate that the magazine has been removed. + /// + /// + /// + /// ERROR_TRAY_MALFUNCTION 0x00000010 + /// + /// The drive at this element address has a tray that must be extended to load or remove media, and the tray is not extending as required. + /// + /// + /// + /// ERROR_UNHANDLED_ERROR 0xFFFFFFFF + /// Unknown error condition. + /// + /// + /// + public ELEMENT_ERROR ExceptionCode; + + /// + /// For a SCSI changer, specifies the SCSI target ID of the drive at this element address. This member is valid only if the + /// ElementType member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_ID_VALID. + /// + public byte TargetId; + + /// + /// The SCSI logical unit number of the drive at this element address. This member is valid only if the ElementType + /// member of the Element structure is ChangerDrive and the Flags member includes ELEMENT_STATUS_LUN_VALID. + /// + public byte Lun; + + /// Reserved for future use. The value of this member must be zero. + public ushort Reserved; + + /// + /// + /// The primary volume identifier for the media. If the changer supports a barcode reader and the reader is installed (as + /// indicated by CHANGER_BAR_CODE_SCANNER_INSTALLED in the Features0 member of GET_CHANGER_PARAMETERS), + /// PrimaryVolumeID is the bar code of the media. If the changer does not support a barcode reader, + /// PrimaryVolumeID is the value previously assigned to the media. + /// + /// This member is valid only if the Flags member includes ELEMENT_STATUS_PVOLTAG. + /// If the volume identifier is missing or unreadable, this member is cleared. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] + public string PrimaryVolumeID; + + /// + /// + /// An alternate volume identification for the media. This member is valid for two-sided media only, and pertains to the ID of + /// the inverted side. It never represents a bar code. + /// + /// This member is valid only if the Flags member includes ELEMENT_STATUS_AVOLTAG. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_ID_SIZE)] + public string AlternateVolumeID; + + /// The vendor identifier. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = VENDOR_ID_LENGTH)] + public string VendorIdentification; + + /// The product identifier. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PRODUCT_ID_LENGTH)] + public string ProductIdentification; + + /// The serial number for the drive. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SERIAL_NUMBER_LENGTH)] + public string SerialNumber; + } + + /// + /// Contains information the IOCTL_CHANGER_EXCHANGE_MEDIUM control code uses to move a piece of media to a destination, and the + /// piece of media originally in the first destination to a second destination. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_exchange_medium typedef struct + // _CHANGER_EXCHANGE_MEDIUM { CHANGER_ELEMENT Transport; CHANGER_ELEMENT Source; CHANGER_ELEMENT Destination1; CHANGER_ELEMENT + // Destination2; BOOLEAN Flip1; BOOLEAN Flip2; } CHANGER_EXCHANGE_MEDIUM, *PCHANGER_EXCHANGE_MEDIUM; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_EXCHANGE_MEDIUM")] + [StructLayout(LayoutKind.Sequential)] + public struct CHANGER_EXCHANGE_MEDIUM + { + /// + /// A CHANGER_ELEMENT structure that indicates which transport element to use for the exchange operation. The ElementType + /// member of this structure must be ChangerTransport. + /// + public CHANGER_ELEMENT Transport; + + /// A CHANGER_ELEMENT structure that indicates the element that contains the media that is to be moved. + public CHANGER_ELEMENT Source; + + /// A CHANGER_ELEMENT structure that indicates the element that is the destination of the media originally at Source. + public CHANGER_ELEMENT Destination1; + + /// A CHANGER_ELEMENT structure that indicates the element that is the destination of the media originally at Destination1. + public CHANGER_ELEMENT Destination2; + + /// + /// If this member is TRUE, the medium at Destination1 should be flipped. Otherwise, it should not. This member is + /// valid only if the Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. + /// + [MarshalAs(UnmanagedType.U1)] + public bool Flip1; + + /// + /// If this member is TRUE, the medium at Destination2 should be flipped. Otherwise, it should not. This member is + /// valid only if the Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. + /// + [MarshalAs(UnmanagedType.U1)] + public bool Flip2; + } + + /// Represents the status of all media changer elements or the specified elements of a particular type. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_initialize_element_status typedef struct + // _CHANGER_INITIALIZE_ELEMENT_STATUS { CHANGER_ELEMENT_LIST ElementList; BOOLEAN BarCodeScan; } CHANGER_INITIALIZE_ELEMENT_STATUS, *PCHANGER_INITIALIZE_ELEMENT_STATUS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_INITIALIZE_ELEMENT_STATUS")] + [StructLayout(LayoutKind.Sequential)] + public struct CHANGER_INITIALIZE_ELEMENT_STATUS + { + /// + /// A CHANGER_ELEMENT_LIST structure that lists the elements and range on which to initialize. + /// + /// If CHANGER_INIT_ELEM_STAT_WITH_RANGE is set in the Features0 member of GET_CHANGER_PARAMETERS, the changer supports + /// initializing a range of elements. In this case, the ElementType member can be one of the following: ChangerTransport, + /// ChangerSlot, ChangerDrive, or ChangerIEPort. Otherwise, the element type must be AllElements and the NumberOfElements + /// member is ignored. + /// + /// + public CHANGER_ELEMENT_LIST ElementList; + + /// + /// + /// If this member is TRUE, a bar-code scan should be used. Otherwise, it should not. If the changer has nonvolatile RAM, + /// using a bar-code scan is an optimization. + /// + /// This member is applicable only if CHANGER_BAR_CODE_SCANNER_INSTALLED is set in the Features0 member of GET_CHANGER_PARAMETERS. + /// + [MarshalAs(UnmanagedType.U1)] + public bool BarCodeScan; + } + + /// Contains information that the IOCTL_CHANGER_MOVE_MEDIUM control code uses to move a piece of media to a destination. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_move_medium typedef struct _CHANGER_MOVE_MEDIUM { + // CHANGER_ELEMENT Transport; CHANGER_ELEMENT Source; CHANGER_ELEMENT Destination; BOOLEAN Flip; } CHANGER_MOVE_MEDIUM, *PCHANGER_MOVE_MEDIUM; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_MOVE_MEDIUM")] + [StructLayout(LayoutKind.Sequential)] + public struct CHANGER_MOVE_MEDIUM + { + /// A CHANGER_ELEMENT structure that indicates which transport element to use for the move operation. + public CHANGER_ELEMENT Transport; + + /// A CHANGER_ELEMENT structure that indicates the element that contains the media that is to be moved. + public CHANGER_ELEMENT Source; + + /// A CHANGER_ELEMENT structure that indicates the element that is the destination of the media originally at Source. + public CHANGER_ELEMENT Destination; + + /// + /// If this member is TRUE, the media should be flipped. Otherwise, it should not. This member is valid only if the + /// Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. + /// + [MarshalAs(UnmanagedType.U1)] + public bool Flip; + } + + /// Represents product data for a changer device. It is used by the IOCTL_CHANGER_GET_PRODUCT_DATA control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_product_data typedef struct _CHANGER_PRODUCT_DATA + // { BYTE VendorId[VENDOR_ID_LENGTH]; BYTE ProductId[PRODUCT_ID_LENGTH]; BYTE Revision[REVISION_LENGTH]; BYTE + // SerialNumber[SERIAL_NUMBER_LENGTH]; BYTE DeviceType; } CHANGER_PRODUCT_DATA, *PCHANGER_PRODUCT_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_PRODUCT_DATA")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct CHANGER_PRODUCT_DATA + { + /// The device manufacturer's name. This is acquired directly from the device inquiry data. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = VENDOR_ID_LENGTH)] + public string VendorId; + + /// The product identification, as defined by the vendor. This is acquired directly from the device inquiry data. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PRODUCT_ID_LENGTH)] + public string ProductId; + + /// The product revision, as defined by the vendor. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = REVISION_LENGTH)] + public string Revision; + + /// A unique value used to globally identify this device, as defined by the vendor. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SERIAL_NUMBER_LENGTH)] + public string SerialNumber; + + /// The device type of data transports, as defined by SCSI-2. This member must be FILE_DEVICE_CHANGER. + public byte DeviceType; + } + + /// + /// Contains information that the IOCTL_CHANGER_GET_ELEMENT_STATUS control code needs to determine the elements whose status is to + /// be retrieved. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_read_element_status typedef struct + // _CHANGER_READ_ELEMENT_STATUS { CHANGER_ELEMENT_LIST ElementList; BOOLEAN VolumeTagInfo; } CHANGER_READ_ELEMENT_STATUS, *PCHANGER_READ_ELEMENT_STATUS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_READ_ELEMENT_STATUS")] + [StructLayout(LayoutKind.Sequential)] + public struct CHANGER_READ_ELEMENT_STATUS + { + /// + /// A CHANGER_ELEMENT_LIST structure that contains an array of structures that represents the range of elements for which + /// information is to be retrieved. The ElementType member of each structure can be one of the following values: + /// ChangerDrive, ChangerSlot, ChangerTransport, ChangerIEPort, or AllElements. + /// + public CHANGER_ELEMENT_LIST ElementList; + + /// + /// If this member is TRUE, volume tag information is to be retrieved. Otherwise, no volume information is retrieved. A + /// volume tag can be a bar code or an application-defined value. This member is valid only if the Features0 member of + /// the GET_CHANGER_PARAMETERS structure is CHANGER_BAR_CODE_SCANNER_INSTALLED or CHANGER_VOLUME_IDENTIFICATION. + /// + [MarshalAs(UnmanagedType.U1)] + public bool VolumeTagInfo; + } + + /// + /// Contains information that the IOCTL_CHANGER_QUERY_VOLUME_TAGS control code uses to determine the volume information to be retrieved. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_send_volume_tag_information typedef struct + // _CHANGER_SEND_VOLUME_TAG_INFORMATION { CHANGER_ELEMENT StartingElement; DWORD ActionCode; BYTE + // VolumeIDTemplate[MAX_VOLUME_TEMPLATE_SIZE]; } CHANGER_SEND_VOLUME_TAG_INFORMATION, *PCHANGER_SEND_VOLUME_TAG_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_SEND_VOLUME_TAG_INFORMATION")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct CHANGER_SEND_VOLUME_TAG_INFORMATION + { + /// A CHANGER_ELEMENT structure that represents the starting element for which information is to be retrieved. + public CHANGER_ELEMENT StartingElement; + + /// + /// The action to be performed. + /// + /// + /// Value + /// Meaning + /// + /// + /// ASSERT_ALTERNATE 0x9 + /// Define the alternate volume tag of a volume that currently has none defined. Requires that Features0 is CHANGER_VOLUME_ASSERT. + /// + /// + /// ASSERT_PRIMARY 0x8 + /// Define the primary volume tag of a volume that currently has none defined. Requires that Features0 is CHANGER_VOLUME_ASSERT. + /// + /// + /// REPLACE_ALTERNATE 0xB + /// Replace the alternate volume tag with a new tag. Requires that Features0 is CHANGER_VOLUME_REPLACE. + /// + /// + /// REPLACE_PRIMARY 0xA + /// Replace the primary volume tag with a new tag. Requires that Features0 is CHANGER_VOLUME_REPLACE. + /// + /// + /// SEARCH_ALL 0x0 + /// Search all defined volume tags. Requires that Features0 is CHANGER_VOLUME_SEARCH. + /// + /// + /// SEARCH_ALL_NO_SEQ 0x4 + /// Search all defined volume tags, but ignore sequence numbers. Requires that Features0 is CHANGER_VOLUME_SEARCH. + /// + /// + /// SEARCH_ALT_NO_SEQ 0x6 + /// Search only alternate volume tags, but ignore sequence numbers. Requires that Features0 is CHANGER_VOLUME_SEARCH. + /// + /// + /// SEARCH_ALTERNATE 02 + /// Search only alternate volume tags. Requires that Features0 is CHANGER_VOLUME_SEARCH. + /// + /// + /// SEARCH_PRI_NO_SEQ 05 + /// Search only primary volume tags but ignore sequence numbers. Requires that Features0 is CHANGER_VOLUME_SEARCH. + /// + /// + /// SEARCH_PRIMARY 0x1 + /// Search only primary volume tags. Requires that Features0 is CHANGER_VOLUME_SEARCH. + /// + /// + /// UNDEFINE_ALTERNATE 0xD + /// Clear the alternate volume tag. Requires that Features0 is CHANGER_VOLUME_UNDEFINE. + /// + /// + /// UNDEFINE_PRIMARY 0xC + /// Clear the primary volume tag. Requires that Features0 is CHANGER_VOLUME_UNDEFINE. + /// + /// + /// + public ChangerActionCode ActionCode; + + /// + /// The template that the device uses to search for volume IDs. For search operations, the template can include wildcard + /// characters to search for volumes that match the template. Supported wildcard characters include the asterisk (*) and + /// question mark (?). For other operations, the template must specify a single volume. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_VOLUME_TEMPLATE_SIZE)] + public string VolumeIDTemplate; + } + + /// + /// Contains information that the IOCTL_CHANGER_SET_ACCESS control code needs to set the state of the device's insert/eject port, + /// door, or keypad. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_set_access typedef struct _CHANGER_SET_ACCESS { + // CHANGER_ELEMENT Element; DWORD Control; } CHANGER_SET_ACCESS, *PCHANGER_SET_ACCESS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_SET_ACCESS")] + [StructLayout(LayoutKind.Sequential)] + public struct CHANGER_SET_ACCESS + { + /// + /// A CHANGER_ELEMENT structure that represents the changer element. The ElementType member can be one of the following + /// values: ChangerDoor, ChangerIEPort, or ChangerKeypad. + /// + public CHANGER_ELEMENT Element; + + /// + /// The operation to be performed. + /// + /// + /// Value + /// Meaning + /// + /// + /// EXTEND_IEPORT 2 + /// The element is to be extended. Requires that Features0 is CHANGER_OPEN_IEPORT. + /// + /// + /// LOCK_ELEMENT 0 + /// The element is to be locked. Requires that Features0 is CHANGER_LOCK_UNLOCK. + /// + /// + /// RETRACT_IEPORT 3 + /// The element is to be retracted. Requires that Features0 is CHANGER_CLOSE_IEPORT. + /// + /// + /// UNLOCK_ELEMENT 1 + /// The element is to be unlocked. Requires that Features0 is CHANGER_LOCK_UNLOCK. + /// + /// + /// + public CHANGER_SET_ACCESS_OP Control; + } + + /// + /// Contains information needed by the IOCTL_CHANGER_SET_POSITION control code to set the changer's robotic transport mechanism to + /// the specified element address. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-changer_set_position typedef struct _CHANGER_SET_POSITION + // { CHANGER_ELEMENT Transport; CHANGER_ELEMENT Destination; BOOLEAN Flip; } CHANGER_SET_POSITION, *PCHANGER_SET_POSITION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_SET_POSITION")] + [StructLayout(LayoutKind.Sequential)] + public struct CHANGER_SET_POSITION + { + /// + /// A CHANGER_ELEMENT structure that indicates the transport to be moved. The ElementType member must be ChangerTransport. + /// + public CHANGER_ELEMENT Transport; + + /// + /// A CHANGER_ELEMENT structure that indicates the final destination of the transport. The ElementType member must be one + /// of the following values: ChangerSlot, ChangerDrive, or ChangerIEPort. + /// + public CHANGER_ELEMENT Destination; + + /// + /// If this member is TRUE, the media currently carried by Transport should be flipped. Otherwise, it should not. + /// This member is valid only if the Features0 member of the GET_CHANGER_PARAMETERS structure is CHANGER_MEDIUM_FLIP. + /// + [MarshalAs(UnmanagedType.U1)] + public bool Flip; + } + + /// Contains information associated with a media change event. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-class_media_change_context typedef struct + // _CLASS_MEDIA_CHANGE_CONTEXT { DWORD MediaChangeCount; DWORD NewState; } CLASS_MEDIA_CHANGE_CONTEXT, *PCLASS_MEDIA_CHANGE_CONTEXT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CLASS_MEDIA_CHANGE_CONTEXT")] + [StructLayout(LayoutKind.Sequential)] + public struct CLASS_MEDIA_CHANGE_CONTEXT + { + /// The number of times that media has been changed since system startup. + public uint MediaChangeCount; + + /// + /// + /// The state information. This member can be one of the following values from the MEDIA_CHANGE_DETECTION_STATE + /// enumeration type. + /// + /// MediaUnknown (0) + /// MediaPresent (1) + /// MediaNotPresent (2) + /// MediaUnavailable (3) + /// + public MEDIA_CHANGE_DETECTION_STATE NewState; + } + + /// Represents a type of CSV control operation. + /// + /// This structure is used with the FSCTL_CSV_CONTROL control code to indicate what kind of CSV control operation is being + /// undertaken. It is an alternative to calling that control code by just passing a CSV_CONTROL_OP enumeration value, as the + /// structure encapsulates an enumeration value of that type. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_control_param typedef struct _CSV_CONTROL_PARAM { + // CSV_CONTROL_OP Operation; LONGLONG Unused; } CSV_CONTROL_PARAM, *PCSV_CONTROL_PARAM; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_CONTROL_PARAM")] + [StructLayout(LayoutKind.Sequential)] + public struct CSV_CONTROL_PARAM + { + /// The type of CSV control operation to undertake. + public CSV_CONTROL_OP Operation; + + /// Unused. + public long Unused; + } + + /// + /// Contains the output for the FSCTL_IS_VOLUME_OWNED_BYCSVFS control code that determines whether a volume is owned by CSVFS. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_is_owned_by_csvfs typedef struct + // _CSV_IS_OWNED_BY_CSVFS { BOOLEAN OwnedByCSVFS; } CSV_IS_OWNED_BY_CSVFS, *PCSV_IS_OWNED_BY_CSVFS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_IS_OWNED_BY_CSVFS")] + [StructLayout(LayoutKind.Sequential)] + public struct CSV_IS_OWNED_BY_CSVFS + { + /// TRUE if a volume is owned by CSVFS; otherwise, FALSE. + [MarshalAs(UnmanagedType.U1)] + public bool OwnedByCSVFS; + } + + /// Contains the output for the FSCTL_IS_CSV_FILE control code that retrieves namespace information for a file. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_namespace_info typedef struct _CSV_NAMESPACE_INFO { + // DWORD Version; DWORD DeviceNumber; LARGE_INTEGER StartingOffset; DWORD SectorSize; } CSV_NAMESPACE_INFO, *PCSV_NAMESPACE_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_NAMESPACE_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct CSV_NAMESPACE_INFO + { + /// + /// The version number. This value must be set to CSV_NAMESPACE_INFO_V1. + /// + /// + /// Value + /// Meaning + /// + /// + /// CSV_NAMESPACE_INFO_V1 + /// Version 1. + /// + /// + /// + public uint Version; + + /// The device number of the disk. + public uint DeviceNumber; + + /// The starting offset of the volume. + public long StartingOffset; + + /// The sector size of the disk. + public uint SectorSize; + } + + /// Contains information about whether files in a stream have been modified. + /// + /// + /// This structure is used if the FSCTL_CSV_CONTROL control code is called with a CSV_CONTROL_OP enumeration value of + /// CsvControlQueryFileRevision, or if the control code is used with an CSV_CONTROL_PARAM structure containing that + /// enumeration value. + /// + /// Revision tracking is per file, not per stream, so the output changes whenever the stream changes. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_file_revision typedef struct + // _CSV_QUERY_FILE_REVISION { LONGLONG FileId; LONGLONG FileRevision[3]; } CSV_QUERY_FILE_REVISION, *PCSV_QUERY_FILE_REVISION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_FILE_REVISION")] + [StructLayout(LayoutKind.Sequential)] + public struct CSV_QUERY_FILE_REVISION + { + /// The identifier of an NTFS file. + public long FileId; + + /// + /// FileRevision[0] increases every time the CSV MDS stack is rebuilt and CSVFLT loses its state. + /// If any of the numbers are 0, the function caller should assume that the file was modified. + /// + public long FileRevision0; + + /// FileRevision[1] increases every time the CSV MDS stack purges the cached revision number for the file. + public long FileRevision1; + + /// + /// FileRevision[2] increases every time the CSV MDS observes that file sizes might have changed or the file might have + /// been written to. The element is also incremented whenever one of the nodes performs the first direct input/output operation + /// on a stream that is associated with this file after opening this stream. + /// + public long FileRevision2; + } + + /// Contains the path that is used by CSV to communicate to the MDS. + /// + /// This structure is used if the FSCTL_CSV_CONTROL control code is called with a CSV_CONTROL_OP enumeration value of + /// CsvControlQueryMdsPath, or if the control code is used with an CSV_CONTROL_PARAM structure containing that enumeration value. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_mds_path typedef struct _CSV_QUERY_MDS_PATH { + // DWORD MdsNodeId; DWORD DsNodeId; DWORD PathLength; WCHAR Path[1]; } CSV_QUERY_MDS_PATH, *PCSV_QUERY_MDS_PATH; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_MDS_PATH")] + [VanaraMarshaler(typeof(AnySizeStringMarshaler), nameof(PathLength) + ":cn")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct CSV_QUERY_MDS_PATH + { + /// The identifier of an MDS node. + public uint MdsNodeId; + + /// The identifier of a DS node. + public uint DsNodeId; + + /// The length of the path. + public uint PathLength; + + /// The path. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] + public string Path; + } + + /// Contains information about whether files in a stream have been redirected. + /// + /// This structure is used if the FSCTL_CSV_CONTROL control code is called with a CSV_CONTROL_OP enumeration value of + /// CsvControlQueryRedirectState, or if the control code is used with an CSV_CONTROL_PARAM structure containing that + /// enumeration value. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_redirect_state typedef struct + // _CSV_QUERY_REDIRECT_STATE { DWORD MdsNodeId; DWORD DsNodeId; BOOLEAN FileRedirected; } CSV_QUERY_REDIRECT_STATE, *PCSV_QUERY_REDIRECT_STATE; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_REDIRECT_STATE")] + [StructLayout(LayoutKind.Sequential)] + public struct CSV_QUERY_REDIRECT_STATE + { + /// The identifier of an MDS node. + public uint MdsNodeId; + + /// The identifier of a DS node. + public uint DsNodeId; + + /// TRUE if the file has been redirected; otherwise, FALSE. + [MarshalAs(UnmanagedType.U1)] + public bool FileRedirected; + } + + /// Contains troubleshooting information about why a volume is in redirected mode. + /// + /// CSV writes the troubleshooting strings to a diagnostic log that, when filtered, can provide hints as to why a volume is in a + /// redirected mode. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-csv_query_veto_file_direct_io_output typedef struct + // _CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT { DWORDLONG VetoedFromAltitudeIntegral; DWORDLONG VetoedFromAltitudeDecimal; WCHAR + // Reason[256]; } CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT, *PCSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT + { + /// The integer portion of VetoedFromAltitude. + public ulong VetoedFromAltitudeIntegral; + + /// The decimal portion of VetoedFromAltitude. + public ulong VetoedFromAltitudeDecimal; + + /// The reason why volume is in a redirected mode. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string Reason; + } + + /// + /// The DEVICE_COPY_OFFLOAD_DESCRIPTOR structure is one of the query result structures returned from an + /// IOCTL_STORAGE_QUERY_PROPERTY request. This structure contains the copy offload capabilities for a storage device. + /// + /// + /// This structure is returned from a IOCTL_STORAGE_QUERY_PROPERTY request when the PropertyId member of + /// STORAGE_PROPERTY_QUERY is set to StorageDeviceCopyOffloadProperty. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_copy_offload_descriptor typedef struct + // _DEVICE_COPY_OFFLOAD_DESCRIPTOR { DWORD Version; DWORD Size; DWORD MaximumTokenLifetime; DWORD DefaultTokenLifetime; DWORDLONG + // MaximumTransferSize; DWORDLONG OptimalTransferCount; DWORD MaximumDataDescriptors; DWORD MaximumTransferLengthPerDescriptor; + // DWORD OptimalTransferLengthPerDescriptor; WORD OptimalTransferLengthGranularity; BYTE Reserved[2]; } + // DEVICE_COPY_OFFLOAD_DESCRIPTOR, *PDEVICE_COPY_OFFLOAD_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_COPY_OFFLOAD_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_COPY_OFFLOAD_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// The maximum lifetime of the token, in seconds. + public uint MaximumTokenLifetime; + + /// The default lifetime of the token, in seconds. + public uint DefaultTokenLifetime; + + /// The maximum transfer size, in bytes. + public ulong MaximumTransferSize; + + /// The optimal transfer size, in bytes. + public ulong OptimalTransferCount; + + /// The maximum number of data descriptors. + public uint MaximumDataDescriptors; + + /// The maximum transfer length, in blocks, per descriptor. + public uint MaximumTransferLengthPerDescriptor; + + /// The optimal transfer length per descriptor. + public uint OptimalTransferLengthPerDescriptor; + + /// + /// The granularity of the optimal transfer length, in blocks. Transfer lengths that are not an even multiple of this length may + /// be delayed. + /// + public ushort OptimalTransferLengthGranularity; + + /// Reserved. + public ushort Reserved; + } + + /// + /// Output structure for the DeviceDsmAction_Allocation action of the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + /// + /// + /// Provisioning state information is returned when the Action member of the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure is + /// set to DeviceDsmAction_Allocation. The caller should include only one data set range in the system buffer at DataSetRangesOffset. + /// + /// + /// On return, the system buffer contains a DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT structure followed by the + /// DEVICE_DATA_SET_LB_PROVISIONING_STATE structure. The DEVICE_DATA_SET_LB_PROVISIONING_STATE structure begins at an + /// offset from the beginning of the system buffer specified by OutputBlockOffset in DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT. + /// + /// + /// Each bit in the allocation bitmap represents a slab mapping within the data set range requested. The bits correspond directly to + /// the slabs in the data set range. This means that bit 0 in the bitmap marks the first slab in the range. A slab is mapped if the + /// bit value = 1 and unmapped if the bit value = 0. + /// + /// + /// Space for SlabAllocationBitMap should be allocated based on the number of possible slabs in the requested data set range. + /// The SlabAllocationBitMapLength of the bitmap returned is + /// (number_of_slabs / 32) + ((number_of_slabs MOD 32) > 0 ? 1 : 0) + /// . + /// + /// + /// Slab size is determined by the OptimalUnmapGranularity member of the DEVICE_LB_PROVISIONING_DESCRIPTOR structure returned + /// from an IOCTL_STORAGE_QUERY_PROPERTY control code. The length of the data set range provided should be a multiple of + /// OptimalUnmapGranularity. When the range length is not a multiple of OptimalUnmapGranularity, it is reduced to be a multiple. + /// + /// + /// If the starting offset in the data set range is not aligned on a slab boundary, a multiple of OptimalUnmapGranularity, + /// the offset will be adjusted to the next boundary. The difference between the requested offset and the adjusted offset is + /// returned in SlabOffsetDeltaInBytes. + /// + /// + /// If the slab allocation total returned in SlabAllocationBitMapBitCount is not as expected because of data set range + /// alignment or length adjustments, an additional request may be submitted with a data set range modified according to the values + /// in both SlabAllocationBitMapBitCount and SlabOffsetDeltaInBytes. The new range will properly select the slabs left + /// out of the bitmap returned by the previous request. + /// + /// + /// If the requested slab size is too large (for example if it is larger than the maximum transfer length of the HBA) then the + /// IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES can fail with ERROR_INVALID_PARAMETER. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_data_set_lb_provisioning_state typedef struct + // _DEVICE_DATA_SET_LB_PROVISIONING_STATE { DWORD Size; DWORD Version; DWORDLONG SlabSizeInBytes; DWORD SlabOffsetDeltaInBytes; + // DWORD SlabAllocationBitMapBitCount; DWORD SlabAllocationBitMapLength; DWORD SlabAllocationBitMap[ANYSIZE_ARRAY]; } + // DEVICE_DATA_SET_LB_PROVISIONING_STATE, *PDEVICE_DATA_SET_LB_PROVISIONING_STATE, DEVICE_DSM_ALLOCATION_OUTPUT, *PDEVICE_DSM_ALLOCATION_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DATA_SET_LB_PROVISIONING_STATE")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(SlabAllocationBitMapLength))] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_DATA_SET_LB_PROVISIONING_STATE + { + /// The size of this structure, including the bitmap, in bytes. + public uint Size; + + /// The version of this structure. + public uint Version; + + /// The size of a slab, in bytes. + public ulong SlabSizeInBytes; + + /// + /// If the range specified is not aligned to the OptimalUnmapGranularity as returned in DEVICE_LB_PROVISIONING_DESCRIPTOR + /// structure then the data represented in the SlabAllocationBitMap is offset from the specified range by this amount. + /// + public uint SlabOffsetDeltaInBytes; + + /// The number of relevant bits in the bitmap. + public uint SlabAllocationBitMapBitCount; + + /// The number of DWORD s in the bitmap array. + public uint SlabAllocationBitMapLength; + + /// + /// The allocation bitmap containing one bit for each slab. If a bit is set then the corresponding slab is allocated. Otherwise, + /// if a bit is clear, the corresponding slab is unallocated. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public uint[] SlabAllocationBitMap; + } + + /// Provides data set range information for use with the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_data_set_range typedef struct + // _DEVICE_DATA_SET_RANGE { LONGLONG StartingOffset; DWORDLONG LengthInBytes; } DEVICE_DATA_SET_RANGE, *PDEVICE_DATA_SET_RANGE, + // DEVICE_DSM_RANGE, *PDEVICE_DSM_RANGE; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DATA_SET_RANGE")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_DATA_SET_RANGE + { + /// + /// Starting offset of the data set range in bytes, relative to the start of the volume. Must align to disk logical sector size. + /// + public long StartingOffset; + + /// Length of the data set range, in bytes. Must be a multiple of disk logical sector size. + public ulong LengthInBytes; + } + + /// + /// Specifies parameters for the repair operation. A repair operation is initiated by specifying DeviceDsmAction_Repair in + /// the Action member of the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure passed in a IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES + /// control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_data_set_repair_parameters typedef struct + // _DEVICE_DATA_SET_REPAIR_PARAMETERS { DWORD NumberOfRepairCopies; DWORD SourceCopy; DWORD RepairCopies[ANYSIZE_ARRAY]; } + // DEVICE_DATA_SET_REPAIR_PARAMETERS, *PDEVICE_DATA_SET_REPAIR_PARAMETERS, DEVICE_DSM_REPAIR_PARAMETERS, *PDEVICE_DSM_REPAIR_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DATA_SET_REPAIR_PARAMETERS")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfRepairCopies))] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_DATA_SET_REPAIR_PARAMETERS + { + /// The number of copies that will be repaired. + public uint NumberOfRepairCopies; + + /// The copy number of the source copy. + public uint SourceCopy; + + /// The copy numbers of all the copies that will be repaired. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public uint[] RepairCopies; + } + + /// + /// Contains parameters for the DeviceDsmAction_Notification action for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_dsm_notification_parameters typedef struct + // _DEVICE_DSM_NOTIFICATION_PARAMETERS { DWORD Size; DWORD Flags; DWORD NumFileTypeIDs; GUID FileTypeID[ANYSIZE_ARRAY]; } + // DEVICE_DSM_NOTIFICATION_PARAMETERS, *PDEVICE_DSM_NOTIFICATION_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DSM_NOTIFICATION_PARAMETERS")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumFileTypeIDs))] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_DSM_NOTIFICATION_PARAMETERS + { + /// + /// Specifies the total size, in bytes, of this structure. The value of this member must include the total size, in bytes, of + /// the FileTypeIDs member. + /// + public uint Size; + + /// + /// Flags specific to the notify operation + /// + /// + /// Value + /// Meaning + /// + /// + /// DEVICE_DSM_NOTIFY_FLAG_BEGIN 0x00000001 + /// + /// The ranges specified in the DEVICE_DATA_SET_RANGE structures following the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure are + /// currently being used by the file types that are specified in the FileTypeIDs member. + /// + /// + /// + /// DEVICE_DSM_NOTIFY_FLAG_END 0x00000002 + /// The ranges are no longer being used by the file types that are specified in the FileTypeIDs member. + /// + /// + /// + public DEVICE_DSM_NOTIFY_FLAG Flags; + + /// The number of entries in the FileTypeIDs member. + public uint NumFileTypeIDs; + + /// + /// One or more GUID values that specify the file type for the notification operation. + /// + /// + /// Value + /// Meaning + /// + /// + /// FILE_TYPE_NOTIFICATION_GUID_PAGE_FILE 0d0a64a1-38fc-4db8-9fe7-3f4352cd7c5c + /// Specifies a notification operation for a page file. + /// + /// + /// FILE_TYPE_NOTIFICATION_GUID_HIBERNATION_FILE b7624d64-b9a3-4cf8-8011-5b86c940e7b7 + /// Specifies a notification operation for the system hibernation file. + /// + /// + /// FILE_TYPE_NOTIFICATION_GUID_CRASHDUMP_FILE 9d453eb7-d2a6-4dbd-a2e3-fbd0ed9109a9 + /// Specifies a notification operation for a system crash dump file. + /// + /// + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public Guid[] FileTypeID; + + /// + /// Initializes a new instance of the struct setting all values appropriately + /// based on parameters. + /// + /// One or more GUID values that specify the file type for the notification operation. + /// Flags specific to the notify operation. + public DEVICE_DSM_NOTIFICATION_PARAMETERS(Guid[] fileTypeID, DEVICE_DSM_NOTIFY_FLAG flags) { - /// - /// A handle to the file to be moved. - /// To retrieve a handle to a file, use CreateFile. - /// - /// If the file is encrypted, the handle must have the FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, - /// or FILE_EXECUTE access right. For more information, see File Security and Access Rights. - /// - /// - public HFILE FileHandle; - - /// A VCN (cluster number relative to the beginning of a file) of the first cluster to be moved. - public long StartingVcn; - - /// An LCN (cluster number on a volume) to which the VCN is to be moved. - public long StartingLcn; - - /// The count of clusters to be moved. - public uint ClusterCount; + FileTypeID = fileTypeID; + NumFileTypeIDs = (uint)fileTypeID.Length; + Flags = flags; + Size = (uint)(Marshal.SizeOf(typeof(DEVICE_DSM_NOTIFICATION_PARAMETERS)) + Marshal.SizeOf(typeof(Guid)) * (NumFileTypeIDs - 1)); } + } - /// Represents volume data. This structure is passed to the FSCTL_GET_NTFS_VOLUME_DATA control code. - /// - /// Reserved clusters are the free clusters reserved for later use by Windows. - /// - /// The NTFS_VOLUME_DATA_BUFFER structure represents the basic information returned by FSCTL_GET_NTFS_VOLUME_DATA. For - /// extended volume information, pass a buffer that is the combined size of the NTFS_VOLUME_DATA_BUFFER and - /// NTFS_EXTENDED_VOLUME_DATA structures. Upon success, the buffer returned by FSCTL_GET_NTFS_VOLUME_DATA will contain - /// the information associated with both structures. The NTFS_VOLUME_DATA_BUFFER structure will always be filled starting at - /// the beginning of the buffer, with the NTFS_EXTENDED_VOLUME_DATA structure immediately following. The - /// NTFS_EXTENDED_VOLUME_DATA structure is defined as follows: - /// - /// - /// This structure contains the major and minor version information for an NTFS volume. The ByteCount member will return the - /// total bytes of the output buffer used for this structure by the call to FSCTL_GET_NTFS_VOLUME_DATA. This value should be - /// sizeof(NTFS_EXTENDED_VOLUME_DATA) - /// if the buffer passed was large enough to hold it, otherwise the value will be less than - /// sizeof(NTFS_EXTENDED_VOLUME_DATA) + /// + /// Contains parameters for the DeviceDsmAction_OffloadRead action for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_dsm_offload_read_parameters typedef struct + // _DEVICE_DSM_OFFLOAD_READ_PARAMETERS { DWORD Flags; DWORD TimeToLive; DWORD Reserved[2]; } DEVICE_DSM_OFFLOAD_READ_PARAMETERS, *PDEVICE_DSM_OFFLOAD_READ_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DSM_OFFLOAD_READ_PARAMETERS")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_DSM_OFFLOAD_READ_PARAMETERS + { + /// Set to 0. + public uint Flags; + + /// The time to live (TTL) for the token, in milliseconds. + public uint TimeToLive; + + /// Set to 0. + public ulong Reserved; + } + + /// + /// Specifies parameters for the offload write operation. An offload write operation is initiated by specifying + /// DeviceDsmAction_OffloadWrite in the Action member of the DEVICE_MANAGE_DATA_SET_ATTRIBUTES structure passed in a + /// IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_dsm_offload_write_parameters typedef struct + // _DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS { DWORD Flags; DWORD Reserved; DWORDLONG TokenOffset; STORAGE_OFFLOAD_TOKEN Token; } + // DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS, *PDEVICE_DSM_OFFLOAD_WRITE_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS + { + /// Set to 0. + public uint Flags; + + /// Reserved. + public uint Reserved; + + /// The starting offset to copy from the range bound to the token + public ulong TokenOffset; + + /// STORAGE_OFFLOAD_TOKEN structure containing the token returned from the offload read operation. + public STORAGE_OFFLOAD_TOKEN Token; + } + + /// + /// The DEVICE_LB_PROVISIONING_DESCRIPTOR structure is one of the query result structures returned from an + /// IOCTL_STORAGE_QUERY_PROPERTY request. This structure contains the thin provisioning capabilities for a storage device. + /// + /// + /// + /// This structure is returned from a IOCTL_STORAGE_QUERY_PROPERTY request when the PropertyId member of + /// STORAGE_PROPERTY_QUERY is set to StorageDeviceLBProvisioningProperty. + /// + /// + /// If UnmapGranularityAlignmentValid = 0, then any code using UnmapGranularityAlignment should assume it has a value + /// of 0. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_lb_provisioning_descriptor typedef struct + // _DEVICE_LB_PROVISIONING_DESCRIPTOR { DWORD Version; DWORD Size; BYTE ThinProvisioningEnabled : 1; BYTE ThinProvisioningReadZeros + // : 1; BYTE AnchorSupported : 3; BYTE UnmapGranularityAlignmentValid : 1; BYTE Reserved0 : 2; BYTE Reserved1[7]; DWORDLONG + // OptimalUnmapGranularity; DWORDLONG UnmapGranularityAlignment; DWORD MaxUnmapLbaCount; DWORD MaxUnmapBlockDescriptorCount; } + // DEVICE_LB_PROVISIONING_DESCRIPTOR, *PDEVICE_LB_PROVISIONING_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_LB_PROVISIONING_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_LB_PROVISIONING_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + private byte flags; + + /// + /// The thin provisioning–enabled status. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// Thin provisioning is disabled. + /// + /// + /// 1 + /// Thin provisioning is enabled. + /// + /// + /// + public bool ThinProvisioningEnabled { get => BitHelper.GetBit(flags, 0); set => BitHelper.SetBit(ref flags, 0, value); } + + /// + /// Reads to unmapped regions return zeros. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// Data read from unmapped regions is undefined. + /// + /// + /// 1 + /// Reads return zeros. + /// + /// + /// + public bool ThinProvisioningReadZeros { get => BitHelper.GetBit(flags, 1); set => BitHelper.SetBit(ref flags, 1, value); } + + /// + /// Deterministic read after trim support. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// Deterministic read after trim is not supported. + /// + /// + /// 1 + /// Deterministic read after trim is supported. + /// + /// + /// + public byte AnchorSupported { get => BitHelper.GetBits(flags, 2, 3); set => BitHelper.SetBits(ref flags, 2, 3, value); } + + /// + /// The validity of unmap granularity alignment for the device. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// Unmap granularity alignment is not valid. + /// + /// + /// 1 + /// Unmap granularity alignment is valid. + /// + /// + /// + public bool UnmapGranularityAlignmentValid { get => BitHelper.GetBit(flags, 5); set => BitHelper.SetBit(ref flags, 5, value); } + + /// Reserved. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] + public byte[] Reserved1; + + /// The optimal number of logical sectors for unmap granularity for the device. + public ulong OptimalUnmapGranularity; + + /// The current value, in logical sectors, set for unmap granularity alignment on the device. + public ulong UnmapGranularityAlignment; + + /// + /// Starting in Windows 10: The maximum number of LBAs that can be unmapped in a single unmap command, in logical blocks. + /// + public uint MaxUnmapLbaCount; + + /// Starting in Windows 10: The maximum number of descriptors allowed in a single unmap command. + public uint MaxUnmapBlockDescriptorCount; + } + + /// Input structure for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + /// The total length of the buffer that contains this structure must be at least + /// (sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + ParameterBlockLength + DataSetRangesLength) + /// . + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_manage_data_set_attributes typedef struct + // _DEVICE_MANAGE_DATA_SET_ATTRIBUTES { DWORD Size; DEVICE_DSM_ACTION Action; DWORD Flags; DWORD ParameterBlockOffset; DWORD + // ParameterBlockLength; DWORD DataSetRangesOffset; DWORD DataSetRangesLength; } DEVICE_MANAGE_DATA_SET_ATTRIBUTES, + // *PDEVICE_MANAGE_DATA_SET_ATTRIBUTES, DEVICE_DSM_INPUT, *PDEVICE_DSM_INPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_MANAGE_DATA_SET_ATTRIBUTES")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_MANAGE_DATA_SET_ATTRIBUTES + { + /// + /// Size of this data structure. Must be set to + /// sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) /// . - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_extended_volume_data typedef struct { DWORD - // ByteCount; WORD MajorVersion; WORD MinorVersion; DWORD BytesPerPhysicalSector; WORD LfsMajorVersion; WORD LfsMinorVersion; DWORD - // MaxDeviceTrimExtentCount; DWORD MaxDeviceTrimByteCount; DWORD MaxVolumeTrimExtentCount; DWORD MaxVolumeTrimByteCount; } - // NTFS_EXTENDED_VOLUME_DATA, *PNTFS_EXTENDED_VOLUME_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_2")] - [StructLayout(LayoutKind.Sequential)] - public struct NTFS_EXTENDED_VOLUME_DATA - { - /// - public uint ByteCount; + /// + public uint Size; - /// - public ushort MajorVersion; + /// + /// A valid value of type DEVICE_DATA_MANAGEMENT_SET_ACTION. + /// + /// + /// Value + /// Meaning + /// + /// + /// DeviceDsmAction_Trim 1 + /// A trim action is performed. This value is not supported for user-mode applications. + /// + /// + /// DeviceDsmAction_Notification 2 | DeviceDsmActionFlag_NonDestructive (0x80000002) + /// + /// A notification action is performed. The additional parameters are in a DEVICE_DSM_NOTIFICATION_PARAMETERS structure. The + /// DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver stack that this operation is non-destructive. + /// + /// + /// + /// DeviceDsmAction_OffloadRead 3 | DeviceDsmActionFlag_NonDestructive (0x80000003) + /// + /// An offload read action is performed. The additional parameters are in a DEVICE_DSM_OFFLOAD_READ_PARAMETERS structure. The + /// DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver stack that this operation is + /// non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_OffloadWrite 4 + /// + /// An offload write action is performed. The additional parameters are in a DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS structure. + /// Windows 7 and Windows Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_Allocation 5 | DeviceDsmActionFlag_NonDestructive (0x80000005) + /// + /// An allocation bitmap is retrieved for the first data set range specified. The DeviceDsmActionFlag_NonDestructive + /// (0x80000000) is a bit flag to indicate to the driver stack that this operation is non-destructive. Windows 7 and Windows + /// Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_Repair 6 | DeviceDsmActionFlag_NonDestructive (0x80000006) + /// + /// A repair action is performed. The additional parameters are in a DEVICE_DATA_SET_REPAIR_PARAMETERS structure. The + /// DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver stack that this operation is + /// non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_Scrub 7 | DeviceDsmActionFlag_NonDestructive (0x80000007) + /// + /// A scrub action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver + /// stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before + /// Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_Resiliency 8 | DeviceDsmActionFlag_NonDestructive (0x80000008) + /// + /// A resiliency action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the + /// driver stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported + /// before Windows 8 and Windows Server 2012. + /// + /// + /// + /// + public DEVICE_DSM_ACTION Action; - /// - public ushort MinorVersion; + /// + /// Flags for the actions. + /// + /// + /// Value + /// Meaning + /// + /// + /// DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED 0x80000000 + /// + /// If set then the described ranges are not allocated by a file system. This flag is specific to the DeviceDsmAction_Trim action. + /// + /// + /// + /// DEVICE_DSM_FLAG_RESILIENCY_START_RESYNC 0x10000000 + /// Starts a resync operation on the storage device. This flag is specific to the DeviceDsmAction_Resiliency action. + /// + /// + /// DEVICE_DSM_FLAG_RESILIENCY_START_LOAD_BALANCING 0x20000000 + /// Starts a load balancing operation on the storage device. This flag is specific to the DeviceDsmAction_Resiliency action. + /// + /// + /// + public uint Flags; - /// - public uint BytesPerPhysicalSector; + /// + /// Byte offset to the start of the parameter block stored in the buffer contiguous to this structure. Must be aligned to the + /// corresponding structure alignment. A value of zero indicates there is no parameter block and the ParameterBlockLength + /// member must also be zero. + /// + public uint ParameterBlockOffset; - /// - public ushort LfsMajorVersion; + /// + /// Length of the parameter block, in bytes. A value of zero indicates there is no parameter block and the + /// ParameterBlockOffset member must also be zero. + /// + public uint ParameterBlockLength; - /// - public ushort LfsMinorVersion; + /// + /// Byte offset to the start of the data set ranges block made up of an array of DEVICE_DATA_SET_RANGE structures stored in the + /// buffer contiguous to this structure. Must be aligned to the DEVICE_DATA_SET_RANGE structure alignment. A value of + /// zero indicates there is no data set ranges block and the DataSetRangesLength member must also be zero. + /// + public uint DataSetRangesOffset; - /// - public uint MaxDeviceTrimExtentCount; + /// + /// Length of the data set ranges block, in bytes. A value of zero indicates there is no data set ranges block and the + /// DataSetRangesOffset member must also be zero. + /// + public uint DataSetRangesLength; + } - /// - public uint MaxDeviceTrimByteCount; - - /// - public uint MaxVolumeTrimExtentCount; - - /// - public uint MaxVolumeTrimByteCount; - } - - /// Contains data for the FSCTL_GET_NTFS_FILE_RECORD control code. - /// Pass this structure as input to the FSCTL_GET_NTFS_FILE_RECORD control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_file_record_input_buffer typedef struct { - // LARGE_INTEGER FileReferenceNumber; } NTFS_FILE_RECORD_INPUT_BUFFER, *PNTFS_FILE_RECORD_INPUT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_8")] - [StructLayout(LayoutKind.Sequential)] - public struct NTFS_FILE_RECORD_INPUT_BUFFER - { - /// - /// The file identifier of the file record to be retrieved. This is not necessarily the file identifier returned in the - /// FileReferenceNumber member of the NTFS_FILE_RECORD_OUTPUT_BUFFER structure. Refer to the Remarks section of the - /// reference page for FSCTL_GET_NTFS_FILE_RECORD for more information. - /// - public long FileReferenceNumber; - } - - /// Receives output data from the FSCTL_GET_NTFS_FILE_RECORD control code. - /// To retrieve data to fill in this structure, use the DeviceIoControl FSCTL_GET_NTFS_FILE_RECORD control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_file_record_output_buffer typedef struct { - // LARGE_INTEGER FileReferenceNumber; DWORD FileRecordLength; BYTE FileRecordBuffer[1]; } NTFS_FILE_RECORD_OUTPUT_BUFFER, *PNTFS_FILE_RECORD_OUTPUT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_9")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(FileRecordLength))] - [StructLayout(LayoutKind.Sequential)] - public struct NTFS_FILE_RECORD_OUTPUT_BUFFER - { - /// - /// The file identifier of the returned file record. This is not necessarily the file identifier specified in the - /// FileReferenceNumber member of the NTFS_FILE_RECORD_INPUT_BUFFER structure. Refer to the Remarks section of the - /// reference page for FSCTL_GET_NTFS_FILE_RECORD for more information. - /// - public long FileReferenceNumber; - - /// The length of the returned file record, in bytes. - public uint FileRecordLength; - - /// The starting location of the buffer for the returned file record. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] FileRecordBuffer; - } - - /// Represents volume data. This structure is passed to the FSCTL_GET_NTFS_VOLUME_DATA control code. - /// - /// Reserved clusters are the free clusters reserved for later use by Windows. - /// - /// The NTFS_VOLUME_DATA_BUFFER structure represents the basic information returned by FSCTL_GET_NTFS_VOLUME_DATA. For - /// extended volume information, pass a buffer that is the combined size of the NTFS_VOLUME_DATA_BUFFER and - /// NTFS_EXTENDED_VOLUME_DATA structures. Upon success, the buffer returned by FSCTL_GET_NTFS_VOLUME_DATA will contain - /// the information associated with both structures. The NTFS_VOLUME_DATA_BUFFER structure will always be filled starting at - /// the beginning of the buffer, with the NTFS_EXTENDED_VOLUME_DATA structure immediately following. The - /// NTFS_EXTENDED_VOLUME_DATA structure is defined as follows: - /// - /// - /// This structure contains the major and minor version information for an NTFS volume. The ByteCount member will return the - /// total bytes of the output buffer used for this structure by the call to FSCTL_GET_NTFS_VOLUME_DATA. This value should be - /// sizeof(NTFS_EXTENDED_VOLUME_DATA) - /// if the buffer passed was large enough to hold it, otherwise the value will be less than - /// sizeof(NTFS_EXTENDED_VOLUME_DATA) + /// Output structure for the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_manage_data_set_attributes_output typedef struct + // _DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT { DWORD Size; DEVICE_DSM_ACTION Action; DWORD Flags; DWORD OperationStatus; DWORD + // ExtendedError; DWORD TargetDetailedError; DWORD ReservedStatus; DWORD OutputBlockOffset; DWORD OutputBlockLength; } + // DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT, *PDEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT, DEVICE_DSM_OUTPUT, *PDEVICE_DSM_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT + { + /// + /// Size of the structure. This is set to + /// sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT) /// . - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_volume_data_buffer typedef struct { LARGE_INTEGER - // VolumeSerialNumber; LARGE_INTEGER NumberSectors; LARGE_INTEGER TotalClusters; LARGE_INTEGER FreeClusters; LARGE_INTEGER - // TotalReserved; DWORD BytesPerSector; DWORD BytesPerCluster; DWORD BytesPerFileRecordSegment; DWORD ClustersPerFileRecordSegment; - // LARGE_INTEGER MftValidDataLength; LARGE_INTEGER MftStartLcn; LARGE_INTEGER Mft2StartLcn; LARGE_INTEGER MftZoneStart; - // LARGE_INTEGER MftZoneEnd; } NTFS_VOLUME_DATA_BUFFER, *PNTFS_VOLUME_DATA_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_1")] - [StructLayout(LayoutKind.Sequential)] - public struct NTFS_VOLUME_DATA_BUFFER - { - /// The serial number of the volume. This is a unique number assigned to the volume media by the operating system. - public long VolumeSerialNumber; - - /// The number of sectors in the specified volume. - public long NumberSectors; - - /// The number of used and free clusters in the specified volume. - public long TotalClusters; - - /// The number of free clusters in the specified volume. - public long FreeClusters; - - /// The number of reserved clusters in the specified volume. - public long TotalReserved; - - /// The number of bytes in a sector on the specified volume. - public uint BytesPerSector; - - /// The number of bytes in a cluster on the specified volume. This value is also known as the cluster factor. - public uint BytesPerCluster; - - /// The number of bytes in a file record segment. - public uint BytesPerFileRecordSegment; - - /// The number of clusters in a file record segment. - public uint ClustersPerFileRecordSegment; - - /// The length of the master file table, in bytes. - public long MftValidDataLength; - - /// The starting logical cluster number of the master file table. - public long MftStartLcn; - - /// The starting logical cluster number of the master file table mirror. - public long Mft2StartLcn; - - /// The starting logical cluster number of the master file table zone. - public long MftZoneStart; - - /// The ending logical cluster number of the master file table zone. - public long MftZoneEnd; - } - - /// Indicates the range of the read operation to perform and the plex from which to read. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-plex_read_data_request typedef struct - // _PLEX_READ_DATA_REQUEST { LARGE_INTEGER ByteOffset; DWORD ByteLength; DWORD PlexNumber; } PLEX_READ_DATA_REQUEST, *PPLEX_READ_DATA_REQUEST; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._PLEX_READ_DATA_REQUEST")] - [StructLayout(LayoutKind.Sequential)] - public struct PLEX_READ_DATA_REQUEST - { - /// - /// The offset of the range to be read. The offset can be the virtual offset to a file or volume. File offsets should be cluster - /// aligned and volume offsets should be sector aligned. - /// - public long ByteOffset; - - /// The length of the range to be read. The maximum value is 64 KB. - public uint ByteLength; - - /// - /// The plex from which to read. A value of zero indicates the primary copy, a value of one indicates the secondary copy, and so on. - /// - public uint PlexNumber; - } - - /// Provides removable media locking data. It is used by the IOCTL_STORAGE_MEDIA_REMOVAL control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-prevent_media_removal typedef struct - // _PREVENT_MEDIA_REMOVAL { BOOLEAN PreventMediaRemoval; } PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._PREVENT_MEDIA_REMOVAL")] - [StructLayout(LayoutKind.Sequential)] - public struct PREVENT_MEDIA_REMOVAL - { - /// If this member is TRUE, the media is to be locked. Otherwise, it is not. - [MarshalAs(UnmanagedType.U1)] - public bool PreventMediaRemoval; - } - - /// Represents the volume tag information. It is used by the IOCTL_CHANGER_QUERY_VOLUME_TAGS control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-read_element_address_info typedef struct - // _READ_ELEMENT_ADDRESS_INFO { DWORD NumberOfElements; CHANGER_ELEMENT_STATUS ElementStatus[1]; } READ_ELEMENT_ADDRESS_INFO, *PREAD_ELEMENT_ADDRESS_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._READ_ELEMENT_ADDRESS_INFO")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfElements))] - [StructLayout(LayoutKind.Sequential)] - public struct READ_ELEMENT_ADDRESS_INFO - { - /// - /// The number of elements matching criteria set forth by the ActionCode member of CHANGER_SEND_VOLUME_TAG_INFORMATION. - /// For information on compatibility with the current device, see the Features0 member of GET_CHANGER_PARAMETERS. - /// - public uint NumberOfElements; - - /// - /// An array of CHANGER_ELEMENT_STATUS structures, one for each element that corresponded with the information passed in with - /// the CHANGER_SEND_VOLUME_TAG_INFORMATION structure. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public CHANGER_ELEMENT_STATUS[] ElementStatus; - } + /// + public uint Size; /// - /// Contains disk block reassignment data. This is a variable length structure where the last member is an array of block numbers to - /// be reassigned. It is used by the IOCTL_DISK_REASSIGN_BLOCKS control code. - /// - /// /// - /// The REASSIGN_BLOCKS structure only supports drives where the Logical Block Address (LBA) is a 4-byte value (typically up - /// to 2 TB). + /// The action related to the instance of this structure. This is a value for the DEVICE_DATA_MANAGEMENT_SET_ACTION data type. /// - /// - /// For larger drives the REASSIGN_BLOCKS_EX structure that is used with the IOCTL_DISK_REASSIGN_BLOCKS_EX control code supports - /// 8-byte LBAs. - /// - /// - /// For device compatibility, the IOCTL_DISK_REASSIGN_BLOCKS control code and REASSIGN_BLOCKS structure should be used where possible. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-reassign_blocks typedef struct _REASSIGN_BLOCKS { WORD - // Reserved; WORD Count; DWORD BlockNumber[1]; } REASSIGN_BLOCKS, *PREASSIGN_BLOCKS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REASSIGN_BLOCKS")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(Count))] - [StructLayout(LayoutKind.Sequential)] - public struct REASSIGN_BLOCKS - { - /// This member is reserved. Do not use it. Set it to zero. - public ushort Reserved; - - /// - /// The number of blocks to be reassigned. - /// This is the number of elements that are in the BlockNumber member array. - /// - public ushort Count; - - /// An array of Count block numbers, one for each block to be reassigned. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public uint[] BlockNumber; - } - - /// - /// Contains disk block reassignment data. This is a variable length structure where the last member is an array of block numbers to - /// be reassigned. It is used by the IOCTL_DISK_REASSIGN_BLOCKS_EX control code. + /// + /// + /// Value + /// Meaning + /// + /// + /// DeviceDsmAction_Trim 1 + /// A trim action is performed. This value is not supported for user-mode applications. + /// + /// + /// DeviceDsmAction_Notification 2 | DeviceDsmActionFlag_NonDestructive (0x80000002) + /// + /// A notification action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the + /// driver stack that this operation is non-destructive. + /// + /// + /// + /// DeviceDsmAction_OffloadRead 3 | DeviceDsmActionFlag_NonDestructive (0x80000003) + /// + /// An offload read action is performed. The output described by the OutputBlockOffset and OutputBlockLength members is a + /// STORAGE_OFFLOAD_READ_OUTPUT structure. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the + /// driver stack that this operation is non-destructive. + /// + /// + /// + /// DeviceDsmAction_OffloadWrite 4 + /// + /// An offload write action is performed. The output described by the OutputBlockOffset and OutputBlockLength members is a + /// STORAGE_OFFLOAD_WRITE_OUTPUT structure. + /// + /// + /// + /// DeviceDsmAction_Allocation 5 | DeviceDsmActionFlag_NonDestructive (0x80000005) + /// + /// An allocation bitmap is returned for the first data set range passed in. The output is in a + /// DEVICE_DATA_SET_LB_PROVISIONING_STATE structure. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to + /// indicate to the driver stack that this operation is non-destructive. + /// + /// + /// + /// DeviceDsmAction_Repair 6 | DeviceDsmActionFlag_NonDestructive (0x80000006) + /// + /// A repair action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver + /// stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before + /// Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_Scrub 7 | DeviceDsmActionFlag_NonDestructive (0x80000007) + /// + /// A scrub action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the driver + /// stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported before + /// Windows 8 and Windows Server 2012. + /// + /// + /// + /// DeviceDsmAction_Resiliency 8 | DeviceDsmActionFlag_NonDestructive (0x80000008) + /// + /// A resiliency action is performed. The DeviceDsmActionFlag_NonDestructive (0x80000000) is a bit flag to indicate to the + /// driver stack that this operation is non-destructive. Windows 7 and Windows Server 2008 R2: This value is not supported + /// before Windows 8 and Windows Server 2012. + /// + /// + /// /// - /// - /// The REASSIGN_BLOCKS_EX structure supports drives that have an 8-byte Logical Block Address (LBA), which is typically - /// required for storage devices larger than 2 TB. The REASSIGN_BLOCKS structure used with the IOCTL_DISK_REASSIGN_BLOCKS control - /// code supports devices with up to a 4-byte LBA should be used where possible. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-reassign_blocks_ex typedef struct _REASSIGN_BLOCKS_EX { - // WORD Reserved; WORD Count; LARGE_INTEGER BlockNumber[1]; } REASSIGN_BLOCKS_EX, *PREASSIGN_BLOCKS_EX; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REASSIGN_BLOCKS_EX")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(Count))] - [StructLayout(LayoutKind.Sequential)] - public struct REASSIGN_BLOCKS_EX + public DEVICE_DSM_ACTION Action; + + /// Not used. + public uint Flags; + + /// Not used. + public uint OperationStatus; + + /// Extended error information. + public uint ExtendedError; + + /// Target specific error. + public uint TargetDetailedError; + + /// Reserved. + public uint ReservedStatus; + + /// The offset, in bytes, from the beginning of this structure to where any action-specific data is located. + public uint OutputBlockOffset; + + /// The length, in bytes, of the action-specific data. + public uint OutputBlockLength; + } + + /// Provides information about the media supported by a device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_media_info typedef struct _DEVICE_MEDIA_INFO { + // union { struct { LARGE_INTEGER Cylinders; STORAGE_MEDIA_TYPE MediaType; DWORD TracksPerCylinder; DWORD SectorsPerTrack; DWORD + // BytesPerSector; DWORD NumberMediaSides; DWORD MediaCharacteristics; } DiskInfo; struct { LARGE_INTEGER Cylinders; + // STORAGE_MEDIA_TYPE MediaType; DWORD TracksPerCylinder; DWORD SectorsPerTrack; DWORD BytesPerSector; DWORD NumberMediaSides; DWORD + // MediaCharacteristics; } RemovableDiskInfo; struct { STORAGE_MEDIA_TYPE MediaType; DWORD MediaCharacteristics; DWORD + // CurrentBlockSize; STORAGE_BUS_TYPE BusType; union { struct { BYTE MediumType; BYTE DensityCode; } ScsiInformation; } + // BusSpecificData; } TapeInfo; } DeviceSpecific; } DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_MEDIA_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_MEDIA_INFO + { + /// A union that contains the following members. + public DEVICESPECIFIC DeviceSpecific; + + /// A union that contains the following members. + [StructLayout(LayoutKind.Explicit)] + public struct DEVICESPECIFIC { - /// This member is reserved. Do not use it. Set it to 0 (zero). - public ushort Reserved; + /// A structure that contains the following members. + [FieldOffset(0)] + public DISKINFO DiskInfo; - /// - /// The number of blocks to be reassigned. - /// This is the number of elements that are in the BlockNumber member array. - /// - public ushort Count; + /// A structure that contains the following members. + [FieldOffset(0)] + public DISKINFO RemovableDiskInfo; - /// An array of Count block numbers, one for each block to be reassigned. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public long[] BlockNumber; - } + /// A structure that contains the following members. + [FieldOffset(0)] + public TAPEINFO TapeInfo; - /// - /// Input structure for the FSCTL_REPAIR_COPIES control code. It describes a single block of data and indicates which of the copies - /// is to be copied to the specified copies of the data. The - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-repair_copies_input typedef struct _REPAIR_COPIES_INPUT { - // DWORD Size; DWORD Flags; LARGE_INTEGER FileOffset; DWORD Length; DWORD SourceCopy; DWORD NumberOfRepairCopies; DWORD - // RepairCopies[ANYSIZE_ARRAY]; } REPAIR_COPIES_INPUT, *PREPAIR_COPIES_INPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REPAIR_COPIES_INPUT")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfRepairCopies))] - [StructLayout(LayoutKind.Sequential)] - public struct REPAIR_COPIES_INPUT - { - /// - /// Set to - /// sizeof(REPAIR_COPIES_INPUT) - /// . - /// - public uint Size; - - /// Reserved (must be zero) - public uint Flags; - - /// The file position to start the repair operation. - public long FileOffset; - - /// The number of bytes to be repaired. - public uint Length; - - /// The zero-based copy number of the source copy. - public uint SourceCopy; - - /// The number of copies that will be repaired. This is the size of the RepairCopies array. - public uint NumberOfRepairCopies; - - /// The zero-based copy numbers of the copies that will be repaired. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public uint[] RepairCopies; - } - - /// Contains output of a repair copies operation returned from the FSCTL_REPAIR_COPIES control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-repair_copies_output typedef struct _REPAIR_COPIES_OUTPUT - // { DWORD Size; DWORD Status; LARGE_INTEGER ResumeFileOffset; } REPAIR_COPIES_OUTPUT, *PREPAIR_COPIES_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REPAIR_COPIES_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct REPAIR_COPIES_OUTPUT - { - /// - /// Set to - /// sizeof(REPAIR_COPIES_OUTPUT) - /// . - /// - public uint Size; - - /// - /// Indicates the status of the repair operation. The value is a NTSTATUS value. See - /// http://msdn.microsoft.com/en-us/library/cc704588(PROT.10).aspx for a list of NTSTATUS values. - /// - public NTStatus Status; - - /// - /// If the Status member indicates the operation was not successful, this is the file offset to use to resume repair - /// operations, skipping the range where errors were found. - /// - public long ResumeFileOffset; - } - - /// - /// Contains the information to request an opportunistic lock (oplock) or to acknowledge an oplock break with the - /// FSCTL_REQUEST_OPLOCK control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-request_oplock_input_buffer typedef struct - // _REQUEST_OPLOCK_INPUT_BUFFER { WORD StructureVersion; WORD StructureLength; DWORD RequestedOplockLevel; DWORD Flags; } - // REQUEST_OPLOCK_INPUT_BUFFER, *PREQUEST_OPLOCK_INPUT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REQUEST_OPLOCK_INPUT_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct REQUEST_OPLOCK_INPUT_BUFFER - { - /// The version of the REQUEST_OPLOCK_INPUT_BUFFER structure that is being used. Set this member to REQUEST_OPLOCK_CURRENT_VERSION. - public ushort StructureVersion; - - /// - /// The length of this structure, in bytes. Must be set to - /// sizeof(REQUEST_OPLOCK_INPUT_BUFFER) - /// . - /// - public ushort StructureLength; - - /// - /// A valid combination of the following oplock level values. - /// - /// - /// Value - /// Meaning - /// - /// - /// OPLOCK_LEVEL_CACHE_READ - /// Allows clients to cache reads. May be granted to multiple clients. - /// - /// - /// OPLOCK_LEVEL_CACHE_HANDLE - /// Allows clients to cache open handles. May be granted to multiple clients. - /// - /// - /// OPLOCK_LEVEL_CACHE_WRITE - /// Allows clients to cache writes and byte range locks. May be granted only to a single client. - /// - /// - /// Valid combinations of these values are as follows: - /// - /// - /// - /// OPLOCK_LEVEL_CACHE_READ - /// - /// - /// - /// - /// OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE - /// - /// - /// - /// - /// OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_WRITE - /// - /// - /// - /// - /// OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_WRITE | OPLOCK_LEVEL_CACHE_HANDLE - /// - /// - /// - /// For more information about these value combinations, see FSCTL_REQUEST_OPLOCK. - /// - public OPLOCK_LEVEL_CACHE RequestedOplockLevel; - - /// - /// A valid combination of the following request flag values. - /// - /// - /// Value - /// Meaning - /// - /// - /// REQUEST_OPLOCK_INPUT_FLAG_REQUEST - /// - /// Request for a new oplock. Setting this flag together with REQUEST_OPLOCK_INPUT_FLAG_ACK is not valid and will cause the - /// request to fail with ERROR_INVALID_PARAMETER. - /// - /// - /// - /// REQUEST_OPLOCK_INPUT_FLAG_ACK - /// - /// Acknowledgment of an oplock break. Setting this flag together with REQUEST_OPLOCK_ INPUT_FLAG_REQUEST is not valid and will - /// cause the request to fail with ERROR_INVALID_PARAMETER. - /// - /// - /// - /// - public OPLOCK_INPUT_FLAG Flags; - } - - /// Contains the opportunistic lock (oplock) information returned by the FSCTL_REQUEST_OPLOCK control code. - /// - /// The REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED flag indicates that the ShareMode and AccessMode fields - /// contain the share and access flags, respectively, of the request causing the oplock break. This information may be provided on - /// breaks where the OPLOCK_LEVEL_CACHE_HANDLE level is being lost and may be useful to callers who can close handles whose - /// share and access modes conflict with the handle causing the break. This may enable them to maintain at least some handle cache - /// state. Note that not all breaks where the OPLOCK_LEVEL_CACHE_HANDLE level is being lost will have this flag set. The - /// primary case where this flag will be set is if the break is a result of a create operation that needs the - /// OPLOCK_LEVEL_CACHE_HANDLE oplock to be broken to avoid failing with ERROR_SHARING_VIOLATION. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-request_oplock_output_buffer typedef struct - // _REQUEST_OPLOCK_OUTPUT_BUFFER { WORD StructureVersion; WORD StructureLength; DWORD OriginalOplockLevel; DWORD NewOplockLevel; - // DWORD Flags; ACCESS_MASK AccessMode; WORD ShareMode; } REQUEST_OPLOCK_OUTPUT_BUFFER, *PREQUEST_OPLOCK_OUTPUT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REQUEST_OPLOCK_OUTPUT_BUFFER")] - [StructLayout(LayoutKind.Sequential)] - public struct REQUEST_OPLOCK_OUTPUT_BUFFER - { - /// The version of the REQUEST_OPLOCK_OUTPUT_BUFFER structure that is being used. - public ushort StructureVersion; - - /// The length of this structure, in bytes. - public ushort StructureLength; - - /// - /// One or more OPLOCK_LEVEL_CACHE_ XXX values that indicate the level of the oplock that was broken. - /// For possible values, see the RequestedOplockLevel member of the REQUEST_OPLOCK_INPUT_BUFFER structure. - /// - public OPLOCK_LEVEL_CACHE OriginalOplockLevel; - - /// - /// - /// One or more OPLOCK_LEVEL_CACHE_ XXX values that indicate the level to which an oplock is being broken, or an oplock - /// level that may be available for granting, depending on the operation returning this buffer. - /// - /// For possible values, see the RequestedOplockLevel member of the REQUEST_OPLOCK_INPUT_BUFFER structure. - /// - public OPLOCK_LEVEL_CACHE NewOplockLevel; - - /// - /// One or more REQUEST_OPLOCK_OUTPUT_FLAG_ XXX values. - /// - /// - /// Value - /// Meaning - /// - /// - /// REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED - /// - /// Indicates that an acknowledgment is required, and the oplock described in OriginalOplockLevel will continue to remain in - /// force until the break is successfully acknowledged. - /// - /// - /// - /// REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED - /// - /// Indicates that the ShareMode and AccessMode members contain the share and access flags, respectively, of the request causing - /// the oplock break. For more information, see the Remarks section. - /// - /// - /// - /// - public OPLOCK_OUTPUT_FLAG Flags; - - /// - /// If the REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED flag is set and the OPLOCK_LEVEL_CACHE_HANDLE level is being - /// lost in an oplock break, contains the access mode mode of the request that is causing the break. - /// - public ACCESS_MASK AccessMode; - - /// - /// If the REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED flag is set and the OPLOCK_LEVEL_CACHE_HANDLE level is being - /// lost in an oplock break, contains the share mode of the request that is causing the break. - /// - public ushort ShareMode; - } - - /// Contains the output for the FSCTL_GET_RETRIEVAL_POINTER_BASE control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-retrieval_pointer_base typedef struct - // _RETRIEVAL_POINTER_BASE { LARGE_INTEGER FileAreaOffset; } RETRIEVAL_POINTER_BASE, *PRETRIEVAL_POINTER_BASE; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._RETRIEVAL_POINTER_BASE")] - [StructLayout(LayoutKind.Sequential)] - public struct RETRIEVAL_POINTER_BASE - { - /// - /// The volume-relative sector offset to the first allocatable unit on the file system, also referred to as the base of the - /// cluster heap. - /// - public long FileAreaOffset; - } - - /// Contains the output for the FSCTL_GET_RETRIEVAL_POINTERS control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-retrieval_pointers_buffer typedef struct - // RETRIEVAL_POINTERS_BUFFER { DWORD ExtentCount; LARGE_INTEGER StartingVcn; struct { LARGE_INTEGER NextVcn; LARGE_INTEGER Lcn; }; - // __unnamed_struct_17d0_54 Extents[1]; } RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.RETRIEVAL_POINTERS_BUFFER")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(ExtentCount))] - [StructLayout(LayoutKind.Sequential)] - public struct RETRIEVAL_POINTERS_BUFFER - { - /// The count of elements in the Extents array. - public uint ExtentCount; - - /// - /// The starting VCN returned by the function call. This is not necessarily the VCN requested by the function call, as the file - /// system driver may round down to the first VCN of the extent in which the requested starting VCN is found. - /// - public long StartingVcn; - - /// + /// A structure that contains the following members. [StructLayout(LayoutKind.Sequential)] - public struct EXTENT + public struct DISKINFO { - /// - public long NextVcn; + /// The number of cylinders on this disk. + public long Cylinders; - /// - public long Lcn; + /// + /// The media type. This member can be one of the values from the STORAGE_MEDIA_TYPE or MEDIA_TYPE enumeration types. + /// + public STORAGE_MEDIA_TYPE MediaType; + + /// The number of tracks per cylinder. + public uint TracksPerCylinder; + + /// The number of sectors per track. + public uint SectorsPerTrack; + + /// The number of bytes per sector. + public uint BytesPerSector; + + /// + /// The number of sides of the disk that can contain data. This member is 1 for one-sided media or 2 for two-sided media. + /// + public uint NumberMediaSides; + + /// + /// The characteristics of the media. This member can be one or more of the following values. + /// DiskInfo.MediaCharacteristics.MEDIA_CURRENTLY_MOUNTED (0x80000000) + /// DiskInfo.MediaCharacteristics.MEDIA_ERASEABLE (0x00000001) + /// DiskInfo.MediaCharacteristics.MEDIA_READ_ONLY (0x00000004) + /// DiskInfo.MediaCharacteristics.MEDIA_READ_WRITE (0x00000008) + /// DiskInfo.MediaCharacteristics.MEDIA_WRITE_ONCE (0x00000002) + /// DiskInfo.MediaCharacteristics.MEDIA_WRITE_PROTECTED (0x00000100) + /// + public MEDIA_CHARACTER MediaCharacteristics; } - /// - /// - /// Array of Extents structures. For the number of members in the array, see ExtentCount. Each member of the array - /// has the following members. - /// - /// NextVcn - /// - /// The VCN at which the next extent begins. This value minus either StartingVcn (for the first Extents array - /// member) or the NextVcn of the previous member of the array (for all other Extents array members) is the - /// length, in clusters, of the current extent. The length is an input to the FSCTL_MOVE_FILE operation. - /// - /// Lcn - /// - /// The LCN at which the current extent begins on the volume. This value is an input to the FSCTL_MOVE_FILE operation. On the - /// NTFS file system, the value (LONGLONG) –1 indicates either a compression unit that is partially allocated, or an unallocated - /// region of a sparse file. - /// - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public EXTENT[] Extents; + /// A structure that contains the following members. + [StructLayout(LayoutKind.Sequential)] + public struct TAPEINFO + { + /// + /// The media type. This member can be one of the values from the STORAGE_MEDIA_TYPE or MEDIA_TYPE enumeration types. + /// + public STORAGE_MEDIA_TYPE MediaType; + + /// + /// The characteristics of the media. This member can be one or more of the following values. + /// TapeInfo.MediaCharacteristics.MEDIA_CURRENTLY_MOUNTED (0x80000000) + /// TapeInfo.MediaCharacteristics.MEDIA_ERASEABLE (0x00000001) + /// TapeInfo.MediaCharacteristics.MEDIA_READ_ONLY (0x00000004) + /// TapeInfo.MediaCharacteristics.MEDIA_READ_WRITE (0x00000008) + /// TapeInfo.MediaCharacteristics.MEDIA_WRITE_ONCE (0x00000002) + /// TapeInfo.MediaCharacteristics.MEDIA_WRITE_PROTECTED (0x00000100) + /// + public MEDIA_CHARACTER MediaCharacteristics; // Bitmask of MEDIA_XXX values. + + /// The current block size, in bytes. + public uint CurrentBlockSize; + + /// + /// The type of bus to which the tape drive is connected. This members can be one of the STORAGE_BUS_TYPE enumeration values. + /// + public STORAGE_BUS_TYPE BusType; + + /// A union that contains the following members. + public BUSSPECIFICDATA BusSpecificData; + + /// A union that contains the following members. + [StructLayout(LayoutKind.Explicit)] + public struct BUSSPECIFICDATA + { + /// + [FieldOffset(0)] + public SCSIINFORMATION ScsiInformation; + + /// + [StructLayout(LayoutKind.Sequential)] + public struct SCSIINFORMATION + { + /// The SCSI-specific medium type. + public byte MediumType; + + /// The SCSI-specific current operating density for read/write operations. + public byte DensityCode; + } + } + } } + } + + /// The DEVICE_POWER_DESCRIPTOR structure describes the power capabilities of a storage device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_power_descriptor typedef struct + // _DEVICE_POWER_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN DeviceAttentionSupported; BOOLEAN + // AsynchronousNotificationSupported; BOOLEAN IdlePowerManagementEnabled; BOOLEAN D3ColdEnabled; BOOLEAN D3ColdSupported; BOOLEAN + // NoVerifyDuringIdlePower; BYTE Reserved[2]; DWORD IdleTimeoutInMS; } DEVICE_POWER_DESCRIPTOR, *PDEVICE_POWER_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_POWER_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_POWER_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// True if device attention is supported. Otherwise, false. + [MarshalAs(UnmanagedType.U1)] + public bool DeviceAttentionSupported; /// - /// Specifies the attributes to be set on a disk device. Passed as the input buffer to the IOCTL_DISK_SET_DISK_ATTRIBUTES control code. + /// True if the device supports asynchronous notifications, delivered via IOCTL_STORAGE_EVENT_NOTIFICATION. Otherwise, false. /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-set_disk_attributes typedef struct _SET_DISK_ATTRIBUTES { - // DWORD Version; BOOLEAN Persist; BYTE Reserved1[3]; DWORDLONG Attributes; DWORDLONG AttributesMask; DWORD Reserved2[4]; } - // SET_DISK_ATTRIBUTES, *PSET_DISK_ATTRIBUTES; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._SET_DISK_ATTRIBUTES")] - [StructLayout(LayoutKind.Sequential)] - public struct SET_DISK_ATTRIBUTES - { - /// - /// Set to - /// sizeof(GET_DISK_ATTRIBUTES) - /// . - /// - public uint Version; + [MarshalAs(UnmanagedType.U1)] + public bool AsynchronousNotificationSupported; - /// If TRUE, these settings are persisted across reboots. - [MarshalAs(UnmanagedType.U1)] - public bool Persist; + /// True if the device has been registered for runtime idle power management. Otherwise, false. + [MarshalAs(UnmanagedType.U1)] + public bool IdlePowerManagementEnabled; - /// Reserved. Must be set to FALSE (0). - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] Reserved1; + /// True if the device will be powered off when put into D3 power state. Otherwise, false. + [MarshalAs(UnmanagedType.U1)] + public bool D3ColdEnabled; - /// - /// Specifies attributes. - /// - /// - /// Value - /// Meaning - /// - /// - /// DISK_ATTRIBUTE_OFFLINE 0x0000000000000001 - /// The disk is offline. - /// - /// - /// DISK_ATTRIBUTE_READ_ONLY 0x0000000000000002 - /// The disk is read-only. - /// - /// - /// - public DISK_ATTRIBUTE Attributes; + /// True if the platform supports D3ColdEnabled for this device. Otherwise, false. + [MarshalAs(UnmanagedType.U1)] + public bool D3ColdSupported; - /// - /// Indicates which attributes are being changed. - /// - /// - /// Value - /// Meaning - /// - /// - /// DISK_ATTRIBUTE_OFFLINE 0x0000000000000001 - /// The offline attribute is being changed. - /// - /// - /// DISK_ATTRIBUTE_READ_ONLY 0x0000000000000002 - /// The read-only attribute is being changed. - /// - /// - /// - public DISK_ATTRIBUTE AttributesMask; + /// + [MarshalAs(UnmanagedType.U1)] + public bool NoVerifyDuringIdlePower; - /// Reserved. Must be set to 0. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] Reserved2; - } + /// Reserved. + public ushort Reserved; + + /// The idle timeout value in milliseconds. This member is ignored unless IdlePowerManagementEnabled is true. + public uint IdleTimeoutInMS; + } + + /// + /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY request to retrieve the seek penalty descriptor data for a device. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_seek_penalty_descriptor typedef struct + // _DEVICE_SEEK_PENALTY_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN IncursSeekPenalty; } DEVICE_SEEK_PENALTY_DESCRIPTOR, *PDEVICE_SEEK_PENALTY_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_SEEK_PENALTY_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_SEEK_PENALTY_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// Specifies whether the device incurs a seek penalty. + [MarshalAs(UnmanagedType.U1)] + public bool IncursSeekPenalty; + } + + /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY request to retrieve the trim descriptor data for a device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_trim_descriptor typedef struct + // _DEVICE_TRIM_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN TrimEnabled; } DEVICE_TRIM_DESCRIPTOR, *PDEVICE_TRIM_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_TRIM_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_TRIM_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// Specifies whether trim is enabled for the device. + [MarshalAs(UnmanagedType.U1)] + public bool TrimEnabled; + } + + /// Reserved for system use. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-device_write_aggregation_descriptor typedef struct + // _DEVICE_WRITE_AGGREGATION_DESCRIPTOR { DWORD Version; DWORD Size; BOOLEAN BenefitsFromWriteAggregation; } + // DEVICE_WRITE_AGGREGATION_DESCRIPTOR, *PDEVICE_WRITE_AGGREGATION_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DEVICE_WRITE_AGGREGATION_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct DEVICE_WRITE_AGGREGATION_DESCRIPTOR + { + /// + /// Contains the size, in bytes, of this structure. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the descriptor, in bytes. + public uint Size; + + /// TRUE if the device benefits from write aggregation. + [MarshalAs(UnmanagedType.U1)] + public bool BenefitsFromWriteAggregation; + } + + /// Contains parameters for the FSCTL_DUPLICATE_EXTENTS control code that performs the Block Cloning operation. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-duplicate_extents_data typedef struct + // _DUPLICATE_EXTENTS_DATA { HANDLE FileHandle; LARGE_INTEGER SourceFileOffset; LARGE_INTEGER TargetFileOffset; LARGE_INTEGER + // ByteCount; } DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._DUPLICATE_EXTENTS_DATA")] + [StructLayout(LayoutKind.Sequential)] + public struct DUPLICATE_EXTENTS_DATA + { + /// + /// A handle to the source file from which the byte range is to be copied. To retrieve a file handle, use the CreateFile function. + /// + public HFILE FileHandle; + + /// The offset, in bytes, to the beginning of the range to copy from the source file. + public long SourceFileOffset; + + /// The offset, in bytes, to place the copied byte range in the destination file. + public long TargetFileOffset; + + /// The length, in bytes, of the range to copy. + public long ByteCount; + } + + /// + /// Indicates a range of bytes in a file. This structure is used with the FSCTL_QUERY_ALLOCATED_RANGES control code. On input, the + /// structure indicates the range of the file to search. On output, the operation retrieves an array of + /// FILE_ALLOCATED_RANGE_BUFFER structures to indicate the allocated ranges within the search range. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_allocated_range_buffer typedef struct + // _FILE_ALLOCATED_RANGE_BUFFER { LARGE_INTEGER FileOffset; LARGE_INTEGER Length; } FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_ALLOCATED_RANGE_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_ALLOCATED_RANGE_BUFFER + { + /// The file offset of the start of a range of bytes in a file, in bytes. + public long FileOffset; + + /// The size of the range, in bytes. + public long Length; + } + + /// Used as input to the FSCTL_FILE_LEVEL_TRIM control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_level_trim typedef struct _FILE_LEVEL_TRIM { DWORD + // Key; DWORD NumRanges; FILE_LEVEL_TRIM_RANGE Ranges[1]; } FILE_LEVEL_TRIM, *PFILE_LEVEL_TRIM; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_LEVEL_TRIM")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumRanges))] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_LEVEL_TRIM + { + /// Reserved. Set to zero (0). + public uint Key; /// - /// Contains information used to set a disk partition's type. - /// NoteSET_PARTITION_INFORMATION has been superseded by the structure. + /// Number of FILE_LEVEL_TRIM_RANGE entries in the Ranges member. On return should be compared with the + /// NumRangesProcessed member of the FILE_LEVEL_TRIM_OUTPUT structure. /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-set_partition_information typedef struct - // _SET_PARTITION_INFORMATION { BYTE PartitionType; } SET_PARTITION_INFORMATION, *PSET_PARTITION_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._SET_PARTITION_INFORMATION")] - [StructLayout(LayoutKind.Sequential)] - public struct SET_PARTITION_INFORMATION - { - /// The type of partition. For a list of values, see Disk Partition Types. - public byte PartitionType; - } + public uint NumRanges; - /// Specifies the volume shrink operation to perform. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-shrink_volume_information typedef struct - // _SHRINK_VOLUME_INFORMATION { SHRINK_VOLUME_REQUEST_TYPES ShrinkRequestType; DWORDLONG Flags; LONGLONG NewNumberOfSectors; } - // SHRINK_VOLUME_INFORMATION, *PSHRINK_VOLUME_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._SHRINK_VOLUME_INFORMATION")] - [StructLayout(LayoutKind.Sequential)] - public struct SHRINK_VOLUME_INFORMATION - { - /// - /// Indicates the operation to perform. The valid values are as follows. - /// - /// - /// Value - /// Meaning - /// - /// - /// ShrinkPrepare - /// Volume should perform any steps necessary to prepare for a shrink operation. - /// - /// - /// ShrinkCommit - /// Volume should commit the shrink operation changes. - /// - /// - /// ShrinkAbort - /// Volume should terminate the shrink operation. - /// - /// - /// - public SHRINK_VOLUME_REQUEST_TYPES ShrinkRequestType; + /// Array of ranges that describe the portions of the file that are to be trimmed. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public FILE_LEVEL_TRIM_RANGE[] Ranges; + } - /// This member must be zero. - public ulong Flags; + /// Used as output to the FSCTL_FILE_LEVEL_TRIM control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_level_trim_output typedef struct + // _FILE_LEVEL_TRIM_OUTPUT { DWORD NumRangesProcessed; } FILE_LEVEL_TRIM_OUTPUT, *PFILE_LEVEL_TRIM_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_LEVEL_TRIM_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_LEVEL_TRIM_OUTPUT + { + /// + /// Contains the number of ranges that were successfully processed. This may be less than the value passed in the + /// NumRanges member of the FILE_LEVEL_TRIM structure. If it is then the last ranges in the array were not processed. + /// + public uint NumRangesProcessed; + } - /// - /// The number of sectors that should be in the shrunken volume. Used only when the ShrinkRequestType member is - /// ShrinkPrepare, otherwise this member should be initialized to zero. - /// - public long NewNumberOfSectors; - } + /// Specifies a range of a file that is to be trimmed. + /// + /// Before the trim operation is passed to the underlying storage system the input ranges are reduced to be aligned to page + /// boundaries (4,096 bytes on 32-bit and x64-based editions of Windows, 8,192 bytes on Itanium-Based editions of Windows). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_level_trim_range typedef struct + // _FILE_LEVEL_TRIM_RANGE { DWORDLONG Offset; DWORDLONG Length; } FILE_LEVEL_TRIM_RANGE, *PFILE_LEVEL_TRIM_RANGE; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_LEVEL_TRIM_RANGE")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_LEVEL_TRIM_RANGE + { + /// Offset, in bytes, from the start of the file for the range to be trimmed. + public ulong Offset; - /// Contains the starting LCN to the FSCTL_GET_VOLUME_BITMAP control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-starting_lcn_input_buffer typedef struct { LARGE_INTEGER - // StartingLcn; } STARTING_LCN_INPUT_BUFFER, *PSTARTING_LCN_INPUT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_4")] - [StructLayout(LayoutKind.Sequential)] - public struct STARTING_LCN_INPUT_BUFFER - { - /// - /// The LCN from which the operation should start when describing a bitmap. This member will be rounded down to a - /// file-system-dependent rounding boundary, and that value will be returned. Its value should be an integral multiple of eight. - /// - public long StartingLcn; - } + /// Length, in bytes, for the range to be trimmed. + public ulong Length; + } - /// Contains the starting VCN to the FSCTL_GET_RETRIEVAL_POINTERS control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-starting_vcn_input_buffer typedef struct { LARGE_INTEGER - // StartingVcn; } STARTING_VCN_INPUT_BUFFER, *PSTARTING_VCN_INPUT_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_7")] - [StructLayout(LayoutKind.Sequential)] - public struct STARTING_VCN_INPUT_BUFFER - { - /// - /// The VCN at which the operation will begin enumerating extents in the file. This value may be rounded down to the first VCN - /// of the extent in which the specified extent is found. - /// - public long StartingVcn; - } + /// + /// Specifies the disc to close the current session for. This control code is used for UDF file systems. This structure is used for + /// input when calling FSCTL_MAKE_MEDIA_COMPATIBLE. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_make_compatible_buffer typedef struct + // _FILE_MAKE_COMPATIBLE_BUFFER { BOOLEAN CloseDisc; } FILE_MAKE_COMPATIBLE_BUFFER, *PFILE_MAKE_COMPATIBLE_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_MAKE_COMPATIBLE_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_MAKE_COMPATIBLE_BUFFER + { + /// If TRUE, indicates the media should be finalized. No new data can be appended to the media. + [MarshalAs(UnmanagedType.U1)] + public bool CloseDisc; + } + + /// Contains an object identifier and user-defined metadata associated with the object identifier. + /// + /// Object identifiers are used to track files and directories. They are invisible to most applications and should never be modified + /// by applications. Modifying an object identifier can result in the loss of data from portions of a file, up to and including + /// entire volumes of data. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_objectid_buffer typedef struct _FILE_OBJECTID_BUFFER + // { BYTE ObjectId[16]; union { struct { BYTE BirthVolumeId[16]; BYTE BirthObjectId[16]; BYTE DomainId[16]; } DUMMYSTRUCTNAME; BYTE + // ExtendedInfo[48]; } DUMMYUNIONNAME; } FILE_OBJECTID_BUFFER, *PFILE_OBJECTID_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_OBJECTID_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_OBJECTID_BUFFER + { + /// The identifier that uniquely identifies the file or directory within the volume on which it resides. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] ObjectId; /// - /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the storage access alignment descriptor data - /// for a device. + /// User-defined extended data to be set with FSCTL_SET_OBJECT_ID_EXTENDED. Use this data as an alternative to the + /// BirthVolumeId, BirthObjectId, and DomainId members. /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_access_alignment_descriptor typedef struct - // _STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR { DWORD Version; DWORD Size; DWORD BytesPerCacheLine; DWORD BytesOffsetForCacheAlignment; - // DWORD BytesPerLogicalSector; DWORD BytesPerPhysicalSector; DWORD BytesOffsetForSectorAlignment; } - // STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR, *PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// The number of bytes in a cache line of the device. - public uint BytesPerCacheLine; - - /// The address offset necessary for proper cache access alignment, in bytes. - public uint BytesOffsetForCacheAlignment; - - /// The number of bytes in a logical sector of the device. - public uint BytesPerLogicalSector; - - /// The number of bytes in a physical sector of the device. - public uint BytesPerPhysicalSector; - - /// - /// The logical sector offset within the first physical sector where the first logical sector is placed, in bytes. - /// Example: Offset = 3 Logical sectors - /// - ///+---------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - ///|LBA |##|##|##|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17| - ///+---------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - ///|Physical | | | ... - ///|Sector | 0 | 1 | 2 - ///+---------+-----------------------+-----------------------+--------------- - /// - /// In this example, BytesOffsetForSectorAlignment = 3 * BytesPerLogicalSector - /// - public uint BytesOffsetForSectorAlignment; - } - - /// Used with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the storage adapter descriptor data for a device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_adapter_descriptor typedef struct - // _STORAGE_ADAPTER_DESCRIPTOR { DWORD Version; DWORD Size; DWORD MaximumTransferLength; DWORD MaximumPhysicalPages; DWORD - // AlignmentMask; BOOLEAN AdapterUsesPio; BOOLEAN AdapterScansDown; BOOLEAN CommandQueueing; BOOLEAN AcceleratedTransfer; #if ... - // BOOLEAN BusType; #else BYTE BusType; #endif WORD BusMajorVersion; WORD BusMinorVersion; BYTE SrbType; BYTE AddressType; } - // STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_ADAPTER_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_ADAPTER_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// Specifies the maximum number of bytes the storage adapter can transfer in a single operation. - public uint MaximumTransferLength; - - /// - /// Specifies the maximum number of discontinuous physical pages the storage adapter can manage in a single transfer (in other - /// words, the extent of its scatter/gather support). - /// - public uint MaximumPhysicalPages; - - /// - /// - /// Specifies the storage adapter's alignment requirements for transfers. The alignment mask indicates alignment restrictions - /// for buffers required by the storage adapter for transfer operations. Valid mask values are also restricted by - /// characteristics of the memory managers on different versions of Windows. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// Buffers must be aligned on BYTE boundaries. - /// - /// - /// 1 - /// Buffers must be aligned on WORD boundaries. - /// - /// - /// 3 - /// Buffers must be aligned on DWORD32 boundaries. - /// - /// - /// 7 - /// Buffers must be aligned on DWORD64 boundaries. - /// - /// - /// - public uint AlignmentMask; - - /// - /// If this member is TRUE, the storage adapter uses programmed I/O (PIO) and requires the use of system-space virtual - /// addresses mapped to physical memory for data buffers. When this member is FALSE, the storage adapter does not use PIO. - /// - [MarshalAs(UnmanagedType.U1)] - public bool AdapterUsesPio; - - /// - /// If this member is TRUE, the storage adapter scans down for BIOS devices, that is, the storage adapter begins scanning - /// with the highest device number rather than the lowest. When this member is FALSE, the storage adapter begins scanning - /// with the lowest device number. This member is reserved for legacy miniport drivers. - /// - [MarshalAs(UnmanagedType.U1)] - public bool AdapterScansDown; - - /// - /// If this member is TRUE, the storage adapter supports SCSI tagged queuing and/or per-logical-unit internal queues, or - /// the non-SCSI equivalent. When this member is FALSE, the storage adapter neither supports SCSI-tagged queuing nor - /// per-logical-unit internal queues. - /// - [MarshalAs(UnmanagedType.U1)] - public bool CommandQueueing; - - /// - /// If this member is TRUE, the storage adapter supports synchronous transfers as a way of speeding up I/O. When this - /// member is FALSE, the storage adapter does not support synchronous transfers as a way of speeding up I/O. - /// - [MarshalAs(UnmanagedType.U1)] - public bool AcceleratedTransfer; - - /// Specifies a value of type STORAGE_BUS_TYPE that indicates the type of the bus to which the device is connected. - public byte BusType; - - /// Specifies the major version number, if any, of the storage adapter. - public ushort BusMajorVersion; - - /// Specifies the minor version number, if any, of the storage adapter. - public ushort BusMinorVersion; - - /// - /// Specifies the SCSI request block (SRB) type used by the HBA. - /// - /// - /// Value - /// Meaning - /// - /// - /// SRB_TYPE_SCSI_REQUEST_BLOCK - /// The HBA uses SCSI request blocks. - /// - /// - /// SRB_TYPE_STORAGE_REQUEST_BLOCK - /// The HBA uses extended SCSI request blocks. - /// - /// - /// This member is valid starting with Windows 8. - /// - public SRB_TYPE SrbType; - - /// - /// Specifies the address type of the HBA. - /// - /// - /// Value - /// Meaning - /// - /// - /// STORAGE_ADDRESS_TYPE_BTL8 - /// The HBA uses 8-bit bus, target, and LUN addressing. - /// - /// - /// This member is valid starting with Windows 8. - /// - public STORAGE_ADDRESS_TYPE AddressType; - } + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] + public byte[] ExtendedInfo; /// - /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the properties of a storage device or adapter. + /// The identifier of the volume on which the object resided when the object identifier was created, or zero if the volume had + /// no object identifier at that time. After copy operations, move operations, or other file operations, this may not be the + /// same as the object identifier of the volume on which the object presently resides. /// - /// The data retrieved by IOCTL_STORAGE_QUERY_PROPERTY is reported in the buffer immediately following this structure. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_descriptor_header typedef struct - // _STORAGE_DESCRIPTOR_HEADER { DWORD Version; DWORD Size; } STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DESCRIPTOR_HEADER")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DESCRIPTOR_HEADER - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; + public byte[] BirthVolumeId { get => ExtendedInfo.Take(16).ToArray(); set => Buffer.BlockCopy(value, 0, ExtendedInfo, 0, 16); } - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; + /// + /// The object identifier of the object at the time it was created. After copy operations, move operations, or other file + /// operations, this may not be the same as the ObjectId member at present. + /// + public byte[] BirthObjectId { get => ExtendedInfo.Skip(16).Take(16).ToArray(); set => Buffer.BlockCopy(value, 0, ExtendedInfo, 16, 16); } + + /// Reserved; must be zero. + public byte[] DomainId { get => ExtendedInfo.Skip(32).Take(16).ToArray(); set => Buffer.BlockCopy(value, 0, ExtendedInfo, 32, 16); } + } + + /// Receives the volume information from a call to FSCTL_QUERY_ON_DISK_VOLUME_INFO. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_query_on_disk_vol_info_buffer typedef struct + // _FILE_QUERY_ON_DISK_VOL_INFO_BUFFER { LARGE_INTEGER DirectoryCount; LARGE_INTEGER FileCount; WORD FsFormatMajVersion; WORD + // FsFormatMinVersion; WCHAR FsFormatName[12]; LARGE_INTEGER FormatTime; LARGE_INTEGER LastUpdateTime; WCHAR CopyrightInfo[34]; + // WCHAR AbstractInfo[34]; WCHAR FormattingImplementationInfo[34]; WCHAR LastModifyingImplementationInfo[34]; } + // FILE_QUERY_ON_DISK_VOL_INFO_BUFFER, *PFILE_QUERY_ON_DISK_VOL_INFO_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_QUERY_ON_DISK_VOL_INFO_BUFFER")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct FILE_QUERY_ON_DISK_VOL_INFO_BUFFER + { + /// + /// The number of directories on the specified disk. This member is -1 if the number is unknown. + /// + /// For UDF file systems with a virtual allocation table, this information is available only if the UDF revision is greater than 1.50. + /// + /// + public long DirectoryCount; + + /// + /// The number of files on the specified disk. Returns -1 if the number is unknown. + /// + /// For UDF file systems with a virtual allocation table, this information is available only if the UDF revision is greater than 1.50. + /// + /// + public long FileCount; + + /// + /// The major version number of the file system. Returns -1 if the number is unknown or not applicable. On UDF 1.02 file + /// systems, 1 is returned. + /// + public ushort FsFormatMajVersion; + + /// + /// The minor version number of the file system. Returns -1 if the number is unknown or not applicable. On UDF 1.02 file + /// systems, 02 is returned. + /// + public ushort FsFormatMinVersion; + + /// Always returns UDF. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)] + public string FsFormatName; + + /// The time the media was formatted. + public long FormatTime; + + /// The time the media was last updated. + public long LastUpdateTime; + + /// Any copyright information associated with the volume. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] + public string CopyrightInfo; + + /// Any abstract information written on the media. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] + public string AbstractInfo; + + /// + /// Implementation-specific information; in some cases, it is the operating system version that the media was formatted by. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] + public string FormattingImplementationInfo; + + /// + /// The last implementation that modified the disk. This information is implementation specific; in some cases, it is the + /// operating system version that the media was last modified by. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] + public string LastModifyingImplementationInfo; + } + + /// Contains defect management properties. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_query_sparing_buffer typedef struct + // _FILE_QUERY_SPARING_BUFFER { DWORD SparingUnitBytes; BOOLEAN SoftwareSparing; DWORD TotalSpareBlocks; DWORD FreeSpareBlocks; } + // FILE_QUERY_SPARING_BUFFER, *PFILE_QUERY_SPARING_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_QUERY_SPARING_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_QUERY_SPARING_BUFFER + { + /// The size of a sparing packet and the underlying error check and correction (ECC) block size of the volume. + public uint SparingUnitBytes; + + /// If TRUE, indicates that sparing behavior is software-based; if FALSE, it is hardware-based. + [MarshalAs(UnmanagedType.U1)] + public bool SoftwareSparing; + + /// The total number of blocks allocated for sparing. + public uint TotalSpareBlocks; + + /// The number of blocks available for sparing. + public uint FreeSpareBlocks; + } + + /// Specifies the defect management state to be set. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_set_defect_mgmt_buffer typedef struct + // _FILE_SET_DEFECT_MGMT_BUFFER { BOOLEAN Disable; } FILE_SET_DEFECT_MGMT_BUFFER, *PFILE_SET_DEFECT_MGMT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_SET_DEFECT_MGMT_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_SET_DEFECT_MGMT_BUFFER + { + /// If TRUE, indicates that defect management is disabled. + [MarshalAs(UnmanagedType.U1)] + public bool Disable; + } + + /// + /// Specifies the sparse state to be set. Windows Server 2003 and Windows XP: This structure is optional. For more + /// information, see FSCTL_SET_SPARSE. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_set_sparse_buffer typedef struct + // _FILE_SET_SPARSE_BUFFER { BOOLEAN SetSparse; } FILE_SET_SPARSE_BUFFER, *PFILE_SET_SPARSE_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_SET_SPARSE_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_SET_SPARSE_BUFFER + { + /// + /// If TRUE, makes the file sparse. + /// If FALSE, makes the file not sparse. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008 and Windows Vista: A value of FALSE for this member is + /// valid only on files that no longer have any sparse regions. For more information, see FSCTL_SET_SPARSE. + /// + /// + /// Windows Server 2003 and Windows XP: A value of FALSE for this member is not supported. Specifying FALSE + /// will cause the FSCTL_SET_SPARSE call to fail. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool SetSparse; + } + + /// Represents an identifier for the storage tier relative to the volume. + /// + /// The storage tier ID for a particular volume has no relationship to the storage tier ID with the same value on a different volume. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_storage_tier typedef struct _FILE_STORAGE_TIER { + // GUID Id; WCHAR Name[FILE_STORAGE_TIER_NAME_LENGTH]; WCHAR Description[FILE_STORAGE_TIER_NAME_LENGTH]; DWORDLONG Flags; DWORDLONG + // ProvisionedCapacity; FILE_STORAGE_TIER_MEDIA_TYPE MediaType; FILE_STORAGE_TIER_CLASS Class; } FILE_STORAGE_TIER, *PFILE_STORAGE_TIER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_STORAGE_TIER")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_STORAGE_TIER + { + /// Tier ID. + public Guid Id; + + /// Name for the tier. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FILE_STORAGE_TIER_NAME_LENGTH)] + public string Name; + + /// Note for the tier. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FILE_STORAGE_TIER_NAME_LENGTH)] + public string Description; + + /// + /// The file storage tier flags. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// FILE_STORAGE_TIER_FLAG_NO_SEEK_PENALTY 0x00020000 + /// Tier does not suffer a seek penalty on IO operations, which indicates that is an SSD (solid state drive). + /// + /// + /// + public FILE_STORAGE_TIER_FLAG Flags; + + /// Provisioned capacity of the tier. + public ulong ProvisionedCapacity; + + /// Media type of the tier. + public FILE_STORAGE_TIER_MEDIA_TYPE MediaType; + + /// + public FILE_STORAGE_TIER_CLASS Class; + } + + /// Describes a single storage tier region. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_storage_tier_region typedef struct + // _FILE_STORAGE_TIER_REGION { GUID TierId; DWORDLONG Offset; DWORDLONG Length; } FILE_STORAGE_TIER_REGION, *PFILE_STORAGE_TIER_REGION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_STORAGE_TIER_REGION")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_STORAGE_TIER_REGION + { + /// Tier ID. + public Guid TierId; + + /// Offset from the beginning of the volume of this region, in bytes. + public ulong Offset; + + /// Length of region in bytes. + public ulong Length; + } + + /// Describes a single storage tier region. + /// Contains file system recognition information retrieved by the FSCTL_QUERY_FILE_SYSTEM_RECOGNITION control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_system_recognition_information typedef struct + // _FILE_SYSTEM_RECOGNITION_INFORMATION { CHAR FileSystem[9]; } FILE_SYSTEM_RECOGNITION_INFORMATION, *PFILE_SYSTEM_RECOGNITION_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_SYSTEM_RECOGNITION_INFORMATION")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct FILE_SYSTEM_RECOGNITION_INFORMATION + { + /// + /// The file system name stored on the disk. This is a null-terminated string of 8 ASCII characters that represents the + /// nonlocalizable human-readable name of the file system the volume is formatted with. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)] + public string FileSystem; + } + + /// Contains a range of a file to set to zeros. This structure is used by the FSCTL_SET_ZERO_DATA control code + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-file_zero_data_information typedef struct + // _FILE_ZERO_DATA_INFORMATION { LARGE_INTEGER FileOffset; LARGE_INTEGER BeyondFinalZero; } FILE_ZERO_DATA_INFORMATION, *PFILE_ZERO_DATA_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FILE_ZERO_DATA_INFORMATION")] + [StructLayout(LayoutKind.Sequential)] + public struct FILE_ZERO_DATA_INFORMATION + { + /// The file offset of the start of the range to set to zeros, in bytes. + public long FileOffset; + + /// The byte offset of the first byte beyond the last zeroed byte. + public long BeyondFinalZero; + } + + /// Contains data for the FSCTL_FIND_FILES_BY_SID control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-find_by_sid_data typedef struct { DWORD Restart; SID Sid; + // } FIND_BY_SID_DATA, *PFIND_BY_SID_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_12")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(SubAuthorityCount))] + [StructLayout(LayoutKind.Sequential)] + public struct FIND_BY_SID_DATA + { + /// + /// Indicates whether to restart the search. This member should be 1 on first call, so the search will start from the root. For + /// subsequent calls, this member should be zero so the search will resume at the point where it stopped. + /// + public uint Restart; + + private byte Revision; + private byte SubAuthorityCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + private readonly byte[] IdentifierAuthority; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + private readonly uint[] SubAuthority; + + /// A SID structure that specifies the desired creator owner. + public byte[] Sid + { + get + { + var value = new byte[8 + SubAuthorityCount * 4]; + value[0] = Revision; + value[1] = SubAuthorityCount; + for (int i = 0; i < 6; i++) + value[i + 2] = IdentifierAuthority[i]; + for (int i = 0; i < SubAuthorityCount; i++) + { + var sa = BitConverter.GetBytes(SubAuthority[i]); + for (int j = 0; j < 4; j++) + value[8 + (i * 4) + j] = sa[j]; + } + return value; + } + set + { + if (value is null || value.Length < 12) throw new ArgumentException(); + Revision = value[0]; + SubAuthorityCount = value[1]; + if (value.Length < 8 + 4 * SubAuthorityCount) throw new ArgumentException(); + for (int i = 0; i < 6; i++) + IdentifierAuthority[i] = value[i + 2]; + for (int i = 0; i < SubAuthorityCount; i++) + SubAuthority[i] = BitConverter.ToUInt32(value, 8 + (i * 4)); + } } + } + + /// Represents a file name. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-find_by_sid_output typedef struct { DWORD + // NextEntryOffset; DWORD FileIndex; DWORD FileNameLength; WCHAR FileName[1]; } FIND_BY_SID_OUTPUT, *PFIND_BY_SID_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_13")] + [VanaraMarshaler(typeof(AnySizeStringMarshaler), nameof(FileNameLength) + ":br")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct FIND_BY_SID_OUTPUT + { + /// + public uint NextEntryOffset; + + /// + public uint FileIndex; + + /// The size of the file name, in bytes. This size does not include the NULL character. + public uint FileNameLength; + + /// A pointer to a null-terminated string that specifies the file name. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] + public string FileName; + } + + /// + /// Contains information used in formatting a contiguous set of disk tracks. It is used by the IOCTL_DISK_FORMAT_TRACKS_EX control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-format_ex_parameters typedef struct _FORMAT_EX_PARAMETERS + // { MEDIA_TYPE MediaType; DWORD StartCylinderNumber; DWORD EndCylinderNumber; DWORD StartHeadNumber; DWORD EndHeadNumber; WORD + // FormatGapLength; WORD SectorsPerTrack; WORD SectorNumber[1]; } FORMAT_EX_PARAMETERS, *PFORMAT_EX_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FORMAT_EX_PARAMETERS")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(SectorsPerTrack))] + [StructLayout(LayoutKind.Sequential)] + public struct FORMAT_EX_PARAMETERS + { + /// The media type. For a list of values, see MEDIA_TYPE. + public MEDIA_TYPE MediaType; + + /// The cylinder number at which to begin the format. + public uint StartCylinderNumber; + + /// The cylinder number at which to end the format. + public uint EndCylinderNumber; + + /// The beginning head location. + public uint StartHeadNumber; + + /// The ending head location. + public uint EndHeadNumber; + + /// The length of the gap between two successive sectors on a track. + public ushort FormatGapLength; + + /// The number of sectors in each track. + public ushort SectorsPerTrack; + + /// An array of values specifying the sector numbers of the sectors to be included in the track to be formatted. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public ushort[] SectorNumber; + } + + /// + /// Contains information used in formatting a contiguous set of disk tracks. It is used by the IOCTL_DISK_FORMAT_TRACKS control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-format_parameters typedef struct _FORMAT_PARAMETERS { + // MEDIA_TYPE MediaType; DWORD StartCylinderNumber; DWORD EndCylinderNumber; DWORD StartHeadNumber; DWORD EndHeadNumber; } + // FORMAT_PARAMETERS, *PFORMAT_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FORMAT_PARAMETERS")] + [StructLayout(LayoutKind.Sequential)] + public struct FORMAT_PARAMETERS + { + /// The media type. For a list of values, see MEDIA_TYPE. + public MEDIA_TYPE MediaType; + + /// The cylinder number at which to begin the format. + public uint StartCylinderNumber; + + /// The cylinder number at which to end the format. + public uint EndCylinderNumber; + + /// The beginning head location. + public uint StartHeadNumber; + + /// The ending head location. + public uint EndHeadNumber; + } + + /// + /// Contains the integrity information for a file or directory. Returned from the FSCTL_GET_INTEGRITY_INFORMATION control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_get_integrity_information_buffer typedef struct + // _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER { WORD ChecksumAlgorithm; WORD Reserved; DWORD Flags; DWORD ChecksumChunkSizeInBytes; + // DWORD ClusterSizeInBytes; } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_GET_INTEGRITY_INFORMATION_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FSCTL_GET_INTEGRITY_INFORMATION_BUFFER + { + /// + /// The checksum algorithm used. + /// + /// + /// Value + /// Meaning + /// + /// + /// CHECKSUM_TYPE_NONE 0x0000 + /// The file or directory is not configured to use integrity. + /// + /// + /// CHECKSUM_TYPE_CRC64 0x0002 + /// The file or directory uses a CRC64 checksum to provide integrity. + /// + /// + /// 3–0xffff + /// Reserved for future use. + /// + /// + /// + public CHECKSUM_TYPE ChecksumAlgorithm; + + /// Reserved for future use. Set to 0. + public ushort Reserved; + + /// + /// Contains one or more flags. + /// + /// + /// Value + /// Meaning + /// + /// + /// FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 + /// If set, the checksum enforcement is disabled. + /// + /// + /// + public FSCTL_INTEGRITY_FLAG Flags; + + /// Size in bytes of the chunks used to calculate checksums. + public uint ChecksumChunkSizeInBytes; + + /// + /// Size in bytes of a cluster for this volume. This value must be a power of 2, must be greater than or equal to the sector + /// size of the underlying hardware and must be a power of 2 multiple of the sector size. + /// + public uint ClusterSizeInBytes; + } + + /// Contains the storage tier regions from the storage stack for a particular volume. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_query_region_info_input typedef struct + // _FSCTL_QUERY_REGION_INFO_INPUT { DWORD Version; DWORD Size; DWORD Flags; DWORD NumberOfTierIds; GUID TierIds[ANYSIZE_ARRAY]; } + // FSCTL_QUERY_REGION_INFO_INPUT, *PFSCTL_QUERY_REGION_INFO_INPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_QUERY_REGION_INFO_INPUT")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfTierIds))] + [StructLayout(LayoutKind.Sequential)] + public struct FSCTL_QUERY_REGION_INFO_INPUT + { + /// The size of this structure serves as the version. Set it to sizeof( FSCTL_QUERY_REGION_INFO_INPUT). + public uint Version; + + /// The size of this structure in bytes. + public uint Size; /// Reserved for future use. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_attributes_descriptor typedef struct - // _STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR { DWORD Version; DWORD Size; DWORD64 Attributes; } STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR, *PSTORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR - { - /// Contains the version of the data reported. - public uint Version; + public uint Flags; - /// - /// Indicates the quantity of data reported, in bytes. This is the - /// sizeof(STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR) - /// . - /// - public uint Size; + /// Number of entries in TierIds, 0 to request IDs for the entire volume. + public uint NumberOfTierIds; - /// Reserved for future use. - public ulong Attributes; - } + /// Array of storage tiers (represented by GUID values) for which to return information. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public Guid[] TierIds; + } + + /// Contains information for one or more regions. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_query_region_info_output typedef struct + // _FSCTL_QUERY_REGION_INFO_OUTPUT { DWORD Version; DWORD Size; DWORD Flags; DWORD Reserved; DWORDLONG Alignment; DWORD + // TotalNumberOfRegions; DWORD NumberOfRegionsReturned; FILE_STORAGE_TIER_REGION Regions[ANYSIZE_ARRAY]; } + // FSCTL_QUERY_REGION_INFO_OUTPUT, *PFSCTL_QUERY_REGION_INFO_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_QUERY_REGION_INFO_OUTPUT")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfRegionsReturned))] + [StructLayout(LayoutKind.Sequential)] + public struct FSCTL_QUERY_REGION_INFO_OUTPUT + { + /// The size of this structure serves as the version. Set it to sizeof( FSCTL_QUERY_REGION_INFO_OUTPUT). + public uint Version; + + /// The size of this structure in bytes. + public uint Size; + + /// Reserved for future use. + public uint Flags; + + /// Reserved for future use. + public uint Reserved; /// - /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the storage device descriptor data for a device. + /// Offset from the beginning of the volume to the first slab of the tiered volume. If the logical disk is made up of multiple + /// tiers and each tier maps to a set of regions then the first tier for the volume contained on the logical disk has a certain + /// offset within the tier that represents the offset of the volume on the logical disk. The Alignment member contains + /// this value. /// - /// - /// An application can determine the required buffer size by issuing a IOCTL_STORAGE_QUERY_PROPERTY control code passing a - /// STORAGE_DESCRIPTOR_HEADER structure for the output buffer, and then using the returned Size member of the - /// STORAGE_DESCRIPTOR_HEADER structure to allocate a buffer of the proper size. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_descriptor typedef struct - // _STORAGE_DEVICE_DESCRIPTOR { DWORD Version; DWORD Size; BYTE DeviceType; BYTE DeviceTypeModifier; BOOLEAN RemovableMedia; BOOLEAN - // CommandQueueing; DWORD VendorIdOffset; DWORD ProductIdOffset; DWORD ProductRevisionOffset; DWORD SerialNumberOffset; - // STORAGE_BUS_TYPE BusType; DWORD RawPropertiesLength; BYTE RawDeviceProperties[1]; } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_DESCRIPTOR")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(RawPropertiesLength))] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; + public ulong Alignment; - /// - /// Specifies the total size of the descriptor, in bytes, which may include vendor ID, product ID, product revision, device - /// serial number strings and bus-specific data which are appended to the structure. - /// - public uint Size; + /// Total number of available regions. + public uint TotalNumberOfRegions; - /// Specifies the device type as defined by the Small Computer Systems Interface (SCSI) specification. - public byte DeviceType; + /// Number of regions that fit in the output. + public uint NumberOfRegionsReturned; - /// - /// Specifies the device type modifier, if any, as defined by the SCSI specification. If no device type modifier exists, this - /// member is zero. - /// - public byte DeviceTypeModifier; + /// FILE_STORAGE_TIER_REGION struct that contains detailed information for each region. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public FILE_STORAGE_TIER_REGION[] Regions; + } - /// - /// Indicates when TRUE that the device's media (if any) is removable. If the device has no media, this member should be - /// ignored. When FALSE the device's media is not removable. - /// - [MarshalAs(UnmanagedType.U1)] - public bool RemovableMedia; + /// Contains information for all tiers of a specific volume. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_query_storage_classes_output typedef struct + // _FSCTL_QUERY_STORAGE_CLASSES_OUTPUT { DWORD Version; DWORD Size; DWORD Flags; DWORD TotalNumberOfTiers; DWORD + // NumberOfTiersReturned; FILE_STORAGE_TIER Tiers[ANYSIZE_ARRAY]; } FSCTL_QUERY_STORAGE_CLASSES_OUTPUT, *PFSCTL_QUERY_STORAGE_CLASSES_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_QUERY_STORAGE_CLASSES_OUTPUT")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfTiersReturned))] + [StructLayout(LayoutKind.Sequential)] + public struct FSCTL_QUERY_STORAGE_CLASSES_OUTPUT + { + /// The size of this structure serves as the version. Set it to sizeof( FSCTL_QUERY_STORAGE_CLASSES_OUTPUT). + public uint Version; - /// - /// Indicates when TRUE that the device supports multiple outstanding commands (SCSI tagged queuing or equivalent). When - /// FALSE, the device does not support SCSI-tagged queuing or the equivalent. - /// - [MarshalAs(UnmanagedType.U1)] - public bool CommandQueueing; - - /// - /// Specifies the byte offset from the beginning of the structure to a null-terminated ASCII string that contains the device's - /// vendor ID. If the device has no vendor ID, this member is zero. - /// - public uint VendorIdOffset; - - /// - /// Specifies the byte offset from the beginning of the structure to a null-terminated ASCII string that contains the device's - /// product ID. If the device has no product ID, this member is zero. - /// - public uint ProductIdOffset; - - /// - /// Specifies the byte offset from the beginning of the structure to a null-terminated ASCII string that contains the device's - /// product revision string. If the device has no product revision string, this member is zero. - /// - public uint ProductRevisionOffset; - - /// - /// Specifies the byte offset from the beginning of the structure to a null-terminated ASCII string that contains the device's - /// serial number. If the device has no serial number, this member is zero. - /// - public uint SerialNumberOffset; - - /// - /// Specifies an enumerator value of type STORAGE_BUS_TYPE that indicates the type of bus to which the device is connected. This - /// should be used to interpret the raw device properties at the end of this structure (if any). - /// - public STORAGE_BUS_TYPE BusType; - - /// Indicates the number of bytes of bus-specific data that have been appended to this descriptor. - public uint RawPropertiesLength; - - /// - /// Contains an array of length one that serves as a place holder for the first byte of the bus specific property data. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] RawDeviceProperties; - } + /// Size of this structure plus all the variable sized fields. + public uint Size; /// - /// Used with the IOCTL_STORAGE_QUERY_PROPERTY control code request to retrieve the device ID descriptor data for a device. + /// The element status. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// FILE_STORAGE_TIER_FLAG_NO_SEEK_PENALTY 0x00020000 + /// Tier does not suffer a seek penalty on IO operations, which indicates that is an SSD (solid state drive). + /// + /// /// - /// - /// The device ID descriptor consists of an array of device IDs taken from the SCSI-3 vital product data (VPD) page 0x83 that was - /// retrieved during discovery. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_id_descriptor typedef struct - // _STORAGE_DEVICE_ID_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NumberOfIdentifiers; BYTE Identifiers[1]; } - // STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_ID_DESCRIPTOR")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfIdentifiers))] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_ID_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; + public FILE_STORAGE_TIER_FLAG Flags; - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; + /// Total number of available tiers for this disk. + public uint TotalNumberOfTiers; - /// Contains the number of identifiers reported by the device in the Identifiers array. - public uint NumberOfIdentifiers; + /// Number of tiers that fit in the output. + public uint NumberOfTiersReturned; - /// Contains a variable-length array of identification descriptors. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] Identifiers; - } + /// FILE_STORAGE_TIER structure that contains detailed info on the storage tiers. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public FILE_STORAGE_TIER[] Tiers; + } - /// The output buffer for the StorageDeviceIoCapabilityProperty as defined in STORAGE_PROPERTY_ID. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_io_capability_descriptor typedef struct - // _STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR { DWORD Version; DWORD Size; DWORD LunMaxIoCount; DWORD AdapterMaxIoCount; } - // STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR, *PSTORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR - { - /// The version of this structure. The Size serves as the version. - public uint Version; + /// Input buffer passed with the FSCTL_SET_INTEGRITY_INFORMATION control code. + /// + /// If FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF is specified and the file is opened with sharing permissions such that + /// subsequent opens can succeed, it's possible for corrupt data to be read by an application that did not specify FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-fsctl_set_integrity_information_buffer typedef struct + // _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { WORD ChecksumAlgorithm; WORD Reserved; DWORD Flags; } + // FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._FSCTL_SET_INTEGRITY_INFORMATION_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct FSCTL_SET_INTEGRITY_INFORMATION_BUFFER + { + /// + /// Specifies the checksum algorithm. + /// + /// + /// Value + /// Meaning + /// + /// + /// CHECKSUM_TYPE_NONE 0x0000 + /// The file or directory is not configured to use integrity. + /// + /// + /// CHECKSUM_TYPE_CRC64 0x0002 + /// The file or directory uses a CRC64 checksum to provide integrity. + /// + /// + /// 3–0xfffe + /// Reserved for future use. Must not be used. + /// + /// + /// CHECKSUM_TYPE_UNCHANGED 0xffff + /// The checksum algorithm is to remain the same. + /// + /// + /// + public CHECKSUM_TYPE ChecksumAlgorithm; - /// The size of this structure. - public uint Size; + /// Must be 0 + public ushort Reserved; - /// The logical unit number (LUN) max outstanding I/O count. - public uint LunMaxIoCount; + /// + /// Contains zero or more flags. + /// + /// + /// Value + /// Meaning + /// + /// + /// FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 + /// + /// If set, the checksum enforcement is disabled and reads will succeed even if the checksums do not match. This flag is valid + /// only if the file has an integrity algorithm set. If there is no algorithm set or the CheckSum member is set to + /// CHECKSUM_TYPE_NONE, then the operation fails with ERROR_INVALID_PARAMETER. + /// + /// + /// + /// + public FSCTL_INTEGRITY_FLAG Flags; + } - /// The adapter max outstanding I/O count. - public uint AdapterMaxIoCount; - } + /// Represents the parameters of a changer. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_changer_parameters typedef struct + // _GET_CHANGER_PARAMETERS { DWORD Size; WORD NumberTransportElements; WORD NumberStorageElements; WORD NumberCleanerSlots; WORD + // NumberIEElements; WORD NumberDataTransferElements; WORD NumberOfDoors; WORD FirstSlotNumber; WORD FirstDriveNumber; WORD + // FirstTransportNumber; WORD FirstIEPortNumber; WORD FirstCleanerSlotAddress; WORD MagazineSize; DWORD DriveCleanTimeout; DWORD + // Features0; DWORD Features1; BYTE MoveFromTransport; BYTE MoveFromSlot; BYTE MoveFromIePort; BYTE MoveFromDrive; BYTE + // ExchangeFromTransport; BYTE ExchangeFromSlot; BYTE ExchangeFromIePort; BYTE ExchangeFromDrive; BYTE LockUnlockCapabilities; BYTE + // PositionCapabilities; BYTE Reserved1[2]; DWORD Reserved2[2]; } GET_CHANGER_PARAMETERS, *PGET_CHANGER_PARAMETERS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_CHANGER_PARAMETERS")] + [StructLayout(LayoutKind.Sequential)] + public struct GET_CHANGER_PARAMETERS + { + /// + /// The size of this structure, in bytes. The caller must set this member to + /// sizeof(GET_CHANGER_PARAMETERS) + /// . + /// + public uint Size; - /// Contains information about a device. This structure is used by the IOCTL_STORAGE_GET_DEVICE_NUMBER control code. - /// - /// The values in the STORAGE_DEVICE_NUMBER structure are guaranteed to remain unchanged until the device is removed or the - /// system is restarted. They are not guaranteed to be persistent across device or system restarts. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_number typedef struct - // _STORAGE_DEVICE_NUMBER { DEVICE_TYPE DeviceType; DWORD DeviceNumber; DWORD PartitionNumber; } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_NUMBER")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_NUMBER - { - /// - /// - /// The type of device. Values from 0 through 32,767 are reserved for use by Microsoft. Values from 32,768 through 65,535 are - /// reserved for use by other vendors. The following values are defined by Microsoft: - /// - /// FILE_DEVICE_8042_PORT - /// FILE_DEVICE_ACPI - /// FILE_DEVICE_BATTERY - /// FILE_DEVICE_BEEP - /// FILE_DEVICE_BLUETOOTH - /// FILE_DEVICE_BUS_EXTENDER - /// FILE_DEVICE_CD_ROM - /// FILE_DEVICE_CD_ROM_FILE_SYSTEM - /// FILE_DEVICE_CHANGER - /// FILE_DEVICE_CONTROLLER - /// FILE_DEVICE_CRYPT_PROVIDER - /// FILE_DEVICE_DATALINK - /// FILE_DEVICE_DFS - /// FILE_DEVICE_DFS_FILE_SYSTEM - /// FILE_DEVICE_DFS_VOLUME - /// FILE_DEVICE_DISK - /// FILE_DEVICE_DISK_FILE_SYSTEM - /// FILE_DEVICE_DVD - /// FILE_DEVICE_FILE_SYSTEM - /// FILE_DEVICE_FIPS - /// FILE_DEVICE_FULLSCREEN_VIDEO - /// FILE_DEVICE_INFINIBAND - /// FILE_DEVICE_INPORT_PORT - /// FILE_DEVICE_KEYBOARD - /// FILE_DEVICE_KS - /// FILE_DEVICE_KSEC - /// FILE_DEVICE_MAILSLOT - /// FILE_DEVICE_MASS_STORAGE - /// FILE_DEVICE_MIDI_IN - /// FILE_DEVICE_MIDI_OUT - /// FILE_DEVICE_MODEM - /// FILE_DEVICE_MOUSE - /// FILE_DEVICE_MULTI_UNC_PROVIDER - /// FILE_DEVICE_NAMED_PIPE - /// FILE_DEVICE_NETWORK - /// FILE_DEVICE_NETWORK_BROWSER - /// FILE_DEVICE_NETWORK_FILE_SYSTEM - /// FILE_DEVICE_NETWORK_REDIRECTOR - /// FILE_DEVICE_NULL - /// FILE_DEVICE_PARALLEL_PORT - /// FILE_DEVICE_PHYSICAL_NETCARD - /// FILE_DEVICE_PRINTER - /// FILE_DEVICE_SCANNER - /// FILE_DEVICE_SCREEN - /// FILE_DEVICE_SERENUM - /// FILE_DEVICE_SERIAL_MOUSE_PORT - /// FILE_DEVICE_SERIAL_PORT - /// FILE_DEVICE_SMARTCARD - /// FILE_DEVICE_SMB - /// FILE_DEVICE_SOUND - /// FILE_DEVICE_STREAMS - /// FILE_DEVICE_TAPE - /// FILE_DEVICE_TAPE_FILE_SYSTEM - /// FILE_DEVICE_TERMSRV - /// FILE_DEVICE_TRANSPORT - /// FILE_DEVICE_UNKNOWN - /// FILE_DEVICE_VDM - /// FILE_DEVICE_VIDEO - /// FILE_DEVICE_VIRTUAL_DISK - /// FILE_DEVICE_VMBUS - /// FILE_DEVICE_WAVE_IN - /// FILE_DEVICE_WAVE_OUT - /// FILE_DEVICE_WPD - /// - public DEVICE_TYPE DeviceType; + /// + /// The number of transport elements in the changer. For a SCSI changer, this is defined in the element address page. This value + /// is almost always 1, because most changers have a single transport element with one or two picker mechanisms. A changer that + /// has two picker mechanisms on its transport must not be represented as having two transports, because pickers are not + /// individually addressable. High-end media libraries can have dual and multiple transport elements for fault tolerance. + /// + public ushort NumberTransportElements; - /// The number of this device. - public uint DeviceNumber; + /// + /// The number of storage elements (slots) in the changer. For a SCSI changer, this is defined in the element address page. This + /// value represents the maximum number of slots available for this changer including those in removable magazines, whether or + /// not the magazines are installed. If NumberCleanerSlots is 1, then NumberStorageElements is 1 less than the + /// maximum number of slots in the changer. + /// + public ushort NumberStorageElements; - /// The partition number of the device, if the device can be partitioned. Otherwise, this member is –1. - public uint PartitionNumber; - } + /// + /// The number of storage elements (slots) for cleaner cartridges in the changer. If NumberCleanerSlots is 1, then + /// FirstCleanerSlotAddress indicates the zero-based address of the slot in which a drive cleaner should be inserted. If + /// the changer does not support drive cleaning by programmatically moving the cleaner cartridge from its slot to a drive, + /// NumberCleanerSlots is 0. NumberCleanerSlots cannot be greater than 1. + /// + public ushort NumberCleanerSlots; - /// This structure is used as an input and output buffer for the IOCTL_STORAGE_DEVICE_POWER_CAP. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_power_cap typedef struct - // _STORAGE_DEVICE_POWER_CAP { DWORD Version; DWORD Size; STORAGE_DEVICE_POWER_CAP_UNITS Units; DWORDLONG MaxPower; } - // STORAGE_DEVICE_POWER_CAP, *PSTORAGE_DEVICE_POWER_CAP; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_POWER_CAP")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_POWER_CAP - { - /// The version of this structure. This should be set to STORAGE_DEVICE_POWER_CAP_VERSION_V1. - public uint Version; + /// + /// The number of import/export elements (insert/eject ports) the changer has for inserting and ejecting media. For a SCSI + /// changer, this is defined in the element address page. An import/export element must not be part of the storage element + /// (slot) space, and it must be possible to transport media between the import/export element and a slot using a MOVE MEDIUM + /// command. If the changer has a door and not a true import/export element, NumberIEElements is 0. + /// + public ushort NumberIEElements; - /// The size of this structure. - public uint Size; + /// + /// The number of data transfer elements (drives) in the changer. For a SCSI changer, this is defined in the element address + /// page. Unlike NumberStorageElements, which indicates the total number of possible slots whether or not the slots are + /// actually present, NumberDataTransferElements indicates the number of drives that are actually present in the changer. + /// + public ushort NumberDataTransferElements; - /// The units of the MaxPower value, of type STORAGE_DEVICE_POWER_CAP_UNITS. - public STORAGE_DEVICE_POWER_CAP_UNITS Units; + /// + /// The number of doors in the changer. A door provides access to all media in the changer at once, unlike an insert/eject port, + /// which provides access to one or more, but not all, media. A changer's door can be a physical front door or a single magazine + /// that contains all media. If a changer supports only an insert/eject port for inserting and ejecting media, + /// NumberOfDoors is 0. + /// + public ushort NumberOfDoors; - /// - /// Contains the value of the actual maximum power consumption level of the device. This may be equal to, less than, or greater - /// than the desired threshold, depending on what the device supports. - /// - public ulong MaxPower; - } + /// + /// The number used by the changer vendor to identify the first storage element (slot) in the changer to the end user, either by + /// marking a magazine or by defining a slot numbering scheme in the changer's operators guide. FirstSlotNumber is + /// typically 0 or 1, but it can be the first address in a consecutive range of slot addresses defined by the vendor. + /// + public ushort FirstSlotNumber; - /// Reserved for system use. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_resiliency_descriptor typedef struct - // _STORAGE_DEVICE_RESILIENCY_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NameOffset; DWORD NumberOfLogicalCopies; DWORD - // NumberOfPhysicalCopies; DWORD PhysicalDiskRedundancy; DWORD NumberOfColumns; DWORD Interleave; } - // STORAGE_DEVICE_RESILIENCY_DESCRIPTOR, *PSTORAGE_DEVICE_RESILIENCY_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_RESILIENCY_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_DEVICE_RESILIENCY_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// Set to - /// sizeof(STORAGE_DEVICE_RESILIENCY_DESCRIPTOR) - /// . - /// - public uint Version; + /// + /// The number used by the changer vendor to identify the first data transfer element (drive) in the changer to the end user. + /// FirstDriveNumber is typically 0 or 1, but it can be the first address in a consecutive range of drive addresses + /// defined by the vendor. + /// + public ushort FirstDriveNumber; - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; + /// + /// The number used by the changer vendor to identify the first (and usually only) transport element in the changer to the end + /// user. FirstTransportNumber is typically 0 or 1, but it can be the first address in a consecutive range of transport + /// addresses defined by the vendor. + /// + public ushort FirstTransportNumber; - /// - /// Byte offset to the null-terminated ASCII string containing the resiliency properties Name. For devices with no Name - /// property, this will be zero. - /// - public uint NameOffset; + /// + /// The number used by the changer vendor to identify the first (and usually only) insert/eject port in the changer to the end + /// user. FirstIEPortNumber is typically 0 or 1, but it can be the first address in a consecutive range of insert/eject + /// port addresses defined by the vendor. If NumberIEElements is 0, FirstIEPortNumber must also be 0. + /// + public ushort FirstIEPortNumber; - /// Number of logical copies of data that are available. - public uint NumberOfLogicalCopies; + /// + /// The number used by the changer vendor to identify the first (and only) slot address assigned to a drive cleaner cartridge to + /// the end user. This must be the value defined by the vendor in the changer's operators guide. For example, if a changer has 8 + /// slots numbered 1 through 8 and its operator's guide designates slot 8 as the drive cleaner slot, FirstSlotNumber + /// would be 1 and FirstCleanerSlotAddress would be 8. If the same 8 slots were numbered 0 through 7, + /// FirstSlotNumber would be 0 and FirstCleanerSlotAddress would be 7. If NumberCleanerSlots is 0, + /// FirstCleanerSlotAddress must be 0. + /// + public ushort FirstCleanerSlotAddress; - /// Number of complete copies of data that are stored. - public uint NumberOfPhysicalCopies; + /// + /// The number of slots in the removable magazines in the changer. This member is valid only if CHANGER_CARTRIDGE_MAGAZINE is + /// set in Features0. + /// + public ushort MagazineSize; - /// Number of disks that can fail without leading to data loss. - public uint PhysicalDiskRedundancy; + /// + /// Twice the maximum number of seconds a cleaning is expected to take. The changer's drives should be cleaned by its cleaner + /// cartridge in half the time specified by DriveCleanTimeout. For example, if a drive is typically cleaned in 300 + /// seconds (5 minutes), DriveCleanTimeout should be set to 600. + /// + public uint DriveCleanTimeout; - /// Number of columns in the storage device. - public uint NumberOfColumns; + /// + /// The features supported by the changer. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CHANGER_BAR_CODE_SCANNER_INSTALLED 0x00000001 + /// The changer supports a bar-code reader and the reader is installed. + /// + /// + /// CHANGER_CARTRIDGE_MAGAZINE 0x00000100 + /// The changer uses removable cartridge magazines for some or all storage slots. + /// + /// + /// CHANGER_CLEANER_ACCESS_NOT_VALID 0x00040000 + /// + /// The ELEMENT_STATUS_ACCESS flag in a CHANGER_ELEMENT_STATUS structure for a data transport element is invalid when the + /// transport element contains a cleaning cartridge. + /// + /// + /// + /// CHANGER_CLEANER_SLOT 0x00000040 + /// + /// The changer has a slot designated for a cleaner cartridge. If this flag is set, NumberCleanerSlots must be 1 and + /// FirstCleanerSlotAddress must specify the address of the cleaner slot. + /// + /// + /// + /// CHANGER_CLOSE_IEPORT 0x00000004 + /// The changer has an insert/eject port and can retract the insert/eject port programmatically. + /// + /// + /// CHANGER_DEVICE_REINITIALIZE_CAPABLE 0x08000000 + /// The changer can recalibrate its transport element in response to an explicit command. + /// + /// + /// CHANGER_DRIVE_CLEANING_REQUIRED 0x00010000 + /// + /// The changer's drives require periodic cleaning, which must be initiated by either the user or an application, and the + /// changer can use its transport element to mount a cleaner cartridge in a drive. + /// + /// + /// + /// CHANGER_DRIVE_EMPTY_ON_DOOR_ACCESS 0x20000000 + /// The changer requires all drives to be empty (dismounted) before they can be accessed through its door. + /// + /// + /// CHANGER_EXCHANGE_MEDIA 0x00000020 + /// + /// The changer can exchange media between elements. For a SCSI changer, this flag indicates whether the changer supports the + /// EXCHANGE MEDIUM command. + /// + /// + /// + /// CHANGER_INIT_ELEM_STAT_WITH_RANGE 0x00000002 + /// + /// The changer can initialize elements within a specified range. For a SCSI changer, this flag indicates whether the changer + /// supports the INITIALIZE ELEMENT STATUS WITH RANGE command. + /// + /// + /// + /// CHANGER_KEYPAD_ENABLE_DISABLE 0x10000000 + /// The changer keypad can be enabled and disabled programmatically. + /// + /// + /// CHANGER_LOCK_UNLOCK 0x00000080 + /// + /// The changer's door, insert/eject port, or keypad can be locked or unlocked programmatically. If this flag is set, + /// LockUnlockCapabilities indicates which elements can be locked or unlocked. + /// + /// + /// + /// CHANGER_MEDIUM_FLIP 0x00000200 + /// + /// The changer's transport element supports flipping (rotating) media. For a SCSI changer, this flag reflects the rotate bit in + /// the transport geometry parameters page. + /// + /// + /// + /// CHANGER_OPEN_IEPORT 0x00000008 + /// The changer has an insert/eject port and can extend the insert/eject port programmatically. + /// + /// + /// CHANGER_POSITION_TO_ELEMENT 0x00000400 + /// + /// The changer can position the transport to a particular destination. For a SCSI changer, this flag indicates whether the + /// changer supports the POSITION TO ELEMENT command. If this flag is set, PositionCapabilities indicates the elements to which + /// the transport can be positioned. + /// + /// + /// + /// CHANGER_PREDISMOUNT_EJECT_REQUIRED 0x00020000 + /// + /// The changer requires an explicit command issued through a mass-storage driver (tape, disk, or CDROM, for example) to eject + /// media from a drive before the changer can move the media from a drive to a slot. + /// + /// + /// + /// CHANGER_PREMOUNT_EJECT_REQUIRED 0x00080000 + /// + /// The changer requires an explicit command issued through a mass storage driver to eject a drive mechanism before the changer + /// can move media from a slot to the drive. For example, a changer with CD-ROM drives might require the tray to be presented to + /// the robotic transport so that a piece of media could be loaded onto the tray during a mount operation. + /// + /// + /// + /// CHANGER_REPORT_IEPORT_STATE 0x00000800 + /// + /// The changer can report whether media is present in the insert/eject port. Such a changer must have a sensor in the + /// insert/eject port to detect the presence or absence of media. + /// + /// + /// + /// CHANGER_SERIAL_NUMBER_VALID 0x04000000 + /// + /// The serial number is valid and unique for all changers of this type. Serial numbers are not guaranteed to be unique across + /// vendor and product lines. + /// + /// + /// + /// CHANGER_STATUS_NON_VOLATILE 0x00000010 + /// The changer uses nonvolatile memory for element status information. + /// + /// + /// CHANGER_STORAGE_DRIVE 0x00001000 + /// + /// The changer can use a drive as an independent storage element; that is, it can store media in the drive without reading it. + /// For a SCSI changer, this flag reflects the state of the DT bit in the device capabilities page. + /// + /// + /// + /// CHANGER_STORAGE_IEPORT 0x00002000 + /// + /// The changer can use an insert/eject port as an independent storage element. For a SCSI changer, this flag reflects the state + /// of the I/E bit in the device capabilities page. + /// + /// + /// + /// CHANGER_STORAGE_SLOT 0x00004000 + /// + /// The changer can use a slot as an independent storage element for media. For a SCSI changer, this flag reflects the state of + /// the ST bit in the device capabilities page. Slots are the normal storage location for media, so the changer must support + /// this functionality. + /// + /// + /// + /// CHANGER_STORAGE_TRANSPORT 0x00008000 + /// + /// The changer can use a transport as an independent storage element. For a SCSI changer, this flag reflects the state of the + /// MT bit in the device capabilities page. + /// + /// + /// + /// CHANGER_VOLUME_ASSERT 0x00400000 + /// + /// The changer can verify volume information. For a SCSI changer, this flag indicates whether the changer supports the SEND + /// VOLUME TAG command with a send action code of ASSERT. + /// + /// + /// + /// CHANGER_VOLUME_IDENTIFICATION 0x00100000 + /// + /// The changer supports volume identification. For a SCSI changer, this flag indicates whether the changer supports the SEND + /// VOLUME TAG and REQUEST VOLUME ELEMENT ADDRESS commands. + /// + /// + /// + /// CHANGER_VOLUME_REPLACE 0x00800000 + /// + /// The changer can replace volume information. For a SCSI changer, this flag indicates whether the changer supports the SEND + /// VOLUME TAG command with a send action code of REPLACE. + /// + /// + /// + /// CHANGER_VOLUME_SEARCH 0x00200000 + /// + /// The changer can search for volume information. For a SCSI changer, this flag indicates whether the changer supports the + /// supports the SEND VOLUME TAG command with a send action code of TRANSLATE. + /// + /// + /// + /// CHANGER_VOLUME_UNDEFINE 0x01000000 + /// + /// The changer can clear existing volume information. For a SCSI changer, this flag indicates whether the changer supports the + /// SEND VOLUME TAG command with a send action code of UNDEFINE. + /// + /// + /// + /// + public CHANGER_FEATURES0 Features0; - /// - /// Size of a stripe unit of the storage device, in bytes. This is also referred to as the stripe width or interleave of the - /// storage device. - /// - public uint Interleave; - } + /// + /// Any additional features supported by the changer. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CHANGER_CLEANER_AUTODISMOUNT 0x80000004 + /// The changer will move the cleaning cartridge back to its original slot automatically after cleaning is finished. + /// + /// + /// CHANGER_CLEANER_OPS_NOT_SUPPORTED 0x80000040 + /// The changer does not support automatic cleaning of its elements. + /// + /// + /// CHANGER_IEPORT_USER_CONTROL_CLOSE 0x80000100 + /// The changer requires the user to manually close an open insert/eject port. + /// + /// + /// CHANGER_IEPORT_USER_CONTROL_OPEN 0x80000080 + /// The changer requires the user to manually open a closed insert/eject port. + /// + /// + /// CHANGER_MOVE_EXTENDS_IEPORT 0x80000200 + /// The changer will extend the tray automatically whenever a command is issued to move media to an insert/eject port. + /// + /// + /// CHANGER_MOVE_RETRACTS_IEPORT 0x80000400 + /// The changer will retract the tray automatically whenever a command is issued to move media from an insert/eject port. + /// + /// + /// CHANGER_PREDISMOUNT_ALIGN_TO_DRIVE 0x80000002 + /// + /// The changer requires an explicit command to position the transport element to a drive before it can eject media from the drive. + /// + /// + /// + /// CHANGER_PREDISMOUNT_ALIGN_TO_SLOT 0x80000001 + /// + /// The changer requires an explicit command to position the transport element to a slot before it can eject media from the slot. + /// + /// + /// + /// CHANGER_RTN_MEDIA_TO_ORIGINAL_ADDR 0x80000020 + /// The changer requires media to be returned to its original slot after it has been moved. + /// + /// + /// CHANGER_SLOTS_USE_TRAYS 0x80000010 + /// + /// The changer uses removable trays in its slots, which require the media to be placed in a tray and the tray moved to the + /// desired position. + /// + /// + /// + /// CHANGER_TRUE_EXCHANGE_CAPABLE 0x80000008 + /// + /// The changer can exchange media between a source and a destination in a single operation. This flag is valid only if + /// CHANGER_EXCHANGE_MEDIA is also set in Features0. + /// + /// + /// + /// + public CHANGER_FEATURES1 Features1; - /// Provides information about the hotplug information of a device. - /// + /// /// - /// The value of the Size member also identifies the version of this structure, as members will be added to this structure in - /// the future. If the value of the Size member is + /// Indicates whether the changer supports moving a piece of media from a transport element to another transport element, a + /// storage slot, an insert/eject port, or a drive. For a SCSI changer, this is defined in the device capabilities page. The + /// transport is not typically the source or destination for moving or exchanging media. + /// + /// To determine whether the changer can move media to a given element, use the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CHANGER_TO_DRIVE 0x08 + /// The changer can carry out the operation from the specified element to a drive. + /// + /// + /// CHANGER_TO_IEPORT 0x04 + /// The changer can carry out the operation from the specified element to an insert/eject port. + /// + /// + /// CHANGER_TO_SLOT 0x02 + /// The changer can carry out the operation from the specified element to a storage slot. + /// + /// + /// CHANGER_TO_TRANSPORT 0x01 + /// The changer can carry out the operation from the specified element to a transport. + /// + /// + /// + public CHANGER_MOVE MoveFromTransport; + + /// + /// Indicates whether the changer supports moving medium from a storage slot to a transport element, another storage slot, an + /// insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether the changer + /// supports the move. + /// + public byte MoveFromSlot; + + /// + /// Indicates whether the changer supports moving medium from an insert/eject port to a transport element, a storage slot, + /// another insert/eject port, or a drive. For a SCSI changer, this is defined in the device capabilities page. Use the flags + /// described under MoveFromTransport to determine whether the changer supports the move. + /// + public byte MoveFromIePort; + + /// + /// Indicates whether the changer supports moving medium from a drive to a transport element, a storage slot, an insert/eject + /// port, or another drive. Use the flags described under MoveFromTransport to determine whether the changer supports the move. + /// + public byte MoveFromDrive; + + /// + /// Indicates whether the changer supports exchanging medium between a transport element and another transport element, a + /// storage slot, an insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether + /// the changer supports the exchange. + /// + public byte ExchangeFromTransport; + + /// + /// Indicates whether the changer supports exchanging medium between a storage slot and a transport element, another storage + /// slot, an insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether the + /// changer supports the exchange. + /// + public byte ExchangeFromSlot; + + /// + /// Indicates whether the changer supports exchanging medium between an insert/eject port and a transport element, a storage + /// slot, another insert/eject port, or a drive. Use the flags described under MoveFromTransport to determine whether the + /// changer supports the exchange. + /// + public byte ExchangeFromIePort; + + /// + /// Indicates whether the changer supports exchanging medium between a drive and a transport element, a storage slot, an + /// insert/eject port, or another drive. Use the flags described under MoveFromTransport to determine whether the changer + /// supports the exchange. + /// + public byte ExchangeFromDrive; + + /// + /// + /// The elements of a changer that can be locked or unlocked programmatically. This member is valid only if CHANGER_LOCK_UNLOCK + /// is set in Features0. + /// + /// To determine whether the changer can lock or unlock a particular element, use one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// LOCK_UNLOCK_DOOR 0x02 + /// The changer can lock or unlock its door. + /// + /// + /// LOCK_UNLOCK_IEPORT 0x01 + /// The changer can lock or unlock its insert/eject port. + /// + /// + /// LOCK_UNLOCK_KEYPAD 0x04 + /// The changer can lock or unlock its keypad. + /// + /// + /// + public CHANGER_LOCK LockUnlockCapabilities; + + /// + /// The elements to which a changer can position its transport. Use the flags described under MoveFromTransport to + /// determine whether the changer supports positioning the transport to a particular element. This member is valid only if + /// CHANGER_POSITION_TO_ELEMENT is set in Features0. + /// + public byte PositionCapabilities; + + /// Reserved for future use. + public ushort Reserved1; + + /// Reserved for future use. + public ulong Reserved2; + } + + /// + /// Contains the attributes of a disk device. Returned as the output buffer from the IOCTL_DISK_GET_DISK_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_disk_attributes typedef struct _GET_DISK_ATTRIBUTES { + // DWORD Version; DWORD Reserved1; DWORDLONG Attributes; } GET_DISK_ATTRIBUTES, *PGET_DISK_ATTRIBUTES; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_DISK_ATTRIBUTES")] + [StructLayout(LayoutKind.Sequential)] + public struct GET_DISK_ATTRIBUTES + { + /// + /// Set to + /// sizeof(GET_DISK_ATTRIBUTES) + /// . + /// + public uint Version; + + /// Reserved. + public uint Reserved1; + + /// + /// Contains attributes. + /// + /// + /// Value + /// Meaning + /// + /// + /// DISK_ATTRIBUTE_OFFLINE 0x0000000000000001 + /// The disk is offline. + /// + /// + /// DISK_ATTRIBUTE_READ_ONLY 0x0000000000000002 + /// The disk is read-only. + /// + /// + /// + public DISK_ATTRIBUTE Attributes; + } + + /// Contains disk, volume, or partition length information used by the IOCTL_DISK_GET_LENGTH_INFO control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_length_information typedef struct + // _GET_LENGTH_INFORMATION { LARGE_INTEGER Length; } GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_LENGTH_INFORMATION")] + [StructLayout(LayoutKind.Sequential)] + public struct GET_LENGTH_INFORMATION + { + /// The length of the disk, volume, or partition, in bytes. + public long Length; + } + + /// Contains information about the media types supported by a device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-get_media_types typedef struct _GET_MEDIA_TYPES { DWORD + // DeviceType; DWORD MediaInfoCount; DEVICE_MEDIA_INFO MediaInfo[1]; } GET_MEDIA_TYPES, *PGET_MEDIA_TYPES; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._GET_MEDIA_TYPES")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(MediaInfoCount))] + [StructLayout(LayoutKind.Sequential)] + public struct GET_MEDIA_TYPES + { + /// + /// + /// The type of device. Values from 0 through 32,767 are reserved for use by Microsoft Corporation. Values from 32,768 through + /// 65,535 are reserved for use by other vendors. The following values are defined by Microsoft: + /// + /// FILE_DEVICE_8042_PORT + /// FILE_DEVICE_ACPI + /// FILE_DEVICE_BATTERY + /// FILE_DEVICE_BEEP + /// FILE_DEVICE_BLUETOOTH + /// FILE_DEVICE_BUS_EXTENDER + /// FILE_DEVICE_CD_ROM + /// FILE_DEVICE_CD_ROM_FILE_SYSTEM + /// FILE_DEVICE_CHANGER + /// FILE_DEVICE_CONTROLLER + /// FILE_DEVICE_CRYPT_PROVIDER + /// FILE_DEVICE_DATALINK + /// FILE_DEVICE_DFS + /// FILE_DEVICE_DFS_FILE_SYSTEM + /// FILE_DEVICE_DFS_VOLUME + /// FILE_DEVICE_DISK + /// FILE_DEVICE_DISK_FILE_SYSTEM + /// FILE_DEVICE_DVD + /// FILE_DEVICE_FILE_SYSTEM + /// FILE_DEVICE_FIPS + /// FILE_DEVICE_FULLSCREEN_VIDEO + /// FILE_DEVICE_INFINIBAND + /// FILE_DEVICE_INPORT_PORT + /// FILE_DEVICE_KEYBOARD + /// FILE_DEVICE_KS + /// FILE_DEVICE_KSEC + /// FILE_DEVICE_MAILSLOT + /// FILE_DEVICE_MASS_STORAGE + /// FILE_DEVICE_MIDI_IN + /// FILE_DEVICE_MIDI_OUT + /// FILE_DEVICE_MODEM + /// FILE_DEVICE_MOUSE + /// FILE_DEVICE_MULTI_UNC_PROVIDER + /// FILE_DEVICE_NAMED_PIPE + /// FILE_DEVICE_NETWORK + /// FILE_DEVICE_NETWORK_BROWSER + /// FILE_DEVICE_NETWORK_FILE_SYSTEM + /// FILE_DEVICE_NETWORK_REDIRECTOR + /// FILE_DEVICE_NULL + /// FILE_DEVICE_PARALLEL_PORT + /// FILE_DEVICE_PHYSICAL_NETCARD + /// FILE_DEVICE_PRINTER + /// FILE_DEVICE_SCANNER + /// FILE_DEVICE_SCREEN + /// FILE_DEVICE_SERENUM + /// FILE_DEVICE_SERIAL_MOUSE_PORT + /// FILE_DEVICE_SERIAL_PORT + /// FILE_DEVICE_SMARTCARD + /// FILE_DEVICE_SMB + /// FILE_DEVICE_SOUND + /// FILE_DEVICE_STREAMS + /// FILE_DEVICE_TAPE + /// FILE_DEVICE_TAPE_FILE_SYSTEM + /// FILE_DEVICE_TERMSRV + /// FILE_DEVICE_TRANSPORT + /// FILE_DEVICE_UNKNOWN + /// FILE_DEVICE_VDM + /// FILE_DEVICE_VIDEO + /// FILE_DEVICE_VIRTUAL_DISK + /// FILE_DEVICE_VMBUS + /// FILE_DEVICE_WAVE_IN + /// FILE_DEVICE_WAVE_OUT + /// FILE_DEVICE_WPD + /// + public DEVICE_TYPE DeviceType; + + private readonly ushort Reserved; + + /// The number of elements in the MediaInfo array. + public uint MediaInfoCount; + + /// + /// A pointer to the first DEVICE_MEDIA_INFO structure in the array. There is one structure for each media type supported by the device. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public DEVICE_MEDIA_INFO[] MediaInfo; + } + + /// + /// Returned from the FSCTL_LOOKUP_STREAM_FROM_CLUSTER control code. Zero or more of these structures follow the + /// LOOKUP_STREAM_FROM_CLUSTER_OUTPUT structure in the output buffer returned. + /// + /// + /// The name in the FileName member can be very long and in a format not recognized by a customer with the stream name and + /// attribute type name following the filename. While it's appropriate to log the entire filename for diagnostic purposes, if it is + /// to be presented to an end-user it should be reformatted to be more understandable (for example, remove the attribute type name + /// and if the Flags member has any flag other than LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_DATA set then an + /// appropriate message should be displayed. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-lookup_stream_from_cluster_entry typedef struct + // _LOOKUP_STREAM_FROM_CLUSTER_ENTRY { DWORD OffsetToNext; DWORD Flags; LARGE_INTEGER Reserved; LARGE_INTEGER Cluster; WCHAR + // FileName[1]; } LOOKUP_STREAM_FROM_CLUSTER_ENTRY, *PLOOKUP_STREAM_FROM_CLUSTER_ENTRY; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._LOOKUP_STREAM_FROM_CLUSTER_ENTRY")] + [VanaraMarshaler(typeof(AnySizeStringMarshaler), "*")] + [StructLayout(LayoutKind.Sequential)] + public struct LOOKUP_STREAM_FROM_CLUSTER_ENTRY + { + /// + /// Offset in bytes from the beginning of this structure to the next LOOKUP_STREAM_FROM_CLUSTER_ENTRY structure returned. + /// If there are no more entries, this value is zero. + /// + public uint OffsetToNext; + + /// + /// + /// Flags describing characteristics about this stream. The value will consist of one or more of these values. At least one of + /// the LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_* values that fall within the + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_MASK (0xff000000) will be set; one or more of the other flag values may be set. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_PAGE_FILE 0x00000001 + /// The stream is part of the system pagefile. + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_DENY_DEFRAG_SET 0x00000002 + /// + /// The stream is locked from defragmentation. The HandleInfo member of the MARK_HANDLE_INFO structure for this stream has the + /// MARK_HANDLE_PROTECT_CLUSTERS flag set. + /// + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_FS_SYSTEM_FILE 0x00000004 + /// The stream is part of a file that is internal to the filesystem. + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_TXF_SYSTEM_FILE 0x00000008 + /// The stream is part of a file that is internal to TxF. + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_DATA 0x01000000 + /// The stream is part of a $DATA attribute for the file (data stream). + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_INDEX 0x02000000 + /// The stream is part of the $INDEX_ALLOCATION attribute for the file. + /// + /// + /// LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_SYSTEM 0x03000000 + /// The stream is part of another attribute for the file. + /// + /// + /// + public LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG Flags; + + /// This value is reserved and is currently zero. + public long Reserved; + + /// This is the cluster that this entry refers to. It will be one of the clusters passed in the input structure. + public long Cluster; + + /// + /// A NULL-terminated Unicode string containing the path of the object relative to the root of the volume. This string + /// will refer to the attribute or stream represented by the cluster. This string is not limited by MAX_PATH and may be + /// up to 32,768 characters (65,536 bytes) in length. Not all of the filenames returned can be opened; some are internal to NTFS + /// and always opened exclusively. The string returned includes the full path including filename, stream name, and attribute + /// type name in the form "full\path\to\file\filename.ext:streamname:typename". + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] + public string FileName; + } + + /// Passed as input to the FSCTL_LOOKUP_STREAM_FROM_CLUSTER control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-lookup_stream_from_cluster_input typedef struct + // _LOOKUP_STREAM_FROM_CLUSTER_INPUT { DWORD Flags; DWORD NumberOfClusters; LARGE_INTEGER Cluster[1]; } + // LOOKUP_STREAM_FROM_CLUSTER_INPUT, *PLOOKUP_STREAM_FROM_CLUSTER_INPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._LOOKUP_STREAM_FROM_CLUSTER_INPUT")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfClusters))] + [StructLayout(LayoutKind.Sequential)] + public struct LOOKUP_STREAM_FROM_CLUSTER_INPUT + { + /// Flags for the operation. Currently no flags are defined. + public uint Flags; + + /// + /// Number of clusters in the following array of clusters. The input buffer must be large enough to contain this number or the + /// operation will fail. + /// + public uint NumberOfClusters; + + /// An array of one or more clusters to look up. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public long[] Cluster; + } + + /// Received as output from the FSCTL_LOOKUP_STREAM_FROM_CLUSTER control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-lookup_stream_from_cluster_output typedef struct + // _LOOKUP_STREAM_FROM_CLUSTER_OUTPUT { DWORD Offset; DWORD NumberOfMatches; DWORD BufferSizeRequired; } + // LOOKUP_STREAM_FROM_CLUSTER_OUTPUT, *PLOOKUP_STREAM_FROM_CLUSTER_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._LOOKUP_STREAM_FROM_CLUSTER_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct LOOKUP_STREAM_FROM_CLUSTER_OUTPUT + { + /// + /// Offset from the beginning of this structure to the first entry returned. If no entries are returned, this value is zero. + /// + public uint Offset; + + /// + /// Number of matches to the input criteria. Note that more matches may be found than entries returned if the buffer provided is + /// not large enough. + /// + public uint NumberOfMatches; + + /// Minimum size of the buffer, in bytes, which would be needed to contain all matching entries to the input criteria. + public uint BufferSizeRequired; + } + + /// + /// Contains information that is used to mark a specified file or directory, and its update sequence number (USN) change journal + /// record with data about changes. It is used by the FSCTL_MARK_HANDLE control code. + /// + /// + /// To retrieve a handle to a volume, call CreateFile with the lpFileName parameter set to a string in the following form: + /// "\.\X:" + /// In the preceding string, X is the letter identifying the drive on which the volume appears. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-mark_handle_info typedef struct { union { DWORD + // UsnSourceInfo; DWORD CopyNumber; } DUMMYUNIONNAME; DWORD UsnSourceInfo; HANDLE VolumeHandle; DWORD HandleInfo; } + // MARK_HANDLE_INFO, *PMARK_HANDLE_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "ns-winioctl-mark_handle_info")] + [StructLayout(LayoutKind.Sequential)] + public struct MARK_HANDLE_INFO + { + /// + /// The type of changes being made. + /// + /// The operation does not modify the file or directory externally from the point of view of the application that created it. + /// + /// + /// When a thread writes a new USN record, the source information flags in the prior record continues to be present only if the + /// thread also sets those flags. Therefore, the source information structure allows applications to filter out USN records that + /// are set only by a known source, such as an antivirus filter. + /// + /// The following values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// USN_SOURCE_DATA_MANAGEMENT 0x00000001 + /// + /// The operation provides information about a change to the file or directory made by the operating system. A typical use is + /// when Remote Storage moves data from external to local storage. Remote Storage is the hierarchical storage management + /// software. Such a move usually at a minimum adds the USN_REASON_DATA_OVERWRITE flag to a USN record. However, the data has + /// not changed from the user point of view. By noting USN_SOURCE_DATA_MANAGEMENT in the SourceInfo member of the USN_RECORD + /// structure that holds the record, you can determine that although a write operation is performed on the item, data has not changed. + /// + /// + /// + /// USN_SOURCE_AUXILIARY_DATA 0x00000002 + /// + /// The operation adds a private data stream to a file or directory. An example might be a virus detector adding checksum + /// information. As the virus detector modifies the item, the system generates USN records. USN_SOURCE_AUXILIARY_DATA indicates + /// that the modifications did not change the application data. + /// + /// + /// + /// USN_SOURCE_REPLICATION_MANAGEMENT 0x00000004 + /// + /// The operation creates or updates the contents of a replicated file. For example, the file replication service sets this flag + /// when it creates or updates a file in a replicated directory. + /// + /// + /// + /// + /// USN_SOURCE_CLIENT_REPLICATION_MANAGEMENT 0x00000008 + /// Replication is being performed on client systems either from the cloud or servers. + /// + /// + /// + public USN_SOURCE UsnSourceInfo { get => (USN_SOURCE)CopyNumber; set => CopyNumber = (uint)value; } + + + /// + public uint CopyNumber; + + /// + /// + /// The volume handle to the volume where the file or directory resides. For more information on obtaining a volume handle, see + /// the Remarks section. + /// + /// This handle is required to check the privileges for this operation. + /// The caller must have the SE_MANAGE_VOLUME_NAME privilege. For more information, see Privileges. + /// + public HFILE VolumeHandle; + + /// + /// + /// The flag that specifies additional information about the file or directory identified by the handle value in the + /// VolumeHandle member. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MARK_HANDLE_PROTECT_CLUSTERS 0x00000001 + /// + /// The file is marked as unable to be defragmented until the handle is closed. Once a handle marked + /// MARK_HANDLE_PROTECT_CLUSTERS is closed, there is no guarantee that the file's clusters won't move. + /// + /// + /// + /// MARK_HANDLE_TXF_SYSTEM_LOG 0x00000004 + /// + /// The file is marked as unable to be defragmented until the handle is closed. Windows Server 2003: This flag is not supported + /// until Windows Server 2003 with SP1. Windows XP: This flag is not supported. + /// + /// + /// + /// MARK_HANDLE_NOT_TXF_SYSTEM_LOG 0x00000008 + /// + /// The file is marked as unable to be defragmented until the handle is closed. Windows Server 2003: This flag is not supported + /// until Windows Server 2003 with SP1. Windows XP: This flag is not supported. + /// + /// + /// + /// MARK_HANDLE_REALTIME 0x00000020 + /// + /// The file is marked for real-time read behavior regardless of the actual file type. Files marked with this flag must be + /// opened for unbuffered I/O. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported. + /// + /// + /// + /// MARK_HANDLE_NOT_REALTIME 0x00000040 + /// + /// The file previously marked for real-time read behavior using the MARK_HANDLE_REALTIME flag can be unmarked using this flag, + /// removing the real-time behavior. Files marked with this flag must be opened for unbuffered I/O. Windows Server 2008, Windows + /// Vista, Windows Server 2003 and Windows XP: This flag is not supported. + /// + /// + /// + /// MARK_HANDLE_READ_COPY 0x00000080 + /// + /// Indicates the copy number specified in the CopyNumber member should be used for reads. Files marked with this flag must be + /// opened for unbuffered I/O. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and + /// Windows XP: This flag is not supported until Windows 8 and Windows Server 2012. + /// + /// + /// + /// MARK_HANDLE_NOT_READ_COPY 0x00000100 + /// + /// The file previously marked for read-copy behavior using the MARK_HANDLE_READ_COPY flag can be unmarked using this flag, + /// removing the read-copy behavior. Files marked with this flag must be opened for unbuffered I/O. Windows Server 2008 R2, + /// Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported until Windows + /// 8 and Windows Server 2012. + /// + /// + /// + /// + /// + /// + /// MARK_HANDLE_DISABLE_FILE_METADATA_OPTIMIZATION 0x00001000 + /// + /// A highly fragmented file in NTFS uses multiple MFT records to describe all of the extents for a file. This list of child MFT + /// records (also known as FRS records) are controlled by a structure known as an attribute list. An attribute list is limited + /// to 128K in size. When the size of an attribute list hits a certain threshold NTFS will trigger a background compaction on + /// the extents so the minimum number of child FRS records will be used. This flag disables this FRS compaction feature for the + /// given file. This flag is not supported until Windows 10. + /// + /// + /// + /// + /// + /// + /// MARK_HANDLE_SKIP_COHERENCY_SYNC_DISALLOW_WRITES 0x00004000 + /// + /// Setting this flag tells the system that writes are not allowed on this file. If an application tries to open the file for + /// write access, the operation is failed with STATUS_ACCESS_DENIED. If a write is seen the operation is failed with + /// STATUS_MARKED_TO_DISALLOW_WRITES This flag is not supported until Windows 10. + /// + /// + /// + /// + public MARK_HANDLE_INFO_FLAG HandleInfo; + } + + /// Contains input data for the FSCTL_MOVE_FILE control code. + /// + /// + /// To retrieve data to fill in this structure, use the DeviceIoControl function with the FSCTL_GET_RETRIEVAL_POINTERS control code. + /// + /// The first cluster of a directory on a FAT file system volume cannot be moved. + /// + /// When possible, move data in blocks aligned relative to each other in 16-kilobyte (KB) increments. This reduces copy-on-write + /// overhead when shadow copies are enabled, because shadow copy space is increased and performance is reduced when the following + /// conditions occur: + /// + /// + /// + /// The move request block size is less than or equal to 16 KB. + /// + /// + /// The move delta is not in increments of 16 KB. + /// + /// + /// + /// The move delta is the number of bytes between the start of the source block and the start of the target block. In other words, a + /// block starting at offset X (on-disk) can be moved to a starting offset Y if the absolute value of X minus Y is an even multiple + /// of 16 KB. So, assuming 4-KB clusters, a move from cluster 3 to cluster 27 will be optimized, but a move from cluster 18 to + /// cluster 24 will not. Note that mod(3,4) = 3 = mod(27,4). Mod 4 is chosen because four clusters at 4 KB each is equivalent to 16 + /// KB. Therefore, a volume formatted to a 16-KB cluster size will result in all move files being optimized. + /// + /// For more information about shadow copies, see Volume Shadow Copy Service. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-move_file_data typedef struct { HANDLE FileHandle; + // LARGE_INTEGER StartingVcn; LARGE_INTEGER StartingLcn; DWORD ClusterCount; } MOVE_FILE_DATA, *PMOVE_FILE_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_10")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MOVE_FILE_DATA + { + /// + /// A handle to the file to be moved. + /// To retrieve a handle to a file, use CreateFile. + /// + /// If the file is encrypted, the handle must have the FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, + /// or FILE_EXECUTE access right. For more information, see File Security and Access Rights. + /// + /// + public HFILE FileHandle; + + /// A VCN (cluster number relative to the beginning of a file) of the first cluster to be moved. + public long StartingVcn; + + /// An LCN (cluster number on a volume) to which the VCN is to be moved. + public long StartingLcn; + + /// The count of clusters to be moved. + public uint ClusterCount; + } + + /// Represents volume data. This structure is passed to the FSCTL_GET_NTFS_VOLUME_DATA control code. + /// + /// Reserved clusters are the free clusters reserved for later use by Windows. + /// + /// The NTFS_VOLUME_DATA_BUFFER structure represents the basic information returned by FSCTL_GET_NTFS_VOLUME_DATA. For + /// extended volume information, pass a buffer that is the combined size of the NTFS_VOLUME_DATA_BUFFER and + /// NTFS_EXTENDED_VOLUME_DATA structures. Upon success, the buffer returned by FSCTL_GET_NTFS_VOLUME_DATA will contain + /// the information associated with both structures. The NTFS_VOLUME_DATA_BUFFER structure will always be filled starting at + /// the beginning of the buffer, with the NTFS_EXTENDED_VOLUME_DATA structure immediately following. The + /// NTFS_EXTENDED_VOLUME_DATA structure is defined as follows: + /// + /// + /// This structure contains the major and minor version information for an NTFS volume. The ByteCount member will return the + /// total bytes of the output buffer used for this structure by the call to FSCTL_GET_NTFS_VOLUME_DATA. This value should be + /// sizeof(NTFS_EXTENDED_VOLUME_DATA) + /// if the buffer passed was large enough to hold it, otherwise the value will be less than + /// sizeof(NTFS_EXTENDED_VOLUME_DATA) + /// . + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_extended_volume_data typedef struct { DWORD + // ByteCount; WORD MajorVersion; WORD MinorVersion; DWORD BytesPerPhysicalSector; WORD LfsMajorVersion; WORD LfsMinorVersion; DWORD + // MaxDeviceTrimExtentCount; DWORD MaxDeviceTrimByteCount; DWORD MaxVolumeTrimExtentCount; DWORD MaxVolumeTrimByteCount; } + // NTFS_EXTENDED_VOLUME_DATA, *PNTFS_EXTENDED_VOLUME_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_2")] + [StructLayout(LayoutKind.Sequential)] + public struct NTFS_EXTENDED_VOLUME_DATA + { + /// + public uint ByteCount; + + /// + public ushort MajorVersion; + + /// + public ushort MinorVersion; + + /// + public uint BytesPerPhysicalSector; + + /// + public ushort LfsMajorVersion; + + /// + public ushort LfsMinorVersion; + + /// + public uint MaxDeviceTrimExtentCount; + + /// + public uint MaxDeviceTrimByteCount; + + /// + public uint MaxVolumeTrimExtentCount; + + /// + public uint MaxVolumeTrimByteCount; + } + + /// Contains data for the FSCTL_GET_NTFS_FILE_RECORD control code. + /// Pass this structure as input to the FSCTL_GET_NTFS_FILE_RECORD control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_file_record_input_buffer typedef struct { + // LARGE_INTEGER FileReferenceNumber; } NTFS_FILE_RECORD_INPUT_BUFFER, *PNTFS_FILE_RECORD_INPUT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_8")] + [StructLayout(LayoutKind.Sequential)] + public struct NTFS_FILE_RECORD_INPUT_BUFFER + { + /// + /// The file identifier of the file record to be retrieved. This is not necessarily the file identifier returned in the + /// FileReferenceNumber member of the NTFS_FILE_RECORD_OUTPUT_BUFFER structure. Refer to the Remarks section of the + /// reference page for FSCTL_GET_NTFS_FILE_RECORD for more information. + /// + public long FileReferenceNumber; + } + + /// Receives output data from the FSCTL_GET_NTFS_FILE_RECORD control code. + /// To retrieve data to fill in this structure, use the DeviceIoControl FSCTL_GET_NTFS_FILE_RECORD control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_file_record_output_buffer typedef struct { + // LARGE_INTEGER FileReferenceNumber; DWORD FileRecordLength; BYTE FileRecordBuffer[1]; } NTFS_FILE_RECORD_OUTPUT_BUFFER, *PNTFS_FILE_RECORD_OUTPUT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_9")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(FileRecordLength))] + [StructLayout(LayoutKind.Sequential)] + public struct NTFS_FILE_RECORD_OUTPUT_BUFFER + { + /// + /// The file identifier of the returned file record. This is not necessarily the file identifier specified in the + /// FileReferenceNumber member of the NTFS_FILE_RECORD_INPUT_BUFFER structure. Refer to the Remarks section of the + /// reference page for FSCTL_GET_NTFS_FILE_RECORD for more information. + /// + public long FileReferenceNumber; + + /// The length of the returned file record, in bytes. + public uint FileRecordLength; + + /// The starting location of the buffer for the returned file record. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] FileRecordBuffer; + } + + /// Represents volume data. This structure is passed to the FSCTL_GET_NTFS_VOLUME_DATA control code. + /// + /// Reserved clusters are the free clusters reserved for later use by Windows. + /// + /// The NTFS_VOLUME_DATA_BUFFER structure represents the basic information returned by FSCTL_GET_NTFS_VOLUME_DATA. For + /// extended volume information, pass a buffer that is the combined size of the NTFS_VOLUME_DATA_BUFFER and + /// NTFS_EXTENDED_VOLUME_DATA structures. Upon success, the buffer returned by FSCTL_GET_NTFS_VOLUME_DATA will contain + /// the information associated with both structures. The NTFS_VOLUME_DATA_BUFFER structure will always be filled starting at + /// the beginning of the buffer, with the NTFS_EXTENDED_VOLUME_DATA structure immediately following. The + /// NTFS_EXTENDED_VOLUME_DATA structure is defined as follows: + /// + /// + /// This structure contains the major and minor version information for an NTFS volume. The ByteCount member will return the + /// total bytes of the output buffer used for this structure by the call to FSCTL_GET_NTFS_VOLUME_DATA. This value should be + /// sizeof(NTFS_EXTENDED_VOLUME_DATA) + /// if the buffer passed was large enough to hold it, otherwise the value will be less than + /// sizeof(NTFS_EXTENDED_VOLUME_DATA) + /// . + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-ntfs_volume_data_buffer typedef struct { LARGE_INTEGER + // VolumeSerialNumber; LARGE_INTEGER NumberSectors; LARGE_INTEGER TotalClusters; LARGE_INTEGER FreeClusters; LARGE_INTEGER + // TotalReserved; DWORD BytesPerSector; DWORD BytesPerCluster; DWORD BytesPerFileRecordSegment; DWORD ClustersPerFileRecordSegment; + // LARGE_INTEGER MftValidDataLength; LARGE_INTEGER MftStartLcn; LARGE_INTEGER Mft2StartLcn; LARGE_INTEGER MftZoneStart; + // LARGE_INTEGER MftZoneEnd; } NTFS_VOLUME_DATA_BUFFER, *PNTFS_VOLUME_DATA_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_1")] + [StructLayout(LayoutKind.Sequential)] + public struct NTFS_VOLUME_DATA_BUFFER + { + /// The serial number of the volume. This is a unique number assigned to the volume media by the operating system. + public long VolumeSerialNumber; + + /// The number of sectors in the specified volume. + public long NumberSectors; + + /// The number of used and free clusters in the specified volume. + public long TotalClusters; + + /// The number of free clusters in the specified volume. + public long FreeClusters; + + /// The number of reserved clusters in the specified volume. + public long TotalReserved; + + /// The number of bytes in a sector on the specified volume. + public uint BytesPerSector; + + /// The number of bytes in a cluster on the specified volume. This value is also known as the cluster factor. + public uint BytesPerCluster; + + /// The number of bytes in a file record segment. + public uint BytesPerFileRecordSegment; + + /// The number of clusters in a file record segment. + public uint ClustersPerFileRecordSegment; + + /// The length of the master file table, in bytes. + public long MftValidDataLength; + + /// The starting logical cluster number of the master file table. + public long MftStartLcn; + + /// The starting logical cluster number of the master file table mirror. + public long Mft2StartLcn; + + /// The starting logical cluster number of the master file table zone. + public long MftZoneStart; + + /// The ending logical cluster number of the master file table zone. + public long MftZoneEnd; + } + + /// Indicates the range of the read operation to perform and the plex from which to read. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-plex_read_data_request typedef struct + // _PLEX_READ_DATA_REQUEST { LARGE_INTEGER ByteOffset; DWORD ByteLength; DWORD PlexNumber; } PLEX_READ_DATA_REQUEST, *PPLEX_READ_DATA_REQUEST; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._PLEX_READ_DATA_REQUEST")] + [StructLayout(LayoutKind.Sequential)] + public struct PLEX_READ_DATA_REQUEST + { + /// + /// The offset of the range to be read. The offset can be the virtual offset to a file or volume. File offsets should be cluster + /// aligned and volume offsets should be sector aligned. + /// + public long ByteOffset; + + /// The length of the range to be read. The maximum value is 64 KB. + public uint ByteLength; + + /// + /// The plex from which to read. A value of zero indicates the primary copy, a value of one indicates the secondary copy, and so on. + /// + public uint PlexNumber; + } + + /// Provides removable media locking data. It is used by the IOCTL_STORAGE_MEDIA_REMOVAL control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-prevent_media_removal typedef struct + // _PREVENT_MEDIA_REMOVAL { BOOLEAN PreventMediaRemoval; } PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._PREVENT_MEDIA_REMOVAL")] + [StructLayout(LayoutKind.Sequential)] + public struct PREVENT_MEDIA_REMOVAL + { + /// If this member is TRUE, the media is to be locked. Otherwise, it is not. + [MarshalAs(UnmanagedType.U1)] + public bool PreventMediaRemoval; + } + + /// Represents the volume tag information. It is used by the IOCTL_CHANGER_QUERY_VOLUME_TAGS control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-read_element_address_info typedef struct + // _READ_ELEMENT_ADDRESS_INFO { DWORD NumberOfElements; CHANGER_ELEMENT_STATUS ElementStatus[1]; } READ_ELEMENT_ADDRESS_INFO, *PREAD_ELEMENT_ADDRESS_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._READ_ELEMENT_ADDRESS_INFO")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfElements))] + [StructLayout(LayoutKind.Sequential)] + public struct READ_ELEMENT_ADDRESS_INFO + { + /// + /// The number of elements matching criteria set forth by the ActionCode member of CHANGER_SEND_VOLUME_TAG_INFORMATION. + /// For information on compatibility with the current device, see the Features0 member of GET_CHANGER_PARAMETERS. + /// + public uint NumberOfElements; + + /// + /// An array of CHANGER_ELEMENT_STATUS structures, one for each element that corresponded with the information passed in with + /// the CHANGER_SEND_VOLUME_TAG_INFORMATION structure. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public CHANGER_ELEMENT_STATUS[] ElementStatus; + } + + /// + /// Contains disk block reassignment data. This is a variable length structure where the last member is an array of block numbers to + /// be reassigned. It is used by the IOCTL_DISK_REASSIGN_BLOCKS control code. + /// + /// + /// + /// The REASSIGN_BLOCKS structure only supports drives where the Logical Block Address (LBA) is a 4-byte value (typically up + /// to 2 TB). + /// + /// + /// For larger drives the REASSIGN_BLOCKS_EX structure that is used with the IOCTL_DISK_REASSIGN_BLOCKS_EX control code supports + /// 8-byte LBAs. + /// + /// + /// For device compatibility, the IOCTL_DISK_REASSIGN_BLOCKS control code and REASSIGN_BLOCKS structure should be used where possible. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-reassign_blocks typedef struct _REASSIGN_BLOCKS { WORD + // Reserved; WORD Count; DWORD BlockNumber[1]; } REASSIGN_BLOCKS, *PREASSIGN_BLOCKS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REASSIGN_BLOCKS")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(Count))] + [StructLayout(LayoutKind.Sequential)] + public struct REASSIGN_BLOCKS + { + /// This member is reserved. Do not use it. Set it to zero. + public ushort Reserved; + + /// + /// The number of blocks to be reassigned. + /// This is the number of elements that are in the BlockNumber member array. + /// + public ushort Count; + + /// An array of Count block numbers, one for each block to be reassigned. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public uint[] BlockNumber; + } + + /// + /// Contains disk block reassignment data. This is a variable length structure where the last member is an array of block numbers to + /// be reassigned. It is used by the IOCTL_DISK_REASSIGN_BLOCKS_EX control code. + /// + /// + /// The REASSIGN_BLOCKS_EX structure supports drives that have an 8-byte Logical Block Address (LBA), which is typically + /// required for storage devices larger than 2 TB. The REASSIGN_BLOCKS structure used with the IOCTL_DISK_REASSIGN_BLOCKS control + /// code supports devices with up to a 4-byte LBA should be used where possible. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-reassign_blocks_ex typedef struct _REASSIGN_BLOCKS_EX { + // WORD Reserved; WORD Count; LARGE_INTEGER BlockNumber[1]; } REASSIGN_BLOCKS_EX, *PREASSIGN_BLOCKS_EX; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REASSIGN_BLOCKS_EX")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(Count))] + [StructLayout(LayoutKind.Sequential)] + public struct REASSIGN_BLOCKS_EX + { + /// This member is reserved. Do not use it. Set it to 0 (zero). + public ushort Reserved; + + /// + /// The number of blocks to be reassigned. + /// This is the number of elements that are in the BlockNumber member array. + /// + public ushort Count; + + /// An array of Count block numbers, one for each block to be reassigned. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public long[] BlockNumber; + } + + /// + /// Input structure for the FSCTL_REPAIR_COPIES control code. It describes a single block of data and indicates which of the copies + /// is to be copied to the specified copies of the data. The + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-repair_copies_input typedef struct _REPAIR_COPIES_INPUT { + // DWORD Size; DWORD Flags; LARGE_INTEGER FileOffset; DWORD Length; DWORD SourceCopy; DWORD NumberOfRepairCopies; DWORD + // RepairCopies[ANYSIZE_ARRAY]; } REPAIR_COPIES_INPUT, *PREPAIR_COPIES_INPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REPAIR_COPIES_INPUT")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfRepairCopies))] + [StructLayout(LayoutKind.Sequential)] + public struct REPAIR_COPIES_INPUT + { + /// + /// Set to + /// sizeof(REPAIR_COPIES_INPUT) + /// . + /// + public uint Size; + + /// Reserved (must be zero) + public uint Flags; + + /// The file position to start the repair operation. + public long FileOffset; + + /// The number of bytes to be repaired. + public uint Length; + + /// The zero-based copy number of the source copy. + public uint SourceCopy; + + /// The number of copies that will be repaired. This is the size of the RepairCopies array. + public uint NumberOfRepairCopies; + + /// The zero-based copy numbers of the copies that will be repaired. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public uint[] RepairCopies; + } + + /// Contains output of a repair copies operation returned from the FSCTL_REPAIR_COPIES control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-repair_copies_output typedef struct _REPAIR_COPIES_OUTPUT + // { DWORD Size; DWORD Status; LARGE_INTEGER ResumeFileOffset; } REPAIR_COPIES_OUTPUT, *PREPAIR_COPIES_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REPAIR_COPIES_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct REPAIR_COPIES_OUTPUT + { + /// + /// Set to + /// sizeof(REPAIR_COPIES_OUTPUT) + /// . + /// + public uint Size; + + /// + /// Indicates the status of the repair operation. The value is a NTSTATUS value. See + /// http://msdn.microsoft.com/en-us/library/cc704588(PROT.10).aspx for a list of NTSTATUS values. + /// + public NTStatus Status; + + /// + /// If the Status member indicates the operation was not successful, this is the file offset to use to resume repair + /// operations, skipping the range where errors were found. + /// + public long ResumeFileOffset; + } + + /// + /// Contains the information to request an opportunistic lock (oplock) or to acknowledge an oplock break with the + /// FSCTL_REQUEST_OPLOCK control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-request_oplock_input_buffer typedef struct + // _REQUEST_OPLOCK_INPUT_BUFFER { WORD StructureVersion; WORD StructureLength; DWORD RequestedOplockLevel; DWORD Flags; } + // REQUEST_OPLOCK_INPUT_BUFFER, *PREQUEST_OPLOCK_INPUT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REQUEST_OPLOCK_INPUT_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct REQUEST_OPLOCK_INPUT_BUFFER + { + /// The version of the REQUEST_OPLOCK_INPUT_BUFFER structure that is being used. Set this member to REQUEST_OPLOCK_CURRENT_VERSION. + public ushort StructureVersion; + + /// + /// The length of this structure, in bytes. Must be set to + /// sizeof(REQUEST_OPLOCK_INPUT_BUFFER) + /// . + /// + public ushort StructureLength; + + /// + /// A valid combination of the following oplock level values. + /// + /// + /// Value + /// Meaning + /// + /// + /// OPLOCK_LEVEL_CACHE_READ + /// Allows clients to cache reads. May be granted to multiple clients. + /// + /// + /// OPLOCK_LEVEL_CACHE_HANDLE + /// Allows clients to cache open handles. May be granted to multiple clients. + /// + /// + /// OPLOCK_LEVEL_CACHE_WRITE + /// Allows clients to cache writes and byte range locks. May be granted only to a single client. + /// + /// + /// Valid combinations of these values are as follows: + /// + /// + /// + /// OPLOCK_LEVEL_CACHE_READ + /// + /// + /// + /// + /// OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE + /// + /// + /// + /// + /// OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_WRITE + /// + /// + /// + /// + /// OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_WRITE | OPLOCK_LEVEL_CACHE_HANDLE + /// + /// + /// + /// For more information about these value combinations, see FSCTL_REQUEST_OPLOCK. + /// + public OPLOCK_LEVEL_CACHE RequestedOplockLevel; + + /// + /// A valid combination of the following request flag values. + /// + /// + /// Value + /// Meaning + /// + /// + /// REQUEST_OPLOCK_INPUT_FLAG_REQUEST + /// + /// Request for a new oplock. Setting this flag together with REQUEST_OPLOCK_INPUT_FLAG_ACK is not valid and will cause the + /// request to fail with ERROR_INVALID_PARAMETER. + /// + /// + /// + /// REQUEST_OPLOCK_INPUT_FLAG_ACK + /// + /// Acknowledgment of an oplock break. Setting this flag together with REQUEST_OPLOCK_ INPUT_FLAG_REQUEST is not valid and will + /// cause the request to fail with ERROR_INVALID_PARAMETER. + /// + /// + /// + /// + public OPLOCK_INPUT_FLAG Flags; + } + + /// Contains the opportunistic lock (oplock) information returned by the FSCTL_REQUEST_OPLOCK control code. + /// + /// The REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED flag indicates that the ShareMode and AccessMode fields + /// contain the share and access flags, respectively, of the request causing the oplock break. This information may be provided on + /// breaks where the OPLOCK_LEVEL_CACHE_HANDLE level is being lost and may be useful to callers who can close handles whose + /// share and access modes conflict with the handle causing the break. This may enable them to maintain at least some handle cache + /// state. Note that not all breaks where the OPLOCK_LEVEL_CACHE_HANDLE level is being lost will have this flag set. The + /// primary case where this flag will be set is if the break is a result of a create operation that needs the + /// OPLOCK_LEVEL_CACHE_HANDLE oplock to be broken to avoid failing with ERROR_SHARING_VIOLATION. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-request_oplock_output_buffer typedef struct + // _REQUEST_OPLOCK_OUTPUT_BUFFER { WORD StructureVersion; WORD StructureLength; DWORD OriginalOplockLevel; DWORD NewOplockLevel; + // DWORD Flags; ACCESS_MASK AccessMode; WORD ShareMode; } REQUEST_OPLOCK_OUTPUT_BUFFER, *PREQUEST_OPLOCK_OUTPUT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._REQUEST_OPLOCK_OUTPUT_BUFFER")] + [StructLayout(LayoutKind.Sequential)] + public struct REQUEST_OPLOCK_OUTPUT_BUFFER + { + /// The version of the REQUEST_OPLOCK_OUTPUT_BUFFER structure that is being used. + public ushort StructureVersion; + + /// The length of this structure, in bytes. + public ushort StructureLength; + + /// + /// One or more OPLOCK_LEVEL_CACHE_ XXX values that indicate the level of the oplock that was broken. + /// For possible values, see the RequestedOplockLevel member of the REQUEST_OPLOCK_INPUT_BUFFER structure. + /// + public OPLOCK_LEVEL_CACHE OriginalOplockLevel; + + /// + /// + /// One or more OPLOCK_LEVEL_CACHE_ XXX values that indicate the level to which an oplock is being broken, or an oplock + /// level that may be available for granting, depending on the operation returning this buffer. + /// + /// For possible values, see the RequestedOplockLevel member of the REQUEST_OPLOCK_INPUT_BUFFER structure. + /// + public OPLOCK_LEVEL_CACHE NewOplockLevel; + + /// + /// One or more REQUEST_OPLOCK_OUTPUT_FLAG_ XXX values. + /// + /// + /// Value + /// Meaning + /// + /// + /// REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED + /// + /// Indicates that an acknowledgment is required, and the oplock described in OriginalOplockLevel will continue to remain in + /// force until the break is successfully acknowledged. + /// + /// + /// + /// REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED + /// + /// Indicates that the ShareMode and AccessMode members contain the share and access flags, respectively, of the request causing + /// the oplock break. For more information, see the Remarks section. + /// + /// + /// + /// + public OPLOCK_OUTPUT_FLAG Flags; + + /// + /// If the REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED flag is set and the OPLOCK_LEVEL_CACHE_HANDLE level is being + /// lost in an oplock break, contains the access mode mode of the request that is causing the break. + /// + public ACCESS_MASK AccessMode; + + /// + /// If the REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED flag is set and the OPLOCK_LEVEL_CACHE_HANDLE level is being + /// lost in an oplock break, contains the share mode of the request that is causing the break. + /// + public ushort ShareMode; + } + + /// Contains the output for the FSCTL_GET_RETRIEVAL_POINTER_BASE control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-retrieval_pointer_base typedef struct + // _RETRIEVAL_POINTER_BASE { LARGE_INTEGER FileAreaOffset; } RETRIEVAL_POINTER_BASE, *PRETRIEVAL_POINTER_BASE; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._RETRIEVAL_POINTER_BASE")] + [StructLayout(LayoutKind.Sequential)] + public struct RETRIEVAL_POINTER_BASE + { + /// + /// The volume-relative sector offset to the first allocatable unit on the file system, also referred to as the base of the + /// cluster heap. + /// + public long FileAreaOffset; + } + + /// Contains the output for the FSCTL_GET_RETRIEVAL_POINTERS control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-retrieval_pointers_buffer typedef struct + // RETRIEVAL_POINTERS_BUFFER { DWORD ExtentCount; LARGE_INTEGER StartingVcn; struct { LARGE_INTEGER NextVcn; LARGE_INTEGER Lcn; }; + // __unnamed_struct_17d0_54 Extents[1]; } RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.RETRIEVAL_POINTERS_BUFFER")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(ExtentCount))] + [StructLayout(LayoutKind.Sequential)] + public struct RETRIEVAL_POINTERS_BUFFER + { + /// The count of elements in the Extents array. + public uint ExtentCount; + + /// + /// The starting VCN returned by the function call. This is not necessarily the VCN requested by the function call, as the file + /// system driver may round down to the first VCN of the extent in which the requested starting VCN is found. + /// + public long StartingVcn; + + /// + [StructLayout(LayoutKind.Sequential)] + public struct EXTENT + { + /// + public long NextVcn; + + /// + public long Lcn; + } + + /// + /// + /// Array of Extents structures. For the number of members in the array, see ExtentCount. Each member of the array + /// has the following members. + /// + /// NextVcn + /// + /// The VCN at which the next extent begins. This value minus either StartingVcn (for the first Extents array + /// member) or the NextVcn of the previous member of the array (for all other Extents array members) is the + /// length, in clusters, of the current extent. The length is an input to the FSCTL_MOVE_FILE operation. + /// + /// Lcn + /// + /// The LCN at which the current extent begins on the volume. This value is an input to the FSCTL_MOVE_FILE operation. On the + /// NTFS file system, the value (LONGLONG) –1 indicates either a compression unit that is partially allocated, or an unallocated + /// region of a sparse file. + /// + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public EXTENT[] Extents; + } + + /// + /// Specifies the attributes to be set on a disk device. Passed as the input buffer to the IOCTL_DISK_SET_DISK_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-set_disk_attributes typedef struct _SET_DISK_ATTRIBUTES { + // DWORD Version; BOOLEAN Persist; BYTE Reserved1[3]; DWORDLONG Attributes; DWORDLONG AttributesMask; DWORD Reserved2[4]; } + // SET_DISK_ATTRIBUTES, *PSET_DISK_ATTRIBUTES; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._SET_DISK_ATTRIBUTES")] + [StructLayout(LayoutKind.Sequential)] + public struct SET_DISK_ATTRIBUTES + { + /// + /// Set to + /// sizeof(GET_DISK_ATTRIBUTES) + /// . + /// + public uint Version; + + /// If TRUE, these settings are persisted across reboots. + [MarshalAs(UnmanagedType.U1)] + public bool Persist; + + /// Reserved. Must be set to FALSE (0). + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] Reserved1; + + /// + /// Specifies attributes. + /// + /// + /// Value + /// Meaning + /// + /// + /// DISK_ATTRIBUTE_OFFLINE 0x0000000000000001 + /// The disk is offline. + /// + /// + /// DISK_ATTRIBUTE_READ_ONLY 0x0000000000000002 + /// The disk is read-only. + /// + /// + /// + public DISK_ATTRIBUTE Attributes; + + /// + /// Indicates which attributes are being changed. + /// + /// + /// Value + /// Meaning + /// + /// + /// DISK_ATTRIBUTE_OFFLINE 0x0000000000000001 + /// The offline attribute is being changed. + /// + /// + /// DISK_ATTRIBUTE_READ_ONLY 0x0000000000000002 + /// The read-only attribute is being changed. + /// + /// + /// + public DISK_ATTRIBUTE AttributesMask; + + /// Reserved. Must be set to 0. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] Reserved2; + } + + /// + /// Contains information used to set a disk partition's type. + /// NoteSET_PARTITION_INFORMATION has been superseded by the structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-set_partition_information typedef struct + // _SET_PARTITION_INFORMATION { BYTE PartitionType; } SET_PARTITION_INFORMATION, *PSET_PARTITION_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._SET_PARTITION_INFORMATION")] + [StructLayout(LayoutKind.Sequential)] + public struct SET_PARTITION_INFORMATION + { + /// The type of partition. For a list of values, see Disk Partition Types. + public byte PartitionType; + } + + /// Specifies the volume shrink operation to perform. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-shrink_volume_information typedef struct + // _SHRINK_VOLUME_INFORMATION { SHRINK_VOLUME_REQUEST_TYPES ShrinkRequestType; DWORDLONG Flags; LONGLONG NewNumberOfSectors; } + // SHRINK_VOLUME_INFORMATION, *PSHRINK_VOLUME_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._SHRINK_VOLUME_INFORMATION")] + [StructLayout(LayoutKind.Sequential)] + public struct SHRINK_VOLUME_INFORMATION + { + /// + /// Indicates the operation to perform. The valid values are as follows. + /// + /// + /// Value + /// Meaning + /// + /// + /// ShrinkPrepare + /// Volume should perform any steps necessary to prepare for a shrink operation. + /// + /// + /// ShrinkCommit + /// Volume should commit the shrink operation changes. + /// + /// + /// ShrinkAbort + /// Volume should terminate the shrink operation. + /// + /// + /// + public SHRINK_VOLUME_REQUEST_TYPES ShrinkRequestType; + + /// This member must be zero. + public ulong Flags; + + /// + /// The number of sectors that should be in the shrunken volume. Used only when the ShrinkRequestType member is + /// ShrinkPrepare, otherwise this member should be initialized to zero. + /// + public long NewNumberOfSectors; + } + + /// Contains the starting LCN to the FSCTL_GET_VOLUME_BITMAP control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-starting_lcn_input_buffer typedef struct { LARGE_INTEGER + // StartingLcn; } STARTING_LCN_INPUT_BUFFER, *PSTARTING_LCN_INPUT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_4")] + [StructLayout(LayoutKind.Sequential)] + public struct STARTING_LCN_INPUT_BUFFER + { + /// + /// The LCN from which the operation should start when describing a bitmap. This member will be rounded down to a + /// file-system-dependent rounding boundary, and that value will be returned. Its value should be an integral multiple of eight. + /// + public long StartingLcn; + } + + /// Contains the starting VCN to the FSCTL_GET_RETRIEVAL_POINTERS control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-starting_vcn_input_buffer typedef struct { LARGE_INTEGER + // StartingVcn; } STARTING_VCN_INPUT_BUFFER, *PSTARTING_VCN_INPUT_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_7")] + [StructLayout(LayoutKind.Sequential)] + public struct STARTING_VCN_INPUT_BUFFER + { + /// + /// The VCN at which the operation will begin enumerating extents in the file. This value may be rounded down to the first VCN + /// of the extent in which the specified extent is found. + /// + public long StartingVcn; + } + + /// + /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the storage access alignment descriptor data + /// for a device. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_access_alignment_descriptor typedef struct + // _STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR { DWORD Version; DWORD Size; DWORD BytesPerCacheLine; DWORD BytesOffsetForCacheAlignment; + // DWORD BytesPerLogicalSector; DWORD BytesPerPhysicalSector; DWORD BytesOffsetForSectorAlignment; } + // STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR, *PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// The number of bytes in a cache line of the device. + public uint BytesPerCacheLine; + + /// The address offset necessary for proper cache access alignment, in bytes. + public uint BytesOffsetForCacheAlignment; + + /// The number of bytes in a logical sector of the device. + public uint BytesPerLogicalSector; + + /// The number of bytes in a physical sector of the device. + public uint BytesPerPhysicalSector; + + /// + /// The logical sector offset within the first physical sector where the first logical sector is placed, in bytes. + /// Example: Offset = 3 Logical sectors + /// + ///+---------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + ///|LBA |##|##|##|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17| + ///+---------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + ///|Physical | | | ... + ///|Sector | 0 | 1 | 2 + ///+---------+-----------------------+-----------------------+--------------- + /// + /// In this example, BytesOffsetForSectorAlignment = 3 * BytesPerLogicalSector + /// + public uint BytesOffsetForSectorAlignment; + } + + /// Used with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the storage adapter descriptor data for a device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_adapter_descriptor typedef struct + // _STORAGE_ADAPTER_DESCRIPTOR { DWORD Version; DWORD Size; DWORD MaximumTransferLength; DWORD MaximumPhysicalPages; DWORD + // AlignmentMask; BOOLEAN AdapterUsesPio; BOOLEAN AdapterScansDown; BOOLEAN CommandQueueing; BOOLEAN AcceleratedTransfer; #if ... + // BOOLEAN BusType; #else BYTE BusType; #endif WORD BusMajorVersion; WORD BusMinorVersion; BYTE SrbType; BYTE AddressType; } + // STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_ADAPTER_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_ADAPTER_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// Specifies the maximum number of bytes the storage adapter can transfer in a single operation. + public uint MaximumTransferLength; + + /// + /// Specifies the maximum number of discontinuous physical pages the storage adapter can manage in a single transfer (in other + /// words, the extent of its scatter/gather support). + /// + public uint MaximumPhysicalPages; + + /// + /// + /// Specifies the storage adapter's alignment requirements for transfers. The alignment mask indicates alignment restrictions + /// for buffers required by the storage adapter for transfer operations. Valid mask values are also restricted by + /// characteristics of the memory managers on different versions of Windows. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// Buffers must be aligned on BYTE boundaries. + /// + /// + /// 1 + /// Buffers must be aligned on WORD boundaries. + /// + /// + /// 3 + /// Buffers must be aligned on DWORD32 boundaries. + /// + /// + /// 7 + /// Buffers must be aligned on DWORD64 boundaries. + /// + /// + /// + public uint AlignmentMask; + + /// + /// If this member is TRUE, the storage adapter uses programmed I/O (PIO) and requires the use of system-space virtual + /// addresses mapped to physical memory for data buffers. When this member is FALSE, the storage adapter does not use PIO. + /// + [MarshalAs(UnmanagedType.U1)] + public bool AdapterUsesPio; + + /// + /// If this member is TRUE, the storage adapter scans down for BIOS devices, that is, the storage adapter begins scanning + /// with the highest device number rather than the lowest. When this member is FALSE, the storage adapter begins scanning + /// with the lowest device number. This member is reserved for legacy miniport drivers. + /// + [MarshalAs(UnmanagedType.U1)] + public bool AdapterScansDown; + + /// + /// If this member is TRUE, the storage adapter supports SCSI tagged queuing and/or per-logical-unit internal queues, or + /// the non-SCSI equivalent. When this member is FALSE, the storage adapter neither supports SCSI-tagged queuing nor + /// per-logical-unit internal queues. + /// + [MarshalAs(UnmanagedType.U1)] + public bool CommandQueueing; + + /// + /// If this member is TRUE, the storage adapter supports synchronous transfers as a way of speeding up I/O. When this + /// member is FALSE, the storage adapter does not support synchronous transfers as a way of speeding up I/O. + /// + [MarshalAs(UnmanagedType.U1)] + public bool AcceleratedTransfer; + + /// Specifies a value of type STORAGE_BUS_TYPE that indicates the type of the bus to which the device is connected. + public byte BusType; + + /// Specifies the major version number, if any, of the storage adapter. + public ushort BusMajorVersion; + + /// Specifies the minor version number, if any, of the storage adapter. + public ushort BusMinorVersion; + + /// + /// Specifies the SCSI request block (SRB) type used by the HBA. + /// + /// + /// Value + /// Meaning + /// + /// + /// SRB_TYPE_SCSI_REQUEST_BLOCK + /// The HBA uses SCSI request blocks. + /// + /// + /// SRB_TYPE_STORAGE_REQUEST_BLOCK + /// The HBA uses extended SCSI request blocks. + /// + /// + /// This member is valid starting with Windows 8. + /// + public SRB_TYPE SrbType; + + /// + /// Specifies the address type of the HBA. + /// + /// + /// Value + /// Meaning + /// + /// + /// STORAGE_ADDRESS_TYPE_BTL8 + /// The HBA uses 8-bit bus, target, and LUN addressing. + /// + /// + /// This member is valid starting with Windows 8. + /// + public STORAGE_ADDRESS_TYPE AddressType; + } + + /// + /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the properties of a storage device or adapter. + /// + /// The data retrieved by IOCTL_STORAGE_QUERY_PROPERTY is reported in the buffer immediately following this structure. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_descriptor_header typedef struct + // _STORAGE_DESCRIPTOR_HEADER { DWORD Version; DWORD Size; } STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DESCRIPTOR_HEADER")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DESCRIPTOR_HEADER + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + } + + /// Reserved for future use. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_attributes_descriptor typedef struct + // _STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR { DWORD Version; DWORD Size; DWORD64 Attributes; } STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR, *PSTORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR + { + /// Contains the version of the data reported. + public uint Version; + + /// + /// Indicates the quantity of data reported, in bytes. This is the + /// sizeof(STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR) + /// . + /// + public uint Size; + + /// Reserved for future use. + public ulong Attributes; + } + + /// + /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve the storage device descriptor data for a device. + /// + /// + /// An application can determine the required buffer size by issuing a IOCTL_STORAGE_QUERY_PROPERTY control code passing a + /// structure for the output buffer, and then using the returned Size member of the + /// STORAGE_DESCRIPTOR_HEADER structure to allocate a buffer of the proper size. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_descriptor typedef struct + // _STORAGE_DEVICE_DESCRIPTOR { DWORD Version; DWORD Size; BYTE DeviceType; BYTE DeviceTypeModifier; BOOLEAN RemovableMedia; BOOLEAN + // CommandQueueing; DWORD VendorIdOffset; DWORD ProductIdOffset; DWORD ProductRevisionOffset; DWORD SerialNumberOffset; + // STORAGE_BUS_TYPE BusType; DWORD RawPropertiesLength; BYTE RawDeviceProperties[1]; } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_DESCRIPTOR")] + [VanaraMarshaler(typeof(STORAGE_DEVICE_DESCRIPTOR_Marshaler))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_DESCRIPTOR_MGD + { + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + public uint Version; + + /// Specifies the device type as defined by the Small Computer Systems Interface (SCSI) specification. + public byte DeviceType; + + /// + /// Specifies the device type modifier, if any, as defined by the SCSI specification. If no device type modifier exists, this member + /// is zero. + /// + public byte DeviceTypeModifier; + + /// + /// Indicates when TRUE that the device's media (if any) is removable. If the device has no media, this member should be + /// ignored. When FALSE the device's media is not removable. + /// + [MarshalAs(UnmanagedType.U1)] + public bool RemovableMedia; + + /// + /// Indicates when TRUE that the device supports multiple outstanding commands (SCSI tagged queuing or equivalent). When + /// FALSE, the device does not support SCSI-tagged queuing or the equivalent. + /// + [MarshalAs(UnmanagedType.U1)] + public bool CommandQueueing; + + /// + /// A null-terminated ASCII string that contains the device's vendor ID. If the device has no vendor ID, this member is . + /// + public string? VendorId; + + /// + /// A null-terminated ASCII string that contains the device's product ID. If the device has no product ID, this member is . + /// + public string? ProductId; + + /// + /// A null-terminated ASCII string that contains the device's product revision string. If the device has no product revision string, + /// this member is . + /// + public string? ProductRevision; + + /// + /// A null-terminated ASCII string that contains the device's serial number. If the device has no serial number, this member is null. + /// + public string? SerialNumber; + + /// + /// Specifies an enumerator value of type STORAGE_BUS_TYPE that indicates the type of bus to which the device is connected. This + /// should be used to interpret the raw device properties at the end of this structure (if any). + /// + public STORAGE_BUS_TYPE BusType; + + /// Contains a byte array of the bus specific property data. + public byte[]? RawDeviceProperties; + } + + /// + /// Used with the IOCTL_STORAGE_QUERY_PROPERTY control code request to retrieve the device ID descriptor data for a device. + /// + /// + /// The device ID descriptor consists of an array of device IDs taken from the SCSI-3 vital product data (VPD) page 0x83 that was + /// retrieved during discovery. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_id_descriptor typedef struct + // _STORAGE_DEVICE_ID_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NumberOfIdentifiers; BYTE Identifiers[1]; } + // STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_ID_DESCRIPTOR")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NumberOfIdentifiers))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_ID_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// Contains the number of identifiers reported by the device in the Identifiers array. + public uint NumberOfIdentifiers; + + /// Contains a variable-length array of identification descriptors. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Identifiers; + } + + /// The output buffer for the StorageDeviceIoCapabilityProperty as defined in STORAGE_PROPERTY_ID. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_io_capability_descriptor typedef struct + // _STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR { DWORD Version; DWORD Size; DWORD LunMaxIoCount; DWORD AdapterMaxIoCount; } + // STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR, *PSTORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR + { + /// The version of this structure. The Size serves as the version. + public uint Version; + + /// The size of this structure. + public uint Size; + + /// The logical unit number (LUN) max outstanding I/O count. + public uint LunMaxIoCount; + + /// The adapter max outstanding I/O count. + public uint AdapterMaxIoCount; + } + + /// Contains information about a device. This structure is used by the IOCTL_STORAGE_GET_DEVICE_NUMBER control code. + /// + /// The values in the STORAGE_DEVICE_NUMBER structure are guaranteed to remain unchanged until the device is removed or the + /// system is restarted. They are not guaranteed to be persistent across device or system restarts. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_number typedef struct + // _STORAGE_DEVICE_NUMBER { DEVICE_TYPE DeviceType; DWORD DeviceNumber; DWORD PartitionNumber; } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_NUMBER")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_NUMBER + { + /// + /// + /// The type of device. Values from 0 through 32,767 are reserved for use by Microsoft. Values from 32,768 through 65,535 are + /// reserved for use by other vendors. The following values are defined by Microsoft: + /// + /// FILE_DEVICE_8042_PORT + /// FILE_DEVICE_ACPI + /// FILE_DEVICE_BATTERY + /// FILE_DEVICE_BEEP + /// FILE_DEVICE_BLUETOOTH + /// FILE_DEVICE_BUS_EXTENDER + /// FILE_DEVICE_CD_ROM + /// FILE_DEVICE_CD_ROM_FILE_SYSTEM + /// FILE_DEVICE_CHANGER + /// FILE_DEVICE_CONTROLLER + /// FILE_DEVICE_CRYPT_PROVIDER + /// FILE_DEVICE_DATALINK + /// FILE_DEVICE_DFS + /// FILE_DEVICE_DFS_FILE_SYSTEM + /// FILE_DEVICE_DFS_VOLUME + /// FILE_DEVICE_DISK + /// FILE_DEVICE_DISK_FILE_SYSTEM + /// FILE_DEVICE_DVD + /// FILE_DEVICE_FILE_SYSTEM + /// FILE_DEVICE_FIPS + /// FILE_DEVICE_FULLSCREEN_VIDEO + /// FILE_DEVICE_INFINIBAND + /// FILE_DEVICE_INPORT_PORT + /// FILE_DEVICE_KEYBOARD + /// FILE_DEVICE_KS + /// FILE_DEVICE_KSEC + /// FILE_DEVICE_MAILSLOT + /// FILE_DEVICE_MASS_STORAGE + /// FILE_DEVICE_MIDI_IN + /// FILE_DEVICE_MIDI_OUT + /// FILE_DEVICE_MODEM + /// FILE_DEVICE_MOUSE + /// FILE_DEVICE_MULTI_UNC_PROVIDER + /// FILE_DEVICE_NAMED_PIPE + /// FILE_DEVICE_NETWORK + /// FILE_DEVICE_NETWORK_BROWSER + /// FILE_DEVICE_NETWORK_FILE_SYSTEM + /// FILE_DEVICE_NETWORK_REDIRECTOR + /// FILE_DEVICE_NULL + /// FILE_DEVICE_PARALLEL_PORT + /// FILE_DEVICE_PHYSICAL_NETCARD + /// FILE_DEVICE_PRINTER + /// FILE_DEVICE_SCANNER + /// FILE_DEVICE_SCREEN + /// FILE_DEVICE_SERENUM + /// FILE_DEVICE_SERIAL_MOUSE_PORT + /// FILE_DEVICE_SERIAL_PORT + /// FILE_DEVICE_SMARTCARD + /// FILE_DEVICE_SMB + /// FILE_DEVICE_SOUND + /// FILE_DEVICE_STREAMS + /// FILE_DEVICE_TAPE + /// FILE_DEVICE_TAPE_FILE_SYSTEM + /// FILE_DEVICE_TERMSRV + /// FILE_DEVICE_TRANSPORT + /// FILE_DEVICE_UNKNOWN + /// FILE_DEVICE_VDM + /// FILE_DEVICE_VIDEO + /// FILE_DEVICE_VIRTUAL_DISK + /// FILE_DEVICE_VMBUS + /// FILE_DEVICE_WAVE_IN + /// FILE_DEVICE_WAVE_OUT + /// FILE_DEVICE_WPD + /// + public DEVICE_TYPE DeviceType; + + /// The number of this device. + public uint DeviceNumber; + + /// The partition number of the device, if the device can be partitioned. Otherwise, this member is –1. + public uint PartitionNumber; + } + + /// This structure is used as an input and output buffer for the IOCTL_STORAGE_DEVICE_POWER_CAP. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_power_cap typedef struct + // _STORAGE_DEVICE_POWER_CAP { DWORD Version; DWORD Size; STORAGE_DEVICE_POWER_CAP_UNITS Units; DWORDLONG MaxPower; } + // STORAGE_DEVICE_POWER_CAP, *PSTORAGE_DEVICE_POWER_CAP; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_POWER_CAP")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_POWER_CAP + { + /// The version of this structure. This should be set to STORAGE_DEVICE_POWER_CAP_VERSION_V1. + public uint Version; + + /// The size of this structure. + public uint Size; + + /// The units of the MaxPower value, of type STORAGE_DEVICE_POWER_CAP_UNITS. + public STORAGE_DEVICE_POWER_CAP_UNITS Units; + + /// + /// Contains the value of the actual maximum power consumption level of the device. This may be equal to, less than, or greater + /// than the desired threshold, depending on what the device supports. + /// + public ulong MaxPower; + } + + /// Reserved for system use. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_device_resiliency_descriptor typedef struct + // _STORAGE_DEVICE_RESILIENCY_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NameOffset; DWORD NumberOfLogicalCopies; DWORD + // NumberOfPhysicalCopies; DWORD PhysicalDiskRedundancy; DWORD NumberOfColumns; DWORD Interleave; } + // STORAGE_DEVICE_RESILIENCY_DESCRIPTOR, *PSTORAGE_DEVICE_RESILIENCY_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_DEVICE_RESILIENCY_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_DEVICE_RESILIENCY_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// Set to + /// sizeof(STORAGE_DEVICE_RESILIENCY_DESCRIPTOR) + /// . + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// + /// Byte offset to the null-terminated ASCII string containing the resiliency properties Name. For devices with no Name + /// property, this will be zero. + /// + public uint NameOffset; + + /// Number of logical copies of data that are available. + public uint NumberOfLogicalCopies; + + /// Number of complete copies of data that are stored. + public uint NumberOfPhysicalCopies; + + /// Number of disks that can fail without leading to data loss. + public uint PhysicalDiskRedundancy; + + /// Number of columns in the storage device. + public uint NumberOfColumns; + + /// + /// Size of a stripe unit of the storage device, in bytes. This is also referred to as the stripe width or interleave of the + /// storage device. + /// + public uint Interleave; + } + + /// Provides information about the hotplug information of a device. + /// + /// + /// The value of the Size member also identifies the version of this structure, as members will be added to this structure in + /// the future. If the value of the Size member is + /// sizeof(STORAGE_HOTPLUG_INFO) + /// , the current version of the structure is the same as the version you compiled with. If the value is not + /// sizeof(STORAGE_HOTPLUG_INFO) + /// , then the current version contains additional members. + /// + /// + /// A hotplug device refers to a device whose RemovalPolicy value displayed in the Device Manager is + /// ExpectSurpriseRemoval. To query whether a particular device is a hotplug device, use the IOCTL_STORAGE_GET_HOTPLUG_INFO + /// operation. To set the hotplug properties of a device, use the IOCTL_STORAGE_SET_HOTPLUG_INFO operation. + /// + /// + /// The IOCTL_STORAGE_SET_HOTPLUG_INFO operation only sets the value of the DeviceHotplug member of this structure. If the + /// value of that member is set, the removal policy of the specified device is set to ExpectSurpriseRemoval and all levels of + /// caching are disabled. If the value of that member is not set, the removal policy of the specified device is set to + /// ExpectOrderlyRemoval, and caching may be selectively enabled. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_hotplug_info typedef struct _STORAGE_HOTPLUG_INFO + // { DWORD Size; BOOLEAN MediaRemovable; BOOLEAN MediaHotplug; BOOLEAN DeviceHotplug; BOOLEAN WriteCacheEnableOverride; } + // STORAGE_HOTPLUG_INFO, *PSTORAGE_HOTPLUG_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_HOTPLUG_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_HOTPLUG_INFO + { + /// + /// The size of this structure, in bytes. The caller must set this member to /// sizeof(STORAGE_HOTPLUG_INFO) - /// , the current version of the structure is the same as the version you compiled with. If the value is not - /// sizeof(STORAGE_HOTPLUG_INFO) - /// , then the current version contains additional members. - /// - /// - /// A hotplug device refers to a device whose RemovalPolicy value displayed in the Device Manager is - /// ExpectSurpriseRemoval. To query whether a particular device is a hotplug device, use the IOCTL_STORAGE_GET_HOTPLUG_INFO - /// operation. To set the hotplug properties of a device, use the IOCTL_STORAGE_SET_HOTPLUG_INFO operation. - /// - /// - /// The IOCTL_STORAGE_SET_HOTPLUG_INFO operation only sets the value of the DeviceHotplug member of this structure. If the - /// value of that member is set, the removal policy of the specified device is set to ExpectSurpriseRemoval and all levels of - /// caching are disabled. If the value of that member is not set, the removal policy of the specified device is set to - /// ExpectOrderlyRemoval, and caching may be selectively enabled. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_hotplug_info typedef struct _STORAGE_HOTPLUG_INFO - // { DWORD Size; BOOLEAN MediaRemovable; BOOLEAN MediaHotplug; BOOLEAN DeviceHotplug; BOOLEAN WriteCacheEnableOverride; } - // STORAGE_HOTPLUG_INFO, *PSTORAGE_HOTPLUG_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_HOTPLUG_INFO")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_HOTPLUG_INFO - { - /// - /// The size of this structure, in bytes. The caller must set this member to - /// sizeof(STORAGE_HOTPLUG_INFO) - /// . - /// - public uint Size; - - /// - /// If this member is set to a nonzero value, the device media is removable. Otherwise, the device media is not removable. - /// - [MarshalAs(UnmanagedType.U1)] - public bool MediaRemovable; - - /// If this member is set to a nonzero value, the media is not lockable. Otherwise, the device media is lockable. - [MarshalAs(UnmanagedType.U1)] - public bool MediaHotplug; - - /// - /// If this member is set to a nonzero value, the device is a hotplug device. Otherwise, the device is not a hotplug device. - /// - [MarshalAs(UnmanagedType.U1)] - public bool DeviceHotplug; - - /// Reserved; set the value to NULL. - [MarshalAs(UnmanagedType.U1)] - public bool WriteCacheEnableOverride; - } - - /// This structure contains information about the downloaded firmware to activate. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_hw_firmware_activate typedef struct - // _STORAGE_HW_FIRMWARE_ACTIVATE { DWORD Version; DWORD Size; DWORD Flags; BYTE Slot; BYTE Reserved0[3]; } - // STORAGE_HW_FIRMWARE_ACTIVATE, *PSTORAGE_HW_FIRMWARE_ACTIVATE; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_HW_FIRMWARE_ACTIVATE")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_HW_FIRMWARE_ACTIVATE - { - /// The version of this structure. This should be set to sizeof(STORAGE_HW_FIRMWARE_ACTIVATE). - public uint Version; - - /// The size of this structure. This should be set to sizeof(STORAGE_HW_FIRMWARE_ACTIVATE). - public uint Size; - - /// - /// The flags associated with the activation request. The following are valid flags that can be set in this member. - /// - /// - /// Flag - /// Description - /// - /// - /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_CONTROLLER - /// - /// Indicates that the target of the request is a controller or adapter, different than the device handle or object itself (e.g. - /// NVMe SSD or HBA). - /// - /// - /// - /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_SWITCH_TO_EXISTING_FIRMWARE - /// Indicates that the existing firmware image in the specified slot should be activated. - /// - /// - /// - public STORAGE_HW_FIRMWARE_REQUEST_FLAG Flags; - - /// The slot with the firmware image that is to be activated. - public byte Slot; - - /// Reserved for future use. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public byte[] Reserved0; - } - - /// This structure contains a firmware image payload to be downloaded to the target. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_hw_firmware_download typedef struct - // _STORAGE_HW_FIRMWARE_DOWNLOAD { DWORD Version; DWORD Size; DWORD Flags; BYTE Slot; BYTE Reserved[3]; DWORDLONG Offset; DWORDLONG - // BufferSize; BYTE ImageBuffer[ANYSIZE_ARRAY]; } STORAGE_HW_FIRMWARE_DOWNLOAD, *PSTORAGE_HW_FIRMWARE_DOWNLOAD; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_HW_FIRMWARE_DOWNLOAD")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(BufferSize))] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_HW_FIRMWARE_DOWNLOAD - { - /// The version of this structure. This should be set to sizeof(STORAGE_HW_FIRMWARE_DOWNLOAD). - public uint Version; - - /// The size of this structure and the download image buffer. - public uint Size; - - /// - /// Flags associated with this download. The following are valid flags that this member can hold. - /// - /// - /// Flag - /// Description - /// - /// - /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_CONTROLLER - /// - /// Indicates that the target of the request is a controller or adapter, different than the device handler or object itself - /// (e.g. NVMe SSD or HBA). - /// - /// - /// - /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_LAST_SEGMENT - /// Indicates that the current firmware image segment is the last one. - /// - /// - /// - public STORAGE_HW_FIRMWARE_REQUEST_FLAG Flags; - - /// The slot number that the firmware image will be downloaded to. - public byte Slot; - - /// Reserved for future use. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public byte[] Reserved; - - /// - /// The offset in this buffer of where the Image file begins. This should be aligned to ImagePayloadAlignment from STORAGE_HW_FIRMWARE_INFO. - /// - public ulong Offset; - - /// The buffer size of the ImageBuffer. This should be a multiple of ImagePayloadAlignment from STORAGE_HW_FIRMWARE_INFO. - public ulong BufferSize; - - /// The firmware image file. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] ImageBuffer; - } - - /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY request to describe the product type of a storage device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_medium_product_type_descriptor typedef struct - // _STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR { DWORD Version; DWORD Size; DWORD MediumProductType; } - // STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR, *PSTORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes, as defined by - /// Sizeof(STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR) - /// . The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// - /// Specifies the product type of the storage device. - /// - /// - /// MediumProductType value - /// Description - /// - /// - /// - /// 00h - /// - /// Not indicated - /// - /// - /// - /// 01h - /// - /// CFast - /// - /// - /// - /// 02h - /// - /// CompactFlash - /// - /// - /// - /// 03h - /// - /// Memory Stick - /// - /// - /// - /// 04h - /// - /// MultiMediaCard - /// - /// - /// - /// 05h - /// - /// Secure Digital Card (SD Card) - /// - /// - /// - /// 06h - /// - /// QXD - /// - /// - /// - /// 07h - /// - /// Universal Flash Storage - /// - /// - /// - /// 08h - /// to - /// EFh - /// - /// Reserved - /// - /// - /// - /// F0h - /// to - /// FFh - /// - /// Vendor-specific - /// - /// - /// - public uint MediumProductType; - } - - /// Reserved for system use. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_miniport_descriptor typedef struct - // _STORAGE_MINIPORT_DESCRIPTOR { DWORD Version; DWORD Size; STORAGE_PORT_CODE_SET Portdriver; BOOLEAN LUNResetSupported; BOOLEAN - // TargetResetSupported; WORD IoTimeoutValue; BOOLEAN ExtraIoInfoSupported; BYTE Reserved0[3]; DWORD Reserved1; } - // STORAGE_MINIPORT_DESCRIPTOR, *PSTORAGE_MINIPORT_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_MINIPORT_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_MINIPORT_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// - /// Type of port driver as enumerated by the STORAGE_PORT_CODE_SET enumeration. - /// - /// - /// Value - /// Meaning - /// - /// - /// StoragePortCodeSetReserved 0 - /// Indicates an unknown storage adapter driver type. - /// - /// - /// StoragePortCodeSetStorport 1 - /// Storage adapter driver is a Storport-miniport driver. - /// - /// - /// StoragePortCodeSetSCSIport 2 - /// Storage adapter driver is a SCSI Port-miniport driver. - /// - /// - /// - public STORAGE_PORT_CODE_SET Portdriver; - - /// Indicates whether a LUN reset is supported. - [MarshalAs(UnmanagedType.U1)] - public bool LUNResetSupported; - - /// Indicates whether a target reset is supported. - [MarshalAs(UnmanagedType.U1)] - public bool TargetResetSupported; - - /// - public ushort IoTimeoutValue; - - /// - [MarshalAs(UnmanagedType.U1)] - public bool ExtraIoInfoSupported; - - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public byte[] Reserved0; - - /// - public uint Reserved1; - } + /// . + /// + public uint Size; /// - /// Output structure for the DeviceDsmAction_OffloadRead action of the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// If this member is set to a nonzero value, the device media is removable. Otherwise, the device media is not removable. /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_offload_read_output typedef struct - // _STORAGE_OFFLOAD_READ_OUTPUT { DWORD OffloadReadFlags; DWORD Reserved; DWORDLONG LengthProtected; DWORD TokenLength; - // STORAGE_OFFLOAD_TOKEN Token; } STORAGE_OFFLOAD_READ_OUTPUT, *PSTORAGE_OFFLOAD_READ_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_OFFLOAD_READ_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_OFFLOAD_READ_OUTPUT - { - /// - /// Output flags. - /// - /// - /// Value - /// Meaning - /// - /// - /// STORAGE_OFFLOAD_READ_RANGE_TRUNCATED 0x0001 - /// - /// The ranges represented by the token is smaller than the ranges specified in the DEVICE_DATA_SET_RANGE structures passed in - /// the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code input buffer. In other words the LengthProtected member is less - /// than the sum of all of the LengthInBytes members of the DEVICE_DATA_SET_RANGE structures passed. - /// - /// - /// - /// - public STORAGE_OFFLOAD_READ OffloadReadFlags; + [MarshalAs(UnmanagedType.U1)] + public bool MediaRemovable; - /// Reserved. - public uint Reserved; - - /// The total length of the snapshot represented by the token. - public ulong LengthProtected; - - /// Length of the token in bytes. - public uint TokenLength; - - /// A STORAGE_OFFLOAD_TOKEN containing the token created. - public STORAGE_OFFLOAD_TOKEN Token; - } + /// If this member is set to a nonzero value, the media is not lockable. Otherwise, the device media is lockable. + [MarshalAs(UnmanagedType.U1)] + public bool MediaHotplug; /// - /// Contains the token used to represent a portion of a file used in by offload read and write operations specified by - /// DeviceDsmAction_OffloadRead or DeviceDsmAction_OffloadWrite actions for the - /// IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// If this member is set to a nonzero value, the device is a hotplug device. Otherwise, the device is not a hotplug device. /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_offload_token typedef struct - // _STORAGE_OFFLOAD_TOKEN { BYTE TokenType[4]; BYTE Reserved[2]; BYTE TokenIdLength[2]; union { struct { BYTE - // Reserved2[STORAGE_OFFLOAD_TOKEN_ID_LENGTH]; } StorageOffloadZeroDataToken; BYTE Token[STORAGE_OFFLOAD_TOKEN_ID_LENGTH]; } - // DUMMYUNIONNAME; } STORAGE_OFFLOAD_TOKEN, *PSTORAGE_OFFLOAD_TOKEN; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_OFFLOAD_TOKEN")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_OFFLOAD_TOKEN - { - /// - /// A 32-bit unsigned integer which defines the type of Token. - /// STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN (0xFFFFFFFF) - /// - /// The Token member uses a well-known format. The first two bytes of the Token member are a 16-bit unsigned - /// integer that describes the region. The possible values are either STORAGE_OFFLOAD_PATTERN_ZERO or - /// STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO. STORAGE_OFFLOAD_PATTERN_ZERO (0x0001) is a well-known token - /// that indicates that the region represented has all bits set to zero. - /// STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO is a well-known token that indicates that the data in the region - /// represented has all bits set to zero and the corresponding protection information is valid. - /// - /// 0x00000000–0xFFFFFFFE - /// The Token member uses a vendor-specific format. - /// - public uint TokenType; + [MarshalAs(UnmanagedType.U1)] + public bool DeviceHotplug; - /// Reserved. - public ushort Reserved; + /// Reserved; set the value to NULL. + [MarshalAs(UnmanagedType.U1)] + public bool WriteCacheEnableOverride; + } - /// The length of the token data in Token. - public ushort TokenIdLength; + /// This structure contains information about the downloaded firmware to activate. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_hw_firmware_activate typedef struct + // _STORAGE_HW_FIRMWARE_ACTIVATE { DWORD Version; DWORD Size; DWORD Flags; BYTE Slot; BYTE Reserved0[3]; } + // STORAGE_HW_FIRMWARE_ACTIVATE, *PSTORAGE_HW_FIRMWARE_ACTIVATE; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_HW_FIRMWARE_ACTIVATE")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_HW_FIRMWARE_ACTIVATE + { + /// The version of this structure. This should be set to sizeof(STORAGE_HW_FIRMWARE_ACTIVATE). + public uint Version; - /// - /// If the TokenType member is STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN then the first two bytes are a 16-bit - /// unsigned integer that describes the range. Otherwise this is a vendor-specific format. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = STORAGE_OFFLOAD_TOKEN_ID_LENGTH)] - public byte[] Token; - } + /// The size of this structure. This should be set to sizeof(STORAGE_HW_FIRMWARE_ACTIVATE). + public uint Size; /// - /// Output structure for the DeviceDsmAction_OffloadWrite action of the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_offload_write_output typedef struct - // _STORAGE_OFFLOAD_WRITE_OUTPUT { DWORD OffloadWriteFlags; DWORD Reserved; DWORDLONG LengthCopied; } STORAGE_OFFLOAD_WRITE_OUTPUT, *PSTORAGE_OFFLOAD_WRITE_OUTPUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_OFFLOAD_WRITE_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_OFFLOAD_WRITE_OUTPUT - { - /// - /// Out flags - /// - /// - /// Value - /// Meaning - /// - /// - /// STORAGE_OFFLOAD_WRITE_RANGE_TRUNCATED 0x0001 - /// The range written is less than the range specified. - /// - /// - /// STORAGE_OFFLOAD_TOKEN_INVALID 0x0002 - /// The token specified is not valid. - /// - /// - /// - public STORAGE_OFFLOAD_WRITE OffloadWriteFlags; - - /// Reserved. - public uint Reserved; - - /// The length of the copied content. - public ulong LengthCopied; - } - - /// Describes a physical storage adapter. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_adapter_data typedef struct - // _STORAGE_PHYSICAL_ADAPTER_DATA { DWORD AdapterId; STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; STORAGE_PROTOCOL_TYPE - // CommandProtocol; STORAGE_SPEC_VERSION SpecVersion; BYTE Vendor[8]; BYTE Model[40]; BYTE FirmwareRevision[16]; BYTE - // PhysicalLocation[32]; BOOLEAN ExpanderConnected; BYTE Reserved0[3]; DWORD Reserved1[3]; } STORAGE_PHYSICAL_ADAPTER_DATA, *PSTORAGE_PHYSICAL_ADAPTER_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_ADAPTER_DATA")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct STORAGE_PHYSICAL_ADAPTER_DATA - { - /// Specifies the adapter ID. - public uint AdapterId; - - /// A STORAGE_COMPONENT_HEALTH_STATUS-typed value. - public STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; - - /// A STORAGE_PROTOCOL_TYPE-typed value. - public STORAGE_PROTOCOL_TYPE CommandProtocol; - - /// A STORAGE_SPEC_VERSION-typed value that specifies the supported storage spec version (for example, AHCI 1.3.1). - public STORAGE_SPEC_VERSION SpecVersion; - - /// Specifies the adapter vendor. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] - public string Vendor; - - /// Specifies the adapter model. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] - public string Model; - - /// Specifies the firmware revision. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] - public string FirmwareRevision; - - /// Reserved for future use. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string PhysicalLocation; - - /// Indicates whether an expander is connected. - [MarshalAs(UnmanagedType.U1)] - public bool ExpanderConnected; - - /// Reserved. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public byte[] Reserved0; - - /// Reserved. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public uint[] Reserved1; - } - - /// Describes a physical storage device. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_device_data typedef struct - // _STORAGE_PHYSICAL_DEVICE_DATA { DWORD DeviceId; DWORD Role; STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; STORAGE_PROTOCOL_TYPE - // CommandProtocol; STORAGE_SPEC_VERSION SpecVersion; STORAGE_DEVICE_FORM_FACTOR FormFactor; BYTE Vendor[8]; BYTE Model[40]; BYTE - // FirmwareRevision[16]; DWORDLONG Capacity; BYTE PhysicalLocation[32]; DWORD Reserved[2]; } STORAGE_PHYSICAL_DEVICE_DATA, *PSTORAGE_PHYSICAL_DEVICE_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_DEVICE_DATA")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PHYSICAL_DEVICE_DATA - { - /// Specifies the device ID. - public uint DeviceId; - - /// Value(s) of bitmask from STORAGE_COMPONENT_ROLE_xxx - public uint Role; - - /// A STORAGE_COMPONENT_HEALTH_STATUS enumeration. - public STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; - - /// A STORAGE_PROTOCOL_TYPE enumeration. - public STORAGE_PROTOCOL_TYPE CommandProtocol; - - /// - /// A STORAGE_SPEC_VERSION structure that specifies the supported storage spec version. For example: SBC 3, SATA 3.2, NVMe 1.2 - /// - public STORAGE_SPEC_VERSION SpecVersion; - - /// A STORAGE_DEVICE_FORM_FACTOR enumeration. - public STORAGE_DEVICE_FORM_FACTOR FormFactor; - - /// Specifies the device vendor. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] - public string Vendor; - - /// Specifies the device model. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] - public string Model; - - /// Specifies the firmware revision of the device. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] - public string FirmwareRevision; - - /// In units of kilobytes (1024 bytes). - public ulong Capacity; - - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string PhysicalLocation; - - /// - public ulong Reserved; - } - - /// Specifies the physical device data of a storage node. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_node_data typedef struct - // _STORAGE_PHYSICAL_NODE_DATA { DWORD NodeId; DWORD AdapterCount; DWORD AdapterDataLength; DWORD AdapterDataOffset; DWORD - // DeviceCount; DWORD DeviceDataLength; DWORD DeviceDataOffset; DWORD Reserved[3]; } STORAGE_PHYSICAL_NODE_DATA, *PSTORAGE_PHYSICAL_NODE_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_NODE_DATA")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PHYSICAL_NODE_DATA - { - /// The hardware ID of the storage node. - public uint NodeId; - - /// A value of 0 or 1 that indicates the adapter count in the storage node. - public uint AdapterCount; - - /// The data length of the storage adapter in the storage node, in units of kilobytes (1024 bytes). - public uint AdapterDataLength; - - /// The data offset from the beginning of the data structure. The buffer contains an array of STORAGE_PHYSICAL_ADAPTER_DATA. - public uint AdapterDataOffset; - - /// A value less than or equal to 1. - public uint DeviceCount; - - /// The data length of the storage device in the storage node, in units of kilobytes (1024 bytes). - public uint DeviceDataLength; - - /// The data offset from the beginning of the data structure. The buffer contains an array of STORAGE_PHYSICAL_DEVICE_DATA. - public uint DeviceDataOffset; - - /// Specifies if the storage adapter is reserved. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public uint[] Reserved; - } - - /// - /// The STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR structure is one of the query result structures returned from an - /// IOCTL_STORAGE_QUERY_PROPERTY request. This structure describes storage device physical topology. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_topology_descriptor typedef struct - // _STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NodeCount; DWORD Reserved; STORAGE_PHYSICAL_NODE_DATA - // Node[ANYSIZE_ARRAY]; } STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR, *PSTORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NodeCount))] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. Set to - /// sizeof(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR) - /// . - /// - public uint Version; - - /// - /// Specifies the total size of the data, in bytes. Should be >= - /// sizeof(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR) - /// . - /// - public uint Size; - - /// Specifies the number of nodes. - public uint NodeCount; - - /// Reserved. - public uint Reserved; - - /// A node as specified by a STORAGE_PHYSICAL_NODE_DATA structure. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public STORAGE_PHYSICAL_NODE_DATA[] Node; - } - - /// - /// Indicates the properties of a storage device or adapter to retrieve as the input buffer passed to the - /// IOCTL_STORAGE_QUERY_PROPERTY control code. - /// - /// - /// The optional output buffer returned through the lpOutBuffer parameter of the IOCTL_STORAGE_QUERY_PROPERTY control code can be - /// one of several structures depending on the value of the PropertyId member. If the QueryType member is set to - /// PropertyExistsQuery, then no structure is returned. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_property_query typedef struct - // _STORAGE_PROPERTY_QUERY { STORAGE_PROPERTY_ID PropertyId; STORAGE_QUERY_TYPE QueryType; BYTE AdditionalParameters[1]; } - // STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROPERTY_QUERY")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "*")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PROPERTY_QUERY - { - /// - /// Indicates whether the caller is requesting a device descriptor, an adapter descriptor, a write cache property, a device - /// unique ID (DUID), or the device identifiers provided in the device's SCSI vital product data (VPD) page. For a list of the - /// property IDs that can be assigned to this member, see STORAGE_PROPERTY_ID. - /// - public STORAGE_PROPERTY_ID PropertyId; - - /// - /// Contains flags indicating the type of query to be performed as enumerated by the STORAGE_QUERY_TYPE enumeration. - /// - /// - /// Value - /// Meaning - /// - /// - /// PropertyStandardQuery 0 - /// Instructs the port driver to report a device descriptor, an adapter descriptor or a unique hardware device ID (DUID). - /// - /// - /// PropertyExistsQuery 1 - /// Instructs the port driver to report whether the descriptor is supported. - /// - /// - /// - public STORAGE_QUERY_TYPE QueryType; - - /// Contains an array of bytes that can be used to retrieve additional parameters for specific queries. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] AdditionalParameters; - } - - /// - /// This structure is used as an input buffer when using the pass-through mechanism to issue a vendor-specific command to a storage - /// device (via IOCTL_STORAGE_PROTOCOL_COMMAND). - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_protocol_command typedef struct - // _STORAGE_PROTOCOL_COMMAND { DWORD Version; DWORD Length; STORAGE_PROTOCOL_TYPE ProtocolType; DWORD Flags; DWORD ReturnStatus; - // DWORD ErrorCode; DWORD CommandLength; DWORD ErrorInfoLength; DWORD DataToDeviceTransferLength; DWORD - // DataFromDeviceTransferLength; DWORD TimeOutValue; DWORD ErrorInfoOffset; DWORD DataToDeviceBufferOffset; DWORD - // DataFromDeviceBufferOffset; DWORD CommandSpecific; DWORD Reserved0; DWORD FixedProtocolReturnData; DWORD Reserved1[3]; BYTE - // Command[ANYSIZE_ARRAY]; } STORAGE_PROTOCOL_COMMAND, *PSTORAGE_PROTOCOL_COMMAND; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROTOCOL_COMMAND")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(CommandLength))] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PROTOCOL_COMMAND - { - /// The version of this structure. This should be set to STORAGE_PROTOCOL_STRUCTURE_VERSION. - public uint Version; - - /// The size of this structure. This should be set to sizeof( STORAGE_PROTOCOL_COMMAND). - public uint Length; - - /// The protocol type, of type STORAGE_PROTOCOL_TYPE. - public STORAGE_PROTOCOL_TYPE ProtocolType; - - /// - /// Flags set for this request. The following are valid flags. - /// - /// - /// Flag - /// Description - /// - /// - /// STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST - /// This flag indicates the request to target an adapter instead of device. - /// - /// - /// - public STORAGE_PROTOCOL_COMMAND_FLAG Flags; - - private ushort FlagsPadding; - - /// - /// The status of the request made to the storage device. In Windows 10, possible values include: - /// - /// - /// Status value - /// Description - /// - /// - /// STORAGE_PROTOCOL_STATUS_PENDING - /// The request is pending. - /// - /// - /// STORAGE_PROTOCOL_STATUS_SUCCESS - /// The request has completed successfully. - /// - /// - /// STORAGE_PROTOCOL_STATUS_ERROR - /// The request has encountered an error. - /// - /// - /// STORAGE_PROTOCOL_STATUS_INVALID_REQUEST - /// The request is not valid. - /// - /// - /// STORAGE_PROTOCOL_STATUS_NO_DEVICE - /// A device is not available to make a request to. - /// - /// - /// STORAGE_PROTOCOL_STATUS_BUSY - /// The device is busy acting on the request. - /// - /// - /// STORAGE_PROTOCOL_STATUS_DATA_OVERRUN - /// The device encountered a data overrun while acting on the request. - /// - /// - /// STORAGE_PROTOCOL_STATUS_INSUFFICIENT_RESOURCES - /// The device cannot complete the request due to insufficient resources. - /// - /// - /// STORAGE_PROTOCOL_STATUS_NOT_SUPPORTED - /// The request is not supported. - /// - /// - /// - public STORAGE_PROTOCOL_STATUS ReturnStatus; - - /// The error code for this request. This is optionally set. - public uint ErrorCode; - - /// The length of the command. A non-zero value must be set by the caller. - public uint CommandLength; - - /// The length of the error buffer. This is optionally set and can be set to 0. - public uint ErrorInfoLength; - - /// The size of the buffer that is to be transferred to the device. This is only used with a WRITE request. - public uint DataToDeviceTransferLength; - - /// The size of the buffer this is to be transferred from the device. This is only used with a READ request. - public uint DataFromDeviceTransferLength; - - /// How long to wait for the device until timing out. This is set in units of seconds. - public uint TimeOutValue; - - /// The offset of the error buffer. This must be pointer-aligned. - public uint ErrorInfoOffset; - - /// - /// The offset of the buffer that is to be transferred to the device. This must be pointer-aligned and is only used with a WRITE request. - /// - public uint DataToDeviceBufferOffset; - - /// - /// The offset of the buffer that is to be transferred from the device. This must be pointer-aligned and is only used with a - /// READ request. - /// - public uint DataFromDeviceBufferOffset; - - /// - /// Command-specific data passed along with the command. This depends on the command from the driver, and is optionally set. - /// - public uint CommandSpecific; - - /// Reserved for future use. - public uint Reserved0; - - /// - /// The return data. This is optionally set. Some protocols such as NVMe, may return a small amount of data (DWORD0 from - /// completion queue entry) without the need of a separate device data transfer. - /// - public uint FixedProtocolReturnData; - - /// Reserved for future use. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public uint[] Reserved1; - - /// The vendor-specific command that is to be passed-through to the device. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] Command; - } - - /// - /// This structure is used in conjunction with IOCTL_STORAGE_QUERY_PROPERTY to return protocol-specific data from a storage device - /// or adapter. . - /// - /// - /// - /// When using IOCTL_STORAGE_QUERY_PROPERTY to retrieve protocol-specific information in the - /// STORAGE_PROTOCOL_DATA_DESCRIPTOR, configure the STORAGE_PROPERTY_QUERY structure as follows: - /// - /// - /// - /// Allocate a buffer that can contains both a STORAGE_PROPERTY_QUERY and a STORAGE_PROTOCOL_SPECIFIC_DATA structure. - /// + /// The flags associated with the activation request. The following are valid flags that can be set in this member. + /// + /// + /// Flag + /// Description + /// /// + /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_CONTROLLER /// - /// Set the PropertyID field to StorageAdapterProtocolSpecificProperty or StorageDeviceProtocolSpecificProperty - /// for a controller or device/namespace request, respectively. + /// Indicates that the target of the request is a controller or adapter, different than the device handle or object itself (e.g. + /// NVMe SSD or HBA). /// /// /// - /// Set the QueryType field to PropertyStandardQuery. - /// - /// - /// - /// Fill the STORAGE_PROTOCOL_SPECIFIC_DATA structure with the desired values. The start of the - /// STORAGE_PROTOCOL_SPECIFIC_DATA is the AdditionalParameters field of STORAGE_PROPERTY_QUERY. - /// + /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_SWITCH_TO_EXISTING_FIRMWARE + /// Indicates that the existing firmware image in the specified slot should be activated. /// /// - /// To specify a type of NVMe protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: - /// - /// - /// Set the ProtocolType field to ProtocolTypeNVMe. - /// - /// - /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_NVME_DATA_TYPE: - /// - /// - /// To specify a type of ATA protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: - /// - /// - /// Set the ProtocolType field to ProtocolTypeAta. - /// - /// - /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_ATA_DATA_TYPE: - /// - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_protocol_data_descriptor typedef struct - // _STORAGE_PROTOCOL_DATA_DESCRIPTOR { DWORD Version; DWORD Size; STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecificData; } - // STORAGE_PROTOCOL_DATA_DESCRIPTOR, *PSTORAGE_PROTOCOL_DATA_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROTOCOL_DATA_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PROTOCOL_DATA_DESCRIPTOR - { - /// The version of this structure. - public uint Version; + /// + public STORAGE_HW_FIRMWARE_REQUEST_FLAG Flags; - /// The total size of the descriptor, including the space for all protocol data. - public uint Size; + /// The slot with the firmware image that is to be activated. + public byte Slot; - /// The protocol-specific data, of type STORAGE_PROTOCOL_SPECIFIC_DATA. - public STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecificData; - } + /// Reserved for future use. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] Reserved0; + } + + /// This structure contains a firmware image payload to be downloaded to the target. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_hw_firmware_download typedef struct + // _STORAGE_HW_FIRMWARE_DOWNLOAD { DWORD Version; DWORD Size; DWORD Flags; BYTE Slot; BYTE Reserved[3]; DWORDLONG Offset; DWORDLONG + // BufferSize; BYTE ImageBuffer[ANYSIZE_ARRAY]; } STORAGE_HW_FIRMWARE_DOWNLOAD, *PSTORAGE_HW_FIRMWARE_DOWNLOAD; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_HW_FIRMWARE_DOWNLOAD")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(BufferSize))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_HW_FIRMWARE_DOWNLOAD + { + /// The version of this structure. This should be set to sizeof(STORAGE_HW_FIRMWARE_DOWNLOAD). + public uint Version; + + /// The size of this structure and the download image buffer. + public uint Size; /// - /// Describes protocol-specific device data, provided in the input and output buffer of an IOCTL_STORAGE_QUERY_PROPERTY request. - /// - /// - /// - /// When using IOCTL_STORAGE_QUERY_PROPERTY to retrieve protocol-specific information in the STORAGE_PROTOCOL_DATA_DESCRIPTOR, - /// configure the STORAGE_PROPERTY_QUERY structure as follows: - /// - /// - /// - /// Allocate a buffer that can contains both a STORAGE_PROPERTY_QUERY and a STORAGE_PROTOCOL_SPECIFIC_DATA structure. - /// + /// Flags associated with this download. The following are valid flags that this member can hold. + /// + /// + /// Flag + /// Description + /// /// + /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_CONTROLLER /// - /// Set the PropertyID field to StorageAdapterProtocolSpecificProperty or StorageDeviceProtocolSpecificProperty - /// for a controller or device/namespace request, respectively. + /// Indicates that the target of the request is a controller or adapter, different than the device handler or object itself + /// (e.g. NVMe SSD or HBA). /// /// /// - /// Set the QueryType field to PropertyStandardQuery. + /// STORAGE_HW_FIRMWARE_REQUEST_FLAG_LAST_SEGMENT + /// Indicates that the current firmware image segment is the last one. + /// + /// + /// + public STORAGE_HW_FIRMWARE_REQUEST_FLAG Flags; + + /// The slot number that the firmware image will be downloaded to. + public byte Slot; + + /// Reserved for future use. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] Reserved; + + /// + /// The offset in this buffer of where the Image file begins. This should be aligned to ImagePayloadAlignment from STORAGE_HW_FIRMWARE_INFO. + /// + public ulong Offset; + + /// The buffer size of the ImageBuffer. This should be a multiple of ImagePayloadAlignment from STORAGE_HW_FIRMWARE_INFO. + public ulong BufferSize; + + /// The firmware image file. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] ImageBuffer; + } + + /// Used in conjunction with the IOCTL_STORAGE_QUERY_PROPERTY request to describe the product type of a storage device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_medium_product_type_descriptor typedef struct + // _STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR { DWORD Version; DWORD Size; DWORD MediumProductType; } + // STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR, *PSTORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes, as defined by + /// Sizeof(STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR) + /// . The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// + /// Specifies the product type of the storage device. + /// + /// + /// MediumProductType value + /// Description + /// + /// + /// + /// 00h + /// + /// Not indicated /// /// /// - /// Fill the STORAGE_PROTOCOL_SPECIFIC_DATA structure with the desired values. The start of the - /// STORAGE_PROTOCOL_SPECIFIC_DATA is the AdditionalParameters field of STORAGE_PROPERTY_QUERY. + /// 01h + /// + /// CFast + /// + /// + /// + /// 02h + /// + /// CompactFlash + /// + /// + /// + /// 03h + /// + /// Memory Stick + /// + /// + /// + /// 04h + /// + /// MultiMediaCard + /// + /// + /// + /// 05h + /// + /// Secure Digital Card (SD Card) + /// + /// + /// + /// 06h + /// + /// QXD + /// + /// + /// + /// 07h + /// + /// Universal Flash Storage + /// + /// + /// + /// 08h + /// to + /// EFh + /// + /// Reserved + /// + /// + /// + /// F0h + /// to + /// FFh + /// + /// Vendor-specific + /// + /// + /// + public uint MediumProductType; + } + + /// Reserved for system use. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_miniport_descriptor typedef struct + // _STORAGE_MINIPORT_DESCRIPTOR { DWORD Version; DWORD Size; STORAGE_PORT_CODE_SET Portdriver; BOOLEAN LUNResetSupported; BOOLEAN + // TargetResetSupported; WORD IoTimeoutValue; BOOLEAN ExtraIoInfoSupported; BYTE Reserved0[3]; DWORD Reserved1; } + // STORAGE_MINIPORT_DESCRIPTOR, *PSTORAGE_MINIPORT_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_MINIPORT_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_MINIPORT_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// + /// Type of port driver as enumerated by the STORAGE_PORT_CODE_SET enumeration. + /// + /// + /// Value + /// Meaning + /// + /// + /// StoragePortCodeSetReserved 0 + /// Indicates an unknown storage adapter driver type. + /// + /// + /// StoragePortCodeSetStorport 1 + /// Storage adapter driver is a Storport-miniport driver. + /// + /// + /// StoragePortCodeSetSCSIport 2 + /// Storage adapter driver is a SCSI Port-miniport driver. + /// + /// + /// + public STORAGE_PORT_CODE_SET Portdriver; + + /// Indicates whether a LUN reset is supported. + [MarshalAs(UnmanagedType.U1)] + public bool LUNResetSupported; + + /// Indicates whether a target reset is supported. + [MarshalAs(UnmanagedType.U1)] + public bool TargetResetSupported; + + /// + public ushort IoTimeoutValue; + + /// + [MarshalAs(UnmanagedType.U1)] + public bool ExtraIoInfoSupported; + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] Reserved0; + + /// + public uint Reserved1; + } + + /// + /// Output structure for the DeviceDsmAction_OffloadRead action of the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_offload_read_output typedef struct + // _STORAGE_OFFLOAD_READ_OUTPUT { DWORD OffloadReadFlags; DWORD Reserved; DWORDLONG LengthProtected; DWORD TokenLength; + // STORAGE_OFFLOAD_TOKEN Token; } STORAGE_OFFLOAD_READ_OUTPUT, *PSTORAGE_OFFLOAD_READ_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_OFFLOAD_READ_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_OFFLOAD_READ_OUTPUT + { + /// + /// Output flags. + /// + /// + /// Value + /// Meaning + /// + /// + /// STORAGE_OFFLOAD_READ_RANGE_TRUNCATED 0x0001 + /// + /// The ranges represented by the token is smaller than the ranges specified in the DEVICE_DATA_SET_RANGE structures passed in + /// the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code input buffer. In other words the LengthProtected member is less + /// than the sum of all of the LengthInBytes members of the DEVICE_DATA_SET_RANGE structures passed. /// /// /// + /// + public STORAGE_OFFLOAD_READ OffloadReadFlags; + + /// Reserved. + public uint Reserved; + + /// The total length of the snapshot represented by the token. + public ulong LengthProtected; + + /// Length of the token in bytes. + public uint TokenLength; + + /// A STORAGE_OFFLOAD_TOKEN containing the token created. + public STORAGE_OFFLOAD_TOKEN Token; + } + + /// + /// Contains the token used to represent a portion of a file used in by offload read and write operations specified by + /// DeviceDsmAction_OffloadRead or DeviceDsmAction_OffloadWrite actions for the + /// IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_offload_token typedef struct + // _STORAGE_OFFLOAD_TOKEN { BYTE TokenType[4]; BYTE Reserved[2]; BYTE TokenIdLength[2]; union { struct { BYTE + // Reserved2[STORAGE_OFFLOAD_TOKEN_ID_LENGTH]; } StorageOffloadZeroDataToken; BYTE Token[STORAGE_OFFLOAD_TOKEN_ID_LENGTH]; } + // DUMMYUNIONNAME; } STORAGE_OFFLOAD_TOKEN, *PSTORAGE_OFFLOAD_TOKEN; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_OFFLOAD_TOKEN")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_OFFLOAD_TOKEN + { + /// + /// A 32-bit unsigned integer which defines the type of Token. + /// STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN (0xFFFFFFFF) /// - /// To specify a type of NVMe protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: + /// The Token member uses a well-known format. The first two bytes of the Token member are a 16-bit unsigned + /// integer that describes the region. The possible values are either STORAGE_OFFLOAD_PATTERN_ZERO or + /// STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO. STORAGE_OFFLOAD_PATTERN_ZERO (0x0001) is a well-known token + /// that indicates that the region represented has all bits set to zero. + /// STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFO is a well-known token that indicates that the data in the region + /// represented has all bits set to zero and the corresponding protection information is valid. /// - /// + /// 0x00000000–0xFFFFFFFE + /// The Token member uses a vendor-specific format. + /// + public uint TokenType; + + /// Reserved. + public ushort Reserved; + + /// The length of the token data in Token. + public ushort TokenIdLength; + + /// + /// If the TokenType member is STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN then the first two bytes are a 16-bit + /// unsigned integer that describes the range. Otherwise this is a vendor-specific format. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = STORAGE_OFFLOAD_TOKEN_ID_LENGTH)] + public byte[] Token; + } + + /// + /// Output structure for the DeviceDsmAction_OffloadWrite action of the IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES control code. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_offload_write_output typedef struct + // _STORAGE_OFFLOAD_WRITE_OUTPUT { DWORD OffloadWriteFlags; DWORD Reserved; DWORDLONG LengthCopied; } STORAGE_OFFLOAD_WRITE_OUTPUT, *PSTORAGE_OFFLOAD_WRITE_OUTPUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_OFFLOAD_WRITE_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_OFFLOAD_WRITE_OUTPUT + { + /// + /// Out flags + /// + /// + /// Value + /// Meaning + /// /// - /// Set the ProtocolType field to ProtocolTypeNVMe. + /// STORAGE_OFFLOAD_WRITE_RANGE_TRUNCATED 0x0001 + /// The range written is less than the range specified. /// /// - /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_NVME_DATA_TYPE: + /// STORAGE_OFFLOAD_TOKEN_INVALID 0x0002 + /// The token specified is not valid. + /// + /// + /// + public STORAGE_OFFLOAD_WRITE OffloadWriteFlags; + + /// Reserved. + public uint Reserved; + + /// The length of the copied content. + public ulong LengthCopied; + } + + /// Describes a physical storage adapter. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_adapter_data typedef struct + // _STORAGE_PHYSICAL_ADAPTER_DATA { DWORD AdapterId; STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; STORAGE_PROTOCOL_TYPE + // CommandProtocol; STORAGE_SPEC_VERSION SpecVersion; BYTE Vendor[8]; BYTE Model[40]; BYTE FirmwareRevision[16]; BYTE + // PhysicalLocation[32]; BOOLEAN ExpanderConnected; BYTE Reserved0[3]; DWORD Reserved1[3]; } STORAGE_PHYSICAL_ADAPTER_DATA, *PSTORAGE_PHYSICAL_ADAPTER_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_ADAPTER_DATA")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct STORAGE_PHYSICAL_ADAPTER_DATA + { + /// Specifies the adapter ID. + public uint AdapterId; + + /// A STORAGE_COMPONENT_HEALTH_STATUS-typed value. + public STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; + + /// A STORAGE_PROTOCOL_TYPE-typed value. + public STORAGE_PROTOCOL_TYPE CommandProtocol; + + /// A STORAGE_SPEC_VERSION-typed value that specifies the supported storage spec version (for example, AHCI 1.3.1). + public STORAGE_SPEC_VERSION SpecVersion; + + /// Specifies the adapter vendor. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public string Vendor; + + /// Specifies the adapter model. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] + public string Model; + + /// Specifies the firmware revision. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] + public string FirmwareRevision; + + /// Reserved for future use. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string PhysicalLocation; + + /// Indicates whether an expander is connected. + [MarshalAs(UnmanagedType.U1)] + public bool ExpanderConnected; + + /// Reserved. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] Reserved0; + + /// Reserved. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] Reserved1; + } + + /// Describes a physical storage device. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_device_data typedef struct + // _STORAGE_PHYSICAL_DEVICE_DATA { DWORD DeviceId; DWORD Role; STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; STORAGE_PROTOCOL_TYPE + // CommandProtocol; STORAGE_SPEC_VERSION SpecVersion; STORAGE_DEVICE_FORM_FACTOR FormFactor; BYTE Vendor[8]; BYTE Model[40]; BYTE + // FirmwareRevision[16]; DWORDLONG Capacity; BYTE PhysicalLocation[32]; DWORD Reserved[2]; } STORAGE_PHYSICAL_DEVICE_DATA, *PSTORAGE_PHYSICAL_DEVICE_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_DEVICE_DATA")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PHYSICAL_DEVICE_DATA + { + /// Specifies the device ID. + public uint DeviceId; + + /// Value(s) of bitmask from STORAGE_COMPONENT_ROLE_xxx + public uint Role; + + /// A STORAGE_COMPONENT_HEALTH_STATUS enumeration. + public STORAGE_COMPONENT_HEALTH_STATUS HealthStatus; + + /// A STORAGE_PROTOCOL_TYPE enumeration. + public STORAGE_PROTOCOL_TYPE CommandProtocol; + + /// + /// A STORAGE_SPEC_VERSION structure that specifies the supported storage spec version. For example: SBC 3, SATA 3.2, NVMe 1.2 + /// + public STORAGE_SPEC_VERSION SpecVersion; + + /// A STORAGE_DEVICE_FORM_FACTOR enumeration. + public STORAGE_DEVICE_FORM_FACTOR FormFactor; + + /// Specifies the device vendor. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public string Vendor; + + /// Specifies the device model. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] + public string Model; + + /// Specifies the firmware revision of the device. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] + public string FirmwareRevision; + + /// In units of kilobytes (1024 bytes). + public ulong Capacity; + + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string PhysicalLocation; + + /// + public ulong Reserved; + } + + /// Specifies the physical device data of a storage node. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_node_data typedef struct + // _STORAGE_PHYSICAL_NODE_DATA { DWORD NodeId; DWORD AdapterCount; DWORD AdapterDataLength; DWORD AdapterDataOffset; DWORD + // DeviceCount; DWORD DeviceDataLength; DWORD DeviceDataOffset; DWORD Reserved[3]; } STORAGE_PHYSICAL_NODE_DATA, *PSTORAGE_PHYSICAL_NODE_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_NODE_DATA")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PHYSICAL_NODE_DATA + { + /// The hardware ID of the storage node. + public uint NodeId; + + /// A value of 0 or 1 that indicates the adapter count in the storage node. + public uint AdapterCount; + + /// The data length of the storage adapter in the storage node, in units of kilobytes (1024 bytes). + public uint AdapterDataLength; + + /// The data offset from the beginning of the data structure. The buffer contains an array of STORAGE_PHYSICAL_ADAPTER_DATA. + public uint AdapterDataOffset; + + /// A value less than or equal to 1. + public uint DeviceCount; + + /// The data length of the storage device in the storage node, in units of kilobytes (1024 bytes). + public uint DeviceDataLength; + + /// The data offset from the beginning of the data structure. The buffer contains an array of STORAGE_PHYSICAL_DEVICE_DATA. + public uint DeviceDataOffset; + + /// Specifies if the storage adapter is reserved. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] Reserved; + } + + /// + /// The STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR structure is one of the query result structures returned from an + /// IOCTL_STORAGE_QUERY_PROPERTY request. This structure describes storage device physical topology. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_physical_topology_descriptor typedef struct + // _STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NodeCount; DWORD Reserved; STORAGE_PHYSICAL_NODE_DATA + // Node[ANYSIZE_ARRAY]; } STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR, *PSTORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(NodeCount))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. Set to + /// sizeof(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR) + /// . + /// + public uint Version; + + /// + /// Specifies the total size of the data, in bytes. Should be >= + /// sizeof(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR) + /// . + /// + public uint Size; + + /// Specifies the number of nodes. + public uint NodeCount; + + /// Reserved. + public uint Reserved; + + /// A node as specified by a STORAGE_PHYSICAL_NODE_DATA structure. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public STORAGE_PHYSICAL_NODE_DATA[] Node; + } + + /// + /// Indicates the properties of a storage device or adapter to retrieve as the input buffer passed to the + /// IOCTL_STORAGE_QUERY_PROPERTY control code. + /// + /// + /// The optional output buffer returned through the lpOutBuffer parameter of the IOCTL_STORAGE_QUERY_PROPERTY control code can be + /// one of several structures depending on the value of the PropertyId member. If the QueryType member is set to + /// PropertyExistsQuery, then no structure is returned. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_property_query typedef struct + // _STORAGE_PROPERTY_QUERY { STORAGE_PROPERTY_ID PropertyId; STORAGE_QUERY_TYPE QueryType; BYTE AdditionalParameters[1]; } + // STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROPERTY_QUERY")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "*")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PROPERTY_QUERY + { + /// + /// Indicates whether the caller is requesting a device descriptor, an adapter descriptor, a write cache property, a device + /// unique ID (DUID), or the device identifiers provided in the device's SCSI vital product data (VPD) page. For a list of the + /// property IDs that can be assigned to this member, see STORAGE_PROPERTY_ID. + /// + public STORAGE_PROPERTY_ID PropertyId; + + /// + /// Contains flags indicating the type of query to be performed as enumerated by the STORAGE_QUERY_TYPE enumeration. + /// + /// + /// Value + /// Meaning + /// + /// + /// PropertyStandardQuery 0 + /// Instructs the port driver to report a device descriptor, an adapter descriptor or a unique hardware device ID (DUID). + /// + /// + /// PropertyExistsQuery 1 + /// Instructs the port driver to report whether the descriptor is supported. + /// + /// + /// + public STORAGE_QUERY_TYPE QueryType; + + /// Contains an array of bytes that can be used to retrieve additional parameters for specific queries. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] AdditionalParameters; + + /// Initializes a new instance of the struct. + /// The property identifier. + /// Type of the query. + public STORAGE_PROPERTY_QUERY(STORAGE_PROPERTY_ID propertyId, STORAGE_QUERY_TYPE queryType = STORAGE_QUERY_TYPE.PropertyStandardQuery) + { + PropertyId = propertyId; + QueryType = queryType; + AdditionalParameters = new byte[1]; + } + } + + /// + /// This structure is used as an input buffer when using the pass-through mechanism to issue a vendor-specific command to a storage + /// device (via IOCTL_STORAGE_PROTOCOL_COMMAND). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_protocol_command typedef struct + // _STORAGE_PROTOCOL_COMMAND { DWORD Version; DWORD Length; STORAGE_PROTOCOL_TYPE ProtocolType; DWORD Flags; DWORD ReturnStatus; + // DWORD ErrorCode; DWORD CommandLength; DWORD ErrorInfoLength; DWORD DataToDeviceTransferLength; DWORD + // DataFromDeviceTransferLength; DWORD TimeOutValue; DWORD ErrorInfoOffset; DWORD DataToDeviceBufferOffset; DWORD + // DataFromDeviceBufferOffset; DWORD CommandSpecific; DWORD Reserved0; DWORD FixedProtocolReturnData; DWORD Reserved1[3]; BYTE + // Command[ANYSIZE_ARRAY]; } STORAGE_PROTOCOL_COMMAND, *PSTORAGE_PROTOCOL_COMMAND; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROTOCOL_COMMAND")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(CommandLength))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PROTOCOL_COMMAND + { + /// The version of this structure. This should be set to STORAGE_PROTOCOL_STRUCTURE_VERSION. + public uint Version; + + /// The size of this structure. This should be set to sizeof( STORAGE_PROTOCOL_COMMAND). + public uint Length; + + /// The protocol type, of type STORAGE_PROTOCOL_TYPE. + public STORAGE_PROTOCOL_TYPE ProtocolType; + + /// + /// Flags set for this request. The following are valid flags. + /// + /// + /// Flag + /// Description + /// + /// + /// STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST + /// This flag indicates the request to target an adapter instead of device. + /// + /// + /// + public STORAGE_PROTOCOL_COMMAND_FLAG Flags; + + private readonly ushort FlagsPadding; + + /// + /// The status of the request made to the storage device. In Windows 10, possible values include: + /// + /// + /// Status value + /// Description + /// + /// + /// STORAGE_PROTOCOL_STATUS_PENDING + /// The request is pending. + /// + /// + /// STORAGE_PROTOCOL_STATUS_SUCCESS + /// The request has completed successfully. + /// + /// + /// STORAGE_PROTOCOL_STATUS_ERROR + /// The request has encountered an error. + /// + /// + /// STORAGE_PROTOCOL_STATUS_INVALID_REQUEST + /// The request is not valid. + /// + /// + /// STORAGE_PROTOCOL_STATUS_NO_DEVICE + /// A device is not available to make a request to. + /// + /// + /// STORAGE_PROTOCOL_STATUS_BUSY + /// The device is busy acting on the request. + /// + /// + /// STORAGE_PROTOCOL_STATUS_DATA_OVERRUN + /// The device encountered a data overrun while acting on the request. + /// + /// + /// STORAGE_PROTOCOL_STATUS_INSUFFICIENT_RESOURCES + /// The device cannot complete the request due to insufficient resources. + /// + /// + /// STORAGE_PROTOCOL_STATUS_NOT_SUPPORTED + /// The request is not supported. + /// + /// + /// + public STORAGE_PROTOCOL_STATUS ReturnStatus; + + /// The error code for this request. This is optionally set. + public uint ErrorCode; + + /// The length of the command. A non-zero value must be set by the caller. + public uint CommandLength; + + /// The length of the error buffer. This is optionally set and can be set to 0. + public uint ErrorInfoLength; + + /// The size of the buffer that is to be transferred to the device. This is only used with a WRITE request. + public uint DataToDeviceTransferLength; + + /// The size of the buffer this is to be transferred from the device. This is only used with a READ request. + public uint DataFromDeviceTransferLength; + + /// How long to wait for the device until timing out. This is set in units of seconds. + public uint TimeOutValue; + + /// The offset of the error buffer. This must be pointer-aligned. + public uint ErrorInfoOffset; + + /// + /// The offset of the buffer that is to be transferred to the device. This must be pointer-aligned and is only used with a WRITE request. + /// + public uint DataToDeviceBufferOffset; + + /// + /// The offset of the buffer that is to be transferred from the device. This must be pointer-aligned and is only used with a + /// READ request. + /// + public uint DataFromDeviceBufferOffset; + + /// + /// Command-specific data passed along with the command. This depends on the command from the driver, and is optionally set. + /// + public uint CommandSpecific; + + /// Reserved for future use. + public uint Reserved0; + + /// + /// The return data. This is optionally set. Some protocols such as NVMe, may return a small amount of data (DWORD0 from + /// completion queue entry) without the need of a separate device data transfer. + /// + public uint FixedProtocolReturnData; + + /// Reserved for future use. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] Reserved1; + + /// The vendor-specific command that is to be passed-through to the device. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Command; + } + + /// + /// This structure is used in conjunction with IOCTL_STORAGE_QUERY_PROPERTY to return protocol-specific data from a storage device + /// or adapter. . + /// + /// + /// + /// When using IOCTL_STORAGE_QUERY_PROPERTY to retrieve protocol-specific information in the + /// STORAGE_PROTOCOL_DATA_DESCRIPTOR, configure the STORAGE_PROPERTY_QUERY structure as follows: + /// + /// + /// + /// Allocate a buffer that can contains both a STORAGE_PROPERTY_QUERY and a STORAGE_PROTOCOL_SPECIFIC_DATA structure. + /// + /// + /// + /// Set the PropertyID field to StorageAdapterProtocolSpecificProperty or StorageDeviceProtocolSpecificProperty + /// for a controller or device/namespace request, respectively. + /// + /// + /// + /// Set the QueryType field to PropertyStandardQuery. + /// + /// + /// + /// Fill the STORAGE_PROTOCOL_SPECIFIC_DATA structure with the desired values. The start of the + /// STORAGE_PROTOCOL_SPECIFIC_DATA is the AdditionalParameters field of STORAGE_PROPERTY_QUERY. + /// + /// + /// + /// To specify a type of NVMe protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: + /// + /// + /// Set the ProtocolType field to ProtocolTypeNVMe. + /// + /// + /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_NVME_DATA_TYPE: + /// + /// + /// To specify a type of ATA protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: + /// + /// + /// Set the ProtocolType field to ProtocolTypeAta. + /// + /// + /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_ATA_DATA_TYPE: + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_protocol_data_descriptor typedef struct + // _STORAGE_PROTOCOL_DATA_DESCRIPTOR { DWORD Version; DWORD Size; STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecificData; } + // STORAGE_PROTOCOL_DATA_DESCRIPTOR, *PSTORAGE_PROTOCOL_DATA_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROTOCOL_DATA_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PROTOCOL_DATA_DESCRIPTOR + { + /// The version of this structure. + public uint Version; + + /// The total size of the descriptor, including the space for all protocol data. + public uint Size; + + /// The protocol-specific data, of type STORAGE_PROTOCOL_SPECIFIC_DATA. + public STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecificData; + } + + /// + /// Describes protocol-specific device data, provided in the input and output buffer of an IOCTL_STORAGE_QUERY_PROPERTY request. + /// + /// + /// + /// When using IOCTL_STORAGE_QUERY_PROPERTY to retrieve protocol-specific information in the STORAGE_PROTOCOL_DATA_DESCRIPTOR, + /// configure the STORAGE_PROPERTY_QUERY structure as follows: + /// + /// + /// + /// Allocate a buffer that can contains both a STORAGE_PROPERTY_QUERY and a STORAGE_PROTOCOL_SPECIFIC_DATA structure. + /// + /// + /// + /// Set the PropertyID field to StorageAdapterProtocolSpecificProperty or StorageDeviceProtocolSpecificProperty + /// for a controller or device/namespace request, respectively. + /// + /// + /// + /// Set the QueryType field to PropertyStandardQuery. + /// + /// + /// + /// Fill the STORAGE_PROTOCOL_SPECIFIC_DATA structure with the desired values. The start of the + /// STORAGE_PROTOCOL_SPECIFIC_DATA is the AdditionalParameters field of STORAGE_PROPERTY_QUERY. + /// + /// + /// + /// + /// To specify a type of NVMe protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: + /// + /// + /// + /// Set the ProtocolType field to ProtocolTypeNVMe. + /// + /// + /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_NVME_DATA_TYPE: + /// + /// + /// + /// To specify a type of ATA protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: + /// + /// + /// + /// Set the ProtocolType field to ProtocolTypeAta. + /// + /// + /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_ATA_DATA_TYPE: + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_protocol_specific_data typedef struct + // _STORAGE_PROTOCOL_SPECIFIC_DATA { STORAGE_PROTOCOL_TYPE ProtocolType; DWORD DataType; DWORD ProtocolDataRequestValue; DWORD + // ProtocolDataRequestSubValue; DWORD ProtocolDataOffset; DWORD ProtocolDataLength; DWORD FixedProtocolReturnData; DWORD + // ProtocolDataRequestSubValue2; DWORD ProtocolDataRequestSubValue3; DWORD Reserved; } STORAGE_PROTOCOL_SPECIFIC_DATA, *PSTORAGE_PROTOCOL_SPECIFIC_DATA; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROTOCOL_SPECIFIC_DATA")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_PROTOCOL_SPECIFIC_DATA + { + /// The protocol type. Values for this member are defined in the STORAGE_PROTOCOL_TYPE enumeration. + public STORAGE_PROTOCOL_TYPE ProtocolType; + + /// + /// The protocol data type. Data types are defined in the STORAGE_PROTOCOL_NVME_DATA_TYPE and STORAGE_PROTOCOL_ATA_DATA_TYPE enumerations. + /// + public uint DataType; + + /// The protocol data request value. + public uint ProtocolDataRequestValue; + + /// The sub value of the protocol data request. + public uint ProtocolDataRequestSubValue; + + /// + /// The offset of the data buffer that is from the beginning of this structure. The typical value can be sizeof( STORAGE_PROTOCOL_SPECIFIC_DATA). + /// + public uint ProtocolDataOffset; + + /// The length of the protocol data. + public uint ProtocolDataLength; + + /// The returned data. + public uint FixedProtocolReturnData; + + /// + public uint ProtocolDataRequestSubValue2; + + /// + public uint ProtocolDataRequestSubValue3; + + /// Reserved for future use. + public uint Reserved; + } + + /// + /// Using the information from IOCTL_STORAGE_QUERY_PROPERTY, an application can create an RPMB frame to perform one of the following + /// actions: • Program Authentication Key • Query RPMB Write Counter • Authenticated Write • Authenticated Read • Authenticated + /// Device Configuration Write • Authenticated Device Configuration Read + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_rpmb_data_frame typedef struct + // _STORAGE_RPMB_DATA_FRAME { BYTE Stuff[196]; BYTE KeyOrMAC[32]; BYTE Data[256]; BYTE Nonce[16]; BYTE WriteCounter[4]; BYTE + // Address[2]; BYTE BlockCount[2]; BYTE OperationResult[2]; BYTE RequestOrResponseType[2]; } STORAGE_RPMB_DATA_FRAME, *PSTORAGE_RPMB_DATA_FRAME; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_RPMB_DATA_FRAME")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_RPMB_DATA_FRAME + { + /// Reserved space. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] + public byte[] Stuff; + + /// Either the key to be programmed or the MAC authenticating this frame or series of frames. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] KeyOrMAC; + + /// The data input or output. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public byte[] Data; + + /// Random 128-bit number generated by host. Only required for reads. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] Nonce; + + /// 32-bit counter. Only required for writes. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] WriteCounter; + + /// The half-sector address to operate on. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] Address; + + /// The count of half-sector blocks to read/write. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] BlockCount; + + /// The result of the operation. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] OperationResult; + + /// The type of request or response. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] RequestOrResponseType; + } + + /// + /// To interface with the Replay Protected Memory Block (RPMB), applications first need to query whether the device contains an RPMB + /// and the max payload size the RPMB supports. To do this, the application sends IOCTL_STORAGE_QUERY_PROPERTY IOCTL with + /// STORAGE_PROPERTY_ID enumeration set to StorageAdapterRpmbProperty (defined in STORAGE_PROPERTY_QUERY in ntddstor.h). Storport + /// then responds with the following payload (defined in ntddstor.h) when STORAGE_QUERY_TYPE enumeration is set to PropertyStandardQuery. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_rpmb_descriptor typedef struct + // _STORAGE_RPMB_DESCRIPTOR { DWORD Version; DWORD Size; DWORD SizeInBytes; DWORD MaxReliableWriteSizeInBytes; + // STORAGE_RPMB_FRAME_TYPE FrameFormat; } STORAGE_RPMB_DESCRIPTOR, *PSTORAGE_RPMB_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_RPMB_DESCRIPTOR")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_RPMB_DESCRIPTOR + { + /// Shall be set to STORAGE_RPMB_DESCRIPTOR_VERSION_1 + public uint Version; + + /// Shall be set to sizeof(STORAGE_RPMB_DESCRIPTOR) + public uint Size; + + /// The size of the RPMB, in bytes. 0 if not supported, RPMB size in bytes otherwise. + public uint SizeInBytes; + + /// The maximum amount of data supported in one transaction in bytes. 0 if not supported, minimum 512 bytes. + public uint MaxReliableWriteSizeInBytes; + + /// + /// To support different RPMB frame formats, specifies which frame format the payload will be in so the port driver can take the + /// appropriate action. + /// + public STORAGE_RPMB_FRAME_TYPE FrameFormat; + } + + /// Storage specification version. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_spec_version typedef union _STORAGE_SPEC_VERSION + // { struct { union { struct { BYTE SubMinor; BYTE Minor; } DUMMYSTRUCTNAME; WORD AsUshort; } MinorVersion; WORD MajorVersion; } + // DUMMYSTRUCTNAME; DWORD AsUlong; } STORAGE_SPEC_VERSION, *PSTORAGE_SPEC_VERSION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_SPEC_VERSION")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_SPEC_VERSION + { + /// + public byte SubMinor; + + /// + public byte Minor; + + /// + public ushort MajorVersion; + } + + /// + /// This structure is used in conjunction with IOCTL_STORAGE_QUERY_PROPERTY to return temperature data from a storage device or adapter. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_temperature_data_descriptor typedef struct + // _STORAGE_TEMPERATURE_DATA_DESCRIPTOR { DWORD Version; DWORD Size; SHORT CriticalTemperature; SHORT WarningTemperature; WORD + // InfoCount; BYTE Reserved0[2]; DWORD Reserved1[2]; STORAGE_TEMPERATURE_INFO TemperatureInfo[ANYSIZE_ARRAY]; } + // STORAGE_TEMPERATURE_DATA_DESCRIPTOR, *PSTORAGE_TEMPERATURE_DATA_DESCRIPTOR; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_TEMPERATURE_DATA_DESCRIPTOR")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(InfoCount))] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_TEMPERATURE_DATA_DESCRIPTOR + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// + /// Indicates the minimum temperature in degrees Celsius that may prevent normal operation. Exceeding this temperature may + /// result in possible data loss, automatic device shutdown, extreme performance throttling, or permanent damage. + /// + public short CriticalTemperature; + + /// + /// Indicates the maximum temperature in degrees Celsius at which the device is capable of operating continuously without + /// degrading operation or reliability. + /// + public short WarningTemperature; + + /// + /// Specifies the number of STORAGE_TEMPERATURE_INFO structures reported in TemperatureInfo. More than one set of + /// temperature data may be returned when there are multiple sensors in the drive. + /// + public ushort InfoCount; + + /// Reserved for future use. + public ushort Reserved0; + + /// Reserved for future use. + public ulong Reserved1; + + /// Device temperature data, of type STORAGE_TEMPERATURE_INFO. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public STORAGE_TEMPERATURE_INFO[] TemperatureInfo; + } + + /// + /// Describes device temperature data. Returned as part of STORAGE_TEMPERATURE_DATA_DESCRIPTOR when querying for temperature data + /// with an IOCTL_STORAGE_QUERY_PROPERTY request. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_temperature_info typedef struct + // _STORAGE_TEMPERATURE_INFO { WORD Index; SHORT Temperature; SHORT OverThreshold; SHORT UnderThreshold; BOOLEAN + // OverThresholdChangable; BOOLEAN UnderThresholdChangable; BOOLEAN EventGenerated; BYTE Reserved0; DWORD Reserved1; } + // STORAGE_TEMPERATURE_INFO, *PSTORAGE_TEMPERATURE_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_TEMPERATURE_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_TEMPERATURE_INFO + { + /// Identifies the instance of temperature information. Starts from 0. Index 0 may indicate a composite value. + public ushort Index; + + /// A signed value that indicates the current temperature, in degrees Celsius. + public short Temperature; + + /// A signed value that specifies the maximum temperature within the desired threshold, in degrees Celsius. + public short OverThreshold; + + /// A signed value that specifies the minimum temperature within the desired threshold, in degrees Celsius. + public short UnderThreshold; + + /// Indicates if OverThreshold can be changed by using IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD. + [MarshalAs(UnmanagedType.U1)] + public bool OverThresholdChangable; + + /// Indicates if UnderThreshold can be changed by using IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD. + [MarshalAs(UnmanagedType.U1)] + public bool UnderThresholdChangable; + + /// Indicates if a notification will be generated when the current temperature crosses a threshold. + [MarshalAs(UnmanagedType.U1)] + public bool EventGenerated; + + /// Reserved for future use. + public byte Reserved0; + + /// Reserved for future use. + public uint Reserved1; + } + + /// This structure is used to set the over or under temperature threshold of a storage device (via IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD). + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_temperature_threshold typedef struct + // _STORAGE_TEMPERATURE_THRESHOLD { DWORD Version; DWORD Size; WORD Flags; WORD Index; SHORT Threshold; BOOLEAN OverThreshold; BYTE + // Reserved; } STORAGE_TEMPERATURE_THRESHOLD, *PSTORAGE_TEMPERATURE_THRESHOLD; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_TEMPERATURE_THRESHOLD")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_TEMPERATURE_THRESHOLD + { + /// The version of the structure. + public uint Version; + + /// The size of this structure. This should be set to sizeof( STORAGE_TEMPERATURE_THRESHOLD). + public uint Size; + + /// + /// Flags set for this request. The following are valid flags. + /// + /// + /// Flag + /// Description + /// + /// + /// STORAGE_TEMPERATURE_THRESHOLD_FLAG_ADAPTER_REQUEST + /// This flag indicates the request to target an adapter instead of device. + /// + /// + /// + public STORAGE_TEMPERATURE_THRESHOLD_FLAG Flags; + + /// Identifies the instance of temperature information. Starts from 0. Index 0 may indicate a composite value. + public ushort Index; + + /// A signed value that indicates the temperature of the threshold, in degrees Celsius. + public short Threshold; + + /// + /// Indicates if the Threshold specifies the over or under temperature threshold. If true, set the OverThreshold + /// temperature value of the device; otherwise, set the UnderThreshold temperature value. + /// + [MarshalAs(UnmanagedType.U1)] + public bool OverThreshold; + + /// Reserved for future use. + public byte Reserved; + } + + /// Used with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve information about a device's write cache property. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_write_cache_property typedef struct + // _STORAGE_WRITE_CACHE_PROPERTY { DWORD Version; DWORD Size; WRITE_CACHE_TYPE WriteCacheType; WRITE_CACHE_ENABLE WriteCacheEnabled; + // WRITE_CACHE_CHANGE WriteCacheChangeable; WRITE_THROUGH WriteThroughSupported; BOOLEAN FlushCacheSupported; BOOLEAN + // UserDefinedPowerProtection; BOOLEAN NVCacheEnabled; } STORAGE_WRITE_CACHE_PROPERTY, *PSTORAGE_WRITE_CACHE_PROPERTY; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_WRITE_CACHE_PROPERTY")] + [StructLayout(LayoutKind.Sequential)] + public struct STORAGE_WRITE_CACHE_PROPERTY + { + /// + /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. + /// + public uint Version; + + /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. + public uint Size; + + /// + /// A value from the WRITE_CACHE_TYPE enumeration that indicates the current write cache type. + /// + /// + /// Value + /// Meaning + /// + /// + /// WriteCacheTypeUnknown 0 + /// The system cannot report the type of the write cache. + /// + /// + /// WriteCacheTypeNone 1 + /// The device does not have a write cache. + /// + /// + /// WriteCacheTypeWriteBack 2 + /// The device has a write-back cache. + /// + /// + /// WriteCacheTypeWriteThrough 3 + /// The device has a write-through cache. + /// + /// + /// + public WRITE_CACHE_TYPE WriteCacheType; + + /// + /// A value from the WRITE_CACHE_ENABLE enumeration that indicates whether the write cache is enabled. + /// + /// + /// Value + /// Meaning + /// + /// + /// WriteCacheEnableUnknown 0 + /// The system cannot report whether the device's write cache is enabled or disabled. + /// + /// + /// WriteCacheDisabled 1 + /// The device's write cache is disabled. + /// + /// + /// WriteCacheEnabled 2 + /// The device's write cache is enabled. + /// + /// + /// + public WRITE_CACHE_ENABLE WriteCacheEnabled; + + /// + /// A value from the WRITE_CACHE_CHANGE enumeration that indicates whether if the host can change the write cache characteristics. + /// + /// + /// Value + /// Meaning + /// + /// + /// WriteCacheChangeUnknown 0 + /// The system cannot report the write cache change capability of the device. + /// + /// + /// WriteCacheNotChangeable 1 + /// Host software cannot change the characteristics of the device's write cache + /// + /// + /// WriteCacheChangeable 2 + /// Host software can change the characteristics of the device's write cache + /// + /// + /// + public WRITE_CACHE_CHANGE WriteCacheChangeable; + + /// + /// A value from the WRITE_THROUGH enumeration that indicates whether the device supports write-through caching. + /// + /// + /// Value + /// Meaning + /// + /// + /// WriteThroughUnknown 0 + /// Indicates that no information is available concerning the write-through capabilities of the device. + /// + /// + /// WriteThroughNotSupported 1 + /// Indicates that the device does not support write-through operations. + /// + /// + /// WriteThroughSupported 2 + /// Indicates that the device supports write-through operations. + /// + /// + /// + public WRITE_THROUGH WriteThroughSupported; + + /// + /// A BOOLEAN value that indicates whether the device allows host software to flush the device cache. If TRUE, the + /// device allows host software to flush the device cache. If FALSE, host software cannot flush the device cache. + /// + [MarshalAs(UnmanagedType.U1)] + public bool FlushCacheSupported; + + /// + /// A BOOLEAN value that indicates whether a user can configure the device's power protection characteristics in the + /// registry. If TRUE, a user can configure the device's power protection characteristics in the registry. If + /// FALSE, the user cannot configure the device's power protection characteristics in the registry. + /// + [MarshalAs(UnmanagedType.U1)] + public bool UserDefinedPowerProtection; + + /// + /// A BOOLEAN value that indicates whether the device has a battery backup for the write cache. If TRUE, the + /// device has a battery backup for the write cache. If FALSE, the device does not have a battery backup for the writer cache. + /// + [MarshalAs(UnmanagedType.U1)] + public bool NVCacheEnabled; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains the version information about the miniversion that is created. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_get_metadata_info_out typedef struct + // _TXFS_GET_METADATA_INFO_OUT { struct { LONGLONG LowPart; LONGLONG HighPart; } TxfFileId; GUID LockingTransaction; DWORDLONG + // LastLsn; DWORD TransactionState; } TXFS_GET_METADATA_INFO_OUT, *PTXFS_GET_METADATA_INFO_OUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_GET_METADATA_INFO_OUT")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_GET_METADATA_INFO_OUT + { + /// Returns the TxfId of the file referenced by the handle used to call this routine. + public TXFFILEID TxfFileId; + + /// The TxfId of the file referenced by the handle used to call this routine. + [StructLayout(LayoutKind.Sequential)] + public struct TXFFILEID + { + /// + /// The lower half of the TxfId of the file referenced by the handle used to call FSCTL_TXFS_GET_METADATA_INFO. It is unique + /// within a resource manager. + /// + public long LowPart; + + /// + /// The higher half of the TxfId of the file referenced by the handle used to call FSCTL_TXFS_GET_METADATA_INFO. It is + /// unique within a resource manager. + /// + public long HighPart; + } + + /// The GUID of the transaction that locked the specified file locked, if the file is locked. + public Guid LockingTransaction; + + /// + /// Receives the last LSN for the most recent log record written for file. It is a property of the file that refers to the log, + /// and references the last log entry of the file. + /// + public ulong LastLsn; + + /// + /// Indicates the state of the transaction that has locked the file. Valid values are: + /// TXFS_TRANSACTION_STATE_ACTIVE + /// TXFS_TRANSACTION_STATE_NONE + /// TXFS_TRANSACTION_STATE_NOTACTIVETXFS_TRANSACTION_STATE_NOTACTIVE + /// TXFS_TRANSACTION_STATE_PREPARED + /// + public TXFS_TRANSACTION_STATE TransactionState; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains the information about the base and latest versions of the specified file. + /// + /// + /// The base version number remains the same for the lifetime of a handle. The latest version number increases as long as a handle + /// is still open to a file and a change is committed. When the handle is closed, the version number is reset to zero. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_get_transacted_version typedef struct + // _TXFS_GET_TRANSACTED_VERSION { DWORD ThisBaseVersion; DWORD LatestVersion; WORD ThisMiniVersion; WORD FirstMiniVersion; WORD + // LatestMiniVersion; } TXFS_GET_TRANSACTED_VERSION, *PTXFS_GET_TRANSACTED_VERSION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_GET_TRANSACTED_VERSION")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_GET_TRANSACTED_VERSION + { + /// + /// The version of the file that this handle is opened with. This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// TXFS_TRANSACTED_VERSION_NONTRANSACTED 0xFFFFFFFE + /// The file is not a transacted file. + /// + /// + /// TXFS_TRANSACTED_VERSION_UNCOMMITTED 0xFFFFFFFF + /// The file has been opened as a transacted writer. /// /// /// - /// To specify a type of ATA protocol-specific information, configure the STORAGE_PROTOCOL_SPECIFIC_DATA structure as follows: + /// If the handle has been opened as a transacted reader, the value returned for this member is a positive integer that + /// represents the version number of the file the handle is associated with. /// - /// - /// - /// Set the ProtocolType field to ProtocolTypeAta. - /// - /// - /// Set the DataType field to an enumeration value defined by STORAGE_PROTOCOL_ATA_DATA_TYPE: - /// - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_protocol_specific_data typedef struct - // _STORAGE_PROTOCOL_SPECIFIC_DATA { STORAGE_PROTOCOL_TYPE ProtocolType; DWORD DataType; DWORD ProtocolDataRequestValue; DWORD - // ProtocolDataRequestSubValue; DWORD ProtocolDataOffset; DWORD ProtocolDataLength; DWORD FixedProtocolReturnData; DWORD - // ProtocolDataRequestSubValue2; DWORD ProtocolDataRequestSubValue3; DWORD Reserved; } STORAGE_PROTOCOL_SPECIFIC_DATA, *PSTORAGE_PROTOCOL_SPECIFIC_DATA; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_PROTOCOL_SPECIFIC_DATA")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_PROTOCOL_SPECIFIC_DATA - { - /// The protocol type. Values for this member are defined in the STORAGE_PROTOCOL_TYPE enumeration. - public STORAGE_PROTOCOL_TYPE ProtocolType; + /// + public uint ThisBaseVersion; - /// - /// The protocol data type. Data types are defined in the STORAGE_PROTOCOL_NVME_DATA_TYPE and STORAGE_PROTOCOL_ATA_DATA_TYPE enumerations. - /// - public uint DataType; - - /// The protocol data request value. - public uint ProtocolDataRequestValue; - - /// The sub value of the protocol data request. - public uint ProtocolDataRequestSubValue; - - /// - /// The offset of the data buffer that is from the beginning of this structure. The typical value can be sizeof( STORAGE_PROTOCOL_SPECIFIC_DATA). - /// - public uint ProtocolDataOffset; - - /// The length of the protocol data. - public uint ProtocolDataLength; - - /// The returned data. - public uint FixedProtocolReturnData; - - /// - public uint ProtocolDataRequestSubValue2; - - /// - public uint ProtocolDataRequestSubValue3; - - /// Reserved for future use. - public uint Reserved; - } + /// The most recently committed version of the file. + public uint LatestVersion; /// - /// Using the information from IOCTL_STORAGE_QUERY_PROPERTY, an application can create an RPMB frame to perform one of the following - /// actions: • Program Authentication Key • Query RPMB Write Counter • Authenticated Write • Authenticated Read • Authenticated - /// Device Configuration Write • Authenticated Device Configuration Read + /// If the handle to a miniversion is open, this member contains the ID of the miniversion. If the handle is not open, this + /// member is zero (0). /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_rpmb_data_frame typedef struct - // _STORAGE_RPMB_DATA_FRAME { BYTE Stuff[196]; BYTE KeyOrMAC[32]; BYTE Data[256]; BYTE Nonce[16]; BYTE WriteCounter[4]; BYTE - // Address[2]; BYTE BlockCount[2]; BYTE OperationResult[2]; BYTE RequestOrResponseType[2]; } STORAGE_RPMB_DATA_FRAME, *PSTORAGE_RPMB_DATA_FRAME; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_RPMB_DATA_FRAME")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_RPMB_DATA_FRAME - { - /// Reserved space. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] - public byte[] Stuff; - - /// Either the key to be programmed or the MAC authenticating this frame or series of frames. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] KeyOrMAC; - - /// The data input or output. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - public byte[] Data; - - /// Random 128-bit number generated by host. Only required for reads. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] Nonce; - - /// 32-bit counter. Only required for writes. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] - public byte[] WriteCounter; - - /// The half-sector address to operate on. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public byte[] Address; - - /// The count of half-sector blocks to read/write. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public byte[] BlockCount; - - /// The result of the operation. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public byte[] OperationResult; - - /// The type of request or response. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public byte[] RequestOrResponseType; - } + public ushort ThisMiniVersion; /// - /// To interface with the Replay Protected Memory Block (RPMB), applications first need to query whether the device contains an RPMB - /// and the max payload size the RPMB supports. To do this, the application sends IOCTL_STORAGE_QUERY_PROPERTY IOCTL with - /// STORAGE_PROPERTY_ID enumeration set to StorageAdapterRpmbProperty (defined in STORAGE_PROPERTY_QUERY in ntddstor.h). Storport - /// then responds with the following payload (defined in ntddstor.h) when STORAGE_QUERY_TYPE enumeration is set to PropertyStandardQuery. + /// The first available miniversion for this file. If there are no miniversions, or they are not visible to the transaction + /// bound to the file handle, this field is zero (0). /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_rpmb_descriptor typedef struct - // _STORAGE_RPMB_DESCRIPTOR { DWORD Version; DWORD Size; DWORD SizeInBytes; DWORD MaxReliableWriteSizeInBytes; - // STORAGE_RPMB_FRAME_TYPE FrameFormat; } STORAGE_RPMB_DESCRIPTOR, *PSTORAGE_RPMB_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_RPMB_DESCRIPTOR")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_RPMB_DESCRIPTOR - { - /// Shall be set to STORAGE_RPMB_DESCRIPTOR_VERSION_1 - public uint Version; - - /// Shall be set to sizeof(STORAGE_RPMB_DESCRIPTOR) - public uint Size; - - /// The size of the RPMB, in bytes. 0 if not supported, RPMB size in bytes otherwise. - public uint SizeInBytes; - - /// The maximum amount of data supported in one transaction in bytes. 0 if not supported, minimum 512 bytes. - public uint MaxReliableWriteSizeInBytes; - - /// - /// To support different RPMB frame formats, specifies which frame format the payload will be in so the port driver can take the - /// appropriate action. - /// - public STORAGE_RPMB_FRAME_TYPE FrameFormat; - } - - /// Storage specification version. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_spec_version typedef union _STORAGE_SPEC_VERSION - // { struct { union { struct { BYTE SubMinor; BYTE Minor; } DUMMYSTRUCTNAME; WORD AsUshort; } MinorVersion; WORD MajorVersion; } - // DUMMYSTRUCTNAME; DWORD AsUlong; } STORAGE_SPEC_VERSION, *PSTORAGE_SPEC_VERSION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_SPEC_VERSION")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_SPEC_VERSION - { - /// - public byte SubMinor; - - /// - public byte Minor; - - /// - public ushort MajorVersion; - } + public ushort FirstMiniVersion; /// - /// This structure is used in conjunction with IOCTL_STORAGE_QUERY_PROPERTY to return temperature data from a storage device or adapter. + /// The latest available miniversion for this file. If there are no miniversions, or they are not visible to the transaction + /// bound to the file handle, this field is zero (0). /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_temperature_data_descriptor typedef struct - // _STORAGE_TEMPERATURE_DATA_DESCRIPTOR { DWORD Version; DWORD Size; SHORT CriticalTemperature; SHORT WarningTemperature; WORD - // InfoCount; BYTE Reserved0[2]; DWORD Reserved1[2]; STORAGE_TEMPERATURE_INFO TemperatureInfo[ANYSIZE_ARRAY]; } - // STORAGE_TEMPERATURE_DATA_DESCRIPTOR, *PSTORAGE_TEMPERATURE_DATA_DESCRIPTOR; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_TEMPERATURE_DATA_DESCRIPTOR")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(InfoCount))] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_TEMPERATURE_DATA_DESCRIPTOR - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; + public ushort LatestMiniVersion; + } - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains a list of files locked by a transacted writer. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transaction_locked_files typedef struct + // _TXFS_LIST_TRANSACTION_LOCKED_FILES { GUID KtmTransaction; DWORDLONG NumberOfFiles; DWORDLONG BufferSizeRequired; DWORDLONG + // Offset; } TXFS_LIST_TRANSACTION_LOCKED_FILES, *PTXFS_LIST_TRANSACTION_LOCKED_FILES; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTION_LOCKED_FILES")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_LIST_TRANSACTION_LOCKED_FILES + { + /// The KTM transaction to enumerate locked files for in this RM. + public Guid KtmTransaction; - /// - /// Indicates the minimum temperature in degrees Celsius that may prevent normal operation. Exceeding this temperature may - /// result in possible data loss, automatic device shutdown, extreme performance throttling, or permanent damage. - /// - public short CriticalTemperature; - - /// - /// Indicates the maximum temperature in degrees Celsius at which the device is capable of operating continuously without - /// degrading operation or reliability. - /// - public short WarningTemperature; - - /// - /// Specifies the number of STORAGE_TEMPERATURE_INFO structures reported in TemperatureInfo. More than one set of - /// temperature data may be returned when there are multiple sensors in the drive. - /// - public ushort InfoCount; - - /// Reserved for future use. - public ushort Reserved0; - - /// Reserved for future use. - public ulong Reserved1; - - /// Device temperature data, of type STORAGE_TEMPERATURE_INFO. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public STORAGE_TEMPERATURE_INFO[] TemperatureInfo; - } + /// The number of files involved for the specified transaction on this resource manager. + public ulong NumberOfFiles; /// - /// Describes device temperature data. Returned as part of STORAGE_TEMPERATURE_DATA_DESCRIPTOR when querying for temperature data - /// with an IOCTL_STORAGE_QUERY_PROPERTY request. + /// The length of the buffer required to hold the complete list of files at the time of this call. This is not guaranteed to be + /// the same length as any other subsequent call. /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_temperature_info typedef struct - // _STORAGE_TEMPERATURE_INFO { WORD Index; SHORT Temperature; SHORT OverThreshold; SHORT UnderThreshold; BOOLEAN - // OverThresholdChangable; BOOLEAN UnderThresholdChangable; BOOLEAN EventGenerated; BYTE Reserved0; DWORD Reserved1; } - // STORAGE_TEMPERATURE_INFO, *PSTORAGE_TEMPERATURE_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_TEMPERATURE_INFO")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_TEMPERATURE_INFO - { - /// Identifies the instance of temperature information. Starts from 0. Index 0 may indicate a composite value. - public ushort Index; + public ulong BufferSizeRequired; - /// A signed value that indicates the current temperature, in degrees Celsius. - public short Temperature; + /// + /// The offset from the beginning of this structure to the beginning of the first TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY structure. + /// + public ulong Offset; + } - /// A signed value that specifies the maximum temperature within the desired threshold, in degrees Celsius. - public short OverThreshold; - - /// A signed value that specifies the minimum temperature within the desired threshold, in degrees Celsius. - public short UnderThreshold; - - /// Indicates if OverThreshold can be changed by using IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD. - [MarshalAs(UnmanagedType.U1)] - public bool OverThresholdChangable; - - /// Indicates if UnderThreshold can be changed by using IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD. - [MarshalAs(UnmanagedType.U1)] - public bool UnderThresholdChangable; - - /// Indicates if a notification will be generated when the current temperature crosses a threshold. - [MarshalAs(UnmanagedType.U1)] - public bool EventGenerated; - - /// Reserved for future use. - public byte Reserved0; - - /// Reserved for future use. - public uint Reserved1; - } - - /// This structure is used to set the over or under temperature threshold of a storage device (via IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD). - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_temperature_threshold typedef struct - // _STORAGE_TEMPERATURE_THRESHOLD { DWORD Version; DWORD Size; WORD Flags; WORD Index; SHORT Threshold; BOOLEAN OverThreshold; BYTE - // Reserved; } STORAGE_TEMPERATURE_THRESHOLD, *PSTORAGE_TEMPERATURE_THRESHOLD; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_TEMPERATURE_THRESHOLD")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_TEMPERATURE_THRESHOLD - { - /// The version of the structure. - public uint Version; - - /// The size of this structure. This should be set to sizeof( STORAGE_TEMPERATURE_THRESHOLD). - public uint Size; - - /// - /// Flags set for this request. The following are valid flags. - /// - /// - /// Flag - /// Description - /// - /// - /// STORAGE_TEMPERATURE_THRESHOLD_FLAG_ADAPTER_REQUEST - /// This flag indicates the request to target an adapter instead of device. - /// - /// - /// - public STORAGE_TEMPERATURE_THRESHOLD_FLAG Flags; - - /// Identifies the instance of temperature information. Starts from 0. Index 0 may indicate a composite value. - public ushort Index; - - /// A signed value that indicates the temperature of the threshold, in degrees Celsius. - public short Threshold; - - /// - /// Indicates if the Threshold specifies the over or under temperature threshold. If true, set the OverThreshold - /// temperature value of the device; otherwise, set the UnderThreshold temperature value. - /// - [MarshalAs(UnmanagedType.U1)] - public bool OverThreshold; - - /// Reserved for future use. - public byte Reserved; - } - - /// Used with the IOCTL_STORAGE_QUERY_PROPERTY control code to retrieve information about a device's write cache property. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_write_cache_property typedef struct - // _STORAGE_WRITE_CACHE_PROPERTY { DWORD Version; DWORD Size; WRITE_CACHE_TYPE WriteCacheType; WRITE_CACHE_ENABLE WriteCacheEnabled; - // WRITE_CACHE_CHANGE WriteCacheChangeable; WRITE_THROUGH WriteThroughSupported; BOOLEAN FlushCacheSupported; BOOLEAN - // UserDefinedPowerProtection; BOOLEAN NVCacheEnabled; } STORAGE_WRITE_CACHE_PROPERTY, *PSTORAGE_WRITE_CACHE_PROPERTY; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_WRITE_CACHE_PROPERTY")] - [StructLayout(LayoutKind.Sequential)] - public struct STORAGE_WRITE_CACHE_PROPERTY - { - /// - /// Contains the size of this structure, in bytes. The value of this member will change as members are added to the structure. - /// - public uint Version; - - /// Specifies the total size of the data returned, in bytes. This may include data that follows this structure. - public uint Size; - - /// - /// A value from the WRITE_CACHE_TYPE enumeration that indicates the current write cache type. - /// - /// - /// Value - /// Meaning - /// - /// - /// WriteCacheTypeUnknown 0 - /// The system cannot report the type of the write cache. - /// - /// - /// WriteCacheTypeNone 1 - /// The device does not have a write cache. - /// - /// - /// WriteCacheTypeWriteBack 2 - /// The device has a write-back cache. - /// - /// - /// WriteCacheTypeWriteThrough 3 - /// The device has a write-through cache. - /// - /// - /// - public WRITE_CACHE_TYPE WriteCacheType; - - /// - /// A value from the WRITE_CACHE_ENABLE enumeration that indicates whether the write cache is enabled. - /// - /// - /// Value - /// Meaning - /// - /// - /// WriteCacheEnableUnknown 0 - /// The system cannot report whether the device's write cache is enabled or disabled. - /// - /// - /// WriteCacheDisabled 1 - /// The device's write cache is disabled. - /// - /// - /// WriteCacheEnabled 2 - /// The device's write cache is enabled. - /// - /// - /// - public WRITE_CACHE_ENABLE WriteCacheEnabled; - - /// - /// A value from the WRITE_CACHE_CHANGE enumeration that indicates whether if the host can change the write cache characteristics. - /// - /// - /// Value - /// Meaning - /// - /// - /// WriteCacheChangeUnknown 0 - /// The system cannot report the write cache change capability of the device. - /// - /// - /// WriteCacheNotChangeable 1 - /// Host software cannot change the characteristics of the device's write cache - /// - /// - /// WriteCacheChangeable 2 - /// Host software can change the characteristics of the device's write cache - /// - /// - /// - public WRITE_CACHE_CHANGE WriteCacheChangeable; - - /// - /// A value from the WRITE_THROUGH enumeration that indicates whether the device supports write-through caching. - /// - /// - /// Value - /// Meaning - /// - /// - /// WriteThroughUnknown 0 - /// Indicates that no information is available concerning the write-through capabilities of the device. - /// - /// - /// WriteThroughNotSupported 1 - /// Indicates that the device does not support write-through operations. - /// - /// - /// WriteThroughSupported 2 - /// Indicates that the device supports write-through operations. - /// - /// - /// - public WRITE_THROUGH WriteThroughSupported; - - /// - /// A BOOLEAN value that indicates whether the device allows host software to flush the device cache. If TRUE, the - /// device allows host software to flush the device cache. If FALSE, host software cannot flush the device cache. - /// - [MarshalAs(UnmanagedType.U1)] - public bool FlushCacheSupported; - - /// - /// A BOOLEAN value that indicates whether a user can configure the device's power protection characteristics in the - /// registry. If TRUE, a user can configure the device's power protection characteristics in the registry. If - /// FALSE, the user cannot configure the device's power protection characteristics in the registry. - /// - [MarshalAs(UnmanagedType.U1)] - public bool UserDefinedPowerProtection; - - /// - /// A BOOLEAN value that indicates whether the device has a battery backup for the write cache. If TRUE, the - /// device has a battery backup for the write cache. If FALSE, the device does not have a battery backup for the writer cache. - /// - [MarshalAs(UnmanagedType.U1)] - public bool NVCacheEnabled; - } + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains information about a locked transaction. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transaction_locked_files_entry typedef struct + // _TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY { DWORDLONG Offset; DWORD NameFlags; LONGLONG FileId; DWORD Reserved1; DWORD Reserved2; + // LONGLONG Reserved3; WCHAR FileName[1]; } TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY, *PTXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY")] + [VanaraMarshaler(typeof(AnySizeStringMarshaler), "*")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY + { + /// The offset, in bytes, from the beginning of the TXFS_LIST_TRANSACTION_LOCKED_FILES structure to the next TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY. + public ulong Offset; /// /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] + /// Indicates whether the current name was deleted or created in the current transaction. Note that both flags may appear if the + /// name was both created and deleted in the same transaction. In that case, the FileName member will contain only an + /// empty string with a terminating null character ("\0") because there is no meaningful name to report. /// - /// Contains the version information about the miniversion that is created. + /// TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY_FLAG_CREATED (0x00000001) + /// TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY_FLAG_DELETED (0x00000002) /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_get_metadata_info_out typedef struct - // _TXFS_GET_METADATA_INFO_OUT { struct { LONGLONG LowPart; LONGLONG HighPart; } TxfFileId; GUID LockingTransaction; DWORDLONG - // LastLsn; DWORD TransactionState; } TXFS_GET_METADATA_INFO_OUT, *PTXFS_GET_METADATA_INFO_OUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_GET_METADATA_INFO_OUT")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_GET_METADATA_INFO_OUT - { - /// Returns the TxfId of the file referenced by the handle used to call this routine. - public TXFFILEID TxfFileId; + public uint NameFlags; - /// The TxfId of the file referenced by the handle used to call this routine. - [StructLayout(LayoutKind.Sequential)] - public struct TXFFILEID + /// The NTFS File ID of the file. + public long FileId; + + /// Reserved. Specify zero. + public uint Reserved1; + + /// Reserved. Specify zero. + public uint Reserved2; + + /// Reserved. Specify zero. + public long Reserved3; + + /// The path to the file, relative to the volume root. The file name is a NULL-terminated Unicode string. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] + public string FileName; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains a list of transactions. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transactions typedef struct + // _TXFS_LIST_TRANSACTIONS { DWORDLONG NumberOfTransactions; DWORDLONG BufferSizeRequired; } TXFS_LIST_TRANSACTIONS, *PTXFS_LIST_TRANSACTIONS; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTIONS")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_LIST_TRANSACTIONS + { + /// The number of transactions for this resource manager. + public ulong NumberOfTransactions; + + /// + /// The length of the buffer required to hold the complete list of transactions at the time of this call. The number of + /// transactions returned from one call to the next can change depending on the number of active transactions at any given point + /// in time. If this call returns a request for a larger buffer, that size may or may not be adequate for the next call, based + /// on the number of active transactions at the time of the next call. + /// + public ulong BufferSizeRequired; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains information about a transaction. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transactions_entry typedef struct + // _TXFS_LIST_TRANSACTIONS_ENTRY { GUID TransactionId; DWORD TransactionState; DWORD Reserved1; DWORD Reserved2; LONGLONG Reserved3; + // } TXFS_LIST_TRANSACTIONS_ENTRY, *PTXFS_LIST_TRANSACTIONS_ENTRY; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTIONS_ENTRY")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_LIST_TRANSACTIONS_ENTRY + { + /// The GUID of the transaction. + public Guid TransactionId; + + /// The current state of the transaction. + public uint TransactionState; + + /// Reserved. + public uint Reserved1; + + /// Reserved. + public uint Reserved2; + + /// Reserved. + public long Reserved3; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains the information required when modifying log parameters and logging mode for a secondary resource manager. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_modify_rm typedef struct _TXFS_MODIFY_RM { DWORD + // Flags; DWORD LogContainerCountMax; DWORD LogContainerCountMin; DWORD LogContainerCount; DWORD LogGrowthIncrement; DWORD + // LogAutoShrinkPercentage; DWORDLONG Reserved; WORD LoggingMode; } TXFS_MODIFY_RM, *PTXFS_MODIFY_RM; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_MODIFY_RM")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_MODIFY_RM + { + /// + /// The log parameters to be set. + /// This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// TXFS_RM_FLAG_LOGGING_MODE 0x00000001 + /// + /// If this flag is set, the LoggingMode member of this structure is being used. If the flag is not set, the LoggingMode member + /// is ignored. + /// + /// + /// + /// TXFS_RM_FLAG_RENAME_RM 0x00000002 + /// If this flag is set, the RM is instructed to rename itself (creating a new GUID). + /// + /// + /// TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MAX 0x00000004 + /// + /// If this flag is set, the LogContainerCountMax member is being used. If the flag is not set, the LogContainerCountMax member + /// is ignored. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MIN 0x00000008 + /// + /// If this flag is set, the LogContainerCountMin member is being used. If the flag is not set, the LogContainerCountMin member + /// is ignored. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS 0x00000010 + /// + /// If this flag is set, the LogGrowthIncrement member is being used. If the flag is not set, the LogGrowthIncrement member is + /// ignored. This flag indicates that the log should grow by the number of containers specified in the LogGrowthIncrement + /// member. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT 0x00000020 + /// + /// If this flag is set, the LogGrowthIncrement member is being used. If the flag is not set, the LogGrowthIncrement member is + /// ignored. This flag indicates that the log should grow by the percentage of the log size specified in the LogGrowthIncrement + /// member. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_AUTO_SHRINK_PERCENTAGE 0x00000040 + /// + /// If this flag is set, the LogAutoShrinkPercentage member is being used. If the flag is not set, the LogAutoShrinkPercentage + /// is ignored. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX 0x00000080 + /// + /// If this flag is set, the RM is instructed to allow its log to grow without bounds. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN 0x00000100 + /// + /// If this flag is set, the RM is instructed to allow its log to shrink the log to only two containers. This flag is mutually + /// exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX. + /// + /// + /// + /// TXFS_RM_FLAG_GROW_LOG 0x00000400 + /// + /// If this flag is set, the log is instructed to immediately increase its size to the size specified in LogContainerCount. If + /// the flag is not set, the LogContainerCount is ignored. + /// + /// + /// + /// TXFS_RM_FLAG_SHRINK_LOG 0x00000800 + /// + /// If this flag is set, the log is instructed to immediately decrease its size to the size specified in LogContainerCount. If + /// this flag and TXFS_RM_FLAG_ENFORCE_MINIMUM_SIZE are set, the log is instructed to shrink to its minimum allowable size, and + /// LogContainerCount is ignored. + /// + /// + /// + /// TXFS_RM_FLAG_ENFORCE_MINIMUM_SIZE 0x00001000 + /// + /// If this flag and TXFS_RM_FLAG_SHRINK_LOG are set, the log is instructed to shrink to its minimum allowable size, and + /// LogContainerCount is ignored. If this flag is set, the TXFS_RM_FLAG_SHRINK_LOG must be set. + /// + /// + /// + /// TXFS_RM_FLAG_PRESERVE_CHANGES 0x00002000 + /// + /// If this flag is set, the log is instructed to preserve the changes on disk. If this flag is not set, any changes made are + /// temporary (that is, until the RM is shut down and restarted). + /// + /// + /// + /// TXFS_RM_FLAG_RESET_RM_AT_NEXT_START 0x00004000 + /// + /// This flag is only valid for default RMs, not secondary RMs. If this flag is set, the RM is instructed to reset itself the + /// next time it is started. The log and the associated metadata are deleted. + /// + /// + /// + /// TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START 0x00008000 + /// + /// This flag is only valid for default RMs, not secondary RMs. If this flag is set, a previous call to FSCTL_TXFS_MODIFY_RM is + /// canceled with the TXFS_RM_FLAG_RESET_RM_AT_NEXT_START flag set. + /// + /// + /// + /// TXFS_RM_FLAG_PREFER_CONSISTENCY 0x00010000 + /// + /// Indicates that the RM is to prefer transaction consistency over system availability. This flag is mutually exclusive with + /// TXFS_RM_FLAG_PREFER_AVAILABILITY and is not supported by the default RM on the system volume. + /// + /// + /// + /// TXFS_RM_FLAG_PREFER_AVAILABILITY 0x00020000 + /// + /// Indicates that the RM is to prefer system availability over transaction consistency. This flag is mutually exclusive with + /// TXFS_RM_FLAG_PREFER_CONSISTENCY and is forced by the default RM on the system volume. + /// + /// + /// + /// + public TXFS_RM_FLAG Flags; + + /// The maximum size of the log, in containers. + public uint LogContainerCountMax; + + /// The minimum size of the log, in containers. + public uint LogContainerCountMin; + + /// The actual size of the log, in containers. + public uint LogContainerCount; + + /// The number of containers or percentage of space that should be added to the log. + public uint LogGrowthIncrement; + + /// + /// The percentage of log space to keep free. This member is used when the TXFS_RM_FLAG_LOG_AUTO_SHRINK_PERCENTAGE flag + /// is used, and instructs the log to automatically shrink itself, so no more than LogAutoShrinkPercentage of the log is + /// free at any given time. + /// + public uint LogAutoShrinkPercentage; + + /// Reserved. + public ulong Reserved; + + /// + /// The current logging mode. + /// + /// + /// Value + /// Meaning + /// + /// + /// TXFS_LOGGING_MODE_SIMPLE 1 + /// Simple logging is used. + /// + /// + /// TXFS_LOGGING_MODE_FULL 2 + /// Full logging is used + /// + /// + /// + public TXFS_LOGGING_MODE LoggingMode; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains information about the resource manager (RM). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_query_rm_information typedef struct + // _TXFS_QUERY_RM_INFORMATION { DWORD BytesRequired; DWORDLONG TailLsn; DWORDLONG CurrentLsn; DWORDLONG ArchiveTailLsn; DWORDLONG + // LogContainerSize; LARGE_INTEGER HighestVirtualClock; DWORD LogContainerCount; DWORD LogContainerCountMax; DWORD + // LogContainerCountMin; DWORD LogGrowthIncrement; DWORD LogAutoShrinkPercentage; DWORD Flags; WORD LoggingMode; WORD Reserved; + // DWORD RmState; DWORDLONG LogCapacity; DWORDLONG LogFree; DWORDLONG TopsSize; DWORDLONG TopsUsed; DWORDLONG TransactionCount; + // DWORDLONG OnePCCount; DWORDLONG TwoPCCount; DWORDLONG NumberLogFileFull; DWORDLONG OldestTransactionAge; GUID RMName; DWORD + // TmLogPathOffset; } TXFS_QUERY_RM_INFORMATION, *PTXFS_QUERY_RM_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_QUERY_RM_INFORMATION")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_QUERY_RM_INFORMATION + { + /// + /// If FSCTL_TXFS_QUERY_RM_INFORMATION returns ERROR_BUFFER_TOO_SMALL, this member specifies the minimum number of bytes + /// needed to return the information requested, including the NULL terminating character. + /// + public uint BytesRequired; + + /// The oldest log sequence number (LSN) currently used by the RM. + public ulong TailLsn; + + /// The LSN most recently used by the RM in its log. + public ulong CurrentLsn; + + /// The LSN of the archive tail of the log. + public ulong ArchiveTailLsn; + + /// The actual size of a log container, in bytes. + public ulong LogContainerSize; + + /// The highest timestamp associated with a log record. + public long HighestVirtualClock; + + /// The number of log containers. + public uint LogContainerCount; + + /// The maximum number of log containers. + public uint LogContainerCountMax; + + /// The minimum number of containers allowed in the log. + public uint LogContainerCountMin; + + /// + /// The amount the log will grow by, which is either a number of containers or percentage of the log size; the growth type used + /// is specified by the flags set in Flags member. + /// + public uint LogGrowthIncrement; + + /// + /// If the auto-shrink policy is active, this member specifies the maximum allowable amount of free space in the log. If this + /// member is zero, the auto-shrink policy is not active. + /// + public uint LogAutoShrinkPercentage; + + /// + /// This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MIN 0x00000008 + /// If the flag is set, the RM's log is allowed to shrink as far as possible. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX. + /// + /// + /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS 0x00000010 + /// + /// Indicates the type of value in LogGrowthIncrement. If this flag is set, LogGrowthIncrement is a number of containers. This + /// flag is mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT 0x00000020 + /// + /// Indicates the type of value in LogGrowthIncrement. If this flag is set, LogGrowthIncrement is a percentage. This flag is + /// mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS. + /// + /// + /// + /// TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX 0x00000080 + /// Indicates that the RM's log can grow without bounds. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN. + /// + /// + /// TXFS_RM_FLAG_RESET_RM_AT_NEXT_START 0x00004000 + /// + /// Indicates the current state of the RM reset flag. If this is set, the RM will reset itself the next time it is started. This + /// flag is only valid for default RMs, not secondary RMs. This flag is mutually exclusive with TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START. + /// + /// + /// + /// TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START 0x00008000 + /// + /// Indicates the current state of the RM reset flag. If this is set, the RM will not reset itself the next time it is started. + /// This flag is only valid for default RMs, not secondary RMs. This flag is mutually exclusive with TXFS_RM_FLAG_RESET_RM_AT_NEXT_START. + /// + /// + /// + /// TXFS_RM_FLAG_PREFER_CONSISTENCY 0x00010000 + /// + /// Indicates that the RM is to prefer transaction consistency over system availability. This flag is mutually exclusive with + /// TXFS_RM_FLAG_PREFER_AVAILABILITY and is not supported by the default RM on the system volume. + /// + /// + /// + /// TXFS_RM_FLAG_PREFER_AVAILABILITY 0x00020000 + /// + /// Indicates that the RM is to prefer system availability over transaction consistency. This flag is mutually exclusive with + /// TXFS_RM_FLAG_PREFER_CONSISTENCY and is forced by the default RM on the system volume. + /// + /// + /// + /// + public TXFS_RM_FLAG Flags; + + /// + /// The current logging mode. + /// + /// + /// Value + /// Meaning + /// + /// + /// TXFS_LOGGING_MODE_SIMPLE 1 + /// Simple logging is used. + /// + /// + /// TXFS_LOGGING_MODE_FULL 2 + /// Full logging is used + /// + /// + /// + public TXFS_LOGGING_MODE LoggingMode; + + /// Reserved. + public ushort Reserved; + + /// + /// The state of the RM. Valid values are as follows. + /// + /// + /// Value + /// Meaning + /// + /// + /// TXFS_RM_STATE_NOT_STARTED 0 + /// The RM is not yet started. + /// + /// + /// TXFS_RM_STATE_STARTING 1 + /// The RM is starting. + /// + /// + /// TXFS_RM_STATE_ACTIVE 2 + /// The RM is active and ready to accept transactions. + /// + /// + /// TXFS_RM_STATE_SHUTTING_DOWN 3 + /// The RM is shutting down. + /// + /// + /// + public TXFS_RM_STATE RmState; + + /// The total capacity of the log, in bytes. + public ulong LogCapacity; + + /// The number of bytes free in the log. + public ulong LogFree; + + /// The size of the $Tops file, in bytes. + public ulong TopsSize; + + /// The amount of the $Tops file that is in use, in bytes. + public ulong TopsUsed; + + /// The number of active transactions, at the time the query was issued. + public ulong TransactionCount; + + /// The number of single-phase commit operations that have occurred on this RM. + public ulong OnePCCount; + + /// The number of two-phase commit operations that have occurred on this RM. + public ulong TwoPCCount; + + /// The number of times this RM's log has become full. + public ulong NumberLogFileFull; + + /// The length of the oldest active transaction, in milliseconds. + public ulong OldestTransactionAge; + + /// The GUID that indicates the name of this RM. + public Guid RMName; + + /// + /// The offset from the beginning of this structure to a NULL-terminated Unicode string that contains the path to the + /// TM's log. + /// + public uint TmLogPathOffset; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains a Transactional NTFS (TxF) specific structure. This information should only be used when calling TXFS_WRITE_BACKUP_INFORMATION. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_read_backup_information_out typedef struct + // _TXFS_READ_BACKUP_INFORMATION_OUT { union { DWORD BufferLength; BYTE Buffer[1]; } DUMMYUNIONNAME; } + // TXFS_READ_BACKUP_INFORMATION_OUT, *PTXFS_READ_BACKUP_INFORMATION_OUT; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_READ_BACKUP_INFORMATION_OUT")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "*")] + [StructLayout(LayoutKind.Sequential, Size = 4)] + public struct TXFS_READ_BACKUP_INFORMATION_OUT + { + /// The buffer for the data. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Buffer; + + /// If the buffer is not large enough, this member receives the required buffer size. + public uint BufferLength => Buffer?.Length >= 4 ? BitConverter.ToUInt32(Buffer, 0) : 0; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains the flag that indicates whether transactions were active or not when a snapshot was taken. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_transaction_active_info typedef struct + // _TXFS_TRANSACTION_ACTIVE_INFO { BOOLEAN TransactionsActiveAtSnapshot; } TXFS_TRANSACTION_ACTIVE_INFO, *PTXFS_TRANSACTION_ACTIVE_INFO; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_TRANSACTION_ACTIVE_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_TRANSACTION_ACTIVE_INFO + { + /// + /// This member is TRUE if the mounted snapshot volume had active transactions when the snapshot was taken; and + /// FALSE otherwise. + /// + [MarshalAs(UnmanagedType.U1)] + public bool TransactionsActiveAtSnapshot; + } + + /// + /// + /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF + /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available + /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using + /// Transactional NTFS.] + /// + /// Contains a Transactional NTFS (TxF) specific structure. This information should only be used when calling TXFS_WRITE_BACKUP_INFORMATION. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_write_backup_information typedef struct + // _TXFS_WRITE_BACKUP_INFORMATION { BYTE Buffer[1]; } TXFS_WRITE_BACKUP_INFORMATION, *PTXFS_WRITE_BACKUP_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_WRITE_BACKUP_INFORMATION")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "*")] + [StructLayout(LayoutKind.Sequential)] + public struct TXFS_WRITE_BACKUP_INFORMATION + { + /// The buffer for the data. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Buffer; + } + + /// Contains information used to verify a disk extent. It is the output buffer for the IOCTL_DISK_VERIFY control code. + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-verify_information typedef struct _VERIFY_INFORMATION { + // LARGE_INTEGER StartingOffset; DWORD Length; } VERIFY_INFORMATION, *PVERIFY_INFORMATION; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._VERIFY_INFORMATION")] + [StructLayout(LayoutKind.Sequential)] + public struct VERIFY_INFORMATION + { + /// The starting offset of the disk extent. + public long StartingOffset; + + /// The length of the disk extent, in bytes. + public uint Length; + } + + /// + /// Represents the occupied and available clusters on a disk. This structure is the output buffer for the FSCTL_GET_VOLUME_BITMAP + /// control code. + /// + /// + /// The BitmapSize member is the number of clusters on the volume starting from the starting LCN returned in the + /// StartingLcn member of this structure. For example, suppose there are 0xD3F7 clusters on the volume. If you start the + /// bitmap query at LCN 0xA007, then both the FAT and NTFS file systems will round down the returned starting LCN to LCN 0xA000. The + /// value returned in the BitmapSize member will be (0xD3F7 – 0xA000), or 0x33F7. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-volume_bitmap_buffer typedef struct { LARGE_INTEGER + // StartingLcn; LARGE_INTEGER BitmapSize; BYTE Buffer[1]; } VOLUME_BITMAP_BUFFER, *PVOLUME_BITMAP_BUFFER; + [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_6")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(BitmapSize))] + [StructLayout(LayoutKind.Sequential)] + public struct VOLUME_BITMAP_BUFFER + { + /// Starting LCN requested as an input to the operation. + public long StartingLcn; + + /// + /// The number of clusters on the volume, starting from the starting LCN returned in the StartingLcn member of this + /// structure. See the following Remarks section for details. + /// + public long BitmapSize; + + /// + /// Array of bytes containing the bitmap that the operation returns. The bitmap is bitwise from bit zero of the bitmap to the + /// end. Thus, starting at the requested cluster, the bitmap goes from bit 0 of byte 0, bit 1 of byte 0 ... bit 7 of byte 0, bit + /// 0 of byte 1, and so on. The value 1 indicates that the cluster is allocated (in use). The value 0 indicates that the cluster + /// is not allocated (free). + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Buffer; + } + + [StructLayout(LayoutKind.Sequential)] + private struct STORAGE_DEVICE_DESCRIPTOR + { + public uint Version; + + public uint Size; + + public byte DeviceType; + + public byte DeviceTypeModifier; + + [MarshalAs(UnmanagedType.U1)] + public bool RemovableMedia; + + [MarshalAs(UnmanagedType.U1)] + public bool CommandQueueing; + + public uint VendorIdOffset; + + public uint ProductIdOffset; + + public uint ProductRevisionOffset; + + public uint SerialNumberOffset; + + public STORAGE_BUS_TYPE BusType; + + public uint RawPropertiesLength; + + public byte RawDeviceProperties; + } + + private class STORAGE_DEVICE_DESCRIPTOR_Marshaler : IVanaraMarshaler + { + static readonly Lazy propOffset = new(() => Marshal.OffsetOf(typeof(STORAGE_DEVICE_DESCRIPTOR), nameof(STORAGE_DEVICE_DESCRIPTOR.RawDeviceProperties)).ToInt64()); + + SizeT IVanaraMarshaler.GetNativeSize() => Marshal.SizeOf(typeof(STORAGE_DEVICE_DESCRIPTOR)); + + SafeAllocatedMemoryHandle IVanaraMarshaler.MarshalManagedToNative(object? managedObject) => new SafeCoTaskMemHandle(1024); + + object? IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes) + { + if (pNativeData == IntPtr.Zero) return null; + var sdd = (STORAGE_DEVICE_DESCRIPTOR)Marshal.PtrToStructure(pNativeData, typeof(STORAGE_DEVICE_DESCRIPTOR))!; + return new STORAGE_DEVICE_DESCRIPTOR_MGD { - /// - /// The lower half of the TxfId of the file referenced by the handle used to call FSCTL_TXFS_GET_METADATA_INFO. It is unique - /// within a resource manager. - /// - public long LowPart; - - /// - /// The higher half of the TxfId of the file referenced by the handle used to call FSCTL_TXFS_GET_METADATA_INFO. It is - /// unique within a resource manager. - /// - public long HighPart; - } - - /// The GUID of the transaction that locked the specified file locked, if the file is locked. - public Guid LockingTransaction; - - /// - /// Receives the last LSN for the most recent log record written for file. It is a property of the file that refers to the log, - /// and references the last log entry of the file. - /// - public ulong LastLsn; - - /// - /// Indicates the state of the transaction that has locked the file. Valid values are: - /// TXFS_TRANSACTION_STATE_ACTIVE - /// TXFS_TRANSACTION_STATE_NONE - /// TXFS_TRANSACTION_STATE_NOTACTIVETXFS_TRANSACTION_STATE_NOTACTIVE - /// TXFS_TRANSACTION_STATE_PREPARED - /// - public TXFS_TRANSACTION_STATE TransactionState; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains the information about the base and latest versions of the specified file. - /// - /// - /// The base version number remains the same for the lifetime of a handle. The latest version number increases as long as a handle - /// is still open to a file and a change is committed. When the handle is closed, the version number is reset to zero. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_get_transacted_version typedef struct - // _TXFS_GET_TRANSACTED_VERSION { DWORD ThisBaseVersion; DWORD LatestVersion; WORD ThisMiniVersion; WORD FirstMiniVersion; WORD - // LatestMiniVersion; } TXFS_GET_TRANSACTED_VERSION, *PTXFS_GET_TRANSACTED_VERSION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_GET_TRANSACTED_VERSION")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_GET_TRANSACTED_VERSION - { - /// - /// The version of the file that this handle is opened with. This member can be one of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// TXFS_TRANSACTED_VERSION_NONTRANSACTED 0xFFFFFFFE - /// The file is not a transacted file. - /// - /// - /// TXFS_TRANSACTED_VERSION_UNCOMMITTED 0xFFFFFFFF - /// The file has been opened as a transacted writer. - /// - /// - /// - /// If the handle has been opened as a transacted reader, the value returned for this member is a positive integer that - /// represents the version number of the file the handle is associated with. - /// - /// - public uint ThisBaseVersion; - - /// The most recently committed version of the file. - public uint LatestVersion; - - /// - /// If the handle to a miniversion is open, this member contains the ID of the miniversion. If the handle is not open, this - /// member is zero (0). - /// - public ushort ThisMiniVersion; - - /// - /// The first available miniversion for this file. If there are no miniversions, or they are not visible to the transaction - /// bound to the file handle, this field is zero (0). - /// - public ushort FirstMiniVersion; - - /// - /// The latest available miniversion for this file. If there are no miniversions, or they are not visible to the transaction - /// bound to the file handle, this field is zero (0). - /// - public ushort LatestMiniVersion; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains a list of files locked by a transacted writer. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transaction_locked_files typedef struct - // _TXFS_LIST_TRANSACTION_LOCKED_FILES { GUID KtmTransaction; DWORDLONG NumberOfFiles; DWORDLONG BufferSizeRequired; DWORDLONG - // Offset; } TXFS_LIST_TRANSACTION_LOCKED_FILES, *PTXFS_LIST_TRANSACTION_LOCKED_FILES; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTION_LOCKED_FILES")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_LIST_TRANSACTION_LOCKED_FILES - { - /// The KTM transaction to enumerate locked files for in this RM. - public Guid KtmTransaction; - - /// The number of files involved for the specified transaction on this resource manager. - public ulong NumberOfFiles; - - /// - /// The length of the buffer required to hold the complete list of files at the time of this call. This is not guaranteed to be - /// the same length as any other subsequent call. - /// - public ulong BufferSizeRequired; - - /// - /// The offset from the beginning of this structure to the beginning of the first TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY structure. - /// - public ulong Offset; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains information about a locked transaction. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transaction_locked_files_entry typedef struct - // _TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY { DWORDLONG Offset; DWORD NameFlags; LONGLONG FileId; DWORD Reserved1; DWORD Reserved2; - // LONGLONG Reserved3; WCHAR FileName[1]; } TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY, *PTXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY")] - [VanaraMarshaler(typeof(AnySizeStringMarshaler), "*")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY - { - /// The offset, in bytes, from the beginning of the TXFS_LIST_TRANSACTION_LOCKED_FILES structure to the next TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY. - public ulong Offset; - - /// - /// - /// Indicates whether the current name was deleted or created in the current transaction. Note that both flags may appear if the - /// name was both created and deleted in the same transaction. In that case, the FileName member will contain only an - /// empty string with a terminating null character ("\0") because there is no meaningful name to report. - /// - /// TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY_FLAG_CREATED (0x00000001) - /// TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY_FLAG_DELETED (0x00000002) - /// - public uint NameFlags; - - /// The NTFS File ID of the file. - public long FileId; - - /// Reserved. Specify zero. - public uint Reserved1; - - /// Reserved. Specify zero. - public uint Reserved2; - - /// Reserved. Specify zero. - public long Reserved3; - - /// The path to the file, relative to the volume root. The file name is a NULL-terminated Unicode string. - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] - public string FileName; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains a list of transactions. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transactions typedef struct - // _TXFS_LIST_TRANSACTIONS { DWORDLONG NumberOfTransactions; DWORDLONG BufferSizeRequired; } TXFS_LIST_TRANSACTIONS, *PTXFS_LIST_TRANSACTIONS; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTIONS")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_LIST_TRANSACTIONS - { - /// The number of transactions for this resource manager. - public ulong NumberOfTransactions; - - /// - /// The length of the buffer required to hold the complete list of transactions at the time of this call. The number of - /// transactions returned from one call to the next can change depending on the number of active transactions at any given point - /// in time. If this call returns a request for a larger buffer, that size may or may not be adequate for the next call, based - /// on the number of active transactions at the time of the next call. - /// - public ulong BufferSizeRequired; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains information about a transaction. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_list_transactions_entry typedef struct - // _TXFS_LIST_TRANSACTIONS_ENTRY { GUID TransactionId; DWORD TransactionState; DWORD Reserved1; DWORD Reserved2; LONGLONG Reserved3; - // } TXFS_LIST_TRANSACTIONS_ENTRY, *PTXFS_LIST_TRANSACTIONS_ENTRY; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_LIST_TRANSACTIONS_ENTRY")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_LIST_TRANSACTIONS_ENTRY - { - /// The GUID of the transaction. - public Guid TransactionId; - - /// The current state of the transaction. - public uint TransactionState; - - /// Reserved. - public uint Reserved1; - - /// Reserved. - public uint Reserved2; - - /// Reserved. - public long Reserved3; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains the information required when modifying log parameters and logging mode for a secondary resource manager. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_modify_rm typedef struct _TXFS_MODIFY_RM { DWORD - // Flags; DWORD LogContainerCountMax; DWORD LogContainerCountMin; DWORD LogContainerCount; DWORD LogGrowthIncrement; DWORD - // LogAutoShrinkPercentage; DWORDLONG Reserved; WORD LoggingMode; } TXFS_MODIFY_RM, *PTXFS_MODIFY_RM; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_MODIFY_RM")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_MODIFY_RM - { - /// - /// The log parameters to be set. - /// This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// TXFS_RM_FLAG_LOGGING_MODE 0x00000001 - /// - /// If this flag is set, the LoggingMode member of this structure is being used. If the flag is not set, the LoggingMode member - /// is ignored. - /// - /// - /// - /// TXFS_RM_FLAG_RENAME_RM 0x00000002 - /// If this flag is set, the RM is instructed to rename itself (creating a new GUID). - /// - /// - /// TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MAX 0x00000004 - /// - /// If this flag is set, the LogContainerCountMax member is being used. If the flag is not set, the LogContainerCountMax member - /// is ignored. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MIN 0x00000008 - /// - /// If this flag is set, the LogContainerCountMin member is being used. If the flag is not set, the LogContainerCountMin member - /// is ignored. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS 0x00000010 - /// - /// If this flag is set, the LogGrowthIncrement member is being used. If the flag is not set, the LogGrowthIncrement member is - /// ignored. This flag indicates that the log should grow by the number of containers specified in the LogGrowthIncrement - /// member. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT 0x00000020 - /// - /// If this flag is set, the LogGrowthIncrement member is being used. If the flag is not set, the LogGrowthIncrement member is - /// ignored. This flag indicates that the log should grow by the percentage of the log size specified in the LogGrowthIncrement - /// member. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_AUTO_SHRINK_PERCENTAGE 0x00000040 - /// - /// If this flag is set, the LogAutoShrinkPercentage member is being used. If the flag is not set, the LogAutoShrinkPercentage - /// is ignored. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX 0x00000080 - /// - /// If this flag is set, the RM is instructed to allow its log to grow without bounds. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN 0x00000100 - /// - /// If this flag is set, the RM is instructed to allow its log to shrink the log to only two containers. This flag is mutually - /// exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX. - /// - /// - /// - /// TXFS_RM_FLAG_GROW_LOG 0x00000400 - /// - /// If this flag is set, the log is instructed to immediately increase its size to the size specified in LogContainerCount. If - /// the flag is not set, the LogContainerCount is ignored. - /// - /// - /// - /// TXFS_RM_FLAG_SHRINK_LOG 0x00000800 - /// - /// If this flag is set, the log is instructed to immediately decrease its size to the size specified in LogContainerCount. If - /// this flag and TXFS_RM_FLAG_ENFORCE_MINIMUM_SIZE are set, the log is instructed to shrink to its minimum allowable size, and - /// LogContainerCount is ignored. - /// - /// - /// - /// TXFS_RM_FLAG_ENFORCE_MINIMUM_SIZE 0x00001000 - /// - /// If this flag and TXFS_RM_FLAG_SHRINK_LOG are set, the log is instructed to shrink to its minimum allowable size, and - /// LogContainerCount is ignored. If this flag is set, the TXFS_RM_FLAG_SHRINK_LOG must be set. - /// - /// - /// - /// TXFS_RM_FLAG_PRESERVE_CHANGES 0x00002000 - /// - /// If this flag is set, the log is instructed to preserve the changes on disk. If this flag is not set, any changes made are - /// temporary (that is, until the RM is shut down and restarted). - /// - /// - /// - /// TXFS_RM_FLAG_RESET_RM_AT_NEXT_START 0x00004000 - /// - /// This flag is only valid for default RMs, not secondary RMs. If this flag is set, the RM is instructed to reset itself the - /// next time it is started. The log and the associated metadata are deleted. - /// - /// - /// - /// TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START 0x00008000 - /// - /// This flag is only valid for default RMs, not secondary RMs. If this flag is set, a previous call to FSCTL_TXFS_MODIFY_RM is - /// canceled with the TXFS_RM_FLAG_RESET_RM_AT_NEXT_START flag set. - /// - /// - /// - /// TXFS_RM_FLAG_PREFER_CONSISTENCY 0x00010000 - /// - /// Indicates that the RM is to prefer transaction consistency over system availability. This flag is mutually exclusive with - /// TXFS_RM_FLAG_PREFER_AVAILABILITY and is not supported by the default RM on the system volume. - /// - /// - /// - /// TXFS_RM_FLAG_PREFER_AVAILABILITY 0x00020000 - /// - /// Indicates that the RM is to prefer system availability over transaction consistency. This flag is mutually exclusive with - /// TXFS_RM_FLAG_PREFER_CONSISTENCY and is forced by the default RM on the system volume. - /// - /// - /// - /// - public TXFS_RM_FLAG Flags; - - /// The maximum size of the log, in containers. - public uint LogContainerCountMax; - - /// The minimum size of the log, in containers. - public uint LogContainerCountMin; - - /// The actual size of the log, in containers. - public uint LogContainerCount; - - /// The number of containers or percentage of space that should be added to the log. - public uint LogGrowthIncrement; - - /// - /// The percentage of log space to keep free. This member is used when the TXFS_RM_FLAG_LOG_AUTO_SHRINK_PERCENTAGE flag - /// is used, and instructs the log to automatically shrink itself, so no more than LogAutoShrinkPercentage of the log is - /// free at any given time. - /// - public uint LogAutoShrinkPercentage; - - /// Reserved. - public ulong Reserved; - - /// - /// The current logging mode. - /// - /// - /// Value - /// Meaning - /// - /// - /// TXFS_LOGGING_MODE_SIMPLE 1 - /// Simple logging is used. - /// - /// - /// TXFS_LOGGING_MODE_FULL 2 - /// Full logging is used - /// - /// - /// - public TXFS_LOGGING_MODE LoggingMode; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains information about the resource manager (RM). - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_query_rm_information typedef struct - // _TXFS_QUERY_RM_INFORMATION { DWORD BytesRequired; DWORDLONG TailLsn; DWORDLONG CurrentLsn; DWORDLONG ArchiveTailLsn; DWORDLONG - // LogContainerSize; LARGE_INTEGER HighestVirtualClock; DWORD LogContainerCount; DWORD LogContainerCountMax; DWORD - // LogContainerCountMin; DWORD LogGrowthIncrement; DWORD LogAutoShrinkPercentage; DWORD Flags; WORD LoggingMode; WORD Reserved; - // DWORD RmState; DWORDLONG LogCapacity; DWORDLONG LogFree; DWORDLONG TopsSize; DWORDLONG TopsUsed; DWORDLONG TransactionCount; - // DWORDLONG OnePCCount; DWORDLONG TwoPCCount; DWORDLONG NumberLogFileFull; DWORDLONG OldestTransactionAge; GUID RMName; DWORD - // TmLogPathOffset; } TXFS_QUERY_RM_INFORMATION, *PTXFS_QUERY_RM_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_QUERY_RM_INFORMATION")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_QUERY_RM_INFORMATION - { - /// - /// If FSCTL_TXFS_QUERY_RM_INFORMATION returns ERROR_BUFFER_TOO_SMALL, this member specifies the minimum number of bytes - /// needed to return the information requested, including the NULL terminating character. - /// - public uint BytesRequired; - - /// The oldest log sequence number (LSN) currently used by the RM. - public ulong TailLsn; - - /// The LSN most recently used by the RM in its log. - public ulong CurrentLsn; - - /// The LSN of the archive tail of the log. - public ulong ArchiveTailLsn; - - /// The actual size of a log container, in bytes. - public ulong LogContainerSize; - - /// The highest timestamp associated with a log record. - public long HighestVirtualClock; - - /// The number of log containers. - public uint LogContainerCount; - - /// The maximum number of log containers. - public uint LogContainerCountMax; - - /// The minimum number of containers allowed in the log. - public uint LogContainerCountMin; - - /// - /// The amount the log will grow by, which is either a number of containers or percentage of the log size; the growth type used - /// is specified by the flags set in Flags member. - /// - public uint LogGrowthIncrement; - - /// - /// If the auto-shrink policy is active, this member specifies the maximum allowable amount of free space in the log. If this - /// member is zero, the auto-shrink policy is not active. - /// - public uint LogAutoShrinkPercentage; - - /// - /// This member can be one or more of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MIN 0x00000008 - /// If the flag is set, the RM's log is allowed to shrink as far as possible. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX. - /// - /// - /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS 0x00000010 - /// - /// Indicates the type of value in LogGrowthIncrement. If this flag is set, LogGrowthIncrement is a number of containers. This - /// flag is mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT 0x00000020 - /// - /// Indicates the type of value in LogGrowthIncrement. If this flag is set, LogGrowthIncrement is a percentage. This flag is - /// mutually exclusive with TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS. - /// - /// - /// - /// TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX 0x00000080 - /// Indicates that the RM's log can grow without bounds. This flag is mutually exclusive with TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN. - /// - /// - /// TXFS_RM_FLAG_RESET_RM_AT_NEXT_START 0x00004000 - /// - /// Indicates the current state of the RM reset flag. If this is set, the RM will reset itself the next time it is started. This - /// flag is only valid for default RMs, not secondary RMs. This flag is mutually exclusive with TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START. - /// - /// - /// - /// TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START 0x00008000 - /// - /// Indicates the current state of the RM reset flag. If this is set, the RM will not reset itself the next time it is started. - /// This flag is only valid for default RMs, not secondary RMs. This flag is mutually exclusive with TXFS_RM_FLAG_RESET_RM_AT_NEXT_START. - /// - /// - /// - /// TXFS_RM_FLAG_PREFER_CONSISTENCY 0x00010000 - /// - /// Indicates that the RM is to prefer transaction consistency over system availability. This flag is mutually exclusive with - /// TXFS_RM_FLAG_PREFER_AVAILABILITY and is not supported by the default RM on the system volume. - /// - /// - /// - /// TXFS_RM_FLAG_PREFER_AVAILABILITY 0x00020000 - /// - /// Indicates that the RM is to prefer system availability over transaction consistency. This flag is mutually exclusive with - /// TXFS_RM_FLAG_PREFER_CONSISTENCY and is forced by the default RM on the system volume. - /// - /// - /// - /// - public TXFS_RM_FLAG Flags; - - /// - /// The current logging mode. - /// - /// - /// Value - /// Meaning - /// - /// - /// TXFS_LOGGING_MODE_SIMPLE 1 - /// Simple logging is used. - /// - /// - /// TXFS_LOGGING_MODE_FULL 2 - /// Full logging is used - /// - /// - /// - public TXFS_LOGGING_MODE LoggingMode; - - /// Reserved. - public ushort Reserved; - - /// - /// The state of the RM. Valid values are as follows. - /// - /// - /// Value - /// Meaning - /// - /// - /// TXFS_RM_STATE_NOT_STARTED 0 - /// The RM is not yet started. - /// - /// - /// TXFS_RM_STATE_STARTING 1 - /// The RM is starting. - /// - /// - /// TXFS_RM_STATE_ACTIVE 2 - /// The RM is active and ready to accept transactions. - /// - /// - /// TXFS_RM_STATE_SHUTTING_DOWN 3 - /// The RM is shutting down. - /// - /// - /// - public TXFS_RM_STATE RmState; - - /// The total capacity of the log, in bytes. - public ulong LogCapacity; - - /// The number of bytes free in the log. - public ulong LogFree; - - /// The size of the $Tops file, in bytes. - public ulong TopsSize; - - /// The amount of the $Tops file that is in use, in bytes. - public ulong TopsUsed; - - /// The number of active transactions, at the time the query was issued. - public ulong TransactionCount; - - /// The number of single-phase commit operations that have occurred on this RM. - public ulong OnePCCount; - - /// The number of two-phase commit operations that have occurred on this RM. - public ulong TwoPCCount; - - /// The number of times this RM's log has become full. - public ulong NumberLogFileFull; - - /// The length of the oldest active transaction, in milliseconds. - public ulong OldestTransactionAge; - - /// The GUID that indicates the name of this RM. - public Guid RMName; - - /// - /// The offset from the beginning of this structure to a NULL-terminated Unicode string that contains the path to the - /// TM's log. - /// - public uint TmLogPathOffset; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains a Transactional NTFS (TxF) specific structure. This information should only be used when calling TXFS_WRITE_BACKUP_INFORMATION. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_read_backup_information_out typedef struct - // _TXFS_READ_BACKUP_INFORMATION_OUT { union { DWORD BufferLength; BYTE Buffer[1]; } DUMMYUNIONNAME; } - // TXFS_READ_BACKUP_INFORMATION_OUT, *PTXFS_READ_BACKUP_INFORMATION_OUT; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_READ_BACKUP_INFORMATION_OUT")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "*")] - [StructLayout(LayoutKind.Sequential, Size = 4)] - public struct TXFS_READ_BACKUP_INFORMATION_OUT - { - /// The buffer for the data. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] Buffer; - - /// If the buffer is not large enough, this member receives the required buffer size. - public uint BufferLength => Buffer?.Length >= 4 ? BitConverter.ToUInt32(Buffer, 0) : 0; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains the flag that indicates whether transactions were active or not when a snapshot was taken. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_transaction_active_info typedef struct - // _TXFS_TRANSACTION_ACTIVE_INFO { BOOLEAN TransactionsActiveAtSnapshot; } TXFS_TRANSACTION_ACTIVE_INFO, *PTXFS_TRANSACTION_ACTIVE_INFO; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_TRANSACTION_ACTIVE_INFO")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_TRANSACTION_ACTIVE_INFO - { - /// - /// This member is TRUE if the mounted snapshot volume had active transactions when the snapshot was taken; and - /// FALSE otherwise. - /// - [MarshalAs(UnmanagedType.U1)] - public bool TransactionsActiveAtSnapshot; - } - - /// - /// - /// [Microsoft strongly recommends developers utilize alternative means to achieve your application’s needs. Many scenarios that TxF - /// was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available - /// in future versions of Microsoft Windows. For more information, and alternatives to TxF, please see Alternatives to using - /// Transactional NTFS.] - /// - /// Contains a Transactional NTFS (TxF) specific structure. This information should only be used when calling TXFS_WRITE_BACKUP_INFORMATION. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-txfs_write_backup_information typedef struct - // _TXFS_WRITE_BACKUP_INFORMATION { BYTE Buffer[1]; } TXFS_WRITE_BACKUP_INFORMATION, *PTXFS_WRITE_BACKUP_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._TXFS_WRITE_BACKUP_INFORMATION")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "*")] - [StructLayout(LayoutKind.Sequential)] - public struct TXFS_WRITE_BACKUP_INFORMATION - { - /// The buffer for the data. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] Buffer; - } - - /// Contains information used to verify a disk extent. It is the output buffer for the IOCTL_DISK_VERIFY control code. - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-verify_information typedef struct _VERIFY_INFORMATION { - // LARGE_INTEGER StartingOffset; DWORD Length; } VERIFY_INFORMATION, *PVERIFY_INFORMATION; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._VERIFY_INFORMATION")] - [StructLayout(LayoutKind.Sequential)] - public struct VERIFY_INFORMATION - { - /// The starting offset of the disk extent. - public long StartingOffset; - - /// The length of the disk extent, in bytes. - public uint Length; - } - - /// - /// Represents the occupied and available clusters on a disk. This structure is the output buffer for the FSCTL_GET_VOLUME_BITMAP - /// control code. - /// - /// - /// The BitmapSize member is the number of clusters on the volume starting from the starting LCN returned in the - /// StartingLcn member of this structure. For example, suppose there are 0xD3F7 clusters on the volume. If you start the - /// bitmap query at LCN 0xA007, then both the FAT and NTFS file systems will round down the returned starting LCN to LCN 0xA000. The - /// value returned in the BitmapSize member will be (0xD3F7 – 0xA000), or 0x33F7. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-volume_bitmap_buffer typedef struct { LARGE_INTEGER - // StartingLcn; LARGE_INTEGER BitmapSize; BYTE Buffer[1]; } VOLUME_BITMAP_BUFFER, *PVOLUME_BITMAP_BUFFER; - [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl.__unnamed_struct_6")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(BitmapSize))] - [StructLayout(LayoutKind.Sequential)] - public struct VOLUME_BITMAP_BUFFER - { - /// Starting LCN requested as an input to the operation. - public long StartingLcn; - - /// - /// The number of clusters on the volume, starting from the starting LCN returned in the StartingLcn member of this - /// structure. See the following Remarks section for details. - /// - public long BitmapSize; - - /// - /// Array of bytes containing the bitmap that the operation returns. The bitmap is bitwise from bit zero of the bitmap to the - /// end. Thus, starting at the requested cluster, the bitmap goes from bit 0 of byte 0, bit 1 of byte 0 ... bit 7 of byte 0, bit - /// 0 of byte 1, and so on. The value 1 indicates that the cluster is allocated (in use). The value 0 indicates that the cluster - /// is not allocated (free). - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public byte[] Buffer; + Version = sdd.Version, + DeviceType = sdd.DeviceType, + DeviceTypeModifier = sdd.DeviceTypeModifier, + RemovableMedia = sdd.RemovableMedia, + CommandQueueing = sdd.CommandQueueing, + VendorId = sdd.VendorIdOffset == 0 ? null : Marshal.PtrToStringAnsi(pNativeData.Offset(sdd.VendorIdOffset))!, + ProductId = sdd.ProductIdOffset == 0 ? null : Marshal.PtrToStringAnsi(pNativeData.Offset(sdd.ProductIdOffset))!, + ProductRevision = sdd.ProductRevisionOffset == 0 ? null : Marshal.PtrToStringAnsi(pNativeData.Offset(sdd.ProductRevisionOffset))!, + SerialNumber = sdd.SerialNumberOffset == 0 ? null : Marshal.PtrToStringAnsi(pNativeData.Offset(sdd.SerialNumberOffset))!, + BusType = sdd.BusType, + RawDeviceProperties = pNativeData.Offset(propOffset.Value).ToArray((int)sdd.RawPropertiesLength)!, + }; } } } \ No newline at end of file diff --git a/UnitTests/PInvoke/Kernel32/IoApiSetTests.cs b/UnitTests/PInvoke/Kernel32/IoApiSetTests.cs index 157ec87b..1b0acf4a 100644 --- a/UnitTests/PInvoke/Kernel32/IoApiSetTests.cs +++ b/UnitTests/PInvoke/Kernel32/IoApiSetTests.cs @@ -1,43 +1,111 @@ using NUnit.Framework; using System; -using System.Runtime.InteropServices; -using System.Text; -using Vanara.InteropServices; -using static Vanara.PInvoke.AdvApi32; +using System.IO; +using Vanara.PInvoke; +using Vanara.PInvoke.Tests; using static Vanara.PInvoke.Kernel32; +using FileAccess = Vanara.PInvoke.Kernel32.FileAccess; -namespace Vanara.PInvoke.Tests +namespace Kernel32; + +[TestFixture] +public class IoApiSetTests { - [TestFixture] - public class IoApiSetTests + private const string vol = @"\\.\PhysicalDrive0"; + + [Test] + public void DeviceIoControlNoInOutTest() { - [Test] - public void DeviceIoControlNoInOutTest() - { - using var hFile = CreateFile(@"\\.\C:", FileAccess.GENERIC_READ, System.IO.FileShare.Read, - default, System.IO.FileMode.Open, 0); - Assert.That(hFile, ResultIs.ValidHandle); - Assert.True(DeviceIoControl(hFile, IOControlCode.FSCTL_IS_VOLUME_MOUNTED)); - } - - [Test] - public void DeviceIoControlOutAndInTest() - { - using var hFile = CreateFile(TestCaseSources.WordDoc, FileAccess.GENERIC_READ | FileAccess.GENERIC_WRITE, - System.IO.FileShare.None, default, System.IO.FileMode.Open, 0); - Assert.That(hFile, ResultIs.ValidHandle); - - Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_GET_COMPRESSION, out COMPRESSION_FORMAT compr), ResultIs.Successful); - Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_SET_COMPRESSION, compr == COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE ? COMPRESSION_FORMAT.COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE), ResultIs.Successful); - Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_GET_COMPRESSION, out COMPRESSION_FORMAT newcompr), ResultIs.Successful); - Assert.That(compr, Is.Not.EqualTo(newcompr)); - Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_SET_COMPRESSION, compr), ResultIs.Successful); - } - - [Test] - public void StructSizeTest() - { - TestHelper.GetNestedStructSizes(typeof(Kernel32)).WriteValues(); - } + using SafeHFILE hFile = CreateFile(vol, FileAccess.GENERIC_READ, FileShare.Read, + default, FileMode.Open, 0); + Assert.That(hFile, ResultIs.ValidHandle); + Assert.False(DeviceIoControl(hFile, IOControlCode.FSCTL_IS_VOLUME_MOUNTED)); } + + [Test] + public void DeviceIoControlOutAndInTest() + { + using SafeHFILE hFile = CreateFile(TestCaseSources.WordDoc, FileAccess.GENERIC_READ | FileAccess.GENERIC_WRITE, + FileShare.None, default, FileMode.Open, 0); + Assert.That(hFile, ResultIs.ValidHandle); + + Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_GET_COMPRESSION, out COMPRESSION_FORMAT compr), ResultIs.Successful); + Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_SET_COMPRESSION, compr == COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE ? COMPRESSION_FORMAT.COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE), ResultIs.Successful); + Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_GET_COMPRESSION, out COMPRESSION_FORMAT newcompr), ResultIs.Successful); + Assert.That(compr, Is.Not.EqualTo(newcompr)); + Assert.That(DeviceIoControl(hFile, IOControlCode.FSCTL_SET_COMPRESSION, compr), ResultIs.Successful); + } + + [Test] + public void StorageAdapterSerialNumberPropertyTest() + { + TestContext.WriteLine(vol + ":"); + using SafeHFILE hdisk = CreateFile(vol.TrimEnd('\\'), 0, FileShare.ReadWrite, null, FileMode.Open, 0); + Assert.IsFalse(hdisk.IsInvalid); + + STORAGE_PROPERTY_QUERY query = new(STORAGE_PROPERTY_ID.StorageAdapterSerialNumberProperty); + Assert.That(DeviceIoControl(hdisk, IOControlCode.IOCTL_STORAGE_QUERY_PROPERTY, query, out STORAGE_ADAPTER_SERIAL_NUMBER outVar), + ResultIs.Successful); + outVar.WriteValues(); + + TestContext.WriteLine(new string('=', 20)); + } + + [Test] + public void StorageDeviceManagementStatusTest() + { + TestContext.WriteLine(vol + ":"); + using SafeHFILE hdisk = CreateFile(vol.TrimEnd('\\'), 0, FileShare.ReadWrite, null, FileMode.Open, 0); + Assert.IsFalse(hdisk.IsInvalid); + + STORAGE_PROPERTY_QUERY query = new(STORAGE_PROPERTY_ID.StorageDeviceManagementStatus); + Assert.That(DeviceIoControl(hdisk, IOControlCode.IOCTL_STORAGE_QUERY_PROPERTY, query, out STORAGE_DEVICE_MANAGEMENT_STATUS outVar), + ResultIs.Successful); + Assert.IsTrue(outVar.Health.HasFlag(STORAGE_DISK_HEALTH_STATUS.DiskHealthHealthy)); + Assert.That(outVar.NumberOfOperationalStatus, Is.GreaterThan(0)); + for (int i = 0; i < outVar.NumberOfOperationalStatus; i++) + Assert.IsTrue(outVar.OperationalStatus[i].HasFlag(STORAGE_DISK_OPERATIONAL_STATUS.DiskOpStatusOk)); + outVar.WriteValues(); + + TestContext.WriteLine(new string('=', 20)); + } + + // Courtesy of @elf2k00 + [Test] + public void StorageDevicePropertyTest() + { + TestContext.WriteLine(vol + ":"); + using SafeHFILE hdisk = CreateFile(vol.TrimEnd('\\'), 0, FileShare.ReadWrite, null, FileMode.Open, 0); + Assert.IsFalse(hdisk.IsInvalid); + + STORAGE_PROPERTY_QUERY query = new(STORAGE_PROPERTY_ID.StorageDeviceProperty); + Assert.That(DeviceIoControl(hdisk, IOControlCode.IOCTL_STORAGE_QUERY_PROPERTY, query, out STORAGE_DESCRIPTOR_HEADER sdh), + ResultIs.Successful); + Assert.That(DeviceIoControl(hdisk, IOControlCode.IOCTL_STORAGE_QUERY_PROPERTY, query, out STORAGE_DEVICE_DESCRIPTOR_MGD outVar, sdh.Size), + ResultIs.Successful); + Assert.IsTrue(Enum.IsDefined(typeof(STORAGE_BUS_TYPE), outVar.BusType)); + outVar.WriteValues(); + + TestContext.WriteLine(new string('=', 20)); + } + + [Test] + public void StorageDeviceUniqueIdPropertyTest() + { + TestContext.WriteLine(vol + ":"); + using SafeHFILE hdisk = CreateFile(vol.TrimEnd('\\'), 0, FileShare.ReadWrite, null, FileMode.Open, 0); + Assert.IsFalse(hdisk.IsInvalid); + + STORAGE_PROPERTY_QUERY query = new(STORAGE_PROPERTY_ID.StorageDeviceUniqueIdProperty); + Assert.That(DeviceIoControl(hdisk, IOControlCode.IOCTL_STORAGE_QUERY_PROPERTY, query, out STORAGE_DESCRIPTOR_HEADER sdh), + ResultIs.Successful); + Assert.That(DeviceIoControl(hdisk, IOControlCode.IOCTL_STORAGE_QUERY_PROPERTY, query, out STORAGE_DEVICE_UNIQUE_IDENTIFIER_MGD outVar, sdh.Size), + ResultIs.Successful); + outVar.WriteValues(); + + TestContext.WriteLine(new string('=', 20)); + } + + [Test] + public void StructSizeTest() => typeof(Vanara.PInvoke.Kernel32).GetNestedStructSizes().WriteValues(); } \ No newline at end of file