1use bitflags::bitflags;
4use plain::Plain;
5use uefi::guid::Guid;
6
7#[derive(Debug)]
8pub enum HeaderKind {
9 Raw,
10 Freeform,
11 SecurityCore,
12 PeiCore,
13 DxeCore,
14 Peim,
15 Driver,
16 CombinedPeimDriver,
17 Application,
18 Mm,
19 VolumeImage,
20 CombinedMmDxe,
21 MmCore,
22 MmStandalone,
23 MmCoreStandalone,
24 Oem(u8),
25 Debug(u8),
26 Ffs(u8),
27 Unknown(u8)
28}
29
30bitflags! {
31 pub struct Attributes: u8 {
32 const ATTRIB_TAIL_PRESENT = 0x01;
33 const ATTRIB_RECOVERY = 0x02;
34 const ATTRIB_HEADER_EXTENSION = 0x04;
35 const ATTRIB_CHECKSUM = 0x40;
36 }
37}
38
39bitflags! {
40 pub struct State: u8 {
41 const STATE_HEADER_CONSTRUCTION = 0x01;
42 const STATE_HEADER_VALID = 0x02;
43 const STATE_DATA_VALID = 0x04;
44 const STATE_MARKED_FOR_UPDATE = 0x08;
45 const STATE_DELETED = 0x10;
46 const STATE_HEADER_INVALID = 0x20;
47 }
48}
49
50#[repr(packed)]
51pub struct Header {
52 pub guid: Guid,
53 pub integrity_check: u16,
54 kind: u8,
55 attributes: u8,
56 size: [u8; 3],
57 state: u8,
58}
59
60impl Header {
61 pub fn kind(&self) -> HeaderKind {
62 match self.kind {
63 0x01 => HeaderKind::Raw,
64 0x02 => HeaderKind::Freeform,
65 0x03 => HeaderKind::SecurityCore,
66 0x04 => HeaderKind::PeiCore,
67 0x05 => HeaderKind::DxeCore,
68 0x06 => HeaderKind::Peim,
69 0x07 => HeaderKind::Driver,
70 0x08 => HeaderKind::CombinedPeimDriver,
71 0x09 => HeaderKind::Application,
72 0x0A => HeaderKind::Mm,
73 0x0B => HeaderKind::VolumeImage,
74 0x0C => HeaderKind::CombinedMmDxe,
75 0x0D => HeaderKind::MmCore,
76 0x0E => HeaderKind::MmStandalone,
77 0x0F => HeaderKind::MmCoreStandalone,
78 oem @ 0xC0..=0xDF => HeaderKind::Oem(oem),
79 debug @ 0xE0..=0xEF => HeaderKind::Debug(debug),
80 ffs @ 0xF0..=0xFF => HeaderKind::Ffs(ffs),
81 unknown => HeaderKind::Unknown(unknown)
82 }
83 }
84
85 pub fn size(&self) -> usize {
86 self.size[0] as usize | (self.size[1] as usize) << 8 | (self.size[2] as usize) << 16
87 }
88
89 pub fn attributes(&self) -> Attributes {
90 Attributes::from_bits_truncate(self.attributes)
91 }
92
93 pub fn alignment(&self) -> u8 {
94 (self.attributes & 0x38) >> 3
95 }
96
97 pub fn state(&self, polarity: bool) -> State {
98 State::from_bits_truncate(if polarity {
99 ! self.state
100 } else {
101 self.state
102 })
103 }
104
105 pub fn sectioned(&self) -> bool {
106 match self.kind() {
107 HeaderKind::Raw => false,
108 HeaderKind::Freeform => true,
109 HeaderKind::SecurityCore => false,
110 HeaderKind::PeiCore => true,
111 HeaderKind::DxeCore => true,
112 HeaderKind::Peim => true,
113 HeaderKind::Driver => true,
114 HeaderKind::CombinedPeimDriver => true,
115 HeaderKind::Application => true,
116 HeaderKind::Mm => true,
117 HeaderKind::VolumeImage => true,
118 HeaderKind::CombinedMmDxe => true,
119 HeaderKind::MmCore => true,
120 HeaderKind::MmStandalone => true,
121 HeaderKind::MmCoreStandalone => false,
122 HeaderKind::Oem(_oem) => false,
123 HeaderKind::Debug(_debug) => false,
124 HeaderKind::Ffs(_ffs) => false,
125 HeaderKind::Unknown(_unknown) => false
126 }
127 }
128}
129
130unsafe impl Plain for Header {}