管理员模式下启动使用YAE导入

This commit is contained in:
BTMuli
2025-12-22 15:56:53 +08:00
parent 86b2dfa184
commit 06ff32d47d
4 changed files with 59 additions and 25 deletions

View File

@@ -1,5 +1,5 @@
//! DLL 注入相关功能
//! @since Beta v0.7.8
//! @since Beta v0.9.1
#![cfg(target_os = "windows")]
use std::ffi::OsStr;
@@ -53,33 +53,38 @@ pub fn create_named_pipe(pipe_name: &str) -> HANDLE {
}
/// 启动目标进程附加cwd
pub fn spawn_process(path: &str) -> PROCESS_INFORMATION {
let wide_path: Vec<u16> = to_wide_string(path);
let cwd = std::path::Path::new(path).parent().unwrap().to_str().unwrap();
let wide_cwd: Vec<u16> = to_wide_string(cwd);
pub fn spawn_process(path: &str, ticket: Option<String>) -> PROCESS_INFORMATION {
let wide_path: Vec<u16> = to_wide_string(path); // 如果有 ticket构造命令行
let mut wide_cmd: Option<Vec<u16>> = None;
if let Some(ref t) = ticket {
let cmdline = format!("{} login_auth_ticket={}", path, t);
wide_cmd = Some(to_wide_string(&cmdline));
} // 如果没有 ticket使用 cwd
let wide_cwd: Option<Vec<u16>> = if ticket.is_none() {
let cwd = std::path::Path::new(path).parent().unwrap().to_str().unwrap();
Some(to_wide_string(cwd))
} else {
None
};
unsafe {
let mut si: STARTUPINFOW = std::mem::zeroed();
si.cb = std::mem::size_of::<STARTUPINFOW>() as u32;
let mut pi: PROCESS_INFORMATION = std::mem::zeroed();
let success = CreateProcessW(
wide_path.as_ptr(),
ptr::null_mut(),
wide_cmd.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(ptr::null_mut()), // 有 ticket 时传命令行
ptr::null_mut(),
ptr::null_mut(),
0,
0,
ptr::null_mut(),
wide_cwd.as_ptr(),
wide_cwd.as_ref().map(|v| v.as_ptr()).unwrap_or(ptr::null()), // 无 ticket 时传 cwd
&mut si,
&mut pi,
);
if success == 0 {
panic!("CreateProcessW failed");
}
pi
}
}

View File

@@ -1,5 +1,5 @@
//! Yae 相关处理
//! @since Beta v0.8.9
//! @since Beta v0.9.1
#![cfg(target_os = "windows")]
pub mod inject;
@@ -67,7 +67,12 @@ fn read_exact_vec<R: Read>(r: &mut R, len: usize) -> io::Result<Vec<u8>> {
/// 调用 dll
#[tauri::command]
pub fn call_yae_dll(app_handle: AppHandle, game_path: String, uid: String) -> Result<(), String> {
pub fn call_yae_dll(
app_handle: AppHandle,
game_path: String,
uid: String,
ticket: Option<String>,
) -> Result<(), String> {
let dll_path = app_handle.path().resource_dir().unwrap().join("resources/YaeAchievementLib.dll");
dbg!(&dll_path);
// 0. 创建 YaeAchievementPipe 的 命名管道,获取句柄
@@ -75,7 +80,7 @@ pub fn call_yae_dll(app_handle: AppHandle, game_path: String, uid: String) -> Re
let _pipe_handle = create_named_pipe("YaeAchievementPipe");
// 1. 启动游戏进程
let pi = spawn_process(&game_path);
let pi = spawn_process(&game_path, ticket);
dbg!("游戏进程启动完成");
// 2. 注入 DLL