FAT(R)12/16/32/LFN Structures, Records
IMPORTANT: boot record start = 0x03
IMPORTANT: partition #1 start = 0x1BE
IMPORTANT: partition #2 start = 0x1CE
IMPORTANT: partition #3 start = 0x1DE
IMPORTANT: partition #4 start = 0x1EE

Partition table Record
[BYTE]Boot_indicator
[BYTE]Beginning_head_number
[BYTE]Beginning_sector_and_high_cylinder_number
[BYTE]Beginning_low_cylinder_number
[BYTE]System_indicator
[BYTE]Ending_head_number
[BYTE]Ending_sector_and_high_cylinder_number
[BYTE]Ending_low_cylinder_number
[DWORD]Number_of_sectors_preceding_the_partition
[DWORD]Number_of_sectors_in_the_partition

Boot sector Record
[BYTE]OEM_Identifier[8]
[WORD]BytesPerSector
[BYTE]SectorsPerCluster
[WORD]ReservedSectors
[BYTE]NumberOfFATs
[WORD]RootEntries
[WORD]NumberOfSectors
[BYTE]MediaDescriptor
[WORD]SectorsPerFAT
[WORD]SectorsPerHead
[WORD]HeadsPerCylinder As ushort
[DWORD]HiddenSectors
[DWORD]BigNumberOfSectors
[DWORD]BigSectorsPerFAT
[WORD]ExtFlags
[WORD]FSVersion
[DWORD]RootDirectoryStart
[WORD]FSInfoSector
[WORD]BackupBootSector As UShort
Const boot_sector_ext_16= &h25
Const boot_sector_ext_32= &h41
Boot sector extension (just after first record)
[BYTE]BIOS_drive_number
[BYTE]Reserved
[BYTE]Extended_Boot_Record_signature
[DWORD]Serial_Number
[BYTE]Volume_label[11]
[DWORD]System_Identifier[2]
Directory entry record
[BYTE]Filename[8]
[BYTE]Extension[3]
[BYTE]Attribute
[BYTE]Case_
[BYTE]Creation_time_ms
[WORD]Creation_time
[WORD]Creation_date
[WORD]Last_access_date
[WORD]Starting_cluster_high
[WORD]Time_stamp
[WORD]Date_stamp
[WORD]Starting_cluster
[DWORD]Size

LFN Directory entry record
[BYTE]Sequence_number_for_the_slot
[WORD]First_five_characters_in_filename[5]
[BYTE]Attribute {=0x0F}
[BYTE]Reserved {=0}
[BYTE]Alias_checksum
[WORD]Next_six_characters_in_filename[6]
[WORD]Starting_cluster {=0}
[WORD]Last_two_characters_in_filename[2]

For long_ ilenames entries:
  • LFN Attribute = 0x0F
  • LFN reserved = 0
  • LFN starting_sector = 0
  • LFN slot_end = 0x40

    Check sum calculation for LFN entries
    dim as ubyte sum,i
    for i=0 to 9
    sum=(((sum and 1)shl 7)|((sum and &HFE)shr 1))+name(i)
    next i

    TIME and DATE format
    Bits Range Translated Range Valid Range Description
    0..4 0..31 0..62 0..59 Seconds/2
    5..10 0..63 0..63 0..59 Minutes
    11..15 0..31 0..31 0..23 Hours
    Date stamp, last accessed date, and creation date have the following format:
    Bits Range Translated Range Valid Range Description
    0..4 0..31 0..31 1..28 up to 1..31 Day, blame Julian for complexity
    5..8 0..15 0..15 1..12 Month
    9..15 0..127 1980..2107 1980..2107 Year, add 1980 to convert



  • FAT stands for FileAllocatioTable. This file system organization is patented by Microsoft(R).
    As I could understand, the impementation of FAT12/16/32 is free as long as you don't ask money for it ...

    Steps to access a FAT partition
    Step (1)read LBA sector 0 (MBR-MasterBootRecord) of disk - sector length 512 bytes
    Step (2)partition #1 record is at byte position 0x1BE - access it using a PARTITION ENTRY structure/record/type
    Step (3)Now we have a PARTITION ENTRY . First byte is 0x80 if this partition is BOOTABLE or 0 if NOT!
    Step (4)Byte 5 gives us information about PARTITION type. FAT partitions have following IDs:
  • FAT12=0x01
  • FAT16_small32m=0x04
  • EXTENDED_PARTITION=0x05
  • FAT16_LBA=0x0E
  • FAT16_CHS=0x06
  • FAT32_LBA=0x0C
  • FAT32_CHS=0x0b
  • FAT32_LBA_EXTENDED=0x0F
  • Step (4)Once we indetifyed our partition type we analyze it's structure: starting sector and length
    If it's of type : fat12/fat16/fat32 then record entry named Number_of_sectors_preceding_the_partition + (plus) the position of MBR (sector 0 in out case) gives us the starting sector of our partition !.
    At that sector [Number_of_sectors_preceding_the_partition + MBR] we have the boot sector that is used to boot
    the operation system on that partition !
    Step (5)Repeat upword steps for the rest three partitions entries (there are 4 entries in total)
    Step (6)Select your desired partition
    Step (7)Read BOOT sector (1 sector, 512bytes) for your favorite partition, located at :[Number_of_sectors_preceding_the_partition + MBR]
    Boot sector of FAT partitions will give information about its settings/structure.
    Step (8)Access boot record from withing BOOT_SECTOR !
    Warning boot_record doesn't start at byte 1 of boot sector, but at byte 3 of the boot sector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Entry [SectorsPerCluster] gives you the FAT block length = [SectorsPerCluster] * 512 = Cluster_size ([SectorsPerCluster] SHL 9)
    Entry [SectorsPerFAT] or [BigSectorsPerFAT] gives you the FileAllocationTable length
    How to choose between [SectorsPerFAT] and [BigSectorsPerFAT] ? If one of this items is zero (0) use the other one !
    Or if [BigSectorsPerFAT] gives a too big FAT size (unusual) use the other entry [SectorsPerFAT] !

    FAT chain starts at : [ReservedSectors] + [HiddenSectors] !
    Warning some times [HiddenSectors] ! HiddeSectors value is actually equal with PARTITION.Number_of_sectors_preceding_the_partition !
    In case HiddenSectors is 0 use PARTITION_TABLE(selectedpartition).Number_of_sectors_preceding_the_partition !