mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-11-24 04:12:20 +08:00
Merge pull request #1628 from 21pages/portable-uac
windows portable uac
This commit is contained in:
commit
0bfb9478bd
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -2537,6 +2537,14 @@ dependencies = [
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "impersonate_system"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/21pages/impersonate-system#af4a82050580217a434c2024e181a98de24823ec"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "include_dir"
|
||||
version = "0.7.2"
|
||||
@ -4329,6 +4337,7 @@ dependencies = [
|
||||
"flutter_rust_bridge_codegen",
|
||||
"hbb_common",
|
||||
"hound",
|
||||
"impersonate_system",
|
||||
"include_dir",
|
||||
"jni",
|
||||
"lazy_static",
|
||||
|
@ -91,6 +91,7 @@ winapi = { version = "0.3", features = ["winuser"] }
|
||||
winreg = "0.10"
|
||||
windows-service = "0.4"
|
||||
virtual_display = { path = "libs/virtual_display" }
|
||||
impersonate_system = { git = "https://github.com/21pages/impersonate-system" }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc = "0.2"
|
||||
|
@ -407,6 +407,15 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Timer(const Duration(seconds: 1), () async {
|
||||
final installed = bind.mainIsInstalled();
|
||||
final root = await bind.mainIsRoot();
|
||||
final release = await bind.mainIsRelease();
|
||||
if (Platform.isWindows && release && !installed && !root) {
|
||||
msgBox('custom-elevation-nocancel', 'Prompt', 'elevation_prompt',
|
||||
gFFI.dialogManager);
|
||||
}
|
||||
});
|
||||
Timer(const Duration(seconds: 5), () async {
|
||||
updateUrl = await bind.mainGetSoftwareUpdateUrl();
|
||||
if (updateUrl.isNotEmpty) setState(() {});
|
||||
|
@ -106,7 +106,12 @@ class PlatformFFI {
|
||||
debugPrint('initializing FFI $_appType');
|
||||
try {
|
||||
_translate = dylib.lookupFunction<F2, F2>('translate');
|
||||
_dir = (await getApplicationDocumentsDirectory()).path;
|
||||
try {
|
||||
// SYSTEM user failed
|
||||
_dir = (await getApplicationDocumentsDirectory()).path;
|
||||
} catch (e) {
|
||||
debugPrint('Failed to get documents directory: $e');
|
||||
}
|
||||
_ffiBind = RustdeskImpl(dylib);
|
||||
_startListenEvent(_ffiBind); // global event
|
||||
try {
|
||||
|
@ -556,6 +556,8 @@ message Misc {
|
||||
bool video_received = 12;
|
||||
BackNotification back_notification = 13;
|
||||
bool restart_remote_device = 14;
|
||||
bool uac = 15;
|
||||
bool foreground_window_elevated = 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1354,7 +1354,11 @@ impl LoginConfigHandler {
|
||||
username: self.id.clone(),
|
||||
password: password.into(),
|
||||
my_id,
|
||||
my_name: crate::username(),
|
||||
my_name: if cfg!(windows) {
|
||||
crate::platform::get_active_username()
|
||||
} else {
|
||||
crate::username()
|
||||
},
|
||||
option: self.get_option_message(true).into(),
|
||||
session_id: self.session_id,
|
||||
version: crate::VERSION.to_string(),
|
||||
|
@ -979,6 +979,21 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Some(misc::Union::Uac(uac)) => {
|
||||
if uac {
|
||||
self.handler
|
||||
.msgbox("custom-uac-nocancel", "Warning", "uac_warning");
|
||||
}
|
||||
}
|
||||
Some(misc::Union::ForegroundWindowElevated(elevated)) => {
|
||||
if elevated {
|
||||
self.handler.msgbox(
|
||||
"custom-elevated-foreground-nocancel",
|
||||
"Warning",
|
||||
"elevated_foreground_window_warning",
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Some(message::Union::TestDelay(t)) => {
|
||||
|
@ -8,12 +8,20 @@ pub fn core_main() -> Option<Vec<String>> {
|
||||
let mut args = Vec::new();
|
||||
let mut i = 0;
|
||||
let mut is_setup = false;
|
||||
let mut _is_elevate = false;
|
||||
let mut _is_run_as_system = false;
|
||||
for arg in std::env::args() {
|
||||
// to-do: how to pass to flutter?
|
||||
if i == 0 && crate::common::is_setup(&arg) {
|
||||
is_setup = true;
|
||||
} else if i > 0 {
|
||||
args.push(arg);
|
||||
if arg == "--elevate" {
|
||||
_is_elevate = true;
|
||||
} else if arg == "--run-as-system" {
|
||||
_is_run_as_system = true;
|
||||
} else {
|
||||
args.push(arg);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
@ -57,6 +65,11 @@ pub fn core_main() -> Option<Vec<String>> {
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
#[cfg(not(debug_assertions))]
|
||||
if !crate::platform::is_installed() && args.is_empty() {
|
||||
crate::platform::elevate_or_run_as_system(is_setup, _is_elevate, _is_run_as_system);
|
||||
}
|
||||
if args.is_empty() {
|
||||
std::thread::spawn(move || crate::start_server(false));
|
||||
} else {
|
||||
|
@ -800,6 +800,14 @@ pub fn main_has_hwcodec() -> SyncReturn<bool> {
|
||||
SyncReturn(has_hwcodec())
|
||||
}
|
||||
|
||||
pub fn main_is_root() -> bool {
|
||||
is_root()
|
||||
}
|
||||
|
||||
pub fn main_is_release() -> bool {
|
||||
is_release()
|
||||
}
|
||||
|
||||
pub fn session_send_mouse(id: String, msg: String) {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(&msg) {
|
||||
let alt = m.get("alt").is_some();
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", "允许局域网发现"),
|
||||
("Deny LAN Discovery", "拒绝局域网发现"),
|
||||
("Write a message", "输入聊天消息"),
|
||||
("Prompt", "提示"),
|
||||
("elevation_prompt", "以当前用户权限运行软件,可能导致远端在访问本机时,没有足够的权限来操作部分窗口。"),
|
||||
("uac_warning", "暂时无法访问远端设备,因为远端设备正在请求用户账户权限,请等待对方关闭UAC窗口。为避免这个问题,建议在远端设备上安装或者以管理员权限运行本软件。"),
|
||||
("elevated_foreground_window_warning", "暂时无法使用鼠标键盘,因为远端桌面的当前窗口需要更高的权限才能操作, 可以请求对方最小化当前窗口。为避免这个问题,建议在远端设备上安装或者以管理员权限运行本软件。"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -30,5 +30,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("android_open_battery_optimizations_tip", "If you want to disable this feature, please go to the next RustDesk application settings page, find and enter [Battery], Uncheck [Unrestricted]"),
|
||||
("remote_restarting_tip", "Remote device is restarting, please close this message box and reconnect with permanent password after a while"),
|
||||
("Are you sure to close the connection?", "Are you sure you want to close the connection?"),
|
||||
].iter().cloned().collect();
|
||||
("elevation_prompt", "Running software without privilege elevation may cause problems when remote users operate certain windows."),
|
||||
("uac_warning", "Temporarily denied access due to elevation request, please wait for the remote user to accept the UAC dialog. To avoid this problem, it is recommended to install the software on the remote device or run it with administrator privileges."),
|
||||
("elevated_foreground_window_warning", "Temporarily unable to use the mouse and keyboard, because the current window of the remote desktop requires higher privilege to operate, you can request the remote user to minimize the current window. To avoid this problem, it is recommended to install the software on the remote device or run it with administrator privileges."),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -359,5 +359,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", "允許局域網發現"),
|
||||
("Deny LAN Discovery", "拒絕局域網發現"),
|
||||
("Write a message", "輸入聊天消息"),
|
||||
("Prompt", "提示"),
|
||||
("elevation_prompt", "以當前用戶權限運行軟件,可能導致遠端在訪問本機時,沒有足夠的權限來操作部分窗口。"),
|
||||
("uac_warning", "暂时无法访问远端设备,因为远端设备正在请求用户账户权限,请等待对方关闭UAC窗口。为避免这个问题,建议在远端设备上安装或者以管理员权限运行本软件。"),
|
||||
("elevated_foreground_window_warning", "暫時無法使用鼠標鍵盤,因為遠端桌面的當前窗口需要更高的權限才能操作, 可以請求對方最小化當前窗口。為避免這個問題,建議在遠端設備上安裝或者以管理員權限運行本軟件。"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -360,5 +360,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable LAN Discovery", ""),
|
||||
("Deny LAN Discovery", ""),
|
||||
("Write a message", ""),
|
||||
("Prompt", ""),
|
||||
("elevation_prompt", ""),
|
||||
("uac_warning", ""),
|
||||
("elevated_foreground_window_warning", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -14,11 +14,21 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use winapi::{
|
||||
ctypes::c_void,
|
||||
shared::{minwindef::*, ntdef::NULL, windef::*},
|
||||
um::{
|
||||
errhandlingapi::GetLastError, handleapi::CloseHandle, minwinbase::STILL_ACTIVE,
|
||||
processthreadsapi::GetExitCodeProcess, shellapi::ShellExecuteA, winbase::*, wingdi::*,
|
||||
winnt::HANDLE, winuser::*,
|
||||
errhandlingapi::GetLastError,
|
||||
handleapi::CloseHandle,
|
||||
minwinbase::STILL_ACTIVE,
|
||||
processthreadsapi::{GetCurrentProcess, GetExitCodeProcess, OpenProcess, OpenProcessToken},
|
||||
securitybaseapi::GetTokenInformation,
|
||||
shellapi::ShellExecuteA,
|
||||
winbase::*,
|
||||
wingdi::*,
|
||||
winnt::{
|
||||
TokenElevation, HANDLE, PROCESS_QUERY_LIMITED_INFORMATION, TOKEN_ELEVATION, TOKEN_QUERY,
|
||||
},
|
||||
winuser::*,
|
||||
},
|
||||
};
|
||||
use windows_service::{
|
||||
@ -1420,16 +1430,145 @@ pub fn get_user_token(session_id: u32, as_user: bool) -> HANDLE {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_super_user_permission() -> ResultType<bool> {
|
||||
pub fn run_uac(exe: &str, arg: &str) -> ResultType<bool> {
|
||||
unsafe {
|
||||
let cstring;
|
||||
let ret = ShellExecuteA(
|
||||
NULL as _,
|
||||
CString::new("runas")?.as_ptr() as _,
|
||||
CString::new("cmd")?.as_ptr() as _,
|
||||
CString::new("/c /q")?.as_ptr() as _,
|
||||
CString::new(exe)?.as_ptr() as _,
|
||||
if arg.is_empty() {
|
||||
NULL as _
|
||||
} else {
|
||||
cstring = CString::new(arg)?;
|
||||
cstring.as_ptr() as _
|
||||
},
|
||||
NULL as _,
|
||||
SW_SHOWNORMAL,
|
||||
);
|
||||
return Ok(ret as i32 > 32);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_super_user_permission() -> ResultType<bool> {
|
||||
run_uac("cmd", "/c /q")
|
||||
}
|
||||
|
||||
pub fn elevate(arg: &str) -> ResultType<bool> {
|
||||
run_uac(
|
||||
std::env::current_exe()?
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
.as_str(),
|
||||
arg,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn run_as_system(arg: &str) -> ResultType<()> {
|
||||
let exe = std::env::current_exe()?.to_string_lossy().to_string();
|
||||
if impersonate_system::run_as_system(&exe, arg).is_err() {
|
||||
bail!(format!("Failed to run {} as system", exe));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_system: bool) {
|
||||
// avoid possible run recursively due to failed run, which hasn't happened yet.
|
||||
let arg_elevate = if is_setup {
|
||||
"--noinstall --elevate"
|
||||
} else {
|
||||
"--elevate"
|
||||
};
|
||||
let arg_run_as_system = if is_setup {
|
||||
"--noinstall --run-as-system"
|
||||
} else {
|
||||
"--run-as-system"
|
||||
};
|
||||
let rerun_as_system = || {
|
||||
if !is_root() {
|
||||
if run_as_system(arg_run_as_system).is_ok() {
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
log::error!("Failed to run as system");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if is_elevate {
|
||||
if !is_elevated(None).map_or(true, |b| b) {
|
||||
log::error!("Failed to elevate");
|
||||
return;
|
||||
}
|
||||
rerun_as_system();
|
||||
} else if is_run_as_system {
|
||||
if !is_root() {
|
||||
log::error!("Failed to be system");
|
||||
}
|
||||
} else {
|
||||
if let Ok(true) = is_elevated(None) {
|
||||
// right click
|
||||
rerun_as_system();
|
||||
} else {
|
||||
// left click || run without install
|
||||
if let Ok(true) = elevate(arg_elevate) {
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
// do nothing but prompt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/mgostIH/process_list/blob/master/src/windows/mod.rs
|
||||
#[repr(transparent)]
|
||||
pub(self) struct RAIIHandle(pub HANDLE);
|
||||
|
||||
impl Drop for RAIIHandle {
|
||||
fn drop(&mut self) {
|
||||
// This never gives problem except when running under a debugger.
|
||||
unsafe { CloseHandle(self.0) };
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_elevated(process_id: Option<DWORD>) -> ResultType<bool> {
|
||||
unsafe {
|
||||
let handle: HANDLE = match process_id {
|
||||
Some(process_id) => OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id),
|
||||
None => GetCurrentProcess(),
|
||||
};
|
||||
if handle == NULL {
|
||||
bail!("Failed to open process, errno {}", GetLastError())
|
||||
}
|
||||
let _handle = RAIIHandle(handle);
|
||||
let mut token: HANDLE = mem::zeroed();
|
||||
if OpenProcessToken(handle, TOKEN_QUERY, &mut token) == FALSE {
|
||||
bail!("Failed to open process token, errno {}", GetLastError())
|
||||
}
|
||||
let _token = RAIIHandle(token);
|
||||
let mut token_elevation: TOKEN_ELEVATION = mem::zeroed();
|
||||
let mut size: DWORD = 0;
|
||||
if GetTokenInformation(
|
||||
token,
|
||||
TokenElevation,
|
||||
(&mut token_elevation) as *mut _ as *mut c_void,
|
||||
mem::size_of::<TOKEN_ELEVATION>() as _,
|
||||
&mut size,
|
||||
) == FALSE
|
||||
{
|
||||
bail!("Failed to get token information, errno {}", GetLastError())
|
||||
}
|
||||
|
||||
Ok(token_elevation.TokenIsElevated != 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_foreground_window_elevated() -> ResultType<bool> {
|
||||
unsafe {
|
||||
let mut process_id: DWORD = 0;
|
||||
GetWindowThreadProcessId(GetForegroundWindow(), &mut process_id);
|
||||
if process_id == 0 {
|
||||
bail!("Failed to get processId, errno {}", GetLastError())
|
||||
}
|
||||
is_elevated(Some(process_id))
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,9 @@ impl Connection {
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
std::thread::spawn(move || Self::handle_input(rx_input, tx_cloned));
|
||||
let mut second_timer = time::interval(Duration::from_secs(1));
|
||||
let mut last_uac = false;
|
||||
let mut last_foreground_window_elevated = false;
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
@ -400,6 +403,26 @@ impl Connection {
|
||||
break;
|
||||
}
|
||||
},
|
||||
_ = second_timer.tick() => {
|
||||
let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone();
|
||||
if last_uac != uac {
|
||||
last_uac = uac;
|
||||
let mut misc = Misc::new();
|
||||
misc.set_uac(uac);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
conn.inner.send(msg.into());
|
||||
}
|
||||
let foreground_window_elevated = crate::video_service::IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap().clone();
|
||||
if last_foreground_window_elevated != foreground_window_elevated {
|
||||
last_foreground_window_elevated = foreground_window_elevated;
|
||||
let mut misc = Misc::new();
|
||||
misc.set_foreground_window_elevated(foreground_window_elevated);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
conn.inner.send(msg.into());
|
||||
}
|
||||
}
|
||||
_ = test_delay_timer.tick() => {
|
||||
if last_recv_time.elapsed() >= SEC30 {
|
||||
conn.on_close("Timeout", true).await;
|
||||
|
@ -33,6 +33,7 @@ use std::{
|
||||
collections::HashSet,
|
||||
io::ErrorKind::WouldBlock,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::Once,
|
||||
time::{self, Duration, Instant},
|
||||
};
|
||||
#[cfg(windows)]
|
||||
@ -51,6 +52,8 @@ lazy_static::lazy_static! {
|
||||
static ref PRIVACY_MODE_CONN_ID: Mutex<i32> = Mutex::new(0);
|
||||
static ref IS_CAPTURER_MAGNIFIER_SUPPORTED: bool = is_capturer_mag_supported();
|
||||
pub static ref VIDEO_QOS: Arc<Mutex<VideoQoS>> = Default::default();
|
||||
pub static ref IS_UAC_RUNNING: Arc<Mutex<bool>> = Default::default();
|
||||
pub static ref IS_FOREGROUND_WINDOW_ELEVATED: Arc<Mutex<bool>> = Default::default();
|
||||
}
|
||||
|
||||
fn is_capturer_mag_supported() -> bool {
|
||||
@ -451,6 +454,8 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
};
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let recorder: Arc<Mutex<Option<Recorder>>> = Default::default();
|
||||
#[cfg(windows)]
|
||||
start_uac_elevation_check();
|
||||
|
||||
while sp.ok() {
|
||||
#[cfg(windows)]
|
||||
@ -832,3 +837,24 @@ pub(super) fn get_current_display_2(mut all: Vec<Display>) -> ResultType<(usize,
|
||||
fn get_current_display() -> ResultType<(usize, usize, Display)> {
|
||||
get_current_display_2(try_get_displays()?)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn start_uac_elevation_check() {
|
||||
static START: Once = Once::new();
|
||||
START.call_once(|| {
|
||||
if !crate::platform::is_installed()
|
||||
&& !crate::platform::is_root()
|
||||
&& !crate::platform::is_elevated(None).map_or(false, |b| b)
|
||||
{
|
||||
std::thread::spawn(|| loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
if let Ok(uac) = crate::ui::win_privacy::is_process_consent_running() {
|
||||
*IS_UAC_RUNNING.lock().unwrap() = uac;
|
||||
}
|
||||
if let Ok(elevated) = crate::platform::is_foreground_window_elevated() {
|
||||
*IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap() = elevated;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
27
src/ui.rs
27
src/ui.rs
@ -20,22 +20,7 @@ use hbb_common::{
|
||||
|
||||
use crate::common::get_app_name;
|
||||
use crate::ipc;
|
||||
use crate::ui_interface::{
|
||||
check_mouse_time, closing, create_shortcut, current_is_wayland, default_video_save_directory,
|
||||
fix_login_wayland, forget_password, get_api_server, get_async_job_status, get_connect_status,
|
||||
get_error, get_fav, get_icon, get_lan_peers, get_langs, get_license, get_local_option,
|
||||
get_mouse_time, get_new_version, get_option, get_options, get_peer, get_peer_option,
|
||||
get_recent_sessions, get_remote_id, get_size, get_socks, get_software_ext,
|
||||
get_software_store_path, get_software_update_url, get_uuid, get_version, goto_install,
|
||||
has_hwcodec, has_rendezvous_service, install_me, install_path, is_can_screen_recording,
|
||||
is_installed, is_installed_daemon, is_installed_lower_version, is_login_wayland,
|
||||
is_ok_change_id, is_process_trusted, is_rdp_service_open, is_share_rdp, is_xfce,
|
||||
modify_default_login, new_remote, open_url, peer_has_password, permanent_password,
|
||||
post_request, recent_sessions_updated, remove_peer, run_without_install, set_local_option,
|
||||
set_option, set_options, set_peer_option, set_permanent_password, set_remote_id, set_share_rdp,
|
||||
set_socks, show_run_without_install, store_fav, t, temporary_password, test_if_valid_server,
|
||||
update_me, update_temporary_password, using_public_server,
|
||||
};
|
||||
use crate::ui_interface::*;
|
||||
|
||||
mod cm;
|
||||
#[cfg(feature = "inline")]
|
||||
@ -349,6 +334,14 @@ impl UI {
|
||||
is_installed()
|
||||
}
|
||||
|
||||
fn is_root(&self) -> bool {
|
||||
is_root()
|
||||
}
|
||||
|
||||
fn is_release(&self) -> bool {
|
||||
is_release()
|
||||
}
|
||||
|
||||
fn is_rdp_service_open(&self) -> bool {
|
||||
is_rdp_service_open()
|
||||
}
|
||||
@ -615,6 +608,8 @@ impl sciter::EventHandler for UI {
|
||||
fn get_icon();
|
||||
fn install_me(String, String);
|
||||
fn is_installed();
|
||||
fn is_root();
|
||||
fn is_release();
|
||||
fn set_socks(String, String, String);
|
||||
fn get_socks();
|
||||
fn is_rdp_service_open();
|
||||
|
@ -1242,3 +1242,9 @@ function refreshCurrentUser() {
|
||||
function getHttpHeaders() {
|
||||
return "Authorization: Bearer " + handler.get_local_option("access_token");
|
||||
}
|
||||
|
||||
$(body).timer(1000, function check_elevation(){
|
||||
if (is_win && handler.is_release() && !handler.is_installed() && !handler.is_root()) {
|
||||
msgbox("custom-elevation-nocancel", "Prompt", "elevation_prompt");
|
||||
}
|
||||
});
|
@ -755,6 +755,19 @@ pub fn has_hwcodec() -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_release() -> bool {
|
||||
#[cfg(not(debug_assertions))]
|
||||
return true;
|
||||
#[cfg(debug_assertions)]
|
||||
return false;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_root() -> bool {
|
||||
crate::platform::is_root()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn check_super_user_permission() -> bool {
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
|
Loading…
Reference in New Issue
Block a user