libusb获取Windows设备实例路径DevicePath

libusb 当前版本(1.0.26)libusb.h 头文件提供的接口似乎没有办法获取 Windows 平台相关的设备实例路径,其形如:

\\?\usb#vid_04ca&pid_7070#5&20d34a76&0&6#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

只是提供了 libusb_get_port_numbers 之类的接口来获取拓扑结构。

我们可以通过 libusb 源码中平台相关的接口来获取DevicePath,但是使用非公有接口意味着替换版本的时候要注意源码相关的修改。目前找了两种方式:

1.通过 winusb_device_priv 结构体中的 path 获取

通过 libusbi.h 头文件中的 usbi_get_device_priv 函数获取 libusb_device 对应的平台相关的数据结构,对应到 windows 平台就是 winusb_device_priv,其包含的 path 字段就是存放DevicePath。

#include "libusb.h"
#include "libusbi.h"void enum_device()
{libusb_init(NULL);libusb_device **device_list;int count = libusb_get_device_list(NULL, &device_list);for(int i = 0 ; i < count; i++){libusb_device_descriptor desc;int ret = libusb_get_device_descriptor(device_list[i], &desc);if (ret != LIBUSB_SUCCESS) {continue;}winusb_device_priv *priv = (winusb_device_priv*)usbi_get_device_priv(device_list[i]);if (priv) {fprintf(stderr, "Device %d path: %s.\n", i, priv->path);}}libusb_free_device_list(device_list, 1);libusb_exit(NULL);
}

从 usbi_get_device_priv 函数推测,公有结构和平台相关结构在内存上是紧挨着的:

#define PTR_ALIGN(v) (((v) + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1))static inline void *usbi_get_device_priv(struct libusb_device *dev)
{return (unsigned char *)dev + PTR_ALIGN(sizeof(*dev));
}

获取 DevicePath 的过程在 windows_winusb.c 的 winusb_get_device_list 和 get_interface_details 函数,使用的 SetupAPI 系列的接口来获取的。有一点需要注意,获取到的 path 内部转换成了大写,见 normalize_path 函数实现。

不修改库源码,而是直接使用私有接口需要用到的源码文件:

其中 config.h 文件来自于源码的 msvc 文件夹。

可能会遇到类型转换报错,自己做下显式转换即可。

2.通过 libusb_device 结构体中的 session_data 和 Windows 的 DevInst 比较

session_data 在 windows 平台上目前就是存储的 SP_DEVINFO_DATA 结构的 DevInst 值。相较于第一种方式,我们需要再次用 SetupAPI 的接口枚举一遍设备信息,然后判断 session_data 和 DevInst 是否相等,相等时就可以用 Win32 接口获取 DevicePath 了。

libusb_device 结构体定义在 libusbi.h 头文件。

#include <stdio.h>
#include <Windows.h>
#include <SetupAPI.h>
#pragma comment(lib, "SetupAPI.lib")
#include <devguid.h>
// 具体的设备 GUID 需要 initguid, 如 usbiodef
#include <initguid.h>
// USB 设备
// GUID_DEVINTERFACE_USB_DEVICE
#include <usbiodef.h>void enum_device()
{// HDEVINFO 标识设备信息集HDEVINFO info_set;// SetupDiGetClassDevs 返回包含本地计算机请求的设备信息元素的设备信息集的句柄// 接口文档:https://learn.microsoft.com/zh-cn/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsa// 若要返回支持任何类的设备接口的设备,设置 DIGCF_DEVICEINTERFACE 和 DIGCF_ALLCLASSES 标志,然后将 ClassGuid 设置为 NULL//info_set = SetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);// 若要仅返回支持指定类的设备接口的设备,设置 DIGCF_DEVICEINTERFACE 标志并使用 ClassGuid 参数提供设备接口类的类 GUID// 实际使用对应设备的 GUIDGUID device_guid{GUID_DEVINTERFACE_USB_DEVICE};info_set = SetupDiGetClassDevsA(&device_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);// 如果操作失败,返回 INVALID_HANDLE_VALUEif (info_set == INVALID_HANDLE_VALUE) {fprintf(stderr, "SetupDiGetClassDevs: [err code] %d.\n", GetLastError());return;}// SP_DEVINFO_DATA 标识设备信息集中的设备SP_DEVINFO_DATA info_data = { 0 };info_data.cbSize = sizeof(info_data);// SetupDiEnumDeviceInfo 枚举设备信息for (int index = 0; SetupDiEnumDeviceInfo(info_set, index, &info_data); index++){fprintf(stderr, "Device %d %d:\n", index, info_data.DevInst);// 获取设备实例路径// SP_DEVICE_INTERFACE_DATA 设备信息集中的设备接口SP_DEVICE_INTERFACE_DATA interface_data = { 0 };interface_data.cbSize = sizeof(interface_data);// SetupDiEnumDeviceInterfaces 枚举包含在设备信息集中的设备接口BOOL ret = SetupDiEnumDeviceInterfaces(info_set, NULL, (LPGUID)&device_guid, index, &interface_data);if (!ret) continue;ULONG required_len = 0;// SetupDiGetDeviceInterfaceDetail 返回有关设备接口的详细信息// 第一次调用是获取长度,这里是返回falseSetupDiGetDeviceInterfaceDetailA(info_set, &interface_data, NULL, 0, &required_len, NULL);if (required_len <= 0) continue;ULONG predicted_len = required_len;// SP_INTERFACE_DEVICE_DETAIL_DATA 包含设备接口的路径SP_INTERFACE_DEVICE_DETAIL_DATA_A detail_data = { 0 };detail_data.cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA_A);// 检索即插即用设备信息if (SetupDiGetDeviceInterfaceDetailA(info_set,&interface_data,&detail_data,predicted_len,&required_len,&info_data)) {fprintf(stderr, "Device Instance Path: %s.\n", detail_data.DevicePath);}}// SetupDiDestroyDeviceInfoList 删除设备信息集并释放所有关联的内存SetupDiDestroyDeviceInfoList(info_set);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/193150.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浙江大学数据结构陈越 第一讲 数据结构和算法

数据结构 数据结构是计算机科学中用来组织和存储数据的方式。它可以理解为一种组织数据的方式&#xff0c;能够有效地管理和操作数据&#xff0c;以及提供对数据进行存储、检索、更新和删除等操作的方法。常见的数据结构包括数组、链表、栈、队列、树和图等&#xff0c;它们各自…

盘点30个Python树莓派源码Python爱好者不容错过

盘点30个Python树莓派源码Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1LA4cLunntKW3qO5aok3xAQ?pwd8888 提取码&#xff1a;8888 项目名称 PiCar-raspber…

图数据库实战-HugeGraph简介

一、HugeGraph简介 HugeGraph是一款易用、高效、通用的开源图数据库系统&#xff08;Graph Database&#xff0c;GitHub项目地址&#xff09;&#xff0c; 实现了Apache TinkerPop3框架及完全兼容Gremlin查询语言&#xff0c; 具备完善的工具链组件&#xff0c;助力用户轻松…

吴恩达《机器学习》8-3->8-4:模型表示I、模型表示II

8.3、模型表示I 一、大脑神经网络的基本原理 为了构建神经网络模型&#xff0c;首先需要理解大脑中的神经网络是如何运作的。每个神经元都可以被看作是一个处理单元或神经核&#xff0c;它包含多个输入&#xff08;树突&#xff09;和一个输出&#xff08;轴突&#xff09;。…

【银行测试】支付功能、支付平台、支持渠道如何测试?

有朋友提问&#xff1a;作为一个支付平台&#xff0c;接入了快钱、易宝或直连银行等多家的渠道&#xff0c;内在的产品流程是自己的。业内有什么比较好的测试办法&#xff0c;来测试各渠道及其支持的银行通道呢&#xff1f; 作为产品&#xff0c;我自己办了十几张银行卡方便测…

使用PHP编写采集药品官方数据的程序

目录 一、引言 二、程序设计和实现 1、确定采集目标 2、使用PHP的cURL库进行数据采集 3、解析JSON数据 4、数据处理和存储 5、数据验证和清理 6、数据输出和可视化 7、数据分析和挖掘 三、注意事项 1、合法性原则 2、准确性原则 3、完整性原则 4、隐私保护原则 …

助力燃气安全运行:智慧燃气管网背景延展

关键词&#xff1a;城市燃气管网、智慧燃气管网、智慧管网、智慧燃气管网解决方案、智慧燃气 01背景 当前&#xff0c;随着我国城市化进程不断加快&#xff0c;城市燃气管网也不断延伸&#xff0c;运行规模庞大&#xff0c;地下管线复杂&#xff0c;不少城市建设“重地上轻地…

使用百度语音识别技术实现文字转语音的Java应用

探讨如何使用百度语音识别技术将文字转换为语音的Java应用。百度语音识别技术是一种强大的语音识别服务&#xff0c;可以将输入的文字转换为自然流畅的语音输出。我们将使用Java编程语言来实现这个应用&#xff0c;并提供相应的源代码。 首先&#xff0c;我们需要准备一些前提…

SpringCloud Alibaba(上):注册中心-nacos、负载均衡-ribbon、远程调用-feign

Nacos 概念&#xff1a;Nacos是阿里巴巴推出的一款新开源项目&#xff0c;它是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos致力于帮助用户发现、配置和管理微服务&#xff0c;它提供了一组简单易用的特性集&#xff0c;包括动态服务发现、服务配置…

Telnet 测试 UDP 端口?

Telnet 并不支持 UDP 端口的测试&#xff0c;可以使用 nc 命令来进行测试。nc 命令两种都支持&#xff1a; TCP # nc -z -v -u [hostname/IP address] [port number] # nc -z -v 192.168.10.12 22 Connection to 192.118.20.95 22 port [tcp/ssh] succeeded! UDP # nc -z -v…

百度搜索智能化算力调控分配方法

作者 | 泰来 导读 随着近年深度学习技术的发展&#xff0c;搜索算法复杂度不断上升&#xff0c;算力供给需求出现了爆发式的增长。伴随着AI技术逐步走到深水区&#xff0c;算法红利在逐步消失&#xff0c;边际效应日益显著&#xff0c;算力效能的提升尤为重要&#xff0c;同时随…

【Mycat2实战】二、Mycat安装部署

1. Mycat下载 Mycat官网下载地址&#xff0c;点击直接前往&#xff1a;http://www.mycat.org.cn/ Mycat 有提供编译好的安装包&#xff0c;支持 windows、Linux、Mac、 Solaris 等系统上安装与运行。 本文及后续系列的文章都是使用Linux的系统进行操作。 这里我们选择使用文…

jQuery使用echarts循环插入图表

目录 jQuery动态循环插入echarts图表 y轴显示最大值和最小值 x轴只显示两个值&#xff0c;开始日期和结束日期 jQuery动态循环插入echarts图表 html .center_img_list 是我们循环数据的地方 <div class"center_img shadow"><div class"center_img_b…

自定义Graph Component:1.2-其它Tokenizer具体实现

本文主要介绍了Rasa中相关Tokenizer的具体实现&#xff0c;包括默认Tokenizer和第三方Tokenizer。前者包括JiebaTokenizer、MitieTokenizer、SpacyTokenizer和WhitespaceTokenizer&#xff0c;后者包括BertTokenizer和AnotherWhitespaceTokenizer。 一.JiebaTokenizer   Ji…

RequestContextHolder详解

最近遇到的问题是在service获取request和response,正常来说在service层是没有request的,然而直接从controlller传过来的话解决方法太粗暴,后来发现了SpringMVC提供的RequestContextHolder遂去分析一番,并借此对SpringMVC的结构深入了解一下,后面会再发文章详细分析源码 1.Reque…

父组件用ref获取子组件数据

子组件 Son/index.vue 子组件的数据和方法一定要记得用defineExpose暴露&#xff0c;不然父组件用ref是获取不到的&#xff01;&#xff01;&#xff01; <script setup> import { ref } from "vue"; const sonNum ref(1); const changeSon () > {sonNum.…

【OpenCV实现图像:用OpenCV图像处理技巧之白平衡算法2】

文章目录 概要Gray-world AlgotithmGround Truth Algorithm结论&#xff1a; 概要 随着数字图像处理技术的不断发展&#xff0c;白平衡算法成为了图像处理中一个关键的环节。白平衡的目标是校正图像中的颜色偏差&#xff0c;使得白色在图像中呈现真实的白色&#xff0c;从而提…

Matter 协议详解

目录 1、Matter 协议发展 1.1、什么是Matter 1.2、Matter能做什么 2、整体介绍 3、架构介绍 3.1、Matter网络拓扑结构 3.2、标识符 3.2.1、Fabric引用和Fabric标识符 3.2.2、供应商标识符&#xff08;Vendor ID&#xff0c;VID&#xff09; 3.2.3、产品标识符&#x…

轻量封装WebGPU渲染系统示例<32>- 若干线框对象(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/WireframeEntityTest.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下: export class WireframeEntityTest {private mRsc…

深入解析JavaScript中的变量作用域与声明提升

JS中的变量作用域 背景&#xff1a; ​ 之前做js逆向的时候&#xff0c;有一个网站很有意思&#xff0c;就是先出现对其赋值&#xff0c;但是后来的变量赋值没有对其发生修改&#xff0c;决定说一下js中的作用域问题. 全局作用域&#xff1a; ​ 全局作用域的变量可以在任何…