Пример #1
0
        protected Stream GetCryptoStream(Stream plainStream)
        {
            if ((Header.CompressedSize == 0)

                && (Header.PkwareTraditionalEncryptionData != null))
            {
                throw new NotSupportedException("Cannot encrypt file with unknown size at start.");
            }
            if ((Header.CompressedSize == 0) &&
                FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor))
            {
                plainStream = new NonDisposingStream(plainStream); //make sure AES doesn't close
            }
            else
            {
                plainStream = new ReadOnlySubStream(plainStream, Header.CompressedSize); //make sure AES doesn't close
            }
            if (Header.PkwareTraditionalEncryptionData != null)
            {
                return(new PkwareTraditionalCryptoStream(plainStream, Header.PkwareTraditionalEncryptionData,
                                                         CryptoMode.Decrypt));
            }

            return(plainStream);
        }
Пример #2
0
        protected Stream GetCryptoStream(Stream plainStream)
        {
            if ((Header.CompressedSize == 0)
#if !PORTABLE && !NETFX_CORE
                && ((Header.PkwareTraditionalEncryptionData != null) ||
                    (Header.WinzipAesEncryptionData != null)))
#else
                && (Header.PkwareTraditionalEncryptionData != null))
#endif
            {
                throw new NotSupportedException("Cannot encrypt file with unknown size at start.");
            }
            if ((Header.CompressedSize == 0) &&
                FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor))
            {
                plainStream = new NonDisposingStream(plainStream); //make sure AES doesn't close
            }
            else
            {
                plainStream = new ReadOnlySubStream(plainStream, Header.CompressedSize); //make sure AES doesn't close
            }
            if (Header.PkwareTraditionalEncryptionData != null)
            {
                return(new PkwareTraditionalCryptoStream(plainStream, Header.PkwareTraditionalEncryptionData,
                                                         CryptoMode.Decrypt));
            }
#if !PORTABLE && !NETFX_CORE
            if (Header.WinzipAesEncryptionData != null)
            {
                //only read 10 less because the last ten are auth bytes
                return(new WinzipAesCryptoStream(plainStream, Header.WinzipAesEncryptionData, Header.CompressedSize - 10));
            }
#endif
            return(plainStream);
        }
Пример #3
0
        protected Stream GetCryptoStream(Stream plainStream)
        {
            bool isFileEncrypted = FlagUtility.HasFlag(Header.Flags, HeaderFlags.Encrypted);

            if (Header.CompressedSize == 0 && isFileEncrypted)
            {
                throw new NotSupportedException("Cannot encrypt file with unknown size at start.");
            }

            if ((Header.CompressedSize == 0 &&
                 FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor)) ||
                Header.IsZip64)
            {
                plainStream = new NonDisposingStream(plainStream); //make sure AES doesn't close
            }
            else
            {
                plainStream = new ReadOnlySubStream(plainStream, Header.CompressedSize); //make sure AES doesn't close
            }

            if (isFileEncrypted)
            {
                switch (Header.CompressionMethod)
                {
                case ZipCompressionMethod.None:
                case ZipCompressionMethod.Deflate:
                case ZipCompressionMethod.Deflate64:
                case ZipCompressionMethod.BZip2:
                case ZipCompressionMethod.LZMA:
                case ZipCompressionMethod.PPMd:
                {
                    return(new PkwareTraditionalCryptoStream(plainStream, Header.ComposeEncryptionData(plainStream), CryptoMode.Decrypt));
                }

                case ZipCompressionMethod.WinzipAes:
                {
#if !NO_FILE
                    if (Header.WinzipAesEncryptionData != null)
                    {
                        return(new WinzipAesCryptoStream(plainStream, Header.WinzipAesEncryptionData, Header.CompressedSize - 10));
                    }
#endif
                    return(plainStream);
                }

                default:
                {
                    throw new ArgumentOutOfRangeException();
                }
                }
            }

            return(plainStream);
        }
Пример #4
0
        public void ShouldReadSubSetOfTextStream()
        {
            //          01234567890123456
            var text = "Here is some text";

            var textBytes = Encoding.ASCII.GetBytes(text);

            using (var baseStream = new MemoryStream(textBytes))
                using (var subStream = new ReadOnlySubStream(baseStream, 5, 7))
                    using (var textReader = new StreamReader(subStream, Encoding.ASCII))
                    {
                        var actual = textReader.ReadLine();
                        Assert.That(actual, Is.EqualTo("is some"));
                    }
        }
Пример #5
0
        internal ArchiveFileStream Open(bool exclusive)
        {
            if (IsOpenedExclusively)
            {
                return(null);                                // file was already opened exclusively
            }
            Stream stream;

            if (exclusive)
            {
                if (Streams.Count > 0)
                {
                    return(null);                           // unable to obtain exclusive access
                }
                IsOpenedExclusively = true;                 // prevent others to access this file
                stream = new MemoryStream();
                if (IsDirty)
                {
                    if (NewData != null)
                    {
                        stream.Write(NewData, 0, NewData.Length);
                    }
                }
                else
                {
                    Archive.Stream.CopyRangeTo(stream, DataOffset, DataLength);
                }
            }
            else
            {
                if (IsDirty)
                {
                    stream = new MemoryStream(NewData, false);
                }
                else
                {
                    stream = new ReadOnlySubStream(Archive.Stream, DataOffset, DataLength);
                }
            }

            stream.Seek(0);
            Streams.Add(stream);
            return(new ArchiveFileStream(this, stream));
        }
Пример #6
0
        internal static Stream CreateDecoderStream(Stream inStream, long startPos, long[] packSizes, CFolder folderInfo, IPasswordProvider pass)
        {
            int num2;
            int num3;

            if (!folderInfo.CheckStructure())
            {
                throw new NotSupportedException("Unsupported stream binding structure.");
            }
            Stream[] packStreams = new Stream[folderInfo.PackStreams.Count];
            for (int i = 0; i < folderInfo.PackStreams.Count; i++)
            {
                packStreams[i] = new ReadOnlySubStream(inStream, new long?(startPos), packSizes[i]);
                startPos      += packSizes[i];
            }
            Stream[] outStreams = new Stream[folderInfo.UnpackSizes.Count];
            FindPrimaryOutStreamIndex(folderInfo, out num2, out num3);
            return(CreateDecoderStream(packStreams, packSizes, outStreams, folderInfo, num2, pass));
        }
Пример #7
0
        internal static Stream CreateDecoderStream(Stream inStream, long startPos, long[] packSizes, CFolder folderInfo,
                                                   IPasswordProvider pass)
        {
            if (!folderInfo.CheckStructure())
            {
                throw new NotSupportedException("Unsupported stream binding structure.");
            }

            Stream[] inStreams = new Stream[folderInfo.PackStreams.Count];
            for (int j = 0; j < folderInfo.PackStreams.Count; j++)
            {
                inStreams[j] = new ReadOnlySubStream(inStream, startPos, packSizes[j]);
                startPos    += packSizes[j];
            }

            Stream[] outStreams = new Stream[folderInfo.UnpackSizes.Count];

            int primaryCoderIndex, primaryOutStreamIndex;

            FindPrimaryOutStreamIndex(folderInfo, out primaryCoderIndex, out primaryOutStreamIndex);
            return(CreateDecoderStream(inStreams, packSizes, outStreams, folderInfo, primaryCoderIndex, pass));
        }
Пример #8
0
        private RarHeader ReadNextHeader(Stream stream)
        {
            FileHeader            header4;
            RarCryptoBinaryReader reader = new RarCryptoBinaryReader(stream, this.Password);

            if (this.IsEncrypted)
            {
                if (this.Password == null)
                {
                    throw new CryptographicException("Encrypted Rar archive has no password specified.");
                }
                reader.SkipQueue();
                byte[] salt = reader.ReadBytes(8);
                reader.InitializeAes(salt);
            }
            RarHeader header = RarHeader.Create(reader);

            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderType)
            {
            case HeaderType.MarkHeader:
                return(header.PromoteHeader <MarkHeader>(reader));

            case HeaderType.ArchiveHeader:
            {
                ArchiveHeader header2 = header.PromoteHeader <ArchiveHeader>(reader);
                this.IsEncrypted = header2.HasPassword;
                return(header2);
            }

            case HeaderType.FileHeader:
                header4 = header.PromoteHeader <FileHeader>(reader);
                switch (this.StreamingMode)
                {
                case SharpCompress.IO.StreamingMode.Streaming:
                {
                    ReadOnlySubStream actualStream = new ReadOnlySubStream(reader.BaseStream, header4.CompressedSize);
                    if (header4.Salt == null)
                    {
                        header4.PackedStream = actualStream;
                        return(header4);
                    }
                    header4.PackedStream = new RarCryptoWrapper(actualStream, this.Password, header4.Salt);
                    return(header4);
                }

                case SharpCompress.IO.StreamingMode.Seekable:
                {
                    header4.DataStartPosition = reader.BaseStream.Position;
                    Stream baseStream = reader.BaseStream;
                    baseStream.Position += header4.CompressedSize;
                    return(header4);
                }
                }
                throw new InvalidFormatException("Invalid StreamingMode");

            case HeaderType.ProtectHeader:
            {
                ProtectHeader header3 = header.PromoteHeader <ProtectHeader>(reader);
                switch (this.StreamingMode)
                {
                case SharpCompress.IO.StreamingMode.Streaming:
                    Utility.Skip(reader.BaseStream, (long)header3.DataSize);
                    return(header3);

                case SharpCompress.IO.StreamingMode.Seekable:
                {
                    Stream stream1 = reader.BaseStream;
                    stream1.Position += header3.DataSize;
                    return(header3);
                }
                }
                throw new InvalidFormatException("Invalid StreamingMode");
            }

            case HeaderType.NewSubHeader:
                header4 = header.PromoteHeader <FileHeader>(reader);
                switch (this.StreamingMode)
                {
                case SharpCompress.IO.StreamingMode.Streaming:
                    Utility.Skip(reader.BaseStream, header4.CompressedSize);
                    return(header4);

                case SharpCompress.IO.StreamingMode.Seekable:
                {
                    header4.DataStartPosition = reader.BaseStream.Position;
                    Stream stream3 = reader.BaseStream;
                    stream3.Position += header4.CompressedSize;
                    return(header4);
                }
                }
                throw new InvalidFormatException("Invalid StreamingMode");

            case HeaderType.EndArchiveHeader:
                return(header.PromoteHeader <EndArchiveHeader>(reader));
            }
            throw new InvalidFormatException("Invalid Rar Header: " + header.HeaderType.ToString());
        }
Пример #9
0
        private RarHeader ReadNextHeader(Stream stream)
        {
#if !NO_CRYPTO
            var reader = new RarCryptoBinaryReader(stream, Options.Password);

            if (IsEncrypted)
            {
                if (Options.Password == null)
                {
                    throw new CryptographicException("Encrypted Rar archive has no password specified.");
                }
                reader.SkipQueue();
                byte[] salt = reader.ReadBytes(8);
                reader.InitializeAes(salt);
            }
#else
            var reader = new MarkingBinaryReader(stream);
#endif

            RarHeader header = RarHeader.Create(reader);
            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderType)
            {
            case HeaderType.ArchiveHeader:
            {
                var ah = header.PromoteHeader <ArchiveHeader>(reader);
                IsEncrypted = ah.HasPassword;
                return(ah);
            }

            case HeaderType.MarkHeader:
            {
                return(header.PromoteHeader <MarkHeader>(reader));
            }

            case HeaderType.ProtectHeader:
            {
                ProtectHeader ph = header.PromoteHeader <ProtectHeader>(reader);

                // skip the recovery record data, we do not use it.
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    reader.BaseStream.Position += ph.DataSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    reader.BaseStream.Skip(ph.DataSize);
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }

                return(ph);
            }

            case HeaderType.NewSubHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    //skip the data because it's useless?
                    reader.BaseStream.Skip(fh.CompressedSize);
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderType.FileHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    var ms = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
                    if (fh.Salt == null)
                    {
                        fh.PackedStream = ms;
                    }
                    else
                    {
#if !NO_CRYPTO
                        fh.PackedStream = new RarCryptoWrapper(ms, Options.Password, fh.Salt);
#else
                        throw new NotSupportedException("RarCrypto not supported");
#endif
                    }
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderType.EndArchiveHeader:
            {
                return(header.PromoteHeader <EndArchiveHeader>(reader));
            }

            default:
            {
                throw new InvalidFormatException("Invalid Rar Header: " + header.HeaderType);
            }
            }
        }
Пример #10
0
        private Rar5Header ReadNextHeader(Stream stream)
        {
#if !NO_CRYPTO
            var reader = new Rar5CryptoBinaryReader(stream, Options.Password);

            if (IsEncrypted)
            {
                if (Options.Password == null)
                {
                    throw new CryptographicException("Encrypted Rar archive has no password specified.");
                }
                reader.SkipQueue();
                byte[] salt = reader.ReadBytes(16);
                reader.InitializeAes(salt);
            }
#else
            var reader = new RarCrcBinaryReader(stream);
#endif

            Rar5Header header = Rar5Header.Create(reader, Options.ArchiveEncoding);
            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderType)
            {
            case Rar5HeaderType.EncriptionHeader:
            {
                var eh = header.PromoteHeader <EncriptionHeader>(reader);
                IsEncrypted = true;
                return(eh);
            }

            case Rar5HeaderType.MainHeader:
            {
                var ah = header.PromoteHeader <MainHeader>(reader);
                return(ah);
            }

            case Rar5HeaderType.FileHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    var ms = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
                    if (fh.Salt == null)
                    {
                        fh.PackedStream = ms;
                    }
                    else
                    {
#if !NO_CRYPTO
                        fh.PackedStream = new RarCryptoWrapper(ms, Options.Password, fh.Salt);
#else
                        throw new NotSupportedException("RarCrypto not supported");
#endif
                    }
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case Rar5HeaderType.EndOfArchiveHeader:
            {
                return(header.PromoteHeader <EndArchiveHeader>(reader));
            }

            default:
            {
                throw new InvalidFormatException("Invalid Rar Header: " + header.HeaderType);
            }
            }
        }
Пример #11
0
        private RarHeader ReadNextHeader(Stream stream)
        {
            MarkingBinaryReader reader = new MarkingBinaryReader(stream);
            RarHeader           header = RarHeader.Create(reader);

            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderType)
            {
            case HeaderType.ArchiveHeader:
            {
                return(header.PromoteHeader <ArchiveHeader>(reader));
            }

            case HeaderType.MarkHeader:
            {
                return(header.PromoteHeader <MarkHeader>(reader));
            }

            case HeaderType.NewSubHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    //skip the data because it's useless?
                    reader.BaseStream.Skip(fh.CompressedSize);
                }
                break;

                default:
                {
                    throw new InvalidRarFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderType.FileHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    ReadOnlySubStream ms
                                    = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
                    fh.PackedStream = ms;
                }
                break;

                default:
                {
                    throw new InvalidRarFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderType.EndArchiveHeader:
            {
                return(header.PromoteHeader <EndArchiveHeader>(reader));
            }

            default:
            {
                throw new InvalidRarFormatException("Invalid Rar Header: " + header.HeaderType.ToString());
            }
            }
        }
Пример #12
0
        private RarHeader TryReadNextHeader(Stream stream)
        {
            RarCrcBinaryReader reader;

            if (!IsEncrypted)
            {
                reader = new RarCrcBinaryReader(stream);
            }
            else
            {
                if (Options.Password == null)
                {
                    throw new CryptographicException("Encrypted Rar archive has no password specified.");
                }
                reader = new RarCryptoBinaryReader(stream, Options.Password);
            }

            var header = RarHeader.TryReadBase(reader, _isRar5, Options.ArchiveEncoding);

            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderCode)
            {
            case HeaderCodeV.RAR5_ARCHIVE_HEADER:
            case HeaderCodeV.RAR4_ARCHIVE_HEADER:
            {
                var ah = new ArchiveHeader(header, reader);
                if (ah.IsEncrypted == true)
                {
                    //!!! rar5 we don't know yet
                    IsEncrypted = true;
                }
                return(ah);
            }

            case HeaderCodeV.RAR4_PROTECT_HEADER:
            {
                var ph = new ProtectHeader(header, reader);
                // skip the recovery record data, we do not use it.
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    reader.BaseStream.Position += ph.DataSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    reader.BaseStream.Skip(ph.DataSize);
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }

                return(ph);
            }

            case HeaderCodeV.RAR5_SERVICE_HEADER:
            {
                var fh = new FileHeader(header, reader, HeaderType.Service);
                SkipData(fh, reader);
                return(fh);
            }

            case HeaderCodeV.RAR4_NEW_SUB_HEADER:
            {
                var fh = new FileHeader(header, reader, HeaderType.NewSub);
                SkipData(fh, reader);
                return(fh);
            }

            case HeaderCodeV.RAR5_FILE_HEADER:
            case HeaderCodeV.RAR4_FILE_HEADER:
            {
                var fh = new FileHeader(header, reader, HeaderType.File);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    var ms = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
                    if (fh.R4Salt == null)
                    {
                        fh.PackedStream = ms;
                    }
                    else
                    {
                        fh.PackedStream = new RarCryptoWrapper(ms, Options.Password, fh.R4Salt);
                    }
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderCodeV.RAR5_END_ARCHIVE_HEADER:
            case HeaderCodeV.RAR4_END_ARCHIVE_HEADER:
            {
                return(new EndArchiveHeader(header, reader));
            }

            case HeaderCodeV.RAR5_ARCHIVE_ENCRYPTION_HEADER:
            {
                var ch = new ArchiveCryptHeader(header, reader);
                IsEncrypted = true;
                return(ch);
            }

            default:
            {
                throw new InvalidFormatException("Unknown Rar Header: " + header.HeaderCode);
            }
            }
        }
Пример #13
0
        private RarHeader TryReadNextHeader(Stream stream)
        {
            RarCrcBinaryReader reader;

            if (!IsEncrypted)
            {
                reader = new RarCrcBinaryReader(stream);
            }
            else
            {
#if !NO_CRYPTO
                if (Options.Password == null)
                {
                    throw new CryptographicException("Encrypted Rar archive has no password specified.");
                }
                reader = new RarCryptoBinaryReader(stream, Options.Password);
#else
                throw new CryptographicException("Rar encryption unsupported on this platform");
#endif
            }

            var header = RarHeader.TryReadBase(reader, this.isRar5, Options.ArchiveEncoding);
            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderCode)
            {
            case HeaderCodeV.Rar5ArchiveHeader:
            case HeaderCodeV.Rar4ArchiveHeader:
            {
                var ah = new ArchiveHeader(header, reader);
                if (ah.IsEncrypted == true)
                {
                    //!!! rar5 we don't know yet
                    IsEncrypted = true;
                }
                return(ah);
            }

            case HeaderCodeV.Rar4ProtectHeader:
            {
                var ph = new ProtectHeader(header, reader);
                // skip the recovery record data, we do not use it.
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    reader.BaseStream.Position += ph.DataSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    reader.BaseStream.Skip(ph.DataSize);
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }

                return(ph);
            }

            case HeaderCodeV.Rar5ServiceHeader:
            {
                var fh = new FileHeader(header, reader, HeaderType.Service);
                SkipData(fh, reader);
                return(fh);
            }

            case HeaderCodeV.Rar4NewSubHeader:
            {
                var fh = new FileHeader(header, reader, HeaderType.NewSub);
                SkipData(fh, reader);
                return(fh);
            }

            case HeaderCodeV.Rar5FileHeader:
            case HeaderCodeV.Rar4FileHeader:
            {
                var fh = new FileHeader(header, reader, HeaderType.File);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    var ms = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
                    if (fh.R4Salt == null)
                    {
                        fh.PackedStream = ms;
                    }
                    else
                    {
#if !NO_CRYPTO
                        fh.PackedStream = new RarCryptoWrapper(ms, Options.Password, fh.R4Salt);
#else
                        throw new NotSupportedException("RarCrypto not supported");
#endif
                    }
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderCodeV.Rar5EndArchiveHeader:
            case HeaderCodeV.Rar4EndArchiveHeader:
            {
                return(new EndArchiveHeader(header, reader));
            }

            case HeaderCodeV.Rar5ArchiveEncryptionHeader:
            {
                var ch = new ArchiveCryptHeader(header, reader);
                IsEncrypted = true;
                return(ch);
            }

            default:
            {
                throw new InvalidFormatException("Unknown Rar Header: " + header.HeaderCode);
            }
            }
        }
Пример #14
0
        private RarHeader ReadNextHeader(Stream stream)
        {
#if PORTABLE
            var reader = new MarkingBinaryReader(stream);
#else
            var reader = new RarCryptoBinaryReader(stream, Password);

            if (IsEncrypted)
            {
                reader.SkipQueue();
                byte[] salt = reader.ReadBytes(8);
                reader.InitializeAes(salt);
            }
#endif

            RarHeader header = RarHeader.Create(reader);
            if (header == null)
            {
                return(null);
            }
            switch (header.HeaderType)
            {
            case HeaderType.ArchiveHeader:
            {
                var ah = header.PromoteHeader <ArchiveHeader>(reader);
                IsEncrypted = ah.HasPassword;
                return(ah);
            }

            case HeaderType.MarkHeader:
            {
                return(header.PromoteHeader <MarkHeader>(reader));
            }

            case HeaderType.NewSubHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    //skip the data because it's useless?
                    reader.BaseStream.Skip(fh.CompressedSize);
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderType.FileHeader:
            {
                FileHeader fh = header.PromoteHeader <FileHeader>(reader);
                switch (StreamingMode)
                {
                case StreamingMode.Seekable:
                {
                    fh.DataStartPosition        = reader.BaseStream.Position;
                    reader.BaseStream.Position += fh.CompressedSize;
                }
                break;

                case StreamingMode.Streaming:
                {
                    var ms = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
                    if (fh.Salt == null)
                    {
                        fh.PackedStream = ms;
                    }
                    else
                    {
#if PORTABLE
                        throw new NotSupportedException("Encrypted Rar files aren't supported in portable distro.");
#else
                        fh.PackedStream = new RarCryptoWrapper(ms, Password, fh.Salt);
#endif
                    }
                }
                break;

                default:
                {
                    throw new InvalidFormatException("Invalid StreamingMode");
                }
                }
                return(fh);
            }

            case HeaderType.EndArchiveHeader:
            {
                return(header.PromoteHeader <EndArchiveHeader>(reader));
            }

            default:
            {
                throw new InvalidFormatException("Invalid Rar Header: " + header.HeaderType.ToString());
            }
            }
        }