Search code examples
cwindowswinapidirectoryfile-search

Windows 10 C Wildcard Directory Search With FindFirstFile api Fails


This is my code:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <windows.h>
void filesearch(char* path,char* fname);


int main()
{
    filesearch("C:\\Users\\Admin Local\\Documents","test.txt");
    int choice;
    char folder[80],fname[80];
    printf("\nWhich directory will I search in?    ");
    gets(folder);
    printf("\nWhat is the filename of the required file?     ");
    gets(fname);
    filesearch(folder,fname);
}

void filesearch(char* folder,char* fname){
    char path[80];
    HANDLE filehandle;
    WIN32_FIND_DATA ffd;


    strcpy(path,folder);
    strcat(path,"\\*");
   // printf("%s\n",path);

    filehandle=FindFirstFile(path,&ffd);

    do{
        if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
            if(strcmp(ffd.cFileName,".")==0){
                FindNextFile(filehandle,&ffd);
                continue;
            }
            char subpath[80];
            strcpy(subpath,folder);
            strcat(subpath,"\\");
            strcat(subpath,ffd.cFileName);
            filesearch(subpath,fname);
            continue;
        }
        if(strcmp(ffd.cFileName,fname)==0)
            printf("\n%s\\%s\n",folder,ffd.cFileName);
    }while(FindNextFile(filehandle,&ffd)!=0);
    FindClose(filehandle);
    return;
}

When I put a directory like: C:\Users\Admin Local\Documents and wildcard *.txt nothing happens. The program abruptly halts and windows shows error and quits.

Yet when I put: C:\Users\Admin Local\Documents and file name test.txt it outputs as it should.

I have a test call in line 10 to the function so that I can check if it properly works without having to worry about user input and errors in input handling.

the test call works fine.

Is there any problem in the code or is this a anti-virus issue and most importantly, how do I fix it?


Solution

  • First problem is that all those 80-character buffers are far too small for a safe search. They should be replaced with at least char folder[_MAX_PATH] and similar. Then the main issue is the following:

        if(strcmp(ffd.cFileName,fname)==0)
            printf("\n%s\\%s\n",folder,ffd.cFileName);
    

    This compares a filename against a wildcard and will fail for true wildcards. It should rather be:

        if(PathMatchSpec(ffd.cFileName,fname))
            /* ... */
    

    Using PathMatchSpec requires #include <shlwapi.h> and linking to shlwapi.lib.