INT SearchList()

in src/wfsearch.c [95:411]


INT  SearchList(
   HWND hwndLB,
   LPWSTR szPath,
   LPWSTR szFileSpec,
   BOOL bRecurse,
   BOOL bIncludeSubdirs,
   LPXDTALINK* plpStart,
   INT iFileCount,
   BOOL bRoot);
VOID ClearSearchLB(BOOL bWorkerCall);
DWORD WINAPI SearchDrive(LPVOID lpParameter);

#define SEARCH_FILE_WIDTH_DEFAULT 50




/////////////////////////////////////////////////////////////////////
//
// Name:     SearchList
//
// Synopsis: Recursive search
//
//
// Return:   INT, # of files found
//
//
// Assumes:
//
// Effects:
//
//
// Notes:
//
/////////////////////////////////////////////////////////////////////

INT
SearchList(
   HWND hwndLB,
   LPWSTR szPath,
   LPWSTR szFileSpec,
   BOOL bRecurse,
   BOOL bIncludeSubdirs,
   LPXDTALINK* plpStart,
   INT iFileCount,
   BOOL bRoot)
{
   INT iRetVal;
   SIZE size;
   BOOL bFound;
   LPWSTR pszNewPath;
   LPWSTR pszNextFile;
   LFNDTA lfndta;
   LPXDTA lpxdta;

   HDC hdc;
   HANDLE hOld;
   DWORD dwTimeNow;

   BOOL bLowercase;
   WCHAR szTemp[MAXPATHLEN];

   BOOL bLFN;
   DWORD dwAttrs;
   INT iBitmap;

   //
   // hack: setup ATTR_LOWERCASE if a letter'd (NON-unc) drive
   // LATER: do GetVolumeInfo for UNC too!
   //

   bLowercase = (wTextAttribs & TA_LOWERCASEALL) ||
      ((wTextAttribs & TA_LOWERCASE) && !SearchInfo.bCasePreserved);

   dwTimeNow = GetTickCount();

   if (dwTimeNow > dwLastUpdateTime+1000) {
      dwLastUpdateTime = dwTimeNow;

      SearchInfo.iDirsRead = iDirsRead;
      SearchInfo.iFileCount = iFileCount;

      PostMessage(hwndFrame, FS_SEARCHUPDATE, iDirsRead, iFileCount);
   }

   iDirsRead++;

   if (!*plpStart) {

      *plpStart = MemNew();

      if (!*plpStart) {
MemoryError:
         SearchInfo.dwError = ERROR_NOT_ENOUGH_MEMORY;
         SearchInfo.eStatus = SEARCH_ERROR;
         return iFileCount;
      }

      //
      // Never shows altname
      //
      MemLinkToHead(*plpStart)->dwAlternateFileNameExtent = 0;

      SetWindowLongPtr(GetParent(hwndLB), GWL_HDTA, (LPARAM)*plpStart);
      SearchInfo.lpStart = *plpStart;
   }

   //
   // allocate the buffer for this level
   //
   pszNewPath = (LPWSTR)LocalAlloc(LPTR, ByteCountOf(lstrlen(szPath) + MAXFILENAMELEN + 2));

   if (!pszNewPath) {
      goto MemoryError;
   }

   lstrcpy(pszNewPath, szPath);
   AddBackslash(pszNewPath);

   pszNextFile = pszNewPath + lstrlen(pszNewPath);
   lstrcpy(pszNextFile, szFileSpec);

   bFound = WFFindFirst(&lfndta, pszNewPath, ATTR_ALL);

   hdc = GetDC(hwndLB);
   hOld = SelectObject(hdc, hFont);

   //
   // Ignore file not found errors AND access denied errors
   // AND PATH_NOT_FOUND when not in the root
   //

   if (!bFound && ERROR_FILE_NOT_FOUND != lfndta.err &&
      (bRoot ||
         ERROR_ACCESS_DENIED != lfndta.err &&
         ERROR_PATH_NOT_FOUND != lfndta.err &&
         ERROR_INVALID_NAME != lfndta.err)) {

      SearchInfo.eStatus = SEARCH_ERROR;
      SearchInfo.dwError = lfndta.err;
      bRecurse = FALSE;

      goto SearchCleanup;
   }

   while (bFound) {

      //
      // allow escape to exit
      //
      if (SearchInfo.bCancel) {

         bRecurse = FALSE;
         break;
      }

	  // default ftSince is 0 and so normally this will be true
	  bFound = CompareFileTime(&SearchInfo.ftSince, &lfndta.fd.ftLastWriteTime) < 0;

	  // if we otherwise match, but shouldn't include directories in the output, skip
	  if (bFound && !bIncludeSubdirs && (lfndta.fd.dwFileAttributes & ATTR_DIR) != 0)
	  {
		  bFound = FALSE;
	  }

      //
      // Make sure this matches date (if specified) and is not a "." or ".." directory 
      //
      if (bFound && !ISDOTDIR(lfndta.fd.cFileName)) {

         lstrcpy(pszNextFile, lfndta.fd.cFileName);

         // Warning: was OemToChar(pszNewPath, szMessage);
         // but taken out since no translation necessary.
         // Here on out _was_ using szMessage
         // (Multithreaded=> szMessage usage BAD)

         bLFN = IsLFN(lfndta.fd.cFileName);

         if (bLowercase) {
            lstrcpy(szTemp, pszNewPath);
            CharLower(szTemp);

            GetTextExtentPoint32(hdc, szTemp, lstrlen(szTemp), &size);
         } else {
            GetTextExtentPoint32(hdc, pszNewPath, lstrlen(pszNewPath), &size);
         }

         maxExt = max(size.cx,maxExt);

         lpxdta = MemAdd(plpStart, lstrlen(pszNewPath), 0);

         if (!lpxdta) {

            bRecurse = FALSE;       // simulate an abort
            SearchInfo.dwError = ERROR_NOT_ENOUGH_MEMORY;
            SearchInfo.eStatus = SEARCH_ERROR;

            break;
         }

         dwAttrs = lpxdta->dwAttrs = lfndta.fd.dwFileAttributes;
         lpxdta->ftLastWriteTime = lfndta.fd.ftLastWriteTime;
         lpxdta->qFileSize.LowPart = lfndta.fd.nFileSizeLow;
         lpxdta->qFileSize.HighPart = lfndta.fd.nFileSizeHigh;

         lstrcpy(MemGetFileName(lpxdta), pszNewPath);
         MemGetAlternateFileName(lpxdta)[0] = CHAR_NULL;

         if (bLFN)
            lpxdta->dwAttrs |= ATTR_LFN;

         if (!SearchInfo.bCasePreserved)
            lpxdta->dwAttrs |= ATTR_LOWERCASE;

         if (dwAttrs & ATTR_DIR)
            iBitmap = BM_IND_CLOSE;
         else if (dwAttrs & (ATTR_HIDDEN | ATTR_SYSTEM))
            iBitmap = BM_IND_RO;
         else if (IsProgramFile(lfndta.fd.cFileName))
            iBitmap = BM_IND_APP;
         else if (IsDocument(lfndta.fd.cFileName))
            iBitmap = BM_IND_DOC;
         else
            iBitmap = BM_IND_FIL;

         lpxdta->byBitmap = iBitmap;
		 lpxdta->pDocB = NULL;

         SendMessage(hwndFrame,
                     FS_SEARCHLINEINSERT,
                     (WPARAM)&iFileCount,
                     (LPARAM)lpxdta);

      }

      //
      // Search for more files in the current directory
      //
      bFound = WFFindNext(&lfndta);
   }

SearchCleanup:

   WFFindClose(&lfndta);

   if (hOld)
      SelectObject(hdc, hOld);
   ReleaseDC(hwndLB, hdc);

   if (!bRecurse)
      goto SearchEnd;

   //
   // Now see if there are any subdirectories here
   //
   lstrcpy(pszNextFile, szStarDotStar);

   bFound = WFFindFirst(&lfndta, pszNewPath, ATTR_DIR | ATTR_HS);

   while (bFound) {

      //
      // allow escape to exit
      //
      if (SearchInfo.bCancel) {

         bRecurse = FALSE;
         break;
      }

      //
      // Make sure this is not a "." or ".." directory.
      //
      if (!ISDOTDIR(lfndta.fd.cFileName) &&
         (lfndta.fd.dwFileAttributes & ATTR_DIR)) {

         //
         // Yes, search and add files in this directory
         //
         lstrcpy(pszNextFile, lfndta.fd.cFileName);

         //
         // Add all files in this subdirectory.
         //
         iRetVal = SearchList(hwndLB,
                              pszNewPath,
                              szFileSpec,
                              bRecurse,
							  bIncludeSubdirs,
                              plpStart,
                              iFileCount,
                              FALSE);

         iFileCount = iRetVal;

         if (SEARCH_ERROR == SearchInfo.eStatus) {
            break;
         }

      }
      bFound = WFFindNext(&lfndta);
   }

   WFFindClose(&lfndta);

SearchEnd:


   //
   // Save the number of files in the xdtahead structure.
   //
   MemLinkToHead(SearchInfo.lpStart)->dwEntries = iFileCount;

   LocalFree((HANDLE)pszNewPath);
   return iFileCount;
}