Reputation: 703
I am trying to recursively search for files in the computer using WinAPI: FindFirstFile
and FindNextFile
I do not understand why, but my code does not work.
on the first run, everything is great - I can see all of the content in the C drive.
when I go into the sub-folders, for example C:\Program Files (x86)
, I am getting that all the files inside the folders are just .
, while if I'd use the function without recursively-search, with the given path of C:\Program Files (x86)
, I would get a list of all the folders inside.
Here is my code :
#include <Windows.h>
#include <iostream>
#include <string>
void FindFile(std::string directory)
{
std::string tmp = directory + "\\*";
WIN32_FIND_DATA file;
HANDLE search_handle=FindFirstFile(tmp.c_str(), &file);
if (search_handle != INVALID_HANDLE_VALUE)
{
do
{
std::wcout << file.cFileName << std::endl;
directory += "\\" + std::string(file.cFileName);
FindFile(directory);
}while(FindNextFile(search_handle,&file));
if (GetLastError() != 18) // Error code 18: No more files left
CloseHandle(search_handle);
}
}
int main()
{
FindFile("C:");
}
The variable tmp
is used to store the wildchar *
, while directory is containing the next file to be searched (inside the loop).
What is my error?
Thank you!
Upvotes: 2
Views: 9243
Reputation: 36318
Each directory (except the root directory) has two entries (.
and ..
) at the beginning which you need to skip.
Otherwise, you have an infinite recursion:
C:\*
C:\Program Files (x86)\*
C:\Program Files (x86)\.\*
C:\Program Files (x86)\.\.\*
C:\Program Files (x86)\.\.\.\*
and so on.
(You'll also need to check whether each entry is a file or a directory and only recurse into directories.)
For example:
#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>
void FindFile(const std::wstring &directory)
{
std::wstring tmp = directory + L"\\*";
WIN32_FIND_DATAW file;
HANDLE search_handle = FindFirstFileW(tmp.c_str(), &file);
if (search_handle != INVALID_HANDLE_VALUE)
{
std::vector<std::wstring> directories;
do
{
if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if ((!lstrcmpW(file.cFileName, L".")) || (!lstrcmpW(file.cFileName, L"..")))
continue;
}
tmp = directory + L"\\" + std::wstring(file.cFileName);
std::wcout << tmp << std::endl;
if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
directories.push_back(tmp);
}
while (FindNextFileW(search_handle, &file));
FindClose(search_handle);
for(std::vector<std::wstring>::iterator iter = directories.begin(), end = directories.end(); iter != end; ++iter)
FindFile(*iter);
}
}
int main()
{
FindFile(L"C:");
return 0;
}
Upvotes: 9
Reputation: 24857
You have to specifically exclude ''.' and '..' from your search results so as not to recurse on them.
Upvotes: 2