WIP: Add boot mode options to boot-diags

This commit is contained in:
2Shirt 2025-01-25 23:56:35 -08:00
parent 1ce7f76229
commit b2b90bb946
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
2 changed files with 92 additions and 29 deletions

View file

@ -22,11 +22,16 @@ use core::{
config::Config, config::Config,
line::{get_disk_description_right, get_part_description, DVLine}, line::{get_disk_description_right, get_part_description, DVLine},
state::{CloneSettings, Mode}, state::{CloneSettings, Mode},
system::{cpu::get_cpu_name, drivers}, system::{
boot::{self, SafeMode},
cpu::get_cpu_name,
drivers,
},
tasks::{Task, Tasks}, tasks::{Task, Tasks},
tui::{Event, Tui}, tui::{Event, Tui},
}; };
use std::{ use std::{
env,
iter::zip, iter::zip,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
@ -41,13 +46,6 @@ use ratatui::{
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::{debug, info}; use tracing::{debug, info};
#[derive(Clone, Debug, Default)]
pub enum SafeMode {
#[default]
Disable,
Enable,
}
pub struct App { pub struct App {
// TUI // TUI
action_rx: mpsc::UnboundedReceiver<Action>, action_rx: mpsc::UnboundedReceiver<Action>,
@ -65,6 +63,7 @@ pub struct App {
list: StatefulList<Mode>, list: StatefulList<Mode>,
boot_modes: Vec<SafeMode>, boot_modes: Vec<SafeMode>,
selections: Vec<Option<usize>>, selections: Vec<Option<usize>>,
system32: String,
tasks: Tasks, tasks: Tasks,
} }
@ -103,6 +102,7 @@ impl App {
cur_mode: Mode::Home, cur_mode: Mode::Home,
list, list,
boot_modes: vec![SafeMode::Enable, SafeMode::Disable], boot_modes: vec![SafeMode::Enable, SafeMode::Disable],
system32: String::new(),
selections: vec![None, None], selections: vec![None, None],
tasks, tasks,
}) })
@ -124,6 +124,25 @@ impl App {
} }
} }
pub fn set_boot_mode(&mut self, boot_mode: SafeMode) {
info!("Setting boot mode to: {:?}", boot_mode);
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) {
if let Some(boot_index) = self.clone.part_index_boot {
if let Ok(task) = boot::set_mode(
disk.get_part_letter(boot_index).as_str(),
boot_mode,
&self.system32,
&disk.part_type,
) {
self.tasks.add(task);
};
}
}
}
}
pub fn set_mode(&mut self, new_mode: Mode) -> Result<()> { pub fn set_mode(&mut self, new_mode: Mode) -> Result<()> {
info!("Setting mode to {new_mode:?}"); info!("Setting mode to {new_mode:?}");
self.cur_mode = new_mode; self.cur_mode = new_mode;
@ -166,7 +185,22 @@ impl App {
} }
let action_tx = self.action_tx.clone(); let action_tx = self.action_tx.clone();
// Late init
self.system32 = if cfg!(windows) {
if let Ok(path) = env::var("SYSTEMROOT") {
format!("{path}/System32")
} else {
self.action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to find SYSTEMROOT",
)))?;
return Ok(());
}
} else {
String::from(".")
};
action_tx.send(Action::SetMode(Mode::ScanDisks))?; action_tx.send(Action::SetMode(Mode::ScanDisks))?;
loop { loop {
self.handle_events(&mut tui).await?; self.handle_events(&mut tui).await?;
self.handle_actions(&mut tui)?; self.handle_actions(&mut tui)?;
@ -299,8 +333,9 @@ impl App {
} }
Mode::SetBootMode => { Mode::SetBootMode => {
if let Some(index) = one { if let Some(index) = one {
// TODO: Make real if let Some(boot_mode) = self.boot_modes.get(index) {
info!("Setting boot mode to: {:?}", self.boot_modes.get(index)); self.set_boot_mode(boot_mode.to_owned());
}
} }
} }
_ => {} _ => {}

View file

@ -18,6 +18,13 @@ use crate::tasks::Task;
use color_eyre::Result; use color_eyre::Result;
use std::path::PathBuf; use std::path::PathBuf;
#[derive(Clone, Debug, Default)]
pub enum SafeMode {
#[default]
Disable,
Enable,
}
pub fn configure_disk( pub fn configure_disk(
letter_boot: &str, letter_boot: &str,
letter_os: &str, letter_os: &str,
@ -55,25 +62,10 @@ pub fn configure_disk(
} }
// Lock in safe mode // Lock in safe mode
let bcd_path = match table_type { tasks.push(
PartitionTableType::Guid => { set_mode(letter_boot, SafeMode::Enable, system32, &table_type)
format!("{letter_boot}:\\EFI\\Microsoft\\Boot\\BCD") .expect("Failed to create set_mode task."),
} );
PartitionTableType::Legacy => {
format!("{letter_boot}:\\Boot\\BCD")
}
};
tasks.push(Task::Command(
PathBuf::from(format!("{system32}/bcdedit.exe")),
vec![
String::from("/store"),
bcd_path,
String::from("/set"),
String::from("{default}"),
String::from("safeboot"),
String::from("minimal"),
],
));
// Done // Done
tasks tasks
@ -92,3 +84,39 @@ pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result
], ],
)) ))
} }
pub fn set_mode(
letter_boot: &str,
mode: SafeMode,
system32: &str,
table_type: &PartitionTableType,
) -> Result<Task> {
let bcd_path = match table_type {
PartitionTableType::Guid => {
format!("{letter_boot}:\\EFI\\Microsoft\\Boot\\BCD")
}
PartitionTableType::Legacy => {
format!("{letter_boot}:\\Boot\\BCD")
}
};
// Build Command
let mut cmd_args = vec![String::from("/store"), bcd_path];
match mode {
SafeMode::Disable => {
cmd_args.push(String::from("/deletevalue"));
cmd_args.push(String::from("{default}"));
cmd_args.push(String::from("safeboot"));
}
SafeMode::Enable => {
cmd_args.push(String::from("/set"));
cmd_args.push(String::from("{default}"));
cmd_args.push(String::from("safeboot"));
cmd_args.push(String::from("minimal"));
}
}
Ok(Task::Command(
PathBuf::from(format!("{system32}/bcdedit.exe")),
cmd_args,
))
}