📄 usbviewdlg.cpp
字号:
*/
VOID CUsbviewDlg::EnumerateHub(
HTREEITEM hTreeParent,
PCHAR HubName,
PUSB_NODE_CONNECTION_INFORMATION ConnectionInfo,
PUSB_DESCRIPTOR_REQUEST ConfigDesc,
PSTRING_DESCRIPTOR_NODE StringDescs,
PCHAR DeviceDesc)
{
HANDLE hHubDevice;
HTREEITEM hItem;
PCHAR deviceName;
BOOL success;
ULONG nBytes;
PUSBDEVICEINFO info;
CHAR leafName[512]; // XXXXX how big does this have to be?
info = NULL;
hHubDevice = INVALID_HANDLE_VALUE;
//为USBDEVICEINFO结构分配内存来存储hub info,hub name和connection info pointers.
info=(PUSBDEVICEINFO)GlobalAlloc(GPTR,sizeof(USBDEVICEINFO));
if (info == NULL)
goto EnumerateHubError;
//保存hub name,connection info和configuration descriptor pointers
info->HubName = HubName;
info->ConnectionInfo = ConnectionInfo;
info->ConfigDesc = ConfigDesc;
info->StringDescs = StringDescs;
//为此hub分配一块存储USB_NODE_INFORMATION结构的内存区域
info->HubInfo=(PUSB_NODE_INFORMATION)GlobalAlloc(GPTR,sizeof(USB_NODE_INFORMATION));
if (info->HubInfo == NULL)
goto EnumerateHubError;
//为完整的hub device name分配一块临时buffer
deviceName = (PCHAR)GlobalAlloc(GPTR,strlen(HubName) + sizeof("\\\\.\\"));
if (deviceName == NULL)
goto EnumerateHubError;
//创建完整的hub device name
strcpy(deviceName,"\\\\.\\");
strcpy(deviceName+sizeof("\\\\.\\")-1,info->HubName);
//获取hub的句柄
hHubDevice = CreateFile(deviceName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
//完整的hub device name临时内存使用后
GlobalFree(deviceName);
if(hHubDevice==INVALID_HANDLE_VALUE)
goto EnumerateHubError;
//为此hub查询其USB_NODE_INFORMATION结构.此结构将告诉我们要枚举的端口数量等等信息
success=DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_INFORMATION,
info->HubInfo,
sizeof(USB_NODE_INFORMATION),
info->HubInfo,
sizeof(USB_NODE_INFORMATION),
&nBytes,
NULL);
if (!success)
goto EnumerateHubError;
//利用port number和device description创建树子项
if (ConnectionInfo) //NULL if root hub
{
wsprintf(leafName, "[Port%d] ", ConnectionInfo->ConnectionIndex);
strcat(leafName, PConnectionStatuse[ConnectionInfo->ConnectionStatus]);
strcat(leafName, " : ");
}
else
leafName[0] = 0;
if (DeviceDesc)
strcat(leafName,DeviceDesc);
else
strcat(leafName, info->HubName);
hItem = AddLeaf(hTreeParent,(LPARAM)info,leafName);
// hItem=m_tree.InsertItem(leafName,hTreeParent);
m_tree.Expand(hTreeParent,TVE_EXPAND);
if(hItem==NULL)
goto EnumerateHubError;
//递归地枚举此hub下的port
EnumerateHubPorts(hItem,hHubDevice,
info->HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts);
CloseHandle(hHubDevice);
return;
EnumerateHubError:
// Clean up any stuff that got allocated
if (hHubDevice != INVALID_HANDLE_VALUE)
{
CloseHandle(hHubDevice);
hHubDevice = INVALID_HANDLE_VALUE;
}
if (info != NULL)
{
if (info->HubName != NULL)
{
GlobalFree(info->HubName);
info->HubName = NULL;
}
if (info->HubInfo != NULL)
{
GlobalFree(info->HubInfo);
info->HubInfo;
}
GlobalFree(info);
info = NULL;
}
if (ConnectionInfo)
GlobalFree(ConnectionInfo);
if (ConfigDesc)
GlobalFree(ConfigDesc);
if (StringDescs != NULL)
{
PSTRING_DESCRIPTOR_NODE Next;
do
{
Next = StringDescs->Next;
GlobalFree(StringDescs);
StringDescs = Next;
}while(StringDescs!=NULL);
}
}
/*++
*函数:
EnumerateHubPorts();
*参数:
hTreeParent TreeItem句柄
hHubDevice 要枚举的hub device的句柄
NumPorts 此hub上的port的数量
*作用:
枚举root hub name下面usb hub中的port
*返回:
VOID
--*/
VOID CUsbviewDlg::EnumerateHubPorts(
HTREEITEM hTreeParent,
HANDLE hHubDevice,
ULONG NumPorts)
{
HTREEITEM hItem;
ULONG index;
BOOL success;
PUSB_NODE_CONNECTION_INFORMATION connectionInfo;
PUSB_DESCRIPTOR_REQUEST configDesc;
PSTRING_DESCRIPTOR_NODE stringDescs;
PUSBDEVICEINFO info;
PCHAR driverKeyName;
PCHAR deviceDesc;
CHAR deviceDescriptor[512];
CHAR leafName[512]; // XXXXX how big does this have to be?
// port索引从1开始,而不是0
for(index=1;index<=NumPorts;index++)
{
memset(deviceDescriptor,0,512);
ULONG nBytes;
// Allocate space to hold the connection info for this port.
// For now, allocate it big enough to hold info for 30 pipes.
// Endpoint numbers are 0-15. Endpoint number 0 is the standard
// control endpoint which is not explicitly listed in the Configuration
// Descriptor. There can be an IN endpoint and an OUT endpoint at
// endpoint numbers 1-15 so there can be a maximum of 30 endpoints
// per device configuration.
// Should probably size this dynamically at some point.
nBytes=sizeof(USB_NODE_CONNECTION_INFORMATION)+sizeof(USB_PIPE_INFO)*30;
connectionInfo=(PUSB_NODE_CONNECTION_INFORMATION)GlobalAlloc(GPTR,nBytes);
if(connectionInfo==NULL)
break;
// Now query USBHUB for the USB_NODE_CONNECTION_INFORMATION structure
// for this port. This will tell us if a device is attached to this
// port, among other things.
//在此port上查询此usb hub的USB_NODE_CONNECTION_INFORMATION结构体信息.它
//将告诉我们连接到此port的设备等等信息.
connectionInfo->ConnectionIndex = index;
success=DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
connectionInfo,
nBytes,
connectionInfo,
nBytes,
&nBytes,
NULL);
if(!success)
{
GlobalFree(connectionInfo);
continue;
}
//更新连接到设备的计数
if(connectionInfo->ConnectionStatus==DeviceConnected)
TotalDevicesConnected++;
//是否是hub
if(connectionInfo->DeviceIsHub)
TotalHubs++;
//如果有设备连接,获取device description
deviceDesc = NULL;
if(connectionInfo->ConnectionStatus!=NoDeviceConnected)
{
driverKeyName=GetDriverKeyName(hHubDevice,index);
if (driverKeyName)
{
deviceDesc=DriverNameToDeviceDesc(driverKeyName); //"USB 人体学输入设备"
strcpy(deviceDescriptor,deviceDesc);
GlobalFree(driverKeyName);
}
}
//如果有设备连接到port上,从设备获取设备的configuration descriptor
if(bConfigDesc&&connectionInfo->ConnectionStatus==DeviceConnected)
configDesc=GetConfigDescriptor(hHubDevice,index,0);
else
configDesc=NULL;
if(configDesc!=NULL&&
AreThereStringDescriptors(&connectionInfo->DeviceDescriptor,
(PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1)))
{
stringDescs=GetAllStringDescriptors(
hHubDevice,
index,
&connectionInfo->DeviceDescriptor,
(PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1));
}
else
stringDescs=NULL;
//如果设备连接的端口是一个外接hub,获取此外接hub的名称并递归地枚举它
if (connectionInfo->DeviceIsHub)
{
PCHAR extHubName;
extHubName = GetExternalHubName(hHubDevice,index);
if (extHubName != NULL)
{
EnumerateHub(hTreeParent, //hTreeItem,
extHubName,
connectionInfo,
configDesc,
stringDescs,
deviceDesc);
//下一个port
continue;
}
}
// Allocate some space for a USBDEVICEINFO structure to hold the
// hub info, hub name, and connection info pointers. GPTR zero
// initializes the structure for us.
info = (PUSBDEVICEINFO) GlobalAlloc(GPTR,sizeof(USBDEVICEINFO));
if (info == NULL)
{
if (configDesc != NULL)
GlobalFree(configDesc);
GlobalFree(connectionInfo);
break;
}
info->ConnectionInfo = connectionInfo;
info->ConfigDesc = configDesc;
info->StringDescs = stringDescs;
wsprintf(leafName, "[Port%d] ", index);
strcat(leafName, PConnectionStatuse[connectionInfo->ConnectionStatus]);
if (deviceDesc)
{
strcat(leafName, " : ");
strcat(leafName, deviceDescriptor);
}
// CString strTemp;
// strTemp.Empty();
// strTemp=leafName;
// m_tree.InsertItem(strTemp,hTreeParent);
hItem=AddLeaf(hTreeParent,(LPARAM)info,leafName);
m_tree.Expand(hTreeParent,TVE_EXPAND);
}
}
/*++
*函数:
GetRootHubName();
*参数:
HostController 打开的host controller句柄
*作用:
获取host controller的根hub名称
*返回:
非NULL 成功
NULL 失败
--*/
PCHAR CUsbviewDlg::GetRootHubName(HANDLE HostController)
{
BOOL success;
ULONG nBytes;
USB_ROOT_HUB_NAME rootHubName;
PUSB_ROOT_HUB_NAME rootHubNameW;
PCHAR rootHubNameA;
rootHubNameW = NULL;
rootHubNameA = NULL;
// Get the length of the name of the Root Hub attached to the
// Host Controller
success = DeviceIoControl(HostController,
IOCTL_USB_GET_ROOT_HUB_NAME,
0,
0,
&rootHubName,
sizeof(rootHubName),
&nBytes,
NULL);
if (!success)
goto GetRootHubNameError;
//分配保存Root Hub name的内存
nBytes = rootHubName.ActualLength;
rootHubNameW=(PUSB_ROOT_HUB_NAME)GlobalAlloc(GPTR,nBytes);
if (rootHubNameW == NULL)
goto GetRootHubNameError;
//获取隶属于host controller的root hub name
success = DeviceIoControl(HostController,
IOCTL_USB_GET_ROOT_HUB_NAME,
NULL,
0,
rootHubNameW,
nBytes,
&nBytes,
NULL);
if (!success)
goto GetRootHubNameError;
//转换Root Hub name
rootHubNameA = WideStrToMultiStr(rootHubNameW->RootHubName);
//返回未转换的root hub name,返回已经转换的root hub name
GlobalFree(rootHubNameW);
return rootHubNameA;
GetRootHubNameError:
if (rootHubNameW != NULL)
{
GlobalFree(rootHubNameW);
rootHubNameW = NULL;
}
return NULL;
}
PCHAR CUsbviewDlg::DriverNameToDeviceDesc (PCHAR DriverName)
{
CHAR buf[512];
DEVINST devInst;
DEVINST devInstNext;
CONFIGRET cr;
ULONG walkDone = 0;
ULONG len;
//获得设备节点的设备实例句柄,此次调用是得到设备管理树的根结点
// cr=CM_Locate_DevNode(&devInst,NULL,CM_LOCATE_DEVNODE_NORMAL);
cr=CM_Locate_DevNode(&devInst,NULL,0);
if (cr != CR_SUCCESS)
return NULL;
// Do a depth first search for the DevNode with a matching
// DriverName value
while (!walkDone)
{
// Get the DriverName value
//
len = sizeof(buf);
cr = CM_Get_DevNode_Registry_Property(devInst,
CM_DRP_DRIVER,
NULL,
buf,
&len,
0);
// If the DriverName value matches, return the DeviceDescription
//
if (cr == CR_SUCCESS && _stricmp(DriverName, buf) == 0)
{
len = sizeof(buf);
cr = CM_Get_DevNode_Registry_Property(devInst,
CM_DRP_DEVICEDESC,
NULL,
buf,
&len,
0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -