Solved

FtpFindFirstFile problem

Posted on 2000-04-15
8
496 Views
Last Modified: 2013-12-03
Im writing my own little automatic FTP program that will backup web sites.  Im using the WinInet API.  I created a function which utilizes FtpFindFirstFile() & InternetFindNextFile().  This function gets called recursively whenever it find a subdirectory.  The biggest problem im having is when I try to traverse a directory tree using FtpFindFirstFile() & InternetFindNextFile().  When the code detects a subdirectory and I call my function recurses, I have to call FtpFindFirstFile() again inside of that recursive call.  In order for that to work, I needed to have closed the hFind in the calling function.  When the recursive function returns, I find myself having to call FtpFindFirstFile() again in the calling function in which it simply finds the same folder again.  An endless loop.  

I can't seem to figure a way around it.  Does anyone have any good code snippets or ideas for traversing a tree using WinInet FTP functions?

Thanks for the help,
-Dan  
0
Comment
Question by:dmaroff
8 Comments
 
LVL 23

Expert Comment

by:chensu
Comment Utility
Look into the following sample. It uses MFC, but you can definitely get the idea.

FTPTREE: Displays the Structure and Content of an FTP Site
http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/devprods/vs6/visualc/vcsample/_sample_mfc_ftptree.htm
0
 

Author Comment

by:dmaroff
Comment Utility
I've seen this code already. The program is designed to be a bit different than mine.  The way that code works is it displays all of the files and folders in breadth order.  In other words it displays all of the files and folders in a root folder, then when you click a folder, it just does another search on that folder by issuing a FindFirstFile for that folder and so on.  

According to this code I'd have to keep a list of all the subfolders Ive seen in a given folder before I dive into one of those subfolders.  This way when I pop back up to that folder, I have a list of folders to go to without reissuing the search on that folder again.  


In other words if the tree looks like this:

\MainFolder
  - File1a
  - Folder1a
      - File1b
      - File2b
      - File3b
  - File2a
  - Folder2a
  - Folder3a

Id first use FindFirstFile() in Mainfolder which will traverse all of the files and folders of MainFolder.  As I do that, Id push all of the folders found (Folder1a, Folder2a, and Folder3a) onto a list.  

Once thats done I'd then dive into the first folder in my list (Folder1a), traverse that folder and when finished, pop back up to MainFolder.  At this point instead of doing a FindFirstFile() again, Id just go to the next folder in the list (Folder2a) and dive into that folder, and so on.  

This avoids having to use FindFirstFile() more than once on a folder, because each folder will have a list of its subfolders.   Thats the only way I can think of doing it.


Im trying to avoid that technique if possible.  If there is no way around it I guess I'll have to do that.  If you know another way that would be great.


Thanks,
-Dan
0
 
LVL 2

Expert Comment

by:xLs
Comment Utility
maybe this will give you an idea

this is just some semipseudo code for doing your list recursivly.

int ListFiles(char* root,filelist* list)
{

   SFILE filestruct;
   DFile data;
   int count = 0;
   FindFirstFile(root,filestruct);
   while(FindNextFile(filestruct,data))
   {
      if(data.type == DIRECTORY)
       count =+ListFiles(data.name,list);
     else
        {
       list.insert(data);
        count++;
        }
   }

 return count;
}


no idea if you want it that way, but could be useful :)

cheers
0
 

Author Comment

by:dmaroff
Comment Utility
Thanks, as a matter of fact I did finish it.  I used an STL list which came in real handy.  I pretty much did it the same way you did.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Accepted Solution

by:
pThread earned 100 total points
Comment Utility
Try this code, I had the same problem and I fixed it with this.  I added in an STL list for you.

Good luck.


void BeginBackup(HANDLE& hConnect, char* remDir)
{
      DWORD size = MAX_PATH;
      
      WIN32_FIND_DATA remData;

      /* Files modification times */
      FILETIME locModified, a, b;
      
      /* Tests if file exists */
      HANDLE hFile;

      /* enumerates all files in a directory */
      HINTERNET hFind;

      /* Keeps track of paths used in directory searches */
      char fullPath[MAX_PATH];
      char parentDir[MAX_PATH];

      /* An STL list used to store enumerated directories */
      list <string> l;
      list <string>::iterator i;
      const char* path;
      
      /* Get the local working directory */
      GetCurrentDirectory(255, parentDir);
      
      /* Find the first file in a directory */
      hFind = FtpFindFirstFile(hConnect, NULL, &remData, NULL, NULL);


      /* If we locate a directory, add it to our list of
            directories that we will latere search */
      if(remData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
            
            /* Add directory to the list here */
            l.push_back(remData.cFileName);
      }

      /* Get the file if it doesn't exist or if file modified time is greater
         than the local file */
      else {
            sprintf(fullPath, "%s\\%s", parentDir, remData.cFileName);
            hFile = CreateFile(fullPath, GENERIC_READ , NULL, NULL, OPEN_EXISTING, NULL, NULL);
            
            if(GetFileTime(hFile, &a, &b, &locModified)) {      
                  if (CompareFileTime(&locModified, &remData.ftLastWriteTime) == -1) {
                        FtpGetFile(hConnect, remData.cFileName, remData.cFileName,
                        FALSE, NULL, FTP_TRANSFER_TYPE_BINARY , NULL);
                  }
            }
            else {
                        FtpGetFile(hConnect, remData.cFileName, remData.cFileName,
                                            FALSE, NULL, FTP_TRANSFER_TYPE_BINARY , NULL);
            }
            CloseHandle(hFile);
      }
            

      /* Search through the rest of the directory */
      while(InternetFindNextFile(hFind, &remData)) {
                        
            /* If we locate a directory, set it as current
            and search that directory using a recursive call */
            if(remData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
                  
                  /* Add directory to the list */
                  l.push_back(remData.cFileName);
            }
            /* If its a file, get it. */
            else {
                  sprintf(fullPath, "%s\\%s", parentDir, remData.cFileName);
                  hFile = CreateFile(fullPath, GENERIC_READ , NULL,
                                                       NULL, OPEN_EXISTING, NULL, NULL);
            
                  if(GetFileTime(hFile, &a, &b, &locModified)) {      
                        if (CompareFileTime(&locModified, &remData.ftLastWriteTime) == -1) {
                              FtpGetFile(hConnect, remData.cFileName, remData.cFileName,
                                                  FALSE, NULL, FTP_TRANSFER_TYPE_BINARY , NULL);
                        }
                  }
                  else {
                        FtpGetFile(hConnect, remData.cFileName, remData.cFileName,
                                                  FALSE, NULL, FTP_TRANSFER_TYPE_BINARY , NULL);
                  }
                  CloseHandle(hFile);
            }      

      }
      InternetCloseHandle(hFind);

      /* Traverse list of directories and dive into them */
      for(i = l.begin(); i != l.end(); ++i) {
            path = (*i).c_str();
            sprintf(fullPath, "%s\\%s", parentDir, path);
            
            if (!SetCurrentDirectory(fullPath)) {
                        CreateDirectory(fullPath, NULL);
                        SetCurrentDirectory(fullPath);
            }
            
            FtpSetCurrentDirectory(hConnect, path);
            BeginBackup(hConnect, (char*)path);
            FtpSetCurrentDirectory(hConnect, "..");
      }
0
 

Author Comment

by:dmaroff
Comment Utility
Thanks, even though I finished it you did give me a few new ideas.

-Dan
0
 
LVL 2

Expert Comment

by:xLs
Comment Utility
just as a tip, try use vector<string> instead of list (list tends to have some allocation problems among other). you will not need to change your code that way anyway.
0
 

Author Comment

by:dmaroff
Comment Utility
Ok, I'll do that.

Thanks,
-Dan
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now