public override bool MoveNext() { var data = new FindData(); switch (state) { case stateInit: { if (isEmpty) { state = stateFinish; goto case stateFinish; } if (searchData.searchOptions == SearchOption.TopDirectoryOnly) { state = stateFindNextFile; if (current != null) { return(true); } goto case stateFindNextFile; } state = stateSearchNextDir; goto case stateSearchNextDir; } case stateSearchNextDir: { Contract.Assert(searchData.searchOptions != 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]; Contract.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 = searchData.fullPath + searchCriteria; // Open a Find handle safeFindHandle = Win32Api.IO.FindFirstFile(searchPath, data); if (safeFindHandle.IsInvalid) { int hr = Marshal.GetLastWin32Error(); if (hr == Win32Error.ERROR_ACCESS_DENIED || hr == Win32Error.ERROR_FILE_NOT_FOUND || hr == Win32Error.ERROR_NO_MORE_FILES || hr == Win32Error.ERROR_PATH_NOT_FOUND) { continue; } safeFindHandle.Dispose(); HandleError(hr, searchData.fullPath); } state = stateFindNextFile; needsParentPathDiscoveryDemand = true; SearchResult searchResult = CreateSearchResult(searchData, data); if (resultHandler.IsResultIncluded(searchResult)) { if (needsParentPathDiscoveryDemand) { DoDemand(searchData.fullPath); needsParentPathDiscoveryDemand = false; } current = resultHandler.CreateObject(searchResult); return(true); } goto case stateFindNextFile; } state = stateFinish; goto case stateFinish; } case stateFindNextFile: { if (searchData != null && safeFindHandle != null) { // Keep asking for more matching files/dirs, add it to the list while (Win32Api.IO.FindNextFile(safeFindHandle, data)) { SearchResult searchResult = CreateSearchResult(searchData, data); if (resultHandler.IsResultIncluded(searchResult)) { if (needsParentPathDiscoveryDemand) { DoDemand(searchData.fullPath); needsParentPathDiscoveryDemand = false; } current = resultHandler.CreateObject(searchResult); return(true); } } // Make sure we quit with a sensible error. int hr = Marshal.GetLastWin32Error(); if (safeFindHandle != null) { safeFindHandle.Dispose(); } // ERROR_FILE_NOT_FOUND is valid here because if the top level // dir doen't contain any subdirs and matching files then // we will get here with this errorcode from the searchStack walk if ((hr != 0) && (hr != Win32Error.ERROR_NO_MORE_FILES) && (hr != Win32Error.ERROR_FILE_NOT_FOUND)) { HandleError(hr, searchData.fullPath); } } if (searchData.searchOptions == SearchOption.TopDirectoryOnly) { state = stateFinish; goto case stateFinish; } state = stateSearchNextDir; goto case stateSearchNextDir; } case stateFinish: { Dispose(); break; } } return(false); }