這篇分析DocumentSummaryInformation流,該流爲可選流,保存文檔的摘要信息。該流的位置同樣通過目錄定位,其名字爲0005DocumentSummaryInformation(0005爲16進制數),定位方法見覆合文檔格式的分析(http://blog.csdn.net/shadow20080578/article/details/50245309)。
該流包含一個或多個屬性組,每個屬性組包含一個或多個屬性。
1.開始爲流的全局信息:
00H-01H爲字節順序,要求爲0xFFFE。
02H-03H屬性集版本。
04H爲一字節的操作系統主版本號。
05H爲一字節的操作系統次版本號。
06H-07H爲操作系統類型,固定爲0x0002.
08H-17H爲10字節的CLSID,未設置時爲默認的全0x00。
018H-01BH的4字節UInt32,是存儲屬性組的個數。
01CH開始的每20字節,是每個屬性組的標誌和偏移:
前16字節爲FMTID,FMTID_DocSummaryInformation 是0x02 0xD5 0xCD 0xD5 0x9C 0x2E 0x1B 0x10 0x93 0x97 0x08 0x00 0x2B 0x2C 0xF9 0xAE。FMTID_UserDefinedProperties 是0x05 0xD5 0xCD 0xD5 0x9C 0x2E 0x1B 0x10 0x93 0x97 0x08 0x00 0x2B 0x2C 0xF9 0xAE。
後4字節UInt32,則是該屬性組相對於流起始的偏移。
2.利用偏移可以在流中定位到屬性組,對於每個屬性組,其結構如下:
從000H到003H的4字節UInt32,是屬性組大小。
從004H到007H的4字節UInt32,是屬性組中屬性的個數。
從008H開始的每8字節,是屬性的信息:
對於前4字節UInt32,是屬性編號,表示屬性的種類:
Unknown = 0x00
CodePage = 0x01
Category = 0x02
PresentationTarget = 0x03,
Bytes = 0x04,
LineCount = 0x05,
ParagraphCount = 0x06,
Slides = 0x07,
Notes = 0x08,
HiddenSlides = 0x09,
MMClips = 0x0A,
Scale = 0x0B
HeadingPairs = 0x0C,
DocumentParts = 0x0D,
Manager = 0x0E,
Company = 0x0F,
LinksDirty = 0x10,
CountCharsWithSpaces = 0x11
SharedDoc = 0x13,
LINKBASE = 0x14
HLINKS = 0x15
HyperLinksChanged = 0x16
Version = 0x17
DIGSIG = 0x18
CONTENTTYPE = 0x1a
ContentStatus = 0x1b
LANGUAGE = 0x1c
DOCVERSION = 0x1d
對於後4字節UInt32,是屬性內容相對於屬性組的偏移。
3.利用屬性信息可以定位到屬性組中的每個屬性,對於每個屬性,其結構如下:
從000H到003H的4字節UInt32,是屬性內容的類型:
類型爲0x02時爲UInt16。
類型爲0x03時爲UInt32。
類型爲0x0B時爲Boolean。
類型爲0x1E時爲String。
剩餘的字節爲屬性的內容。
除了類型是String時爲不定長,其餘三種均爲4位字節(多餘字節置0)。類型是String時前4字節是字符串的長度(包括“\0”),所以沒法使用BinaryReader的ReadString讀取。之後長度爲字符串內容,字符串是使用單字節編碼進行存儲的,可以使用Encoding中的GetString獲取字符串內容。