1 #include "rar.hpp"
2
3 #ifndef SHELL_EXT
4 #include "arccmt.cpp"
5 #endif
6
7
Archive(RAROptions * InitCmd)8 Archive::Archive(RAROptions *InitCmd)
9 {
10 Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
11 OpenShared=Cmd->OpenShared;
12 OldFormat=false;
13 Solid=false;
14 Volume=false;
15 MainComment=false;
16 Locked=false;
17 Signed=false;
18 NotFirstVolume=false;
19 SFXSize=0;
20 LatestTime.Reset();
21 Protected=false;
22 Encrypted=false;
23 FailedHeaderDecryption=false;
24 BrokenFileHeader=false;
25 LastReadBlock=0;
26
27 CurBlockPos=0;
28 NextBlockPos=0;
29
30 RecoveryPos=SIZEOF_MARKHEAD;
31 RecoverySectors=-1;
32
33 memset(&NewMhd,0,sizeof(NewMhd));
34 NewMhd.HeadType=MAIN_HEAD;
35 NewMhd.HeadSize=SIZEOF_NEWMHD;
36 HeaderCRC=0;
37 VolWrite=0;
38 AddingFilesSize=0;
39 AddingHeadersSize=0;
40 #if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
41 *HeadersSalt=0;
42 *SubDataSalt=0;
43 #endif
44 *FirstVolumeName=0;
45 *FirstVolumeNameW=0;
46
47 Splitting=false;
48 NewArchive=false;
49
50 SilentOpen=false;
51
52 }
53
54
55 #ifndef SHELL_EXT
CheckArc(bool EnableBroken)56 void Archive::CheckArc(bool EnableBroken)
57 {
58 if (!IsArchive(EnableBroken))
59 {
60 Log(FileName,St(MBadArc),FileName);
61 ErrHandler.Exit(FATAL_ERROR);
62 }
63 }
64 #endif
65
66
67 #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
CheckOpen(const char * Name,const wchar * NameW)68 void Archive::CheckOpen(const char *Name,const wchar *NameW)
69 {
70 TOpen(Name,NameW);
71 CheckArc(false);
72 }
73 #endif
74
75
WCheckOpen(const char * Name,const wchar * NameW)76 bool Archive::WCheckOpen(const char *Name,const wchar *NameW)
77 {
78 if (!WOpen(Name,NameW))
79 return(false);
80 if (!IsArchive(false))
81 {
82 #ifndef SHELL_EXT
83 Log(FileName,St(MNotRAR),FileName);
84 #endif
85 Close();
86 return(false);
87 }
88 return(true);
89 }
90
91
IsSignature(byte * D)92 bool Archive::IsSignature(byte *D)
93 {
94 bool Valid=false;
95 if (D[0]==0x52)
96 #ifndef SFX_MODULE
97 if (D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
98 {
99 OldFormat=true;
100 Valid=true;
101 }
102 else
103 #endif
104 if (D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07 && D[6]==0x00)
105 {
106 OldFormat=false;
107 Valid=true;
108 }
109 return(Valid);
110 }
111
112
IsArchive(bool EnableBroken)113 bool Archive::IsArchive(bool EnableBroken)
114 {
115 Encrypted=false;
116 #ifndef SFX_MODULE
117 if (IsDevice())
118 {
119 #ifndef SHELL_EXT
120 Log(FileName,St(MInvalidName),FileName);
121 #endif
122 return(false);
123 }
124 #endif
125 if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
126 return(false);
127 SFXSize=0;
128 if (IsSignature(MarkHead.Mark))
129 {
130 if (OldFormat)
131 Seek(0,SEEK_SET);
132 }
133 else
134 {
135 Array<char> Buffer(MAXSFXSIZE);
136 long CurPos=(long)Tell();
137 int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
138 for (int I=0;I<ReadSize;I++)
139 if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
140 {
141 if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
142 {
143 char *D=&Buffer[28-CurPos];
144 if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
145 continue;
146 }
147 SFXSize=CurPos+I;
148 Seek(SFXSize,SEEK_SET);
149 if (!OldFormat)
150 Read(MarkHead.Mark,SIZEOF_MARKHEAD);
151 break;
152 }
153 if (SFXSize==0)
154 return(false);
155 }
156 ReadHeader();
157 SeekToNext();
158 #ifndef SFX_MODULE
159 if (OldFormat)
160 {
161 NewMhd.Flags=OldMhd.Flags & 0x3f;
162 NewMhd.HeadSize=OldMhd.HeadSize;
163 }
164 else
165 #endif
166 {
167 if (HeaderCRC!=NewMhd.HeadCRC)
168 {
169 #ifndef SHELL_EXT
170 Log(FileName,St(MLogMainHead));
171 #endif
172 Alarm();
173 if (!EnableBroken)
174 return(false);
175 }
176 }
177 Volume=(NewMhd.Flags & MHD_VOLUME);
178 Solid=(NewMhd.Flags & MHD_SOLID)!=0;
179 MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
180 Locked=(NewMhd.Flags & MHD_LOCK)!=0;
181 Signed=(NewMhd.PosAV!=0);
182 Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
183 Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
184
185 if (NewMhd.EncryptVer>UNP_VER)
186 {
187 #ifdef RARDLL
188 Cmd->DllError=ERAR_UNKNOWN_FORMAT;
189 #else
190 ErrHandler.SetErrorCode(WARNING);
191 #if !defined(SILENT) && !defined(SFX_MODULE)
192 Log(FileName,St(MUnknownMeth),FileName);
193 Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
194 #endif
195 #endif
196 return(false);
197 }
198 #ifdef RARDLL
199 // If callback function is not set, we cannot get the password,
200 // so we skip the initial header processing for encrypted header archive.
201 // It leads to skipped archive comment, but the rest of archive data
202 // is processed correctly.
203 if (Cmd->Callback==NULL)
204 SilentOpen=true;
205 #endif
206
207 // If not encrypted, we'll check it below.
208 NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;
209
210 if (!SilentOpen || !Encrypted)
211 {
212 SaveFilePos SavePos(*this);
213 int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
214
215 NotFirstVolume=false;
216 while (ReadHeader()!=0)
217 {
218 int HeaderType=GetHeaderType();
219 if (HeaderType==NEWSUB_HEAD)
220 {
221 if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
222 MainComment=true;
223 if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
224 Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
225 NotFirstVolume=true;
226 }
227 else
228 {
229 if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
230 Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
231 NotFirstVolume=true;
232 break;
233 }
234 SeekToNext();
235 }
236 CurBlockPos=SaveCurBlockPos;
237 NextBlockPos=SaveNextBlockPos;
238 }
239 if (!Volume || !NotFirstVolume)
240 {
241 strcpy(FirstVolumeName,FileName);
242 wcscpy(FirstVolumeNameW,FileNameW);
243 }
244
245 return(true);
246 }
247
248
249
250
SeekToNext()251 void Archive::SeekToNext()
252 {
253 Seek(NextBlockPos,SEEK_SET);
254 }
255
256
257 #ifndef SFX_MODULE
GetRecoverySize(bool Required)258 int Archive::GetRecoverySize(bool Required)
259 {
260 if (!Protected)
261 return(0);
262 if (RecoverySectors!=-1 || !Required)
263 return(RecoverySectors);
264 SaveFilePos SavePos(*this);
265 Seek(SFXSize,SEEK_SET);
266 SearchSubBlock(SUBHEAD_TYPE_RR);
267 return(RecoverySectors);
268 }
269 #endif
270
271
272
273
274