首页
社区
课程
招聘
[求助]STORAGE_DEVICE_DESCRIPTOR 怎么获取序列号
发表于: 2014-4-15 13:15 10605

[求助]STORAGE_DEVICE_DESCRIPTOR 怎么获取序列号

2014-4-15 13:15
10605
我百度了很久,还是没解决,所以不好意思占用下大家的时间,这是一段用来查询U盘序列号的代码:

PSTORAGE_DEVICE_DESCRIPTOR Descriptor;
.....

// 设置查询参数
//         DeviceIoControl(hDevice,         // 设备句柄
//                 IOCTL_STORAGE_QUERY_PROPERTY,        // 设备属性信息
//                 &Query, sizeof(STORAGE_PROPERTY_QUERY),        // 输出buffer
//                 outBuf, 512,         // 输出buffer
//                 &dwOutBytes,         // 输出长度
//                 (LPOVERLAPPED)NULL);

但是在DDK好像没DeviceIoControl,我用的是这个:
NewIrp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY, DeviceObject, (PVOID)&Query, sizeof(Query), (PVOID)Buffer, 1024, FALSE, &WaitEvent, &IoStatus);
IoCallDriver(DeviceObject, NewIrp);

Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
DbgPrint("DeviceType:%X\n",Descriptor->DeviceType);
DbgPrint("VendorIdOffset:%X\n",Descriptor->VendorIdOffset);
DbgPrint("ProductIdOffset:%X\n",Descriptor->ProductIdOffset);
但是得到的是序列号的偏移 怎么才能得到长度啊?

//// 查询属性输出的数据结构
//typedef struct _STORAGE_DEVICE_DESCRIPTOR {
//    ULONG Version;                    // 版本
//    ULONG Size;                       // 结构大小
//    UCHAR DeviceType;                 // 设备类型
//    UCHAR DeviceTypeModifier;         // SCSI-2额外的设备类型
//    BOOLEAN RemovableMedia;           // 是否可移动
//    BOOLEAN CommandQueueing;          // 是否支持命令队列
//    ULONG VendorIdOffset;             // 厂家设定值的偏移
//    ULONG ProductIdOffset;            // 产品ID的偏移
//    ULONG ProductRevisionOffset;      // 产品版本的偏移
//    ULONG SerialNumberOffset;         // 序列号的偏移
//    STORAGE_BUS_TYPE BusType;         // 总线类型
//    ULONG RawPropertiesLength;        // 额外的属性数据长度
//    UCHAR RawDeviceProperties[1];     // 额外的属性数据(仅定义了象征性的1个字节)
//} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
2
msdn:
SerialNumberOffset
Specifies the byte offset from the beginning of the structure to a NULL-terminated ASCII string that contains the device's serial number.
If the device has no serial number, this member is zero.
这个成员指向的是以0结尾的ascii字符串。所以直接(BYTE*)(Descriptor+(*Descriptor).SerialNumberOffset)就是这个字符串了。然后自己挨个字符找零就能知道长度了。
不过最好先看一下SerialNumberOffset的值是不是0。
2014-4-15 14:49
0
雪    币: 53
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢,看来我的英语还需要再加强了,当时看过但是没能理解。
2014-4-15 15:49
0
雪    币: 53
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
PSTORAGE_DEVICE_DESCRIPTOR Descriptor;
PUCHAR         p;
char ProductIdOffset[128];
char VendorIdOffset[128];
char SerialNumberOffset[128];
int index=0;
int i;

Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
p = (PUCHAR) Buffer;

if ( Descriptor->ProductIdOffset && p[Descriptor->ProductIdOffset] )
        {
                for(i=Descriptor->ProductIdOffset; p[i] != '0' ; i++ )
                {
                        ProductIdOffset[index]=p[i];
                        index++;               
                }
                DbgPrint("ProductIdOffset:%s\n",ProductIdOffset);
        }
if (Descriptor->SerialNumberOffset && p[Descriptor->SerialNumberOffset])
        {
                index=0;
                for(i=Descriptor->SerialNumberOffset; p[i] != '0'||p[i] != (int)NULL||p[i] != '\0' ; i++ ) //写错了 下面更正
                {
                        SerialNumberOffset[index]=p[i];
                        index++;       
                        DbgPrint("%c\n",p[i]);
                }
                DbgPrint("\nSerialNumberOffset:%s\n",SerialNumberOffset);
        }

确实是以‘/0’结束的 刚才我昏头了 居然写出了这样的代码:for(i=Descriptor->SerialNumberOffset; p[i] != '0'||p[i] != (int)NULL||p[i] != '\0' ; i++ )

正确的是for(i=Descriptor->SerialNumberOffset;p[i] != '\0' ; i++ )

效果:
上传的附件:
2014-4-15 20:20
0
雪    币: 221
活跃值: (2256)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
DeviceObject ,是如何获取?
2015-1-12 17:26
0
雪    币: 53
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我用过四个办法各有各的优缺点:
1.在sfilter框架下 SfFsControlMountVolume例程里面可以获取刚插入存储设备DeviceObject,然后使用上面说的去获取设备信息,我也不知道这样做好不好,反正能行,但是sfilter框架下实现其他功能太麻烦了,最后决定不用,就当是练习。

2.在minifiter框架的PtInstanceSetup 回调里面能获取刚插入设备的信息,当然是一个PCFLT_RELATED_OBJECTS 结构体的,没有直接的DeviceObject,不过你可以用FltDeviceIoControlFile来向设备发送IoControl来获取设备信息。如果实现了的话,还可以实现透明加解密传输的功能,而且驱动和客户端通信也很好写。这个办法我觉得最好,我现在正在做,我还没完全实现,只是我的想法。

3.第三个办法最简单,就是遍历A-Z盘符,用设备链接来打开设备,然后获取设备信息。

4.用windows驱动开发技术详解的第22章那个 U盘过滤驱动例子,是个WDM型驱动,但是加载方法却是个难题。
加载方法一:加载在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR相应的U盘下面,能获取到插入的U盘DeviceObject,但是只能获取这一个U盘的,也就是必须等U盘先存在了在注册表,然后手工加一个过滤驱动。
加载方法二:加载在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Class\{4D36E967-E325-11CE-BFC1-08002B-E10318},所有的磁盘包括硬盘都过滤,也就是系统重新启动时,你需要去判断U盘和硬盘的区别,不然会出问题。
2015-1-21 13:10
0
游客
登录 | 注册 方可回帖
返回
//