private SearchResult CreateSearchResult(SearchData localSearchData, Interop.mincore.WIN32_FIND_DATA findData) { string findData_fileName = findData.cFileName; Contract.Requires(findData_fileName.Length != 0 && !Path.IsPathRooted(findData_fileName), "Expected file system enumeration to not have empty file/directory name and not have rooted name"); String userPathFinal = Path.Combine(localSearchData.userPath, findData_fileName); String fullPathFinal = Path.Combine(localSearchData.fullPath, findData_fileName); return(new SearchResult(fullPathFinal, userPathFinal, findData)); }
internal Win32FileSystemEnumerableIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler <TSource> resultHandler) { Contract.Requires(path != null); Contract.Requires(originalUserPath != null); Contract.Requires(searchPattern != null); Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); Contract.Requires(resultHandler != null); _oldMode = Interop.mincore.SetErrorMode(Interop.mincore.SEM_FAILCRITICALERRORS); _searchStack = new List <SearchData>(); String normalizedSearchPattern = NormalizeSearchPattern(searchPattern); if (normalizedSearchPattern.Length == 0) { _empty = true; } else { _resultHandler = resultHandler; this._searchOption = searchOption; _fullPath = Path.GetFullPath(path); String fullSearchString = GetFullSearchString(_fullPath, normalizedSearchPattern); _normalizedSearchPath = Path.GetDirectoryName(fullSearchString); // normalize search criteria _searchCriteria = GetNormalizedSearchCriteria(fullSearchString, _normalizedSearchPath); // fix up user path String searchPatternDirName = Path.GetDirectoryName(normalizedSearchPattern); String userPathTemp = originalUserPath; if (searchPatternDirName != null && searchPatternDirName.Length != 0) { userPathTemp = Path.Combine(userPathTemp, searchPatternDirName); } this._userPath = userPathTemp; _searchData = new SearchData(_normalizedSearchPath, this._userPath, searchOption); CommonInit(); } }
private Win32FileSystemEnumerableIterator(String fullPath, String normalizedSearchPath, String searchCriteria, String userPath, SearchOption searchOption, SearchResultHandler <TSource> resultHandler) { this._fullPath = fullPath; this._normalizedSearchPath = normalizedSearchPath; this._searchCriteria = searchCriteria; this._resultHandler = resultHandler; this._userPath = userPath; this._searchOption = searchOption; _searchStack = new List <SearchData>(); if (searchCriteria != null) { PathHelpers.CheckInvalidPathChars(fullPath, true); _searchData = new SearchData(normalizedSearchPath, userPath, searchOption); CommonInit(); } else { _empty = true; } }
public override bool MoveNext() { Interop.mincore.WIN32_FIND_DATA data = new Interop.mincore.WIN32_FIND_DATA(); switch (state) { case STATE_INIT: { if (_empty) { state = STATE_FINISH; goto case STATE_FINISH; } if (_searchData.searchOption == SearchOption.TopDirectoryOnly) { state = STATE_FIND_NEXT_FILE; if (current != null) { return(true); } else { goto case STATE_FIND_NEXT_FILE; } } else { state = STATE_SEARCH_NEXT_DIR; goto case STATE_SEARCH_NEXT_DIR; } } case STATE_SEARCH_NEXT_DIR: { Debug.Assert(_searchData.searchOption != SearchOption.TopDirectoryOnly, "should not reach this code path if searchOption == TopDirectoryOnly"); // Traverse directory structure. We need to get '*' while (_searchStack.Count > 0) { _searchData = _searchStack[0]; Debug.Assert((_searchData.fullPath != null), "fullpath can't be null!"); _searchStack.RemoveAt(0); // Traverse the subdirs AddSearchableDirsToStack(_searchData); // Execute searchCriteria against the current directory String searchPath = Path.Combine(_searchData.fullPath, _searchCriteria); // Open a Find handle _hnd = Interop.mincore.FindFirstFile(searchPath, ref data); if (_hnd.IsInvalid) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == Interop.mincore.Errors.ERROR_FILE_NOT_FOUND || errorCode == Interop.mincore.Errors.ERROR_NO_MORE_FILES || errorCode == Interop.mincore.Errors.ERROR_PATH_NOT_FOUND) { continue; } _hnd.Dispose(); HandleError(errorCode, _searchData.fullPath); } state = STATE_FIND_NEXT_FILE; SearchResult searchResult = CreateSearchResult(_searchData, data); if (_resultHandler.IsResultIncluded(searchResult)) { current = _resultHandler.CreateObject(searchResult); return(true); } else { goto case STATE_FIND_NEXT_FILE; } } state = STATE_FINISH; goto case STATE_FINISH; } case STATE_FIND_NEXT_FILE: { if (_searchData != null && _hnd != null) { // Keep asking for more matching files/dirs, add it to the list while (Interop.mincore.FindNextFile(_hnd, ref data)) { SearchResult searchResult = CreateSearchResult(_searchData, data); if (_resultHandler.IsResultIncluded(searchResult)) { current = _resultHandler.CreateObject(searchResult); return(true); } } // Make sure we quit with a sensible error. int errorCode = Marshal.GetLastWin32Error(); if (_hnd != null) { _hnd.Dispose(); } // ERROR_FILE_NOT_FOUND is valid here because if the top level // dir doesn't contain any subdirs and matching files then // we will get here with this errorcode from the searchStack walk if ((errorCode != 0) && (errorCode != Interop.mincore.Errors.ERROR_NO_MORE_FILES) && (errorCode != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND)) { HandleError(errorCode, _searchData.fullPath); } } if (_searchData.searchOption == SearchOption.TopDirectoryOnly) { state = STATE_FINISH; goto case STATE_FINISH; } else { state = STATE_SEARCH_NEXT_DIR; goto case STATE_SEARCH_NEXT_DIR; } } case STATE_FINISH: { Dispose(); break; } } return(false); }