遍历USB设备,获取扫描仪序列号之一 您所在的位置:网站首页 扫描仪设备序列号怎么看 遍历USB设备,获取扫描仪序列号之一

遍历USB设备,获取扫描仪序列号之一

2024-07-15 20:19| 来源: 网络整理| 查看: 265

对于USB接口的设备,现在越来越多了。本篇我们就通过获取一个USB扫描仪设备中的序列号,来介绍如何获取usb设备的一些硬件信息。对于usb设备都是采用HCD0,HCD1,HCD2,HCD3等符号描述的。如下图:

因此,有了这个名字,我们就可以使用CreateFile来打开usb设备。然后使用DeviceIoControl函数与usb设备通讯了。HCD是host controller driver的简写。需要了解详情的,还要仔细的阅读usb协议。usb的通讯基本步骤如下图所示:

基本步骤:    1)打开HCD%X    2) 得到上面的USB root hub    3) 遍历usb root hub上连接的usb 设备。获取信息    4)如果有多个usb口,循环前3步。下面介绍通讯用的几个IOCTL:1)USB_HCD_DRIVERKEY_NAME ,用于获取USB设备驱动在注册表中的键名。相应的一个结构体是:typedef struct _USB_HCD_DRIVERKEY_NAME {   ULONG   ActualLength;   WCHAR   DriverKeyName[1];} USB_HCD_DRIVERKEY_NAME, *PUSB_HCD_DRIVERKEY_NAME;2)IOCTL_USB_GET_ROOT_HUB_NAME,用于获取root hub 键名。使用的结构体,跟上面一样。typedef struct _USB_ROOT_HUB_NAME {    ULONG ActualLength;     WCHAR RootHubName[1]; } USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;3)IOCTL_USB_GET_NODE_INFORMATION,用于获取连接在root hub上的节点设备信息。也就是我们接在usb口上的所有usb设备的信息,对应的结构体:typedef struct _USB_NODE_INFORMATION {    USB_HUB_NODE NodeType;        union {        USB_HUB_INFORMATION HubInformation;        USB_MI_PARENT_INFORMATION MiParentInformation;    } u;} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;typedef struct _USB_MI_PARENT_INFORMATION {    ULONG NumberOfInterfaces;} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION;typedef struct _USB_HUB_INFORMATION{    USB_HUB_DESCRIPTOR HubDescriptor;    BOOLEAN HubIsBusPowered;} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;typedef struct _USB_HUB_DESCRIPTOR{    UCHAR        bDescriptorLength;      // Length of this descriptor    UCHAR        bDescriptorType;        // Hub configuration type    UCHAR        bNumberOfPorts;         // number of ports on this hub    USHORT       wHubCharacteristics;    // Hub Charateristics    UCHAR        bPowerOnToPowerGood;    // port power on till power good in 2ms    UCHAR        bHubControlCurrent;     // max current in mA    //    // room for 255 ports power control and removable bitmask    UCHAR        bRemoveAndPowerMask[64];       } USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;4) IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, 用于获取接在usb口上的单个usb设备的信息,对应的结构体:typedef struct _USB_NODE_CONNECTION_INFORMATION {    ULONG ConnectionIndex;    USB_DEVICE_DESCRIPTOR DeviceDescriptor;    UCHAR CurrentConfigurationValue;    BOOLEAN LowSpeed;    BOOLEAN DeviceIsHub;    USHORT DeviceAddress;    ULONG NumberOfOpenPipes;    USB_CONNECTION_STATUS ConnectionStatus;    USB_PIPE_INFO PipeList[0];} USB_NODE_CONNECTION_INFORMATION, *PUSB_NODE_CONNECTION_INFORMATION;4)IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, 用于获取usb设备的描述信息。typedef struct _USB_DEVICE_DESCRIPTOR {    UCHAR bLength;    UCHAR bDescriptorType;    USHORT bcdUSB;    UCHAR bDeviceClass;    UCHAR bDeviceSubClass;    UCHAR bDeviceProtocol;    UCHAR bMaxPacketSize0;    USHORT idVendor;    USHORT idProduct;    USHORT bcdDevice;    UCHAR iManufacturer;    UCHAR iProduct;    UCHAR iSerialNumber;    UCHAR bNumConfigurations;} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;typedef struct _USB_DEVICE_DESCRIPTOR {    UCHAR bLength;    UCHAR bDescriptorType;    USHORT bcdUSB;    UCHAR bDeviceClass;    UCHAR bDeviceSubClass;    UCHAR bDeviceProtocol;    UCHAR bMaxPacketSize0;    USHORT idVendor;    USHORT idProduct;    USHORT bcdDevice;    UCHAR iManufacturer;    UCHAR iProduct;    UCHAR iSerialNumber;    UCHAR bNumConfigurations;} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;typedef enum _USB_CONNECTION_STATUS {    NoDeviceConnected,    DeviceConnected,    /* failure codes, these map to fail reasons */    DeviceFailedEnumeration,    DeviceGeneralFailure,    DeviceCausedOvercurrent,    DeviceNotEnoughPower,    DeviceNotEnoughBandwidth,    DeviceHubNestedTooDeeply,    DeviceInLegacyHub} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;typedef struct _USB_PIPE_INFO{    USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;    ULONG ScheduleOffset;} USB_PIPE_INFO, *PUSB_PIPE_INFO;typedef struct _USB_ENDPOINT_DESCRIPTOR{    UCHAR bLength;    UCHAR bDescriptorType;    UCHAR bEndpointAddress;    UCHAR bmAttributes;    USHORT wMaxPacketSize;    UCHAR bInterval;} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;需要注意一点,如果要得到pid,vid,则直接从USB_DEVICE_DESCRIPTOR结构中取出idVendor,idProduct这两项的值就行了。如果要得到序列号,则不是取出 iSerialNumber就可以的。这里的 iSerialNumber仅仅是一个索引值。如果想得到序列号,就需要定义一个结构,然后给设备发送个请求。请求的结构如下图:

代码参照GetStringDescriptor函数。可以根据 iSerialNumber偏移,取出其对应的字符串,存放在上图USB_STRING_DESCRIPTOR结构中。  


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有