public CommentAuthorTable(FileInformationBlock fib, VirtualStream tableStream) { tableStream.Seek(fib.fcGrpXstAtnOwners, System.IO.SeekOrigin.Begin); VirtualStreamReader reader = new VirtualStreamReader(tableStream); while (tableStream.Position < (fib.fcGrpXstAtnOwners + fib.lcbGrpXstAtnOwners)) { Int16 cch = reader.ReadInt16(); this.Add(Encoding.Unicode.GetString(reader.ReadBytes(cch * 2))); } }
public AnnotationReferenceExtraTable(FileInformationBlock fib, VirtualStream tableStream) { if (fib.nFib >= FileInformationBlock.FibVersion.Fib2002) { tableStream.Seek((long)fib.fcAtrdExtra, System.IO.SeekOrigin.Begin); VirtualStreamReader reader = new VirtualStreamReader(tableStream); int n = (int)fib.lcbAtrdExtra / ARTDPost10_LENGTH; //read the n ATRDPost10 structs for (int i = 0; i < n; i++) { this.Add(new AnnotationReferenceDescriptorExtra(reader, ARTDPost10_LENGTH)); } } }
public OfficeArtContent(FileInformationBlock fib, VirtualStream tableStream) { VirtualStreamReader reader = new VirtualStreamReader(tableStream); tableStream.Seek(fib.fcDggInfo, System.IO.SeekOrigin.Begin); if (fib.lcbDggInfo > 0) { int maxPosition = (int)(fib.fcDggInfo + fib.lcbDggInfo); //read the DrawingGroupData this.DrawingGroupData = (DrawingGroup)Record.ReadRecord(reader); //read the Drawings this.Drawings = new List <OfficeArtWordDrawing>(); while (reader.BaseStream.Position < maxPosition) { OfficeArtWordDrawing drawing = new OfficeArtWordDrawing(); drawing.dgglbl = (DrawingType)reader.ReadByte(); drawing.container = (DrawingContainer)Record.ReadRecord(reader); for (int i = 0; i < drawing.container.Children.Count; i++) { Record groupChild = drawing.container.Children[i]; if (groupChild.TypeCode == 0xF003) { // the child is a subgroup GroupContainer group = (GroupContainer)drawing.container.Children[i]; group.Index = i; drawing.container.Children[i] = group; } else if (groupChild.TypeCode == 0xF004) { // the child is a shape ShapeContainer shape = (ShapeContainer)drawing.container.Children[i]; shape.Index = i; drawing.container.Children[i] = shape; } } this.Drawings.Add(drawing); } } }
/// <summary> /// Parses the streams to retrieve a StyleSheet. /// </summary> /// <param name="fib">The FileInformationBlock</param> /// <param name="tableStream">The 0Table or 1Table stream</param> public StyleSheet(FileInformationBlock fib, VirtualStream tableStream, VirtualStream dataStream) { IStreamReader tableReader = new VirtualStreamReader(tableStream); //read size of the STSHI byte[] stshiLengthBytes = new byte[2]; tableStream.Read(stshiLengthBytes, 0, stshiLengthBytes.Length, fib.fcStshf); Int16 cbStshi = System.BitConverter.ToInt16(stshiLengthBytes, 0); //read the bytes of the STSHI byte[] stshi = tableReader.ReadBytes(fib.fcStshf + 2, cbStshi); //parses STSHI this.stshi = new StyleSheetInformation(stshi); //create list of STDs this.Styles = new List <StyleSheetDescription>(); for (int i = 0; i < this.stshi.cstd; i++) { //get the cbStd UInt16 cbStd = tableReader.ReadUInt16(); if (cbStd != 0) { //read the STD bytes byte[] std = tableReader.ReadBytes(cbStd); //parse the STD bytes this.Styles.Add(new StyleSheetDescription(std, (int)this.stshi.cbSTDBaseInFile, dataStream)); } else { this.Styles.Add(null); } } }
public CommandTable(FileInformationBlock fib, VirtualStream tableStream) { tableStream.Seek(fib.fcCmds, System.IO.SeekOrigin.Begin); VirtualStreamReader reader = new VirtualStreamReader(tableStream); //byte[] bytes = reader.ReadBytes((int)fib.lcbCmds); this.MacroDatas = new List <MacroData>(); this.KeyMapEntries = new List <KeyMapEntry>(); this.MacroNames = new Dictionary <int, string>(); //skip the version reader.ReadByte(); //parse the commandtable while (reader.BaseStream.Position < (fib.fcCmds + fib.lcbCmds) && !breakWhile) { //read the type byte ch = reader.ReadByte(); switch (ch) { case 0x1: //it's a PlfMcd int iMacMcd = reader.ReadInt32(); for (int i = 0; i < iMacMcd; i++) { this.MacroDatas.Add(new MacroData(reader)); } break; case 0x2: //it's a PlfAcd //skip the ACDs int iMacAcd = reader.ReadInt32(); reader.ReadBytes(iMacAcd * 4); break; case 0x3: //Keymap Entries int iMacKme = reader.ReadInt32(); for (int i = 0; i < iMacKme; i++) { this.KeyMapEntries.Add(new KeyMapEntry(reader)); } break; case 0x4: //Keymap Entries int iMacKmeInvalid = reader.ReadInt32(); for (int i = 0; i < iMacKmeInvalid; i++) { this.KeyMapEntries.Add(new KeyMapEntry(reader)); } break; case 0x10: //it's a TcgSttbf this.CommandStringTable = new StringTable(typeof(String), reader); break; case 0x11: //it's a MacroNames table int iMacMn = reader.ReadInt16(); for (int i = 0; i < iMacMn; i++) { Int16 ibst = reader.ReadInt16(); Int16 cch = reader.ReadInt16(); this.MacroNames[ibst] = Encoding.Unicode.GetString(reader.ReadBytes(cch * 2)); //skip the terminating zero reader.ReadBytes(2); } break; case 0x12: //it's a CTBWRAPPER structure this.CustomToolbars = new CustomToolbarWrapper(reader); break; default: breakWhile = true; break; } } }
private void parse(StructuredStorageReader reader, Int32 fibFC) { this.Storage = reader; this.WordDocumentStream = reader.GetStream("WordDocument"); //parse FIB this.WordDocumentStream.Seek(fibFC, System.IO.SeekOrigin.Begin); this.FIB = new FileInformationBlock(new VirtualStreamReader(this.WordDocumentStream)); //check the file version if ((int)FIB.nFib != 0) { if (this.FIB.nFib < FileInformationBlock.FibVersion.Fib1997) { throw new ByteParseException("Could not parse the file because it was created by an unsupported application (Word 95 or older)."); } } else { if (this.FIB.nFibNew < FileInformationBlock.FibVersion.Fib1997) { throw new ByteParseException("Could not parse the file because it was created by an unsupported application (Word 95 or older)."); } } //get the streams if (this.FIB.fWhichTblStm) { this.TableStream = reader.GetStream("1Table"); } else { this.TableStream = reader.GetStream("0Table"); } try { this.DataStream = reader.GetStream("Data"); } catch (StreamNotFoundException) { this.DataStream = null; } //Read all needed STTBs this.RevisionAuthorTable = new StringTable(typeof(String), this.TableStream, this.FIB.fcSttbfRMark, this.FIB.lcbSttbfRMark); this.FontTable = new StringTable(typeof(FontFamilyName), this.TableStream, this.FIB.fcSttbfFfn, this.FIB.lcbSttbfFfn); this.BookmarkNames = new StringTable(typeof(String), this.TableStream, this.FIB.fcSttbfBkmk, this.FIB.lcbSttbfBkmk); this.AutoTextNames = new StringTable(typeof(String), this.TableStream, this.FIB.fcSttbfGlsy, this.FIB.lcbSttbfGlsy); //this.ProtectionUsers = new StringTable(typeof(String), this.TableStream, this.FIB.fcSttbProtUser, this.FIB.lcbSttbProtUser); //Read all needed PLCFs this.AnnotationsReferencePlex = new Plex <AnnotationReferenceDescriptor>(30, this.TableStream, this.FIB.fcPlcfandRef, this.FIB.lcbPlcfandRef); this.TextboxBreakPlex = new Plex <BreakDescriptor>(6, this.TableStream, this.FIB.fcPlcfTxbxBkd, this.FIB.lcbPlcfTxbxBkd); this.TextboxBreakPlexHeader = new Plex <BreakDescriptor>(6, this.TableStream, this.FIB.fcPlcfTxbxHdrBkd, this.FIB.lcbPlcfTxbxHdrBkd); this.OfficeDrawingPlex = new Plex <FileShapeAddress>(26, this.TableStream, this.FIB.fcPlcSpaMom, this.FIB.lcbPlcSpaMom); this.OfficeDrawingPlexHeader = new Plex <FileShapeAddress>(26, this.TableStream, this.FIB.fcPlcSpaHdr, this.FIB.lcbPlcSpaHdr); this.SectionPlex = new Plex <SectionDescriptor>(12, this.TableStream, this.FIB.fcPlcfSed, this.FIB.lcbPlcfSed); this.BookmarkStartPlex = new Plex <BookmarkFirst>(4, this.TableStream, this.FIB.fcPlcfBkf, this.FIB.lcbPlcfBkf); this.EndnoteReferencePlex = new Plex <Int16>(2, this.TableStream, this.FIB.fcPlcfendRef, this.FIB.lcbPlcfendRef); this.FootnoteReferencePlex = new Plex <Int16>(2, this.TableStream, this.FIB.fcPlcffndRef, this.FIB.lcbPlcffndRef); // PLCFs without types this.BookmarkEndPlex = new Plex <Exception>(0, this.TableStream, this.FIB.fcPlcfBkl, this.FIB.lcbPlcfBkl); this.AutoTextPlex = new Plex <Exception>(0, this.TableStream, this.FIB.fcPlcfGlsy, this.FIB.lcbPlcfGlsy); //read the FKPs this.AllPapxFkps = FormattedDiskPagePAPX.GetAllPAPXFKPs(this.FIB, this.WordDocumentStream, this.TableStream, this.DataStream); this.AllChpxFkps = FormattedDiskPageCHPX.GetAllCHPXFKPs(this.FIB, this.WordDocumentStream, this.TableStream); //read custom tables this.DocumentProperties = new DocumentProperties(this.FIB, this.TableStream); this.Styles = new StyleSheet(this.FIB, this.TableStream, this.DataStream); this.ListTable = new ListTable(this.FIB, this.TableStream); this.ListFormatOverrideTable = new ListFormatOverrideTable(this.FIB, this.TableStream); this.OfficeArtContent = new OfficeArtContent(this.FIB, this.TableStream); this.HeaderAndFooterTable = new HeaderAndFooterTable(this); this.AnnotationReferenceExtraTable = new AnnotationReferenceExtraTable(this.FIB, this.TableStream); this.CommandTable = new CommandTable(this.FIB, this.TableStream); this.AnnotationOwners = new AnnotationOwnerList(this.FIB, this.TableStream); //parse the piece table and construct a list that contains all chars this.PieceTable = new PieceTable(this.FIB, this.TableStream); this.Text = this.PieceTable.GetAllChars(this.WordDocumentStream); //build a dictionaries of all PAPX this.AllPapx = new Dictionary <Int32, ParagraphPropertyExceptions>(); for (int i = 0; i < this.AllPapxFkps.Count; i++) { for (int j = 0; j < this.AllPapxFkps[i].grppapx.Length; j++) { this.AllPapx.Add(this.AllPapxFkps[i].rgfc[j], this.AllPapxFkps[i].grppapx[j]); } } //build a dictionary of all SEPX this.AllSepx = new Dictionary <Int32, SectionPropertyExceptions>(); for (int i = 0; i < this.SectionPlex.Elements.Count; i++) { //Read the SED SectionDescriptor sed = (SectionDescriptor)this.SectionPlex.Elements[i]; Int32 cp = this.SectionPlex.CharacterPositions[i + 1]; //Get the SEPX VirtualStreamReader wordReader = new VirtualStreamReader(this.WordDocumentStream); this.WordDocumentStream.Seek(sed.fcSepx, System.IO.SeekOrigin.Begin); Int16 cbSepx = wordReader.ReadInt16(); SectionPropertyExceptions sepx = new SectionPropertyExceptions(wordReader.ReadBytes(cbSepx - 2)); this.AllSepx.Add(cp, sepx); } //read the Glossary if (this.FIB.pnNext > 0) { this.Glossary = new WordDocument(this.Storage, (int)(this.FIB.pnNext * 512)); } }
/// <summary> /// Parses the pice table and creates a list of PieceDescriptors. /// </summary> /// <param name="fib">The FIB</param> /// <param name="tableStream">The 0Table or 1Table stream</param> public PieceTable(FileInformationBlock fib, VirtualStream tableStream) { //Read the bytes of complex file information byte[] bytes = new byte[fib.lcbClx]; tableStream.Read(bytes, 0, (int)fib.lcbClx, (int)fib.fcClx); this.Pieces = new List <PieceDescriptor>(); this.FileCharacterPositions = new Dictionary <int, int>(); this.CharacterPositions = new Dictionary <int, int>(); int pos = 0; bool goon = true; while (goon) { try { byte type = bytes[pos]; //check if the type of the entry is a piece table if (type == 2) { Int32 lcb = System.BitConverter.ToInt32(bytes, pos + 1); //read the piece table byte[] piecetable = new byte[lcb]; Array.Copy(bytes, pos + 5, piecetable, 0, piecetable.Length); //count of PCD _entries int n = (lcb - 4) / 12; //and n piece descriptors for (int i = 0; i < n; i++) { //read the CP int indexCp = i * 4; Int32 cp = System.BitConverter.ToInt32(piecetable, indexCp); //read the next CP int indexCpNext = (i + 1) * 4; Int32 cpNext = System.BitConverter.ToInt32(piecetable, indexCpNext); //read the PCD int indexPcd = ((n + 1) * 4) + (i * 8); byte[] pcdBytes = new byte[8]; Array.Copy(piecetable, indexPcd, pcdBytes, 0, 8); PieceDescriptor pcd = new PieceDescriptor(pcdBytes); pcd.cpStart = cp; pcd.cpEnd = cpNext; //add pcd this.Pieces.Add(pcd); //add positions Int32 f = (Int32)pcd.fc; Int32 multi = 1; if (pcd.encoding == Encoding.Unicode) { multi = 2; } for (int c = pcd.cpStart; c < pcd.cpEnd; c++) { if (!this.FileCharacterPositions.ContainsKey(c)) { this.FileCharacterPositions.Add(c, f); } if (!this.CharacterPositions.ContainsKey(f)) { this.CharacterPositions.Add(f, c); } f += multi; } } int maxCp = this.FileCharacterPositions.Count; this.FileCharacterPositions.Add(maxCp, fib.fcMac); this.CharacterPositions.Add(fib.fcMac, maxCp); //piecetable was found goon = false; } //entry is no piecetable so goon else if (type == 1) { Int16 cb = System.BitConverter.ToInt16(bytes, pos + 1); pos = pos + 1 + 2 + cb; } else { goon = false; } } catch (Exception) { goon = false; } } }