Searching for a File or Directory

Use the FindFirstFile, FindNextFile, and FindClose functions to search for file names 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 that is passed in through the lpFileName parameter.

    The FindFirstFile function returns a handle that you can use in the FindNextFile function. FindFirstFile also returns the file name, alternate file name, file size, Windows CE object identifier, 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 the FindFirstFile function.

    The FindNextFile function returns the same data as the FindFirstFile function. 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 the FindFirstFile function by using the FindClose function.

The following code example shows how to copy all .txt files to a new directory of read-only files that is named Textro. If necessary, the example changes all of the files in the new directory to read-only. The example uses the FindFirstFile and FindNextFile functions 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 the SetFileAttribute function to convert the copied file to read-only. After the example copies all of the .txt files, it uses the FindClose function 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