我假设如果您使用CreateFileW请求独占访问,如果它已被打开,我应该收到共享冲突。但是,我遇到过这种情况并非如此。如果调用LoadLibraryEx来加载设置了LOAD_LIBRARY_AS_DATAFILE标志的DLL,则CreateFileW将成功返回。但是有些操作会被拒绝(比如设置文件尾等属性)。有没有更好的方法来检测这些文件是否打开?我是否错误地使用CreateFileW?加载没有LOAD_LIBRARY_AS_DATAFILE标志的DLL会导致CreateFileW失败,表明它无法访问文件,因为它正在被另一个进程使用。当LoadLibraryEx调用LOAD_LIBRARY_AS_DATAFILE
HMODULE hModule = LoadLibraryEx(L"\\Pathto\\module.dll", NULL, NULL);
DWORD access = GENERIC_READ | GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY;
DWORD creation = OPEN_EXISTING;
DWORD flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
HANDLE file = CreateFileW(L"\\Pathto\\module.dll", access, 0, NULL, creation, flags, 0);
上面将导致CreateFileW,错误代码32(不能访问的原因是在通过另一进程使用),这是预期的结果失败。如果我的标志添加到LoadLibraryEx:
HMODULE hModule = LoadLibraryEx(name, NULL, LOAD_LIBRARY_AS_DATAFILE);
,并使用完全相同的调用CreateFileW然后有人告诉我这是成功的,但试图设置文件结尾(作为一个例子)的时候我会遇到问题后。此外,删除文件将失败并出现拒绝访问错误(没有应用程序或任何其他打开的句柄)。
其他奇怪的行为涉及与加载库的硬链接。如果我生成一个新的硬链接到加载的模块,并尝试删除备用的新创建的硬链接,它也失败(没有打开文件句柄,只是加载模块)。为什么?它不应该只是删除链接并取消引用链接计数,或者在模块关闭时计划删除,因为以前我可能获得了独占访问权限?
另外值得注意的是,这个过程本身与下面的附加特权的特权用户帐户运行启用: SE_SECURITY_NAME,SE_BACKUP_NAME,SE_RESTORE_NAME,SE_TAKE_OWNERSHIP_NAME
如何将一个确定如果你真的有一个文件时,独占访问库加载?
编辑:只是为了双倍检查,除了通过SysInternals工具“处理”加载模块外,我没有验证其他打开的句柄。
我猜数据只是放在内存中,但文件不保持打开状态。 https://blogs.msdn.microsoft.com/oldnewthing/20141120-00/?p=43573可能是相关的。 –
我觉得还有比这更多的东西。它显然仍然被拥有进程引用(如果你在SysInternals Process Explorer中查看,它将被列为进程生命周期的DLL)。您的链接还声明它已映射到进程地址空间。 另外,为什么downvotes没有解释?这很容易重现。如果这是一个“愚蠢的”问题,请解释原因。 – ConfusedDeveloper
Raymond的博客建议,如果仅作为数据文件打开,则不应将其列为DLL。顺便说一句,downvotes不是我的。 –