创建文件FILE_FLAG_DELETE_ON_CLOSE在关闭任何句柄后失败
CreateFile FILE_FLAG_DELETE_ON_CLOSE fails after any handle has been closed
我们创建一个用作内存映射文件的文件。
我们以GENERIC_READ | GENERIC_WRITE
开场我们使用与FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
共享我们使用文件属性FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE
我们成功创建文件。我们可以根据需要使用相同的标志多次重新打开它。
关闭一个句柄后,我们无法再打开任何句柄,它会返回ERROR_ACCESS_DENIED。我们可以通过关闭任何句柄来引起这种情况,第一个来自 CreateFile(ALWAYS_CREATE),或者来自 CreateFile(OPEN_EXISTING) 的其他句柄。
有什么办法可以避免这种情况吗?我们使用 memoryMappedFile 作为必须共享资源的不同进程之间的通信。这些进程有时会启动和停止。现在,一旦我们关闭一个句柄,我们就无法打开内存映射文件。
我尝试将打开的调用更改为使用 FILE_ATTRIBUTE_NORMAL,因此只有创建调用使用 CLOSE_ON_DELETE但这对这种情况没有影响。
您遇到的问题是,一旦关闭了使用 FILE_FLAG_DELETE_ON_CLOSE
打开的文件句柄,操作系统将不再允许创建新句柄。
血腥的细节:当为打开的关闭时删除的文件处理IRP_MJ_CLEANUP
(这就是发生句柄关闭的情况),Windows 文件系统将在文件对象上设置一个内部标志,指示它正在出路。 随后对文件的打开尝试将失败,并显示 STATUS_DELETE_PENDING
,Win32 子系统将映射到您看到的 Win32 ERROR_ACCESS_DENIED
代码。
对于您的用例,您可能需要考虑使用命名共享内存 (MSDN) 模式。 基本上,让操作系统管理共享内存的空间。 只需确保应用适当的安全属性,就可以开始了。
事实证明,令人尊敬的Raymond Chen在他的Microsoft开发博客The Old New Thing上回复了这个问题。Bukes是正确的,但作为替代方案,正如Raymond在他的文章中所说:
看起来他们真的希望文件保持有效(包括允许进一步的 CreateFile 调用成功),只要任何打开的句柄继续引用该文件。幸运的是,客户只需要句柄来创建内存映射视图。文件指针并不重要。因此,客户可以使用 DuplicateHandle 而不是 CreateFile 来获取文件的其他句柄。由于所有句柄都引用同一个文件对象,因此在关闭所有句柄之前,文件对象不会删除该文件。
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- 如何获取边缘窗口句柄 (HWND)?
- 枚举进程模块在有效句柄上返回无效句柄
- 在 c/c++ 中打开 PhysicalDrive 的句柄并写入 MBR 的 linux 等效是什么?
- 从运行服务的应用程序代码中提取窗口句柄
- 在读取文件后重置句柄
- 是否有像地图这样的C++结构,但我得到的不是值的键,而是值的句柄?
- Microsoft ODBC 无法创建有效的句柄
- 我是否可以使用 win32 句柄以编程方式记录发送到/接收到 USB/COM 的内容
- 获取特定进程的句柄数
- C++ 创建 NdisProt 驱动程序的句柄
- 是否需要关闭来自 WinHTTP 异步的句柄?
- 句柄OK全部崩溃
- 我需要通过窗口句柄(HWND)获取文件,我该怎么办?
- 什么是 C# 等同于C++句柄
- 未知C++错误:致命错误:glibc检测到无效的stdio句柄
- 获取现有进程句柄
- GetModuleHandle() 无法检索由 "notepad.exe" 加载的"advapi32.dll"的句柄
- 创建文件FILE_FLAG_DELETE_ON_CLOSE在关闭任何句柄后失败
- 是否有任何已实现的 RAII 文件句柄