Esempio n. 1
0
        private void CheckAllDirectoryContents(DirectoryEntry dir)
        {
            IEnumerator <Entry> it = dir.Entries;

            //foreach (Entry entry in dir)
            while (it.MoveNext())
            {
                Entry entry = it.Current;
                if (entry is DirectoryEntry)
                {
                    CheckAllDirectoryContents((DirectoryEntry)entry);
                }
                else
                {
                    DocumentNode        doc = (DocumentNode)entry;
                    DocumentInputStream dis = new DocumentInputStream(doc);
                    try
                    {
                        int    numBytes = dis.Available();
                        byte[] data     = new byte[numBytes];
                        dis.Read(data);
                    }
                    finally
                    {
                        dis.Close();
                    }
                }
            }
        }
Esempio n. 2
0
        public void TestAvailable()
        {
            DocumentInputStream ostream = new DocumentInputStream(_workbook_o);
            DocumentInputStream nstream = new NDocumentInputStream(_workbook_n);

            Assert.AreEqual(_workbook_size, ostream.Available());
            Assert.AreEqual(_workbook_size, nstream.Available());
            ostream.Close();
            nstream.Close();

            try
            {
                ostream.Available();
                Assert.Fail("Should have caught IOException");
            }
            catch (InvalidOperationException)
            {
                // as expected
            }
            try
            {
                nstream.Available();
                Assert.Fail("Should have caught IOException");
            }
            catch (InvalidOperationException)
            {
                // as expected
            }
        }
Esempio n. 3
0
        /**
         * Decrypt the Document-/SummaryInformation and other optionally streams.
         * Opposed to other crypto modes, cryptoapi is record based and can't be used
         * to stream-decrypt a whole file
         *
         * @see <a href="http://msdn.microsoft.com/en-us/library/dd943321(v=office.12).aspx">2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream</a>
         */

        public override InputStream GetDataStream(DirectoryNode dir)
        {
            NPOIFSFileSystem    fsOut = new NPOIFSFileSystem();
            DocumentNode        es    = (DocumentNode)dir.GetEntry("EncryptedSummary");
            DocumentInputStream dis   = dir.CreateDocumentInputStream(es);
            MemoryStream        bos   = new MemoryStream();

            IOUtils.Copy(dis, bos);
            dis.Close();
            SeekableMemoryStream    sbis    = new SeekableMemoryStream(bos.ToArray());
            LittleEndianInputStream leis    = new LittleEndianInputStream(sbis);
            int streamDescriptorArrayOffset = (int)leis.ReadUInt();
            int streamDescriptorArraySize   = (int)leis.ReadUInt();

            sbis.Seek(streamDescriptorArrayOffset - 8, SeekOrigin.Current);// sbis.Skip(streamDescriptorArrayOffset - 8);

            sbis.SetBlock(0);
            int encryptedStreamDescriptorCount = (int)leis.ReadUInt();

            StreamDescriptorEntry[] entries = new StreamDescriptorEntry[encryptedStreamDescriptorCount];
            for (int i = 0; i < encryptedStreamDescriptorCount; i++)
            {
                StreamDescriptorEntry entry = new StreamDescriptorEntry();
                entries[i]         = entry;
                entry.streamOffset = (int)leis.ReadUInt();
                entry.streamSize   = (int)leis.ReadUInt();
                entry.block        = leis.ReadUShort();
                int nameSize = leis.ReadUByte();
                entry.flags = leis.ReadUByte();
                bool IsStream = StreamDescriptorEntry.flagStream.IsSet(entry.flags);
                entry.reserved2  = leis.ReadInt();
                entry.streamName = StringUtil.ReadUnicodeLE(leis, nameSize);
                leis.ReadShort();
                Debug.Assert(entry.streamName.Length == nameSize);
            }

            foreach (StreamDescriptorEntry entry in entries)
            {
                sbis.Seek(entry.streamOffset);
                sbis.SetBlock(entry.block);
                Stream is1 = new BufferedStream(sbis, entry.streamSize);
                fsOut.CreateDocument(is1, entry.streamName);
            }

            leis.Close();
            sbis = null;

            bos.Seek(0, SeekOrigin.Begin); //bos.Reset();
            fsOut.WriteFileSystem(bos);
            fsOut.Close();
            _length = bos.Length;
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.ToArray());

            throw new NotImplementedException("ByteArrayInputStream should be derived from InputStream");
        }
Esempio n. 4
0
        /**
         * Closes the MemoryStream and Reads it into a MemoryStream.
         * When finished writing information this method is used in the Tests to
         * start Reading from the Created document and then the see if the results match.
         *
         */
        private void CloseAndReOpen()
        {
            dsi.Write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME);
            si.Write(dir, SummaryInformation.DEFAULT_STREAM_NAME);


            si  = null;
            dsi = null;
            try
            {
                poifs.WriteFileSystem(bout);
                bout.Flush();
            }
            catch (IOException)
            {
                ////e.printStackTrace();
                Assert.Fail();
            }

            Stream is1 = new MemoryStream(bout.ToArray());

            Assert.IsNotNull(is1);
            poifs = new POIFSFileSystem(is1);;
            is1.Close();

            Assert.IsNotNull(poifs);
            /* Read the document summary information. */
            dir = poifs.Root;

            DocumentEntry dsiEntry = (DocumentEntry)
                                     dir.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
            DocumentInputStream dis = new DocumentInputStream(dsiEntry);
            PropertySet         ps  = new PropertySet(dis);

            dis.Close();
            dsi = new DocumentSummaryInformation(ps);


            try
            {
                dsiEntry = (DocumentEntry)
                           dir.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME);
                dis = new DocumentInputStream(dsiEntry);
                ps  = new PropertySet(dis);
                dis.Close();
                si = new SummaryInformation(ps);
            }
            catch (FileNotFoundException)
            {
                /* There is no document summary information yet. We have to Create a
                 * new one. */
                si = PropertySetFactory.CreateSummaryInformation();
                Assert.IsNotNull(si);
            }
        }
Esempio n. 5
0
        /**
         * <p>Creates the most specific {@link PropertySet} from an entry
         *  in the specified POIFS Directory. This is preferrably a {@link
         * DocumentSummaryInformation} or a {@link SummaryInformation}. If
         * the specified entry does not contain a property Set stream, an
         * exception is thrown. If no entry is found with the given name,
         * an exception is thrown.</p>
         *
         * @param dir The directory to find the PropertySet in
         * @param name The name of the entry Containing the PropertySet
         * @return The Created {@link PropertySet}.
         * @if there is no entry with that name
         * @if the stream does not
         * contain a property Set.
         * @if some I/O problem occurs.
         * @exception EncoderFallbackException if the specified codepage is not
         * supported.
         */
        public static PropertySet Create(DirectoryEntry dir, String name)
        {
            Stream inp = null;

            try
            {
                DocumentEntry entry = (DocumentEntry)dir.GetEntry(name);
                inp = new DocumentInputStream(entry);
                try
                {
                    return(Create(inp));
                }
                catch (MarkUnsupportedException) { return(null); }
            }
            finally
            {
                if (inp != null)
                {
                    inp.Close();
                }
            }
        }
Esempio n. 6
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();
                }
            }
        }
Esempio n. 7
0
        public void TestMultiBlockStream()
        {
            byte[] data1B = new byte[63];
            byte[] data2B = new byte[64 + 14];
            for (int i = 0; i < data1B.Length; i++)
            {
                data1B[i] = (byte)(i + 2);
            }
            for (int i = 0; i < data2B.Length; i++)
            {
                data2B[i] = (byte)(i + 4);
            }

            // New filesystem and store to use
            NPOIFSFileSystem fs        = new NPOIFSFileSystem();
            NPOIFSMiniStore  ministore = fs.GetMiniStore();

            // Initially has Properties + BAT but nothing else
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(2));

            // Store the 2 block one, should use 2 mini blocks, and request
            // the use of 2 big blocks
            ministore = fs.GetMiniStore();
            fs.Root.CreateDocument("mini2", new ByteArrayInputStream(data2B));

            // Check
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); // SBAT
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(3)); // Mini
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(4));

            // First 2 Mini blocks will be used
            Assert.AreEqual(2, ministore.GetFreeBlock());

            // Add one more mini-stream, and check
            fs.Root.CreateDocument("mini1", new ByteArrayInputStream(data1B));

            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2)); // SBAT
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(3)); // Mini
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(4));

            // One more mini-block will be used
            Assert.AreEqual(3, ministore.GetFreeBlock());

            // Check the contents too
            byte[] r1 = new byte[data1B.Length];
            DocumentInputStream dis = fs.CreateDocumentInputStream("mini1");

            IOUtils.ReadFully(dis, r1);
            dis.Close();
            CollectionAssert.AreEqual(data1B, r1);

            byte[] r2 = new byte[data2B.Length];
            dis = fs.CreateDocumentInputStream("mini2");
            IOUtils.ReadFully(dis, r2);
            dis.Close();
            CollectionAssert.AreEqual(data2B, r2);

            fs.Close();
        }
Esempio n. 8
0
        public void TestCreateMiniStoreFirst()
        {
            NPOIFSFileSystem    fs        = new NPOIFSFileSystem();
            NPOIFSMiniStore     ministore = fs.GetMiniStore();
            DocumentInputStream dis;
            DocumentEntry       entry;

            // Initially has Properties + BAT but nothing else
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(2));
            // Ministore has no blocks, so can't iterate until used
            try
            {
                ministore.GetNextBlock(0);
            }
            catch (ArgumentOutOfRangeException e) { }

            // Write a very small new document, will populate the ministore for us
            byte[] data = new byte[8];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (byte)(i + 42);
            }
            fs.Root.CreateDocument("mini", new ByteArrayInputStream(data));

            // Should now have a mini-fat and a mini-stream
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(3));
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(4));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, ministore.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, ministore.GetNextBlock(1));

            // Re-fetch the mini store, and add it a second time
            ministore = fs.GetMiniStore();
            fs.Root.CreateDocument("mini2", new ByteArrayInputStream(data));

            // Main unchanged, ministore has a second
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.FAT_SECTOR_BLOCK, fs.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(2));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, fs.GetNextBlock(3));
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, fs.GetNextBlock(4));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, ministore.GetNextBlock(0));
            Assert.AreEqual(POIFSConstants.END_OF_CHAIN, ministore.GetNextBlock(1));
            Assert.AreEqual(POIFSConstants.UNUSED_BLOCK, ministore.GetNextBlock(2));

            // Check the data is unchanged and the right length
            entry = (DocumentEntry)fs.Root.GetEntry("mini");
            Assert.AreEqual(data.Length, entry.Size);
            byte[] rdata = new byte[data.Length];
            dis = new DocumentInputStream(entry);
            IOUtils.ReadFully(dis, rdata);
            CollectionAssert.AreEqual(data, rdata);

            dis.Close();

            entry = (DocumentEntry)fs.Root.GetEntry("mini2");
            Assert.AreEqual(data.Length, entry.Size);
            rdata = new byte[data.Length];
            dis   = new DocumentInputStream(entry);
            IOUtils.ReadFully(dis, rdata);
            CollectionAssert.AreEqual(data, rdata);
            dis.Close();

            // Done
            fs.Close();
        }
Esempio n. 9
0
 public override void Close()
 {
     _stream.Close();
 }
Esempio n. 10
0
        /**
         * Encrypt the Document-/SummaryInformation and other optionally streams.
         * Opposed to other crypto modes, cryptoapi is record based and can't be used
         * to stream-encrypt a whole file
         *
         * @see <a href="http://msdn.microsoft.com/en-us/library/dd943321(v=office.12).aspx">2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream</a>
         */
        public override OutputStream GetDataStream(DirectoryNode dir)
        {
            CipherByteArrayOutputStream bos = new CipherByteArrayOutputStream(this);

            byte[] buf = new byte[8];

            bos.Write(buf, 0, 8); // skip header
            String[] entryNames =
            {
                SummaryInformation.DEFAULT_STREAM_NAME,
                DocumentSummaryInformation.DEFAULT_STREAM_NAME
            };

            List <CryptoAPIDecryptor.StreamDescriptorEntry> descList = new List <CryptoAPIDecryptor.StreamDescriptorEntry>();

            int block = 0;

            foreach (String entryName in entryNames)
            {
                if (!dir.HasEntry(entryName))
                {
                    continue;
                }
                CryptoAPIDecryptor.StreamDescriptorEntry descEntry = new CryptoAPIDecryptor.StreamDescriptorEntry();
                descEntry.block        = block;
                descEntry.streamOffset = (int)bos.Length;
                descEntry.streamName   = entryName;
                descEntry.flags        = CryptoAPIDecryptor.StreamDescriptorEntry.flagStream.SetValue(0, 1);
                descEntry.reserved2    = 0;

                bos.SetBlock(block);
                DocumentInputStream dis = dir.CreateDocumentInputStream(entryName);
                IOUtils.Copy(dis, bos);
                dis.Close();

                descEntry.streamSize = (int)(bos.Length - descEntry.streamOffset);
                descList.Add(descEntry);

                dir.GetEntry(entryName).Delete();

                block++;
            }

            int streamDescriptorArrayOffset = (int)bos.Length;

            bos.SetBlock(0);
            LittleEndian.PutUInt(buf, 0, descList.Count);
            bos.Write(buf, 0, 4);

            foreach (CryptoAPIDecryptor.StreamDescriptorEntry sde in descList)
            {
                LittleEndian.PutUInt(buf, 0, sde.streamOffset);
                bos.Write(buf, 0, 4);
                LittleEndian.PutUInt(buf, 0, sde.streamSize);
                bos.Write(buf, 0, 4);
                LittleEndian.PutUShort(buf, 0, sde.block);
                bos.Write(buf, 0, 2);
                LittleEndian.PutUByte(buf, 0, (short)sde.streamName.Length);
                bos.Write(buf, 0, 1);
                LittleEndian.PutUByte(buf, 0, (short)sde.flags);
                bos.Write(buf, 0, 1);
                LittleEndian.PutUInt(buf, 0, sde.reserved2);
                bos.Write(buf, 0, 4);
                byte[] nameBytes = StringUtil.GetToUnicodeLE(sde.streamName);
                bos.Write(nameBytes, 0, nameBytes.Length);
                LittleEndian.PutShort(buf, 0, (short)0); // null-termination
                bos.Write(buf, 0, 2);
            }

            int savedSize = (int)bos.Length;
            int streamDescriptorArraySize = savedSize - streamDescriptorArrayOffset;

            LittleEndian.PutUInt(buf, 0, streamDescriptorArrayOffset);
            LittleEndian.PutUInt(buf, 4, streamDescriptorArraySize);

            bos.Reset();
            bos.SetBlock(0);
            bos.Write(buf, 0, 8);
            bos.SetSize(savedSize);

            dir.CreateDocument("EncryptedSummary", new MemoryStream(bos.GetBuf(), 0, savedSize));
            DocumentSummaryInformation dsi = PropertySetFactory.NewDocumentSummaryInformation();

            try
            {
                dsi.Write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME);
            }
            catch (WritingNotSupportedException e)
            {
                throw new IOException(e.Message);
            }

            //return bos;
            throw new NotImplementedException("CipherByteArrayOutputStream should be derived from OutputStream");
        }
Esempio n. 11
0
 public void SetUp()
 {
     bout  = new MemoryStream();
     poifs = new POIFSFileSystem();
     dir   = poifs.Root;
     dsi   = null;
     try
     {
         DocumentEntry dsiEntry = (DocumentEntry)
                                  dir.GetEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
         DocumentInputStream dis = new DocumentInputStream(dsiEntry);
         PropertySet         ps  = new PropertySet(dis);
         dis.Close();
         dsi = new DocumentSummaryInformation(ps);
     }
     catch (FileNotFoundException)
     {
         /* There is no document summary information yet. We have to Create a
          * new one. */
         dsi = PropertySetFactory.CreateDocumentSummaryInformation();
         Assert.IsNotNull(dsi);
     }
     catch (IOException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     catch (NoPropertySetStreamException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     catch (MarkUnsupportedException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     catch (UnexpectedPropertySetTypeException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     Assert.IsNotNull(dsi);
     try
     {
         DocumentEntry dsiEntry = (DocumentEntry)
                                  dir.GetEntry(SummaryInformation.DEFAULT_STREAM_NAME);
         DocumentInputStream dis = new DocumentInputStream(dsiEntry);
         PropertySet         ps  = new PropertySet(dis);
         dis.Close();
         si = new SummaryInformation(ps);
     }
     catch (FileNotFoundException)
     {
         /* There is no document summary information yet. We have to Create a
          * new one. */
         si = PropertySetFactory.CreateSummaryInformation();
         Assert.IsNotNull(si);
     }
     catch (IOException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     catch (NoPropertySetStreamException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     catch (MarkUnsupportedException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     catch (UnexpectedPropertySetTypeException)
     {
         ////e.printStackTrace();
         Assert.Fail();
     }
     Assert.IsNotNull(dsi);
 }
Esempio n. 12
0
 public void Close()
 {
     _stream.Close();
 }
Esempio n. 13
0
        /// <summary>
        /// For a given named property entry, either return it or null if
        /// if it wasn't found
        /// </summary>
        /// <param name="setName">The property to read</param>
        /// <param name="encryptionInfo">the encryption descriptor in case of cryptoAPI encryption</param>
        /// <returns>The value of the given property or null if it wasn't found.</returns>
        /// <exception cref="IOException">If retrieving properties fails</exception>
        protected PropertySet GetPropertySet(string setName, EncryptionInfo encryptionInfo)
        {
            DirectoryNode dirNode = directory;

            NPOIFSFileSystem encPoifs = null;
            String           step     = "getting";

            try
            {
                if (encryptionInfo != null)
                {
                    step = "getting encrypted";
                    InputStream is1 = encryptionInfo.Decryptor.GetDataStream(directory);
                    try
                    {
                        encPoifs = new NPOIFSFileSystem(is1);
                        dirNode  = encPoifs.Root;
                    }
                    finally
                    {
                        is1.Close();
                    }
                }

                //directory can be null when creating new documents
                if (dirNode == null || !dirNode.HasEntry(setName))
                {
                    return(null);
                }

                // Find the entry, and get an input stream for it
                step = "getting";
                DocumentInputStream dis = dirNode.CreateDocumentInputStream(dirNode.GetEntry(setName));
                try
                {
                    // Create the Property Set
                    step = "creating";
                    return(PropertySetFactory.Create(dis));
                }
                finally
                {
                    dis.Close();
                }
            }
            catch (Exception e)
            {
                logger.Log(POILogger.WARN, "Error " + step + " property set with name " + setName, e);
                return(null);
            }
            finally
            {
                if (encPoifs != null)
                {
                    try
                    {
                        encPoifs.Close();
                    }
                    catch (IOException e)
                    {
                        logger.Log(POILogger.WARN, "Error closing encrypted property poifs", e);
                    }
                }
            }
        }