Searching for a File or Directory

Use the FindFirstFile, FindNextFile, and FindClose functions to search for file or directory names that match a specified pattern. The pattern must be a valid file name and can include the asterisk (*) and question mark (?) wildcards.

    To find a single file or a series of files

  1. Call the FindFirstFile function with the file name passed in through the lpFileName parameter.

    FindFirstFile returns a handle that you can use in FindNextFile. FindFirstFile also returns the file name, alternate file name, file size, CEOID, attributes, creation time, last access time, and last write time of the found file.

  2. If necessary, call the FindNextFile function with the handle that was returned by FindFirstFile.

    FindNextFile returns the same data as FindFirstFile. You can call FindNextFile multiple times to find variations of the same file.

  3. Modify the file, as necessary.
  4. Destroy the handle that was created by FindFirstFile by using FindClose.

The following code example shows how to copy all text files to a new directory of read-only files named Textro. If necessary, the example changes all files in the new directory to read-only. The example uses FindFirstFile and FindNextFile to search the root directory for all .txt files. It then copies each .txt file to Textro. If a file is not read-only, the example changes to the Textro directory and uses SetFileAttribute to convert the copied file to read-only. After the example copies all .txt file, it uses FindClose to close the search handle.

void FindFileExample (void)
{
  WIN32_FIND_DATA FileData;   // Data structure describes the file found
  HANDLE hSearch;             // Search handle returned by FindFirstFile
  TCHAR szMsg[100];           // String to store the error message
  TCHAR szNewPath[MAX_PATH];  // Name and path of the file copied
  TCHAR szDirPath[] = TEXT("\TEXTRO");

  BOOL bFinished = FALSE;

  // Create a new directory.

  if (!CreateDirectory (szDirPath, NULL))
  {
    wsprintf (szMsg, TEXT("Unable to create new directory."));
    return;
  }

  // Start searching for .txt files in the root directory.

  hSearch = FindFirstFile (TEXT("\*.txt"), &FileData);
  if (hSearch == INVALID_HANDLE_VALUE)
  {
    wsprintf (szMsg, TEXT("No .TXT files found."));
    return;
  }

  // Copy each .txt file to the new directory and change it to
  // read-only, if it is not already read-only.

  while (!bFinished)
  {
    lstrcpy (szNewPath, szDirPath);
    lstrcat (szNewPath, TEXT("\\"));
    lstrcat (szNewPath, FileData.cFileName);

    if (CopyFile (FileData.cFileName, szNewPath, FALSE))
    {
      if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
      {
        SetFileAttributes (szNewPath,
                FileData.dwFileAttributes | FILE_ATTRIBUTE_READONLY);
      }
    }
    else
    {
      wsprintf (szMsg, TEXT("Unable to copy file."));

      // Your error-handling code goes here.
    }

    if (!FindNextFile (hSearch, &FileData))
    {
      bFinished = TRUE;

      if (GetLastError () == ERROR_NO_MORE_FILES)
      {
        wsprintf (szMsg, TEXT("Found all of the files."));
      }
      else
      {
        wsprintf (szMsg, TEXT("Unable to find next file."));
      }
    }
  }

  // Close the search handle.

  if (!FindClose (hSearch))
  {
    wsprintf (szMsg, TEXT("Unable to close search handle."));
  }
} // End of FindFileExample code