查询描述符
USB驱动对外提供了一系列用来查询描述符的控制码,所有控制码在 usbioctl.h
头文件中定义。
从结构上来说,所有的USB设备起始于 根控制器(Host Controller)
,然后下边挂接 HUB
进行扩展,
整体是一个树形结构。根控制器
可以同时存在多个,但一般情况下只有一个 根控制器
,每个 根控制器
对外提供的访问名称为 "\\.\HCDx"
,x为数字,比如第一个 根控制器
为 "\\.\HCD0"
。
查询的流程
工作流程:
1、从 根控制器
开始,查询 RootHub
名称,然后打开 RootHub
设备。
2、查询 RootHub
设备 端口
的数量,查询每个 端口
连接的设备信息。
3、如果 端口
连接的是 扩展Hub
设备,跟 RootHub
一样查询并打开设备。
4、如果 端口
连接的不是Hub设备,就可以查询这个设备的所有信息。
如下为相关代码
1 2 3 4 5 6
| #define HUBNAME_LEN 128 #define HUBNAME_LEN_WIDE 256 typedef struct _HUB_NAME { WCHAR szNameW[HUBNAME_LEN]; } HUB_NAME, *PHUB_NAME;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| BOOL EnumHost() { HANDLE hHCDevice = CreateFileW( L"\\\\.\\HCD0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hHCDevice == INVALID_HANDLE_VALUE) return FALSE; HUB_NAME stRootHub = { 0 }; BOOL bRet = GetRootHubName(hHCDevice, stRootHub); CloseHandle(hHCDevice); if (!bRet) return FALSE; if (!EnumHub(stRootHub)) return FALSE; return TRUE; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BOOL GetRootHubName(HANDLE hHCDevice, HUB_NAME &stRootHub) { DWORD dwSize = 0; char szBuffer[HUBNAME_LEN_WIDE] = { 0 }; PUSB_ROOT_HUB_NAME pHubName = (PUSB_ROOT_HUB_NAME)szBuffer; HUB_NAME stTemp = { 0 }; BOOL isSuccess = DeviceIoControl( hHCDevice, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, pHubName, HUBNAME_LEN_WIDE, &dwSize, NULL); if (!isSuccess) return FALSE; if (pHubName->ActualLength > HUBNAME_LEN_WIDE) return FALSE; wcscpy_s(stRootHub.szwName, HUBNAME_LEN, L"\\\\.\\"); wcscat_s(stRootHub.szwName, HUBNAME_LEN, pHubName->RootHubName); return TRUE; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| BOOL EnumHub(HUB_NAME &stHubName) { HANDLE hHubDevice = CreateFileW( stHubName.szwName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hHubDevice == INVALID_HANDLE_VALUE) return FALSE; ULONG nSize = 0; USB_NODE_INFORMATION stHubInfo = { UsbHub }; BOOL isSuccess = DeviceIoControl( hHubDevice, IOCTL_USB_GET_NODE_INFORMATION, &stHubInfo, sizeof(USB_NODE_INFORMATION), &stHubInfo, sizeof(USB_NODE_INFORMATION), &nSize, NULL); if (!isSuccess) { CloseHandle(hHubDevice); return FALSE; } isSuccess = EnumHubPorts(hHubDevice, stHubInfo.u.HubInformation.HubDescriptor.bNumberOfPorts); CloseHandle(hHubDevice); return isSuccess; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| BOOL EnumHubPorts(HANDLE hHubDevice, UCHAR nNumPorts) { DWORD dwSize = sizeof(USB_NODE_CONNECTION_INFORMATION) + sizeof(USB_PIPE_INFO) * 30; PUSB_NODE_CONNECTION_INFORMATION pConnInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(dwSize); if (pConnInfo == NULL) return FALSE; BOOL isSuccess = FALSE; HUB_NAME stExtHub = { 0 }; PUSB_DESCRIPTOR_REQUEST pDescRequest = NULL; for (UCHAR i = 1; i <= nNumPorts; i++) { memset(pConnInfo, 0, dwSize); pConnInfo->ConnectionIndex = i; isSuccess = DeviceIoControl( hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, pConnInfo, dwSize, pConnInfo, dwSize, &dwSize, NULL); if (!isSuccess) continue; if (pConnInfo->ConnectionStatus != DeviceConnected) continue; if (pConnInfo->DeviceIsHub) { memset(&stExtHub, 0, sizeof(HUB_NAME)); if (GetExtHubName(hHubDevice, i, stExtHub)) { EnumHub(stExtHub); } continue; } pConnInfo->DeviceDescriptor; pDescRequest = GetConfigDescriptor(hHubDevice, i); if (pDescRequest == NULL) continue; GetInterfaceDescriptor(pDescRequest); free(pDescRequest); GetStringDescriptor(hHubDevice, i, pConnInfo); } free(pConnInfo); return TRUE; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| BOOL GetExtHubName(HANDLE hHubDevice, UCHAR bPortIndex, HUB_NAME &stExtHub) { char szBuffer[HUBNAME_LEN_WIDE] = { 0 }; PUSB_NODE_CONNECTION_NAME pNodeName = (PUSB_NODE_CONNECTION_NAME)szBuffer; pNodeName->ConnectionIndex = bPortIndex; ULONG dwSize = 0; BOOL isSuccess = DeviceIoControl( hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_NAME, pNodeName, HUBNAME_LEN_WIDE, pNodeName, HUBNAME_LEN_WIDE, &dwSize, NULL); if (!isSuccess) return FALSE; if (pNodeName->ActualLength > HUBNAME_LEN_WIDE) return FALSE; wcscpy_s(stExtHub.szwName, HUBNAME_LEN, L"\\\\.\\"); wcscat_s(stExtHub.szwName, HUBNAME_LEN, pNodeName->NodeName); return TRUE; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| PUSB_DESCRIPTOR_REQUEST GetConfigDescriptor(HANDLE hHubDevice, UCHAR bPortIndex) { UCHAR bBuffer[sizeof(USB_DESCRIPTOR_REQUEST) + sizeof(USB_CONFIGURATION_DESCRIPTOR)] = { 0 }; PUSB_DESCRIPTOR_REQUEST pDescReq = (PUSB_DESCRIPTOR_REQUEST)bBuffer; pDescReq->ConnectionIndex = bPortIndex; pDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | 0; pDescReq->SetupPacket.wLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); DWORD dwSize = 0; BOOL isSuccess = DeviceIoControl( hHubDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, pDescReq, sizeof(bBuffer), pDescReq, sizeof(bBuffer), &dwSize, NULL); if (!isSuccess) return NULL; PUSB_CONFIGURATION_DESCRIPTOR pConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(pDescReq + 1); dwSize = sizeof(USB_DESCRIPTOR_REQUEST) + pConfigDesc->wTotalLength; pDescReq = (PUSB_DESCRIPTOR_REQUEST)malloc(dwSize); if (pDescReq == NULL) return NULL; memset(pDescReq, 0, dwSize); pDescReq->ConnectionIndex = bPortIndex; pDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | 0; pDescReq->SetupPacket.wLength = pConfigDesc->wTotalLength; isSuccess = DeviceIoControl( hHubDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, pDescReq, dwSize, pDescReq, dwSize, &dwSize, NULL); if (!isSuccess) { free(pDescReq); return NULL; } return pDescReq; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| PUSB_INTERFACE_DESCRIPTOR GetInterfaceDescriptor(PUSB_DESCRIPTOR_REQUEST pDescReq) { PUSB_CONFIGURATION_DESCRIPTOR pConfigDesc = PUSB_CONFIGURATION_DESCRIPTOR(pDescReq + 1); PUCHAR pDescEnd = (PUCHAR)pConfigDesc + pConfigDesc->wTotalLength; PUSB_COMMON_DESCRIPTOR pCommonDesc = (PUSB_COMMON_DESCRIPTOR)pConfigDesc; while (((PUCHAR)pCommonDesc + sizeof(USB_COMMON_DESCRIPTOR) < pDescEnd) && ((PUCHAR)pCommonDesc + pCommonDesc->bLength <= pDescEnd)) { if (pCommonDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { return (PUSB_INTERFACE_DESCRIPTOR)pCommonDesc; } pCommonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR)pCommonDesc + pCommonDesc->bLength); } return NULL; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| BOOL GetAllStringDescriptor( IN HANDLE hHubDevice, IN UCHAR bPortIndex, IN PUSB_NODE_CONNECTION_INFORMATION pConnInfo) { PUSB_DESCRIPTOR_REQUEST pLangReq = GetStringDescriptor(hHubDevice, bPortIndex, 0, 0); if (pLangReq == NULL) return FALSE; PUSB_STRING_DESCRIPTOR pStringLang = (PUSB_STRING_DESCRIPTOR)(pLangReq + 1); if (pStringLang->bLength < sizeof(USB_STRING_DESCRIPTOR)) return FALSE; USHORT numLanguageIDs = (pStringLang->bLength - sizeof(USB_STRING_DESCRIPTOR) + sizeof(WCHAR)) / 2; PUSHORT pLanguageIDs = (PUSHORT)&pStringLang->bString[0]; PUSB_DESCRIPTOR_REQUEST pDescReq = NULL; PUSB_STRING_DESCRIPTOR pStringDesc = NULL; if (pConnInfo->DeviceDescriptor.iSerialNumber != 0) { pDescReq = GetStringDescriptor( hHubDevice, bPortIndex, pConnInfo->DeviceDescriptor.iSerialNumber, pLanguageIDs[0]); if (pDescReq != NULL) { pStringDesc = (PUSB_STRING_DESCRIPTOR)(pDescReq + 1); free(pDescReq); } } free(pLangReq); return TRUE; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| PUSB_DESCRIPTOR_REQUEST GetStringDescriptor( HANDLE hHubDevice, UCHAR bPortIndex, UCHAR bDescIndex, USHORT wLanguageID) { DWORD dwSize = sizeof(USB_DESCRIPTOR_REQUEST) + 256; PUSB_DESCRIPTOR_REQUEST pDescReq = (PUSB_DESCRIPTOR_REQUEST)malloc(dwSize); if (pDescReq == NULL) return NULL; memset(pDescReq, 0, dwSize); pDescReq->ConnectionIndex = bPortIndex; pDescReq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | bDescIndex; pDescReq->SetupPacket.wIndex = wLanguageID; pDescReq->SetupPacket.wLength = 256; BOOL isSuccess = DeviceIoControl( hHubDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, pDescReq, dwSize, pDescReq, dwSize, &dwSize, NULL); if (!isSuccess) { free(pDescReq); return NULL; } return pDescReq; }
|