efivar_fix/efi/
variable_flags.rs1use std::{fmt::Display, str::FromStr};
4
5use crate::Error;
6
7bitflags::bitflags! {
8 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10 pub struct VariableFlags : u32 {
11 const NON_VOLATILE = 0x1;
12 const BOOTSERVICE_ACCESS = 0x2;
13 const RUNTIME_ACCESS = 0x4;
14 const HARDWARE_ERROR_RECORD = 0x8;
15 const AUTHENTICATED_WRITE_ACCESS = 0x10;
16 const TIME_BASED_AUTHENTICATED_WRITE_ACCESS = 0x20;
17 const APPEND_WRITE = 0x40;
18 const ENHANCED_AUTHENTICATED_ACCESS = 0x80;
19 }
20}
21
22impl Default for VariableFlags {
23 fn default() -> Self {
24 VariableFlags::NON_VOLATILE
25 | VariableFlags::BOOTSERVICE_ACCESS
26 | VariableFlags::RUNTIME_ACCESS
27 }
28}
29
30impl FromStr for VariableFlags {
31 type Err = Error;
32
33 fn from_str(s: &str) -> Result<VariableFlags, Self::Err> {
34 match s {
35 "EFI_VARIABLE_NON_VOLATILE" => Ok(VariableFlags::NON_VOLATILE),
36 "EFI_VARIABLE_BOOTSERVICE_ACCESS" => Ok(VariableFlags::BOOTSERVICE_ACCESS),
37 "EFI_VARIABLE_RUNTIME_ACCESS" => Ok(VariableFlags::RUNTIME_ACCESS),
38 "EFI_VARIABLE_HARDWARE_ERROR_RECORD" => Ok(VariableFlags::HARDWARE_ERROR_RECORD),
39 "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS" => {
40 Ok(VariableFlags::AUTHENTICATED_WRITE_ACCESS)
41 }
42 "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS" => {
43 Ok(VariableFlags::TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
44 }
45 "EFI_VARIABLE_APPEND_WRITE" => Ok(VariableFlags::APPEND_WRITE),
46 "EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS" => {
47 Ok(VariableFlags::ENHANCED_AUTHENTICATED_ACCESS)
48 }
49 _ => Err(Error::UnknownFlag { flag: s.to_owned() }),
50 }
51 }
52}
53
54impl Display for VariableFlags {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 let mut flag_strings = Vec::new();
57
58 if self.contains(VariableFlags::NON_VOLATILE) {
59 flag_strings.push("EFI_VARIABLE_NON_VOLATILE");
60 }
61 if self.contains(VariableFlags::BOOTSERVICE_ACCESS) {
62 flag_strings.push("EFI_VARIABLE_BOOTSERVICE_ACCESS");
63 }
64 if self.contains(VariableFlags::RUNTIME_ACCESS) {
65 flag_strings.push("EFI_VARIABLE_RUNTIME_ACCESS");
66 }
67 if self.contains(VariableFlags::HARDWARE_ERROR_RECORD) {
68 flag_strings.push("EFI_VARIABLE_HARDWARE_ERROR_RECORD");
69 }
70 if self.contains(VariableFlags::AUTHENTICATED_WRITE_ACCESS) {
71 flag_strings.push("EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS");
72 }
73 if self.contains(VariableFlags::TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
74 flag_strings.push("EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS");
75 }
76 if self.contains(VariableFlags::APPEND_WRITE) {
77 flag_strings.push("EFI_VARIABLE_APPEND_WRITE");
78 }
79 if self.contains(VariableFlags::ENHANCED_AUTHENTICATED_ACCESS) {
80 flag_strings.push("EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS");
81 }
82
83 f.write_str(&flag_strings.join("\n"))
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn variable_flags_to_string_empty() {
93 assert_eq!(VariableFlags::empty().to_string(), "");
94 }
95
96 #[test]
97 fn variable_flags_to_string_all() {
98 let s = (VariableFlags::NON_VOLATILE
99 | VariableFlags::BOOTSERVICE_ACCESS
100 | VariableFlags::RUNTIME_ACCESS
101 | VariableFlags::HARDWARE_ERROR_RECORD
102 | VariableFlags::AUTHENTICATED_WRITE_ACCESS
103 | VariableFlags::TIME_BASED_AUTHENTICATED_WRITE_ACCESS
104 | VariableFlags::APPEND_WRITE
105 | VariableFlags::ENHANCED_AUTHENTICATED_ACCESS)
106 .to_string();
107
108 assert!(s.contains("NON_VOLATILE"));
109 assert!(s.contains("BOOTSERVICE_ACCESS"));
110 assert!(s.contains("RUNTIME_ACCESS"));
111 assert!(s.contains("HARDWARE_ERROR_RECORD"));
112 assert!(s.contains("AUTHENTICATED_WRITE_ACCESS"));
113 assert!(s.contains("TIME_BASED_AUTHENTICATED_WRITE_ACCESS"));
114 assert!(s.contains("APPEND_WRITE"));
115 assert!(s.contains("ENHANCED_AUTHENTICATED_ACCESS"));
116 }
117
118 #[test]
119 fn variable_flags_from_string_all() {
120 assert_eq!(
121 VariableFlags::from_str("EFI_VARIABLE_NON_VOLATILE").unwrap(),
122 VariableFlags::NON_VOLATILE
123 );
124 assert_eq!(
125 VariableFlags::from_str("EFI_VARIABLE_BOOTSERVICE_ACCESS").unwrap(),
126 VariableFlags::BOOTSERVICE_ACCESS
127 );
128 assert_eq!(
129 VariableFlags::from_str("EFI_VARIABLE_RUNTIME_ACCESS").unwrap(),
130 VariableFlags::RUNTIME_ACCESS
131 );
132 assert_eq!(
133 VariableFlags::from_str("EFI_VARIABLE_HARDWARE_ERROR_RECORD").unwrap(),
134 VariableFlags::HARDWARE_ERROR_RECORD
135 );
136 assert_eq!(
137 VariableFlags::from_str("EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS").unwrap(),
138 VariableFlags::AUTHENTICATED_WRITE_ACCESS
139 );
140 assert_eq!(
141 VariableFlags::from_str("EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS").unwrap(),
142 VariableFlags::TIME_BASED_AUTHENTICATED_WRITE_ACCESS
143 );
144 assert_eq!(
145 VariableFlags::from_str("EFI_VARIABLE_APPEND_WRITE").unwrap(),
146 VariableFlags::APPEND_WRITE
147 );
148 assert_eq!(
149 VariableFlags::from_str("EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS").unwrap(),
150 VariableFlags::ENHANCED_AUTHENTICATED_ACCESS
151 );
152 }
153
154 #[test]
155 fn variable_flags_from_string_invalid() {
156 assert!(matches!(
157 VariableFlags::from_str("UNKNOWN_FLAG").unwrap_err(),
158 Error::UnknownFlag {
159 flag
160 } if flag == "UNKNOWN_FLAG"
161 ));
162 }
163}