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;
}