Skip to content

Commit

Permalink
Fixed #403
Browse files Browse the repository at this point in the history
  • Loading branch information
dahall committed Jun 2, 2023
1 parent 0ca079b commit 91490dc
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 10 deletions.
59 changes: 49 additions & 10 deletions PInvoke/Kernel32/WinIOCtl.Enums.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Vanara.InteropServices;

namespace Vanara.PInvoke
{
Expand Down Expand Up @@ -2119,28 +2120,33 @@ public enum STORAGE_PORT_CODE_SET
public enum STORAGE_PROPERTY_ID
{
/// <summary>Indicates that the caller is querying for the device descriptor, STORAGE_DEVICE_DESCRIPTOR.</summary>
StorageDeviceProperty,
[CorrespondingType(typeof(STORAGE_DEVICE_DESCRIPTOR))]
StorageDeviceProperty = 0,

/// <summary>Indicates that the caller is querying for the adapter descriptor, STORAGE_ADAPTER_DESCRIPTOR.</summary>
[CorrespondingType(typeof(STORAGE_ADAPTER_DESCRIPTOR))]
StorageAdapterProperty,

/// <summary>
/// Indicates that the caller is querying for the device identifiers provided with the SCSI vital product data pages. Data is
/// returned using the STORAGE_DEVICE_ID_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_DEVICE_ID_DESCRIPTOR))]
StorageDeviceIdProperty,

/// <summary>
/// Intended for driver usage. Indicates that the caller is querying for the unique device identifiers. Data is returned using
/// 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.
/// </summary>
[CorrespondingType(typeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER))]
StorageDeviceUniqueIdProperty,

/// <summary>
/// Indicates that the caller is querying for the write cache property. Data is returned using the STORAGE_WRITE_CACHE_PROPERTY
/// structure. Windows Server 2003 and Windows XP: This value is not supported before Windows Vista and Windows Server 2008.
/// </summary>
[CorrespondingType(typeof(STORAGE_WRITE_CACHE_PROPERTY))]
StorageDeviceWriteCacheProperty,

/// <summary>Reserved for system use.</summary>
Expand All @@ -2150,19 +2156,22 @@ public enum STORAGE_PROPERTY_ID
/// Indicates that the caller is querying for the access alignment descriptor, STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR. Windows
/// Server 2003 and Windows XP: This value is not supported before Windows Vista and Windows Server 2008.
/// </summary>
[CorrespondingType(typeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR))]
StorageAccessAlignmentProperty,

/// <summary>
/// Indicates that the caller is querying for the trim descriptor, DEVICE_TRIM_DESCRIPTOR. Windows Server 2008, Windows Vista,
/// Windows Server 2003 and Windows XP: This value is not supported before Windows 7 and Windows Server 2008 R2.
/// </summary>
[CorrespondingType(typeof(DEVICE_TRIM_DESCRIPTOR))]
StorageDeviceTrimProperty,

/// <summary>
/// Indicates that the caller is querying for the device power descriptor. Data is returned using the DEVICE_POWER_DESCRIPTOR
/// structure. Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This
/// value is not supported before Windows 8 and Windows Server 2012.
/// </summary>
[CorrespondingType(typeof(DEVICE_POWER_DESCRIPTOR))]
StorageDevicePowerProperty,

/// <summary>Reserved for system use.</summary>
Expand All @@ -2172,81 +2181,111 @@ public enum STORAGE_PROPERTY_ID
/// Indicates that the caller is querying for the medium product type. Data is returned using the
/// STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR))]
StorageDeviceMediumProductType,

/// <summary>
/// Indicates that the caller is querying for RPMB support and properties. Data is returned using the STORAGE_RPMB_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_RPMB_DESCRIPTOR))]
StorageAdapterRpmbProperty,

/// <summary/>
/// <summary>
/// Provides info on the storage adapter encryption capabilities. This is currently supported on UFS (Universal Flash Storage) adapters.
/// </summary>
StorageAdapterCryptoProperty,

/// <summary>
/// Indicates that the caller is querying for the device I/O capability property. Data is returned using the
/// DEVICE_IO_CAPABILITY_DESCRIPTOR structure.
/// </summary>
StorageDeviceIoCapabilityProperty,
[CorrespondingType(typeof(STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR))]
StorageDeviceIoCapabilityProperty = 48,

/// <summary>
/// Indicates that the caller is querying for protocol-specific data from the adapter. Data is returned using the
/// STORAGE_PROTOCOL_DATA_DESCRIPTOR structure. See the remarks for more info.
/// </summary>
[CorrespondingType(typeof(STORAGE_PROTOCOL_DATA_DESCRIPTOR))]
StorageAdapterProtocolSpecificProperty,

/// <summary>
/// Indicates that the caller is querying for protocol-specific data from the device. Data is returned using the
/// STORAGE_PROTOCOL_DATA_DESCRIPTOR structure. See the remarks for more info.
/// </summary>
[CorrespondingType(typeof(STORAGE_PROTOCOL_DATA_DESCRIPTOR))]
StorageDeviceProtocolSpecificProperty,

/// <summary>
/// Indicates that the caller is querying temperature data from the adapter. Data is returned using the
/// STORAGE_TEMPERATURE_DATA_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_TEMPERATURE_DATA_DESCRIPTOR))]
StorageAdapterTemperatureProperty,

/// <summary>
/// Indicates that the caller is querying for temperature data from the device. Data is returned using the
/// STORAGE_TEMPERATURE_DATA_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_TEMPERATURE_DATA_DESCRIPTOR))]
StorageDeviceTemperatureProperty,

/// <summary>
/// Indicates that the caller is querying for topology information from the adapter. Data is returned using the
/// STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR))]
StorageAdapterPhysicalTopologyProperty,

/// <summary>
/// Indicates that the caller is querying for topology information from the device. Data is returned using the
/// STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR))]
StorageDevicePhysicalTopologyProperty,

/// <summary>Reserved for future use.</summary>
StorageDeviceAttributesProperty,

/// <summary/>
/// <summary>Provides health information about the storage device (specifically for the persistent memory stack).</summary>
[CorrespondingType(typeof(STORAGE_DEVICE_MANAGEMENT_STATUS))]
StorageDeviceManagementStatus,

/// <summary/>
/// <summary>
/// Indicates that the caller is querying for the adapter serial number. Data is returned using the STORAGE_ADAPTER_SERIAL_NUMBER structure.
/// </summary>
[CorrespondingType(typeof(STORAGE_ADAPTER_SERIAL_NUMBER))]
StorageAdapterSerialNumberProperty,

/// <summary/>
/// <summary>Reserved for system use.</summary>
StorageDeviceLocationProperty,

/// <summary/>
/// <summary>Provides the non-uniform memory access (NUMA) node of the storage device.</summary>
StorageDeviceNumaProperty,

/// <summary/>
/// <summary>Reserved for system use.</summary>
StorageDeviceZonedDeviceProperty,

/// <summary/>
/// <summary>
/// Provides the unsafe shutdown count value used to determine if the device data might have been lost during a power loss event
/// (specifically for the persistent memory stack).
/// </summary>
StorageDeviceUnsafeShutdownCount,

/// <summary/>
/// <summary>
/// Provides info on how many bytes have been read/write from a solid-state drive (SSD). This property is supported only for
/// Non-Volatile Memory Express (NVMe) devices that implement a certain NVMe feature.
/// </summary>
StorageDeviceEnduranceProperty,

/// <summary>Provides info on the state of the LED associated with a storage device. This is a server-oriented feature.</summary>
StorageDeviceLedStateProperty,

/// <summary>Reserved for system use.</summary>
StorageDeviceSelfEncryptionProperty = 64,

/// <summary>Provides identification info for a storage device that can be physically replaced with a Field Replacement Unit (FRU).</summary>
StorageFruIdProperty
}

/// <summary>
Expand Down
204 changes: 204 additions & 0 deletions PInvoke/Kernel32/WinIOCtl.STORAGE_DEVICE_MANAGEMENT_STATUS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
using System.Runtime.InteropServices;
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;

private const int STORAGE_DEVICE_MAX_OPERATIONAL_STATUS = 16;

/// <summary>Constants for StorageDeviceManagementStatus</summary>
[PInvokeData("winioctl.h")]
public enum STORAGE_DISK_HEALTH_STATUS
{
DiskHealthUnknown = 0,
DiskHealthUnhealthy,
DiskHealthWarning,
DiskHealthHealthy,
DiskHealthMax,
}

/// <summary>Operational States</summary>
[PInvokeData("winioctl.h")]
public enum STORAGE_DISK_OPERATIONAL_STATUS
{
DiskOpStatusNone = 0,
DiskOpStatusUnknown,
DiskOpStatusOk,
DiskOpStatusPredictingFailure,
DiskOpStatusInService,
DiskOpStatusHardwareError,
DiskOpStatusNotUsable,
DiskOpStatusTransientError,
DiskOpStatusMissing,
}

/// <summary>Operational Reasons</summary>
[PInvokeData("winioctl.h")]
public enum STORAGE_OPERATIONAL_STATUS_REASON
{
DiskOpReasonUnknown = 0,
DiskOpReasonScsiSenseCode,
DiskOpReasonMedia,
DiskOpReasonIo,
DiskOpReasonThresholdExceeded,
DiskOpReasonLostData,
DiskOpReasonEnergySource,
DiskOpReasonConfiguration,
DiskOpReasonDeviceController,
DiskOpReasonMediaController,
DiskOpReasonComponent,
DiskOpReasonNVDIMM_N,
DiskOpReasonBackgroundOperation,
DiskOpReasonInvalidFirmware,
DiskOpReasonHealthCheck,
DiskOpReasonLostDataPersistence,
DiskOpReasonDisabledByPlatform,
DiskOpReasonLostWritePersistence,
DiskOpReasonDataPersistenceLossImminent,
DiskOpReasonWritePersistenceLossImminent,
DiskOpReasonMax,
}

/// <summary>
/// The NULL-terminated Unicode string of the adapter serial number for the StorageAdapterSerialNumberProperty as defined in STORAGE_PROPERTY_ID.
/// </summary>
// https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-storage_adapter_serial_number typedef struct
// _STORAGE_ADAPTER_SERIAL_NUMBER { DWORD Version; DWORD Size; WCHAR SerialNumber[STORAGE_ADAPTER_SERIAL_NUMBER_V1_MAX_LENGTH]; }
// STORAGE_ADAPTER_SERIAL_NUMBER, *PSTORAGE_ADAPTER_SERIAL_NUMBER;
[PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._STORAGE_ADAPTER_SERIAL_NUMBER")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STORAGE_ADAPTER_SERIAL_NUMBER
{
/// <summary>The version of this structure. The Size serves as the version.</summary>
public uint Version;

/// <summary>The size of this structure.</summary>
public uint Size;

/// <summary>The serial number.</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = STORAGE_ADAPTER_SERIAL_NUMBER_V1_MAX_LENGTH)]
public string SerialNumber;
}

/// <summary>Structure for STORAGE_PROPERTY_ID.StorageDeviceManagementStatus</summary>
[PInvokeData("winioctl.h")]
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<STORAGE_DEVICE_MANAGEMENT_STATUS>), nameof(NumberOfAdditionalReasons))]
[StructLayout(LayoutKind.Sequential)]
public struct STORAGE_DEVICE_MANAGEMENT_STATUS
{
/// <summary>Sizeof() of this structure serves as the version.</summary>
public uint Version;

/// <summary>
/// The total size of the structure, including operational status reasons that didn't fit in the caller's array. Callers should use
/// this field to learn how big the input buffer should be to contain all the available information.
/// </summary>
public uint Size;

/// <summary>Health status.</summary>
public STORAGE_DISK_HEALTH_STATUS Health;

/// <summary>The number of operational status returned.</summary>
public uint NumberOfOperationalStatus;

/// <summary>The number of additional reasons returned.</summary>
public uint NumberOfAdditionalReasons;

/// <summary>
/// Operational statuses. The primary operational status is the first element in the array. There are NumberOfOperationalStatus valid
/// elements in the array.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = STORAGE_DEVICE_MAX_OPERATIONAL_STATUS)]
public STORAGE_DISK_OPERATIONAL_STATUS[] OperationalStatus;

/// <summary>Additional reasons. There are NumberOfAdditionalReasons valid elements in the array.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public STORAGE_OPERATIONAL_REASON[] AdditionalReasons;
}

/// <summary>The STORAGE_DEVICE_UNIQUE_IDENTIFIER structure defines a device unique identifier (DUID).</summary>
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/storduid/ns-storduid-_storage_device_unique_identifier typedef struct
// _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
{
/// <summary>The version of the DUID.</summary>
public uint Version;

/// <summary>The size, in bytes, of the identifier header and the identifiers (IDs) that follow the header.</summary>
public uint Size;

/// <summary>
/// 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).
/// </summary>
public uint StorageDeviceIdOffset;

/// <summary>
/// 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.
/// </summary>
public uint StorageDeviceOffset;

/// <summary>The offset, in bytes, to the drive layout signature (STORAGE_DEVICE_LAYOUT_SIGNATURE).</summary>
public uint DriveLayoutSignatureOffset;
}

/// <summary>Additional reasons.</summary>
[PInvokeData("winioctl.h")]
[StructLayout(LayoutKind.Explicit)]
public struct STORAGE_OPERATIONAL_REASON
{
[FieldOffset(0)]
public uint Version;

[FieldOffset(4)]
public uint Size;

[FieldOffset(8)]
public STORAGE_OPERATIONAL_STATUS_REASON Reason;

[FieldOffset(12)]
public RawBytesUnion RawBytes;

/// <summary>This is the format if Reason == DiskOpReasonScsiSenseCode.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct ScsiSenseKeyStruct
{
public byte SenseKey;
public byte ASC;
public byte ASCQ;
public byte Reserved;
}

/// <summary>This is the format if Reason == DiskOpReasonNVDIMM_N.</summary>
[StructLayout(LayoutKind.Sequential)]
public unsafe struct NVDIMM_NStruct
{
public byte CriticalHealth;
public fixed byte ModuleHealth[2];
public byte ErrorThresholdStatus;
}

[StructLayout(LayoutKind.Explicit)]
public struct RawBytesUnion
{
/// <summary>This is the format if Reason == DiskOpReasonScsiSenseCode.</summary>
[FieldOffset(0)]
public ScsiSenseKeyStruct ScsiSenseKey;

/// <summary>This is the format if Reason == DiskOpReasonNVDIMM_N.</summary>
[FieldOffset(0)]
public NVDIMM_NStruct NVDIMM_N;

[FieldOffset(0)]
public uint AsUlong;
}
}
}

0 comments on commit 91490dc

Please sign in to comment.