📄 extract.cpp
字号:
#include "rar.hpp"CmdExtract::CmdExtract(){ TotalFileCount=0; *Password=0; Unp=new Unpack(&DataIO); Unp->Init(NULL);}CmdExtract::~CmdExtract(){ delete Unp; memset(Password,0,sizeof(Password));}void CmdExtract::DoExtract(CommandData *Cmd){ DataIO.SetCurrentCommand(*Cmd->Command); struct FindData FD; while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) if (FindFile::FastFind(ArcName,ArcNameW,&FD)) DataIO.TotalArcSize+=FD.Size; Cmd->ArcNames->Rewind(); while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) { while (ExtractArchive(Cmd)==EXTRACT_ARC_REPEAT) ; if (FindFile::FastFind(ArcName,ArcNameW,&FD)) DataIO.ProcessedArcSize+=FD.Size; } if (TotalFileCount==0 && *Cmd->Command!='I') { mprintf(St(MExtrNoFiles)); ErrHandler.SetErrorCode(WARNING); }#ifndef GUI else if (*Cmd->Command=='I') mprintf(St(MDone)); else if (ErrHandler.GetErrorCount()==0) mprintf(St(MExtrAllOk)); else mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount());#endif}void CmdExtract::ExtractArchiveInit(CommandData *Cmd,Archive &Arc){ DataIO.UnpArcSize=Arc.FileLength(); FileCount=0; MatchedArgs=0;#ifndef SFX_MODULE FirstFile=true;#endif if (*Cmd->Password!=0) strcpy(Password,Cmd->Password); PasswordAll=(*Cmd->Password!=0); DataIO.UnpVolume=false; PrevExtracted=false; SignatureFound=false; AllMatchesExact=true; ReconstructDone=false;}EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd){ Archive Arc(Cmd); if (!Arc.WOpen(ArcName,ArcNameW)) { ErrHandler.SetErrorCode(OPEN_ERROR); return(EXTRACT_ARC_NEXT); } if (!Arc.IsArchive(true)) {#ifndef GUI mprintf(St(MNotRAR),ArcName);#endif if (CmpExt(ArcName,"rar")) ErrHandler.SetErrorCode(WARNING); return(EXTRACT_ARC_NEXT); }#ifndef SFX_MODULE if (Arc.Volume && Arc.NotFirstVolume) { char FirstVolName[NM]; VolNameToFirstName(ArcName,FirstVolName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)); if (stricomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) && Cmd->ArcNames->Search(FirstVolName,NULL,false)) return(EXTRACT_ARC_NEXT); }#endif ExtractArchiveInit(Cmd,Arc); if (*Cmd->Command=='T' || *Cmd->Command=='I') Cmd->Test=true;#ifndef GUI if (*Cmd->Command=='I') Cmd->DisablePercentage=true; else if (Cmd->Test) mprintf(St(MExtrTest),ArcName); else mprintf(St(MExtracting),ArcName);#endif Arc.ViewComment(); while (1) { int Size=Arc.ReadHeader(); bool Repeat=false; if (!ExtractCurrentFile(Cmd,Arc,Size,Repeat)) if (Repeat) { return(EXTRACT_ARC_REPEAT); } else break; } return(EXTRACT_ARC_NEXT);}bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize,bool &Repeat){ char Command=*Cmd->Command; if (HeaderSize<=0) if (DataIO.UnpVolume) {#ifdef NOVOLUME return(false);#else if (!MergeArchive(Arc,NULL,false,Command)) { ErrHandler.SetErrorCode(WARNING); return(false); } SignatureFound=false;#endif } else return(false); int HeadType=Arc.GetHeaderType(); if (HeadType!=FILE_HEAD) { if (HeadType==AV_HEAD || HeadType==SIGN_HEAD) SignatureFound=true;#if !defined(SFX_MODULE) && !defined(_WIN_CE) if (HeadType==SUB_HEAD && PrevExtracted) SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);#endif if (HeadType==NEWSUB_HEAD) { if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV)) SignatureFound=true;#if !defined(NOSUBBLOCKS) && !defined(_WIN_CE) if (PrevExtracted) SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);#endif } if (HeadType==ENDARC_HEAD) if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME) {#ifndef NOVOLUME if (!MergeArchive(Arc,NULL,false,Command)) { ErrHandler.SetErrorCode(WARNING); return(false); } SignatureFound=false;#endif Arc.Seek(Arc.CurBlockPos,SEEK_SET); return(true); } else return(false); Arc.SeekToNext(); return(true); } PrevExtracted=false; if (SignatureFound || !Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() && AllMatchesExact) return(false); char ArcFileName[NM]; IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName); strcpy(ArcFileName,Arc.NewLhd.FileName); wchar ArcFileNameW[NM]; *ArcFileNameW=0; bool EqualNames=false; int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames); bool ExactMatch=MatchNumber!=0;#if !defined(SFX_MODULE) && !defined(_WIN_CE) if (Cmd->ExclPath==EXCL_BASEPATH) { *Cmd->ArcPath=0; if (ExactMatch) { Cmd->FileArgs->Rewind(); if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1)) *PointToName(Cmd->ArcPath)=0; } }#endif if (ExactMatch && !EqualNames) AllMatchesExact=false;#ifdef UNICODE_SUPPORTED bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE);#else bool WideName=false;#endif#ifdef _APPLE if (WideName) { WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,sizeof(ArcFileName)); WideName=false; }#endif wchar *DestNameW=WideName ? DestFileNameW:NULL;#ifdef UNICODE_SUPPORTED if (WideName) { ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW); char Name[NM]; WideToChar(ArcFileNameW,Name); if (IsNameUsable(Name)) strcpy(ArcFileName,Name); }#endif ConvertPath(ArcFileName,ArcFileName); if (Arc.IsArcLabel()) return(true); if (Arc.NewLhd.Flags & LHD_VERSION) { if (Cmd->VersionControl!=1 && !EqualNames) { if (Cmd->VersionControl==0) ExactMatch=false; int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false); if (Cmd->VersionControl-1==Version) ParseVersionFileName(ArcFileName,ArcFileNameW,true); else ExactMatch=false; } } else if (!Arc.IsArcDir() && Cmd->VersionControl>1) ExactMatch=false; Arc.ConvertAttributes();#ifndef SFX_MODULE if ((Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/)) && FirstFile) { char CurVolName[NM]; strcpy(CurVolName,ArcName); VolNameToFirstName(ArcName,ArcName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)); if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName)) { *ArcNameW=0; Repeat=true; return(false); }#if !defined(RARDLL) && !defined(_WIN_CE) if (!ReconstructDone) { ReconstructDone=true; RecVolumes RecVol; if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true)) { Repeat=true; return(false); } }#endif strcpy(ArcName,CurVolName); }#endif DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER); DataIO.NextVolumeMissing=false; Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); bool TestMode=false; bool ExtrFile=false; bool SkipSolid=false;#ifndef SFX_MODULE if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0) { if (ExactMatch) { Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName);#ifdef RARDLL Cmd->DllError=ERAR_BAD_DATA;#endif } ExactMatch=false; } FirstFile=false;#endif if (ExactMatch || (SkipSolid=Arc.Solid)!=0) { if (Arc.NewLhd.Flags & LHD_PASSWORD)#ifndef RARDLL if (*Password==0)#endif {#ifdef RARDLL if (*Cmd->Password==0) if (Cmd->Callback==NULL || Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LONG)Cmd->Password,sizeof(Cmd->Password))==-1) return(false); strcpy(Password,Cmd->Password);#else if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password))) { return(false); }#endif }#if !defined(GUI) && !defined(SILENT) else if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0)) { eprintf(St(MUseCurPsw),ArcFileName); switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll))) { case -1: ErrHandler.Exit(USER_BREAK); case 2: if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password))) { return(false); } break; case 3: PasswordAll=true; break; } }#endif#ifndef SFX_MODULE if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0) WideToChar(Cmd->ExtrPathW,DestFileName); else#endif strcpy(DestFileName,Cmd->ExtrPath);#ifndef SFX_MODULE if (Cmd->AppendArcNameToPath) { strcat(DestFileName,PointToName(Arc.FileName)); SetExt(DestFileName,NULL); AddEndSlash(DestFileName); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -