feat(host/windows): two-process secure-desktop step 5 — DDA mux on Winlogon
`virtual_stream_relay` now muxes the AU source by input desktop. A DesktopWatcher (SYSTEM-only Winlogon-name poll) drives it: the user-session WGC helper relay feeds the normal (Default) desktop; the host's OWN DDA capturer+encoder — opened lazily on the first secure transition, on the same SudoVDA target with a no-op keepalive (the host still holds the real isolation owner) — captures the secure (Winlogon: UAC/lock/login) desktop that WGC can't see. Every switch latches "wait for IDR" and forces the now-active source to emit a keyframe (the two encoders keep independent infinite-GOP state, so the client must resume on an IDR); returning to the helper also drains its stale buffered AUs first. Reconfigure drops the stale-target DDA; keyframe requests route to the live source. Send path (FEC/seal/paced-send) unchanged. Also: wgc_relay gains try_recv (drain on switch-back); open_dda takes dims as args (avoids a closure borrow of the reassigned cur_mode); the forward! macro returns bool with `break 'outer` at the call site (no in-macro label hygiene). cfg-gated windows-only. Live validation (UAC switch over a session) pending. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,30 @@
|
||||
# Windows secure-desktop capture — two-process design
|
||||
|
||||
Status: **design validated, implementation in progress.** The WGC animation fix ships and works
|
||||
(host in user-mode); this doc is the plan for adding **secure-desktop (UAC / lock / login) coverage**
|
||||
on top of it, since WGC and the secure desktop need conflicting process tokens.
|
||||
Status: **steps 1–5 implemented (compiles on the 4090); live validation pending.** The WGC animation
|
||||
fix ships and works (host in user-mode); this doc is the plan for adding **secure-desktop (UAC / lock
|
||||
/ login) coverage** on top of it, since WGC and the secure desktop need conflicting process tokens.
|
||||
|
||||
Implemented so far:
|
||||
- **Step 1 — DesktopWatcher** (`capture/desktop_watch.rs`): polls the input-desktop name → atomic
|
||||
`Default`/`Winlogon`. Committed `80e222d`.
|
||||
- **Step 3 — WGC helper subcommand** (`wgc_helper.rs`, `m3-host wgc-helper`): WGC→NVENC→framed AUs on
|
||||
stdout, stdin keyframe control. Committed `a0f6cdd`.
|
||||
- **Step 4 — spawn + relay** (`capture/wgc_relay.rs`, `m3::virtual_stream_relay`): SYSTEM host spawns
|
||||
the helper via `CreateProcessAsUserW` into `winsta0\default`, relays its stdout AUs to the QUIC send
|
||||
thread, forwards keyframe requests, surfaces helper stderr in host tracing. Committed `9f50b39`.
|
||||
- **Step 5 — source mux** (`m3::virtual_stream_relay`): the DesktopWatcher switches the AU source —
|
||||
helper relay on `Default`, the host's own DDA capturer+encoder on `Winlogon`; every switch latches
|
||||
"wait for IDR" + forces the now-active source to emit a keyframe.
|
||||
|
||||
Remaining: **step 6** (helper relaunch watchdog on console connect/disconnect + crash, then a
|
||||
lock/unlock+UAC soak) and **step 2** (SendInput retry-on-failure refactor — input works today via the
|
||||
existing path; this hardens it across the desktop boundary).
|
||||
|
||||
Live validation to run when the box is up (single session, host as SYSTEM via the `-s -i 1` scheduled
|
||||
task): connect a client → confirm video via the helper relay on the normal desktop (host log
|
||||
`source switch … normal(WGC relay)` + `WGC helper spawned`), trigger a UAC prompt → the stream shows
|
||||
the UAC dialog (host log `source switch … secure(DDA)`), dismiss → back to the helper; the QUIC
|
||||
session stays up throughout.
|
||||
|
||||
## The constraint (verified live on the RTX 4090)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user