bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath) { if (CmpPath!=MATCH_NAMES) { int WildLength=strlenw(Wildcard); if (CmpPath!=MATCH_EXACTPATH && strnicompcw(Wildcard,Name,WildLength)==0) { wchar NextCh=Name[WildLength]; if (NextCh==L'\\' || NextCh==L'/' || NextCh==0) return(true); } wchar Path1[NM],Path2[NM]; GetFilePath(Wildcard,Path1); GetFilePath(Name,Path2); if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && stricompcw(Path1,Path2)!=0) return(false); if (CmpPath==MATCH_SUBPATH || CmpPath==MATCH_WILDSUBPATH) if (IsWildcard(NULL,Path1)) return(match(Wildcard,Name)); else if (CmpPath==MATCH_SUBPATH || IsWildcard(NULL,Wildcard)) { if (*Path1 && strnicompcw(Path1,Path2,strlenw(Path1))!=0) return(false); } else if (stricompcw(Path1,Path2)!=0) return(false); } wchar *Name1=PointToName(Wildcard); wchar *Name2=PointToName(Name); if (strnicompcw(L"__rar_",Name2,6)==0) return(false); return(match(Name1,Name2)); }
bool CmpName(wchar *Wildcard,wchar *Name,int CmpMode) { bool ForceCase=(CmpMode&MATCH_FORCECASESENSITIVE)!=0; CmpMode&=MATCH_MODEMASK; if (CmpMode!=MATCH_NAMES) { size_t WildLength=strlenw(Wildcard); if (CmpMode!=MATCH_EXACT && CmpMode!=MATCH_EXACTPATH && mstrnicompcw(Wildcard,Name,WildLength,ForceCase)==0) { // For all modes except MATCH_NAMES, MATCH_EXACT and MATCH_EXACTPATH // "path1" mask must match "path1\path2\filename.ext" and "path1" names. wchar NextCh=Name[WildLength]; if (NextCh==L'\\' || NextCh==L'/' || NextCh==0) return(true); // Nothing more to compare for MATCH_SUBPATHONLY. if (CmpMode==MATCH_SUBPATHONLY) return(false); } wchar Path1[NM],Path2[NM]; GetFilePath(Wildcard,Path1,ASIZE(Path1)); GetFilePath(Name,Path2,ASIZE(Path2)); if ((CmpMode==MATCH_EXACT || CmpMode==MATCH_EXACTPATH) && mstricompcw(Path1,Path2,ForceCase)!=0) return(false); if (CmpMode==MATCH_SUBPATH || CmpMode==MATCH_WILDSUBPATH) { if (IsWildcard(NULL,Path1)) return(match(Wildcard,Name,ForceCase)); else if (CmpMode==MATCH_SUBPATH || IsWildcard(NULL,Wildcard)) { if (*Path1 && mstrnicompcw(Path1,Path2,strlenw(Path1),ForceCase)!=0) return(false); } else if (mstricompcw(Path1,Path2,ForceCase)!=0) return(false); } } wchar *Name1=PointToName(Wildcard); wchar *Name2=PointToName(Name); // Always return false for RAR temporary files to exclude them // from archiving operations. if (mstrnicompcw(L"__rar_",Name2,6,false)==0) return(false); if (CmpMode==MATCH_EXACT) return(mstricompcw(Name1,Name2,ForceCase)==0); return(match(Name1,Name2,ForceCase)); }
void ExtractStreamsNew(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; wchar NameW[NM]; if (FileNameW!=NULL && *FileNameW!=0) strcpyw(NameW,FileNameW); else CharToWide(FileName,NameW); wchar StreamNameW[NM+2]; if (NameW[0]!=0 && NameW[1]==0) { strcpyw(StreamNameW,L".\\"); strcpyw(StreamNameW+2,NameW); } else strcpyw(StreamNameW,NameW); wchar *DestName=StreamNameW+strlenw(StreamNameW); byte *SrcName=&Arc.SubHead.SubData[0]; int DestSize=Arc.SubHead.SubData.Size()/2; if (strlenw(StreamNameW)+DestSize>=sizeof(StreamNameW)/sizeof(StreamNameW[0])) { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName,St(MStreamBroken),FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } RawToWide(SrcName,DestName,DestSize); DestName[DestSize]=0; FindData fd; bool Found=FindFile::FastFind(FileName,FileNameW,&fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); char StreamName[NM]; WideToChar(StreamNameW,StreamName); File CurFile; if (CurFile.WCreate(StreamName,StreamNameW) && Arc.ReadSubData(NULL,&CurFile)) CurFile.Close(); File HostFile; if (Found && HostFile.Open(FileName,FileNameW,true,true)) SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime, &fd.ftLastWriteTime); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr); }
bool WideToChar(const wchar *Src,char *Dest,size_t DestSize) { bool RetCode=true; #ifdef _WIN_32 if (WideCharToMultiByte(CP_ACP,0,Src,-1,Dest,(int)DestSize,NULL,NULL)==0) RetCode=false; #else #ifdef _APPLE WideToUtf(Src,Dest,DestSize); #else #ifdef MBFUNCTIONS size_t ResultingSize=wcstombs(Dest,Src,DestSize); if (ResultingSize==(size_t)-1) RetCode=false; if (ResultingSize==0 && *Src!=0) RetCode=false; if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && strlenw(Src)<NM) { /* Workaround for strange Linux Unicode functions bug. Some of wcstombs and mbstowcs implementations in some situations (we are yet to find out what it depends on) can return an empty string and success code if buffer size value is too large. */ return(WideToChar(Src,Dest,NM)); } #else if (UnicodeEnabled()) { #if defined(_EMX) && !defined(_DJGPP) int len=Min(strlenw(Src)+1,DestSize-1); if (uni_fromucs((UniChar*)Src,len,Dest,(size_t*)&DestSize)==-1 || DestSize>len*2) RetCode=false; Dest[DestSize]=0; #endif } else for (int I=0;I<DestSize;I++) { Dest[I]=(char)Src[I]; if (Src[I]==0) break; } #endif #endif #endif return(RetCode); }
wchar* strrchrw(const wchar *s,int c) { for (int I=strlenw(s)-1;I>=0;I--) if (s[I]==c) return((wchar *)(s+I)); return(NULL); }
wchar* PointToName(const wchar *Path) { for (int I=strlenw(Path)-1;I>=0;I--) if (IsPathDiv(Path[I])) return (wchar*)&Path[I+1]; return (wchar*)((*Path && IsDriveDiv(Path[1])) ? Path+2:Path); }
EXTERNC unsigned short *precatenatew(unsigned short *original, unsigned short *insert) { unsigned short *ret_val; unsigned int a, b; ret_val = (unsigned short)malloc((strlenw(insert) + strlenw(original) + 1) * sizeof(unsigned short)); //declare enough size to place both string and a terminator into it for (a = 0; insert[a] != 0xFFFF; a++) { ret_val[a] = insert[a]; } for (b = 0; original[b] != 0xFFFF; b++, a++) { ret_val[a] = original[a]; } ret_val[a] = 0xFFFF; return ret_val; }
int CommandData::IsProcessFile(FileHeader &NewLhd,bool *ExactMatch,int MatchType) { if (strlen(NewLhd.FileName)>=NM || strlenw(NewLhd.FileNameW)>=NM) return(0); if (ExclCheck(NewLhd.FileName,false)) return(0); #ifndef SFX_MODULE if (TimeCheck(NewLhd.mtime)) return(0); if ((NewLhd.FileAttr & ExclFileAttr)!=0 || InclAttrSet && (NewLhd.FileAttr & InclFileAttr)==0) return(0); if ((NewLhd.Flags & LHD_WINDOWMASK)!=LHD_DIRECTORY && SizeCheck(NewLhd.FullUnpSize)) return(0); #endif char *ArgName; wchar *ArgNameW; FileArgs->Rewind(); for (int StringCount=1;FileArgs->GetString(&ArgName,&ArgNameW);StringCount++) { #ifndef SFX_MODULE bool Unicode=(NewLhd.Flags & LHD_UNICODE) || ArgNameW!=NULL; if (Unicode) { wchar NameW[NM],ArgW[NM],*NamePtr=NewLhd.FileNameW; bool CorrectUnicode=true; if (ArgNameW==NULL) { if (!CharToWide(ArgName,ArgW) || *ArgW==0) CorrectUnicode=false; ArgNameW=ArgW; } if ((NewLhd.Flags & LHD_UNICODE)==0) { if (!CharToWide(NewLhd.FileName,NameW) || *NameW==0) CorrectUnicode=false; NamePtr=NameW; } if (CmpName(ArgNameW,NamePtr,MatchType)) { if (ExactMatch!=NULL) *ExactMatch=stricompcw(ArgNameW,NamePtr)==0; return(StringCount); } if (CorrectUnicode) continue; } #endif if (CmpName(ArgName,NewLhd.FileName,MatchType)) { if (ExactMatch!=NULL) *ExactMatch=stricompc(ArgName,NewLhd.FileName)==0; return(StringCount); } } return(0); }
wchar* strncatw(wchar *dest,const wchar *src,int n) { dest+=strlenw(dest); while (true) if (--n<0) { *dest=0; break; } else if ((*(dest++)=*(src++))==0) break; return(dest); }
int CommandData::IsProcessFile(FileHeader &NewLhd,bool *ExactMatch,int MatchType) { if (strlen(NewLhd.FileName)>=NM || strlenw(NewLhd.FileNameW)>=NM) return(0); if (ExclCheck(NewLhd.FileName,false)) return(0); #ifndef SFX_MODULE if (TimeCheck(NewLhd.mtime)) return(0); #endif char *ArgName; wchar *ArgNameW; FileArgs->Rewind(); for (int StringCount=1;FileArgs->GetString(&ArgName,&ArgNameW);StringCount++) { #ifndef SFX_MODULE bool Unicode=(NewLhd.Flags & LHD_UNICODE) || ArgNameW!=NULL; if (Unicode) { wchar NameW[NM],ArgW[NM],*NamePtr=NewLhd.FileNameW; if (ArgNameW==NULL) { CharToWide(ArgName,ArgW); ArgNameW=ArgW; } if ((NewLhd.Flags & LHD_UNICODE)==0) { CharToWide(NewLhd.FileName,NameW); NamePtr=NameW; } if (CmpName(ArgNameW,NamePtr,MatchType)) { if (ExactMatch!=NULL) *ExactMatch=stricompcw(ArgNameW,NamePtr)==0; return(StringCount); } continue; } #endif if (CmpName(ArgName,NewLhd.FileName,MatchType)) { if (ExactMatch!=NULL) *ExactMatch=stricompc(ArgName,NewLhd.FileName)==0; return(StringCount); } } return(0); }
unsigned int StringList::AddString(const char *Str,const wchar *StrW) { int PrevSize=StringData.Size(); StringData.Add(strlen(Str)+1); strcpy(&StringData[PrevSize],Str); if (StrW!=NULL && *StrW!=0) { int PrevPos=PosDataW.Size(); PosDataW.Add(1); PosDataW[PrevPos]=PrevSize; int PrevSizeW=StringDataW.Size(); StringDataW.Add(strlenw(StrW)+1); strcpyw(&StringDataW[PrevSizeW],StrW); } StringsCount++; return(PrevSize); }
wchar* UnixSlashToDos(wchar *SrcName,wchar *DestName,uint MaxLength) { if (DestName!=NULL && DestName!=SrcName) if (strlenw(SrcName)>=MaxLength) { *DestName=0; return(DestName); } else strcpyw(DestName,SrcName); for (wchar *s=SrcName;*s!=0;s++) { if (*s=='/') if (DestName==NULL) *s='\\'; else DestName[s-SrcName]='\\'; } return(DestName==NULL ? SrcName:DestName); }
bool StringList::GetString(char **Str,wchar **StrW) { if (CurPos>=StringData.Size()) { *Str=NULL; return(false); } *Str=&StringData[CurPos]; if (PosDataItem<PosDataW.Size() && PosDataW[PosDataItem]==CurPos) { PosDataItem++; if (StrW!=NULL) *StrW=&StringDataW[CurPosW]; CurPosW+=strlenw(&StringDataW[CurPosW])+1; } else if (StrW!=NULL) *StrW=NULL; CurPos+=strlen(*Str)+1; return(true); }
bool WideToChar(const wchar *Src,char *Dest,int DestSize) { bool RetCode=true; #ifdef _WIN_32 if (WideCharToMultiByte(CP_ACP,0,Src,-1,Dest,DestSize,NULL,NULL)==0) RetCode=false; #else #ifdef _APPLE WideToUtf(Src,Dest,DestSize); #else #ifdef MBFUNCTIONS if (wcstombs(Dest,Src,DestSize)==-1) RetCode=false; #else if (UnicodeEnabled()) { #if defined(_EMX) && !defined(_DJGPP) int len=Min(strlenw(Src)+1,DestSize-1); if (uni_fromucs((UniChar*)Src,len,Dest,(size_t*)&DestSize)==-1 || DestSize>len*2) RetCode=false; Dest[DestSize]=0; #endif } else for (int I=0;I<DestSize;I++) { Dest[I]=(char)Src[I]; if (Src[I]==0) break; } #endif #endif #endif return(RetCode); }
void NextVolumeName(char *ArcName,wchar *ArcNameW,uint MaxLength,bool OldNumbering) { SVP_LogMsg3("ArcName0 %s %s" , ArcName , CStringA(ArcNameW)); if( CStringA(ArcName).IsEmpty()) WideToChar(ArcNameW, ArcName, MaxLength); char *ChPtr; if ((ChPtr=GetExt(ArcName))==NULL) { strcat(ArcName,".rar"); ChPtr=GetExt(ArcName); } else if (ChPtr[1]==0 || stricomp(ChPtr+1,"exe")==0 || stricomp(ChPtr+1,"sfx")==0) strcpy(ChPtr+1,"rar"); if (!OldNumbering) { ChPtr=GetVolNumPart(ArcName); while ((++(*ChPtr))=='9'+1) { *ChPtr='0'; ChPtr--; if (ChPtr<ArcName || !IsDigit(*ChPtr)) { for (char *EndPtr=ArcName+strlen(ArcName);EndPtr!=ChPtr;EndPtr--) *(EndPtr+1)=*EndPtr; *(ChPtr+1)='1'; break; } } } else if (!IsDigit(*(ChPtr+2)) || !IsDigit(*(ChPtr+3))) strcpy(ChPtr+2,"00"); else { ChPtr+=3; while ((++(*ChPtr))=='9'+1) if (*(ChPtr-1)=='.') { *ChPtr='A'; //or R ?? break; } else { *ChPtr='0'; ChPtr--; } } if (ArcNameW!=NULL && *ArcNameW!=0) { // Copy incremented trailing low ASCII volume name part to Unicode name. // It is simpler than implementing Unicode version of entire function. char *NumPtr=GetVolNumPart(ArcName); // moving to first digit in volume number while (NumPtr>ArcName && IsDigit(*NumPtr) && IsDigit(*(NumPtr-1))) NumPtr--; // also copy the first character before volume number, // because it can be changed when going from .r99 to .s00 if (NumPtr>ArcName) NumPtr--; int CharsToCopy=(int)(strlen(ArcName)-(NumPtr-ArcName)); int DestPos=(int)(strlenw(ArcNameW)-CharsToCopy); if (DestPos>0) // if (DestPos>=0) { CharToWide(NumPtr,ArcNameW+DestPos,MaxLength-DestPos-1); ArcNameW[MaxLength-1]=0; } } }
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat) { char Command=*Cmd->Command; if (HeaderSize==0) if (DataIO.UnpVolume) { #ifdef NOVOLUME return(false); #else if (!MergeArchive(Arc,&DataIO,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,&DataIO,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)!=0); 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)!=0; 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(OPEN_ERROR); } ExactMatch=false; } FirstFile=false; #endif if (ExactMatch || (SkipSolid=Arc.Solid)!=0) { if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0) #ifndef RARDLL if (*Password==0) #endif { #ifdef RARDLL if (*Cmd->Password==0) if (Cmd->Callback==NULL || Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)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.FirstVolumeName)); SetExt(DestFileName,NULL); AddEndSlash(DestFileName); } #endif char *ExtrName=ArcFileName; bool EmptyName=false; #ifndef SFX_MODULE size_t 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); char DiskLetter=etoupper(DestFileName[0]); if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) && DiskLetter>='A' && DiskLetter<='Z') 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.FirstVolumeNameW!=0) strcpyw(FileNameW,Arc.FirstVolumeNameW); else CharToWide(Arc.FirstVolumeName,FileNameW); strcatw(DestFileNameW,PointToName(FileNameW)); SetExt(DestFileNameW,NULL); AddEndSlash(DestFileNameW); } #endif wchar *ExtrNameW=ArcFileNameW; #ifndef SFX_MODULE if (Length>0) { wchar ArcPathW[NM]; GetWideName(Cmd->ArcPath,Cmd->ArcPathW,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; if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X')) { struct FindData FD; if (FindFile::FastFind(DestFileName,DestNameW,&FD)) { if (FD.mtime >= Arc.NewLhd.mtime) { // If directory already exists and its modification time is newer // than start of extraction, it is likely it was created // when creating a path to one of already extracted items. // In such case we'll better update its time even if archived // directory is older. if (!FD.IsDir || FD.mtime<StartTime) ExtrFile=false; } } else if (Cmd->FreshFiles) ExtrFile=false; } // Skip encrypted file if no password is specified. if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && *Password==0) { ErrHandler.SetErrorCode(WARNING); #ifdef RARDLL Cmd->DllError=ERAR_MISSING_PASSWORD; #endif ExtrFile=false; } #ifdef RARDLL if (*Cmd->DllDestName) { strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName)); *DestFileNameW=0; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } if (*Cmd->DllDestNameW) { strncpyzw(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW)); DestNameW=DestFileNameW; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } #endif #ifdef SFX_MODULE if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) && 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,!Cmd->IgnoreGeneralAttr,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,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); } if (MDCode==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DestFileName); mprintf(" %s",St(MOk)); #endif PrevExtracted=true; } else if (DirExist) { if (!Cmd->IgnoreGeneralAttr) 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,DestNameW,true); #endif SetDirTime(DestFileName,DestNameW, 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)); char OrigName[sizeof(DestFileName)]; strncpyz(OrigName,DestFileName,ASIZE(OrigName)); MakeNameUsable(DestFileName,true); CreatePath(DestFileName,NULL,true); if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) { #ifndef SFX_MODULE Log(Arc.FileName,St(MRenaming),OrigName,DestFileName); #endif 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, Arc.NewLhd.UnpVer>=36); 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)!=0); } 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; /* else Arc.NewLhd.FileAttr|=FA_ARCH; //set archive bit for unpacked files (file is not backed up) */ #endif if (!BrokenFile || Cmd->KeepBroken) { if (BrokenFile) CurFile.Truncate(); CurFile.SetOpenFileTime( 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.SetCloseFileTime( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); if (!Cmd->IgnoreGeneralAttr) SetFileAttr(CurFile.FileName,CurFile.FileNameW,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); }
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command) { RAROptions *Cmd=Arc.GetRAROptions(); int HeaderType=Arc.GetHeaderType(); FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd; bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) && (hd->Flags & LHD_SPLIT_AFTER)!=0; if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 && hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC) { Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName); } Int64 PosBeforeClose=Arc.Tell(); Arc.Close(); char NextName[NM]; wchar NextNameW[NM]; *NextNameW=0; strcpy(NextName,Arc.FileName); NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat); if (*Arc.FileNameW!=0) { // Copy incremented trailing low ASCII volume name part to Unicode name. // It is simpler than also implementing Unicode version of NextVolumeName. strcpyw(NextNameW,Arc.FileNameW); char *NumPtr=GetVolNumPart(NextName); // moving to first digit in volume number while (NumPtr>NextName && isdigit(*NumPtr) && isdigit(*(NumPtr-1))) NumPtr--; // also copy the first character before volume number, // because it can be changed when going from .r99 to .s00 if (NumPtr>NextName) NumPtr--; int CharsToCopy=strlen(NextName)-(NumPtr-NextName); int DestPos=strlenw(NextNameW)-CharsToCopy; if (DestPos>0) { CharToWide(NumPtr,NextNameW+DestPos,ASIZE(NextNameW)-DestPos-1); NextNameW[ASIZE(NextNameW)-1]=0; } } #if !defined(SFX_MODULE) && !defined(RARDLL) bool RecoveryDone=false; #endif bool FailedOpen=false,OldSchemeTested=false; while (!Arc.Open(NextName,NextNameW)) { if (!OldSchemeTested) { char AltNextName[NM]; strcpy(AltNextName,Arc.FileName); NextVolumeName(AltNextName,true); OldSchemeTested=true; if (Arc.Open(AltNextName)) { strcpy(NextName,AltNextName); *NextNameW=0; break; } } #ifdef RARDLL if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL || Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } if (Cmd->ChangeVolProc!=NULL) { #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _EBX=_ESP; #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK); #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _ESP=_EBX; #endif if (RetCode==0) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } } #else // RARDLL #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (!RecoveryDone) { RecVolumes RecVol; RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true); RecoveryDone=true; continue; } #endif #ifndef GUI if (!Cmd->VolumePause && !IsRemovable(NextName)) { FailedOpen=true; break; } #endif #ifndef SILENT if (Cmd->AllYes || !AskNextVol(NextName)) #endif { FailedOpen=true; break; } #endif // RARDLL *NextNameW=0; } if (FailedOpen) { #if !defined(SILENT) && !defined(_WIN_CE) Log(Arc.FileName,St(MAbsNextVol),NextName); #endif Arc.Open(Arc.FileName,Arc.FileNameW); Arc.Seek(PosBeforeClose,SEEK_SET); return(false); } Arc.CheckArc(true); #ifdef RARDLL if (Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1) return(false); if (Cmd->ChangeVolProc!=NULL) { #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _EBX=_ESP; #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY); #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _ESP=_EBX; #endif if (RetCode==0) return(false); } #endif if (Command=='T' || Command=='X' || Command=='E') mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName); if (SplitHeader) Arc.SearchBlock(HeaderType); else Arc.ReadHeader(); if (Arc.GetHeaderType()==FILE_HEAD) { Arc.ConvertAttributes(); Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); } #ifndef GUI if (ShowFileName) { char OutName[NM]; IntToExt(Arc.NewLhd.FileName,OutName); #ifdef UNICODE_SUPPORTED bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled(); if (WideName) { wchar NameW[NM]; ConvertPath(Arc.NewLhd.FileNameW,NameW); char Name[NM]; if (WideToChar(NameW,Name) && IsNameUsable(Name)) strcpy(OutName,Name); } #endif mprintf(St(MExtrPoints),OutName); if (!Cmd->DisablePercentage) mprintf(" "); } #endif if (DataIO!=NULL) { if (HeaderType==ENDARC_HEAD) DataIO->UnpVolume=false; else { DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER); DataIO->SetPackedSizeToRead(hd->FullPackSize); } #ifdef SFX_MODULE DataIO->UnpArcSize=Arc.FileLength(); DataIO->CurUnpRead=0; #endif DataIO->PackedCRC=0xffffffff; // DataIO->SetFiles(&Arc,NULL); } return(true); }
void AddEndSlash(wchar *Path) { int Length=strlenw(Path); if (Length>0 && Path[Length-1]!=CPATHDIVIDER) strcatw(Path,PATHDIVIDERW); }
wchar* strcatw(wchar *dest,const wchar *src) { return(strcpyw(dest+strlenw(dest),src)); }
bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError, bool ConvertToAnsi,bool Unquote,bool SkipComments) { char FileName[NM]; if (Config) GetConfigName(Name,FileName,true); else strcpy(FileName,Name); File SrcFile; if (*FileName) { bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName):SrcFile.Open(FileName); if (!OpenCode) { if (AbortOnError) ErrHandler.Exit(OPEN_ERROR); return(false); } } else SrcFile.SetHandleType(FILE_HANDLESTD); unsigned int DataSize=0,ReadSize; const int ReadBlock=1024; Array<char> Data(ReadBlock+5); while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0) { DataSize+=ReadSize; Data.Add(ReadSize); } memset(&Data[DataSize],0,5); if (IsUnicode((byte *)&Data[0],DataSize)) { wchar *CurStr=(wchar *)&Data[2]; Array<char> AnsiName; while (*CurStr!=0) { wchar *NextStr=CurStr,*CmtPtr=NULL; while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) { if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') { *NextStr=0; CmtPtr=NextStr; } NextStr++; } *NextStr=0; for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) { if (*SpacePtr!=' ' && *SpacePtr!='\t') break; *SpacePtr=0; } if (*CurStr) { int Length=strlenw(CurStr); int AddSize=Length-AnsiName.Size()+1; if (AddSize>0) AnsiName.Add(AddSize); if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"') { CurStr[Length-1]=0; CurStr++; } WideToChar(CurStr,&AnsiName[0]); List->AddString(&AnsiName[0],CurStr); } CurStr=NextStr+1; while (*CurStr=='\r' || *CurStr=='\n') CurStr++; } } else { char *CurStr=&Data[0]; while (*CurStr!=0) { char *NextStr=CurStr,*CmtPtr=NULL; while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) { if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') { *NextStr=0; CmtPtr=NextStr; } NextStr++; } *NextStr=0; for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) { if (*SpacePtr!=' ' && *SpacePtr!='\t') break; *SpacePtr=0; } if (*CurStr) { if (Unquote && *CurStr=='\"') { int Length=strlen(CurStr); if (CurStr[Length-1]=='\"') { CurStr[Length-1]=0; CurStr++; } } #if defined(_WIN_32) && !defined(_XBOX) && !defined(_LINUX) if (ConvertToAnsi) OemToChar(CurStr,CurStr); #endif List->AddString(CurStr); } CurStr=NextStr+1; while (*CurStr=='\r' || *CurStr=='\n') CurStr++; } } return(true); }
bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError, RAR_CHARSET SrcCharset,bool Unquote,bool SkipComments) { char FileName[NM]; if (Config) GetConfigName(Name,FileName,true); else strcpy(FileName,Name); File SrcFile; if (*FileName) { bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName):SrcFile.Open(FileName); if (!OpenCode) { if (AbortOnError) ErrHandler.Exit(OPEN_ERROR); return(false); } } else SrcFile.SetHandleType(FILE_HANDLESTD); unsigned int DataSize=0,ReadSize; const int ReadBlock=1024; Array<char> Data(ReadBlock+5); while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0) { DataSize+=ReadSize; Data.Add(ReadSize); } memset(&Data[DataSize],0,5); if (SrcCharset==RCH_UNICODE || SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize)) { // Unicode in native system format, can be more than 2 bytes per character Array<wchar> DataW(Data.Size()/2+1); for (int I=2;I<Data.Size()-1;I+=2) DataW[(I-2)/2]=(wchar)Data[I]+(wchar)Data[I+1]*256; wchar *CurStr=&DataW[0]; Array<char> AnsiName; while (*CurStr!=0) { wchar *NextStr=CurStr,*CmtPtr=NULL; while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) { if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') { *NextStr=0; CmtPtr=NextStr; } NextStr++; } *NextStr=0; for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) { if (*SpacePtr!=' ' && *SpacePtr!='\t') break; *SpacePtr=0; } if (*CurStr) { int Length=strlenw(CurStr); int AddSize=4*(Length-AnsiName.Size()+1); if (AddSize>0) AnsiName.Add(AddSize); if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"') { CurStr[Length-1]=0; CurStr++; } WideToChar(CurStr,&AnsiName[0],AnsiName.Size()); List->AddString(&AnsiName[0],CurStr); } CurStr=NextStr+1; while (*CurStr=='\r' || *CurStr=='\n') CurStr++; } } else { char *CurStr=&Data[0]; while (*CurStr!=0) { char *NextStr=CurStr,*CmtPtr=NULL; while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) { if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') { *NextStr=0; CmtPtr=NextStr; } NextStr++; } *NextStr=0; for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) { if (*SpacePtr!=' ' && *SpacePtr!='\t') break; *SpacePtr=0; } if (*CurStr) { if (Unquote && *CurStr=='\"') { int Length=strlen(CurStr); if (CurStr[Length-1]=='\"') { CurStr[Length-1]=0; CurStr++; } } #if defined(_WIN_32) if (SrcCharset==RCH_OEM) OemToChar(CurStr,CurStr); #endif List->AddString(CurStr); } CurStr=NextStr+1; while (*CurStr=='\r' || *CurStr=='\n') CurStr++; } } return(true); }
void CryptData::SetCryptKeys(char *Password,unsigned char *Salt,bool Encrypt,bool OldOnly) { if (*Password==0) return; if (OldOnly) { #ifndef SFX_MODULE if (CRCTab[1]==0) InitCRC(); unsigned char Psw[MAXPASSWORD]; SetOldKeys(Password); Key[0]=0xD3A3B879L; Key[1]=0x3F6D12F7L; Key[2]=0x7515A235L; Key[3]=0xA4E7F123L; memset(Psw,0,sizeof(Psw)); #if defined(_WIN_32) && !defined(GUI) CharToOemBuff(Password,(char*)Psw,strlen(Password)); #else strncpy((char *)Psw,Password,MAXPASSWORD-1); #endif int PswLength=strlen(Password); memcpy(SubstTable,InitSubstTable,sizeof(SubstTable)); for (int J=0;J<256;J++) for (int I=0;I<PswLength;I+=2) { unsigned int N1=(unsigned char)CRCTab[(Psw[I]-J)&0xff]; unsigned int N2=(unsigned char)CRCTab[(Psw[I+1]+J)&0xff]; for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++) Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xff]); } for (int I=0;I<PswLength;I+=16) EncryptBlock20(&Psw[I]); #endif return; } bool Cached=false; for (int I=0;I<sizeof(Cache)/sizeof(Cache[0]);I++) if (strcmp(Cache[I].Password,Password)==0 && (Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL && Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0)) { memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey)); memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit)); Cached=true; break; } if (!Cached) { wchar PswW[MAXPASSWORD]; CharToWide(Password,PswW,MAXPASSWORD-1); PswW[MAXPASSWORD-1]=0; unsigned char RawPsw[2*MAXPASSWORD+SALT_SIZE]; WideToRaw(PswW,RawPsw); int RawLength=2*strlenw(PswW); if (Salt!=NULL) { memcpy(RawPsw+RawLength,Salt,SALT_SIZE); RawLength+=SALT_SIZE; } hash_context c; hash_initial(&c); const int HashRounds=0x40000; for (int I=0;I<HashRounds;I++) { hash_process( &c, RawPsw, RawLength); unsigned char PswNum[3]; PswNum[0]=(unsigned char)I; PswNum[1]=(unsigned char)(I>>8); PswNum[2]=(unsigned char)(I>>16); hash_process( &c, PswNum, 3); if (I%(HashRounds/16)==0) { hash_context tempc=c; uint32 digest[5]; hash_final( &tempc, digest); AESInit[I/(HashRounds/16)]=(unsigned char)digest[4]; } } uint32 digest[5]; hash_final( &c, digest); for (int I=0;I<4;I++) for (int J=0;J<4;J++) AESKey[I*4+J]=(unsigned char)(digest[I]>>(J*8)); strcpy(Cache[CachePos].Password,Password); if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true) memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE); memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey)); memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit)); CachePos=(CachePos+1)%(sizeof(Cache)/sizeof(Cache[0])); }