Compare commits

..

4 commits

Author SHA1 Message Date
de7520324b
WIP: Add InjetDrivers section 2025-01-26 00:33:03 -08:00
b2b90bb946
WIP: Add boot mode options to boot-diags 2025-01-26 00:19:49 -08:00
1ce7f76229
WIP: Add BootMode menu logic 2025-01-25 22:59:06 -08:00
aa4ac8d5e8
WIP: Initial boot-diags outline
Currently not working

Update footer lines

WIP 47
2025-01-25 22:17:08 -08:00
8 changed files with 314 additions and 93 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},
}; };
@ -56,7 +61,9 @@ pub struct App {
clone: CloneSettings, clone: CloneSettings,
cur_mode: Mode, cur_mode: Mode,
list: StatefulList<Mode>, list: StatefulList<Mode>,
boot_modes: Vec<SafeMode>,
selections: Vec<Option<usize>>, selections: Vec<Option<usize>>,
system32: String,
tasks: Tasks, tasks: Tasks,
} }
@ -70,7 +77,7 @@ impl App {
Mode::BootDiags, Mode::BootDiags,
Mode::BootSetup, Mode::BootSetup,
Mode::InjectDrivers, Mode::InjectDrivers,
Mode::ToggleSafeMode, Mode::SetBootMode,
]); ]);
Ok(Self { Ok(Self {
// TUI // TUI
@ -94,11 +101,32 @@ impl App {
clone: CloneSettings::new(disk_list_arc), clone: CloneSettings::new(disk_list_arc),
cur_mode: Mode::Home, cur_mode: Mode::Home,
list, list,
boot_modes: vec![SafeMode::Enable, SafeMode::Disable],
system32: String::new(),
selections: vec![None, None], selections: vec![None, None],
tasks, tasks,
}) })
} }
pub fn inject_driver(&mut self, index: usize) {
if let Some(driver) = self.clone.driver_list.get(index) {
if let Some(disk_index) = self.clone.disk_index_dest {
let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk) = disk_list.get(disk_index) {
if let Some(boot_index) = self.clone.part_index_boot {
if let Ok(task) = boot::inject_driver(
driver,
disk.get_part_letter(boot_index).as_str(),
&self.system32,
) {
self.tasks.add(task);
}
}
}
}
}
}
pub fn next_mode(&mut self) -> Mode { pub fn next_mode(&mut self) -> Mode {
match self.cur_mode { match self.cur_mode {
Mode::Home => Mode::ScanDisks, Mode::Home => Mode::ScanDisks,
@ -106,13 +134,8 @@ 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::DiagMenu => { Mode::BootDiags | Mode::BootSetup | Mode::InjectDrivers | Mode::SetBootMode => {
// Use highlighted entry Mode::DiagMenu
if let Some(new_mode) = self.list.get_selected() {
new_mode
} else {
self.cur_mode
}
} }
Mode::Failed => Mode::Failed, Mode::Failed => Mode::Failed,
// Default to current mode // Default to current mode
@ -120,10 +143,34 @@ 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;
match new_mode { match new_mode {
Mode::DiagMenu => {
self.selections[0] = None;
self.selections[1] = None;
self.list.select_first_item();
}
Mode::InjectDrivers | Mode::InstallDrivers => self.clone.scan_drivers(), Mode::InjectDrivers | Mode::InstallDrivers => self.clone.scan_drivers(),
Mode::ScanDisks => { Mode::ScanDisks => {
if self.tasks.idle() { if self.tasks.idle() {
@ -157,7 +204,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)?;
@ -247,8 +309,23 @@ impl App {
.send(Action::DisplayPopup(popup::Type::Error, msg.clone()))?; .send(Action::DisplayPopup(popup::Type::Error, msg.clone()))?;
self.action_tx.send(Action::SetMode(Mode::Failed))?; self.action_tx.send(Action::SetMode(Mode::Failed))?;
} }
Action::InstallDriver => {
self.action_tx.send(Action::SetMode(Mode::InstallDrivers))?;
}
Action::NextScreen => {
let next_mode = self.next_mode();
self.cur_mode = next_mode;
self.action_tx.send(Action::DismissPopup)?;
self.action_tx.send(Action::SetMode(next_mode))?;
}
Action::Process => match self.cur_mode { Action::Process => match self.cur_mode {
Mode::DiagMenu => { Mode::DiagMenu => {
// Use highlighted entry
if let Some(new_mode) = self.list.get_selected() {
self.action_tx.send(Action::SetMode(new_mode))?;
}
}
Mode::BootDiags | Mode::BootSetup => {
let new_mode = self.next_mode(); let new_mode = self.next_mode();
self.action_tx.send(Action::SetMode(new_mode))?; self.action_tx.send(Action::SetMode(new_mode))?;
} }
@ -257,30 +334,37 @@ impl App {
Action::Resize(w, h) => self.handle_resize(tui, w, h)?, Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
Action::Render => self.render(tui)?, Action::Render => self.render(tui)?,
Action::ScanDisks => self.action_tx.send(Action::SetMode(Mode::ScanDisks))?, Action::ScanDisks => self.action_tx.send(Action::SetMode(Mode::ScanDisks))?,
Action::Select(one, two) => { Action::Select(one, two) => match self.cur_mode {
match self.cur_mode { Mode::InjectDrivers => {
Mode::InstallDrivers => { if let Some(index) = one {
if let Some(index) = one { self.inject_driver(index);
if let Some(driver) = self.clone.driver_list.get(index).cloned() { }
drivers::load(&driver.inf_paths); }
self.clone.driver = Some(driver); Mode::InstallDrivers => {
} if let Some(index) = one {
if let Some(driver) = self.clone.driver_list.get(index).cloned() {
drivers::load(&driver.inf_paths);
self.clone.driver = Some(driver);
} }
} }
Mode::SelectDisks => {
self.clone.disk_index_dest = one;
}
Mode::SelectParts => {
self.clone.part_index_boot = one;
self.clone.part_index_os = two;
}
_ => {}
} }
self.selections[0] = one; Mode::SelectDisks => {
self.selections[1] = two; self.clone.disk_index_dest = one;
} }
Mode::SelectParts => {
self.clone.part_index_boot = one;
self.clone.part_index_os = two;
}
Mode::SetBootMode => {
if let Some(index) = one {
if let Some(boot_mode) = self.boot_modes.get(index) {
self.set_boot_mode(boot_mode.to_owned());
}
}
}
_ => {}
},
Action::SetMode(new_mode) => { Action::SetMode(new_mode) => {
self.cur_mode = new_mode;
self.set_mode(new_mode)?; self.set_mode(new_mode)?;
self.action_tx self.action_tx
.send(Action::UpdateFooter(build_footer_string(self.cur_mode)))?; .send(Action::UpdateFooter(build_footer_string(self.cur_mode)))?;
@ -382,23 +466,28 @@ 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 {
// Boot Diags Mode::BootDiags | Mode::BootSetup | Mode::Home | Mode::PEMenu | Mode::ScanDisks => {
Mode::BootSetup String::from("(q) to quit")
| Mode::DiagMenu }
| Mode::InjectDrivers Mode::InstallDrivers | Mode::InjectDrivers | Mode::SetBootMode => {
| Mode::PEMenu String::from("(Enter) to select / (q) to quit")
| Mode::ToggleSafeMode => String::from("(Enter) or (q) to quit"), }
// Copied from Clone Mode::DiagMenu | Mode::SelectParts => {
Mode::Home | Mode::ScanDisks | Mode::BootDiags => String::from("(q) to quit"), String::from("(Enter) to select / (s) to start over / (q) to quit")
Mode::SelectParts => String::from("(Enter) to select / (s) to start over / (q) to quit"), }
Mode::SelectDisks => String::from( Mode::SelectDisks => String::from(
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit", "(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
), ),
Mode::SelectTableType => String::from("(Enter) to select / (b) to go back / (q) to quit"), Mode::Failed => String::from("(Enter) or (q) to quit"),
Mode::Confirm => String::from("(Enter) to confirm / (b) to go back / (q) to quit"),
Mode::Done | Mode::Failed | Mode::InstallDrivers => String::from("(Enter) or (q) to quit"),
// Invalid states // Invalid states
Mode::Clone | Mode::PreClone | Mode::PostClone => panic!("This shouldn't happen?"), Mode::Confirm
| Mode::Clone
| Mode::PreClone
| Mode::PostClone
| Mode::Done
| Mode::SelectTableType => {
panic!("This shouldn't happen?")
}
} }
} }
@ -451,8 +540,8 @@ fn build_left_items(app: &App) -> Action {
Mode::SelectParts => { Mode::SelectParts => {
select_num = 2; select_num = 2;
title = String::from("Select Boot and OS Partitions"); title = String::from("Select Boot and OS Partitions");
labels.push(String::from("boot")); labels[0] = String::from("boot");
labels.push(String::from("os")); labels[1] = String::from("os");
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
if let Some(index) = app.clone.disk_index_dest { if let Some(index) = app.clone.disk_index_dest {
if let Some(disk) = disk_list.get(index) { if let Some(disk) = disk_list.get(index) {
@ -462,11 +551,18 @@ fn build_left_items(app: &App) -> Action {
} }
} }
} }
Mode::BootDiags | Mode::BootSetup | Mode::ToggleSafeMode => { Mode::BootDiags | Mode::BootSetup => {
select_num = 0; select_num = 0;
let (new_title, _) = get_mode_strings(app.cur_mode); let (new_title, _) = get_mode_strings(app.cur_mode);
title = new_title; title = new_title;
} }
Mode::SetBootMode => {
select_num = 1;
title = String::from("Set Boot Mode");
app.boot_modes.iter().for_each(|entry| {
items.push(format!("{:?} Safe Mode", entry));
});
}
Mode::Done | Mode::Failed => { Mode::Done | Mode::Failed => {
select_num = 0; select_num = 0;
title = String::from("Done"); title = String::from("Done");
@ -485,11 +581,72 @@ fn build_left_items(app: &App) -> Action {
} }
fn build_right_items(app: &App) -> Action { fn build_right_items(app: &App) -> Action {
let mut items = 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;
// TODO: DELETE THIS SECTION
start_index = 1;
items.push(vec![
DVLine {
line_parts: vec![format!("Mode: {:?}", app.cur_mode)],
line_colors: vec![Color::Reset],
},
DVLine {
line_parts: vec![format!(
"Parts: {:?} // {:?}",
app.clone.part_index_boot, app.clone.part_index_os
)],
line_colors: vec![Color::Reset],
},
DVLine {
line_parts: vec![format!(
"Selected: {:?} // {:?}",
app.list.selected(),
app.list.get_selected(),
)],
line_colors: vec![Color::Reset],
},
DVLine {
line_parts: vec![String::from("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")],
line_colors: vec![Color::Reset],
},
]);
// TODO: DELETE THIS SECTION
match app.cur_mode { match app.cur_mode {
Mode::DiagMenu => { Mode::DiagMenu => {
let mut header_lines: Vec<DVLine> = 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 mut parts: Vec<usize> = Vec::new();
if let Some(index) = app.clone.part_index_boot {
parts.push(index);
}
if let Some(index) = app.clone.part_index_os {
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)));
// Add header
if !header_lines.is_empty() {
items[0].append(&mut header_lines);
// TODO: Replace line above with lines below
// items.push(header_lines);
// start_index = 1;
}
}
}
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![
@ -522,13 +679,13 @@ fn build_right_items(app: &App) -> Action {
Mode::SelectDisks => { Mode::SelectDisks => {
let dest_dv_line = DVLine { let dest_dv_line = DVLine {
line_parts: vec![String::from("Disk")], line_parts: vec![String::from("Disk")],
line_colors: vec![Color::Cyan, Color::Red], line_colors: vec![Color::Cyan],
}; };
labels.push(vec![dest_dv_line]); labels.push(vec![dest_dv_line]);
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
disk_list disk_list
.iter() .iter()
.for_each(|disk| items.push(get_disk_description_right(&disk))); .for_each(|disk| items.push(get_disk_description_right(&disk, None)));
} }
Mode::SelectParts => { Mode::SelectParts => {
vec!["Boot", "OS"].iter().for_each(|s| { vec!["Boot", "OS"].iter().for_each(|s| {
@ -542,7 +699,7 @@ fn build_right_items(app: &App) -> Action {
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
if let Some(disk) = disk_list.get(index) { if let Some(disk) = disk_list.get(index) {
// Disk Details // Disk Details
items.push(get_disk_description_right(&disk)); items.push(get_disk_description_right(&disk, None));
// Partition Details // Partition Details
disk.parts disk.parts
@ -551,6 +708,24 @@ fn build_right_items(app: &App) -> Action {
} }
} }
} }
Mode::SetBootMode => {
app.boot_modes.iter().for_each(|mode| {
match mode {
SafeMode::Disable => {
items.push(vec![DVLine {
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)
@ -570,7 +745,7 @@ fn get_mode_strings(mode: Mode) -> (String, String) {
String::from("Inject Drivers"), String::from("Inject Drivers"),
String::from("Inject drivers into existing Windows environment"), String::from("Inject drivers into existing Windows environment"),
), ),
Mode::ToggleSafeMode => ( Mode::SetBootMode => (
String::from("Toggle Safe Mode"), String::from("Toggle Safe Mode"),
String::from("Enable or disable safe mode"), String::from("Enable or disable safe mode"),
), ),

View file

@ -99,6 +99,7 @@
"<Enter>": "Process", "<Enter>": "Process",
"<Up>": "KeyUp", "<Up>": "KeyUp",
"<Down>": "KeyDown", "<Down>": "KeyDown",
"<s>": "ScanDisks",
"<q>": "Quit", "<q>": "Quit",
"<Ctrl-d>": "Quit", "<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",
@ -131,7 +132,7 @@
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",
"<Ctrl-z>": "Suspend" "<Ctrl-z>": "Suspend"
}, },
"ToggleSafeMode": { "SetBootMode": {
"<Enter>": "Process", "<Enter>": "Process",
"<Up>": "KeyUp", "<Up>": "KeyUp",
"<Down>": "KeyDown", "<Down>": "KeyDown",

View file

@ -138,14 +138,10 @@ impl Component for Left {
.areas(area); .areas(area);
// Title // Title
let title_text = if self.selections[1].is_some() || self.select_num == 1 { let title = Paragraph::new(
"Confirm Selections" Line::from(Span::styled(self.title_text.as_str(), Style::default())).centered(),
} else { )
self.title_text.as_str() .block(Block::default().borders(Borders::NONE));
};
let title =
Paragraph::new(Line::from(Span::styled(title_text, Style::default())).centered())
.block(Block::default().borders(Borders::NONE));
frame.render_widget(title, title_area); frame.render_widget(title, title_area);
// Body (Blank) // Body (Blank)

View file

@ -55,7 +55,7 @@ impl<T: Clone> StatefulList<T> {
self.state.selected() self.state.selected()
} }
fn select_first_item(&mut self) { pub fn select_first_item(&mut self) {
if self.items.is_empty() { if self.items.is_empty() {
self.state.select(None); self.state.select(None);
} else { } else {

View file

@ -45,7 +45,10 @@ impl DVLine {
} }
} }
pub fn get_disk_description_right(disk: &Disk) -> Vec<DVLine> { pub fn get_disk_description_right(
disk: &Disk,
boot_os_indicies: Option<Vec<usize>>,
) -> Vec<DVLine> {
let mut description: Vec<DVLine> = vec![ let mut description: Vec<DVLine> = vec![
DVLine { DVLine {
line_parts: vec![format!( line_parts: vec![format!(
@ -67,12 +70,29 @@ pub fn get_disk_description_right(disk: &Disk) -> Vec<DVLine> {
line_colors: vec![Color::Blue], line_colors: vec![Color::Blue],
}, },
]; ];
for line in &disk.parts_description { disk.parts_description
description.push(DVLine { .iter()
line_parts: vec![line.clone()], .enumerate()
line_colors: vec![Color::Reset], .for_each(|(index, line)| {
let mut line_parts = vec![line.clone()];
let mut line_colors = vec![Color::Reset];
if let Some(indicies) = &boot_os_indicies {
let boot_index = indicies.get(0);
if boot_index.is_some_and(|i| i == &index) {
line_parts.push(String::from(" <-- Boot Partition"));
line_colors.push(Color::Cyan);
}
let boot_index = indicies.get(1);
if boot_index.is_some_and(|i| i == &index) {
line_parts.push(String::from(" <-- OS Partition"));
line_colors.push(Color::Cyan);
}
}
description.push(DVLine {
line_parts,
line_colors,
});
}); });
}
description description
} }

View file

@ -35,7 +35,7 @@ pub enum Mode {
BootDiags, BootDiags,
BootSetup, BootSetup,
InjectDrivers, InjectDrivers,
ToggleSafeMode, SetBootMode,
// Clone // Clone
ScanDisks, ScanDisks,
InstallDrivers, InstallDrivers,

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,
))
}

View file

@ -120,7 +120,7 @@ impl App {
| Mode::DiagMenu | Mode::DiagMenu
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::PEMenu | Mode::PEMenu
| Mode::ToggleSafeMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
new_mode new_mode
} }
@ -144,7 +144,7 @@ impl App {
| Mode::DiagMenu | Mode::DiagMenu
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::PEMenu | Mode::PEMenu
| Mode::ToggleSafeMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
if new_mode == self.cur_mode { if new_mode == self.cur_mode {
@ -576,19 +576,20 @@ fn build_footer_string(cur_mode: Mode) -> String {
String::from("(q) to quit") String::from("(q) to quit")
} }
Mode::SelectParts => String::from("(Enter) to select / (s) to start over / (q) to quit"), Mode::SelectParts => String::from("(Enter) to select / (s) to start over / (q) to quit"),
Mode::InstallDrivers => String::from("(Enter) to select / (q) to quit"),
Mode::SelectDisks => String::from( Mode::SelectDisks => String::from(
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit", "(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
), ),
Mode::SelectTableType => String::from("(Enter) to select / (b) to go back / (q) to quit"), Mode::SelectTableType => String::from("(Enter) to select / (b) to go back / (q) to quit"),
Mode::Confirm => String::from("(Enter) to confirm / (b) to go back / (q) to quit"), Mode::Confirm => String::from("(Enter) to confirm / (b) to go back / (q) to quit"),
Mode::Done | Mode::Failed | Mode::InstallDrivers => String::from("(Enter) or (q) to quit"), Mode::Done | Mode::Failed => String::from("(Enter) or (q) to quit"),
// Invalid states // Invalid states
Mode::BootDiags Mode::BootDiags
| Mode::BootSetup | Mode::BootSetup
| Mode::DiagMenu | Mode::DiagMenu
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::PEMenu | Mode::PEMenu
| Mode::ToggleSafeMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
} }
} }
@ -658,7 +659,7 @@ fn build_left_items(app: &App, cur_mode: Mode) -> Action {
| Mode::DiagMenu | Mode::DiagMenu
| Mode::InjectDrivers | Mode::InjectDrivers
| Mode::PEMenu | Mode::PEMenu
| Mode::ToggleSafeMode => panic!("This shouldn't happen?"), | Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
Action::UpdateLeft(title, labels, items, select_num) Action::UpdateLeft(title, labels, items, select_num)
} }
@ -711,7 +712,7 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
disk_list disk_list
.iter() .iter()
.for_each(|disk| items.push(get_disk_description_right(&disk))); .for_each(|disk| items.push(get_disk_description_right(&disk, None)));
} }
Mode::SelectParts => { Mode::SelectParts => {
vec!["Boot", "OS"].iter().for_each(|s| { vec!["Boot", "OS"].iter().for_each(|s| {
@ -725,7 +726,7 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
if let Some(disk) = disk_list.get(index) { if let Some(disk) = disk_list.get(index) {
// Disk Details // Disk Details
items.push(get_disk_description_right(&disk)); items.push(get_disk_description_right(&disk, None));
// Partition Details // Partition Details
disk.parts disk.parts