Skip to content

fix(inject): call LockWorkStation/SetSuspendState on Windows - #1447

Open
4ni1ak wants to merge 2 commits into
AprilNEA:masterfrom
4ni1ak:fix/windows-sleep-lock-actions
Open

4ni1ak wants to merge 2 commits into
AprilNEA:masterfrom
4ni1ak:fix/windows-sleep-lock-actions

Conversation

@4ni1ak

@4ni1ak 4ni1ak commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • NativeAction::LockScreen and NativeAction::Sleep both did nothing useful on Windows.

Changes

  • crates/openlogi-inject/src/inject/windows.rs:
    • LockScreen synthesised Win+L via SendInput, but as a second reporter confirmed in the issue thread, only the bare L key actually took effect — winlogon's own secure-desktop hotkey doesn't reliably react to a synthetic Win key press. Switch to calling LockWorkStation() directly, the documented, privilege-free API for exactly this, matching the precedent this same file already sets for macOS Sleep (calling pmset sleepnow instead of faking a key combo).
    • Sleep was entirely unimplemented (skipped with a debug log, per the existing comment: "no clean win from a background agent"). Wired it to SetSuspendState, which needs SeShutdownPrivilege enabled on the process token first — every process has the privilege available but disabled by default. Added the standard OpenProcessToken/LookupPrivilegeValueW/AdjustTokenPrivileges dance, checking GetLastError immediately after AdjustTokenPrivileges (before any other call can overwrite it) since that API reports success even when it silently enabled none of the requested privileges.
  • crates/openlogi-inject/Cargo.toml: added the windows-sys feature flags these APIs live behind (Win32_Foundation, Win32_Security, Win32_System_Power, Win32_System_Shutdown, Win32_System_Threading).

Testing

  • No Windows machine available, so I set up cross-compilation instead of guessing: rustup target add x86_64-pc-windows-gnu, then:
    • cargo check --target x86_64-pc-windows-gnu -p openlogi-inject (caught a real type mismatch on SetSuspendState's bool-typed parameters in this windows-sys version — fixed before this PR)
    • cargo clippy --target x86_64-pc-windows-gnu -p openlogi-inject --all-targets -- -D warnings
  • Full local gate on the host (Linux), since Cargo.toml changed: cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace, cargo doc --workspace --no-deps --document-private-items (excluding the GUI crates) — all green.
  • Not runtime-tested on Windows. The cross-compile confirms this type-checks correctly against the real Win32 API signatures, but I have no way to confirm LockWorkStation/SetSuspendState actually lock/sleep the machine, or that the privilege-enable dance succeeds from this agent's actual process context, without real Windows hardware.

Fixes #1266

NativeAction::LockScreen synthesised Win+L via SendInput, but winlogon's
own secure-desktop hotkey doesn't reliably react to a synthetic Win key
press — only the bare L key took effect, so the screen never locked.
Call the documented LockWorkStation API directly instead, the same way
the macOS backend already calls pmset for Sleep rather than faking a
key combo.

NativeAction::Sleep was entirely unimplemented on Windows (skipped with
a debug log). Wire it to SetSuspendState, which needs SeShutdownPrivilege
enabled on the process token first — every process has the privilege
available but disabled by default, so add the standard
OpenProcessToken/LookupPrivilegeValueW/AdjustTokenPrivileges dance.

Fixes AprilNEA#1266
@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with no actionable new correctness or rule-compliance issues identified.

Summary

This PR implements previously ineffective Windows native lock and sleep actions.

  • Replaces synthetic Win+L input with LockWorkStation.
  • Implements suspend through SetSuspendState after enabling SeShutdownPrivilege.
  • Serializes concurrent sleep requests and disables the privilege after the suspend attempt.
  • Adds the required windows-sys feature flags.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Windows NativeAction] --> B{Action}
    B -->|LockScreen| C[LockWorkStation]
    B -->|Sleep| D[Acquire SLEEP_LOCK]
    D --> E[Open process token]
    E --> F[Enable SeShutdownPrivilege]
    F --> G[SetSuspendState]
    G --> H[Disable SeShutdownPrivilege]
    H --> I[Close token handle]
    I --> J[Release SLEEP_LOCK]
Loading

Reviews (2) · Last reviewed commit: "fix(inject): disable SeShutdownPrivilege..."

Comment thread crates/openlogi-inject/src/inject/windows.rs
enable_shutdown_privilege() flipped SeShutdownPrivilege on for the
process token but never restored it — the privilege is a process-wide
token attribute, not scoped to the enabling call, so it stayed enabled
for the rest of this long-running agent process regardless of whether
SetSuspendState succeeded.

Splits enable/disable into one adjust_shutdown_privilege(token,
attributes) helper reused for both directions, disables the privilege
again after the SetSuspendState attempt (success or failure), and adds
a mutex around the whole enable/suspend/disable sequence so concurrent
Sleep requests can't interleave their privilege toggles.

Addresses the Greptile security finding on AprilNEA#1447.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: "Sleep" and "Lock" actions do not work

1 participant