void WriteToPOIFS() { int oleStreamSize = (int)(fileOut.Length + LittleEndianConsts.LONG_SIZE); dir.CreateDocument(DEFAULT_POIFS_ENTRY, oleStreamSize, this); // TODO: any properties??? }
/** * 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"); }