-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTArchive.cpp
More file actions
420 lines (373 loc) · 12.6 KB
/
TArchive.cpp
File metadata and controls
420 lines (373 loc) · 12.6 KB
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
/////////////////////////////////////////////////////////////////////////////
//TArchive.cpp
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TArchive.h"
#include <time.h>
#include <string.h>
/////////////////////////////////////////////////////////////////////////////
//Construction/Destruction
/////////////////////////////////////////////////////////////////////////////
//dfa - utochnyayushie dannie
// PathLF - imya logfile (esli net to ne sozdavat')
// NewLF - rejim zapisi logfile 0 - prodoljit' 1 - noviy
// DetailLF - detalizaciya logfayla 1 - lowdetail 2 - highdetail
// SFX - 1 - proveryat' SFX arhivi 0 - net
//namearch - imya typa archiva kotoriy rabotaet
TArchive::
TArchive(DataForArchive& dfa, LanguageMessages& langmsg, LanguageResults& langres, char* namearch):
m_LangMsg(langmsg), m_LangRes(langres), m_h(0),
m_pOriginalName(0), m_pAuthVerification(0), m_pTextComment(0),
m_LogFile(0), m_hWnd(0), m_hEventEnd(0), m_BeginThread(0),
m_CheckSFX(dfa.SFX), m_MAX_LEN_SFX(dfa.SizeSFX),
m_InvertRatio(dfa.InvertRatio),
m_pTargetFile(dfa.pTargetFile), m_pUnArchiveDll(dfa.pUnArchiveDll),
m_pInternalName(0), m_pMethodPack(0)
{
//infa svyazannaya s logfaylom
int size = strlen(dfa.PathLF);
if (size > 0)
{
//detalizaciya logfayla
if (dfa.DetailLF == 2)
m_DetailLF = dfa.DetailLF;
else
m_DetailLF = 1;
//sozdaem logfayl
m_LogFile = new MLogFile(m_LangRes, dfa.pTargetFile, namearch, dfa.WidthAuthorName, dfa.WidthMessage);
if (!m_LogFile->OpenLogFile(dfa.PathLF, dfa.NewLF)) m_DetailLF = 0;
}
else m_DetailLF = 0;
//proverki
if (!m_pTargetFile) m_pTargetFile = "";
if (!m_pUnArchiveDll) m_pUnArchiveDll = "";
}
TArchive::
~TArchive()
{
try
{
if (m_h)
{ ::CloseHandle(m_h); m_h = 0; }
if (m_pOriginalName)
{ delete[] m_pOriginalName; m_pOriginalName = 0; }
if (m_pAuthVerification)
{ delete[] m_pAuthVerification; m_pAuthVerification = 0; }
if (m_pTextComment)
{ delete[] m_pTextComment; m_pTextComment = 0; }
if (m_pMethodPack)
{ delete[] m_pMethodPack; m_pMethodPack = 0; }
if (m_LogFile)
{ m_LogFile->CloseLogFile(); delete m_LogFile; m_LogFile = 0; }
if (m_pInternalName)
{ delete[] m_pInternalName; m_pInternalName = 0; }
m_hWnd = 0;
m_hEventEnd = 0;
m_BeginThread = 0;
}
catch (...) {;}
}
/////////////////////////////////////////////////////////////////////////////
//FUNCTIONS PROTECTED
/////////////////////////////////////////////////////////////////////////////
//obnulenie dannih
void TArchive::
InitialParametrs()
{
//informaciya ob arhive
m_UnpackSizeFiles = 0; //nezaarhivir razmer faylov
m_PackSizeFiles = 0; //zaarhivir razmer faylov
m_ArchiveSize = 0; //razmer arhiva
m_NumberFiles = 0; //kolichestvo faylov
m_NumberFolders = 0; //kolichestvo papok
m_NumberChapters = 0; //kolichestvo glav (dlya ARJ)
m_DictionarySize = 0; //razmer slovarya
if (m_pOriginalName) { delete[] m_pOriginalName; m_pOriginalName = 0; } //imya arhiva(dlya ARJ) fayla(dlya GZIP) magic(dlya TAR) pri sozdanii
m_HostOS = -1; //OS arhivirovaniya
m_ExtractOS = -1; //OS dlya raspakovki
m_MethodPack = -1; //metod sjatiya
m_MethodPackAdd = -1; //metod sjatiya (dlya ZIP/JAR/CAB)
m_MemorySize = 0; //vozvrat ob'em ispol'zuemoy operativnoy pamyati v Mb(dlya PPM)
m_RatioArchiveSize = 0.0; //sjatie ot razmera arhiva
m_RatioPackFileSize = 0.0; //sjatie ot upak razmera faylov
m_PackVersion = 0.0; //versiya zapakovki
m_UnpackVersion = 0.0; //versiya dlya raspakovki
m_SfxModule = 0; //modul' SFX (*.exe)
m_RecoveryRecord = 0; //est' infa dlya vosstanovleniya
m_Solid = FALSE;//neprerivniy arhiv
m_MultiArc = FALSE;//mnogotomniy arhiv
m_VolumeNumber = 0; //nomer toma mnogotomnogo arhiva
m_MainComment = FALSE;//est' comentariy arhiva
m_FileComment = FALSE;//est' comentarii faylov
m_ChapterComment = FALSE;//est' comentarii chapter'a (dlya ARJ)
m_Password = FALSE;//est' parol'
m_ArchiveLock = FALSE;//arhiv zablokirovan
m_AuthVerification = FALSE;//est' electronnaya podpis'
if (m_pAuthVerification) { delete[] m_pAuthVerification; m_pAuthVerification = 0; } //stroka electronnaya podpis'
m_ArchiveType = FALSE;/*FALSE or TRUE
ARC ili PAK arhiv (dlya ARC/PAK)
LHA ili LZH arhiv (dlya LHA/LZH)
ZIP ili JAR arhiv (dlya ZIP/JAR)*/
if(m_pTextComment) { delete[] m_pTextComment; m_pTextComment = 0; } //ukazatel' na text - kommentariy
if(m_pMethodPack) { delete[] m_pMethodPack; m_pMethodPack = 0; } //ukazatel' na text - metod sjatiya
m_HeadersSize = 0;
m_NumBlocks = 0;
m_Offset = 0;
//vremya raboti
m_TestTime = 0; //vremya raboti TestFile
m_AnalyzeTime = 0; //vremya raboti AnalyzeInfoOfArc
m_AllTime = 0; //polnoe vremya raboti
m_CommentSize = 0; //dlya zapisi dlini kommentariya (v simvolah)
m_CommentOffset = 0; //dlya zapisi smesheniya kommentariya ot nachala arhiva
//vnutrennie peremennie
::CloseHandle(m_h); m_h = 0;//dlya raboti s faylami
m_loffset = 0; //smeshenie v fayle
m_hoffset = 0; //smeshenie v fayle (high-order DWORD)
m_BigOffset = FALSE;//bol'shoe smeshenie v fayle vpered, kogda starshie 4 byte smesheniya eshe = 0x0, a starshie uje doshli do bita-znaka (chtob znat' chto eto chislo polojitel'noe)
m_Unicode = FALSE;//imena faulov v yunikode
MSG = 0; //soobsheniya funkciy
m_BlockType = 0; //dlya detalizacii vida obrabotannogo bloka arhiva
//dlya realizacii v rabochem potoke (tol'ko funkciya Start())
m_hWnd = 0; //okno dlya vozvrata soobsheniy ot potoka
m_hEventEnd = 0; //sobitie zakritiya potoka
m_BeginThread = 0; //zapusk v rabochem potoke ili net
m_Percent = 0; //procent vipolneniya raboti
}
//schitat' sjatie ot razmera arhiva
void TArchive::
CountRatioArchiveSize()
{
LONGLONG as = m_ArchiveSize;
LONGLONG usf = m_UnpackSizeFiles;
if (usf == 0)
m_RatioArchiveSize = 0;
else
m_RatioArchiveSize = ((double)as / (double)usf) * 100.0;
if (m_InvertRatio)
m_RatioArchiveSize = 100 - m_RatioArchiveSize;
}
//schitat' sjatie ot upak razmera faylov
void TArchive::
CountRatioPackFileSize()
{
LONGLONG psf = m_PackSizeFiles;
LONGLONG usf = m_UnpackSizeFiles;
if (usf == 0)
m_RatioPackFileSize = 0;
else
m_RatioPackFileSize = ((double)psf / (double)usf) * 100.0;
if (m_InvertRatio)
m_RatioPackFileSize = 100 - m_RatioPackFileSize;
}
//ustanovka dati i vremeni sozdaniya archiva iz DOS formata
//
// 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
// |<---- year-1980 --->|<- month ->|<--- day ---->|
//
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// |<--- hour --->|<---- minute --->|<- second/2 ->|
//
//datetime - chislo predstavlyayushee datu i vremya (format vverhu)
//date - strokovoe predstavlenie dati
//time - strokovoe predstavlenie vremeni
void TArchive::
DateTimeDosFormat(DWORD datetime, char* date, char* time)
{
WORD hour = 0;
WORD minute = 0;
WORD second = 0;
WORD year = 0;
WORD month = 0;
WORD day = 0;
//razbor dati i vremeni
second = (datetime & 0x1F) * 2;
minute = (datetime >> 5) & 0x3F;
hour = (datetime >> 11) & 0x1F;
day = (datetime >> 16) & 0x1F;
month = (datetime >> 21) & 0x0F;
year = ((datetime >> 25) & 0x7F) + 1980;
char buf[5];
//sostavlenie stroki dati
if (day < 10)
{
strcpy(date, "0");
strcat(date, _itoa(day, buf, 10));
}
else strcpy(date, _itoa(day, buf, 10));
strcat(date, "/");
if (month < 10)
{
strcat(date, "0");
strcat(date, _itoa(month, buf, 10));
}
else strcat(date, _itoa(month, buf, 10));
strcat(date, "/");
strcat(date, _itoa(year, buf, 10));
//sostavlenie stroki vremeni
if (hour < 10)
{
strcpy(time, "0");
strcpy(time, _itoa(hour, buf, 10));
}
else strcpy(time, _itoa(hour, buf, 10));
strcat(time, ":");
if (minute < 10)
{
strcat(time, "0");
strcat(time, _itoa(minute, buf, 10));
}
else strcat(time, _itoa(minute, buf, 10));
strcat(time, ":");
if (second < 10)
{
strcat(time, _itoa(second, buf, 10));
strcat(time, "0");
}
else strcat(time, _itoa(second, buf, 10));
}
//razmer fayla arhiva
LONGLONG TArchive::
GetArchSize()
{
DWORD FileSize = 0;
DWORD FileSizeHigh = 0;
FileSize = ::GetFileSize(m_h, &FileSizeHigh);
return TakeLong(FileSize, FileSizeHigh);
}
//sobrat' LONGLONG iz LONGs
//ll - mladshiy LONG
//hl - starshiy LONG
LONGLONG TArchive::
TakeLong(DWORD ll, LONG hl)
{
LARGE_INTEGER ull;
ull.HighPart = hl;
ull.LowPart = ll;
return ull.QuadPart;
}
//sobrat' WORD iz BYTEs
//lb - mladshiy BYTE
//hb - starshiy BYTE
WORD TArchive::
TakeWord(BYTE lb, BYTE hb)
{
return (WORD)lb | ((WORD)hb) << 8;
}
//sobrat' DWORD iz WORDs
//lw - mladshiy WORD
//hw - starshiy WORD
DWORD TArchive::
TakeDWord(WORD lw, WORD hw)
{
return (DWORD)lw | ((DWORD)hw) << 16;
}
/////////////////////////////////////////////////////////////////////////////
//FUNCTIONS PUBLIC
/////////////////////////////////////////////////////////////////////////////
//chtenie iz fayla
//lpBuffer - bufer kuda chitat'
//uBytes - kolichestvo BYTE dlya chteniya
//return
// TERROR_READ_FILE - oshibka chteniya
// TMESSAGE_OK - ok
int TArchive::
ReadArc(LPVOID lpBuffer, UINT uBytes)
{
DWORD NumBytesRead = 0;
//prochita' dannie
if (!::ReadFile(m_h, lpBuffer, uBytes, &NumBytesRead, NULL))
return TERROR_READ_FILE;
//esli nado ukazat' skol'ko bayt prochitano
if (uBytes != NumBytesRead) return TSUDDEN_END_FILE; //(uBytes - NumBytesRead);
return TMESSAGE_OK;
}
//smeshenie v arhive
//loffset - mladshee smeshenie
//hoffset - starshee smeshenie
//MoveMetod:
// FILE_BEGIN The starting point is zero or the beginning of the file.
// FILE_CURRENT The starting point is the current value of the file pointer.
// FILE_END The starting point is the current end-of-file position.
//return
// TERROR_SEEK_FILE - oshibka smesheniya
// TMESSAGE_OK - ok
int TArchive::
SeekArc(LONG loffset, PLONG hoffset, DWORD MoveMethod)
{
LARGE_INTEGER Offset;
if (hoffset == NULL)
Offset.QuadPart = loffset;
else
{
Offset.LowPart = loffset;
Offset.HighPart = *hoffset;
}
Offset.LowPart = ::SetFilePointer(m_h, Offset.LowPart, &Offset.HighPart, MoveMethod);
if (Offset.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
return TERROR_SEEK_FILE;
else
return TMESSAGE_OK;
}
//opredelit' smeshenie v arhive
LONGLONG TArchive::
GetArcPointer()
{
LARGE_INTEGER ull;
ull.LowPart = 0;
ull.HighPart = 0;
ull.LowPart = ::SetFilePointer(m_h, 0, &ull.HighPart, FILE_CURRENT);
if (ull.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
{
ull.QuadPart = -1;
}
return ull.QuadPart;
}
/////////////////////////////////////////////////////////////////////////////
//FUNCTIONS PUBLIC
/////////////////////////////////////////////////////////////////////////////
//vizov testirovaniya ili sbora informacii
//lpDataForThread - dannie peredavaemie v potok (mojno i bez potoka)
//return
//TTERMINATE_THREAD - iskustvennoe zavershenie
//TMESSAGE_OK - ok
//ERROR_OPEN_FILE - oshibka otckritiya fayla
//ERROR_READ_FILE - oshibka chteniya fayla
//ERROR_SEEK_FILE - oshibka smesheniya fayla
//SUDDEN_END_FILE - vnezapniy konec fayla
//ERROR_FORMAT - oshibka formata fayla
int TArchive::
Start(LPVOID lpDataForThread)
{
DataForThread* dft = (DataForThread*)lpDataForThread;
//nujni tol'ko dlya zapuska v rabochem potoke
m_hWnd = dft->hWnd;
m_hEventEnd = dft->hEventEnd;
m_BeginThread = dft->BeginThread;
//dlya vremeni
clock_t start = 0;
clock_t finish = 0;
start = clock();
if (dft->Flag == TEST_ARC)
{
MSG = TestFile(dft->Path);
if (m_DetailLF >= 1)
m_LogFile->WriteMessage(m_LangMsg._TestArchive, MSG);
}
if (dft->Flag == ANALYZE_ARC)
{
MSG = AnalyzeInfoOfArc(dft->Path);
if (m_DetailLF >= 1)
m_LogFile->WriteMessage(m_LangMsg._AnalyzeArchive, MSG);
}
finish = clock();
//podschet vremeni
if (dft->Flag == TEST_ARC)
m_TestTime = ((double)(finish - start) / CLOCKS_PER_SEC);
if (dft->Flag == ANALYZE_ARC)
m_AnalyzeTime = ((double)(finish - start) / CLOCKS_PER_SEC);
m_AllTime = m_TestTime + m_AnalyzeTime;
//esli rabochiy potok to poslat' soobshenie
if (m_BeginThread)
::PostMessage(m_hWnd, WM_THREAD_FINISHED, 0, (LPARAM)MSG);
return MSG;
}