use crate::{guid, Guid};
pub const EFI_DEVICE_PATH_PROTOCOL_GUID: Guid = guid!(
0x9576e91,
0x6d3f,
0x11d2,
[0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b]
);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(u8)]
pub enum DevicePathType {
EFI_DEV_MEDIA = 4,
EFI_DEV_END_PATH = 0x7f,
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(u8)]
pub enum DevicePathSubtype {
EFI_DEV_MEDIA_VENDOR = 3,
EFI_DEV_END_ENTIRE = 0xff,
}
#[derive(Clone, PartialEq, Debug)]
#[repr(C, packed)]
pub struct DevicePath {
pub _type: DevicePathType,
pub subtype: DevicePathSubtype,
pub size: u16,
}
impl Copy for DevicePath {}
#[repr(C)]
pub struct VendorMedia {
pub header: DevicePath,
pub vendor_guid: Guid,
}
impl DevicePath {
pub(crate) fn is_prefix_of(&self, other: &DevicePath) -> Option<isize> {
let mut ret = 0;
let mut l = self;
let mut r = other;
while *l == *r {
if l._type == DevicePathType::EFI_DEV_END_PATH || l.size != r.size {
break;
}
let p1 = l as *const _ as *const u8;
let p2 = r as *const _ as *const u8;
let s = l.size as isize;
let (s1, s2) = unsafe {
(
core::slice::from_raw_parts(p1, s as usize),
core::slice::from_raw_parts(p2, s as usize),
)
};
if s1 != s2 {
return None;
}
l = unsafe { &*(p1.offset(s) as *const DevicePath) };
r = unsafe { &*(p2.offset(s) as *const DevicePath) };
ret += s;
}
if l._type == DevicePathType::EFI_DEV_END_PATH {
Some(ret)
} else {
None
}
}
pub(crate) fn equals(&self, other: &DevicePath) -> bool {
self.is_prefix_of(other).is_some() && other.is_prefix_of(self).is_some()
}
}