From aa740f4263abaa62dd572d36870de9ca33191ac5 Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 22 Jul 2023 14:16:41 +0800 Subject: [PATCH] remove many unwrap and enum_value_or_default Signed-off-by: 21pages --- libs/hbb_common/src/fs.rs | 43 +++++++++++----- libs/hbb_common/src/lib.rs | 36 ++++++++----- libs/scrap/src/android/ffi.rs | 28 ++++++----- libs/scrap/src/common/codec.rs | 37 +++++++++----- libs/scrap/src/dxgi/mag.rs | 6 +-- libs/scrap/src/wayland/pipewire.rs | 13 ++--- .../dylib/examples/idd_controller.rs | 50 ++++++++++++++++--- src/cli.rs | 44 ++++++++++++---- src/client.rs | 30 +++++------ src/common.rs | 2 +- src/flutter.rs | 5 +- src/naming.rs | 17 +++---- src/platform/delegate.rs | 18 ++++--- src/platform/linux.rs | 9 +++- src/platform/macos.rs | 34 +++++++++---- src/platform/windows.rs | 37 +++++++------- src/privacy_win_mag.rs | 9 ++-- src/rendezvous_mediator.rs | 14 +++--- src/server/audio_service.rs | 15 +++--- src/server/connection.rs | 20 ++++---- src/server/input_service.rs | 6 +-- src/server/portable_service.rs | 28 ++++++++--- src/server/video_service.rs | 2 +- src/ui.rs | 15 ++++-- src/ui/remote.rs | 2 +- src/ui_interface.rs | 16 +++--- 26 files changed, 345 insertions(+), 191 deletions(-) diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index 6b8205acf..33902e575 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -6,7 +6,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use serde_derive::{Deserialize, Serialize}; use tokio::{fs::File, io::*}; -use crate::{bail, get_version_number, message_proto::*, ResultType, Stream}; +use crate::{anyhow::anyhow, bail, get_version_number, message_proto::*, ResultType, Stream}; // https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html use crate::{ compress::{compress, decompress}, @@ -403,10 +403,18 @@ impl TransferJob { } if block.compressed { let tmp = decompress(&block.data); - self.file.as_mut().unwrap().write_all(&tmp).await?; + self.file + .as_mut() + .ok_or(anyhow!("file is None"))? + .write_all(&tmp) + .await?; self.finished_size += tmp.len() as u64; } else { - self.file.as_mut().unwrap().write_all(&block.data).await?; + self.file + .as_mut() + .ok_or(anyhow!("file is None"))? + .write_all(&block.data) + .await?; self.finished_size += block.data.len() as u64; } self.transferred += block.data.len() as u64; @@ -456,7 +464,13 @@ impl TransferJob { let mut compressed = false; let mut offset: usize = 0; loop { - match self.file.as_mut().unwrap().read(&mut buf[offset..]).await { + match self + .file + .as_mut() + .ok_or(anyhow!("file is None"))? + .read(&mut buf[offset..]) + .await + { Err(err) => { self.file_num += 1; self.file = None; @@ -501,7 +515,12 @@ impl TransferJob { async fn send_current_digest(&mut self, stream: &mut Stream) -> ResultType<()> { let mut msg = Message::new(); let mut resp = FileResponse::new(); - let meta = self.file.as_ref().unwrap().metadata().await?; + let meta = self + .file + .as_ref() + .ok_or(anyhow!("file is None"))? + .metadata() + .await?; let last_modified = meta .modified()? .duration_since(SystemTime::UNIX_EPOCH)? @@ -750,13 +769,13 @@ pub async fn handle_read_jobs( Ok(None) => { if job.job_completed() { finished.push(job.id()); - let err = job.job_error(); - if err.is_some() { - stream - .send(&new_error(job.id(), err.unwrap(), job.file_num())) - .await?; - } else { - stream.send(&new_done(job.id(), job.file_num())).await?; + match job.job_error() { + Some(err) => { + stream + .send(&new_error(job.id(), err, job.file_num())) + .await? + } + None => stream.send(&new_done(job.id(), job.file_num())).await?, } } else { // waiting confirmation. diff --git a/libs/hbb_common/src/lib.rs b/libs/hbb_common/src/lib.rs index 5c618182f..b8a7f4f2f 100644 --- a/libs/hbb_common/src/lib.rs +++ b/libs/hbb_common/src/lib.rs @@ -127,7 +127,7 @@ impl AddrMangle { SocketAddr::V4(addr_v4) => { let tm = (SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .unwrap_or(std::time::Duration::ZERO) .as_micros() as u32) as u128; let ip = u32::from_le_bytes(addr_v4.ip().octets()) as u128; let port = addr.port() as u128; @@ -160,9 +160,9 @@ impl AddrMangle { if bytes.len() != 18 { return Config::get_any_listen_addr(false); } - let tmp: [u8; 2] = bytes[16..].try_into().unwrap(); + let tmp: [u8; 2] = bytes[16..].try_into().unwrap_or_default(); let port = u16::from_le_bytes(tmp); - let tmp: [u8; 16] = bytes[..16].try_into().unwrap(); + let tmp: [u8; 16] = bytes[..16].try_into().unwrap_or_default(); let ip = std::net::Ipv6Addr::from(tmp); return SocketAddr::new(IpAddr::V6(ip), port); } @@ -290,16 +290,24 @@ pub fn get_time() -> i64 { #[inline] pub fn is_ipv4_str(id: &str) -> bool { - regex::Regex::new(r"^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(:\d+)?$") - .unwrap() - .is_match(id) + if let Ok(reg) = regex::Regex::new( + r"^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(:\d+)?$", + ) { + reg.is_match(id) + } else { + false + } } #[inline] pub fn is_ipv6_str(id: &str) -> bool { - regex::Regex::new(r"^((([a-fA-F0-9]{1,4}:{1,2})+[a-fA-F0-9]{1,4})|(\[([a-fA-F0-9]{1,4}:{1,2})+[a-fA-F0-9]{1,4}\]:\d+))$") - .unwrap() - .is_match(id) + if let Ok(reg) = regex::Regex::new( + r"^((([a-fA-F0-9]{1,4}:{1,2})+[a-fA-F0-9]{1,4})|(\[([a-fA-F0-9]{1,4}:{1,2})+[a-fA-F0-9]{1,4}\]:\d+))$", + ) { + reg.is_match(id) + } else { + false + } } #[inline] @@ -312,11 +320,13 @@ pub fn is_domain_port_str(id: &str) -> bool { // modified regex for RFC1123 hostname. check https://stackoverflow.com/a/106223 for original version for hostname. // according to [TLD List](https://data.iana.org/TLD/tlds-alpha-by-domain.txt) version 2023011700, // there is no digits in TLD, and length is 2~63. - regex::Regex::new( + if let Ok(reg) = regex::Regex::new( r"(?i)^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z-]{0,61}[a-z]:\d{1,5}$", - ) - .unwrap() - .is_match(id) + ) { + reg.is_match(id) + } else { + false + } } pub fn init_log(_is_async: bool, _name: &str) -> Option { diff --git a/libs/scrap/src/android/ffi.rs b/libs/scrap/src/android/ffi.rs index 97d677272..6855fd3f6 100644 --- a/libs/scrap/src/android/ffi.rs +++ b/libs/scrap/src/android/ffi.rs @@ -99,9 +99,11 @@ pub extern "system" fn Java_com_carriez_flutter_1hbb_MainService_onVideoFrameUpd buffer: JObject, ) { let jb = JByteBuffer::from(buffer); - let data = env.get_direct_buffer_address(&jb).unwrap(); - let len = env.get_direct_buffer_capacity(&jb).unwrap(); - VIDEO_RAW.lock().unwrap().update(data, len); + if let Ok(data) = env.get_direct_buffer_address(&jb) { + if let Ok(len) = env.get_direct_buffer_capacity(&jb) { + VIDEO_RAW.lock().unwrap().update(data, len); + } + } } #[no_mangle] @@ -111,9 +113,11 @@ pub extern "system" fn Java_com_carriez_flutter_1hbb_MainService_onAudioFrameUpd buffer: JObject, ) { let jb = JByteBuffer::from(buffer); - let data = env.get_direct_buffer_address(&jb).unwrap(); - let len = env.get_direct_buffer_capacity(&jb).unwrap(); - AUDIO_RAW.lock().unwrap().update(data, len); + if let Ok(data) = env.get_direct_buffer_address(&jb) { + if let Ok(len) = env.get_direct_buffer_capacity(&jb) { + AUDIO_RAW.lock().unwrap().update(data, len); + } + } } #[no_mangle] @@ -142,12 +146,12 @@ pub extern "system" fn Java_com_carriez_flutter_1hbb_MainService_init( ctx: JObject, ) { log::debug!("MainService init from java"); - let jvm = env.get_java_vm().unwrap(); - - *JVM.write().unwrap() = Some(jvm); - - let context = env.new_global_ref(ctx).unwrap(); - *MAIN_SERVICE_CTX.write().unwrap() = Some(context); + if let Ok(jvm) = env.get_java_vm() { + *JVM.write().unwrap() = Some(jvm); + if let Ok(context) = env.new_global_ref(ctx) { + *MAIN_SERVICE_CTX.write().unwrap() = Some(context); + } + } } pub fn call_main_service_mouse_input(mask: i32, x: i32, y: i32) -> JniResult<()> { diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 11b42e769..b6847dba0 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -19,20 +19,19 @@ use crate::{ use hbb_common::{ anyhow::anyhow, + bail, config::PeerConfig, log, message_proto::{ supported_decoding::PreferCodec, video_frame, EncodedVideoFrames, Message, SupportedDecoding, SupportedEncoding, }, + sysinfo::{System, SystemExt}, + tokio::time::Instant, ResultType, }; #[cfg(any(feature = "hwcodec", feature = "mediacodec"))] use hbb_common::{config::Config2, lazy_static}; -use hbb_common::{ - sysinfo::{System, SystemExt}, - tokio::time::Instant, -}; lazy_static::lazy_static! { static ref PEER_DECODINGS: Arc>> = Default::default(); @@ -88,9 +87,9 @@ impl DerefMut for Encoder { } pub struct Decoder { - vp8: VpxDecoder, - vp9: VpxDecoder, - av1: AomDecoder, + vp8: Option, + vp9: Option, + av1: Option, #[cfg(feature = "hwcodec")] hw: HwDecoders, #[cfg(feature = "hwcodec")] @@ -279,12 +278,12 @@ impl Decoder { let vp8 = VpxDecoder::new(VpxDecoderConfig { codec: VpxVideoCodecId::VP8, }) - .unwrap(); + .ok(); let vp9 = VpxDecoder::new(VpxDecoderConfig { codec: VpxVideoCodecId::VP9, }) - .unwrap(); - let av1 = AomDecoder::new().unwrap(); + .ok(); + let av1 = AomDecoder::new().ok(); Decoder { vp8, vp9, @@ -314,13 +313,25 @@ impl Decoder { ) -> ResultType { match frame { video_frame::Union::Vp8s(vp8s) => { - Decoder::handle_vpxs_video_frame(&mut self.vp8, vp8s, rgb) + if let Some(vp8) = &mut self.vp8 { + Decoder::handle_vpxs_video_frame(vp8, vp8s, rgb) + } else { + bail!("vp8 decoder not available"); + } } video_frame::Union::Vp9s(vp9s) => { - Decoder::handle_vpxs_video_frame(&mut self.vp9, vp9s, rgb) + if let Some(vp9) = &mut self.vp9 { + Decoder::handle_vpxs_video_frame(vp9, vp9s, rgb) + } else { + bail!("vp9 decoder not available"); + } } video_frame::Union::Av1s(av1s) => { - Decoder::handle_av1s_video_frame(&mut self.av1, av1s, rgb) + if let Some(av1) = &mut self.av1 { + Decoder::handle_av1s_video_frame(av1, av1s, rgb) + } else { + bail!("av1 decoder not available"); + } } #[cfg(feature = "hwcodec")] video_frame::Union::H264s(h264s) => { diff --git a/libs/scrap/src/dxgi/mag.rs b/libs/scrap/src/dxgi/mag.rs index 62e90c08b..ac94472c0 100644 --- a/libs/scrap/src/dxgi/mag.rs +++ b/libs/scrap/src/dxgi/mag.rs @@ -129,7 +129,7 @@ impl MagInterface { unsafe { // load lib let lib_file_name = "Magnification.dll"; - let lib_file_name_c = CString::new(lib_file_name).unwrap(); + let lib_file_name_c = CString::new(lib_file_name)?; s.lib_handle = LoadLibraryExA( lib_file_name_c.as_ptr() as _, NULL, @@ -189,7 +189,7 @@ impl MagInterface { } unsafe fn load_func(lib_module: HMODULE, func_name: &str) -> Result { - let func_name_c = CString::new(func_name).unwrap(); + let func_name_c = CString::new(func_name)?; let func = GetProcAddress(lib_module, func_name_c.as_ptr() as _); if func.is_null() { return Err(Error::new( @@ -442,7 +442,7 @@ impl CapturerMag { } pub(crate) fn exclude(&mut self, cls: &str, name: &str) -> Result { - let name_c = CString::new(name).unwrap(); + let name_c = CString::new(name)?; unsafe { let mut hwnd = if cls.len() == 0 { FindWindowExA(NULL as _, NULL as _, NULL as _, name_c.as_ptr()) diff --git a/libs/scrap/src/wayland/pipewire.rs b/libs/scrap/src/wayland/pipewire.rs index 5583dfef5..f7eb84537 100644 --- a/libs/scrap/src/wayland/pipewire.rs +++ b/libs/scrap/src/wayland/pipewire.rs @@ -594,13 +594,14 @@ fn request_screen_cast( } let fd_res = fd_res.lock().unwrap(); let streams_res = streams_res.lock().unwrap(); - if fd_res.is_some() && !streams_res.is_empty() { - Ok((conn, fd_res.clone().unwrap(), streams_res.clone())) - } else { - Err(Box::new(DBusError( - "Failed to obtain screen capture.".into(), - ))) + if let Some(fd_res) = fd_res.clone() { + if !streams_res.is_empty() { + return Ok((conn, fd_res, streams_res.clone())); + } } + Err(Box::new(DBusError( + "Failed to obtain screen capture.".into(), + ))) } pub fn get_capturables(capture_cursor: bool) -> Result, Box> { diff --git a/libs/virtual_display/dylib/examples/idd_controller.rs b/libs/virtual_display/dylib/examples/idd_controller.rs index c9a3fbbab..4d3bdc5e5 100644 --- a/libs/virtual_display/dylib/examples/idd_controller.rs +++ b/libs/virtual_display/dylib/examples/idd_controller.rs @@ -30,7 +30,12 @@ fn prompt_input() -> u8 { unsafe fn plug_in(index: idd::UINT, edid: idd::UINT) { println!("Plug in monitor begin"); if idd::FALSE == idd::MonitorPlugIn(index, edid, 25) { - println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap()); + println!( + "{}", + CStr::from_ptr(idd::GetLastMsg()) + .to_str() + .unwrap_or_default() + ); } else { println!("Plug in monitor done"); @@ -46,7 +51,12 @@ unsafe fn plug_in(index: idd::UINT, edid: idd::UINT) { sync: 60 as idd::DWORD, }); if idd::FALSE == idd::MonitorModesUpdate(index, modes.len() as u32, modes.as_mut_ptr()) { - println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap()); + println!( + "{}", + CStr::from_ptr(idd::GetLastMsg()) + .to_str() + .unwrap_or_default() + ); } } } @@ -55,7 +65,12 @@ unsafe fn plug_in(index: idd::UINT, edid: idd::UINT) { unsafe fn plug_out(index: idd::UINT) { println!("Plug out monitor begin"); if idd::FALSE == idd::MonitorPlugOut(index) { - println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap()); + println!( + "{}", + CStr::from_ptr(idd::GetLastMsg()) + .to_str() + .unwrap_or_default() + ); } else { println!("Plug out monitor done"); } @@ -64,7 +79,13 @@ unsafe fn plug_out(index: idd::UINT) { fn main() { #[cfg(windows)] { - let abs_path = Path::new(DRIVER_INSTALL_PATH).canonicalize().unwrap(); + let abs_path = match Path::new(DRIVER_INSTALL_PATH).canonicalize() { + Ok(p) => p, + Err(e) => { + println!("Failed to get absolute path of driver install: {:?}", e); + return; + } + }; unsafe { let invalid_device = 0 as idd::HSWDEVICE; @@ -86,7 +107,12 @@ fn main() { if idd::InstallUpdate(full_inf_path.as_ptr() as _, &mut reboot_required) == idd::FALSE { - println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap()); + println!( + "{}", + CStr::from_ptr(idd::GetLastMsg()) + .to_str() + .unwrap_or_default() + ); } else { println!( "Install or update driver done, reboot is {} required", @@ -104,7 +130,12 @@ fn main() { if idd::Uninstall(full_inf_path.as_ptr() as _, &mut reboot_required) == idd::FALSE { - println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap()); + println!( + "{}", + CStr::from_ptr(idd::GetLastMsg()) + .to_str() + .unwrap_or_default() + ); } else { println!( "Uninstall driver done, reboot is {} required", @@ -123,7 +154,12 @@ fn main() { continue; } if idd::FALSE == idd::DeviceCreate(&mut h_sw_device) { - println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap()); + println!( + "{}", + CStr::from_ptr(idd::GetLastMsg()) + .to_str() + .unwrap_or_default() + ); idd::DeviceClose(h_sw_device); h_sw_device = invalid_device; } else { diff --git a/src/cli.rs b/src/cli.rs index 13e70987b..0f49c5530 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -56,9 +56,15 @@ impl Interface for Session { } "re-input-password" => { log::error!("{}: {}", title, text); - let password = rpassword::prompt_password("Enter password: ").unwrap(); - let login_data = Data::Login((password, true)); - self.sender.send(login_data).ok(); + match rpassword::prompt_password("Enter password: ") { + Ok(password) => { + let login_data = Data::Login((password, true)); + self.sender.send(login_data).ok(); + } + Err(e) => { + log::error!("reinput password failed, {:?}", e); + } + } } msg if msg.contains("error") => { log::error!("{}: {}: {}", msgtype, title, text); @@ -85,8 +91,23 @@ impl Interface for Session { handle_hash(self.lc.clone(), &pass, hash, self, peer).await; } - async fn handle_login_from_ui(&mut self, os_username: String, os_password: String, password: String, remember: bool, peer: &mut Stream) { - handle_login_from_ui(self.lc.clone(), os_username, os_password, password, remember, peer).await; + async fn handle_login_from_ui( + &mut self, + os_username: String, + os_password: String, + password: String, + remember: bool, + peer: &mut Stream, + ) { + handle_login_from_ui( + self.lc.clone(), + os_username, + os_password, + password, + remember, + peer, + ) + .await; } async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) { @@ -117,13 +138,14 @@ pub async fn connect_test(id: &str, key: String, token: String) { break; } Ok(Some(Ok(bytes))) => { - let msg_in = Message::parse_from_bytes(&bytes).unwrap(); - match msg_in.union { - Some(message::Union::Hash(hash)) => { - log::info!("Got hash"); - break; + if let Ok(msg_in) = Message::parse_from_bytes(&bytes) { + match msg_in.union { + Some(message::Union::Hash(hash)) => { + log::info!("Got hash"); + break; + } + _ => {} } - _ => {} } } _ => {} diff --git a/src/client.rs b/src/client.rs index a123be71e..a8bc52c72 100644 --- a/src/client.rs +++ b/src/client.rs @@ -317,19 +317,20 @@ impl Client { if !ph.other_failure.is_empty() { bail!(ph.other_failure); } - match ph.failure.enum_value_or_default() { - punch_hole_response::Failure::ID_NOT_EXIST => { + match ph.failure.enum_value() { + Ok(punch_hole_response::Failure::ID_NOT_EXIST) => { bail!("ID does not exist"); } - punch_hole_response::Failure::OFFLINE => { + Ok(punch_hole_response::Failure::OFFLINE) => { bail!("Remote desktop is offline"); } - punch_hole_response::Failure::LICENSE_MISMATCH => { + Ok(punch_hole_response::Failure::LICENSE_MISMATCH) => { bail!("Key mismatch"); } - punch_hole_response::Failure::LICENSE_OVERUSE => { + Ok(punch_hole_response::Failure::LICENSE_OVERUSE) => { bail!("Key overuse"); } + _ => bail!("other punch hole failure"), } } else { peer_nat_type = ph.nat_type(); @@ -470,11 +471,8 @@ impl Client { ) .await; interface.update_direct(Some(false)); - if conn.is_err() { - bail!( - "Failed to connect via relay server: {}", - conn.err().unwrap() - ); + if let Err(e) = conn { + bail!("Failed to connect via relay server: {}", e); } direct = false; } else { @@ -507,11 +505,13 @@ impl Client { }); let mut sign_pk = None; let mut option_pk = None; - if !signed_id_pk.is_empty() && rs_pk.is_some() { - if let Ok((id, pk)) = decode_id_pk(&signed_id_pk, &rs_pk.unwrap()) { - if id == peer_id { - sign_pk = Some(sign::PublicKey(pk)); - option_pk = Some(pk.to_vec()); + if !signed_id_pk.is_empty() { + if let Some(rs_pk) = rs_pk { + if let Ok((id, pk)) = decode_id_pk(&signed_id_pk, &rs_pk) { + if id == peer_id { + sign_pk = Some(sign::PublicKey(pk)); + option_pk = Some(pk.to_vec()); + } } } if sign_pk.is_none() { diff --git a/src/common.rs b/src/common.rs index d42e27285..ee2ec1516 100644 --- a/src/common.rs +++ b/src/common.rs @@ -725,7 +725,7 @@ pub fn run_me>(args: Vec) -> std::io::Result, outlen: *mut c_int) -> *mut *mut c_cha // Let's fill a vector with null-terminated strings for s in args { - v.push(CString::new(s).unwrap()); + match CString::new(s) { + Ok(s) => v.push(s), + Err(_) => return std::ptr::null_mut() as _, + } } // Turning each null-terminated string into a pointer. diff --git a/src/naming.rs b/src/naming.rs index 7a8d0cecc..1b70af923 100644 --- a/src/naming.rs +++ b/src/naming.rs @@ -12,15 +12,14 @@ fn main() { let args: Vec<_> = std::env::args().skip(1).collect(); let api = args.get(2).cloned().unwrap_or_default(); if args.len() >= 2 { - println!( - "rustdesk-licensed-{}.exe", - gen_name(&License { - key: args[0].clone(), - host: args[1].clone(), - api, - }) - .unwrap() - ); + match gen_name(&License { + key: args[0].clone(), + host: args[1].clone(), + api, + }) { + Ok(name) => println!("rustdesk-licensed-{}.exe", name), + Err(e) => println!("{:?}", e), + } } if args.len() == 1 { println!("{:?}", get_license_from_string(&args[0])); diff --git a/src/platform/delegate.rs b/src/platform/delegate.rs index e4d9cc396..d2a073888 100644 --- a/src/platform/delegate.rs +++ b/src/platform/delegate.rs @@ -64,11 +64,10 @@ impl AppHandler for Rc { // https://github.com/xi-editor/druid/blob/master/druid-shell/src/platform/mac/application.rs pub unsafe fn set_delegate(handler: Option>) { - let decl = ClassDecl::new("AppDelegate", class!(NSObject)); - if decl.is_none() { + let Some(mut decl) = ClassDecl::new("AppDelegate", class!(NSObject)) else { + log::error!("Failed to new AppDelegate"); return; - } - let mut decl = decl.unwrap(); + }; decl.add_ivar::<*mut c_void>(APP_HANDLER_IVAR); decl.add_method( @@ -116,7 +115,10 @@ pub unsafe fn set_delegate(handler: Option>) { let handler_ptr = Box::into_raw(Box::new(state)); (*delegate).set_ivar(APP_HANDLER_IVAR, handler_ptr as *mut c_void); // Set the url scheme handler - let cls = Class::get("NSAppleEventManager").unwrap(); + let Some(cls) = Class::get("NSAppleEventManager") else { + log::error!("Failed to get NSAppleEventManager"); + return; + }; let manager: *mut Object = msg_send![cls, sharedAppleEventManager]; let _: () = msg_send![manager, setEventHandler: delegate @@ -199,10 +201,10 @@ fn service_should_handle_reopen( _sel: Sel, _sender: id, _has_visible_windows: BOOL, - ) -> BOOL { +) -> BOOL { log::debug!("Invoking the main rustdesk process"); - std::thread::spawn(move || crate::handle_url_scheme("".to_string())); - // Prevent default logic. + std::thread::spawn(move || crate::handle_url_scheme("".to_string())); + // Prevent default logic. NO } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index bbe415c71..9c5a8b9fc 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -728,7 +728,9 @@ pub fn get_double_click_time() -> u32 { // g_object_get (settings, "gtk-double-click-time", &double_click_time, NULL); unsafe { let mut double_click_time = 0u32; - let property = std::ffi::CString::new("gtk-double-click-time").unwrap(); + let Ok(property) = std::ffi::CString::new("gtk-double-click-time") else { + return 0; + }; let settings = gtk_settings_get_default(); g_object_get( settings, @@ -801,7 +803,10 @@ pub fn resolutions(name: &str) -> Vec { if let Some(resolutions) = caps.name("resolutions") { let resolution_pat = r"\s*(?P\d+)x(?P\d+)\s+(?P(\d+\.\d+\D*)+)\s*\n"; - let resolution_re = Regex::new(&format!(r"{}", resolution_pat)).unwrap(); + let Ok(resolution_re) = Regex::new(&format!(r"{}", resolution_pat)) else { + log::error!("Regex new failed"); + return vec![]; + }; for resolution_caps in resolution_re.captures_iter(resolutions.as_str()) { if let Some((width, height)) = get_width_height_from_captures(&resolution_caps) diff --git a/src/platform/macos.rs b/src/platform/macos.rs index fb61c7335..f00435907 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -74,7 +74,7 @@ pub fn is_can_input_monitoring(prompt: bool) -> bool { // remove just one app from all the permissions: tccutil reset All com.carriez.rustdesk pub fn is_can_screen_recording(prompt: bool) -> bool { // we got some report that we show no permission even after set it, so we try to use new api for screen recording check - // the new api is only available on macOS >= 10.15, but on stackoverflow, some people said it works on >= 10.16 (crash on 10.15), + // the new api is only available on macOS >= 10.15, but on stackoverflow, some people said it works on >= 10.16 (crash on 10.15), // but also some said it has bug on 10.16, so we just use it on 11.0. unsafe { if CanUseNewApiForScreenCaptureCheck() == YES { @@ -146,14 +146,26 @@ pub fn is_installed_daemon(prompt: bool) -> bool { return true; } - let install_script = PRIVILEGES_SCRIPTS_DIR.get_file("install.scpt").unwrap(); - let install_script_body = install_script.contents_utf8().unwrap(); + let Some(install_script) = PRIVILEGES_SCRIPTS_DIR.get_file("install.scpt") else { + return false; + }; + let Some(install_script_body) = install_script.contents_utf8() else { + return false; + }; - let daemon_plist = PRIVILEGES_SCRIPTS_DIR.get_file(&daemon).unwrap(); - let daemon_plist_body = daemon_plist.contents_utf8().unwrap(); + let Some(daemon_plist) = PRIVILEGES_SCRIPTS_DIR.get_file(&daemon) else { + return false; + }; + let Some(daemon_plist_body) = daemon_plist.contents_utf8() else { + return false; + }; - let agent_plist = PRIVILEGES_SCRIPTS_DIR.get_file(&agent).unwrap(); - let agent_plist_body = agent_plist.contents_utf8().unwrap(); + let Some(agent_plist) = PRIVILEGES_SCRIPTS_DIR.get_file(&agent) else { + return false; + }; + let Some(agent_plist_body) = agent_plist.contents_utf8() else { + return false; + }; std::thread::spawn(move || { match std::process::Command::new("osascript") @@ -198,8 +210,12 @@ pub fn uninstall_service(show_new_window: bool) -> bool { return false; } - let script_file = PRIVILEGES_SCRIPTS_DIR.get_file("uninstall.scpt").unwrap(); - let script_body = script_file.contents_utf8().unwrap(); + let Some(script_file) = PRIVILEGES_SCRIPTS_DIR.get_file("uninstall.scpt") else { + return false; + }; + let Some(script_body) = script_file.contents_utf8() else { + return false; + }; std::thread::spawn(move || { match std::process::Command::new("osascript") diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 3710389bf..d3dcbae81 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -6,7 +6,9 @@ use crate::{ privacy_win_mag::{self, WIN_MAG_INJECTED_PROCESS_EXE}, }; use hbb_common::{ - allow_err, bail, + allow_err, + anyhow::anyhow, + bail, config::{self, Config}, log, message_proto::Resolution, @@ -848,10 +850,9 @@ pub fn check_update_broker_process() -> ResultType<()> { let origin_process_exe = privacy_win_mag::ORIGIN_PROCESS_EXE; let exe_file = std::env::current_exe()?; - if exe_file.parent().is_none() { + let Some(cur_dir) = exe_file.parent() else { bail!("Cannot get parent of current exe file"); - } - let cur_dir = exe_file.parent().unwrap(); + }; let cur_exe = cur_dir.join(process_exe); if !std::path::Path::new(&cur_exe).exists() { @@ -902,29 +903,29 @@ fn get_install_info_with_subkey(subkey: String) -> (String, String, String, Stri (subkey, path, start_menu, exe) } -pub fn copy_raw_cmd(src_raw: &str, _raw: &str, _path: &str) -> String { +pub fn copy_raw_cmd(src_raw: &str, _raw: &str, _path: &str) -> ResultType { let main_raw = format!( "XCOPY \"{}\" \"{}\" /Y /E /H /C /I /K /R /Z", PathBuf::from(src_raw) .parent() - .unwrap() + .ok_or(anyhow!("Can't get parent directory of {src_raw}"))? .to_string_lossy() .to_string(), _path ); - return main_raw; + return Ok(main_raw); } -pub fn copy_exe_cmd(src_exe: &str, exe: &str, path: &str) -> String { - let main_exe = copy_raw_cmd(src_exe, exe, path); - format!( +pub fn copy_exe_cmd(src_exe: &str, exe: &str, path: &str) -> ResultType { + let main_exe = copy_raw_cmd(src_exe, exe, path)?; + Ok(format!( " {main_exe} copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\" ", ORIGIN_PROCESS_EXE = privacy_win_mag::ORIGIN_PROCESS_EXE, broker_exe = privacy_win_mag::INJECTED_PROCESS_EXE, - ) + )) } fn get_after_install(exe: &str) -> String { @@ -1118,7 +1119,7 @@ copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{path}\\\" } else { &dels }, - copy_exe = copy_exe_cmd(&src_exe, &exe, &path), + copy_exe = copy_exe_cmd(&src_exe, &exe, &path)?, import_config = get_import_config(&exe), ); run_cmds(cmds, debug, "install")?; @@ -1200,7 +1201,7 @@ fn write_cmds(cmds: String, ext: &str, tip: &str) -> ResultType &[u8] { unsafe { v.align_to().1 } } -fn get_undone_file(tmp: &PathBuf) -> PathBuf { +fn get_undone_file(tmp: &PathBuf) -> ResultType { let mut tmp1 = tmp.clone(); tmp1.set_file_name(format!( "{}.undone", - tmp.file_name().unwrap().to_string_lossy() + tmp.file_name() + .ok_or(anyhow!("Failed to get filename of {:?}", tmp))? + .to_string_lossy() )); - tmp1 + Ok(tmp1) } fn run_cmds(cmds: String, show: bool, tip: &str) -> ResultType<()> { let tmp = write_cmds(cmds, "bat", tip)?; - let tmp2 = get_undone_file(&tmp); + let tmp2 = get_undone_file(&tmp)?; let tmp_fn = tmp.to_str().unwrap_or(""); let res = runas::Command::new("cmd") .args(&["/C", &tmp_fn]) diff --git a/src/privacy_win_mag.rs b/src/privacy_win_mag.rs index 446cba260..05c2daf05 100644 --- a/src/privacy_win_mag.rs +++ b/src/privacy_win_mag.rs @@ -153,10 +153,10 @@ pub fn start() -> ResultType<()> { } let exe_file = std::env::current_exe()?; - if exe_file.parent().is_none() { + let Some(cur_dir) = exe_file + .parent() else { bail!("Cannot get parent of current exe file"); - } - let cur_dir = exe_file.parent().unwrap(); + }; let dll_file = cur_dir.join("WindowInjection.dll"); if !dll_file.exists() { @@ -344,6 +344,7 @@ async fn set_privacy_mode_state( } pub(super) mod privacy_hook { + use super::*; use std::sync::mpsc::{channel, Sender}; @@ -426,7 +427,7 @@ pub(super) mod privacy_hook { } Err(e) => { // Fatal error - tx.send(format!("Unexpected err when hook {}", e)).unwrap(); + allow_err!(tx.send(format!("Unexpected err when hook {}", e))); return; } } diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 4b2e8bbc6..3e3b6c9b3 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -186,16 +186,18 @@ impl RendezvousMediator { } Some(rendezvous_message::Union::RegisterPkResponse(rpr)) => { update_latency(); - match rpr.result.enum_value_or_default() { - register_pk_response::Result::OK => { + match rpr.result.enum_value() { + Ok(register_pk_response::Result::OK) => { Config::set_key_confirmed(true); Config::set_host_key_confirmed(&rz.host_prefix, true); *SOLVING_PK_MISMATCH.lock().unwrap() = "".to_owned(); } - register_pk_response::Result::UUID_MISMATCH => { + Ok(register_pk_response::Result::UUID_MISMATCH) => { allow_err!(rz.handle_uuid_mismatch(&mut socket).await); } - _ => {} + _ => { + log::error!("unknown RegisterPkResponse"); + } } } Some(rendezvous_message::Union::PunchHole(ph)) => { @@ -376,7 +378,7 @@ impl RendezvousMediator { async fn handle_punch_hole(&self, ph: PunchHole, server: ServerPtr) -> ResultType<()> { let relay_server = self.get_relay_server(ph.relay_server); - if ph.nat_type.enum_value_or_default() == NatType::SYMMETRIC + if ph.nat_type.enum_value() == Ok(NatType::SYMMETRIC) || Config::get_nat_type() == NatType::SYMMETRIC as i32 { let uuid = Uuid::new_v4().to_string(); @@ -515,7 +517,7 @@ async fn direct_server(server: ServerPtr) { listener = Some(l); log::info!( "Direct server listening on: {:?}", - listener.as_ref().unwrap().local_addr() + listener.as_ref().map(|l| l.local_addr()) ); } Err(err) => { diff --git a/src/server/audio_service.rs b/src/server/audio_service.rs index 5a2184fe4..ac3cd6b95 100644 --- a/src/server/audio_service.rs +++ b/src/server/audio_service.rs @@ -13,10 +13,10 @@ // https://github.com/krruzic/pulsectl use super::*; -use magnum_opus::{Application::*, Channels::*, Encoder}; -use std::sync::atomic::{AtomicBool, Ordering}; #[cfg(not(any(target_os = "linux", target_os = "android")))] use hbb_common::anyhow::anyhow; +use magnum_opus::{Application::*, Channels::*, Encoder}; +use std::sync::atomic::{AtomicBool, Ordering}; pub const NAME: &'static str = "audio"; pub const AUDIO_DATA_SIZE_U8: usize = 960 * 4; // 10ms in 48000 stereo @@ -206,13 +206,10 @@ mod cpal_impl { } } } - if device.is_none() { - device = Some( - HOST.default_input_device() - .with_context(|| "Failed to get default input device for loopback")?, - ); - } - let device = device.unwrap(); + let device = device.unwrap_or( + HOST.default_input_device() + .with_context(|| "Failed to get default input device for loopback")?, + ); log::info!("Input device: {}", device.name().unwrap_or("".to_owned())); let format = device .default_input_config() diff --git a/src/server/connection.rs b/src/server/connection.rs index 84f540027..39a87547e 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -665,11 +665,11 @@ impl Connection { } MessageInput::Key((mut msg, press)) => { // todo: press and down have similar meanings. - if press && msg.mode.unwrap() == KeyboardMode::Legacy { + if press && msg.mode.enum_value() == Ok(KeyboardMode::Legacy) { msg.down = true; } handle_key(&msg); - if press && msg.mode.unwrap() == KeyboardMode::Legacy { + if press && msg.mode.enum_value() == Ok(KeyboardMode::Legacy) { msg.down = false; handle_key(&msg); } @@ -1621,11 +1621,11 @@ impl Connection { me.press }; - let key = match me.mode.enum_value_or_default() { - KeyboardMode::Map => { + let key = match me.mode.enum_value() { + Ok(KeyboardMode::Map) => { Some(crate::keyboard::keycode_to_rdev_key(me.chr())) } - KeyboardMode::Translate => { + Ok(KeyboardMode::Translate) => { if let Some(key_event::Union::Chr(code)) = me.union { Some(crate::keyboard::keycode_to_rdev_key(code & 0x0000FFFF)) } else { @@ -1908,11 +1908,9 @@ impl Connection { // Drop the audio sender previously. drop(std::mem::replace(&mut self.audio_sender, None)); self.audio_sender = Some(start_audio_thread()); - allow_err!(self - .audio_sender + self.audio_sender .as_ref() - .unwrap() - .send(MediaData::AudioFormat(format))); + .map(|a| allow_err!(a.send(MediaData::AudioFormat(format)))); } } #[cfg(feature = "flutter")] @@ -2341,6 +2339,8 @@ async fn start_ipc( mut _rx_desktop_ready: mpsc::Receiver<()>, tx_stream_ready: mpsc::Sender<()>, ) -> ResultType<()> { + use hbb_common::anyhow::anyhow; + loop { if !crate::platform::is_prelogin() { break; @@ -2434,7 +2434,7 @@ async fn start_ipc( } let _res = tx_stream_ready.send(()).await; - let mut stream = stream.unwrap(); + let mut stream = stream.ok_or(anyhow!("none stream"))?; loop { tokio::select! { res = stream.next() => { diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 8562ca3eb..f5e4aebd3 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1497,11 +1497,11 @@ pub fn handle_key_(evt: &KeyEvent) { _ => {} }; - match evt.mode.unwrap() { - KeyboardMode::Map => { + match evt.mode.enum_value() { + Ok(KeyboardMode::Map) => { map_keyboard_mode(evt); } - KeyboardMode::Translate => { + Ok(KeyboardMode::Translate) => { translate_keyboard_mode(evt); } _ => { diff --git a/src/server/portable_service.rs b/src/server/portable_service.rs index c8185b709..155f2acb4 100644 --- a/src/server/portable_service.rs +++ b/src/server/portable_service.rs @@ -231,7 +231,13 @@ pub mod server { } pub fn run_portable_service() { - let shmem = Arc::new(SharedMemory::open_existing(SHMEM_NAME).unwrap()); + let shmem = match SharedMemory::open_existing(SHMEM_NAME) { + Ok(shmem) => Arc::new(shmem), + Err(e) => { + log::error!("Failed to open existing shared memory: {:?}", e); + return; + } + }; let shmem1 = shmem.clone(); let shmem2 = shmem.clone(); let mut threads = vec![]; @@ -249,7 +255,7 @@ pub mod server { })); let record_pos_handle = crate::input_service::try_start_record_cursor_pos(); for th in threads.drain(..) { - th.join().unwrap(); + th.join().ok(); log::info!("thread joined"); } @@ -319,7 +325,11 @@ pub mod server { } if c.is_none() { *crate::video_service::CURRENT_DISPLAY.lock().unwrap() = current_display; - let (_, _current, display) = get_current_display().unwrap(); + let Ok((_, _current, display)) = get_current_display() else { + log::error!("Failed to get current display"); + *EXIT.lock().unwrap() = true; + return; + }; display_width = display.width(); display_height = display.height(); match Capturer::new(display, use_yuv) { @@ -380,8 +390,8 @@ pub mod server { continue; } } - match c.as_mut().unwrap().frame(spf) { - Ok(f) => { + match c.as_mut().map(|f| f.frame(spf)) { + Some(Ok(f)) => { utils::set_frame_info( &shmem, FrameInfo { @@ -396,7 +406,7 @@ pub mod server { first_frame_captured = true; dxgi_failed_times = 0; } - Err(e) => { + Some(Err(e)) => { if e.kind() != std::io::ErrorKind::WouldBlock { // DXGI_ERROR_INVALID_CALL after each success on Microsoft GPU driver // log::error!("capture frame failed:{:?}", e); @@ -406,7 +416,8 @@ pub mod server { std::thread::sleep(spf); continue; } - if !c.as_ref().unwrap().is_gdi() { + if c.as_ref().map(|c| c.is_gdi()) == Some(false) { + // nog gdi dxgi_failed_times += 1; } if dxgi_failed_times > MAX_DXGI_FAIL_TIME { @@ -418,6 +429,9 @@ pub mod server { shmem.write(ADDR_CAPTURE_WOULDBLOCK, &utils::i32_to_vec(TRUE)); } } + _ => { + println!("unreachable!"); + } } } } diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 109982985..bb0697409 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -144,7 +144,7 @@ pub fn capture_cursor_embedded() -> bool { #[inline] pub fn notify_video_frame_fetched(conn_id: i32, frame_tm: Option) { - FRAME_FETCHED_NOTIFIER.0.send((conn_id, frame_tm)).unwrap() + FRAME_FETCHED_NOTIFIER.0.send((conn_id, frame_tm)).ok(); } #[inline] diff --git a/src/ui.rs b/src/ui.rs index 8f075b7de..5554a3020 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -124,8 +124,16 @@ pub fn start(args: &mut [String]) { crate::platform::windows::enable_lowlevel_keyboard(hw as _); } let mut iter = args.iter(); - let cmd = iter.next().unwrap().clone(); - let id = iter.next().unwrap().clone(); + let Some(cmd) = iter.next() else { + log::error!("Failed to get cmd arg"); + return; + }; + let cmd = cmd.to_owned(); + let Some(id) = iter.next() else { + log::error!("Failed to get id arg"); + return; + }; + let id = id.to_owned(); let pass = iter.next().unwrap_or(&"".to_owned()).clone(); let args: Vec = iter.map(|x| x.clone()).collect(); frame.set_title(&id); @@ -259,7 +267,8 @@ impl UI { } fn get_options(&self) -> Value { - let hashmap: HashMap = serde_json::from_str(&get_options()).unwrap(); + let hashmap: HashMap = + serde_json::from_str(&get_options()).unwrap_or_default(); let mut m = Value::map(); for (k, v) in hashmap { m.set_item(k, v); diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 4c2af77bd..6826c7e54 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -377,7 +377,7 @@ impl sciter::EventHandler for SciterSession { let source = Element::from(source); use sciter::dom::ELEMENT_AREAS; let flags = ELEMENT_AREAS::CONTENT_BOX as u32 | ELEMENT_AREAS::SELF_RELATIVE as u32; - let rc = source.get_location(flags).unwrap(); + let rc = source.get_location(flags).unwrap_or_default(); log::debug!( "[video] start video thread on <{}> which is about {:?} pixels", source, diff --git a/src/ui_interface.rs b/src/ui_interface.rs index b10fad206..c620f4f91 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -233,7 +233,7 @@ pub fn get_options() -> String { for (k, v) in options.iter() { m.insert(k.into(), v.to_owned().into()); } - serde_json::to_string(&m).unwrap() + serde_json::to_string(&m).unwrap_or_default() } #[inline] @@ -1112,23 +1112,23 @@ async fn check_id( { match msg_in.union { Some(rendezvous_message::Union::RegisterPkResponse(rpr)) => { - match rpr.result.enum_value_or_default() { - register_pk_response::Result::OK => { + match rpr.result.enum_value() { + Ok(register_pk_response::Result::OK) => { ok = true; } - register_pk_response::Result::ID_EXISTS => { + Ok(register_pk_response::Result::ID_EXISTS) => { return "Not available"; } - register_pk_response::Result::TOO_FREQUENT => { + Ok(register_pk_response::Result::TOO_FREQUENT) => { return "Too frequent"; } - register_pk_response::Result::NOT_SUPPORT => { + Ok(register_pk_response::Result::NOT_SUPPORT) => { return "server_not_support"; } - register_pk_response::Result::SERVER_ERROR => { + Ok(register_pk_response::Result::SERVER_ERROR) => { return "Server error"; } - register_pk_response::Result::INVALID_ID_FORMAT => { + Ok(register_pk_response::Result::INVALID_ID_FORMAT) => { return INVALID_FORMAT; } _ => {}