【发布时间】:2017-09-01 11:44:34
【问题描述】:
所以我正在尝试编写一个仅连接到特定 USB 设备的微过滤器驱动程序,以区分我使用产品 ID + 供应商 ID + 序列号的组合的所述设备。
我可以成功地将 IOCTL_STORAGE_QUERY_PROPERTY 发送到返回产品 ID、供应商 ID、序列号的设备。
我遇到的问题是返回到我的微过滤器的序列号对于某些 USB 是正确的,但不是全部。
例如:当我打电话时
C:\Windows\system32>wmic diskdrive get pnpdeviceid
PNPDeviceID
USBSTOR\DISK&VEN_SONY&PROD_STORAGE_MEDIA&REV_PMAP\5C3000637C2070A595&0
USBSTOR\DISK&VEN_BM&PROD_&REV_1.10\070007AA1F02CF40063F&0
这些是我的微过滤器返回的序列号:
Serial Number found 57C03A050905.
Serial Number found 070007AA1F02CF400630.
可以看出,第二个设备的序列号成功返回,但第一个没有。那么我的微过滤器收到的序列号是什么?这是存储在可以查询的地方吗?
如果需要,我可以附上代码,但由于我正确获取了一些序列号,我怀疑我的代码是错误的。
编辑:代码
STORAGE_PROPERTY_QUERY query;
pQuery.PropertyId = StorageDeviceProperty;
pQuery.QueryType = PropertyStandardQuery
KeInitializeEvent(&event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY, pDeviceObject, (PVOID)&query, sizeof(query), infoBuffer,
sizeof(infoBuffer), FALSE, &event, &ioStatusBlock);
if (Irp) {
if(!NT_SUCCESS(IoCallDriver(pDeviceObject, Irp)))
return STATUS_FLT_DO_NOT_ATTACH;
}
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
pDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)infoBuffer;
ULONG offset = pDescriptor->SerialNumberOfffset;
size_t size;
if (offset == 0)
return;
PCHAR c = offset + &buffer[0];
size = strlen(c);
*dest = ExAllocatePoolWithTag(PagedPool, size + 1, 'DIcI');
RtlZeroMemory(*dest, size + 1);
RtlCopyMemory(*dest, c, size + 1);
DbgPrint("Serial Number Found %s \n", *dest);
// String comparison of serial number and more processing
在我的外部硬盘上测试过,这是我从设备管理器中得到的
575834314137363534565656
来自我的微过滤器:
WX41A7654VVV
似乎设备管理器中的序列号是我从微过滤器获得的序列号的十六进制表示
57 58 34 31 41 37 36 35 34 56 56 56
W X 4 1 A 7 6 5 4 V V V
所以对于某些设备,它以十六进制格式表示,而其他设备则以字符格式表示?
那么有没有办法从内核级别获取序列号,或者调用用户应用程序会更容易?
【问题讨论】:
-
... since I get some Serial Numbers correctly i doubt that my code is wrong这是一种完全错误的思维方式...发布您的代码并询问是否有人可以发现错误 -
编辑原帖添加代码
-
infoBuffer, sizeof(infoBuffer)- 这表示您对infoBuffer使用硬编码数组 - 这已经是错误的。它的大小未知,您需要在运行时查询它。正确的代码 - stackoverflow.com/a/44656144/6401656 -
真正的代码包含很多错误。您没有检查从
IoCallDriver返回的状态。但是它可以是STATUS_BUFFER_OVERFLOW。即使在STATUS_SUCCESS上,您也需要检查Size的STORAGE_DEVICE_DESCRIPTOR成员,如果它大于您的sizeof(infoBuffer),您需要使用此Size缓冲区大小重新发送请求。仅在STATUS_PENDING的情况下调用KeWaitForSingleObject存在意义 -
是什么让您认为设备 ID 包含确切的序列号?此字符串的确切格式未记录在 AFAIK 中。