Merge pull request #2974 from 21pages/fix-elevate
fix elevation && dialog focus
This commit is contained in:
		
						commit
						747e001678
					
				| @ -608,12 +608,11 @@ class CustomAlertDialog extends StatelessWidget { | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     FocusNode focusNode = FocusNode(); | ||||
|     // request focus if there is no focused FocusNode in the dialog | ||||
|     Future.delayed(Duration.zero, () { | ||||
|       if (!focusNode.hasFocus) focusNode.requestFocus(); | ||||
|     }); | ||||
|     // request focus | ||||
|     FocusScopeNode scopeNode = FocusScopeNode(); | ||||
|     Future.delayed(Duration.zero, () { | ||||
|       if (!scopeNode.hasFocus) scopeNode.requestFocus(); | ||||
|     }); | ||||
|     return FocusScope( | ||||
|       node: scopeNode, | ||||
|       autofocus: true, | ||||
|  | ||||
| @ -666,6 +666,8 @@ Future<bool?> verificationCodeDialog(UserPayload? user) async { | ||||
|                 child: const LinearProgressIndicator()), | ||||
|           ], | ||||
|         ), | ||||
|         onCancel: close, | ||||
|         onSubmit: onVerify, | ||||
|         actions: [ | ||||
|           dialogButton("Cancel", onPressed: close, isOutline: true), | ||||
|           dialogButton("Verify", onPressed: onVerify), | ||||
|  | ||||
| @ -653,6 +653,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> { | ||||
|         )); | ||||
|       } | ||||
|       if (pi.platform != kPeerPlatformAndroid && | ||||
|           pi.platform != kPeerPlatformMacOS && // unsupport yet | ||||
|           version_cmp(peer_version, '1.2.0') >= 0) { | ||||
|         displayMenu.add(MenuEntryButton<String>( | ||||
|           childBuilder: (TextStyle? style) => Text( | ||||
|  | ||||
| @ -28,7 +28,7 @@ class ServerModel with ChangeNotifier { | ||||
|   bool _inputOk = false; | ||||
|   bool _audioOk = false; | ||||
|   bool _fileOk = false; | ||||
|   bool _showElevation = true; | ||||
|   bool _showElevation = false; | ||||
|   bool _hideCm = false; | ||||
|   int _connectStatus = 0; // Rendezvous Server status | ||||
|   String _verificationMethod = ""; | ||||
|  | ||||
| @ -54,11 +54,6 @@ pub fn core_main() -> Option<Vec<String>> { | ||||
|         return core_main_invoke_new_connection(std::env::args()); | ||||
|     } | ||||
|     let click_setup = cfg!(windows) && args.is_empty() && crate::common::is_setup(&arg_exe); | ||||
|     #[cfg(not(feature = "flutter"))] | ||||
|     { | ||||
|         _is_quick_support = | ||||
|             cfg!(windows) && args.is_empty() && arg_exe.to_lowercase().ends_with("qs.exe"); | ||||
|     } | ||||
|     if click_setup { | ||||
|         args.push("--install".to_owned()); | ||||
|         flutter_args.push("--install".to_string()); | ||||
| @ -70,6 +65,14 @@ pub fn core_main() -> Option<Vec<String>> { | ||||
|         println!("{}", crate::VERSION); | ||||
|         return None; | ||||
|     } | ||||
|     #[cfg(windows)] | ||||
|     { | ||||
|         _is_quick_support |= !crate::platform::is_installed() | ||||
|             && args.is_empty() | ||||
|             && (arg_exe.to_lowercase().ends_with("qs.exe") | ||||
|                 || (!click_setup && crate::platform::is_elevated(None).unwrap_or(false))); | ||||
|         crate::portable_service::client::set_quick_support(_is_quick_support); | ||||
|     } | ||||
|     #[cfg(debug_assertions)] | ||||
|     { | ||||
|         use hbb_common::env_logger::*; | ||||
|  | ||||
| @ -3,6 +3,8 @@ use super::{input_service::*, *}; | ||||
| use crate::clipboard_file::*; | ||||
| #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||
| use crate::common::update_clipboard; | ||||
| #[cfg(windows)] | ||||
| use crate::portable_service::client as portable_client; | ||||
| use crate::video_service; | ||||
| #[cfg(any(target_os = "android", target_os = "ios"))] | ||||
| use crate::{common::DEVICE_NAME, flutter::connection_manager::start_channel}; | ||||
| @ -101,8 +103,8 @@ pub struct Connection { | ||||
|     lr: LoginRequest, | ||||
|     last_recv_time: Arc<Mutex<Instant>>, | ||||
|     chat_unanswered: bool, | ||||
|     #[allow(unused)] | ||||
|     elevation_requested: bool, | ||||
|     #[cfg(windows)] | ||||
|     portable: PortableState, | ||||
|     from_switch: bool, | ||||
| } | ||||
| 
 | ||||
| @ -199,7 +201,8 @@ impl Connection { | ||||
|             lr: Default::default(), | ||||
|             last_recv_time: Arc::new(Mutex::new(Instant::now())), | ||||
|             chat_unanswered: false, | ||||
|             elevation_requested: false, | ||||
|             #[cfg(windows)] | ||||
|             portable: Default::default(), | ||||
|             from_switch: false, | ||||
|         }; | ||||
|         #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||
| @ -247,14 +250,6 @@ 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)); | ||||
|         #[cfg(windows)] | ||||
|         let mut last_uac = false; | ||||
|         #[cfg(windows)] | ||||
|         let mut last_foreground_window_elevated = false; | ||||
|         #[cfg(windows)] | ||||
|         let mut last_portable_service_running = false; | ||||
|         #[cfg(windows)] | ||||
|         let is_installed = crate::platform::is_installed(); | ||||
| 
 | ||||
|         loop { | ||||
|             tokio::select! { | ||||
| @ -362,8 +357,7 @@ impl Connection { | ||||
|                         } | ||||
|                         #[cfg(windows)] | ||||
|                         ipc::Data::DataPortableService(ipc::DataPortableService::RequestStart) => { | ||||
|                             use crate::portable_service::client; | ||||
|                             if let Err(e) = client::start_portable_service(client::StartPara::Direct) { | ||||
|                             if let Err(e) = portable_client::start_portable_service(portable_client::StartPara::Direct) { | ||||
|                                 log::error!("Failed to start portable service from cm:{:?}", e); | ||||
|                             } | ||||
|                         } | ||||
| @ -458,46 +452,7 @@ impl Connection { | ||||
|                 }, | ||||
|                 _ = second_timer.tick() => { | ||||
|                     #[cfg(windows)] | ||||
|                     { | ||||
|                         if !is_installed  && conn.file_transfer.is_none() && conn.port_forward_socket.is_none(){ | ||||
|                             let portable_service_running = crate::portable_service::client::running(); | ||||
|                             if portable_service_running != last_portable_service_running { | ||||
|                                 last_portable_service_running = portable_service_running; | ||||
|                                 if portable_service_running && conn.elevation_requested { | ||||
|                                     let mut misc = Misc::new(); | ||||
|                                     misc.set_portable_service_running(portable_service_running); | ||||
|                                     let mut msg = Message::new(); | ||||
|                                     msg.set_misc(misc); | ||||
|                                     conn.inner.send(msg.into()); | ||||
|                                 } | ||||
|                             } | ||||
|                             let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone(); | ||||
|                             if last_uac != uac { | ||||
|                                 last_uac = uac; | ||||
|                                 if !uac || !portable_service_running{ | ||||
|                                     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; | ||||
|                                 if !foreground_window_elevated || !portable_service_running { | ||||
|                                     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()); | ||||
|                                 } | ||||
|                             } | ||||
|                             let show_elevation = !portable_service_running; | ||||
|                             conn.send_to_cm(ipc::Data::DataPortableService(ipc::DataPortableService::CmShowElevation(show_elevation))); | ||||
| 
 | ||||
|                         } | ||||
|                     } | ||||
|                     conn.portable_check(); | ||||
|                 } | ||||
|                 _ = test_delay_timer.tick() => { | ||||
|                     if last_recv_time.elapsed() >= SEC30 { | ||||
| @ -1537,15 +1492,14 @@ impl Connection { | ||||
|                             #[cfg(windows)] | ||||
|                             { | ||||
|                                 let mut err = "No need to elevate".to_string(); | ||||
|                                 if !crate::platform::is_installed() | ||||
|                                     && !crate::portable_service::client::running() | ||||
|                                 { | ||||
|                                     use crate::portable_service::client; | ||||
|                                     err = client::start_portable_service(client::StartPara::Direct) | ||||
|                                         .err() | ||||
|                                         .map_or("".to_string(), |e| e.to_string()); | ||||
|                                 if !crate::platform::is_installed() && !portable_client::running() { | ||||
|                                     err = portable_client::start_portable_service( | ||||
|                                         portable_client::StartPara::Direct, | ||||
|                                     ) | ||||
|                                     .err() | ||||
|                                     .map_or("".to_string(), |e| e.to_string()); | ||||
|                                 } | ||||
|                                 self.elevation_requested = err.is_empty(); | ||||
|                                 self.portable.elevation_requested = err.is_empty(); | ||||
|                                 let mut misc = Misc::new(); | ||||
|                                 misc.set_elevation_response(err); | ||||
|                                 let mut msg = Message::new(); | ||||
| @ -1557,18 +1511,14 @@ impl Connection { | ||||
|                             #[cfg(windows)] | ||||
|                             { | ||||
|                                 let mut err = "No need to elevate".to_string(); | ||||
|                                 if !crate::platform::is_installed() | ||||
|                                     && !crate::portable_service::client::running() | ||||
|                                 { | ||||
|                                     use crate::portable_service::client; | ||||
|                                     err = client::start_portable_service(client::StartPara::Logon( | ||||
|                                         _r.username, | ||||
|                                         _r.password, | ||||
|                                     )) | ||||
|                                 if !crate::platform::is_installed() && !portable_client::running() { | ||||
|                                     err = portable_client::start_portable_service( | ||||
|                                         portable_client::StartPara::Logon(_r.username, _r.password), | ||||
|                                     ) | ||||
|                                     .err() | ||||
|                                     .map_or("".to_string(), |e| e.to_string()); | ||||
|                                 } | ||||
|                                 self.elevation_requested = err.is_empty(); | ||||
|                                 self.portable.elevation_requested = err.is_empty(); | ||||
|                                 let mut misc = Misc::new(); | ||||
|                                 misc.set_elevation_response(err); | ||||
|                                 let mut msg = Message::new(); | ||||
| @ -1810,6 +1760,59 @@ impl Connection { | ||||
|     pub fn alive_conns() -> Vec<i32> { | ||||
|         ALIVE_CONNS.lock().unwrap().clone() | ||||
|     } | ||||
| 
 | ||||
|     #[cfg(windows)] | ||||
|     fn portable_check(&mut self) { | ||||
|         if self.portable.is_installed | ||||
|             || self.file_transfer.is_some() | ||||
|             || self.port_forward_socket.is_some() | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|         let running = portable_client::running(); | ||||
|         let show_elevation = !running; | ||||
|         self.send_to_cm(ipc::Data::DataPortableService( | ||||
|             ipc::DataPortableService::CmShowElevation(show_elevation), | ||||
|         )); | ||||
|         if self.authorized { | ||||
|             let p = &mut self.portable; | ||||
|             if running != p.last_running { | ||||
|                 p.last_running = running; | ||||
|                 if running && p.elevation_requested { | ||||
|                     let mut misc = Misc::new(); | ||||
|                     misc.set_portable_service_running(running); | ||||
|                     let mut msg = Message::new(); | ||||
|                     msg.set_misc(misc); | ||||
|                     self.inner.send(msg.into()); | ||||
|                 } | ||||
|             } | ||||
|             let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone(); | ||||
|             if p.last_uac != uac { | ||||
|                 p.last_uac = uac; | ||||
|                 if !uac || !running { | ||||
|                     let mut misc = Misc::new(); | ||||
|                     misc.set_uac(uac); | ||||
|                     let mut msg = Message::new(); | ||||
|                     msg.set_misc(misc); | ||||
|                     self.inner.send(msg.into()); | ||||
|                 } | ||||
|             } | ||||
|             let foreground_window_elevated = crate::video_service::IS_FOREGROUND_WINDOW_ELEVATED | ||||
|                 .lock() | ||||
|                 .unwrap() | ||||
|                 .clone(); | ||||
|             if p.last_foreground_window_elevated != foreground_window_elevated { | ||||
|                 p.last_foreground_window_elevated = foreground_window_elevated; | ||||
|                 if !foreground_window_elevated || !running { | ||||
|                     let mut misc = Misc::new(); | ||||
|                     misc.set_foreground_window_elevated(foreground_window_elevated); | ||||
|                     let mut msg = Message::new(); | ||||
|                     msg.set_misc(misc); | ||||
|                     self.inner.send(msg.into()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn insert_switch_sides_uuid(id: String, uuid: uuid::Uuid) { | ||||
| @ -1984,3 +1987,25 @@ pub enum FileAuditType { | ||||
|     RemoteSend = 0, | ||||
|     RemoteReceive = 1, | ||||
| } | ||||
| 
 | ||||
| #[cfg(windows)] | ||||
| pub struct PortableState { | ||||
|     pub last_uac: bool, | ||||
|     pub last_foreground_window_elevated: bool, | ||||
|     pub last_running: bool, | ||||
|     pub is_installed: bool, | ||||
|     pub elevation_requested: bool, | ||||
| } | ||||
| 
 | ||||
| #[cfg(windows)] | ||||
| impl Default for PortableState { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             is_installed: crate::platform::is_installed(), | ||||
|             last_uac: Default::default(), | ||||
|             last_foreground_window_elevated: Default::default(), | ||||
|             last_running: Default::default(), | ||||
|             elevation_requested: Default::default(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -459,6 +459,7 @@ pub mod client { | ||||
|         static ref RUNNING: Arc<Mutex<bool>> = Default::default(); | ||||
|         static ref SHMEM: Arc<Mutex<Option<SharedMemory>>> = Default::default(); | ||||
|         static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(client::start_ipc_server()); | ||||
|         static ref QUICK_SUPPORT: Arc<Mutex<bool>> = Default::default(); | ||||
|     } | ||||
| 
 | ||||
|     pub enum StartPara { | ||||
| @ -561,6 +562,10 @@ pub mod client { | ||||
|         *SHMEM.lock().unwrap() = None; | ||||
|     } | ||||
| 
 | ||||
|     pub fn set_quick_support(v: bool) { | ||||
|         *QUICK_SUPPORT.lock().unwrap() = v; | ||||
|     } | ||||
| 
 | ||||
|     fn set_dir_permission(dir: &PathBuf) -> bool { | ||||
|         // // give Everyone RX permission
 | ||||
|         std::process::Command::new("icacls") | ||||
| @ -685,17 +690,7 @@ pub mod client { | ||||
|         use DataPortableService::*; | ||||
|         let rx = Arc::new(tokio::sync::Mutex::new(rx)); | ||||
|         let postfix = IPC_SUFFIX; | ||||
|         #[cfg(feature = "flutter")] | ||||
|         let quick_support = { | ||||
|             let args: Vec<_> = std::env::args().collect(); | ||||
|             args.contains(&"--quick_support".to_string()) | ||||
|         }; | ||||
|         #[cfg(not(feature = "flutter"))] | ||||
|         let quick_support = std::env::current_exe() | ||||
|             .unwrap_or("".into()) | ||||
|             .to_string_lossy() | ||||
|             .to_lowercase() | ||||
|             .ends_with("qs.exe"); | ||||
|         let quick_support = QUICK_SUPPORT.lock().unwrap().clone(); | ||||
| 
 | ||||
|         match new_listener(postfix).await { | ||||
|             Ok(mut incoming) => loop { | ||||
|  | ||||
| @ -956,15 +956,17 @@ fn start_uac_elevation_check() { | ||||
|     START.call_once(|| { | ||||
|         if !crate::platform::is_installed() | ||||
|             && !crate::platform::is_root() | ||||
|             && !crate::platform::is_elevated(None).map_or(false, |b| b) | ||||
|             && !crate::portable_service::client::running() | ||||
|         { | ||||
|             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; | ||||
|                 if !crate::platform::is_elevated(None).unwrap_or(false) { | ||||
|                     if let Ok(elevated) = crate::platform::is_foreground_window_elevated() { | ||||
|                         *IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap() = elevated; | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
| @ -789,9 +789,7 @@ fn cm_inner_send(id: i32, data: Data) { | ||||
| 
 | ||||
| pub fn can_elevate() -> bool { | ||||
|     #[cfg(windows)] | ||||
|     { | ||||
|         return !crate::platform::is_installed() && !crate::portable_service::client::running(); | ||||
|     } | ||||
|     return !crate::platform::is_installed(); | ||||
|     #[cfg(not(windows))] | ||||
|     return false; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user