目录项

8.6.5.3 目录项
  在  FAT32  文件系统中,根据结构不同可以将目录项大致分为四种:卷标目录项、 “.”目录项和“..”
目录项、短文件名目录项、长文件名目录项。短文件名目录项是最重要的数据结构,其中存放着有关子目
录或文件的短文件名、属性、起始簇号、时间值以及内容大小等信息。在 FAT32 文件系统中,将子目录看
作是一种特殊的文件。
1.  短文件名目录项
短文件名目录项是 FAT 文件系统中非常重要的一种数据结构。之所以称其为短文件名目录项,是因为
它所记录的文件名延续了 DOS时代的 8.3 格式,即 8个字符的名字加上 3个字符的扩展名:
  如果文件名不足 8个字符,用 0x20 进行填充。
  超过 8 个字符时则会被截短,因为短文件名目录项中没有足够的空间记录超出的部分。截短的
方法是取文件名的前 6 个字符加上“~1”(如果有同名文件,则会依次递增该数值),然后加上
其扩展名。
  如果是子目录,则将扩展名部分用“0x20”进行填充。
为了解决长文件名的问题,FAT 文件系统又增加了一种“长文件名”目录项结构。其从 windows95 开
始,不管文件名的长度是否超过 8 个字符,都会同时为其创建短文件名目录项和长文件名目录项,因为短
文件名不区分大小写,而长文件名则是区分大小写的。

2. 短文件目录项的特性
每个文件或子目录都分配有一个大小为  32 字节的短文件目录项,用以描述文件或目录的属性。
  所有的目录项并不是具有相同的地址,要找到一个目录项的位置只能用分配给文件或子目录的
全名进行是搜索。
  目录项结构中有一个属性区域,每个文件可以设置  7 中属性。
  每个文件或目录还有四个非关键性属性:
  只读属性

  隐藏属性
  存档属性
  每个目录项包括三个时间值,即建立时间、最后访问时间、最后修改时间:
  建立时间,精确到十分之一
  最后访问时间,精确到日
  最后修改时间,精确到 2 秒
  一个目录项是否被分配使用由它的第一个字节来描述。对于已经分配使用的目录项,它的第一个字
节是文件名的第一个字符,而文件或目录被删除后,它所对应的目录项的第一个字节将被置为
0xE5,这就是为什么有的 FAT数据恢复工具需要用户自己输入文件名的第一个字符的原因。
3.短文件名目录项的数据结构
每个短文件名目录项占 32 个字节,数据结构如下图所示:

具体解释如下:
【1】0x00~0x00:1个字节,如果该目录项正在使用中,则为文件名或子目录名的第一个字符。
  0x00:说明该目录项未被分配使用。
  0xE5:说明该目录项曾经被使用过,但是现在已被删除。目前处于未分配状态
【2】0x01~0x0A:10 个字节,文件名的第 2至第 11 个ASCII 码,除扩展名外,如果文件的名字不足 8
个字符则用 0x20 进行填充。
【3】0x0B~0x0B:1个字节,所描述文件的属性
  0x01-只读
  0x02-隐藏
  0x04-系统文件
  0x08-卷标
  0x0F-为此值时表示该目录项为长文件名目录项
  0x10-目录
  0x20-存档
【4】0x0C~0x0C:1字节,保留 (这个位默认为0,在只有短文件名时才有用.当为0x00时为basename全大写,当为0x08时为全basename小写;0x10时extname全大写,0x00全extname小写;当为0x18时为全basename小写,extname全大写)
【5】0x0D~0x0D:1个字节,文件穿件的时间,精确到创建时刻的十分之一秒
【6】0x0E~0x0F:2个字节,文件创建的时间——时分秒

两个字节的 16bit 被划分为 3个部分:
  0~4bit 为秒,以 2秒为单位,有效值为 0~29,可以表示的时刻为 0~58
  5~10bit 为分,有效值为 0~59
  11~15bit 为时,有效值为 0~23
下面举例说明:
如上图所示,其子目录项偏移 0x0E~0x0F 字节处的内容为“A1A9”,我们来计算一下。由于 FAT 文件系
统数据采用的小端存储方式,因此“A1A9”表示成16进制为0xA9A1,换算成2进制就是1010 1001 1010 0001,
我们将其分成三部分并计算它的值,如下图所示:

 

 

可以看到上面的创建时间是 21:13:03,在误差允许的范围内。
【7】0x10~0x11:2个字节,文件创立的日期,16bit 也划分为三个部分:
  0~4bit 为日,有效值为 1~31
  5~10bit 为月,有效值为 1~12
  11~15bit 为时,有效值为 0~127,这是一个相对于 1980 年的年数值,也就是说该值加上 1980
即为文件创建的日期值。该部分笔者就不再举例就计算了,原理和计算创建时间是一样的。请
读者自己去计算。 
【8】0x12~0x13:2 个字节,最后访问日期。
【9】0x14~0x15:2 个字节,文件起始簇号的高两个字节。
【10】0x16~0x17:2 个字节,文件最后修改的时间。

【11】0x18~0x19:2 个字节,文件最后被修改时的日期。
【12】0x1A~0x1B:文件内容起始簇号的低两个字节,与 0x14~0x15 字节处的高两个字节组成文件内容
起始簇号。
【13】0x1C~0x1F:文件内容大小字节数,只对文件有效,子目录的目录项此处全部设置为 0。

5.长文件名目录项
  FAT32 文件系统在为文件分配短文件名目录项的同时会为其分配长文件名目录项。文件系统在为文件
创建长文件名(Long File  Name,LFN)类型的目录项时,并没有舍弃原有的短文件名目录项,具有 LFN 的
文件同时也有一个常规的 SFN(Short File Name,短文件名)类型目录项。之所以仍然需要 SFN,是因为
LFN目录项只包含文件的名字,而不包括任何有关时间、大小及起始簇号等信息,这些信息仍然需要用 SFN
目录项来记录。
6.长文件名目录项特性
  如果一个文件的文件名超过了 8个字符,则会为其名字截短后为其建立短文件名。将短文件名存储在
短文件名目录项中。长文件名则存放在长文件名目录项中。长文件名目录项有以下的特性:
  LFN和 SFN 目录项结构在相同位置有一个属性标志字节,LFN 目录项使用一个特定的属性值,以
说明它是一个长文件名项。
  项中的其他字节,使用 UTF-16 编码(UTF-16 是 Unicode 的其中一个使用方式。 UTF 是
Unicode/UCS Transformation Format,即把 Unicode 转做某种格式的意思),存储 13个 Unicode
字符的文件名,每个字符占用两个字节。
  如果文件名长于 13个字符,则继续为其分配 LFN项,知道够用为止。
  所有 LFN都包含一个校验和,通过这个校验和将其与相应的 SFN项关联起来。
  一个文件的所有 LFN 项按倒序排列在它的 SFN 项前面,即文件名的第一部分距离 SFN 是最近的。
7.长文件名目录项数据结构

详细解释如下:
【1】0x00~0x00:1 个字节,长文件名目录项的序列号,一个文件的第一个长文件名序列号为 1,然
后依次递增。如果是该文件的最后一个长文件名目录项,则将该目录项的序号与 0x40 进行“或(OR)运算”
的结果写入该位置。如果该长文件名目录项对应的文件或子目录被删除,则将该字节设置成删除标志0xE5。
【2】0x01~0x0A:5 个字节,长文件名的第 1~5 个字符。长文件名使用 Unicode 码,每个字符需要两
个字节的空间。如果文件名结束但还有未使用的字节,则会在文件名后先填充两个字节的“00”,然后开始
使用 0xFF 填充。
【3】0x0B~0x0B:1 个字节,长目录项的属性标志,一定是 0x0F。
【4】0x0C~0x0C:保留。
【5】0x0D~0x0D:1 个字节,校验和。如果一个文件的长文件名需要几个长文件名目录项进行存储,
则这些长文件名目录项具有相同的校验和。
【6】0x0E~0x19:12 个字节,文件名的第 6~11 个字符,未使用的字节用 0xFF 填充。
【7】0x1A~0x1B:2 个字节,保留。

【8】0x1C~0x1F:4 个字节,文件名的第 12~13 个字符,未使用的字节用 0xFF 填充。
8.长文件名目录项实例分析
  首先我们在根目录下建立一个名字为“amp3foryatoumadebyfgd20090808summer.txt”的文件,然后
用winhex 来看看它的长文件名目录项,如下图:

上面看的第二幅图就是由“amp3foryatoumadebyfgd20090808summer.txt”文件的短文件名目录项和长文件
名目录项组成。最下面的一个目录项就是该文件的短文件名目录项,我们可以看到,
“amp3foryatoumadebyfgd20090808summer.txt”文件名被截断,取出前六个字符“AMP3FO”(注意短文件
名是不分大小写的),然后加上“~1”,最后加上它的扩展名。由短文件名向上,是它的长文件名目录项。
“amp3foryatoumadebyfgd20090808summer.txt”共有39个字符,每个长文件名目录项可以记录13个字符,
因此需要 3 个长文件名目录项。短文件名目录项向上第一个小方框卷定的目录项是它的第一个长文件名目
录项,向上依次为 2、3号,从每个长文件名目录项的第一个字节可以看出他们的序号。
  【1】我们先来看第一个内容:
  0x0B 字节处的“0F”表示这是一个长文件名目录项。
  0x00 字节处的“01”表示这是该文件的第一个长文件名目录项。
  0x01~0x0A 字节处的 10个字节为文件名的第 1~5 个字符“amp3f”。0x0E~0x19 子接触的 12 个字
节是文件名的第6~11个字符“oryato”, 0x1C~0x1F处的4个字节是文件名的第12~13个字符“um”。 
【2】第二个长文件名目录项的第一个字节“02”表示这是该文件的第二个长文件名目录项,各部分
字节含义由读者自行分析。
【3】第三个长文件名目录项的第一个字节为“43”,是 0x40 和0x03 进行或运算的结果。说明这是该
文件的第 3个长文件名目录项,也是最后一个。
【4】  我们分别看3个长文件名目录项0x0D字节处的值——0x8B,这是长文件名目录项的校验和。
说明这 3个目录项同属一个长文件名目录项。
【5】  Winhex 也提供了 FAT 长文件名目录项的模板,如下图:

(注:以上这张图片似乎有点问题,可能与笔者使用的软件版本有关)
9.“.”目录项和“..”目录项
  前面曾经介绍过,一个子目录的起始簇,前两个目录为“.”目录项和“..”目录项,子目录通过这
两个目录项及它在父目录中的目录项建立起父子目录的联系。
  “.”目录项位于子目录起始簇的第一个目录项位置,它用以表明该簇是一个子目录的起始簇。
另外,该目录项实际上是对目录自身的描述,它记录了该子目录时间信息、起始簇号等。需要
注意的是,它所记录的起始簇号也就是该子目录目前所处的位置。
  “..”目录项位于子目录起始簇的第二个目录项位置,用于描述该子目录的父目录的相关信息。
下面分析“yatou”目录,如图:

我们重点看两个目录项的簇号描述部分(被标记部分)
  第一个目录项也就是“.”目录项,记录的簇号为 4 号簇,也正是本子目录所在的簇。
  第二个目录项记录的簇号为这个子目录的父目录的起始簇号,如果父目录是根目录,则簇号位
置全部设置为 0。
10.卷目录项 

名不足 11 个字节,则用 0x20 填充。(由于每个汉字占用 2 个字节空间,而卷标最多允许 11 个
字节,所以用汉字命名卷标时,卷标的长度不能超过 5 个汉字)。
  卷标目录项结构与普通短文件名目录项结构完全相同,但没有创建时间和访问时间,只有一个
最后修改时间。
  另外,卷标目录项也没有起始簇号和大小值,这些字节位置全部这只为  0,0x0B  字节处的属性
值为 0x08.
  如果创建文件系统时制定了卷标,则会在根目录下第一个目录项项的位置建立一个卷标目录项:
  卷标名最多允许占用长度为 11 个字节,也就是为短文件名分配的 11 个文件名区域,如果卷标

本文链接:https://my.lmcjl.com/post/1455.html

展开阅读全文

4 评论

留下您的评论.