Fix disabled installation bypass (#15598)

* Fix disabled installation bypass

Prevent install.exe and --install from opening the install flow when disable-installation is set.

Signed-off-by: 21pages <sunboeasy@gmail.com>

* Refine disabled installation handling for portable clients

Document why --install must be filtered from both Rust and Flutter runner arguments for portable wrappers such as no-install.exe. Remove redundant UI-
    layer installation checks because the install entry points are already gated upstream.

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2026-07-16 16:00:38 +08:00
committed by GitHub
parent cf2b28faf9
commit 5abf4e9724
4 changed files with 31 additions and 2 deletions

View File

@@ -14,6 +14,7 @@
typedef char** (*FUNC_RUSTDESK_CORE_MAIN)(int*); typedef char** (*FUNC_RUSTDESK_CORE_MAIN)(int*);
typedef void (*FUNC_RUSTDESK_FREE_ARGS)( char**, int); typedef void (*FUNC_RUSTDESK_FREE_ARGS)( char**, int);
typedef int (*FUNC_RUSTDESK_GET_APP_NAME)(wchar_t*, int); typedef int (*FUNC_RUSTDESK_GET_APP_NAME)(wchar_t*, int);
typedef int (*FUNC_RUSTDESK_IS_DISABLE_INSTALLATION)();
/// Note: `--server`, `--service` are already handled in [core_main.rs]. /// Note: `--server`, `--service` are already handled in [core_main.rs].
const std::vector<std::string> parameters_white_list = {"--install", "--cm"}; const std::vector<std::string> parameters_white_list = {"--install", "--cm"};
@@ -62,6 +63,22 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
} }
std::vector<std::string> rust_args(c_args, c_args + args_len); std::vector<std::string> rust_args(c_args, c_args + args_len);
free_c_args(c_args, args_len); free_c_args(c_args, args_len);
FUNC_RUSTDESK_IS_DISABLE_INSTALLATION rustdesk_is_disable_installation =
(FUNC_RUSTDESK_IS_DISABLE_INSTALLATION)GetProcAddress(hInstance, "rustdesk_is_disable_installation");
bool is_disable_installation =
rustdesk_is_disable_installation && rustdesk_is_disable_installation() != 0;
const auto installParam = std::string("--install");
// Flutter reads the original process command line, not only rust_args, so
// remove the `--install` injected by the portable wrapper here as well. This
// also lets `no-install.exe` continue as a portable app when installation is
// disabled. See: https://github.com/rustdesk/rustdesk-server-pro/issues/991#issuecomment-4978376890
if (is_disable_installation) {
command_line_arguments.erase(
std::remove(command_line_arguments.begin(),
command_line_arguments.end(),
installParam),
command_line_arguments.end());
}
std::wstring app_name = L"RustDesk"; std::wstring app_name = L"RustDesk";
FUNC_RUSTDESK_GET_APP_NAME get_rustdesk_app_name = (FUNC_RUSTDESK_GET_APP_NAME)GetProcAddress(hInstance, "get_rustdesk_app_name"); FUNC_RUSTDESK_GET_APP_NAME get_rustdesk_app_name = (FUNC_RUSTDESK_GET_APP_NAME)GetProcAddress(hInstance, "get_rustdesk_app_name");
@@ -118,7 +135,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
is_cm_page = true; is_cm_page = true;
} }
bool is_install_page = false; bool is_install_page = false;
auto installParam = std::string("--install");
if (!command_line_arguments.empty() && command_line_arguments.front().compare(0, installParam.size(), installParam.c_str()) == 0) { if (!command_line_arguments.empty() && command_line_arguments.front().compare(0, installParam.size(), installParam.c_str()) == 0) {
is_install_page = true; is_install_page = true;
} }

View File

@@ -1024,7 +1024,7 @@ pub fn get_full_name() -> String {
} }
pub fn is_setup(name: &str) -> bool { pub fn is_setup(name: &str) -> bool {
name.to_lowercase().ends_with("install.exe") !config::is_disable_installation() && name.to_lowercase().ends_with("install.exe")
} }
pub fn get_custom_rendezvous_server(custom: String) -> String { pub fn get_custom_rendezvous_server(custom: String) -> String {

View File

@@ -127,6 +127,13 @@ pub fn core_main() -> Option<Vec<String>> {
if args.contains(&"--noinstall".to_string()) { if args.contains(&"--noinstall".to_string()) {
args.clear(); args.clear();
} }
// The portable wrapper injects `--install` when its name ends with `install.exe`,
// including `no-install.exe`. Drop the argument instead of exiting so disabled
// clients can continue running as portable applications.
if config::is_disable_installation() {
args.retain(|arg| arg != "--install");
flutter_args.retain(|arg| arg != "--install");
}
if args.len() > 0 { if args.len() > 0 {
if args[0] == "--version" { if args[0] == "--version" {
println!("{}", crate::VERSION); println!("{}", crate::VERSION);

View File

@@ -136,6 +136,12 @@ pub extern "C" fn rustdesk_core_main_args(args_len: *mut c_int) -> *mut *mut c_c
return std::ptr::null_mut() as _; return std::ptr::null_mut() as _;
} }
#[cfg(windows)]
#[no_mangle]
pub extern "C" fn rustdesk_is_disable_installation() -> c_int {
hbb_common::config::is_disable_installation() as c_int
}
// https://gist.github.com/iskakaushik/1c5b8aa75c77479c33c4320913eebef6 // https://gist.github.com/iskakaushik/1c5b8aa75c77479c33c4320913eebef6
#[cfg(windows)] #[cfg(windows)]
fn rust_args_to_c_args(args: Vec<String>, outlen: *mut c_int) -> *mut *mut c_char { fn rust_args_to_c_args(args: Vec<String>, outlen: *mut c_int) -> *mut *mut c_char {