/// <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;
                    }
                }
            }
        }
Exemple #3
0
        /// <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;
              }
            }
              }
        }
            /// <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;
            }