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