feat(host/windows): seal the host↔driver channels (frame + gamepad, proto v2)

Frame ring (pf-vdisplay) and both gamepad SHM channels move off named Global\
objects (openable by any sibling LocalService) to UNNAMED sections/events whose
handles the host DuplicateHandles into the driver's verified WUDFHost with least
access — frame delivery over the SYSTEM+admins-only IOCTL_SET_FRAME_CHANNEL,
pads over a 32-byte named bootstrap mailbox (pid + handle value only, DoS-bounded;
HID minidrivers have no control device). Driver-validated pad_index kills
cross-pad redirects; v1↔v2 mixes fail closed with diagnosis logs on both sides.
Sibling-LocalService denial proven empirically (design/idd-push-security.md,
design/gamepad-channel-sealing.md).

Driver-side raw ops now live behind pf-umdf-util (checked shm accessors, the
forbid(unsafe_code) ChannelClient state machine, WDF request tokens) — the pad
drivers' logic is 100% safe Rust; whole drivers workspace clippy-gated in CI.

driver install --gamepad now sweeps SWD\punktfunk phantom devnodes: a re-created
SwDevice REVIVES the old devnode with its previously-bound driver (never
re-ranks), so an upgrade otherwise leaves the old driver serving — or, across
the v1→v2 fence, a dead pad (found live on the RTX box).

On-glass validated on the RTX 4090 box: frame path 7007 frames p50 2.06 ms
cross-machine; DualSense + XUSB "sealed pad channel mapped"/proto=2 attach via
both the test harness and a real streaming session; phantom-sweep repro.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 12:08:56 +00:00
parent 16a7991cea
commit 8b47be668f
35 changed files with 2604 additions and 1174 deletions
@@ -162,9 +162,28 @@ fn install_gamepad(dir: &Path) -> Result<()> {
eprintln!("warning: pnputil /add-driver {} failed", inf.display());
}
}
// Sweep pad devnodes, INCLUDING phantoms a host crash / service stop left behind: a re-created
// SwDevice with a known instance id REVIVES the existing devnode with its previously-bound
// driver — it never re-ranks against the store — so after an upgrade the old driver keeps
// serving (or, across the v1→v2 sealed-channel fence, fails closed and the pad plays dead).
// Proven in the field on the RTX box: a v1 phantom pinned the old package through a v2
// install. The devnodes are per-session objects the host recreates on demand, so removing
// them at driver-install time is always safe; the next pad binds the fresh package.
remove_pad_devnodes();
Ok(())
}
/// `pnputil /remove-device` every punktfunk virtual-pad devnode (live or phantom).
fn remove_pad_devnodes() {
for id in pad_instance_ids() {
if run_quiet("pnputil", &["/remove-device", &id]) {
println!("removed stale pad devnode {id}");
} else {
eprintln!("warning: pnputil /remove-device {id} failed");
}
}
}
// ── `driver uninstall [--gamepad]` ──────────────────────────────────────────────────────────────
// The uninstaller's cleanup counterpart (Inno [UninstallRun]) — the field report was that our
// virtual-device drivers survived an uninstall. Removes the pf-vdisplay device node(s) + driver
@@ -204,6 +223,9 @@ fn uninstall_pf_vdisplay() -> Result<()> {
}
fn uninstall_gamepad() -> Result<()> {
// Devnodes first (incl. phantoms — the same ghost-device complaint the vdisplay uninstall
// fixed), then the store packages.
remove_pad_devnodes();
delete_store_drivers(&["pf_dualsense", "pf_dualshock4", "pf_xusb"]);
Ok(())
}
@@ -235,6 +257,28 @@ fn pf_vdisplay_instance_ids() -> Vec<String> {
ids
}
/// Instance IDs of punktfunk virtual-pad devnodes (`SWD\PUNKTFUNK\…`), INCLUDING phantoms left by
/// a host crash / service stop (`pnputil /enum-devices` lists disconnected devnodes too). Same
/// un-localized VALUE-side parsing as [`pf_vdisplay_instance_ids`]; matched on the instance-id
/// prefix itself — the pads span two device classes (HIDClass + System), so no `/class` filter.
fn pad_instance_ids() -> Vec<String> {
let out = run_capture("pnputil", &["/enum-devices"]);
let mut ids = Vec::new();
for block in out.split("\r\n\r\n").flat_map(|b| b.split("\n\n")) {
let Some(first) = block.lines().find(|l| !l.trim().is_empty()) else {
continue;
};
let Some((_, value)) = first.split_once(':') else {
continue;
};
let id = value.trim();
if id.to_ascii_uppercase().starts_with("SWD\\PUNKTFUNK\\") && !id.contains(' ') {
ids.push(id.to_string());
}
}
ids
}
/// Delete every driver-store package (`%WINDIR%\INF\oem*.inf`) whose INF text mentions one of
/// `needles` — our driver names are unique enough that a content match identifies the package
/// without parsing `pnputil /enum-drivers`' localized output. `/uninstall /force` also unbinds it