硬件白皮书
NTFS文件系统规范
关键字:Windows NT NTFS 文件系统
NTFS作为Microsoft Windows NT操作系统的标配文件系统克服了FAT/FAT32文件系统的大量缺点;同时又随着Microsoft Windows 2000、Microsoft Windows XP操作系统的推广得到越来越广泛的应用。
和FAT/FAT32文件系统相比,NTFS文件系统主要有以下优点。
支持大容量存储单元(最大支持 GB)
内建数据压缩支持
支持事务日志文件
加强数据安全
目录
基本数据类型
文件记录是$MFT文件的基本组成部分,卷中的所有文件都由至少一个文件记录来描述,对于使用多个文件记录的文件,其第一个文件记录叫基本文件记录,其余的叫做扩展文件记录。
文件记录由记录头 数个文件属性和结束标志(0xFFFFFFFF)组成。
文件记录头格式:
名字 | 偏移 | 尺寸 | 描述 | FR_Sign | 0 | 4 | 记录签名:,值为:‘ELIF’ | FR_USOff | 4 | 2 | 序列号的偏移(M) | FR_USNSz | 6 | 2 | 序列值个数+1(N) | FR_LSN | 8 | 8 | 日志文件序列号,该值在记录每次被修改时都会被改动 | FR_SN | 16 | 2 | 记录序列号 | FR_LnkCnt | 18 | 2 | 目录中记录本文件的引用计数,该值只用于基本文件记录 | FR_USAOff | 20 | 2 | 第一个属性数据的偏移 | FR_Flags | 22 | 2 | 标志,该成员可以是以下各值中之一 0x01 本记录已经被使用 0x02 本记录未使用 0x04 不明 0x08 不明 | FR_Size | 24 | 4 | 当前记录的尺寸 | FR_AllocSz | 28 | 4 | 当前记录分配的空间的尺寸 | FR_BaseFR | 32 | 8 | 当前文件记录的基本文件记录的索引, 如果当前文件记录是基本文件记录则该值为0,否则指向基本文件记录的记录索引。 注意:该值的低6字节是MFT记录号,高2字节是该MFT记录的序列号 | FR_NxtAttrId | 40 | 2 | 下一个属性的ID。 下一次将会被添加到文件记录的属性的ID,每次往文件记录中添加属性时该值都会增加,每次文件记录被重新使用时该值都会被清零,第一个值肯定是0 | FR_Resvd | 42 | 2 | 保留(XP新增) | FR_NumOfFR | 44 | 4 | 不明(XP新增) | FR_USN | M | 2 | 序列号。 该值记录文件记录被修改的次数,每次修改时该值+1,(包括文件被删除操作)该值不能为0 | FR_USA | M+2 | (N-1)*2 | 序列值占用的空间的原值 |
目录记录由标准头和存储目录键及目录数据的数据块组成,在$Boot文件中定义了目录记录的尺寸,这个值通常是4KB(到目录为止没有使用其他值)。
名字 | 偏移 | 尺寸 | 描述 | IR_Sign | 0 | 4 | 记录签名:,值为:‘XDNI’ | IR_USOff | 4 | 2 | 序列号的偏移(M) | IR_USNSz | 6 | 2 | 序列值个数+1(N) | IR_LSN | 8 | 8 | 日志文件序列号,该值在记录每次被修改时都会被改动 | IR_VCN | 16 | 8 | 当前目录记录在目录存储区中的虚拟簇号 | IR_EntryOff | 24 | 4 | 第一个目录项的偏移 | IR_EntrySz | 28 | 4 | 目录项的尺寸 | IR_AllocSz | 32 | 4 | 为目录项分配的空间的尺寸 | IR_Flags | 36 | 1 | 为1表示有子节点 | IR_Resvd | 37 | 3 | 保留 | IR_USN | 40 | 2 | 序列号 | IR_USA | 42 | 2 | 序列值占用的空间的原值 |
记录序列号
记录序列号是Microsoft公司为了确保记录数据的可靠性而在NTFS卷中提出的一项技术,在NTFS卷中,所有的记录类型数据(FR、IR)占用的空间都是按扇区尺寸(512字节)对齐。保护记录数据时,在每512字节的最末2个字节都会写入一个校验值以确保记录中的所有数据都被正确的写入磁盘中,而校验值所在位置的数据被拷贝到记录头之后被称作USA(Update Sequence Array)的数据块中,系统将记录数据从磁盘读入内存时将检查每个校验值是否与记录头的中序列号是否相同,如果相同则用USA中相应位置的数据恢复校验值位置的数据,反之则表明该记录被没有正确地修改。
在每次写记录数据时序列号都会加1,当序列号为0时则再加1。
虚拟簇号
非驻留数据中的每个簇都有一个特定的序号,这个序号就叫做虚拟簇号,虚拟簇号0指向数据流的第一个簇。
逻辑簇号
卷中的每一个簇都有一个特定的序号,这个序号就叫做虚拟簇号,虚拟簇号0指向卷中的第一个簇(引导扇区)。
数据流描述
存放在间隔的簇中的属性数据称为流。每一个流都由起始簇号和尺寸来描述。流的起始簇号是相对于前一个流的偏移,该值是一个有符号数。流描述的格式如下:
名字 | 偏移 | 尺寸 | 说明 | SD_Desc | 0 | 1 | 流描述说明,高4位(M)描述流描述偏移的字节数,低4位(N)描述流描述尺寸的字节数 | SD_Size | 1 | N | 当前流的尺寸 | SD_Off | N+1 | M | 当前流相对于上一个流的偏移,如果该值的最高位为1则表示该值是一个负数 |
一个流描述之后紧随着下一个流描述,如果下一个描述的SD_Desc为0则表示当前描述是最后一个。
一般情况下压缩文件和稀疏文件数据都以流的形式描述。
例1:通常情况
流描述:21 20 ED 5 22 48 7 48 22 21 28 C8 DB 0
流1: SD_Desc = 21 –偏移占2个字节,尺寸占1个字节。
SD_Size = 20 (1字节)
SD_Off = 5ED (2字节)
Offset = 5ED
Length= 20
流2: SD_Desc = 22 –偏移占2个字节,尺寸占2个字节。
SD_Size = 748 (2字节)
SD_Off = 2248 (2字节)
Offset = 2835 (2248+5ED)
Length=748
流3: SD_Desc = 21 –偏移占2个字节,尺寸占1个字节。
SD_Size = 28 (1字节)
SD_Off = DBC8 (2字节)
Offset = 3FD (2835+FFFFDBC8)
Length=28
流4: SD_Desc = 0。描述结束标志
小计:
0x20 个簇存放在簇号 0x5ED 开始处
0x748 个簇存放在簇号 0x2853 开始处
0x28 个簇存放在簇号 0x3FD 开始处
例2:压缩流
流描述:11 08 40 01 08 11 10 08 11 0C 10 01 04 00
流1: SD_Desc = 11 –偏移占1个字节,尺寸占1个字节。
SD_Size = 8 (1字节)
SD_Off = 40 (1字节)
Offset = 40
Length= 8
流2: SD_Desc = 01 –偏移占0个字节,尺寸占1个字节。
SD_Size = 8 (1字节)
SD_Off = -
Offset = -
Length= 8
流3: SD_Desc = 11 –偏移占1个字节,尺寸占1个字节。
SD_Size = 10 (1字节)
SD_Off = 8 (1字节)
Offset = 48 (40+8)
Length= 20
流4: SD_Desc = 11 –偏移占个字节,尺寸占1个字节。
SD_Size = C (1字节)
SD_Off = 10 (1字节)
Offset = 58(48+10)
Length= C
流5: SD_Desc = 01 –偏移占0个字节,尺寸占1个字节。
SD_Size = 4
SD_Off = -
Offset = -
Length= 4
流6: SD_Desc = 0。流描述结束标志。
小计:
0x08 个簇存放在簇号 0x40 开始处
0x08 个稀疏簇(未分配空间)
0x10 个簇存放在簇号 0x48 开始处
0x0C 个簇存放在簇号 0x58 开始处
0x04 个稀疏簇(未分配空间)
引导扇区与BPB
NTFS卷的第一个重要的数据区是BPB(BIOS Parameter Block),数据区位于卷中第一个个区域:$Boot文件的第一个扇区中。该扇区也叫做引导扇区。
引导扇区与BPB结构
名字 | 偏移 | 尺寸 | 描述 | BS_jmpBoot | 0 | 3 | 跳转到引导代码处。本域允许有以下两种格式: jmpBoot[0]=0xEB,jmpBoot[1]=0x??,jmpBoot[2]=0x90 或 jmpBoot[0]=0xE9,jmpBoot[1]=0x??,jmpBoot[2]=0x?? 0x??指这里可以是任意值,上述格式是跳转到代码的Intel x86无条件跳转指令,引导代码存放在卷中第一个扇区中BPB表的后面 | BS_OEMName | 3 | 8 | “NTFS ”本域是判别卷是否为NTFS卷的必要条件,NTFS卷中此域必须设置为上述值 | BPB_BytsPerSec | 11 | 2 | 每扇区字节数,该值仅可以从以下值中选取一个:512、1024、2048、1096。为了兼容以前的软件,建议使用512这个值 | BPB_SecPerClus | 13 | 1 | 每个分配单元扇区数,大于0而且必须是2的整数次幂,本值可以是1,2,4,8,16,32,64,128。注意本值必须保证使每簇字节数(BPB_BytsPerSec * BPB_SecPerClus)小于4K。 | BPB_RsvdSecCnt | 14 | 2 | 保留区域中保留的扇区数 | BPB_NumFATs | 16 | 1 | FAT表的个数,本域是为了保持与FAT/FAT32的BPB兼容而保留,其值固定为0 | BPB_RootEntCnt | 17 | 2 | 为保持兼容性而保留,值固定为0 | BPB_TotSec16 | 19 | 2 | 为保持兼容性而保留,值固定为0 | BPB_Media | 21 | 1 | 存储介质代码,对固定磁盘为0xF8,对于可移动介质,其值通常是0xF0,合法的值有0xF0,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF。 | BPB_FATSz16 | 22 | 2 | 为保持兼容性而保留,值固定为0 | BPB_SecPerTrk | 24 | 2 | Int 13H调用中的每磁道扇区,本值仅当存储介质按CHS方式寻址且能被Int 13H识别才有意义。 | BPB_NumHeads | 26 | 2 | Int 13H调用中的磁头数,其意义同前面的BPB_SecPerTrk。注意该值的基数是1。 | BPB_HiddenSec | 28 | 4 | 隐藏扇区数,分区每一个扇区相对于分区表的偏移扇区数。 | BPB_TotSec32 | 32 | 4 | 为保持兼容性而保留,值固定为0 | BS_DrvNum | 36 | 1 | Int 13H调用的磁盘号参数。 | BS_Reserved1 | 37 | 1 | 保留,值为0。 | BS_Reserved2 | 38 | 2 | 保留,值80H。 | BS_TotSec64 | 40 | 8 | 卷总扇区数。 | BS_1stClusOfMFT | 48 | 8 | $MFT文件第一个簇的簇号 | BS_1stClusOfMFTMirr | 56 | 8 | $MFTMirr文件第一个簇的簇号 | BS_ClusPerFR | 64 | 4 | 每个文件记录占用的簇数1 | BS_ClusPerDR | 68 | 4 | 每个目录记录点用的簇数1 | BS_Serial | 72 | 8 | 卷序列号 |
注1:每个记录占用的簇数如果为正值则表示该记录占用的簇数;如果为负值则表明记录尺寸小于簇尺寸,此时计算记录尺寸的方法应该是:记录的尺寸=2^(~每文件记录占用簇数)。
比如:BS_ClusPerFR=0xF6(-10),此时记录的尺寸是
BytsPerRecord=2^(~0xf6)
=2^10
=1024
系统文件
不同于FAT/FAT32分区固定的数据块布局,NTFS卷中所有的数据都以文件的方式保存,包括引导记录与目录等卷重要数据(在NTFS卷中重要数据块被称为系统文件),这样就允许将卷重要数据存放到卷中的任何地方(除了引导记录),并且对于所有重要数据都有一个标准的方法对其进行操作。这个特性使得任意改变卷尺寸十分方便(在卷位图文件后加上或减去增减的扇区信息就行了),而且也可以很容易地避免了FAT/FAT32卷中FAT表部分有物理损坏则卷中就会有很大部分空间使用的问题。
对应于重要数据的种类,NTFS分区共有12个系统文件,他们分别是:
名字 | 描述 | $MFT | Master File Tab 主文件表。该文件记录了卷中所有的文件(包括$MFT自己)的描述信息,通过$MFT文件可以访问卷中的所有信息。$MFT文件由多个文件记录(FRS)组成。每个文件的描述信息占用一个或多个文件记录。对于每一个文件,$MFT用一套被称为属性(Attributes)的记录来保存其信息。$MFT中前12个文件信息分别记录了12个系统文件的信息,从12-23号记录保留,从24号记录起记录其他文件的信息。 | $MFTMirr | Mirror of $MFT $MFT文件中前4个文件($MFT、$MFTMirr、$LogFile、$Volume)的描述的备份。本文件主要用于卷数据损坏时恢复卷。 | $LogFile | 卷事务的日志信息文件。 | $Volume | 卷基本信息,包括卷名,序列号等信息。 | $AttrDef | 属性定义,该文件定义了本卷中可用的属性类型。 | . (Root Directory) | NTFS卷的根目录。 | $Bitmap | 记录卷中所有分配单元的使用情况。本文件中每一个Bit数据对应一个簇。 | $Boot | 引导记录,通过本文件的代码系统才能从NTFS卷中启动。本文件是NTFS卷中唯一一个位置固定的文件,必须置于卷的第一个扇区处。 | $BadClus | 记录卷中坏簇的信息,本文件是稀疏文件,只包含坏簇的信息。 | $Secure | 记录卷中用到的安全描述符信息。 | $UpCase | 本记录Unicode编码下的所有字符的大写的代码,用于比较和排序文件名。 | $Extend | 本文件是一个目录,其中记录了卷中的对象的GUID及配额等信息。 |
属性
$MFT文件中的每个记录都是由属性组成。每个属性由相同的格式构成,首先是一个标准属性记录头,然后存放属性的专用数据。下面列出$AttrDef中定义的可用到的属性。
类型 | 操作系统 | 描述 | 0x10 | | STANDARD_INFORMATION | 0x20 | | ATTRIBUTE_LIST | 0x30 | | FILE_NAME | 0x40 | NT | VOLUME_VERSION | 0x40 | 2000 | OBJECT_ID | 0x50 | | SECURITY_DESCRIPTOR | 0x60 | | VOLUME_NAME | 0x70 | | VOLUME_INFORMATION | 0x80 | | DATA | 0x90 | | INDEX_ROOT | 0xA0 | | INDEX_ALLOCATION | 0xB0 | | BITMAP | 0xC0 | NT | SYMBOL_LINK | 0xC0 | 2000 | REPARSE_POINT | 0xD0 | | EA_INFORMATION | 0xE0 | | EA | 0xF0 | NT | PROPERTY_SET | 0x100 | 2000 | LOGGED_UNTILITY_STREAM |
标准属性记录头
每个MFT属性记录都有一个标准属性记录头,这个头记录了属性的类型、名字(可选)、有两种格式:
1. 驻留属性记录
名字 | 偏移 | 尺寸 | 说明 | ATTR_Type | 0 | 4 | 属性类型。该值必须是$AttrDef文件中定义的属性列表中的一项 | ATTR_Size | 4 | 4 | 记录尺寸(包括记录头) | ATTR_ResFlag | 8 | 1 | 属性数据驻留标志,值为0,驻留属性不能被压缩 | ATTR_NamSz | 9 | 1 | 属性名尺寸,该值为0时表示当前属性没有名字 | ATTR_NamOff | 10 | 2 | 属性名相对于属性头的偏移,该值总是固定为0x18 | ATTR_Flags | 12 | 2 | 属性标志,在当前的版本中只支持以下3个标志: 0x0001属性被压缩 0x4000属性被加密 0x8000稀疏属性 注意:只有非驻留的数据(Data)属性才能被压缩 | ATTR_Id | 14 | 2 | 属性ID,在MFT记录中的每个属性都有一个唯一的ID。 | ATTR_DatSz | 16 | 4 | 属性数据尺寸 | ATTR_DatOff | 20 | 2 | 属性数据相对于属性头的偏移 | ATTR_Indx | 22 | 1 | 属性索引标志 | ATTR_Resvd | 23 | 1 | 保留 | ATTR_AttrNam | 24 | 2*N | 属性名字Unicode字符串,这个字符串不用在结尾处加0 | ATTR_AttrDat | 24+2*N | | 属性数据,所以的数据都应该按双字对齐 |
2. 非驻留属性记录
名字 | 偏移 | 尺寸 | 说明 | ATTR_Type | 0 | 4 | 属性类型。该值必须是$AttrDef文件中定义的属性列表中的一项 | ATTR_Size | 4 | 4 | 记录尺寸(包括记录头) | ATTR_ResFlag | 8 | 1 | 属性数据驻留标志,值为0x01,驻留属性不能被压缩 | ATTR_NamSz | 9 | 1 | 属性名尺寸,该值为0时表示当前属性没有名字 | ATTR_NamOff | 10 | 2 | 属性名相对于属性头的偏移,该值总是固定为0x18 | ATTR_Flags | 12 | 2 | 属性标志,在当前的版本中只支持以下3个标志: 0x0001属性被压缩 0x4000属性被加密 0x8000稀疏属性 注意:只有非驻留的数据(Data)属性才能被压缩 | ATTR_Id | 14 | 2 | 属性ID,在MFT记录中的每个属性都有一个唯一的ID。 | ATTR_StartVCN | 16 | 8 | 本属性中数据流开始的簇号 | ATTR_EndVCN | 24 | 8 | 本属性中数据流最后一簇的簇号 | ATTR_DatOff | 32 | 2 | 数据流描述相对于属性头的偏移,数据应该按双字对齐 | ATTR_CmpSz | 34 | 2 | 压缩单元的尺寸。压缩单元的尺寸必须是2的整数次幂,为0表示未压缩 | ATTR_Resvd | 36 | 4 | 保留 | ATTR_AllocSz | 40 | 8 | 属性记录数据块分配的空间的尺寸,该尺寸按簇尺寸对齐 | ATTR_ValidSz | 48 | 8 | 属性记录数据块的实际尺寸 | ATTR_InitedSz | 56 | 8 | 属性记录数据块已经初始化数据的尺寸,到目前为止该值都与属性记录数据块分配的尺寸相同 | ATTR_AttrNam | 64 | 2*N | 属性名的UNICODE字符串,该字符串不以0结尾 | ATTR_DataRuns | 64+2*N | | 属性数据流描述 |
注意
1. 只有非驻留的数据(Data)属性才可以被压缩或是稀疏类型。
2. 只有驻留属性才有索引标志,是否表示只有驻留属性才能被索引?
STANDARD_INFORMATION
在老的NTFS版本中,STARDAND_INFORMATION属性只用于存放文件的时间和DOS文件属性信息。在Windows 2000中新引进了4个域来描述配额、安全、文件尺寸和日志信息。
属性描述如下表:
名字 | 偏移 | 尺寸 | 描述 | SI_Head | - | - | 标记记录头 | SI_CreatTime | 0 | 8 | 文件创建时间 | SI_AlterTime | 8 | 8 | 文件最后一次修改时间 | SI_MFTChgTime | 16 | 8 | 文件的MFT记录修改的时间 | SI_ReadTime | 24 | 8 | 最后一次访问的时间 | SI_DOSAttr | 32 | 4 | DOS文件属性,可以是以下各值的组合: 0x0001 只读 0x0002 隐藏 0x0004 系统 0x0020 归档 0x0040 设备 0x0080 常规 0x0100 临时文件 0x0200 稀疏文件 0x0400 重解析点 0x0800 压缩 0x1000 离线 0x2000 无内容索引 0x4000 加密 | SI_MaxVer | 36 | 4 | 文件可用的最大版本号,此值为0表示版本功能被禁止(目前未使用?) | SI_Ver | 40 | 4 | 文件版本号,如果最大版本号为0则值也必须为0 | SI_ClassId | 44 | 4 | 不明(目前未使用?) | SI_OwnerId | 48 | 8 | 文件拥有者的ID,本ID是$Quota文件中$O或$Q记录中的键,如果该值为0则表示配额设置被禁止 | SI_SecurityId | 52 | 8 | 安全ID,本值是$Securce文件中$SII索引及$SDS数据流的键 | SI_QuotaCharged | 56 | 8 | 该文件最大可使用的空间配额。如果该值为0则表示无配额限制 | SI_USN | 64 | 8 | 文件最后一次更新的记录号,该值是$UsnJrnl文件的直接索引,如果该值为0则表示更新日志被禁止 |
ATTRIBUTE_LIST
当MFT记录中的属性太多太长时,MFT记录就容纳不下这么多属性记录了,这时就只能将属性的数据以非驻留数据的形式存放到卷中的其他位置,如果这样还是存放不下,就必须用到属性表属性了。存放不下的属性会被转移到一个新分配的MFT记录中,然后在原MFT中加入一个属性表属性以描述如何搜索到当前文件的所有属性。
紧随标准属性头之后存放各属性的描述记录,记录了属性的位置和所在MFT记录,每个属性描述按4字对齐,记录了属性的类型、名字(有名属性)、序号。
属性表属性中不包括对自身的描述。
名字 | 偏移 | 尺寸 | 描述 | AL_Head | - | - | 标准记录头 | AL_RD_Type | 0 | 4 | 属性类型 | AL_RD_Len | 4 | 2 | 属性描述尺寸 | AL_RD_NamLen | 6 | 1 | 属性名尺寸,值为N | AL_RD_NamOff | 7 | 1 | 属性名相对于属性描述的偏移 | AL_RD_StartVCN | 8 | 8 | 本属性中数据流开始的簇号 | AL_RD_BaseFRS | 16 | 8 | 本属性记录所属的MFT记录的记录号。 注意:该值的低6字节是MFT记录号,高2字节是该MFT记录的序列号 | AL_RD_AttrId | 24 | 2 | 属性的ID | AL_RD_Name | 26 | 2*N | 属性名UNICODE字符串。该字符串不以0字符为结束标志 |
注:使用属性表属性通常因为以下情况:
1. 文件有太多的别名。
2. 碎片太多以至于数据流描述填满了MFT记录。
3. 有太复杂的安全描述(在NTFS 3.0以后的版本中不会再出现这种情况)。
4. 有太多的命令流,比如数据流。
FILE_NAME
本属性用于描述文件的名字,本属性总是驻留在MFT记录中。
在$AttrDef的定义中,本属性的最小尺寸是68字节,最大是578字节,因此最大文件名长度是255个字节。
名字 | 偏移 | 尺寸 | 描述 | FN_Head | - | - | 标准记录头 | FN_ParentFR | 0 | 8 | 父目录的MFT记录的记录索引。 注意:该值的低6字节是MFT记录号,高2字节是该MFT记录的序列号 | FN_CreatTime | 8 | 8 | 文件创建的时间 | FN_AlterTime | 16 | 8 | 文件最后一次被修改的时间 | FN_MFTChg | 24 | 8 | 文件的MFT记录被修改的时间 | FN_ReadTime | 32 | 8 | 最后一次访问文件的时间 | FN_AllocSz | 40 | 8 | 文件数据占用的空间尺寸,该值按簇尺寸对齐 | FN_ValidSz | 48 | 8 | 文件的真实尺寸,目录项中显示的文件尺寸就是该值。如果文件的数据属性中的开始簇号不为0则本项的值为空,此时需要查询文件尺寸的话必须访问SI属性 | FN_DOSAttr | 56 | 4 | DOS文件属性,可以是以下各值的组合: 0x0001 只读 0x0002 隐藏 0x0004 系统 0x0020 归档 0x0040 设备 0x0080 常规 0x0100 临时文件 0x0200 稀疏文件 0x0400 重解析点 0x0800 压缩 0x1000 离线 0x2000 无内容索引 0x4000 加密 | FN_EA_Reparse | 60 | 4 | 扩展属性与链接 | FN_NameSz | 64 | 1 | 文件名的字符数 | FN_NamSpace | 65 | 1 | 命名空间,该值可为以下值中的任意一个 0:POSIX 可以使用除NULL和分隔符“/”之外的所有UNICODE字符,最大可以使用255个字符。注意:“:”是合法字符,但Windows不允许使用。 1:Win32 Win32是POSIX的一个子集,不区分大小写,可以使用除““”、“*”、“?”、“:”、“/”、“<”、“>”、“/”、“|”之外的任意UNICODE字符,但名字不能以“.”或空格结尾。 2:DOS DOS命名空间是Win32的子集,只支持ASCII码大于空格的8BIT大写字符并且不支持以下字符““”、“*”、“?”、“:”、“/”、“<”、“>”、“/”、“|”、“+”、“,”、“;”、“=”;同时名字必须按以下格式命名:1~8个字符,然后是“.”,然后再是1~3个字符。 3:Win32&DOS 这个命名空间意味着Win32和DOS文件名都存放在同一个文件名属性中。 | FN_FileName | 66 | 2*L | 不需要以0作为结束字符 |
将POSIX或Win32文件名转换成DOS文件名要遵循以下步骤:
1. 去掉所有的UNICODE字符。
2. 去掉除最后一个以外的所有“.”,除非该符号在文件名的最前面。
3. 所有字符转换成大写。
4. 去掉所有禁止的字符。
5. 把“.”号前面的字符减少到6个,然后在后面加上“~1”。
6. 把“.”号后面的字符缩减为3个。
7. 如果文件名已经存在,则增加字符串“~1”的值。
VOLUME_VERSION
本属性只用于Microsoft Windows NT。
OBJECT_ID
对象ID属性是从Microsoft Windows 2000开始引入的新属性。每个MFT记录都有一个唯一的GUID。同样地,一个记录也包含了出生卷ID,原始对象ID和域ID,它们都拥有GUID。
该属性没有最小尺寸限制,但最大尺寸不得超过256个字节。
名字 | 偏移 | 尺寸 | 描述 | OID_Head | - | - | 标准记录头 | OID_ObjID | 0 | 16 | 文件的GUID | OID_BirthVolID | 16 | 16 | 文件建立时所在卷的ID | OID_BirthID | 32 | 16 | 文件的原始ID | OID_DomainID | 48 | 16 | 对象所创建时所在域的ID |
SECRUITY_DESCRIPTOR
VOLUME_NAME
该属性记录卷的名字。该属性最小2个字节,最大256个字节,因此卷标最大允许有127个字符。卷名的UNICODE字符串紧随标准记录头存放,卷名的长度由记录头中的ATTR_DatSz来指定。
卷序列号存放在$Boot文件中。
VOLUME_INFORMATION
该属性记录卷的基本信息,如版本号。
名字 | 偏移 | 尺寸 | 描述 | VI_Head | - | - | 标准文件头 | VI_Resvd | 0 | 8 | 保留,始终为0 | VI_MajVer | 8 | 1 | 卷主版本号 | VI_MinVer | 9 | 1 | 卷子版本号 | VI_Flags | 10 | 2 | 标志位,可以是以下各值组合 0x0001 脏位,当该值被设置时Windows将会在下次启动时运行chkdsk/F命令。 0x0002 日志文件改变尺寸 0x0004 卷挂接时升级 0x0008 由Windows NT 4挂接 0x0010 启动时删除USN 0x0020 修复过的ID 0x8000 被chkdsk修改过 |
操作系统格式化的卷对应的NTFS卷版本
操作系统 | NTFS版本 | Microsoft Windows NT | 1.2 | Microsoft Windows 2000 | 3.0 | Microsoft Windows XP | 3.1 |
DATA
该属性包含文件的数据,文件的尺寸就是记录中无名数据流的尺寸。该属性没有最大最小值限制。
对于驻留数据,数据紧接着记录头存放;对于非驻留数据,记录头后存放的是数据流的描述。
通常目录文件没有数据属性,文件的数据属性是没有名字的。文件必须有一个无名的数据属性。
注:NTFS有一个特性:允许在一个文件存放多个数据属性,这就使得用户可以轻松的实现HFS提供的那种将文件分为两部分(在HFS术语中被称为叉):一个资源块一个数据块。对于数据块可以使用缺省的无名数据属性,对于资源块可以使用一个命名数据属性,如:“resource”
INDEX_ROOT
该属性作为B+树的根节点以实现目录功能(比如目录文件)。该属性总是驻留。
名字 | 偏移 | 尺寸 | 描述 | 所属结构 | IR_Head | - | - | 标准属性头 | 目录根节点 | IR_AttrType | 0 | 4 | 属性的类型 | IR_ColRule | 4 | 4 | 整理规则 | IR_EntrySz | 8 | 4 | 目录分配项尺寸 | IR_ClusPerRec | 12 | 1 | 每个目录项占用的簇数 | IR_Resvd | 13 | 3 | 保留 | IH_EntryOff | 16 | 4 | 第一个目录项的偏移 | 目录头 | IH_TalSzOfEntries | 20 | 4 | 目录项的总尺寸 | IH_AllocSize | 24 | 4 | 目录项分配的尺寸 | IH_Flags | 28 | 1 | 标志位,此值可能是以下和值之一: 0x00 小目录(数据存放在根节点的数据区中) 0x01 大目录(需要目录项存储区和索引项位图) | IH_Resvd | 29 | 3 | 保留 | IE_FR | 32 | 8 | 目录项对应的文件的记录索引。 注意:该值的低6字节是MFT记录号,高2字节是该MFT记录的序列号 | 目录项 如果当前属性驻留则目录项直接存放在当前属性的数据区中,否则会放到目录存储区属性中 | IE_Size | 40 | 2 | 整个当前目录项的尺寸(L) | IE_DataSize | 42 | 2 | 目录项数据尺寸(M) | IE_Flags | 44 | 1 | 标志。该值可能是以下值之一: 0x00 普通文件项 0x01 有子项 0x02 当前项是最后一个目录项 在读取索引项数据时应该首先检查该成员的值以确定当前项的类型 | IE_Stream | 45 | M | 目录项数据,结构与文件名属性的数据相同 | IE_SubNodeFR | 45+M | L-8 | 子项的记录索引。 注意:该值的低6字节是MFT记录号,高2字节是该MFT记录的序列号 |
INDEX_ALLOCATION
该属性是索引数据(比如磁盘目录)的基本组成部分,用于存放B+树的子节点和实现索引数据。对于该属性如果是驻留属性,则目录项数据直接存放在属性的数据区中;如果属性是非驻留,则属性的数据流描述指向一个索引记录。
BITMAP
该属性记录了一组BIT序列,每个位描述一个单元的使用情况。
该属性主要用于两种情况:索引(比如目录)和$MFT文件中。
在用于索引时,每个位表示一个索引项是否被使用。每个位描述一个虚拟簇号(VCN)。
在用于$MFT文件时,每个位记录一个文件记录是否使用。
位序列表紧随标准记录头存放。
SYMBOL_LINK
本属性只用于Microsoft Windows NT。
REPARSE_POINT
该属性描述对象的解析信息,该属性最大尺寸是16384字节。
名字 | 偏移 | 尺寸 | 描述 | RP_Head | - | - | 标准记录头 | RP_Type | 0 | 4 | 重解析数据类型,该值可以是以下值之一 0x20000000 别名 0x40000000 最高等待时间 0x80000000 微软使用 0x68000005 NSS 0x68000006 NSS恢复 0x68000007 SIS 0x68000008 DFS 0x88000003 卷挂接点 0xA8000004 HSM 0xE8000000 硬连接 | RP_DatSz | 4 | 2 | 重解析数据尺寸 | RP_Resvd | 6 | 2 | 保留 | RP_Data | 8 | L | 重解析数据 |
EA_INFORMATION
该属性用于实现为OS/2子系统或Windows NT服务器的OS/2客户提供基于NTFS的HPFS扩展属性。因为数据流可能会增大,所以该属性可以是非驻留的。
名字 | 偏移 | 尺寸 | 描述 | EI_Head | - | - | 标准记录头 | EI_PackedSz | 0 | 2 | 压缩扩展属性尺寸 | EI_NumOfEA | 0 | 2 | 拥有NEED_EA记录的扩展属性个数 | EI_UnpackedSz | 4 | 4 | 未压缩扩展属性尺寸 |
EA
该属性用于在NTFS卷上实现HPFS的扩展属性。因为数据流可能会增大,所以该属性可以是非驻留的。该属性的最大尺寸是65536字节。
该属性保存HPFS卷所需的名字-参数对。
名字 | 偏移 | 尺寸 | 描述 | EA_Head | - | - | 标准记录头 | EA_Next | 0 | 4 | 下一个扩展属性的偏移(本记录的尺寸) | EA_Flags | 4 | 1 | 标志位,值取0x80表示需要EA | EA_NamLen | 5 | 1 | 名字数据的长度(M) | EA_ValLen | 6 | 2 | 值数据的长度 | EA_Name | 8 | M | 名字数据 | EA_Value | 8+M | N | 值数据 |
EA名字不使用UNICODE字符。关于该属性的特性,参考一下HPFS的规范会很有帮助。
PROPERTY_SET
本属性只用于Microsoft Windows NT。
LOGGED_UNTILITY_STREAM
该属性记录日志操作的元数据。
$MFTMirr
该文件是$MFT文件的备份,存放了$MFT中前4个文件的文件记录。该文件的作用就是当$MFT文件被损坏时恢复卷中的数据。
$Bitmap
该文件记录了卷中所有逻辑簇的使用情况。文件中每个BIT表示一个逻辑簇。在每个字节中,逻辑簇号按从小到大的顺序排列,如:BIT0对应逻辑簇号A,则BIT1对应逻辑簇号A+1。
$BadClus
该文件记录了卷中的坏簇的信息。该文件是一个稀疏文件,只记录有坏簇的描述。该文件拥有两个数据属性,第一个数据属性无名且是空属性,第二个数据属性名为:“$Bad”,该属性记录了卷中的坏簇的VCN,该属性中的数据分配的空间是整个卷的尺寸,数据占用的实际空间也是卷的尺寸,已初始化数据尺寸为0。在属性的数据流描述中非稀疏的描述就是坏簇的VCN。
坏簇在$Bitmap文件中相应的位总是被标记为已使用。
NTFS卷初始化
NTFS卷初始化时系统首先检查引导扇区中的卷类型签名,如果签名不是“NTFS ”则认为该卷不是NTFS卷。然后读取引导扇区中的卷BPB数据确定卷布局,然后读取$MFT文件自己的文件记录,按记录中描述读取$Bitmap、$Root文件用于分配/释放簇及目录树访问。
分区结尾与备份主引导扇区
在NTFS卷,$Boot文件中的卷尺寸(BS_TotSec64)的值至少比分区表中的分区尺寸少一个扇区。这个扇区用来存放$Boot文件第一个扇区的副本,这个扇区一定位于NTFS卷的最后一个扇区的下一个扇区的位置。如果NTFS卷的头部数据被破坏可以通过这个扇区来恢复。
目录结构
在NTFS卷中,文件在目录中以B+树的形式排列,在目录中查找文件时按B+树的搜索方法先搜索根节点,然后按要找的文件名与根节点中的子节点对应的文件名相比较以确定在哪个子节点对应的存储区中搜索,然后以子节点为当前的根节点再搜索,直到找到文件为止。 |