【问题标题】:CreateFile always returns error 5 (Access is denied) when trying to open directory for reading尝试打开目录进行读取时,CreateFile 总是返回错误 5(访问被拒绝)
【发布时间】:2019-07-11 20:59:33
【问题描述】:

我想打开目录句柄,以便我可以查看该目录的文件更改。我已经在 winapi 上编写了一个简单的类包装器,这就是我在开始监视之前设置目录路径的方式:

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;
  }
}

错误总是:

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

我尝试了不同卷上的不同文件夹,看看这是否是一个实际的权限问题,但看起来不像。我电脑中的D:\tools 是一个普通文件夹,所有用户都可以访问。但正如我所说,我也尝试了其他文件夹,错误总是一样的。

我还尝试使用FILE_LIST_DIRECTORY(我只需要目录列表)和GENERIC_READ 打开。错误还是一样。

可能CreateFile 参数有误?

【问题讨论】:

  • FindFirstChangeNotification 没有文件句柄,你想做什么?
  • 您是否尝试过使用 CreateFile “打开”目录句柄的一个强制标志?即FILE_FLAG_BACKUP_SEMANTICSCreateFile 清楚地记录了这一点:“您必须设置此标志才能获得目录句柄。目录句柄可以传递给某些函数而不是文件句柄。”。没关系;我怀疑目录句柄获取是看起来是 XY 问题的 Y。
  • 因为win32错误非常糟糕的设计。你没有被拒绝访问。如果打电话给RtlGetLastNtStatus(),你会得到STATUS_FILE_IS_A_DIRECTORY。因为你没有添加FILE_FLAG_BACKUP_SEMANTICS。只需win32将STATUS_FILE_IS_A_DIRECTORY转换为ERROR_ACCESS_DENIED
  • @AlanBirtles FindFirstChangeNotification 功能不够,比较 ReadDirectoryChangesW。不得使用

标签: c++ winapi createfile


【解决方案1】:

不要使用 FILE_ATTRIBUTE_NORMAL!

要使用 CreateFile 打开目录,请使用 FILE_FLAG_BACKUP_SEMANTICS 而不是 FILE_ATTRIBUTE_NORMAL

您应该在dwFlagsAndAttributes 参数中指定FILE_FLAG_BACKUP_SEMANTICS

现在应该可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    相关资源
    最近更新 更多