inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,int n) { wchar Wide1[NM*2],Wide2[NM*2]; strncpyw(Wide1,s1,sizeof(Wide1)/sizeof(Wide1[0])-1); strncpyw(Wide2,s2,sizeof(Wide2)/sizeof(Wide2[0])-1); Wide1[Min(sizeof(Wide1)/sizeof(Wide1[0])-1,n)]=0; Wide2[Min(sizeof(Wide2)/sizeof(Wide2[0])-1,n)]=0; char Ansi1[NM*2],Ansi2[NM*2]; WideToChar(Wide1,Ansi1,sizeof(Ansi1)); WideToChar(Wide2,Ansi2,sizeof(Ansi2)); return(stricomp(Ansi1,Ansi2)); }
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath) { const wchar *DestPtr=SrcPath; for (const wchar *s=DestPtr;*s!=0;s++) if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3])) DestPtr=s+4; while (*DestPtr) { const wchar *s=DestPtr; if (s[0] && IsDriveDiv(s[1])) s+=2; if (s[0]=='\\' && s[1]=='\\') { const wchar *Slash=strchrw(s+2,'\\'); if (Slash!=NULL && (Slash=strchrw(Slash+1,'\\'))!=NULL) s=Slash+1; } for (const wchar *t=s;*t!=0;t++) if (IsPathDiv(*t)) s=t+1; else if (*t!='.') break; if (s==DestPtr) break; DestPtr=s; } if (DestPath!=NULL) { wchar TmpStr[NM]; strncpyw(TmpStr,DestPtr,sizeof(TmpStr)/sizeof(TmpStr[0])-1); strcpyw(DestPath,TmpStr); } return((wchar *)DestPtr); }
void GetFilePath(const wchar *FullName,wchar *Path) { const wchar *PathPtr=/*(*FullName && IsDriveDiv(FullName[1])) ? FullName+2:*/FullName; int PathLength=PointToName(FullName)-FullName; strncpyw(Path,PathPtr,PathLength); Path[PathLength]=0; }
// safe strncpyw: copies maxlen-1 max and always returns zero terminated dest wchar* strncpyzw(wchar *dest, const wchar *src, size_t maxlen) { if (maxlen>0) { strncpyw(dest,src,maxlen-1); dest[maxlen-1]=0; } return(dest); }
bool StringList::GetString(char *Str,wchar *StrW,int MaxLength) { char *StrPtr; wchar *StrPtrW; if (Str==NULL || !GetString(&StrPtr,&StrPtrW)) return(false); strncpy(Str,StrPtr,MaxLength); if (StrW!=NULL) strncpyw(StrW,NullToEmpty(StrPtrW),MaxLength); return(true); }
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName) { #ifdef _WIN_32 uint DirAttr=0; #else uint DirAttr=0777; #endif int PosW=0; for (const char *s=Path;*s!=0 && PosW<NM;s=charnext(s),PosW++) { bool Wide=PathW!=NULL && *PathW!=0; if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER) { wchar *DirPtrW=NULL; if (Wide) { wchar DirNameW[NM]; strncpyw(DirNameW,PathW,PosW); DirNameW[PosW]=0; DirPtrW=DirNameW; } char DirName[NM]; strncpy(DirName,Path,s-Path); DirName[s-Path]=0; if (MakeDir(DirName,DirPtrW,DirAttr)==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DirName); mprintf(" %s",St(MOk)); #endif } } } if (!SkipLastName) MakeDir(Path,PathW,DirAttr); }
void CommandData::ParseArg(char *Arg,wchar *ArgW) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-') NoMoreSwitches=true; else ProcessSwitch(&Arg[1]); else if (*Command==0) { strncpy(Command,Arg,sizeof(Command)); if (ArgW!=NULL) strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0])); if (toupper(*Command)=='S') { const char *SFXName=Command[1] ? Command+1:DefSFXName; if (PointToName(SFXName)!=SFXName || FileExist(SFXName)) strcpy(SFXModule,SFXName); else GetConfigName(SFXName,SFXModule,true); } #ifndef GUI *Command=toupper(*Command); if (*Command!='I' && *Command!='S') strupper(Command); #endif } else if (*ArcName==0) { strncpy(ArcName,Arg,sizeof(ArcName)); if (ArgW!=NULL) strncpyw(ArcNameW,ArgW,sizeof(ArcNameW)/sizeof(ArcNameW[0])); } else { int Length=strlen(Arg); char EndChar=Arg[Length-1]; char CmdChar=toupper(*Command); bool Add=strchr("AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add) strcpy(ExtrPath,Arg); else if ((Add || CmdChar=='T') && *Arg!='@') FileArgs->AddString(Arg); else { struct FindData FileData; bool Found=FindFile::FastFind(Arg,NULL,&FileData); if (!Found && *Arg=='@' && !IsWildcard(Arg)) { ReadTextFile(Arg+1,FileArgs,false,true,true,true,true); FileLists=true; } else if (Found && FileData.IsDir && Extract && *ExtrPath==0) { strcpy(ExtrPath,Arg); AddEndSlash(ExtrPath); } else FileArgs->AddString(Arg); } } }
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW) { DataSet *Data=(DataSet *)hArcData; //try //{ Data->Cmd.DllError=0; if (Data->OpenMode==RAR_OM_LIST || Data->OpenMode==RAR_OM_LIST_INCSPLIT || Operation==RAR_SKIP && !Data->Arc.Solid) { if (Data->Arc.Volume && Data->Arc.GetHeaderType()==FILE_HEAD && (Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0) if (MergeArchive(Data->Arc,NULL,false,'L')) { Data->Extract.SignatureFound=false; Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); return(0); } else return(ERAR_EOPEN); Data->Arc.SeekToNext(); } else { Data->Cmd.DllOpMode=Operation; if (DestPath!=NULL || DestName!=NULL) { #ifdef _WIN_32 OemToChar(NullToEmpty(DestPath),Data->Cmd.ExtrPath); #else strcpy(Data->Cmd.ExtrPath,NullToEmpty(DestPath)); #endif AddEndSlash(Data->Cmd.ExtrPath); #ifdef _WIN_32 OemToChar(NullToEmpty(DestName),Data->Cmd.DllDestName); #else strcpy(Data->Cmd.DllDestName,NullToEmpty(DestName)); #endif } else { *Data->Cmd.ExtrPath=0; *Data->Cmd.DllDestName=0; } if (DestPathW!=NULL || DestNameW!=NULL) { strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2); AddEndSlash(Data->Cmd.ExtrPathW); strncpyw(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1); if (*Data->Cmd.DllDestNameW!=0 && *Data->Cmd.DllDestName==0) WideToChar(Data->Cmd.DllDestNameW,Data->Cmd.DllDestName); } else { *Data->Cmd.ExtrPathW=0; *Data->Cmd.DllDestNameW=0; } strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T"); Data->Cmd.Test=Operation!=RAR_EXTRACT; bool Repeat=false; Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat); while (Data->Arc.ReadHeader()!=0 && Data->Arc.GetHeaderType()==NEWSUB_HEAD) { Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat); Data->Arc.SeekToNext(); } Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); } //} //catch (int ErrCode) //{ // return(RarErrorToDll(ErrCode)); //} return(Data->Cmd.DllError); }
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D) { DataSet *Data=(DataSet *)hArcData; //try //{ if ((Data->HeaderSize=(int)Data->Arc.SearchBlock(FILE_HEAD))<=0) { if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD && (Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)) if (MergeArchive(Data->Arc,NULL,false,'L')) { Data->Extract.SignatureFound=false; Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); return(RARReadHeaderEx(hArcData,D)); } else return(ERAR_EOPEN); return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE); } if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)) { int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL); if (Code==0) return(RARReadHeaderEx(hArcData,D)); else return(Code); } strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName)); if (*Data->Arc.FileNameW) strncpyw(D->ArcNameW,Data->Arc.FileNameW,sizeof(D->ArcNameW)); else CharToWide(Data->Arc.FileName,D->ArcNameW); strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName)); if (*Data->Arc.NewLhd.FileNameW) strncpyw(D->FileNameW,Data->Arc.NewLhd.FileNameW,sizeof(D->FileNameW)); else { #ifdef _WIN_32 char AnsiName[NM]; OemToChar(Data->Arc.NewLhd.FileName,AnsiName); if (!CharToWide(AnsiName,D->FileNameW,ASIZE(D->FileNameW))) *D->FileNameW=0; #else if (!CharToWide(Data->Arc.NewLhd.FileName,D->FileNameW,ASIZE(D->FileNameW))) *D->FileNameW=0; #endif } D->Flags=Data->Arc.NewLhd.Flags; D->PackSize=Data->Arc.NewLhd.PackSize; D->PackSizeHigh=Data->Arc.NewLhd.HighPackSize; D->UnpSize=Data->Arc.NewLhd.UnpSize; D->UnpSizeHigh=Data->Arc.NewLhd.HighUnpSize; D->HostOS=Data->Arc.NewLhd.HostOS; D->FileCRC=Data->Arc.NewLhd.FileCRC; D->FileTime=Data->Arc.NewLhd.FileTime; D->UnpVer=Data->Arc.NewLhd.UnpVer; D->Method=Data->Arc.NewLhd.Method; D->FileAttr=Data->Arc.NewLhd.FileAttr; D->CmtSize=0; D->CmtState=0; // } // catch (int ErrCode) //{ // return(RarErrorToDll(ErrCode)); // } return(0); }
void CommandData::ParseArg(char *Arg,wchar *ArgW) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-') NoMoreSwitches=true; else ProcessSwitch(&Arg[1],(ArgW!=NULL && *ArgW!=0 ? &ArgW[1]:NULL)); else if (*Command==0) { strncpyz(Command,Arg,ASIZE(Command)); if (ArgW!=NULL) strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0])); if (etoupper(*Command)=='S') { const char *SFXName=Command[1] ? Command+1:DefSFXName; if (PointToName(SFXName)!=SFXName || FileExist(SFXName)) strcpy(SFXModule,SFXName); else GetConfigName(SFXName,SFXModule,true); } #ifndef GUI *Command=etoupper(*Command); if (*Command!='I' && *Command!='S') strupper(Command); #endif } else if (*ArcName==0) { strncpyz(ArcName,Arg,ASIZE(ArcName)); if (ArgW!=NULL) strncpyzw(ArcNameW,ArgW,ASIZE(ArcNameW)); } else { size_t Length=strlen(Arg); char EndChar=Length==0 ? 0:Arg[Length-1]; char CmdChar=etoupper(*Command); bool Add=strchr("AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add) { strncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); if (ArgW!=NULL) strncpyzw(ExtrPathW,ArgW,ASIZE(ExtrPathW)); } else if ((Add || CmdChar=='T') && *Arg!='@') FileArgs->AddString(Arg); else { struct FindData FileData; bool Found=FindFile::FastFind(Arg,NULL,&FileData); if (!Found && *Arg=='@' && !IsWildcard(Arg)) { FileLists=true; RAR_CHARSET Charset=FilelistCharset; #if defined(_WIN_32) && !defined(GUI) // for compatibility reasons we use OEM encoding // in Win32 console version by default if (Charset==RCH_DEFAULT) Charset=RCH_OEM; #endif ReadTextFile(Arg+1,FileArgs,false,true,Charset,true,true,true); } else if (Found && FileData.IsDir && Extract && *ExtrPath==0) { strcpy(ExtrPath,Arg); AddEndSlash(ExtrPath); } else FileArgs->AddString(Arg); } } }
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName) { #ifdef _WIN_32 uint DirAttr=0; #else uint DirAttr=0777; #endif #ifdef UNICODE_SUPPORTED bool Wide=PathW!=NULL && *PathW!=0 && UnicodeEnabled(); #else bool Wide=false; #endif bool IgnoreAscii=false; const char *s=Path; for (int PosW=0;;PosW++) { if (s==NULL || s-Path>=NM || *s==0) IgnoreAscii=true; if (Wide && (PosW>=NM || PathW[PosW]==0) || !Wide && IgnoreAscii) break; if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER) { wchar *DirPtrW=NULL,DirNameW[NM]; if (Wide) { strncpyw(DirNameW,PathW,PosW); DirNameW[PosW]=0; DirPtrW=DirNameW; } char DirName[NM]; if (IgnoreAscii) WideToChar(DirPtrW,DirName); else { #ifndef DBCS_SUPPORTED if (*s!=CPATHDIVIDER) for (const char *n=s;*n!=0 && n-Path<NM;n++) if (*n==CPATHDIVIDER) { s=n; break; } #endif strncpy(DirName,Path,s-Path); DirName[s-Path]=0; } if (MakeDir(DirName,DirPtrW,DirAttr)==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DirName); mprintf(" %s",St(MOk)); #endif } } if (!IgnoreAscii) s=charnext(s); } if (!SkipLastName) MakeDir(Path,PathW,DirAttr); }
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW, string sParfileName) { DataSet *Data=(DataSet *)hArcData; try { Data->Arc.m_sParfileName = sParfileName; if (Data->OpenMode==RAR_OM_LIST || Operation==RAR_SKIP && !Data->Arc.Solid) { if (/*Data->OpenMode==RAR_OM_LIST && */Data->Arc.Volume && Data->Arc.GetHeaderType()==FILE_HEAD && (Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0) if (MergeArchive(Data->Arc,NULL,false,'L')) { Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); return(0); } else return(ERAR_EOPEN); Data->Arc.SeekToNext(); } else { if (DestPath!=NULL || DestName!=NULL) { OemToChar(NullToEmpty(DestPath),Data->Cmd.ExtrPath); OemToChar(NullToEmpty(DestName),Data->Cmd.ArcName); AddEndSlash(Data->Cmd.ExtrPath); } else { *Data->Cmd.ExtrPath=0; } if (DestPathW!=NULL || DestNameW!=NULL) { strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2); AddEndSlash(Data->Cmd.ExtrPathW); } else { *Data->Cmd.ExtrPathW=0; } strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T"); Data->Cmd.Test=Operation!=RAR_EXTRACT; bool Repeat=false; Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat); while (Data->Arc.ReadHeader()!=0 && Data->Arc.GetHeaderType()==NEWSUB_HEAD) { Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat); Data->Arc.SeekToNext(); } Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); } } catch (int ErrCode) { return(RarErrorToDll(ErrCode)); } catch(...) { return -1; } return 0; }
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; int MatchType=MATCH_WILDSUBPATH; bool EqualNames=false; int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType); 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) && UnicodeEnabled(); #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]; if (WideToChar(ArcFileNameW,Name) && 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 ErrHandler.SetErrorCode(WARNING); } 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))) { PasswordCancelled=true; 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); } #endif char *ExtrName=ArcFileName; bool EmptyName=false; #ifndef SFX_MODULE int Length=strlen(Cmd->ArcPath); if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) && strlen(ArcFileName)==Length-1) Length--; if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0) { ExtrName+=Length; while (*ExtrName==CPATHDIVIDER) ExtrName++; if (*ExtrName==0) EmptyName=true; } #endif bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':'); if (AbsPaths) *DestFileName=0; if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) strcat(DestFileName,PointToName(ExtrName)); else strcat(DestFileName,ExtrName); if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2])) DestFileName[1]=':'; #ifndef SFX_MODULE if (!WideName && *Cmd->ExtrPathW!=0) { DestNameW=DestFileNameW; WideName=true; CharToWide(ArcFileName,ArcFileNameW); } #endif if (WideName) { if (*Cmd->ExtrPathW!=0) strcpyw(DestFileNameW,Cmd->ExtrPathW); else CharToWide(Cmd->ExtrPath,DestFileNameW); #ifndef SFX_MODULE if (Cmd->AppendArcNameToPath) { wchar FileNameW[NM]; if (*Arc.FileNameW!=0) strcpyw(FileNameW,Arc.FileNameW); else CharToWide(Arc.FileName,FileNameW); strcatw(DestFileNameW,PointToName(FileNameW)); SetExt(DestFileNameW,NULL); AddEndSlash(DestFileNameW); } #endif wchar *ExtrNameW=ArcFileNameW; #ifndef SFX_MODULE if (Length>0) { wchar ArcPathW[NM]; CharToWide(Cmd->ArcPath,ArcPathW); Length=strlenw(ArcPathW); } ExtrNameW+=Length; while (*ExtrNameW==CPATHDIVIDER) ExtrNameW++; #endif if (AbsPaths) *DestFileNameW=0; if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) strcatw(DestFileNameW,PointToName(ExtrNameW)); else strcatw(DestFileNameW,ExtrNameW); if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2])) DestFileNameW[1]=':'; } else *DestFileNameW=0; ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0/* && *ExtrName*/; if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X')) { struct FindData FD; if (FindFile::FastFind(DestFileName,DestNameW,&FD)) { if (FD.mtime >= Arc.NewLhd.mtime) ExtrFile=false; } else if (Cmd->FreshFiles) ExtrFile=false; } #ifdef RARDLL if (*Cmd->DllDestName) { strncpy(DestFileName,Cmd->DllDestName,sizeof(DestFileName)); *DestFileNameW=0; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } if (*Cmd->DllDestNameW) { strncpyw(DestFileNameW,Cmd->DllDestNameW,sizeof(DestFileNameW)/sizeof(DestFileNameW[0])); DestNameW=DestFileNameW; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } #endif #ifdef SFX_MODULE if (Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.Method!=0x30) #else if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER) #endif { #ifndef SILENT Log(Arc.FileName,St(MUnknownMeth),ArcFileName); #ifndef SFX_MODULE Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10); #endif #endif ExtrFile=false; ErrHandler.SetErrorCode(WARNING); #ifdef RARDLL Cmd->DllError=ERAR_UNKNOWN_FORMAT; #endif } File CurFile; if (!IsLink(Arc.NewLhd.FileAttr)) if (Arc.IsArcDir()) { if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) return(true); if (SkipSolid) { #ifndef GUI mprintf(St(MExtrSkipFile),ArcFileName); #endif return(true); } TotalFileCount++; if (Cmd->Test) { #ifndef GUI mprintf(St(MExtrTestFile),ArcFileName); mprintf(" %s",St(MOk)); #endif return(true); } MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,Arc.NewLhd.FileAttr); bool DirExist=false; if (MDCode!=MKDIR_SUCCESS) { DirExist=FileExist(DestFileName,DestNameW); if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW))) { bool UserReject; FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime); DirExist=false; } CreatePath(DestFileName,DestNameW,true); MDCode=MakeDir(DestFileName,DestNameW,Arc.NewLhd.FileAttr); } if (MDCode==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DestFileName); mprintf(" %s",St(MOk)); #endif PrevExtracted=true; } else if (DirExist) { SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr); PrevExtracted=true; } else { Log(Arc.FileName,St(MExtrErrMkDir),DestFileName); ErrHandler.SysErrMsg(); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif ErrHandler.SetErrorCode(CREATE_ERROR); } if (PrevExtracted) { #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(DestFileName,DestFileNameW,true); #endif SetDirTime(DestFileName, Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); } return(true); } else { if (Cmd->Test && ExtrFile) TestMode=true; #if !defined(GUI) && !defined(SFX_MODULE) if (Command=='P' && ExtrFile) CurFile.SetHandleType(FILE_HANDLESTD); #endif if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test) { bool UserReject; if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) { ExtrFile=false; if (!UserReject) { ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName); ErrHandler.SetErrorCode(CREATE_ERROR); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif if (!IsNameUsable(DestFileName)) { Log(Arc.FileName,St(MCorrectingName)); MakeNameUsable(DestFileName,true); CreatePath(DestFileName,NULL,true); if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) ExtrFile=true; else ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName); } } } } } if (!ExtrFile && Arc.Solid) { SkipSolid=true; TestMode=true; ExtrFile=true; } if (ExtrFile) { if (!SkipSolid) { if (!TestMode && Command!='P' && CurFile.IsDevice()) { Log(Arc.FileName,St(MInvalidName),DestFileName); ErrHandler.WriteError(Arc.FileName,DestFileName); } TotalFileCount++; } FileCount++; #ifndef GUI if (Command!='I') if (SkipSolid) mprintf(St(MExtrSkipFile),ArcFileName); else switch(Cmd->Test ? 'T':Command) { case 'T': mprintf(St(MExtrTestFile),ArcFileName); break; #ifndef SFX_MODULE case 'P': mprintf(St(MExtrPrinting),ArcFileName); break; #endif case 'X': case 'E': mprintf(St(MExtrFile),DestFileName); break; } if (!Cmd->DisablePercentage) mprintf(" "); #endif DataIO.CurUnpRead=0; DataIO.CurUnpWrite=0; DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff; DataIO.PackedCRC=0xffffffff; DataIO.SetEncryption( (Arc.NewLhd.Flags & LHD_PASSWORD) ? Arc.NewLhd.UnpVer:0,Password, (Arc.NewLhd.Flags & LHD_SALT) ? Arc.NewLhd.Salt:NULL,false); DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize); DataIO.SetFiles(&Arc,&CurFile); DataIO.SetTestMode(TestMode); DataIO.SetSkipUnpCRC(SkipSolid); #ifndef _WIN_CE if (!TestMode && !Arc.BrokenFileHeader && (Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize && (Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize)) CurFile.Prealloc(Arc.NewLhd.FullUnpSize); #endif CurFile.SetAllowDelete(!Cmd->KeepBroken); bool LinkCreateMode=!Cmd->Test && !SkipSolid; if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode)) PrevExtracted=LinkCreateMode; else if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0) if (Arc.NewLhd.Method==0x30) UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize); else { Unp->SetDestSize(Arc.NewLhd.FullUnpSize); #ifndef SFX_MODULE if (Arc.NewLhd.UnpVer<=15) Unp->DoUnpack(15,FileCount>1 && Arc.Solid); else #endif Unp->DoUnpack(Arc.NewLhd.UnpVer,Arc.NewLhd.Flags & LHD_SOLID); } if (Arc.IsOpened()) Arc.SeekToNext(); bool BrokenFile=false; if (!SkipSolid) { if (Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) || !Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff)) { #ifndef GUI if (Command!='P' && Command!='I') mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk)); #endif } else { char *BadArcName=(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE) ? NULL:Arc.FileName; if (Arc.NewLhd.Flags & LHD_PASSWORD) { Log(BadArcName,St(MEncrBadCRC),ArcFileName); } else { Log(BadArcName,St(MCRCFailed),ArcFileName); } BrokenFile=true; ErrHandler.SetErrorCode(CRC_ERROR); #ifdef RARDLL Cmd->DllError=ERAR_BAD_DATA; #endif Alarm(); } } #ifndef GUI else mprintf("\b\b\b\b\b "); #endif if (!TestMode && (Command=='X' || Command=='E') && !IsLink(Arc.NewLhd.FileAttr)) { #if defined(_WIN_32) || defined(_EMX) if (Cmd->ClearArc) Arc.NewLhd.FileAttr&=~FA_ARCH; #endif if (!BrokenFile || Cmd->KeepBroken) { if (BrokenFile) CurFile.Truncate(); CurFile.SetOpenFileStat( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); CurFile.Close(); #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(CurFile.FileName,CurFile.FileNameW,true); #endif CurFile.SetCloseFileStat( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime, Arc.NewLhd.FileAttr); PrevExtracted=true; } } } } if (ExactMatch) MatchedArgs++; if (DataIO.NextVolumeMissing || !Arc.IsOpened()) return(false); if (!ExtrFile) if (!Arc.Solid) Arc.SeekToNext(); else if (!SkipSolid) return(false); return(true); }
// Returns file path including the trailing path separator symbol. void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength) { size_t PathLength=Min(MaxLength-1,PointToName(FullName)-FullName); strncpyw(Path,FullName,PathLength); Path[PathLength]=0; }