Files
riojoy/driver/README.md
T
CydandClaude Opus 4.8 24cdf495e3 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>
2026-06-26 21:06:16 -05:00

2.5 KiB

RioGamepad — virtual HID driver

The RioGamepad virtual HID device replaces the legacy vJoy dependency. It is a KMDF driver built on the Windows Virtual HID Framework (VHF, vhf.sys) that presents a single HID game controller to Windows matching the layout the old app drove through vJoy:

Report field Count Notes
Axes 6 X, Y, Z, Rx, Ry, Rz — 16-bit
Hat switch 1 4-direction POV with null state
Buttons 96 12 bytes of button bits

The C# tray app feeds input reports to the driver through a custom DeviceIoControl IOCTL on the driver's control device; the driver relays them to Windows via VhfReadReportSubmit.

Status

Phase 1 — implemented and compiling. The driver source under 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).

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).

Building

With the EWDK mounted (e.g. drive E:), from this folder:

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

For the cockpit cabinets, enable test signing (bcdedit /set testsigning on) and install a self-signed test certificate — appropriate for hardware you own. Redistribution would instead use Microsoft attestation signing via Partner Center. See the deployment notes in ../docs/PLAN.md (Phase 6).