1 /** @file
2   Definitions for on-disk FAT structures.
3 
4 Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 
8 **/
9 
10 #ifndef _FATFILESYSTEM_H_
11 #define _FATFILESYSTEM_H_
12 
13 #pragma pack(1)
14 //
15 // FAT info signature
16 //
17 #define FAT_INFO_SIGNATURE        0x41615252
18 #define FAT_INFO_BEGIN_SIGNATURE  0x61417272
19 #define FAT_INFO_END_SIGNATURE    0xAA550000
20 //
21 // FAT entry values
22 //
23 #define FAT_CLUSTER_SPECIAL_EXT       (MAX_UINTN & (~0xF))
24 #define FAT_CLUSTER_SPECIAL           ((FAT_CLUSTER_SPECIAL_EXT) | 0x07)
25 #define FAT_CLUSTER_FREE              0
26 #define FAT_CLUSTER_RESERVED          (FAT_CLUSTER_SPECIAL)
27 #define FAT_CLUSTER_BAD               (FAT_CLUSTER_SPECIAL)
28 #define FAT_CLUSTER_LAST              (-1)
29 #define FAT_END_OF_FAT_CHAIN(Cluster) ((Cluster) > (FAT_CLUSTER_SPECIAL))
30 #define FAT_MIN_CLUSTER               2
31 #define FAT_MAX_FAT12_CLUSTER         0xFF5
32 #define FAT_MAX_FAT16_CLUSTER         0xFFF5
33 #define FAT_CLUSTER_SPECIAL_FAT12     0xFF7
34 #define FAT_CLUSTER_SPECIAL_FAT16     0xFFF7
35 #define FAT_CLUSTER_SPECIAL_FAT32     0x0FFFFFF7
36 #define FAT_CLUSTER_MASK_FAT12        0xFFF
37 #define FAT_CLUSTER_UNMASK_FAT12      0xF000
38 #define FAT_CLUSTER_MASK_FAT32        0x0FFFFFFF
39 #define FAT_CLUSTER_UNMASK_FAT32      0xF0000000
40 #define FAT_POS_FAT12(a)              ((a) * 3 / 2)
41 #define FAT_POS_FAT16(a)              ((a) * 2)
42 #define FAT_POS_FAT32(a)              ((a) * 4)
43 #define FAT_ODD_CLUSTER_FAT12(a)      (((a) & 1) != 0)
44 
45 
46 //
47 // FAT attribute define
48 //
49 #define FAT_ATTRIBUTE_READ_ONLY 0x01
50 #define FAT_ATTRIBUTE_HIDDEN    0x02
51 #define FAT_ATTRIBUTE_SYSTEM    0x04
52 #define FAT_ATTRIBUTE_VOLUME_ID 0x08
53 #define FAT_ATTRIBUTE_DIRECTORY 0x10
54 #define FAT_ATTRIBUTE_ARCHIVE   0x20
55 #define FAT_ATTRIBUTE_DEVICE    0x40
56 #define FAT_ATTRIBUTE_LFN       0x0F
57 //
58 // Some Long File Name definitions
59 //
60 #define FAT_LFN_LAST            0x40  // Ordinal field
61 #define MAX_LFN_ENTRIES         20
62 #define LFN_CHAR1_LEN           5
63 #define LFN_CHAR2_LEN           6
64 #define LFN_CHAR3_LEN           2
65 #define LFN_CHAR_TOTAL          (LFN_CHAR1_LEN + LFN_CHAR2_LEN + LFN_CHAR3_LEN)
66 #define LFN_ENTRY_NUMBER(a)     (((a) + LFN_CHAR_TOTAL - 1) / LFN_CHAR_TOTAL)
67 //
68 // Some 8.3 File Name definitions
69 //
70 #define FAT_MAIN_NAME_LEN       8
71 #define FAT_EXTEND_NAME_LEN     3
72 #define FAT_NAME_LEN            (FAT_MAIN_NAME_LEN + FAT_EXTEND_NAME_LEN)
73 //
74 // Some directory entry information
75 //
76 #define FAT_ENTRY_INFO_OFFSET   13
77 #define DELETE_ENTRY_MARK       0xE5
78 #define EMPTY_ENTRY_MARK        0x00
79 
80 //
81 // Volume dirty Mask
82 //
83 #define FAT16_DIRTY_MASK        0x7fff
84 #define FAT32_DIRTY_MASK        0xf7ffffff
85 //
86 // internal flag
87 //
88 #define FAT_CASE_MIXED          0x01
89 #define FAT_CASE_NAME_LOWER     0x08
90 #define FAT_CASE_EXT_LOWER      0x10
91 
92 typedef struct {
93   UINT8   Ia32Jump[3];
94   CHAR8   OemId[8];
95   UINT16  SectorSize;
96   UINT8   SectorsPerCluster;
97   UINT16  ReservedSectors;
98   UINT8   NumFats;
99   UINT16  RootEntries;          // < FAT32, root dir is fixed size
100   UINT16  Sectors;
101   UINT8   Media;
102   UINT16  SectorsPerFat;        // < FAT32
103   UINT16  SectorsPerTrack;      // (ignored)
104   UINT16  Heads;                // (ignored)
105   UINT32  HiddenSectors;        // (ignored)
106   UINT32  LargeSectors;         // Used if Sectors==0
107 } FAT_BOOT_SECTOR_BASIC;
108 
109 typedef struct {
110   UINT8 PhysicalDriveNumber;    // (ignored)
111   UINT8 CurrentHead;            // holds boot_sector_dirty bit
112   UINT8 Signature;              // (ignored)
113   CHAR8 Id[4];
114   CHAR8 FatLabel[11];
115   CHAR8 SystemId[8];
116 } FAT_BOOT_SECTOR_EXT;
117 
118 typedef struct {
119   UINT32  LargeSectorsPerFat;   // FAT32
120   UINT16  ExtendedFlags;        // FAT32 (ignored)
121   UINT16  FsVersion;            // FAT32 (ignored)
122   UINT32  RootDirFirstCluster;  // FAT32
123   UINT16  FsInfoSector;         // FAT32
124   UINT16  BackupBootSector;     // FAT32
125   UINT8   Reserved[12];         // FAT32 (ignored)
126   UINT8   PhysicalDriveNumber;  // (ignored)
127   UINT8   CurrentHead;          // holds boot_sector_dirty bit
128   UINT8   Signature;            // (ignored)
129   CHAR8   Id[4];
130   CHAR8   FatLabel[11];
131   CHAR8   SystemId[8];
132 } FAT32_BOOT_SECTOR_EXT;
133 
134 typedef union {
135     FAT_BOOT_SECTOR_EXT   FatBse;
136     FAT32_BOOT_SECTOR_EXT Fat32Bse;
137   } FAT_BSE;
138 
139 typedef struct {
140   FAT_BOOT_SECTOR_BASIC   FatBsb;
141   FAT_BSE  FatBse;
142 } FAT_BOOT_SECTOR;
143 
144 //
145 // FAT Info Structure
146 //
147 typedef struct {
148   UINT32  ClusterCount;
149   UINT32  NextCluster;
150 } FAT_FREE_INFO;
151 
152 typedef struct {
153   UINT32        Signature;
154   UINT8         ExtraBootCode[480];
155   UINT32        InfoBeginSignature;
156   FAT_FREE_INFO FreeInfo;
157   UINT8         Reserved[12];
158   UINT32        InfoEndSignature;
159 } FAT_INFO_SECTOR;
160 
161 //
162 // Directory Entry
163 //
164 #define FAT_MAX_YEAR_FROM_1980  0x7f
165 typedef struct {
166   UINT16  Day : 5;
167   UINT16  Month : 4;
168   UINT16  Year : 7;                 // From 1980
169 } FAT_DATE;
170 
171 typedef struct {
172   UINT16  DoubleSecond : 5;
173   UINT16  Minute : 6;
174   UINT16  Hour : 5;
175 } FAT_TIME;
176 
177 typedef struct {
178   FAT_TIME  Time;
179   FAT_DATE  Date;
180 } FAT_DATE_TIME;
181 
182 typedef struct {
183   CHAR8         FileName[11];       // 8.3 filename
184   UINT8         Attributes;
185   UINT8         CaseFlag;
186   UINT8         CreateMillisecond;  // (creation milliseconds - ignored)
187   FAT_DATE_TIME FileCreateTime;
188   FAT_DATE      FileLastAccess;
189   UINT16        FileClusterHigh;    // >= FAT32
190   FAT_DATE_TIME FileModificationTime;
191   UINT16        FileCluster;
192   UINT32        FileSize;
193 } FAT_DIRECTORY_ENTRY;
194 
195 typedef struct {
196   UINT8   Ordinal;
197   CHAR8   Name1[10];                // (Really 5 chars, but not WCHAR aligned)
198   UINT8   Attributes;
199   UINT8   Type;
200   UINT8   Checksum;
201   CHAR16  Name2[6];
202   UINT16  MustBeZero;
203   CHAR16  Name3[2];
204 } FAT_DIRECTORY_LFN;
205 
206 #pragma pack()
207 
208 #endif
209