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

2023-12-14

概述...

我读过了如何获取设备的设备接口 GUID? and 如何使用设备实例 ID 打开设备的句柄?,但我仍然对如何(或者是否应该)使用感到困惑设置DiEnumDeviceInterfaces设置DiGetDeviceInterfaceDetail得到一个设备路径可以用以下命令打开创建文件没有时访问设备设备接口类GUID 已知。我的问题是基于 MSDN 文章here and here依赖于这些功能。

更多细节...

我的最大问题是我有一个音频 USB 设备,我需要发送控制传输命令。为此,我想使用 WinUSBAPI,并要做that我需要通过 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,
   0,
   &usbInterface)

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

那么,一般来说,当不知道接口类 guid 时,我是否可以以任何形式使用上述函数来获取完整的设备路径? 在此先感谢您的时间。


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

Example:

#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)
       ;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 游戏在快速从后台恢复后退出暂停状态

    我正在使用 SpriteKit 开发一个游戏 可以在执行期间暂停并可以恢复 但我有一个问题applicationDidEnterBackground当游戏暂停时按下主页按钮时 因为当我恢复游戏时 即使游戏之前已暂停 实体也会立即开始移动 我
  • android studio 禁用日期选择器中的天数

    我想禁用日期选择器中的某一天 我有一个数组存储我想要禁用的日期 我有这个代码来禁用日历中的日期 for Calendar loopdate min date c min date c before max date c min date c
  • 如何将原始电子邮件 (MIME) 从 AWS SES 转换为 Gmail?

    我有一个 Gmail 帐户链接到我的域帐户 AWS SES 会将消息发送到我的 S3 存储桶 从那里 SNS 将以原始格式将消息转发到我的 Gmail 地址 如何自动将原始消息转换为标准电子邮件格式 原始消息采用标准电子邮件格式 我认为您想
  • python 中的运算符重载,对象位于运算符右侧

    我最近了解了 python 中的运算符重载 我想知道以下内容是否可行 考虑以下假设 人为的类 class My Num object def init self val self val val def add self other num
  • C++ getline 方法不起作用

    抱歉 我对 C 很陌生 但一般不熟悉编程 所以我尝试做一个简单的加密 解密 然而 当我对以前的代码添加修改时 因此没有两个用于加密和解密的程序 我发现代码 getline 方法不再起作用 相反 它只是在运行代码时忽略它 这是代码 int m
  • 在 Google 自定义搜索中使用 TBS(或等效参数)

    使用时谷歌自定义搜索用于选择特定类型搜索引擎的 TBM 参数 例如 专利的 tbm pts 或博客的 tbm blg 似乎受到支持 尽管参数列表中没有正确记录这一点 然而 当使用这种 特殊 搜索时 通常会使用 TBS 参数来扩展查询 不幸的
  • 敏感的 ASP.NET Session 数据是否需要加密?

    ASP NET Session string key 数据是否需要加密才能安全 如果此类数据始终保留在服务器上 那么只要数据是通过 SSL 从客户端发送的 那么在那里存储信用卡信息 密码等是否就可以安全了 鉴于所有的反对票都投在这里 我将添
  • 在android中显示后台服务的弹出窗口

    您好 android 中可以显示后台运行服务的弹出对话框吗 答案是肯定的 我该怎么做 有几种选择 您可以使用主题并使活动的外观和行为类似于对话框 如这个问题 通过设置android theme你的属性
  • img 标签显示方向错误

    我在这个链接中有一张图片 http d38daqc8ucuvuv cloudfront net avatars 216 2014 02 19 2017 13 48 jpg 正如您所看到的 这是一个方向正确的正常图像 但是 当我将此链接设置为
  • 如何使用seaborn实现Lineplot,x轴为“日期”

    我尝试实现seaborn lineplot 数据框具有日期值列表作为索引 试图将其作为 x 轴 Dataframe info 将 日期 字段显示为对象 我需要以日期为 x 轴的 4 种类型的列值的线图 当我尝试执行下面的代码时 它显示错误消
  • 为什么从 java 9 PhantomReference java doc 开始,它就专门用于 POST-mortem 清理操作,尽管它之前是 PRE-mortem

    PhantomReference java 8 的 java 文档更少看起来像这样 幻像引用对象 在收集器之后排队 确定它们的引用对象可以以其他方式被回收 幻影 参考最常用于调度事前清理 行动以比 Java 更灵活的方式 最终确定机制 如果
  • Android - XPath 评估速度非常慢

    我在用着XPath查询我的XML file目前大约有100KB 我正在迭代一个数组并查询列表中的每个值 不幸的是单个查询大约需要 3 4 秒在调试器下 在禁用调试器的情况下稍微少一些 有什么想法为什么这么慢吗 我用一个Galaxy S2供测
  • 为什么非 pic 代码不能使用运行时修复完全实现 ASLR?

    据我了解 PIC 代码使 ASLR 随机化更加高效 更加容易 因为代码可以放置在内存中的任何位置 而无需更改代码 但如果我根据维基百科理解正确的话搬迁动态链接器可以在运行时进行 修复 以便可以找到符号 尽管代码不是位置无关的 但根据我在这里
  • Java中ConcurrentSkipListMap的非线程安全方法

    在我的 Java 项目中 我需要以多线程方式使用 TreeMap 我发现 ConcurrentSkipListMap 是我所需要的 但有些方法不是线程安全的 其中之一 containsKey 对象键 以多线程方式使用此方法的典型解决方案是什
  • 标题应该按什么顺序包含? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 在头文件 cpp 文件中应该以什么顺序声明头文件 显然 后续标头所需的标头应该更早 并且特定于类的标头应该在 cpp 范围而不是标头范围中 但是是否有设定的顺序约定 最佳实践 在头文件中
  • 安装适用于 Android 的 ADB 接口驱动程序

    我尝试通过设备管理器安装 将手机连接到笔记本电脑后 我在设备管理器的 其他设备 部分中收到 Celkon 内置 GSM 手机 链接 我右键单击并单击 更新驱动程序 和 从指定位置安装 并找到 inf 文件 usb2ser 2kXP inf
  • 无法在 Windows 上克隆,但可以从 Gitlab 服务器在 Linux 上克隆

    我正在尝试通过 SSH 从远程 Gitlab 服务器克隆存储库 我在用Gitlab CE version 9 3 9 755bb71 and TortoiseGIT version 2 5 0 and git for windows ver
  • 如何使用 prettier 忽略特定规则?

    有没有办法不format write or check更具体的规则 例如 我不在乎我的代码中是否有分号 我想检查除此之外的其他规则 prettier useTabs true tabWidth 4 很不幸的是 不行 有人指出 它永远不会提供
  • 保持图像的长宽比?

    我正在使用 pictureBox 来显示从服务器接收的图像 但我的问题是紧凑框架中的图片框只有三种尺寸模式 拉伸图像 正常 中心图像 我收到的图片通常尺寸较大 因此我必须使用 StrecthImage 模式 但随后纵横比保持不变 因此显示的
  • 当不知道 InterfaceClassGUID 时,我可以使用 SetupDiEnumDeviceInterfaces 从 SetupDiGetDeviceInterfaceDetail 获取 DevicePath 吗?

    概述 我读过了如何获取设备的设备接口 GUID and 如何使用设备实例 ID 打开设备的句柄 但我仍然对如何 或者是否应该 使用感到困惑设置DiEnumDeviceInterfaces与设置DiGetDeviceInterfaceDeta