一、获得U盘的逻辑序列号
重点函数:FltQueryVolumeInformation :查询卷实例的信息
可查询的类型如下:
typedef enum _FSINFOCLASS {
FileFsVolumeInformation = 1,
FileFsLabelInformation, // 2
FileFsSizeInformation, // 3
FileFsDeviceInformation, // 4
FileFsAttributeInformation, // 5
FileFsControlInformation, // 6
FileFsFullSizeInformation, // 7
FileFsObjectIdInformation, // 8
FileFsDriverPathInformation, // 9
FileFsVolumeFlagsInformation,// 10
FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
查询U盘的逻辑序列号选用FileFsVolumeFlagsInformation,
BOOLEAN
GetVolumeSerial(
__in PCFLT_RELATED_OBJECTS FltObjects,
__out ULONG* ulSerial)
{
BOOLEAN bRet = TRUE;
NTSTATUS Status = STATUS_SUCCESS;
IO_STATUS_BLOCK ioBlock = {0};
FILE_FS_VOLUME_INFORMATION vinfo[2]={0};
ULONG ulRetLength = 2*sizeof(FILE_FS_VOLUME_INFORMATION);
Status = FltQueryVolumeInformation(FltObjects->Instance,&ioBlock,vinfo,ulRetLength,FileFsVolumeInformation);
if (NT_SUCCESS(Status))
{
KdPrint(("\nFltQueryVolumeInformation OK;vinfo.VolumeSerialNumber %u",vinfo[0].VolumeSerialNumber));
*ulSerial = vinfo[0].VolumeSerialNumber;
bRet = TRUE;
}
else
{
*ulSerial = 0;
bRet = FALSE;
}
return bRet;
}
二、获得U盘的物理序列号(注册表方式仅仅适用于USB 3.0)
1、XP和Server 2003 使用IOCTL_STORAGE_QUERY_PROPERTY获得的结构体中SerialNumberOffset项一直都是0,所以使用读取注册表的方式获得U盘的物理序列号
注册表路径
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\services\\Disk\\Enum"
2、Win7及以上的系统使用ZwDeviceIoControlFile发送IOCTL_STORAGE_QUERY_PROPERTY到设备上查看设备描述符
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;
pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR)+1024;
Status = ZwDeviceIoControlFile(
hDevice,
NULL,
NULL,
NULL,
&IoStatus,
IOCTL_STORAGE_QUERY_PROPERTY,
&Query,
sizeof(STORAGE_PROPERTY_QUERY),
pDevDesc,
sizeof(STORAGE_DEVICE_DESCRIPTOR)+1024
);