walnutcy

识别USB端口程序开发感想收藏 (转)

0
阅读(4087)

程序功能:识别USB设备插在左边的U口还是右边的U口。

准备工作:1.下载资源:因为这个功能设计到驱动级别的编程(本人才疏学浅,可能对这一点的认识有偏差),所以windows自带的
API中没有实现此功能的函数,需要下载一套新的开发包。大家熟知的是Win_DDK,它里面有我们需要的API,这个软件XP版的非常不好下,因为微软是收费的,而且用它开发的人少,我记得当初是在某个ftp服务器上下的。

2.安装Win_DDK,我直接安装在了C:\\的路径下。然后在VC中设置Tools->Options->Directories中设置Win_DDK的路径,比如C:\WINDDK\2600\INC\WXP Project->setting->Link中设置需要的库文件,比如hid.lib setupapi.lib 库文件的路径我没有设置,直接把需要的.lib文件拷到当前路径下了。

识别USB端口函数的调用过程:

void IdentifyUSB::IdenUSB() 
{...}{
    HANDLE    hHCDev;
    HANDLE    hHubDevice;
    BOOL    success;
    PCHAR    deviceName;
    ULONG   nBytes;
    PCHAR   rootHubName;
    PUSB_NODE_CONNECTION_INFORMATION    connectionInfo;
//------打开HCDx端口,得到它的句柄------
    hHCDev = CreateFile("\\.\HCD2",        //注意这个形式:\.HCD0。具体原因我就不知道了,呵呵。
                    GENERIC_WRITE,
                    FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    0,
                    NULL);
    rootHubName =(char*) GetRootHubName(hHCDev);    //例子中现成的函数,直接拿来用了。

    deviceName = (PCHAR)malloc(strlen(rootHubName) + sizeof("\\.\"));
    strcpy(deviceName, "\\.\");
    strcpy(deviceName + sizeof("\\.\") - 1, rootHubName);
    hHubDevice = CreateFile(deviceName,    //形式大概是\.USB#ROOT_HUB#4&5f8db32&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
                    GENERIC_WRITE,
                    FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    0,
                    NULL);
    nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) + sizeof(USB_PIPE_INFO) * 30;              
    connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes);

    connectionInfo->ConnectionIndex = 1;        //查找端口1
//------得到端口1的一些参数------
    success = DeviceIoControl(hHubDevice,        //刚才得到的设备句柄
                      IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
                      connectionInfo,
                      nBytes,
                      connectionInfo,
                      nBytes,
                      &nBytes,
                      NULL);
    if (connectionInfo->ConnectionStatus == DeviceConnected)    //这里DeviceConnected是头文件中枚举类型
    {...}{
        m_Port = RIGHT_PORT;    //连同的是端口1
    }
    else    //查找端口2
    {...}{
//------得到端口2的一些参数------
        connectionInfo->ConnectionIndex = 2;
        success = DeviceIoControl(hHubDevice,
                          IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
                          connectionInfo,
                          nBytes,
                          connectionInfo,
                          nBytes,
                          &nBytes,
                          NULL);
        if (connectionInfo->ConnectionStatus == DeviceConnected)
        {
            m_Port = LEFT_PORT;
        }            
    }    
    
    CloseHandle(hHubDevice);
    CloseHandle(hHCDev);
}


PCHAR IdentifyUSB::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 IdentifyUSB::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;
}