wc171170
驱动牛犊
驱动牛犊
  • 注册日期2008-01-22
  • 最后登录2008-02-01
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:3282回复:6

有关USB设备数据通讯的问题

楼主#
更多 发布于:2008-01-22 14:06
我正在做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;
}
spin
驱动小牛
驱动小牛
  • 注册日期2001-04-17
  • 最后登录2015-10-27
  • 粉丝1
  • 关注0
  • 积分46分
  • 威望354点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-01-22 16:58
比较特别的思路,为何不用SetupEnumDeviceXXX(),,然后CreateFile()
wc171170
驱动牛犊
驱动牛犊
  • 注册日期2008-01-22
  • 最后登录2008-02-01
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-01-22 17:30
SetupEnumDeviceXXX()怎么用?
butflying
驱动牛犊
驱动牛犊
  • 注册日期2008-01-21
  • 最后登录2008-08-06
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于: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}};
希望对你有帮助。
wc171170
驱动牛犊
驱动牛犊
  • 注册日期2008-01-22
  • 最后登录2008-02-01
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-01-23 14:23
但是这么做只能打开HID设备,如果是非HID的USB设备呢
butflying
驱动牛犊
驱动牛犊
  • 注册日期2008-01-21
  • 最后登录2008-08-06
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-01-23 17:42
我的是usb dongle,可以找到并打开的。你试一下。
BrightLiu
驱动牛犊
驱动牛犊
  • 注册日期2008-02-22
  • 最后登录2008-03-26
  • 粉丝1
  • 关注0
  • 积分10分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
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值对的话, 获得句柄是没有问题的应该
游客

返回顶部