【发布时间】:2011-05-17 18:55:05
【问题描述】:
我们目前面临调用WriteFile(或者,更确切地说是CFile::Write - 但只是在内部调用WriteFile)导致Win32错误5ERROR_ACCESS_DENIED的问题。
(编辑:请注意,我们无法重现该行为。我们目前只有一个日志文件,指示 CFile::Write 所在的源行并包含错误 ERROR_ACCESS_DENIED!)
(编辑:该文件位于本地驱动器上,它实际上是一个文件而不是目录。)
现在,WriteFiles's documentation 并没有真正的帮助,尝试一个简单的测试应用程序会产生以下结果:
- WriteFile 将在为未打开写入的文件句柄调用(即打开只读)时导致 ERROR_ACCESS_DENIED。
- 它将不会在以下情况下导致 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