Search code examples
cwindowsdirectory-structure

Listing directory contents using C and Windows


I'm looking to list and store the contents of a directory in a struct using C on Windows.

I'm not necessarily looking for anyone to write out the code I'm looking for, rather point me in the right direction when it comes to which library I should be looking at.

I've been Googling for a few hours now and all I'm finding is C#, C++ solutions so any help would be greatly appreciated.


Solution

  • Just like everyone else said (with FindFirstFile, FindNextFile and FindClose)... but with recursion!

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    bool ListDirectoryContents(const char *sDir)
    {
        WIN32_FIND_DATA fdFile;
        HANDLE hFind = NULL;
    
        char sPath[2048];
    
        //Specify a file mask. *.* = We want everything!
        sprintf(sPath, "%s\\*.*", sDir);
    
        if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
        {
            printf("Path not found: [%s]\n", sDir);
            return false;
        }
    
        do
        {
            //Find first file will always return "."
            //    and ".." as the first two directories.
            if(strcmp(fdFile.cFileName, ".") != 0
                    && strcmp(fdFile.cFileName, "..") != 0)
            {
                //Build up our file path using the passed in
                //  [sDir] and the file/foldername we just found:
                sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);
    
                //Is the entity a File or Folder?
                if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
                {
                    printf("Directory: %s\n", sPath);
                    ListDirectoryContents(sPath); //Recursion, I love it!
                }
                else{
                    printf("File: %s\n", sPath);
                }
            }
        }
        while(FindNextFile(hFind, &fdFile)); //Find the next file.
    
        FindClose(hFind); //Always, Always, clean things up!
    
        return true;
    }
    
    ListDirectoryContents("C:\\Windows\\");
    

    And now its UNICODE counterpart:

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    bool ListDirectoryContents(const wchar_t *sDir)
    { 
        WIN32_FIND_DATA fdFile; 
        HANDLE hFind = NULL; 
    
        wchar_t sPath[2048]; 
    
        //Specify a file mask. *.* = We want everything! 
        wsprintf(sPath, L"%s\\*.*", sDir); 
    
        if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE) 
        { 
            wprintf(L"Path not found: [%s]\n", sDir); 
            return false; 
        } 
    
        do
        { 
            //Find first file will always return "."
            //    and ".." as the first two directories. 
            if(wcscmp(fdFile.cFileName, L".") != 0
                    && wcscmp(fdFile.cFileName, L"..") != 0) 
            { 
                //Build up our file path using the passed in 
                //  [sDir] and the file/foldername we just found: 
                wsprintf(sPath, L"%s\\%s", sDir, fdFile.cFileName); 
    
                //Is the entity a File or Folder? 
                if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY) 
                { 
                    wprintf(L"Directory: %s\n", sPath); 
                    ListDirectoryContents(sPath); //Recursion, I love it! 
                } 
                else{ 
                    wprintf(L"File: %s\n", sPath); 
                } 
            }
        } 
        while(FindNextFile(hFind, &fdFile)); //Find the next file. 
    
        FindClose(hFind); //Always, Always, clean things up! 
    
        return true; 
    } 
     
    ListDirectoryContents(L"C:\\Windows\\");