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(); } } } }
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 } }
/** * 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"); }
/** * 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); } }
/** * <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(); } } }
/** * 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(); } } }
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(); }
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(); }
public override void Close() { _stream.Close(); }
/** * 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"); }
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); }
public void Close() { _stream.Close(); }
/// <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); } } } }