run_uac with wchar, refactor elevate_or_run_as_system
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
627ccd4c01
commit
a2f1ab80da
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2559,7 +2559,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "impersonate_system"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/21pages/impersonate-system#c48f37a8fd17413b2a4ba655c3873bdc5c8d25aa"
|
||||
source = "git+https://github.com/21pages/impersonate-system#84b401893d5b6628c8b33b295328d13fbbe2674b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
@ -9,7 +9,7 @@ use hbb_common::{
|
||||
};
|
||||
use std::io::prelude::*;
|
||||
use std::{
|
||||
ffi::{CString, OsString},
|
||||
ffi::OsString,
|
||||
fs, io, mem,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
@ -27,7 +27,7 @@ use winapi::{
|
||||
OpenProcessToken,
|
||||
},
|
||||
securitybaseapi::GetTokenInformation,
|
||||
shellapi::ShellExecuteA,
|
||||
shellapi::ShellExecuteW,
|
||||
winbase::*,
|
||||
wingdi::*,
|
||||
winnt::{
|
||||
@ -1481,17 +1481,19 @@ pub fn get_user_token(session_id: u32, as_user: bool) -> HANDLE {
|
||||
}
|
||||
|
||||
pub fn run_uac(exe: &str, arg: &str) -> ResultType<bool> {
|
||||
let wop = wide_string("runas");
|
||||
let wexe = wide_string(exe);
|
||||
let warg;
|
||||
unsafe {
|
||||
let cstring;
|
||||
let ret = ShellExecuteA(
|
||||
let ret = ShellExecuteW(
|
||||
NULL as _,
|
||||
CString::new("runas")?.as_ptr() as _,
|
||||
CString::new(exe)?.as_ptr() as _,
|
||||
wop.as_ptr() as _,
|
||||
wexe.as_ptr() as _,
|
||||
if arg.is_empty() {
|
||||
NULL as _
|
||||
} else {
|
||||
cstring = CString::new(arg)?;
|
||||
cstring.as_ptr() as _
|
||||
warg = wide_string(arg);
|
||||
warg.as_ptr() as _
|
||||
},
|
||||
NULL as _,
|
||||
SW_SHOWNORMAL,
|
||||
@ -1529,7 +1531,7 @@ pub fn run_as_system(arg: &str) -> ResultType<()> {
|
||||
}
|
||||
|
||||
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.
|
||||
// avoid possible run recursively due to failed run.
|
||||
let arg_elevate = if is_setup {
|
||||
"--noinstall --elevate"
|
||||
} else {
|
||||
@ -1540,39 +1542,39 @@ pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_syst
|
||||
} else {
|
||||
"--run-as-system"
|
||||
};
|
||||
let rerun_as_system = || {
|
||||
if !is_root() {
|
||||
|
||||
if is_root() {
|
||||
log::debug!("portable run as system user");
|
||||
} else {
|
||||
match is_elevated(None) {
|
||||
Ok(elevated) => {
|
||||
if elevated {
|
||||
if !is_run_as_system {
|
||||
if run_as_system(arg_run_as_system).is_ok() {
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
log::error!("Failed to run as system");
|
||||
unsafe {
|
||||
log::error!("Failed to run as system, errno={}", GetLastError());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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 !is_elevate {
|
||||
if let Ok(true) = elevate(arg_elevate) {
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
// do nothing but prompt
|
||||
unsafe {
|
||||
log::error!("Failed to elevate, errno={}", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => unsafe {
|
||||
log::error!("Failed to get elevation status, errno={}", GetLastError());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/mgostIH/process_list/blob/master/src/windows/mod.rs
|
||||
@ -1636,3 +1638,11 @@ fn get_current_pid() -> u32 {
|
||||
pub fn get_double_click_time() -> u32 {
|
||||
unsafe { GetDoubleClickTime() }
|
||||
}
|
||||
|
||||
fn wide_string(s: &str) -> Vec<u16> {
|
||||
use std::os::windows::prelude::OsStrExt;
|
||||
std::ffi::OsStr::new(s)
|
||||
.encode_wide()
|
||||
.chain(Some(0).into_iter())
|
||||
.collect()
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ pub fn start_tray(options: Arc<Mutex<HashMap<String, String>>>) {
|
||||
.build()
|
||||
.unwrap();
|
||||
let old_state = Arc::new(Mutex::new(0));
|
||||
let _ = crate::ui_interface::SENDER.lock().unwrap();
|
||||
let _sender = crate::ui_interface::SENDER.lock().unwrap();
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
if options.lock().unwrap().get("ipc-closed").is_some() {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
|
Loading…
x
Reference in New Issue
Block a user