Skip to main content

efivar_fix/boot/parse/
device_path_list.rs

1//! This module contains parsing code for the device path list component of a boot entry
2
3use std::fmt::Display;
4
5use super::{
6    device_path::{self, FilePath},
7    DevicePath, EFIHardDrive,
8};
9
10/// holds the potential fields we may get from a packed file path list
11/// TODO remove ?
12#[derive(Debug)]
13pub struct OptFilePathList {
14    pub file_path: Option<FilePath>,
15    pub hard_drive: Option<EFIHardDrive>,
16}
17
18/// Same structure as OptFilePathList, but we ensure that the file path list
19/// is a valid file path overall
20#[derive(Debug, PartialEq, Clone)]
21pub struct FilePathList {
22    pub file_path: FilePath,
23    pub hard_drive: EFIHardDrive,
24}
25
26impl From<OptFilePathList> for Option<FilePathList> {
27    fn from(value: OptFilePathList) -> Self {
28        Some(FilePathList {
29            file_path: value.file_path?,
30            hard_drive: value.hard_drive?,
31        })
32    }
33}
34
35impl Display for FilePathList {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        write!(f, "{}/File({})", self.hard_drive, self.file_path.path)
38    }
39}
40
41impl FilePathList {
42    pub fn parse(full_buf: &mut &[u8]) -> crate::Result<OptFilePathList> {
43        let mut file_path_list = OptFilePathList {
44            file_path: None,
45            hard_drive: None,
46        };
47
48        loop {
49            if full_buf.is_empty() {
50                break;
51            } else {
52                match DevicePath::parse(full_buf)? {
53                    Some(DevicePath::FilePath(inner_path)) => {
54                        file_path_list.file_path = Some(inner_path);
55                    }
56                    Some(DevicePath::HardDrive(inner_hard_drive)) => {
57                        file_path_list.hard_drive = Some(inner_hard_drive);
58                    }
59                    None => {}
60                };
61            };
62        }
63
64        Ok(file_path_list)
65    }
66
67    pub fn to_bytes(&self) -> Vec<u8> {
68        let mut bytes: Vec<u8> = vec![];
69
70        bytes.append(&mut self.hard_drive.to_bytes_encap());
71        bytes.append(&mut self.file_path.to_bytes_encap());
72        bytes.append(&mut device_path::get_end_device_path_bytes());
73
74        bytes
75    }
76}