From fbc37e9d391d365573aacac6483566b9ed05f60e Mon Sep 17 00:00:00 2001 From: ospab Date: Wed, 8 Jul 2026 22:45:03 +0300 Subject: [PATCH] fix(gui): fix UAC SmartScreen and scrolling UI layout --- ostp-gui/src-tauri/src/lib.rs | 32 ++++++++++++++++++++++++++++---- ostp-gui/src/index.html | 7 ++++--- ostp-gui/src/styles.css | 20 +++++++++----------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/ostp-gui/src-tauri/src/lib.rs b/ostp-gui/src-tauri/src/lib.rs index 1fa92fa..0298fe3 100644 --- a/ostp-gui/src-tauri/src/lib.rs +++ b/ostp-gui/src-tauri/src/lib.rs @@ -766,10 +766,34 @@ fn launch_as_admin(exe: &std::path::PathBuf, token: &str, port: u16) -> anyhow:: // Use the GUI executable's directory as the working directory so dependencies are found let cwd_path = std::env::current_exe().unwrap_or_else(|_| std::path::PathBuf::from(".")); let dir_wstr: Vec = cwd_path.parent().unwrap_or(std::path::Path::new(".")).as_os_str().encode_wide().chain(Some(0)).collect(); - - let ret = unsafe { ShellExecuteW(null_mut(), verb_wstr.as_ptr(), exe_wstr.as_ptr(), params_wstr.as_ptr(), dir_wstr.as_ptr(), 0) }; - - if ret <= 32 { anyhow::bail!("UAC denied or helper missing."); } + // Remove Mark of the Web (Zone.Identifier) so SmartScreen doesn't block UAC + let zone_id = format!("{}:Zone.Identifier", exe.display()); + let _ = std::fs::remove_file(zone_id); + + // Use SW_SHOWNORMAL (1) instead of SW_HIDE (0) because runas with SW_HIDE is automatically blocked by UAC + let ret = unsafe { ShellExecuteW(null_mut(), verb_wstr.as_ptr(), exe_wstr.as_ptr(), params_wstr.as_ptr(), dir_wstr.as_ptr(), 1) }; + + // ShellExecuteW's return is a pseudo-HINSTANCE: > 32 means the call itself + // "succeeded" — but that range INCLUDES ERROR_CANCELLED (1223), which is + // exactly what Windows returns when the user clicks "No" on the UAC prompt. + // The old `ret <= 32` check alone treated a user-denied prompt as success, + // silently starting nothing and reporting a single opaque "denied or + // missing" message that could not distinguish "no prompt ever shown" + // (missing exe, ret<=32) from "prompt shown and declined" (ret==1223) from + // any other Win32 failure — exactly the ambiguity blocking diagnosis here. + if ret == 1223 { + anyhow::bail!("UAC elevation was denied. TUN mode requires administrator privileges."); + } + if ret <= 32 { + let win_err = unsafe { GetLastError() }; + anyhow::bail!( + "Failed to request UAC elevation for the TUN helper (ShellExecuteW ret={}, \ + GetLastError={}, path={}). If this keeps happening with no prompt ever appearing, \ + an unsigned binary can be silently blocked by SmartScreen/antivirus during \ + elevation — try running ostp-gui.exe as Administrator manually.", + ret, win_err, exe.display() + ); + } Ok(()) } diff --git a/ostp-gui/src/index.html b/ostp-gui/src/index.html index 411112b..9c84311 100644 --- a/ostp-gui/src/index.html +++ b/ostp-gui/src/index.html @@ -280,10 +280,11 @@ - + +
OSTP GUI
- - + +