Move boot scan queue code to new file

app.rs was just too long, no other reason for this.
This commit is contained in:
2Shirt 2025-07-06 20:13:08 -07:00
parent 827451322d
commit c789f51bac
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
3 changed files with 183 additions and 159 deletions

View file

@ -31,7 +31,6 @@ use core::{
system::{
boot::{self, SafeMode, configure_disk},
cpu::get_cpu_name,
disk::PartitionTableType,
drivers,
},
tasks::{Task, TaskResult, TaskType, Tasks},
@ -40,7 +39,6 @@ use core::{
use std::{
env,
iter::zip,
path::PathBuf,
sync::{Arc, Mutex},
};
@ -54,9 +52,12 @@ use ratatui::{
use tokio::sync::mpsc;
use tracing::{debug, info};
use crate::diags::{
DiagGroup, Type as DiagType, get_diag_type, parse_bcd, parse_bitlocker, parse_chkdsk,
parse_dism, parse_registry_hives, parse_system_files,
use crate::{
diags::{
DiagGroup, Type as DiagType, get_diag_type, parse_bcd, parse_bitlocker, parse_chkdsk,
parse_dism, parse_registry_hives, parse_system_files,
},
scan,
};
pub struct App {
@ -204,7 +205,13 @@ impl App {
popup::Type::Info,
String::from("Gathering info..."),
))?;
self.queue_boot_scan_tasks()?;
scan::queue_boot_scan_tasks(
self.action_tx.clone(),
&self.clone,
self.diag_groups.clone(),
self.system32.clone(),
&mut self.tasks,
)?;
}
Mode::InjectDrivers | Mode::InstallDrivers => self.clone.scan_drivers(),
Mode::Process => {
@ -546,159 +553,6 @@ impl App {
Ok(())
}
fn queue_boot_scan_tasks(&mut self) -> Result<()> {
if let Ok(mut diag_groups) = self.diag_groups.lock() {
diag_groups.clear();
}
let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest {
if let Some(disk) = disk_list.get(disk_index) {
let table_type = disk.part_type.clone();
let letter_boot = disk.get_part_letter(self.clone.part_index_boot.unwrap());
let letter_os = disk.get_part_letter(self.clone.part_index_os.unwrap());
// Safety check
if letter_os.is_empty() {
if letter_boot.is_empty() {
self.action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to get drive letters for the boot and OS volumes",
)))?;
} else {
self.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() {
self.tasks.add_group(
DiagType::BootConfigData.to_string().as_str(),
vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\bcdedit.exe", &self.system32)),
vec![
String::from("/store"),
format!(
"{letter_boot}:{}\\Boot\\BCD",
if table_type == PartitionTableType::Guid {
"\\EFI\\Microsoft"
} else {
""
}
),
String::from("/enum"),
],
)],
);
}
// Bitlocker
self.tasks.add_group(
DiagType::Bitlocker.to_string().as_str(),
vec![
TaskType::CommandWait(
PathBuf::from(format!("{}\\manage-bde.exe", &self.system32)),
vec![String::from("-status"), format!("{letter_os}:")],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\manage-bde.exe", &self.system32)),
vec![
String::from("-protectors"),
String::from("-get"),
format!("{letter_os}:"),
],
),
],
);
// Filesystem Health
self.tasks.add_group(
DiagType::CheckDisk.to_string().as_str(),
vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\chkdsk.exe", &self.system32)),
vec![format!("{letter_os}:")],
)],
);
// DISM Health
self.tasks.add_group(
DiagType::ComponentStore.to_string().as_str(),
vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\dism.exe", &self.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();
self.tasks.add_group(
DiagType::SystemFiles.to_string().as_str(),
vec![TaskType::TestPaths(paths)],
);
// Registry
self.tasks.add_group(
DiagType::Registry.to_string().as_str(),
vec![
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &self.system32)),
vec![
String::from("load"),
String::from("HKLM\\TmpSoftware"),
format!("{letter_os}:\\Windows\\System32\\config\\SOFTWARE"),
],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &self.system32)),
vec![
String::from("load"),
String::from("HKLM\\TmpSystem"),
format!("{letter_os}:\\Windows\\System32\\config\\SYSTEM"),
],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &self.system32)),
vec![
String::from("load"),
String::from("HKU\\TmpDefault"),
format!("{letter_os}:\\Windows\\System32\\config\\DEFAULT"),
],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &self.system32)),
vec![String::from("unload"), String::from("HKLM\\TmpSoftware")],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &self.system32)),
vec![String::from("unload"), String::from("HKLM\\TmpSystem")],
),
TaskType::CommandWait(
PathBuf::from(format!("{}\\reg.exe", &self.system32)),
vec![String::from("unload"), String::from("HKU\\TmpDefault")],
),
],
);
self.tasks.add(TaskType::Sleep); // NOTE: DELETEME
}
}
Ok(())
}
fn render(&mut self, tui: &mut Tui) -> Result<()> {
tui.draw(|frame| {
if let [header, _body, footer, left, right, popup, progress, results] =

View file

@ -21,6 +21,7 @@ use crate::app::App;
mod app;
mod components;
mod diags;
mod scan;
#[tokio::main]
async fn main() -> Result<()> {

169
boot_diags/src/scan.rs Normal file
View file

@ -0,0 +1,169 @@
use color_eyre::Result;
use core::state::CloneSettings;
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};
pub fn queue_boot_scan_tasks(
action_tx: mpsc::UnboundedSender<Action>,
clone: &CloneSettings,
diag_groups: Arc<Mutex<Vec<DiagGroup>>>,
system32: String,
tasks: &mut Tasks,
) -> Result<()> {
if let Ok(mut diag_groups) = diag_groups.lock() {
diag_groups.clear();
}
let disk_list = clone.disk_list.lock().unwrap();
if let Some(disk_index) = clone.disk_index_dest {
if let Some(disk) = disk_list.get(disk_index) {
let table_type = disk.part_type.clone();
let letter_boot = disk.get_part_letter(clone.part_index_boot.unwrap());
let letter_os = disk.get_part_letter(clone.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(())
}