| 238 | |
| 239 | |
| 240 | SCAN_CODE ScanTree::FindProc(FindData *FD) |
| 241 | { |
| 242 | if (*CurMask==0) |
| 243 | return SCAN_NEXT; |
| 244 | bool FastFindFile=false; |
| 245 | |
| 246 | if (FindStack[Depth]==NULL) // No FindFile object for this depth yet. |
| 247 | { |
| 248 | bool Wildcards=IsWildcard(CurMask); |
| 249 | |
| 250 | // If we have a file name without wildcards, we can try to use |
| 251 | // FastFind to optimize speed. For example, in Unix it results in |
| 252 | // stat call instead of opendir/readdir/closedir. |
| 253 | bool FindCode=!Wildcards && FindFile::FastFind(CurMask,FD,GetLinks); |
| 254 | |
| 255 | // Link check is important for NTFS, where links can have "Directory" |
| 256 | // attribute, but we do not want to recurse to them in "get links" mode. |
| 257 | bool IsDir=FindCode && FD->IsDir && (!GetLinks || !FD->IsLink); |
| 258 | |
| 259 | // SearchAll means that we'll use "*" mask for search, so we'll find |
| 260 | // subdirectories and will be able to recurse into them. |
| 261 | // We do not use "*" for directories at any level or for files |
| 262 | // at top level in recursion mode. We always comrpess the entire directory |
| 263 | // if folder wildcard is specified. |
| 264 | bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS || |
| 265 | FolderWildcards && Recurse!=RECURSE_DISABLE || |
| 266 | Wildcards && Recurse==RECURSE_WILDCARDS || |
| 267 | ScanEntireDisk && Recurse!=RECURSE_DISABLE); |
| 268 | if (Depth==0) |
| 269 | SearchAllInRoot=SearchAll; |
| 270 | if (SearchAll || Wildcards) |
| 271 | { |
| 272 | // Create the new FindFile object for wildcard based search. |
| 273 | FindStack[Depth]=new FindFile; |
| 274 | |
| 275 | wchar SearchMask[NM]; |
| 276 | wcsncpyz(SearchMask,CurMask,ASIZE(SearchMask)); |
| 277 | if (SearchAll) |
| 278 | SetName(SearchMask,MASKALL,ASIZE(SearchMask)); |
| 279 | FindStack[Depth]->SetMask(SearchMask); |
| 280 | } |
| 281 | else |
| 282 | { |
| 283 | // Either we failed to fast find or we found a file or we found |
| 284 | // a directory in RECURSE_DISABLE mode, so we do not need to scan it. |
| 285 | // We can return here and do not need to process further. |
| 286 | // We need to process further only if we fast found a directory. |
| 287 | if (!FindCode || !IsDir || Recurse==RECURSE_DISABLE) |
| 288 | { |
| 289 | // Return SCAN_SUCCESS if we found a file. |
| 290 | SCAN_CODE RetCode=SCAN_SUCCESS; |
| 291 | |
| 292 | if (!FindCode) |
| 293 | { |
| 294 | // Return SCAN_ERROR if problem is more serious than just |
| 295 | // "file not found". |
| 296 | RetCode=FD->Error ? SCAN_ERROR:SCAN_NEXT; |
| 297 |
nothing calls this directly
no test coverage detected