1
0

headers.hpp 8.6 KB

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