mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
@@ -101,6 +101,7 @@ pub struct Connection {
|
||||
last_recv_time: Arc<Mutex<Instant>>,
|
||||
chat_unanswered: bool,
|
||||
close_manually: bool,
|
||||
elevation_requested: bool,
|
||||
}
|
||||
|
||||
impl Subscriber for ConnInner {
|
||||
@@ -196,6 +197,7 @@ impl Connection {
|
||||
last_recv_time: Arc::new(Mutex::new(Instant::now())),
|
||||
chat_unanswered: false,
|
||||
close_manually: false,
|
||||
elevation_requested: false,
|
||||
};
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
tokio::spawn(async move {
|
||||
@@ -247,6 +249,8 @@ impl Connection {
|
||||
#[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 {
|
||||
@@ -353,7 +357,8 @@ impl Connection {
|
||||
}
|
||||
#[cfg(windows)]
|
||||
ipc::Data::DataPortableService(ipc::DataPortableService::RequestStart) => {
|
||||
if let Err(e) = crate::portable_service::client::start_portable_service() {
|
||||
use crate::portable_service::client;
|
||||
if let Err(e) = client::start_portable_service(client::StartPara::Direct) {
|
||||
log::error!("Failed to start portable service from cm:{:?}", e);
|
||||
}
|
||||
}
|
||||
@@ -440,8 +445,18 @@ impl Connection {
|
||||
_ = second_timer.tick() => {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if !is_installed {
|
||||
let portable_service_running = crate::portable_service::client::PORTABLE_SERVICE_RUNNING.lock().unwrap().clone();
|
||||
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;
|
||||
@@ -1476,6 +1491,51 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(misc::Union::ElevationRequest(r)) => match r.union {
|
||||
Some(elevation_request::Union::Direct(_)) => {
|
||||
#[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());
|
||||
}
|
||||
self.elevation_requested = err.is_empty();
|
||||
let mut misc = Misc::new();
|
||||
misc.set_elevation_response(err);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
self.send(msg).await;
|
||||
}
|
||||
}
|
||||
Some(elevation_request::Union::Logon(r)) => {
|
||||
#[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,
|
||||
))
|
||||
.err()
|
||||
.map_or("".to_string(), |e| e.to_string());
|
||||
}
|
||||
self.elevation_requested = err.is_empty();
|
||||
let mut misc = Misc::new();
|
||||
misc.set_elevation_response(err);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
self.send(msg).await;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
||||
@@ -451,18 +451,24 @@ pub mod server {
|
||||
// functions called in main process.
|
||||
pub mod client {
|
||||
use hbb_common::anyhow::Context;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::*;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref PORTABLE_SERVICE_RUNNING: Arc<Mutex<bool>> = Default::default();
|
||||
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());
|
||||
}
|
||||
|
||||
pub(crate) fn start_portable_service() -> ResultType<()> {
|
||||
pub enum StartPara {
|
||||
Direct,
|
||||
Logon(String, String),
|
||||
}
|
||||
|
||||
pub(crate) fn start_portable_service(para: StartPara) -> ResultType<()> {
|
||||
log::info!("start portable service");
|
||||
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
if RUNNING.lock().unwrap().clone() {
|
||||
bail!("already running");
|
||||
}
|
||||
if SHMEM.lock().unwrap().is_none() {
|
||||
@@ -491,14 +497,60 @@ pub mod client {
|
||||
unsafe {
|
||||
libc::memset(shmem.as_ptr() as _, 0, shmem.len() as _);
|
||||
}
|
||||
if crate::platform::run_background(
|
||||
&std::env::current_exe()?.to_string_lossy().to_string(),
|
||||
"--portable-service",
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
bail!("Failed to run portable service process");
|
||||
drop(option);
|
||||
match para {
|
||||
StartPara::Direct => {
|
||||
if let Err(e) = crate::platform::run_background(
|
||||
&std::env::current_exe()?.to_string_lossy().to_string(),
|
||||
"--portable-service",
|
||||
) {
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
bail!("Failed to run portable service process:{}", e);
|
||||
}
|
||||
}
|
||||
StartPara::Logon(username, password) => {
|
||||
#[allow(unused_mut)]
|
||||
let mut exe = std::env::current_exe()?.to_string_lossy().to_string();
|
||||
#[cfg(feature = "flutter")]
|
||||
{
|
||||
if let Some(dir) = PathBuf::from(&exe).parent() {
|
||||
if !set_dir_permission(&PathBuf::from(dir)) {
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
bail!("Failed to set permission of {:?}", dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "flutter"))]
|
||||
match hbb_common::directories_next::UserDirs::new() {
|
||||
Some(user_dir) => {
|
||||
let dir = user_dir
|
||||
.home_dir()
|
||||
.join("AppData")
|
||||
.join("Local")
|
||||
.join("rustdesk-sciter");
|
||||
if std::fs::create_dir_all(&dir).is_ok() {
|
||||
let dst = dir.join("rustdesk.exe");
|
||||
if std::fs::copy(&exe, &dst).is_ok() {
|
||||
if dst.exists() {
|
||||
if set_dir_permission(&dir) {
|
||||
exe = dst.to_string_lossy().to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
if let Err(e) = crate::platform::windows::create_process_with_logon(
|
||||
username.as_str(),
|
||||
password.as_str(),
|
||||
&exe,
|
||||
"--portable-service",
|
||||
) {
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
bail!("Failed to run portable service process:{}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
let _sender = SENDER.lock().unwrap();
|
||||
Ok(())
|
||||
@@ -509,6 +561,16 @@ pub mod client {
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
}
|
||||
|
||||
fn set_dir_permission(dir: &PathBuf) -> bool {
|
||||
// // give Everyone RX permission
|
||||
std::process::Command::new("icacls")
|
||||
.arg(dir.as_os_str())
|
||||
.arg("/grant")
|
||||
.arg("Everyone:(OI)(CI)RX")
|
||||
.arg("/T")
|
||||
.spawn()
|
||||
.is_ok()
|
||||
}
|
||||
pub struct CapturerPortable;
|
||||
|
||||
impl CapturerPortable {
|
||||
@@ -668,7 +730,7 @@ pub mod client {
|
||||
}
|
||||
Pong => {
|
||||
nack = 0;
|
||||
*PORTABLE_SERVICE_RUNNING.lock().unwrap() = true;
|
||||
*RUNNING.lock().unwrap() = true;
|
||||
},
|
||||
ConnCount(None) => {
|
||||
if !quick_support {
|
||||
@@ -699,7 +761,7 @@ pub mod client {
|
||||
}
|
||||
}
|
||||
}
|
||||
*PORTABLE_SERVICE_RUNNING.lock().unwrap() = false;
|
||||
*RUNNING.lock().unwrap() = false;
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -752,7 +814,7 @@ pub mod client {
|
||||
use_yuv: bool,
|
||||
portable_service_running: bool,
|
||||
) -> ResultType<Box<dyn TraitCapturer>> {
|
||||
if portable_service_running != PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
if portable_service_running != RUNNING.lock().unwrap().clone() {
|
||||
log::info!("portable service status mismatch");
|
||||
}
|
||||
if portable_service_running {
|
||||
@@ -767,7 +829,7 @@ pub mod client {
|
||||
}
|
||||
|
||||
pub fn get_cursor_info(pci: PCURSORINFO) -> BOOL {
|
||||
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
if RUNNING.lock().unwrap().clone() {
|
||||
get_cursor_info_(&mut SHMEM.lock().unwrap().as_mut().unwrap(), pci)
|
||||
} else {
|
||||
unsafe { winuser::GetCursorInfo(pci) }
|
||||
@@ -775,7 +837,7 @@ pub mod client {
|
||||
}
|
||||
|
||||
pub fn handle_mouse(evt: &MouseEvent) {
|
||||
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
if RUNNING.lock().unwrap().clone() {
|
||||
handle_mouse_(evt).ok();
|
||||
} else {
|
||||
crate::input_service::handle_mouse_(evt);
|
||||
@@ -783,12 +845,16 @@ pub mod client {
|
||||
}
|
||||
|
||||
pub fn handle_key(evt: &KeyEvent) {
|
||||
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
if RUNNING.lock().unwrap().clone() {
|
||||
handle_key_(evt).ok();
|
||||
} else {
|
||||
crate::input_service::handle_key_(evt);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn running() -> bool {
|
||||
RUNNING.lock().unwrap().clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
@@ -20,14 +20,10 @@
|
||||
|
||||
use super::{video_qos::VideoQoS, *};
|
||||
#[cfg(windows)]
|
||||
use crate::portable_service::client::PORTABLE_SERVICE_RUNNING;
|
||||
#[cfg(windows)]
|
||||
use hbb_common::get_version_number;
|
||||
use hbb_common::{
|
||||
tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
},
|
||||
use hbb_common::tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
use scrap::Capturer;
|
||||
@@ -419,7 +415,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
#[cfg(target_os = "linux")]
|
||||
super::wayland::ensure_inited()?;
|
||||
#[cfg(windows)]
|
||||
let last_portable_service_running = PORTABLE_SERVICE_RUNNING.lock().unwrap().clone();
|
||||
let last_portable_service_running = crate::portable_service::client::running();
|
||||
#[cfg(not(windows))]
|
||||
let last_portable_service_running = false;
|
||||
|
||||
@@ -518,14 +514,14 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
bail!("SWITCH");
|
||||
}
|
||||
#[cfg(windows)]
|
||||
if last_portable_service_running != PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
if last_portable_service_running != crate::portable_service::client::running() {
|
||||
bail!("SWITCH");
|
||||
}
|
||||
check_privacy_mode_changed(&sp, c.privacy_mode_id)?;
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if crate::platform::windows::desktop_changed()
|
||||
&& !PORTABLE_SERVICE_RUNNING.lock().unwrap().clone()
|
||||
&& !crate::portable_service::client::running()
|
||||
{
|
||||
bail!("Desktop changed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user