diff --git a/src/ipc.rs b/src/ipc.rs index 83533c447..29954d61f 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -186,6 +186,7 @@ pub enum Data { MouseMoveTime(i64), Authorize, Close, + #[cfg(windows)] SAS, UserSid(Option), OnlineStatus(Option<(i64, bool)>), diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 9679a7a02..89801f89a 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -675,7 +675,7 @@ async fn send_close_async(postfix: &str) -> ResultType<()> { // https://docs.microsoft.com/en-us/windows/win32/api/sas/nf-sas-sendsas // https://www.cnblogs.com/doutu/p/4892726.html -fn send_sas() { +pub fn send_sas() { #[link(name = "sas")] extern "system" { pub fn SendSAS(AsUser: BOOL); @@ -744,6 +744,17 @@ pub fn get_current_process_session_id() -> Option { } } +pub fn is_physical_console_session() -> Option { + if let Some(sid) = get_current_process_session_id() { + let physical_console_session_id = unsafe { get_current_session(TRUE) }; + if physical_console_session_id == u32::MAX { + return None; + } + return Some(physical_console_session_id == sid); + } + None +} + pub fn get_active_username() -> String { // get_active_user will give console username higher priority if let Some(name) = get_current_session_username() { diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 92e818d36..79443b1f2 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1,3 +1,5 @@ +#[cfg(target_os = "linux")] +use super::rdp_input::client::{RdpInputKeyboard, RdpInputMouse}; use super::*; #[cfg(target_os = "macos")] use crate::common::is_server; @@ -5,8 +7,6 @@ use crate::input::*; #[cfg(target_os = "macos")] use dispatch::Queue; use enigo::{Enigo, Key, KeyboardControllable, MouseButton, MouseControllable}; -#[cfg(target_os = "linux")] -use super::rdp_input::client::{RdpInputKeyboard, RdpInputMouse}; use hbb_common::{ get_time, message_proto::{pointer_device_event::Union::TouchEvent, touch_event::Union::ScaleUpdate}, @@ -1316,6 +1316,7 @@ fn is_function_key(ck: &EnumOrUnknown) -> bool { let mut res = false; if ck.value() == ControlKey::CtrlAltDel.value() { // have to spawn new thread because send_sas is tokio_main, the caller can not be tokio_main. + #[cfg(windows)] std::thread::spawn(|| { allow_err!(send_sas()); }); @@ -1564,10 +1565,15 @@ async fn lock_screen_2() { lock_screen().await; } +#[cfg(windows)] #[tokio::main(flavor = "current_thread")] async fn send_sas() -> ResultType<()> { - let mut stream = crate::ipc::connect(1000, crate::POSTFIX_SERVICE).await?; - timeout(1000, stream.send(&crate::ipc::Data::SAS)).await??; + if crate::platform::is_physical_console_session().unwrap_or(true) { + let mut stream = crate::ipc::connect(1000, crate::POSTFIX_SERVICE).await?; + timeout(1000, stream.send(&crate::ipc::Data::SAS)).await??; + } else { + crate::platform::send_sas(); + }; Ok(()) }