use std::convert::TryFrom;
use std::io::Error;
use std::io::ErrorKind;
use std::io::Result;
use crate::le;
use crate::Partition;
const SECTOR_SIZE: usize = 512;
pub fn parse_partition_table(sector: &[u8; SECTOR_SIZE]) -> Result<Vec<Partition>> {
let mut partitions = Vec::with_capacity(4);
for entry_id in 0..4 {
let first_entry_offset = 446;
let entry_size = 16;
let entry_offset = first_entry_offset + entry_id * entry_size;
let partition = §or[entry_offset..entry_offset + entry_size];
let status = partition[0];
let bootable = match status {
0x00 => false,
0x80 => true,
_ => {
return Err(Error::new(
ErrorKind::InvalidData,
format!(
"invalid status code in partition {}: {:x}",
entry_id, status
),
))
}
};
let type_code = partition[4];
if 0 == type_code {
continue;
}
let sector_size = u64::try_from(SECTOR_SIZE).expect("u64 constant");
let first_byte = u64::from(le::read_u32(&partition[8..])) * sector_size;
let len = u64::from(le::read_u32(&partition[12..])) * sector_size;
partitions.push(Partition {
id: entry_id,
first_byte,
len,
attributes: crate::Attributes::MBR {
type_code,
bootable,
},
});
}
Ok(partitions)
}