FAT32 Spec (SDA Contribution)
FAT32 Spec (SDA Contribution)
Microsoft Corporation
August 30 2005
Microsoft makes this contribution to the SD Card Association ("SDA") pursuant to the SDA IPR Policy, with
acknowledgement by the SDA Board of Directors of the following:
Ownership. Microsoft retains ownership of its copyrights in and to the Microsoft Contribution. Nothing in SDA’s
Intellectual Property Policy shall be construed as an assignment of such copyrights to SDA or any other person or
entity. Microsoft acknowledges and will not challenge SDA’s assertion of copyright ownership according to SDA’s
Intellectual Property Policy of final SDA specifications subject to the underlying copyrights in Microsoft’s
Contribution and the terms hereof.
Development License. Microsoft hereby grants to SDA and to each other Member a worldwide, irrevocable,
non-transferable, non-sublicensable, royalty-free, non-exclusive, perpetual, fully-paid, copyright license
under its copyrights in the Microsoft Contribution to use, copy, modify, disclose and create derivative works
of such Microsoft Contribution for the sole purpose of incorporation (whether by express incorporation or
incorporation by reference) of such Microsoft Contribution, and/or modifications thereof into any SDA
Specifications, and for the development of any SDA Specifications.
Publication License. Microsoft hereby grants to SDA a worldwide, irrevocable, non-transferable, royalty-
free, non-exclusive, perpetual, fully-paid, copyright license (with the right to sublicense) under its copyrights
in the Microsoft Contribution to use, copy, disclose, publicly display and perform, publish and distribute
such Microsoft Contribution, and/or modifications thereof (which may be made by SDA or any Member),
solely as part of and/or incorporated in (whether by express incorporation or incorporation by reference) one
or more SDA Final Specification(s).
MICROSOFT WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY USE OR DISTRIBUTION OF
THE SPECIFICATION.
Table of Contents
......................................................................................................................................................... 1
Microsoft FAT Specification............................................................................................................. 1
Table of Contents ............................................................................................................................ 2
Overview and Purpose .................................................................................................................... 3
Section 1: Definitions and Notations................................................................................................ 4
1.1 Definitions:............................................................................................................................. 4
1.2 Notations ............................................................................................................................... 4
Section 2: Volume Structure............................................................................................................ 6
Section 3: Boot Sector and BPB...................................................................................................... 7
3.1 BPB structure common to FAT12, FAT16, and FAT32 implementations ............................. 7
3.2 Extended BPB structure for FAT12 and FAT16 volumes ................................................... 10
3.3 Extended BPB structure for FAT32 volumes ...................................................................... 11
3.4 Initialization of a FAT volume .............................................................................................. 12
3.5 Determination of FAT type when mounting the volume...................................................... 14
3.6 Backup BPB Structure ........................................................................................................ 15
Section 4: FAT ............................................................................................................................... 16
4.1: Determination of FAT entry for a cluster ............................................................................ 17
4.2 Reserved FAT entries ......................................................................................................... 19
4.3 Free space determination ................................................................................................... 20
4.4 Other points to note............................................................................................................. 20
Section 5: File System Information (FSInfo) Structure .................................................................. 21
Section 6: Directory Structure........................................................................................................ 23
6.1 File/Directory Name (field DIR_Name)................................................................................ 24
6.2 File/Directory Attributes ....................................................................................................... 25
6.3 Date / Time.......................................................................................................................... 26
6.4 File/Directory Size ............................................................................................................... 27
6.5 Directory creation ................................................................................................................ 27
6.6 Root Directory ..................................................................................................................... 28
6.7 File allocation ...................................................................................................................... 28
Section 7: Long File Name Implementation (optional) .................................................................. 30
7.1 Ordinal Number Generation ................................................................................................ 31
7.2 Checksum Generation ........................................................................................................ 32
7.3 Example illustrating persistence of a long name................................................................. 32
7.4 Rules governing name creation and matching.................................................................... 33
Section 8: EA Support (optional) ................................................................................................... 35
Appendix 1: Example BPB for 512 byte sector-size 128 MB HDD media formatted FAT16 ........ 36
Appendix 2: Example BPB for 512 byte sector-size 128 MB HDD media formatted FAT32 ........ 37
This document does not describe all algorithms contained in the Microsoft FAT file system driver
implementation neither does it describe all algorithms contained in associated utilities (Microsoft
format and chkdsk utilities). However, it is expected that the reader will refer to the Microsoft
Corporation FAT file system reference source code for additional clarification as/when needed.
• FAT12
• FAT16
• FAT32
Data structures comprising all three variants are described here. Also provided are descriptions of
specific algorithms that will be useful to the engineer implementing a FAT driver for reading
and/or writing to media.
It is expected that the FAT Test Specification document will be used by the reader to validate
interoperability and correctness of the resultant FAT implementation.
1.1 Definitions:
• byte
• file
• sector
A unit of data that can be accessed independently of other units on the media
• cluster
A unit of allocation comprising a set of logically contiguous sectors. Each cluster within the
volume is referred to by a cluster number “N”. All allocation for a file must be an integral
multiple of a cluster.
• partition
• volume
A logically contiguous sector address space as specified in the relevant standard for
recording.
1.2 Notations
Numerical Notation
Arithmetic Notation
The notation ceil(x) shall mean the minimum integer that is greater than x.
The notation rem(x,y) shall mean the remainder of the integer division of x by y.
The below figure illustrates the four regions in a volume formatted FAT:
B B File
P … P Allocation FAT Root Data
B B Table Copy Directory
All of the FAT file systems were originally developed for the IBM PC machine architecture.
Hence, on disk data structures for the FAT format are all “little endian.”
To illustrate, below is an instance of a 32-bit FAT entry stored on disk as a series of four 8-bit
bytes—the first being byte[0] and the last being byte[3]. The 32 bits numbered 00 through 31 are
stored as follows (00 being the least significant bit):
byte[3] 33222222
10987654
byte[2] 22221111
32109876
byte[1] 11111100
54321098
byte[0] 00000000
76543210
All FAT volumes must have a BPB in the boot sector. The BPB has evolved over the years as
follows:
• The FAT implementation in MS-DOS 1.x did not include a BPB (introduced in MS-DOS
2.x)
• The BPB in MS-DOS 3.x was modified to allow > 64K sectors
• For FAT32, the BPB differs from that for FAT16/FAT12 beginning at offset 36
The BPB in the boot sector of a FAT volume must always have all of the BPB fields for either the
FAT12/FAT16 or FAT32 BPB type. This ensures maximum compatibility of the FAT volume and
will also ensure that all FAT file system drivers understand and support the volume correctly.
NOTE: In the following description, all the fields whose names start with BPB_ are part of the
BPB. All the fields whose names start with BS_ are part of the boot sector and not really part of
the BPB.
The fields comprising the BPB are described further in this section.
and
BPB_Media 21 1 The legal values for this field are 0xF0, 0xF8, 0xF9,
0xFA, 0xFB, 0xFC, 0xFD, 0xFE, and 0xFF.
At this point, the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for
FAT32.
NOTE: It is recommended that the first sector of the partition (if any) be aligned to the required
alignment unit.
Signature_word 510 2 Set to 0x55 (at byte offset 510) and 0xAA (at byte
offset 511)
BPB_BkBootSe 50 2 Set to 0 or 6.
c
If non-zero, indicates the sector number in the
reserved area of the volume of a copy of the boot
record.
Signature_word 510 2 Set to 0x55 (at byte offset 510) and 0xAA (at byte
offset 511)
This section describes the determination of values for specific fields in the BPB during volume
initialization for a given target volume. FAT implementations must be capable of mounting media
with all legal values for fields comprising the BPB.
• Floppy disks are formatted as FAT12. A simple (pre-specified) table determines the BPB
structure contents for floppy media. Note that media size for FAT12 volumes must be <=
4MB.
• For 512 byte sector sized media: if volume size is < 512 MB, the volume is formatted
FAT16 else it is formatted FAT32. It is possible to override the default FAT type selection.
The below tables are used by the Microsoft Corporation FAT format utility - an entry in these
tables is selected based on the size of the volume in 512 byte sectors (the value that will go
in BPB_TotSec16 or BPB_TotSec32), and the value that this table sets is the
BPB_SecPerClus value:
struct DSKSZTOSECPERCLUS {
DWORD DiskSize;
BYTE SecPerClusVal;
};
/*
*This is the table for FAT16 drives. NOTE that this table includes
* entries for disk sizes larger than 512 MB even though typically
* only the entries for disks < 512 MB in size are used.
* The way this table is accessed is to look for the first entry
* in the table for which the disk size is less than or equal
* to the DiskSize field in that table entry. For this table to
* work properly BPB_RsvdSecCnt must be 1, BPB_NumFATs
* must be 2, and BPB_RootEntCnt must be 512. Any of these values
* being different may require the first table entries DiskSize value
* to be changed otherwise the cluster count may be to low for FAT16.
*/
DSKSZTOSECPERCLUS DskTableFAT16 [] = {
{8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */
{32680, 2}, /* disks up to 16 MB, 1k cluster */
{262144, 4}, /* disks up to 128 MB, 2k cluster */
{524288, 8}, /* disks up to 256 MB, 4k cluster */
{1048576, 16}, /* disks up to 512 MB, 8k cluster */
/* The entries after this point are not used unless FAT16 is forced */
{2097152, 32}, /* disks up to 1 GB, 16k cluster */
{4194304, 64}, /* disks up to 2 GB, 32k cluster */
{0xFFFFFFFF, 0} /*any disk greater than 2GB, 0 value for SecPerClusVal trips an error */
};
/*
* This is the table for FAT32 drives. NOTE that this table includes
* entries for disk sizes smaller than 512 MB even though typically
* only the entries for disks >= 512 MB in size are used.
* The way this table is accessed is to look for the first entry
* in the table for which the disk size is less than or equal
* to the DiskSize field in that table entry. For this table to
* work properly BPB_RsvdSecCnt must be 32, and BPB_NumFATs
* must be 2. Any of these values being different may require the first
* table entries DiskSize value to be changed otherwise the cluster count
* may be to low for FAT32.
*/
DSKSZTOSECPERCLUS DskTableFAT32 [] = {
{66600, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */
{532480, 1}, /* disks up to 260 MB, .5k cluster */
{16777216, 8}, /* disks up to 8 GB, 4k cluster */
{33554432, 16}, /* disks up to 16 GB, 8k cluster */
{67108864, 32}, /* disks up to 32 GB, 16k cluster */
{0xFFFFFFFF, 64}/* disks greater than 32GB, 32k cluster */
};
Given a disk size and a FAT type of FAT16 or FAT32, the above determines the
BPB_SecPerClus value.
The below computes how many sectors the FAT takes up to enable setting the
BPB_FATSz16 or BPB_FATSz32 fields (see Section 4 for a description of the FAT). At
this point, it is assumed that BPB_RootEntCnt, BPB_RsvdSecCnt, and BPB_NumFATs
are appropriately set. It is also assumed that DskSize is the size of the volume that will
be reflected in BPB_TotSec32 or BPB_TotSec16.
RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
TmpVal1 = DskSize – (BPB_ResvdSecCnt + RootDirSectors);
TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs;
If(FATType == FAT32)
TmpVal2 = TmpVal2 / 2;
FATSz = (TMPVal1 + (TmpVal2 – 1)) / TmpVal2;
If(FATType == FAT32) {
BPB_FATSz16 = 0;
BPB_FATSz32 = FATSz;
} else {
BPB_FATSz16 = LOWORD(FATSz);
/* there is no BPB_FATSz32 in a FAT16 BPB */
}
NOTE: The above math does not work perfectly. It will occasionally set a FATSz that is
up to 2 sectors too large for FAT16, and occasionally up to 8 sectors too large for FAT32.
It will never compute a FATSz value that is too small, however. Because it is OK to have
a FATSz that is too large, at the expense of wasting a few sectors, the fact that this
computation is surprisingly simple more than makes up for it being off in a safe way in
some cases.
2. Next, determine the count of sectors in the data region of the volume:
If(BPB_FATSz16 != 0)
FATSz = BPB_FATSz16;
Else
FATSz = BPB_FATSz32;
If(BPB_TotSec16 != 0)
TotSec = BPB_TotSec16;
Else
TotSec = BPB_TotSec32;
The above algorithm determines the FAT type. Note the following:
It is recommended that volumes not be created with a count of clusters that is exactly equal to the
1
boundary values listed above (i.e. 4085 clusters or 65525 clusters).
The Maximum Valid Cluster Number (MAX) for the volume is (CountofClusters + 1).
The “count of clusters including the two reserved clusters” is (CountofClusters + 2).
The BPB_BkBootSec field contains the value 6 for both copies of the BPB (the one in sector 0
and the backup copy located in sector 6).
Volume repair utilities are expected to retrieve contents of the BPB from sector #6 in a situation
when sector #0 is unreadable.
NOTE: Starting at the BPB_BkBootSec sector is a complete boot record. The Microsoft FAT32
“boot sector” is actually three sectors long. There is a copy of all three of these sectors starting at
the BPB_BkBootSec sector. A copy of the FSInfo sector (see Section 5) is also there, although
the BPB_FSInfo field in this backup boot sector is set to the same value as is stored in the
sector #0 BPB.
1
To avoid hitting the boundary condition which may lead to computation errors in the FAT
implementation, ensure count of clusters is at least 16 clusters greater than or less than these values.
Section 4: FAT
Each valid entry in the File Allocation Table (FAT) represents the state of a cluster from the set of
clusters comprising the Root Directory Region (when applicable) and the File and Directory Data
Region. The size of each (packed) entry in the FAT is as follows:
As stated earlier, a FAT may be larger than that required to describe all allocatable sectors
comprising the Root/Data regions. Extra entries in the FAT (located at the tail/end of the FAT)
must be set to a value of 0.
The FAT defines a singly linked list of the “extents” (clusters) of a file and thereby maps the data
region of the volume by cluster number. The first data cluster in the volume is cluster #2.
NOTE: A FAT directory or file container is simply a regular file with a special attribute indicating
the directory type. The contents of the directory are a series of 32 byte directory entries
(described in Section 6)).
NOTE: The high 4 bits of a FAT32 FAT entry are reserved. All FAT implementations must
preserve the current value of the high 4 bits when modifying any FAT32 FAT entry except during
volume initialization (formatting) when the entire FAT table must be set to 0.
NOTE: No FAT32 volume should ever be configured containing cluster numbers available for
allocation >= 0xFFFFFF7.
NOTE: The size of the FAT is limited to 6K sectors on volumes formatted FAT12. The size of the
FAT is limited to 128K sectors on volumes formatted FAT16. There is no limit on the size of the
FAT on volumes formatted FAT32.
If(BPB_FATSz16 != 0)
FATSz = BPB_FATSz16;
Else
FATSz = BPB_FATSz32;
If(FATType == FAT16)
FATOffset = N * 2;
Else if (FATType == FAT32)
FATOffset = N * 4;
ThisFATSecNum is the sector number of the FAT sector that contains the entry for cluster N in
the first FAT.
where, FatNumber will be 2 for the second FAT, 3 for the third FAT, and so on.
The contents of the FAT entry can be extracted from the sector contents (once the sector has
been read from media) as per below:
If(FATType == FAT16)
FAT16ClusEntryVal = *((WORD *) &SecBuff[ThisFATEntOffset]);
Else
FAT32ClusEntryVal = (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0x0FFFFFFF;
To modify an in-memory instance of a FAT entry contained within the sector, use the following
logic:
If(FATType == FAT16)
*((WORD *) &SecBuff[ThisFATEntOffset]) = FAT16ClusEntryVal;
Else {
FAT32ClusEntryVal = FAT32ClusEntryVal & 0x0FFFFFFF;
*((DWORD *) &SecBuff[ThisFATEntOffset]) =
(*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0xF0000000;
*((DWORD *) &SecBuff[ThisFATEntOffset]) =
(*((DWORD *) &SecBuff[ThisFATEntOffset])) | FAT32ClusEntryVal;
}
NOTE: The type WORD is defined as an unsigned 16-bit quantity. The type DWORD is defined
as a 32-bit unsigned quantity.
2
REM is the remainder operator.
FAT 12
Each FAT12 FAT entry has a length of 1.5 bytes (12-bits). The FAT entry in the first FAT is
determined as described below:
if (FATType == FAT12)
FATOffset = N + (N / 2);
/* Multiply by 1.5 without using floating point, the divide by 2 rounds DOWN */
The logic below checks for the entry spanning a sector boundary and comments on an
approach to deal with this case:
ThisFATSecNum is the sector number of the FAT sector that contains the entry for cluster N in
the first FAT.
where, FatNumber will be 2 for the second FAT, 3 for the third FAT, and so on.
The contents of the FAT entry can be extracted from the sector contents (once the sector has
been read from media) as per below:
NOTE: For even numbered clusters, the logic above correctly obtains the low 12 bits describing
the FAT entry. For odd numbered clusters, the logic correctly obtains the high 12 bits.
To modify an in-memory instance of a FAT entry contained within the sector, use the following
logic:
NOTE: It is assumed that the >> operator shifts a bit value of 0 into the high 4 bits and that the <<
operator shifts a bit value of 0 into the low 4 bits.
The first reserved entry (FAT[0]), contains the BPB_Media byte value in its low 8 bits, and all
other bits are set to 1. For example, if the BPB_Media value is 0xF8, then:
The second reserved entry (FAT[1]), is set by the format utility to the EOC value.
On FAT12 volumes, this entry is not modified subsequent to the format and, therefore,
always contains an EOC mark.
For FAT16 and FAT32, the file system driver implementation on Microsoft Windows may use
the high two bits of the FAT[1] entry for dirty volume flags (note that all other bits, are always
left set to 1). Also note that the bit location is different for FAT16 and FAT32, because they
are the high 2 bits of the entry.
For FAT16:
ClnShutBitMask = 0x8000;
HrdErrBitMask = 0x4000;
For FAT32:
ClnShutBitMask = 0x08000000;
HrdErrBitMask = 0x04000000;
Bit ClnShutBitMask: If bit is 1, the volume is “clean”. The volume can be mounted for
access. If bit is 0, the volume is “dirty” indicating that a FAT file
system driver was unable to dismount the volume properly (during a
prior mount operation). The volume contents should be scanned for
any damage to file system metadata.
Bit HrdErrBitMask: If this bit is 1, no disk read/write errors were encountered.
If this bit is 0, the file system driver implementation encountered a
disk I/O error on the volume the last time it was mounted, which is an
indicator that some sectors may have gone bad. The volume
contents should be scanned with a disk repair utility that does
surface analysis on it looking for new bad sectors.
FAT12: 0x000
FAT16: 0x0000
FAT32: 0x0000000 (note that the highest order 4 bits are reserved and ignored)
Note that the list of free clusters is not stored on the volume. On FAT32 volumes, the
BPB_FSInfo sector may contain a valid count of free clusters on the volume (see Section 5).
FAT implementations must not make any assumptions about what the contents of the last
FAT sector are after the (CountOfClusters + 1) FAT entry. When initializing (formatting)
a volume, the implementation must zero all bytes after this last FAT entry.
The number of sectors reserved for each FAT (count of sectors in the BPB_FATSz16 or
BPB_FATSz32 fields) may be bigger than the actual number of sectors required for
containing the entire FAT. Therefore, there may be totally unused FAT sectors at the end of
each FAT in the FAT region of the volume. Each implementation must determine the value
for the last valid sector in the FAT using CountOfClusters (the last valid sector in the FAT
is the one containing the FAT entry numbered CountOfClusters + 1).
All sectors reserved for the FAT beyond the last valid sector (defined as the one containing
the FAT entry for the last cluster) must be set to 0x0 during volume initialization/format.
NOTE: The information contained in the structure must be considered as advisory only and file
system driver implementations must validate the values at volume mount. File system driver
implementations are not required to ensure that information within the structure is kept consistent
although this is recommended.
The FSInfo structure is only present on volumes formatted FAT32. The structure must be
persisted on the media during volume initialization (format). The structure must be located at
sector #1 – immediately following the sector containing the BPB.
The below table describes the fields comprising the FSInfo structure:
FSI_Free_Count 488 4 Contains the last known free cluster count on the
volume.
ATTR_READ_ONLY 0x01
ATTR_HIDDEN 0x02
ATTR_SYSTEM 0x04
ATTR_VOLUME_ID 0x08
ATTR_DIRECTORY 0x10
ATTR_ARCHIVE 0x20
Each of the above two components are “trailing space padded” if required (using value: 0x20).
1. An implied ‘.’ character separates the main part of the name from the extension. The “.”
separator character is never stored in the DIR_Name field.
2. DIR_Name[0]3 = 0xE5 indicates the directory entry is free (available). However, 0xE5 is a
valid KANJI lead byte value for the character set used in Japan. For KANJI character set
based names, the value 0x05 is stored in DIR_Name[0] - if required - to represent 0xE5. If
the FAT file system implementation reads DIR_NAME[0] = 0x05 and if the character set
used is KANJI, it must perform the appropriate substitution in memory prior to returning the
name to the application.
3. DIR_Name[0] = 0x00 also indicates the directory entry is free (available). However,
DIR_Name[0] = 0x00 is an additional indicator that all directory entries following the current
free entry are also free.
4. DIR_Name[0] cannot equal 0x20 (in other words, names cannot start with a space
character).
5. All names in the directory must be unique.
o 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B,
0x5C, 0x5D, and 0x7C
The below examples illustrate how names are handled and persisted:
3
This indicates the first byte in the field.
Short file names are limited to 8 characters followed by an optional period (“.”) and extension of
up to 3 characters. The characters comprising a short file name may be any combination of
letters, digits, or characters with code point values greater than 127. The following special
characters are also allowed:
$ % ' - _ @ ~ ` ! ( ) { } ^ # &
Names are stored in a short name directory entry in the OEM code page that the system is
configured for at the time the directory entry is created. Short name directory entries remain in
OEM character set for compatibility. OEM characters are single 8-bit characters or can be DBCS
character pairs for certain code pages.
Short file names passed to the file system are always converted to upper case and their original
case value is lost. A problem that is generally true of most OEM code pages is that they map
lower to upper case extended characters in a non-unique fashion i.e. they map multiple extended
characters to a single upper case character. This creates problems because it does not preserve
the information that the extended character provides. This mapping also prevents the creation of
some file names that would normally differ, but because of the mapping to upper case they
become the same file name.
DIR_CrtTime
DIR_CrtTimeTenth
DIR_CrtDate
DIR_LstAccDate
Any of the fields above not supported by a file system implementation must be set to 0. Field
values set to 0 should be ignored by a file system implementation.
The following date/time fields must be appropriately updated by the file system driver
implementation:
DIR_WrtTime
4
Bit position 0 is the least significant bit; bit position 15 is the most significant bit of a 16-bit word
DIR_WrtDate
Date format
Bit positions 0 through 4 represent the day of the month (valid range: 1..31 inclusive)
Bit positions 5 through 8 represent the month of the year (1 = January, 12 = December, valid
range: 1..12 inclusive)
Bit positions 9 through 15 are the count of years from 1980 (valid range: 0..127 inclusive
allowing representation of years 1980 through 2107)
Time format
Directory entry timestamps are 16-bit values with a granularity of 2 seconds. Contents of the
DIR_CrtTime and DIR_WrtTime must be in the following format:
Bit positions 0 through 4 contain elapsed seconds – as a count of 2-second increments (valid
range: 0..29 inclusive allowing representation of 0 through 58 seconds)
Bit positions 5 through 10 represent number of minutes (valid range: 0..59 inclusive)
Bit positions 11 through 15 represent hours (valid range: 0..23 inclusive)
o The first directory entry must have a directory name set to “.”
This dot entry refers to the current directory. Rules listed above for the DIR_Attr
field and DIR_FileSize field must be followed. Since the dot entry refers to the
current directory (the one containing the dot entry), the contents of the
DIR_FstClusLO and DIR_FstClusHI fields must be the same as that of the
current directory. All date and time fields must be set to the same value as that for
the containing directory.
o The second directory entry must have the directory name set to “..”
This dotdot entry refers to the parent of the current directory. Rules listed above for
the DIR_Attr field and DIR_FileSize field must be followed. Since the dotdot
entry refers to the parent of the current directory (the one containing the dotdot
entry), the contents of the DIR_FstClusLO and DIR_FstClusHI fields must be the
same as that of the parent of the current directory. If the parent of the current
directory is the root directory (see below), the DIR_FstClusLO and
DIR_FstClusHI contents must be set to 0. All date and time fields must be set to
the same value as that for the containing directory.
On FAT12 and FAT16 volumes, the root directory must immediately follow the last file allocation
table. The location of the first sector of the root directory is computed as below:
The size of the root directory on FAT12 and FAT16 volumes is computed using the contents of
the BPB_RootEntCnt field.
On volumes formatted FAT32, the root directory can be of variable size. The location of the first
cluster of the root directory on the FAT32 volume is stored in the BPB_RootClus field.
Only the root directory can contain an entry with the DIR_Attr field contents equal to
ATTR_VOLUME_ID.
There is no name for the root directory (on most operating system implementations, the implied
name “\” is used). Further, the root directory does not have any associated date/time stamps.
Lastly, the root directory does not contain either the dot or dotdot entries.
The file allocation table entry corresponding to the first allocated cluster for a file either indicates
that this is the sole/last allocated cluster for the file or contains the cluster number for the next
allocated cluster.
The first sector of the beginning of the data region (cluster #2) is computed as given below:
Given any valid data cluster number N, the sector number of the first sector of that cluster is
computed as follows:
Support for long file names is optional for file system implementations. However, such support is
very strongly recommended.
NOTE: Long file names can be supported on any FAT variant i.e. on media formatted FAT12,
FAT16 or FAT32.
A long file name for a target file or sub-directory is stored in a set (one or more) of additional
directory entries associated with the short name directory entry describing the target file or sub-
directory. This set of additional directory entries (also known as the long name directory entries)
must immediately precede the corresponding short name directory entry and is, therefore,
physically contiguous with the short name directory entry.
NOTE: The sequence of long name directory entries is stored in reverse order (last entry in the
set is stored first, followed by entry n-1, followed by entry n-2, and so on, until entry 1).
ATTR_LONG_NAME = (ATTR_READ_ONLY |
ATTR_HIDDEN |
ATTR_SYSTEM |
ATTR_VOLUME_ID)
#define ATTR_LONG_NAME_MASK =
(ATTR_READ_ONLY |
ATTR_HIDDEN |
ATTR_SYSTEM |
ATTR_VOLUME_ID |
ATTR_DIRECTORY |
ATTR_ARCHIVE)
The below illustrates how long name directory entries are stored:
Entry Ordinal
th
N long name directory entry LAST_LONG_ENTRY (0x40) | N
… Additional long name directory entries …
st
1 long name directory entry 1
Short name directory entry associated with preceding N/A
long name directory entry set
If any member of the set of long name directory entries does not follow the rules above, the set is
considered corrupt.
The below algorithm describes the logic used to generate the check sum value:
//-----------------------------------------------------------------------------
// ChkSum()
// Returns an unsigned byte checksum computed on an unsigned byte
// array. The array must be 11 bytes long and is assumed to contain
// a name stored in the format of a MS-DOS directory entry.
// Passed: pFcbName Pointer to an unsigned byte array assumed to be
// 11 bytes long.
// Returns: Sum An 8-bit unsigned checksum of the array pointed
// to by pFcbName.
//------------------------------------------------------------------------------
unsigned char ChkSum (unsigned char *pFcbName)
{
short FcbNameLen;
unsigned char Sum;
Sum = 0;
for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--) {
// NOTE: The operation is an unsigned char rotate right
Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pFcbName++;
}
return (Sum);
}
T h e q chk- u
1st long entry 01h 0Fh 00h
sum
i c k b 0000h r o
Created
Short entry T H E Q U I ~ 1 F O X 20h NT Rsvd Time
Created Last Last Last First
Access 0000h Modified Modified File Size
Date Date Time Date Cluster
Long file names are limited to 255 characters, not including the trailing NULL. The characters
may be any combination of those defined for short file names (see Section 6.1) with the addition
of the period (“.”) character used multiple times within the long name. A space is also a valid
character in a long file name as it always has been for a short file name. The following six special
characters are allowed in a long file name (they are not legal in a short file name):
+ , ; = [ ]
Embedded spaces within a long file name are allowed. Leading and trailing spaces in a long file
name are ignored.
Leading and embedded periods are allowed in a name and are stored in the long file name.
Trailing periods are ignored.
Long file names are stored in long directory entries in UNICODE. UNICODE characters are 16-bit
characters. It is not be possible to store UNICODE in short name directory entries since the
names stored there are 8-bit characters or DBCS characters.
Long file names passed to the file system are not converted to upper case and their original case
value is preserved. UNICODE solves the case mapping problem prevalent in some OEM code
pages by always providing a translation for lower case characters to a single, unique upper case
character
Any name within a specific directory, whether it is a short name or a long name, can occur
only once (difference in case is ignored and such names must be considered as conflicting)
When a character on the media (whether stored in the OEM character set or in UNICODE)
cannot be translated into the appropriate character in the OEM or ANSI code page, it is
always translated to the "_" (underscore) character – the character is not modified on the
media. The “_” character is the same in all OEM code pages and ANSI.