MFC枚举USB设备碰到的一个疑难,还没解决
代码如下: 打开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 }