René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle - Most wanted - Feedback -
 

Recursively Searching for Files

#define WIN32_WINNT 0x0400

#include <windows.h>
#include <iostream>
#include <string>PImproveSite();

using namespace std;

typedef bool (*FF) (string fileName, char fileType, int indent);

const string gPattern="*.sql";

void MyFindFile(string path, string pattern, FF func) {
  WIN32_FIND_DATA ffd;
  HANDLE hFind;

  static indent = 0;

  // 1st Part: find the files

  hFind = FindFirstFileEx(
    (path+"\"+pattern).c_str(), // File Name
     FindExInfoStandard,    // information Level
     &ffd,                  // information buffer
     FindExSearchNameMatch, // 
     NULL,                  // search Criteria
     0                      // reserved
   );

  
  if (hFind == INVALID_HANDLE_VALUE) {
    DWORD le = GetLastError();

    if (le != ERROR_FILE_NOT_FOUND) {
      printf ("Invalid File Handle, err code: %d\n", le);
      return;
    }
  } 

  if (hFind != INVALID_HANDLE_VALUE) {
  do {
    if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      continue;

    string fileName = ffd.cFileName;

    if (! (*func)(fileName,'f',indent)) {  
      return;
    }
 
  }
  while (FindNextFile(hFind,&ffd));

  FindClose(hFind);
  }


  // 2nd Part: Find the directories

  hFind = FindFirstFileEx(
    (path+"\*").c_str(), // File Name
    FindExInfoStandard,    // information Level
    &ffd,                  // information buffer
    FindExSearchLimitToDirectories, // only Directories
    NULL,                  // search Criteria
    0                      // reserved
   );

  if (hFind == INVALID_HANDLE_VALUE) {
    DWORD le = GetLastError();
    printf ("Invalid File Handle, err code: %d\n", le);
    return;
  } 

  do {
    string dirName = ffd.cFileName;

    if (dirName == "." || dirName == "..")
      continue;

    if (! (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
      continue;

    if (! (*func)(dirName,'d', indent)) {  
      return;
    }

    indent ++;
    MyFindFile(path+"\" + ffd.cFileName,gPattern,func); 
    indent--;

  } 
  while (FindNextFile(hFind,&ffd));

  FindClose(hFind);


}


bool printFile(string fileName, char type, int indent) {
  for (int i=0; i<indent; i++)
    cout << "  "; 

  cout << (type == 'd' ? " [ Dir  ]  " : "[ File ]  ") << fileName  << endl;
  return true;
}

int main(int argc, char* argv[]) {

  MyFindFile("C:\temp",gPattern, printFile);
  
  return (0);

}
See also SearchTreeForFile.