Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}