protected override void ReadFinish(MarkingBinaryReader reader) { var cryptVersion = reader.ReadRarVIntUInt32(); if (cryptVersion > CRYPT_VERSION) { //error? return; } var encryptionFlags = reader.ReadRarVIntUInt32(); _usePswCheck = FlagUtility.HasFlag(encryptionFlags, EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK); _lg2Count = reader.ReadRarVIntByte(1); //UsePswCheck = HasHeaderFlag(EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK); if (_lg2Count > CRYPT5_KDF_LG2_COUNT_MAX) { //error? return; } _salt = reader.ReadBytes(SIZE_SALT50); if (_usePswCheck) { _pswCheck = reader.ReadBytes(SIZE_PSWCHECK); _pswCheckCsm = reader.ReadBytes(SIZE_PSWCHECK_CSUM); } }
protected override void ReadFromReader(MarkingBinaryReader reader) { EncriptionVersion = reader.ReadVInt(); EncriptionFlags = reader.ReadVInt(); KdfCount = reader.ReadByte(); Salt = reader.ReadBytes(16); if (PasswordCheckDataIsPresent) { CheckValue = reader.ReadBytes(12); } }
protected override void ReadFromReader(MarkingBinaryReader reader) { Version = reader.ReadByte(); RecSectors = reader.ReadUInt16(); TotalBlocks = reader.ReadUInt32(); Mark = reader.ReadBytes(8); }
internal override void Read(MarkingBinaryReader reader) { Version = reader.ReadUInt16(); Flags = reader.ReadUInt16(); CompressionMethod = reader.ReadUInt16(); LastModifiedTime = reader.ReadUInt16(); LastModifiedDate = reader.ReadUInt16(); Crc = reader.ReadUInt32(); CompressedSize = reader.ReadUInt32(); UncompressedSize = reader.ReadUInt32(); ushort nameLength = reader.ReadUInt16(); ushort extraLength = reader.ReadUInt16(); byte[] name = reader.ReadBytes(nameLength); Extra = reader.ReadBytes(extraLength); Name = DefaultEncoding.GetString(name, 0, name.Length); }
internal override void Read(MarkingBinaryReader reader) { VolumeNumber = reader.ReadUInt16(); FirstVolumeWithDirectory = reader.ReadUInt16(); TotalNumberOfEntriesInDisk = reader.ReadUInt16(); TotalNumberOfEntries = reader.ReadUInt16(); DirectorySize = reader.ReadUInt32(); DirectoryStartOffsetRelativeToDisk = reader.ReadUInt32(); CommentLength = reader.ReadUInt16(); Comment = reader.ReadBytes(CommentLength); }
internal override void Read(MarkingBinaryReader reader) { Version = reader.ReadUInt16(); VersionNeededToExtract = reader.ReadUInt16(); Flags = reader.ReadUInt16(); CompressionMethod = reader.ReadUInt16(); LastModifiedTime = reader.ReadUInt16(); LastModifiedDate = reader.ReadUInt16(); Crc = reader.ReadUInt32(); CompressedSize = reader.ReadUInt32(); UncompressedSize = reader.ReadUInt32(); ushort nameLength = reader.ReadUInt16(); ushort extraLength = reader.ReadUInt16(); ushort commentLength = reader.ReadUInt16(); DiskNumberStart = reader.ReadUInt16(); InternalFileAttributes = reader.ReadUInt16(); ExternalFileAttributes = reader.ReadUInt32(); RelativeOffsetOfEntryHeader = reader.ReadUInt32(); Name = DefaultEncoding.GetString(reader.ReadBytes(nameLength)); Extra = reader.ReadBytes(extraLength); Comment = reader.ReadBytes(commentLength); }
internal T PromoteHeader <T>(MarkingBinaryReader reader) where T : RarHeader, new() { T local = Activator.CreateInstance <T>(); local.FillBase(this); reader.Mark(); local.ReadFromReader(reader); local.ReadBytes += reader.CurrentReadByteCount; int count = local.HeaderSize - ((int)local.ReadBytes); if (count > 0) { reader.ReadBytes(count); } return(local); }
internal T PromoteHeader <T>(MarkingBinaryReader 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); } return(header); }
protected override void ReadFromReader(MarkingBinaryReader reader) { uint lowUncompressedSize = reader.ReadUInt32(); HostOS = (HostOS)(int)reader.ReadByte(); FileCRC = reader.ReadUInt32(); FileLastModifiedTime = Utility.DosDateToDateTime(reader.ReadInt32()); RarVersion = reader.ReadByte(); PackingMethod = reader.ReadByte(); short nameSize = reader.ReadInt16(); FileAttributes = reader.ReadInt32(); uint highCompressedSize = 0; uint highUncompressedkSize = 0; if (FileFlags.HasFlag(FileFlags.LARGE)) { highCompressedSize = reader.ReadUInt32(); highUncompressedkSize = reader.ReadUInt32(); } else { if (lowUncompressedSize == 0xffffffff) { lowUncompressedSize = 0xffffffff; highUncompressedkSize = int.MaxValue; } } CompressedSize = UInt32To64(highCompressedSize, AdditionalSize); UncompressedSize = UInt32To64(highUncompressedkSize, lowUncompressedSize); nameSize = nameSize > 4 * 1024 ? (short)(4 * 1024) : nameSize; byte[] fileNameBytes = reader.ReadBytes(nameSize); switch (HeaderType) { case HeaderType.FileHeader: { if (FileFlags.HasFlag(FileFlags.UNICODE)) { int length = 0; while (length < fileNameBytes.Length && fileNameBytes[length] != 0) { length++; } if (length != nameSize) { length++; FileName = FileNameDecoder.Decode(fileNameBytes, length); } else { FileName = DecodeDefault(fileNameBytes); } } else { FileName = DecodeDefault(fileNameBytes); } FileName = ConvertPath(FileName, HostOS); } break; case HeaderType.NewSubHeader: { int datasize = HeaderSize - NEWLHD_SIZE - nameSize; if (FileFlags.HasFlag(FileFlags.SALT)) { datasize -= SALT_SIZE; } if (datasize > 0) { SubData = reader.ReadBytes(datasize); } if (NewSubHeaderType.SUBHEAD_TYPE_RR.Equals(fileNameBytes)) { RecoverySectors = SubData[8] + (SubData[9] << 8) + (SubData[10] << 16) + (SubData[11] << 24); } } break; } if (FileFlags.HasFlag(FileFlags.SALT)) { Salt = reader.ReadBytes(SALT_SIZE); } if (FileFlags.HasFlag(FileFlags.EXTTIME)) { ushort extendedFlags = reader.ReadUInt16(); FileLastModifiedTime = ProcessExtendedTime(extendedFlags, FileLastModifiedTime, reader, 0); FileCreatedTime = ProcessExtendedTime(extendedFlags, null, reader, 1); FileLastAccessedTime = ProcessExtendedTime(extendedFlags, null, reader, 2); FileArchivedTime = ProcessExtendedTime(extendedFlags, null, reader, 3); } }
protected override void ReadFromReader(MarkingBinaryReader reader) { uint y = reader.ReadUInt32(); this.HostOS = (SharpCompress.Common.Rar.Headers.HostOS)reader.ReadByte(); this.FileCRC = reader.ReadUInt32(); this.FileLastModifiedTime = new DateTime?(Utility.DosDateToDateTime(reader.ReadInt32())); this.RarVersion = reader.ReadByte(); this.PackingMethod = reader.ReadByte(); short count = reader.ReadInt16(); this.FileAttributes = reader.ReadInt32(); uint x = 0; uint num4 = 0; if (this.FileFlags_HasFlag(SharpCompress.Common.Rar.Headers.FileFlags.LARGE)) { x = reader.ReadUInt32(); num4 = reader.ReadUInt32(); } else if (y == uint.MaxValue) { y = uint.MaxValue; num4 = 0x7fffffff; } this.CompressedSize = this.UInt32To64(x, base.AdditionalSize); this.UncompressedSize = this.UInt32To64(num4, y); count = (count > 0x1000) ? ((short)0x1000) : count; byte[] name = reader.ReadBytes(count); switch (base.HeaderType) { case HeaderType.FileHeader: if (this.FileFlags_HasFlag(SharpCompress.Common.Rar.Headers.FileFlags.UNICODE)) { int index = 0; while ((index < name.Length) && (name[index] != 0)) { index++; } if (index != count) { index++; this.FileName = FileNameDecoder.Decode(name, index); } else { this.FileName = this.DecodeDefault(name); } } else { this.FileName = this.DecodeDefault(name); } this.FileName = ConvertPath(this.FileName, this.HostOS); break; case HeaderType.NewSubHeader: { int num6 = (base.HeaderSize - 0x20) - count; if (this.FileFlags_HasFlag(SharpCompress.Common.Rar.Headers.FileFlags.SALT)) { num6 -= 8; } if (num6 > 0) { this.SubData = reader.ReadBytes(num6); } if (NewSubHeaderType.SUBHEAD_TYPE_RR.Equals(name)) { this.RecoverySectors = ((this.SubData[8] + (this.SubData[9] << 8)) + (this.SubData[10] << 0x10)) + (this.SubData[11] << 0x18); } break; } } if (this.FileFlags_HasFlag(SharpCompress.Common.Rar.Headers.FileFlags.SALT)) { this.Salt = reader.ReadBytes(8); } if (this.FileFlags_HasFlag(SharpCompress.Common.Rar.Headers.FileFlags.EXTTIME) && ((base.ReadBytes + reader.CurrentReadByteCount) <= (base.HeaderSize - 2))) { ushort extendedFlags = reader.ReadUInt16(); this.FileLastModifiedTime = ProcessExtendedTime(extendedFlags, this.FileLastModifiedTime, reader, 0); DateTime?time = null; this.FileCreatedTime = ProcessExtendedTime(extendedFlags, time, reader, 1); time = null; this.FileLastAccessedTime = ProcessExtendedTime(extendedFlags, time, reader, 2); this.FileArchivedTime = ProcessExtendedTime(extendedFlags, null, reader, 3); } }
private void ReadFromReaderV5(MarkingBinaryReader reader) { Flags = reader.ReadRarVIntUInt16(); var lvalue = checked ((long)reader.ReadRarVInt()); // long.MaxValue causes the unpack code to finish when the input stream is exhausted UncompressedSize = HasFlag(FileFlagsV5.UNPACKED_SIZE_UNKNOWN) ? long.MaxValue : lvalue; FileAttributes = reader.ReadRarVIntUInt32(); if (HasFlag(FileFlagsV5.HAS_MOD_TIME)) { FileLastModifiedTime = Utility.UnixTimeToDateTime(reader.ReadUInt32()); } if (HasFlag(FileFlagsV5.HAS_CRC32)) { FileCrc = reader.ReadUInt32(); } var compressionInfo = reader.ReadRarVIntUInt16(); // Lower 6 bits (0x003f mask) contain the version of compression algorithm, resulting in possible 0 - 63 values. Current version is 0. // "+ 50" to not mix with old RAR format algorithms. For example, // we may need to use the compression algorithm 15 in the future, // but it was already used in RAR 1.5 and Unpack needs to distinguish // them. CompressionAlgorithm = (byte)((compressionInfo & 0x3f) + 50); // 7th bit (0x0040) defines the solid flag. If it is set, RAR continues to use the compression dictionary left after processing preceding files. // It can be set only for file headers and is never set for service headers. IsSolid = (compressionInfo & 0x40) == 0x40; // Bits 8 - 10 (0x0380 mask) define the compression method. Currently only values 0 - 5 are used. 0 means no compression. CompressionMethod = (byte)((compressionInfo >> 7) & 0x7); // Bits 11 - 14 (0x3c00) define the minimum size of dictionary size required to extract data. Value 0 means 128 KB, 1 - 256 KB, ..., 14 - 2048 MB, 15 - 4096 MB. WindowSize = IsDirectory ? 0 : ((size_t)0x20000) << ((compressionInfo >> 10) & 0xf); HostOs = reader.ReadRarVIntByte(); var nameSize = reader.ReadRarVIntUInt16(); // Variable length field containing Name length bytes in UTF-8 format without trailing zero. // For file header this is a name of archived file. Forward slash character is used as the path separator both for Unix and Windows names. // Backslashes are treated as a part of name for Unix names and as invalid character for Windows file names. Type of name is defined by Host OS field. // // TODO: not sure if anything needs to be done to handle the following: // If Unix file name contains any high ASCII characters which cannot be correctly converted to Unicode and UTF-8 // we map such characters to to 0xE080 - 0xE0FF private use Unicode area and insert 0xFFFE Unicode non-character // to resulting string to indicate that it contains mapped characters, which need to be converted back when extracting. // Concrete position of 0xFFFE is not defined, we need to search the entire string for it. Such mapped names are not // portable and can be correctly unpacked only on the same system where they were created. // // For service header this field contains a name of service header. Now the following names are used: // CMT Archive comment // QO Archive quick open data // ACL NTFS file permissions // STM NTFS alternate data stream // RR Recovery record var b = reader.ReadBytes(nameSize); FileName = ConvertPathV5(Encoding.UTF8.GetString(b, 0, b.Length)); // extra size seems to be redudant since we know the total header size if (ExtraSize != RemainingHeaderBytes(reader)) { throw new InvalidFormatException("rar5 header size / extra size inconsistency"); } isEncryptedRar5 = false; while (RemainingHeaderBytes(reader) > 0) { var size = reader.ReadRarVIntUInt16(); int n = RemainingHeaderBytes(reader); var type = reader.ReadRarVIntUInt16(); switch (type) { //TODO case 1: // file encryption { isEncryptedRar5 = true; //var version = reader.ReadRarVIntByte(); //if (version != 0) throw new InvalidFormatException("unknown encryption algorithm " + version); } break; // case 2: // file hash // { // // } // break; case 3: // file time { ushort flags = reader.ReadRarVIntUInt16(); var isWindowsTime = (flags & 1) == 0; if ((flags & 0x2) == 0x2) { FileLastModifiedTime = ReadExtendedTimeV5(reader, isWindowsTime); } if ((flags & 0x4) == 0x4) { FileCreatedTime = ReadExtendedTimeV5(reader, isWindowsTime); } if ((flags & 0x8) == 0x8) { FileLastAccessedTime = ReadExtendedTimeV5(reader, isWindowsTime); } } break; //TODO // case 4: // file version // { // // } // break; // case 5: // file system redirection // { // // } // break; // case 6: // unix owner // { // // } // break; // case 7: // service data // { // // } // break; default: // skip unknown record types to allow new record types to be added in the future break; } // drain any trailing bytes of extra record int did = n - RemainingHeaderBytes(reader); int drain = size - did; if (drain > 0) { reader.ReadBytes(drain); } } if (AdditionalDataSize != 0) { CompressedSize = AdditionalDataSize; } }
private void ReadFromReaderV4(MarkingBinaryReader reader) { Flags = HeaderFlags; IsSolid = HasFlag(FileFlagsV4.SOLID); WindowSize = IsDirectory ? 0U : ((size_t)0x10000) << ((Flags & FileFlagsV4.WINDOW_MASK) >> 5); uint lowUncompressedSize = reader.ReadUInt32(); HostOs = reader.ReadByte(); FileCrc = reader.ReadUInt32(); FileLastModifiedTime = Utility.DosDateToDateTime(reader.ReadUInt32()); CompressionAlgorithm = reader.ReadByte(); CompressionMethod = (byte)(reader.ReadByte() - 0x30); short nameSize = reader.ReadInt16(); FileAttributes = reader.ReadUInt32(); uint highCompressedSize = 0; uint highUncompressedkSize = 0; if (HasFlag(FileFlagsV4.LARGE)) { highCompressedSize = reader.ReadUInt32(); highUncompressedkSize = reader.ReadUInt32(); } else { if (lowUncompressedSize == 0xffffffff) { lowUncompressedSize = 0xffffffff; highUncompressedkSize = int.MaxValue; } } CompressedSize = UInt32To64(highCompressedSize, checked ((uint)AdditionalDataSize)); UncompressedSize = UInt32To64(highUncompressedkSize, lowUncompressedSize); nameSize = nameSize > 4 * 1024 ? (short)(4 * 1024) : nameSize; byte[] fileNameBytes = reader.ReadBytes(nameSize); const int saltSize = 8; const int newLhdSize = 32; switch (HeaderCode) { case HeaderCodeV.RAR4_FILE_HEADER: { if (HasFlag(FileFlagsV4.UNICODE)) { int length = 0; while (length < fileNameBytes.Length && fileNameBytes[length] != 0) { length++; } if (length != nameSize) { length++; FileName = FileNameDecoder.Decode(fileNameBytes, length); } else { FileName = ArchiveEncoding.Decode(fileNameBytes); } } else { FileName = ArchiveEncoding.Decode(fileNameBytes); } FileName = ConvertPathV4(FileName); } break; case HeaderCodeV.RAR4_NEW_SUB_HEADER: { int datasize = HeaderSize - newLhdSize - nameSize; if (HasFlag(FileFlagsV4.SALT)) { datasize -= saltSize; } if (datasize > 0) { SubData = reader.ReadBytes(datasize); } if (NewSubHeaderType.SUBHEAD_TYPE_RR.Equals(fileNameBytes)) { RecoverySectors = SubData[8] + (SubData[9] << 8) + (SubData[10] << 16) + (SubData[11] << 24); } } break; } if (HasFlag(FileFlagsV4.SALT)) { R4Salt = reader.ReadBytes(saltSize); } if (HasFlag(FileFlagsV4.EXT_TIME)) { // verify that the end of the header hasn't been reached before reading the Extended Time. // some tools incorrectly omit Extended Time despite specifying FileFlags.EXTTIME, which most parsers tolerate. if (RemainingHeaderBytes(reader) >= 2) { ushort extendedFlags = reader.ReadUInt16(); FileLastModifiedTime = ProcessExtendedTimeV4(extendedFlags, FileLastModifiedTime, reader, 0); FileCreatedTime = ProcessExtendedTimeV4(extendedFlags, null, reader, 1); FileLastAccessedTime = ProcessExtendedTimeV4(extendedFlags, null, reader, 2); FileArchivedTime = ProcessExtendedTimeV4(extendedFlags, null, reader, 3); } } }
protected override void ReadFromReader(MarkingBinaryReader reader) { FileHeaderFlags = (FileFlags)reader.ReadVInt(); UnpackedSize = reader.ReadVInt(); Attributes = reader.ReadVInt(); if (FileHeaderFlags.HasFlag(FileFlags.TimeFieldIsPresent)) { MTime = reader.ReadUInt32(); FileLastModifiedTime = Utility.UnixTimeToDateTime(MTime); } if (FileHeaderFlags.HasFlag(FileFlags.CRC32IsPresent)) { DataCRC32 = reader.ReadUInt32(); } CompressionInformation = reader.ReadVInt(); HostOS = (HostOS)reader.ReadVInt(); var nameSize = (int)reader.ReadVInt(); Name = Encoding.UTF8.GetString(reader.ReadBytes(nameSize)); uint highCompressedSize = 0; uint highUncompressedkSize = 0; if (FileFlags.HasFlag(FileFlags.LARGE)) { highCompressedSize = reader.ReadUInt32(); highUncompressedkSize = reader.ReadUInt32(); } else { if (lowUncompressedSize == 0xffffffff) { lowUncompressedSize = 0xffffffff; highUncompressedkSize = int.MaxValue; } } CompressedSize = UInt32To64(highCompressedSize, AdditionalSize); UncompressedSize = UInt32To64(highUncompressedkSize, lowUncompressedSize); nameSize = nameSize > 4 * 1024 ? (short)(4 * 1024) : nameSize; byte[] fileNameBytes = reader.ReadBytes(nameSize); switch (HeaderType) { case HeaderType.FileHeader: { if (FileFlags.HasFlag(FileFlags.UNICODE)) { int length = 0; while (length < fileNameBytes.Length && fileNameBytes[length] != 0) { length++; } if (length != nameSize) { length++; FileName = FileNameDecoder.Decode(fileNameBytes, length); } else { FileName = ArchiveEncoding.Decode(fileNameBytes); } } else { FileName = ArchiveEncoding.Decode(fileNameBytes); } FileName = ConvertPath(FileName, HostOS); } break; case HeaderType.NewSubHeader: { int datasize = HeaderSize - NEWLHD_SIZE - nameSize; if (FileFlags.HasFlag(FileFlags.SALT)) { datasize -= SALT_SIZE; } if (datasize > 0) { SubData = reader.ReadBytes(datasize); } if (NewSubHeaderType.SUBHEAD_TYPE_RR.Equals(fileNameBytes)) { RecoverySectors = SubData[8] + (SubData[9] << 8) + (SubData[10] << 16) + (SubData[11] << 24); } } break; } if (FileFlags.HasFlag(FileFlags.SALT)) { Salt = reader.ReadBytes(SALT_SIZE); } if (FileFlags.HasFlag(FileFlags.EXTTIME)) { // verify that the end of the header hasn't been reached before reading the Extended Time. // some tools incorrectly omit Extended Time despite specifying FileFlags.EXTTIME, which most parsers tolerate. if (ReadBytes + reader.CurrentReadByteCount <= HeaderSize - 2) { ushort extendedFlags = reader.ReadUInt16(); FileLastModifiedTime = ProcessExtendedTime(extendedFlags, FileLastModifiedTime, reader, 0); FileCreatedTime = ProcessExtendedTime(extendedFlags, null, reader, 1); FileLastAccessedTime = ProcessExtendedTime(extendedFlags, null, reader, 2); FileArchivedTime = ProcessExtendedTime(extendedFlags, null, reader, 3); } } }