feat(windows): pf-vdisplay CLEAR_ALL — reap orphaned virtual monitors on startup

The "5-6 stale monitors that never tear down" failure (also seen with SudoVDA):
an orphan from a crashed/killed previous host lingers because the driver watchdog
is kept reset by a still-pinging new session, so it never fires for the orphan.

- Driver (pf-vdisplay control.rs): new IOCTL_CLEAR_ALL (0x804) -> tear down every
  monitor. A pf-vdisplay extension; SudoVDA returns invalid for it (ignored), so
  the host can issue it unconditionally.
- Host (vdisplay/sudovda.rs): send IOCTL_CLEAR_ALL once on startup (best-effort)
  to reap orphans before creating ours; and surface a failing keepalive PING (the
  old `let _ =` swallowed it, masking a lost control handle).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 22:07:14 +02:00
parent d39da4bc06
commit e27abc065e
2 changed files with 33 additions and 2 deletions
@@ -30,6 +30,10 @@ const IOCTL_ADD: u32 = ctl(0x800);
const IOCTL_REMOVE: u32 = ctl(0x801);
const IOCTL_SET_RENDER_ADAPTER: u32 = ctl(0x802);
const IOCTL_GET_WATCHDOG: u32 = ctl(0x803);
/// pf-vdisplay extension (NOT in SudoVDA): tear down every monitor. The host issues this on startup to
/// reap monitors orphaned by a crashed/killed previous host instance. SudoVDA returns invalid for it
/// (harmlessly ignored), so the host can send it unconditionally.
const IOCTL_CLEAR_ALL: u32 = ctl(0x804);
const IOCTL_PING: u32 = ctl(0x888);
const IOCTL_GET_VERSION: u32 = ctl(0x8FF);
@@ -112,6 +116,10 @@ pub extern "C-unwind" fn device_io_control(
IOCTL_SET_RENDER_ADAPTER => do_set_render_adapter(request, input_len),
IOCTL_GET_WATCHDOG => do_get_watchdog(request, output_len, &mut bytes),
IOCTL_PING => NTSTATUS::STATUS_SUCCESS,
IOCTL_CLEAR_ALL => {
disconnect_all_monitors();
NTSTATUS::STATUS_SUCCESS
}
IOCTL_GET_VERSION => do_get_version(request, output_len, &mut bytes),
_ => NTSTATUS::STATUS_INVALID_DEVICE_REQUEST,
}