Editor's note: COTD Entry: File Enumeration by Andrew Grant [AndrewGrant@hothouse.org] #include #include // Function name : EnumerateFiles // Description : Takes an initial directory and calls the provided function pointers for each file or directory // which it contains and which matches the specified wildcard search. Replace dirCallback or // fileCallback with NULL to ignore these types. To enumerate all files and directories use *.* // // // Argument : const char *pDirectory - directory to begin searching. do NOT specify a trailing slash! // Argument : const char* pWildCard - wildcard to specify files, e.g *.txt. use *.* for all fiels/directories // Argument : bool recurse - check sub folders? // Argument : void(*fileCallback) - callback for each directory which matches the wildcard // Argument : void* pFileParam - param to be provided to the directory callback functon // Argument : void(*dirCallback) - callback for each directory which matches the wildcard // Argument : void* pDirParam - param to be provided to the directory callback functon void EnumerateFiles(const char *pDirectory, const char* pWildCard, bool recurse, void(*fileCallback)(const char *pFilename, const char *pFilePath, void* pFileParam), void* pFileParam, void(*dirCallback)(const char *pDirname, const char *pDirPath, void* pDirParam), void* pDirParam) { WIN32_FIND_DATA finddata; HANDLE handle; char searchPath[256]; // first search for files matching the wildcard value sprintf(searchPath, "%s\\%s", pDirectory, pWildCard); handle = FindFirstFile(searchPath, &finddata); if (handle != INVALID_HANDLE_VALUE) { // check all files and directories do { if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // ignore directories with "." and ".." if (strcmp(finddata.cFileName, ".") && strcmp(finddata.cFileName, "..")) { if (dirCallback) { dirCallback(finddata.cFileName, pDirectory, pDirParam); } } } else { if (fileCallback) { fileCallback(finddata.cFileName, pDirectory, pFileParam); } } } while (FindNextFile(handle, &finddata)); FindClose(handle); } // now repeat for all directories if the recurse flag was specified if (recurse) { sprintf(searchPath, "%s\\*.*", pDirectory); handle = FindFirstFile(searchPath, &finddata); if (INVALID_HANDLE_VALUE == handle) return; do { // only interested in proper directories... if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (strcmp(finddata.cFileName, ".") && strcmp(finddata.cFileName, "..")) { // call ourself on this dir sprintf(searchPath, "%s\\%s", pDirectory, finddata.cFileName); EnumerateFiles(searchPath, pWildCard, true, fileCallback, pFileParam, dirCallback, pDirParam); } } } while (FindNextFile(handle, &finddata)); FindClose(handle); } return; }