【问题标题】:What causes WriteFile to return ERROR_ACCESS_DENIED?是什么导致 WriteFile 返回 ERROR_ACCESS_DENIED?
【发布时间】:2011-05-17 18:55:05
【问题描述】:

我们目前面临调用WriteFile(或者,更确切地说是CFile::Write - 但只是在内部调用WriteFile)导致Win32错误5ERROR_ACCESS_DENIED的问题。

(编辑:请注意,我们无法重现该行为。我们目前只有一个日志文件,指示 CFile::Write 所在的源行并包含错误 ERROR_ACCESS_DENIED!)

(编辑:该文件位于本地驱动器上,它实际上是一个文件而不是目录。)

现在,WriteFiles's documentation 并没有真正的帮助,尝试一个简单的测试应用程序会产生以下结果:

  1. WriteFile 在为未打开写入的文件句柄调用(即打开只读)时导致 ERROR_ACCESS_DENIED。
  2. 不会在以下情况下导致 ERROR_ACCESS_DENIED
    • 句柄无效或文件根本没有打开
    • 文件的访问权限写保护标志在进程打开文件后被修改。 (如果在打开文件之前修改了这些,那么我们将永远无法访问 WriteFile,因为打开文件将失败。)
    • 文件被另一个进程/句柄以某种方式锁定(这最多会导致错误32ERROR_SHARING_VIOLATION)。

这给我们留下了这样的情况,如果文件实际上是用读取标志而不是写入标志打开的,那么显然这个调用失败的唯一可能性。然而,看看我们的代码,这似乎极不可能。 (由于我们的跟踪,我们可以确定 WriteFile 失败并且我们可以确定错误是 ERROR_ACCESS_DENIED,我们不能 100.1%确定打开标志,因为这些没有被追踪出来。)

WriteFile (CFile::Write) 是否存在任何其他已知情况会导致 ERROR_ACCESS_DENIED?

注意:另外澄清这个问题的上下文:

  • 文件已打开,因此它不能是目录或类似的东西
  • 我执行的所有测试都表明,当文件打开时,它不能被删除,因此在调用 WriteFile 时该文件应该仍然存在
  • 该文件位于本地驱动器上,而不是网络驱动器上。

我应该补充一点,我们在 WIndows XP sp3 上运行,并且该应用程序是使用 Visual Studio 2005 编译的。

【问题讨论】:

  • 为什么你不能追踪开始标志?如果您不想编辑代码,只需使用进程监视器来检查它们。
  • 当然我们可以添加跟踪。这只会在客户现场偶尔发生一次。我们无法在那里添加调试器。
  • 文件系统过滤驱动程序也可能导致这种情况,最明显的例子是防病毒扫描程序(尽管还有其他的,例如加密等)。
  • 告诉您的客户停止使用 SysInternals 的 Handle 实用程序。
  • @Hans - 我们使用 Handle Utility 的客户就像修补汽车发动机内部的木匠。不太可能。 :-)

标签: c++ windows winapi visual-c++ file-io


【解决方案1】:

如果你可以调试它,你应该。可能是一百万件事:

  • msdn 错误(经常发生)
  • 某些应用程序(病毒?)正在挂钩 WriteFile 并导致不同的行为
  • 文件系统问题?
  • 您的日志记录或观察有问题

【讨论】:

  • 恕我直言,这应该是一条评论。目前无法调试问题。
【解决方案2】:

大约有十几种不同的情况可能导致 ERROR_ACCESS_DENIED。在内部,WriteFile 所做的只是调用 NtWriteFile 并将其(有点意义的)NTSTATUS 错误代码映射到意义不大的 HRESULT 中。

除其他外,ERROR_ACCESS_DENIED 可能表示文件位于网络卷上并且写入权限出现问题,或者该文件实际上不是文件而是目录。

【讨论】:

  • 该文件不在网络 volumje 上,它实际上是一个文件。
【解决方案3】:

问题是

是什么导致 WriteFile 返回 ERROR_ACCESS_DENIED?

我在问题中说明了

  1. WriteFile 将导致 ERROR_ACCESS_DENIED 如果它被调用 对于未打开的文件句柄 用于写作(即为 只读)。

在为打开的标志和另一个事件添加进一步的日志记录后,事实证明这是正确的。打开标志的日志显示,在错误点,文件对象是用 CFile::modeRead 打开的,因此我们得到了 ERROR_ACCESS_DENIED。

尚未发现导致此问题的奇怪代码路径,但这只是表明:永远不要相信自己的代码。 :-)

(哦,顺便说一句。失败的不是 ::WriteFile,而是 ::FlushFileBuffers API,但显然返回相同的错误。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多