forked from pmachapman/unrar
-
Notifications
You must be signed in to change notification settings - Fork 0
/
recvol.cpp
111 lines (98 loc) · 2.55 KB
/
recvol.cpp
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
#include "rar.hpp"
#include "recvol3.cpp"
#include "recvol5.cpp"
bool RecVolumesRestore(CommandData *Cmd,const wchar *Name,bool Silent)
{
Archive Arc(Cmd);
if (!Arc.Open(Name))
{
if (!Silent)
ErrHandler.OpenErrorMsg(Name);
return false;
}
RARFORMAT Fmt=RARFMT15;
if (Arc.IsArchive(true))
Fmt=Arc.Format;
else
{
byte Sign[REV5_SIGN_SIZE];
Arc.Seek(0,SEEK_SET);
if (Arc.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0)
Fmt=RARFMT50;
}
Arc.Close();
// We define RecVol as local variable for proper stack unwinding when
// handling exceptions. So it can close and delete files on Cancel.
if (Fmt==RARFMT15)
{
RecVolumes3 RecVol(Cmd,false);
return RecVol.Restore(Cmd,Name,Silent);
}
else
{
RecVolumes5 RecVol(Cmd,false);
return RecVol.Restore(Cmd,Name,Silent);
}
}
void RecVolumesTest(CommandData *Cmd,Archive *Arc,const wchar *Name)
{
wchar RevName[NM];
*RevName=0;
if (Arc!=NULL)
{
// We received .rar or .exe volume as a parameter, trying to find
// the matching .rev file number 1.
bool NewNumbering=Arc->NewNumbering;
wchar ArcName[NM];
wcsncpyz(ArcName,Name,ASIZE(ArcName));
wchar *VolNumStart=VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),NewNumbering);
wchar RecVolMask[NM];
wcsncpyz(RecVolMask,ArcName,ASIZE(RecVolMask));
size_t BaseNamePartLength=VolNumStart-ArcName;
wcsncpyz(RecVolMask+BaseNamePartLength,L"*.rev",ASIZE(RecVolMask)-BaseNamePartLength);
FindFile Find;
Find.SetMask(RecVolMask);
FindData RecData;
while (Find.Next(&RecData))
{
wchar *Num=GetVolNumPart(RecData.Name);
if (*Num!='1') // Name must have "0...01" numeric part.
continue;
bool FirstVol=true;
while (--Num>=RecData.Name && IsDigit(*Num))
if (*Num!='0')
{
FirstVol=false;
break;
}
if (FirstVol)
{
wcsncpyz(RevName,RecData.Name,ASIZE(RevName));
Name=RevName;
break;
}
}
if (*RevName==0) // First .rev file not found.
return;
}
File RevFile;
if (!RevFile.Open(Name))
{
ErrHandler.OpenErrorMsg(Name); // It also sets RARX_OPEN.
return;
}
mprintf(L"\n");
byte Sign[REV5_SIGN_SIZE];
bool Rev5=RevFile.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0;
RevFile.Close();
if (Rev5)
{
RecVolumes5 RecVol(Cmd,true);
RecVol.Test(Cmd,Name);
}
else
{
RecVolumes3 RecVol(Cmd,true);
RecVol.Test(Cmd,Name);
}
}