Contains a search result from a find file call.
Exemplo n.º 1
0
        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);
        }