Ivan  Silkin
Ivan Silkin

Reputation: 485

How to prevent my function from delayed deleting in RemoveDirectory() WINAPI?

How do I correct the piece of code below for it to work properly? The purpose of the function is only to delete directories and files inside of the directory.

Because when I run this function (even in a separate thread), it doesn't delete the folder passed in the first argument due to some handles existing (probably).

And Windows doesn't delete the folder until the end of the program, see code below.

How do I fix existing of handles before the RemoveDirectory is called?

I already tried to move the HANDLE variable (which is inside of the function below) out of stack when RemoveDirectory is called.

The problem is just in the delayed deleting of the folder (not other files, they delete normally).

int DeleteDirectory(const std::string &refcstrRootDirectory,
                    bool              bDeleteSubdirectories = true)
{
  bool            bSubdirectory = false;       // Flag, indicating whether
                                               // subdirectories have been found
  HANDLE          hFile;                       // Handle to directory
  std::string     strFilePath;                 // Filepath
  std::string     strPattern;                  // Pattern
  WIN32_FIND_DATA FileInformation;             // File information


  strPattern = refcstrRootDirectory + "\\*.*";
  hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
  if(hFile != INVALID_HANDLE_VALUE)
  {
    do
    {
      if(FileInformation.cFileName[0] != '.')
      {
        strFilePath.erase();
        strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

        if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          if(bDeleteSubdirectories)
          {
            // Delete subdirectory
            int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories);
            if(iRC)
              return iRC;
          }
          else
            bSubdirectory = true;
        }
        else
        {
          // Set file attributes
          if(::SetFileAttributes(strFilePath.c_str(),
                                 FILE_ATTRIBUTE_NORMAL) == FALSE)
            return ::GetLastError();

          // Delete file
          if(::DeleteFile(strFilePath.c_str()) == FALSE)
            return ::GetLastError();
        }
      }
    } while(::FindNextFile(hFile, &FileInformation) == TRUE);

    // Close handle
    ::FindClose(hFile);

    DWORD dwError = ::GetLastError();
    if(dwError != ERROR_NO_MORE_FILES)
      return dwError;
    else
    {
      if(!bSubdirectory)
      {
        // Set directory attributes
        if(::SetFileAttributes(refcstrRootDirectory.c_str(),
                               FILE_ATTRIBUTE_NORMAL) == FALSE)
          return ::GetLastError();

        // Delete directory
        if(::RemoveDirectory(refcstrRootDirectory.c_str()) == FALSE)
          return ::GetLastError();
      }
    }
  }
  return 0;
}

p.s. the piece of code was taken from here: How to delete a folder in C++?

Upvotes: 1

Views: 296

Answers (1)

Ivan  Silkin
Ivan Silkin

Reputation: 485

First of all, I apologize for asking such a misleading question but...

I have found my mistake, It is not in the function that I posted in the question.

I have a project where I used my function DirectoryExists, and there was a function from the header "opendir" (It is a portable version of linux header for Windows and there are probably WINAPI HANDLEs inside of it). And I forgot to close the directory after I've opened it to check if it exists.

bool DirectoryExists(const std::string & path)
{
    DIR *dir = opendir(path.c_str());
    if (dir) {
        return true;
    }
    else
        return false;
}

And I've corrected the error:

bool DirectoryExists(const std::string & path)
{
    DIR *dir = opendir(path.c_str());
    closedir(dir);
    if (dir) {
        return true;
    }
    else
        return false;
}

I hope that this question can help someone to understand why RemoveDirectory() could work as not expected. There could be some handles that you did not notice and It's not that clear If you're not a professional Windows programmer.

Upvotes: 1

Related Questions