2013-07-22 15 views
5

Właśnie miałem zaskakujący błąd, w którym plik DLL, który został załadowany przy użyciu połączenia API LoadLibrary, został zmieniony podczas ładowania. Wygląda na to, że posiadanie otwartego uchwytu DLL w pliku nie zapobiega zmianie nazwy tego pliku ani nawet przeniesieniu go do innej ścieżki. Jest jednak chroniony przed usunięciem i przenoszony na inny dysk. Program używający biblioteki DLL nadal działa dobrze, jeśli tak się stanie. ProcessExplorer pokazuje, że ścieżka uchwytu DLL jest odpowiednio aktualizowana.Dlaczego otwarty uchwyt DLL nie chroni pliku przed przeniesieniem?

To zachowanie różni się od zwykłych uchwytów plików w systemie Windows. Na przykład, przy zachowaniu otwartego std::ifstream dla tej samej biblioteki DLL, zmiana nazwy nie jest już dozwolona przez system operacyjny. Uważam, że to zachowanie jest dość zaskakujące i zastanawiałem się, czy ktoś mógłby podać wyjaśnienie tego? W szczególności byłbym zainteresowany racjonalnym uzasadnieniem tego, ponieważ wyobrażam sobie, że śledzenie pliku na dysku jest trudniejsze niż samo zablokowanie go na miejscu. Więc system operacyjny prawdopodobnie musi aktywnie wspierać tę funkcję, co oznacza, że ​​musi to być przypadek użycia?

Odpowiedz

6

To nie jest błąd. LoadLibrary używa File Mapping, aby uzyskać dostęp do pliku. Chociaż masz zmapowaną sekcję do pliku, nie można go usunąć (lub przenieść na inny dysk). Wygląda na to, że LoadLibrary zamyka uchwyt pliku (nie jest potrzebny) i używa tylko uchwytu do zamapowanej sekcji, dzięki czemu można dowolnie zmienić nazwę pliku, ale nie można go usunąć.

Z drugiej strony std::ifstream używa uchwytu pliku, aby uzyskać dostęp do pliku. Nie ustawia też dostępu do udziałów, który jest wymagany do operacji zmiany nazwy i usuwania.

W rzeczywistości nie ma specjalnego śledzenia pliku na dysku. Uchwyt pliku wskazuje na plik i to wszystko. Po otwarciu pliku i uzyskaniu jego obsługi plik może zostać zmieniony, a nawet usunięty i nadal masz dostęp do tego pliku (ograniczony dostęp, jeśli plik został usunięty, ale możesz cofnąć usunięcie pliku i mieć pełny dostęp) .

+0

To ma sens. Rzeczywiście uchwyt pliku w dll zostanie zamknięty po załadowaniu i tylko mapowanie pamięci będzie się utrzymywać. Dziękujemy również za wskazanie opcji 'FILE_SHARE_DELETE' jako opcji dla [' CreateFile'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx) , Wcześniej nie wiedziałem o tej opcji. – ComicSansMS