From f8253a0272e3999e213884b5e9b89be5e7fd9b76 Mon Sep 17 00:00:00 2001 From: Linghong Date: Tue, 15 Sep 2026 00:26:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=B0=E5=BB=BA=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=9B=AE=E5=BD=95=E6=9D=83=E9=99=90=E6=94=B6=E7=B4=A7?= =?UTF-8?q?=E5=85=9C=E5=BA=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新建目录优先使用当前进程初始化 owner 与私有 DACL 仅在受控 managed 路径本地加固失败时执行一次 UAC 修复 统一目录创建分支并复核最终 Windows ACL --- .../src-tauri/src/config.rs | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/config.rs b/apps/ai-game-creator-shell/src-tauri/src/config.rs index e32c70bb5..b66b976af 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/config.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/config.rs @@ -1319,12 +1319,10 @@ pub(crate) fn ensure_game_creator_private_directory_tree( #[cfg(all(windows, test))] initialize_windows_game_creator_directory_owner_for_current_user(&directory)?; #[cfg(windows)] - // This invocation created the directory, so initialize its - // owner/DACL in-process. Marker-based managed-path detection - // must not route a newly-created descendant into UAC. - secure_windows_game_creator_path_for_current_user_with_owner_policy( - &directory, true, true, true, - )?; + // This invocation created the directory: initialize it in + // process first, with a narrowly-scoped managed-path fallback + // only if Windows rejects that local ACL update. + harden_new_game_creator_private_path(&directory, true, label)?; #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; @@ -1363,11 +1361,7 @@ pub(crate) fn ensure_game_creator_private_directory_tree( fs::create_dir(&directory).map_err(|retry_error| { format!("创建 {label} 失败:{}: {retry_error}", directory.display()) })?; - // The retry also created this directory in the current - // process; keep it on the local hardening path. - secure_windows_game_creator_path_for_current_user_with_owner_policy( - &directory, true, true, true, - )?; + harden_new_game_creator_private_path(&directory, true, label)?; } Err(error) => { return Err(format!( @@ -1432,15 +1426,34 @@ pub(crate) fn harden_new_game_creator_private_path( path.display() )); } - // This invocation created the object, so its owner is the current - // user. Tighten the inherited descriptor in-process; UAC repair is - // reserved for existing, externally-owned objects. - secure_windows_game_creator_path_for_current_user_with_owner_policy( - path, - is_directory, - true, - true, - )?; + // This invocation created the object, so local hardening is always + // the first path. Some Windows configurations can nevertheless + // reject the descriptor update (for example when an inherited ACL is + // protected by the parent). Only a managed path may use the existing + // one-shot repair in that exceptional case; ordinary new projects do + // not prompt for UAC. + if let Err(local_error) = + secure_windows_game_creator_path_for_current_user_with_owner_policy( + path, + is_directory, + true, + true, + ) + { + if !game_creator_private_path_allows_auto_elevation(path) + || !windows_acl_error_may_need_elevation(&local_error) + { + return Err(local_error); + } + secure_windows_game_creator_path_for_current_user_with_auto_elevation( + path, + is_directory, + true, + ) + .map_err(|repair_error| { + format!("{local_error};新建对象的受控 ACL 修复未完成:{repair_error}") + })?; + } } #[cfg(unix)] {