Pourquoi une DLL ouverte ne protège-t-elle pas le fichier d’être déplacé?

J’ai juste eu un bogue surprenant où un fichier DLL chargé à l’aide de l’appel de l’API LoadLibrary été renommé pendant son chargement. Apparemment, avoir un handle de DLL ouvert sur un fichier n’empêche pas ce fichier d’être renommé, ou même déplacé vers un chemin différent. Il est toutefois protégé contre la suppression et déplacé sur un autre disque. Le programme utilisant la DLL continue de fonctionner correctement si cela se produit. ProcessExplorer montre que le chemin de la DLL gère les mises à jour en conséquence.

Ce comportement est différent des descripteurs de fichiers ordinaires dans Windows. Par exemple, lors de la conservation d’un std::ifstream sur la même DLL, le renommage n’est plus autorisé par le système d’exploitation. Je trouve ce comportement assez surprenant et je me demandais si quelqu’un pouvait l’expliquer? En particulier, je serais intéressé par la justification de cette autorisation, car j’imagine que le suivi du fichier sur disque est plus difficile que de le verrouiller. Donc, le système d’exploitation doit probablement supporter activement cette fonctionnalité, ce qui signifie qu’il doit y avoir un cas d’utilisation pour cela?

Ce n’est pas un bug. LoadLibrary utilise le mappage de fichiers pour accéder à un fichier. Lorsque vous avez une section mappée dans un fichier, elle ne peut pas être supprimée (ou déplacée sur un autre disque). Il semble que LoadLibrary ferme un handle de fichier (il n’est pas nécessaire) et utilise uniquement un handle vers la section mappée pour que vous puissiez librement renommer le fichier mais ne pouvez pas le supprimer.

std::ifstream utilise un handle de fichier pour accéder à un fichier. Et il ne définit pas l’access au partage FILE_SHARE_DELETE requirejs pour les opérations de renommage et de suppression.

En fait, il n’y a pas de suivi spécial d’un fichier sur le disque. Un handle de fichier pointe vers le fichier et c’est tout. Après avoir ouvert un fichier et obtenu son nom, le fichier peut être renommé, voire supprimé, et vous avez toujours access à ce fichier (access limité si le fichier a été supprimé, mais vous pouvez annuler la suppression du fichier et avoir un access complet). .