tmp commit
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
35ec3ffef6
commit
042a4e575f
@ -196,7 +196,7 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice)
|
|||||||
}
|
}
|
||||||
if (created == TRUE)
|
if (created == TRUE)
|
||||||
{
|
{
|
||||||
SetLastMsg("Device is created before, please uninstall it first\n");
|
SetLastMsg("Device is already created, please destroy it first\n");
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -288,7 +288,7 @@ BOOL MonitorPlugIn(UINT index, UINT edid, INT retries)
|
|||||||
|
|
||||||
if (retries < 0)
|
if (retries < 0)
|
||||||
{
|
{
|
||||||
SetLastMsg("invalid tries %d\n", retries);
|
SetLastMsg("Invalid tries %d\n", retries);
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
|
@ -68,4 +68,4 @@ pub mod clipboard_file;
|
|||||||
pub mod rc;
|
pub mod rc;
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub mod privacy_mode;
|
pub mod privacy_win_mag;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use super::{CursorData, ResultType};
|
use super::{CursorData, ResultType};
|
||||||
use crate::common::PORTABLE_APPNAME_RUNTIME_ENV_KEY;
|
use crate::common::PORTABLE_APPNAME_RUNTIME_ENV_KEY;
|
||||||
#[cfg(feature = "privacy_win_mag")]
|
use crate::{
|
||||||
use crate::privacy_mode::privacy_win_mag;
|
ipc,
|
||||||
use crate::{ipc, license::*, privacy_mode::WIN_MAG_INJECTED_PROCESS_EXE};
|
license::*,
|
||||||
|
privacy_win_mag::{self, WIN_MAG_INJECTED_PROCESS_EXE},
|
||||||
|
};
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err, bail,
|
allow_err, bail,
|
||||||
config::{self, Config},
|
config::{self, Config},
|
||||||
@ -10,12 +12,10 @@ use hbb_common::{
|
|||||||
message_proto::Resolution,
|
message_proto::Resolution,
|
||||||
sleep, timeout, tokio,
|
sleep, timeout, tokio,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "privacy_win_mag")]
|
|
||||||
use std::fs;
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
io,
|
fs, io,
|
||||||
io::prelude::*,
|
io::prelude::*,
|
||||||
mem,
|
mem,
|
||||||
os::windows::process::CommandExt,
|
os::windows::process::CommandExt,
|
||||||
@ -839,7 +839,6 @@ fn get_default_install_path() -> String {
|
|||||||
format!("{}\\{}", pf, crate::get_app_name())
|
format!("{}\\{}", pf, crate::get_app_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "privacy_win_mag")]
|
|
||||||
pub fn check_update_broker_process() -> ResultType<()> {
|
pub fn check_update_broker_process() -> ResultType<()> {
|
||||||
// let (_, path, _, _) = get_install_info();
|
// let (_, path, _, _) = get_install_info();
|
||||||
let process_exe = privacy_win_mag::INJECTED_PROCESS_EXE;
|
let process_exe = privacy_win_mag::INJECTED_PROCESS_EXE;
|
||||||
@ -925,32 +924,17 @@ 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 {
|
pub fn copy_exe_cmd(src_exe: &str, exe: &str, path: &str) -> String {
|
||||||
let main_exe = copy_raw_cmd(src_exe, exe, path);
|
let main_exe = copy_raw_cmd(src_exe, exe, path);
|
||||||
|
format!(
|
||||||
#[cfg(feature = "privacy_win_mag")]
|
"
|
||||||
{
|
{main_exe}
|
||||||
format!(
|
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
|
||||||
"
|
\"{src_exe}\" --extract \"{path}\"
|
||||||
{main_exe}
|
",
|
||||||
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
|
main_exe = main_exe,
|
||||||
\"{src_exe}\" --extract \"{path}\"
|
path = path,
|
||||||
",
|
ORIGIN_PROCESS_EXE = privacy_win_mag::ORIGIN_PROCESS_EXE,
|
||||||
main_exe = main_exe,
|
broker_exe = privacy_win_mag::INJECTED_PROCESS_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<()> {
|
pub fn update_me() -> ResultType<()> {
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,188 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,9 +31,15 @@ use winapi::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ORIGIN_PROCESS_EXE: &'static str = "C:\\Windows\\System32\\RuntimeBroker.exe";
|
pub const ORIGIN_PROCESS_EXE: &'static str = "C:\\Windows\\System32\\RuntimeBroker.exe";
|
||||||
pub const INJECTED_PROCESS_EXE: &'static str = super::WIN_MAG_INJECTED_PROCESS_EXE;
|
pub const WIN_MAG_INJECTED_PROCESS_EXE: &'static str = "RuntimeBroker_rustdesk.exe";
|
||||||
|
pub const INJECTED_PROCESS_EXE: &'static str = WIN_MAG_INJECTED_PROCESS_EXE;
|
||||||
pub const PRIVACY_WINDOW_NAME: &'static str = "RustDeskPrivacyWindow";
|
pub const PRIVACY_WINDOW_NAME: &'static str = "RustDeskPrivacyWindow";
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
pub const GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT: u32 = 2;
|
pub const GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT: u32 = 2;
|
||||||
pub const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 4;
|
pub const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 4;
|
||||||
|
|
@ -2346,11 +2346,11 @@ fn try_activate_screen() {
|
|||||||
|
|
||||||
mod privacy_mode {
|
mod privacy_mode {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
use crate::privacy_mode::privacy_win_mag;
|
use crate::privacy_win_mag;
|
||||||
|
|
||||||
pub(super) fn turn_off_privacy(_conn_id: i32) -> Message {
|
pub(super) fn turn_off_privacy(_conn_id: i32) -> Message {
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let res = privacy_win_mag::turn_off_privacy(_conn_id, None);
|
let res = privacy_win_mag::turn_off_privacy(_conn_id, None);
|
||||||
match res {
|
match res {
|
||||||
@ -2365,19 +2365,19 @@ mod privacy_mode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
#[cfg(not(windows))]
|
||||||
{
|
{
|
||||||
crate::common::make_privacy_mode_msg(back_notification::PrivacyModeState::PrvOffFailed)
|
crate::common::make_privacy_mode_msg(back_notification::PrivacyModeState::PrvOffFailed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn turn_on_privacy(_conn_id: i32) -> ResultType<bool> {
|
pub(super) fn turn_on_privacy(_conn_id: i32) -> ResultType<bool> {
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let plugin_exist = privacy_win_mag::turn_on_privacy(_conn_id)?;
|
let plugin_exist = privacy_win_mag::turn_on_privacy(_conn_id)?;
|
||||||
Ok(plugin_exist)
|
Ok(plugin_exist)
|
||||||
}
|
}
|
||||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
#[cfg(not(windows))]
|
||||||
{
|
{
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,10 @@
|
|||||||
|
|
||||||
use super::{video_qos::VideoQoS, *};
|
use super::{video_qos::VideoQoS, *};
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::platform::windows::is_process_consent_running;
|
use crate::{platform::windows::is_process_consent_running, privacy_win_mag};
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
|
||||||
use crate::privacy_mode::privacy_win_mag;
|
|
||||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||||
use hbb_common::config::LocalConfig;
|
use hbb_common::config::LocalConfig;
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
use hbb_common::get_version_number;
|
use hbb_common::get_version_number;
|
||||||
use hbb_common::tokio::sync::{
|
use hbb_common::tokio::sync::{
|
||||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||||
@ -78,9 +76,9 @@ lazy_static::lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_capturer_mag_supported() -> bool {
|
fn is_capturer_mag_supported() -> bool {
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
return scrap::CapturerMag::is_supported();
|
return scrap::CapturerMag::is_supported();
|
||||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
#[cfg(not(windows))]
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,10 +99,10 @@ pub fn get_privacy_mode_conn_id() -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_privacy_mode_supported() -> bool {
|
pub fn is_privacy_mode_supported() -> bool {
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
return *IS_CAPTURER_MAGNIFIER_SUPPORTED
|
return *IS_CAPTURER_MAGNIFIER_SUPPORTED
|
||||||
&& get_version_number(&crate::VERSION) > get_version_number("1.1.9");
|
&& get_version_number(&crate::VERSION) > get_version_number("1.1.9");
|
||||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
#[cfg(not(windows))]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,12 +208,12 @@ fn create_capturer(
|
|||||||
_current: usize,
|
_current: usize,
|
||||||
_portable_service_running: bool,
|
_portable_service_running: bool,
|
||||||
) -> ResultType<Box<dyn TraitCapturer>> {
|
) -> ResultType<Box<dyn TraitCapturer>> {
|
||||||
#[cfg(not(all(windows, feature = "privacy_win_mag")))]
|
#[cfg(not(windows))]
|
||||||
let c: Option<Box<dyn TraitCapturer>> = None;
|
let c: Option<Box<dyn TraitCapturer>> = None;
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
let mut c: Option<Box<dyn TraitCapturer>> = None;
|
let mut c: Option<Box<dyn TraitCapturer>> = None;
|
||||||
if privacy_mode_id > 0 {
|
if privacy_mode_id > 0 {
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
match scrap::CapturerMag::new(
|
match scrap::CapturerMag::new(
|
||||||
display.origin(),
|
display.origin(),
|
||||||
@ -942,21 +940,39 @@ fn try_get_displays() -> ResultType<Vec<Display>> {
|
|||||||
log::debug!("no displays, create virtual display");
|
log::debug!("no displays, create virtual display");
|
||||||
// Try plugin monitor
|
// Try plugin monitor
|
||||||
if LocalConfig::get_virtual_display_num() > 0 {
|
if LocalConfig::get_virtual_display_num() > 0 {
|
||||||
if !virtual_display::is_device_created() {
|
let mut device_already_created = false;
|
||||||
if let Err(e) = virtual_display::create_device() {
|
if let Err(e) = virtual_display::create_device() {
|
||||||
|
if e.to_string().contains("Device is already created") {
|
||||||
|
device_already_created = true;
|
||||||
|
} else {
|
||||||
log::debug!("Create device failed {}", e);
|
log::debug!("Create device failed {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if virtual_display::is_device_created() {
|
if device_already_created || virtual_display::is_device_created() {
|
||||||
|
// Reboot is not required for this case.
|
||||||
|
let mut _reboot_required = false;
|
||||||
|
virtual_display::install_update_driver(&mut _reboot_required)?;
|
||||||
if let Err(e) = virtual_display::plug_in_monitor(VIRTUAL_DISPLAY_INDEX_FOR_HEADLESS)
|
if let Err(e) = virtual_display::plug_in_monitor(VIRTUAL_DISPLAY_INDEX_FOR_HEADLESS)
|
||||||
{
|
{
|
||||||
log::debug!("Plug in monitor failed {}", e);
|
log::debug!("Plug in monitor failed {}", e);
|
||||||
|
} else {
|
||||||
|
let modes = [virtual_display::MonitorMode {
|
||||||
|
width: 1920,
|
||||||
|
height: 1080,
|
||||||
|
sync: 60,
|
||||||
|
}];
|
||||||
|
if let Err(e) = virtual_display::update_monitor_modes(
|
||||||
|
VIRTUAL_DISPLAY_INDEX_FOR_HEADLESS,
|
||||||
|
&modes,
|
||||||
|
) {
|
||||||
|
log::debug!("Update monitor modes failed {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displays = Display::all()?;
|
displays = Display::all()?;
|
||||||
}
|
}
|
||||||
} else if displays.len() > 1 {
|
} else if displays.len() > 1 {
|
||||||
// to-do: do not close if in privacy mode.
|
// to-do: do not close if in idd privacy mode.
|
||||||
|
|
||||||
// If more than one displays exists, close RustDeskVirtualDisplay
|
// If more than one displays exists, close RustDeskVirtualDisplay
|
||||||
if virtual_display::is_device_created() {
|
if virtual_display::is_device_created() {
|
||||||
|
@ -495,7 +495,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
||||||
#[cfg(all(windows, feature = "privacy_win_mag"))]
|
#[cfg(windows)]
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
log::info!("try create privacy mode window");
|
log::info!("try create privacy mode window");
|
||||||
if let Err(e) = crate::platform::windows::check_update_broker_process() {
|
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
|
e
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
allow_err!(crate::privacy_mode::privacy_win_mag::start());
|
allow_err!(crate::privacy_win_mag::start());
|
||||||
});
|
});
|
||||||
|
|
||||||
match ipc::new_listener("_cm").await {
|
match ipc::new_listener("_cm").await {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user