一、所用接口总结
整个工程里,只用了如下几种与USB驱动相关的接口:
1、DeviceIoControl
HANDLE hHCDev = CreateFile("\\.\HCD0", , , , OPEN_EXISTING, 0, NULL); DeviceIoControl(hHCDev, IOCTL_USB_GET_xxx,,,struct, sizeof(struct),); CloseHandle(hHCDev);
它们定义在系统头文件<WinBase.h>中:
(c:\program files\microsoft sdks\windows\v7.0a\include)
(c:\winddk\7600.16385.1\inc\api)
2、CM_***
CM_Locate_DevNode(&devInst, NULL, 0) CM_Get_Child(&devInstNext, devInst, 0) CM_Get_Sibling(&devInstNext, devInst, 0) CM_Get_Parent(&devInstNext, devInst, 0) CM_Get_Device_ID(devInst, buf, len, 0); CM_Get_DevNode_Registry_Property(devInst,CM_DRP_DRIVER, NULL, buf, &len, 0); CM_Get_DevNode_Registry_Property(devInst, CM_DRP_DEVICEDESC, NULL, buf, &len, 0);
它们定义在系统头文件<CfgMgr32.h>中:
(c:\program files\microsoft sdks\windows\v7.0a\include)
(c:\winddk\7600.16385.1\inc\api)
3、SetupDi***
HDEVINFO hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER,,,,); SetupDiEnumDeviceInterfaces(hDevInfo,,,,&devIntfData); SetupDiGetDeviceInterfaceDetail(hDevInfo, &devIntfData, devIntfDetailData,,); SetupDiDestroyDeviceInfoList(hDevInfo);
它们定义在系统头文件<SetupAPI.h>中:
(c:\program files\microsoft sdks\windows\v7.0a\include)
(c:\winddk\7600.16385.1\inc\api)
二、基本过程分析
EnumerateHostControllers()//主入口,枚举系统所有USB Host Controller for(i = 0; i < 10; i++){ HANDLE hHCDev = CreateFile("\\.\HCD0", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); EnumerateHostController(hHCDev)//枚举一个具体的USB Host Controller USB_HCD_DRIVERKEY_NAME drvKeyName = {0}; BOOL bRet = DeviceIoControl(hHCDev, IOCTL_GET_HCD_DRIVERKEY_NAME,,,drvKeyName, sizeof(drvKeyName),); drvKeyNameA: "{36FC9E60-C465-11CF-8056-444553540000}\0000" PTSTR deviceID/deviceDesc = DriverNameToDeviceDesc(drvKeyNameA, *); DEVINST devInst = 0; CONFIGRET cRet = CM_Locate_DevNode(&devInst, NULL, 0); cRet = CM_Get_Child(&devInstNext, devInst, 0); devInst = devInstNext; cRet = CM_Get_Sibling(&devInstNext, devInst, 0); devInst = devInstNext; cRet = CM_Get_Parent(&devInstNext, devInst, 0); devInst = devInstNext; cRet = CM_Get_DevNode_Registry_Property(devInst,CM_DRP_DRIVER, NULL, buf, &len, 0); buf: "{4D36E966-E325-11CE-BFC1-08002BE10318}\0000" cRet = CM_Get_Device_ID(devInst, buf, len, 0); buf: "PCI\VEN_8086&DEV_3B3C&SUBSYS_04401028&REV_06\3&11583659&0&D0" deviceID: buf cRet = CM_Get_DevNode_Registry_Property(devInst, CM_DRP_DEVICEDESC, NULL, buf, &len, 0); buf: "Intel(R) 5 Series/3400 Series Chipset Family USB Enhanced Host Controller - 3B3C" deviceDesc: buf USB_ROOT_HUB_NAME rootHubName; BOOL bRet = DeviceIoControl(hHCDev, IOCTL_USB_GET_ROOT_HUB_NAME,,,rootHubName, sizeof(rootHubName),); rootHubNameA: "USB#ROOT_HUB20#4&8985dfa&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}" EnumerateHub(rootHubNameA)//获取一个具体的USB Hub的信息 HANDLE hHubDevice =CreateFile("\\.\USB#ROOT_HUB20#4&8985dfa&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}",...); USB_HUB_CAPABILITIES_EX hubCapsEx = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_HUB_CAPABILITIES_EX,,,hubCapsEx, sizeof(hubCapsEx),); USB_HUB_CAPABILITIES hubCaps = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_HUB_CAPABILITIES,,,hubCaps, sizeof(hubCaps),); hubCaps.HubIs2xCapable: 1 USB_NODE_INFORMATION hubInfo = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_INFORMATION,,,hubInfo, sizeof(hubInfo),); hubInfo.u.HubInformation.HubDescriptor.bNumberOfPorts: 2 EnumerateHubPorts(hHubDevice, bNumberOfPorts)//枚举一个具体的USB Hub的所有端口 for(index = 1; index <= bNumberOfPorts; index++){ USB_NODE_CONNECTION_INFORMATION_EX connInfoEx; = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,,,connInfoEx, sizeof(connInfoEx),); USB_NODE_CONNECTION_INFORMATION connInfo; = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,,,connInfo, sizeof(connInfo),); connInfoEx.DeviceDescriptor USB_NODE_CONNECTION_DRIVERKEY_NAME drvKeyName = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,,,drvKeyName, sizeof(drvKeyName),); drvKeyNameA: "{36FC9E60-C465-11CF-8056-444553540000}\0005" PTSTR deviceDesc = DriverNameToDeviceDesc(drvKeyNameA, *); deviceDesc: "Generic USB Hub" USB_DESCRIPTOR_REQUEST configDescReq = {0}; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,,,configDescReq, nBytes,); if(connInfoEx.DeviceIsHub)//如果是USB Hub,递归调用EnumerateHub() USB_NODE_CONNECTION_NAME extHubName; BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_NAME,,,extHubName, sizeof(extHubName extHubNameA: "USB#Vid_8087&Pid_0020#5&2fd74a1d&0&1#{f18a0e88-c30c-11d0-8815-00a0c906bed8}" EnumerateHub()//递归枚举一个具体的USB Hub HubInformation.HubDescriptor.bNumberOfPorts: 6 EnumerateHubPorts()//递归枚举一个具体的USB Hub的所有端口 for(index = 1; index <= bNumberOfPorts; index++) { if(connInfoEx1.DeviceIsHub)//如果是USB Hub,递归调用EnumerateHub() extHubNameA: "USB#Vid_0a5c&Pid_4500#6&2cd76888&0&1#{f18a0e88-c30c-11d0-8815-00a0c906bed8} EnumerateHub()//获取一个具体的USB Hub的信息 HubInformation.HubDescriptor.bNumberOfPorts: 3 EnumerateHubPorts()//枚举一个具体的USB Hub的所有端口 for(index = 1; index <= bNumberOfPorts; index++) { //如果不是USB Hub,可能没连设备,或没配置 connInfoEx1.CurrentConfigurationValue: 0 connInfoEx2.CurrentConfigurationValue: 0 connInfoEx3.ConnectionStatus: NoDeviceConnected } connInfoEx2.ConnectionStatus: NoDeviceConnected connInfoEx3.CurrentConfigurationValue: NoDeviceConnected //如果有连设备,则获取设备的具体信息 connInfoEx4: drvKeyNameA: "{53D29EF7-377C-4D14-864B-EB3A85769359}\0001" deviceDesc: "Validity Sensor (VFS300)" }
三、疑点难点问题
1、如何获取设备描述符?
各种描述符都是用DeviceIoControl()接口获取的。
USB_NODE_INFORMATION里包含有USB_HUB_DESCRIPTOR;
USB_NODE_CONNECTION_INFORMATION里包含有USB_DEVICE_DESCRIPTOR。
2、如何获取接口描述符和端点描述符?
答:接口描述符和端点描述符,是紧跟在配置描述符后面的。
具体实现是在GetConfigDescriptor()里完成的,都保存在configDescReq中。
3、如何获取字符串描述符中的字符串是否支持国际化?
答:是的,获取字符串描述符时,可以指定LangID;
而LangNum和LangIDs在所有字符串描述符的起始位置(index=0),可以首先获取到。
LangIDs参见:http://www.usb.org/developers/docs/USB_LANGIDs.pdf