I just had a surprising bug where a DLL file that was loaded using the LoadLibrary
API call was renamed while being loaded. Apparently, having an open DLL handle on a file does not prevent that file from being renamed, or even moved to a different path. It is however protected from deletion and being moved to a different disk. The program using the DLL continues to work fine if this happens. ProcessExplorer shows that the path of the DLL handle updates accordingly.
This behavior is different from ordinary file handles in Windows. For example, when keeping an open std::ifstream
to the same DLL, renaming is no longer allowed by the operating system. I find this behavior quite surprising and was wondering if anyone could give an explanation for it? In particular I'd be interested in the rationale for allowing this, as I'd imagine the tracking of the file on disk to be more difficult than just locking it in place. So the OS probably has to actively support this feature, which means there has to be a use case for it?
It is not a bug. LoadLibrary
uses File Mapping to access a file. While you have a mapped section to a file it cannot be deleted (or moved to another disk). It seems that LoadLibrary
closes a file handle (it's not needed) and uses only a handle to the mapped section so you can freely rename the file but cannot delete it.
On the other hand std::ifstream
uses a file handle to access a file. And it doesn't set FILE_SHARE_DELETE
share access that is required for rename and delete operations.
Actually there is no special tracking of a file on the disk. A file handle points to the file and that's all. After you have opened a file and got its handle the file can be renamed or even deleted and you still have an access to that file (a limited access if the file has been deleted, but you can undelete the file and have a full access).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With