windows 是什么导致 WriteFile 返回 ERROR_ACCESS_DENIED?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4312568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:42:02  来源:igfitidea点击:

What causes WriteFile to return ERROR_ACCESS_DENIED?

c++windowswinapivisual-c++file-io

提问by Martin Ba

We currently face the problem of a call to WriteFile(or, rather CFile::Write - but that just calls WriteFile internally) causing the Win32 error 5ERROR_ACCESS_DENIED.

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

(EDIT: Note that we can't repro the behavior. All we have at the moment is a logfile indicating the source line where the CFile::Write was and containing as error ERROR_ACCESS_DENIED!)

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

(EDIT: The file is on a localdrive and it is in fact a file and not a directory.)

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

Now, WriteFiles's documentationdoesn't really help, and experimenting with a simple test-app yields the following results:

现在,WriteFiles 的文档并没有真正的帮助,用一个简单的测试应用程序进行试验会产生以下结果:

  1. WriteFile willcause ERROR_ACCESS_DENIED if it is called for a file handle that is not opened for writing (i.e. is opened for reading only).
  2. It will notcause ERROR_ACCESS_DENIED if
    • The handle is not valid or the file isn't open at all
    • The access rights, or the write protected flagfor the file are modified afterthe file has been opened by the process. (If these are modified beforethe file is opened, then we never get to WriteFile because opening the file will fail.)
    • The file is somehow locked by another process/handle (This will at best result in error 32ERROR_SHARING_VIOLATION).
  1. 如果为未为写入而打开的文件句柄调用WriteFile导致 ERROR_ACCESS_DENIED(即为只读而打开)。
  2. 不会导致ERROR_ACCESS_DENIED如果
    • 句柄无效或文件根本没有打开
    • 文件的访问权限写保护标志在进程打开文件后被修改。(如果打开文件之前修改了这些,那么我们永远不会到达 WriteFile 因为打开文件会失败。)
    • 该文件以某种方式被另一个进程/句柄锁定(这最多会导致错误32ERROR_SHARING_VIOLATION)。

That leaves us with the situation, that apparently the only possibility for this call to fail if the file was actually opened with the read flag instead of the write flag. However, looking at our code, this seems extremely unlikely. (Due to our tracing, we canbe sure that WriteFile failed and we canbe sure that the error is ERROR_ACCESS_DENIED, we cannot be 100.1% sure of the opening flags, because these are not traced out.)

这给我们留下了这种情况,如果文件实际上是使用读取标志而不是写入标志打开的,那么显然这是此调用失败的唯一可能性。然而,看看我们的代码,这似乎不太可能。(由于我们的跟踪,我们可以确信的WriteFile失败,我们可以肯定的是,错误是ERROR_ACCESS_DENIED,我们不能肯定的开幕标志100.1%,因为这些不被描绘出。)

Are there any other known circumstances where WriteFile (CFile::Write) would cause an ERROR_ACCESS_DENIED?

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

Note: To additionally clarify the context of this question:

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

  • The file was open, therefore it can't be a directory or somesuch
  • All tests I performed indicate that while the file is open it cannot be deleted, so the file should still have been there on the call to WriteFile
  • The file is located on a local drive and not on a network drive.
  • 该文件已打开,因此它不能是目录或类似内容
  • 我执行的所有测试都表明,当文件打开时无法删除,因此在调用 WriteFile 时该文件应该仍然存在
  • 该文件位于本地驱动器而不是网络驱动器上。

I should add that we're running on WIndows XP sp3 and the app is compiled with Visual Studio 2005.

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

采纳答案by Martin Ba

The question was

问题是

What causes WriteFile to return ERROR_ACCESS_DENIED?

是什么导致 WriteFile 返回 ERROR_ACCESS_DENIED?

and I stated in the question

我在问题中说

  1. WriteFile will cause ERROR_ACCESS_DENIED if it is called for a file handle that is not opened for writing (i.e. is opened for reading only).
  1. 如果为未为写入而打开的文件句柄调用 WriteFile 将导致 ERROR_ACCESS_DENIED(即为只读而打开)。

After adding further logging for the open flags and another incident, it turns out this was correct. The logging for the open flags shows that at the point of error, the file object was opened with CFile::modeRead and therefore we got ERROR_ACCESS_DENIED.

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

Haven't found out yet which weird code path leads to this, but this just goes to show: Never trust your own code. :-)

还没有发现哪个奇怪的代码路径导致了这个,但这只是表明:永远不要相信你自己的代码。:-)

(Oh, and btw. It wasn't ::WriteFilethat failed, but the ::FlushFileBuffersAPI, but apparently that returns the same error.)

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

回答by Eugene Smith

There is about a dozen different situations that might result in ERROR_ACCESS_DENIED. Internally, all WriteFile does is call NtWriteFile and map its (somewhat meaningful) NTSTATUS error code into a less meaningful HRESULT.

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

Among other things, ERROR_ACCESS_DENIED could indicate that the file is on a network volume and something went wrong with write permissions, or that the file is really not a file but a directory.

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

回答by tenfour

if you can debug it, you should. it could be a million things:

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

  • msdn is wrong (it happens a lot)
  • some app (virus?) is hooking WriteFile and causing different behavior
  • filesystem problem?
  • something wrong in your logging, or observations
  • msdn 是错误的(它经常发生)
  • 某些应用程序(病毒?)正在挂钩 WriteFile 并导致不同的行为
  • 文件系统问题?
  • 您的日志记录或观察中出现问题