4.2.1 FAT文件的组织结构
1.硬盘的数据组织方式
刚刚从厂商处购买的新硬盘既无任何数据,也不能写入任何数据,必须先进行低级格式化、FDISK分区和FORMAT高级格式化后方可使用。对硬盘的这一系列初始化工作,称之为硬盘准备。过程如下:
低级格式化→FDISK分区→FORMAT高级格式化。
(1)低级格式化
对硬盘划分磁道和扇区,在扇区的地址域上标注地址信息,并剔出坏磁道。
(2)FDISK
允许整个物理硬盘在逻辑上划分成多个分区(最多4个),以实现多个操作系统共享硬盘空间。如果将整个物理盘全部划归DOS/Windows管理,则FDISK分区的作用是将一个物理盘划分成一个主分区和一个扩展分区,然后再将扩展分区划分成一个或多个逻辑盘。在硬盘上建立分区表的同时,FDISK把主引导记录MBR写到硬盘的主引导记录(柱面0、磁头0、扇区1),并激活一个用户指定的分区。
(3)FORMAT
在DOS分区空间划分逻辑扇区,生成DOS引导扇区(即逻辑0扇区)DBR、文件分配表FAT和根文件目录表FDT。
硬盘在DOS/Windows的管理下,数据信息由MBR、DBR、FAT、FDT和数据区5个部分组成。
为了能更深入地了解硬盘文件的存储结构,图4-5所示是一块40GB硬盘的分区示意图,它使我们对硬盘的数据结构有一个基本了解。各分区长度是:第一分区6.32GB、第二分区6.32GB、第三分区6.32GB,第一逻辑分区19.86GB、第二逻辑分区2.15GB。图中用黑框标明的扇区(尤以主引导扇区和第一分区引导扇区为最)是易受病毒攻击的扇区。
图4-5 40GB硬盘分区示意图
2.主引导记录
硬盘的0柱面、0磁头、1扇区称为主引导扇区,FD ISK程序写到该扇区的内容称为主引导记录。该记录占用512个字节,它用于硬盘启动时将系统控制权转给用户指定,并在分区表中登记某个操作系统分区。
(1)MBR的组成
在总共512字节的主引导扇区中,MBR占用了其中的446个字节(偏移地址0~偏移地址1BDH),另外的64个字节(偏移地址1BEH~偏移地址1FDH)交给了DPT(Disk Partition Table,译为硬盘分区表),最后两个字节“55AA”(偏移地址1FEH~偏移地址1FFH)是分区的结束标志。这个整体构成了硬盘的主引导扇区。MBR结构如图4-6所示。
图4-6 硬盘的主引导扇区结构图
主引导记录中包含了硬盘的一些参数和一段引导程序。其中的硬盘引导程序的主要作用是检查分区表是否正确,并且在系统硬件完成自检以后引导具有激活标志的分区上的操作系统,并将控制权交给启动程序。MBR是由分区程序(如Fdisk.com)所产生的,它不依赖任何操作系统,而且硬盘引导程序也是可以改变的,从而实现多系统共存。主引导记录由三部分组成:主引导程序、四个分区表、主引导记录有效标志字。
主引导程序代码又称第一关键代码,它的作用是找出系统当前的活动分区,负责把对应的一个操作系统的引导记录即当前活动分区的引导记录载入内存。此后,主引导记录就把控制权转给该分区的引导记录。IBM微型机及其兼容机用DOS的实用程序FDISK分区后,主引导程序代码是通用的。在主引导扇区中,从偏移000H开始到偏移1BEH结束的这446字节内容可以用带参数/mbr的FDISK命令FDISK/mbr重写,除了一并改写分区表之外,不会触及硬盘中其他数据。如果主引导记录被病毒覆盖、清零,或者被某些分区软件(如System Commander Deluxe4.0)改写,则可以用相应DOS版本的FDISK/mbr命令加以更正。
硬盘分区表分为四小部分,每一小部分表示一个分区的信息,占16字节。这64字节的硬盘分区表又称为主引导扇区上的第二关键代码。在这里我们可以看出,硬盘的总分区数为什么不能大于4。此外,其中可激活分区数不得大于3,扩展分区数不得大于1,当前活动分区数必须等于1。图4-7所示为硬盘分区表的结构示意图。从偏移1BEH开始到偏移1FEH结束的64个字节是硬盘分区表。
图4-7 硬盘分区表
分区表的每一部分长16字节。第0个字节是自举标志,其值为80H时,表示该分区是当前活动分区,可引导;其值为00H时,表示该分区不可引导。
第4字节是分区类型。如果分区不是NetWare服务器或Linux分区,则两个16进制数各表示不同的含义。左边的16进制数(即8个二进制位中的高4位)只取两个值即0H或1H,0H时表示此分区为非隐藏分区,1H时则表示是隐藏分区。右边的16进制数(即8个二进制位中的低4位)表示分区的文件系统格式、类别(是操作系统所在的基本分区还是扩展分区)等信息:取6H则表示是FAT16格式,且大于32MB;取5H表示是DOS扩展分区;取7H表示是NTFS文件格式;取BH表示是FAT32文件格式;取CH表示是FAT32X文件格式;取EH表示是FAT16X文件格式;取FH表示是ExtendedX扩展分区。
每一分区的第1至第3字节是该分区起始地址。其中第1字节为起始磁头号(面号);第2字节的低6位为起始扇区号,高2位则为起始柱面号的高2位;第3字节为起始柱面号的低8位。因此,分区的起始柱面号是用10位二进制数表示的,最大值为210=1024,因逻辑柱面号从0开始计,故柱面号的显示最大值为1023。同理,用6位二进制数表示的扇区号不会超过26-1=63;用8位二进制数表示的磁头号不会超过28-1=255。
每一分区的第5至第7字节表示分区的终止地址,各字节的释义与第1至第3字节雷同,故不再赘述。这里我们假设一种极端的情况:如果让第5至第7字节的所有二进制位都取1,就获得了柱面号、磁头号和扇区号所能表示的最大值,从而得到最大绝对扇区号为:
1024×256×63=16515072
这个扇区之前的所有物理扇区所包含的字节数为:
16515072×512≈8.46×109=8.46GB
由此可见,分区表每一分区的第1至第3字节以及第5至第7字节的数据结构已经不能满足大于8.46GB的大容量硬盘的需要。由此也可知硬盘的容量设计为什么会有8.4GB这一挡。由于考虑到向下兼容的需要,业界并未对从DOS时代就如此定义的硬盘分区表提出更改意见,否则改动所牵涉的面太广,会造成硬件和软件发展上的一个断层,几乎无法被业界和用户所接受。硬盘厂商解决这一问题的方法是定义了新的INT13服务扩展标准。新的INT13服务扩展标准不再使用操作系统的寄存器传递硬盘的寻址参数,而使用存储在操作系统内存里的地址包。地址包里保存的是64位LBA地址,如果硬盘支持LBA寻址,就把低28位直接传递给ATA接口,如果不支持,操作系统就先把LBA地址转换为CHS地址,再传递给ATA接口。通过这种方式,能实现在ATA总线基础上CHS寻址的最大容量是136.9GB,而LBA寻址的最大容量是137.4GB。新的硬盘传输规范ATA133规范又把28位可用的寄存器空间提高到48位,从而支持更大的硬盘。
分区表每一分区的第8至第11字节表示该分区的起始相对扇区号(即该扇区之前的绝对扇区个数),高位在右,低位在左;第12至第15字节表示该分区的实际占用扇区数,也是高位在右,低位在左。分区表数据结构的图示表达方式与机器中数据的实际存储方式在顺序上是一致的,即低位在前,高位在后。然而人类的数据读/写习惯却恰恰相反,是高位在前(左),低位在后(右)。因此,在目读分区表或类似结构的字段,并且从16进制向十进制作数值转换时,需将字段中的16进制数以字节为单位翻转调位。
主引导扇区的第三关键代码是本扇区的最后两个字节(偏移1FEH和偏移1FFH),其值为AA55H,它表示该扇区是有效的引导扇区,可用来引导硬盘系统。
(2)MBR的读取
硬盘的引导记录是不属于任何一个操作系统,也不能用操作系统提供的磁盘操作命令来读取它。但是我们可以利用ROM-BIOS中的INT13H的2号功能来读出该扇区的内容(也可以使用工具软件来读取)。
使用INT13H读取磁盘扇区功能的调用参数如表4-1所示。
表4-1 INT13H读取磁盘扇区功能的调用参数表
用DEBUG读取位于硬盘0柱面、0磁头和1扇区的操作如下:
A:>DEBUG
-A 100(汇编下面程序)
1BD4:0100 B80102 MOV AX,0210 (读一个扇区)
1BD4:0103 BB0010 MOV BX,0000 (置内存缓冲区为CS∶0000)
1BD4:0106 B90100 MOV CX,0001 (读0柱面,1扇区)
1BD4:0109 BA8000 MOV DX,0080 (指定第一物理磁盘的0磁头)
1BD4:010C CD13 INT 13
1BD4:010E CC INT3(程序结束)
1BD4:010F
-G=100 (执行以上程序段)
-D 0000 01FF (显示512字节的MBR内容)
(3)MBR的主要功能及其工作流程
启动计算机时,系统首先对硬件设备进行测试,成功后进入自举程序INT19H。然后读系统磁盘0柱面、0磁头、1扇区的主引导记录内容到内存指定单元0∶7C00首址开始的区域,并执行MBR程序段。
硬盘的引导记录是不属于任何一个操作系统的,它先于所有的操作系统而被调入内存并发挥作用,然后才将控制权交给主分区内的操作系统,并让主分区信息表来管理硬盘。
MBR程序段的主要功能如下:
1)检查硬盘分区表是否完好。
2)在分区表中寻找可引导的活动分区。
3)将活动分区的第一逻辑扇区内容装入内存。在DOS/Windows分区中,此扇区内容称为DOS引导记录。
MBR引导程序段的执行流程如图4-8所示。
图4-8 MBR引导程序段执行流程图
3.引导记录
磁盘的逻辑0扇区统称为DOS引导扇区,又称为BOOT区。它通常位于硬盘的0磁道、1柱面、1扇区,是操作系统可以直接访问的第一个扇区,它包括一个引导程序和一个被称为BPB的本分区参数记录表。引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区跟目录前两个文件是不是操作系统的引导文件(以DOS为例,即是IO.sys和MSDOS.sys)。如果确定存在,就把其读入内存,并把控制权交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数,分配单元的大小等重要参数。下面介绍BPB表。
(1)描述逻辑盘结构的BPB表
FAT16的BPB表描述逻辑盘结构组成,包含隐藏扇区数目(从0-1-1开始计算)、FAT扇区数、FAT拷贝数、硬盘磁头总数、根目录表项最大值等。FAT32系统中,BPB表的偏移地址与FAT16不同,但表项基本相同。整个隐藏扇区部分都作为逻辑盘的描述区域。硬盘BPB结构说明如表4-2所示。由于FAT32格式是目前最普遍使用的文件系统格式,表中的后半部分是按照FAT32格式给出字段释义的。其中偏移2AH处2字节表示文件系统格式版本号。高4位表示主版本号,低4位表示次版本号,对于Windows95OSR2及以后的操作系统则双双置零。FAT32的根目录与其他子目录一样,是以簇链的方式存储的,这意味着它需要多大就可以多大,对项数无限制。根目录起始簇的簇号至少为2。
对FAT32格式而言,文件系统信息扇区是个新扇区,其结构如左边的表。表中除标明字段之外的所有其他字段均置零。每个FAT32分区至少应有一个这样的文件系统信息扇区,且寓于保留扇区范围内,还不能与引导扇区备份所在的扇区重叠。一般情况下,文件系统信息扇区紧随分区引导扇区之后,故其相对扇区号为1。
从偏移36开始,对不同的文件系统格式,表4-2有不同的内容。前面已经给出了适用于FAT32格式的内容。表4-2中前36个字节曾被称为标准BPB,其后的部分可称为扩展BPB。表4-3给出了扩展BPB适用于FAT16、FAT12格式的内容。
表4-2 BPB中每个字段的字节偏移、长度和含义
(续表)
表4-3 BPB自偏移24H开始适用FAT16格式的字段释义
(2)引导记录DBR的读取
可以用DEBUG中的L命令读出DBR扇区的内容。
在DEBUG中,L命令的格式是:
−L内存缓冲区地址,盘号,起始扇区号和要读取的扇区数
其中,磁盘A、B、C、D、E……的盘号分别为0、1、2、3、4……例如,进入DEBUG后,将D盘DBR扇区的读入内存CS∶100的命令为:
−L 100,3,0,1
(3)DBR的主要功能和工作流程
DOS/Windows系统在引导的时候,DBR是第一个(除硬盘的MBR之外)需装载的程序段。DBR装入内存后,开始执行该引导程序段,其主要任务是装载DOS的系统隐藏文件IO.SYS。DBR程序段所完成的主要任务如下:
1)重新设置引导驱动器。
2)将根目录的第一个扇区(即根目录FDT中的前16个文件项)装载到内存。
3)检查FDT中的前两个文件是否为DOS的两个系统隐藏文件。
4)将其中一个系统隐藏文件IO.SYS装载到内存。
5)将控制权交给该系统隐藏文件IO.SYS。
DBR引导程序段执行流程如图4-9所示。
图4-9 DBR引导程序段执行流程图
4.文件分配表
文件分配表FAT是文件管理系统用来给每个文件分配磁盘物理空间的表格,它告诉操作系统文件存放在磁盘什么地方。
文件分配表型文件系统是微软操作系统最传统和应用最广的文件系统。标准的FAT使用16位寻址方式,Windows95OSR2中引入FAT32方案。FAT16簇数的上限是2的16次方即65 536个,每簇扇区数的上限是64个,因此其分区空间的上限为2GB(Windows NT/2000每簇扇区数可为128,FAT16空间扩充到4GB);FAT32簇使用32位寻址方式,其中高4位保留,实际簇数最多为2的28次方,同时受当前磁盘物理结构和工业标准的限制,一个磁盘或磁盘阵列中扇区最大个数为2的32次方,空间为2的41次方即2TB。Windows2000将FAT32卷的大小限制为32GB。
(1)FAT表的大小及位置
FAT在磁盘上是安排在紧接DOS引导扇区DBR之后的。在FAT16中,它总是从磁盘的逻辑1扇区开始。
在磁盘上共有FAT表的两个拷贝(一个是基本FAT表FAT1,另一个是FAT表的备份表FAT2),两者在磁盘上前后紧排在一起,其大小根据分区的大小不同而变化。
(2)文件的簇号链
磁盘格式后,用户文件是以簇为单位存放在数据区中的,一个文件至少占用一个簇。当一个文件占用多个簇时,这些簇的簇号是不一定连续的,但这些簇号之间又由存储该文件时确定了顺序,形成了每个文件都有其特定的“簇号链”。
假设一个文件长度为4个簇,首簇号是n1,形成的簇号链为“n1→n4→n3→n2”。该文件在FAT表中的簇号链、逻辑空间和物理存放空间的对应关系如图4-10所示。
图4-10 FAT表中文件簇号链对应关系示意图
磁盘上每一个可用的簇在FAT中只有一个登记项,通过在对应簇号的登记项内填入“表项值”来表明数据区中的该簇是已占用、空闲或是已损坏的。损坏的簇是在格式化的过程中,通过FORMAT命令发现的,在一个簇中,只要有一个扇区有问题,该簇就不能使用了。
磁盘上的簇在FAT中的表项占12、16或32位。在FAT16文件系统中,每簇在FAT中所取表项值是占12位还是16位与所用磁盘的容量有关,12位表项值可表示4096个簇,若磁盘的簇数大于4096,则必须用16位表项值。一般来说,小于20740个扇区(10MB)的硬盘DOS分区用12位映射一个簇,多于20740个扇区的硬盘分区,必须采用16位的FAT。FAT12和FAT16表项的组成如图4-11、图4-12所示。
图4-11 FAT12表项的组成
图4-12 FAT16表项的组成
由于FAT对于文件管理的重要性,所以为了安全起见,FAT有一个备份,即在原FAT的后面再建一个同样的FAT。对一个分区而言,无论它是基本分区还是扩展分区中的逻辑分区,都有两个相同的、前后顺序排列的FAT表,后面的一个作为前面一个的备份。如果第一FAT表被病毒改写,可以实施的简便方法是用第二FAT表的相应扇区(或全部扇区)覆盖第一FAT表被破坏的扇区(或全部扇区),以挽救分区数据。
FAT16分区的FAT表每项为2字节,FAT32分区的FAT表每项为4字节。其值用下式计算:
FAT表项数=数据区簇数=数据区字节总数/每簇字节数
每项字节数=FAT表扇区数×512/FAT表项数
该标志信息可取的表项值及其含义如表4-4所示。
FAT表的头两项为系统所保留,第一项的第一个字节是磁盘规格说明,对于固定硬盘应为F8。从第三项开始与数据区的簇一一对应,即第三项与数据区第一个簇相对应,第四项与数据区第二个簇相对应……以此类推。
(3)FAT表的组成格式及功能
综上所述,现将FAT表的组成格式及功能总结如下:
1)表明磁盘类型。FAT的第0簇和第1簇为保留簇,其中第0字节(首字节)表示磁盘类型,其值与BPB中磁介质说明符对应的磁盘类型相同。
表4-4 FAT表项赋予不同值时的含义
2)表明一个文件所占用各簇的簇链分配情况。FAT从002簇开始分配给文件。表项值“001H~FEFH”、“0001H~FFEFH”或“00000001H~FFFFFFEFH”中的任一值表明文件的下一簇号。文件的起始簇号由文件目录表(FDT)中每个目录登记项的第26、27字节决定,作为FAT的入口,起始簇号在FAT中的表项值即文件的第2簇号,第二簇号的表项值即第3簇号,以此类推,直到表项值为FF8H~FFFH、FFF8H~FFFFH或FFFFFFF8H~FFFFFFFFH即表示该簇为文件的最后一簇。
3)标明坏簇和可用簇
若软盘格式化时发现坏扇区,即在相应簇的表项中写入FF7H(或FFF7H),表明该扇区所在簇不能使用,DOS就不会将它分配给用户文件。
磁盘上未用但可用的“空簇”的表项值为000H(或0000H)。当需要存放新文件时,文件管理系统将它们按一定顺序分配给新文件。
虽然FAT表记录了文件所用的磁盘空间信息,但是DOS引导区、两个FAT表、文件目录区等并不由FAT表中的簇表示。
(4)FAT表登记项与文件的簇链关系
以FAT16文件系统的16位登记项为例,文件寻找簇链的计算步骤如下:
1)假如我们已经从文件目录表FDT中查得该文件的起始簇号。
2)将该起始簇号换为十进制数a,a即为查找下一簇号的本簇号。
3)a×2(若是12位FAT项,则a×1.5的乘积取整),即得到FAT中的相对位移b,该位置存放着文件簇链的下一簇号。
4)从该相对位移b开始取一个字(低位在前,高位在后)。
5)重复上述簇链的查找过程,直至找到其值为FFF8H~FFFFH(FAT16文件系统)的簇号。
(5)文件簇链的操作实例
下面用一个例子来说明文件簇链的查找过程。
1)假如已经从FDT中知道一个在1.44MB软盘上文件11.TXT的起始簇号为02。
2)a=02即为查找下一簇号的本簇号。
用DEBUG调出第一个FAT的内容如下:
A:\>DEBUG
−L CS∶0 0 1 7(将A盘第1扇区开始的7个扇区的根目录FAT读入内存)
−D CS∶0(显示FAT的部分内容)
0F74∶0000 F0 FF FF 03 40 00 FF 5F-01 07 F0 FF FF FF FF FF....@.._........
0F74∶0010 FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF 6F...............o......
3)由文件起始簇号2×1.5=3.0,取整后得3,即0003开始的一个字中存放下一簇号。
4)从FAT的第3字节开始,取一个字4003。
5)由于本簇号2为偶数,则保留低12位,003(第3簇)。
6)重复上述的查找过程:
3×1.5=4.5,4.5取整后为4,即0004开始的一个字中存放下一簇号。
从FAT的第4字节开始,取一个字0040。
由于本簇号3为奇数,则保留高12位,004(第4簇)。
7)再重复上述的查找过程:
4×1.5=6,即0006开始的一个字中存放下一簇号。
从FAT的第6字节开始,取一个字5FFFH。
由于本簇号4为偶数,则保留低12位,FFFH(表明第4簇为结束簇)。
由此得到该文件的簇号链为2→3→4。
另外为了在实际中检查簇号链方便一些,我们经常使用工具软件Norton 8.0中的DISKEDIT.EXE来查找更方便一些。
5.文件目录表
用FORMAT命令对磁盘(或逻辑盘)进行格式化的时候,就已经为整个硬盘建立了一个根目录FDT。在根目录下,用户可以用DOS命令“MD”再创建不同的子目录,以及子目录下的子目录。
根目录以及各级子目录都有自己的FDT。
在具体操作中,系统规定用字母C~Z代表逻辑盘符,所以DOS简单地用“[盘符:]\”表示在根目录下。根目录的作用是分配根目录下的所有文件和子目录的存储空间(逻辑扇区号),并且通过设备驱动程序接口确定有效的最大目录项。
(1)根目录中的FDT
根目录的作用是分配根目录下的所有文件和子目录的存储空间(逻辑扇区号),并通过设备驱动程序接口确定有效的最大目录项。
根目录下的所有文件及其子目录在根目录的文件目录表(FDT)中都有一个“目录登记项”或简称为“目录项”。每个目录登记项占用32个字节,分为8个区域,提供有关文件或子目录的信息。其中包括了DOS的系统文件(IO.SYS、MSDOS.SYS和COMMAND.COM)的目录项。
常用软盘的根目录(FDT)所在逻辑扇区如下:
360KB:5~11扇区,共7个扇区。
1.2MB:15~28扇区,共14个扇区。
1.44MB:19~32扇区,共14个扇区。
在硬盘中,各逻辑盘的根目录FDT的起始逻辑扇区由分区容量确定。在FAT16中,其大小总是32(20H)个扇区。FAT32中的根目录FDT大小与其逻辑盘容量有关。
下面是用DEBUG读出1.44MB软盘逻辑13H扇区开始的14个扇区内容的例子:
C:>DEBUG
−L 00 0 13E
−D 00
0DE5:0000 49 4F 20 20 20 20 20 20-53 59 53 27 00 00 00 00 IO SYS'....
0DE5:0010 00 00 00 00 00 00C0 32-BF 1C 1D 00 46 9F 00 00......2...F.....
0DE5:0020 4D 53 44 4F 53 20 20 20-53 59 53 27 00 00 00 00MSDOS SYS'....
0DE5:0030 00 00 00 00 00 00C0 32-BF 1C 6D 00 FA 94 00 00.......2..m...
0DE5:0040 43 4F 4D 4D 41 4E 44 20-43 4F 4D 20 00 00 00 00COMMAND COM..
0DE5:0050 00 00 00 00 00 00C0 32-BF 1C B8 00 75D5 00 00.......2..u...
(2)FDT中的目录项
由于每个文件的目录登记项占用32个字节,用做目录的一个扇区(512字节)最多只能装入512/32=16个文件。因此,在常用磁盘的根目录下最多可建文件或子目录数如下:
360KB:共7个扇区,7×16=112个文件或子目录。
1.2MB:共14个扇区,14×16=224个文件或子目录。
1.44MB:共14个扇区,14×16=224个文件或子目录。
硬盘逻辑盘:共32个扇区,16×32=512个文件或子目录。
在FDT中,每个目录登记项占用32个字节,分为8个区域,提供有关文件或子目录的信息,包括DOS的系统文件IO.SYS、MSDOS.SYS的目录项。
在FAT16文件系统中,一个文件目录登记项32个字节中各字节的内容及含义列于表4-5中。
表4-5 FAT16文件目录项内容及含义
FAT16文件系统对每个文件来说其数据结构是一个单项簇链表,而文件在文件目录表FDT中占一个文件目录项,每个文件的首簇号就存放在该文件的目录项中,一个文件目录项占32个字节。对FDT中一个文件目录项的几个参数值作如下说明:
1)文件名
FAT16文件系统中,FDT的文件目录项中第0~7字节为文件名(若有剩余字节,则用空白符20H填充)。其中,第1字节又表明了该文件的状态,它有如下3种取值方式:
①00H目录项的空表目。
②E5H表示该目录项曾经使用过,但文件已被删除。
③2EH表示该项为子目录项。
其他任何字符表示一个文件名(或子目录名)的第一个字符的ASCII码值。
2)文件属性
第11字节为文件属性字节,按位规定如下:
3)文件创建(修改)时间
①(第22字节0~4位)以2秒为增量的二进制数。
②(23字节0~2位)+(22字节5~7位)为分钟。
③(第23字节3~7位)为小时。
4)文件创建(修改)日期
①(第24字节0~4位)为日期1~31。
②(25字节0位)+(24字节5~7位)为月份1~12。
③(第25字节1~7位)为年号0~119(1980~2099)。
5)文件首簇号
第26、27字节存放该文件的首簇号。系统根据FAT中该文件的单链表即可找到它的全部内容。
要注意区分文件目录表(FDT)和FDT中的目录登记项这两个概念。
目录登记项是一个32字节长的数据块,它记录了一个文件或子目录的相关信息。FDT是由若干目录登记项组成的一个表。根目录区是盘卷上的一个固定区域,根目录及各子目录都有各自的FDT。
6.子目录中的FDT簇链结构
在FAT文件系统中的目录结构是层次性的树形结构,根目录下可以包含文件和子目录,子目录下可以包含文件并且还可以再包含子目录。图4-13所示是一个树形目录结构的例子。
图4-13 FAT文件系统中的数形目录结构
在FDT中,子目录的管理与普通文件相同,一个子目录文件在FDT表中也占据32个字节的目录项。但是,子目录项中的文件长度总为零,尽管它的文件长度实际上不为零,它的意义在于不能使用不同的DOS读/写命令来读/写一个子目录文件。
(1)子目录FDT中的目录项
当前目录为子目录时,在使用DOS命令DIR列文件目录清单时,通常可以看到前两项特殊文件。
“·”表示当前目录。
“··”表示上一级目录。
这两项同其他子目录一样也没有长度。“·”项所报告的“首簇号”是子目录FDT第一个扇区所在的簇;“··”所报告的“首簇号”是上一级目录的开始簇号。如果上一级目录是根目录,则该簇号值被置成0。系统利用此结构来实现目录之间的双向联系。
只有当文件需要时,系统才给文件分配数据区空间。存放数据的空间是按每次一个簇的方式分配的。分配的时候,系统跳过已分配的簇,第一个遇到的空簇就是下一个将要分配的簇,此时系统并不考虑簇在磁盘上的物理位置。同时,文件已被删除后空出来的簇也可以分配给新的文件,这样做可使磁盘空间得到有效的利用。
数据区空间的使用是在文件分配表和文件目录表统一控制下完成的,每个文件所有的簇在文件分配表中都是链接在一起的。
需要注意的是:若使用DOS命令“MD”在磁盘上建立子目录SUB1,我们在FDT中可查到SUB1目录项的第0字节的值不是2E,而是“S”的ASCII码值53,如表4-6所示,且子目录SUB1中的所有文件不占根目录的FDT,而是按SUB1的首簇号2AH在相应的逻辑扇区中建立子目录SUB1自己的文件目录表FDT。这是因为DOS是将子目录作为一个普通文件的文件目录项来处理的。只是在第11字节的文件属性位设为10H,以表示为子目录项。在文件目录项中的第0字节为2EH,也仅是出现在子目录FDT中的第一、第二两个目录项中如表4-7所示。
假设一个FAT16结构逻辑硬盘根目录的文件目录表FDT的起始扇区为129(81H),共32(20H)个扇区。用DEBUG中的命令“L 100 2 81 20”读出硬盘逻辑81H扇区开始的20H个扇区,来查看硬盘根目录的FDT,可得到一个表4-6中的根目录文件目录表(FDT)。
表4-6 根目录文件目录表
从显示结果可以看出,SUB1表项的第11字节的值为10H,表明SUB1不是一个文件,而是一个子目录,其首簇号为第3簇。
在根目录下的文件或子目录在磁盘上的存储位置(逻辑扇区号)按以下公式计算:
逻辑扇区号=1+2×FAT的扇区数+根目录FDT+(首簇号-2)×每簇扇区数
所以,子目录SUB1的FDT存放的首扇区号应该是:
首扇区号=1+2×201扇区+32扇区+(3-2)×8扇区=443(1BBH)扇区
用DEBUG命令“−L 00 2 1BB 1”将第1BBH扇区的SUB1子目录FDT的1个扇区内容读入00开始的内容,然后用“−D 00”命令显示子目录SUB1的FDT部分内容如表4-7所示。
表4-7 子目录/SUB1下文件目录表
从表4-7中看出,两个特殊文件“·”和“··”的表项中,第0个字节都是2EH,第11个字节是10H。文件“·”表项的第26、27字节内容是0003H,第26、27字节的内容就是子目录SUB1的首簇号;文件“··”表项的第26、27字节内容是0000H,它表示其上级目录为根目录,内容不是0000H时表示其上级目录的首簇号;DLSD1.TXT和DLSD2.TXT是子目录SUB1中的文件。
(2)子目录下FDT表的扩充
根目录FDT表和子目录中的FDT表有两个最大的区别。
1)根目录FDT表的扇区数是固定不变的,所以根目录下能够存放的文件或子目录数量是有限制的,而子目录FDT表的扇区数是不固定的,因而其存放的文件或目录数量没有限制。
2)根目录FDT表的所有扇区在物理上是连续存放的,而子目录FDT表的所有扇区在物理上是不连续存放的,所以子目录FDT的扇区之间存在一种逻辑上的链接关系。
文件系统是将子目录作为一个普通文件的文件目录项来管理的。FDT中的一个扇区最多只能存放16个文件项,对于子目录FDT的首扇区来说,子目录下的两个特殊目录“·”和“··”要占该扇区的前64字节,也就是说该扇区只能存放(512-64)/8=14个文件的文件目录项。子目录FDT中不止可以存储14文件,下面就介绍超过14个文件的子目录的存放位置和操作系统的查找过程。
与普通文件在FAT中的簇号一样,子目录FDT的第一个扇区簇号及其扩展扇区的簇号在FAT中也会形成一个簇号链,并且也是以FF8H~FFFH或FFF8H~FFFFH作为最后一个FDT扇区的结束标志。
假设一个子目录的FDT共由3个扇区组成,在根目录FDT中查得该子目录的首簇号为a,再从FAT表中查得该子目录FDT扇区的簇链关系为“a→b→c”。如图4-14所示是其簇链示意图。
FAT表:
图4-14 FAT表中子目录FDT扇区的簇链关系为“a→b→c”的示意图
假如该子目录下有一个文件DLSD.txt,系统查找该文件的步骤如下:
1)在根目录FDT中查得子目录的目录项,从该目录项中得到该子目录的首簇号a,该簇所在的扇区即为子目录FDT的首扇区,并在该扇区中查找文件DLSD.txt。
2)如果没有找到,则在FAT表中从簇号a开始查得该子目录FDT的下一个扇区的簇号为b,然后再在该扇区中查找文件DLSD.txt。
3)如果在簇号b扇区中仍然没有找到,则在FAT表中从簇号b查得该子目录FDT的下一个扇区的簇号为c,然后再在该扇区中查找文件DLSD.txt。
4)如此继续,直到查到该文件的目录表项。
如果直到该子目录FDT簇链的最后一个扇区仍然没有找到该文件,就报告查找失败。
7.FAT文件系统的长文件名
根据前面的叙述我们知道,在FAT16文件系统中,由于FDT中的文件目录登记项只为文件名保留了8个字节,为扩展名保留了3个字节,所以DOS和Windows的用户为文件起名字时要受到8.3格式的限制。但是,从Windows95开始,这种限制被打破了。
在Windows9X中是如何实现长文件名、怎样解决与DOS的兼容性、方案存在什么问题、使用中应该注意的事项有哪些等一系列问题需要了解,这些问题将会对用户在Windows 9X中使用长文件名非常有益。
(1)文件名格式
FDT中文件目录登记项的内容及意义在前面已经有了详细的说明,图4-15所示是一个具有32个字节的8.3格式的文件目录登记项的示意图。
因为长文件名需要考虑Windows 9X与DOS 6.X和Windows 3.X的兼容问题,所以在Windows9X中实现的长文件名并不是对8.3格式的简单扩展,否则Windows9X中的长文件名就会在DOS 6.X和Windows3.X系统中无法读取。
图4-15 32字节的8.3文件名格式目录登记项示意图
(2)长文件名兼容的处理办法
除一些磁盘工具软件之外,大多数应用程序都不是直接访问磁盘,而是通过操作系统获得文件或目录名。此外,如果设置文件属性为0FH,DOS和Windows3.X就会忽略该目录的登记项。Windows9X正是基于这两点来解决长文件名与DOS和Windows3.X的兼容问题的。
在Windows9X中,文件或目录实际存储着两个名字,一个长文件名和一个长文件名的别名(短文件名)。其中,作为别名的短文件名存储在8.3格式的32字节的目录登记项中,长文件名则存储在属性标志为0FH的32字节目录登记项中,每个这样的目录登记项存储13个字符,每个文件名需要若干个这样的目录登记项,当需要的时候Windows9X会把它们重新组成长文件名。
当创建一个长文件名时,长文件名目录项和对应的别名(短文件名)目录项的存储有以下6个处理原则:
1)取长文件名的前6个字符加上“~1”形成长文件名的别名(即短文件名),并将长文件名中最后一部分(最后一个间隔符“.”后面字符)的前3个字符作为其扩展名。
2)如果已存在这个名字的文件,则符号“~”后的数字会自动增加。
3)任何包括小写字母的文件名都被看成是长文件名,而不管其长度是多少。如果有对于DOS和Windows3.X非法的字符,则用下划线替代。
4)长文件名存储在属性标志为0FH的32字节目录登记项中(这是与短文件名目录项的区别)。用Unicode格式编码,每个字符(无论是英文或是汉字)均占2字节。
5)每个目录登记项用26个字节存储13个字符(序号由第1字节指定)。位置多余时,先用00表示结束,再用FFH填充。
6)长文件名用若干个长文件名目录项保存,长文件名目录项倒序排在短文件名目录项前面。
采用上述的存储办法后,在Windows9X下创建的长文件名在DOS或Windows3.X下就只能看见其对应的短文件名,完全忽略了长文件名。在Windows9X下运行的应用程序通过操作系统请求文件名时,Windows9X会根据应用程序的性质分别给予不同的文件名,16位应用程序得到8.3格式的文件名,而32位应用程序得到长文件名。
表4-8所示是一些长文件名和对应的8.3格式短文件名的实例。
表4-8 长文件名及所对应的8.3格式短文件名实例
图4-16所示是长文件名使用的目录登记项的格式。其中长文件名使用Unicode格式,每个字符需要2个字节的空间,一个长文件名需要若干个这样的目录登记项。
图4-16 32字节的长文件名格式目录登记项示意图
目录登记项第一个字节的低5位指明它在文件名中的顺序号,例如第一个为1,第二个为2,以此类推。第一个字节的第六位是“1”就表明它是最后一个。
在Windows9X下即使创建一个少于8个字符的文件名,仍然会使用长文件名格式的目录登记项,因为长文件名是要区分大小写的。
(3)短文件名与长文件名目录项的链接关系
Windows9X采用多个连续的长文件名目录项来存储长文件名,这就形成了一个目录链,在这个目录链中,长文件名目录按照图4-17所示的方式存储。并且长文件名不能脱离短文件名目录项而单独存在,否则长文件名无效。
图4-17 长文件名目录项的链接关系
下面,我们详细地说明长文件名目录项与短文件名目录项是如何链接的。
1)若长文件名长度小于13个字符,则长文件名仅占用一个长文件名目录项,并且第一个字节为“A”(第6位是“1”),表明该目录项既是第一个又是最后一个。
例如文件名为“Forest.bmp”的长文件名目录项和对应的短文件名目录项为:
(长文件名目录项)
41 46 00 6F 00 72 00 65-00 73 000F 00 91 74 00AF.o.r.e.s....t.
2E 00 62 00 6D 00 70 00-00 00 00 00 FF FF FF FF..b.m.p........
(短文件名目录项)
46 4F 52 45 53 5420 20-42 4D 5020 00 00 00 00 FOREST BMP...
00 00CA 20 00 00 40 4E-88 1F 10 24 62 02 01 00.....@N...$b...
用D IR命令列表显示为:
FOREST BMP 66,146 12-08-95 9:50 Forest.bmp
2)若长文件名长度等于13个字符,则长文件名也仅占用一个长文件名目录项。并且第一个字节为“A”(第6位仍然是“1”),表明该目录项既是第一个又是最后一个。
3)若长文件名长度大于13个字符,则长文件名占用多个长文件名目录项。第一个目录项的序号为ASCII码01,第二项的序号为ASCII码02……最后一项的序号采用公式CHR(X−1+字母“A”的ASCII码)确定(一定是个英文字母)。其中X表示长文件名占用的目录项数,其计算方法如下:
①L=长文件名/13。
②若L是整数,则X=L;若L不是整数,则X=(取L的整数部分+1)。
例如文件名为“123456789abcdefghijk.txt”的长文件名目录项和对应的短文件名目录项为:
(长文件名目录项2)
42 65 00 66 00 67 00 68-00 69 000F 00 2A 6A 00 Be.f.g.h.i...*j.
6B 002E 00 74 00 78 00-7400 00 00 00 00 FF FF k...t.x.t.....
(长文件名目录项1)
01 31 00 32 00 33 00 34-00 35 000F 00 2A 36 00 .1.2.3.4.5...*6.
37 00 38 00 39 00 61 00-62 0000 00 63 00 64 00 7.8.9.a.b...c.d.
(短文件名目录项)
31 32 33 34 35 36 7E 31-54 58 5420 00 6C 69 60 123456~1TXT.li`
A6 2A A6 2A 00 00 50 60-A6 2A 02 00 9C 00 00 00 .*.*..P`.*....
用DIR命令列表显示为:
123456~1TXT 156 05-06-01 12:02 123456789abcdefghijk.txt
在查看长文件名的目录项的时候,应按照图4-16所示的说明,注意观察长文件名每个目录项中的第一个字节。例如,上述“(长文件名目录项2)”中的“42”,表示该项为第2项,且为最后一个目录项。
8.数据区
数据区(DATA)是真正意义上的数据存储空间,位于DIR区之后,占据硬盘上的大部分数据空间。为了实现文件一级的硬盘数据恢复,我们有必要关注一下FAT文件系统的目录和长文件名。
除了FAT16、FAT12的根目录之外,所有的目录实际上与文件一样,都是以簇链方式存储的。文件的实际大小记录在它所归属的目录结构里。但目录所占用的字节数却没有什么地方可以记录。目录总是被当做由多个簇组成来对待。当一个新条目(下级子目录或文件的产生)加入时,目录就要扩展,而且目录总是充满的。但FAT16、FAT12的根目录是例外,它们的大小是不能扩展的,在分区被格式化时就确定了。每个目录划分为小结构,称为目录项。每个目录项恰好32字节长,存储着目录所含文件或下级子目录的名称、属性、长度、日期、时间和起始簇号。
FAT文件系统在长文件名方面的扩展又称虚拟FAT(VFAT)。由虚拟FAT支持的长文件名存储在它的缩略文件名目录项之前的一个或几个目录项中。长文件名占用的目录项用旧版本的DOS工具软件是看不到的,因为它使用了在旧版本看来是非法的属性值。长文件名以Unicode格式存储。Unicode是ASCII码的16位变形,每个Unicode字符看起来就像是一个ASCII码字符后面再跟上一个空字节。每个长文件名目录项最多可以存放13个Unicode字符。如果长文件名比13字符还要长,就会有新的目录项加入到目录中来用于存放长文件名的其余部分。应该注意长文件名是逆序存放的,它的第一部分占用的目录项刚好在它的缩略文件名目录项之前。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。