public ProtectHeader(RarHeader header, RarCrcBinaryReader reader) : base(header, reader, HeaderType.Protect) { if (IsRar5) { throw new InvalidFormatException("unexpected rar5 record"); } }
internal static RarHeader?TryReadBase(RarCrcBinaryReader reader, bool isRar5, ArchiveEncoding archiveEncoding) { try { return(new RarHeader(reader, isRar5, archiveEncoding)); } catch (EndOfStreamException) { return(null); } }
private void ReadStartFromReader(RarCrcBinaryReader reader) { HeadCRC = reader.ReadUInt16(); reader.ResetCrc(); HeaderType = (HeaderType)(reader.ReadByte() & 0xff); Flags = reader.ReadInt16(); HeaderSize = reader.ReadInt16(); if (FlagUtility.HasFlag(Flags, LONG_BLOCK)) { AdditionalSize = reader.ReadUInt32(); } }
internal static RarHeader Create(RarCrcBinaryReader reader) { try { RarHeader header = new RarHeader(); reader.Mark(); header.ReadStartFromReader(reader); header.ReadBytes += reader.CurrentReadByteCount; return(header); } catch (EndOfStreamException) { return(null); } }
private void SkipData(FileHeader fh, RarCrcBinaryReader 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"); } } }
internal static RarHeader Create(RarCrcBinaryReader reader, ArchiveEncoding archiveEncoding) { try { RarHeader header = new RarHeader(); header.ArchiveEncoding = archiveEncoding; reader.Mark(); header.ReadStartFromReader(reader); header.ReadBytes += reader.CurrentReadByteCount; return header; } catch (EndOfStreamException) { return null; } }
internal T PromoteHeader<T>(RarCrcBinaryReader reader) where T : RarHeader, new() { T header = new T(); header.FillBase(this); reader.Mark(); header.ReadFromReader(reader); header.ReadBytes += reader.CurrentReadByteCount; int headerSizeDiff = header.HeaderSize - (int)header.ReadBytes; if (headerSizeDiff > 0) { reader.ReadBytes(headerSizeDiff); } VerifyHeaderCrc(reader.GetCrc()); return header; }
protected RarHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType) { _headerType = headerType; _isRar5 = header.IsRar5; HeaderCrc = header.HeaderCrc; HeaderCode = header.HeaderCode; HeaderFlags = header.HeaderFlags; HeaderSize = header.HeaderSize; ExtraSize = header.ExtraSize; AdditionalDataSize = header.AdditionalDataSize; ArchiveEncoding = header.ArchiveEncoding; ReadFinish(reader); int n = RemainingHeaderBytes(reader); if (n > 0) { reader.ReadBytes(n); } VerifyHeaderCrc(reader.GetCrc32()); }
private RarHeader(RarCrcBinaryReader reader, bool isRar5, ArchiveEncoding archiveEncoding) { _headerType = HeaderType.Null; _isRar5 = isRar5; ArchiveEncoding = archiveEncoding; if (IsRar5) { HeaderCrc = reader.ReadUInt32(); reader.ResetCrc(); HeaderSize = (int)reader.ReadRarVIntUInt32(3); reader.Mark(); HeaderCode = reader.ReadRarVIntByte(); HeaderFlags = reader.ReadRarVIntUInt16(2); if (HasHeaderFlag(HeaderFlagsV5.HAS_EXTRA)) { ExtraSize = reader.ReadRarVIntUInt32(); } if (HasHeaderFlag(HeaderFlagsV5.HAS_DATA)) { AdditionalDataSize = (long)reader.ReadRarVInt(); } } else { reader.Mark(); HeaderCrc = reader.ReadUInt16(); reader.ResetCrc(); HeaderCode = reader.ReadByte(); HeaderFlags = reader.ReadUInt16(); HeaderSize = reader.ReadInt16(); if (HasHeaderFlag(HeaderFlagsV4.HAS_DATA)) { AdditionalDataSize = reader.ReadUInt32(); } } }
public ArchiveHeader(RarHeader header, RarCrcBinaryReader reader) : base(header, reader, HeaderType.Archive) { }
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); } } }
public FileHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType) : base(header, reader, headerType) { }
public ArchiveCryptHeader(RarHeader header, RarCrcBinaryReader reader) : base(header, reader, HeaderType.Crypt) { }
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); } } }
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 RarCrcBinaryReader(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); } } }
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); } } }