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

如何解决当不知道 InterfaceClassGUID 时,我可以使用 SetupDiEnumDeviceInterfaces 从 SetupDiGetDeviceInterfaceDetail 获取 DevicePath 吗?

概述...

我已经阅读了 How to get device interface GUID for a device?How to open a handle to a device using its Device Instance ID?,但我仍然对如何(或者我是否应该)使用 SetupDiEnumDeviceInterfacesSetupDiGetDeviceInterfaceDetail 配对感到困惑获取一个 DevicePath,当不知道 device interface class GUID 时,可以使用 CreateFile 打开它以访问设备。我的问题基于依赖这些函数的 MSDN 文章 herehere

更多详情...

我的问题最严重的是我有一个音频 USB 设备,我需要发送控制传输命令。为此,我想使用 WinUSB 的 API,并且要做到这一点,我需要通过 CreateFile 获取设备句柄。不幸的是,没有与设备关联的 .inf 文件,因此没有已知的设备接口类 GUID。如果插入设备,Windows 会将其关联为 usbaudio.sys 作为驱动程序。为了开始讨论 WinUSB,我使用 libwdi 安装 WinUSB 作为设备驱动程序,以便我可以通过 WinUSB API 与它通信。为了完成 WinUSB 的安装,libwdi 动态创建了一个自签名的 .cat 和 .inf 文件对,遗憾的是没有定义设备接口类。其实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,&usbInterface)

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

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

解决方法

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

示例:

#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,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,interfaceGuid,instance,&devInterfaceData))
        goto cleanup;

    // Call this with an empty buffer to the required size of the structure.
    ULONG requiredSize;
    SetupDiGetDeviceInterfaceDetailW(hDevInfo,&devInterfaceData,&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,devInterfaceDetailData,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)
       ;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?