为什么打开的DLL句柄不能保护文件不被移动



我刚刚遇到一个令人惊讶的错误,使用LoadLibrary API调用加载的DLL文件在加载时被重命名。显然,在一个文件上有一个打开的DLL句柄并不能阻止该文件被重命名,甚至不能阻止其移动到其他路径。但是,它受到保护,不会被删除和移动到其他磁盘。如果发生这种情况,使用DLL的程序将继续正常运行。ProcessExplorer显示DLL句柄的路径会相应更新。

这种行为不同于Windows中的普通文件句柄。例如,将打开的std::ifstream保留到同一DLL时,操作系统不再允许重命名。我觉得这种行为非常令人惊讶,想知道是否有人能对此做出解释?我特别感兴趣的是允许这样做的理由,因为我认为跟踪磁盘上的文件比将其锁定在适当位置更困难。所以操作系统可能必须积极支持这一功能,这意味着必须有一个用例来支持它?

这不是一个bug。LoadLibrary使用文件映射来访问文件。当您有一个映射到文件的分区时,它不能被删除(或移动到另一个磁盘)。似乎LoadLibrary关闭了一个文件句柄(这是不需要的),并且只使用映射部分的句柄,因此您可以自由重命名文件,但不能删除它。

另一方面,std::ifstream使用文件句柄来访问文件。并且它没有设置重命名和删除操作所需的FILE_SHARE_DELETE共享访问权限。

实际上,磁盘上没有对文件进行特殊跟踪。文件句柄指向文件,仅此而已。打开文件并获得其句柄后,可以重命名甚至删除该文件,并且您仍然可以访问该文件(如果文件已被删除,则访问权限有限,但您可以取消删除该文件并拥有完全访问权限)。

相关内容

  • 没有找到相关文章

最新更新