#[derive(Debug, Clone)]
pub struct BootEntry {
pub bootable: bool,
pub media_type: u8,
pub lba: u32,
pub sector_count: u16,
}
pub fn parse_boot_catalog(catalog: &[u8]) -> Vec<BootEntry> {
let mut entries = Vec::new();
if catalog.len() < 64 {
return entries;
}
if catalog[0] != 0x01 || catalog[30] != 0x55 || catalog[31] != 0xAA {
return entries;
}
let mut offset = 32;
while offset + 32 <= catalog.len() {
let e = &catalog[offset..offset + 32];
let boot_indicator = e[0];
if boot_indicator != 0x88 && boot_indicator != 0x00 {
break;
}
entries.push(BootEntry {
bootable: boot_indicator == 0x88,
media_type: e[1] & 0x0F,
lba: u32::from_le_bytes(e[8..12].try_into().unwrap()),
sector_count: u16::from_le_bytes(e[6..8].try_into().unwrap()),
});
offset += 32;
}
entries
}
pub fn boot_catalog_lba(sector: &[u8]) -> Option<u32> {
if sector.len() < 75 {
return None;
}
if sector[0] != 0x00 || §or[1..6] != b"CD001" || sector[6] != 0x01 {
return None;
}
if !sector[7..39].starts_with(b"EL TORITO SPECIFICATION") {
return None;
}
Some(u32::from_le_bytes(sector[71..75].try_into().unwrap()))
}