0

我对 USB IOCTL IOCTL_USB_GET_ROOT_HUB_NAME有点困惑。它的目标设备是什么?虽然 MSDN WDK 文档清楚地表明了目标设备,但我仍然对 WDK 提供的 USBVIEW 示例感到困惑。我感到困惑的原因如下:

我是在 Windows 中编写内核模式和 USB 驱动程序的新手,现在正在研究 Windows 驱动程序套件中的 USBVIEW 示例http://msdn.microsoft.com/en-us/library/ff558728(v=vs.85).aspx . MSDN 将 USBVIEW 示例执行的第一步描述为:

枚举主机控制器和根集线器。主机控制器具有“HCDx”形式的符号链接名称,其中 x 从 0 开始。

使用 CreateFile() 打开每个主机控制器符号链接。

在树视图中创建一个节点来表示每个主机控制器。

打开主机控制器后,向主机控制器发送 IOCTL_USB_GET_ROOT_HUB_NAME 请求以获取作为主机控制器一部分的根集线器的符号链接名称

但是,我仔细检查了 MSDN http://msdn.microsoft.com/en-us/library/ff537326(v=VS.85).aspx中 IOCTL_USB_GET_ROOT_HUB_NAME 的使用情况,上面 写着:

IOCTL_USB_GET_ROOT_HUB_NAME 是用户模式 ​​I/O 控制请求。此请求以USB 集线器 FDO为目标。

请注意,IOCTL_USB_GET_ROOT_HUB_NAME IRP 的目标是 USB 集线器 FDO。但是,正如 USBVIEW 示例所描述的,我们只是检索了主机控制器符号链接,这意味着设备对象是主机控制器设备对象。我们如何向它发送 IOCTL_USB_GET_ROOT_HUB_NAME IRP?我们应该先以某种方式检索 USB 集线器 FDO 吗?

4

2 回答 2

2

我猜这是一个不幸的复制粘贴错误。IOCTL_USB_GET_ROOT_HUB_NAME确实发送到主机控制器,因此由 USB 主机控制器 FDO 处理。

顺便说一句,只是为了让您了解上下文:术语“FDO”只是松散地涉及用户模式-无论如何您都不能访问任何其他“xDO”。如果您要在内核模式下发送此 IOCTL,那么可以肯定,您可以将 IOCTL 发送到设备堆栈中的任何特定设备对象(“可以”并不意味着“应该”,请注意)。但是,DeviceIoControl来自用户模式的应用程序总是将 IOCTL 发送到设备堆栈的顶部(因此它通过所有过滤器、FDO 并向下传递到 PDO)。

这个问题是在 3 月 28 日提出的,所以我真的希望你现在已经解决了:)

于 2011-04-27T20:04:40.560 回答
0

正如文档所述,您将需要 USB 主机控制器的句柄,但不清楚您应该如何获得这样的句柄。在 USBView 中,与此函数类似的东西用于通过传递GUID_DEVINTERFACE_USB_HOST_CONTROLLER(包括initguid.husbiodef.h)来获取设备路径名:

vector<wstring> EnumDevices(
    _In_    const GUID Guid
)
{
    vector<wstring> r;

    int index = 0;
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    SP_DEVINFO_DATA DevInfoData;
    memset(&DevInfoData, 0, sizeof(SP_DEVINFO_DATA));
    DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    while (SetupDiEnumDeviceInfo(hDevInfo, index, &DevInfoData)) {
        index++;

        int jndex = 0;
        SP_DEVICE_INTERFACE_DATA DevIntData;
        memset(&DevIntData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
        DevIntData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

        while (SetupDiEnumDeviceInterfaces(
            hDevInfo,
            &DevInfoData, &Guid, jndex, &DevIntData
        )) {
            jndex++;

            // Get the size required for the structure.
            DWORD RequiredSize;
            SetupDiGetDeviceInterfaceDetail(
                hDevInfo, &DevIntData, NULL, NULL, &RequiredSize, NULL
            );

            PSP_DEVICE_INTERFACE_DETAIL_DATA pDevIntDetData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(
                sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + RequiredSize
            );
            memset(pDevIntDetData, 0, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + RequiredSize);
            pDevIntDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

            SetupDiGetDeviceInterfaceDetail(
                hDevInfo,
                &DevIntData,
                pDevIntDetData, RequiredSize,
                NULL,
                &DevInfoData
            );

            r.push_back(wstring(pDevIntDetData->DevicePath));
            free(pDevIntDetData);
        }
    }

    return r;
}

请记住,使用上述功能,您还可以请求类型的设备,GUID_DEVINTERFACE_USB_HUBGUID_DEVINTERFACE_USB_DEVICE可以消除直接与主机控制器或集线器交互的任何需要。

于 2018-06-17T21:33:34.420 回答