Update boot-diags menus

This commit is contained in:
2Shirt 2025-07-05 17:38:44 -07:00
parent 46e53ef105
commit 827451322d
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
5 changed files with 126 additions and 68 deletions

View file

@ -29,7 +29,7 @@ use core::{
line::{DVLine, get_disk_description_right, get_part_description}, line::{DVLine, get_disk_description_right, get_part_description},
state::{CloneSettings, Mode}, state::{CloneSettings, Mode},
system::{ system::{
boot::{self, SafeMode}, boot::{self, SafeMode, configure_disk},
cpu::get_cpu_name, cpu::get_cpu_name,
disk::PartitionTableType, disk::PartitionTableType,
drivers, drivers,
@ -76,6 +76,7 @@ pub struct App {
diag_groups: Arc<Mutex<Vec<DiagGroup>>>, diag_groups: Arc<Mutex<Vec<DiagGroup>>>,
list: StatefulList<Mode>, list: StatefulList<Mode>,
boot_modes: Vec<SafeMode>, boot_modes: Vec<SafeMode>,
setup_modes: Vec<SafeMode>,
selections: Vec<Option<usize>>, selections: Vec<Option<usize>>,
system32: String, system32: String,
tasks: Tasks, tasks: Tasks,
@ -122,6 +123,7 @@ impl App {
diag_groups: diag_groups_arc, diag_groups: diag_groups_arc,
list, list,
boot_modes: vec![SafeMode::Enable, SafeMode::Disable], boot_modes: vec![SafeMode::Enable, SafeMode::Disable],
setup_modes: vec![SafeMode::Disable, SafeMode::Enable],
system32: String::new(), system32: String::new(),
selections: vec![None, None], selections: vec![None, None],
tasks, tasks,
@ -154,9 +156,10 @@ impl App {
Mode::ScanDisks => Mode::SelectDisks, Mode::ScanDisks => Mode::SelectDisks,
Mode::SelectDisks => Mode::SelectParts, Mode::SelectDisks => Mode::SelectParts,
Mode::SelectParts => Mode::DiagMenu, Mode::SelectParts => Mode::DiagMenu,
Mode::BootDiags | Mode::BootSetup => Mode::DiagMenu, Mode::BootDiags => Mode::DiagMenu,
Mode::BootScan => Mode::BootDiags, Mode::BootScan => Mode::BootDiags,
Mode::InjectDrivers | Mode::SetBootMode => Mode::DiagMenu, Mode::BootSetup | Mode::InjectDrivers | Mode::SetBootMode => Mode::Process,
Mode::Process => Mode::DiagMenu,
Mode::Done => Mode::DiagMenu, Mode::Done => Mode::DiagMenu,
Mode::Failed => Mode::Failed, Mode::Failed => Mode::Failed,
// Default to current mode // Default to current mode
@ -204,6 +207,10 @@ impl App {
self.queue_boot_scan_tasks()?; self.queue_boot_scan_tasks()?;
} }
Mode::InjectDrivers | Mode::InstallDrivers => self.clone.scan_drivers(), Mode::InjectDrivers | Mode::InstallDrivers => self.clone.scan_drivers(),
Mode::Process => {
self.action_tx
.send(Action::DisplayPopup(popup::Type::Info, String::from("...")))?;
}
Mode::ScanDisks => { Mode::ScanDisks => {
if self.tasks.idle() { if self.tasks.idle() {
self.tasks.add(TaskType::ScanDisks); self.tasks.add(TaskType::ScanDisks);
@ -361,10 +368,6 @@ impl App {
Mode::Done => { Mode::Done => {
self.action_tx.send(Action::NextScreen)?; self.action_tx.send(Action::NextScreen)?;
} }
Mode::BootSetup => {
let new_mode = self.next_mode();
self.action_tx.send(Action::SetMode(new_mode))?;
}
_ => {} _ => {}
}, },
Action::Resize(w, h) => self.handle_resize(tui, w, h)?, Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
@ -384,6 +387,14 @@ impl App {
} }
} }
} }
Mode::BootSetup => {
if let Some(index) = one {
if let Some(boot_mode) = self.setup_modes.get(index) {
info!("create_boot_files?");
create_boot_files(self, boot_mode.clone());
}
}
}
Mode::SelectDisks => { Mode::SelectDisks => {
self.clone.disk_index_dest = one; self.clone.disk_index_dest = one;
} }
@ -774,19 +785,17 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
fn build_footer_string(cur_mode: Mode) -> String { fn build_footer_string(cur_mode: Mode) -> String {
match cur_mode { match cur_mode {
Mode::BootDiags => { Mode::BootDiags | Mode::BootSetup | Mode::InjectDrivers | Mode::SetBootMode => {
String::from("(Enter) to select / (m) for menu / (s) to start over / (q) to quit") String::from("(Enter) to select / (m) for menu / (s) to start over / (q) to quit")
} }
Mode::BootScan | Mode::BootSetup | Mode::Home | Mode::ScanDisks => { Mode::BootScan | Mode::Home | Mode::Process | Mode::ScanDisks => {
String::from("(q) to quit") String::from("(q) to quit")
} }
Mode::DiagMenu | Mode::SelectParts => { Mode::DiagMenu | Mode::SelectParts => {
String::from("(Enter) to select / (s) to start over / (q) to quit") String::from("(Enter) to select / (s) to start over / (q) to quit")
} }
Mode::Done => String::from("(Enter) to continue / (q) to quit"), Mode::Done => String::from("(Enter) to continue / (q) to quit"),
Mode::InstallDrivers | Mode::InjectDrivers | Mode::SetBootMode => { Mode::InstallDrivers => String::from("(Enter) to select / (q) to quit"),
String::from("(Enter) to select / (q) to quit")
}
Mode::LogView => { Mode::LogView => {
String::from("(Enter | Esc) to close log / (up | down) to scroll / (q) to quit") String::from("(Enter | Esc) to close log / (up | down) to scroll / (q) to quit")
} }
@ -848,7 +857,7 @@ fn build_left_items(app: &App) -> Action {
.iter() .iter()
.for_each(|disk| items.push(disk.description.to_string())); .for_each(|disk| items.push(disk.description.to_string()));
} }
Mode::BootScan | Mode::ScanDisks => { Mode::BootScan | Mode::Process | Mode::ScanDisks => {
select_type = SelectionType::Loop; select_type = SelectionType::Loop;
title = String::from("Processing"); title = String::from("Processing");
} }
@ -887,13 +896,18 @@ fn build_left_items(app: &App) -> Action {
} }
} }
Mode::BootSetup => { Mode::BootSetup => {
select_type = SelectionType::Loop; select_type = SelectionType::One;
let (new_title, _) = get_mode_strings(app.cur_mode); let (new_title, _) = get_mode_strings(app.cur_mode);
title = new_title; title = new_title;
app.boot_modes.iter().rev().for_each(|entry| match entry {
SafeMode::Disable => items.push(String::from("Normal Mode")),
SafeMode::Enable => items.push(String::from("Locked in Safe Mode")),
});
} }
Mode::SetBootMode => { Mode::SetBootMode => {
select_type = SelectionType::One; select_type = SelectionType::One;
title = String::from("Set Boot Mode"); let (new_title, _) = get_mode_strings(app.cur_mode);
title = new_title;
app.boot_modes.iter().for_each(|entry| { app.boot_modes.iter().for_each(|entry| {
items.push(format!("{:?} Safe Mode", entry)); items.push(format!("{:?} Safe Mode", entry));
}); });
@ -919,13 +933,37 @@ fn build_right_items(app: &App) -> Action {
let mut items: Vec<Vec<DVLine>> = Vec::new(); let mut items: Vec<Vec<DVLine>> = Vec::new();
let mut labels: Vec<Vec<DVLine>> = Vec::new(); let mut labels: Vec<Vec<DVLine>> = Vec::new();
let mut start_index = 0; let mut start_index = 0;
let disk_header = get_disk_header(app);
match app.cur_mode { match app.cur_mode {
Mode::DiagMenu => { Mode::BootDiags
let header_lines = get_disk_header(app); | Mode::BootSetup
if !header_lines.is_empty() { | Mode::DiagMenu
items.push(header_lines); | Mode::InjectDrivers
| Mode::InstallDrivers
| Mode::Process
| Mode::SetBootMode => {
items.push(vec![DVLine {
line_parts: vec![String::from("CPU")],
line_colors: vec![Color::Cyan],
}]);
items.push(vec![DVLine {
line_parts: vec![get_cpu_name()],
line_colors: vec![Color::Reset],
}]);
items.push(vec![DVLine {
line_parts: vec![String::new()],
line_colors: vec![Color::Reset],
}]);
start_index += 3;
if !disk_header.is_empty() {
items.push(disk_header);
start_index += 1; start_index += 1;
} }
}
_ => {}
}
match app.cur_mode {
Mode::DiagMenu => {
app.list.items.iter().for_each(|mode| { app.list.items.iter().for_each(|mode| {
let (name, description) = get_mode_strings(*mode); let (name, description) = get_mode_strings(*mode);
items.push(vec![ items.push(vec![
@ -945,11 +983,6 @@ fn build_right_items(app: &App) -> Action {
}); });
} }
Mode::BootDiags => { Mode::BootDiags => {
let header_lines = get_disk_header(app);
if !header_lines.is_empty() {
items.push(header_lines);
start_index += 1;
}
if let Ok(diag_groups) = app.diag_groups.lock() { if let Ok(diag_groups) = app.diag_groups.lock() {
let mut summary: Vec<DVLine> = Vec::new(); let mut summary: Vec<DVLine> = Vec::new();
diag_groups diag_groups
@ -958,16 +991,15 @@ fn build_right_items(app: &App) -> Action {
items.push(summary); items.push(summary);
} }
} }
Mode::InjectDrivers | Mode::InstallDrivers => { Mode::BootSetup => {
items.push(vec![DVLine { items.push(vec![DVLine {
line_parts: vec![String::from("CPU")], line_parts: vec![String::from("Normal Mode")],
line_colors: vec![Color::Cyan], line_colors: vec![Color::Reset],
}]); }]);
items.push(vec![DVLine { items.push(vec![DVLine {
line_parts: vec![get_cpu_name()], line_parts: vec![String::from("Safe Mode")],
line_colors: vec![Color::Reset], line_colors: vec![Color::Reset],
}]); }]);
start_index += 2;
} }
Mode::SelectDisks => { Mode::SelectDisks => {
let dest_dv_line = DVLine { let dest_dv_line = DVLine {
@ -1002,28 +1034,41 @@ fn build_right_items(app: &App) -> Action {
} }
} }
Mode::SetBootMode => { Mode::SetBootMode => {
app.boot_modes.iter().for_each(|mode| { items.push(vec![DVLine {
match mode { line_parts: vec![String::from("Enable Safe Mode (minimal)")],
SafeMode::Disable => { line_colors: vec![Color::Reset],
items.push(vec![DVLine { }]);
line_parts: vec![String::from("Disable Safe Mode")], items.push(vec![DVLine {
line_colors: vec![Color::Reset], line_parts: vec![String::from("Disable Safe Mode")],
}]); line_colors: vec![Color::Reset],
} }]);
SafeMode::Enable => {
items.push(vec![DVLine {
line_parts: vec![String::from("Enable Safe Mode (minimal)")],
line_colors: vec![Color::Reset],
}]);
}
};
});
} }
_ => {} _ => {}
} }
Action::UpdateRight(labels, start_index, items) Action::UpdateRight(labels, start_index, items)
} }
fn create_boot_files(app: &mut App, safe_mode: SafeMode) {
let mut tasks: Vec<TaskType> = Vec::new();
if let Some(index) = app.clone.disk_index_dest {
let disk_list = app.clone.disk_list.lock().unwrap();
if let Some(disk) = disk_list.get(index) {
let letter_boot = disk.get_part_letter(app.clone.part_index_boot.unwrap());
let letter_os = disk.get_part_letter(app.clone.part_index_os.unwrap());
tasks = configure_disk(
&letter_boot,
&letter_os,
safe_mode,
&app.system32,
&disk.part_type,
);
}
}
tasks
.into_iter()
.for_each(|task_type| app.tasks.add(task_type));
}
fn get_disk_header(app: &App) -> Vec<DVLine> { fn get_disk_header(app: &App) -> Vec<DVLine> {
let mut header_lines: Vec<DVLine> = Vec::new(); let mut header_lines: Vec<DVLine> = Vec::new();
if let Some(index) = app.clone.disk_index_dest { if let Some(index) = app.clone.disk_index_dest {
@ -1036,17 +1081,6 @@ fn get_disk_header(app: &App) -> Vec<DVLine> {
if let Some(index) = app.clone.part_index_os { if let Some(index) = app.clone.part_index_os {
parts.push(index); parts.push(index);
} }
// Disk Details
header_lines.append(&mut vec![
DVLine {
line_parts: vec![String::from("Disk")],
line_colors: vec![Color::Cyan],
},
DVLine {
line_parts: vec![String::new()],
line_colors: vec![Color::Reset],
},
]);
header_lines.append(&mut get_disk_description_right(disk, &Some(parts))); header_lines.append(&mut get_disk_description_right(disk, &Some(parts)));
} }
} }

View file

@ -127,6 +127,8 @@
"<Enter>": "Process", "<Enter>": "Process",
"<Up>": "KeyUp", "<Up>": "KeyUp",
"<Down>": "KeyDown", "<Down>": "KeyDown",
"<m>": "DiagMainMenu",
"<s>": "ScanDisks",
"<q>": "Quit", "<q>": "Quit",
"<Ctrl-d>": "Quit", "<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",
@ -150,6 +152,14 @@
"<Enter>": "Process", "<Enter>": "Process",
"<Up>": "KeyUp", "<Up>": "KeyUp",
"<Down>": "KeyDown", "<Down>": "KeyDown",
"<m>": "DiagMainMenu",
"<s>": "ScanDisks",
"<q>": "Quit",
"<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit",
"<Ctrl-z>": "Suspend"
},
"Process": {
"<q>": "Quit", "<q>": "Quit",
"<Ctrl-d>": "Quit", "<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",
@ -159,6 +169,8 @@
"<Enter>": "Process", "<Enter>": "Process",
"<Up>": "KeyUp", "<Up>": "KeyUp",
"<Down>": "KeyDown", "<Down>": "KeyDown",
"<m>": "DiagMainMenu",
"<s>": "ScanDisks",
"<q>": "Quit", "<q>": "Quit",
"<Ctrl-d>": "Quit", "<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",

View file

@ -36,6 +36,7 @@ pub enum Mode {
BootScan, BootScan,
BootSetup, BootSetup,
LogView, LogView,
Process,
InjectDrivers, InjectDrivers,
SetBootMode, SetBootMode,
// Clone // Clone

View file

@ -20,7 +20,7 @@ use crate::tasks::TaskType;
use color_eyre::Result; use color_eyre::Result;
use std::path::PathBuf; use std::path::PathBuf;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default, PartialEq)]
pub enum SafeMode { pub enum SafeMode {
#[default] #[default]
Disable, Disable,
@ -31,6 +31,7 @@ pub enum SafeMode {
pub fn configure_disk( pub fn configure_disk(
letter_boot: &str, letter_boot: &str,
letter_os: &str, letter_os: &str,
safe_mode: SafeMode,
system32: &str, system32: &str,
table_type: &PartitionTableType, table_type: &PartitionTableType,
) -> Vec<TaskType> { ) -> Vec<TaskType> {
@ -64,11 +65,13 @@ pub fn configure_disk(
)); ));
} }
// Lock in safe mode // Lock in safe mode (if needed)
tasks.push( if safe_mode == SafeMode::Enable {
set_mode(letter_boot, &SafeMode::Enable, system32, table_type) tasks.push(
.expect("Failed to create set_mode task."), set_mode(letter_boot, &SafeMode::Enable, system32, table_type)
); .expect("Failed to create set_mode task."),
);
}
// Done // Done
tasks tasks
@ -82,7 +85,7 @@ pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result
vec![ vec![
format!("/image:{letter_os}:\\"), format!("/image:{letter_os}:\\"),
String::from("/add-driver"), String::from("/add-driver"),
format!("/driver:\"{}\"", driver_path,), format!("/driver:{driver_path}"),
String::from("/recurse"), String::from("/recurse"),
], ],
)) ))

View file

@ -128,6 +128,7 @@ impl App {
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::LogView | Mode::LogView
| Mode::PEMenu | Mode::PEMenu
| Mode::Process
| Mode::SetBootMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
} }
} }
@ -152,6 +153,7 @@ impl App {
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::LogView | Mode::LogView
| Mode::PEMenu | Mode::PEMenu
| Mode::Process
| Mode::SetBootMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
@ -242,9 +244,13 @@ impl App {
} }
// Create boot files // Create boot files
for task in for task in boot::configure_disk(
boot::configure_disk(&letter_boot, &letter_os, &system32, &table_type) &letter_boot,
{ &letter_os,
boot::SafeMode::Enable,
&system32,
&table_type,
) {
self.tasks.add(task); self.tasks.add(task);
} }
@ -631,6 +637,7 @@ fn build_footer_string(cur_mode: Mode) -> String {
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::LogView | Mode::LogView
| Mode::PEMenu | Mode::PEMenu
| Mode::Process
| Mode::SetBootMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
} }
} }
@ -703,6 +710,7 @@ fn build_left_items(app: &App, cur_mode: Mode) -> Action {
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::LogView | Mode::LogView
| Mode::PEMenu | Mode::PEMenu
| Mode::Process
| Mode::SetBootMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
Action::UpdateLeft(title, labels, items, select_type) Action::UpdateLeft(title, labels, items, select_type)