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);
        }
示例#3
0
        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);
                        }
                });
            }
        }