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)
95 if (D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
102 if (D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07 && D[6]==0x00)
111 bool Archive::IsArchive(bool EnableBroken)
118 Log(FileName,St(MInvalidName),FileName);
123 if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
126 if (IsSignature(MarkHead.Mark))
133 Array<char> Buffer(0x40000);
134 long CurPos=int64to32(Tell());
135 int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
136 for (int I=0;I<ReadSize;I++)
137 if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
139 if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
141 char *D=&Buffer[28-CurPos];
142 if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
146 Seek(SFXSize,SEEK_SET);
148 Read(MarkHead.Mark,SIZEOF_MARKHEAD);
159 NewMhd.Flags=OldMhd.Flags & 0x3f;
160 NewMhd.HeadSize=OldMhd.HeadSize;
165 if (HeaderCRC!=NewMhd.HeadCRC)
168 Log(FileName,St(MLogMainHead));
175 Volume=(NewMhd.Flags & MHD_VOLUME);
176 Solid=(NewMhd.Flags & MHD_SOLID)!=0;
177 MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
178 Locked=(NewMhd.Flags & MHD_LOCK)!=0;
179 Signed=(NewMhd.PosAV!=0);
180 Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
181 Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
186 if (!SilentOpen || !Encrypted)
188 SaveFilePos SavePos(*this);
189 Int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
191 NotFirstVolume=false;
194 int HeaderType=GetHeaderType();
195 if (HeaderType==NEWSUB_HEAD)
197 if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
199 if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
200 Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
205 if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
206 Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
212 CurBlockPos=SaveCurBlockPos;
213 NextBlockPos=SaveNextBlockPos;
221 void Archive::SeekToNext()
223 Seek(NextBlockPos,SEEK_SET);
228 int Archive::GetRecoverySize(bool Required)
232 if (RecoverySectors!=-1 || !Required)
233 return(RecoverySectors);
234 SaveFilePos SavePos(*this);
235 Seek(SFXSize,SEEK_SET);
236 SearchSubBlock(SUBHEAD_TYPE_RR);
237 return(RecoverySectors);