Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FindNextFile Faild with Space Character

Tags:

c++

winapi

I wrote a simple code to do some operation on every file in every folder (subfolders). It's perfectly works until the path comes with 'SPACE ' character program crashs and INVALID_HANDLE_VALUE has been called. This is function:

int dirListFiles(char* startDir)
{
    HANDLE hFind;
    WIN32_FIND_DATAA  wfd;
    char path[MAX_PATH];

    sprintf(path, "%s\\*", startDir);

    std::string fileName;
    std::string s_path = startDir;
    std::string fullPath;

    fprintf(stdout, "In Directory \"%s\"\n\n", startDir);

    if ((hFind = FindFirstFileA(path, &wfd)) == INVALID_HANDLE_VALUE)
    {
        printf("FindFirstFIle failed on path = \"%s\"\n", path);
        abort();
    }

    BOOL cont = TRUE;
    while (cont == TRUE)
    {
        if ((strncmp(".", wfd.cFileName, 1) != 0) && (strncmp("..", wfd.cFileName, 2) != 0))
        {
            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                sprintf(path, "%s\\%s", startDir, wfd.cFileName);
                dirListFiles(path);
            }
        else
        {
            fileName = wfd.cFileName;
            fullPath = s_path + "\\" + fileName;    

            std::string fileExt = PathFindExtension(fullPath.c_str());
            if (fileExt == ".cpp")
            {
                ... Some operation on file
            }
        }
    }
    cont = FindNextFile(hFind, &wfd);
}

FindClose(hFind);

For example, If FindNextFile wants to Open Program Files (x86) which has space between file name cause error and program exit. What Can I do for supporting spaces? What Is Problem?

like image 947
Ali Sepehri-Amin Avatar asked Dec 03 '25 21:12

Ali Sepehri-Amin


1 Answers

Space is legal character in directory and file names.

First I propose to modify slightly your code:

if ((hFind = FindFirstFileA(path, &wfd)) == INVALID_HANDLE_VALUE)
{
    printf("FindFirstFIle failed on path = \"%s\". Error %d\n", path, GetLastError());
    return 0; // I think you shouldn't abort on error, just skip this dir.
}

Now check error codes reported by your program.

For some paths I have got error #5 (access denied). Examples:

c:\Program Files (x86)\Google\CrashReports\*
c:\ProgramData\Microsoft\Windows Defender\Clean Store\*
c:\Windows\System32\config\*

Got two cases with code #123 (Invalid name) for path names unmanageable by FindFirstFileA. To correct this behavior it would be better to use wide version of function FindFirstFileW. See both answers for c++ folder only search. For new Windows applications you should use wide version of API, converting with MultiByteToWideChar and WideCharToMultiByte if needed.

You have also logic error. Code skips all directories and files starting with dot.

like image 163
Daniel Sęk Avatar answered Dec 05 '25 11:12

Daniel Sęk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!