| #ifndef _RAR_HEADERS_ |
| #define _RAR_HEADERS_ |
| |
| namespace third_party_unrar { |
| |
| #define SIZEOF_MARKHEAD3 7 // Size of RAR 4.x archive mark header. |
| #define SIZEOF_MAINHEAD14 7 // Size of RAR 1.4 main archive header. |
| #define SIZEOF_MAINHEAD3 13 // Size of RAR 4.x main archive header. |
| #define SIZEOF_FILEHEAD14 21 // Size of RAR 1.4 file header. |
| #define SIZEOF_FILEHEAD3 32 // Size of RAR 3.0 file header. |
| #define SIZEOF_SHORTBLOCKHEAD 7 |
| #define SIZEOF_LONGBLOCKHEAD 11 |
| #define SIZEOF_SUBBLOCKHEAD 14 |
| #define SIZEOF_COMMHEAD 13 |
| #define SIZEOF_PROTECTHEAD 26 |
| #define SIZEOF_UOHEAD 18 |
| #define SIZEOF_STREAMHEAD 26 |
| |
| #define VER_PACK 29U |
| #define VER_PACK5 50U // It is stored as 0, but we subtract 50 when saving an archive. |
| #define VER_UNPACK 29U |
| #define VER_UNPACK5 50U // It is stored as 0, but we add 50 when reading an archive. |
| #define VER_UNKNOWN 9999U // Just some large value. |
| |
| #define MHD_VOLUME 0x0001U |
| |
| // Old style main archive comment embed into main archive header. Must not |
| // be used in new archives anymore. |
| #define MHD_COMMENT 0x0002U |
| |
| #define MHD_LOCK 0x0004U |
| #define MHD_SOLID 0x0008U |
| #define MHD_PACK_COMMENT 0x0010U |
| #define MHD_NEWNUMBERING 0x0010U |
| #define MHD_AV 0x0020U |
| #define MHD_PROTECT 0x0040U |
| #define MHD_PASSWORD 0x0080U |
| #define MHD_FIRSTVOLUME 0x0100U |
| |
| #define LHD_SPLIT_BEFORE 0x0001U |
| #define LHD_SPLIT_AFTER 0x0002U |
| #define LHD_PASSWORD 0x0004U |
| |
| // Old style file comment embed into file header. Must not be used |
| // in new archives anymore. |
| #define LHD_COMMENT 0x0008U |
| |
| // For non-file subheaders it denotes 'subblock having a parent file' flag. |
| #define LHD_SOLID 0x0010U |
| |
| |
| #define LHD_WINDOWMASK 0x00e0U |
| #define LHD_WINDOW64 0x0000U |
| #define LHD_WINDOW128 0x0020U |
| #define LHD_WINDOW256 0x0040U |
| #define LHD_WINDOW512 0x0060U |
| #define LHD_WINDOW1024 0x0080U |
| #define LHD_WINDOW2048 0x00a0U |
| #define LHD_WINDOW4096 0x00c0U |
| #define LHD_DIRECTORY 0x00e0U |
| |
| #define LHD_LARGE 0x0100U |
| #define LHD_UNICODE 0x0200U |
| #define LHD_SALT 0x0400U |
| #define LHD_VERSION 0x0800U |
| #define LHD_EXTTIME 0x1000U |
| |
| #define SKIP_IF_UNKNOWN 0x4000U |
| #define LONG_BLOCK 0x8000U |
| |
| #define EARC_NEXT_VOLUME 0x0001U // Not last volume. |
| #define EARC_DATACRC 0x0002U // Store CRC32 of RAR archive (now is used only in volumes). |
| #define EARC_REVSPACE 0x0004U // Reserve space for end of REV file 7 byte record. |
| #define EARC_VOLNUMBER 0x0008U // Store a number of current volume. |
| |
| enum HEADER_TYPE { |
| // RAR 5.0 header types. |
| HEAD_MARK=0x00, HEAD_MAIN=0x01, HEAD_FILE=0x02, HEAD_SERVICE=0x03, |
| HEAD_CRYPT=0x04, HEAD_ENDARC=0x05, HEAD_UNKNOWN=0xff, |
| |
| // RAR 1.5 - 4.x header types. |
| HEAD3_MARK=0x72,HEAD3_MAIN=0x73,HEAD3_FILE=0x74,HEAD3_CMT=0x75, |
| HEAD3_AV=0x76,HEAD3_OLDSERVICE=0x77,HEAD3_PROTECT=0x78,HEAD3_SIGN=0x79, |
| HEAD3_SERVICE=0x7a,HEAD3_ENDARC=0x7b |
| }; |
| |
| |
| // RAR 2.9 and earlier. |
| enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103, |
| NTACL_HEAD=0x104,STREAM_HEAD=0x105 }; |
| |
| |
| // Internal implementation, depends on archive format version. |
| enum HOST_SYSTEM { |
| // RAR 5.0 host OS |
| HOST5_WINDOWS=0,HOST5_UNIX=1, |
| |
| // RAR 3.0 host OS. |
| HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4, |
| HOST_BEOS=5,HOST_MAX |
| }; |
| |
| // Unified archive format independent implementation. |
| enum HOST_SYSTEM_TYPE { |
| HSYS_WINDOWS, HSYS_UNIX, HSYS_UNKNOWN |
| }; |
| |
| |
| // We also use these values in extra field, so do not modify them. |
| enum FILE_SYSTEM_REDIRECT { |
| FSREDIR_NONE=0, FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION, |
| FSREDIR_HARDLINK, FSREDIR_FILECOPY |
| }; |
| |
| |
| #define SUBHEAD_TYPE_CMT L"CMT" |
| #define SUBHEAD_TYPE_QOPEN L"QO" |
| #define SUBHEAD_TYPE_ACL L"ACL" |
| #define SUBHEAD_TYPE_STREAM L"STM" |
| #define SUBHEAD_TYPE_UOWNER L"UOW" |
| #define SUBHEAD_TYPE_AV L"AV" |
| #define SUBHEAD_TYPE_RR L"RR" |
| #define SUBHEAD_TYPE_OS2EA L"EA2" |
| |
| /* new file inherits a subblock when updating a host file */ |
| #define SUBHEAD_FLAGS_INHERITED 0x80000000 |
| |
| #define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001 |
| |
| |
| struct MarkHeader |
| { |
| byte Mark[8]; |
| |
| // Following fields are virtual and not present in real blocks. |
| uint HeadSize; |
| }; |
| |
| |
| struct BaseBlock |
| { |
| uint HeadCRC; // 'ushort' for RAR 1.5. |
| HEADER_TYPE HeaderType; // 1 byte for RAR 1.5. |
| uint Flags; // 'ushort' for RAR 1.5. |
| uint HeadSize; // 'ushort' for RAR 1.5, up to 2 MB for RAR 5.0. |
| |
| bool SkipIfUnknown; |
| |
| void Reset() |
| { |
| SkipIfUnknown=false; |
| } |
| }; |
| |
| |
| struct BlockHeader:BaseBlock |
| { |
| uint DataSize; |
| }; |
| |
| |
| struct MainHeader:BaseBlock |
| { |
| ushort HighPosAV; |
| uint PosAV; |
| bool CommentInHeader; |
| bool PackComment; // For RAR 1.4 archive format only. |
| bool Locator; |
| uint64 QOpenOffset; // Offset of quick list record. |
| uint64 QOpenMaxSize; // Maximum size of QOpen offset in locator extra field. |
| uint64 RROffset; // Offset of recovery record. |
| uint64 RRMaxSize; // Maximum size of RR offset in locator extra field. |
| void Reset(); |
| }; |
| |
| |
| struct FileHeader:BlockHeader |
| { |
| byte HostOS; |
| uint UnpVer; // It is 1 byte in RAR29 and bit field in RAR5. |
| byte Method; |
| union { |
| uint FileAttr; |
| uint SubFlags; |
| }; |
| wchar FileName[NM]; |
| |
| Array<byte> SubData; |
| |
| RarTime mtime; |
| RarTime ctime; |
| RarTime atime; |
| |
| int64 PackSize; |
| int64 UnpSize; |
| int64 MaxSize; // Reserve packed and unpacked size bytes for vint of this size. |
| |
| HashValue FileHash; |
| |
| uint FileFlags; |
| |
| bool SplitBefore; |
| bool SplitAfter; |
| |
| bool UnknownUnpSize; |
| |
| bool Encrypted; |
| CRYPT_METHOD CryptMethod; |
| bool SaltSet; |
| byte Salt[SIZE_SALT50]; |
| byte InitV[SIZE_INITV]; |
| bool UsePswCheck; |
| byte PswCheck[SIZE_PSWCHECK]; |
| |
| // Use HMAC calculated from HashKey and checksum instead of plain checksum. |
| bool UseHashKey; |
| |
| // Key to convert checksum to HMAC. Derived from password with PBKDF2 |
| // using additional iterations. |
| byte HashKey[SHA256_DIGEST_SIZE]; |
| |
| uint Lg2Count; // Log2 of PBKDF2 repetition count. |
| |
| bool Solid; |
| bool Dir; |
| bool CommentInHeader; // RAR 2.0 file comment. |
| bool Version; // name.ext;ver file name containing the version number. |
| size_t WinSize; |
| bool Inherited; // New file inherits a subblock when updating a host file (for subblocks only). |
| |
| // 'true' if file sizes use 8 bytes instead of 4. Not used in RAR 5.0. |
| bool LargeFile; |
| |
| // 'true' for HEAD_SERVICE block, which is a child of preceding file block. |
| // RAR 4.x uses 'solid' flag to indicate child subheader blocks in archives. |
| bool SubBlock; |
| |
| HOST_SYSTEM_TYPE HSType; |
| |
| FILE_SYSTEM_REDIRECT RedirType; |
| wchar RedirName[NM]; |
| bool DirTarget; |
| |
| bool UnixOwnerSet,UnixOwnerNumeric,UnixGroupNumeric; |
| char UnixOwnerName[256],UnixGroupName[256]; |
| #ifdef _UNIX |
| uid_t UnixOwnerID; |
| gid_t UnixGroupID; |
| #else // Need these Unix fields in Windows too for 'list' command. |
| uint UnixOwnerID; |
| uint UnixGroupID; |
| #endif |
| |
| void Reset(size_t SubDataSize=0); |
| |
| bool CmpName(const wchar *Name) |
| { |
| return(wcscmp(FileName,Name)==0); |
| } |
| |
| FileHeader& operator = (FileHeader &hd); |
| }; |
| |
| |
| struct EndArcHeader:BaseBlock |
| { |
| // Optional CRC32 of entire archive up to start of EndArcHeader block. |
| // Present in RAR 4.x archives if EARC_DATACRC flag is set. |
| uint ArcDataCRC; |
| |
| uint VolNumber; // Optional number of current volume. |
| |
| // 7 additional zero bytes can be stored here if EARC_REVSPACE is set. |
| |
| bool NextVolume; // Not last volume. |
| bool DataCRC; |
| bool RevSpace; |
| bool StoreVolNumber; |
| void Reset() |
| { |
| BaseBlock::Reset(); |
| NextVolume=false; |
| DataCRC=false; |
| RevSpace=false; |
| StoreVolNumber=false; |
| } |
| }; |
| |
| |
| struct CryptHeader:BaseBlock |
| { |
| bool UsePswCheck; |
| uint Lg2Count; // Log2 of PBKDF2 repetition count. |
| byte Salt[SIZE_SALT50]; |
| byte PswCheck[SIZE_PSWCHECK]; |
| }; |
| |
| |
| // SubBlockHeader and its successors were used in RAR 2.x format. |
| // RAR 4.x uses FileHeader with HEAD_SERVICE HeaderType for subblocks. |
| struct SubBlockHeader:BlockHeader |
| { |
| ushort SubType; |
| byte Level; |
| }; |
| |
| |
| struct CommentHeader:BaseBlock |
| { |
| ushort UnpSize; |
| byte UnpVer; |
| byte Method; |
| ushort CommCRC; |
| }; |
| |
| |
| struct ProtectHeader:BlockHeader |
| { |
| byte Version; |
| ushort RecSectors; |
| uint TotalBlocks; |
| byte Mark[8]; |
| }; |
| |
| |
| struct UnixOwnersHeader:SubBlockHeader |
| { |
| ushort OwnerNameSize; |
| ushort GroupNameSize; |
| /* dummy */ |
| char OwnerName[256]; |
| char GroupName[256]; |
| }; |
| |
| |
| struct EAHeader:SubBlockHeader |
| { |
| uint UnpSize; |
| byte UnpVer; |
| byte Method; |
| uint EACRC; |
| }; |
| |
| |
| struct StreamHeader:SubBlockHeader |
| { |
| uint UnpSize; |
| byte UnpVer; |
| byte Method; |
| uint StreamCRC; |
| ushort StreamNameSize; |
| char StreamName[260]; |
| }; |
| |
| } // namespace third_party_unrar |
| |
| #endif |