1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
use core::ptr; use uefi::guid::GLOBAL_VARIABLE_GUID; use uefi::status::{Error, Result}; use crate::ffi::wstr; use crate::system_table; fn get(name: &str, data: &mut [u8]) -> Result<usize> { let wname = wstr(name); let mut data_size = data.len(); (system_table().RuntimeServices.GetVariable)(wname.as_ptr(), &GLOBAL_VARIABLE_GUID, ptr::null_mut(), &mut data_size, data.as_mut_ptr())?; Ok(data_size) } fn set(name: &str, data: &[u8]) -> Result<usize> { let wname = wstr(name); let access = 1 | 2 | 4; let data_size = data.len(); (system_table().RuntimeServices.SetVariable)(wname.as_ptr(), &GLOBAL_VARIABLE_GUID, access, data_size, data.as_ptr())?; Ok(data_size) } pub fn get_boot_current() -> Result<u16> { let mut data = [0; 2]; let count = get("BootCurrent", &mut data)?; if count == 2 { Ok((data[0] as u16) | ((data[1] as u16) << 8)) } else { Err(Error::LoadError) } } pub fn get_boot_next() -> Result<u16> { let mut data = [0; 2]; let count = get("BootNext", &mut data)?; if count == 2 { Ok((data[0] as u16) | ((data[1] as u16) << 8)) } else { Err(Error::LoadError) } } pub fn set_boot_next(num_opt: Option<u16>) -> Result<usize> { if let Some(num) = num_opt { set("BootNext", &[ num as u8, (num >> 8) as u8 ]) } else { set("BootNext", &[]) } } pub fn get_boot_order() -> Result<Vec<u16>> { let mut data = [0; 4096]; let count = get("BootOrder", &mut data)?; let mut order = vec![]; for chunk in data[..count].chunks(2) { if chunk.len() == 2 { order.push((chunk[0] as u16) | (chunk[1] as u16) << 8); } } Ok(order) } pub fn get_boot_item(num: u16) -> Result<Vec<u8>> { let mut data = [0; 4096]; let count = get(&format!("Boot{:>04X}", num), &mut data)?; if count < 6 { Err(Error::LoadError) } else { Ok(data[..count].to_vec()) } } pub fn set_boot_item(num: u16, data: &[u8]) -> Result<usize> { set(&format!("Boot{:>04X}", num), &data) } pub fn get_os_indications() -> Result<u64> { let mut data = [0; 8]; let count = get("OsIndications", &mut data)?; if count == 8 { Ok( (data[0] as u64) | ((data[1] as u64) << 8) | ((data[2] as u64) << 16) | ((data[3] as u64) << 24) | ((data[4] as u64) << 32) | ((data[5] as u64) << 40) | ((data[6] as u64) << 48) | ((data[7] as u64) << 56) ) } else { Err(Error::LoadError) } } pub fn set_os_indications(indications_opt: Option<u64>) -> Result<usize> { if let Some(indications) = indications_opt { set("OsIndications", &[ indications as u8, (indications >> 8) as u8, (indications >> 16) as u8, (indications >> 24) as u8, (indications >> 32) as u8, (indications >> 40) as u8, (indications >> 48) as u8, (indications >> 56) as u8 ]) } else { set("OsIndications", &[]) } } pub fn get_os_indications_supported() -> Result<u64> { let mut data = [0; 8]; let count = get("OsIndicationsSupported", &mut data)?; if count == 8 { Ok( (data[0] as u64) | ((data[1] as u64) << 8) | ((data[2] as u64) << 16) | ((data[3] as u64) << 24) | ((data[4] as u64) << 32) | ((data[5] as u64) << 40) | ((data[6] as u64) << 48) | ((data[7] as u64) << 56) ) } else { Err(Error::LoadError) } }