CreateFile always returns error 5 (Access is denied) when trying to open directory for reading
Asked Answered
P

1

3

I want to open directory handle so that I can watch that directory for file changes. I have written a simple class wrapper over the winapi, and this is how I set the directory path before starting the watch:

bool SetDirectory(const std::string& dirname)
{
  HANDLE dirHandleNew = CreateFile(
    dirname.c_str(),
    // Just normal reading
    FILE_GENERIC_READ,
    // Share all, do not lock the file
    FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL
  );

  if (INVALID_HANDLE_VALUE != dirHandleNew)
  {
    _dirHandle = dirHandleNew;
    return true;
  }
  else
  {
    _dirHandle = 0;
    RLog("Cannot open directory %s for filesystem watching. Win error: %d (%s)", dirname.c_str(), GetLastError(), GetLastErrorAsString().c_str());
    return false;
  }
}

The error is always:

Cannot open directory D:\tools for filesystem watching. Win error: 5 (Access is denied.)

I tried different folders on different volumes to see if this is an actual permissions issue, but it doesn't seem like it. D:\tools in my PC is a normal folder, accessible to all users. But as I said, I tried other folders too, error is always the same.

I also tried to instead open with FILE_LIST_DIRECTORY (I only need dir listing) and GENERIC_READ. Error was still the same.

Maybe the CreateFile parameters are wrong?

Phocomelia answered 11/7, 2019 at 10:21 Comment(6)
FindFirstChangeNotification doesn't take a file handle, what are you trying to do?Smile
Possible duplicate of How do I make my program watch for file modification in C++?Smile
Did you try the one mandatory flag for "opening" a directory handle with CreateFile ? Namely FILE_FLAG_BACKUP_SEMANTICS ? CreateFile clearly documents this: "You must set this flag to obtain a handle to a directory. A directory handle can be passed to some functions instead of a file handle.". Not that it matters; I suspect a directory handle acquisition is the Y of what appears to be an XY problem.Berfield
because win32 errors very bad design. you not got access denied. you got STATUS_FILE_IS_A_DIRECTORY if call RtlGetLastNtStatus(). because you not add FILE_FLAG_BACKUP_SEMANTICS. simply win32 convert STATUS_FILE_IS_A_DIRECTORY to ERROR_ACCESS_DENIEDUnbraid
@AlanBirtles FindFirstChangeNotification not enough functional, compare ReadDirectoryChangesW. must not be usedUnbraid
@AlanBirtles Thi is not a duplicate of the linked question at all. As you observed yourself, in this question I am concerned about opening the directory, not watching the files. RbMm's comments are correct.Arsyvarsy
C
4

Don't use FILE_ATTRIBUTE_NORMAL!

To open a directory with CreateFile, Use FILE_FLAG_BACKUP_SEMANTICS instead of FILE_ATTRIBUTE_NORMAL.

You should specify FILE_FLAG_BACKUP_SEMANTICS in the dwFlagsAndAttributes parameter.

This should work now.

Chaworth answered 11/7, 2019 at 12:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.