blob: 396361d2901d84e07a39dd70c93541cc4803385e [file] [log] [blame]
Lorenz Brunbd2ce6d2022-07-22 00:00:13 +00001package fat32
2
3const (
4 // FAT32 entries are only 28 bits
5 fatMask = 0x0fffffff
6 // Free entries are 0
7 fatFree = 0x0
8 // Entry at the end of a cluster chain
9 fatEOF = 0x0ffffff8
10)
11
12// FAT32 Boot Sector and BIOS Parameter Block. This structure is 512 bytes long,
13// even if the logical block size is longer. The rest should be filled up with
14// zeroes.
15type bootSector struct {
16 // Jump instruction to boot code.
17 JmpInstruction [3]byte
18 // Creator name. "MSWIN4.1" recommended for compatibility.
19 OEMName [8]byte
20 // Count of bytes per block (i.e. logical block size)
21 // Must be one of 512, 1024, 2048 or 4096
22 BlockSize uint16
23 // Number of blocks per allocation unit (cluster).
24 // Must be a power of 2 that is greater than 0.
25 BlocksPerCluster uint8
26 // Number of reserved blocks in the reserved region of the volume starting
27 // at the first block of the volume. This field must not be 0.
28 ReservedBlocks uint16
29 // The count of FAT data structures on the volume. This field should always
30 // contain the value of 2 for any FAT volume of any type.
31 NumFATs uint8
32 _ [4]byte
33 // Legacy value for media determination, must be 0xf8.
34 MediaCode uint8
35 _ [2]byte
36 // Number of sectors per track for 0x13 interrupts.
37 SectorsPerTrack uint16
38 // Number of heads for 0x13 interrupts.
39 NumHeads uint16
40 // Count of hidden blocks preceding the partition that contains this FAT
41 // volume.
42 HiddenBlocks uint32
43 // Total count of blocks on the volume.
44 TotalBlocks uint32
45 // Count of blocks per FAT.
46 BlocksPerFAT uint32
47 // Flags for FAT32
48 Flags uint16
49 _ [2]byte
50 // Cluster number of the first cluster of the root directory. Usually 2.
51 RootClusterNumber uint32
52 // Block number of the FSINFO structure in the reserved area.
53 FSInfoBlock uint16
54 // Block number of the copy of the boot record in the reserved area.
55 BackupStartBlock uint16
56 _ [12]byte
57 // Drive number for 0x13 interrupts.
58 DriveNumber uint8
59 _ [1]byte
60 BootSignature uint8
61 // ID of this filesystem
62 ID uint32
63 // Human-readable label of this filesystem, padded with spaces (0x20)
64 Label [11]byte
65 // Always set to ASCII "FAT32 "
66 Type [8]byte
67 _ [420]byte
68 // Always 0x55, 0xAA
69 Signature [2]byte
70}
71
72// Special block (usually at block 1) containing additional metadata,
73// specifically the number of free clusters and the next free cluster.
74// Always 512 bytes, rest of the block should be padded with zeroes.
75type fsinfo struct {
76 // Validates that this is an FSINFO block. Always 0x52, 0x52, 0x61, 0x41
77 LeadSignature [4]byte
78 _ [480]byte
79 // Another signature. Always 0x72, 0x72, 0x41, 0x61
80 StructSignature [4]byte
81 // Last known number of free clusters on the volume.
82 FreeCount uint32
83 // Next free cluster hint. All 1's is interpreted as undefined.
84 NextFreeCluster uint32
85 _ [14]byte
86 // One more signature. Always 0x55, 0xAA.
87 TrailingSignature [2]byte
88}
89
90// Directory entry
91type dirEntry struct {
92 // DOS 8.3 file name.
93 DOSName [11]byte
94 // Attribtes of the file or directory, 0x0f reserved to mark entry as a
95 // LFN entry (see lfnEntry below)
96 Attributes uint8
97 _ byte
98 CreationTenMilli uint8 // Actually 10ms units, 0-199 range
99 CreationTime uint16
100 CreationDate uint16
101 _ [2]byte
102 FirstClusterHigh uint16
103 LastWrittenToTime uint16
104 LastWrittenToDate uint16
105 FirstClusterLow uint16
106 FileSize uint32
107}
108
109const (
110 // lastSequenceNumberFlag is logically-ORed with the sequence number of the
111 // last Long File Name entry to mark it as such.
112 lastSequenceNumberFlag = 0x40
113 // codepointsPerEntry is the number of UTF-16 codepoints that fit into a
114 // single Long File Name entry.
115 codepointsPerEntry = 5 + 6 + 2
116)
117
118// VFAT long file name prepended entry
119type lfnEntry struct {
120 SequenceNumber uint8
121 // First 5 UTF-16 code units
122 NamePart1 [5]uint16
123 // Attributes (must be 0x0f)
124 Attributes uint8
125 _ byte
126 // Checksum of the 8.3 name.
127 Checksum uint8
128 // Next 6 UTF-16 code units
129 NamePart2 [6]uint16
130 _ [2]byte
131 // Next 2 UTF-16 code units
132 NamePart3 [2]uint16
133}