windows - 当不知道 InterfaceClassGUID 时,我可以使用 SetupDiEnumDeviceInterfaces 从 SetupDiGetDeviceInterfaceDetail 获取 DevicePath 吗?

标签 windows winapi driver setupapi

概览...

我已阅读 How to get device interface GUID for a device?How to open a handle to a device using its Device Instance ID? , 但我仍然对我将如何(或者我是否应该)使用 SetupDiEnumDeviceInterfaces 感到困惑与 SetupDiGetDeviceInterfaceDetail 配对得到 DevicePath当没有 device interface class 时,可以用 CreateFile 打开以访问设备GUID 是已知的。我的问题基于 MSDN 文章 herehere它依赖于这些功能。

更多详情...

我的问题的高级别是我有一个音频 USB 设备,我需要发送控制传输命令。为此,我想使用 WinUSB 的 API。 ,要做到这一点,我需要通过 CreateFile 获取设备句柄。遗憾的是,没有与设备关联的 .inf 文件,因此没有已知的设备接口(interface)类 GUID。如果插入设备,Windows 将与其关联 usbaudio.sys作为司机。要开始讨论 WinUSB,我使用 libwdi安装 WinUSB 作为设备驱动程序,以便我可以通过 WinUSB API 与其通信。为了完成 WinUSB 的安装,libwdi 动态创建了一个自签名的 .cat 和 .inf 文件对,遗憾的是它没有定义设备接口(interface)类。事实上,INF 文件中有以下内容:

[NoDeviceInterfaceGUID]
; Avoids adding a DeviceInterfaceGUID for generic driver

因此,尽管我现在已将 usbaudio.sys 换成 winusb.sys,但我无法与设备通信。

起初我想也许我应该尝试使用 GUID_DEVINTERFACE_USB_DEVICE ,推断这是 WinUSB,因此被视为通用 USB 设备。但是,如果我调用

SetupDiEnumDeviceInterfaces(_deviceList,
   &devInfo,
   &GUID_DEVINTERFACE_USB_DEVICE,
   0,
   &usbInterface)

失败,GetLastError 立即返回 259 或 ERROR_NO_MORE_ITEMS。我假设这意味着它没有实现接口(interface)?

因此,一般来说,当不知道接口(interface)类 guid 时,我是否能够以任何形式使用上述函数来获取完整的设备路径? 提前感谢您的宝贵时间。

最佳答案

是的,首先需要通过SetupDiGetClassDevs获取实现接口(interface)的设备的设备信息集,然后选择其中一个设备读取其设备接口(interface)数据,并使用它来获取包含设备路径的设备接口(interface)详细信息。

例子:

#include <windows.h>
#include <setupapi.h>
#include <initguid.h>
#include <usbioctl.h>
#include <stdio.h>

BOOL DevicePath(_In_ LPCGUID interfaceGuid, DWORD instance)
{
    BOOL result = FALSE;
    PSP_DEVICE_INTERFACE_DETAIL_DATA_W devInterfaceDetailData = NULL;

    HDEVINFO hDevInfo = SetupDiGetClassDevsW(interfaceGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if(hDevInfo == INVALID_HANDLE_VALUE)
        goto cleanup;

    SP_DEVICE_INTERFACE_DATA devInterfaceData;
    devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    if(!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, interfaceGuid, instance, &devInterfaceData))
        goto cleanup;

    // Call this with an empty buffer to the required size of the structure.
    ULONG requiredSize;
    SetupDiGetDeviceInterfaceDetailW(hDevInfo, &devInterfaceData, NULL, 0, &requiredSize, NULL);
    if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        goto cleanup;

    devInterfaceDetailData = malloc(requiredSize);
    if(!devInterfaceDetailData)
        goto cleanup;

    devInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    if(!SetupDiGetDeviceInterfaceDetailW(hDevInfo, &devInterfaceData, devInterfaceDetailData, requiredSize, &requiredSize, NULL))
        goto cleanup;

    wprintf(L"%s\n", devInterfaceDetailData->DevicePath);
    result = TRUE;

cleanup:
    if(hDevInfo != INVALID_HANDLE_VALUE)
        SetupDiDestroyDeviceInfoList(hDevInfo);
    free(devInterfaceDetailData);
    return result;
}

int main()
{
    for(DWORD i = 0; DevicePath(&GUID_DEVINTERFACE_USB_DEVICE, i); ++i)
       ;
}

关于windows - 当不知道 InterfaceClassGUID 时,我可以使用 SetupDiEnumDeviceInterfaces 从 SetupDiGetDeviceInterfaceDetail 获取 DevicePath 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67527315/

相关文章:

c++ - 使用 __debugbreak 在 GoogleTest 中捕获自定义断言

c# - 在 C# 中,HttpClient.getStringAsync() 方法的同步替代方法是什么?

c++ - 使用c++和cygwin sshd服务的黑色截图

linux - Nvidia 显示驱动程序经常停止工作

Linux RFID 读取器 HID 设备与驱动程序不匹配

android - Eclipse IDE 无法识别 LG G2 (Android 4.2.2)

windows - .Net core 2.0 windows和jwt认证

windows - Windows 上的 Node.js 和文件系统 - EBUSY 错误

c++ - 在 win32 上将 wav 文件解码为 raw

windows - 在哪些情况下,GetSystemInfo/GetLogicalProcessorInformationEx 在同一程序运行中返回不同的处理器计数?