diff --git a/Cargo.lock b/Cargo.lock index dfee2ca2..be5f5f4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ "rustc_version", "toml 0.8.22", "vswhom", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -436,6 +436,7 @@ dependencies = [ "uefi-services", "windows 0.59.0", "windows-version", + "winreg 0.55.0", "wmi", ] @@ -1603,6 +1604,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.0" @@ -1816,6 +1826,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + [[package]] name = "winresource" version = "0.1.20" diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index 62e0e5d8..162538f4 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -51,6 +51,7 @@ clap = { version = "4.5", features = ["derive", "cargo"] } clap-num = { version = "1.2.0" } clap-verbosity-flag = { version = "2.2.1" } windows-version = "0.1.4" +winreg = "0.55.0" [target.'cfg(unix)'.dependencies] libc = "0.2.155" diff --git a/framework_lib/src/esrt/mod.rs b/framework_lib/src/esrt/mod.rs index 5d43ecf0..645c5669 100644 --- a/framework_lib/src/esrt/mod.rs +++ b/framework_lib/src/esrt/mod.rs @@ -24,6 +24,11 @@ use std::io; #[cfg(target_os = "linux")] use std::path::Path; +#[cfg(target_os = "windows")] +use winreg::enums::HKEY_LOCAL_MACHINE; +#[cfg(target_os = "windows")] +use winreg::RegKey; + #[cfg(target_os = "freebsd")] use nix::ioctl_readwrite; #[cfg(target_os = "freebsd")] @@ -425,67 +430,28 @@ pub fn get_esrt() -> Option { resource_version: ESRT_FIRMWARE_RESOURCE_VERSION, entries: vec![], }; - use wmi::*; - debug!("Opening WMI"); - let wmi_con = WMIConnection::new(COMLibrary::new().unwrap()).unwrap(); - use std::collections::HashMap; - use wmi::Variant; - debug!("Querying WMI"); - let results: Vec> = wmi_con.raw_query("SELECT HardwareID, Name FROM Win32_PnPEntity WHERE ClassGUID = '{f2e7dd72-6468-4e36-b6f1-6488f42c1b52}'").unwrap(); - - let re = regex::Regex::new(r"([\-a-h0-9]+)\}&REV_([A-F0-9]+)").expect("Bad regex"); - for (i, val) in results.iter().enumerate() { - let hwid = &val["HardwareID"]; - if let Variant::Array(strs) = hwid { - if let Variant::String(s) = &strs[0] { - // Sample "UEFI\\RES_{c57fd615-2ac9-4154-bf34-4dc715344408}&REV_CF" - let caps = re.captures(s).expect("No caps"); - let guid_str = caps.get(1).unwrap().as_str().to_string(); - let ver_str = caps.get(2).unwrap().as_str().to_string(); - - let guid = GUID::parse(guid_str.trim()).expect("Kernel provided wrong value"); - let guid_kind = match_guid_kind(&CGuid::from(guid)); - let ver = u32::from_str_radix(&ver_str, 16).unwrap(); - debug!("ESRT Entry {}", i); - debug!(" Name: {:?}", guid_kind); - debug!(" GUID: {}", guid_str); - debug!(" Version: {:X} ({})", ver, ver); - - let fw_type = if let Variant::String(name) = &val["Name"] { - match name.as_str() { - "System Firmware" => 1, - "Device Firmware" => 2, - _ => 0, - } - } else { - 0 - }; - // TODO: The missing fields are present in Device Manager - // So there must be a way to get at them - let esrt = EsrtResourceEntry { - fw_class: CGuid::from(guid), - fw_type, - fw_version: ver, - // TODO: Not exposed by windows - lowest_supported_fw_version: 0, - // TODO: Not exposed by windows - capsule_flags: 0, - // TODO: Not exposed by windows - last_attempt_version: 0, - // TODO: Not exposed by windows - last_attempt_status: 0, - }; - esrt_table.resource_count += 1; - esrt_table.resource_count_max += 1; - esrt_table.entries.push(esrt); - } else { - error!("Strs: {:#?}", strs[0]); - } - } else { - error!("{:#?}", hwid); - } + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + let esrt = hklm.open_subkey("HARDWARE\\UEFI\\ESRT").ok()?; + for subkey in esrt.enum_keys() { + let guid = subkey.ok()?; + let short_guid = guid.trim_matches(|c| c == '{' || c == '}'); + let esrt_entry = esrt.open_subkey(&guid).ok()?; + let esrt = EsrtResourceEntry { + fw_class: GUID::parse(&short_guid).ok()?.into(), + fw_type: esrt_entry.get_value("Type").ok()?, + fw_version: esrt_entry.get_value("Version").ok()?, + lowest_supported_fw_version: esrt_entry.get_value("LowestSupportedVersion").ok()?, + capsule_flags: 0, + last_attempt_version: esrt_entry.get_value("LastAttemptVersion").ok()?, + last_attempt_status: esrt_entry.get_value("LastAttemptStatus").ok()?, + }; + + esrt_table.resource_count += 1; + esrt_table.resource_count_max += 1; + esrt_table.entries.push(esrt); } + Some(esrt_table) }