# 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/`](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)). 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: ```cmd RioGamepad\build.cmd E: ``` This sources the EWDK env (`\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. ## Test-signing & install (cabinets you own) Scripts in this folder automate the test-signing flow. Steps marked **(admin)** need an elevated shell; everything else is non-admin. ```cmd :: 1. Build the driver (non-admin), EWDK mounted at E: RioGamepad\build.cmd E: :: 2. Test-sign: makes a self-signed cert, builds + signs the .cat and .sys, :: and exports RIOJoyTest.cer (non-admin) powershell -ExecutionPolicy Bypass -File sign.ps1 -Ewdk E: :: 3. (admin) Trust the cert, stage the driver, enable test signing powershell -ExecutionPolicy Bypass -File install.ps1 -Ewdk E: :: 4. REBOOT (test signing only takes effect after a restart) :: 5. (admin) Create the device; PnP then installs the staged driver powershell -ExecutionPolicy Bypass -File install.ps1 -Ewdk E: -CreateDevice ``` Then open **`joy.cpl`** and confirm **"RIOJoy Virtual Gamepad"** appears with 6 axes / POV / 96 buttons. To roll back: `uninstall.ps1 [-DisableTestSigning] [-RemoveCert]`. The signed package (`package/`) and the exported cert are local artifacts and are git-ignored. Redistribution beyond owned hardware would instead use Microsoft **attestation signing** via Partner Center (see [../docs/PLAN.md](../docs/PLAN.md), Phase 6). The user-mode side opens this device by `GUID_DEVINTERFACE_RIOGAMEPAD` and feeds reports via `IOCTL_RIO_SUBMIT_REPORT` — implemented by `RioJoy.Core.Output.HidFeederJoystickSink`, which the tray app uses automatically when the driver is present (falling back to a no-op sink when it is not).