You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取NVMe硬盘的真实序列号?

解决Delphi中获取NVMe真实序列号的问题

1. 修正IOCTL_STORAGE_QUERY_PROPERTY的调用参数

IOCTL_STORAGE_QUERY_PROPERTY默认返回通用存储设备信息,而非NVMe专属序列号。需指定协议特定属性获取NVMe原生数据:

  • 将STORAGE_PROPERTY_QUERY的PropertyId设为StorageDeviceProtocolSpecificProperty
  • QueryType设为PropertyStandardQuery
  • 在AdditionalParameters中填充STORAGE_PROTOCOL_SPECIFIC_DATA,指定ProtocolType为ProtocolTypeNvme,DataType为NVMeDataTypeIdentify(对应NVMe的Identify命令)

2. 严格匹配Windows API的Delphi结构体定义

NVMe相关结构体的字节布局必须和C语言完全一致,否则会解析错误。关键结构体示例:

type
  STORAGE_PROTOCOL_SPECIFIC_DATA = packed record
    ProtocolType: DWORD;
    DataType: DWORD;
    ProtocolDataRequestValue: DWORD;
    ProtocolDataRequestSubValue: DWORD;
    ProtocolDataOffset: DWORD;
    ProtocolDataLength: DWORD;
    FixedProtocolReturnData: array[0..31] of Byte;
  end;

  NVME_IDENTIFY_NAMESPACE_DATA = packed record
    NamespaceSize: UInt64;
    Capacity: UInt64;
    LBAFormat: array[0..15] of Byte;
    SerialNumber: array[0..29] of AnsiChar; // NVMe序列号为30字节ASCII
    // 省略其他无关字段
  end;

必须使用packed record保证结构体无额外对齐字节,避免字段偏移错误。

3. 直接发送NVMe Identify命令(替代方案)

若IOCTL_STORAGE_QUERY_PROPERTY仍无效,可通过IOCTL_SCSI_PASS_THROUGH_DIRECT直接发送NVMe Identify命令(命令码0x06):

  • 构造SCSI_PASS_THROUGH_DIRECT结构,指定CdbLength为16(NVMe命令CDB长度),数据方向设为DataIn
  • CDB数组填充命令参数:操作码0x06,目标命名空间ID
  • 用NVME_IDENTIFY_NAMESPACE_DATA作为接收缓冲区,提取SerialNumber字段

4. 常见排查点

  • 程序需以管理员权限运行:存储设备IOCTL调用需要高权限,普通权限可能返回错误或无效数据
  • 验证设备路径正确性:需打开NVMe物理设备路径(如\\.\PhysicalDriveX),而非逻辑盘符
  • 检查错误码:调用DeviceIoControl后,通过GetLastError()获取具体错误,定位参数或结构问题

内容的提问来源于stack exchange,提问作者yonni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 22:12:26