Files
punktfunk/crates/pf-driver-proto
enricobuehler 66b041e4ba feat(host/windows,drivers): gamepad driver attach/heartbeat health surfaced in logs
The gamepad drivers have no IOCTL plane (hidclass gates the stack), so
until now the host had ZERO visibility into whether a driver ever
bound: a pad could be "created" with no driver installed and nothing
was logged. Two health fields are carved from reserved shm space
(layout-compatible; pf-driver-proto pins the offsets): driver_proto —
stamped by pf-xusb at device add + per serviced XInput IOCTL (movement
= the game-visible path) and by pf-dualsense/DS4 from its ~125Hz timer
— and driver_heartbeat. Host-side, every pad owns a DriverAttach
watcher fed from the existing service() poll: INFO on attach (WARN on
proto mismatch), and after 3s of silence ONE diagnosis WARN combining
a cached pnputil /enum-drivers store check, the devnode's CM problem
code (CM_Locate_DevNodeW/CM_Get_DevNode_Status on the instance id now
captured from the create callback, with plain-language hints: 28 = not
installed, 52 = signature/Memory Integrity, …) and the driver's debug
log path. Also fixes a real bug both SwDeviceCreate wrappers shared:
the 10s WaitForSingleObject result was ignored and the callback
HRESULT zero-initialised, so a PnP timeout read as SUCCESS (now E_FAIL
init + explicit timeout error). Failure-mode table:
design/gamepad-driver-health.md.

Linux workspace green; Windows host + drivers CI-compile only, on-box
recipe at the bottom of the design doc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:36:15 +00:00
..

pf-driver-proto

The shared host ↔ driver binary contract for punktfunk's Windows pf-vdisplay virtual display — the control IOCTLs and the IDD-push frame transport, defined exactly once.

It's a path dependency of both the host workspace (crates/punktfunk-host) and the out-of-workspace driver workspace (packaging/windows/drivers/), so it must resolve identically from either build graph. That's why it's deliberately self-contained: no_std (+ alloc), platform-neutral (GUID/LUID are plain integers each side converts to its own OS type), and free of *.workspace = true inheritance.

Defining every wire struct here — with const size/offset asserts and bytemuck round-trips — turns host↔driver ABI drift into a compile error instead of a silent frame or IOCTL corruption.

See the crate root (src/) for the wire types; the Windows virtual-display design is in design/windows-virtual-display-rust-port.md.