1use core::fmt;
21
22#[macro_export]
23macro_rules! guid {
24 ($guid_str:literal) => {
25 $crate::guid::Guid::parse_str($guid_str)
26 };
27}
28
29const HYPHENATED_LEN: usize = 36;
31
32#[deprecated(note = "use `Guid::NULL`")]
33pub const NULL_GUID: Guid = guid!("00000000-0000-0000-0000-000000000000");
34pub const MPS_TABLE_GUID: Guid = guid!("eb9d2d2f-2d88-11d3-9a16-0090273fc14d");
35pub const ACPI_TABLE_GUID: Guid = guid!("eb9d2d30-2d88-11d3-9a16-0090273fc14d");
36pub const ACPI_20_TABLE_GUID: Guid = guid!("8868e871-e4f1-11d3-bc22-0080c73c8881");
37pub const SMBIOS_TABLE_GUID: Guid = guid!("eb9d2d31-2d88-11d3-9a16-0090273fc14d");
38pub const SMBIOS3_TABLE_GUID: Guid = guid!("f2fd1544-9794-4a2c-992e-e5bbcf20e394");
39pub const SAL_SYSTEM_TABLE_GUID: Guid = guid!("eb9d2d32-2d88-11d3-9a16-0090273fc14d");
40pub const HCDP_TABLE_GUID: Guid = guid!("f951938d-620b-42ef-8279-a84b79617898");
41pub const UGA_IO_PROTOCOL_GUID: Guid = guid!("61a4d49e-6f68-4f1b-b922-a86eed0b07a2");
42#[deprecated(note = "use `TextOutput::GUID`")]
43pub const SIMPLE_TEXT_OUTPUT_GUID: Guid = guid!("387477c2-69c7-11d2-8e39-00a0c969723b");
44pub const GLOBAL_VARIABLE_GUID: Guid = guid!("8be4df61-93ca-11d2-aa0d-00e098032b8c");
45pub const UV_SYSTEM_TABLE_GUID: Guid = guid!("3b13a7d4-633e-11dd-93ec-da2556d89593");
46pub const LINUX_EFI_CRASH_GUID: Guid = guid!("cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0");
47#[deprecated(note = "use `LoadedImage::GUID`")]
48pub const LOADED_IMAGE_PROTOCOL_GUID: Guid = guid!("5b1b31a1-9562-11d2-8e3f-00a0c969723b");
49pub const LOADED_IMAGE_DEVICE_PATH_GUID: Guid = guid!("bc62157e-3e33-4fec-9920-2d3b36d750df");
50#[deprecated(note = "use `GraphicsOutput::GUID`")]
51pub const GRAPHICS_OUTPUT_PROTOCOL_GUID: Guid = guid!("9042a9de-23dc-4a38-96fb-7aded080516a");
52pub const UGA_PROTOCOL_GUID: Guid = guid!("982c298b-f4fa-41cb-b838-77aa688fb839");
53pub const PCI_IO_PROTOCOL_GUID: Guid = guid!("4cf5b200-68b8-4ca5-9eec-b23e3f50029a");
54#[deprecated(note = "use `FileInfo::ID`")]
55pub const FILE_INFO_ID: Guid = guid!("09576e92-6d3f-11d2-8e39-00a0c969723b");
56pub const SYSTEM_RESOURCE_TABLE_GUID: Guid = guid!("b122a263-3661-4f68-9929-78f8b0d62180");
57#[deprecated(note = "use `BlockIo::GUID`")]
58pub const BLOCK_IO_GUID: Guid = guid!("964e5b21-6459-11d2-8e39-00a0c969723b");
59#[deprecated(note = "use `SimplFileSystem::GUID`")]
60pub const FILE_SYSTEM_GUID: Guid = guid!("964e5b22-6459-11d2-8e39-00a0c969723b");
61pub const LOAD_FILE_GUID: Guid = guid!("56ec3091-954c-11d2-8e3f-00a0c969723b");
62#[deprecated(note = "use `DevicePath::GUID`")]
63pub const DEVICE_PATH_GUID: Guid = guid!("09576e91-6d3f-11d2-8e39-00a0c969723b");
64pub const DEVICE_TREE_GUID: Guid = guid!("b1b621d5-f19c-41a5-830b-d9152c69aae0");
65pub const PROPERTIES_TABLE_GUID: Guid = guid!("880aaca3-4adc-4a04-9079-b747340825e5");
66pub const RNG_PROTOCOL_GUID: Guid = guid!("3152bca5-eade-433d-862e-c01cdc291f44");
67pub const RNG_ALGORITHM_RAW: Guid = guid!("e43176d7-b6e8-4827-b784-7ffdc4b68561");
68pub const MEMORY_ATTRIBUTES_TABLE_GUID: Guid = guid!("dcfa911d-26eb-469f-a220-38b7dc461220");
69pub const CONSOLE_OUT_DEVICE_GUID: Guid = guid!("d3b36f2c-d551-11d4-9a46-0090273fc14d");
70pub const SECTION_TIANO_COMPRESS_GUID: Guid = guid!("a31280ad-481e-41b6-95e8-127f4c984779");
71pub const SECTION_LZMA_COMPRESS_GUID: Guid = guid!("ee4e5898-3914-4259-9d6e-dc7bd79403cf");
72pub const DXE_SERVICES_TABLE_GUID: Guid = guid!("05ad34ba-6f02-4214-952e-4da0398e2bb9");
73pub const HOB_LIST_GUID: Guid = guid!("7739f24c-93d7-11d4-9a3a-0090273fc14d");
74pub const MEMORY_TYPE_INFORMATION_GUID: Guid = guid!("4c19049f-4137-4dd3-9c10-8b97a83ffdfa");
75pub const DEBUG_IMAGE_INFO_TABLE_GUID: Guid = guid!("49152e77-1ada-4764-b7a2-7afefed95e8b");
76#[deprecated(note = "use `Shell::GUID`")]
77pub const SHELL_GUID: Guid = guid!("6302d008-7f9b-4f30-87ac-60c9fef5da4e");
78#[deprecated(note = "use `ShellParameters::GUID`")]
79pub const SHELL_PARAMETERS_GUID: Guid = guid!("752f3136-4e16-4fdc-a22a-e5f46812f4ca");
80#[deprecated(note = "use `SimplePointer::GUID`")]
81pub const SIMPLE_POINTER_GUID: Guid = guid!("31878c87-0b75-11d5-9a4f-0090273fc14d");
82#[deprecated(note = "use `HiiDatabase::GUID`")]
83pub const HII_DATABASE_GUID: Guid = guid!("ef9fc172-a1b2-4693-b327-6d32fc416042");
84#[deprecated(note = "use `ComponentName::GUID`")]
85pub const COMPONENT_NAME2_GUID: Guid = guid!("6a7a5cff-e8d9-4f70-bada-75ab3025ce14");
86
87#[derive(Copy, Clone, Debug, Eq, PartialEq)]
88#[repr(C)]
89pub struct Guid(pub u32, pub u16, pub u16, pub [u8; 8]);
90
91#[deprecated(note = "use `Guid` directly")]
92#[derive(Copy, Clone, Debug, Eq, PartialEq)]
93pub enum GuidKind {
94 Null,
95 Mps,
96 Acpi,
97 Acpi2,
98 Smbios,
99 Smbios3,
100 SalSystem,
101 Hcdp,
102 UgaIo,
103 GlobalVariable,
104 SimpleTextOutput,
105 UvSystem,
106 LinuxEfiCrash,
107 LoadedImage,
108 GraphicsOutput,
109 Uga,
110 PciIo,
111 FileInfo,
112 SystemResource,
113 BlockIo,
114 FileSystem,
115 LoadFile,
116 DevicePath,
117 DeviceTree,
118 Properties,
119 Rng,
120 RngAlrorithm,
121 MemoryAttributes,
122 ConsoleOut,
123 SectionTianoCompress,
124 SectionLzmaCompress,
125 DxeServices,
126 HobList,
127 MemoryTypeInformation,
128 DebugImageInfo,
129 Shell,
130 ShellParameters,
131 SimplePointer,
132 HiiDatabase,
133 ComponentName2,
134 Unknown,
135}
136
137impl Guid {
138 pub const NIL: Self = guid!("00000000-0000-0000-0000-000000000000");
140 pub const NULL: Self = Self::NIL;
142 pub const MAX: Self = guid!("ffffffff-ffff-ffff-ffff-ffffffffffff");
144
145 pub const fn parse_str(literal: &str) -> Self {
155 if literal.len() != HYPHENATED_LEN {
156 panic!("invalid GUID length");
157 }
158
159 let bytes = literal.as_bytes();
160
161 if bytes[8] != b'-' || bytes[13] != b'-' || bytes[18] != b'-' || bytes[23] != b'-' {
163 panic!("invalid GUID format");
164 }
165
166 let mut raw = [0u8; 16];
167
168 let mut i = 0;
169 let mut j = 0;
170 while i < HYPHENATED_LEN {
171 if i == 8 || i == 13 || i == 18 || i == 23 {
172 i += 1;
174 }
175
176 let hi = hex_to_u8(bytes[i]);
177 let lo = hex_to_u8(bytes[i + 1]);
178
179 let b = hi << 4 | lo;
180 raw[j] = b;
181
182 i += 2;
183 j += 1;
184 }
185
186 let d1 = u32::from_be_bytes([raw[0], raw[1], raw[2], raw[3]]);
187 let d2 = u16::from_be_bytes([raw[4], raw[5]]);
188 let d3 = u16::from_be_bytes([raw[6], raw[7]]);
189 let d4 = [
190 raw[8], raw[9], raw[10], raw[11], raw[12], raw[13], raw[14], raw[15],
191 ];
192
193 Self(d1, d2, d3, d4)
194 }
195
196 #[allow(deprecated)]
197 #[deprecated(note = "compare `Guid`s directly")]
198 pub fn kind(&self) -> GuidKind {
199 match *self {
200 NULL_GUID => GuidKind::Null,
201 MPS_TABLE_GUID => GuidKind::Mps,
202 ACPI_TABLE_GUID => GuidKind::Acpi,
203 ACPI_20_TABLE_GUID => GuidKind::Acpi2,
204 SMBIOS_TABLE_GUID => GuidKind::Smbios,
205 SMBIOS3_TABLE_GUID => GuidKind::Smbios3,
206 SAL_SYSTEM_TABLE_GUID => GuidKind::SalSystem,
207 HCDP_TABLE_GUID => GuidKind::Hcdp,
208 UGA_IO_PROTOCOL_GUID => GuidKind::UgaIo,
209 GLOBAL_VARIABLE_GUID => GuidKind::GlobalVariable,
210 SIMPLE_TEXT_OUTPUT_GUID => GuidKind::SimpleTextOutput,
211 UV_SYSTEM_TABLE_GUID => GuidKind::UvSystem,
212 LINUX_EFI_CRASH_GUID => GuidKind::LinuxEfiCrash,
213 LOADED_IMAGE_PROTOCOL_GUID => GuidKind::LoadedImage,
214 GRAPHICS_OUTPUT_PROTOCOL_GUID => GuidKind::GraphicsOutput,
215 UGA_PROTOCOL_GUID => GuidKind::Uga,
216 PCI_IO_PROTOCOL_GUID => GuidKind::PciIo,
217 FILE_INFO_ID => GuidKind::FileInfo,
218 SYSTEM_RESOURCE_TABLE_GUID => GuidKind::SystemResource,
219 BLOCK_IO_GUID => GuidKind::BlockIo,
220 FILE_SYSTEM_GUID => GuidKind::FileSystem,
221 LOAD_FILE_GUID => GuidKind::LoadFile,
222 DEVICE_PATH_GUID => GuidKind::DevicePath,
223 DEVICE_TREE_GUID => GuidKind::DeviceTree,
224 PROPERTIES_TABLE_GUID => GuidKind::Properties,
225 RNG_PROTOCOL_GUID => GuidKind::Rng,
226 RNG_ALGORITHM_RAW => GuidKind::RngAlrorithm,
227 MEMORY_ATTRIBUTES_TABLE_GUID => GuidKind::MemoryAttributes,
228 CONSOLE_OUT_DEVICE_GUID => GuidKind::ConsoleOut,
229 SECTION_TIANO_COMPRESS_GUID => GuidKind::SectionTianoCompress,
230 SECTION_LZMA_COMPRESS_GUID => GuidKind::SectionLzmaCompress,
231 DXE_SERVICES_TABLE_GUID => GuidKind::DxeServices,
232 HOB_LIST_GUID => GuidKind::HobList,
233 MEMORY_TYPE_INFORMATION_GUID => GuidKind::MemoryTypeInformation,
234 DEBUG_IMAGE_INFO_TABLE_GUID => GuidKind::DebugImageInfo,
235 SHELL_GUID => GuidKind::Shell,
236 SHELL_PARAMETERS_GUID => GuidKind::ShellParameters,
237 SIMPLE_POINTER_GUID => GuidKind::SimplePointer,
238 HII_DATABASE_GUID => GuidKind::HiiDatabase,
239 COMPONENT_NAME2_GUID => GuidKind::ComponentName2,
240 _ => GuidKind::Unknown,
241 }
242 }
243}
244
245#[doc(hidden)]
248const fn hex_to_u8(hex: u8) -> u8 {
249 match hex {
250 b'0'..=b'9' => hex - b'0',
251 b'A'..=b'F' => hex - b'A' + 10,
252 b'a'..=b'f' => hex - b'a' + 10,
253 _ => panic!("invalid hex value in GUID"),
254 }
255}
256
257impl fmt::Display for Guid {
258 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
259 write!(f, "{:x}", &self)
261 }
262}
263
264impl fmt::LowerHex for Guid {
265 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
266 write!(
267 f,
268 "{:08x}-{:04x}-{:04x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
269 self.0,
271 self.1,
273 self.2,
275 self.3[0],
277 self.3[1],
278 self.3[2],
280 self.3[3],
281 self.3[4],
282 self.3[5],
283 self.3[6],
284 self.3[7],
285 )
286 }
287}
288
289impl fmt::UpperHex for Guid {
290 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
291 write!(
292 f,
293 "{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
294 self.0,
296 self.1,
298 self.2,
300 self.3[0],
302 self.3[1],
303 self.3[2],
305 self.3[3],
306 self.3[4],
307 self.3[5],
308 self.3[6],
309 self.3[7],
310 )
311 }
312}