From d43c95db7e59de43c34af191c9a360aa65d134c7 Mon Sep 17 00:00:00 2001 From: CRT Date: Sun, 25 Oct 2026 21:11:31 +0800 Subject: [PATCH] desktop: read StartupApproved through the registry API, no reg.exe (the security test allows no other programs) --- apps/desktop/src-tauri/Cargo.lock | 1 + apps/desktop/src-tauri/Cargo.toml | 2 ++ apps/desktop/src-tauri/src/lib.rs | 27 ++++++++++----------------- apps/desktop/src-tauri/tests/d5.rs | 10 +++++----- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/apps/desktop/src-tauri/Cargo.lock b/apps/desktop/src-tauri/Cargo.lock index 15deadb..6dfcec4 100644 --- a/apps/desktop/src-tauri/Cargo.lock +++ b/apps/desktop/src-tauri/Cargo.lock @@ -4126,6 +4126,7 @@ dependencies = [ "url", "webview2-com", "windows-core", + "winreg", "zip", ] diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 9a6707f..14112cb 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -53,6 +53,8 @@ zip = { version = "4", default-features = false, features = ["deflate-flate2-zli [target.'cfg(windows)'.dependencies] webview2-com = "0.39" windows-core = "0.62" +# reads Startup apps' StartupApproved value (already in the tree through the autostart plugin) +winreg = "0.56" [dev-dependencies] tempfile = "3" diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index c2cd10e..0e55f5c 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -90,27 +90,20 @@ fn tray(app: &tauri::App) -> tauri::Result<()> { } /// A tray menu pick (a menu panel row or the native fallback menu): tray.rs maps the id to what it does. -/// Whether the person turned storebound off in Windows' Startup apps (Settings / Task Manager), from the `reg query` -/// output of HKCU\...\Explorer\StartupApproved\Run /v storebound: the first byte of the REG_BINARY is even when enabled -/// (02, 06), odd when disabled (03, 07). No entry: not turned off. Pure. -pub fn startup_approved_off(reg_query_out: &str) -> bool { - reg_query_out - .lines() - .find(|l| l.contains("REG_BINARY")) - .and_then(|l| l.split_whitespace().last()) - .and_then(|hex| u8::from_str_radix(hex.get(0..2)?, 16).ok()) - .is_some_and(|b| b & 1 == 1) +/// Whether the person turned storebound off in Windows' Startup apps (Settings / Task Manager), from the +/// HKCU\...\Explorer\StartupApproved\Run value named like the Run entry: its first byte is even when enabled (02, 06), +/// odd when disabled (03, 07). No value: not turned off. Pure. +pub fn startup_approved_off(value: &[u8]) -> bool { + value.first().is_some_and(|b| b & 1 == 1) } #[cfg(windows)] fn startup_disabled_by_user() -> bool { - use std::os::windows::process::CommandExt; - const CREATE_NO_WINDOW: u32 = 0x0800_0000; - std::process::Command::new("reg") - .args(["query", r"HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run", "/v", "storebound"]) - .creation_flags(CREATE_NO_WINDOW) - .output() - .map(|o| startup_approved_off(&String::from_utf8_lossy(&o.stdout))) + use winreg::{enums::HKEY_CURRENT_USER, RegKey}; + RegKey::predef(HKEY_CURRENT_USER) + .open_subkey(r"Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run") + .and_then(|k| k.get_raw_value("storebound")) + .map(|v| startup_approved_off(&v.bytes)) .unwrap_or(false) } diff --git a/apps/desktop/src-tauri/tests/d5.rs b/apps/desktop/src-tauri/tests/d5.rs index 6342910..9f2f382 100644 --- a/apps/desktop/src-tauri/tests/d5.rs +++ b/apps/desktop/src-tauri/tests/d5.rs @@ -146,9 +146,9 @@ fn background_updater_schedule_and_defer() { #[test] fn startup_apps_choice_is_read_from_startup_approved() { use storebound_desktop::startup_approved_off; - let on = "\r\nHKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run\r\n storebound REG_BINARY 020000000000000000000000\r\n"; - let off = "\r\nHKEY_CURRENT_USER\\Run\r\n storebound REG_BINARY 0300000020D1D3B1F0B3DC01\r\n"; - assert!(!startup_approved_off(on)); - assert!(startup_approved_off(off)); - assert!(!startup_approved_off("ERROR: The system was unable to find the specified registry key or value.")); + assert!(!startup_approved_off(&[0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])); + assert!(!startup_approved_off(&[0x06, 0, 0, 0])); + assert!(startup_approved_off(&[0x03, 0, 0, 0, 0x20, 0xD1, 0xD3, 0xB1, 0xF0, 0xB3, 0xDC, 0x01])); + assert!(startup_approved_off(&[0x07])); + assert!(!startup_approved_off(&[])); }