feat(gamepad): SwDeviceCreate per-session devnode (best-effort) + windows self-test

DualSenseWindowsManager now SwDeviceCreate's the pf_dualsense devnode per session
(SwDeviceClose on drop), matching the Linux UHID pad's lifecycle. It's best-effort:
SwDeviceCreate currently hits an unresolved E_INVALIDARG when a completion callback is
passed (an underscore in the enumerator name was a second cause, fixed by using
"punktfunk"), so on failure the host keeps the section + data plane and falls back to
an out-of-band devnode (installer/devgen) — see docs/windows-dualsense-scoping.md.

Add a `dualsense-windows-test` host CLI that drives the manager (create devnode + push
a frame + hold), used to validate the path. Live on the RTX box: the manager creates
the section + pushes report 0x01 and a devnode serves it to a HID read (b1=0xC0,
b8=0x28) — the host-side data plane works end to end.

cargo check + clippy -D warnings clean on x86_64-pc-windows-msvc.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 21:34:00 +00:00
parent 01dc0b616c
commit fde438a1ed
4 changed files with 185 additions and 11 deletions
+13
View File
@@ -340,6 +340,19 @@ Three bugs had to be fixed to get there — the load wall was the PE **FORCE_INT
`/INTEGRITYCHECK`; clear bit `0x80` at PE+0x5e + re-sign), then `WdfTimerCreate` exec-level, then a parallel
queue's zeroed `NumberOfPresentedRequests`. **Option R (Rust) confirmed for M2; no C shim needed.**
**Host integration status (2026-06-21): M1/M3/M4 landed; data plane runtime-proven.** The Linux
DualSense logic is shared via `inject/dualsense_proto.rs`; the Windows backend
`inject/dualsense_windows.rs` (`DualSenseWindowsManager`) drives the driver over the
`Global\pfds-shm-<idx>` section, and the `PadBackend`/`pick_gamepad` seam now resolves DualSense on
Windows. Live-verified on the RTX box: the manager creates the section + pushes report `0x01` and a
devnode serves it to a HID read (manager data plane works). **Open item — `SwDeviceCreate`
per-session devnode:** two `E_INVALIDARG` causes found — (1) an underscore in the enumerator name
(`pf_dualsense` → use `punktfunk`), (2) passing the completion callback is still rejected (cause
unresolved; needs a known-good C reference). So per-session auto-creation is **best-effort/non-fatal**:
the host falls back to an out-of-band `pf_dualsense` devnode (the INF lists both `root\pf_dualsense`
for devgen and `pf_dualsense` for SwDevice; the installer would create it, as SudoVDA does). Remaining:
fix the SwDeviceCreate callback E_INVALIDARG, then the M5 on-glass game test.
## Milestone plan (M0M6)
| # | Milestone | Output | Gate / risk |