windows sdk編程系列文章 ---- 遍歷USB設備,獲取掃描儀序列號之二
代碼:見光盤GetSerialNo
#include "windows.h" #include "PlkUsbIo.h" #include <malloc.h> #define NUM_HCS_TO_CHECK 10 /******************************************************************/ bool EnumUsbDevice(); PCHAR GetDriverKeyName(HANDLE Hub, ULONG ConnectionIndex); PCHAR 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 EnumUsbDevice() { char HCName[16]; int HCNum; HANDLE hHCDev; PCHAR rootHubName; ULONG index; BOOL success; PUSB_NODE_CONNECTION_INFORMATION connectionInfo; HANDLE hHubDevice; for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++) { wsprintf(HCName, "\\\\.\\HCD%d", HCNum); hHCDev = CreateFile(HCName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hHCDev == INVALID_HANDLE_VALUE) break; PCHAR driverKeyName, deviceDesc; driverKeyName = GetHCDDriverKeyName(hHCDev); if(driverKeyName == NULL) goto end; ULONG nBytes; rootHubName =(char*) GetRootHubName(hHCDev); if(rootHubName==NULL) goto end; PUSB_NODE_INFORMATION HubInfo; HubInfo = (PUSB_NODE_INFORMATION)malloc(sizeof(USB_NODE_INFORMATION)); PCHAR deviceName; deviceName = (PCHAR)malloc(strlen(rootHubName) + sizeof("\\\\.\\")); if (rootHubName != NULL) { strcpy(deviceName, "\\\\.\\"); strcpy(deviceName + sizeof("\\\\.\\") - 1, rootHubName); hHubDevice = CreateFile(deviceName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); free(deviceName); if (hHubDevice == INVALID_HANDLE_VALUE) goto end; success = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_INFORMATION, HubInfo, sizeof(USB_NODE_INFORMATION), HubInfo, sizeof(USB_NODE_INFORMATION), &nBytes, NULL); if (!success) goto end; } int port; port=HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts; for (index=1; index <= port; index++) { ULONG nBytes; nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) + sizeof(USB_PIPE_INFO) * 30; connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes); if (connectionInfo == NULL) goto end; connectionInfo->ConnectionIndex = index; success = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, connectionInfo, nBytes, connectionInfo, nBytes, &nBytes, NULL); if (!success) { free(connectionInfo); goto end; } deviceDesc = NULL; if (connectionInfo->ConnectionStatus != NoDeviceConnected) { driverKeyName = GetDriverKeyName(hHubDevice, index); if (driverKeyName) { free(driverKeyName); } } if (connectionInfo->ConnectionStatus == DeviceConnected) { //取出序列號索引 UCHAR nSerialno = connectionInfo->DeviceDescriptor.iSerialNumber; CHAR OutBuff[20] = {0}; GetStringDescriptor(hHubDevice,connectionInfo->ConnectionIndex,nSerialno,OutBuff); //判斷序列號是否有效 if(序列號是否有效) { CloseHandle(hHubDevice); CloseHandle(hHCDev); return true; } } } end:; } 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 = NULL; driverKeyName.ConnectionIndex = ConnectionIndex; success = DeviceIoControl(Hub, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, &driverKeyName, sizeof(driverKeyName), &driverKeyName, sizeof(driverKeyName), &nBytes, NULL); if (!success) { goto GetDriverKeyNameError; } nBytes = driverKeyName.ActualLength; if (nBytes <= sizeof(driverKeyName)) { goto GetDriverKeyNameError; } driverKeyNameW = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)malloc(nBytes); if (driverKeyNameW == NULL) { goto GetDriverKeyNameError; } driverKeyNameW->ConnectionIndex = ConnectionIndex; success = DeviceIoControl(Hub, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, driverKeyNameW, nBytes, driverKeyNameW, nBytes, &nBytes, NULL); if (!success) { goto GetDriverKeyNameError; } driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName); free(driverKeyNameW); return driverKeyNameA; GetDriverKeyNameError: if (driverKeyNameW != NULL) { free(driverKeyNameW); driverKeyNameW = NULL; } return NULL; } PCHAR GetRootHubName(HANDLE HostController) { BOOL success; ULONG nBytes; USB_ROOT_HUB_NAME rootHubName; PUSB_ROOT_HUB_NAME rootHubNameW; PCHAR rootHubNameA; rootHubNameW = NULL; rootHubNameA = NULL; success = DeviceIoControl(HostController, IOCTL_USB_GET_ROOT_HUB_NAME, 0, 0, &rootHubName, sizeof(rootHubName), &nBytes, NULL); if (!success) { goto GetRootHubNameError; } nBytes = rootHubName.ActualLength; rootHubNameW =(PUSB_ROOT_HUB_NAME) malloc(nBytes); if (rootHubNameW == NULL) { goto GetRootHubNameError; } success = DeviceIoControl(HostController, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, rootHubNameW, nBytes, &nBytes, NULL); if (!success) { goto GetRootHubNameError; } rootHubNameA = WideStrToMultiStr(rootHubNameW->RootHubName); free(rootHubNameW); return rootHubNameA; GetRootHubNameError: if (rootHubNameW != NULL) { free(rootHubNameW); rootHubNameW = NULL; } return NULL; } PCHAR GetHCDDriverKeyName(HANDLE HCD) { BOOL success; ULONG nBytes; USB_HCD_DRIVERKEY_NAME driverKeyName; PUSB_HCD_DRIVERKEY_NAME driverKeyNameW; PCHAR driverKeyNameA; driverKeyNameW = NULL; driverKeyNameA = NULL; success = DeviceIoControl(HCD, IOCTL_GET_HCD_DRIVERKEY_NAME, &driverKeyName, sizeof(driverKeyName), &driverKeyName, sizeof(driverKeyName), &nBytes, NULL); if (!success) { goto GetHCDDriverKeyNameError; } nBytes = driverKeyName.ActualLength; if (nBytes <= sizeof(driverKeyName)) { goto GetHCDDriverKeyNameError; } driverKeyNameW =(PUSB_HCD_DRIVERKEY_NAME) malloc(nBytes); if (driverKeyNameW == NULL) { goto GetHCDDriverKeyNameError; } success = DeviceIoControl(HCD, IOCTL_GET_HCD_DRIVERKEY_NAME, driverKeyNameW, nBytes, driverKeyNameW, nBytes, &nBytes, NULL); if (!success) { goto GetHCDDriverKeyNameError; } driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName); free(driverKeyNameW); return driverKeyNameA; GetHCDDriverKeyNameError: if (driverKeyNameW != NULL) { free(driverKeyNameW); driverKeyNameW = NULL; } return NULL; } PCHAR WideStrToMultiStr(PWCHAR WideStr) { ULONG nBytes; PCHAR MultiStr; nBytes = WideCharToMultiByte( CP_ACP, 0, WideStr, -1, NULL, 0, NULL, NULL); if (nBytes == 0) { return NULL; } MultiStr =(PCHAR) malloc(nBytes); if (MultiStr == NULL) { return NULL; } nBytes = WideCharToMultiByte( CP_ACP, 0, WideStr, -1, MultiStr, nBytes, NULL, NULL); if (nBytes == 0) { free(MultiStr); return NULL; } return MultiStr; } bool GetStringDescriptor ( HANDLE hHubDevice, ULONG ConnectionIndex, UCHAR DescriptorIndex , CHAR * outBuff ) { BOOL success; ULONG nBytes; ULONG nBytesReturned; UCHAR stringDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) + MAXIMUM_USB_STRING_LENGTH]; PUSB_DESCRIPTOR_REQUEST stringDescReq; PUSB_STRING_DESCRIPTOR stringDesc; nBytes = sizeof(stringDescReqBuf); stringDescReq = (PUSB_DESCRIPTOR_REQUEST)stringDescReqBuf; stringDesc = (PUSB_STRING_DESCRIPTOR)(stringDescReq+1); ::ZeroMemory(stringDescReq,nBytes); stringDescReq->ConnectionIndex = ConnectionIndex; stringDescReq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex; stringDescReq->SetupPacket.wIndex = GetSystemDefaultLangID(); stringDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST)); success = DeviceIoControl(hHubDevice,IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, stringDescReq,nBytes, stringDescReq,nBytes, &nBytesReturned,NULL); if (!success || nBytesReturned < 2) return false; if (stringDesc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE) return false; if (stringDesc->bLength != nBytesReturned - sizeof(USB_DESCRIPTOR_REQUEST)) return false; if (stringDesc->bLength % 2 != 0) return false; WCHAR * wChar = new WCHAR[stringDesc->bLength + 1]; memcpy(wChar,stringDesc->bString,stringDesc->bLength); char *szTemp = WideStrToMultiStr(wChar); lstrcpy(outBuff, szTemp); if(szTemp) delete []szTemp; if(wChar) delete []wChar; return true; } 分析: 1)首先假定有10個usb接口 #define NUM_HCS_TO_CHECK 10 2)循環打開這10個usb端口,如果端口沒有這么多,調用CreateFile,就會返回 INVALID_HANDLE_VALUE。 for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++) { wsprintf(HCName, "\\\\.\\HCD%d", HCNum); hHCDev = CreateFile(HCName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hHCDev == INVALID_HANDLE_VALUE) break; 3)獲取root hub ULONG nBytes; rootHubName =(char*) GetRootHubName(hHCDev); if(rootHubName==NULL) goto end; 4) 遍歷連接在root hub上的節點 int port; port=HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts; for (index=1; index <= port; index++) { ULONG nBytes; nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) + sizeof(USB_PIPE_INFO) * 30; connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes); if (connectionInfo == NULL) goto end; connectionInfo->ConnectionIndex = index; success = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, connectionInfo, nBytes, connectionInfo, nBytes, &nBytes, NULL); if (!success) { free(connectionInfo); goto end; } 5)根據節點的連接狀態,獲取節點信息,得到序列號。 if (connectionInfo->ConnectionStatus == DeviceConnected) { //取出序列號索引 UCHAR nSerialno = connectionInfo->DeviceDescriptor.iSerialNumber; CHAR OutBuff[20] = {0}; GetStringDescriptor(hHubDevice,connectionInfo->ConnectionIndex,nSerialno,OutBuff); 6)得到序列號的方法在理論部分已經詳細說明了,對應的函數是GetStringDescriptor,這里不再重復 |