1 #ifndef _RAR_HEADERS_ 2 #define _RAR_HEADERS_ 3 4 #define SIZEOF_MARKHEAD3 7 // Size of RAR 4.x archive mark header. 5 #define SIZEOF_MAINHEAD14 7 // Size of RAR 1.4 main archive header. 6 #define SIZEOF_MAINHEAD3 13 // Size of RAR 4.x main archive header. 7 #define SIZEOF_FILEHEAD14 21 // Size of RAR 1.4 file header. 8 #define SIZEOF_FILEHEAD3 32 // Size of RAR 3.0 file header. 9 #define SIZEOF_SHORTBLOCKHEAD 7 10 #define SIZEOF_LONGBLOCKHEAD 11 11 #define SIZEOF_SUBBLOCKHEAD 14 12 #define SIZEOF_COMMHEAD 13 13 #define SIZEOF_PROTECTHEAD 26 14 #define SIZEOF_UOHEAD 18 15 #define SIZEOF_STREAMHEAD 26 16 17 #define VER_PACK 29U 18 #define VER_PACK5 50U // It is stored as 0, but we subtract 50 when saving an archive. 19 #define VER_UNPACK 29U 20 #define VER_UNPACK5 50U // It is stored as 0, but we add 50 when reading an archive. 21 #define VER_UNKNOWN 9999U // Just some large value. 22 23 #define MHD_VOLUME 0x0001U 24 25 // Old style main archive comment embed into main archive header. Must not 26 // be used in new archives anymore. 27 #define MHD_COMMENT 0x0002U 28 29 #define MHD_LOCK 0x0004U 30 #define MHD_SOLID 0x0008U 31 #define MHD_PACK_COMMENT 0x0010U 32 #define MHD_NEWNUMBERING 0x0010U 33 #define MHD_AV 0x0020U 34 #define MHD_PROTECT 0x0040U 35 #define MHD_PASSWORD 0x0080U 36 #define MHD_FIRSTVOLUME 0x0100U 37 38 #define LHD_SPLIT_BEFORE 0x0001U 39 #define LHD_SPLIT_AFTER 0x0002U 40 #define LHD_PASSWORD 0x0004U 41 42 // Old style file comment embed into file header. Must not be used 43 // in new archives anymore. 44 #define LHD_COMMENT 0x0008U 45 46 // For non-file subheaders it denotes 'subblock having a parent file' flag. 47 #define LHD_SOLID 0x0010U 48 49 50 #define LHD_WINDOWMASK 0x00e0U 51 #define LHD_WINDOW64 0x0000U 52 #define LHD_WINDOW128 0x0020U 53 #define LHD_WINDOW256 0x0040U 54 #define LHD_WINDOW512 0x0060U 55 #define LHD_WINDOW1024 0x0080U 56 #define LHD_WINDOW2048 0x00a0U 57 #define LHD_WINDOW4096 0x00c0U 58 #define LHD_DIRECTORY 0x00e0U 59 60 #define LHD_LARGE 0x0100U 61 #define LHD_UNICODE 0x0200U 62 #define LHD_SALT 0x0400U 63 #define LHD_VERSION 0x0800U 64 #define LHD_EXTTIME 0x1000U 65 66 #define SKIP_IF_UNKNOWN 0x4000U 67 #define LONG_BLOCK 0x8000U 68 69 #define EARC_NEXT_VOLUME 0x0001U // Not last volume. 70 #define EARC_DATACRC 0x0002U // Store CRC32 of RAR archive (now is used only in volumes). 71 #define EARC_REVSPACE 0x0004U // Reserve space for end of REV file 7 byte record. 72 #define EARC_VOLNUMBER 0x0008U // Store a number of current volume. 73 74 enum HEADER_TYPE { 75 // RAR 5.0 header types. 76 HEAD_MARK=0x00, HEAD_MAIN=0x01, HEAD_FILE=0x02, HEAD_SERVICE=0x03, 77 HEAD_CRYPT=0x04, HEAD_ENDARC=0x05, HEAD_UNKNOWN=0xff, 78 79 // RAR 1.5 - 4.x header types. 80 HEAD3_MARK=0x72,HEAD3_MAIN=0x73,HEAD3_FILE=0x74,HEAD3_CMT=0x75, 81 HEAD3_AV=0x76,HEAD3_OLDSERVICE=0x77,HEAD3_PROTECT=0x78,HEAD3_SIGN=0x79, 82 HEAD3_SERVICE=0x7a,HEAD3_ENDARC=0x7b 83 }; 84 85 86 // RAR 2.9 and earlier. 87 enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103, 88 NTACL_HEAD=0x104,STREAM_HEAD=0x105 }; 89 90 91 // Internal implementation, depends on archive format version. 92 enum HOST_SYSTEM { 93 // RAR 5.0 host OS 94 HOST5_WINDOWS=0,HOST5_UNIX=1, 95 96 // RAR 3.0 host OS. 97 HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4, 98 HOST_BEOS=5,HOST_MAX 99 }; 100 101 // Unified archive format independent implementation. 102 enum HOST_SYSTEM_TYPE { 103 HSYS_WINDOWS, HSYS_UNIX, HSYS_UNKNOWN 104 }; 105 106 107 // We also use these values in extra field, so do not modify them. 108 enum FILE_SYSTEM_REDIRECT { 109 FSREDIR_NONE=0, FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION, 110 FSREDIR_HARDLINK, FSREDIR_FILECOPY 111 }; 112 113 114 #define SUBHEAD_TYPE_CMT L"CMT" 115 #define SUBHEAD_TYPE_QOPEN L"QO" 116 #define SUBHEAD_TYPE_ACL L"ACL" 117 #define SUBHEAD_TYPE_STREAM L"STM" 118 #define SUBHEAD_TYPE_UOWNER L"UOW" 119 #define SUBHEAD_TYPE_AV L"AV" 120 #define SUBHEAD_TYPE_RR L"RR" 121 #define SUBHEAD_TYPE_OS2EA L"EA2" 122 123 /* new file inherits a subblock when updating a host file */ 124 #define SUBHEAD_FLAGS_INHERITED 0x80000000 125 126 #define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001 127 128 129 struct MarkHeader 130 { 131 byte Mark[8]; 132 133 // Following fields are virtual and not present in real blocks. 134 uint HeadSize; 135 }; 136 137 138 struct BaseBlock 139 { 140 uint HeadCRC; // 'ushort' for RAR 1.5. 141 HEADER_TYPE HeaderType; // 1 byte for RAR 1.5. 142 uint Flags; // 'ushort' for RAR 1.5. 143 uint HeadSize; // 'ushort' for RAR 1.5, up to 2 MB for RAR 5.0. 144 145 bool SkipIfUnknown; 146 ResetBaseBlock147 void Reset() 148 { 149 SkipIfUnknown=false; 150 } 151 }; 152 153 154 struct BlockHeader:BaseBlock 155 { 156 uint DataSize; 157 }; 158 159 160 struct MainHeader:BaseBlock 161 { 162 ushort HighPosAV; 163 uint PosAV; 164 bool CommentInHeader; 165 bool PackComment; // For RAR 1.4 archive format only. 166 bool Locator; 167 uint64 QOpenOffset; // Offset of quick list record. 168 uint64 QOpenMaxSize; // Maximum size of QOpen offset in locator extra field. 169 uint64 RROffset; // Offset of recovery record. 170 uint64 RRMaxSize; // Maximum size of RR offset in locator extra field. 171 void Reset(); 172 }; 173 174 175 struct FileHeader:BlockHeader 176 { 177 byte HostOS; 178 uint UnpVer; // It is 1 byte in RAR29 and bit field in RAR5. 179 byte Method; 180 union { 181 uint FileAttr; 182 uint SubFlags; 183 }; 184 wchar FileName[NM]; 185 186 Array<byte> SubData; 187 188 RarTime mtime; 189 RarTime ctime; 190 RarTime atime; 191 192 int64 PackSize; 193 int64 UnpSize; 194 int64 MaxSize; // Reserve packed and unpacked size bytes for vint of this size. 195 196 HashValue FileHash; 197 198 uint FileFlags; 199 200 bool SplitBefore; 201 bool SplitAfter; 202 203 bool UnknownUnpSize; 204 205 bool Encrypted; 206 CRYPT_METHOD CryptMethod; 207 bool SaltSet; 208 byte Salt[SIZE_SALT50]; 209 byte InitV[SIZE_INITV]; 210 bool UsePswCheck; 211 byte PswCheck[SIZE_PSWCHECK]; 212 213 // Use HMAC calculated from HashKey and checksum instead of plain checksum. 214 bool UseHashKey; 215 216 // Key to convert checksum to HMAC. Derived from password with PBKDF2 217 // using additional iterations. 218 byte HashKey[SHA256_DIGEST_SIZE]; 219 220 uint Lg2Count; // Log2 of PBKDF2 repetition count. 221 222 bool Solid; 223 bool Dir; 224 bool CommentInHeader; // RAR 2.0 file comment. 225 bool Version; // name.ext;ver file name containing the version number. 226 size_t WinSize; 227 bool Inherited; // New file inherits a subblock when updating a host file (for subblocks only). 228 229 // 'true' if file sizes use 8 bytes instead of 4. Not used in RAR 5.0. 230 bool LargeFile; 231 232 // 'true' for HEAD_SERVICE block, which is a child of preceding file block. 233 // RAR 4.x uses 'solid' flag to indicate child subheader blocks in archives. 234 bool SubBlock; 235 236 HOST_SYSTEM_TYPE HSType; 237 238 FILE_SYSTEM_REDIRECT RedirType; 239 wchar RedirName[NM]; 240 bool DirTarget; 241 242 bool UnixOwnerSet,UnixOwnerNumeric,UnixGroupNumeric; 243 char UnixOwnerName[256],UnixGroupName[256]; 244 #ifdef _UNIX 245 uid_t UnixOwnerID; 246 gid_t UnixGroupID; 247 #else // Need these Unix fields in Windows too for 'list' command. 248 uint UnixOwnerID; 249 uint UnixGroupID; 250 #endif 251 252 void Reset(size_t SubDataSize=0); 253 CmpNameFileHeader254 bool CmpName(const wchar *Name) 255 { 256 return(wcscmp(FileName,Name)==0); 257 } 258 259 FileHeader& operator = (FileHeader &hd); 260 }; 261 262 263 struct EndArcHeader:BaseBlock 264 { 265 // Optional CRC32 of entire archive up to start of EndArcHeader block. 266 // Present in RAR 4.x archives if EARC_DATACRC flag is set. 267 uint ArcDataCRC; 268 269 uint VolNumber; // Optional number of current volume. 270 271 // 7 additional zero bytes can be stored here if EARC_REVSPACE is set. 272 273 bool NextVolume; // Not last volume. 274 bool DataCRC; 275 bool RevSpace; 276 bool StoreVolNumber; ResetEndArcHeader277 void Reset() 278 { 279 BaseBlock::Reset(); 280 NextVolume=false; 281 DataCRC=false; 282 RevSpace=false; 283 StoreVolNumber=false; 284 } 285 }; 286 287 288 struct CryptHeader:BaseBlock 289 { 290 bool UsePswCheck; 291 uint Lg2Count; // Log2 of PBKDF2 repetition count. 292 byte Salt[SIZE_SALT50]; 293 byte PswCheck[SIZE_PSWCHECK]; 294 }; 295 296 297 // SubBlockHeader and its successors were used in RAR 2.x format. 298 // RAR 4.x uses FileHeader with HEAD_SERVICE HeaderType for subblocks. 299 struct SubBlockHeader:BlockHeader 300 { 301 ushort SubType; 302 byte Level; 303 }; 304 305 306 struct CommentHeader:BaseBlock 307 { 308 ushort UnpSize; 309 byte UnpVer; 310 byte Method; 311 ushort CommCRC; 312 }; 313 314 315 struct ProtectHeader:BlockHeader 316 { 317 byte Version; 318 ushort RecSectors; 319 uint TotalBlocks; 320 byte Mark[8]; 321 }; 322 323 324 struct UnixOwnersHeader:SubBlockHeader 325 { 326 ushort OwnerNameSize; 327 ushort GroupNameSize; 328 /* dummy */ 329 char OwnerName[256]; 330 char GroupName[256]; 331 }; 332 333 334 struct EAHeader:SubBlockHeader 335 { 336 uint UnpSize; 337 byte UnpVer; 338 byte Method; 339 uint EACRC; 340 }; 341 342 343 struct StreamHeader:SubBlockHeader 344 { 345 uint UnpSize; 346 byte UnpVer; 347 byte Method; 348 uint StreamCRC; 349 ushort StreamNameSize; 350 char StreamName[260]; 351 }; 352 353 354 #endif 355