阅读:3282回复:6
有关USB设备数据通讯的问题
我正在做USB的上位机程序。我准备使用API做。
算法如下: 利用CreateFile获得计算机上的所有USB控制器 通过DeviceIoControl函数获得这个控制器的驱动程序和Hub名称 利用CreateFile函数打开刚刚获得的HUB 用DeviceIoControl函数获得HUB上可用的所有端口 用DeviceIoControl函数测量每一个端口上是否连接设备 若连接,则打开设备,开始对设备读写。 现在就有这个问题:能够检测到这个计算机上连接的所有设备,以及它连接的Hub的句柄和端口好。但是想建立这个设备的句柄(使用CreateFile),就出问题了。打开的Handle是-1。我不知道为什么 wc171170@163.com QQ:467664150 #include "stdafx.h" #include "USB.h" #ifdef _DEBUG #include<iostream> using namespace std; #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CUSB::CUSB() { char sHCD[16]; int i,j,PortNum; HANDLE hHCD,hHUB,hDevice; PCHAR rootHubName,DeviceName; PCHAR sHUB,sDevice; PUSB_NODE_INFORMATION HubInfo; PUSB_NODE_CONNECTION_INFORMATION connection; unsigned long lResult,nBytes; DefNum=0; for(i=0;i<32;i++) { wsprintf(sHCD, "\\\\.\\HCD%d", i); hHCD=CreateFile(sHCD,GENERIC_WRITE + GENERIC_READ, FILE_SHARE_WRITE + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(hHCD==INVALID_HANDLE_VALUE) break; rootHubName=GetHubName(hHCD); sHUB=(PCHAR)malloc(strlen(rootHubName)+strlen("\\\\.\\")+1); strcpy(sHUB,"\\\\.\\"); strcpy(sHUB + strlen("\\\\.\\"), rootHubName); free(rootHubName); cout<<sHUB<<endl; hHUB=CreateFile(sHUB, GENERIC_WRITE + GENERIC_READ, FILE_SHARE_WRITE + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); free(sHUB); HubInfo=PUSB_NODE_INFORMATION(malloc(sizeof(USB_NODE_INFORMATION))); lResult=DeviceIoControl(hHUB, IOCTL_USB_GET_NODE_INFORMATION, HubInfo, sizeof(USB_NODE_INFORMATION), HubInfo, sizeof(USB_NODE_INFORMATION), &nBytes, NULL); PortNum=HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts; for(j=0;j<PortNum;j++) { nBytes=sizeof(USB_NODE_CONNECTION_INFORMATION)+sizeof(USB_PIPE_INFO)*30; connection= (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes); connection->ConnectionIndex=j; lResult = DeviceIoControl(hHUB, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, connection, nBytes, connection, nBytes, &nBytes, NULL); if (connection->ConnectionStatus == DeviceConnected) { DeviceName=GetDeviceName(hHUB,j); cout<<DeviceName<<endl; sDevice=(PCHAR)malloc(strlen(DeviceName)+strlen("\\\\.\\")+1); strcpy(sDevice,"\\\\.\\"); strcat(sDevice, DeviceName); free(DeviceName); hDevice=CreateFile(sDevice, GENERIC_WRITE + GENERIC_READ, FILE_SHARE_WRITE + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); Devices[DefNum++]=hDevice; free(sDevice); } free(connection); } free(HubInfo); CloseHandle(hHUB); CloseHandle(hHCD); } DefNum=0; } CUSB::~CUSB() { for(int i=0;i<DefNum;i++) CloseHandle(Devices); } PCHAR CUSB::GetHubName(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 CUSB::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; } PCHAR CUSB::GetDeviceName(HANDLE Hub, ULONG ConnectionIndex) { BOOL success; ULONG nBytes; USB_NODE_CONNECTION_NAME nodeName; PUSB_NODE_CONNECTION_NAME nodeNameW=NULL; PCHAR nodeNameA=NULL; nodeName.ConnectionIndex=ConnectionIndex; success = DeviceIoControl(Hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, &nodeName, sizeof(nodeName), &nodeName, sizeof(nodeName), &nBytes, NULL); if(!success) goto GetDeviceNameError; nBytes=nodeName.ActualLength; if(nBytes<sizeof(nodeName)) goto GetDeviceNameError; nodeNameW=(PUSB_NODE_CONNECTION_NAME)malloc(nBytes); nodeNameW->ConnectionIndex=ConnectionIndex; success = DeviceIoControl(Hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, nodeNameW, nBytes, nodeNameW, nBytes, &nBytes, NULL); if(!success) goto GetDeviceNameError; nodeNameA=WideStrToMultiStr(nodeNameW->NodeName); return nodeNameA; GetDeviceNameError: if(nodeNameW) free(nodeNameW); return NULL; } PCHAR CUSB::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; } |
|
沙发#
发布于:2008-01-22 16:58
比较特别的思路,为何不用SetupEnumDeviceXXX(),,然后CreateFile()
|
|
板凳#
发布于:2008-01-22 17:30
问
SetupEnumDeviceXXX()怎么用? |
|
地板#
发布于:2008-01-23 13:26
楼主的这个思路是参考了DDk自带的程序usbview里做的。我原来也是这么做的,不太好理解。可以用spin提出的枚举的方法来实现。
unsigned long ReqLength=0; unsigned long Length; int Flags=DIGCF_PRESENT|DIGCF_DEVICEINTERFACE; HANDLE hDevInfo; int Index =1; BOOL status; int Error_Code; bool bResult=FALSE; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceDetailData; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; memset(&DeviceInterfaceData,0,sizeof(SP_DEVICE_INTERFACE_DATA)); DeviceInterfaceData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA); hDevInfo=SetupDiGetClassDevs(&USBGuid,NULL,NULL,Flags); status=SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&USBGuid,Index, &DeviceInterfaceData); if(!status) { Error_Code=GetLastError(); CloseHandle(hDevInfo); return; } SetupDiGetInterfaceDeviceDetail(hDevInfo,&DeviceInterfaceData,NULL,0,&Length,NULL); DeviceDetailData=(PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(Length); if(!DeviceDetailData) { Error_Code=GetLastError(); CloseHandle(hDevInfo); return; } memset(DeviceDetailData,0,sizeof(PSP_INTERFACE_DEVICE_DETAIL_DATA)); ReqLength = Length; DeviceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); status=SetupDiGetInterfaceDeviceDetail(hDevInfo,&DeviceInterfaceData,DeviceDetailData,Length,&ReqLength,NULL); if(!status) { Error_Code=GetLastError(); free(DeviceDetailData); DeviceDetailData=NULL; return; } Driver_Handle=CreateFile(DeviceDetailData->DevicePath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if (Driver_Handle==INVALID_HANDLE_VALUE) { Error_Code=GetLastError(); return; } 注意:这里的USBGuid是通用的GUID,定义如下: GUID USBGuid= {0xA5DCBF10,0x6530,0x11D2,{0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}}; 希望对你有帮助。 |
|
地下室#
发布于:2008-01-23 14:23
但是这么做只能打开HID设备,如果是非HID的USB设备呢
|
|
5楼#
发布于:2008-01-23 17:42
我的是usb dongle,可以找到并打开的。你试一下。
|
|
6楼#
发布于:2008-03-26 09:09
先输出rootHubName看看值对不
若对 再检查sHUB的值对不??? 若不对 把 sHUB=(PCHAR)malloc(strlen(rootHubName)+strlen("\\\\.\\")+1); strcpy(sHUB,"\\\\.\\"); strcpy(sHUB + strlen("\\\\.\\"), rootHubName); 换成 sHUB= (PCHAR)malloc(strlen(rootHubName) + sizeof("\\\\.\\")); strcpy(sHUB, "\\\\.\\"); strcpy(sHUB+ sizeof("\\\\.\\"), rootHubName); 试试 如果sHUB值对的话, 获得句柄是没有问题的应该 |
|