📄 usbtree.cpp
字号:
// UsbTree.cpp: implementation of the CUsbTree class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "HidTool.h"
#include <cfgmgr32.h>
#include "UsbTree.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#pragma comment(lib, "cfgmgr32.lib")
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CUsbTree::CUsbTree()
{
}
CUsbTree::~CUsbTree()
{
}
DWORD CUsbTree::EnumHostControllers( // 枚举USB主机控制器
IN OUT LPDWORD pdwHCCount,
OUT HC_InfoStruct * lpHCInfo
)
{
DWORD dwHCCount, dwNameLen;
TCHAR szHCName[MAX_HC_DEVNAME_LEN];
HANDLE hHCDev;
HC_InfoStruct phcInfo[MAX_PORTS_NUM];
// 检查存放控制器信息的缓存指针
if (lpHCInfo == NULL)
return UT_INVALID_BUFFER;
for (dwHCCount=0 ; dwHCCount<MAX_PORTS_NUM; dwHCCount++)
{
// 构造主机控制器的设备名称
wsprintf(szHCName, "\\\\.\\HCD%d", dwHCCount);
// 尝试打开设备
hHCDev = CreateFile(szHCName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hHCDev == INVALID_HANDLE_VALUE)
{
// 如果不存在指定的主机控制器,结束枚举过程
break;
}
// 指定的主机控制器存在,获取控制器信息
lstrcpy(phcInfo[dwHCCount].szDevName, szHCName);
dwNameLen = MAX_PATH - 2;
GetHCDDriverKeyName(hHCDev, &dwNameLen, phcInfo[dwHCCount].szDriverName);
// 获取设备描述名称
dwNameLen = sizeof(phcInfo[dwHCCount].szDevDesc) - 2;
DriverNameToDeviceDesc(phcInfo[dwHCCount].szDriverName,
&dwNameLen,
phcInfo[dwHCCount].szDevDesc);
// 获取 Root Hub 名称
GetRootHubName(hHCDev, &dwNameLen, phcInfo[dwHCCount].szRootHub);
CloseHandle(hHCDev);
}
if (*pdwHCCount < dwHCCount)
{
*pdwHCCount = dwHCCount;
return UT_BUFFER_TOO_SMALL;
}
// 设置枚举到的控制器数量,并往缓存里拷贝控制器信息
*pdwHCCount = dwHCCount;
memcpy(lpHCInfo, phcInfo, dwHCCount * sizeof(HC_InfoStruct));
return UT_SUCESS;
}
DWORD CUsbTree::EnumerateHubPorts (
IN LPCTSTR szHubName,
IN OUT LPDWORD pdwPortNum,
OUT HubPortStruct * lpHubPorts
)
{
BOOL bSuccess;
HANDLE hHubDevice = INVALID_HANDLE_VALUE;
DWORD nBytes, dwPortCount, dwRV;
DWORD dwIndex, dwErr;
TCHAR szHubDevName[MAX_PATH];
USB_NODE_INFORMATION hubInfo;
PUSB_NODE_CONNECTION_INFORMATION connectionInfo;
// 打开集线器设备
wsprintf(szHubDevName, "\\\\.\\%s", szHubName);
hHubDevice = CreateFile(szHubDevName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hHubDevice == INVALID_HANDLE_VALUE)
return UT_UNABLE_ACCESS_DEV;
// 最多包含30个端点的信息
nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) +
sizeof(USB_PIPE_INFO) * 30;
connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes);
if (connectionInfo == NULL)
{
dwRV = UT_FAIL_MEM_ACCESS;
goto exitEnumerateHubPorts;
}
dwRV = UT_SUCESS;
// 获取集线器节点的信息
bSuccess = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_INFORMATION,
&hubInfo,
sizeof(USB_NODE_INFORMATION),
&hubInfo,
sizeof(USB_NODE_INFORMATION),
&nBytes,
NULL);
if (!bSuccess)
{
dwErr = GetLastError();
dwRV = UT_UNABLE_GET_NODEINFO;
goto exitEnumerateHubPorts;
}
dwPortCount = hubInfo.u.HubInformation.HubDescriptor.bNumberOfPorts;
// 检查函数调用者是否分配足够的缓冲区
if (*pdwPortNum < dwPortCount)
{
*pdwPortNum = dwPortCount;
dwRV = UT_BUFFER_TOO_SMALL;
goto exitEnumerateHubPorts;
}
// 逐个获取每个端口的信息
*pdwPortNum = dwPortCount;
for (dwIndex=0 ; dwIndex<dwPortCount ; dwIndex++)
{
// 获取当前节点的连接信息
nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) +
sizeof(USB_PIPE_INFO) * 30;
connectionInfo->ConnectionIndex = dwIndex + 1;
bSuccess = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
connectionInfo,
nBytes,
connectionInfo,
nBytes,
&nBytes,
NULL);
if (!bSuccess)
{
dwErr = GetLastError();
dwRV = UT_UNABLE_GET_NODEINFO;
goto exitEnumerateHubPorts;
}
lpHubPorts[dwIndex].bExtHub = connectionInfo->DeviceIsHub;
lpHubPorts[dwIndex].bConnected = (connectionInfo->ConnectionStatus == DeviceConnected);
// 获取连接设备的驱动名称和设备描述
if (lpHubPorts[dwIndex].bConnected)
{
nBytes = sizeof(lpHubPorts[dwIndex].szDriverName) - 2;
dwRV = GetDriverKeyName(hHubDevice, dwIndex+1, &nBytes, lpHubPorts[dwIndex].szDriverName);
if (dwRV != UT_SUCESS)
goto exitEnumerateHubPorts;
nBytes = sizeof(lpHubPorts[dwIndex].szDevDesc) - 2;
dwRV = DriverNameToDeviceDesc(lpHubPorts[dwIndex].szDriverName,
&nBytes,
lpHubPorts[dwIndex].szDevDesc);
if (dwRV != UT_SUCESS)
goto exitEnumerateHubPorts;
}
// 如果端口上连接的是HUB,则获得其名称
if (lpHubPorts[dwIndex].bExtHub)
{
nBytes = sizeof(lpHubPorts[dwIndex].szHubName) - 2;
dwRV = GetExternalHubName(hHubDevice, dwIndex+1, &nBytes, lpHubPorts[dwIndex].szHubName);
if (dwRV != UT_SUCESS)
goto exitEnumerateHubPorts;
}
}
exitEnumerateHubPorts:
// 关闭集线器设备句柄
if (INVALID_HANDLE_VALUE != hHubDevice)
{
CloseHandle(hHubDevice);
hHubDevice = INVALID_HANDLE_VALUE;
}
//
if (connectionInfo != NULL)
{
free(connectionInfo);
connectionInfo = NULL;
}
return dwRV;
}
DWORD CUsbTree::GetHCDDriverKeyName (
IN HANDLE hHcd,
IN OUT LPDWORD pdwNameLen,
OUT LPTSTR szHcdDrvName
)
{
BOOL bSuccess;
DWORD nBytes;
USB_HCD_DRIVERKEY_NAME driverKeyName;
PUSB_HCD_DRIVERKEY_NAME driverKeyNameW;
driverKeyNameW = NULL;
// 获取控制器驱动名称的长度
bSuccess = DeviceIoControl(hHcd,
IOCTL_GET_HCD_DRIVERKEY_NAME,
&driverKeyName,
sizeof(driverKeyName),
&driverKeyName,
sizeof(driverKeyName),
&nBytes,
NULL);
if (!bSuccess)
return UT_UNABLE_GET_HCDNAME;
// 如果缓冲区太小,返回实际长度(附加两个字节的冗余)
if (driverKeyName.ActualLength > *pdwNameLen)
{
*pdwNameLen = driverKeyName.ActualLength + 2;
return UT_BUFFER_TOO_SMALL;
}
// 分配接收UNICODE名称的内存
nBytes = driverKeyName.ActualLength;
driverKeyNameW = (PUSB_HCD_DRIVERKEY_NAME)malloc(nBytes);
if (driverKeyNameW == NULL)
return UT_FAIL_MEM_ACCESS;
DWORD dwRV = UT_SUCESS;
// 获取实际的主机控制器名称
bSuccess = DeviceIoControl(hHcd,
IOCTL_GET_HCD_DRIVERKEY_NAME,
driverKeyNameW,
nBytes,
driverKeyNameW,
nBytes,
&nBytes,
NULL);
if (!bSuccess)
{
dwRV = UT_UNABLE_GET_HCDNAME;
goto GetHCDDriverKeyNameError;
}
// Convert the driver key name
//
*pdwNameLen = WideCharToMultiByte(CP_ACP, 0, driverKeyNameW->DriverKeyName,
-1, (PCHAR)szHcdDrvName, nBytes, NULL, NULL);
GetHCDDriverKeyNameError:
// There was an error, free anything that was allocated
//
if (driverKeyNameW != NULL)
{
free(driverKeyNameW);
driverKeyNameW = NULL;
}
return dwRV;
}
DWORD CUsbTree::GetDriverKeyName (
IN HANDLE hHubDevice,
IN DWORD dwPortIndex,
IN OUT LPDWORD pdwNameLen,
OUT LPTSTR szDrvName
)
{
DWORD dwRV = UT_SUCESS;
BOOL bSuccess;
ULONG nBytes;
USB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyName;
PUSB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyNameW;
driverKeyNameW = NULL;
// Get the length of the name of the driver key of the device attached to
// the specified port.
//
driverKeyName.ConnectionIndex = dwPortIndex;
bSuccess = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
&driverKeyName,
sizeof(driverKeyName),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -