From 4fca7d669645b318303796dc76b3f26c2485d9fa Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Wed, 4 Jun 2025 19:25:07 -0700 Subject: [PATCH] Add Bitlocker result parsing logic --- boot_diags/src/app.rs | 8 +++-- boot_diags/src/diags.rs | 79 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/boot_diags/src/app.rs b/boot_diags/src/app.rs index 503b82b..c34d06f 100644 --- a/boot_diags/src/app.rs +++ b/boot_diags/src/app.rs @@ -54,7 +54,7 @@ use ratatui::{ use tokio::sync::mpsc; use tracing::{debug, info}; -use crate::diags::{DiagGroup, Type as DiagType, get_diag_type, parse_chkdsk}; +use crate::diags::{DiagGroup, Type as DiagType, get_diag_type, parse_bitlocker, parse_chkdsk}; pub struct App { // TUI @@ -445,9 +445,13 @@ impl App { if let Ok(mut diag_groups) = self.diag_groups.lock() { if let Some(current_group) = diag_groups.last_mut() { match current_group.diag_type { + DiagType::Bitlocker => { + if let Some(task_result) = &task.result { + parse_bitlocker(current_group, task_result.clone()); + } + } DiagType::CheckDisk => { if let Some(task_result) = &task.result { - // parse_chkdsk(current_group, task_result.clone()); } } diff --git a/boot_diags/src/diags.rs b/boot_diags/src/diags.rs index 12c20d8..e0e1403 100644 --- a/boot_diags/src/diags.rs +++ b/boot_diags/src/diags.rs @@ -21,11 +21,21 @@ use regex::Regex; use tracing::{info, warn}; pub struct RegexList { + bitlocker_locked: OnceLock, + bitlocker_off: OnceLock, carriage_returns: OnceLock, chkdsk_splits: OnceLock, } impl RegexList { + fn bitlocker_locked(&self) -> &Regex { + self.bitlocker_locked + .get_or_init(|| Regex::new(r"Lock Status:\s+Locked").unwrap()) + } + fn bitlocker_off(&self) -> &Regex { + self.bitlocker_off + .get_or_init(|| Regex::new(r"Protection Status:\s+Protection Off").unwrap()) + } fn carriage_returns(&self) -> &Regex { self.carriage_returns .get_or_init(|| Regex::new(r"^.*\r").unwrap()) @@ -42,6 +52,8 @@ impl RegexList { } static REGEXES: RegexList = RegexList { + bitlocker_locked: OnceLock::new(), + bitlocker_off: OnceLock::new(), carriage_returns: OnceLock::new(), chkdsk_splits: OnceLock::new(), }; @@ -130,6 +142,73 @@ pub fn get_diag_type(label: &str) -> Type { } } +pub fn parse_bitlocker(diag_group: &mut DiagGroup, task_result: TaskResult) { + if !cfg!(windows) { + sleep(Duration::from_millis(500)); + return (); + } + let re_bitlocker_locked = REGEXES.bitlocker_locked(); + let re_bitlocker_off = REGEXES.bitlocker_off(); + match task_result { + TaskResult::Error(err) => { + diag_group.passed = false; + diag_group.result = String::from("Error"); + diag_group.logs.push(Log { + label: String::from("Bitlocker"), + summary: vec![DVLine { + line_parts: vec![String::from("Bitlocker: "), String::from("Error")], + line_colors: vec![Color::Reset, Color::Red], + }], + raw: err, + }); + } + TaskResult::Output(stdout, stderr, _) => { + let output_text = if stderr.is_empty() { + stdout.clone() + } else { + format!("{stdout}\n\n-------\n\n{stderr}") + }; + let result: String; + let set_result_text = !output_text.contains("All Key Protectors"); + + if re_bitlocker_off.is_match(&output_text) { + diag_group.passed &= true; + result = String::from("OK"); + diag_group.logs.push(Log { + label: String::from("Bitlocker"), + summary: vec![DVLine { + line_parts: vec![String::from("Bitlocker: "), String::from("OFF")], + line_colors: vec![Color::Reset, Color::Green], + }], + raw: output_text, + }); + } else if re_bitlocker_locked.is_match(&output_text) { + diag_group.passed = false; + result = String::from("Locked"); + diag_group.logs.push(Log { + label: String::from("Bitlocker"), + summary: vec![DVLine { + line_parts: vec![String::from("Bitlocker: "), String::from("Locked")], + line_colors: vec![Color::Reset, Color::Red], + }], + raw: output_text, + }); + } else { + diag_group.passed &= true; + result = String::from("Unknown"); + diag_group.logs.push(Log { + label: String::from("Bitlocker"), + summary: Vec::new(), + raw: output_text, + }); + } + if set_result_text { + diag_group.result = result; + } + } + } +} + pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) { if !cfg!(windows) { sleep(Duration::from_millis(500));