From 9a282baccfda5c49b0e1cc2ac180bbde63af5d07 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 8 Jul 2025 19:14:16 +0800 Subject: [PATCH 1/3] try to set variable from windows Signed-off-by: Daniel Schaefer --- framework_lib/Cargo.toml | 1 + framework_lib/src/os_specific.rs | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index 3ba39e3d..9dbf370e 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -70,6 +70,7 @@ features = [ "Win32_System_IO", "Win32_System_Ioctl", "Win32_System_SystemServices", + "Win32_System_WindowsProgramming", # For HID devices "Win32_Devices_DeviceAndDriverInstallation", "Win32_Devices_HumanInterfaceDevice", diff --git a/framework_lib/src/os_specific.rs b/framework_lib/src/os_specific.rs index 83ae2f37..861817f5 100644 --- a/framework_lib/src/os_specific.rs +++ b/framework_lib/src/os_specific.rs @@ -3,6 +3,9 @@ #[cfg(not(feature = "uefi"))] use std::{thread, time}; +#[cfg(windows)] +use windows::{core::*, Win32::System::WindowsProgramming::*}; + /// Sleep a number of microseconds pub fn sleep(micros: u64) { #[cfg(not(feature = "uefi"))] @@ -19,3 +22,23 @@ pub fn sleep(micros: u64) { bs.stall(micros as usize); } } + +#[cfg(windows)] +pub fn set_dbx() -> Option<()> { + set_uefi_var("dbx", "d719b2cb-3d3a-4596-a3bc-dad00e67656f", &[], 0) +} + +#[cfg(windows)] +pub fn set_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Option<()> { + unsafe { + SetFirmwareEnvironmentVariableExW( + // PCWSTR + &HSTRING::from(name), + // PCWSTR + &HSTRING::from(guid), + Some(value.as_ptr() as *const core::ffi::c_void), + value.len() as u32, + attributes, + ).ok() + } +} From 606e939c09253e8c319453325861943fb74e592f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 9 Jul 2025 20:44:11 +0800 Subject: [PATCH 2/3] Add --set-uefi-var Not working yet Signed-off-by: Daniel Schaefer --- framework_lib/src/commandline/clap_std.rs | 5 ++++ framework_lib/src/commandline/mod.rs | 20 +++++++++++++++ framework_lib/src/os_specific.rs | 31 +++++++++++++++++++---- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index a26aa4ba..0b5e6ab6 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -240,6 +240,10 @@ struct ClapCli { #[arg(long)] ec_hib_delay: Option>, + /// Set UEFI variable (name, file path) + #[arg(long)] + set_uefi_var: Option, + /// Hash a file of arbitrary data #[arg(long)] hash: Option, @@ -450,6 +454,7 @@ pub fn parse(args: &[String]) -> Cli { console: args.console, reboot_ec: args.reboot_ec, ec_hib_delay: args.ec_hib_delay, + set_uefi_var: args.set_uefi_var, hash: args.hash.map(|x| x.into_os_string().into_string().unwrap()), driver: args.driver, pd_addrs, diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 265f6796..93851a97 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -49,6 +49,7 @@ use crate::ec_binary; use crate::esrt; #[cfg(feature = "rusb")] use crate::inputmodule::check_inputmodule_version; +use crate::os_specific; use crate::power; use crate::smbios; use crate::smbios::ConfigDigit0; @@ -204,6 +205,7 @@ pub struct Cli { pub console: Option, pub reboot_ec: Option, pub ec_hib_delay: Option>, + pub set_uefi_var: Option, pub hash: Option, pub pd_addrs: Option<(u16, u16, u16)>, pub pd_ports: Option<(u8, u8, u8)>, @@ -1116,6 +1118,24 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { print_err(ec.set_ec_hib_delay(*delay)); } print_err(ec.get_ec_hib_delay()); + } else if let Some(filepath) = &args.set_uefi_var { + #[cfg(feature = "uefi")] + let data = crate::uefi::fs::shell_read_file(filepath); + #[cfg(not(feature = "uefi"))] + let data = match fs::read(filepath) { + Ok(data) => Some(data), + // TODO: Perhaps a more user-friendly error + Err(e) => { + println!("Error {:?}", e); + None + } + }; + if let Some(data) = data { + println!("File"); + println!(" Size: {:>20} B", data.len()); + println!(" Size: {:>20} KB", data.len() / 1024); + os_specific::set_dbx(&data); + } } else if args.test { println!("Self-Test"); let result = selftest(&ec); diff --git a/framework_lib/src/os_specific.rs b/framework_lib/src/os_specific.rs index 861817f5..150d0ee7 100644 --- a/framework_lib/src/os_specific.rs +++ b/framework_lib/src/os_specific.rs @@ -23,14 +23,27 @@ pub fn sleep(micros: u64) { } } +pub const EFI_VARIABLE_NON_VOLATILE: u32 = 0x00000001; +pub const EFI_VARIABLE_BOOTSERVICE_ACCESS: u32 = 0x00000002; +pub const EFI_VARIABLE_RUNTIME_ACCESS: u32 = 0x00000004; +//pub const EFI_VARIABLE_HARDWARE_ERROR_RECORD: u32 = 0x00000008; +pub const EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS: u32 = 0x00000010; +//pub const EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS: u32 = 0x00000020; +pub const EFI_VARIABLE_APPEND_WRITE: u32 = 0x00000040; + #[cfg(windows)] -pub fn set_dbx() -> Option<()> { - set_uefi_var("dbx", "d719b2cb-3d3a-4596-a3bc-dad00e67656f", &[], 0) +pub fn set_dbx(data: &[u8]) -> Option<()> { + let attrs = EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS + | EFI_VARIABLE_APPEND_WRITE; + set_uefi_var("dbx", "d719b2cb-3d3a-4596-a3bc-dad00e67656f", data, attrs) } #[cfg(windows)] pub fn set_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Option<()> { - unsafe { + let res = unsafe { SetFirmwareEnvironmentVariableExW( // PCWSTR &HSTRING::from(name), @@ -39,6 +52,14 @@ pub fn set_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Op Some(value.as_ptr() as *const core::ffi::c_void), value.len() as u32, attributes, - ).ok() - } + ) + }; + println!("{:?}", res); + res.ok() +} + +#[cfg(not(windows))] +pub fn set_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Option<()> { + error!("Setting UEFI variable not supported on this OS"); + None } From b332a9b79db7a0dac403441db4e68c6796fed6f6 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 9 Jul 2025 20:45:58 +0800 Subject: [PATCH 3/3] wip: Also read uefi variable Signed-off-by: Daniel Schaefer --- framework_lib/src/commandline/mod.rs | 3 +- framework_lib/src/os_specific.rs | 41 +++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 93851a97..f6766bdd 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -1134,7 +1134,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { println!("File"); println!(" Size: {:>20} B", data.len()); println!(" Size: {:>20} KB", data.len() / 1024); - os_specific::set_dbx(&data); + os_specific::get_dbx(); + //os_specific::set_dbx(&data); } } else if args.test { println!("Self-Test"); diff --git a/framework_lib/src/os_specific.rs b/framework_lib/src/os_specific.rs index 150d0ee7..ac20f7d4 100644 --- a/framework_lib/src/os_specific.rs +++ b/framework_lib/src/os_specific.rs @@ -4,7 +4,7 @@ use std::{thread, time}; #[cfg(windows)] -use windows::{core::*, Win32::System::WindowsProgramming::*}; +use windows::{core::*, Win32::Foundation::*, Win32::System::WindowsProgramming::*}; /// Sleep a number of microseconds pub fn sleep(micros: u64) { @@ -41,6 +41,11 @@ pub fn set_dbx(data: &[u8]) -> Option<()> { set_uefi_var("dbx", "d719b2cb-3d3a-4596-a3bc-dad00e67656f", data, attrs) } +#[cfg(windows)] +pub fn get_dbx() -> Option> { + get_uefi_var(w!("dbx"), w!("d719b2cb-3d3a-4596-a3bc-dad00e67656f")) +} + #[cfg(windows)] pub fn set_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Option<()> { let res = unsafe { @@ -63,3 +68,37 @@ pub fn set_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Op error!("Setting UEFI variable not supported on this OS"); None } + +#[cfg(windows)] +pub fn get_uefi_var(name: PCWSTR, guid: PCWSTR) -> Option> { + let mut data = [0; 1024]; + let mut attributes: u32 = 0; + let (res, error) = unsafe { + let res = GetFirmwareEnvironmentVariableExW( + // PCWSTR + //&HSTRING::from(name), + name, + // PCWSTR + //&HSTRING::from(guid), + guid, + Some(data.as_mut_ptr() as *mut core::ffi::c_void), + data.len() as u32, + Some(&mut attributes), + ); + let error = GetLastError(); + (res, error) + }; + + //let data = std::slice::from_raw_parts::(credentials_ptr as _, count as usize); + + println!("Res: {:?}", res); + println!("LastError: {:?}", error); + println!("Data: {:X?}", data); + Some(vec![]) +} + +#[cfg(not(windows))] +pub fn get_uefi_var(name: &str, guid: &str, value: &[u8], attributes: u32) -> Option> { + error!("Getting UEFI variable not supported on this OS"); + None +}