Files
2025-04-07 07:44:27 -07:00

1620 lines
52 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright (C) LibreHardwareMonitor and Contributors.
// All Rights Reserved.
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
// ReSharper disable InconsistentNaming
namespace LibreHardwareMonitor.Interop;
public class Kernel32
{
public const int ERROR_SERVICE_ALREADY_RUNNING = unchecked((int)0x80070420);
public const int ERROR_SERVICE_EXISTS = unchecked((int)0x80070431);
internal const uint BATTERY_UNKNOWN_CAPACITY = 0xFFFFFFFF;
internal const uint BATTERY_UNKNOWN_VOLTAGE = 0xFFFFFFFF;
internal const int BATTERY_UNKNOWN_RATE = unchecked((int)0x80000000);
internal const uint BATTERY_UNKNOWN_TIME = 0xFFFFFFFF;
internal const string IntelNVMeMiniPortSignature1 = "NvmeMini";
internal const string IntelNVMeMiniPortSignature2 = "IntelNvm";
internal const uint LPTR = 0x0000 | 0x0040;
internal const int MAX_DRIVE_ATTRIBUTES = 512;
internal const uint NVME_PASS_THROUGH_SRB_IO_CODE = 0xe0002000;
internal const byte SMART_LBA_HI = 0xC2;
internal const byte SMART_LBA_HI_EXCEEDED = 0x2C;
internal const byte SMART_LBA_MID = 0x4F;
internal const byte SMART_LBA_MID_EXCEEDED = 0xF4;
private const string DllName = "kernel32.dll";
[Flags]
public enum NVME_CRITICAL_WARNING
{
None = 0x00,
/// <summary>
/// If set to 1, then the available spare space has fallen below the threshold.
/// </summary>
AvailableSpaceLow = 0x01,
/// <summary>
/// If set to 1, then a temperature is above an over temperature threshold or below an under temperature threshold.
/// </summary>
TemperatureThreshold = 0x02,
/// <summary>
/// If set to 1, then the device reliability has been degraded due to significant media related errors or any internal error that degrades device reliability.
/// </summary>
ReliabilityDegraded = 0x04,
/// <summary>
/// If set to 1, then the media has been placed in read only mode
/// </summary>
ReadOnly = 0x08,
/// <summary>
/// If set to 1, then the volatile memory backup device has failed. This field is only valid if the controller has a volatile memory backup solution.
/// </summary>
VolatileMemoryBackupDeviceFailed = 0x10
}
/// <summary>
/// Create a instance from a struct with zero initialized memory arrays
/// no need to init every inner array with the correct sizes
/// </summary>
/// <typeparam name="T">type of struct that is needed</typeparam>
/// <returns></returns>
internal static T CreateStruct<T>()
{
int size = Marshal.SizeOf<T>();
IntPtr ptr = Marshal.AllocHGlobal(size);
RtlZeroMemory(ptr, size);
T result = Marshal.PtrToStructure<T>(ptr);
Marshal.FreeHGlobal(ptr);
return result;
}
internal static SafeFileHandle OpenDevice(string devicePath)
{
SafeFileHandle hDevice = CreateFile(devicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
if (hDevice.IsInvalid || hDevice.IsClosed)
hDevice = null;
return hDevice;
}
[DllImport(DllName, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern SafeFileHandle CreateFile
(
[MarshalAs(UnmanagedType.LPTStr)] string lpFileName,
[MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
[MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
IntPtr lpSecurityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
DFP dwIoControlCode,
ref SENDCMDINPARAMS lpInBuffer,
int nInBufferSize,
out ATTRIBUTECMDOUTPARAMS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
DFP dwIoControlCode,
ref SENDCMDINPARAMS lpInBuffer,
int nInBufferSize,
out THRESHOLDCMDOUTPARAMS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
DFP dwIoControlCode,
ref SENDCMDINPARAMS lpInBuffer,
int nInBufferSize,
out SENDCMDOUTPARAMS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
DFP dwIoControlCode,
ref SENDCMDINPARAMS lpInBuffer,
int nInBufferSize,
out IDENTIFYCMDOUTPARAMS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
DFP dwIoControlCode,
ref SENDCMDINPARAMS lpInBuffer,
int nInBufferSize,
out STATUSCMDOUTPARAMS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
IOCTL dwIoControlCode,
ref STORAGE_PROPERTY_QUERY lpInBuffer,
int nInBufferSize,
out STORAGE_DEVICE_DESCRIPTOR_HEADER lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
IOCTL dwIoControlCode,
ref STORAGE_PROPERTY_QUERY lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
IOCTL dwIoControlCode,
IntPtr lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeHandle hDevice,
IOCTL dwIoControlCode,
IntPtr lpInBuffer,
int nInBufferSize,
out DISK_PERFORMANCE lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_QUERY_INFORMATION lpInBuffer,
int nInBufferSize,
ref BATTERY_INFORMATION lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref uint lpInBuffer,
int nInBufferSize,
ref uint lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_WAIT_STATUS lpInBuffer,
int nInBufferSize,
ref BATTERY_STATUS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_QUERY_INFORMATION lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_QUERY_INFORMATION lpInBuffer,
int nInBufferSize,
ref uint lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr LocalAlloc(uint uFlags, ulong uBytes);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr LocalFree(IntPtr hMem);
[DllImport(DllName, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern void RtlZeroMemory(IntPtr Destination, int Length);
[DllImport(DllName, SetLastError = false)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern void RtlCopyMemory(IntPtr Destination, IntPtr Source, uint Length);
[DllImport(DllName, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport(DllName, ExactSpelling = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr GetProcAddress(IntPtr module, string methodName);
[DllImport(DllName)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr module);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr GetCurrentThread();
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern ushort GetActiveProcessorGroupCount();
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern bool SetThreadGroupAffinity(IntPtr thread, ref GROUP_AFFINITY groupAffinity, out GROUP_AFFINITY previousGroupAffinity);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, MEM flAllocationType, PAGE flProtect);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, MEM dwFreeType);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern bool DeviceIoControl
(
SafeFileHandle device,
IOControlCode ioControlCode,
[MarshalAs(UnmanagedType.AsAny)] [In] object inBuffer,
uint inBufferSize,
[MarshalAs(UnmanagedType.AsAny)] [Out] object outBuffer,
uint nOutBufferSize,
out uint bytesReturned,
IntPtr overlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern IntPtr CreateFile
(
string lpFileName,
uint dwDesiredAccess,
FileShare dwShareMode,
IntPtr lpSecurityAttributes,
FileMode dwCreationDisposition,
FileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern int EnumSystemFirmwareTables(Provider firmwareTableProviderSignature, IntPtr firmwareTableBuffer, int bufferSize);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern int GetSystemFirmwareTable(Provider firmwareTableProviderSignature, int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize);
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct GROUP_AFFINITY
{
public UIntPtr Mask;
[MarshalAs(UnmanagedType.U2)]
public ushort Group;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U2)]
public ushort[] Reserved;
}
internal enum DFP : uint
{
DFP_GET_VERSION = 0x00074080,
DFP_SEND_DRIVE_COMMAND = 0x0007c084,
DFP_RECEIVE_DRIVE_DATA = 0x0007c088
}
internal enum IOCTL : uint
{
IOCTL_SCSI_PASS_THROUGH = 0x04d004,
IOCTL_SCSI_MINIPORT = 0x04d008,
IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x04d014,
IOCTL_SCSI_GET_ADDRESS = 0x41018,
IOCTL_DISK_PERFORMANCE = 0x70020,
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400,
IOCTL_BATTERY_QUERY_TAG = 0x294040,
IOCTL_BATTERY_QUERY_INFORMATION = 0x294044,
IOCTL_BATTERY_QUERY_STATUS = 0x29404C
}
[Flags]
internal enum BatteryCapabilities : uint
{
BATTERY_CAPACITY_RELATIVE = 0x40000000,
BATTERY_IS_SHORT_TERM = 0x20000000,
BATTERY_SET_CHARGE_SUPPORTED = 0x00000001,
BATTERY_SET_DISCHARGE_SUPPORTED = 0x00000002,
BATTERY_SYSTEM_BATTERY = 0x80000000
}
internal enum BATTERY_QUERY_INFORMATION_LEVEL
{
BatteryInformation,
BatteryGranularityInformation,
BatteryTemperature,
BatteryEstimatedTime,
BatteryDeviceName,
BatteryManufactureDate,
BatteryManufactureName,
BatteryUniqueID,
BatterySerialNumber
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_QUERY_INFORMATION
{
public uint BatteryTag;
public BATTERY_QUERY_INFORMATION_LEVEL InformationLevel;
public uint AtRate;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_INFORMATION
{
public BatteryCapabilities Capabilities;
public byte Technology;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] Chemistry;
public uint DesignedCapacity;
public uint FullChargedCapacity;
public uint DefaultAlert1;
public uint DefaultAlert2;
public uint CriticalBias;
public uint CycleCount;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_WAIT_STATUS
{
public uint BatteryTag;
public uint Timeout;
public uint PowerState;
public uint LowCapacity;
public uint HighCapacity;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_STATUS
{
public uint PowerState;
public uint Capacity;
public uint Voltage;
public int Rate;
}
[Flags]
internal enum NVME_DIRECTION : uint
{
NVME_FROM_HOST_TO_DEV = 1,
NVME_FROM_DEV_TO_HOST = 2,
NVME_BI_DIRECTION = NVME_FROM_DEV_TO_HOST | NVME_FROM_HOST_TO_DEV
}
internal enum NVME_LOG_PAGES
{
NVME_LOG_PAGE_ERROR_INFO = 0x01,
NVME_LOG_PAGE_HEALTH_INFO = 0x02,
NVME_LOG_PAGE_FIRMWARE_SLOT_INFO = 0x03,
NVME_LOG_PAGE_CHANGED_NAMESPACE_LIST = 0x04,
NVME_LOG_PAGE_COMMAND_EFFECTS = 0x05,
NVME_LOG_PAGE_DEVICE_SELF_TEST = 0x06,
NVME_LOG_PAGE_TELEMETRY_HOST_INITIATED = 0x07,
NVME_LOG_PAGE_TELEMETRY_CTLR_INITIATED = 0x08,
NVME_LOG_PAGE_RESERVATION_NOTIFICATION = 0x80,
NVME_LOG_PAGE_SANITIZE_STATUS = 0x81
}
internal enum ATA_COMMAND : byte
{
/// <summary>
/// SMART data requested.
/// </summary>
ATA_SMART = 0xB0,
/// <summary>
/// Identify data is requested.
/// </summary>
ATA_IDENTIFY_DEVICE = 0xEC
}
internal enum SCSI_IOCTL_DATA
{
SCSI_IOCTL_DATA_OUT = 0,
SCSI_IOCTL_DATA_IN = 1,
SCSI_IOCTL_DATA_UNSPECIFIED = 2
}
internal enum SMART_FEATURES : byte
{
/// <summary>
/// Read SMART data.
/// </summary>
SMART_READ_DATA = 0xD0,
/// <summary>
/// Read SMART thresholds.
/// obsolete
/// </summary>
READ_THRESHOLDS = 0xD1,
/// <summary>
/// Autosave SMART data.
/// </summary>
ENABLE_DISABLE_AUTOSAVE = 0xD2,
/// <summary>
/// Save SMART attributes.
/// </summary>
SAVE_ATTRIBUTE_VALUES = 0xD3,
/// <summary>
/// Set SMART to offline immediately.
/// </summary>
EXECUTE_OFFLINE_DIAGS = 0xD4,
/// <summary>
/// Read SMART log.
/// </summary>
SMART_READ_LOG = 0xD5,
/// <summary>
/// Write SMART log.
/// </summary>
SMART_WRITE_LOG = 0xD6,
/// <summary>
/// Write SMART thresholds.
/// obsolete
/// </summary>
WRITE_THRESHOLDS = 0xD7,
/// <summary>
/// Enable SMART.
/// </summary>
ENABLE_SMART = 0xD8,
/// <summary>
/// Disable SMART.
/// </summary>
DISABLE_SMART = 0xD9,
/// <summary>
/// Get SMART status.
/// </summary>
RETURN_SMART_STATUS = 0xDA,
/// <summary>
/// Set SMART to offline automatically.
/// </summary>
ENABLE_DISABLE_AUTO_OFFLINE = 0xDB /* obsolete */
}
internal enum STORAGE_BUS_TYPE
{
BusTypeUnknown = 0x00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,
BusTypeRAID,
BusTypeiScsi,
BusTypeSas,
BusTypeSata,
BusTypeSd,
BusTypeMmc,
BusTypeVirtual,
BusTypeFileBackedVirtual,
BusTypeSpaces,
BusTypeNvme,
BusTypeSCM,
BusTypeMax,
BusTypeMaxReserved = 0x7F
}
internal enum STORAGE_PROPERTY_ID
{
StorageDeviceProperty = 0,
StorageAdapterProperty,
StorageDeviceIdProperty,
StorageDeviceUniqueIdProperty,
StorageDeviceWriteCacheProperty,
StorageMiniportProperty,
StorageAccessAlignmentProperty,
StorageDeviceSeekPenaltyProperty,
StorageDeviceTrimProperty,
StorageDeviceWriteAggregationProperty,
StorageDeviceDeviceTelemetryProperty,
StorageDeviceLBProvisioningProperty,
StorageDevicePowerProperty,
StorageDeviceCopyOffloadProperty,
StorageDeviceResiliencyProperty,
StorageDeviceMediumProductType,
StorageAdapterRpmbProperty,
StorageDeviceIoCapabilityProperty = 48,
StorageAdapterProtocolSpecificProperty,
StorageDeviceProtocolSpecificProperty,
StorageAdapterTemperatureProperty,
StorageDeviceTemperatureProperty,
StorageAdapterPhysicalTopologyProperty,
StorageDevicePhysicalTopologyProperty,
StorageDeviceAttributesProperty,
StorageDeviceManagementStatus,
StorageAdapterSerialNumberProperty,
StorageDeviceLocationProperty
}
internal enum STORAGE_PROTOCOL_NVME_DATA_TYPE
{
NVMeDataTypeUnknown = 0,
NVMeDataTypeIdentify,
NVMeDataTypeLogPage,
NVMeDataTypeFeature
}
internal enum STORAGE_PROTOCOL_NVME_PROTOCOL_DATA_REQUEST_VALUE
{
NVMeIdentifyCnsSpecificNamespace = 0,
NVMeIdentifyCnsController = 1,
NVMeIdentifyCnsActiveNamespaces = 2
}
internal enum STORAGE_PROTOCOL_TYPE
{
ProtocolTypeUnknown = 0x00,
ProtocolTypeScsi,
ProtocolTypeAta,
ProtocolTypeNvme,
ProtocolTypeSd,
ProtocolTypeProprietary = 0x7E,
ProtocolTypeMaxReserved = 0x7F
}
internal enum STORAGE_QUERY_TYPE
{
PropertyStandardQuery = 0,
PropertyExistsQuery,
PropertyMaskQuery,
PropertyQueryMaxDefined
}
[StructLayout(LayoutKind.Sequential)]
internal struct MEMORYSTATUSEX
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SMART_ATTRIBUTE
{
public byte Id;
public short Flags;
public byte CurrentValue;
public byte WorstValue;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] RawValue;
public byte Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SMART_THRESHOLD
{
public byte Id;
public byte Threshold;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct SENDCMDINPARAMS
{
public uint cBufferSize;
public IDEREGS irDriveRegs;
public byte bDriveNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] bReserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] dwReserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] bBuffer;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct IDEREGS
{
public SMART_FEATURES bFeaturesReg;
public byte bSectorCountReg;
public byte bSectorNumberReg;
public byte bCylLowReg;
public byte bCylHighReg;
public byte bDriveHeadReg;
public ATA_COMMAND bCommandReg;
public byte bReserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct DRIVERSTATUS
{
public byte bDriverError;
public byte bIDEError;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct SENDCMDOUTPARAMS
{
public uint cBufferSize;
public DRIVERSTATUS DriverStatus;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] bBuffer;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct ATTRIBUTECMDOUTPARAMS
{
public uint cBufferSize;
public DRIVERSTATUS DriverStatus;
public byte Version;
public byte Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
public SMART_ATTRIBUTE[] Attributes;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct THRESHOLDCMDOUTPARAMS
{
public uint cBufferSize;
public DRIVERSTATUS DriverStatus;
public byte Version;
public byte Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
public SMART_THRESHOLD[] Thresholds;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct STATUSCMDOUTPARAMS
{
public uint cBufferSize;
public DRIVERSTATUS DriverStatus;
public IDEREGS irDriveRegs;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct IDENTIFY_DATA
{
public ushort GeneralConfiguration;
public ushort NumberOfCylinders;
public ushort Reserved1;
public ushort NumberOfHeads;
public ushort UnformattedBytesPerTrack;
public ushort UnformattedBytesPerSector;
public ushort SectorsPerTrack;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public ushort[] VendorUnique;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] SerialNumber;
public ushort BufferType;
public ushort BufferSectorSize;
public ushort NumberOfEccBytes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] FirmwareRevision;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] ModelNumber;
public byte MaximumBlockTransfer;
public byte VendorUnique2;
public ushort DoubleWordIo;
public ushort Capabilities;
public ushort Reserved2;
public byte VendorUnique3;
public byte PioCycleTimingMode;
public byte VendorUnique4;
public byte DmaCycleTimingMode;
public ushort TranslationFieldsValid;
public ushort NumberOfCurrentCylinders;
public ushort NumberOfCurrentHeads;
public ushort CurrentSectorsPerTrack;
public uint CurrentSectorCapacity;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 197)]
public ushort[] Reserved3;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct IDENTIFYCMDOUTPARAMS
{
public uint cBufferSize;
public DRIVERSTATUS DriverStatus;
public IDENTIFY_DATA Identify;
}
[StructLayout(LayoutKind.Sequential)]
internal struct STORAGE_PROPERTY_QUERY
{
public STORAGE_PROPERTY_ID PropertyId;
public STORAGE_QUERY_TYPE QueryType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] AdditionalParameters;
}
[StructLayout(LayoutKind.Sequential)]
internal struct STORAGE_DEVICE_DESCRIPTOR_HEADER
{
public uint Version;
public uint Size;
}
[StructLayout(LayoutKind.Sequential)]
internal 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;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISK_PERFORMANCE
{
/// <nodoc />
public ulong BytesRead;
/// <nodoc />
public ulong BytesWritten;
/// <nodoc />
public ulong ReadTime;
/// <nodoc />
public ulong WriteTime;
/// <nodoc />
public ulong IdleTime;
/// <nodoc />
public uint ReadCount;
/// <nodoc />
public uint WriteCount;
/// <nodoc />
public uint QueueDepth;
/// <nodoc />
public uint SplitCount;
/// <nodoc />
public ulong QueryTime;
/// <nodoc />
public int StorageDeviceNumber;
/// <nodoc />
public long StorageManagerName0;
/// <nodoc />
public long StorageManagerName1;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SRB_IO_CONTROL
{
public uint HeaderLenght;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Signature;
public uint Timeout;
public uint ControlCode;
public uint ReturnCode;
public uint Length;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NVME_PASS_THROUGH_IOCTL
{
public SRB_IO_CONTROL srb;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public uint[] VendorSpecific;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public uint[] NVMeCmd;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] CplEntry;
public NVME_DIRECTION Direction;
public uint QueueId;
public uint DataBufferLen;
public uint MetaDataLen;
public uint ReturnBufferLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)]
public byte[] DataBuffer;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SCSI_PASS_THROUGH
{
[MarshalAs(UnmanagedType.U2)]
public ushort Length;
public byte ScsiStatus;
public byte PathId;
public byte TargetId;
public byte Lun;
public byte CdbLength;
public byte SenseInfoLength;
public byte DataIn;
public uint DataTransferLength;
public uint TimeOutValue;
public IntPtr DataBufferOffset;
public uint SenseInfoOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] Cdb;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SCSI_PASS_THROUGH_WITH_BUFFERS
{
public SCSI_PASS_THROUGH Spt;
public uint Filler;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] SenseBuf;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)]
public byte[] DataBuf;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NVME_POWER_STATE_DESC
{
/// <summary>
/// bit 0:15 Maximum Power (MP) in centiwatts
/// </summary>
public ushort MP;
/// <summary>
/// bit 16:23
/// </summary>
public byte Reserved0;
/// <summary>
/// bit 24 Max Power Scale (MPS), bit 25 Non-Operational State (NOPS)
/// </summary>
public byte MPS_NOPS;
/// <summary>
/// bit 32:63 Entry Latency (ENLAT) in microseconds
/// </summary>
public uint ENLAT;
/// <summary>
/// bit 64:95 Exit Latency (EXLAT) in microseconds
/// </summary>
public uint EXLAT;
/// <summary>
/// bit 96:100 Relative Read Throughput (RRT)
/// </summary>
public byte RRT;
/// <summary>
/// bit 104:108 Relative Read Latency (RRL)
/// </summary>
public byte RRL;
/// <summary>
/// bit 112:116 Relative Write Throughput (RWT)
/// </summary>
public byte RWT;
/// <summary>
/// bit 120:124 Relative Write Latency (RWL)
/// </summary>
public byte RWL;
/// <summary>
/// bit 128:143 Idle Power (IDLP)
/// </summary>
public ushort IDLP;
/// <summary>
/// bit 150:151 Idle Power Scale (IPS)
/// </summary>
public byte IPS;
/// <summary>
/// bit 152:159
/// </summary>
public byte Reserved7;
/// <summary>
/// bit 160:175 Active Power (ACTP)
/// </summary>
public ushort ACTP;
/// <summary>
/// bit 176:178 Active Power Workload (APW), bit 182:183 Active Power Scale (APS)
/// </summary>
public byte APW_APS;
/// <summary>
/// bit 184:255.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
public byte[] Reserved9;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NVME_IDENTIFY_CONTROLLER_DATA
{
/// <summary>
/// byte 0:1 M - PCI Vendor ID (VID)
/// </summary>
public ushort VID;
/// <summary>
/// byte 2:3 M - PCI Subsystem Vendor ID (SSVID)
/// </summary>
public ushort SSVID;
/// <summary>
/// byte 4: 23 M - Serial Number (SN)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] SN;
/// <summary>
/// byte 24:63 M - Model Number (MN)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] MN;
/// <summary>
/// byte 64:71 M - Firmware Revision (FR)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] FR;
/// <summary>
/// byte 72 M - Recommended Arbitration Burst (RAB)
/// </summary>
public byte RAB;
/// <summary>
/// byte 73:75 M - IEEE OUI Identifier (IEEE). Controller Vendor code.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] IEEE;
/// <summary>
/// byte 76 O - Controller Multi-Path I/O and Namespace Sharing Capabilities (CMIC)
/// </summary>
public byte CMIC;
/// <summary>
/// byte 77 M - Maximum Data Transfer Size (MDTS)
/// </summary>
public byte MDTS;
/// <summary>
/// byte 78:79 M - Controller ID (CNTLID)
/// </summary>
public ushort CNTLID;
/// <summary>
/// byte 80:83 M - Version (VER)
/// </summary>
public uint VER;
/// <summary>
/// byte 84:87 M - RTD3 Resume Latency (RTD3R)
/// </summary>
public uint RTD3R;
/// <summary>
/// byte 88:91 M - RTD3 Entry Latency (RTD3E)
/// </summary>
public uint RTD3E;
/// <summary>
/// byte 92:95 M - Optional Asynchronous Events Supported (OAES)
/// </summary>
public uint OAES;
/// <summary>
/// byte 96:239.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)]
public byte[] Reserved0;
/// <summary>
/// byte 240:255. Refer to the NVMe Management Interface Specification for definition.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] ReservedForManagement;
/// <summary>
/// byte 256:257 M - Optional Admin Command Support (OACS)
/// </summary>
public ushort OACS;
/// <summary>
/// byte 258 M - Abort Command Limit (ACL)
/// </summary>
public byte ACL;
/// <summary>
/// byte 259 M - Asynchronous Event Request Limit (AERL)
/// </summary>
public byte AERL;
/// <summary>
/// byte 260 M - Firmware Updates (FRMW)
/// </summary>
public byte FRMW;
/// <summary>
/// byte 261 M - Log Page Attributes (LPA)
/// </summary>
public byte LPA;
/// <summary>
/// byte 262 M - Error Log Page Entries (ELPE)
/// </summary>
public byte ELPE;
/// <summary>
/// byte 263 M - Number of Power States Support (NPSS)
/// </summary>
public byte NPSS;
/// <summary>
/// byte 264 M - Admin Vendor Specific Command Configuration (AVSCC)
/// </summary>
public byte AVSCC;
/// <summary>
/// byte 265 O - Autonomous Power State Transition Attributes (APSTA)
/// </summary>
public byte APSTA;
/// <summary>
/// byte 266:267 M - Warning Composite Temperature Threshold (WCTEMP)
/// </summary>
public ushort WCTEMP;
/// <summary>
/// byte 268:269 M - Critical Composite Temperature Threshold (CCTEMP)
/// </summary>
public ushort CCTEMP;
/// <summary>
/// byte 270:271 O - Maximum Time for Firmware Activation (MTFA)
/// </summary>
public ushort MTFA;
/// <summary>
/// byte 272:275 O - Host Memory Buffer Preferred Size (HMPRE)
/// </summary>
public uint HMPRE;
/// <summary>
/// byte 276:279 O - Host Memory Buffer Minimum Size (HMMIN)
/// </summary>
public uint HMMIN;
/// <summary>
/// byte 280:295 O - Total NVM Capacity (TNVMCAP)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] TNVMCAP;
/// <summary>
/// byte 296:311 O - Unallocated NVM Capacity (UNVMCAP)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] UNVMCAP;
/// <summary>
/// byte 312:315 O - Replay Protected Memory Block Support (RPMBS)
/// </summary>
public uint RPMBS;
/// <summary>
/// byte 316:511
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)]
public byte[] Reserved1;
/// <summary>
/// byte 512 M - Submission Queue Entry Size (SQES)
/// </summary>
public byte SQES;
/// <summary>
/// byte 513 M - Completion Queue Entry Size (CQES)
/// </summary>
public byte CQES;
/// <summary>
/// byte 514:515
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] Reserved2;
/// <summary>
/// byte 516:519 M - Number of Namespaces (NN)
/// </summary>
public uint NN;
/// <summary>
/// byte 520:521 M - Optional NVM Command Support (ONCS)
/// </summary>
public ushort ONCS;
/// <summary>
/// byte 522:523 M - Fused Operation Support (FUSES)
/// </summary>
public ushort FUSES;
/// <summary>
/// byte 524 M - Format NVM Attributes (FNA)
/// </summary>
public byte FNA;
/// <summary>
/// byte 525 M - Volatile Write Cache (VWC)
/// </summary>
public byte VWC;
/// <summary>
/// byte 526:527 M - Atomic Write Unit Normal (AWUN)
/// </summary>
public ushort AWUN;
/// <summary>
/// byte 528:529 M - Atomic Write Unit Power Fail (AWUPF)
/// </summary>
public ushort AWUPF;
/// <summary>
/// byte 530 M - NVM Vendor Specific Command Configuration (NVSCC)
/// </summary>
public byte NVSCC;
/// <summary>
/// byte 531
/// </summary>
public byte Reserved3;
/// <summary>
/// byte 532:533 O - Atomic Compare and Write Unit (ACWU)
/// </summary>
public ushort ACWU;
/// <summary>
/// byte 534:535
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] Reserved4;
/// <summary>
/// byte 536:539 O - SGL Support (SGLS)
/// </summary>
public uint SGLS;
/// <summary>
/// byte 540:703
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)]
public byte[] Reserved5;
/// <summary>
/// byte 704:2047
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1344)]
public byte[] Reserved6;
/// <summary>
/// byte 2048:3071 Power State Descriptors
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public NVME_POWER_STATE_DESC[] PDS;
/// <summary>
/// byte 3072:4095 Vendor Specific
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public byte[] VS;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NVME_HEALTH_INFO_LOG
{
/// <summary>
/// This field indicates critical warnings for the state of the controller.
/// Each bit corresponds to a critical warning type; multiple bits may be set.
/// </summary>
public byte CriticalWarning;
/// <summary>
/// Composite Temperature: Contains the temperature of the overall device (controller and NVM included) in units of Kelvin.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] CompositeTemp;
/// <summary>
/// Available Spare: Contains a normalized percentage (0 to 100%) of the remaining spare capacity available
/// </summary>
public byte AvailableSpare;
/// <summary>
/// Available Spare Threshold: When the Available Spare falls below the threshold indicated in this field,
/// an asynchronous event completion may occur. The value is indicated as a normalized percentage (0 to 100%).
/// </summary>
public byte AvailableSpareThreshold;
/// <summary>
/// Percentage Used: Contains a vendor specific estimate of the percentage of NVM subsystem life used based on
/// the actual usage and the manufacturers prediction of NVM life. A value of 100 indicates that the estimated endurance of
/// the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100.
/// </summary>
public byte PercentageUsed;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public byte[] Reserved1;
/// <summary>
/// Data Units Read: Contains the number of 512 byte data units the host has read from the controller;
/// this value does not include metadata. This value is reported in thousands
/// (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] DataUnitRead;
/// <summary>
/// Data Units Written: Contains the number of 512 byte data units the host has written to the controller;
/// this value does not include metadata. This value is reported in thousands
/// (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] DataUnitWritten;
/// <summary>
/// Host Read Commands: Contains the number of read commands completed by the controller.
/// For the NVM command set, this is the number of Compare and Read commands.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] HostReadCommands;
/// <summary>
/// Host Write Commands: Contains the number of write commands completed by the controller.
/// For the NVM command set, this is the number of Write commands.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] HostWriteCommands;
/// <summary>
/// Controller Busy Time: Contains the amount of time the controller is busy with I/O commands.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] ControllerBusyTime;
/// <summary>
/// Power Cycles: Contains the number of power cycles.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] PowerCycles;
/// <summary>
/// Power On Hours: Contains the number of power-on hours.
/// This does not include time that the controller was powered and in a low power state condition.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] PowerOnHours;
/// <summary>
/// Unsafe Shutdowns: Contains the number of unsafe shutdowns.
/// This count is incremented when a shutdown notification is not received prior to loss of power.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] UnsafeShutdowns;
/// <summary>
/// Media Errors: Contains the number of occurrences where the controller detected an unrecoverable data integrity error.
/// Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] MediaAndDataIntegrityErrors;
/// <summary>
/// Number of Error Information Log Entries: Contains the number of Error Information log entries over the life of the controller
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] NumberErrorInformationLogEntries;
/// <summary>
/// Warning Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite
/// Temperature Threshold.
/// </summary>
public uint WarningCompositeTemperatureTime;
/// <summary>
/// Critical Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than the Critical Composite Temperature
/// Threshold.
/// </summary>
public uint CriticalCompositeTemperatureTime;
/// <summary>
/// Contains the current temperature reported by temperature sensor 1-8.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public ushort[] TemperatureSensor;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 296)]
internal byte[] Reserved2;
}
[StructLayout(LayoutKind.Sequential)]
internal struct STORAGE_PROTOCOL_SPECIFIC_DATA
{
public STORAGE_PROTOCOL_TYPE ProtocolType;
public uint DataType;
public uint ProtocolDataRequestValue;
public uint ProtocolDataRequestSubValue;
public uint ProtocolDataOffset;
public uint ProtocolDataLength;
public uint FixedProtocolReturnData;
public uint ProtocolDataRequestSubValue2;
public uint ProtocolDataRequestSubValue3;
public uint Reserved;
}
[StructLayout(LayoutKind.Sequential)]
internal struct STORAGE_QUERY_BUFFER
{
public STORAGE_PROPERTY_ID PropertyId;
public STORAGE_QUERY_TYPE QueryType;
public STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecific;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)]
internal byte[] Buffer;
}
[Flags]
internal enum MEM : uint
{
MEM_COMMIT = 0x1000,
MEM_RESERVE = 0x2000,
MEM_DECOMMIT = 0x4000,
MEM_RELEASE = 0x8000,
MEM_RESET = 0x80000,
MEM_LARGE_PAGES = 0x20000000,
MEM_PHYSICAL = 0x400000,
MEM_TOP_DOWN = 0x100000,
MEM_WRITE_WATCH = 0x200000
}
[Flags]
internal enum PAGE : uint
{
PAGE_EXECUTE = 0x10,
PAGE_EXECUTE_READ = 0x20,
PAGE_EXECUTE_READWRITE = 0x40,
PAGE_EXECUTE_WRITECOPY = 0x80,
PAGE_NOACCESS = 0x01,
PAGE_READONLY = 0x02,
PAGE_READWRITE = 0x04,
PAGE_WRITECOPY = 0x08,
PAGE_GUARD = 0x100,
PAGE_NOCACHE = 0x200,
PAGE_WRITECOMBINE = 0x400
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct IOControlCode
{
/// <summary>
/// Gets the resulting IO control code.
/// </summary>
public uint Code { get; }
/// <summary>
/// Initializes a new instance of the <see cref="IOControlCode" /> struct.
/// </summary>
/// <param name="deviceType">Type of the device.</param>
/// <param name="function">The function.</param>
/// <param name="access">The access.</param>
public IOControlCode(uint deviceType, uint function, Access access) : this(deviceType, function, Method.Buffered, access)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="IOControlCode" /> struct.
/// </summary>
/// <param name="deviceType">Type of the device.</param>
/// <param name="function">The function.</param>
/// <param name="method">The method.</param>
/// <param name="access">The access.</param>
public IOControlCode(uint deviceType, uint function, Method method, Access access)
{
Code = (deviceType << 16) | ((uint)access << 14) | (function << 2) | (uint)method;
}
public enum Method : uint
{
Buffered = 0,
InDirect = 1,
OutDirect = 2,
Neither = 3
}
public enum Access : uint
{
Any = 0,
Read = 1,
Write = 2
}
}
internal enum Provider
{
ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I',
FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M',
RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B'
}
}