logo资料库

FAT32中文版.pdf

第1页 / 共24页
第2页 / 共24页
第3页 / 共24页
第4页 / 共24页
第5页 / 共24页
第6页 / 共24页
第7页 / 共24页
第8页 / 共24页
资料共24页,剩余部分请下载后查看
本文的一些约定
概述(适用于所有FAT类型)
启动扇区与BPB
FAT数据结构(FAT Data Structure)
FAT类型辨别(FAT Type Determination)
初始化FAT卷(FAT Volume Initialization)
FAT32 FSInfo扇区结构和备份启动扇区
FAT目录结构(FAT Directory Structure)
长目录项(FAT Long Directory Entries)
命名规则和字符设置(Name Limits and Character Sets)
长/短目录名的匹配(Name Matching In Short & Long Names)
文件名转换以及长文件名(Naming Conventions and Long Names)
长目录项在低版本FAT中的状况(Effect of Long Directory Entries on Down Lev
确认目录的内容(Validating The Contents of a Directory)
FAT目录应该注意的其他地方(Other Notes Relating to FAT Directories)
Microsoft® Hardware White Paper Designing Hardware for Microsoft® Operating Systems Microsoft Extensible Firmware Initiative FAT32 File System Specification FAT: General Overview of On-Disk Format Version 1.03, December 6, 2000 Microsoft Corporation 译注: 刚完成的项目内容涉及 FAT 文件系统,因此在查阅手册的同时把文档翻译了一下,希望能对那些和我 一样初次使用 FAT 的朋友有所帮助。因本人对 FAT 并不十分了解,翻译所做的也只是文字表面工作,出现 各种错误在所难免,因此:本文只适用于初学者作为了解材料,需要获得技术信息的朋友请查阅原版英文 资料! 发现错误的朋友请mail yuwh@amoi.com.cn指正,本人将不胜感激。 Microsoft Extensible Firmware Initiative FAT32 File System Specification IMPORTANT-READ CAREFULLY: …… 原文长 5 页,大意是告诫人们不要使用 D 版云云,此略。 本文的一些约定 以字符“0x”开头的数字为 16 进制,若开头没有字符“0x”则表明该数字为 10 进制。 本文的程序使用 C 语言书写,书写风格可能与教科书中严格定义的有所出入。 一些变量在程序中没有注明其数据类型是 16-bit 还是 32-bit,因为我们知道你有能力正确地完成这 些数据类型之间的转换,并保证在转换 32-bit 为 16-bit 的过程中不会造成数据丢失。同时请注意,所有 的数据类型均是无符号类型(UNSIGNED),不要尝试使用有符号整形(signed integer types)来进行 FAT 运算,否则一些 FAT 卷将会因此而出错。 概述(适用于所有 FAT 类型) 起先所有的 FAT 文件系统都是为 IBM PC 机器而设计的,这说明了一个重要的问题:FAT 文件系统在磁 盘上的数据是以“小端” (little-endian) 结构存储的。我们使用 4 个 8-bit 的字节 -- 起始字节为
byte[0],结束字节为 byte[3] -- 来存储一个 32-bit 的 FAT 项(FAT entry)。然后分别给这 32 位编号为 00-31,从下表我们可以清楚地看到这 32 位是如何排序的(最低位为 00). FAT: General Overview of On-Disk Format byte[3] 3 3 2 2 2 2 2 2 1 0 9 8 7 6 5 4 byte[0] 0 0 0 0 0 0 0 0 7 6 5 4 3 2 1 0 byte[2] 2 2 2 2 1 1 1 1 3 2 1 0 9 8 7 6 byte[1] 1 1 1 1 1 1 0 0 5 4 3 2 1 0 9 8 这对于那些使用“大端”(big-endian)存储结构的机器就显得尤为重要,因为在磁盘存取数据之前, 必须先完成 big-endian 和 little-endian 之间的转换。 每个 FAT 文件系统由 4 部分组成,这些基本区域按如下顺序排列: 0 – 保留区(Reserved Region) 1 – FAT 区(FAT Region) 2 – 根目录区(Root Directory Region, FAT32 卷没有此域) 3 – 文件和目录数据区(File and Directory Data Region) 启动扇区与 BPB BPB(BIOS Parameter Block)是 FAT 文件系统中第一个重要的数据结构,它位于该 FAT 卷的第一个扇区, 同时也属于 FAT 文件系统基本区域的保留区。这个扇区又叫做“启动扇区”、“保留扇区”、“0 扇区”,众多 的叫法都说明一个相同的问题:该扇区是 FAT 卷的第一个扇区。 这是 FAT 文件系统中第一个让人感到迷惑的地方,对于 MS-DOS 1.x 的版本,启动扇区中并没有 BPB 这 么一个东西,FAT 文件系统的最早期版本只有两种不同的格式:使用于单面或双面的 360K 5 寸软盘。这两 种格式是通过 FAT 的第一个字节(FAT[0]的低 8 位)来区分的。 在 MS-DOS 2.x 以后,启动扇区里增加了 BPB 用于区分磁盘介质,同时不再支持老的磁盘介质区分方式 (用 FAT 的第一个字节来区分),所有的 FAT 文件系统卷必须在启动扇区中包含 BPB。 这又是一个迷惑人的地方,BPB 具体是什么样的?在 MS-DOS 2.x 的定义中,每个 FAT 卷的扇区数不能 多于 65536(每个扇区 512 字节的话最多 32M),这一限定是由于定义“总扇区数”的变量本身是一个 16-bit 的数据类型。这一个限制在 MS-DOS 3.x 中有所改进,它使用一个 32-bit 的变量来存储“总扇区数”。 在 Win95 操作系统,确切的说应该是在 OSR2(OEM Service Release 2)出现的时候 BPB 的内容有了 新的变化,在这一版本中引入了新的 FAT 类型 —— FAT32。在 FAT16 中,由于 FAT 表的大小限制了有效的 簇数(cluster),同时也就限制了磁盘空间的大小,如果每个扇区为 512 字节的话,那么 FAT16 格式只能 支持到 2G。FAT32 的引入改变了这一状况,不再需要增加分区来管理大于 2G 的硬盘。 FAT32 的 BPB 内容和 FAT12/FAT16 的内容在 BPB_ToSet32 区域以前完全一致,而从偏移量 36 开始他们 的内容有所区别,具体内容要看 FAT 类型为 FAT12/FAT16 还是 FAT32(后面的内容会提到如何区分 FAT 格式) 这点保证了在启动扇区中包含一个完整的 FAT12/FAT16 或 FAT32 的 BPB 内容,这么做是为了达到最好的兼 容性,同时也为了保证所有的 FAT 文件系统驱动程序能正确地识别和驱动不同 FAT 格式,并让他们良好地 工作,因为他们包含了现有的全部内容。 NOTE: 在以下的描述中,凡名称与 BPB_开头的域都是 BPB 的一部分,凡名称与 BS_开头的项都是启动 第 2 页
扇区(boot sector)的一部分,而不是真正属于 BPB 内容。下面是 FAT 0 扇区的内容,BPB 也包含其中。 FAT: General Overview of On-Disk Format 启动扇区与 BPB 结构 名称 Offset (byte) 大小 (byte) BS_jmpBoot 0 3 描述 跳转指令。指向启动代码,允许以下两种形式: jmpBoot[0] = 0xEB, jmpBoot[1] = 0x??, jmpBoot[2] = 0x90 和 jmpBoot[0] = 0xE9, jmpBoot[1] = 0x??, jmpBoot[2] = 0x?? 0x??表示该字节可以为任意 8-bit 值,这是 Intel x86 架构 3 字节的无条件转移指令,跳转到操作系统的启动代码,这些 启动代码往往紧接 BPB 后面 0 扇区里的剩余字节,当然也 可能位于其他扇区。以上的两种形式任取。jmpBoot[0] = 0xEB 是较常用的一种格式 建议值为“MSWIN4.1” 此域经常引起人们的误解,其实这 只是一个字符串而已,Microsoft 的操作系统似乎并不关心 此域。但其他厂商的 FAT 驱动程序可能会检测此项,这就是 BS_OEMName 3 8 为什么建议将此域设为 “MSWIN4.1”的原因,这样可以尽 量避免兼容性的问题。你可以更改它的内容,但这有可能造 成某些 FAT 驱动程序无法识别该磁盘。很多情况下该域用于 显示格式化该 FAT 卷的操作系统的名称。 每扇区字节数,取值只能是以下的几种情况:512、1024、 2048 或是 4096,设置为 512 将取得最好的兼容性,目前有 很多的 FAT 代码都是硬性的规定每扇区字节数为 512,而不 是实际检测该此域的值,Microsoft 的操作系统能够很好地 BPB_BytsPerSec 11 2 支持 1024、2048 和 4096 各种数值。 NOTE: 请勿曲解此处“最好的兼容性”的意思,如果某些存 储介质的物体特性决定其值为 N,那么你就必须使用该数值 N,该 N 值一定是小于或是等于 4096。那么取得“最好的兼 容性”的办法就是使用该特定的 N 值。 每簇扇区数,其值必须是 2 的整数次方(该整数必须>=0), 如 1、2、4、8、16、32、64 或 128,同时还必须保证每簇 的 字 节 数 不 超 过 32K , 既 : 保 证 BPB_SecPerClus 13 1 (BPB_BytsPerSec * BPB_SecPerClus <= 32K (1024*32) BPB_RsvdSecCnt BPB_NumFATs 14 16 2 1 该值大于 32K 是绝对不允许的,虽然有些版本的操作系统支 持每簇字节数最大到 64K,但很多应用程序的安装程序都无 法在这样的 FAT 文件系统上正常运行。 保留区中保留扇区的数目,保留扇区从 FAT 卷的第一个扇区 开始,此域不能为 0,对于 FAT12 和 FAT16 必须为 1,FAT32 的 典 型 取 值 为 32, 目 前 很 多 FAT 程 序 都 是 硬 性 规 定 FAT12/FAT16 的保留扇区数为 1,而不对此域进行实际的检 测,Microsoft 的操作系统支持任何非零的值. 此卷中 FAT 表的份数。任何 FAT 格式此域都建议为2。虽 然此域取值为其他>=1 的数值也是合法的,但是很多 FAT 程序和部分操作系统对于此项不为2的时候将无法正常工 第 3 页
FAT: General Overview of On-Disk Format 作。当不为2时,Microsoft 的操作系统仍能良好的工作。 但仍然强烈建议此域为2。 选择此项的标准值为2的原因是为了提供一份 FAT 表的备 份,当其中一个 FAT 表所在的扇区被损坏时我们可以从备 份的 FAT 表中读取正确的数据。但是对于一些非磁盘介质 的存储器(如 FLASH 卡),这一特性变得毫无用处,如果想 使用 1 个 FAT 表来节省空间,那么带来的问题将是某些操 作系统无法识别该 FAT 卷。 对于 FAT12 和 FAT16 此域包含根目录中的目录项数(每个 项长度为 32 bytes),对于 FAT32,此项必须为 0。对于 FAT12 和 FAT16,此数值乘以 32 必须为 BPB_BytsPerSec 的偶数倍, 为了达到最好的兼容性,FAT12/FAT16 应该取值为 512. 早期版本中 16-bit 的总扇区数,这里的总扇区数包括 FAT 卷上四个基本区的全部扇区,此域可以为 0,若此域为 0, BPB_RootEntCnt 17 2 BPB_TotSec16 19 2 那么 BPB_TotSec32 必须非 0,对于 FAT32,此域必须为 0。 对于 FAT12/FAT16,此域填写总扇区数, 如果该数值小于 0x10000 的话,BPB_TotSec32 必须为 0。 对于“固定”(不可移动)存储介质而言,0xF8 是标准值, 对于可移动存储介质,经常使用的数值是 0xF0,此域合法的 取值可以取 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE 和 0xFF。另外要提醒的一点是,无论此域写入什么数 值,同时也必须在 FAT[0]的低字节写入相同的值,这是因 为早期的 MSDOS 1.x 使用该字节来判定是何种存储介质。 FAT12/FAT16 一个 FAT 表所占的扇区数,对于 FAT32 此域必 须为零,在 BPB_FATSz32 中有指定其 FAT 表的大小 每磁道扇区数,用于 BIOS 中断 0x13,此域只对于有“特殊 形状”(由磁头和柱面分割为若干磁道)的存储介质有效, 同时必须可以调用 BIOS 的 0x13 中断得到此数值 磁 头 数 , 用 于 BIOS 的 0x13 中 断 , 类 似 于 上 面 的 BPB_SecPerTrk,只有对特殊的介质才有效,此域包含一个至 少为 1 的数值,比如 1.4M 的软盘此域为 2 在此 FAT 分区之前所隐藏的扇区数,必须使得调用 BIOS 的 0x13 中断可以得到此数值,对于那些没有分区的存储介质, 此域必须为 0,具体使用什么值由操作系统决定。 该卷总扇区数(32-bit),这里的总扇区数包括 FAT 卷上四 个 基 本 区 的 全 部 扇 区 , 此 域 可 以 为 0, 若 此 域 为 0 , BPB_TotSec16 必须为非 0,对于 FAT32,此域一定是非 0。对 于 FAT12/FAT16,如果总扇区数大于或等于 0x10000 的话, 此域就是总扇区数,同时 BPB_TotSec16 的值为 0 1 2 2 2 4 4 21 22 24 26 28 32 BPB_Media BPB_FATSz16 BPB_SecPerTrk BPB_NumHeads BPB_HiddSec BPB_TotSec32 从 Offset 36 开始 FAT12/FAT16 的内容开始区别于 FAT32,现在分两个表格列出,下表为 FAT12/FAT16 的内容: 第 4 页
名称 BS_drvNum BS_Reserved1 (壹) BS_BootSig BS_VolID Offset (byte) 大小 (byte) 36 37 38 39 1 1 1 4 BS_VolLab 43 11 BS_FilSysType 54 8 下表为 FAT32 的内容: 名称 Offset (byte) 大小 (byte) BPB_FATSz32 36 4 BPB_ExtFlags 40 2 FAT: General Overview of On-Disk Format 描述 用于 BIOS 中断 0x13 得到磁盘驱动器参数,(0x00 为软盘, 0x80 为硬盘)。 NOTE:此域的值实际上由操作系统来决定 保留(供 NT 使用),格式化 FAT 卷时必须把此域设置为 0 扩展引导标记(0x29),用于指明此后的 3 个域可用 卷标序列号,此域以 BS_VolLab 一起可以用来检测磁盘是否 正确,FAT 文件系统可以用此判断连接的可移动磁盘是否正 确,此域往往是由时间和日期组成的一个 32 位值。 磁盘卷标,此域必须与根目录中 11 字节长的卷标一致。 NOTE: FAT 文件系统必须保证在根目录的卷标文件更改或 是创建的同时,此域的内容能得到及时的更新,当 FAT 卷没 有卷标时,此域的内容为“NO NANM ” 以下的几种之一:“ FAT12 ”、“FAT16 ”、“FAT32 ”. NOTE: 不少人错误的认为 FAT 文件系统的类型由此域来 确定,仔细点你就能发现此域并不是 BPB 的一部分,只是一 个字符串而已,Microsoft 的操作系统并不使用此域来确定 FAT 文件的类型,因为它常常被写错或是根本就不存在,后 面将讨论如何来检测一个 FAT 文件系统的类型,但不管如 何,建议您在此域填写正确的信息,因为一些非 Microsoft 的操作系统会检测此域。 描述 一个 FAT 表所占的扇区数,此域为 FAT32 特有,同时 BPB_FATSz16 必须为 0。 此域 FAT32 特有。 Bits 0-3:不小于 0 的活动 FAT(active FAT)数目,只有 在镜像(mirroring)禁止时才有效。 Bits 4-6: 保留。 Bits 7: -- 0 表示 FAT 实时镜像到所有的 FAT 表中。 -- 1 表示只有一个活动的 FAT 表,这个表就是 bits 0-3 所指定的那个。 Bits 8-15: 保留 此域 FAT32 特有。高位为 FAT32 的主版本号,底位为次版本 号,这个版本号是为了以后更高级 FAT 版本考虑,假设当前 BPB_FSVer 42 2 的操作系统所能支持的 FAT32 版本号为 0:0。那么该操作系 BPB_RootClus 44 4 统检测到此域不为 0 时,它便会忽略这个 FAT 卷,因为它的 版本号比系统能支持的版本要高。 此域 FAT32 特有。根目录所在第一个簇的簇号,通常该数值 为 2,但不是必须为 2。 NOTE: 磁盘工具在改变根目录的位置时,必须想办法让磁 盘上第一个非坏簇作为根目录的第一个簇(比如第 2 簇,除 第 5 页
FAT: General Overview of On-Disk Format 非它已经被标记为坏簇),这样的话,如果此域正好为 0 的 话磁盘检测工具也能轻松的找到根目录所在簇的位置。 此域 FAT32 特有。保留区中 FAT32 卷 FSINFO 结构所占的扇 区数,通常为 1。 NOTE: 在 Backup Boot 中会有一个 FSINFO 的备份,但该备 份只是更新其中的指针,也就是说无论是主引导记录还是备 份引导记录都是指向同一个 FSINFO 结构 此域 FAT32 特有。如果不为 0,表示在保留区中引导记录的 备份数据所占的扇区数,通常为 6。同时不建议使用 6 以外 的其他数值。 此域 FAT32 特有。用于以后 FAT 的扩展使用,对于 FAT32, 此域用 0 填充。 与 FAT12/FAT16 的定义相同,只不过两者位于启动扇区不同 位置而已。 与 FAT12/FAT16 的定义相同,只不过两者位于启动扇区不同 位置而已。 与 FAT12/FAT16 的定义相同,只不过两者位于启动扇区不同 位置而已。 与 FAT12/FAT16 的定义相同,只不过两者位于启动扇区不同 位置而已。 与 FAT12/FAT16 的定义相同,只不过两者位于启动扇区不同 位置而已。 通常设置为“FAT32 ”,请参照 FAT12/FAT16 部分关于此 域的陈述,该域的内容和 FAT 类型的判定无关。 2 2 12 1 1 1 4 11 8 BPB_FSInfo BPB_BkBootSec BPB_Reserved BS_DrvNum BS_Reserved1 BS_BootSig BS_VolID BS_FilSysType BS_FilSysType 48 50 52 64 65 66 67 71 82 关于 FAT 启动扇区还有一点重要的说明:我们假设里面的内容是按字节排序的,那么扇区[510]的内容 一定是 0x55,扇区[511]的内容一定是 0xAA。 NOTE: 很多 FAT 的资料文档会错误地把 0xAA55 说成是“启动扇区最后两字节的内容”,这样的陈述是 正确的如果 -- 仅仅是如果 -- BPB_BytsPerSec 的值为 512 的话。若是 BPB_BytsPerSec 的值大于 512, 该标记的位置并没有变(虽然在启动扇区的最后两个字节写上 0xAA55 完全没有问题)。 关于 BPB_TotSec16/32 这里再作一点补充:假设现在我们有一块磁盘或一个分区,它的扇区数为 DskSz, 如果 BPB_aTotSec(BPB_TotSec16 或是 BPB_TotSec32 其中不为 0 的那个)的值小于或等于DskSz 并不会使 该 FAT 卷在使用中出现什么错误,实际上,BPB_TotSec16/32 的值不要比 DskSz 小得离谱就不会有什么错 误。 这 样 做 将 造 成 磁 盘 空 间 的 浪 费 , 程 序 本 身 并 不 会 认 为 该 FAT 卷 存 在 什 么 错 误 。 但 是 , 如 果 BPB_TotSec16/32 的值比 DskSz 大的话将会使 FAT 卷遭到严重的损坏,因为它超出了存储介质或是磁盘分 区的边界。当 BPB_TotSec16/32 的值比 DskSz 大时,一些数据将不幸地被丢失。 FAT 数据结构(FAT Data Structure) 接下来一个重要的数据结构就是 FAT 表(File Allocation Table) ,它是一一对应于数据区簇号的列 表。 文件系统分配磁盘空间按簇来分配的。因此,文件占用磁盘空间时,基本单位不是字节而是簇,即使 某个文件只有一个字节,操作系统也会给他分配一个最小单元——即一个簇。为了可以将磁盘空间有序地 分 配 给 相 应 的 文 件 , 而 读 取 文 件 的 时 候 又 可 以 从 相 应 的 地 址 读 出 文 件 , 我 们 把 数 据 区 空 间 分 成 第 6 页
FAT: General Overview of On-Disk Format BPB_BytsPerSec * BPB_SecPerClus 字节长的簇来管理, FAT 表项的大小与 FAT 类型有关,FAT12 的 表项 为 12-bit,FAT16 为 16-bit,而 FAT32 则为 32-bit。对于大文件,需要分配多个簇。同一个文件的数据并 不一定完整地存放在磁盘中一个连续的区域内,而往往会分成若干段,像链子一样存放。这种存储方式称 为文件的链式存储。为了实现文件的链式存储,文件系统必须准确地记录哪些簇已经被文件占用,还必须 为每个已经占用的簇指明存储后继内容的下一个簇的簇号,对文件的最后一簇,则要指明本簇无后继簇。 这些都是由 FAT 表来保存的,FAT 表的对应表项中记录着它所代表的簇的有关信息:诸如是否空,是否是 坏簇,是否已经是某个文件的尾簇等。 以 FAT16 为例说明 FAT 区的结构如下: 表项 示例代码 描述 0 1 2 3 …… N N+1 …… FFF8 FFFF 0003 0004 …… FFFF 0000 …… 磁盘标识字,必须为 FFF8 第一簇已经被占用 0000h : 可用簇 0002h – FFFEFh: 已用簇,表项中存放文件下 个簇的簇号 FFFF0h - FFF6h : 保留簇 FFF7h : 坏簇 FFF8h – FFFFh : 文件的最后一簇 FAT 的项数与硬盘上的总簇数相关(因为每一个项要代表一个簇,簇越多当然需要的 FAT 表项越多), 每一项占用的字节数也与总簇数有关(因为其中需要存放簇号,簇号越大当然每项占用的字节数就大) 这里说一下 FAT 目录,其实它和普通的文件并没有什么不一样的地方,只是多了一个表示它是目录的 属性(attrib),另外就是目录所链接的内容是一个 32 字节的目录项(32-byte FAT directory entries 后面有具体讨论)。除此之外,目录和文件没什么区别。FAT 表是根据簇数和文件对应的。第一个存放数据 的簇是簇 2。 簇 2 的第一个扇区(磁盘的数据区)根据 BPB 来计算,首先我们计算根目录所占的扇区数: RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec; 因为 FAT32 的 BPB_RootEntCnt 为 0, 所以对于 FAT32 卷 RootDirSectors 的值也一定是 0。上式中的 32 是每个目录项所占的字节数。计算结果四舍五入。 数据区的起始地址,簇 2 的第一个扇区由下面公式计算: If(BPB_FATSz16 != 0) FATSz = BPB_FATSz16; Else FATSz = BPB_FATSz32; FirstDataSector = BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors; NOTE: 扇区号指的是针对卷中包含 BPB 的第一个扇区的偏移量(包含 BPB 的第一个扇区是扇区 0), 并不是必须直接和磁盘的扇区相对应。因为卷的扇区 0 并不一定就是磁盘的扇区 0。 给一个合法的簇号 N,该簇的第一个扇区号(针对 FAT 卷扇区 0 的偏移量)由下式计算: FirstSectorofCluster = ((N – 2) * BPB_SecPerClust) + FirstDataSector; NOTE: 因为 BPB_SecPerClus 总是 2 的整数次方(1,2,4,8,……)这意味这 BPB_SecPerClus 的 乘除法运算可以通过移位(SHIFT)来进行。在当前 Intel x86 架构 2 进制的机器上乘法(MULT)和除法 (DIV)的机器指令非常的繁杂和庞大,而使用移位来运算则会相对的快许多。 第 7 页
FAT: General Overview of On-Disk Format FAT 类型辨别(FAT Type Determination) 这是一个经常产生错误的地方,并且常常会出现诸如 “off by 1”, “off by 2”, “off by 10” 和 “massively off”的错误,事实上,FAT 类型的检测非常简单,FAT 的类型 ——FAT12,或是 FAT16 或 是 FAT32 —— 只能通过 FAT 卷中簇的数量来判定,没有其他办法。 请仔细阅读本段的每一个细节,每个词都很关键。比如“簇数(count of cluster)”并不是指“最大 可取得的簇的数量(maximum valid cluster number)”,因为数据区的第一个簇是簇 2 而不是 0 或 1。 首先我们讨论这个“簇数”是如何计算的,它完全根据 BPB 的内容来确定,我们先计算根目录所占的 扇区数(前面已经有叙述)。 RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec; FAT32 的 RootDirSectors 为 0。 接下来我们检测数据区中扇区数: If (BPB_FATSz16 != 0) FATSz = BPB_FATSz16; Else FATSz = BPB_FATSz32; If (BPB_TotSec16 != 0) TotSec = BPB_TotSec16; Else TotSec = BPB_TotSec32; DataSec = TotSec – (BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors); 计算簇数: CountofClusters = DataSec / BPB_SecPerClus; 请记住计算结果四舍五入。 现在我们就可以判定 FAT 的类型了,这部分请仔细阅读,否则会导致 off-by-one的错误 在下面的程序中, “<”和 “<=”是不一样的,另外请注意数字不要弄错。 If (CountofCluster < 4085) { /* FAT 类型是 FAT12 */ } Else if (CountofCluster < 65525) { /* FAT 类型是 FAT16 */ } Else { /* FAT 类型是 FAT32*/ } 这是检测 FAT 类型的唯一办法。世上不存在簇数大于 4084 的 FAT12 卷,也不存在簇数小于 4085 或是 大于 65524 的 FAT16 卷,同样没有哪个 FAT32 卷的簇数小于 65525。如果你坚持要违背这个规则来创建一 个 FAT 卷那么 Microsoft 的操作系统将无法对此卷进行操作,因为它不认为这是 FAT 文件系统。 NOTE: 如前面所说,目前有很多 FAT 的代码有一些错误,常常会出现 off by 1,2,8,10 或是 off by 16 的错误 。因此,为和现存的所有代码取得最好的兼容性,强烈建议在格式化 FAT 文件系统时,尽量 使簇数的取值不要接近 4085 或 65525,最好能和这分割点的值相差 16 或更多。 同时请注意这里的簇数(Count of Cluster)是指数据区所占簇的数量(the count of data clusters) 从簇 2 开始算起,而“最大可用的簇数”(Maximum valid cluster number for the volume)是簇数 + 1, “包括保留簇的簇数”(count of cluster including the two reserved cluster)则为 簇数 + 2。 第 8 页
分享到:
收藏