1、windows sdk 编程系列文章 - 遍历 USB 设备,获取扫描仪序列号之一2008-08-08 16:33理论:对于 USB接口的设备,现在越来越多了。本篇我们就通过获取一个 USB扫描仪设备中的序列号,来介绍如何获取 usb设备的一些硬件信息。对于 usb设备都是采用 HCD0,HCD1,HCD2,HCD3等符号描述的。如下图:因此,有了这个名字,我们就可以使用 CreateFile来打开 usb设备。然后使用DeviceIoControl函数与 usb设备通讯了。HCD 是 host controller driver的简写。需要了解详情的,还要仔细的阅读 usb协议。usb的通讯
2、基本步骤如下:Host Controllers- Usb root hub usb function(device)基本步骤:1)打开 HCD%X2) 得到上面的 USB root hub3) 遍历 usb root hub上连接的 usb 设备。获取信息4)如果有多个 usb口,循环前 3步。下面介绍通讯用的几个 IOCTL:1)USB_HCD_DRIVERKEY_NAME ,用于获取 USB设备驱动在注册表中的键名。相应的一个结构体是:typedef struct _USB_HCD_DRIVERKEY_NAME ULONG ActualLength;WCHAR DriverKeyName1
3、; 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 RootHubName1; USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;3)IOCTL_USB_GET_NODE_INFORMATION,用于获取连接在 root hub上的节点设备信息。也就是我们接在 usb口上的所有 u
4、sb设备的信息,对应的结构体: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_INFORMA
5、TION, *PUSB_MI_PARENT_INFORMATION;typedef struct _USB_HUB_INFORMATIONUSB_HUB_DESCRIPTOR HubDescriptor;BOOLEAN HubIsBusPowered; USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;typedef struct _USB_HUB_DESCRIPTORUCHAR bDescriptorLength; / Length of this descriptorUCHAR bDescriptorType; / Hub configuration t
6、ypeUCHAR bNumberOfPorts; / number of ports on this hubUSHORT wHubCharacteristics; / Hub CharateristicsUCHAR bPowerOnToPowerGood; / port power on till power good in 2msUCHAR bHubControlCurrent; / max current in mA/ room for 255 ports power control and removable bitmaskUCHAR bRemoveAndPowerMask64; USB
7、_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
8、 DeviceAddress;ULONG NumberOfOpenPipes;USB_CONNECTION_STATUS ConnectionStatus;USB_PIPE_INFO PipeList0; 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 bDescri
9、ptorType;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
10、 _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
11、_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;typedef enum _USB_CONNECTION_STATUS NoDeviceConnected,DeviceConnected,/* failure codes, these map to fail reasons */DeviceFailedEnumeration,DeviceGeneralFailure,DeviceCausedOvercurrent,DeviceNotEnoughPower,DeviceNotEnoughBandwidth,DeviceHubNestedTooDeeply,DeviceI
12、nLegacyHub USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;typedef struct _USB_PIPE_INFOUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;ULONG ScheduleOffset; USB_PIPE_INFO, *PUSB_PIPE_INFO;typedef struct _USB_ENDPOINT_DESCRIPTORUCHAR bLength;UCHAR bDescriptorType;UCHAR bEndpointAddress;UCHAR bmAttributes;
13、USHORT wMaxPacketSize;UCHAR bInterval; USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;需要注意一点,如果要得到 pid,vid,则直接从 USB_DEVICE_DESCRIPTOR结构中取出 idVendor,idProduct 这两项的值就行了。如果要得到序列号,则不是取出 iSerialNumber 就可以的。这里的 iSerialNumber 仅仅是一个索引值。如果想得到序列号,就需要定义一个结构,然后给设备发送个请求。代码参照GetStringDescriptor函数。可以根据 iSerial
14、Number偏移,取出其对应的字符串,存放在上图 USB_STRING_DESCRIPTOR结构中。【转帖】windows sdk 编程系列文章 - 遍历 USB 设备,获取扫描仪序列号之二网上的好文章 2009-08-13 18:36 阅读 33 评论 0 字号: 大 中 小 #include “windows.h“#include “PlkUsbIo.h“#include #define NUM_HCS_TO_CHECK 10/*/bool EnumUsbDevice();PCHAR GetDriverKeyName(HANDLE Hub, ULONG ConnectionIndex);P
15、CHAR GetHCDDriverKeyName(HANDLE HCD);PCHAR GetRootHubName(HANDLE HostController);PCHAR WideStrToMultiStr(PWCHAR WideStr);bool GetStringDescriptor (HANDLE hHubDevice,ULONG ConnectionIndex,UCHAR DescriptorIndex ,CHAR * outBuff);/*/int main(int argc, char* argv)EnumUsbDevice();return 0;bool EnumUsbDevi
16、ce()char HCName16;int HCNum;HANDLE hHCDev;PCHAR rootHubName;ULONG index;BOOL success;PUSB_NODE_CONNECTION_INFORMATION connectionInfo;HANDLE hHubDevice;for (HCNum = 0; HCNum u.HubInformation.HubDescriptor.bNumberOfPorts;for (index=1; index ConnectionIndex = index;success = DeviceIoControl(hHubDevice,
17、IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,connectionInfo,nBytes,connectionInfo,nBytes,if (!success)free(connectionInfo);goto end;deviceDesc = NULL;if (connectionInfo-ConnectionStatus != NoDeviceConnected)driverKeyName = GetDriverKeyName(hHubDevice,index);if (driverKeyName)free(driverKeyName);if (con
18、nectionInfo-ConnectionStatus = DeviceConnected)/取出序列号索引UCHAR nSerialno = connectionInfo-DeviceDescriptor.iSerialNumber;CHAR OutBuff20 = 0;GetStringDescriptor(hHubDevice,connectionInfo-ConnectionIndex,nSerialno,OutBuff);/判断序列号是否有效if(序列号是否有效)CloseHandle(hHubDevice);CloseHandle(hHCDev);return true;end:
19、; CloseHandle(hHubDevice);CloseHandle(hHCDev);return false;PCHAR GetDriverKeyName(HANDLE Hub, ULONG ConnectionIndex)BOOL success;ULONG nBytes;USB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyName;PUSB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyNameW;PCHAR driverKeyNameA;driverKeyNameW = NULL;driverKeyNameA
20、= NULL;driverKeyName.ConnectionIndex = ConnectionIndex;success = DeviceIoControl(Hub,IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,if (!success)goto GetDriverKeyNameError;nBytes = driverKeyName.ActualLength;if (nBytes ConnectionIndex = ConnectionIndex;success = DeviceIoControl(Hub,IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,