Problem
The end-stream hotkey added in 0e5ff426 never registers. With end_stream_hotkey set, pressing the shortcut does nothing, and the service log repeats this every 5 seconds:
Warning: End-stream hotkey unavailable; retrying the interactive helper.The log never shows End-stream hotkey registered in interactive console session N. or the "another application may own the combination" warning.
Cause
The service creates the helper's named pipe with this DACL:
D:P(A;;GA;;;SY)(A;;GW;;;<console user SID>)S:(ML;;NW;;;ME)The helper opens the pipe with CreateFileA(..., GENERIC_WRITE, ...). CreateFile always adds FILE_READ_ATTRIBUTES (and SYNCHRONIZE) to the requested access, and GENERIC_WRITE maps to FILE_GENERIC_WRITE, which doesn't include FILE_READ_ATTRIBUTES. So the open fails with access denied, the helper exits with code 4 before calling RegisterHotKey, and the supervisor retries forever.
Fix
Grant FILE_READ_ATTRIBUTES in the user ACE alongside GENERIC_WRITE (0x40000080). SDDL can't mix a hex mask with GW, so the mask is written out, with a comment.
Evidence
I copied the service side of the handshake into a small standalone program (same pipe flags and SDDL, then launching the installed tools\sunshine_end_stream_hotkey.exe as the console user):
| User ACE | Result |
|---|---|
GW (current) | helper never connects, exits with code 4 |
GW, without the S: integrity label | same, exits with code 4 |
0x40000080 (GW + read attributes) | helper connects, sends ready, then a heartbeat every second |
On my Windows 11 host (service running as SYSTEM), after deploying a build with this change:
14:06:53 Info: End-stream hotkey registered in interactive console session 1.
14:10:48 Info: Host end-stream shortcut: ending all streams and restoring the physical desktop.
14:10:49 Info: Process terminated
14:10:51 Info: Virtual display cleanup: begin (reason=end_stream_hotkey, ...)
14:10:54 Info: Virtual display cleanup: terminal driver and helper watchdog shutdown completed (reason=end_stream_hotkey).Testing
- Tested on the host as above: the hotkey ended a live stream, closed the app and restored the display, and none of the end-stream failure warnings appeared.
- That host build is this commit on top of
master1b316787 plus other local changes (#571, #654 and two unrelated display fixes). This branch's version ofend_stream_hotkey.cppand its headers is identical to the tested one apart from this change. I haven't built this exact branch by itself.
🤖 Generated with Claude Code
Activity
5Retargeted to canary and rebased the commit onto it (e3d13d10). The PR now contains only the one-file change to src/platform/windows/end_stream_hotkey.cpp. The CI/release workflow changes were the two ci(nightly) commits on master that aren't in canary.
🤖 Addressed by Claude Code
Reviewed 507b057375ecb44a91dfb3d9d37e5e760d07756b against canary at e3d13d104c0b7f4af1d0a3dad156a3e3c7d1bc44. No actionable issues identified. The rebased patch matches the original change, and the helper and server retain their PID and session checks.
This review was static; I did not build or run this exact revision on Windows. The reported Windows test used a build with additional local changes.
Tested this exact revision on Windows. I built 507b057375ecb44a91dfb3d9d37e5e760d07756b on its own from a clean worktree (MSYS2 UCRT64, Release, WebRTC off) and swapped only sunshine.exe into my installed host (Windows 11, service running as SYSTEM, end_stream_hotkey = A with the default ctrl+alt+shift).
The log reports commit: 507b057375ec.... During a live Moonlight stream of Desktop, I sent Ctrl+Alt+Shift+A at 11:07:52.205:
11:07:15.201 Info: End-stream hotkey registered in interactive console session 1.
11:07:38.502 Info: CLIENT CONNECTED
11:07:52.262 Info: Host end-stream shortcut: ending all streams and restoring the physical desktop.
11:07:52.446 Info: Terminating app [Desktop] when all clients are disconnected. Pause commands are skipped.
11:07:52.726 Info: Process terminated
11:07:55.322 Info: Virtual display cleanup: begin (reason=end_stream_hotkey, ...)
11:07:55.364 Info: Virtual display cleanup: finished (reason=end_stream_hotkey, had_active_virtual_display=false, virtual_displays_removed=true, helper_revert_dispatched=true, database_restore_applied=false)
11:07:58.384 Info: Virtual display cleanup: terminal driver and helper watchdog shutdown completed (reason=end_stream_hotkey).None of the end-stream failure warnings appeared: no "display recovery did not confirm", no "ownership remains" and no "did not drain".
Limits of this test: tools\ (including the end-stream helper) and the assets were not replaced. They come from my 10-24 build, and their helper and display-helper sources match this revision. The keypress was synthesized with SendInput, not typed.
🤖 Addressed by Claude Code
Please retarget this PR to
canaryand reconcile the branch against that base. The current comparison also includes changes to Windows CI and release workflows unrelated to the hotkey fix; please check that the resulting PR contains the intended changes.