예제 #1
0
        /**
         * Reads module from DIR node in input stream and Adds it to the modules map for decompression later
         * on the second pass through this function, the module will be decompressed
         *
         * Side-effects: Adds a new module to the module map or Sets the buf field on the module
         * to the decompressed stream contents (the VBA code for one module)
         *
         * @param in the Run-length encoded input stream to read from
         * @param streamName the stream name of the module
         * @param modules a map to store the modules
         * @throws IOException
         */
        private static void ReadModule(RLEDecompressingInputStream in1, String streamName, ModuleMap modules)
        {
            int    moduleOffset = in1.ReadInt();
            Module module       = modules.Get(streamName);

            if (module == null)
            {
                // First time we've seen the module. Add it to the ModuleMap and decompress it later
                module        = new Module();
                module.offset = moduleOffset;
                modules.Put(streamName, module);
                // Would Adding module.Read(in1) here be correct?
            }
            else
            {
                // Decompress a previously found module and store the decompressed result into module.buf
                InputStream stream = new RLEDecompressingInputStream(
                    new MemoryStream(module.buf, moduleOffset, module.buf.Length - moduleOffset)
                    );
                module.Read(stream);
                stream.Close();
            }
        }
예제 #2
0
        /**
         * Reads VBA Project modules from a VBA Project directory located at
         * <tt>macroDir</tt> into <tt>modules</tt>.
         *
         * @since 3.15-beta2
         */
        protected void ReadMacros(DirectoryNode macroDir, ModuleMap modules)
        {
            foreach (Entry entry in macroDir)
            {
                if (!(entry is DocumentNode))
                {
                    continue;
                }

                String              name     = entry.Name;
                DocumentNode        document = (DocumentNode)entry;
                DocumentInputStream dis      = new DocumentInputStream(document);
                try
                {
                    if ("dir".Equals(name, StringComparison.OrdinalIgnoreCase))
                    {
                        // process DIR
                        RLEDecompressingInputStream in1 = new RLEDecompressingInputStream(dis);
                        String streamName = null;
                        int    recordId   = 0;
                        try
                        {
                            while (true)
                            {
                                recordId = in1.ReadShort();
                                if (EOF == recordId ||
                                    VERSION_INDEPENDENT_TERMINATOR == recordId)
                                {
                                    break;
                                }
                                int recordLength = in1.ReadInt();
                                switch (recordId)
                                {
                                case PROJECTVERSION:
                                    TrySkip(in1, 6);
                                    break;

                                case PROJECTCODEPAGE:
                                    int codepage = in1.ReadShort();
                                    ModuleMap.charset = Encoding.GetEncoding(codepage);     //Charset.ForName("Cp" + codepage);
                                    break;

                                case STREAMNAME:
                                    streamName = ReadString(in1, recordLength, ModuleMap.charset);
                                    break;

                                case MODULEOFFSET:
                                    ReadModule(in1, streamName, modules);
                                    break;

                                default:
                                    TrySkip(in1, recordLength);
                                    break;
                                }
                            }
                        }
                        catch (IOException e)
                        {
                            throw new IOException(
                                      "Error occurred while Reading macros at section id "
                                      + recordId + " (" + HexDump.ShortToHex(recordId) + ")", e);
                        }
                        finally
                        {
                            in1.Close();
                        }
                    }
                    else if (!name.StartsWith("__SRP", StringComparison.OrdinalIgnoreCase) &&
                             !name.StartsWith("_VBA_PROJECT", StringComparison.OrdinalIgnoreCase))
                    {
                        // process module, skip __SRP and _VBA_PROJECT since these do not contain macros
                        ReadModule(dis, name, modules);
                    }
                }
                finally
                {
                    dis.Close();
                }
            }
        }