#[cfg(windows)] pub mod win10; use hbb_common::{bail, lazy_static, ResultType}; use std::{path::Path, sync::Mutex}; lazy_static::lazy_static! { // If device is uninstalled though "Device Manager" Window. // Rustdesk is unable to handle device any more... static ref H_SW_DEVICE: Mutex = Mutex::new(0); static ref MONITOR_PLUGIN: Mutex> = Mutex::new(Vec::new()); } pub fn download_driver() -> ResultType<()> { #[cfg(windows)] let _download_url = win10::DRIVER_DOWNLOAD_URL; #[cfg(target_os = "linux")] let _download_url = ""; // process download and report progress Ok(()) } pub fn install_update_driver(_reboot_required: &mut bool) -> ResultType<()> { #[cfg(windows)] let install_path = win10::DRIVER_INSTALL_PATH; #[cfg(not(windows))] let install_path = ""; let abs_path = Path::new(install_path).canonicalize()?; if !abs_path.exists() { bail!("{} not exists", install_path) } #[cfg(windows)] unsafe { { // Device must be created before install driver. // https://github.com/fufesou/RustDeskIddDriver/issues/1 if let Err(e) = create_device() { bail!("{}", e); } let full_install_path: Vec = abs_path .to_string_lossy() .as_ref() .encode_utf16() .chain(Some(0).into_iter()) .collect(); let mut reboot_required_tmp = win10::idd::FALSE; if win10::idd::InstallUpdate(full_install_path.as_ptr() as _, &mut reboot_required_tmp) == win10::idd::FALSE { bail!("{}", win10::get_last_msg()?); } *_reboot_required = reboot_required_tmp == win10::idd::TRUE; } } Ok(()) } pub fn uninstall_driver(_reboot_required: &mut bool) -> ResultType<()> { #[cfg(windows)] let install_path = win10::DRIVER_INSTALL_PATH; #[cfg(not(windows))] let install_path = ""; let abs_path = Path::new(install_path).canonicalize()?; if !abs_path.exists() { bail!("{} not exists", install_path) } #[cfg(windows)] unsafe { { let full_install_path: Vec = abs_path .to_string_lossy() .as_ref() .encode_utf16() .chain(Some(0).into_iter()) .collect(); let mut reboot_required_tmp = win10::idd::FALSE; if win10::idd::Uninstall(full_install_path.as_ptr() as _, &mut reboot_required_tmp) == win10::idd::FALSE { bail!("{}", win10::get_last_msg()?); } *_reboot_required = reboot_required_tmp == win10::idd::TRUE; } } Ok(()) } pub fn is_device_created() -> bool { #[cfg(windows)] return *H_SW_DEVICE.lock().unwrap() != 0; #[cfg(not(windows))] return false; } pub fn create_device() -> ResultType<()> { if is_device_created() { return Ok(()); } #[cfg(windows)] unsafe { let mut lock_device = H_SW_DEVICE.lock().unwrap(); let mut h_sw_device = *lock_device as win10::idd::HSWDEVICE; if win10::idd::DeviceCreate(&mut h_sw_device) == win10::idd::FALSE { bail!("{}", win10::get_last_msg()?); } else { *lock_device = h_sw_device as u64; } } Ok(()) } pub fn close_device() { #[cfg(windows)] unsafe { win10::idd::DeviceClose(*H_SW_DEVICE.lock().unwrap() as win10::idd::HSWDEVICE); *H_SW_DEVICE.lock().unwrap() = 0; MONITOR_PLUGIN.lock().unwrap().clear(); } } pub fn plug_in_monitor() -> ResultType<()> { #[cfg(windows)] unsafe { let monitor_index = 0 as u32; let mut plug_in_monitors = MONITOR_PLUGIN.lock().unwrap(); for i in 0..plug_in_monitors.len() { if let Some(d) = plug_in_monitors.get(i) { if *d == monitor_index { return Ok(()); } }; } if win10::idd::MonitorPlugIn(monitor_index, 0, 30) == win10::idd::FALSE { bail!("{}", win10::get_last_msg()?); } (*plug_in_monitors).push(monitor_index); } Ok(()) } pub fn plug_out_monitor() -> ResultType<()> { #[cfg(windows)] unsafe { let monitor_index = 0 as u32; if win10::idd::MonitorPlugOut(monitor_index) == win10::idd::FALSE { bail!("{}", win10::get_last_msg()?); } let mut plug_in_monitors = MONITOR_PLUGIN.lock().unwrap(); for i in 0..plug_in_monitors.len() { if let Some(d) = plug_in_monitors.get(i) { if *d == monitor_index { plug_in_monitors.remove(i); break; } }; } } Ok(()) } pub fn update_monitor_modes() -> ResultType<()> { #[cfg(windows)] unsafe { let monitor_index = 0 as u32; let mut modes = vec![win10::idd::MonitorMode { width: 1920, height: 1080, sync: 60, }]; if win10::idd::FALSE == win10::idd::MonitorModesUpdate( monitor_index as win10::idd::UINT, modes.len() as win10::idd::UINT, modes.as_mut_ptr(), ) { bail!("{}", win10::get_last_msg()?); } } Ok(()) }