遍历USB设备,获取扫描仪序列号之一 | 您所在的位置:网站首页 › 扫描仪设备序列号怎么看 › 遍历USB设备,获取扫描仪序列号之一 |
对于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仅仅是一个索引值。如果想得到序列号,就需要定义一个结构,然后给设备发送个请求。请求的结构如下图: ![]() |
CopyRight 2018-2019 实验室设备网 版权所有 |