Compare commits

..

No commits in common. "25b6fe4b7ea0ab6bd971db6c28dd5455e55f4850" and "c789f51bac0abc7ac2bd2ac07ecdf4936abd09ae" have entirely different histories.

16 changed files with 378 additions and 371 deletions

View file

@ -132,19 +132,20 @@ impl App {
} }
pub fn inject_driver(&mut self, index: usize) { pub fn inject_driver(&mut self, index: usize) {
if let Some(driver) = self.clone.driver_list.get(index) if let Some(driver) = self.clone.driver_list.get(index) {
&& let Some(disk_index) = self.clone.disk_index_dest if let Some(disk_index) = self.clone.disk_index_dest {
{ let disk_list = self.clone.disk_list.lock().unwrap();
let disk_list = self.clone.disk_list.lock().unwrap(); if let Some(disk) = disk_list.get(disk_index) {
if let Some(disk) = disk_list.get(disk_index) if let Some(os_index) = self.clone.part_index_os {
&& let Some(os_index) = self.clone.part_index_os if let Ok(task) = boot::inject_driver(
&& let Ok(task) = boot::inject_driver( driver,
driver, disk.get_part_letter(os_index).as_str(),
disk.get_part_letter(os_index).as_str(), &self.system32,
&self.system32, ) {
) self.tasks.add(task);
{ }
self.tasks.add(task); }
}
} }
} }
} }
@ -174,18 +175,20 @@ impl App {
}; };
info!("Setting boot mode to: {new_mode}"); info!("Setting boot mode to: {new_mode}");
let disk_list = self.clone.disk_list.lock().unwrap(); let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest if let Some(disk_index) = self.clone.disk_index_dest {
&& let Some(disk) = disk_list.get(disk_index) if let Some(disk) = disk_list.get(disk_index) {
&& let Some(boot_index) = self.clone.part_index_boot if let Some(boot_index) = self.clone.part_index_boot {
&& let Ok(task) = boot::set_mode( if let Ok(task) = boot::set_mode(
disk.get_part_letter(boot_index).as_str(), disk.get_part_letter(boot_index).as_str(),
&boot_mode, &boot_mode,
&self.system32, &self.system32,
&disk.part_type, &disk.part_type,
) ) {
{ self.tasks.add(task);
self.tasks.add(task); };
}; }
}
}
} }
pub fn set_mode(&mut self, new_mode: Mode) -> Result<()> { pub fn set_mode(&mut self, new_mode: Mode) -> Result<()> {
@ -384,19 +387,19 @@ impl App {
} }
} }
Mode::InstallDrivers => { Mode::InstallDrivers => {
if let Some(index) = one if let Some(index) = one {
&& let Some(driver) = self.clone.driver_list.get(index).cloned() if let Some(driver) = self.clone.driver_list.get(index).cloned() {
{ drivers::load(&driver.inf_paths);
drivers::load(&driver.inf_paths); self.clone.driver = Some(driver);
self.clone.driver = Some(driver); }
} }
} }
Mode::BootSetup => { Mode::BootSetup => {
if let Some(index) = one if let Some(index) = one {
&& let Some(boot_mode) = self.setup_modes.get(index) if let Some(boot_mode) = self.setup_modes.get(index) {
{ info!("create_boot_files?");
info!("create_boot_files?"); create_boot_files(self, boot_mode.clone());
create_boot_files(self, boot_mode.clone()); }
} }
} }
Mode::SelectDisks => { Mode::SelectDisks => {
@ -407,10 +410,10 @@ impl App {
self.clone.part_index_os = two; self.clone.part_index_os = two;
} }
Mode::SetBootMode => { Mode::SetBootMode => {
if let Some(index) = one if let Some(index) = one {
&& let Some(boot_mode) = self.boot_modes.get(index) if let Some(boot_mode) = self.boot_modes.get(index) {
{ self.set_boot_mode(boot_mode.to_owned());
self.set_boot_mode(boot_mode.to_owned()); }
} }
} }
_ => {} _ => {}
@ -430,7 +433,7 @@ impl App {
text: title.clone(), text: title.clone(),
})?; })?;
if let Ok(mut diag_groups) = self.diag_groups.lock() { if let Ok(mut diag_groups) = self.diag_groups.lock() {
diag_groups.push(DiagGroup::new(get_diag_type(title))); diag_groups.push(DiagGroup::new(get_diag_type(&title)));
} }
} }
} }
@ -461,57 +464,57 @@ impl App {
fn handle_task(&mut self, task: &Task) -> Result<()> { fn handle_task(&mut self, task: &Task) -> Result<()> {
info!("Handling Task: {task:?}"); info!("Handling Task: {task:?}");
if self.cur_mode == Mode::BootScan { if self.cur_mode == Mode::BootScan {
if let Ok(mut diag_groups) = self.diag_groups.lock() if let Ok(mut diag_groups) = self.diag_groups.lock() {
&& let Some(current_group) = diag_groups.last_mut() if let Some(current_group) = diag_groups.last_mut() {
{ match current_group.diag_type {
match current_group.diag_type { DiagType::Bitlocker => {
DiagType::Bitlocker => { if let Some(task_result) = &task.result {
if let Some(task_result) = &task.result { parse_bitlocker(current_group, task_result.clone());
parse_bitlocker(current_group, task_result.clone());
}
}
DiagType::BootConfigData => {
if let Some(task_result) = &task.result {
parse_bcd(current_group, task_result.clone());
}
}
DiagType::CheckDisk => {
if let Some(task_result) = &task.result {
parse_chkdsk(current_group, task_result.clone());
}
}
DiagType::ComponentStore => {
if let Some(task_result) = &task.result {
parse_dism(current_group, task_result.clone());
}
}
DiagType::SystemFiles => {
if let Some(task_result) = &task.result {
parse_system_files(current_group, task_result.clone());
}
}
DiagType::Registry => {
if let Some(task_result) = &task.result {
match &task.task_type {
TaskType::CommandWait(_, cmd_args) => {
parse_registry_hives(
current_group,
task_result.clone(),
cmd_args.clone(),
);
}
_ => {}
} }
} }
DiagType::BootConfigData => {
if let Some(task_result) = &task.result {
parse_bcd(current_group, task_result.clone());
}
}
DiagType::CheckDisk => {
if let Some(task_result) = &task.result {
parse_chkdsk(current_group, task_result.clone());
}
}
DiagType::ComponentStore => {
if let Some(task_result) = &task.result {
parse_dism(current_group, task_result.clone());
}
}
DiagType::SystemFiles => {
if let Some(task_result) = &task.result {
parse_system_files(current_group, task_result.clone());
}
}
DiagType::Registry => {
if let Some(task_result) = &task.result {
match &task.task_type {
TaskType::CommandWait(_, cmd_args) => {
parse_registry_hives(
current_group,
task_result.clone(),
cmd_args.clone(),
);
}
_ => {}
}
}
}
DiagType::Unknown => {
panic!("This shouldn't happen?");
}
} }
DiagType::Unknown => { self.action_tx.send(Action::DiagLineUpdate {
panic!("This shouldn't happen?"); result: current_group.get_pass_fail_warn(),
} text: current_group.result.clone(),
})?;
} }
self.action_tx.send(Action::DiagLineUpdate {
result: current_group.get_pass_fail_warn(),
text: current_group.result.clone(),
})?;
} }
return Ok(()); return Ok(());
} }
@ -718,12 +721,12 @@ fn build_left_items(app: &App) -> Action {
labels[0] = String::from("boot"); labels[0] = String::from("boot");
labels[1] = 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 {
&& let Some(disk) = disk_list.get(index) if let Some(disk) = disk_list.get(index) {
{ disk.get_parts().iter().for_each(|part| {
disk.get_parts().iter().for_each(|part| { items.push(part.to_string());
items.push(part.to_string()); });
}); }
} }
} }
Mode::BootDiags | Mode::LogView => { Mode::BootDiags | Mode::LogView => {
@ -743,7 +746,7 @@ fn build_left_items(app: &App) -> Action {
format!("{label}{status}") format!("{label}{status}")
}) })
.collect(); .collect();
items.extend(labels); items.extend(labels.into_iter());
} }
} }
Mode::BootSetup => { Mode::BootSetup => {
@ -838,7 +841,7 @@ fn build_right_items(app: &App) -> Action {
let mut summary: Vec<DVLine> = Vec::new(); let mut summary: Vec<DVLine> = Vec::new();
diag_groups diag_groups
.iter() .iter()
.for_each(|group| summary.extend(group.get_logs_summary())); .for_each(|group| summary.extend(group.get_logs_summary().into_iter()));
items.push(summary); items.push(summary);
} }
} }

View file

@ -70,7 +70,7 @@ impl Component for LogView {
Action::KeyUp => { Action::KeyUp => {
if self.mode == Mode::LogView { if self.mode == Mode::LogView {
if self.line_index > 0 { if self.line_index > 0 {
self.line_index -= 1; self.line_index = self.line_index - 1;
} }
} else { } else {
self.list.previous(); self.list.previous();
@ -116,18 +116,18 @@ impl Component for LogView {
} }
} }
Action::KeyEnd => { Action::KeyEnd => {
if self.mode == Mode::LogView if self.mode == Mode::LogView {
&& let Some(log_text) = self.list.get_selected() if let Some(log_text) = self.list.get_selected() {
{ let lines: Vec<&str> = log_text.split('\n').collect();
let lines: Vec<&str> = log_text.split('\n').collect(); self.line_index = (lines.len() - 3) as u16;
self.line_index = (lines.len() - 3) as u16; }
} }
} }
Action::Process => { Action::Process => {
if self.mode == Mode::LogView if self.mode == Mode::LogView {
&& let Some(command_tx) = self.command_tx.clone() if let Some(command_tx) = self.command_tx.clone() {
{ command_tx.send(Action::SetMode(Mode::BootDiags))?;
command_tx.send(Action::SetMode(Mode::BootDiags))?; }
} }
} }
Action::SetMode(new_mode) => { Action::SetMode(new_mode) => {

View file

@ -121,13 +121,13 @@ impl DiagGroup {
let mut summaries: Vec<DVLine> = Vec::new(); let mut summaries: Vec<DVLine> = Vec::new();
self.logs self.logs
.iter() .iter()
.for_each(|log| summaries.extend(log.summary.clone())); .for_each(|log| summaries.extend(log.summary.clone().into_iter()));
summaries summaries
} }
pub fn get_pass_fail_warn(&self) -> DiagResult { pub fn get_pass_fail_warn(&self) -> DiagResult {
let all_passed = self.passed.iter().all(|result| *result); let all_passed = self.passed.iter().fold(true, |acc, result| acc && *result);
let all_failed = self.passed.iter().all(|result| !*result); let all_failed = self.passed.iter().fold(true, |acc, result| acc && !*result);
if all_passed { if all_passed {
DiagResult::Pass DiagResult::Pass
} else if all_failed { } else if all_failed {
@ -157,7 +157,7 @@ pub fn get_diag_type(label: &str) -> Type {
pub fn parse_bcd(diag_group: &mut DiagGroup, task_result: TaskResult) { pub fn parse_bcd(diag_group: &mut DiagGroup, task_result: TaskResult) {
if !cfg!(windows) { if !cfg!(windows) {
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
return; return ();
} }
match task_result { match task_result {
TaskResult::Error(err) => { TaskResult::Error(err) => {
@ -209,7 +209,7 @@ pub fn parse_bcd(diag_group: &mut DiagGroup, task_result: TaskResult) {
pub fn parse_bitlocker(diag_group: &mut DiagGroup, task_result: TaskResult) { pub fn parse_bitlocker(diag_group: &mut DiagGroup, task_result: TaskResult) {
if !cfg!(windows) { if !cfg!(windows) {
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
return; return ();
} }
let re_bitlocker_locked = REGEXES.bitlocker_locked(); let re_bitlocker_locked = REGEXES.bitlocker_locked();
let re_bitlocker_off = REGEXES.bitlocker_off(); let re_bitlocker_off = REGEXES.bitlocker_off();
@ -276,7 +276,7 @@ pub fn parse_bitlocker(diag_group: &mut DiagGroup, task_result: TaskResult) {
pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) { pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) {
if !cfg!(windows) { if !cfg!(windows) {
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
return; return ();
} }
match task_result { match task_result {
TaskResult::Error(err) => { TaskResult::Error(err) => {
@ -334,7 +334,7 @@ pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) {
pub fn parse_dism(diag_group: &mut DiagGroup, task_result: TaskResult) { pub fn parse_dism(diag_group: &mut DiagGroup, task_result: TaskResult) {
if !cfg!(windows) { if !cfg!(windows) {
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
return; return ();
} }
match task_result { match task_result {
TaskResult::Error(err) => { TaskResult::Error(err) => {
@ -390,7 +390,7 @@ pub fn parse_registry_hives(
) { ) {
if !cfg!(windows) { if !cfg!(windows) {
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
return; return ();
} }
let hive = cmd_args.get(2); let hive = cmd_args.get(2);
match task_result { match task_result {
@ -464,7 +464,7 @@ pub fn parse_registry_hives(
pub fn parse_system_files(diag_group: &mut DiagGroup, task_result: TaskResult) { pub fn parse_system_files(diag_group: &mut DiagGroup, task_result: TaskResult) {
if !cfg!(windows) { if !cfg!(windows) {
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
return; return ();
} }
match task_result { match task_result {
TaskResult::Error(err) => { TaskResult::Error(err) => {

View file

@ -20,150 +20,150 @@ pub fn queue_boot_scan_tasks(
diag_groups.clear(); diag_groups.clear();
} }
let disk_list = clone.disk_list.lock().unwrap(); let disk_list = clone.disk_list.lock().unwrap();
if let Some(disk_index) = clone.disk_index_dest if let Some(disk_index) = clone.disk_index_dest {
&& let Some(disk) = disk_list.get(disk_index) if let Some(disk) = disk_list.get(disk_index) {
{ let table_type = disk.part_type.clone();
let table_type = disk.part_type.clone(); let letter_boot = disk.get_part_letter(clone.part_index_boot.unwrap());
let letter_boot = disk.get_part_letter(clone.part_index_boot.unwrap()); let letter_os = disk.get_part_letter(clone.part_index_os.unwrap());
let letter_os = disk.get_part_letter(clone.part_index_os.unwrap());
// Safety check // Safety check
if letter_os.is_empty() { if letter_os.is_empty() {
if letter_boot.is_empty() { if letter_boot.is_empty() {
action_tx.send(Action::Error(String::from( action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to get drive letters for the boot and OS volumes", "ERROR\n\n\nFailed to get drive letters for the boot and OS volumes",
)))?; )))?;
} else { } else {
action_tx.send(Action::Error(String::from( action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to get drive letter for the OS volume", "ERROR\n\n\nFailed to get drive letter for the OS volume",
)))?; )))?;
}
return Ok(());
} }
return Ok(());
}
// BCD // BCD
if !letter_boot.is_empty() { 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( tasks.add_group(
DiagType::BootConfigData.to_string().as_str(), 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( vec![TaskType::CommandWait(
PathBuf::from(format!("{}\\bcdedit.exe", &system32)), 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![ vec![
String::from("/store"), format!("/Image:{letter_os}:"),
format!( String::from("/Cleanup-Image"),
"{letter_boot}:{}\\Boot\\BCD", String::from("/ScanHealth"),
if table_type == PartitionTableType::Guid {
"\\EFI\\Microsoft"
} else {
""
}
),
String::from("/enum"),
], ],
)], )],
); );
}
// Bitlocker // Critical Files/Folders
tasks.add_group( let paths: Vec<PathBuf> = [
DiagType::Bitlocker.to_string().as_str(), // Files/Folders
vec![ "Users",
TaskType::CommandWait( "Program Files",
PathBuf::from(format!("{}\\manage-bde.exe", &system32)), "Program Files (x86)",
vec![String::from("-status"), format!("{letter_os}:")], "ProgramData",
), "Windows\\System32\\config",
TaskType::CommandWait( ]
PathBuf::from(format!("{}\\manage-bde.exe", &system32)), .iter()
vec![ .map(|s| PathBuf::from(format!("{letter_os}:\\{s}")))
String::from("-protectors"), .collect();
String::from("-get"), tasks.add_group(
format!("{letter_os}:"), DiagType::SystemFiles.to_string().as_str(),
], vec![TaskType::TestPaths(paths)],
), );
],
);
// Filesystem Health // Registry
tasks.add_group( tasks.add_group(
DiagType::CheckDisk.to_string().as_str(), DiagType::Registry.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![ vec![
format!("/Image:{letter_os}:"), TaskType::CommandWait(
String::from("/Cleanup-Image"), PathBuf::from(format!("{}\\reg.exe", &system32)),
String::from("/ScanHealth"), 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
}
// 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(()) Ok(())
} }

View file

@ -159,37 +159,37 @@ impl Component for Right {
} }
// First selection // First selection
if let Some(first_index) = self.get_first() if let Some(first_index) = self.get_first() {
&& let Some(first_desc) = self.list.get(first_index) if let Some(first_desc) = self.list.get(first_index) {
{ if let Some(label) = self.list_labels.first() {
if let Some(label) = self.list_labels.first() { label
label .iter()
.for_each(|dv| body_text.push(dv.as_line().bold()));
body_text.push(Line::from(""));
}
first_desc
.iter() .iter()
.for_each(|dv| body_text.push(dv.as_line().bold())); .for_each(|dv| body_text.push(dv.as_line()));
body_text.push(Line::from(""));
} }
first_desc
.iter()
.for_each(|dv| body_text.push(dv.as_line()));
} }
// Second selection // Second selection
if let Some(second_index) = self.get_second() if let Some(second_index) = self.get_second() {
&& let Some(second_desc) = self.list.get(second_index) if let Some(second_desc) = self.list.get(second_index) {
{ // Divider
// Divider body_text.push(Line::from(""));
body_text.push(Line::from("")); body_text.push(Line::from(str::repeat("", (body_area.width - 4) as usize)));
body_text.push(Line::from(str::repeat("", (body_area.width - 4) as usize))); body_text.push(Line::from(""));
body_text.push(Line::from("")); if let Some(label) = self.list_labels.get(1) {
if let Some(label) = self.list_labels.get(1) { label
label .iter()
.for_each(|dv| body_text.push(dv.as_line().bold()));
}
body_text.push(Line::from(""));
second_desc
.iter() .iter()
.for_each(|dv| body_text.push(dv.as_line().bold())); .for_each(|dv| body_text.push(dv.as_line()));
} }
body_text.push(Line::from(""));
second_desc
.iter()
.for_each(|dv| body_text.push(dv.as_line()));
} }
// Build Paragraph // Build Paragraph

View file

@ -130,24 +130,26 @@ impl Config {
#[must_use] #[must_use]
pub fn get_data_dir() -> PathBuf { pub fn get_data_dir() -> PathBuf {
if let Some(s) = DATA_FOLDER.clone() { let directory = if let Some(s) = DATA_FOLDER.clone() {
s s
} else if let Some(proj_dirs) = project_directory() { } else if let Some(proj_dirs) = project_directory() {
proj_dirs.data_local_dir().to_path_buf() proj_dirs.data_local_dir().to_path_buf()
} else { } else {
PathBuf::from(".").join(".data") PathBuf::from(".").join(".data")
} };
directory
} }
#[must_use] #[must_use]
pub fn get_config_dir() -> PathBuf { pub fn get_config_dir() -> PathBuf {
if let Some(s) = CONFIG_FOLDER.clone() { let directory = if let Some(s) = CONFIG_FOLDER.clone() {
s s
} else if let Some(proj_dirs) = project_directory() { } else if let Some(proj_dirs) = project_directory() {
proj_dirs.config_local_dir().to_path_buf() proj_dirs.config_local_dir().to_path_buf()
} else { } else {
PathBuf::from(".").join(".config") PathBuf::from(".").join(".config")
} };
directory
} }
fn project_directory() -> Option<ProjectDirs> { fn project_directory() -> Option<ProjectDirs> {
@ -331,8 +333,8 @@ pub fn parse_key_sequence(raw: &str) -> Result<Vec<KeyEvent>, String> {
let raw = if raw.contains("><") { let raw = if raw.contains("><") {
raw raw
} else { } else {
let mut raw = raw.strip_prefix('<').unwrap_or(raw); let raw = raw.strip_prefix('<').unwrap_or(raw);
raw = raw.strip_prefix('>').unwrap_or(raw); let raw = raw.strip_prefix('>').unwrap_or(raw);
raw raw
}; };
let sequences = raw let sequences = raw

View file

@ -31,10 +31,10 @@ pub fn init() -> Result<()> {
.into_hooks(); .into_hooks();
eyre_hook.install()?; eyre_hook.install()?;
std::panic::set_hook(Box::new(move |panic_info| { std::panic::set_hook(Box::new(move |panic_info| {
if let Ok(mut t) = crate::tui::Tui::new() if let Ok(mut t) = crate::tui::Tui::new() {
&& let Err(r) = t.exit() if let Err(r) = t.exit() {
{ error!("Unable to exit Terminal: {:?}", r);
error!("Unable to exit Terminal: {:?}", r); }
} }
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]

View file

@ -31,7 +31,7 @@ pub struct DVLine {
impl DVLine { impl DVLine {
/// Convert to Line with colored span(s) /// Convert to Line with colored span(s)
#[must_use] #[must_use]
pub fn as_line(&self) -> Line<'_> { pub fn as_line(&self) -> Line {
let mut spans = Vec::new(); let mut spans = Vec::new();
zip(self.line_parts.clone(), self.line_colors.clone()) zip(self.line_parts.clone(), self.line_colors.clone())
.for_each(|(part, color)| spans.push(Span::styled(part, Style::default().fg(color)))); .for_each(|(part, color)| spans.push(Span::styled(part, Style::default().fg(color))));

View file

@ -387,11 +387,12 @@ pub fn run_script_raw(script: &str) -> Output {
script_file script_file
.write_all(script.as_bytes()) .write_all(script.as_bytes())
.expect("Failed to write script to disk"); .expect("Failed to write script to disk");
Command::new("diskpart") let output = Command::new("diskpart")
.args(["/s", format!("{}", script_path.display()).as_str()]) .args(["/s", format!("{}", script_path.display()).as_str()])
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.output() .output()
.expect("Failed to execute Diskpart script") .expect("Failed to execute Diskpart script");
output
} }
#[must_use] #[must_use]

View file

@ -73,14 +73,14 @@ pub fn scan() -> Vec<Driver> {
let driver_path = exe_path.with_file_name("drivers"); let driver_path = exe_path.with_file_name("drivers");
if let Ok(dir_entry) = read_dir(driver_path) { if let Ok(dir_entry) = read_dir(driver_path) {
for entry in dir_entry.flatten() { for entry in dir_entry.flatten() {
if entry.path().is_dir() if entry.path().is_dir() {
&& let Ok(name) = entry.file_name().into_string() if let Ok(name) = entry.file_name().into_string() {
{ drivers.push(Driver {
drivers.push(Driver { name,
name, path: entry.path(),
path: entry.path(), inf_paths: Vec::new(),
inf_paths: Vec::new(), });
}); }
} }
} }
} }
@ -95,10 +95,10 @@ pub fn scan() -> Vec<Driver> {
.into_iter() .into_iter()
.filter_map(Result::ok) .filter_map(Result::ok)
{ {
if let Some(ext) = entry.path().extension() if let Some(ext) = entry.path().extension() {
&& ext == "inf" if ext == "inf" {
{ driver.inf_paths.push(entry.into_path());
driver.inf_paths.push(entry.into_path()); }
} }
} }
} }

View file

@ -152,11 +152,11 @@ impl Tasks {
pub fn poll(&mut self) -> Result<Option<Task>> { pub fn poll(&mut self) -> Result<Option<Task>> {
let mut return_task: Option<Task> = None; let mut return_task: Option<Task> = None;
// Handle task channel item(s) // Handle task channel item(s)
if let Ok(result) = self.task_rx.try_recv() if let Ok(result) = self.task_rx.try_recv() {
&& let Some(mut task) = self.cur_task.take() if let Some(mut task) = self.cur_task.take() {
{ task.result.replace(result);
task.result.replace(result); self.cur_task.replace(task);
self.cur_task.replace(task); }
} }
// Check status of current task (if one is running). // Check status of current task (if one is running).

View file

@ -60,6 +60,7 @@ mod diskpart {
letter: String::from("C"), letter: String::from("C"),
part_type: String::from("ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"), part_type: String::from("ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"),
size: 50465865728, size: 50465865728,
..Default::default()
}; };
// Right // Right
@ -91,7 +92,7 @@ mod diskpart {
#[test] #[test]
fn parse_disk_numbers() { fn parse_disk_numbers() {
let disk_numbers = let disk_numbers =
system::diskpart::parse_disk_numbers(sample_output::LIST_DISK_DETAIL_DISKS); system::diskpart::parse_disk_numbers(&sample_output::LIST_DISK_DETAIL_DISKS);
assert_eq!(vec!["0", "2"], disk_numbers); assert_eq!(vec!["0", "2"], disk_numbers);
} }
@ -110,7 +111,7 @@ mod diskpart {
system::diskpart::parse_partition_details( system::diskpart::parse_partition_details(
&mut disk.parts, &mut disk.parts,
sample_output::SELECT_PART_DETAIL_ONE_PART, &sample_output::SELECT_PART_DETAIL_ONE_PART,
); );
assert_eq!(partition_1, disk.parts[0]); assert_eq!(partition_1, disk.parts[0]);
} }

View file

@ -197,12 +197,12 @@ impl App {
// Build Diskpart script to format destination disk // Build Diskpart script to format destination disk
let disk_list = self.clone.disk_list.lock().unwrap(); let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest if let Some(disk_index) = self.clone.disk_index_dest {
&& let Some(disk) = disk_list.get(disk_index) if let Some(disk) = disk_list.get(disk_index) {
{ let table_type = self.clone.table_type.clone().unwrap();
let table_type = self.clone.table_type.clone().unwrap(); let diskpart_script = build_dest_format_script(disk.id, &table_type);
let diskpart_script = build_dest_format_script(disk.id, &table_type); self.tasks.add(TaskType::Diskpart(diskpart_script));
self.tasks.add(TaskType::Diskpart(diskpart_script)); }
} }
} }
Mode::Clone => { Mode::Clone => {
@ -229,41 +229,41 @@ impl App {
// Add actions // Add actions
let disk_list = self.clone.disk_list.lock().unwrap(); let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest if let Some(disk_index) = self.clone.disk_index_dest {
&& let Some(disk) = disk_list.get(disk_index) if let Some(disk) = disk_list.get(disk_index) {
{ let table_type = self.clone.table_type.clone().unwrap();
let table_type = self.clone.table_type.clone().unwrap(); let letter_boot = disk.get_part_letter(self.clone.part_index_boot.unwrap());
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());
let letter_os = disk.get_part_letter(self.clone.part_index_os.unwrap());
// Safety check // Safety check
if letter_boot.is_empty() || letter_os.is_empty() { if letter_boot.is_empty() || letter_os.is_empty() {
self.action_tx.send(Action::Error(String::from( self.action_tx.send(Action::Error(String::from(
"ERROR\n\n\nFailed to get drive letters for the destination", "ERROR\n\n\nFailed to get drive letters for the destination",
)))?;
return Ok(());
}
// Create boot files
for task in boot::configure_disk(
&letter_boot,
&letter_os,
boot::SafeMode::Enable,
&system32,
&table_type,
) {
self.tasks.add(task);
}
// Inject driver(s) (if selected)
if let Some(driver) = &self.clone.driver {
if let Ok(task) = boot::inject_driver(driver, &letter_os, &system32) {
self.tasks.add(task);
} else {
self.action_tx.send(Action::Error(format!(
"Failed to inject driver:\n{}",
driver.name
)))?; )))?;
return Ok(());
}
// Create boot files
for task in boot::configure_disk(
&letter_boot,
&letter_os,
boot::SafeMode::Enable,
&system32,
&table_type,
) {
self.tasks.add(task);
}
// Inject driver(s) (if selected)
if let Some(driver) = &self.clone.driver {
if let Ok(task) = boot::inject_driver(driver, &letter_os, &system32) {
self.tasks.add(task);
} else {
self.action_tx.send(Action::Error(format!(
"Failed to inject driver:\n{}",
driver.name
)))?;
}
} }
} }
} }
@ -415,11 +415,11 @@ impl App {
Action::Select(one, two) => { Action::Select(one, two) => {
match self.cur_mode { match self.cur_mode {
Mode::InstallDrivers => { Mode::InstallDrivers => {
if let Some(index) = one if let Some(index) = one {
&& let Some(driver) = self.clone.driver_list.get(index).cloned() if let Some(driver) = self.clone.driver_list.get(index).cloned() {
{ drivers::load(&driver.inf_paths);
drivers::load(&driver.inf_paths); self.clone.driver = Some(driver);
self.clone.driver = Some(driver); }
} }
} }
Mode::SelectDisks => { Mode::SelectDisks => {
@ -690,12 +690,12 @@ fn build_left_items(app: &App, cur_mode: Mode) -> Action {
labels.push(String::from("boot")); labels.push(String::from("boot"));
labels.push(String::from("os")); labels.push(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 {
&& let Some(disk) = disk_list.get(index) if let Some(disk) = disk_list.get(index) {
{ disk.get_parts().iter().for_each(|part| {
disk.get_parts().iter().for_each(|part| { items.push(part.to_string());
items.push(part.to_string()); });
}); }
} }
} }
Mode::Done | Mode::Failed => { Mode::Done | Mode::Failed => {

BIN
logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

BIN
logo.xcf

Binary file not shown.

View file

@ -205,25 +205,25 @@ impl App {
Action::ClearScreen => tui.terminal.clear()?, Action::ClearScreen => tui.terminal.clear()?,
Action::KeyUp => { Action::KeyUp => {
self.list.previous(); self.list.previous();
if let Some(tool) = self.list.get_selected() if let Some(tool) = self.list.get_selected() {
&& tool.separator if tool.separator {
{ // Skip over separator
// Skip over separator self.list.previous();
self.list.previous(); if let Some(index) = self.list.selected() {
if let Some(index) = self.list.selected() { self.action_tx.send(Action::Highlight(index))?;
self.action_tx.send(Action::Highlight(index))?; }
} }
} }
} }
Action::KeyDown => { Action::KeyDown => {
self.list.next(); self.list.next();
if let Some(tool) = self.list.get_selected() if let Some(tool) = self.list.get_selected() {
&& tool.separator if tool.separator {
{ // Skip over separator
// Skip over separator self.list.next();
self.list.next(); if let Some(index) = self.list.selected() {
if let Some(index) = self.list.selected() { self.action_tx.send(Action::Highlight(index))?;
self.action_tx.send(Action::Highlight(index))?; }
} }
} }
} }
@ -391,12 +391,12 @@ pub fn build_tool_command(app: &App, tool: &Tool) -> TaskType {
cmd_path = PathBuf::from(tool.command.clone()); cmd_path = PathBuf::from(tool.command.clone());
start_index = 0; start_index = 0;
} }
if let Some(args) = &tool.args if let Some(args) = &tool.args {
&& args.len() > start_index if args.len() > start_index {
{ args[start_index..].iter().for_each(|a| {
args[start_index..].iter().for_each(|a| { cmd_args.push(a.clone());
cmd_args.push(a.clone()); });
}); }
} }
TaskType::CommandNoWait(cmd_path, cmd_args) TaskType::CommandNoWait(cmd_path, cmd_args)
} }