windows portable: request elevation && run as system
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
		
							parent
							
								
									77276dd78e
								
							
						
					
					
						commit
						e1c2b8de6e
					
				
							
								
								
									
										19
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								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" | ||||
| @ -2593,6 +2601,15 @@ version = "2.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "is_elevated" | ||||
| version = "0.1.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5299060ff5db63e788015dcb9525ad9b84f4fd9717ed2cbdeba5018cbf42f9b5" | ||||
| dependencies = [ | ||||
|  "winapi 0.3.9", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "itertools" | ||||
| version = "0.9.0" | ||||
| @ -4329,7 +4346,9 @@ dependencies = [ | ||||
|  "flutter_rust_bridge_codegen", | ||||
|  "hbb_common", | ||||
|  "hound", | ||||
|  "impersonate_system", | ||||
|  "include_dir", | ||||
|  "is_elevated", | ||||
|  "jni", | ||||
|  "lazy_static", | ||||
|  "libc", | ||||
|  | ||||
| @ -91,6 +91,8 @@ winapi = { version = "0.3", features = ["winuser"] } | ||||
| winreg = "0.10" | ||||
| windows-service = "0.4" | ||||
| virtual_display = { path = "libs/virtual_display" } | ||||
| is_elevated = "0.1.2" | ||||
| impersonate_system = { git = "https://github.com/21pages/impersonate-system" } | ||||
| 
 | ||||
| [target.'cfg(target_os = "macos")'.dependencies] | ||||
| objc = "0.2" | ||||
|  | ||||
| @ -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(), | ||||
|  | ||||
| @ -57,6 +57,12 @@ pub fn core_main() -> Option<Vec<String>> { | ||||
|                 .ok(); | ||||
|         } | ||||
|     } | ||||
|     #[cfg(windows)] | ||||
|     #[cfg(not(debug_assertions))] | ||||
|     if !crate::platform::is_installed() && args.is_empty() { | ||||
|         let arg = if is_setup { "--noinstall" } else { "" }; | ||||
|         crate::platform::run_check_elevation(arg); | ||||
|     } | ||||
|     if args.is_empty() { | ||||
|         std::thread::spawn(move || crate::start_server(false)); | ||||
|     } else { | ||||
|  | ||||
| @ -1420,16 +1420,63 @@ 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 run_check_elevation(arg: &str) { | ||||
|     if !is_elevated::is_elevated() { | ||||
|         if let Ok(true) = elevate(arg) { | ||||
|             std::process::exit(0); | ||||
|         } else { | ||||
|             // do nothing but prompt
 | ||||
|         } | ||||
|     } else { | ||||
|         if !is_root() { | ||||
|             if run_as_system(arg).is_ok() { | ||||
|                 std::process::exit(0); | ||||
|             } else { | ||||
|                 // to-do: should not happen
 | ||||
|                 log::error!("Failed to run as system"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user