deja-vu/boot_diags/src/scan.rs
2025-11-08 21:46:31 -08:00

184 lines
6.6 KiB
Rust

// This file is part of Deja-Vu.
//
// Deja-Vu is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Deja-Vu is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
//
use color_eyre::Result;
use core::system::disk::PartitionTableType;
use core::tasks::Tasks;
use core::{action::Action, tasks::TaskType};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc;
use crate::diags::{DiagGroup, Type as DiagType};
use crate::state::State;
pub fn queue_boot_scan_tasks(
action_tx: mpsc::UnboundedSender<Action>,
diag_groups: Arc<Mutex<Vec<DiagGroup>>>,
state: &State,
system32: String,
tasks: &mut Tasks,
) -> Result<()> {
if let Ok(mut diag_groups) = diag_groups.lock() {
diag_groups.clear();
}
let disk_list = state.disk_list.lock().unwrap();
if let Some(disk_index) = state.disk_index_dest
&& let Some(disk) = disk_list.get(disk_index)
{
let table_type = disk.part_type.clone();
let letter_boot = disk.get_part_letter(state.part_index_boot.unwrap());
let letter_os = disk.get_part_letter(state.part_index_os.unwrap());
// Safety check
if letter_os.is_empty() {
if letter_boot.is_empty() {
action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to get drive letters for the boot and OS volumes",
)))?;
} else {
action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to get drive letter for the OS volume",
)))?;
}
return Ok(());
}
// BCD
if !letter_boot.is_empty() {
tasks.add_group(
DiagType::BootConfigData.to_string().as_str(),
vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\bcdedit.exe", &system32)),
vec![
String::from("/store"),
format!(
"{letter_boot}:{}\\Boot\\BCD",
if table_type == PartitionTableType::Guid {
"\\EFI\\Microsoft"
} else {
""
}
),
String::from("/enum"),
],
)],
);
}
// Bitlocker
tasks.add_group(
DiagType::Bitlocker.to_string().as_str(),
vec![
TaskType::CommandWait(
PathBuf::from(format!("{}\\manage-bde.exe", &system32)),
vec![String::from("-status"), format!("{letter_os}:")],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\manage-bde.exe", &system32)),
vec![
String::from("-protectors"),
String::from("-get"),
format!("{letter_os}:"),
],
),
],
);
// Filesystem Health
tasks.add_group(
DiagType::CheckDisk.to_string().as_str(),
vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\chkdsk.exe", &system32)),
vec![format!("{letter_os}:")],
)],
);
// DISM Health
tasks.add_group(
DiagType::ComponentStore.to_string().as_str(),
vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\dism.exe", &system32)),
vec![
format!("/Image:{letter_os}:"),
String::from("/Cleanup-Image"),
String::from("/ScanHealth"),
],
)],
);
// Critical Files/Folders
let paths: Vec<PathBuf> = [
// Files/Folders
"Users",
"Program Files",
"Program Files (x86)",
"ProgramData",
"Windows\\System32\\config",
]
.iter()
.map(|s| PathBuf::from(format!("{letter_os}:\\{s}")))
.collect();
tasks.add_group(
DiagType::SystemFiles.to_string().as_str(),
vec![TaskType::TestPaths(paths)],
);
// Registry
tasks.add_group(
DiagType::Registry.to_string().as_str(),
vec![
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &system32)),
vec![
String::from("load"),
String::from("HKLM\\TmpSoftware"),
format!("{letter_os}:\\Windows\\System32\\config\\SOFTWARE"),
],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &system32)),
vec![
String::from("load"),
String::from("HKLM\\TmpSystem"),
format!("{letter_os}:\\Windows\\System32\\config\\SYSTEM"),
],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &system32)),
vec![
String::from("load"),
String::from("HKU\\TmpDefault"),
format!("{letter_os}:\\Windows\\System32\\config\\DEFAULT"),
],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &system32)),
vec![String::from("unload"), String::from("HKLM\\TmpSoftware")],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &system32)),
vec![String::from("unload"), String::from("HKLM\\TmpSystem")],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &system32)),
vec![String::from("unload"), String::from("HKU\\TmpDefault")],
),
],
);
tasks.add(TaskType::Sleep); // NOTE: DELETEME
}
Ok(())
}