fix(windows): name the privacy window executable explicitly (#16711)

Turning on privacy mode 1 could fail with `os error 193`, "%1 is not a valid
Win32 application", naming a broker executable that is perfectly intact.

`CreateProcessAsUserW` was given a NULL `lpApplicationName` and the unquoted
broker path as `lpCommandLine`. With no application name Windows has to work
out the image from the command line, and it does so by trying each
whitespace-delimited prefix in turn. The default install path is
`C:\Program Files\RustDesk\...`, so the first candidate is `C:\Program`. On a
machine where a file by that name happens to exist, Windows loads it, fails to
read it as a PE image, and returns ERROR_BAD_EXE_FORMAT. The path in the error
message is the command line that was intended, not the file Windows tried.

Pass the path as `lpApplicationName`, which removes the guessing entirely, and
quote the copy that goes in as `lpCommandLine` so the child still sees a
well-formed `argv[0]`. Bind that buffer mutably while here: the API declares it
as an in/out `LPWSTR` the Unicode implementation may rewrite, so handing over a
const pointer cast to mutable was the wrong interface for the call.

Both other `CreateProcess` call sites in the tree already name the executable
explicitly, one of them with a comment giving this exact reason, so this brings
the third into line rather than introducing a pattern.

Refs #16705
This commit is contained in:
Minh Nguyen authored and GitHub committed 2026-10-26 17:23:08 +08:00
1 parent a5e986401c
commit 59f2953c94
1 file changed
+10 -3
+10 -3
View File
@@ -226,7 +226,14 @@ impl PrivacyModeImpl {
.to_string();
unsafe {
let cmd_utf16: Vec<u16> = cmdline.encode_utf16().chain(Some(0).into_iter()).collect();
// The path goes in as `lpApplicationName` too: given only a command line, Windows
// treats every whitespace-delimited prefix as a candidate image, and the default
// install path contains a space.
let app_utf16: Vec<u16> = cmdline.encode_utf16().chain(Some(0).into_iter()).collect();
let mut cmd_utf16: Vec<u16> = format!("\"{cmdline}\"")
.encode_utf16()
.chain(Some(0).into_iter())
.collect();
let mut start_info = STARTUPINFOW {
cb: 0,
@@ -263,8 +270,8 @@ impl PrivacyModeImpl {
let create_res = CreateProcessAsUserW(
token,
NULL as _,
cmd_utf16.as_ptr() as _,
app_utf16.as_ptr() as _,
cmd_utf16.as_mut_ptr() as _,
NULL as _,
NULL as _,
FALSE,