File Attributes and Directory Processing

We can search a directory with the functions FindFirstFile(), FindNextFile(), and FindClose().

The FindFirstFile() function accepts two parameters, a string pointer indicating the file name, and a pointer to a WIN32_FIND_DATA structure. We use the FindFirstFile() function to obtain a search handle, which is the return value of the function.

The WIN32_FIND_DATA structure has 9 fields. The first field, dwFileAttributes, is a DWORD value indicating the file attributes via bit settings. The next three fields are FILETIME structures that indicate the creation time, last access time, and last write time of the file. The next two values are DWORD values that indicate the high order and low order value of the file size, in bytes.  The value of the high-order DWORD value is 0, unless the size of the file is greater than MAXDWORD. 

#include "stdafx.h"
#include <Windows.h>

int main()
{
 WIN32_FIND_DATA structFindData;

 //find the cpp file in this folder
 TCHAR tszFilename[] = _T("*.cpp");
 HANDLE hFile;
 hFile = FindFirstFile(tszFilename, &structFindData);

 //our source code is certainly less than this number
 printf("The size of MAXDWORD is %lu\n", MAXDWORD);

 if (hFile == INVALID_HANDLE_VALUE) {
 printf("Error finding file.\n");
 }

 if (structFindData.nFileSizeHigh == 0) {
 _tprintf(_T("The size of %s is %d bytes\n"), structFindData.cFileName, structFindData.nFileSizeLow);
 }

 return 0;
}

Note that the cFileName field is not the pathname; it is just the file name by itself.

In order to find multiple files matching the search criteria, we can call the FindNextFile() function, passing in the search handle we obtained from the FindFirstHandle() function.

The FindNextFile() function returns a Boolean value, true if the function found another file, false if the file did not find another file or received bad arguments. We can use GetLastError() to check if the functions failed to find another matching file.

#include "stdafx.h"
#include <Windows.h>

int main()
{
 WIN32_FIND_DATA structWin32;
 //find all files/directories in C drive
 HANDLE hSearch = FindFirstFile(_T("C:\\*"), &structWin32);

 _tprintf(_T("%s\n"), structWin32.cFileName);

 //FindNextFile returns a Boolean
 while (FindNextFile(hSearch, &structWin32)) {
 _tprintf(_T("%s\n"), structWin32.cFileName);
 }
 if (GetLastError() == ERROR_NO_MORE_FILES) {
 printf("No more files...\n");
 }

 //FindClose to close search handle
 FindClose(hSearch);

 return 0;
}

Be sure and use the FindClose() function to close the search handle, not CloseHandle().

We can obtain a file’s full pathname using the GetFullPathName() function. The GetFullPathName() function has four parameters. The first parameter is the name of the file. The second parameter is the buffer size in TCHARs of the buffer that is to get the null-terminated string for the drive and path. The third argument is a pointer to the buffer that receives the null-terminated string for the drive and path. The fourth parameter is optional.

 #include "stdafx.h"
#include <Windows.h>

int main()
{
 
 WIN32_FIND_DATA structFData;
 HANDLE hFindFile;
 TCHAR tszBuffer[MAX_PATH];
 hFindFile = FindFirstFile(_T("."), &structFData);

 if (hFindFile == INVALID_HANDLE_VALUE) {
 printf("Error %d.\n", GetLastError());
 exit(EXIT_FAILURE);
 }

 GetFullPathName(structFData.cFileName, MAX_PATH, tszBuffer, NULL);

 printf("%s \n%s\n\n", tszBuffer, structFData.cFileName);

 FindClose(hFindFile);

 return 0;
}

Please note that the GetFullPathName() function is not recommended for multi-threaded programs.