diff --git a/apps/desktop/src-tauri/src/rustdesk.rs b/apps/desktop/src-tauri/src/rustdesk.rs index 5293cbc..cb46f85 100644 --- a/apps/desktop/src-tauri/src/rustdesk.rs +++ b/apps/desktop/src-tauri/src/rustdesk.rs @@ -22,6 +22,7 @@ const SERVER_KEY: &str = "0mxocQKmK6GvTZQYKgjrG9tlNkKOqf81gKgqwAmnZuI="; const DEFAULT_PASSWORD: &str = "FMQ9MA>e73r.FI> = Lazy::new(|| Mutex::new(())); @@ -60,7 +61,11 @@ pub fn provision(machine_id: &str) -> Result Result<(), RustdeskError> { fn write_config_files() -> Result { let config_contents = build_config_contents(); - let program_data = PathBuf::from(env::var("PROGRAMDATA").unwrap_or_else(|_| "C:/ProgramData".to_string())); - let main_path = program_data.join("RustDesk").join("config").join("RustDesk2.toml"); + let main_path = program_data_config_dir().join("RustDesk2.toml"); write_file(&main_path, &config_contents)?; - let service_profile = PathBuf::from(r"C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Roaming\\RustDesk\\config\\RustDesk2.toml"); + let service_profile = PathBuf::from(LOCAL_SERVICE_CONFIG).join("RustDesk2.toml"); write_file(&service_profile, &config_contents).ok(); + if let Some(appdata_path) = user_appdata_config_path("RustDesk2.toml") { + let _ = write_file(&appdata_path, &config_contents); + } + Ok(main_path) } @@ -148,6 +156,22 @@ fn write_file(path: &Path, contents: &str) -> Result<(), io::Error> { fs::write(path, contents) } +fn program_data_config_dir() -> PathBuf { + PathBuf::from(env::var("PROGRAMDATA").unwrap_or_else(|_| "C:/ProgramData".to_string())) + .join("RustDesk") + .join("config") +} + +fn user_appdata_config_dir() -> Option { + env::var("APPDATA") + .ok() + .map(|value| Path::new(&value).join("RustDesk").join("config")) +} + +fn user_appdata_config_path(filename: &str) -> Option { + user_appdata_config_dir().map(|dir| dir.join(filename)) +} + fn build_config_contents() -> String { format!( r#"[options] @@ -184,6 +208,7 @@ fn set_password(exe_path: &Path) -> Result<(), RustdeskError> { fn set_custom_id(exe_path: &Path, machine_id: &str) -> Result { let custom_id = derive_numeric_id(machine_id); run_with_args(exe_path, &["--set-id", &custom_id])?; + ensure_remote_id_files(&custom_id); Ok(custom_id) } @@ -250,6 +275,88 @@ fn query_version(exe_path: &Path) -> Result { Ok(String::from_utf8_lossy(&output.stdout).trim().to_string()) } +fn ensure_remote_id_files(id: &str) { + for dir in remote_id_directories() { + let path = dir.join("RustDesk_local.toml"); + if let Err(error) = write_remote_id_value(&path, id) { + eprintln!("[rustdesk] Falha ao atualizar remote_id em {}: {}", path.display(), error); + } + } +} + +fn remote_id_directories() -> Vec { + let mut dirs = Vec::new(); + dirs.push(program_data_config_dir()); + dirs.push(PathBuf::from(LOCAL_SERVICE_CONFIG)); + if let Some(appdir) = user_appdata_config_dir() { + dirs.push(appdir); + } + dirs +} + +fn write_remote_id_value(path: &Path, id: &str) -> io::Result<()> { + if let Some(parent) = path.parent() { + fs::create_dir_all(parent)?; + } + let replacement = format!("remote_id = '{}'\n", id); + if let Ok(existing) = fs::read_to_string(path) { + let mut replaced = false; + let mut buffer = String::with_capacity(existing.len() + replacement.len()); + for line in existing.lines() { + if line.trim_start().starts_with("remote_id") { + buffer.push_str(&replacement); + replaced = true; + } else { + buffer.push_str(line); + buffer.push('\n'); + } + } + if !replaced { + buffer.push_str(&replacement); + } + fs::write(path, buffer) + } else { + fs::write(path, replacement) + } +} + +fn read_remote_id_from_profiles() -> Option { + for dir in remote_id_directories() { + for candidate in [dir.join("RustDesk_local.toml"), dir.join("RustDesk.toml")] { + if let Some(id) = read_remote_id_file(&candidate) { + if !id.is_empty() { + return Some(id); + } + } + } + } + None +} + +fn read_remote_id_file(path: &Path) -> Option { + let content = fs::read_to_string(path).ok()?; + for line in content.lines() { + if let Some(value) = parse_assignment(line, "remote_id") { + return Some(value); + } + } + None +} + +fn parse_assignment(line: &str, key: &str) -> Option { + let trimmed = line.trim(); + if !trimmed.starts_with(key) { + return None; + } + let (_, rhs) = trimmed.split_once('=')?; + let value = rhs.trim().trim_matches(|c| c == '\'' || c == '"'); + if value.is_empty() { + None + } else { + Some(value.to_string()) + } +} + fn run_with_args(exe_path: &Path, args: &[&str]) -> Result<(), RustdeskError> { let status = Command::new(exe_path) .args(args)