123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- #include "rar.hpp"
- #ifndef SHELL_EXT
- #include "arccmt.cpp"
- #endif
- Archive::Archive(RAROptions *InitCmd)
- {
- Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
- OpenShared=Cmd->OpenShared;
- OldFormat=false;
- Solid=false;
- Volume=false;
- MainComment=false;
- Locked=false;
- Signed=false;
- NotFirstVolume=false;
- SFXSize=0;
- LatestTime.Reset();
- Protected=false;
- Encrypted=false;
- FailedHeaderDecryption=false;
- BrokenFileHeader=false;
- LastReadBlock=0;
- CurBlockPos=0;
- NextBlockPos=0;
- RecoveryPos=SIZEOF_MARKHEAD;
- RecoverySectors=-1;
- memset(&NewMhd,0,sizeof(NewMhd));
- NewMhd.HeadType=MAIN_HEAD;
- NewMhd.HeadSize=SIZEOF_NEWMHD;
- HeaderCRC=0;
- VolWrite=0;
- AddingFilesSize=0;
- AddingHeadersSize=0;
- #if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
- *HeadersSalt=0;
- *SubDataSalt=0;
- #endif
- *FirstVolumeName=0;
- *FirstVolumeNameW=0;
- Splitting=false;
- NewArchive=false;
- SilentOpen=false;
- }
- #ifndef SHELL_EXT
- void Archive::CheckArc(bool EnableBroken)
- {
- if (!IsArchive(EnableBroken))
- {
- Log(FileName,St(MBadArc),FileName);
- ErrHandler.Exit(FATAL_ERROR);
- }
- }
- #endif
- #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
- void Archive::CheckOpen(const char *Name,const wchar *NameW)
- {
- TOpen(Name,NameW);
- CheckArc(false);
- }
- #endif
- bool Archive::WCheckOpen(const char *Name,const wchar *NameW)
- {
- if (!WOpen(Name,NameW))
- return(false);
- if (!IsArchive(false))
- {
- #ifndef SHELL_EXT
- Log(FileName,St(MNotRAR),FileName);
- #endif
- Close();
- return(false);
- }
- return(true);
- }
- bool Archive::IsSignature(byte *D)
- {
- bool Valid=false;
- if (D[0]==0x52)
- #ifndef SFX_MODULE
- if (D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
- {
- OldFormat=true;
- Valid=true;
- }
- else
- #endif
- if (D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07 && D[6]==0x00)
- {
- OldFormat=false;
- Valid=true;
- }
- return(Valid);
- }
- bool Archive::IsArchive(bool EnableBroken)
- {
- Encrypted=false;
- #ifndef SFX_MODULE
- if (IsDevice())
- {
- #ifndef SHELL_EXT
- Log(FileName,St(MInvalidName),FileName);
- #endif
- return(false);
- }
- #endif
- if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
- return(false);
- SFXSize=0;
- if (IsSignature(MarkHead.Mark))
- {
- if (OldFormat)
- Seek(0,SEEK_SET);
- }
- else
- {
- Array<char> Buffer(MAXSFXSIZE);
- long CurPos=(long)Tell();
- int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
- for (int I=0;I<ReadSize;I++)
- if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
- {
- if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
- {
- char *D=&Buffer[28-CurPos];
- if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
- continue;
- }
- SFXSize=CurPos+I;
- Seek(SFXSize,SEEK_SET);
- if (!OldFormat)
- Read(MarkHead.Mark,SIZEOF_MARKHEAD);
- break;
- }
- if (SFXSize==0)
- return(false);
- }
- ReadHeader();
- SeekToNext();
- #ifndef SFX_MODULE
- if (OldFormat)
- {
- NewMhd.Flags=OldMhd.Flags & 0x3f;
- NewMhd.HeadSize=OldMhd.HeadSize;
- }
- else
- #endif
- {
- if (HeaderCRC!=NewMhd.HeadCRC)
- {
- #ifndef SHELL_EXT
- Log(FileName,St(MLogMainHead));
- #endif
- Alarm();
- if (!EnableBroken)
- return(false);
- }
- }
- Volume=(NewMhd.Flags & MHD_VOLUME);
- Solid=(NewMhd.Flags & MHD_SOLID)!=0;
- MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
- Locked=(NewMhd.Flags & MHD_LOCK)!=0;
- Signed=(NewMhd.PosAV!=0);
- Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
- Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
- if (NewMhd.EncryptVer>UNP_VER)
- {
- #ifdef RARDLL
- Cmd->DllError=ERAR_UNKNOWN_FORMAT;
- #else
- ErrHandler.SetErrorCode(WARNING);
- #if !defined(SILENT) && !defined(SFX_MODULE)
- Log(FileName,St(MUnknownMeth),FileName);
- Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
- #endif
- #endif
- return(false);
- }
- #ifdef RARDLL
- // If callback function is not set, we cannot get the password,
- // so we skip the initial header processing for encrypted header archive.
- // It leads to skipped archive comment, but the rest of archive data
- // is processed correctly.
- if (Cmd->Callback==NULL)
- SilentOpen=true;
- #endif
- // If not encrypted, we'll check it below.
- NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;
- if (!SilentOpen || !Encrypted)
- {
- SaveFilePos SavePos(*this);
- int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
- NotFirstVolume=false;
- while (ReadHeader()!=0)
- {
- int HeaderType=GetHeaderType();
- if (HeaderType==NEWSUB_HEAD)
- {
- if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
- MainComment=true;
- if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
- Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
- NotFirstVolume=true;
- }
- else
- {
- if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
- Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
- NotFirstVolume=true;
- break;
- }
- SeekToNext();
- }
- CurBlockPos=SaveCurBlockPos;
- NextBlockPos=SaveNextBlockPos;
- }
- if (!Volume || !NotFirstVolume)
- {
- strcpy(FirstVolumeName,FileName);
- wcscpy(FirstVolumeNameW,FileNameW);
- }
- return(true);
- }
- void Archive::SeekToNext()
- {
- Seek(NextBlockPos,SEEK_SET);
- }
- #ifndef SFX_MODULE
- int Archive::GetRecoverySize(bool Required)
- {
- if (!Protected)
- return(0);
- if (RecoverySectors!=-1 || !Required)
- return(RecoverySectors);
- SaveFilePos SavePos(*this);
- Seek(SFXSize,SEEK_SET);
- SearchSubBlock(SUBHEAD_TYPE_RR);
- return(RecoverySectors);
- }
- #endif
|