解析NTFS底层结构

2008-10-17 08:42

一、NTFS系统结构
NTFS是Windows NT引入的新型文件系统,如果您是一位熟悉FAT磁盘格式的专业人士,您可能会觉得NTFS系统的思想蹩脚而晦涩,如果您对FAT格式一无所知,那么恭喜您,您会更快的了解这种更有效率的磁盘格式。
NTFS的结构复杂,内容繁多,笔者仅对NTFS卷上的底层结构做分析,并提供卷上数据删除的特征状态供大家参考。
现在,我们首先来建立了解NTFS需要的基本概念。
1.0基本结构及基本概念
在NTFS中,文件以簇的形式分配。最小的单位为扇区,N个扇区为一簇。其中,N的值可以通过BPB(引导扇区)读出(以下会详细介绍)。
1.0.1卷与簇

卷大小(分区大小) 每簇的扇区 缺省的簇大小
小于等于512MB 1 512字节
513MB~1024MB(1GB) 2 1024字节(1KB)
1025MB~2048MB(2GB) 4 2048字节(2KB)
大于等于2049MB 8 4KB
表1 卷与簇的关系
从上面可以看出,也就是说不管驱动器多大NTFS簇的大小不会超过4KB。
1.0.2 NTFS的基本数据结构
NTFS的数据大体上可分为4个部分
(1) Partition boot sector(引导扇区,又称BPB),此部分为所有磁盘格式都共有,占用一个扇区,但是具体的内容当然各不相同(见表3)。
(2) Master File Table(主文件列表,MFT),它是对卷上所有文件的记录,每一个文件对应一个记录项,理论上占用该卷12%的空间。
(3) System files(系统文件),NTFS系统一共有16个系统文件,和8个保留文件。
(4) File area(数据区),留给用户的空间。


Partition boot sector
引导扇区 Master File Table
主文件列表 System files
系统文件 File area
用户文件区(数据区)
表2 NTFS的磁盘分配情况
1.0.3 NTFS中关于目录的说明
NTFS中目录也是以文件的形式存在的。因此,每一个目录也可以看作一个文件。如果您熟悉FAT,那么此时您可能会觉得很别扭,因为在FAT中,文件是以目录-文件的树型结构联系起来的。但是,您必须相信的是,NTFS将会提供比搜索树更快的读写方式。
1.1 引导扇区

字节偏移 长度(字节) 常用值 意义
0X00 3 0XEB5290 JMP指令
0X03 4 NTFS 文件系统 ID
0X0B 2 0X0002 每扇区字节数
0X0D 1 0X08 每簇扇区数
0X0E 2 0X0000 保留扇区
0X10 3 0X000000 总为0
0X13 2 0X0000 NTFS未使用,为0
0X15 1 0XF8 介质描述
0X16 1 0X0000 总为0
0X18 2 0X3F00 每磁道扇区数
0X1A 2 0XFF00 磁头数
0X1C 4 0X3F000000 隐含扇区
0X20 4 0X00000000 NTFS未使用,为0
0X24 4 0X80008000 NTFS未使用,为0
0X28 8 0X4AF57F0000000000 扇区总数
0X30 8 0X0400000000000000 $MFT的逻辑簇号
0X38 8 0X54FF070000000000 $MFTMirr的逻辑簇号
0X40 4 0XF6000000 每MFT记录簇数
0X44 4 0X0100000 每索引簇数
0X48 8 0X14A51B74C91B741C 卷标
0X50 4 0X00000000 校验和
0X54 430 略 引导代码
0X1FE 2 0X55AA 签名
表3 NTFS引导扇区说明
1.2 MFT(主文件表)
MFT是一个对应的数据库,由一系列的文件记录组成。卷中每一个文件都有一个文件记录(对于大型文件还可能有多个记录与之相对应)。主文件表本身也有它自己的文件记录。如果您还不胜了解,那么我们来打个比喻。假设一个班有30个人,老师那里有一本花名册,记录了每个人的名字,年龄,每天出勤的情况和科目成绩等等。把每个人看做每一个文件,那么那本花名册就是这里的MFT。
当然,事实往往是复杂而多变的,MFT中包含文件的哪些信息?这些信息又是如何关联的?这些问题,我们会一个个解决。现在首先对MFT做几点必要的说明:
(1)实际上,MFT自身也是一个文件,因此,主文件列表的第一个记录就是它自身。所以,刚才的例子其实不太贴切,因为事实上,花名册也是人,那么好吧,我们假设这本花名册在老师的脑子里。这样,您可以知道,既然老师也是人,那么其实老师也是一个文件。
(2)MFT的每个记录都有一个编号,这里我们称它为ID号。这个ID从0开始。我们知道MFT自身是NTFS系统的第一个文件,所以文件$MFT的ID号为0。
(3)$MFT和其他23个文件一起(共24个),组成所谓的“Metafiles”(元文件,也是之前提到的System files,系统文件)。这24个文件中,前16(ID为0-15)个文件是固定的,剩下的8个文件为保留文件。我们可以假设,这16个系统文件为此班的任课老师,因为虽然他们也是人,但是属性跟普通的同学不一样,他们管理着整个卷的活动方式,正如老师们管理着整个班级一样。
(4)用户的文件(也包括目录)的MFT中的ID号从24开始排。
(5)用户每添加一个文件ID号加1,当某文件被删除时,与之对应的MFT记录将被空出来,如果此时再次添加文件,系统会优先填充ID小的空位。正如,大家上课的时候都会抢前排的位子坐,但是坐定之后就不能换位子了。
(6)无论簇的大小,文件记录大小都是1K,老师脑中的花名册对每个人都是公平的。
(7)理论上$MFT在卷中的分配空间(占12%)。
(8)逻辑上,$MFT在卷中会占用一块连续的空间,但实际情况$MFT可能会被分散在磁盘的几个不同的区域。甚至,可能在元文件的部分就被拆分开。据笔者分析,这些情况的发生可能由于卷上的文件不断增加,最先开辟的$MFT文件已经用完,系统会再次开辟空间存放文件记录。另一种情况是,卷是由FAT或者其他格式转化而来,当卷空间不足的时候,也可能将MFT分散存储。
1.2.1 MFT中的元文件(固定)
以下是元文件的列表。其中ID为0-15的文件为系统文件,用户文件从第24个MFT记录开始排。

序号(ID) 元文件 功能
0 $MFT 主文件列表本身
1 $MFTMirr 主文件表的部分镜像
2 $LogFile 日志文件
3 $Volume 卷文件
4 $AttrDef 属性定义列表
5 $Root 根目录
6 $Bitmap 位图文件
7 $Boot 引导文件
8 $BadClus 坏簇文件
9 $Secure 安全文件
10 $UpCase 大写文件
11-15 $Extend 扩展文件(一共5个文件)
16-23 保留
表4 NTFS元文件
1.2.2 NTFS中MFT的备份
在NTFS中,因其前16个文件的重要性,对它们的MFT记录在文件区有一个备份。如图:

图1 MFT的备份
1.2.3 NTFS中的$BITMAP(位图)文件
在元文件中,除了$MFT文件还有一个位图文件十分重要。文件$Bitmap标识的是该卷中簇的占用情况。它用一位代表一簇。为0代表此簇空闲,为1代表此簇已使用。这样可以更合理的分配磁盘空间。当文件被删除,它所占用的簇对应的为会被清空(置0)。NTFS通过这个文件管理卷的使用情况。



二、文件记录(MFT记录)详解
相信对NTFS您已经有一个大致的了解,但是对老师脑中的花名册是不是充满了好奇和期待呢?
简单的说,花名册清楚描述了班里每一个人的状况。描述的每一个项目在这里被叫做属性。
NTFS将文件作为属性、属性值的集合来处理。每个属性由单个的流(stream)组成,即简单的字符排列。严格的说,NTFS并不对文件进行操作,而只对属性流进行读写。
可以想想的是,花名册的大小有限(因为花名册是用来查询的),而文件的属性可能很大(对于那些调皮的学生,老师总要花费更多的心血),因此,当文件属性太大的时候,NTFS系统会将该属性值存放到卷中某个位置,而花名册中的属性只会记录该属性索引到外部的地址,以及索引区的大小。这种“装不下”的属性又被称为文件的属性又分为“非常驻属性”。与之相反,能够保存在“花名册”中的属性又叫做“常驻属性”。
2.1文件的存储
我想我已经清楚的向您展示了MFT的全貌,再来回顾一下,文件$MFT本身是一个文件(老师也是人),但是它亦是卷上每个文件的记录集合(花名册),每个文件拥有1K的空间(老师是公平的),用来记录文件属性,包括常驻属性和非常驻属性。
那么您现在是不是有老大一个问号,我一直在强调文件的记录,那么文件的真实数据是如何存放的呢?
想要知道这一点,就要请您耐心的看完下面对MFT属性的介绍。它将向您展示,这本花名册的精妙之处。
2.2 文件的MFT属性介绍
MFT的内容由不同的属性组合而成。以下是一个真实的MFT记录。现在,我们来剖析一下它的属性内容。
表5是这MFT记录的属性列表。对于每一个MFT记录来说,都会包含几种属性,但不可能包含所有的属性。老师当然根据学生不同的特点设计花名册的属性。


属性号 属性名 属性描述
0X10 $STANDRD_INFORMATION(标准属性) 包括基本文件属性,如只读、存档;时间标记,如文件的创建时间和最近一次修改的时间;有多少目录指向本文件
0X20 $ATTRIBUTE_LIST(属性列表) 当一个文件需要使用多个MFT文件记录时,用来表示该文件的属性列表
0X30 $FILE_NAME(文件名属性) 这是以Unicode字符表示的,由于MS-DOS不能正确识别Win32子系统创建的文件名,当Win32子系统创建一个文件名时,MTFS会自动生成一个备用的MS-DOS文件名,所以一个文件可以有多种文件名属性。
0X40 $VOLUME_VERSION(卷版本) 卷版本号
0X50 $SECURITY_DEscriptOR(安全描述符) 这是为了向后兼容而被保留的,主要用于保护文件以防止未授权访问。
0X60 $VOLUME_NAME(卷名) 卷名称或卷标识
0X70 $VOLUME_INFORMATION(卷信息) 卷信息
0X80 $DATA(数据属性) 这是文件的内容
0X90 $INDEX_ROOT(索引根属性) 索引根
0XA0 $INDEX_ALLOCATION(索引分配属性) 索引分配
0XB0 $BITMAP(位图属性) 位图
0XC0 $SYMBOLIC_LINK(符号链接) 符号链接
0XD0 $EA_INFORMATION(EA信息) 扩充属性信息:主要为与OS/2兼容
0XE0 $EA 扩充属性:主要为与OS/2兼容
0X100 $OBJECT_ID 对象ID:一个具有64个字节的标识符,其中最低的16个字节对卷来说是唯一的
表5 NTFS卷上常用属性说明

以下是一个实际的MFT记录,我们通过对它的分析向您展示MFT记录的属性。
46 49 4c 45 30 00 03 00 17 cd 13 1a 00 00 00 00 头属性
01 00 01 00 38 00 01 00 b0 01 00 00 00 04 00 00
00 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00
bb 02 00 00 00 00 00 00 10 00 00 00 60 00 00 00 标准头
00 00 18 00 00 00 00 00 48 00 00 00 18 00 00 00 属性
e0 e3 e1 a0 66 e9 c3 01 e0 e3 e1 a0 66 e9 c3 01
e0 e3 e1 a0 66 e9 c3 01 e0 e3 e1 a0 66 e9 c3 01
06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 30 00 00 00 68 00 00 00 文件名
00 00 18 00 00 00 03 00 4a 00 00 00 18 00 01 00 属性
05 00 00 00 00 00 05 00 e0 e3 e1 a0 66 e9 c3 01
e0 e3 e1 a0 66 e9 c3 01 e0 e3 e1 a0 66 e9 c3 01
e0 e3 e1 a0 66 e9 c3 01 00 40 00 00 00 00 00 00
00 40 00 00 00 00 00 00 06 00 00 00 00 00 00 00
04 03 24 00 4d 00 46 00 54 00 00 00 00 00 00 00
80 00 00 00 68 00 00 00 01 00 40 00 00 00 01 00 数据流
00 00 00 00 00 00 00 00 f1 1f 00 00 00 00 00 00 属性
40 00 00 00 00 00 00 00 00 20 ff 01 00 00 00 00
00 1c ff 01 00 00 00 00 00 1c ff 01 00 00 00 00
21 48 06 24 31 01 f3 aa 02 31 01 fd 7a 05 31 01
f3 38 02 31 01 c3 4b 05 00 a2 6b 81 d0 50 3d e1
b0 00 00 00 48 00 00 00 01 00 10 00 00 00 05 00 位图
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 属性
40 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00
00 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00
31 01 40 4b 0f 00 00 00 ff ff ff ff 00 00 00 00 结束标志



MFT记录中的每一个属性都用不同的颜色标识出来。第一个属性被称为属性头,此属性是每一个MFT的都有的(见表6)。接下来分别是标准头属性、文件名属性(见表7)、数据流属性(见表9)和位图属性。这些属性(不包括属性头)的的共性在于,它们的前8个字节(我称它为小头属性)的前4个字节为此属性的号(属性号与属性名称的对应见下表4),后4个字节,代表的是此属性的长度(字节数)。最后,MFT的结束标志为ff ff ff ff。

以下是几个重要的MFT属性介绍

(1)MFT文件记录属性头结构

偏移 长度 描述
0X00 4 固定值“FILE”
0X04 2 更新序列号偏移,与操作系统有关
0X06 2 固定列表大小
0X08 8 日志文件序列号
0X10 2 序列号(用于记录文件被反复使用的次数)
0X12 2 硬连接数,跟目录中的项目关联,非常重要的参数
0X14 2 第一个属性的偏移
0X16 2 标志字节①
0X18 4 文件记录实时大小(字节)②
0X1C 4 文件记录分配大小(字节)
0C20 8 基础记录 (0: itself)
0X28 2 下一个自由ID号
0X2A 2 边界
0X2C 4 WINDOWS XP中使用,本MFT记录号
0X30 4 MFT的使用标记③
表6 文件属性头说明

(2)文件名属性

偏移 大小 值 描述
0X00 4 0X30 属性类型
0X04 4 0X68 总长度
0X08 1 0X00 非常驻标志(0X00:常驻属性;0X01:非常驻属性)
0X09 1 0X00 属性名的名称长度
0X0A 2 0X18 属性名的名称偏移
0X0C 2 0X00 标志
0X0E 2 0X03 标识
0X10 4 0X4A 属性长度(L)
0X14 2 0X18 属性内容起始偏移
0X16 1 0X01 索引标志
0X17 1 0X00 填充
0X18 8 0500000000000500 父目录记录号(前6个字节)+序列号(与目录相关)
0X20 8 e0e3e1a066e9c301 文件创建时间
0X28 8 同上 文件修改时间
0X30 8 同上 最后一次MFT更新的时间
0X38 8 同上 最后一次访问时间
0X40 8 0040000000000000 文件分配大小
0X48 8 0040000000000000 文件实际大小
0X50 4 06000000 标志,如目录、压缩、隐藏等
0X54 4 00000000 用于EAS和重解析点
0X58 1 04 以字符计的文件名长度⑤,每字节占用字节数由下一字节命名空间确定,一个字节长度,所以文件名最大为255字节长(L)
0X59 1 03 文件名命名空间,见表8
0X60 2L 24004d004600 以Unicode方式标识的文件名
表7 文件名属性说明




标志 意义 描述
0 POSIX 这是最大的命名空间。它大小写敏感,并允许使用除NULL(0)和左斜框(/)以外的所有Unicode字符作为文件名,文件名最大长度为255个字符。有一些字符,如冒号(:),在NTFS下有效,但WINDOWS不让使用。
1 WIN32 WIN32和POSIX命名空间的一个子集,不区分大小写,可以使用除“*/:<>?/|”以外的所有Unicode字符。另外,文件不能以句点和空格结束。
2 DOS DOS是WIN32命名空间的一个子集,要求比空格的ASC||码要大,且不能使用* + / , : ; < > ? / | 等字符,另外其格式是1-8个字符的文件名,然后是句点分隔,然后是1-3个字符的扩展名。
3 Win32 & DOS 该命名空间要求文件名对Win32和DOS命名空间都有效,这样,文件名就可以在文件记录中只保存一个文件名
表8 常见命名空间

(3)数据流属性

偏移 大小 值 意义
0X00 4 0X80 属性类型(0X80,数据流属性)
0X04 4 0X48 属性长度(包括本头部的总大小)
0X08 1 0X01 非常驻标志(0X00:常驻属性;0X01:非常驻属性)
0X09 1 0X00 名称长度,$AttrDef中定义,所以名称长度为0
0X0A 2 0X0040 名称偏移
0X0C 2 0X00 标志,0X0001为压缩标志,0X4000为加密标志,0X8000为系数文件标志
0X0E 2 0X0001 标识
0X10 8 0X00 其实VCN
0X18 8 0X1FF1 结束VCN
0X20 2 0X40 数据运行的偏移
0X22 2 0X00 压缩引擎
0X24 4 0X00 填充
0X28 8 0X1FF2000 为属性值分配大小(按分配的簇的字节数计算)
0X30 8 0X1FF1C00 属性值实际大小
0X38 8 0X1FF1C00 属性压缩大小
0X40 … 2148062431… 数据运行④
表9 数据流属性说明
(4) 位图属性
位图属性在NTFS的属性中是一个很灵活的属性。当它位于不同的文件下有不同的含义。比如:例子中的MFT是文件$MFT自身的记录。这里的位图属性有特殊的含义。它在此处为非常驻属性,标志MFT文件的使用情况(类似$BITMAP的作用)。例子中31 01 40 4b 0f为数据运行,起始簇为0x0f4b40,占用一个簇。该簇中以每一位代表一个MFT记录的使用情况(占用为1,未使用为0)。实际操作中,可以根据文件的ID号查找与该文件的MFT对应的位。具体方法为,首先在$MFT的记录中读取0xB0属性运行,根据运行找到$MFT:bitmap位置。对于文件file,根据MFT记录的顺序记录文件file位于第几个,假设记录号为ID,ID/8=A, ID%8=B。表明该文件的MFT记录的位图位从$MFT:bitmap的首字节偏移A个字节,之后的第B个位。
2.3关于文件属性的说明
现在说明几点在数据恢复中很重要的几个属性标志(已用颜色标出)
① 第一处标志代表的是文件的状态:
1表示普通文件;
0表示文件被删除;
3表示普通目录;
2表示目录被删除。
当然,对于系统的文件可能有除此以外的标志符。

② 第二处为文件记录的实际大小。虽然每一个MFT记录都分配1K的空间,但实际使用的字节数并相同。因此,这里记录的是实际使用的字节数。

③ 第三处为MFT的使用标记,它在MFT记录的两个扇区中与每扇区的最末4个字节相对应,如若不然,系统将示此记录为非法记录。

④ 第四处为数据运行,是在数据流属性为非常驻的状况下索引到数据流的关键。其具体计算方式如下:
这是例子中的80H属性,其中蓝色部分为该80H属性(数据属性)的运行:
80 00 00 00 68 00 00 00 01 04 40 00 00 00 08 00
00 00 00 00 00 00 00 00 4b 00 00 00 00 00 00 00
48 00 00 00 00 00 00 00 00 c0 04 00 00 00 00 00
88 bc 04 00 00 00 00 00 88 bc 04 00 00 00 00 00
24 00 53 00 44 00 53 00 21 48 06 24 31 01 f3 aa
02 31 01 0d 7a fd 31 01 f3 38 02 31 01 c3 4b 05
00 a2 6b 81 d0 50 3d e1

该运行分为
子运行1:21 48 06 24
子运行2:31 01 f3 aa 02
子运行3:31 01 0d 7a fd
子运行4:31 01 f3 38 02
子运行5:31 01 c3 4b 05

以子运行1:“21 48 06 24”为例,“2”表示后面4个字节中后面2个字节是子运行的起始簇号,即子运行的起始簇号为“24 06”,“1”表示前面的1个字节表示子运行的大小,即该子运行的大小为“48”。所以该文件数据实际是从起始扇区号为0x2406的地方,占用0x48个簇。接下来是子运行2,运行2的簇号的起始位置为0x2406 + 0x02aaf3 = 0x2cef9。占用0x01个簇。接下来是子运行3,按照前面的理论,子运行3的起始簇号应该是0x2cef9+0xfd0a0d。但是0xfd0a0d的第一个字节为1(fd的首字节),证明此数为负数,所以不能简单的做加法,而应该取该数的补数来计算。既,0xfd7a0d取反加1,得到0x2F5F2,所以运行3的起始扇区号为0x2cef9 - 0x285f3 = 0x4096。占用0x01个簇。依此类推直到子运行之后为“00”时结束。
在程序中,一个Run代表整个运行,每一个子运行以链表的方式链接在一起。

⑤ 此处由一个字节标识文件名的长度,故NTFS磁盘格式下的文件名长度不能超过256个字节,但是文件名的存储格式是以Unicode的形式存储的,所以,文件名在磁盘中占用的真实字节数是该值的两倍。

除此以外,关于数据属性的还有几个方面需要说明
(1) 关于文件名属性。在MFT中,可能有多个文件名属性。这可能是因为文件的命名空间不同。例如:一个DOS命名空间下是8+3的短文件名格式。而WINDOWS下是Unicode的命名空间。
(2) 当数据运行中的簇号的首字节为“1”时,表明应用前次的簇数减去该簇号数,得到结果(此点在运行的例子中有详尽的说明)。
(3) NTFS使用逻辑簇号(LCN,Logical Cluster Number)和虚拟簇号(VCN,Virtual Cluster Number)来对簇进行定位。LCN是对整个卷中的所有的簇从头到尾进行简单编号。VCN是对属于特定文件的簇从头到尾进行编号,是逻辑编号。
(4) 文件$Bitmap标识的是硬盘空间里簇的占用情况。它用一位代表一簇。但是对于MFT记录的空间,因为硬盘是预先保留下来的,所以,它在文件$Bitmap已经将分配给MFT记录的所有簇都标识为已占用(这个大小一般是硬盘整个空间的12%),所以,它就不能充分表示有多少个记录项被使用。$MFT:bitmap作为文件属性恰好可以弥补这一缺点。事实上,NTFS的bitmap属性就是为了更方便更精确的计算磁盘的使用空间。



三 关于目录的文件
看到这个题目,您会不会和诧异?前面我苦口婆心的告诉您,在NTFS系统说,目录也是文件,目录以文件的形式存在,那么为什么这里又要专门用一节来讨论目录呢?
3.1 目录文件的属性
我还是举前面那个例子,对于一个班来说,虽然大家都是平等的,但是班级里面有小组长,小组长和组员一样,都是人,但是,所行使的职能不同。因此,目录虽然是文件,但是目录包含的属性不同。一般来说,目录包括头属性、标准属性(0X10)、文件名属性(0X30)、索引根属性(0X90),大多数时候还会包含索引分配属性(0XA0)。
对于真实的文档来说,它的内容是它其中的文字。那么对于目录来说,它的内容应该是什么呢?
相信您可以猜到,当然是目录中包含的保存在该目录下的所有文件的信息啦 (如果您了解FAT的格式,您对这一点将会深信不疑) 。事实当然应该如此,不然目录与文件如何联系呢?目录的数据区(与文件的数据区相似)中,保存在该目录下的每一个文件都有一个项目。这个项目我们把它称作索引项,因为目录通过它索引到文件。因此,与文件的数据属性一样,目录的“数据属性”有一个新的名字叫做“索引根属性”(0X90属性)。索引根属性包括两个方面的内容。一个是该属性的头,这里我把他叫做索引头。还有一个部分是索引部分。索引部分又包括“索引项”和“索引项尾”。以下是一个目录典型的MFT。


属性头
10属性头
10属性
30属性头
30属性
90属性头(索引头)
90属性 (索引项)
索引项1
索引项2
………
00 00 00 00 00 00 00 00 10 00 00 00 02 00 00 00 (索引尾)
FF FF FF FF 82 79 47 11
表10 小目录典型MFT记录

好了现在你可以阅读下表,详细了解0X90属性中的索引头和索引部分。

偏移 大小 意义
0X00 4 属性号
0X04 4 属性长度
0X08 1 常驻标志
0X09 1 名称长度
0X0A 2 名称偏移
0X0C 2 标志(常驻属性不能压缩)
0X0E 2 属性ID
0X10 4 属性长度(不含头)
0X14 2 属性偏移
0X16 1 索引标志
0X17 1 填充
0X18 8 属性名
0X20 4 索引属性类型
0X24 4 排序规则
0X28 4 索引项分配大小
0X2C 1 每索引记录的簇数
0X2D 3 填充
0X30 4 每索引的偏移
0X34 4 索引项的总大小
0X38 4 索引项的分配
0X3C 1 标志,(0X01大索引)
0X3C 3 填充
表11 索引根属性中索引头部分结构


偏移 大小 意义
0X00 8 文件的MFT记录号
0X08 2 索引项大小
0X0A 2 名称偏移
0X0C 4 索引标志+填充
0X10 8 父目录的MFT文件参考号
0X18 8 文件创建时间
0X20 8 文件修改时间
0X28 8 文件最后修改时间
0X30 8 文件最后访问时间
0X38 8 文件分配大小
0X40 8 文件实际大小
0X48 8 文件标志
0X50 1 文件名长度(F)
0X51 1 文件名命名空间
0X52 2F 文件名(填充到8字节)
0X52+2F P
0X52 +P+2F 8 子节点索引缓存的VCL
表12 索引项结构

索引根属性就是由索引头和这一个个的索引项组成。每个索引项对应一个文件。当文件被删除,索引项也会随之消失。
那么您还记不记得,索引根属性是在MFT记录里的。当索引项越来越多,1K的空间当然无法存储该属性的。那么这个时候,NTFS系统是如何处理的呢?
也许,您会想到,它可能和数据流的方法一样。通过数据运行索引到外部的数据区。如果您想到这一层,那么恭喜您,您已经开始熟悉NTFS系统。NTFS的确是这么做的。但是,与数据属性(0X80)有一点小小的区别。它并非简单的在0X90属性中添加一个运行。这是因为目录可能很大,而通过目录查找文件需要一个有效的算法。NTFS中,系统利用B+树的方法查找文件(这是一个较为复杂的问题,后面有详细介绍)。于是,当索引项太大,不能全部存储在MFT记录中时,就会有两个附加的属性出现:索引分配属性(0XA0),用于描述B+树目录的子节点;索引位图属性(0XB0),用于描述索引分配属性使用的虚拟簇号。我需要保存在MFT外部的索引称作“外部索引”。0XA0属性的结构与0X80属性完全一致。因此您可以参见表9。我们把这种有0XA0属性的目录称作大目录。大目录的MFT记录可能如下(在此只提出重要的属性,真实的MFT记录可能还包含别的属性)


属性头
0X10属性头
0X10属性
0X30属性头
0X30属性
0X90属性头(索引头)
0X90属性 (可能为空,也可能含有子项目。为1级节点)
注意:90H属性的最后8位是它的子节点VCN,可以根据该簇号和运行定位它的子节点。
0XA0属性头
0XA0属性
0XB0属性头
0XB0属性
FF FF FF FF 82 79 47 11
表12 大目录典型MFT记录



0XA0属性的运行记录了外部索引分配的空间。目录的外部索引是以一个索引块为单位分配的(与簇的概念类似)。一般来说,一个索引块占4K的空间。索引块以“INDEX”开头,其头部的固定结构如下:


偏移 大小 意义
0X00 4 INDEX
0X04 2 更新序列号的偏移
0X06 2 更新序列号与更新数组(以字节为单位)
0X08 8 日志文件序列号
0X10 8 本索引缓存在索引分配中的VCN
0X18 4 索引项的偏移(以字节为单位,相对0x18偏移到索引项)
0X1C 4 总的索引项的大小(相对0X18偏移到结尾)
0X20 4 索引项分配大小
0X24 1 如果不是叶节点,置1,表示还有子节点
0X25 3 用0填充
0X28 2 更新序列(重要:与每扇区最后2个字节的值一致)
0X2A 2S-1 更新序列数组
表13 索引区头部结构

索引块头部之后,连接的是索引目录项,其结构与前面介绍的索引项目是一致的。这里不重复介绍。
3.2 文件的查找方式
文件的索引延展到外部是分层次的。其层级结构图如下。
理论上说,3级目录可以容纳几千个文件。已经足够满足现在的需求。
简单的介绍一下目录的生成方式。目录一定是从小目录到大目录(因为文件需要一个个的拷贝)。小目录的结构很简单,前面也已经做了详细的分析。此时再不断增加文件,目录会有以下几个步骤的变化。
1、 一级大目录(仅有一个索引块)
索引块既是叶节点。它的VCL为0。一个索引块只能存放20-30个文件。索引块中的索引项,以文件名按照字母大小排列。
2、 二级大目录(有多个索引块)
当文件继续增加,一个索引块不能满足要求,此时再增加一个索引块,VCL为1,并在0X90属性中增加一个索引项目,为了描述,我把这个项目叫做基点。仍然对所有的项目按字母大小排序,其字母比基点小的排在VCL为0的索引块中,否则排在VCL为1的索引块中。当文件继续增加,会再次开辟一个VCL为2的索引块,工作方式同上。
3、三级大目录
二级目录有一个限制,那就是,每增加一个索引块,0X90属性就要增加一个项目。而0X90属性是在MFT中,其大小有限制,因此,不能无限的扩大二级目录。此时,系统很聪明地把一个外部的索引块当做基点。索引块的头部0X24的值置1,表示不是叶节点。

NTFS的目录结构是一个很复杂的部分,总的来说是利用平衡B+树的方式来安排每一个目录项的,但是,也不是标准的。您可以借助WINHEX进一步分析NTFS的目录结构。

四 总结
现在,相信您已经对NTFS磁盘格式有一个大致的了解了,您会发现,FAT格式的是如此之简陋和无效率。想象一下,对文件的查询,NTFS的目录结构(包含排序)将会节约多少时间!
这里只是简单介绍了NTFS的底层磁盘结构,WINDOWS还为它量身定做了磁盘的自修复等功能,有兴趣的朋友还可以研究。
以下是一个转载于硅谷动力的一张表,可以很清楚地看到NTFS的优势所在。FAT唯一的优势在于它的兼容性,因为它支持微软所有的操作系统。但是,NTFS的优越性不言而喻,如果在软件的行业里真的存在一统天下的传说,那么“但随着操作系统的顺利统一,应用环境的逐步迁移,NTFS将最终一统文件系统的天下。走过这个命运的交点,两条轨迹在不远处汇成一线……”


比较标准 NTFS5 NTFS FAT32 FAT16
适用操作系统 Windows 2000、XP Windows NT、2000、XP Windows 98、Me、2000、XP DOS、Windows所有版本
磁盘管理限制
最大分区尺寸 2TB 2TB 理论上2TB 2GB
分区中做多文件数目 接近无限 接近无限 接近无限 小于65000
最大文件尺寸 决定于文件存放分区的尺寸 决定于文件存放分区的尺寸 4GB 2GB
最大簇数 几乎无限 几乎无限 268435456 65535
最大文件名长度 255个英文字符 255个英文字符 255个英文字符 8.3文件名标准,VFAT中为255个英文字符
文件系统特征
Unicode(统一代码)文件命名 由Unicode字符设定 由Unicode字符设定 由系统字符设定 由系统字符设定
系统记录镜像 MFT镜像文件 MFT镜像文件 FAT文件表的第二拷贝 FAT文件表的第二拷贝
引导扇区位置 第一和最后的扇区 第一和最后的扇区 第一扇区 第一扇区
文件属性 标准属性加自定义属性 标准属性加自定义属性 标准属性设定 标准属性设定
交替数据流支持 支持 支持 不支持 不支持
数据压缩支持 支持 支持 不支持 不支持
数据加密支持 支持 不支持 不支持 不支持
对象标识支持 支持 支持 不支持 不支持
磁盘配额支持 支持 不支持 不支持 不支持
稀疏文件支持 支持 不支持 不支持 不支持
重装入点支持 支持 不支持 不支持 不支持
卷装入点支持 支持 不支持 不支持 不支持
性能概述
安全性构造 支持 支持 不支持 不支持
可恢复性 支持 支持 不支持 不支持
性能 在大分区上(>500MB)性能很高但在有非常多小文件的小分区上性能较低 在大分区上(>500MB)性能很高但在有非常多小文件的小分区上性能较低 在小分区上(<500MB)性能较低 在小分区上(<256MB)性能最高
磁盘空间节约 最大 最大 一般 在大分区上最低
磁盘数据容错性 最大 最大 最低 一般
表14 磁盘格式性能比较

你可能感兴趣的:(Win程序开发)