Merge pull request #2974 from 21pages/fix-elevate

fix elevation && dialog focus
This commit is contained in:
RustDesk 2023-01-28 17:56:03 +08:00 committed by GitHub
commit 747e001678
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 123 additions and 98 deletions

View File

@ -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,

View File

@ -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),

View File

@ -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(

View File

@ -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 = "";

View File

@ -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::*;

View File

@ -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(),
}
}
}

View File

@ -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 {

View File

@ -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;
}
}
});
}

View File

@ -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;
}