private static bool TryGetEncryptedPackage(Stream fileStream, CompoundDocument document, string password, out Stream stream) { var encryptedPackage = document.FindEntry(DirectoryEntryEncryptedPackage); var encryptionInfo = document.FindEntry(DirectoryEntryEncryptionInfo); if (encryptedPackage == null || encryptionInfo == null) { stream = null; return(false); } var infoBytes = document.ReadStream(fileStream, encryptionInfo.StreamFirstSector, (int)encryptionInfo.StreamSize, encryptionInfo.IsEntryMiniStream); var encryption = EncryptionInfo.Create(infoBytes); if (encryption.VerifyPassword("VelvetSweatshop")) { // Magic password used for write-protected workbooks password = "******"; } else if (password == null || !encryption.VerifyPassword(password)) { throw new InvalidPasswordException(Errors.ErrorInvalidPassword); } var secretKey = encryption.GenerateSecretKey(password); var packageStream = new CompoundStream(document, fileStream, encryptedPackage.StreamFirstSector, (int)encryptedPackage.StreamSize, encryptedPackage.IsEntryMiniStream, false); stream = encryption.CreateEncryptedPackageStream(packageStream, secretKey); return(true); }
private static bool TryGetWorkbook(Stream fileStream, CompoundDocument document, out Stream stream) { var workbookEntry = document.FindEntry(DirectoryEntryWorkbook) ?? document.FindEntry(DirectoryEntryBook); if (workbookEntry != null) { if (workbookEntry.EntryType != STGTY.STGTY_STREAM) { throw new ExcelReaderException(Errors.ErrorWorkbookIsNotStream); } stream = new CompoundStream(document, fileStream, workbookEntry.StreamFirstSector, (int)workbookEntry.StreamSize, workbookEntry.IsEntryMiniStream, false); return(true); } stream = null; return(false); }
public void CompoundStreamZiplikeRoundTripTest() { // File with the same size as write byte GenerateRandomFile(CheckBytesUsingReadBufferSize); // Test some common powers of two GenerateRandomFile(1024); GenerateRandomFile(2048); GenerateRandomFile(4096); // Test boundary conditions around block size GenerateRandomFile(CompoundStream.DefaultBlockSize); GenerateRandomFile(CompoundStream.DefaultBlockSize * 2); GenerateRandomFile(CompoundStream.DefaultBlockSize * 4); GenerateRandomFile(CompoundStream.DefaultBlockSize - 1); GenerateRandomFile(CompoundStream.DefaultBlockSize + 1); // Zero length file GenerateRandomFile(0); // Single byte file GenerateRandomFile(1); // Large file test GenerateRandomFile(CompoundStream.DefaultBlockSize * 16 + 3243); var allFiles = m_fileSystem.Keys.ToArray(); var fileIdMap = new ConcurrentDictionary <string, int>(StringComparer.OrdinalIgnoreCase); var filesWithIds = new BlockingCollection <string>(); var zipLikePath = "ZipLikeCompoundStream"; using (var zipLikeFileStream = new MemoryStream()) { using (var zipLikeStream = CompoundStream.OpenWrite(zipLikeFileStream)) { var directoryWriteTask = Task.Run(() => { using (var listingStream = zipLikeStream.InitialPartStream) using (var writer = new BinaryWriter(listingStream)) { writer.Write(allFiles.Length); foreach (var file in filesWithIds.GetConsumingEnumerable()) { writer.Write(file); writer.Write(fileIdMap[file]); } } }); Parallel.ForEach(allFiles, file => { using (var filePartStream = zipLikeStream.CreateWritePartStream(4096)) using (var fileStream = OpenRead(file)) { fileIdMap[file] = filePartStream.Index; filesWithIds.Add(file); fileStream.CopyTo(filePartStream); } }); filesWithIds.CompleteAdding(); directoryWriteTask.GetAwaiter().GetResult(); } m_fileSystem[zipLikePath] = zipLikeFileStream.ToArray().ToReadOnlyArray(); } var readFileIdMap = new ConcurrentDictionary <string, int>(StringComparer.OrdinalIgnoreCase); var readFilesWithIds = new BlockingCollection <string>(); using (var zipLikeStream = CompoundStream.OpenRead(() => OpenRead(zipLikePath))) { var listingReadTask = Task.Run(() => { using (var listingStream = zipLikeStream.InitialPartStream) using (var reader = new BinaryReader(listingStream)) { var fileCount = reader.ReadInt32(); for (int i = 0; i < fileCount; i++) { var file = reader.ReadString(); var fileId = reader.ReadInt32(); readFileIdMap[file] = fileId; readFilesWithIds.Add(file); } readFilesWithIds.CompleteAdding(); } }); Parallel.ForEach(readFilesWithIds.GetConsumingEnumerable(), file => { using (var filePartStream = zipLikeStream.OpenReadPartStream(readFileIdMap[file])) using (var fileContentsStream = new MemoryStream((int)filePartStream.Length)) { if (file.GetHashCode() % 2 == 1) { CheckBytesUsingCopyTo(filePartStream, file); } else { CheckBytesUsingRead(filePartStream, file); } filePartStream.CopyTo(fileContentsStream); } }); } }