复合文档格式(四) - 主扇区分配表和扇区分配表

xiaoxiao2021-02-28  60

一. 概述

上一篇介绍了复合文档头Compound Document Header:http://write.blog.csdn.net/postedit/76737002接下来介绍一下主扇区分配表MSAT和扇区分配表SAT

二.主扇区分配表 - MSAT

1.主扇区分配表 -  Master Sector Allocation Table ,简称MSAT,扇区分配表 -  Sector Allocation Table ,简称SAT 主扇区分配表(MSAT)是由扇区分配表(SAT)使用的所有的扇区(sector)的一个SecID数组,即MSAT数组中存储的是SAT占据的扇区的SecID主扇区分配表(MSAT)的大小(即存储SecID数组的长度)等于扇区分配表(SAT)占据的扇区数,该值存储在复合文档头中,详情看上一篇:http://blog.csdn.net/lipinganq/article/details/76737002由于SAT占据的扇区是不成链的,所以SAT所使用的扇区的SecID都存储在MSAT中 主扇区分配表(MSAT)的前109个SecID在复合文档头中直接存储,该SecID对应的扇区就是被SAT使用的扇区,但是当SAT所使用的扇区个数超过109个,则需要额外的扇区存储超过的扇区的SecID,在复合文档头部中存储了添加的额外扇区中的第一个扇区的SecID鲁国平SAT所使用的扇区数没有超过109,就没有添加额外的扇区,则复合文档头部中存储的添加的额外扇区中的第一个扇区的SecID值为-2,表示一个特殊的End Of Chain SecID MSAT所使用的扇区是成链的,所以MSAT中添加的额外扇区的MSAT由复合文档头中和添加额外扇区中的最后4个字节就是下一个额外扇区的SecID,最后一个额外扇区的最后4字节为-2,表示一个特殊的End Of Chain SecID 2.MSAT中一个扇区的内容 MSAT是一个SecID数组,每个SecID为32位整数,指向一个SAT占据的扇区,扇区的最后4个字节就是下一个扇区的SecIDsec_size 表示一个扇区的大小,单位为字节则一个扇区最多可以存储(sec_size-4)/4个SecID

三.一个主扇区分配表实例

2.1 假设一个复合文档文件包含一个扇区分配表SAT,该SAT需要300个扇区去存储 假设头中指定一个扇区的大小为512字节,因为每个SecID是32位整数,占4字节,则意味着每个扇区可以存储128个SecID由于SAT需要300个扇区存储,所以主扇区分配表MSAT由300个SrcID组成,该SecID对应的扇区就是SAT占据的扇区,由于在复合文档头中存储了109个SecID,这意味着其余191个SecID需要2个额外的扇区来存储MSAT的最后一个额外扇区可能没有使用完,未使用的空间用-1填充,表示一个特殊的 Free SecID在本例中,头中指定了MSAT所使用的2个额外扇区中第一个扇区的SecID是1,即扇区1,扇区1中包含了余下191个SecID中的127个,扇区1中第128个SecID就是MSATd的第二个额外扇区的SecID,MSAT的第二个额外扇区中包含剩下的64个SecID,剩下的空间用-1填充

四.扇区分配表 - SAT

1.扇区分配表 -  Sector Allocation Table ,简称SAT 2.扇区分配表(SAT)是一个SecID数组,它包含所有用户流streams(短流short-streams除外)和其余内部控制流(short-stream container stream、shortsector allocation table、directory)的SecID链。扇区分配表SAT的大小(即存储SecID数组的长度)等于复合文档中现有扇区Sector的数量 3.扇区分配表SAT是一个数组,数组元素是一个32位的整数,它与主扇区分配表MSAT是截然不同的 扇区分配表SAT是按照数组下标(或数组索引)来对应扇区的,如扇区分配表SAT的下标0(或索引0),对应扇区SecID为0,下标1对应扇区SecID为1。。。扇区分配表SAT数组下标处的数组元素对应的是下一个扇区的SecID,如下标0处的值为2,则流中紧接着下一个扇区SecID是2,同时在下标2中又存储了下下一个扇区的SecID。。。这样就形成了一个SecID链(SecID Chain),将相关的扇区串联起来,形成一个完整的"流"。SecID链在数组值为-2的位置结束

4.1 构建扇区分配表 - Sector Allocation Table

3.1.1. 扇区分配表SAT是通过read并连接在主扇区分配表MSAT中给出的所有扇区sector的内容构建的。 这些扇区sector必须根据在MSAT中的SecID的顺序进行读取。 3.1.2. 扇区分配表SAT中一个扇区sector的内容如图: 扇区分配表SAT是一个SecID数组,数组元素是一个32位的整数,表示一个扇区的SecID,所以每个数组元素占据2个字节SAT可能由多个扇区构建而成sec_size 是一个扇区sector的大小,单位为字节,则一个扇区中SecID的个数为sec_size /4

4.2 使用扇区分配表 - Sector Allocation Table

4.2.1  SecID链的入口必须在其他地方获得 SecID链的入口获得了,就可以构造整个SecID链了 例如:从用户流的目录条目;从内部控制流(如短扇区分配表short-sector allocation table)的头;从目录流(directory stream )本身 4.2.2 构造SecID链 - SecID Chain 当为一个特殊流构建一个SecID链,扇区分配表SAT中的当前位置(即数组索引)就是当前扇区sector的SecID,即数组索引就是当前扇区的SecID当前数组索引处的值就是SecID链中下一个扇区的SecID 4.2.3  特殊扇区 扇区分配表SAT可能在任意位置包含特殊的Free SID(对应的值为-1),这些扇区不被流所使用如果该位置包含特殊的End Of Chain SecID (对应的值为-2),表示一个流的最后一个扇区 扇区分配表SAT自身使用的扇区sector是没有链(chain)的,但是用特殊的SAT SecID (对应的值为-3)标记 主扇区分配表MSAT自身使用的扇区sector使用特殊的MSAT SecID(对应的值为-4)标记

五.一个扇区分配表的实例

4.1 假设复合文档中包含一个扇区,它是一个扇区分配表SAT(扇区sector 1)和两个流所需的 4.2 扇区Sector 1包含上图扇区分配表SAT显示出的SecID数组,在数组索引1处的值为-3,-3是一个特殊的 SAT SecID ,标记这个扇区是一个扇区分配表SAT的一部分 4.3 第一个流 如果一个流是内部目录流( internal directory stream),假设在复合文档头部中指定从扇区sector 0开始,即从SAT中下标0处开始从图中看出SAT下标0处的值为2,表示紧接着的下一个扇区是sector 2,下标2处的值为3,表示下一个扇区是sector 3,下标3处的值为-2,表示流完了从上面知道该目录流的SecID链是[0, 2, 3, –2] ,该目录流存储在3个扇区中 4.4 第二个流 假设该内部目录流( internal directory stream)包含一个用户流的条目,从扇区sector 10开始该用户流的SecID链是[10,6,7,8,9,-2]

六.实例

6.1 复合文档头中的第68 - 71的4个字节表示主扇区分配表Master Sector Allocation Table  MSAT)附加扇区中的第一个扇区(sector)的SecID 6.2 复合文档头中的第72 - 75的4个字节主扇区分配表Master Sector Allocation Table  MSAT)占据的扇区总数 6.3 复合文档的头部的第76 - 511的436个字节表示主扇区分配表( master sector allocation table MSAT)的一部分,包含MSAT的前109个SecID,如果SAT占据的扇区总数大于109,则MSAT就会有附加扇区,5.1中记录的就是附加扇区中第一个扇区的SecID 6.4例子中扇区分配表(SAT)仅使用了一个扇区(sector),没有超过109,所以没有附加扇区,所以其他所有剩余的SecID都设置为-1,表示为特殊的Free SecID。 这里SAT仅使用的扇区为扇区0

七.下一篇

1.下一篇 - 复合文档格式(五) - 短流、短流容器流和短扇区分配表: http://blog.csdn.net/lipinganq/article/details/76804850
转载请注明原文地址: https://www.6miu.com/read-59264.html

最新回复(0)