/// <summary> /// Constructor /// </summary> /// <param name="h">Find handle returned by FindFirstFile.</param> /// <param name="p">Path corresponding to find handle.</param> public SearchInfo(Win32.SafeFindHandle h, string p) { Handle = h; Path = p; }
/// <summary> /// Get an enumerator that returns all of the files that match the wildcards that /// are in any of the directories to be searched. /// </summary> /// <returns>An IEnumerable that returns all matching files one by one.</returns> /// <remarks>The enumerator that is returned finds files using a lazy algorithm that /// searches directories incrementally as matches are consumed.</remarks> public IEnumerable <FileInfo> Matches() { foreach (string rootPath in m_paths) { string path = rootPath.Trim(); // we "recurse" into a new directory by jumping to this spot top: // check security - ensure that caller has rights to read this directory new FileIOPermission(FileIOPermissionAccess.PathDiscovery, Path.Combine(path, ".")).Demand(); // now that security is checked, go read the directory Win32.FindData findData = new Win32.FindData(); Win32.SafeFindHandle handle = Win32.SafeNativeMethods.FindFirstFile(Path.Combine(path, "*"), findData); m_scopes.Push(new SearchInfo(handle, path)); bool restart = false; // we "return" from a sub-directory by jumping to this spot restart: if (!handle.IsInvalid) { do { // if we restarted the loop (unwound a recursion), fetch the next match if (restart) { restart = false; continue; } // don't match . or .. if (findData.fileName.Equals(@".") || findData.fileName.Equals(@"..")) { continue; } if ((findData.fileAttributes & (int)FileAttributes.Directory) != 0) { if (m_includeSubDirs) { // it's a directory - recurse into it path = Path.Combine(path, findData.fileName); goto top; } } else { // it's a file, see if any of the filespecs matches it foreach (Regex fileSpec in m_fileSpecs) { // if this spec matches, return this file's info if (fileSpec.IsMatch(findData.fileName)) { yield return(new FileInfo(Path.Combine(path, findData.fileName))); } } } } while (Win32.SafeNativeMethods.FindNextFile(handle, findData)); // close this find handle handle.Close(); // unwind the stack - are we still in a recursion? m_scopes.Pop(); if (m_scopes.Count > 0) { SearchInfo si = m_scopes.Peek(); handle = si.Handle; path = si.Path; restart = true; goto restart; } } } }
/// <summary> /// Get an enumerator that returns all of the files that match the wildcards that /// are in any of the directories to be searched. /// </summary> /// <returns>An IEnumerable that returns all matching files one by one.</returns> /// <remarks>The enumerator that is returned finds files using a lazy algorithm that /// searches directories incrementally as matches are consumed.</remarks> public IEnumerable<FileInfo> Matches() { foreach (string rootPath in m_paths) { string path = rootPath.Trim(); // we "recurse" into a new directory by jumping to this spot top: Win32.FindData findData = new Win32.FindData(); Win32.SafeFindHandle handle = new Win32.SafeFindHandle( Win32.SafeNativeMethods.FindFirstFile(Path.Combine(path, "*"), findData) ); m_scopes.Push(new SearchInfo(handle, path)); bool restart = false; // we "return" from a sub-directory by jumping to this spot restart: if (!handle.IsInvalid) { do { // if we restarted the loop (unwound a recursion), fetch the next match if (restart) { restart = false; continue; } // don't match . or .. if (findData.fileName.Equals(@".") || findData.fileName.Equals(@"..")) continue; if ((findData.fileAttributes & (int)FileAttributes.Directory) != 0) { if (m_includeSubDirs) { // it's a directory - recurse into it path = Path.Combine(path, findData.fileName); goto top; } } else { // it's a file, see if any of the filespecs matches it foreach (Regex fileSpec in m_fileSpecs) { // if this spec matches, return this file's info if (fileSpec.IsMatch(findData.fileName)) yield return new FileInfo(Path.Combine(path, findData.fileName)); } } } while (Win32.SafeNativeMethods.FindNextFile(handle.DangerousGetHandle(), findData)); // close this find handle handle.Close(); // unwind the stack - are we still in a recursion? m_scopes.Pop(); if (m_scopes.Count > 0) { SearchInfo si = m_scopes.Peek(); handle = si.Handle; path = si.Path; restart = true; goto restart; } } } }