use io::Read; use crate::io_ext::ReadLeExt; #[derive(Debug, Clone, Copy)] pub struct Fat32BootSector { // --- Jump + OEM --- pub jump_boot: [u8; 3], pub oem_name: [u8; 8], // --- BPB (BIOS Parameter Block) --- pub bytes_per_sector: u16, pub sectors_per_cluster: u8, pub reserved_sector_count: u16, pub num_fats: u8, pub root_entry_count: u16, pub total_sectors_16: u16, pub media: u8, pub fat_size_16: u16, pub sectors_per_track: u16, pub num_heads: u16, pub hidden_sectors: u32, pub total_sectors_32: u32, // --- FAT32 Extended BPB --- pub fat_size_32: u32, pub ext_flags: u16, pub fs_version: u16, pub root_cluster: u32, pub fs_info: u16, pub bk_boot_sec: u16, pub reserved: [u8; 12], // --- FAT32 Drive Info --- pub drive_number: u8, pub reserved1: u8, pub boot_signature: u8, pub volume_id: u32, pub volume_label: [u8; 11], pub fs_type: [u8; 8], // --- Boot code --- pub boot_code: [u8; 420], // --- Signature --- pub boot_sector_signature: u16, // 0xAA55 } impl core::fmt::Display for Fat32BootSector { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("Fat32BootSector") .field("jump_boot", &self.jump_boot) .field("oem_name", &self.get_oem_name()) .field("bytes_per_sector", &self.bytes_per_sector) .field("sectors_per_cluster", &self.sectors_per_cluster) .field("reserved_sector_count", &self.reserved_sector_count) .field("num_fats", &self.num_fats) .field("root_entry_count", &self.root_entry_count) .field("total_sectors_16", &self.total_sectors_16) .field("media", &self.media) .field("fat_size_16", &self.fat_size_16) .field("sectors_per_track", &self.sectors_per_track) .field("num_heads", &self.num_heads) .field("hidden_sectors", &self.hidden_sectors) .field("total_sectors_32", &self.total_sectors_32) .field("fat_size_32", &self.fat_size_32) .field("ext_flags", &self.ext_flags) .field("fs_version", &self.fs_version) .field("root_cluster", &self.root_cluster) .field("fs_info", &self.fs_info) .field("bk_boot_sec", &self.bk_boot_sec) .field("reserved", &self.reserved) .field("drive_number", &self.drive_number) .field("reserved1", &self.reserved1) .field("boot_signature", &self.boot_signature) .field("volume_id", &self.volume_id) .field("volume_label", &self.get_volume_label()) .field("fs_type", &self.get_fs_type()) .field("boot_code", &"[_; 420]") .field("boot_sector_signature", &self.boot_sector_signature) .finish() } } impl Fat32BootSector { pub fn get_oem_name(&self) -> Result<&str, core::str::Utf8Error> { str::from_utf8(&self.oem_name) } pub fn get_volume_label(&self) -> Result<&str, core::str::Utf8Error> { str::from_utf8(&self.volume_label) } pub fn get_fs_type(&self) -> Result<&str, core::str::Utf8Error> { str::from_utf8(&self.fs_type) } } impl Fat32BootSector { pub fn deserialize(disk: &mut T) -> Result { let mut jump_boot = [0u8; _]; disk.read_exact(&mut jump_boot)?; let mut oem_name = [0u8; _]; disk.read_exact(&mut oem_name)?; let bytes_per_sector = disk.read_u16_le()?; let sectors_per_cluster = disk.read_u8()?; let reserved_sector_count = disk.read_u16_le()?; let num_fats = disk.read_u8()?; let root_entry_count = disk.read_u16_le()?; let total_sectors_16 = disk.read_u16_le()?; let media = disk.read_u8()?; let fat_size_16 = disk.read_u16_le()?; let sectors_per_track = disk.read_u16_le()?; let num_heads = disk.read_u16_le()?; let hidden_sectors = disk.read_u32_le()?; let total_sectors_32 = disk.read_u32_le()?; let fat_size_32 = disk.read_u32_le()?; let ext_flags = disk.read_u16_le()?; let fs_version = disk.read_u16_le()?; let root_cluster = disk.read_u32_le()?; let fs_info = disk.read_u16_le()?; let bk_boot_sec = disk.read_u16_le()?; let mut reserved = [0u8; _]; disk.read_exact(&mut reserved)?; let drive_number = disk.read_u8()?; let reserved1 = disk.read_u8()?; let boot_signature = disk.read_u8()?; let volume_id = disk.read_u32_le()?; let mut volume_label = [0u8; _]; disk.read_exact(&mut volume_label)?; let mut fs_type = [0u8; _]; disk.read_exact(&mut fs_type)?; let mut boot_code = [0u8; _]; disk.read_exact(&mut boot_code)?; let boot_sector_signature = disk.read_u16_le()?; Ok(Self { jump_boot, oem_name, bytes_per_sector, sectors_per_cluster, reserved_sector_count, num_fats, root_entry_count, total_sectors_16, media, fat_size_16, sectors_per_track, num_heads, hidden_sectors, total_sectors_32, fat_size_32, ext_flags, fs_version, root_cluster, fs_info, bk_boot_sec, reserved, drive_number, reserved1, boot_signature, volume_id, volume_label, fs_type, boot_code, boot_sector_signature, }) } }