Make the virtual gamepad deployable on owned cabinets and wire the real user-mode feeder: - driver/sign.ps1 (non-admin): create a self-signed code-signing cert, build the catalog with inf2cat, and SHA-256-sign RioGamepad.sys + .cat (embed-sign the sys before cataloguing so the .cat matches). Exports RIOJoyTest.cer. Verified end-to-end against the EWDK (signability + catalog clean; both files signed). - driver/install.ps1 (admin, two-phase): trust the cert (LocalMachine Root + TrustedPublisher), stage the package (pnputil /add-driver), enable test signing; after reboot, -CreateDevice runs devgen to create root\RioGamepad so PnP installs it. uninstall.ps1 reverses it. - RioJoy.Core.Output.HidFeederJoystickSink: opens the driver by GUID_DEVINTERFACE_RIOGAMEPAD (SetupAPI), maintains a RioHidReport, and submits it via DeviceIoControl(IOCTL_RIO_SUBMIT_REPORT) on each axis/button/hat change. RioCoordinator now uses it when the driver is present and falls back to the no-op sink otherwise (status shows "[no joystick driver]"). - gitignore the signing outputs (driver/package/, *.cat); driver/README.md gets the full build → sign → install → joy.cpl workflow. Remaining = the actual elevated install + reboot + joy.cpl verification on the cabinet (admin steps), and on-hardware confirmation of the feeder. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
84 lines
3.6 KiB
Markdown
84 lines
3.6 KiB
Markdown
# 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 (`<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.
|
|
|
|
## 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).
|