-
Notifications
You must be signed in to change notification settings - Fork 127
/
ArchiveRecovery.h
432 lines (394 loc) · 10.6 KB
/
ArchiveRecovery.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
//this file is part of eMule
//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#pragma once
class CPartFile;
class CShareableFile;
struct Gap_Struct;
#define ZIP_LOCAL_HEADER_MAGIC 0x04034b50
#define ZIP_LOCAL_HEADER_EXT_MAGIC 0x08074b50
#define ZIP_CD_MAGIC 0x02014b50
#define ZIP_END_CD_MAGIC 0x06054b50
#define ZIP_COMMENT "Recovered by eMule"
#define RAR_HEAD_FILE 0x74
#pragma pack(1)
struct ZIP_Entry
{
uint32 header;
uint16 versionToExtract;
uint16 generalPurposeFlag;
uint16 compressionMethod;
uint16 lastModFileTime;
uint16 lastModFileDate;
uint32 crc32;
uint32 lenCompressed;
uint32 lenUncompressed;
uint16 lenFilename;
uint16 lenExtraField;
BYTE *filename;
BYTE *extraField;
BYTE *compressedData;
};
#pragma pack()
#pragma pack(1)
struct ZIP_CentralDirectory
{
ZIP_CentralDirectory() {
lenFilename = 0;
filename = NULL;
lenExtraField = 0;
extraField = NULL;
lenComment = 0;
comment = NULL;
}
uint32 header;
uint16 versionMadeBy;
uint16 versionToExtract;
uint16 generalPurposeFlag;
uint16 compressionMethod;
uint16 lastModFileTime;
uint16 lastModFileDate;
uint32 crc32;
uint32 lenCompressed;
uint32 lenUncompressed;
uint16 lenFilename;
uint16 lenExtraField;
uint16 lenComment;
uint16 diskNumberStart;
uint16 internalFileAttributes;
uint32 externalFileAttributes;
uint32 relativeOffsetOfLocalHeader;
BYTE *filename;
BYTE *extraField;
BYTE *comment;
};
#pragma pack()
#pragma pack(1)
struct RAR_BlockFile
{
RAR_BlockFile()
{
EXT_DATE = NULL;
EXT_DATE_SIZE = 0;
}
~RAR_BlockFile()
{
delete[] EXT_DATE;
}
// This indicates the position in the input file just after the filename
ULONGLONG offsetData;
// This indicates how much of the block is after this offset
uint32 dataLength;
uint16 HEAD_CRC;
BYTE HEAD_TYPE;
uint16 HEAD_FLAGS;
uint16 HEAD_SIZE;
uint32 PACK_SIZE;
uint32 UNP_SIZE;
BYTE HOST_OS;
uint32 FILE_CRC;
uint32 FTIME;
BYTE UNP_VER;
BYTE METHOD;
uint16 NAME_SIZE;
uint32 ATTR;
uint32 HIGH_PACK_SIZE;
uint32 HIGH_UNP_SIZE;
BYTE *FILE_NAME;
BYTE *EXT_DATE;
uint32 EXT_DATE_SIZE;
BYTE SALT[8];
};
#pragma pack()
#pragma pack(1)
struct ACE_ARCHIVEHEADER
{
uint16 HEAD_CRC;
uint16 HEAD_SIZE;
BYTE HEAD_TYPE;
uint16 HEAD_FLAGS;
BYTE HEAD_SIGN[7];
BYTE VER_EXTRACT;
BYTE VER_CREATED;
BYTE HOST_CREATED;
BYTE VOLUME_NUM;
uint32 FTIME;
BYTE RESERVED[8];
BYTE AVSIZE;
//**AV
uint16 COMMENT_SIZE;
char* AV;
char* COMMENT;
char* DUMP;
ACE_ARCHIVEHEADER() {
AV=NULL;
COMMENT=NULL;
DUMP=NULL;
COMMENT_SIZE=0;
}
~ACE_ARCHIVEHEADER() {
if (AV) { free(AV); AV=NULL;}
if (COMMENT){ free(COMMENT);COMMENT=NULL;}
if (DUMP) { free(DUMP); DUMP=NULL;}
}
};
#pragma pack()
#pragma pack(1)
struct ACE_BlockFile
{
uint16 HEAD_CRC;
uint16 HEAD_SIZE;
BYTE HEAD_TYPE;
uint16 HEAD_FLAGS;
uint32 PACK_SIZE;
uint32 ORIG_SIZE;
uint32 FTIME;
uint32 FILE_ATTRIBS;
uint32 CRC32;
uint32 TECHINFO;
uint16 RESERVED;
uint16 FNAME_SIZE;
// fname
uint16 COMM_SIZE;
// comment
char* FNAME;
char* COMMENT;
uint64 data_offset;
ACE_BlockFile() {
FNAME=NULL;
COMMENT=NULL;
COMM_SIZE=0;
}
~ACE_BlockFile() {
free(FNAME);
free(COMMENT);
}
};
#pragma pack()
// ################################
// ISO related
static unsigned char sig_udf_bea[5] = { 0x42, 0x45, 0x41, 0x30, 0x31 }; // "BEA01"
static unsigned char sig_udf_nsr2[5] = { 0x4e, 0x53, 0x52, 0x30, 0x32 }; // "NSR02"
static unsigned char sig_udf_nsr3[5] = { 0x4e, 0x53, 0x52, 0x30, 0x33 }; // "NSR03"
static unsigned char sig_tea[5] = { 0x54, 0x45, 0x41, 0x30, 0x31 }; // "TEA01"
static const char sElToritoID[] = "EL TORITO SPECIFICATION";
enum ISO_ImageType
{
ISOtype_unknown = 0,
ISOtype_9660 = 1,
ISOtype_joliet = 2,
ISOtype_UDF_nsr02 = 4,
ISOtype_UDF_nsr03 = 8,
};
enum ISO_FileFlags
{
ISO_HIDDEN = 1,
ISO_DIRECTORY = 2,
ISO_FILE = 4,
ISO_RECORD = 8,
ISO_READONLY = 16
};
#pragma pack(1)
struct ISO_DateTimePVD_s
{
unsigned char year[4];
unsigned char month[2];
unsigned char day[2];
unsigned char hour[2];
unsigned char minute[2];
unsigned char second[2];
unsigned char sechundr[2];
unsigned char offsetGreenwich;
};
#pragma pack()
#pragma pack(1)
struct ISO_DateTimeFileFolder_s
{
unsigned char year;
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned char offsetGreenwich;
};
#pragma pack()
#pragma pack(1)
struct ISO_PVD_s {
unsigned char descr_type;
unsigned char magic[5];
unsigned char descr_ver;
unsigned char unused;
unsigned char sysid[32];
unsigned char volid[32];
unsigned char zeros1[8];
unsigned char seknum[8];
unsigned char escSeq[32];
UINT32 volsetsize;
UINT32 volseqnum;
UINT32 seksize;
UINT64 pathtablen;
UINT32 firstSek_LEpathTab1_LE;
UINT32 firstsek_LEpathtab2_LE;
UINT32 firstsek_BEpathtab1_BE;
UINT32 firstsek_BEpathtab2_BE;
unsigned char rootdir[34];
unsigned char volsetid[128];
unsigned char pubid[128];
unsigned char dataprepid[128];
unsigned char appid[128];
unsigned char copyr[37];
unsigned char abstractfileid[37];
unsigned char bibliofileid[37];
ISO_DateTimePVD_s creationdate;
ISO_DateTimePVD_s modifydate;
ISO_DateTimePVD_s expiredate;
unsigned char effective[17];
unsigned char filestruc_ver;
unsigned char zero;
unsigned char app_use[512];
unsigned char res[653];
};
#pragma pack()
#pragma pack(1)
struct BootDescr
{
unsigned char descr_type;
unsigned char magic[5];
unsigned char descr_ver;
unsigned char sysid[32];
unsigned char bootid[32];
unsigned char system_use[1977];
};
#pragma pack()
#pragma pack(1)
struct ISO_BootDescr_s
{
unsigned char descr_type;
unsigned char magic[5];
unsigned char descr_ver;
unsigned char sysid[32];
unsigned char bootid[32];
unsigned char system_use[1977];
};
#pragma pack()
#pragma pack(1)
struct ISO_PathtableEntry
{
BYTE len;
BYTE lenExt;
unsigned int sectorOfExtension;
UINT16 sectorOfParent;
char* name;
};
#pragma pack()
#pragma pack(1)
struct ISO_FileFolderEntry
{
BYTE lenRecord;
BYTE nrOfSecInExt;
UINT64 sector1OfExtension;
UINT64 dataSize;
ISO_DateTimeFileFolder_s dateTime;
BYTE fileFlags;
BYTE fileUnitSize;
BYTE interleaveGapSize;
unsigned int volSeqNr;
BYTE nameLen;
TCHAR* name;
ISO_FileFolderEntry() { name=NULL;};
~ISO_FileFolderEntry() { if (name) free(name);};
};
#pragma pack()
struct ISOInfos_s
{
bool bBootable;
DWORD secSize;
bool bUDF;
int iJolietUnicode;
DWORD type;
};
struct ThreadParam
{
CPartFile *partFile;
CTypedPtrList<CPtrList, Gap_Struct*> *filled;
bool preview;
bool bCreatePartFileCopy;
};
struct archiveinfo_s {
CTypedPtrList<CPtrList, ZIP_CentralDirectory*> *centralDirectoryEntries;
CTypedPtrList<CPtrList, RAR_BlockFile*> *RARdir;
CTypedPtrList<CPtrList, ACE_BlockFile*> *ACEdir;
CTypedPtrList<CPtrList, ISO_FileFolderEntry*> *ISOdir;
bool bZipCentralDir;
WORD rarFlags;
ISOInfos_s isoInfos;
ACE_ARCHIVEHEADER *ACEhdr;
archiveinfo_s() {
centralDirectoryEntries=NULL;
RARdir=NULL;
ACEdir=NULL;
rarFlags=0;
bZipCentralDir=false;
ACEhdr=NULL;
isoInfos.bBootable=false;
isoInfos.secSize=false;
isoInfos.iJolietUnicode=0;
}
};
struct archiveScannerThreadParams_s {
CShareableFile* file;
archiveinfo_s* ai;
CTypedPtrList<CPtrList, Gap_Struct*> *filled;
int type;
HWND ownerHwnd;
HWND progressHwnd;
int curProgress;
bool m_bIsValid;
};
class CArchiveRecovery
{
public:
static void recover(CPartFile *partFile, bool preview = false, bool bCreatePartFileCopy = true);
static bool recoverZip(CFile *zipInput, CFile *zipOutput, archiveScannerThreadParams_s* ai, CTypedPtrList<CPtrList, Gap_Struct*> *filled, bool fullSize);
static bool recoverRar(CFile *rarInput, CFile *rarOutput, archiveScannerThreadParams_s* ai, CTypedPtrList<CPtrList, Gap_Struct*> *filled);
static bool recoverAce(CFile *aceInput, CFile *aceOutput, archiveScannerThreadParams_s* ai, CTypedPtrList<CPtrList, Gap_Struct*> *filled);
static bool recoverISO(CFile *aceInput, CFile *aceOutput, archiveScannerThreadParams_s* ai, CTypedPtrList<CPtrList, Gap_Struct*> *filled);
private:
CArchiveRecovery(void); // Just use static recover method
static UINT AFX_CDECL run(LPVOID lpParam);
static bool performRecovery(CPartFile *partFile, CTypedPtrList<CPtrList, Gap_Struct*> *filled, bool preview, bool bCreatePartFileCopy = true);
static bool scanForZipMarker(CFile *input, archiveScannerThreadParams_s* aitp, uint32 marker, uint32 available);
static bool processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 available, CTypedPtrList<CPtrList, ZIP_CentralDirectory*> *centralDirectoryEntries);
static bool readZipCentralDirectory(CFile *zipInput, CTypedPtrList<CPtrList, ZIP_CentralDirectory*> *centralDirectoryEntries, CTypedPtrList<CPtrList, Gap_Struct*> *filled);
static RAR_BlockFile *scanForRarFileHeader(CFile *input, archiveScannerThreadParams_s* aitp, UINT64 available);
static bool validateRarFileBlock(RAR_BlockFile *block);
static void writeRarBlock(CFile *input, CFile *output, RAR_BlockFile *block);
static ACE_BlockFile *scanForAceFileHeader(CFile *input, archiveScannerThreadParams_s* aitp, UINT64 available);
static void writeAceBlock(CFile *input, CFile *output, ACE_BlockFile *block);
static void CArchiveRecovery::writeAceHeader(CFile *output, ACE_ARCHIVEHEADER* hdr);
static bool CopyFile(CPartFile *partFile, CTypedPtrList<CPtrList, Gap_Struct*> *filled, CString tempFileName);
static void DeleteMemory(ThreadParam *tp);
static bool IsFilled(uint32 start, uint32 end, CTypedPtrList<CPtrList, Gap_Struct*> *filled);
static void ISOReadDirectory(archiveScannerThreadParams_s* aitp, UINT32 startSec, CFile* isoInput, CString currentDirName);
static void ProcessProgress(archiveScannerThreadParams_s* aitp, UINT64 pos);
static uint16 readUInt16(CFile *input);
static uint32 readUInt32(CFile *input);
static uint16 calcUInt16(BYTE *input);
static uint32 calcUInt32(BYTE *input);
static void writeUInt16(CFile *output, uint16 val);
static void writeUInt32(CFile *output, uint32 val);
}; // class