The driver installed but the device failed with Code 31
(CM_PROB_FAILED_ADD): VhfCreate returned STATUS_INVALID_DEVICE_REQUEST
(0xC0000010) because vhf.sys was never attached beneath the FDO. Add the
required LowerFilters=vhf AddReg to the INF so VHF loads as a lower
filter; the device now starts clean and enumerates in joy.cpl.
A VHF virtual HID device cannot supply a HID product string (VHF_CONFIG
has no string field and VHF owns IOCTL_HID_GET_STRING), so register the
DirectInput OEMName (VID_1209&PID_5249 -> RIOJoy Virtual Gamepad) in
install.ps1 -CreateDevice and remove it in uninstall.ps1, giving the
controller a proper name instead of the generic VHF default.
Also fix a non-ASCII em-dash in sign.ps1 that broke parsing under
Windows PowerShell 5.1 (UTF-8 without BOM), and document the Code 52 /
Code 31 / friendly-name troubleshooting in driver/README.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>