Enumerating Directories

Enumeration of a directory on an FTP server requires the creation of a handle by FtpFindFirstFile. This handle is a branch of the FTP session handle created by InternetConnect. FtpFindFirstFile locates the first file or directory on the server and returns it in a WIN32_FIND_DATA structure. Use InternetFindNextFile until it returns ERROR_NO_MORE_FILES. This method finds all subsequent files and directories on the server.

To determine if the file retrieved by FtpFindFirstFile or InternetFindNextFile is a directory, check the dwFileAttributes member of the WIN32_FIND_DATA structure to see if it is equal to FILE_ATTRIBUTE_DIRECTORY.

If the application makes changes on the FTP server or if the FTP server changes frequently, the INTERNET_FLAG_NO_CACHE_WRITE and INTERNET_FLAG_RELOAD flags should be set in FtpFindFirstFile. These flags ensure that the directory information being retrieved from the FTP server is current.

After the application completes the directory enumeration, the application must make a call to InternetCloseHandle on the handle created by FtpFindFirstFile. Until that handle is closed, the application cannot call FtpFindFirstFile again on the session handle created by InternetConnect. If a call to FtpFindFirstFile is made on the same session handle before the previous call to the same function is closed, the function fails, returning ERROR_FTP_TRANSFER_IN_PROGRESS.

The following example shows how to obtain a handle to the first file in the directory, enumerate the files, and close the handle.

int WINAPI DisplayDir(HWND hX, DWORD dwFlags)
{
    WIN32_FIND_DATA pDirInfo;
    HINTERNET hDir;
    DWORD dError;
    char DirList[MAX_PATH+7];
    DWORD dwTemp=MAX_PATH;
    LPDWORD temp =&dwTemp;
    LPVOID lpOption;
    DWORD dwSize;
    LPDWORD lpdwSize = &dwSize;

SendDlgItemMessage(hX,IDC_FTPList,LB_RESETCONTENT,0,0);
    if ( !(hDir = FtpFindFirstFile (hSecondary, TEXT ("*.*"), &pDirInfo,
        dwFlags, 0) ))
        if (GetLastError()  == ERROR_NO_MORE_FILES) 
        {
            MessageBox(hX,"There are no files here.","Display Dir",MB_OK);
            InternetCloseHandle(hDir);
            return 1;
        }
        else 
        {
            ErrorOut (hX, GetLastError (), "FindFirst error: ");
            InternetCloseHandle(hDir);
            return 0;
        }

        sprintf(DirList, pDirInfo.cFileName);
        if (pDirInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
            strcat(DirList," <DIR> ");
    
        SendDlgItemMessage(hX,IDC_FTPList,LB_ADDSTRING,0,(LPARAM)DirList);

    dError = NO_ERROR;
    do
    {
         if (!InternetFindNextFile (hDir, &pDirInfo))
         {
             dError = GetLastError();
             if ( dError == ERROR_NO_MORE_FILES ) 
             {
                 InternetCloseHandle(hDir);
                 return 1;
             }
             else
             {
                 ErrorOut (hX,GetLastError(), "InternetFindNextFile");
                 InternetCloseHandle(hDir);
                 return 0;
             }
         }
         else
         {
            sprintf(DirList, pDirInfo.cFileName);
            if (pDirInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
                strcat(DirList," <DIR> ");    
            SendDlgItemMessage(hX,IDC_FTPList,LB_ADDSTRING,0,
                (LPARAM)DirList);
         }
    }

    if (!InternetCloseHandle(hDir) )
    {
        InternetCloseHandle(hDir);
        ErrorOut (hX,GetLastError(), "InternetCloseHandle error");
        return 0;
    }
    else
        return 1;

}

See Also

FTP Sessions | Windows Internet Services (WinInet)

Last updated on Wednesday, April 13, 2005

© 2005 Microsoft Corporation. All rights reserved.