前言

本节将学习到 exFAT 文件系统的 FAT 表、簇位图、目录结构。

知识点总览

  • exFAT 分区 FAT 表结构
  • exFAT 分区 Bitmap 结构
  • exFAT 分区大写字符文件结构
  • exFAT 分区目录结构

exFAT 分区 FAT 表结构

FAT(File Allocation Table)即文件分配表,对于 ExFAT 文件系统来讲也是很重要的一个组成部分,ExFAT 文件系统 FAT 表的功能主要是记录不连续存储的文件的簇链,所以在 FAT 中看到数值为 0 的 FAT 项,并不能说明该 FAT 项对应的簇是可用簇。

系统是如何定位到 FAT 表的?

① 从 MBR 的分区表定位到该分区的 DBR 扇区。

② 读取 DBR 的 BPB 参数,主要读取 “ FAT 表起始扇区号” 这个参数,它在 DBR 的 50H~54H 偏移处。

③ 读取到 “FAT 表起始扇区号” 这个参数的值后,跳转到该分区的偏移扇区,这里就是 FAT 表的开始。

FAT 表的实际应用

把分区格式化为 exFAT 文件系统时,格式化程序会把分配给 FAT 表的第一个扇区清零,然后写入 0 号 FAT 项和 1 号 FAT 项,另外还会写入簇位图文件、大写字符文件及根目录所占簇对应的 FAT 项。

ExFAT文件系统的FAT表分析

由上图可以看出每个 FAT 项占用 4 字节:其中 0 号 FAT 项描述介质类型,其首字节为“F8”,表示介质类型为硬盘;1 号 FAT 项写入 4 个“FF”;从 2 号 FAT 项开始对应 2 号簇,3 号 FAT 项对应 3 号簇,一直到最后一个簇。目前 2、3、4 三个 FAT 项中都是结束标志,说明簇位图文件、大写字符文件、根目录各占一个簇。

除了这 5 个 FAT 项以外,其他 FAT 项都是 0,但这并不能说这些 FAT 项对应的簇就是空簇。

exFAT 分区 Bitmap 结构

ExFAT 文件系统的 FAT 表之后就是数据区了,但数据区并不一定紧跟在 FAT 表之后,FAT 表后面可能还会有一些保留扇区,每个分区不一样,这要看实际情况。所以不能通过 Bitmap 的位置减去 FAT 表的位置直接计算分区大小。数据区的开始位置在 DBR 的 BPB 中有描述,“首簇起始扇区号”起始就是数据区的开始。数据区中第一个簇就是 2 号簇,2 号簇一般都分配给簇位图文件使用。

簇位图文件是在分区格式化时创建的,该文件不允许用户访问和修改。

ExFAT文件系统的簇位图文件分析

上图为一个 exFAT 分区的 Bitmap。

该扇区中只有一个字节“07H”,这就是簇位图文件的内容。

簇位图文件是 ExFAT 文件系统中的一个元文件,类似于 NTFS 文件系统中的元文件$BitMap,它的作用是用来管理分区中簇的使用情况。簇位图文件中的每一个位,映射到数据区中的每一个簇。如果某个簇分配给了文件,该簇在簇位图文件中对应的位就会被填入“1”,表示该簇已经占用;如果没用使用的空簇,它们在簇位图文件中对应的位就是“0”。

exFAT 分区大写字符文件结构

大写字符文件是 exFAT 文件系统中的第二个元文件,类似于 NTFS 文件系统中的元文件$UpCase。Unicode 字母表中每一个字符在这个文件中都有一个对应的条目,用于比较、排序、计算 Hash 值等方面。

大写字符文件是在分区格式化时创建的,该文件不允许用户访问和修改。

簇位图文件结束后的下一个簇一般就分配给大写字符文件使用。

大写字符文件的大小固定为 5836 字节,约为 12 个扇区。

下图为一个大写字符文件的第一个扇区的前半部分。

ExFAT文件系统的大写字符文件分析

从图中可以看到其内容都是 Unicode 字母表中的字符,每一个字符占用两个字节。

exFAT 分区目录结构

目录项对于 exFAT 文件系统来讲是非常重要的组成部分,其主要作用及结构特点如下:

① 分区中的每个文件和文件夹(也称为目录)都被分配多个大小为 32 字节 的目录项,用以描述文件或文件夹的属性、大小、起始簇号和时间、日期等信息,当然还会把文件名或目录名也记录在目录项中。

② 在 exFAT 文件系统中,目录也被视为特殊类型的文件,所以每个目录也与文件一样有目录项

③ 在 exFAT 文件系统下,分区根目录下的文件及文件夹的目录项存放在根目录区中,分区子目录下的文件及文件夹的目录项存放在数据区相应的簇中

④ exFAT 文件系统目录项的第一个字节用来描述目录项的类型,剩下的 31 字节用来记录文件的相关信息。

⑤ 根据目录项的作用和结构特点,可以把目录项分为四种类型:

  • 卷标目录项
  • 簇位图文件的目录项
  • 大写字符文件的目录项
  • 用户文件的目录项

卷标目录项

卷标就是一个分区的名字,可以在格式化分区时创建,也可以随时修改。ExFAT 文件系统把卷标当作文件,用文件目录项进行管理。系统为卷标建一个目录项,放在根目录区中。

卷标的目录项占用 32 字节,其中第一个字节是特征值,用来描述类型。

卷标目录项的特征值为“83H”,如果没有卷标或者将卷标删除,该特征值为“03H”。

没有卷标的目录项

image-20211220163515076

上图为一个没有卷标的 exFAT 类型分区,其特征值为“03H”,占用 32 字节。

有卷标的目录项

接下来查看有卷标的目录项(M:):

image-20211220164218881

image-20211220164201504

上图为一个有卷标的 exFAT 类型分区,其特征值为“83H”,紧接着标识符后的即为卷标名,共占用 32 字节。

卷标的长度理论上为 11 字符,但实际上可以达到 15 字符。

被修改过卷标的目录项

将上图 “M:” 分区的卷标改为 expart 后从底层查看该属性。

image-20211220164640907

由上图可以看出,该分区根目录的第一个目录项 “83H” 的内容被修改了。

接下来查看将 “没有卷标的目录项” 改为 “有卷标的目录项”:

将 “N:” 分区的卷标改为 newpart 后从底层查看该属性。

image-20211220164824037

从根目录可以看出,该分区的第一个目录项还是 “03H”。

image-20211220164906019

但是在最后一个目录项(改完卷标后没有做任何文件操作)中可以看到一条特征值为 “83H” 的目录项。

image-20211220164946680

该目录项为刚刚修改的 newpart,再次修改卷标后,只有该目录项变更值。

簇位图文件的目录项

ExFAT 文件系统格式化时会创建一个簇位图文件,并为其建一个目录项,放在根目录区中。

簇位图文件的目录项占用 32 字节,其中第一个字节是特征值,用来描述类型。簇位图文件目录项的特征值为“81H”。

ExFAT 簇位图文件目录项的含义:

字节偏移 字段长度(字节) 内容及含义
0x00 1 目录项的类型(簇位图文件目录项的特征值为“81H”)
0x01 1 保留
0x02 18 保留
0x14 4 起始簇号
0x18 8 文件大小

簇位图文件的目录项有如下特点:

① 对于 ExFAT 格式的分区,簇位图文件起始簇号一般都为 2。

② 簇位图文件的目录项中不记录时间戳。

下图为一个示例分区的簇位图目录项:

image-20211220165914241

从上图可以看出,该分区的簇位图的起始簇号为:00 00 00 02 H

簇位图的大小为:00 00 D0 12 H (53,266 字节)

故该分区 BPB 参数中的 “分区总簇数” 为 (53266 - 1) * 8 ≈ 426,120

由于最后一个字节不一定完整表示 8 个簇,为避免误差,则将字节数 - 1,算出来的结果与原总簇号最多误差 8 个簇。

大写字符文件的目录项

ExFAT 文件系统格式化时会创建一个大写字符文件文件,并为其建一个目录项,放在根目录区中。

大写字符文件的目录项占用 32 字节,其中第一个字节是特征值,用来描述类型。大写字符文件目录项的特征值为“82H”。

ExFAT 大写字符文件目录项的含义:

字节偏移 字段长度(字节) 内容及含义
0x00 1 目录项的类型(大写字符文件目录项的特征值为“82H”)
0x01 3 保留
0x08 14 保留
0x14 4 起始簇号
0x18 8 文件大小

大写字符文件的目录项有如下特点:

① 对于 ExFAT 格式的分区,大写字符文件的目录项一般都跟在簇位图文件的目录项之后。

② 大写字符文件的目录项中不记录时间戳。

下图为一个示例分区的大写字符文件目录项:

image-20211220172019066

从上图可以看出,该分区的大写字符文件的起始簇号为:00 00 00 04 H

大写字符文件的大小为:00 00 16 CC H (5,836 字节)

跳转到大写字符文件数据区(4 号簇)后查看其扇区位置:

image-20211220172400321

大写字符的位置为 6,335 号扇区

根目录的数据区在大写字符后一个簇(即 5 号簇),向下跳转 5836 字节后搜索 !00 到达根目录:

image-20211220172727237

根目录的位置为 6,399 扇区。

用根目录的位置(5 号簇)减去大写字符文件位置(4 号簇)可得每簇扇区数为:6399 - 6335 = 64 。

用户文件的目录项

ExFAT 文件系统中每个用户文件至少有三个目录项,这三个目录项被称为三个属性:第一个目录项称为“属性 1”,目录项首字节的特征值为“85H”;第二个目录项称为“属性 2”,目录项首字节的特征值为“C0H”;第三个目录项称为“属性 3”,目录项首字节的特征值为“C1H”。

“属性 1”目录项

“属性 1”目录项用来记录该目录项的附属目录项数、校验和、文件属性、时间戳等信息。

用户文件的“属性 1”目录项如图所示。

image-20211220175047782

用户文件的“属性 1”目录项的含义

字节偏移 字段长度(字节) 内容及含义
0x00 1 目录项的类型(“属性 1”目录项的特征值为“85H”)
0x01 1 附属目录项数
0x02 2 校验和
0x04 4 文件属性
0x08 4 文件创建时间
0x0C 4 文件最后修改时间
0x10 4 文件最后访问时间
0x14 1 文件创建时间精确至 10ms
0x15 3 保留
0x18 8 保留

①0x00 ~ 0x00:类型。该参数为目录项类型的特征值,“属性 1”目录项的特征值为“85H”。

②0x01 ~ 0x01:附属目录项数。该参数指除此目录项外,该文件还有几个目录项,当前值为 2,说明这个文件除了“属性 1”目录项外,后面还有两个目录项,起始就是“属性 2”目录项和“属性 3”目录项。

③0x02 ~ 0x03:校验和。该参数是校验算法算出来的目录项的校验和。

④0x04 ~ 0x07:文件属性。该参数描述文件的常规属性,属性具体含义见下表。

二进制值 属性含义 二进制值 属性含义
00000000 读/写 00001000 卷标
00000001 只读 00010000 子目录
00000010 隐藏 00100000 存档
00000100 系统

⑤0x08 ~ 0x0B:文件创建时间。该参数是文件的具体创建时间,格式为 32 位的 DOS 时间,包括年、月、日、时、分、秒,具体表示方法与 FAT 文件系统一样,这里就不再重复讲述。

⑥0x0C ~ 0x0F:文件最后修改时间。该参数是文件最后一次修改时的具体时间,格式为 32 位的 DOS 时间,包括年、月、日、时、分、秒,具体表示方法跟 FAT 文件系统一样,这里就不再重复讲述。

⑦0x10 ~ 0x13:文件最后访问时间。该参数是文件最后一次访问时的具体时间,格式为 32 位的 DOS 时间,包括年、月、日,也包含时、分、秒,这一点跟 FAT 不一样,FAT 中改时间只有年、月、日,没有时、分、秒。

⑧0x14 ~ 0x14:文件创建时间,精确至 10ms。该参数是文件的具体创建时间精确到 10ms 的数值。

“属性 2”目录项

“属性 2”目录项用来记录文件是否有碎片、文件名的字符数、文件名的 Hash 值、文件的起始簇号及大小等信息。

用户文件的“属性 2”目录项如图所示。

image-20211220180123226

用户文件的“属性 2”目录项的含义

字节偏移 字段长度(字节) 内容及含义
0x00 1 目录项的类型(“属性 2”目录项的特征值为“C0H”)
0x01 1 文件碎片标志
0x02 1 保留
0x03 1 文件名字符数 N
0x04 2 文件名 Hash 值
0x06 2 保留
0x08 8 文件大小 1
0x10 4 保留
0x14 4 起始簇号
0x18 8 文件大小 2

①0x00 ~ 0x00:类型。该参数为目录项类型的特征值,“属性 2”目录项的特征值为“C0H”。

②0x01 ~ 0x01:文件碎片标志。该参数能够反映出文件是否连续存放。如果是连续存放没有碎片,该标志为 03H;如果不是连续存放,文件有碎片,该标志就为 01H。

③0x03 ~ 0x03:文件名字符数。该参数用来说明文件名的长度,ExFAT 文件系统的文件名用 Unicode 码表示,每个字符占用两个字节。

④0x04 ~ 0x05:文件名 Hash 值。该参数是根据相应算法算出的文件名的校验值,当文件名发生改变时,Hash 值也会发生改变,但当文件移动时,该值并不改变。

⑤0x08 ~ 0x0F:文件大小 1。该参数是文件的总字节数,用 64 位记录文件大小。

⑥0x14 ~ 0x17:起始簇号。该参数描述文件的起始簇号,用 32 位记录簇的地址。

⑦0x18 ~ 0x1F:文件大小 2。该参数也是文件的总字节数,是为 NTFS 文件系统的压缩属性准备的,一般情况下与“文件大小 1”的数值保持一致。

“属性 3”目录项

“属性 3”目录项用来具体记录文件的名称。如果文件名很长,“属性 3”可以包含多个目录项,每个目录项称为一个片段,从上至下依次记录文件名的每一个字符,记录的方向刚好跟 FAT 文件系统中长文件名目录项从下至上的顺序相反。

image-20211220182437323

用户文件的“属性 3”目录项的含义

字节偏移 字段长度(字节) 内容及含义
0x00 1 目录项的类型(“属性 3”目录项的特征值为“C1H”)
0x01 1 保留
0x02 2N 文件名

因为该文件名很短,所以只有一个片段,如果文件名足够长,则有多个“属性 3”(C1H)。