feat: Add KPM module management function, support loading, unloading and deleting all KPM modules.
This commit is contained in:
@@ -1,14 +1,35 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use notify::{Watcher, RecommendedWatcher, RecursiveMode, EventKind};
|
use notify::{Watcher, RecommendedWatcher, RecursiveMode, EventKind};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
pub const KPM_DIR: &str = "/data/adb/kpm";
|
pub const KPM_DIR: &str = "/data/adb/kpm";
|
||||||
|
pub const KPMMGR_PATH: &str = "/data/adb/ksu/bin/kpmmgr";
|
||||||
|
|
||||||
|
|
||||||
|
pub fn ensure_kpm_dir() -> Result<()> {
|
||||||
|
if !Path::new(KPM_DIR).exists() {
|
||||||
|
fs::create_dir_all(KPM_DIR)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn start_kpm_watcher() -> Result<()> {
|
pub fn start_kpm_watcher() -> Result<()> {
|
||||||
|
ensure_kpm_dir()?;
|
||||||
|
|
||||||
|
// 检查是否处于安全模式
|
||||||
|
if crate::utils::is_safe_mode() {
|
||||||
|
log::warn!("The system is in safe mode and is deleting all KPM modules...");
|
||||||
|
if let Err(e) = remove_all_kpms() {
|
||||||
|
log::error!("Error deleting all KPM modules: {}", e);
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let mut watcher = notify::recommended_watcher(|res| {
|
let mut watcher = notify::recommended_watcher(|res| {
|
||||||
match res {
|
match res {
|
||||||
Ok(event) => handle_kpm_event(event),
|
Ok(event) => handle_kpm_event(event),
|
||||||
Err(e) => log::error!("watch error: {:?}", e),
|
Err(e) => log::error!("monitoring error: {:?}", e),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -16,7 +37,8 @@ pub fn start_kpm_watcher() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_kpm_event(event: notify::Event) {
|
// 处理 KPM 文件事件
|
||||||
|
fn handle_kpm_event(event: notify::Event) {
|
||||||
if event.kind.is_create() {
|
if event.kind.is_create() {
|
||||||
event.paths.iter().for_each(|path| {
|
event.paths.iter().for_each(|path| {
|
||||||
if path.extension().map_or(false, |ext| ext == "kpm") {
|
if path.extension().map_or(false, |ext| ext == "kpm") {
|
||||||
@@ -34,8 +56,9 @@ pub fn handle_kpm_event(event: notify::Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载 KPM 模块
|
||||||
pub fn load_kpm(path: &Path) -> Result<()> {
|
pub fn load_kpm(path: &Path) -> Result<()> {
|
||||||
let status = std::process::Command::new("/data/adb/ksu/bin/kpmmgr")
|
let status = std::process::Command::new(KPMMGR_PATH)
|
||||||
.args(["load", path.to_str().unwrap(), ""])
|
.args(["load", path.to_str().unwrap(), ""])
|
||||||
.status()?;
|
.status()?;
|
||||||
|
|
||||||
@@ -45,13 +68,50 @@ pub fn load_kpm(path: &Path) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 卸载 KPM 模块并删除文件
|
||||||
pub fn unload_kpm(name: &str) -> Result<()> {
|
pub fn unload_kpm(name: &str) -> Result<()> {
|
||||||
let status = std::process::Command::new("/data/adb/ksu/bin/kpmmgr")
|
let status = std::process::Command::new(KPMMGR_PATH)
|
||||||
.args(["unload", name])
|
.args(["unload", name])
|
||||||
.status()?;
|
.status()?;
|
||||||
|
|
||||||
if status.success() {
|
if status.success() {
|
||||||
log::info!("Unloaded KPM: {}", name);
|
let kpm_path = Path::new(KPM_DIR).join(format!("{}.kpm", name));
|
||||||
|
if kpm_path.exists() {
|
||||||
|
if let Err(e) = fs::remove_file(&kpm_path) {
|
||||||
|
log::error!("Failed to delete KPM file: {}", e);
|
||||||
|
} else {
|
||||||
|
log::info!("Deleted KPM files: {}", kpm_path.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log::info!("Uninstalled KPM: {}", name);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除所有 KPM 模块
|
||||||
|
pub fn remove_all_kpms() -> Result<()> {
|
||||||
|
ensure_kpm_dir()?;
|
||||||
|
|
||||||
|
for entry in fs::read_dir(KPM_DIR)? {
|
||||||
|
let path = entry?.path();
|
||||||
|
if path.extension().map_or(false, |ext| ext == "kpm") {
|
||||||
|
if let Some(name) = path.file_stem() {
|
||||||
|
let _ = unload_kpm(name.to_string_lossy().as_ref());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载所有现有的 KPM 模块
|
||||||
|
pub fn load_existing_kpms() -> Result<()> {
|
||||||
|
ensure_kpm_dir()?;
|
||||||
|
|
||||||
|
for entry in fs::read_dir(KPM_DIR)? {
|
||||||
|
let path = entry?.path();
|
||||||
|
if path.extension().map_or(false, |ext| ext == "kpm") {
|
||||||
|
let _ = load_kpm(&path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user