代码如下:
打开USB Hub设备之后,返回句柄hHubDevice,然后使用EnumerateHubPorts来枚举Hub的端
口。疑问在代码的中文注释中。
1 bool CUsbEnumHub::EnumerateHubPorts(HANDLE hHubDevice, ULONG NumPorts, UsbItem* pRootItem)
2 {
3 ULONG index;
4 BOOL bSuccess;
5 PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo;
6 CString strDriverKeyName;
7
8
9 // Loop over all ports of the hub.
10 // Port indices are 1 based, not 0 based.
11 for (index=1; index <= NumPorts; index++)
12 {
13 ULONG nBytes;
14 bAwUsb = FALSE;
15 // Allocate space to hold the connection info for this port.
16 // For now, allocate it big enough to hold info for 30 pipes.
17 //
18 // Endpoint numbers are 0-15. Endpoint number 0 is the standard
19 // control endpoint which is not explicitly listed in the Configuration
20 // Descriptor. There can be an IN endpoint and an OUT endpoint at
21 // endpoint numbers 1-15 so there can be a maximum of 30 endpoints
22 // per device configuration.
23 // Should probably size this dynamically at some point.
24 nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION_EX) +
25 sizeof(USB_PIPE_INFO) * 30;
26
27 connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION_EX)ALLOC(nBytes);
28
29 if (connectionInfo == NULL)
30 {
31 OOPS();
32 break;
33 }
34
35 //
36 // Now query USBHUB for the USB_NODE_CONNECTION_INFORMATION_EX structure
37 // for this port. This will tell us if a device is attached to this
38 // port, among other things.
39 //
40 connectionInfo->ConnectionIndex = index;
41
42 bSuccess = DeviceIoControl(hHubDevice,
43 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
44 connectionInfo,
45 nBytes,
46 connectionInfo,
47 nBytes,
48 &nBytes,
49 NULL);
50
51 if (!bSuccess)
52 {
53 FREE(connectionInfo);
54 continue;
55 }
56 UsbItem *pItemChild = new UsbItem;
57 pItemChild->parent = pRootItem;
58 pItemChild->strDisplayName.Format(_T("[Port%d]"), index);
59
60 // Update the count of connected devices
61 if (connectionInfo->ConnectionStatus == DeviceConnected)
62 {
63 //获取Dirver Key Name
64 GetDriverKeyName(hHubDevice, index, pItemChild->strName);
65 //在这里,判断到端口有设备连接,请教怎么获取该设备的路径,就是可以使用CreateFile打开的那种路径。
66 //这里获取的Driver Key Name并不是路径,无法使用CreateFile来打开。
67 }
68
69
70
71 // If the device connected to the port is an external hub, get the
72 // name of the external hub and recursively enumerate it.
73 if (connectionInfo->DeviceIsHub)
74 {
75 CString strExtHubName;
76 bSuccess = GetExternalHubName(hHubDevice, index, strExtHubName);
77 if (bSuccess)
78 {
79 pItemChild->strName = strExtHubName;
80 pItemChild->usbType = USB_TYPE_HUB;
81 pRootItem->childArray.Add(pItemChild);
82 EnumerateHub(strExtHubName, pItemChild);
83 // On to the next port
84 FREE(connectionInfo);
85 continue;
86 }
87 else
88 {
89 delete pItemChild;
90 }
91 }
92 else
93 {
94 pItemChild->usbType = USB_TYPE_PORT;
95 pRootItem->childArray.Add(pItemChild);
96 }
97 FREE(connectionInfo);
98 }
99
100 return bSuccess ? true : false;
101 }
另一端代码,这段代码直接枚举USB设备,忽略USB Hub的枚举。这里的枚举可以获取到每
个连接到USB端口的设备的路径,可以使用CreateFile打开操作。
有没有办法把这里枚举到的USB设备和上面枚举到的USB设备建立联系呢?,代码如下:
1 void CTurboDemoDlg::OnBnClickedSusb()
2 {
3 HANDLE hHCDev;
4 HDEVINFO hDevInfo;
5 SP_DEVICE_INTERFACE_DATA hDevInfoData;
6 PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData;
7 ULONG index;
8 ULONG requiredLength;
9
10 hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE,
11 NULL,
12 NULL,
13 (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
14 if (hDevInfo == INVALID_HANDLE_VALUE)
15 {
16 return ;
17 }
18 hDevInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
19 for (index=0; SetupDiEnumDeviceInterfaces(hDevInfo,
20 0,
21 (LPGUID)&GUID_CLASS_USB_DEVICE,
22 index,
23 &hDevInfoData); index++)
24 {
25 SetupDiGetDeviceInterfaceDetail(hDevInfo,
26 &hDevInfoData,
27 NULL,
28 0,
29 &requiredLength,
30 NULL);
31
32 deviceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)GlobalAlloc(GPTR, requi
33 redLength);
34
35 deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
36
37 SetupDiGetDeviceInterfaceDetail(hDevInfo,
38 &hDevInfoData,
39 deviceDetailData,
40 requiredLength,
41 &requiredLength,
42 NULL);
43
44 //deviceDetailData->DevicePath就是USB设备的路径
45 //但是使用该方法却又无法知道该设备在哪个Hub端口,苦恼。
46 hHCDev = CreateFile(deviceDetailData->DevicePath,
47 GENERIC_WRITE,
48 FILE_SHARE_WRITE,
49 NULL,
50 OPEN_EXISTING,
51 0,
52 NULL);
53
54 // If the handle is valid, then we've successfully opened a Host
55 // Controller. Display some info about the Host Controller itself,
56 // then enumerate the Root Hub attached to the Host Controller.
57 if (hHCDev != INVALID_HANDLE_VALUE)
58 {
59 CString strMsg;
60 strMsg.Format(_T("Found: %s\n"), deviceDetailData->DevicePath);
61 OutputDebugString(strMsg);
62
63 CloseHandle(hHCDev);
64 }
65
66 GlobalFree(deviceDetailData);
67 }
68
69 SetupDiDestroyDeviceInfoList(hDevInfo);
70 }