Phase 1: RioGamepad virtual HID driver (KMDF + VHF) + C# report packer

Author the custom virtual HID gamepad that replaces vJoy, and pin its wire
format on both sides. Builds clean to RioGamepad.sys against the EWDK
(KMDF 1.15 + VHF, x64, warnings-as-errors).

driver/RioGamepad/:
- ReportDescriptor.h: 6x16-bit axes (X,Y,Z,Rx,Ry,Rz), one 4-direction hat with
  null state, and 96 buttons — the legacy vJoy layout. 25-byte input report.
- Device.c/Driver.c: KMDF root-enumerated device that creates the VHF virtual HID
  device (VhfCreate in DeviceAdd, VhfStart in D0Entry, VhfDelete on cleanup) and
  exposes a device interface + IOCTL_RIO_SUBMIT_REPORT that forwards the caller's
  report bytes to VhfReadReportSubmit. Thin relay: no report logic in the kernel.
- Public.h: device-interface GUID, IOCTL, and the report byte layout shared with
  the C# client. RioGamepad.inf + build.cmd (EWDK build, catalog/sign disabled).

src/RioJoy.Core/Hid/RioHidReport.cs: packs AxisOutputs + hat + 96 buttons into
the exact 25-byte report (LE axes, hat nibble with 0x0F=centered, button bitmap).
13 new xUnit tests (136 total).

Remaining (deploy-side): test-sign + pnputil install + verify in joy.cpl, and
wire the real DeviceIoControl feeder sink (replacing NullJoystickSink). The
EWDK's in-build catalog task (DrvCat) can't load Microsoft.Kits.Logger on this
image, so the .cat is produced with inf2cat/signtool at install time instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-06-26 21:06:16 -05:00
co-authored by Claude Opus 4.8
parent 1348040e1c
commit 24cdf495e3
13 changed files with 664 additions and 15 deletions
+27 -5
View File
@@ -17,13 +17,35 @@ to Windows via `VhfReadReportSubmit`.
## Status
Phase 0 placeholder. Implementation is **Phase 1** in [../docs/PLAN.md](../docs/PLAN.md).
**Phase 1 — implemented and compiling.** The driver source under
[`RioGamepad/`](RioGamepad/) builds cleanly to `RioGamepad.sys` against the EWDK
(KMDF 1.15 + VHF, x64). It is a thin VHF relay: it creates the virtual HID device
from the report descriptor and, on each `IOCTL_RIO_SUBMIT_REPORT`, forwards the
caller's 25-byte report to `VhfReadReportSubmit`. All report packing lives in the
C# client (`RioJoy.Core.Hid.RioHidReport`, unit-tested) so the wire format is
pinned on both sides ([`RioGamepad/Public.h`](RioGamepad/Public.h)).
## Build prerequisites (Phase 1)
Not yet done: **test-signing + install + verify in `joy.cpl`** (the on-cabinet
step), and wiring the real `DeviceIoControl` feeder sink (replacing the C# side's
`NullJoystickSink`).
- Windows Driver Kit (WDK) for Windows 11 + matching Visual Studio + Windows SDK
- A separate WDK/MSBuild project lives here (`RioGamepad.vcxproj`); it is **not**
part of `RioJoy.sln` (different toolchain).
## Building
With the **EWDK** mounted (e.g. drive `E:`), from this folder:
```cmd
RioGamepad\build.cmd E:
```
This sources the EWDK env (`<EWDK>\BuildEnv\SetupBuildEnv.cmd`) and runs MSBuild,
producing `RioGamepad\x64\Release\RioGamepad.sys`. The project is a WDK/MSBuild
`.vcxproj`; it is **not** part of `RioJoy.sln` (different toolchain).
> **EWDK note:** the build disables the managed catalog task
> (`/p:DriverCatalog_Enable=false`) and auto-signing (`/p:SignMode=Off`). On this
> EWDK image the in-build `DrvCat` task can't load `Microsoft.Kits.Logger`, so the
> `.cat` is produced separately with `inf2cat.exe` and signed with `signtool.exe`
> as part of install (below), rather than during compilation.
## Signing