168 lines
5.6 KiB
Rust
168 lines
5.6 KiB
Rust
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<T: Read>(disk: &mut T) -> Result<Self, io::Error> {
|
|
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,
|
|
})
|
|
}
|
|
}
|