windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析

获取磁盘的序列号或者厂商号的时候,发现了IOCTL_STORAGE_QUERY_PROPERTY的请求可以设置Property参数,

// ==================STORAGE_DEVICE_ID_DESCRIPTOR==================== pPropertyQuery->PropertyId = STORAGE_PROPERTY_ID::StorageDeviceIdProperty; STORAGE_DEVICE_ID_DESCRIPTOR* pDeviceIdDescriptor = (STORAGE_DEVICE_ID_DESCRIPTOR*)new BYTE[sizeof(STORAGE_DEVICE_ID_DESCRIPTOR) + 400]; status = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, pPropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), pDeviceIdDescriptor, sizeof(STORAGE_DEVICE_ID_DESCRIPTOR) + 400, &returned, FALSE); //=====STORAGE_DEVICE_UNIQUE_IDENTIFIER包含STORAGE_DEVICE_ID_DESCRIPTOR======== pPropertyQuery->PropertyId = STORAGE_PROPERTY_ID::StorageDeviceUniqueIdProperty; STORAGE_DEVICE_UNIQUE_IDENTIFIER* pDeviceUniqueId = (STORAGE_DEVICE_UNIQUE_IDENTIFIER*)new BYTE[sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER) + 500]; memset(pDeviceUniqueId, 0, sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER) + 500); status = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, pPropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), pDeviceUniqueId, sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER) + 500, &returned, FALSE); STORAGE_DEVICE_ID_DESCRIPTOR* pDeviceID = (STORAGE_DEVICE_ID_DESCRIPTOR*)((char*)pDeviceUniqueId + pDeviceUniqueId->StorageDeviceIdOffset);

如上两种方式都可以获得STORAGE_DEVICE_ID_DESCRIPTOR,但是微软官方并没有这个结构里面Identifiers的解释。
STORAGE_DEVICE_ID_DESCRIPTOR - Win32 apps | Microsoft Docs
经过google百度的查询得知Identifiers是一个buffer,里面存储了NumberOfIdentifiers个数据结构。
windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析
文章图片

从微软官方定义的结构看
typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR { DWORD Version; DWORD Size; DWORD NumberOfIdentifiers; BYTEIdentifiers[1]; } STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR;

【windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析】0-3Bytes,4个字节,表示Version,值为0x00000010
4-7Bytes,4个字节,表示Size,值为0x00000064,也就是整个结构的大小
8-11Bytes,4个字节,表示NumberOfIdentifiers,值是0x00000001,也就是Identifiers对应的数据只包含一个数据结构
根据微软官方的提示,这个结构式SCSI的vpd数据,
参考如下资源
https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-CSVP/%5BMS-CSVP%5D-140213.doc
如果失效,可以前往CSDN下载,0积分
https://download.csdn.net/download/youyudexiaowangzi/84213040
此文件在msdn上 有如下下载链接,但是前往下载提示游客没有访问权限
[MS-CSVP]: SCSI-3 Persistent Reservations | Microsoft Docs
章节2.2.9
windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析
文章图片

章节2.2.10
windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析
文章图片

文章中对应SPC-3是SCSC Primary Command - 3,下载连接如下:
https://www.t10.org/ftp/t10/document.08/08-309r0.pdfyy
如果失效,可以前往CSDN下载,0积分
https://download.csdn.net/download/youyudexiaowangzi/84213161
对应的7.6.3.1章节CODE SET field described
windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析
文章图片

DENTIFIER TYPE field described
windows|STORAGE_DEVICE_ID_DESCRIPTOR数据结构解析
文章图片

再次分析
12-15Bytes,表示Code Set,值为0x02,也就是The IDENTIFIER field shall contain ASCII printable characters
(i.e., code values 20h through 7Eh)
表示的类型是可读的ascii字符串
16-19Bytes,表示Type,值为0x01,也就是T10 vendor ID based,表示本结构显示的是Vendor ID信息
20-21Bytes,表示IdentifierSize ,值为0x44,也就是本结构里面Identifier 的长度,本结构除了Identifier 以外的长度是CodeSet+Type+IdentifierSize+NextOffset+Association一共16字节,本结构大小为0x44 + 16 = 68 + 16 = 84个字节,算上STORAGE_DEVICE_ID_DESCRIPTOR除Identifiers以外的大小,也就是84+12=96个字节,后面的四个字节是全0
22-23Bytes,表示NextOffset ,也就死下一个结构的偏移,本结构的偏移是0,下一个结构的偏移是0x58,算上STORAGE_DEVICE_ID_DESCRIPTOR除Identifiers以外的大小,也就是0x58+12=88+12=100,也就是超过了整个STORAGE_DEVICE_ID_DESCRIPTOR结构,正好印证了STORAGE_DEVICE_ID_DESCRIPTOR只有一个结构
24-27Bytes,表示Association,值为0,暂时不用管
28 - ...表示Identifier,长度为IdentifierSize也就是0x44,也就是ATA开始的字符和空格
A T A H o o d i s kS S D K B T M C G C 2 1 2 3 6 2 2 0

解析完发现只是一个合并了多种信息的字符串。不足以作为硬盘的唯一标识,但是这个结构被微软定义了却没有在MSDN中定义SCSI的细节,于是只能自己去晚上慢慢摸索。

    推荐阅读