#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Bpb {
pub bytes_per_sector: u16,
pub sectors_per_cluster: u8,
pub reserved_sectors: u16,
pub hidden_sectors: u32,
}
#[must_use]
pub fn parse_bpb(sector: &[u8]) -> Option<Bpb> {
if sector.len() < 512 {
return None;
}
if sector[510] != 0x55 || sector[511] != 0xAA {
return None;
}
let bytes_per_sector = u16::from_le_bytes([sector[11], sector[12]]);
if !matches!(bytes_per_sector, 512 | 1024 | 2048 | 4096) {
return None;
}
let sectors_per_cluster = sector[13];
if !sectors_per_cluster.is_power_of_two() {
return None;
}
let reserved_sectors = u16::from_le_bytes([sector[14], sector[15]]);
let hidden_sectors = u32::from_le_bytes([sector[28], sector[29], sector[30], sector[31]]);
Some(Bpb {
bytes_per_sector,
sectors_per_cluster,
reserved_sectors,
hidden_sectors,
})
}