2016-02-29 62 views
1

从我读的MSDN documentation,我认为(如果该基名的dll是尚未加载)传递完全限定的绝对文件名到LoadLibraryExW只会查看该路径。LoadLibraryEx忽略完全归档的路径名?

E.g. (请注意,这是正确的CSIDL_SYSTEM的路径,如果有差别),如果该文件不存在该位置

LoadLibraryExW (L"C:\\Windows\\System32\\foobar.dll", LOAD_LIBRARY_AS_DATAFILE); 

应该失败。但是我得到了一些有趣的结果,这让我认为它取得了基本名称并将它应用于Windows 8.1上的PATH。并在其他地方找到具有相同名称的文件。

此外,如果我使用LOAD_LIBRARY_AS_DATAFILE它阻止我发现它实际上找到它的位置。

这个功能是什么真的在这方面做了什么,并且它随操作系统版本而变化吗?

(顺便说一句,我知道LOAD_LIBRARY_SEARCH_SYSTEM32,但这并不能在所有操作系统版本存在的。我想在任何运行早在XP)。

这是因为我觉得特别混乱,使用绝对路径是一个有效的修补程序,我以前看到它通过PATH找到不正确的文件,作为LOAD_LIBRARY_SEARCH_SYSTEM32的便携式替代品。所以也许它会因操作系统或其他一些神奇的变化而改变行为。

+0

您需要显示代码并提供完整详细的测试用例。尤其要注意,您链接的文档中提到的适用的“LOAD_”标志。 – dxiv

+0

您可以使用Process Monitor(可从MS网站获得)来确认文件是否真的从其他地方加载。一个想法:你记得在路径中使用反斜杠,而不是正斜杠,对吧? –

+2

我认为完全指定的DLL路径将来自另一个实际位置的情况是涉及Wow64重定向的情况。如果您的应用程序是运行在Win64操作系统上的32位应用程序,默认情况下,System32的文件访问权限将被重定向到SysWow64。见https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187.aspx也许这就是发生在你身上的事情?将路径更改为System32以外的其他路径,我认为您会看到LoadLibraryEx()函数失败。 –

回答

1

如果已加载该名称的DLL,Windows将忽略该路径。

因此,如果有一个foobar.dll已经从其他路径加载过程中,那么即使您指定了完整的绝对路径到不同的foobar.dll,它也会返回第一个句柄,并将引用计数。

编辑:发现的documentation for this behavior

如果用相同的模块名称的DLL已加载到内存,系统仅检查重定向和清单解决所加载的DLL之前,无论它所在的目录。系统不搜索DLL。

+0

对不起,有问题的DLL尚未加载(与观察到的行为)。我知道这是引用现有加载文件的情况。我会澄清这个问题。 –

+1

也许您可以编辑问题以显示调试器中输出窗口中的所有“模块加载”消息。这应该告诉我们究竟发生了什么(包括是否加载了另一个同名的DLL)。 –

2

我一直在使用Process Monitor是用作LoadLibraryEx参数完全合格的文件名确实会导致只路径进行检查(即,当它需要加载一个文件,因为没有观察到该名称的DLL已经加载)。这在32位进程中被观察到。

对于System32目录,在64位操作系统上,作为C:\ Windows \ System32作为参数给出的参数在ProcMon中显示为C:\ Windows \ SysWOW64。

这在

  • 视窗XP SP3观察到,32位(古怪:如果DLL不存在,QueryOpen与相同的路径称为两次)
  • Windows 7中,32位
  • 的Windows 10,64位

一个需要注意的是,即使命名的DLL从指定目录加载了绝对路径,其依赖的DLL加载与PATH的正常搜索。当使用LOAD_LIBRARY_AS_DATAFILE时,这不是问题。