📄 enum.c
字号:
/*++
Copyright (c) 1997-1998 Microsoft Corporation
Module Name:
ENUM.C
Abstract:
This source file contains the routines which enumerate the USB bus
and populate the TreeView control.
The enumeration process goes like this:
(1) Enumerate Host Controllers and Root Hubs
Host controllers currently have symbolic link names of the form HCDx,
where x starts at 0. Use CreateFile() to open each host controller
symbolic link. Create a node in the TreeView to represent each host
controller.
After a host controller has been opened, send the host controller an
IOCTL_USB_GET_ROOT_HUB_NAME request to get the symbolic link name of
the root hub that is part of the host controller.
(2) Enumerate Hubs (Root Hubs and External Hubs)
Given the name of a hub, use CreateFile() to hub the hub. Send the
hub an IOCTL_USB_GET_NODE_INFORMATION request to get info about the
hub, such as the number of downstream ports. Create a node in the
TreeView to represent each hub.
(3) Enumerate Downstream Ports
Given an handle to an open hub and the number of downstream ports on
the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
request for each downstream port of the hub to get info about the
device (if any) attached to each port. If there is a device attached
to a port, send the hub an IOCTL_USB_GET_NODE_CONNECTION_NAME request
to get the symbolic link name of the hub attached to the downstream
port. If there is a hub attached to the downstream port, recurse to
step (2). Create a node in the TreeView to represent each hub port
and attached device.
Environment:
user mode
Revision History:
04-25-97 : created
--*/
//*****************************************************************************
// I N C L U D E S
//*****************************************************************************
#include <windows.h>
#include <basetyps.h>
#include <winioctl.h>
#include <setupapi.h>
#include <string.h>
#include <stdio.h>
#include "usbview.h"
//*****************************************************************************
// D E F I N E S
//*****************************************************************************
#define NUM_HCS_TO_CHECK 10
//*****************************************************************************
// G L O B A L S
//*****************************************************************************
// List of enumerated host controllers.
//
LIST_ENTRY EnumeratedHCListHead =
{
&EnumeratedHCListHead,
&EnumeratedHCListHead
};
//*****************************************************************************
// L O C A L F U N C T I O N P R O T O T Y P E S
//*****************************************************************************
VOID
EnumerateHub (
HTREEITEM hTreeParent,
PCHAR HubName,
PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo,
PUSB_DESCRIPTOR_REQUEST ConfigDesc,
PSTRING_DESCRIPTOR_NODE StringDescs,
PCHAR DeviceDesc
);
VOID
EnumerateHubPorts (
HTREEITEM hTreeParent,
HANDLE hHubDevice,
ULONG NumPorts
);
PCHAR GetRootHubName (
HANDLE HostController
);
PCHAR GetExternalHubName (
HANDLE Hub,
ULONG ConnectionIndex
);
PCHAR GetHCDDriverKeyName (
HANDLE HCD
);
PCHAR GetDriverKeyName (
HANDLE Hub,
ULONG ConnectionIndex
);
PUSB_DESCRIPTOR_REQUEST
GetConfigDescriptor (
HANDLE hHubDevice,
ULONG ConnectionIndex,
UCHAR DescriptorIndex
);
BOOL
AreThereStringDescriptors (
PUSB_DEVICE_DESCRIPTOR DeviceDesc,
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
);
PSTRING_DESCRIPTOR_NODE
GetAllStringDescriptors (
HANDLE hHubDevice,
ULONG ConnectionIndex,
PUSB_DEVICE_DESCRIPTOR DeviceDesc,
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
);
PSTRING_DESCRIPTOR_NODE
GetStringDescriptor (
HANDLE hHubDevice,
ULONG ConnectionIndex,
UCHAR DescriptorIndex,
USHORT LanguageID
);
PSTRING_DESCRIPTOR_NODE
GetStringDescriptors (
HANDLE hHubDevice,
ULONG ConnectionIndex,
UCHAR DescriptorIndex,
ULONG NumLanguageIDs,
USHORT *LanguageIDs,
PSTRING_DESCRIPTOR_NODE StringDescNodeTail
);
//*****************************************************************************
// G L O B A L S P R I V A T E T O T H I S F I L E
//*****************************************************************************
PCHAR ConnectionStatuses[] =
{
"NoDeviceConnected",
"DeviceConnected",
"DeviceFailedEnumeration",
"DeviceGeneralFailure",
"DeviceCausedOvercurrent",
"DeviceNotEnoughPower"
};
ULONG TotalDevicesConnected;
//*****************************************************************************
//
// EnumerateHostController()
//
// hTreeParent - Handle of the TreeView item under which host controllers
// should be added.
//
//*****************************************************************************
VOID
EnumerateHostController (
HTREEITEM hTreeParent,
HANDLE hHCDev,
PCHAR leafName
)
{
PCHAR driverKeyName;
PCHAR deviceDesc;
PCHAR deviceId;
HTREEITEM hHCItem;
PCHAR rootHubName;
PLIST_ENTRY listEntry;
PUSBHOSTCONTROLLERINFO hcInfo;
PUSBHOSTCONTROLLERINFO hcInfoInList;
// Allocate a structure to hold information about this host controller.
//
hcInfo = (PUSBHOSTCONTROLLERINFO)ALLOC(sizeof(USBHOSTCONTROLLERINFO));
if (hcInfo != NULL)
{
hcInfo->DeviceInfoType = HostControllerInfo;
// Obtain the driver key name for this host controller.
//
driverKeyName = GetHCDDriverKeyName(hHCDev);
if (driverKeyName)
{
// Don't enumerate this host controller again if it already
// on the list of enumerated host controllers.
//
listEntry = EnumeratedHCListHead.Flink;
while (listEntry != &EnumeratedHCListHead)
{
hcInfoInList = CONTAINING_RECORD(listEntry,
USBHOSTCONTROLLERINFO,
ListEntry);
if (strcmp(driverKeyName, hcInfoInList->DriverKey) == 0)
{
// Already on the list, exit
//
FREE(driverKeyName);
FREE(hcInfo);
return;
}
listEntry = listEntry->Flink;
}
// Obtain the device id string for this host controller.
// (Note: this a tmp global string buffer, make a copy of
// this string if it will used later.)
//
deviceId = DriverNameToDeviceDesc(driverKeyName, TRUE);
if (deviceId)
{
ULONG ven, dev, subsys, rev;
if (sscanf(deviceId,
"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x",
&ven, &dev, &subsys, &rev) != 4)
{
OOPS();
}
hcInfo->DriverKey = driverKeyName;
hcInfo->VendorID = ven;
hcInfo->DeviceID = dev;
hcInfo->SubSysID = subsys;
hcInfo->Revision = rev;
}
else
{
OOPS();
}
// Obtain the device description string for this host controller.
// (Note, this a tmp global string buffer, make a copy of
// this string if it will be used later.)
//
deviceDesc = DriverNameToDeviceDesc(driverKeyName, FALSE);
if (deviceDesc)
{
leafName = deviceDesc;
}
else
{
OOPS();
}
// Add this host controller to the USB device tree view.
//
hHCItem = AddLeaf(hTreeParent,
(LPARAM)hcInfo,
leafName,
GoodDeviceIcon);
if (hHCItem)
{
// Add this host controller to the list of enumerated
// host controllers.
//
InsertTailList(&EnumeratedHCListHead,
&hcInfo->ListEntry);
// Get the name of the root hub for this host
// controller and then enumerate the root hub.
//
rootHubName = GetRootHubName(hHCDev);
if (rootHubName != NULL)
{
EnumerateHub(hHCItem,
rootHubName,
NULL, // ConnectionInfo
NULL, // ConfigDesc
NULL, // StringDescs
"RootHub" // DeviceDesc
);
}
else
{
// Failure obtaining root hub name.
OOPS();
}
}
else
{
// Failure adding host controller to USB device tree
// view.
OOPS();
FREE(driverKeyName);
FREE(hcInfo);
}
}
else
{
// Failure obtaining driver key name.
OOPS();
FREE(hcInfo);
}
}
}
//*****************************************************************************
//
// EnumerateHostControllers()
//
// hTreeParent - Handle of the TreeView item under which host controllers
// should be added.
//
//*****************************************************************************
VOID
EnumerateHostControllers (
HTREEITEM hTreeParent,
ULONG *DevicesConnected
)
{
char HCName[16];
int HCNum;
HANDLE hHCDev;
PCHAR leafName;
HDEVINFO deviceInfo;
SP_DEVICE_INTERFACE_DATA deviceInfoData;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData;
ULONG index;
ULONG requiredLength;
TotalDevicesConnected = 0;
TotalHubs = 0;
// Iterate over some Host Controller names and try to open them.
//
for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)
{
wsprintf(HCName, "\\\\.\\HCD%d", HCNum);
hHCDev = CreateFile(HCName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
// If the handle is valid, then we've successfully opened a Host
// Controller. Display some info about the Host Controller itself,
// then enumerate the Root Hub attached to the Host Controller.
//
if (hHCDev != INVALID_HANDLE_VALUE)
{
leafName = HCName + sizeof("\\\\.\\") - sizeof("");
EnumerateHostController(hTreeParent,
hHCDev,
leafName);
CloseHandle(hHCDev);
}
}
// Now iterate over host controllers using the new GUID based interface
//
deviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER,
NULL,
NULL,
(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (index=0;
SetupDiEnumDeviceInterfaces(deviceInfo,
0,
(LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER,
index,
&deviceInfoData);
index++)
{
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&deviceInfoData,
NULL,
0,
&requiredLength,
NULL);
deviceDetailData = GlobalAlloc(GPTR, requiredLength);
deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&deviceInfoData,
deviceDetailData,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -