public AnnotationReferenceExtraTable(FileInformationBlock fib, VirtualStream tableStream)
        {
            if (fib.nFib >= FileInformationBlock.FibVersion.Fib2002)
            {
                tableStream.Seek((long)fib.fcAtrdExtra, System.IO.SeekOrigin.Begin);
                var 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));
                }
            }
        }
Beispiel #2
0
        public OfficeArtContent(FileInformationBlock fib, VirtualStream tableStream)
        {
            var 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)
                {
                    var drawing = new OfficeArtWordDrawing
                    {
                        dgglbl    = (DrawingType)reader.ReadByte(),
                        container = (DrawingContainer)Record.ReadRecord(reader)
                    };

                    for (int i = 0; i < drawing.container.Children.Count; i++)
                    {
                        var groupChild = drawing.container.Children[i];
                        if (groupChild.TypeCode == 0xF003)
                        {
                            // the child is a subgroup
                            var group = (GroupContainer)drawing.container.Children[i];
                            group.Index = i;
                            drawing.container.Children[i] = group;
                        }
                        else if (groupChild.TypeCode == 0xF004)
                        {
                            // the child is a shape
                            var shape = (ShapeContainer)drawing.container.Children[i];
                            shape.Index = i;
                            drawing.container.Children[i] = shape;
                        }
                    }

                    this.Drawings.Add(drawing);
                }
            }
        }
Beispiel #3
0
        /// <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
            var stshiLengthBytes = new byte[2];

            tableStream.Read(stshiLengthBytes, 0, stshiLengthBytes.Length, fib.fcStshf);
            short cbStshi = System.BitConverter.ToInt16(stshiLengthBytes, 0);

            //read the bytes of the STSHI
            var 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
                ushort cbStd = tableReader.ReadUInt16();

                if (cbStd != 0)
                {
                    //read the STD bytes
                    var std = tableReader.ReadBytes(cbStd);

                    //parse the STD bytes
                    this.Styles.Add(new StyleSheetDescription(std, (int)this.stshi.cbSTDBaseInFile, dataStream));
                }
                else
                {
                    this.Styles.Add(null);
                }
            }
        }
Beispiel #4
0
        void Parse(StructuredStorageReader reader, int 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)this.FIB.nFib != 0)
            {
                if (this.FIB.nFib < FileInformationBlock.FibVersion.Fib1997Beta)
                {
                    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.Fib1997Beta)
                {
                    throw new ByteParseException("Could not parse the file because it was created by an unsupported application (Word 95 or older).");
                }
            }

            //get the streams
            this.TableStream = reader.GetStream(this.FIB.fWhichTblStm ? "1Table" : "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);
            //
            this.UserVariables = new StwStructure(this.TableStream, this.FIB.fcStwUser, this.FIB.lcbStwUser);

            //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 <short>(2, this.TableStream, this.FIB.fcPlcfendRef, this.FIB.lcbPlcfendRef);
            this.FootnoteReferencePlex = new Plex <short>(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 <int, 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 <int, SectionPropertyExceptions>();
            for (int i = 0; i < this.SectionPlex.Elements.Count; i++)
            {
                //Read the SED
                var sed = (SectionDescriptor)this.SectionPlex.Elements[i];
                int cp  = this.SectionPlex.CharacterPositions[i + 1];

                //Get the SEPX
                var wordReader = new VirtualStreamReader(this.WordDocumentStream);
                this.WordDocumentStream.Seek(sed.fcSepx, System.IO.SeekOrigin.Begin);
                short cbSepx = wordReader.ReadInt16();
                var   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));
            }
        }
Beispiel #5
0
        /// <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
            var 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)
                    {
                        int lcb = System.BitConverter.ToInt32(bytes, pos + 1);

                        //read the piece table
                        var 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;
                            int cp      = System.BitConverter.ToInt32(piecetable, indexCp);

                            //read the next CP
                            int indexCpNext = (i + 1) * 4;
                            int cpNext      = System.BitConverter.ToInt32(piecetable, indexCpNext);

                            //read the PCD
                            int indexPcd = ((n + 1) * 4) + (i * 8);
                            var pcdBytes = new byte[8];
                            Array.Copy(piecetable, indexPcd, pcdBytes, 0, 8);
                            var pcd = new PieceDescriptor(pcdBytes)
                            {
                                cpStart = cp,
                                cpEnd   = cpNext
                            };

                            //add pcd
                            this.Pieces.Add(pcd);

                            //add positions
                            int f     = (int)pcd.fc;
                            int 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)
                    {
                        short cb = System.BitConverter.ToInt16(bytes, pos + 1);
                        pos = pos + 1 + 2 + cb;
                    }
                    else
                    {
                        goon = false;
                    }
                }
                catch (Exception)
                {
                    goon = false;
                }
            }
        }
Beispiel #6
0
        public CommandTable(FileInformationBlock fib, VirtualStream tableStream)
        {
            tableStream.Seek(fib.fcCmds, System.IO.SeekOrigin.Begin);
            var 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) && !this.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++)
                    {
                        short ibst = reader.ReadInt16();
                        short 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:
                    this.breakWhile = true;
                    break;
                }
            }
        }