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>
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-buildDrvCattask can't loadMicrosoft.Kits.Logger, so the.catis produced separately withinf2cat.exeand signed withsigntool.exeas 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).