tmp commit
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
8b35eade0a
commit
06a52e1b54
@ -31,6 +31,7 @@ default = ["use_dasp"]
|
||||
hwcodec = ["scrap/hwcodec"]
|
||||
mediacodec = ["scrap/mediacodec"]
|
||||
linux_headless = ["pam", "users"]
|
||||
virtual_display_driver = ["virtual_display"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -94,7 +95,7 @@ winit = "0.26"
|
||||
winapi = { version = "0.3", features = ["winuser", "wincrypt"] }
|
||||
winreg = "0.10"
|
||||
windows-service = "0.4"
|
||||
virtual_display = { path = "libs/virtual_display" }
|
||||
virtual_display = { path = "libs/virtual_display", optional = true }
|
||||
impersonate_system = { git = "https://github.com/21pages/impersonate-system" }
|
||||
shared_memory = "0.12"
|
||||
shutdown_hooks = "0.1"
|
||||
|
@ -66,5 +66,6 @@ pub mod clipboard_file;
|
||||
|
||||
#[cfg(all(windows, feature = "with_rc"))]
|
||||
pub mod rc;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub mod win_privacy;
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub mod privacy_mode;
|
||||
|
@ -1,7 +1,8 @@
|
||||
use super::{CursorData, ResultType};
|
||||
use crate::common::PORTABLE_APPNAME_RUNTIME_ENV_KEY;
|
||||
use crate::ipc;
|
||||
use crate::license::*;
|
||||
#[cfg(feature = "privacy_win_mag")]
|
||||
use crate::privacy_mode::privacy_win_mag;
|
||||
use crate::{ipc, license::*, privacy_mode::WIN_MAG_INJECTED_PROCESS_EXE};
|
||||
use hbb_common::{
|
||||
allow_err, bail,
|
||||
config::{self, Config},
|
||||
@ -9,10 +10,12 @@ use hbb_common::{
|
||||
message_proto::Resolution,
|
||||
sleep, timeout, tokio,
|
||||
};
|
||||
#[cfg(feature = "privacy_win_mag")]
|
||||
use std::fs;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::OsString,
|
||||
fs, io,
|
||||
io,
|
||||
io::prelude::*,
|
||||
mem,
|
||||
os::windows::process::CommandExt,
|
||||
@ -836,10 +839,11 @@ fn get_default_install_path() -> String {
|
||||
format!("{}\\{}", pf, crate::get_app_name())
|
||||
}
|
||||
|
||||
#[cfg(feature = "privacy_win_mag")]
|
||||
pub fn check_update_broker_process() -> ResultType<()> {
|
||||
// let (_, path, _, _) = get_install_info();
|
||||
let process_exe = crate::win_privacy::INJECTED_PROCESS_EXE;
|
||||
let origin_process_exe = crate::win_privacy::ORIGIN_PROCESS_EXE;
|
||||
let process_exe = privacy_win_mag::INJECTED_PROCESS_EXE;
|
||||
let origin_process_exe = privacy_win_mag::ORIGIN_PROCESS_EXE;
|
||||
|
||||
let exe_file = std::env::current_exe()?;
|
||||
if exe_file.parent().is_none() {
|
||||
@ -922,17 +926,31 @@ pub fn copy_raw_cmd(src_raw: &str, _raw: &str, _path: &str) -> String {
|
||||
pub fn copy_exe_cmd(src_exe: &str, exe: &str, path: &str) -> String {
|
||||
let main_exe = copy_raw_cmd(src_exe, exe, path);
|
||||
|
||||
return format!(
|
||||
"
|
||||
{main_exe}
|
||||
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
",
|
||||
main_exe = main_exe,
|
||||
path = path,
|
||||
ORIGIN_PROCESS_EXE = crate::win_privacy::ORIGIN_PROCESS_EXE,
|
||||
broker_exe = crate::win_privacy::INJECTED_PROCESS_EXE,
|
||||
);
|
||||
#[cfg(feature = "privacy_win_mag")]
|
||||
{
|
||||
format!(
|
||||
"
|
||||
{main_exe}
|
||||
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
",
|
||||
main_exe = main_exe,
|
||||
path = path,
|
||||
ORIGIN_PROCESS_EXE = privacy_win_mag::ORIGIN_PROCESS_EXE,
|
||||
broker_exe = privacy_win_mag::INJECTED_PROCESS_EXE,
|
||||
)
|
||||
}
|
||||
#[cfg(not(feature = "privacy_win_mag"))]
|
||||
{
|
||||
format!(
|
||||
"
|
||||
{main_exe}
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
",
|
||||
main_exe = main_exe,
|
||||
path = path,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_me() -> ResultType<()> {
|
||||
@ -963,7 +981,7 @@ pub fn update_me() -> ResultType<()> {
|
||||
",
|
||||
copy_exe = copy_exe_cmd(&src_exe, &exe, &path),
|
||||
copy_dll = copy_dll,
|
||||
broker_exe = crate::win_privacy::INJECTED_PROCESS_EXE,
|
||||
broker_exe = WIN_MAG_INJECTED_PROCESS_EXE,
|
||||
app_name = crate::get_app_name(),
|
||||
lic = register_licence(),
|
||||
cur_pid = get_current_pid(),
|
||||
@ -1257,7 +1275,7 @@ fn get_before_uninstall(kill_self: bool) -> String {
|
||||
netsh advfirewall firewall delete rule name=\"{app_name} Service\"
|
||||
",
|
||||
app_name = app_name,
|
||||
broker_exe = crate::win_privacy::INJECTED_PROCESS_EXE,
|
||||
broker_exe = WIN_MAG_INJECTED_PROCESS_EXE,
|
||||
ext = ext,
|
||||
filter = filter,
|
||||
)
|
||||
@ -2180,6 +2198,14 @@ pub fn get_unicode_from_vk(vk: u32) -> Option<u16> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_process_consent_running() -> ResultType<bool> {
|
||||
let output = std::process::Command::new("cmd")
|
||||
.args(&["/C", "tasklist | findstr consent.exe"])
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.output()?;
|
||||
Ok(output.status.success() && !output.stdout.is_empty())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
43
src/privacy_mode/mod.rs
Normal file
43
src/privacy_mode/mod.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::ipc::PrivacyModeState;
|
||||
use hbb_common::{bail, ResultType};
|
||||
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
pub mod privacy_win_mag;
|
||||
pub const WIN_MAG_INJECTED_PROCESS_EXE: &'static str = "RuntimeBroker_rustdesk.exe";
|
||||
|
||||
pub const OCCUPIED: &'static str = "Privacy occupied by another one";
|
||||
pub const TURN_OFF_OTHER_ID: &'static str =
|
||||
"Failed to turn off privacy mode that belongs to someone else";
|
||||
pub const NO_DISPLAYS: &'static str = "No displays";
|
||||
|
||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||
pub mod privacy_win_idd;
|
||||
|
||||
pub trait PrivacyMode {
|
||||
fn turn_on_privacy(&mut self, conn_id: i32) -> ResultType<bool>;
|
||||
fn turn_off_privacy(&mut self, conn_id: i32, state: Option<PrivacyModeState>)
|
||||
-> ResultType<()>;
|
||||
|
||||
fn cur_conn_id(&self) -> i32;
|
||||
|
||||
#[inline]
|
||||
fn check_on_conn_id(&self, conn_id: i32) -> ResultType<bool> {
|
||||
let pre_conn_id = self.cur_conn_id();
|
||||
if pre_conn_id == conn_id {
|
||||
return Ok(true);
|
||||
}
|
||||
if pre_conn_id != 0 {
|
||||
bail!(OCCUPIED);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn check_off_conn_id(&self, conn_id: i32) -> ResultType<()> {
|
||||
let pre_conn_id = self.cur_conn_id();
|
||||
if pre_conn_id != 0 && conn_id != 0 && pre_conn_id != conn_id {
|
||||
bail!(TURN_OFF_OTHER_ID)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
188
src/privacy_mode/privacy_win_idd.rs
Normal file
188
src/privacy_mode/privacy_win_idd.rs
Normal file
@ -0,0 +1,188 @@
|
||||
use super::{PrivacyModeState, NO_DISPLAYS};
|
||||
use hbb_common::{allow_err, bail, lazy_static, log, ResultType};
|
||||
use scrap::dxgi;
|
||||
use winapi::{
|
||||
shared::{
|
||||
minwindef::{DWORD, FALSE},
|
||||
ntdef::{NULL, WCHAR},
|
||||
},
|
||||
um::{
|
||||
errhandlingapi::GetLastError,
|
||||
wingdi::{DEVMODEW, DISPLAY_DEVICEW, DISPLAY_DEVICE_ATTACHED_TO_DESKTOP, DM_POSITION},
|
||||
winuser::{
|
||||
ChangeDisplaySettingsExW, EnumDisplayDevicesW, EnumDisplaySettingsW, CDS_NORESET,
|
||||
CDS_SET_PRIMARY, CDS_UPDATEREGISTRY, DISP_CHANGE_SUCCESSFUL,
|
||||
EDD_GET_DEVICE_INTERFACE_NAME, ENUM_CURRENT_SETTINGS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const IDD_DEVICE_STRING: &'static str = "RustDeskIddDriver Device";
|
||||
|
||||
struct Display {
|
||||
dm: DEVMODEW,
|
||||
name: [WCHAR; 32],
|
||||
primary: bool,
|
||||
}
|
||||
|
||||
pub struct PrivacyModeImpl {
|
||||
conn_id: i32,
|
||||
displays: Vec<Display>,
|
||||
virtual_displays: Vec<Display>,
|
||||
virtual_displays_added: Option<u32>,
|
||||
}
|
||||
|
||||
impl PrivacyModeImpl {
|
||||
fn set_displays(&mut self) {
|
||||
self.displays.clear();
|
||||
self.virtual_displays.clear();
|
||||
for display in dxgi::Displays::get_from_gdi().into_iter() {
|
||||
if let Some(gdi_info) = display.gdi() {
|
||||
if let Ok(s) = std::string::String::from_utf16(&gdi_info.dd.DeviceString) {
|
||||
if s == IDD_DEVICE_STRING {
|
||||
self.virtual_displays.push(Display {
|
||||
dm: gdi_info.dm,
|
||||
name: gdi_info.dd.DeviceName,
|
||||
primary: gdi_info.is_primary,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
self.displays.push(Display {
|
||||
dm: gdi_info.dm,
|
||||
name: gdi_info.dd.DeviceName,
|
||||
primary: gdi_info.is_primary,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn restore(&self) {}
|
||||
|
||||
fn set_primary_display(&mut self) -> ResultType<()> {
|
||||
self.ensure_virtual_display()?;
|
||||
if self.virtual_displays.is_empty() {
|
||||
bail!("No virtual displays");
|
||||
}
|
||||
let display = &self.virtual_displays[0];
|
||||
|
||||
let mut new_primary_dm: DEVMODEW = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
|
||||
new_primary_dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
||||
new_primary_dm.dmDriverExtra = 0;
|
||||
unsafe {
|
||||
if FALSE
|
||||
== EnumDisplaySettingsW(
|
||||
display.name.as_ptr(),
|
||||
ENUM_CURRENT_SETTINGS,
|
||||
&mut new_primary_dm,
|
||||
)
|
||||
{
|
||||
bail!(
|
||||
"Failed EnumDisplaySettingsW, device name: {:?}, error code: {}",
|
||||
std::string::String::from_utf16(&display.name),
|
||||
GetLastError()
|
||||
);
|
||||
}
|
||||
|
||||
let mut i: DWORD = 0;
|
||||
loop {
|
||||
let mut flags = CDS_UPDATEREGISTRY | CDS_NORESET;
|
||||
let mut dd: DISPLAY_DEVICEW = std::mem::MaybeUninit::uninit().assume_init();
|
||||
dd.cb = std::mem::size_of::<DISPLAY_DEVICEW>() as _;
|
||||
if FALSE
|
||||
== EnumDisplayDevicesW(NULL as _, i, &mut dd, EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if dd.DeviceName == display.name {
|
||||
flags |= CDS_SET_PRIMARY;
|
||||
}
|
||||
|
||||
let mut dm: DEVMODEW = std::mem::MaybeUninit::uninit().assume_init();
|
||||
dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
||||
dm.dmDriverExtra = 0;
|
||||
if FALSE
|
||||
== EnumDisplaySettingsW(dd.DeviceName.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm)
|
||||
{
|
||||
bail!(
|
||||
"Failed EnumDisplaySettingsW, device name: {:?}, error code: {}",
|
||||
std::string::String::from_utf16(&dd.DeviceName),
|
||||
GetLastError()
|
||||
);
|
||||
}
|
||||
|
||||
dm.u1.s2_mut().dmPosition.x -= new_primary_dm.u1.s2().dmPosition.x;
|
||||
dm.u1.s2_mut().dmPosition.y -= new_primary_dm.u1.s2().dmPosition.y;
|
||||
dm.dmFields |= DM_POSITION;
|
||||
let rc = ChangeDisplaySettingsExW(
|
||||
dd.DeviceName.as_ptr(),
|
||||
&mut dm,
|
||||
NULL as _,
|
||||
flags,
|
||||
NULL,
|
||||
);
|
||||
|
||||
if rc != DISP_CHANGE_SUCCESSFUL {
|
||||
log::error!(
|
||||
"Failed ChangeDisplaySettingsEx, device name: {:?}, flags: {}, ret: {}",
|
||||
std::string::String::from_utf16(&dd.DeviceName),
|
||||
flags,
|
||||
rc
|
||||
);
|
||||
bail!("Failed ChangeDisplaySettingsEx, ret: {}", rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ensure_virtual_display(&mut self) -> ResultType<()> {
|
||||
if self.virtual_displays.is_empty() {
|
||||
virtual_display::create_device()?;
|
||||
}
|
||||
if virtual_display::is_device_created() {
|
||||
// to-do: add monitor index here
|
||||
virtual_display::plug_in_monitor()?;
|
||||
self.virtual_displays_added = Some(0);
|
||||
}
|
||||
|
||||
self.set_displays();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl super::PrivacyMode for PrivacyModeImpl {
|
||||
fn turn_on_privacy(&mut self, conn_id: i32) -> ResultType<bool> {
|
||||
if self.check_on_conn_id(conn_id)? {
|
||||
return Ok(true);
|
||||
}
|
||||
self.set_displays();
|
||||
if self.displays.is_empty() {
|
||||
bail!(NO_DISPLAYS);
|
||||
}
|
||||
self.set_primary_display()?;
|
||||
|
||||
bail!("unimplemented")
|
||||
}
|
||||
|
||||
fn turn_off_privacy(
|
||||
&mut self,
|
||||
conn_id: i32,
|
||||
state: Option<PrivacyModeState>,
|
||||
) -> ResultType<()> {
|
||||
self.check_off_conn_id(conn_id)?;
|
||||
self.restore();
|
||||
bail!("unimplemented")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn cur_conn_id(&self) -> i32 {
|
||||
self.conn_id
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ use crate::{
|
||||
use hbb_common::{allow_err, bail, lazy_static, log, tokio, ResultType};
|
||||
use std::{
|
||||
ffi::CString,
|
||||
os::windows::process::CommandExt,
|
||||
sync::Mutex,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
@ -25,16 +24,14 @@ use winapi::{
|
||||
CreateProcessAsUserW, GetCurrentThreadId, QueueUserAPC, ResumeThread,
|
||||
PROCESS_INFORMATION, STARTUPINFOW,
|
||||
},
|
||||
winbase::{
|
||||
WTSGetActiveConsoleSessionId, CREATE_NO_WINDOW, CREATE_SUSPENDED, DETACHED_PROCESS,
|
||||
},
|
||||
winbase::{WTSGetActiveConsoleSessionId, CREATE_SUSPENDED, DETACHED_PROCESS},
|
||||
winnt::{MEM_COMMIT, PAGE_READWRITE},
|
||||
winuser::*,
|
||||
},
|
||||
};
|
||||
|
||||
pub const ORIGIN_PROCESS_EXE: &'static str = "C:\\Windows\\System32\\RuntimeBroker.exe";
|
||||
pub const INJECTED_PROCESS_EXE: &'static str = "RuntimeBroker_rustdesk.exe";
|
||||
pub const INJECTED_PROCESS_EXE: &'static str = super::WIN_MAG_INJECTED_PROCESS_EXE;
|
||||
pub const PRIVACY_WINDOW_NAME: &'static str = "RustDeskPrivacyWindow";
|
||||
|
||||
pub const GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT: u32 = 2;
|
||||
@ -317,14 +314,6 @@ fn wait_find_privacy_hwnd(msecs: u128) -> ResultType<HWND> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_process_consent_running() -> ResultType<bool> {
|
||||
let output = std::process::Command::new("cmd")
|
||||
.args(&["/C", "tasklist | findstr consent.exe"])
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.output()?;
|
||||
Ok(output.status.success() && !output.stdout.is_empty())
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn set_privacy_mode_state(
|
||||
conn_id: i32,
|
@ -2346,13 +2346,13 @@ fn try_activate_screen() {
|
||||
|
||||
mod privacy_mode {
|
||||
use super::*;
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
use crate::privacy_mode::privacy_win_mag;
|
||||
|
||||
pub(super) fn turn_off_privacy(_conn_id: i32) -> Message {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
{
|
||||
use crate::win_privacy::*;
|
||||
|
||||
let res = turn_off_privacy(_conn_id, None);
|
||||
let res = privacy_win_mag::turn_off_privacy(_conn_id, None);
|
||||
match res {
|
||||
Ok(_) => crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::PrvOffSucceeded,
|
||||
@ -2365,19 +2365,19 @@ mod privacy_mode {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
||||
{
|
||||
crate::common::make_privacy_mode_msg(back_notification::PrivacyModeState::PrvOffFailed)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn turn_on_privacy(_conn_id: i32) -> ResultType<bool> {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
{
|
||||
let plugin_exist = crate::win_privacy::turn_on_privacy(_conn_id)?;
|
||||
let plugin_exist = privacy_win_mag::turn_on_privacy(_conn_id)?;
|
||||
Ok(plugin_exist)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
||||
{
|
||||
Ok(true)
|
||||
}
|
||||
|
@ -20,6 +20,10 @@
|
||||
|
||||
use super::{video_qos::VideoQoS, *};
|
||||
#[cfg(windows)]
|
||||
use crate::platform::windows::is_process_consent_running;
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
use crate::privacy_mode::privacy_win_mag;
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
use hbb_common::get_version_number;
|
||||
use hbb_common::tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
@ -41,7 +45,7 @@ use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
time::{self, Duration, Instant},
|
||||
};
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||
use virtual_display;
|
||||
|
||||
pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version.";
|
||||
@ -69,9 +73,9 @@ lazy_static::lazy_static! {
|
||||
}
|
||||
|
||||
fn is_capturer_mag_supported() -> bool {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
return scrap::CapturerMag::is_supported();
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
||||
false
|
||||
}
|
||||
|
||||
@ -92,10 +96,10 @@ pub fn get_privacy_mode_conn_id() -> i32 {
|
||||
}
|
||||
|
||||
pub fn is_privacy_mode_supported() -> bool {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
return *IS_CAPTURER_MAGNIFIER_SUPPORTED
|
||||
&& get_version_number(&crate::VERSION) > get_version_number("1.1.9");
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -201,15 +205,13 @@ fn create_capturer(
|
||||
_current: usize,
|
||||
_portable_service_running: bool,
|
||||
) -> ResultType<Box<dyn TraitCapturer>> {
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
||||
let c: Option<Box<dyn TraitCapturer>> = None;
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
let mut c: Option<Box<dyn TraitCapturer>> = None;
|
||||
if privacy_mode_id > 0 {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
{
|
||||
use crate::win_privacy::*;
|
||||
|
||||
match scrap::CapturerMag::new(
|
||||
display.origin(),
|
||||
display.width(),
|
||||
@ -220,7 +222,7 @@ fn create_capturer(
|
||||
let mut ok = false;
|
||||
let check_begin = Instant::now();
|
||||
while check_begin.elapsed().as_secs() < 5 {
|
||||
match c1.exclude("", PRIVACY_WINDOW_NAME) {
|
||||
match c1.exclude("", privacy_win_mag::PRIVACY_WINDOW_NAME) {
|
||||
Ok(false) => {
|
||||
ok = false;
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
@ -229,7 +231,7 @@ fn create_capturer(
|
||||
bail!(
|
||||
"Failed to exclude privacy window {} - {}, err: {}",
|
||||
"",
|
||||
PRIVACY_WINDOW_NAME,
|
||||
privacy_win_mag::PRIVACY_WINDOW_NAME,
|
||||
e
|
||||
);
|
||||
}
|
||||
@ -243,7 +245,7 @@ fn create_capturer(
|
||||
bail!(
|
||||
"Failed to exclude privacy window {} - {} ",
|
||||
"",
|
||||
PRIVACY_WINDOW_NAME
|
||||
privacy_win_mag::PRIVACY_WINDOW_NAME
|
||||
);
|
||||
}
|
||||
log::debug!("Create magnifier capture for {}", privacy_mode_id);
|
||||
@ -275,7 +277,8 @@ fn create_capturer(
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
// to-do: do not close if in privacy mode.
|
||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||
fn ensure_close_virtual_device() -> ResultType<()> {
|
||||
let num_displays = Display::all()?.len();
|
||||
if num_displays == 0 {
|
||||
@ -309,11 +312,11 @@ pub fn test_create_capturer(privacy_mode_id: i32, timeout_millis: u64) -> bool {
|
||||
fn check_uac_switch(privacy_mode_id: i32, capturer_privacy_mode_id: i32) -> ResultType<()> {
|
||||
if capturer_privacy_mode_id != 0 {
|
||||
if privacy_mode_id != capturer_privacy_mode_id {
|
||||
if !crate::win_privacy::is_process_consent_running()? {
|
||||
if !is_process_consent_running()? {
|
||||
bail!("consent.exe is running");
|
||||
}
|
||||
}
|
||||
if crate::win_privacy::is_process_consent_running()? {
|
||||
if is_process_consent_running()? {
|
||||
bail!("consent.exe is running");
|
||||
}
|
||||
}
|
||||
@ -374,7 +377,7 @@ fn get_capturer(use_yuv: bool, portable_service_running: bool) -> ResultType<Cap
|
||||
let mut capturer_privacy_mode_id = privacy_mode_id;
|
||||
#[cfg(windows)]
|
||||
if capturer_privacy_mode_id != 0 {
|
||||
if crate::win_privacy::is_process_consent_running()? {
|
||||
if is_process_consent_running()? {
|
||||
capturer_privacy_mode_id = 0;
|
||||
}
|
||||
}
|
||||
@ -447,7 +450,7 @@ fn check_get_displays_changed_msg() -> Option<Message> {
|
||||
}
|
||||
|
||||
fn run(sp: GenericService) -> ResultType<()> {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||
ensure_close_virtual_device()?;
|
||||
|
||||
// ensure_inited() is needed because release_resource() may be called.
|
||||
@ -922,12 +925,12 @@ pub async fn switch_to_primary() {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(all(windows, feature = "virtual_display_driver")))]
|
||||
fn try_get_displays() -> ResultType<Vec<Display>> {
|
||||
Ok(Display::all()?)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||
fn try_get_displays() -> ResultType<Vec<Display>> {
|
||||
let mut displays = Display::all()?;
|
||||
if displays.len() == 0 {
|
||||
@ -949,6 +952,8 @@ fn try_get_displays() -> ResultType<Vec<Display>> {
|
||||
}
|
||||
displays = Display::all()?;
|
||||
} else if displays.len() > 1 {
|
||||
// to-do: do not close if in privacy mode.
|
||||
|
||||
// If more than one displays exists, close RustDeskVirtualDisplay
|
||||
if virtual_display::is_device_created() {
|
||||
virtual_display::close_device()
|
||||
@ -991,7 +996,7 @@ fn start_uac_elevation_check() {
|
||||
if !crate::platform::is_installed() && !crate::platform::is_root() {
|
||||
std::thread::spawn(|| loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
if let Ok(uac) = crate::win_privacy::is_process_consent_running() {
|
||||
if let Ok(uac) = is_process_consent_running() {
|
||||
*IS_UAC_RUNNING.lock().unwrap() = uac;
|
||||
}
|
||||
if !crate::platform::is_elevated(None).unwrap_or(false) {
|
||||
|
@ -495,7 +495,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
||||
std::thread::spawn(move || {
|
||||
log::info!("try create privacy mode window");
|
||||
if let Err(e) = crate::platform::windows::check_update_broker_process() {
|
||||
@ -504,7 +504,7 @@ pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
||||
e
|
||||
);
|
||||
}
|
||||
allow_err!(crate::win_privacy::start());
|
||||
allow_err!(crate::privacy_mode::privacy_win_mag::start());
|
||||
});
|
||||
|
||||
match ipc::new_listener("_cm").await {
|
||||
|
Loading…
Reference in New Issue
Block a user