☰
Windows HID 迷你驱动实战:用 WDF 将非 HID USB 设备映射为 HID 设备(HIDUSBFX2 示例剖析)
2026/9/27 23:43:54 网站建设 项目流程
  • 示例工程

【免费下载链接】Windows-driver-samples

This repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-driver-samples
点击查看免费下载

导读

本文以微软官方驱动示例仓库中的 hid/hidusbfx2 为核心,深入讲解如何基于 Windows Driver Frameworks(WDF)编写 HID 迷你驱动,将一台不具备 HID 描述符的非 HID 标准 USB 设备(OSR USB-FX2 学习板)完整映射为操作系统可识别的 HID 设备。你将掌握 HID 类驱动(hidclass.sys)与 KMDF 驱动的"调度表所有权冲突"的经典解决方案、双驱动栈拆分架构、硬编码报告描述符的编写技巧,以及选择性挂起(Selective Suspend)、开关去抖动、Feature 报告控制七段数码管与条形 LED 等完整实战能力。

背景:为什么需要自定义 HID 迷你驱动

一个标准的 HID USB 设备,会通过接口描述符(Interface Descriptor)提供 HID 描述符,将自身标识为 HID 兼容设备。系统据此加载内置的 HID 迷你驱动hidusb.sys与 HID 类驱动hidclass.sys:类驱动解析 HID 描述符,并枚举出子 HID 设备栈。由于系统对 HID 设备支持非常完善,绝大多数场景下你不需要编写 HID 迷你驱动。

但存在两类必须自行编写 HID 迷你驱动的情形(见 hid/hidusbfx2/README.md):

  1. 难以修改 HID 兼容设备的固件:希望在现有固件能力之上,通过软件层改变暴露给系统的 HID 行为;
  2. 把非 HID 兼容设备"伪装"成 HID 设备:设备本身没有 HID 描述符,又不打算更新固件,则可以在驱动层补齐 HID 视图。

HIDUSBFX2 示例正是第二种情形的完整范本:目标设备是OSR USB-FX2 Learning Kit(以 Cypress EZ-USB FX2 开发板 CY3681 为基础的非 HID 设备),示例在驱动层为其凭空构建出完整的 HID 描述符与 HID 输入/Feature 报告,让系统把它当 HID 设备使用。

设备硬件概览

接口与端点

该设备含一个接口、三个端点(Interrupt IN、Bulk Out、Bulk IN):

  • Interrupt IN:以 8 位值表示拨码开关(Switch Pack)状态,在启动、从挂起恢复、开关状态变化时发送;
  • Bulk 端点:配置为环回(loopback)用途;
  • 固件厂商命令:支持查询/设置 LED 条状图(bar graph)显示、7 段数码管显示,以及查询拨码开关状态。

开关数据的两个细节(固件行为约束)

源码注释与 README 明确指出两点,直接影响驱动设计:

  • 无硬件去抖动:固件不对拨码开关做 de-bounce 处理,一次开关变化可能发送多个字节,因此驱动必须自行实现软件去抖动(见下文"开关去抖动"一节);
  • 位序与标签相反:8 位值中bit 0x80对应开关组上标记为 "1" 的开关,即高位对应最左侧标签。源码中的 HIDFX2_INPUT_REPORT 结构体注释"Individual switches starting from the right of the set of switches"也印证了这一约定。

驱动栈架构:解决 HID 架构与 KMDF 的调度表冲突

冲突的本质

HID 架构要求hidclass.sys 拥有 HID 迷你驱动的分发表(dispatch table),以便正确处理 PnP、电源与 I/O 请求;而 KMDF 框架同样要求驱动交出分发表控制权以注入框架回调。两者直接冲突,因此KMDF 不能原生支持 HID 迷你驱动(README 说明)。

经典解法:最小 WDM 函数驱动 + 完整 KMDF 过滤驱动

示例采用的架构(README 描述):

hidclass.sys (HID 类驱动, 拥有上层分发表) │ 内部 IOCTL ▼ hidkmdf.sys (最小 WDM 函数驱动, 向 hidclass 注册) │ IRP 透传 ▼ hidusbfx2.sys (完整 KMDF 驱动, 作为下过滤驱动, 真正处理请求) │ ▼ USB 协议栈 → OSR USB-FX2 设备
组件目录二进制职责
函数驱动hid/hidusbfx2/hidkmdfhidkmdf.sys最小 WDM 驱动,向 HID 类注册,可原样复用
过滤驱动hid/hidusbfx2/syshidusbfx2.sys完整 KMDF 驱动,处理全部 HID 请求,需按设备定制

复用函数驱动时的注意事项:hidkmdf.sys 是一个通用透传层,无需修改即可复用,但务必重命名二进制文件以避免名称冲突(README 明确提醒,见 L51)。

函数驱动的实现要点(hidkmdf.c)

hid/hidusbfx2/hidkmdf/hidkmdf.c 展示了 HID 迷你驱动的注册模型:

  • 在DriverEntry中调用HidRegisterMinidriver注册HID_MINIDRIVER_REGISTRATION结构,其中Revision必须为HID_REVISION,并将DevicesArePolled = FALSE(USB HID 设备无需 HID 类驱动轮询,注释解释了 ping-pong IRP 机制,见 L125-L132);
  • 所有 IRP 默认走HidKmdfPassThrough(IoCopyCurrentIrpStackLocationToNext+IoCallDriver透传到下层);
  • 电源 IRP 单独走HidKmdfPowerPassThrough(PoStartNextPowerIrp+PoCallDriver透传),保证电源管理语义正确;
  • HidKmdfAddDevice不创建设备对象——注释明确说明"hidclass 会替我们创建 FDO 并挂接到 PDO"。

将非 HID USB 设备映射为 HID:核心原理

当 HID 类驱动查询迷你驱动时,迷你驱动返回硬编码的报告描述符(report descriptor),HID 类驱动依据该描述符创建子设备。HIDUSBFX2 的报告描述符声明了3 个顶层应用集合(top-level application collections):

集合报告 ID用途
Consumer control(消费控制)1应用启动/动作热键(浏览器、计算器、邮件等)
System control(系统控制)2电源睡眠(Sleep)
Vendor-defined(厂商自定义)37 段数码管与条形 LED 的 Feature 控制

HID 类驱动会为每个顶层集合各创建一个驱动栈:操作系统自动打开消费控制与系统控制集合(数据来自 USB 中断端点);厂商集合暴露 Feature 按钮,任何客户端应用都可以打开该集合发送 Feature 请求(README L55-L63)。

从源码看,硬编码描述符定义在 hid/hidusbfx2/sys/hidusbfx2.h 的G_DefaultReportDescriptor数组中(由#define USE_HARDCODED_HID_REPORT_DESCRIPTOR控制),对应的G_DefaultHidDescriptor(L241-L249)给出 HID 描述符头与报告描述符长度;hid.c中的HidFx2GetReportDescriptor/HidFx2GetHidDescriptor分别在IOCTL_HID_GET_REPORT_DESCRIPTOR/IOCTL_HID_GET_DEVICE_DESCRIPTOR时将这些硬编码数据拷贝给 HID 类驱动。

完整报告描述符逐段解析

以下是示例中硬编码报告描述符的完整内容(含逐项注释,来自 hid/hidusbfx2/sys/hidusbfx2.h):

1. Consumer control 集合(报告 ID 1)

0x05,0x0C, // USAGE_PAGE (Consumer Page) 0x09,0x01, // USAGE (Consumer Control Usage 0x01) 0xA1,0x01, // COLLECTION (Application) 0x85,0x01, // REPORT_ID (1) 0x0A, 0x23, 0x02, // USAGE (Usage Browser) 0x0A, 0x24, 0x02, // USAGE (Usage AC Back) 0x0A, 0x25, 0x02, // USAGE (Usage AC Forward) 0x0A, 0x27, 0x02, // USAGE (Usage AC Refresh) 0x0A, 0x2A, 0x02, // USAGE (Usage AC BookMarks) 0x0A, 0x8A, 0x01, // USAGE (Usage AL Mail) 0x0A, 0x92, 0x01, // USAGE (Usage AL Calculator) 0x15, 0x00, // LOGICAL_MINIMUM(0) 0x25, 0x01, // LOGICAL_MAXIMUM(1) 0x75, 0x01, // REPORT_SIZE (1 bit) 0x95, 0x07, // REPORT_COUNT (7) 0x81, 0x02, // INPUT (Data, Variable, Abs) 0x75, 0x01, // REPORT_SIZE 0x95, 0x01, // REPORT_COUNT 0x81, 0x07, // INPUT (const, 填充位) 0xC0, // END_COLLECTION

7 个拨码开关位按位映射到 7 个消费控制 Usage;第 8 位为常量填充位,凑满 8 位。

2. System control 集合(报告 ID 2)

0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x80, // Usage (System Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x02, // Report ID (2) 0x95, 0x07, // Report Count (7) 0x81, 0x07, // Input (Constant) -- PADDING 0x09, 0x82, // Usage (System Sleep) 0x95, 0x01, // Report Count (1) 0x81, 0x06, // Input (Data, Variable, Relative, Preferred) 0xC0, // End Collection

最高位开关(0x80)映射为 System Sleep(系统睡眠键)。

3. Vendor-defined Feature 集合(报告 ID 3,含 7 段数码管与条形 LED 两个子报告)

0x06,0x00, 0xFF, // USAGE_PAGE (Vendor Defined Usage Page 0xFF00) 0x09,0x01, // USAGE (Vendor Usage 0x01) 0xA1,0x01, // COLLECTION (Application) 0x85,0x03, // Report ID (3) -- 7 段数码管 0x19,0x00, // USAGE MINIMUM 0x29,0xff, // USAGE MAXIMUM 0x15,0x00, // LOGICAL_MINIMUM(0) 0x26,0xff, 0x00, // LOGICAL_MAXIMUM(255) 0x75,0x08, // REPORT_SIZE (8 bit) 0x95,0x01, // REPORT_COUNT (1) 0xB1,0x00, // Feature (Data, Ary, Abs) 0x85,0x04, // Report ID (4) -- 条形 LED 0x19,0x00, // USAGE MINIMUM 0x29,0xff, // USAGE MAXIMUM 0x15,0x00, // LOGICAL_MINIMUM(0) 0x26,0xff, 0x00, // LOGICAL_MAXIMUM(255) 0x75,0x08, // REPORT_SIZE (8 bit) 0x95,0x01, // REPORT_COUNT (1) 0xB1,0x00, // Feature (Data, Ary, Abs) 0xC0 // END_COLLECTION

注意源码中的报告 ID 与 README 表格中的 Usage ID 对应关系:报告 ID 3(SEVEN_SEGMENT_REPORT_ID)承载 7 段数码管 Feature,报告 ID 4(BARGRAPH_REPORT_ID)承载条形 LED Feature(宏定义见 hid/hidusbfx2/sys/hidusbfx2.h#L63-L67)。

开关映射表(Consumer / System Control)

示例将拨码开关组映射为现代键盘常见的快捷键(README 表格):

Switch12345678
MappingSleepCalculatorMailFavoritesRefreshForwardBackBrowser

结合位序约定(0x80= 标签 1),可以推断:标签 1(Sleep)对应最高位,走 System Control 集合;标签 2~8 依次对应低位 7 位(0x40~0x01),走 Consumer Control 集合。源码 usb.c 中的映射逻辑用CONSUMER_CONTROL_BUTTONS_BIT_MASK(0x7F)与SYSTEM_CONTROL_BUTTONS_BIT_MASK(0x80)划分两个集合的报告 ID。

七段数码管与条形 LED 的 Feature 映射

数码管与条形 LED 被映射为HID Feature 控件,用户态应用可通过HidD_SetFeature函数操作。Feature 控件映射到厂商自定义 Usage Page 0xFF00(README L75)。

七段数码管映射表

Feature 数据字节与显示数字的对应关系(README 表格):

Usage ID0xD70x060xB30xA70x660xE50xF40x070xF70x67
MappingDisplay 0Display 1Display 2Display 3Display 4Display 5Display 6Display 7Display 8Display 9

从源码角度,这些字节实际是 7 段数码管各段(SEGMENT_BIT_1~SEGMENT_BIT_8,hidusbfx2.h#L92-L99)按字形组合的结果,例如SEGMENT_DISPLAY_1(显示 1)为SEGMENT_BIT_2 | SEGMENT_BIT_3(0x06)、SEGMENT_DISPLAY_2(显示 2)为0xB3,与表格逐项吻合。

条形 LED 映射表

条形 LED 按位点亮,各值可 OR 组合以同时点亮多个 LED(README 表格):

Usage ID0x010x020x040x080x100x200x400x800xFF0x00
MappingLED 1 ONLED 2 ONLED 3 ONLED 4 ONLED 5 ONLED 6 ONLED 7 ONLED 8 ONAll LEDs ONAll LEDs OFF

源码 hidusbfx2.h#L154-L163 定义了BARGRAPH_LED_1_ON~BARGRAPH_LED_ALL_ON/OFF同名宏,与表格完全一致。

Feature 请求的底层实现(hid.c)

IOCTL_HID_SET_FEATURE/IOCTL_HID_GET_FEATURE由 hid.c 的 HidFx2SetFeature / HidFx2GetFeature 处理:

  1. 校验HID_XFER_PACKET输入/输出缓冲区长度;
  2. 通过WdfRequestWdmGetIrp(Request)->UserBuffer直接取得用户缓冲区(注释说明:Set/Get Feature 不是 METHOD_NEITHER IOCTL,KMDF 无法用WdfRequestRetrieveOutputMemory取得该缓冲区,必须"逃逸"到 WDM 层);
  3. 按transferPacket->reportId区分SEVEN_SEGMENT_REPORT_ID(4)与BARGRAPH_REPORT_ID(5);
  4. 调用SendVendorCommand/GetVendorData构造厂商 USB 控制传输(WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR,请求码如HIDFX2_SET_7SEGMENT_DISPLAY0xDB、HIDFX2_SET_BARGRAPH_DISPLAY0xD8、HIDFX2_READ_7SEGMENT_DISPLAY0xD4、HIDFX2_READ_BARGRAPH_DISPLAY0xD7),并通过WdfUsbTargetDeviceSendControlTransferSynchronously同步下发,带 5 秒超时(WDF_REL_TIMEOUT_IN_SEC(5),防止用户线程被挂死)。

完整厂商命令表定义在 hidusbfx2.h#L81-L87:

命令宏值方向
HIDFX2_READ_SWITCH_STATE0xD6设备 → 主机
HIDFX2_READ_7SEGMENT_DISPLAY0xD4设备 → 主机
HIDFX2_READ_BARGRAPH_DISPLAY0xD7设备 → 主机
HIDFX2_SET_BARGRAPH_DISPLAY0xD8主机 → 设备
HIDFX2_IS_HIGH_SPEED0xD9查询
HIDFX2_REENUMERATE0xDA重枚举
HIDFX2_SET_7SEGMENT_DISPLAY0xDB主机 → 设备

输入报告通路:中断端点连续读 + 开关去抖动

USB 初始化(usb.c)

在HidFx2EvtDevicePrepareHardware(usb.c#L42-L201)中:

  1. WdfUsbTargetDeviceCreate创建 USB 设备对象;
  2. WdfUsbTargetDeviceSelectConfig(WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE)选择单接口配置;
  3. 用WdfUsbInterfaceGetConfiguredPipe按INTERRUPT_ENDPOINT_INDEX(0) 取得中断管道;
  4. WdfUsbTargetPipeSetNoMaximumPacketSizeCheck允许读取小于最大包长的数据;
  5. HidFx2ConfigContReaderForInterruptEndPoint在中断管道上配置WDF USB 连续读取器(continuous reader),每次读取sizeof(UCHAR)(1 字节)——这正好对应开关状态的一个字节。

中断数据处理

连续读取完成回调HidFx2EvtUsbInterruptPipeReadComplete(usb.c#L262-L398)是输入通路的枢纽:

  • 丢弃开机/唤醒首包:IsPowerUpSwitchState标志为真时,启动或从挂起恢复后的首个中断数据被丢弃(该数据不是用户真实操作);
  • 异或求变化:toggledSwitch = (previousSwitchState ^ currentSwitchState) & currentSwitchState——固件总是返回全部开关状态,驱动通过与上一次状态异或,仅取"从 0 变 1"的开关作为本次按键事件;
  • 启动去抖动定时器:一旦检测到开关拨到 On,就启动 10 ms 定时器(SWICTHPACK_DEBOUNCE_TIME_IN_MS,见 hidusbfx2.h#L74)。定时器回调HidFx2EvtTimerFunction(usb.c#L733-L773)在去抖窗口结束后调用HidFx2CompleteReadReport完成挂起的 HID 读请求。

读请求排队与完成

  • IOCTL_HID_READ_REPORT到达时(hid.c#L129-L146),驱动通过WdfRequestForwardToIoQueue将请求转发到手动队列InterruptMsgQueue(该队列在 driver.c#L225-L240 创建,并设置为非电源管理队列,因为挂起的读请求无需等待设备完全上电);
  • 去抖定时器触发后,HidFx2CompleteReadReport(usb.c#L401-L523)从队列取回请求,按掩码判断本次变化属于消费控制(低 7 位)还是系统控制(最高位),填入对应报告 ID 的HIDFX2_INPUT_REPORT,以WdfRequestCompleteWithInformation完成。

选择性挂起(Selective Suspend)支持

HID 类驱动本身支持选择性挂起,迷你驱动通过正确处理 HID 类 IOCTL参与该特性。关键路径:

  • 在HidFx2EvtInternalDeviceControl中处理IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST(hid.c#L152-L180);
  • HidFx2SendIdleNotification(hid.c#L869-L969)将该 IOCTL 转换为IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION透传给 USB 栈挂起等待。hidclass 是电源策略所有者:它决定何时发送/取消空闲通知;USB 栈判定设备空闲后完成请求,触发 wait-wake IRP 并下电;设备被重新打开或外部唤醒事件到来时再上电。

启用方法:通过 INF 在设备硬件键(hardware key)添加注册表值,SelectiveSuspendEnabled= 1。HIDUSBFX2 的 INF(hid/hidusbfx2/sys/hidusbfx2.inx)在厂商集合安装节中给出示例:

[customCollection.Inst.AddReg.NT.HW] HKR,,"SelectiveSuspendEnabled",0x00000001,0x1

同时,驱动过滤部分还通过 INF 设置了AllowIdleIrpInD3:

[hidusbfx2_Parameters.AddReg] HKR,,"AllowIdleIrpInD3",0x00010001,0x1

注意:INF 依赖 Windows 11 及以上

hidusbfx2.inx头部注释明确声明(L8-L9):该 INF 依赖 Windows 11(build 22000)开始可用的特性——使用内置的mshidkmdf.inf作为 shim,并通过AddFilter指令把 hidusbfx2 注册为下过滤驱动(Lower Filter)。若面向旧系统,需要改写 INF 采用传统 co-installer 方式。

构建与安装

构建

使用 Visual Studio + WDK 打开解决方案 hid/hidusbfx2/hidusbfx2.sln 即可构建出hidusbfx2.sys与hidkmdf.sys两个驱动。

需要复制的文件

按 README 安装清单,将以下文件复制到硬盘某文件夹:

  • hidusbfx2.inf(由 hidusbfx2.inx 转换生成)
  • hidusbfx2.sys
  • Hidkmdf.sys
  • WDF 联合安装程序(coinstaller),位于%ProgramFiles(x86)%\Windows Kits\8.0\redist\wdf\<platform>目录

提示:若未随 WDK 安装重分发组件,可运行wdfcoinstaller.msi静默安装到 WDK 目录;安装无确认提示,可通过检查 WDK 根目录下是否存在redist\wdf子目录来验证。

安装步骤

  1. 插入设备,在命令窗口运行devmgmt.msc打开设备管理器;
  2. 在"其他设备"分类下选中OSR USB-FX2 device,右键选择"更新驱动程序软件";
  3. 选择"浏览计算机以查找软件",提供驱动文件所在位置;
  4. 出现 Windows 安全对话框时,选择"仍然安装此驱动程序软件";
  5. 安装完成后,设备应出现在设备管理器的**人体学输入设备(Human Interface Devices)**分类下。

适配自己的设备

将示例用于自有设备时,需修改 INF 中的硬件 ID(VID/PID)与设备描述文本以匹配你的测试板(README L97)。示例 INF 中硬编码的硬件 ID 为USB\VID_0547&PID_1002(Cypress FX2 系列),应替换为目标设备的 VID/PID。

功能测试:开关与显示

测试开关映射

无需任何用户态程序,直接操作系统:

  • 将 8 号开关拨到 On(向下拨)→打开 Web 浏览器;
  • 将 2 号开关拨到 On →启动计算器应用。

这验证了报告描述符中 Consumer 集合的 Browser(0x0A 0x23 0x02)与 Calculator(0x0A 0x92 0x01)映射已正确注册到系统。

使用 HidClient 测试数码管与条形 LED

Windows 驱动工具包(WDK)自带的hidclient.exe图形应用可用来操纵显示。该应用的源码就位于本仓库的 hid/hclient 目录,是演示用户态 HID 客户端应用的配套示例(见 hid/hclient/README.md)。

操作流程(README 测试步骤):

  1. 启动hidclient.exe;
  2. 在"HID Device to examine"下拉菜单中,选择包含"UsagePage 0ff00, Usage 01"子字符串的设备——这正是厂商自定义集合的 Usage Page;
  3. 点击Modify Features,打开 Feature Data 对话框;
  4. 在输入框输入7并点击Send to Device,7 段数码管应显示数字 7;
  5. 输入 1~8,数码管依次显示对应数字;
  6. 输入 9~17(含边界),条形 LED 依次点亮(对应 条形 LED 映射表 中的各位)。

从实现上看,hidclient 是通过HidD_SetFeature向报告 ID 3/4 的 Feature 集合发送单字节数据,驱动侧HidFx2SetFeature再将其转换为厂商控制传输命令,完成"用户态 → HID 类驱动 → 过滤驱动 → USB 设备"的完整链路。

源码文件清单

\hidusbfx2\hidkmdf(函数驱动)

文件说明
hid/hidusbfx2/hidkmdf/hidkmdf.c驱动入口与 IRP 透传分发
hid/hidusbfx2/hidkmdf/hidkmdf.rc驱动资源文件
hid/hidusbfx2/hidkmdf/hidkmdf.vcxprojVisual Studio 项目文件

\hidusbfx2\sys(KMDF 过滤驱动)

文件说明
hid/hidusbfx2/sys/driver.cKMDF 驱动入口、DeviceAdd、队列与定时器创建
hid/hidusbfx2/sys/hid.c处理全部 HID 内部 IOCTL(描述符/属性/读报告/Feature/空闲通知)
hid/hidusbfx2/sys/usb.cUSB 配置、中断连续读、去抖、开关状态处理
hid/hidusbfx2/sys/hidusbfx2.h类型定义、宏、报告描述符与函数声明
hid/hidusbfx2/sys/hidusbfx2.inx驱动 INF 源文件(构建时转换为 .inf)
hid/hidusbfx2/sys/hidusbfx2.rc驱动资源文件
hid/hidusbfx2/sys/trace.hWPP 跟踪相关定义

复用与扩展建议

  1. 函数驱动直接复用:hidkmdf.sys是通用透传层,换用任何设备都无需修改,但必须重命名二进制;
  2. 报告描述符是定制核心:设备暴露的按键、开关、传感器等能力,全部通过改写G_DefaultReportDescriptor来定义——集合划分、Usage 选择、报告 ID、输入/Feature/输出属性都在这里决定;
  3. 改造输入通路:若设备输入不是"中断端点 + 单字节状态",需要同步调整usb.c中的连续读配置与HidFx2CompleteReadReport的打包逻辑;示例还预置了USE_ALTERNATE_HID_REPORT_DESCRIPTOR编译开关,可切换到"纯厂商集合上报开关状态"的替代模式,适合不希望系统自动处理按键的场景;
  4. Feature 命令映射:hid.c中SendVendorCommand/GetVendorData的厂商命令字(0xD4~0xDB)与目标设备固件协议一一对应,需要按新设备固件改写;
  5. 注意版本约束:当前 INF 面向 Windows 11 及更新版本;面向旧系统部署时需改用传统 WDF co-installer INF 写法。

通过上述架构与源码路径,你可以完整复现"非 HID 设备 → HID 设备"的映射流程,并以此为模板快速适配自己的硬件。

  • 示例工程

【免费下载链接】Windows-driver-samples

This repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-driver-samples
点击查看免费下载
上一篇:Kornia ManyToManyAugmentationDispather 输入校验强化:数量不匹配立即报错,杜绝静默丢弃
下一篇:WindowsCleaner:终极C盘清理神器,让你的系统重获新生

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询