Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,9 +993,19 @@ fn get_api_server_(api: String, custom: String) -> String {
"https://admin.rustdesk.com".to_owned()
}

#[inline]
pub fn is_public(url: &str) -> bool {
url.contains("rustdesk.com")
}

#[inline]
pub fn is_selfhost(url: &str) -> bool {
!is_public(url)
}

pub fn get_audit_server(api: String, custom: String, typ: String) -> String {
let url = get_api_server(api, custom);
if url.is_empty() || url.contains("rustdesk.com") {
if url.is_empty() || is_public(&url) {
return "".to_owned();
}
format!("{}/api/audit/{}", url, typ)
Expand Down
61 changes: 33 additions & 28 deletions src/hbbs_http/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,40 +106,45 @@ async fn start_hbbs_sync_async() {
v[keys::OPTION_PRESET_DEVICE_GROUP_NAME] = json!(device_group_name);
}
let v = v.to_string();
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
hasher.update(url.as_bytes());
hasher.update(&v.as_bytes());
let res = hasher.finalize();
let hash = hbb_common::base64::encode(&res[..]);
let old_hash = config::Status::get("sysinfo_hash");
let ver = config::Status::get("sysinfo_ver"); // sysinfo_ver is the version of sysinfo on server's side
if hash == old_hash {
// When the api doesn't exist, Ok("") will be returned in test.
let samever = match crate::post_request(url.replace("heartbeat", "sysinfo_ver"), "".to_owned(), "").await {
Ok(x) => {
sysinfo_ver = x.clone();
*PRO.lock().unwrap() = true;
x == ver
}
_ => {
false // to make sure Pro can be assigned in below post for old
// hbbs pro not supporting sysinfo_ver, use false for ensuring
}
};
if samever {
info_uploaded = (true, url.clone(), None, id.clone());
log::info!("sysinfo not changed, skip upload");
continue;
}
let mut hash = "".to_owned();
if crate::is_selfhost(&url) {
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
hasher.update(url.as_bytes());
hasher.update(&v.as_bytes());
let res = hasher.finalize();
hash = hbb_common::base64::encode(&res[..]);
let old_hash = config::Status::get("sysinfo_hash");
let ver = config::Status::get("sysinfo_ver"); // sysinfo_ver is the version of sysinfo on server's side
if hash == old_hash {
// When the api doesn't exist, Ok("") will be returned in test.
let samever = match crate::post_request(url.replace("heartbeat", "sysinfo_ver"), "".to_owned(), "").await {
Ok(x) => {
sysinfo_ver = x.clone();
*PRO.lock().unwrap() = true;
x == ver
}
_ => {
false // to make sure Pro can be assigned in below post for old
// hbbs pro not supporting sysinfo_ver, use false for ensuring
}
};
if samever {
info_uploaded = (true, url.clone(), None, id.clone());
log::info!("sysinfo not changed, skip upload");
continue;
}
}
}
match crate::post_request(url.replace("heartbeat", "sysinfo"), v, "").await {
Ok(x) => {
if x == "SYSINFO_UPDATED" {
info_uploaded = (true, url.clone(), None, id.clone());
log::info!("sysinfo updated");
config::Status::set("sysinfo_hash", hash);
config::Status::set("sysinfo_ver", sysinfo_ver.clone());
if !hash.is_empty() {
config::Status::set("sysinfo_hash", hash);
config::Status::set("sysinfo_ver", sysinfo_ver.clone());
}
*PRO.lock().unwrap() = true;
} else if x == "ID_NOT_FOUND" {
info_uploaded.2 = None; // next heartbeat will upload sysinfo again
Expand Down
43 changes: 36 additions & 7 deletions src/platform/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,7 @@ fn get_after_install(
}

pub fn install_me(options: &str, path: String, silent: bool, debug: bool) -> ResultType<()> {
let uninstall_str = get_uninstall(false);
let uninstall_str = get_uninstall(false, false);
let mut path = path.trim_end_matches('\\').to_owned();
let (subkey, _path, start_menu, exe) = get_default_install_info();
let mut exe = exe;
Expand Down Expand Up @@ -1428,10 +1428,10 @@ cscript \"{uninstall_shortcut}\"
{tray_shortcuts}
{shortcuts}
copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{path}\\\"
{install_remote_printer}
{dels}
{import_config}
{after_install}
{install_remote_printer}
{sleep}
",
version = crate::VERSION.replace("-", "."),
Expand Down Expand Up @@ -1488,22 +1488,39 @@ fn get_before_uninstall(kill_self: bool) -> String {
)
}

fn get_uninstall(kill_self: bool) -> String {
/// Constructs the uninstall command string for the application.
///
/// # Parameters
/// - `kill_self`: The command will kill the process of current app name. If `true`, it will kill
/// the current process as well. If `false`, it will exclude the current process from the kill
/// command.
/// - `uninstall_printer`: If `true`, includes commands to uninstall the remote printer.
///
/// # Details
/// The `uninstall_printer` parameter determines whether the command to uninstall the remote printer
/// is included in the generated uninstall script. If `uninstall_printer` is `false`, the printer
/// related command is omitted from the script.
fn get_uninstall(kill_self: bool, uninstall_printer: bool) -> String {
let reg_uninstall_string = get_reg("UninstallString");
if reg_uninstall_string.to_lowercase().contains("msiexec.exe") {
return reg_uninstall_string;
}

let mut uninstall_cert_cmd = "".to_string();
let mut uninstall_printer_cmd = "".to_string();
if let Ok(exe) = std::env::current_exe() {
if let Some(exe_path) = exe.to_str() {
uninstall_cert_cmd = format!("\"{}\" --uninstall-cert", exe_path);
if uninstall_printer {
uninstall_printer_cmd = format!("\"{}\" --uninstall-remote-printer", &exe_path);
}
}
}
let (subkey, path, start_menu, _) = get_install_info();
format!(
"
{before_uninstall}
{uninstall_printer_cmd}
{uninstall_cert_cmd}
reg delete {subkey} /f
{uninstall_amyuni_idd}
Expand All @@ -1519,10 +1536,7 @@ fn get_uninstall(kill_self: bool) -> String {
}

pub fn uninstall_me(kill_self: bool) -> ResultType<()> {
if crate::platform::is_win_10_or_greater() {
remote_printer::uninstall_printer(&crate::get_app_name());
}
run_cmds(get_uninstall(kill_self), true, "uninstall")
run_cmds(get_uninstall(kill_self, true), true, "uninstall")
}

fn write_cmds(cmds: String, ext: &str, tip: &str) -> ResultType<std::path::PathBuf> {
Expand Down Expand Up @@ -2467,6 +2481,19 @@ reg add {subkey} /f /v EstimatedSize /t REG_DWORD /d {size}
} else {
"".to_owned()
};

// No need to check the install option here, `is_rd_printer_installed` rarely fails.
let is_printer_installed = remote_printer::is_rd_printer_installed(&app_name).unwrap_or(false);
// Do nothing if the printer is not installed or failed to query if the printer is installed.
let (uninstall_printer_cmd, install_printer_cmd) = if is_printer_installed {
(
format!("\"{}\" --uninstall-remote-printer", &src_exe),
format!("\"{}\" --install-remote-printer", &src_exe),
)
} else {
("".to_owned(), "".to_owned())
};

// We do not try to remove all files in the old version.
// Because I don't know whether additional files will be installed here after installation, such as drivers.
// Just copy files to the installation directory works fine.
Expand All @@ -2487,6 +2514,8 @@ taskkill /F /IM {app_name}.exe{filter}
{reg_cmd}
{copy_exe}
{restore_service_cmd}
{uninstall_printer_cmd}
{install_printer_cmd}
{sleep}
",
app_name = app_name,
Expand Down
Loading