unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

recvol3.cpp
Go to the documentation of this file.
1// Buffer size for all volumes involved.
2static const size_t TotalBufferSize=0x4000000;
3
4class RSEncode // Encode or decode data area, one object per one thread.
5{
6 private:
8 public:
9 void EncodeBuf();
10 void DecodeBuf();
11
13 byte *Buf;
14 byte *OutBuf;
16 int BufEnd;
22};
23
24
25#ifdef RAR_SMP
26THREAD_PROC(RSEncodeThread)
27{
28 RSEncode *rs=(RSEncode *)Data;
29 rs->EncodeBuf();
30}
31
32THREAD_PROC(RSDecodeThread)
33{
34 RSEncode *rs=(RSEncode *)Data;
35 rs->DecodeBuf();
36}
37#endif
38
40{
41 memset(SrcFile,0,sizeof(SrcFile));
42 if (TestOnly)
43 {
44#ifdef RAR_SMP
45 RSThreadPool=NULL;
46#endif
47 }
48 else
49 {
51 memset(SrcFile,0,sizeof(SrcFile));
52#ifdef RAR_SMP
53 RSThreadPool=new ThreadPool(Cmd->Threads);
54#endif
55 }
56}
57
58
60{
61 for (size_t I=0;I<ASIZE(SrcFile);I++)
62 delete SrcFile[I];
63#ifdef RAR_SMP
64 delete RSThreadPool;
65#endif
66}
67
68
69
70
72{
73 for (int BufPos=BufStart;BufPos<BufEnd;BufPos++)
74 {
75 byte Data[256],Code[256];
76 for (int I=0;I<FileNumber;I++)
77 Data[I]=Buf[I*RecBufferSize+BufPos];
78 RSC.Encode(Data,FileNumber,Code);
79 for (int I=0;I<RecVolNumber;I++)
80 OutBuf[I*RecBufferSize+BufPos]=Code[I];
81 }
82}
83
84
85// Check for names like arc5_3_1.rev created by RAR 3.0.
86static bool IsNewStyleRev(const wchar *Name)
87{
88 wchar *Ext=GetExt(Name);
89 if (Ext==NULL)
90 return true;
91 int DigitGroup=0;
92 for (Ext--;Ext>Name;Ext--)
93 if (!IsDigit(*Ext))
94 if (*Ext=='_' && IsDigit(*(Ext-1)))
95 DigitGroup++;
96 else
97 break;
98 return DigitGroup<2;
99}
100
101
102bool RecVolumes3::Restore(RAROptions *Cmd,const wchar *Name,bool Silent)
103{
104 wchar ArcName[NM];
105 wcsncpyz(ArcName,Name,ASIZE(ArcName));
106 wchar *Ext=GetExt(ArcName);
107 bool NewStyle=false; // New style .rev volumes are supported since RAR 3.10.
108 bool RevName=Ext!=NULL && wcsicomp(Ext,L".rev")==0;
109 if (RevName)
110 {
111 NewStyle=IsNewStyleRev(ArcName);
112 while (Ext>ArcName+1 && (IsDigit(*(Ext-1)) || *(Ext-1)=='_'))
113 Ext--;
114 wcsncpyz(Ext,L"*.*",ASIZE(ArcName)-(Ext-ArcName));
115
116 FindFile Find;
117 Find.SetMask(ArcName);
118 FindData fd;
119 while (Find.Next(&fd))
120 {
121 Archive Arc(Cmd);
122 if (Arc.WOpen(fd.Name) && Arc.IsArchive(true))
123 {
124 wcsncpyz(ArcName,fd.Name,ASIZE(ArcName));
125 break;
126 }
127 }
128 }
129
130 Archive Arc(Cmd);
131 if (!Arc.WCheckOpen(ArcName))
132 return false;
133 if (!Arc.Volume)
134 {
135 uiMsg(UIERROR_NOTVOLUME,ArcName);
136 return false;
137 }
138 bool NewNumbering=Arc.NewNumbering;
139 Arc.Close();
140
141 wchar *VolNumStart=VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),NewNumbering);
142 wchar RecVolMask[NM];
143 wcsncpyz(RecVolMask,ArcName,ASIZE(RecVolMask));
144 size_t BaseNamePartLength=VolNumStart-ArcName;
145 wcsncpyz(RecVolMask+BaseNamePartLength,L"*.rev",ASIZE(RecVolMask)-BaseNamePartLength);
146
147 int64 RecFileSize=0;
148
149 // We cannot display "Calculating CRC..." message here, because we do not
150 // know if we'll find any recovery volumes. We'll display it after finding
151 // the first recovery volume.
152 bool CalcCRCMessageDone=false;
153
154 FindFile Find;
155 Find.SetMask(RecVolMask);
156 FindData RecData;
157 int FileNumber=0,RecVolNumber=0,FoundRecVolumes=0,MissingVolumes=0;
158 wchar PrevName[NM];
159 while (Find.Next(&RecData))
160 {
161 wchar *CurName=RecData.Name;
162 int P[3];
163 if (!RevName && !NewStyle)
164 {
165 NewStyle=true;
166
167 wchar *Dot=GetExt(CurName);
168 if (Dot!=NULL)
169 {
170 int LineCount=0;
171 Dot--;
172 while (Dot>CurName && *Dot!='.')
173 {
174 if (*Dot=='_')
175 LineCount++;
176 Dot--;
177 }
178 if (LineCount==2)
179 NewStyle=false;
180 }
181 }
182 if (NewStyle)
183 {
184 if (!CalcCRCMessageDone)
185 {
187 CalcCRCMessageDone=true;
188 }
189
190 uiMsg(UIMSG_STRING,CurName);
191
192 File CurFile;
193 CurFile.TOpen(CurName);
194 CurFile.Seek(0,SEEK_END);
195 int64 Length=CurFile.Tell();
196 CurFile.Seek(Length-7,SEEK_SET);
197 for (int I=0;I<3;I++)
198 P[2-I]=CurFile.GetByte()+1;
199 uint FileCRC=0;
200 for (int I=0;I<4;I++)
201 FileCRC|=CurFile.GetByte()<<(I*8);
202 uint CalcCRC;
203 CalcFileSum(&CurFile,&CalcCRC,NULL,Cmd->Threads,Length-4);
204 if (FileCRC!=CalcCRC)
205 {
206 uiMsg(UIMSG_CHECKSUM,CurName);
207 continue;
208 }
209 }
210 else
211 {
212 wchar *Dot=GetExt(CurName);
213 if (Dot==NULL)
214 continue;
215 bool WrongParam=false;
216 for (size_t I=0;I<ASIZE(P);I++)
217 {
218 do
219 {
220 Dot--;
221 } while (IsDigit(*Dot) && Dot>=CurName+BaseNamePartLength);
222 P[I]=atoiw(Dot+1);
223 if (P[I]==0 || P[I]>255)
224 WrongParam=true;
225 }
226 if (WrongParam)
227 continue;
228 }
229 if (P[1]+P[2]>255)
230 continue;
231 if (RecVolNumber!=0 && RecVolNumber!=P[1] || FileNumber!=0 && FileNumber!=P[2])
232 {
233 uiMsg(UIERROR_RECVOLDIFFSETS,CurName,PrevName);
234 return false;
235 }
236 RecVolNumber=P[1];
237 FileNumber=P[2];
238 wcsncpyz(PrevName,CurName,ASIZE(PrevName));
239 File *NewFile=new File;
240 NewFile->TOpen(CurName);
241 SrcFile[FileNumber+P[0]-1]=NewFile;
242 FoundRecVolumes++;
243
244 if (RecFileSize==0)
245 RecFileSize=NewFile->FileLength();
246 }
247 if (!Silent || FoundRecVolumes!=0)
248 uiMsg(UIMSG_RECVOLFOUND,FoundRecVolumes);
249 if (FoundRecVolumes==0)
250 return false;
251
252 bool WriteFlags[256];
253 memset(WriteFlags,0,sizeof(WriteFlags));
254
255 wchar LastVolName[NM];
256 *LastVolName=0;
257
258 for (int CurArcNum=0;CurArcNum<FileNumber;CurArcNum++)
259 {
260 Archive *NewFile=new Archive(Cmd);
261 bool ValidVolume=FileExist(ArcName);
262 if (ValidVolume)
263 {
264 NewFile->TOpen(ArcName);
265 ValidVolume=NewFile->IsArchive(false);
266 if (ValidVolume)
267 {
268 while (NewFile->ReadHeader()!=0)
269 {
270 if (NewFile->GetHeaderType()==HEAD_ENDARC)
271 {
272 uiMsg(UIMSG_STRING,ArcName);
273
274 if (NewFile->EndArcHead.DataCRC)
275 {
276 uint CalcCRC;
277 CalcFileSum(NewFile,&CalcCRC,NULL,Cmd->Threads,NewFile->CurBlockPos);
278 if (NewFile->EndArcHead.ArcDataCRC!=CalcCRC)
279 {
280 ValidVolume=false;
281 uiMsg(UIMSG_CHECKSUM,ArcName);
282 }
283 }
284 break;
285 }
286 NewFile->SeekToNext();
287 }
288 }
289 if (!ValidVolume)
290 {
291 NewFile->Close();
292 wchar NewName[NM];
293 wcsncpyz(NewName,ArcName,ASIZE(NewName));
294 wcsncatz(NewName,L".bad",ASIZE(NewName));
295
296 uiMsg(UIMSG_BADARCHIVE,ArcName);
297 uiMsg(UIMSG_RENAMING,ArcName,NewName);
298 RenameFile(ArcName,NewName);
299 }
300 NewFile->Seek(0,SEEK_SET);
301 }
302 if (!ValidVolume)
303 {
304 // It is important to return 'false' instead of aborting here,
305 // so if we are called from extraction, we will be able to continue
306 // extracting. It may happen if .rar and .rev are on read-only disks
307 // like CDs.
308 if (!NewFile->Create(ArcName,FMF_WRITE|FMF_SHAREREAD))
309 {
310 // We need to display the title of operation before the error message,
311 // to make clear for user that create error is related to recovery
312 // volumes. This is why we cannot use WCreate call here. Title must be
313 // before create error, not after that.
314
315 uiMsg(UIERROR_RECVOLFOUND,FoundRecVolumes); // Intentionally not displayed in console mode.
317 ErrHandler.CreateErrorMsg(ArcName);
318 return false;
319 }
320
321 WriteFlags[CurArcNum]=true;
322 MissingVolumes++;
323
324 if (CurArcNum==FileNumber-1)
325 wcsncpyz(LastVolName,ArcName,ASIZE(LastVolName));
326
327 uiMsg(UIMSG_MISSINGVOL,ArcName);
328 uiMsg(UIEVENT_NEWARCHIVE,ArcName);
329 }
330 SrcFile[CurArcNum]=(File*)NewFile;
331 NextVolumeName(ArcName,ASIZE(ArcName),!NewNumbering);
332 }
333
334 uiMsg(UIMSG_RECVOLMISSING,MissingVolumes);
335
336 if (MissingVolumes==0)
337 {
339 return false;
340 }
341
342 if (MissingVolumes>FoundRecVolumes)
343 {
344 uiMsg(UIERROR_RECVOLFOUND,FoundRecVolumes); // Intentionally not displayed in console mode.
346 return false;
347 }
348
350
351 int TotalFiles=FileNumber+RecVolNumber;
352 int Erasures[256],EraSize=0;
353
354 for (int I=0;I<TotalFiles;I++)
355 if (WriteFlags[I] || SrcFile[I]==NULL)
356 Erasures[EraSize++]=I;
357
358 int64 ProcessedSize=0;
359 int LastPercent=-1;
360 mprintf(L" ");
361 // Size of per file buffer.
362 size_t RecBufferSize=TotalBufferSize/TotalFiles;
363
364#ifdef RAR_SMP
365 uint ThreadNumber=Cmd->Threads;
366#else
367 uint ThreadNumber=1;
368#endif
369 RSEncode *rse=new RSEncode[ThreadNumber];
370 for (uint I=0;I<ThreadNumber;I++)
371 rse[I].Init(RecVolNumber);
372
373 while (true)
374 {
375 Wait();
376 int MaxRead=0;
377 for (int I=0;I<TotalFiles;I++)
378 if (WriteFlags[I] || SrcFile[I]==NULL)
379 memset(&Buf[I*RecBufferSize],0,RecBufferSize);
380 else
381 {
382 int ReadSize=SrcFile[I]->Read(&Buf[I*RecBufferSize],RecBufferSize);
383 if ((size_t)ReadSize!=RecBufferSize)
384 memset(&Buf[I*RecBufferSize+ReadSize],0,RecBufferSize-ReadSize);
385 if (ReadSize>MaxRead)
386 MaxRead=ReadSize;
387 }
388 if (MaxRead==0)
389 break;
390
391 int CurPercent=ToPercent(ProcessedSize,RecFileSize);
392 if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
393 {
394 uiProcessProgress("RC",ProcessedSize,RecFileSize);
395 LastPercent=CurPercent;
396 }
397 ProcessedSize+=MaxRead;
398
399 int BlockStart=0;
400 int BlockSize=MaxRead/ThreadNumber;
401 if (BlockSize<0x100)
402 BlockSize=MaxRead;
403
404 for (uint CurThread=0;BlockStart<MaxRead;CurThread++)
405 {
406 // Last thread processes all left data including increasement
407 // from rounding error.
408 if (CurThread==ThreadNumber-1)
409 BlockSize=MaxRead-BlockStart;
410
411 RSEncode *curenc=rse+CurThread;
412 curenc->Buf=&Buf[0];
413 curenc->BufStart=BlockStart;
414 curenc->BufEnd=BlockStart+BlockSize;
415 curenc->FileNumber=TotalFiles;
416 curenc->RecBufferSize=RecBufferSize;
417 curenc->Erasures=Erasures;
418 curenc->EraSize=EraSize;
419
420#ifdef RAR_SMP
421 if (ThreadNumber>1)
422 RSThreadPool->AddTask(RSDecodeThread,(void*)curenc);
423 else
424 curenc->DecodeBuf();
425#else
426 curenc->DecodeBuf();
427#endif
428
429 BlockStart+=BlockSize;
430 }
431
432#ifdef RAR_SMP
433 RSThreadPool->WaitDone();
434#endif // RAR_SMP
435
436 for (int I=0;I<FileNumber;I++)
437 if (WriteFlags[I])
438 SrcFile[I]->Write(&Buf[I*RecBufferSize],MaxRead);
439 }
440 delete[] rse;
441
442 for (int I=0;I<RecVolNumber+FileNumber;I++)
443 if (SrcFile[I]!=NULL)
444 {
445 File *CurFile=SrcFile[I];
446 if (NewStyle && WriteFlags[I])
447 {
448 int64 Length=CurFile->Tell();
449 CurFile->Seek(Length-7,SEEK_SET);
450 for (int J=0;J<7;J++)
451 CurFile->PutByte(0);
452 }
453 CurFile->Close();
454 SrcFile[I]=NULL;
455 }
456 if (*LastVolName!=0)
457 {
458 // Truncate the last volume to its real size.
459 Archive Arc(Cmd);
460 if (Arc.Open(LastVolName,FMF_UPDATE) && Arc.IsArchive(true) &&
462 {
463 Arc.Seek(Arc.NextBlockPos,SEEK_SET);
464 char Buf[8192];
465 int ReadSize=Arc.Read(Buf,sizeof(Buf));
466 int ZeroCount=0;
467 while (ZeroCount<ReadSize && Buf[ZeroCount]==0)
468 ZeroCount++;
469 if (ZeroCount==ReadSize)
470 {
471 Arc.Seek(Arc.NextBlockPos,SEEK_SET);
472 Arc.Truncate();
473 }
474 }
475 }
476#if !defined(SILENT)
477 if (!Cmd->DisablePercentage)
478 mprintf(L"\b\b\b\b100%%");
479 if (!Silent && !Cmd->DisableDone)
480 mprintf(St(MDone));
481#endif
482 return true;
483}
484
485
487{
488 for (int BufPos=BufStart;BufPos<BufEnd;BufPos++)
489 {
490 byte Data[256];
491 for (int I=0;I<FileNumber;I++)
492 Data[I]=Buf[I*RecBufferSize+BufPos];
494 for (int I=0;I<EraSize;I++)
495 Buf[Erasures[I]*RecBufferSize+BufPos]=Data[Erasures[I]];
496 }
497}
498
499
500void RecVolumes3::Test(RAROptions *Cmd,const wchar *Name)
501{
502 if (!IsNewStyleRev(Name)) // RAR 3.0 name#_#_#.rev do not include CRC32.
503 {
504 ErrHandler.UnknownMethodMsg(Name,Name);
505 return;
506 }
507
508 wchar VolName[NM];
509 wcsncpyz(VolName,Name,ASIZE(VolName));
510
511 while (FileExist(VolName))
512 {
513 File CurFile;
514 if (!CurFile.Open(VolName))
515 {
516 ErrHandler.OpenErrorMsg(VolName); // It also sets RARX_OPEN.
517 continue;
518 }
519 if (!uiStartFileExtract(VolName,false,true,false))
520 return;
521 mprintf(St(MExtrTestFile),VolName);
522 mprintf(L" ");
523 CurFile.Seek(0,SEEK_END);
524 int64 Length=CurFile.Tell();
525 CurFile.Seek(Length-4,SEEK_SET);
526 uint FileCRC=0;
527 for (int I=0;I<4;I++)
528 FileCRC|=CurFile.GetByte()<<(I*8);
529
530 uint CalcCRC;
531 CalcFileSum(&CurFile,&CalcCRC,NULL,1,Length-4,Cmd->DisablePercentage ? 0 : CALCFSUM_SHOWPROGRESS);
532 if (FileCRC==CalcCRC)
533 {
534 mprintf(L"%s%s ",L"\b\b\b\b\b ",St(MOk));
535 }
536 else
537 {
538 uiMsg(UIERROR_CHECKSUM,VolName,VolName);
540 }
541
542 NextVolumeName(VolName,ASIZE(VolName),false);
543 }
544}
ErrorHandler ErrHandler
size_t ReadHeader()
Definition: arcread.cpp:3
HEADER_TYPE GetHeaderType()
Definition: archive.hpp:85
bool IsArchive(bool EnableBroken)
Definition: archive.cpp:126
EndArcHeader EndArcHead
Definition: archive.hpp:105
void SeekToNext()
Definition: archive.cpp:276
int64 NextBlockPos
Definition: archive.hpp:115
size_t SearchBlock(HEADER_TYPE HeaderType)
Definition: arcread.cpp:48
bool WCheckOpen(const wchar *Name)
Definition: archive.cpp:85
int64 CurBlockPos
Definition: archive.hpp:114
bool NewNumbering
Definition: archive.hpp:124
bool Volume
Definition: archive.hpp:119
void Alloc(size_t Items)
Definition: array.hpp:139
void OpenErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:164
void SetErrorCode(RAR_EXIT Code)
Definition: errhnd.cpp:243
void UnknownMethodMsg(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:229
void CreateErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:179
Definition: file.hpp:57
virtual void Seek(int64 Offset, int Method)
Definition: file.cpp:514
bool Truncate()
Definition: file.cpp:640
int64 FileLength()
Definition: file.cpp:750
void PutByte(byte Byte)
Definition: file.cpp:634
bool Create(const wchar *Name, uint Mode=FMF_UPDATE|FMF_SHAREREAD)
Definition: file.cpp:176
bool Write(const void *Data, size_t Size)
Definition: file.cpp:298
virtual int Read(void *Data, size_t Size)
Definition: file.cpp:374
virtual bool Open(const wchar *Name, uint Mode=FMF_READ)
Definition: file.cpp:48
virtual int64 Tell()
Definition: file.cpp:576
byte GetByte()
Definition: file.cpp:626
virtual bool Close()
Definition: file.cpp:241
bool WOpen(const wchar *Name)
Definition: file.cpp:167
void TOpen(const wchar *Name)
Definition: file.cpp:159
void SetMask(const wchar *Mask)
Definition: find.cpp:27
bool Next(FindData *fd, bool GetSymLink=false)
Definition: find.cpp:34
bool DisableDone
Definition: options.hpp:137
bool DisablePercentage
Definition: options.hpp:135
uint Threads
Definition: options.hpp:206
Definition: rs.hpp:8
void Init(int ParSize)
Definition: rs.cpp:5
void Encode(byte *Data, int DataSize, byte *DestData)
Definition: rs.cpp:74
bool Decode(byte *Data, int DataSize, int *EraLoc, int EraSize)
Definition: rs.cpp:93
byte * Buf
Definition: recvol3.cpp:13
int FileNumber
Definition: recvol3.cpp:17
int * Erasures
Definition: recvol3.cpp:20
int EraSize
Definition: recvol3.cpp:21
size_t RecBufferSize
Definition: recvol3.cpp:19
void EncodeBuf()
Definition: recvol3.cpp:71
void Init(int RecVolNumber)
Definition: recvol3.cpp:12
int BufStart
Definition: recvol3.cpp:15
int BufEnd
Definition: recvol3.cpp:16
int RecVolNumber
Definition: recvol3.cpp:18
byte * OutBuf
Definition: recvol3.cpp:14
void DecodeBuf()
Definition: recvol3.cpp:486
RSCoder RSC
Definition: recvol3.cpp:7
File * SrcFile[256]
Definition: recvol.hpp:10
Array< byte > Buf
Definition: recvol.hpp:11
bool Restore(RAROptions *Cmd, const wchar *Name, bool Silent)
Definition: recvol3.cpp:102
~RecVolumes3()
Definition: recvol3.cpp:59
void Test(RAROptions *Cmd, const wchar *Name)
Definition: recvol3.cpp:500
RecVolumes3(RAROptions *Cmd, bool TestOnly)
Definition: recvol3.cpp:39
void mprintf(const wchar *fmt,...)
Definition: consio.cpp:118
@ RARX_CRC
Definition: errhnd.hpp:9
@ FMF_WRITE
Definition: file.hpp:31
@ FMF_SHAREREAD
Definition: file.hpp:40
@ FMF_UPDATE
Definition: file.hpp:28
void CalcFileSum(File *SrcFile, uint *CRC32, byte *Blake2, uint Threads, int64 Size, uint Flags)
Definition: filefn.cpp:361
bool RenameFile(const wchar *SrcName, const wchar *DestName)
Definition: filefn.cpp:439
bool FileExist(const wchar *Name)
Definition: filefn.cpp:190
@ CALCFSUM_SHOWPROGRESS
Definition: filefn.hpp:34
@ HEAD_ENDARC
Definition: headers.hpp:77
#define MDone
Definition: loclang.hpp:184
#define MExtrTestFile
Definition: loclang.hpp:216
#define MOk
Definition: loclang.hpp:183
wchar * VolNameToFirstName(const wchar *VolName, wchar *FirstName, size_t MaxSize, bool NewNumbering)
Definition: pathfn.cpp:632
wchar * GetExt(const wchar *Name)
Definition: pathfn.cpp:107
void NextVolumeName(wchar *ArcName, uint MaxLength, bool OldNumbering)
Definition: pathfn.cpp:359
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
int64_t int64
Definition: rartypes.hpp:12
unsigned int uint
Definition: rartypes.hpp:8
static bool IsNewStyleRev(const wchar *Name)
Definition: recvol3.cpp:86
static const size_t TotalBufferSize
Definition: recvol3.cpp:2
const wchar * St(MSGID StringId)
Definition: resource.cpp:8
int ToPercent(int64 N1, int64 N2)
Definition: smallfn.cpp:3
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:275
void wcsncatz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:300
bool IsDigit(int ch)
Definition: strfn.cpp:151
uint ArcDataCRC
Definition: headers.hpp:267
bool DataCRC
Definition: headers.hpp:274
Definition: find.hpp:9
wchar Name[NM]
Definition: find.hpp:10
void Wait()
Definition: system.cpp:80
void uiProcessProgress(const char *Command, int64 CurSize, int64 TotalSize)
Definition: uiconsole.cpp:82
void uiMsg(UIMESSAGE_CODE Code)
Definition: ui.hpp:148
bool uiStartFileExtract(const wchar *FileName, bool Extract, bool Test, bool Skip)
Definition: uiconsole.cpp:66
@ UIERROR_NOTVOLUME
Definition: ui.hpp:25
@ UIEVENT_NEWARCHIVE
Definition: ui.hpp:64
@ UIERROR_RECVOLFOUND
Definition: ui.hpp:27
@ UIMSG_BADARCHIVE
Definition: ui.hpp:49
@ UIMSG_CHECKSUM
Definition: ui.hpp:51
@ UIMSG_RECVOLFOUND
Definition: ui.hpp:50
@ UIERROR_CHECKSUM
Definition: ui.hpp:11
@ UIMSG_RECVOLCALCCHECKSUM
Definition: ui.hpp:50
@ UIERROR_RECONSTRUCTING
Definition: ui.hpp:27
@ UIMSG_MISSINGVOL
Definition: ui.hpp:51
@ UIERROR_RECVOLCANNOTFIX
Definition: ui.hpp:28
@ UIMSG_STRING
Definition: ui.hpp:45
@ UIERROR_RECVOLDIFFSETS
Definition: ui.hpp:26
@ UIMSG_RECONSTRUCTING
Definition: ui.hpp:51
@ UIMSG_RECVOLMISSING
Definition: ui.hpp:50
@ UIERROR_RECVOLALLEXIST
Definition: ui.hpp:27
@ UIMSG_RENAMING
Definition: ui.hpp:49
int wcsicomp(const wchar *s1, const wchar *s2)
Definition: unicode.cpp:425
int atoiw(const wchar *s)
Definition: unicode.cpp:550
THREAD_PROC(UnpackDecodeThread)
Definition: unpack50mt.cpp:12