C++ 是什么导致WriteFile返回错误\u访问被拒绝?

C++ 是什么导致WriteFile返回错误\u访问被拒绝?,c++,windows,winapi,visual-c++,file-io,C++,Windows,Winapi,Visual C++,File Io,我们目前面临的问题是调用WriteFile(或者更确切地说是CFile::Write-但这只是在内部调用WriteFile)导致Win32错误5错误\u访问被拒绝 (编辑:请注意,我们无法重新设置该行为。目前我们只有一个日志文件,指示CFile::Write所在的源代码行,并包含作为错误的\u访问\u拒绝!) (编辑:文件位于本地驱动器上,实际上是一个文件而不是目录。) 现在,这并没有真正的帮助,使用一个简单的测试应用程序进行实验会得到以下结果: 如果调用WriteFile的文件句柄不是为写入而

我们目前面临的问题是调用
WriteFile
(或者更确切地说是CFile::Write-但这只是在内部调用WriteFile)导致Win32错误
5
错误\u访问被拒绝

(编辑:请注意,我们无法重新设置该行为。目前我们只有一个日志文件,指示CFile::Write所在的源代码行,并包含作为错误的\u访问\u拒绝!)

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

现在,这并没有真正的帮助,使用一个简单的测试应用程序进行实验会得到以下结果:

  • 如果调用WriteFile的文件句柄不是为写入而打开(即仅为读取而打开),则WriteFile将导致错误\访问\拒绝
  • 如果出现以下情况,将导致错误\u访问\u被拒绝
    • 句柄无效或文件根本未打开
    • 进程打开文件后,将修改文件的访问权限或写保护标志。(如果这些文件在打开文件之前被修改,那么我们将永远无法获得WriteFile,因为打开文件将失败。)
    • 文件被另一个进程/句柄以某种方式锁定(这最多会导致错误
      32
      error\u SHARING\u违规)
  • 这就给我们留下了这样的情况,如果文件实际上是用读标志而不是写标志打开的,那么这显然是这个调用失败的唯一可能性。然而,看看我们的代码,这似乎是极不可能的。(由于我们的跟踪,我们可以确定WriteFile失败,并且我们可以确定错误为error\u ACCESS\u DENIED,我们无法100.1%确定打开标志,因为这些标志没有被跟踪出来。)

    是否存在其他已知情况下WriteFile(CFile::Write)会导致错误\u访问被拒绝

    注意:为了进一步澄清此问题的背景:

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

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

    如果您可以调试它,您应该这样做。这可能是一百万件事:

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

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

    除此之外,ERROR\u ACCESS\u DENIED可能表示该文件位于网络卷上,并且写入权限出现问题,或者该文件实际上不是一个文件,而是一个目录。

    问题是

    是什么导致WriteFile返回 错误\u访问\u被拒绝

    我在问题中说

  • WriteFile将导致 错误\u访问\u如果被调用,则被拒绝 对于未打开的文件句柄 用于写作(即,为 只读)
  • 在为打开标志和另一个事件添加进一步的日志记录之后,结果证明这是正确的。打开标志的日志记录显示,在出现错误时,文件对象是用CFile::modeRead打开的,因此我们得到了错误\u访问\u拒绝

    我还没有发现是哪条奇怪的代码路径导致了这种情况,但这正好说明:永远不要相信自己的代码。:-)


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

    为什么不能跟踪开始标志?如果您不想编辑代码,只需使用进程监视器来检查它们。当然,我们可以添加跟踪。这只在客户站点偶尔发生一次。我们不可能在那里添加调试器。文件系统筛选器驱动程序也可能导致这种情况,最明显的例子是防病毒扫描程序(尽管还有其他一些,如加密等)。告诉您的客户停止使用SysInternals的Handle实用程序。@Hans-我们的客户使用Handle实用程序就像木匠在修补汽车发动机的内部部件一样。不太可能。:-)嗯,这应该是一个评论。此时无法调试该问题。该文件不在网络卷上,实际上是一个文件。