exFAT Directory Structure

Understanding of underlying mechanisms of data storage, organization and data recovery.

exFAT uses tree structure to describe relationship between files and directories. The root of the directory tree is defined by directory located at RootDirectoryCluster. Subdirectories are single-linked to there parents. There is no special (.) and (..) directories pointing to itself and to parent like in FAT16/FAT32.

Each directory consists of a series of directory entries. Directory entries are classified as critical/benign and primary/secondary as follows:

  • Primary Directory Entries
  • Critical Primary Entries
  • Benign Primary Entries
  • Secondary Directory Entries
  • Critical Secondary Entries
  • Benign Secondary Entries

Critical entries are required while benign entries are optional. Primary directory entries correspond to the entries in file system and describe main characteristics. Secondary directory entries extend the metadata associated with a primary directory entry end follow it. A group of primary/secondary entries make up a directory entry set describing a file or directory. The first directory entry in the set is a primary directory entry. All subsequent entries, if any, must be secondary directory entries.

Each directory entry derives from Generic Directory Entry template. Size of directory entry is 32 bytes.

Table 1. Generic Directory Entry Template
Offset Size Description Comments
0 (0x00) 1 EntryType (see below)  
1 (0x01) 19 CustomDefined  
20 (0x14) 4 FirstCluster 0 – no cluster allocation 2..ClusterCount+1 – cluster index
24 (0x18) 8 DataLength In bytes
Table 2. Entry Types description
Bits Size Description Comments
0-4 5 Code  
5 1 Importance 0 – Critical entry, 1 – Benign entry
6 1 Category 0 – Primary entry, 1 – Secondary entry
7 1 In use status 0 – Not in use, 1 – In use

Entry Type can have the following values:

  • 0x00 – End Of Directory marker. All other fields in directory entry are invalid. All subsequent directory entries are also End Of Directory markers
  • 0x01-0x7F (InUse = 0). All other fields in this entry are not defined
  • 0x81-0xFF (InUse = 1). Regular record with all fields defined.
Table 3. Generic Primary Directory Entry Template
Offset Size Description Comments
0 (0x00) 1 EntryType
1 (0x01) 1 SecondaryCount Number of secondary entries which immediately follow this primary entry and together comprise a directory entry set. Valid value is 0..255
2 (0x02) 2 SetChecksum Checksum of all directory entries in the given set excluding this field. See EntrySetCheckSum().
4 (0x04) 2 GeneralPrimaryFlags (see below)  
6 (0x06) 14 CustomDefined  
20 (0x14) 4 FirstCluster  
24 (0x18) 8 DataLength  
Bits Size Description Comments
0 1 AllocationPossible 0-not possible (FirstCluster and DataLength undefined), 1-possible
1 1 NoFatChain 0-FAT cluster chain is valid 1-FAT cluster chain is not used (contiguous data)
2 14 CustomDefined  

All critical primary directory entries are located in root directory (except file directory entries). Benign primary directory entries are optional. If one benign primary entry is not recognized, all directory entry set is ignored.


// data points to directory entry set in memory
UINT16 EntrySetChecksum(const unsigned char data[], int secondaryCount)
{
	UINT16 checksum = 0;
	int bytes = (secondaryCount + 1) * 32;

	for (int i = 0; i < bytes; i++)
	{
		if (i == 2 || i == 3)
			continue;
		checksum = (checksum << 15) | (checksum >> 1) + data[i];
	}
	return checksum;
}