Exemple #1
0
        public override bool MoveNext()
        {
            Win32Native.WIN32_FIND_DATA data = new Win32Native.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:
            {
                Contract.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];
                    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 = Path.InternalCombine(searchData.fullPath, searchCriteria);

                    // Open a Find handle
#if MONO
                    int error;
                    _hnd = new SafeFindHandle(MonoIO.FindFirstFile(searchPath, out data.cFileName, out data.dwFileAttributes, out error));
#else
                    _hnd = Win32Native.FindFirstFile(searchPath, data);
#endif
                    if (_hnd.IsInvalid)
                    {
#if MONO
                        int hr = error;
#else
                        int hr = Marshal.GetLastWin32Error();
#endif
                        if (hr == Win32Native.ERROR_FILE_NOT_FOUND || hr == Win32Native.ERROR_NO_MORE_FILES || hr == Win32Native.ERROR_PATH_NOT_FOUND)
                        {
                            continue;
                        }

                        _hnd.Dispose();
                        HandleError(hr, searchData.fullPath);
                    }

                    state = STATE_FIND_NEXT_FILE;
                    needsParentPathDiscoveryDemand = true;
                    SearchResult searchResult = CreateSearchResult(searchData, data);
                    if (_resultHandler.IsResultIncluded(searchResult))
                    {
                        if (needsParentPathDiscoveryDemand)
                        {
                            DoDemand(searchData.fullPath);
                            needsParentPathDiscoveryDemand = false;
                        }
                        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
#if MONO
                    int error;
                    while (MonoIO.FindNextFile(_hnd.DangerousGetHandle(), out data.cFileName, out data.dwFileAttributes, out error))
#else
                    while (Win32Native.FindNextFile(_hnd, data))
#endif
                    {
                        SearchResult searchResult = CreateSearchResult(searchData, data);
                        if (_resultHandler.IsResultIncluded(searchResult))
                        {
                            if (needsParentPathDiscoveryDemand)
                            {
                                DoDemand(searchData.fullPath);
                                needsParentPathDiscoveryDemand = false;
                            }
                            current = _resultHandler.CreateObject(searchResult);
                            return(true);
                        }
                    }

#if MONO
                    int hr = error;
#else
                    // Make sure we quit with a sensible error.
                    int hr = Marshal.GetLastWin32Error();
#endif

                    if (_hnd != null)
                    {
                        _hnd.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 != Win32Native.ERROR_NO_MORE_FILES) &&
                        (hr != Win32Native.ERROR_FILE_NOT_FOUND))
                    {
                        HandleError(hr, 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);
        }
Exemple #2
0
        [System.Security.SecurityCritical]  // auto-generated
        private void AddSearchableDirsToStack(Directory.SearchData localSearchData)
        {
            Contract.Requires(localSearchData != null);

            String         searchPath = Path.InternalCombine(localSearchData.fullPath, "*");
            SafeFindHandle hnd        = null;

            Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
            try
            {
                // Get all files and dirs
#if MONO
                int error;
                hnd = new SafeFindHandle(MonoIO.FindFirstFile(searchPath, out data.cFileName, out data.dwFileAttributes, out error));
#else
                hnd = Win32Native.FindFirstFile(searchPath, data);
#endif

                if (hnd.IsInvalid)
                {
#if MONO
                    int hr = error;
#else
                    int hr = Marshal.GetLastWin32Error();
#endif

                    // This could happen if the dir doesn't contain any files.
                    // Continue with the recursive search though, eventually
                    // searchStack will become empty
                    if (hr == Win32Native.ERROR_FILE_NOT_FOUND || hr == Win32Native.ERROR_NO_MORE_FILES || hr == Win32Native.ERROR_PATH_NOT_FOUND)
                    {
                        return;
                    }

                    HandleError(hr, localSearchData.fullPath);
                }

                // Add subdirs to searchStack. Exempt ReparsePoints as appropriate
                int incr = 0;
                do
                {
                    if (FileSystemEnumerableHelpers.IsDir(data))
                    {
                        String tempFullPath = Path.InternalCombine(localSearchData.fullPath, data.cFileName);
                        String tempUserPath = Path.InternalCombine(localSearchData.userPath, data.cFileName);

                        SearchOption option = localSearchData.searchOption;

#if EXCLUDE_REPARSEPOINTS
                        // Traverse reparse points depending on the searchoption specified
                        if ((searchDataSubDir.searchOption == SearchOption.AllDirectories) && (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_REPARSE_POINT)))
                        {
                            option = SearchOption.TopDirectoryOnly;
                        }
#endif
                        // Setup search data for the sub directory and push it into the stack
                        Directory.SearchData searchDataSubDir = new Directory.SearchData(tempFullPath, tempUserPath, option);

                        searchStack.Insert(incr++, searchDataSubDir);
                    }
#if MONO
                } while (MonoIO.FindNextFile(hnd.DangerousGetHandle(), out data.cFileName, out data.dwFileAttributes, out error));
#else
                } while (Win32Native.FindNextFile(hnd, data));
#endif
                // We don't care about errors here
            }
Exemple #3
0
        static internal IEnumerable <FileSystemInfo> EnumerateFileSystemInfos(string basePath, string searchPattern, SearchOption searchOption)
        {
            Path.Validate(basePath);

            SafeFindHandle findHandle = null;

            try {
                string filePath;
                int    nativeAttrs;

                string basePathWithPattern = Path.Combine(basePath, searchPattern);

                int nativeError;
                try {} finally {
                    findHandle = new SafeFindHandle(MonoIO.FindFirstFile(basePathWithPattern, out filePath, out nativeAttrs, out nativeError));
                }

                if (findHandle.IsInvalid)
                {
                    MonoIOError error = (MonoIOError)nativeError;
                    if (error != MonoIOError.ERROR_FILE_NOT_FOUND)
                    {
                        throw MonoIO.GetException(Path.GetDirectoryName(basePathWithPattern), error);
                    }

                    yield break;
                }

                do
                {
                    if (filePath == null)
                    {
                        yield break;
                    }

                    if (filePath == "." || filePath == "..")
                    {
                        continue;
                    }

                    FileAttributes attrs = (FileAttributes)nativeAttrs;

                    string fullPath = Path.Combine(basePath, filePath);

                    if ((attrs & FileAttributes.ReparsePoint) == 0)
                    {
                        if ((attrs & FileAttributes.Directory) != 0)
                        {
                            yield return(new DirectoryInfo(fullPath));
                        }
                        else
                        {
                            yield return(new FileInfo(fullPath));
                        }
                    }

                    if ((attrs & FileAttributes.Directory) != 0 && searchOption == SearchOption.AllDirectories)
                    {
                        foreach (FileSystemInfo child in EnumerateFileSystemInfos(fullPath, searchPattern, searchOption))
                        {
                            yield return(child);
                        }
                    }
                } while (MonoIO.FindNextFile(findHandle.DangerousGetHandle(), out filePath, out nativeAttrs, out int _));
            } finally {
                if (findHandle != null)
                {
                    findHandle.Dispose();
                }
            }
        }