2013-07-22 10 views
5

私はちょうど、LoadLibrary API呼び出しを使ってロードされたDLLファイルがロードされている間に名前が変更されたという驚くべきバグがありました。どうやら、ファイルに開いているDLLハンドルを持っていても、そのファイルの名前が変更されたり、別のパスに移動したりすることはありません。しかし、削除から保護され、別のディスクに移動されます。この場合、DLL を使用しているプログラムは、引き続き正常に動作します。 ProcessExplorerは、DLLハンドルのパスがそれに応じて更新されることを示します。オープンされたDLLハンドルがファイルの移動を保護しないのはなぜですか?

この動作は、Windowsの通常のファイルハンドルと異なります。たとえば、開いているstd::ifstreamを同じDLLに保つと、名前変更はオペレーティングシステムによって許可されなくなります。私はこの行動が非常に驚くべきものだと誰もそれを説明することができますか?特に、私はディスク上のファイルの追跡が単にそれを固定するよりも難しいと想像していたので、これを許す根拠に興味があります。したがって、OSはおそらくこの機能を積極的にサポートしなければならないでしょう。つまり、そのためのユースケースが必要です。

答えて

6

これはバグではありません。 LoadLibraryFile Mappingを使用してファイルにアクセスします。ファイルにマップされたセクションがある間は、そのセクションを削除(または別のディスクに移動)することはできません。 LoadLibraryはファイルハンドルをクローズする(不要)と思われ、マップされたセクションへのハンドルのみを使用するので、ファイルの名前を自由に変更できますが、削除することはできません。

一方、std::ifstreamはファイルハンドルを使用してファイルにアクセスします。また、名前変更と削除操作に必要な共有アクセスはFILE_SHARE_DELETEに設定されていません。

実際には、ディスク上のファイルの特別な追跡はありません。ファイルハンドルがファイルを指しており、それがすべてです。ファイルを開いてそのハンドルを取得すると、そのファイルの名前を変更したり削除したりすることができます。そのファイルにはまだアクセスできます(ファイルが削除されている場合はアクセスが制限されますが、ファイルの復元を取り消してフルアクセスできます) 。

+0

これは理にかなっています。実際には、dllのファイルハンドルはロード後に閉じられ、メモリマッピングだけが存続します。また、['CreateFile']のオプションとして' FILE_SHARE_DELETE'を指してくれてありがとう(http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx) 、私はその前にそのオプションを知らなかった。 – ComicSansMS

関連する問題