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", |  "tiff", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "impersonate_system" | ||||||
|  | version = "0.1.0" | ||||||
|  | source = "git+https://github.com/21pages/impersonate-system#af4a82050580217a434c2024e181a98de24823ec" | ||||||
|  | dependencies = [ | ||||||
|  |  "cc", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "include_dir" | name = "include_dir" | ||||||
| version = "0.7.2" | version = "0.7.2" | ||||||
| @ -2593,6 +2601,15 @@ version = "2.5.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" | 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]] | [[package]] | ||||||
| name = "itertools" | name = "itertools" | ||||||
| version = "0.9.0" | version = "0.9.0" | ||||||
| @ -4329,7 +4346,9 @@ dependencies = [ | |||||||
|  "flutter_rust_bridge_codegen", |  "flutter_rust_bridge_codegen", | ||||||
|  "hbb_common", |  "hbb_common", | ||||||
|  "hound", |  "hound", | ||||||
|  |  "impersonate_system", | ||||||
|  "include_dir", |  "include_dir", | ||||||
|  |  "is_elevated", | ||||||
|  "jni", |  "jni", | ||||||
|  "lazy_static", |  "lazy_static", | ||||||
|  "libc", |  "libc", | ||||||
|  | |||||||
| @ -91,6 +91,8 @@ winapi = { version = "0.3", features = ["winuser"] } | |||||||
| winreg = "0.10" | winreg = "0.10" | ||||||
| windows-service = "0.4" | windows-service = "0.4" | ||||||
| virtual_display = { path = "libs/virtual_display" } | 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] | [target.'cfg(target_os = "macos")'.dependencies] | ||||||
| objc = "0.2" | objc = "0.2" | ||||||
|  | |||||||
| @ -1354,7 +1354,11 @@ impl LoginConfigHandler { | |||||||
|             username: self.id.clone(), |             username: self.id.clone(), | ||||||
|             password: password.into(), |             password: password.into(), | ||||||
|             my_id, |             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(), |             option: self.get_option_message(true).into(), | ||||||
|             session_id: self.session_id, |             session_id: self.session_id, | ||||||
|             version: crate::VERSION.to_string(), |             version: crate::VERSION.to_string(), | ||||||
|  | |||||||
| @ -57,6 +57,12 @@ pub fn core_main() -> Option<Vec<String>> { | |||||||
|                 .ok(); |                 .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() { |     if args.is_empty() { | ||||||
|         std::thread::spawn(move || crate::start_server(false)); |         std::thread::spawn(move || crate::start_server(false)); | ||||||
|     } else { |     } 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 { |     unsafe { | ||||||
|  |         let cstring; | ||||||
|         let ret = ShellExecuteA( |         let ret = ShellExecuteA( | ||||||
|             NULL as _, |             NULL as _, | ||||||
|             CString::new("runas")?.as_ptr() as _, |             CString::new("runas")?.as_ptr() as _, | ||||||
|             CString::new("cmd")?.as_ptr() as _, |             CString::new(exe)?.as_ptr() as _, | ||||||
|             CString::new("/c /q")?.as_ptr() as _, |             if arg.is_empty() { | ||||||
|  |                 NULL as _ | ||||||
|  |             } else { | ||||||
|  |                 cstring = CString::new(arg)?; | ||||||
|  |                 cstring.as_ptr() as _ | ||||||
|  |             }, | ||||||
|             NULL as _, |             NULL as _, | ||||||
|             SW_SHOWNORMAL, |             SW_SHOWNORMAL, | ||||||
|         ); |         ); | ||||||
|         return Ok(ret as i32 > 32); |         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