none
What am I missing... RRS feed

  • Question

  • I found the web site http://www.codeproject.com/KB/files/Folder_Utility.aspx that has a useful function EmptyDirectory, the idea of this function is  to delete everything within a folder/directory provided it's given the path. The code works I've tested it, however it's not working when I pass a variable to it that contains the path to Temporary Internet Files. The code ...

     

    void EmptyDirectory(char* folderPath){
     char fileFound[256];
     WIN32_FIND_DATA info;
     HANDLE hp; 
     sprintf(fileFound, "%s\\*.*", folderPath);
     hp = FindFirstFile(fileFound, &info);
     do
      {
        if (!((strcmp(info.cFileName, ".")==0)||
           (strcmp(info.cFileName, "..")==0)))
        {
         if((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==
                       FILE_ATTRIBUTE_DIRECTORY)
         {
           string subFolder = folderPath;
           subFolder.append("\\");
           subFolder.append(info.cFileName);
           EmptyDirectory((char*)subFolder.c_str());
           RemoveDirectory(subFolder.c_str());
         }
         else
         {
           sprintf(fileFound,"%s\\%s", folderPath, info.cFileName);
           BOOL retVal = DeleteFile(fileFound);
         }
        }
     
      }while(FindNextFile(hp, &info)); 
     FindClose(hp);
    }
    
    int main(){
      char buf[MAX_PATH];
      SHGetFolderPath(0,CSIDL_INTERNET_CACHE,0,0,buf);
      cout << buf << endl;
      EmptyDirectory(buf);
      return 0;
    }
    buf returns C:\Users\Owner\AppData\Local\Microsoft\Windows\Temporary Internet Files when I cout it so I'm thinking that's what EmptyDirectory see's as well when it processes it. But if you look at the first sprintf function it prints "\\" to fileFound buffer. But I would understand if you needed to provide the path in that format, I just don't know what I'm missing to do this. Any suggestions? Thanx.

    Wednesday, November 17, 2010 10:39 PM

Answers

  • A few things to be suspicious of:  First of all make sure that you have access to actually delete all the files in that folder.

    Second:  Getting "\\" written in your sprintf statement is also very fishy -- even if you passed an empty string to EmptyDirectory, you would get "\\*.*" written.

    I would put a breakpoint on that line of code (the sprintf) and note the contents of fileFound before the call and after.  Also note the value of folderPath at that point.

    Thursday, November 18, 2010 1:41 AM
  • >it's not working when I pass a variable to it that
    >contains the path to Temporary Internet Files.

    Which version of Windows are you running this under?
    XP? Vista? 7? Other?

    What privileges do you have when running it? Admin?

    Note that the Temporary Internet Files directory may
    have the System attribute set, may be a subdirectory
    of a directory which has the Hidden attribute set,
    may contain subdirectories and/or files which have
    the System and/or Hidden attributes set, etc. All
    of which may prevent or restrict attempts to alter
    or delete.

    >if you look at the first sprintf function it prints "\\"
    >to fileFound buffer.

    How and when are you checking the contents of the variables?
    Keep in mind that this function (EmptyDirectory) uses
    recursion - it calls itself. So what you see for a given
    variable in the debugger will depend on what level you
    are at in the recursion tree. I agree with Simon that
    seeing just a double backslash here is "fishy". You would
    see "\*.*" for an empty string (the doubled slashes are in
    the source code only).

    - Wayne
    Thursday, November 18, 2010 6:07 AM

All replies

  • A few things to be suspicious of:  First of all make sure that you have access to actually delete all the files in that folder.

    Second:  Getting "\\" written in your sprintf statement is also very fishy -- even if you passed an empty string to EmptyDirectory, you would get "\\*.*" written.

    I would put a breakpoint on that line of code (the sprintf) and note the contents of fileFound before the call and after.  Also note the value of folderPath at that point.

    Thursday, November 18, 2010 1:41 AM
  • >it's not working when I pass a variable to it that
    >contains the path to Temporary Internet Files.

    Which version of Windows are you running this under?
    XP? Vista? 7? Other?

    What privileges do you have when running it? Admin?

    Note that the Temporary Internet Files directory may
    have the System attribute set, may be a subdirectory
    of a directory which has the Hidden attribute set,
    may contain subdirectories and/or files which have
    the System and/or Hidden attributes set, etc. All
    of which may prevent or restrict attempts to alter
    or delete.

    >if you look at the first sprintf function it prints "\\"
    >to fileFound buffer.

    How and when are you checking the contents of the variables?
    Keep in mind that this function (EmptyDirectory) uses
    recursion - it calls itself. So what you see for a given
    variable in the debugger will depend on what level you
    are at in the recursion tree. I agree with Simon that
    seeing just a double backslash here is "fishy". You would
    see "\*.*" for an empty string (the doubled slashes are in
    the source code only).

    - Wayne
    Thursday, November 18, 2010 6:07 AM
  • Wow, what a horrible function! Uses char, not TCHAR? A massive no-no since, I dunno, 1995? Uses fileFound[256] (a hard-coded constant), when appropriate #define coming from the SDK exist? Another no-no. Calls system APIs (RemoveDirectory and DeleteFile) without ever checking returned result? Another massive error. Uses sprintf on a char* passed effectively as an input? Bzzzzzzt, wrong , in both style and good practices! And finally, it's not exception-safe: use of std::string can cause exceptions, e.g. bad_alloc/CMemoryException, which, if happen, will leak hp; but that's the least of problems.

    People really should abstain from putting such code on the Internet. Also, codeproject should have better moderation, so that such code doesn't go through even if people want it out.

    That said, try debugging with these changes:

    void StupidCheck(BOOL b)

    { // Don't put this in production!

       if (!b)

    {

      DWORD err = GetLastError();

      ASSERT(FALSE);

    }

    and then change to:

    StupidCheck(RemoveDirectory(subFolder.c_str()));

    and

    StupidCheck(DeleteFile(fileFound));

    Then, while in debugging, inspect err, stack and other variables when ASSERT fires.

    Goran.

    Thursday, November 18, 2010 7:40 AM