use e_utils::system::cmd;
use std::ptr;
use std::ptr::null_mut;
use winapi::shared::minwindef::{DWORD, HKEY};
use winapi::shared::winerror::{ERROR_NO_MORE_ITEMS, ERROR_SUCCESS, S_OK};
use winapi::um::shellapi::{
SHEmptyRecycleBinW, SHERB_NOCONFIRMATION, SHERB_NOPROGRESSUI, SHERB_NOSOUND,
};
use winapi::um::winnt::{KEY_ENUMERATE_SUB_KEYS, KEY_SET_VALUE};
use winapi::um::winreg::{
RegCloseKey, RegDeleteKeyW, RegDeleteValueW, RegEnumValueW, RegOpenKeyExW, HKEY_CURRENT_USER,
LSTATUS,
};
use crate::share::{default_cmd_res, get_powershell_path, CmdRes, SYSTEM_WIN32};
use std::env;
use std::ffi::OsString;
use std::fs;
use std::os::windows::ffi::OsStrExt;
use std::path::PathBuf;
fn add_log(message: &str, level: &str) {
println!("[{}] {}", level, message);
}
pub fn empty_recycle_bin() -> CmdRes {
let mut outres = default_cmd_res();
let result = unsafe {
SHEmptyRecycleBinW(
ptr::null_mut(),
ptr::null(),
SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND,
)
};
if result == S_OK || result == 0x8000ffffu32 as i32 {
outres.status = true;
outres.content = "Recycle Bin has been successfully cleared!".to_string();
} else {
outres.status = false;
outres.content = format!("Error while clearing the Recycle Bin:{:x}", result);
}
outres
}
pub fn empty_access_log() -> CmdRes {
let mut outres = default_cmd_res();
match env::var("APPDATA") {
Ok(appdata) => {
let recent_folder = PathBuf::from(&appdata).join("Microsoft\\Windows\\Recent");
let automatic_destinations = recent_folder.join("AutomaticDestinations");
let custom_destinations = recent_folder.join("CustomDestinations");
if let Ok(entries) = fs::read_dir(&recent_folder) {
for entry in entries {
if let Ok(entry) = entry {
if let Ok(metadata) = entry.metadata() {
if metadata.is_file() {
let _ = fs::remove_file(entry.path());
}
}
}
}
}
if automatic_destinations.exists() {
let _ = fs::remove_dir_all(&automatic_destinations);
}
if custom_destinations.exists() {
let _ = fs::remove_dir_all(&custom_destinations);
}
add_log("Quick Access history cleared successfully.", "info");
let keys = [
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Start_TrackProgs",
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Start_TrackDocs",
];
for key_path in &keys {
let key_path: Vec<u16> = key_path.encode_utf16().chain(Some(0)).collect();
let mut key: HKEY = null_mut();
let result: LSTATUS = unsafe {
RegOpenKeyExW(
winapi::um::winreg::HKEY_CURRENT_USER,
key_path.as_ptr(),
0,
KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS,
&mut key,
)
};
if result == ERROR_SUCCESS as LSTATUS {
let delete_result: LSTATUS = unsafe {
RegDeleteKeyW(
key,
"Recent\0".encode_utf16().collect::<Vec<u16>>().as_ptr(),
)
};
if delete_result == ERROR_SUCCESS as LSTATUS {
add_log(
&format!(
"Quick Access history in {} cleared successfully.",
String::from_utf16_lossy(&key_path)
),
"info",
);
} else {
add_log(
&format!(
"Error clearing Quick Access history in {}: {}",
String::from_utf16_lossy(&key_path),
delete_result
),
"info",
);
}
unsafe {
RegCloseKey(key);
}
} else {
add_log(
&format!(
"Error opening registry key {}: {}",
String::from_utf16_lossy(&key_path),
result
),
"info",
);
}
}
outres.content = "PASS".to_string();
outres.status = true
}
Err(e) => outres.content = format!("Error getting APPDATA environment variable: {}", e),
}
outres
}
pub fn empty_activity_history() -> CmdRes {
let mut outres = default_cmd_res();
match cmd(
"powershell.exe",
[
"-Command",
"Get-History | ForEach-Object { Remove-History $_.Id }",
],
Some(std::path::Path::new(&get_powershell_path()).to_path_buf()),
false,
false,
) {
Ok(_x) => {
outres.content = format!("Windows search history cleared successfully");
outres.status = true
}
Err(e) => {
outres.content = format!("Error clearing Windows search history: {}", e);
outres.status = false
}
}
outres
}
fn to_utf16_null_terminated(s: &str) -> Vec<u16> {
OsString::from(s).encode_wide().chain(Some(0)).collect()
}
pub fn empty_run_history() -> CmdRes {
let mut outres = default_cmd_res();
let path = to_utf16_null_terminated(r"Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU");
let mut hkey: winapi::shared::minwindef::HKEY = null_mut();
let result = unsafe {
RegOpenKeyExW(
HKEY_CURRENT_USER,
path.as_ptr(),
0,
KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS,
&mut hkey,
)
};
if result != ERROR_SUCCESS as i32 {
outres.content = format!("Failed to open registry key: {}", result);
return outres;
}
let mut index: DWORD = 0;
let mut value_name: [u16; 16383] = [0; 16383]; loop {
let mut value_name_size: DWORD = value_name.len() as DWORD;
let mut value_type: DWORD = 0;
let mut value_data: [u8; 1024] = [0; 1024]; let mut value_data_size: DWORD = value_data.len() as DWORD;
let enum_result = unsafe {
RegEnumValueW(
hkey,
index,
value_name.as_mut_ptr(),
&mut value_name_size,
null_mut(),
&mut value_type,
value_data.as_mut_ptr(),
&mut value_data_size,
)
};
if enum_result == ERROR_NO_MORE_ITEMS as i32 {
break; } else if enum_result != ERROR_SUCCESS as i32 {
outres.content = format!("Failed to enumerate registry values: {}", enum_result);
unsafe { RegCloseKey(hkey) };
return outres;
}
let delete_result = unsafe { RegDeleteValueW(hkey, value_name.as_ptr()) };
if delete_result != ERROR_SUCCESS as i32 {
outres.content = format!("Failed to delete registry value: {}", delete_result);
unsafe { RegCloseKey(hkey) };
return outres;
}
index += 1;
}
unsafe { RegCloseKey(hkey) };
outres.content = "运行历史记录已清理成功!".to_string();
outres.status = true;
outres
}
pub fn empty_netshare(name: &str) -> CmdRes {
let mut outres = default_cmd_res();
let mut name = name;
if name == "" {
name = "*";
}
match cmd(
"net",
["use", name, "/DELETE", "/YES"],
Some(std::path::Path::new(SYSTEM_WIN32).to_path_buf()),
false,
true,
) {
Ok(x) => {
outres.status = !x.stdout.contains("NET HELPMSG");
outres.content = x.stdout;
}
Err(e) => {
outres.content = format!("清空网络共享失败: {e}");
}
}
outres.content = "清空网络共享成功!".to_string();
outres.status = true;
outres
}