Thread: [code] Recursive Search Function

  1. #1
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544

    [code] Recursive Search Function

    The xxRecursiveSearch function provides a simple API to search for files and folders in a directory and its recursive subfolders. The provided callback routine is called for each file or folder that matches the given file spec. It aims to provide an easy-to-use and reusable solution to a problem that has typically involved messing around with FindNextFile, etc.

    Samples
    Code:
    BOOL CALLBACK search_callback(LPTSTR szFileName, WIN32_FIND_DATA* pwfd, ULONG_PTR parameter)
    {
        _tprintf(TEXT("%s\n"), szFileName);
        return TRUE;
    }
    
    int main(void)
    {
        // Return all files and folders under "C:\Windows\System32\"...
        xxRecursiveSearch(TEXT("C:\\Windows\\System32\\"), TEXT("*"),
                          search_callback, 0, RSEARCH_RET_FILES | RSEARCH_RET_FOLDERS);
    
        // Return all folders with "temp" in the path under "C:\Documents and Settings\"...
        xxRecursiveSearch(TEXT("C:\\Documents And Settings\\"), TEXT("*temp*"),
                          search_callback, 0, RSEARCH_RET_FOLDERS);
    
        getchar();
        return 0;
    }
    Code:
    /*
     * Sample Two: Create a list of MP3 files under "C:\Documents and Settings\" in a string vector.
     */
    BOOL CALLBACK search_callback(LPTSTR szFileName, WIN32_FIND_DATA* pwfd, ULONG_PTR parameter)
    {
       vector<string>* pVec = (vector<string>*) parameter; /* Retrieve the vector pointer from the parameter. */
       pVec->push_back(szFileName); /* Add the file to the vector. */
       
       return TRUE; /* Return TRUE to continue the search. */
    }
    
    int main(void)
    {
        vector<string> vecMP3s; /* Create a vector of MP3 files. */
    
        /* Return only files which match the spec *.mp3" under "C:\Documents And Settings\" 
         * Pass a pointer to our vector so it can be used by the callback. */
        xxRecursiveSearch(TEXT("C:\\Documents And Settings\\"), TEXT("*.mp3"),
                          search_callback, (ULONG_PTR) &vecMP3s, RSEARCH_RET_FILES);
    
        /* Copy our vector to cout to make sure we succeeded. */
        copy(vecMP3s.begin(), vecMP3s.end(), ostream_iterator<string>(cout, "\n"));
    
        getchar();
        return 0;
    }
    Implementation
    Code:
    /*
     * Function to search a folder and subfolders for files and folders matching a given file spec.
     * Calls a callback function for each matching file or folder that is found.
     */
    RSEARCH_RESULT
    WINAPI
    xxRecursiveSearch(LPCTSTR szRootPath,
                      LPCTSTR szFileSpec,
                      PSEARCH_CALLBACK_FUNC pCallback,
                      ULONG_PTR parameter,
                      UINT flags)
    {
        WIN32_FIND_DATA wfd;
        HANDLE          hSearch;
        RSEARCH_RESULT  res                 = RSEARCH_SUCCESS;
        TCHAR           szSearch[MAX_PATH];
    
        if (szRootPath == NULL || szFileSpec == NULL || pCallback == NULL)
        {
            return RSEARCH_INVALID_ARG;
        }
    
        StringCchCopy(szSearch, MAX_PATH, szRootPath);
        StringCchCat(szSearch, MAX_PATH, TEXT("*"));
    
        hSearch = FindFirstFile(szSearch, &wfd);
        if (INVALID_HANDLE_VALUE == hSearch)
        {
            return RSEARCH_ERROR;
        }
    
        for (;;)
        {
            if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
                (flags & RSEARCH_RET_FILES))
            {
                TCHAR szFileName[MAX_PATH];
                StringCchCopy(szFileName, MAX_PATH, szRootPath);
                StringCchCat(szFileName, MAX_PATH, wfd.cFileName);
    
                if (PathMatchSpec(szFileName, szFileSpec) &&
                    !pCallback(szFileName, &wfd, parameter))
                {
                    res = RSEARCH_ABORTED;
                    break;
                }
            }
            else if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
                     lstrcmp(wfd.cFileName, TEXT("."))  != 0 &&
                     lstrcmp(wfd.cFileName, TEXT("..")) != 0)
            {
                TCHAR szNewPath[MAX_PATH];
                StringCchCopy(szNewPath, MAX_PATH, szRootPath);
                StringCchCat(szNewPath, MAX_PATH, wfd.cFileName);
                StringCchCat(szNewPath, MAX_PATH, TEXT("\\"));
    
                if (flags & RSEARCH_RET_FOLDERS &&
                    PathMatchSpec(szNewPath, szFileSpec) &&
                    !pCallback(szNewPath, &wfd, parameter))
                {
                        res = RSEARCH_ABORTED;
                        break;
                }
    
                if (!(flags & RSEARCH_NO_RECURSION) &&
                    (res = xxRecursiveSearch(szNewPath, szFileSpec, pCallback, parameter, flags)) == RSEARCH_ABORTED)
                {
                    break;
                }
            }
    
            if (!FindNextFile(hSearch, &wfd))
            {
                if (GetLastError() != ERROR_NO_MORE_FILES)
                {
                    res = RSEARCH_ERROR;
                }
                break;
            }
        }
    
        FindClose(hSearch);
        return res;
    }
    Zip Contents

    In the zip is the source file, header file, documentation, Dev-C++ project, more samples and a kitchen sink. xxRecursiveSearch has been tested with MSVC.NET, Dev-C++ and LCC-WIN32. Feel free to provide feedback, etc.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Very nice job, and well coded too

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Search function not working fully
    By tabstop in forum C Programming
    Replies: 7
    Last Post: 12-04-2008, 02:57 AM
  2. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  3. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  4. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM