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