#include /** * media organization: * * boot record (1 sector, so could be called boot sector): BPB + Extended Boot Record * * File Allocation Table (FAT) * * data area */ struct ebr_fat16 { // Extended Boot Record for FAT16 uint8_t drive_number; uint8_t flags; uint8_t signature; // Must be 0x29 for FAT16 uint8_t vol_id[4]; uint8_t vol_label[11]; uint8_t sys_id[8]; // Do not trust this! uint8_t bootcode[448]; uint16_t bootable_signature; // 0xAA55 } __attribute__((packed)); struct ebr_fat32 { // Extended Boot Record for FAT32 uint32_t fat_size; uint16_t flags; uint16_t fat_version_number; uint32_t root_cluster_nb; uint8_t reserved[12]; uint8_t drive_number; uint8_t flags_nt; uint8_t signature; uint8_t vol_id[4]; uint8_t vol_label[11]; uint8_t sys_id[8]; // Should be always "FAT32" uint8_t bootcode[420]; uint16_t bootable_signature; // 0xAA55 } __attribute__((packed)); struct bpb { // Bios Param Block uint8_t jump_ins[3]; uint8_t oem_id[3]; uint16_t bytes_per_sector; uint8_t sector_per_cluster; uint16_t reserved_sectors; // boot sectors included uint8_t nb_fat; uint16_t nb_root_dirs; uint16_t nb_sectors; uint8_t media_description_type; uint16_t sectors_per_fat; uint16_t sectors_per_track; uint16_t number_of_heads; uint32_t hidden_sectors; uint32_t nb_large_sectors; union { struct ebr_fat32 fat32; struct ebr_fat16 fat16; }; } __attribute__((packed)); typedef enum { READ_ONLY = 0x01, HIDDEN = 0x02, SYSTEM = 0x04, VOLUME_ID = 0x08, DIRECTORY = 0x10, ARCHIVE = 0x20, LFN = READ_ONLY | HIDDEN | SYSTEM | VOLUME_ID, } __attribute__((__packed__)) directory_entry_type_t; struct directory_entry { uint8_t filename[11]; directory_entry_type_t type; uint8_t reserved; uint8_t creation_time_hundredths_sec; uint16_t creation_time; // hour[5] min[6] sec[5] uint16_t creation_date; // year[7] month[4] day[5] uint16_t last_access_date; // year[7] month[4] day[5] uint16_t cluster_nb_high; uint16_t modification_time; // hour[5] min[6] sec[5] uint16_t modification_date; // year[7] month[4] day[5] uint16_t cluster_nb_low; uint32_t size; // in bytes } __attribute__((packed));