Files
punktfunk/tools/win-input-matrix/Cargo.toml
T
enricobuehler 13438b1287 test(tools): ask Windows which input APIs can see the pad, and find what promotes it
The Xbox-pad-on-Windows programme is a five-row matrix — classic XInput, WGI `Gamepad`, WGI
`RawGameController`, GameInput, and the HID/DirectInput/Steam family — and nothing in this tree
measured any of it. Every reading in the handoff came from ad-hoc off-tree tools, which is why
several could not be reproduced later and why one was a false positive. `win-input-matrix` makes
the matrix a command you can run twice and diff.

Two traps are baked into it because both have already cost this programme a wrong conclusion.
`--watch` samples repeatedly and reports LIVE vs MUTE per device, because an API listing a pad that
never reports is the exact failure mode here — worse than not listing it, since a title that binds
the first gamepad latches a dead one. And the doc comment insists on a baseline with the virtual pad
STOPPED: a real Xbox pad owns XInput slot 0, which is how `rc=0 LX=-885` was once read as success
with our pad already killed.

 `wake_wgi()` is not optional and is commented as such. `Gamepad::Gamepads()` and
`RawGameController::RawGameControllers()` return a cache filled by WGI's device-watcher, which a
GUI app has already started and a console app has not. Without subscribing to the Added events
first, BOTH collections come back empty with real controllers attached — measured here: a DualSense
sitting in the HID interface class, `RawGameControllers` count=0. A probe missing this reports "WGI
cannot see the pad" when WGI could not see anything.

WHAT IT FOUND (full record in measurements/2026-08-09-xbox-hid-xinputhid-busfilter.md): with
`UpperFilters=xinputhid` on the pad's PARENT devnode AND `DevicePropertyFlags=1` in that parent's
SOFTWARE key, the HID Xbox pad is promoted for the first time — the child gains the `IG_00` token,
an XUSB interface appears, classic XInput admits it, and WGI `Gamepad` lists it. All four had never
happened on this backend. A one-value A/B proves `DevicePropertyFlags` is the decisive half:
removing it alone reverts all four. That retro-explains the earlier "the filter installs fine and
produces nothing" result — the filter was loading without ever being put in bus-filter mode, which
is what `BusDevice = 0x1` means in Microsoft's own comment in `xinputhid.inf`.

Not a workspace member, for the same reason as `hid-descriptor-dump`: it is a Windows-only
bring-your-own-hardware tool with no business on a CI leg.

VERIFIED
  * `cargo fmt --check` clean; `cargo clippy --target x86_64-pc-windows-msvc --all-targets
    -- -D warnings` clean (cross-checked from macOS; the target is installed).
  * Builds and runs on .173 (Win11 26200).
  * Self-checked against known-good hardware before any conclusion was drawn from it: baseline
    reads the USB DualSense as LIVE in both WGI collections and the resting 8BitDo as MUTE.
  * The A/B was run in both directions on the same box in one session.
  * `cargo metadata` on the root workspace resolves and does NOT list this crate.
  * .173 fully reverted: registry values removed, devnodes removed, oem100.inf deleted, both certs
    delstored, 6 pre-existing pf_gamepad packages and the production service untouched.

NOT VERIFIED
  * GameInput — no binding in the `windows` crate, needs hand-written COM vtables. Not covered;
    the doc comment says so.
  * That the promotion survives a reboot or a devnode re-create from a shipped INF `AddReg` rather
    than a hand-written registry value. Nothing is shipped: `pf_gamepad.inx` is UNCHANGED and still
    contains no AddReg of any kind.
  * WHY the promoted pad still translates no data. Enumeration is fixed; translation is not. The
    evidence points at the report descriptor, which is gated on the §3.3 decision.
2026-08-09 19:24:28 +02:00

35 lines
1.3 KiB
TOML

# Ask every Windows input API, in one shot, whether it can see a given gamepad.
#
# The whole Xbox-pad-on-Windows programme is a matrix of five rows — classic XInput, WGI `Gamepad`,
# WGI `RawGameController`, GameInput, and the HID/DirectInput/Steam family — and until this crate
# existed NOTHING in the tree measured any of it. Every reading in
# `design/xbox-pad-windows-handoff.md` came from ad-hoc off-tree tools, which is why several of them
# could not be reproduced or A/B'd later. This makes the matrix a command.
#
# Deliberately NOT a workspace member (see the root `Cargo.toml` `exclude` list): it is a
# bring-your-own-hardware measurement tool, Windows-only, and has no business on a CI leg.
#
# cargo run --release -- --watch 20
#
[workspace]
[package]
name = "win-input-matrix"
description = "Which Windows input APIs can see this gamepad? XInput / WGI Gamepad / WGI RawGameController / XUSB"
version = "0.26.0"
edition = "2024"
rust-version = "1.96.0"
license = "MIT OR Apache-2.0"
publish = false
[target.'cfg(windows)'.dependencies]
windows = { version = "0.62", features = [
"Win32_Foundation",
"Win32_UI_Input_XboxController",
"Win32_Devices_DeviceAndDriverInstallation",
"Win32_System_Com",
"Gaming_Input",
"Foundation",
"Foundation_Collections",
] }