首页
学习
活动
专区
圈层
工具
发布

VBA解析复合文档02——复合文档结构

尽量用一些通俗的语言来讲一下复合文档的结构,如果要真正掌握每一个细节,还是要看官方的文档,所以这里讲的可能不会完全正确,只是大概了解一下复合文档的结构逻辑。

复合文档结构

一个文件在被创建的时候,文档的结构也同时生成,这里不讲生成的过程如何去创建这个结构,只拿生成后的文件来讲。

假如一个10KB文件,每个扇区大小是512Byte,举例如下:

01

扇区

复合文档把保存文件的磁盘空间划分了扇区(Sector),在扇区里存放数据信息。文件的开头一个扇区固定是Header结构,这个结构的信息非常重要,是解析整个文件的基础。

每个扇区之间的关系是通过FAT(Main allocator of space within the compound file.)确定的,它是一个数组,数组的下标是扇区的编号、数组的值代表的是下一个扇区的编号。所以通过FAT就能够构建出一个扇区的链表,FAT数组的值也有几个特殊值:

Sector name

Integer value

Description

REGSECT

0x00000000 - 0xFFFFFFF9

Regular sector number.

MAXREGSECT

0xFFFFFFFA

Maximum regular sector number.

Not applicable

0xFFFFFFFB

Reserved for future use.

DIFSECT

0xFFFFFFFC

Specifies a DIFAT sector in the FAT.

FATSECT

0xFFFFFFFD

Specifies a FAT sector in the FAT.

ENDOFCHAIN

0xFFFFFFFE

End of a linked chain of sectors.

FREESECT

0xFFFFFFFF

Specifies an unallocated sector in the FAT, Mini FAT, or DIFAT.

注:来源是微软的官方文档。

所以,在构建扇区的链表的时候,一般是通过判断FAT数组的值是否等于0xFFFFFFFE来结束的。

假设FAT内容如下:

扇区的编号要注意的是,Header结构占用的那个扇区是没有被编号的,所以在计算某个扇区的偏移位置时,一定要记得加上一个Header结构的大小,也就是一个扇区的大小。

02

目录

目录记录的是复合文档中真正需要保存的数据流的信息,首先在Header结构中会有首个目录的所在的扇区,目录结构大小一般128Byte,也就是1个扇区能够记录4个目录结构,当读完一个扇区的时候,比如图中举例的首先读取的扇区下标是1,读完之后,需要继续读取,这个时候就读取FAT(1)的值对应的扇区下标4,仍然是要读取4个。

如何判断是否读取完成?

目前我的做法是在读取下一个目录的时候,如果读取到的目录名称是空,就可以结束了。目前没有发现有具体指明目录个数的信息。

03

MiniFAT

MiniFAT其实完全可以理解为它是一个单独的复合文档结构,只是没有目录结构。

MiniFAT是一种更短的流,而它就是把一个标准的Sector再进行了划分,一般是划分为64Byte,逻辑上和FAT是完全一样的。

存放MiniFAT的扇区也在Header结构中指定了,而短流总共的大小在目录结构的第一个中明确了,所以通过读取扇区的数据以及通过短流数据的大小计算的扇区个数就能获取MiniFAT的数组。

比如举例中10个目录,假设其中有3个目录,7个数据流(其中4个短流),这4个短流数据读取就需要使用MiniFAT构建的短扇区链表。

如果4个加起来都还小于512Byte的话,就很有可能被存放在一个Sector里,而正常的数据流是不可能会存在2个数据流在一个Sector中的情况。

04

DIFAT

FAT数组的构建依赖的就是这个叫做DIFAT(Used to locate FAT sectors in the compound file.)的,DIFAT也是一个数组,数组的值代表的是扇区的编号,并且代表的这个扇区存储的就是FAT数组。

DIFAT数组的前109个元素是被存放在Header结构中的,如果某个文件超过了6.875M,那就需要另外的扇区来存储DIFAT数组,这个另外的扇区编号是在Header结构中指定的,每个扇区存放127个DIFAT数组,最后1个元素指明下一个扇区的编号(512Byte / 4Byte = 128),这样DIFAT数组就能够构建出来。

DIFAT数组构建出来之后,就可以去对应的扇区读取FAT数组的信息,每个扇区128个FAT数组元素。

只要理解了Header结构、目录结构、DIFAT数组、FAT数组、MiniFAT数组,解析复合文档就没什么难度了。

通过这些信息,构建出来扇区链表,就可以到分布的扇区中,读取或者改写数据。

举报
领券