8 Archive::Archive(RAROptions *InitCmd)
10 Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
11 OpenShared=Cmd->OpenShared;
23 BrokenFileHeader=false;
29 RecoveryPos=SIZEOF_MARKHEAD;
32 memset(&NewMhd,0,sizeof(NewMhd));
33 NewMhd.HeadType=MAIN_HEAD;
34 NewMhd.HeadSize=SIZEOF_NEWMHD;
39 #if !defined(SHELL_EXT) && !defined(NOCRYPT)
54 void Archive::CheckArc(bool EnableBroken)
56 if (!IsArchive(EnableBroken))
58 Log(FileName,St(MBadArc),FileName);
59 ErrHandler.Exit(FATAL_ERROR);
65 #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
66 void Archive::CheckOpen(char *Name,wchar *NameW)
74 bool Archive::WCheckOpen(char *Name,wchar *NameW)
76 if (!WOpen(Name,NameW))
78 if (!IsArchive(false))
81 Log(FileName,St(MNotRAR),FileName);
90 bool Archive::IsSignature(byte *D)
96 if (D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
104 if (D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07 && D[6]==0x00)
115 bool Archive::IsArchive(bool EnableBroken)
122 Log(FileName,St(MInvalidName),FileName);
127 if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
131 if (IsSignature(MarkHead.Mark))
138 Array<char> Buffer(0x80000);
139 long CurPos=int64to32(Tell());
140 int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
141 for (int I=0;I<ReadSize;I++)
142 if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
144 if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
146 char *D=&Buffer[28-CurPos];
147 if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
151 Seek(SFXSize,SEEK_SET);
153 Read(MarkHead.Mark,SIZEOF_MARKHEAD);
164 NewMhd.Flags=OldMhd.Flags & 0x3f;
165 NewMhd.HeadSize=OldMhd.HeadSize;
170 if (HeaderCRC!=NewMhd.HeadCRC)
173 Log(FileName,St(MLogMainHead));
180 Volume=(NewMhd.Flags & MHD_VOLUME);
181 Solid=(NewMhd.Flags & MHD_SOLID)!=0;
182 MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
183 Locked=(NewMhd.Flags & MHD_LOCK)!=0;
184 Signed=(NewMhd.PosAV!=0);
185 Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
186 Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
191 if (!SilentOpen || !Encrypted)
193 SaveFilePos SavePos(*this);
194 Int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
196 NotFirstVolume=false;
199 int HeaderType=GetHeaderType();
200 if (HeaderType==NEWSUB_HEAD)
202 if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
204 if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
205 (Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
210 if ((HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0)) ||
211 (Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
217 CurBlockPos=SaveCurBlockPos;
218 NextBlockPos=SaveNextBlockPos;
226 void Archive::SeekToNext()
228 Seek(NextBlockPos,SEEK_SET);
233 int Archive::GetRecoverySize(bool Required)
237 if (RecoverySectors!=-1 || !Required)
238 return(RecoverySectors);
239 SaveFilePos SavePos(*this);
240 Seek(SFXSize,SEEK_SET);
241 SearchSubBlock(SUBHEAD_TYPE_RR);
242 return(RecoverySectors);