bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink) { fd->Error=false; #ifndef _UNIX if (IsWildcard(FindMask,FindMaskW)) return(false); #endif #ifdef _WIN_32 HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd); if (hFind==INVALID_HANDLE_VALUE) return(false); FindClose(hFind); #else struct stat st; if (GetSymLink) { #ifdef SAVE_LINKS if (lstat(FindMask,&st)!=0) #else if (stat(FindMask,&st)!=0) #endif { fd->Error=(errno!=ENOENT); return(false); } } else if (stat(FindMask,&st)!=0) { fd->Error=(errno!=ENOENT); return(false); } #ifdef _DJGPP fd->FileAttr=_chmod(FindMask,0); #elif defined(_EMX) fd->FileAttr=st.st_attr; #else fd->FileAttr=st.st_mode; #endif fd->IsDir=IsDir(st.st_mode); fd->Size=st.st_size; fd->mtime=st.st_mtime; fd->atime=st.st_atime; fd->ctime=st.st_ctime; fd->FileTime=fd->mtime.GetDos(); strcpy(fd->Name,FindMask); *fd->NameW=0; #ifdef _APPLE if (!LowAscii(fd->Name)) UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW)); #elif defined(UNICODE_SUPPORTED) if (!LowAscii(fd->Name) && UnicodeEnabled()) CharToWide(fd->Name,fd->NameW); #endif #endif fd->Flags=0; fd->IsDir=IsDir(fd->FileAttr); return(true); }
bool FindFile::Next(struct FindData *fd,bool GetSymLink) { fd->Error=false; if (*FindMask==0) return(false); #ifdef _WIN_32 if (FirstCall) { if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE) return(false); } else if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE) return(false); #else if (FirstCall) { char DirName[NM]; strcpy(DirName,FindMask); RemoveNameFromPath(DirName); if (*DirName==0) strcpy(DirName,"."); /* else { int Length=strlen(DirName); if (Length>1 && DirName[Length-1]==CPATHDIVIDER && (Length!=3 || !IsDriveDiv(DirName[1]))) DirName[Length-1]=0; } */ if ((dirp=opendir(DirName))==NULL) { fd->Error=(errno!=ENOENT); return(false); } } while (1) { struct dirent *ent=readdir(dirp); if (ent==NULL) return(false); if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0) continue; if (CmpName(FindMask,ent->d_name,MATCH_NAMES)) { char FullName[NM]; strcpy(FullName,FindMask); *PointToName(FullName)=0; if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1) { #ifndef SILENT Log(NULL,"\n%s%s",FullName,ent->d_name); Log(NULL,St(MPathTooLong)); #endif return(false); } strcat(FullName,ent->d_name); if (!FastFind(FullName,NULL,fd,GetSymLink)) { ErrHandler.OpenErrorMsg(FullName); continue; } strcpy(fd->Name,FullName); break; } } *fd->NameW=0; #ifdef _APPLE if (!LowAscii(fd->Name)) UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW)); #elif defined(UNICODE_SUPPORTED) if (!LowAscii(fd->Name) && UnicodeEnabled()) CharToWide(fd->Name,fd->NameW); #endif #endif fd->Flags=0; fd->IsDir=IsDir(fd->FileAttr); FirstCall=false; char *Name=PointToName(fd->Name); if (strcmp(Name,".")==0 || strcmp(Name,"..")==0) return(Next(fd)); return(true); }
HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd) { #ifndef _WIN_CE if (WinNT()) #endif { wchar WideMask[NM]; if (MaskW!=NULL && *MaskW!=0) strcpyw(WideMask,MaskW); else CharToWide(Mask,WideMask); WIN32_FIND_DATAW FindData; if (hFind==INVALID_HANDLE_VALUE) { hFind=FindFirstFileW(WideMask,&FindData); if (hFind==INVALID_HANDLE_VALUE) { int SysErr=GetLastError(); fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND && SysErr!=ERROR_NO_MORE_FILES); } } else if (!FindNextFileW(hFind,&FindData)) { hFind=INVALID_HANDLE_VALUE; fd->Error=GetLastError()!=ERROR_NO_MORE_FILES; } if (hFind!=INVALID_HANDLE_VALUE) { strcpyw(fd->NameW,WideMask); strcpyw(PointToName(fd->NameW),FindData.cFileName); WideToChar(fd->NameW,fd->Name); fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow); fd->FileAttr=FindData.dwFileAttributes; WideToChar(FindData.cAlternateFileName,fd->ShortName); fd->ftCreationTime=FindData.ftCreationTime; fd->ftLastAccessTime=FindData.ftLastAccessTime; fd->ftLastWriteTime=FindData.ftLastWriteTime; fd->mtime=FindData.ftLastWriteTime; fd->ctime=FindData.ftCreationTime; fd->atime=FindData.ftLastAccessTime; fd->FileTime=fd->mtime.GetDos(); #ifndef _WIN_CE if (LowAscii(fd->NameW)) *fd->NameW=0; #endif } } #ifndef _WIN_CE else { char CharMask[NM]; if (Mask!=NULL && *Mask!=0) strcpy(CharMask,Mask); else WideToChar(MaskW,CharMask); WIN32_FIND_DATA FindData; if (hFind==INVALID_HANDLE_VALUE) { hFind=FindFirstFile(CharMask,&FindData); if (hFind==INVALID_HANDLE_VALUE) { int SysErr=GetLastError(); fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND; } } else if (!FindNextFile(hFind,&FindData)) { hFind=INVALID_HANDLE_VALUE; fd->Error=GetLastError()!=ERROR_NO_MORE_FILES; } if (hFind!=INVALID_HANDLE_VALUE) { strcpy(fd->Name,CharMask); strcpy(PointToName(fd->Name),FindData.cFileName); CharToWide(fd->Name,fd->NameW); fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow); fd->FileAttr=FindData.dwFileAttributes; strcpy(fd->ShortName,FindData.cAlternateFileName); fd->ftCreationTime=FindData.ftCreationTime; fd->ftLastAccessTime=FindData.ftLastAccessTime; fd->ftLastWriteTime=FindData.ftLastWriteTime; fd->mtime=FindData.ftLastWriteTime; fd->ctime=FindData.ftCreationTime; fd->atime=FindData.ftLastAccessTime; fd->FileTime=fd->mtime.GetDos(); if (LowAscii(fd->Name)) *fd->NameW=0; } } #endif fd->Flags=0; return(hFind); }
int ScanTree::FindProc(FindData *FindData) { if (*CurMask==0) return(SCAN_NEXT); FastFindFile=false; if (FindStack[Depth]==NULL) { bool Wildcards=IsWildcard(CurMask,CurMaskW); bool FindCode=!Wildcards && FindFile::FastFind(CurMask,CurMaskW,FindData,GetLinks); bool IsDir=FindCode && FindData->IsDir; bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS || Wildcards && Recurse==RECURSE_WILDCARDS); if (Depth==0) SearchAllInRoot=SearchAll; if (SearchAll || Wildcards) { FindStack[Depth]=new FindFile; char SearchMask[NM]; strcpy(SearchMask,CurMask); if (SearchAll) strcpy(PointToName(SearchMask),MASKALL); FindStack[Depth]->SetMask(SearchMask); if (*CurMaskW) { wchar SearchMaskW[NM]; strcpyw(SearchMaskW,CurMaskW); if (SearchAll) strcpyw(PointToName(SearchMaskW),MASKALLW); FindStack[Depth]->SetMaskW(SearchMaskW); } } else { FastFindFile=true; if (!FindCode) { if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true)) return(SCAN_NEXT); ErrHandler.OpenErrorMsg(ErrArcName,CurMask); return(FindData->Error ? SCAN_ERROR:SCAN_NEXT); } } } if (!FastFindFile && !FindStack[Depth]->Next(FindData,GetLinks)) { bool Error=FindData->Error; #ifdef _WIN_32 if (Error) { // Do not display an error if we cannot scan contents of reparse // point. Vista contains a lot of reparse (or junction) points, // which are not accessible. if ((FindData->FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0) Error=false; // Do not display an error if we cannot scan contents of // "System Volume Information" folder. Normally it is not accessible. if (strstr(CurMask,"System Volume Information\\")!=NULL) Error=false; } #endif if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true)) Error=false; #ifndef SILENT if (Error) { Log(NULL,St(MScanError),CurMask); } #endif char DirName[NM]; wchar DirNameW[NM]; *DirName=0; *DirNameW=0; delete FindStack[Depth]; FindStack[Depth--]=NULL; while (Depth>=0 && FindStack[Depth]==NULL) Depth--; if (Depth < 0) { if (Error) Errors++; return(SCAN_DONE); } char *Slash=strrchrd(CurMask,CPATHDIVIDER); if (Slash!=NULL) { char Mask[NM]; strcpy(Mask,Slash); if (Depth<SetAllMaskDepth) strcpy(Mask+1,PointToName(OrigCurMask)); *Slash=0; strcpy(DirName,CurMask); char *PrevSlash=strrchrd(CurMask,CPATHDIVIDER); if (PrevSlash==NULL) strcpy(CurMask,Mask+1); else strcpy(PrevSlash,Mask); } if (*CurMaskW!=0) { wchar *Slash=strrchrw(CurMaskW,CPATHDIVIDER); if (Slash!=NULL) { wchar Mask[NM]; strcpyw(Mask,Slash); if (Depth<SetAllMaskDepth) strcpyw(Mask+1,PointToName(OrigCurMaskW)); *Slash=0; strcpyw(DirNameW,CurMaskW); wchar *PrevSlash=strrchrw(CurMaskW,CPATHDIVIDER); if (PrevSlash==NULL) strcpyw(CurMaskW,Mask+1); else strcpyw(PrevSlash,Mask); } #ifndef _WIN_CE if (LowAscii(CurMaskW)) *CurMaskW=0; #endif } if (GetDirs==SCAN_GETDIRSTWICE && FindFile::FastFind(DirName,DirNameW,FindData,GetLinks) && FindData->IsDir) return(Error ? SCAN_ERROR:SCAN_SUCCESS); return(Error ? SCAN_ERROR:SCAN_NEXT); } if (FindData->IsDir) { if (!FastFindFile && Depth==0 && !SearchAllInRoot) return(GetDirs==SCAN_GETCURDIRS ? SCAN_SUCCESS:SCAN_NEXT); // if (GetDirs==SCAN_GETCURDIRS && Depth==0 && !SearchAllInRoot) // return(SCAN_SUCCESS); char Mask[NM]; bool MaskAll=FastFindFile; // bool MaskAll=CmpName(CurMask,FindData->Name,MATCH_NAMES); strcpy(Mask,MaskAll ? MASKALL:PointToName(CurMask)); strcpy(CurMask,FindData->Name); if (strlen(CurMask)+strlen(Mask)+1>=NM || Depth>=MAXSCANDEPTH-1) { #ifndef SILENT Log(NULL,"\n%s%c%s",CurMask,CPATHDIVIDER,Mask); Log(NULL,St(MPathTooLong)); #endif return(SCAN_ERROR); } AddEndSlash(CurMask); strcat(CurMask,Mask); if (*CurMaskW && *FindData->NameW==0) CharToWide(FindData->Name,FindData->NameW); if (*FindData->NameW!=0) { wchar Mask[NM]; if (FastFindFile) strcpyw(Mask,MASKALLW); else if (*CurMaskW) strcpyw(Mask,PointToName(CurMaskW)); else CharToWide(PointToName(CurMask),Mask); strcpyw(CurMaskW,FindData->NameW); AddEndSlash(CurMaskW); strcatw(CurMaskW,Mask); } Depth++; if (MaskAll) SetAllMaskDepth=Depth; } if (!FastFindFile && !CmpName(CurMask,FindData->Name,MATCH_NAMES)) return(SCAN_NEXT); return(SCAN_SUCCESS); }
int ScanTree::FindProc(FindData *FindData) { if (*CurMask==0) return(SCAN_NEXT); FastFindFile=false; if (FindStack[Depth]==NULL) { bool Wildcards=IsWildcard(CurMask,CurMaskW); bool FindCode=!Wildcards && FindFile::FastFind(CurMask,CurMaskW,FindData,GetLinks); bool IsDir=FindCode && FindData->IsDir; bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS || Wildcards && Recurse==RECURSE_WILDCARDS); if (Depth==0) SearchAllInRoot=SearchAll; if (SearchAll || Wildcards) { FindStack[Depth]=new FindFile; char SearchMask[NM]; strcpy(SearchMask,CurMask); if (SearchAll) strcpy(PointToName(SearchMask),MASKALL); FindStack[Depth]->SetMask(SearchMask); if (*CurMaskW) { wchar SearchMaskW[NM]; strcpyw(SearchMaskW,CurMaskW); if (SearchAll) strcpyw(PointToName(SearchMaskW),MASKALLW); FindStack[Depth]->SetMaskW(SearchMaskW); } } else { FastFindFile=true; if (!FindCode) { ErrHandler.OpenErrorMsg(CurMask); return(FindData->Error ? SCAN_ERROR:SCAN_NEXT); } } } if (!FastFindFile && !FindStack[Depth]->Next(FindData,GetLinks)) { bool Error=FindData->Error; #ifdef _WIN_32 if (Error && strstr(CurMask,"System Volume Information\\")!=NULL) Error=false; #endif #ifndef SILENT if (Error) { Log(NULL,St(MScanError),CurMask); } #endif char DirName[NM]; wchar DirNameW[NM]; *DirName=0; *DirNameW=0; delete FindStack[Depth]; FindStack[Depth--]=NULL; while (Depth>=0 && FindStack[Depth]==NULL) Depth--; if (Depth < 0) return(SCAN_DONE); char *Slash=strrchrd(CurMask,CPATHDIVIDER); if (Slash!=NULL) { char Mask[NM]; strcpy(Mask,Slash); *Slash=0; strcpy(DirName,CurMask); char *PrevSlash=strrchrd(CurMask,CPATHDIVIDER); if (PrevSlash==NULL) strcpy(CurMask,Mask+1); else strcpy(PrevSlash,Mask); } if (*CurMaskW!=0) { wchar *Slash=strrchrw(CurMaskW,CPATHDIVIDER); if (Slash!=NULL) { wchar Mask[NM]; strcpyw(Mask,Slash); *Slash=0; strcpyw(DirNameW,CurMaskW); wchar *PrevSlash=strrchrw(CurMaskW,CPATHDIVIDER); if (PrevSlash==NULL) strcpyw(CurMaskW,Mask+1); else strcpyw(PrevSlash,Mask); } if (LowAscii(CurMaskW)) *CurMaskW=0; } if (GetDirs==SCAN_GETDIRSTWICE && FindFile::FastFind(DirName,DirNameW,FindData,GetLinks) && FindData->IsDir) return(Error ? SCAN_ERROR:SCAN_SUCCESS); return(Error ? SCAN_ERROR:SCAN_NEXT); } if (FindData->IsDir) { if (!FastFindFile && Depth==0 && !SearchAllInRoot) return(GetDirs==SCAN_GETCURDIRS ? SCAN_SUCCESS:SCAN_NEXT); char Mask[NM]; strcpy(Mask,FastFindFile ? MASKALL:PointToName(CurMask)); strcpy(CurMask,FindData->Name); if (strlen(CurMask)+strlen(Mask)+1>=NM || Depth>=MAXSCANDEPTH-1) { #ifndef SILENT Log(NULL,"\n%s%c%s",CurMask,CPATHDIVIDER,Mask); Log(NULL,St(MPathTooLong)); #endif return(SCAN_ERROR); } AddEndSlash(CurMask); strcat(CurMask,Mask); if (*CurMaskW && *FindData->NameW==0) CharToWide(FindData->Name,FindData->NameW); if (*FindData->NameW!=0) { wchar Mask[NM]; if (FastFindFile) strcpyw(Mask,MASKALLW); else if (*CurMaskW) strcpyw(Mask,PointToName(CurMaskW)); else CharToWide(PointToName(CurMask),Mask); strcpyw(CurMaskW,FindData->NameW); AddEndSlash(CurMaskW); strcatw(CurMaskW,Mask); } Depth++; } if (!FastFindFile && !CmpName(CurMask,FindData->Name,MATCH_NAMES)) return(SCAN_NEXT); return(SCAN_SUCCESS); }