PRB: DLLs Used by In-context Winevent Hooks Fail to Load
ID: Q195254
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
SYMPTOMS
During in-process event hooking, the hook must reside in a separate DLL
that is loaded into any process that fires a WinEvent. If this hooking DLL
links to other DLLs, either implicitly or explicitly (use of .libs/exports
versus LoadLibrary), the DLLs that are linked to might fail to load.
However, linking to system DLLs such as User, Kernel, and so forth, works
correctly. The DLLs retain the link when the hook DLL is loaded in the
process that installs it, rather than when the DLL is loaded by another
application.
CAUSE
Both implicit and explicit dynamic linking, results in the search for the
DLL in the following places in the following order:
- The directory from which the application was loaded.
- The current directory.
- The Windows System or System32 directory.
- The Windows directory.
- Directories listed in the PATH environment variable.
The DLL that is linked to by the hook DLL normally resides in the directory
where the hook DLL and the application that installs it reside. It works
well if the application that installs the hook loads the DLLs. However, if
other applications load the DLLs, the linked DLLs are not found in the
directory in which the loading application resides. Therefore, it fails.
RESOLUTION
If you use implicit linking, your only option is to make the DLLs available
on one of the search paths mentioned above. To do this, do one of the
following:
- Place the DLL in the System/System32 or Windows directories.
- Place the DLL somewhere on the search path.
- Modify the PATH variable to include the directory where the DLLs are
located.
If the DLLs are explicitly loaded, in addition to the above, you can
specify the full path of the DLL with the filename.
The most effective solution is:
- Use GetModuleFileName() (using its own module instance handle obtained
when its DllMain is called) to get the full pathname to Event.dll.
- Strip the filename part of the path (in this case, Event.exe) and
replace it with the filename of the desired .dll (for example, foo.Dll).
- Call LoadLibrary() using this path.
You can then use GetProcAddress to link to functions in the loaded DLL in
the usual manner. This method does not require files to be copied to the
system directory, nor does it require the path to be changed.
MORE INFORMATION
The following example demonstrates the problem and how it could be
resolved.
Accevent.exe, Event.dll, and Foo.dll exist in the same directory, which is
not on the path.
If Accevent.exe installs a hook that resides in Event.dll and Event.dll
links to Foo.dll, Event.dll successfully loads and links to Foo.dll when
Event.dll is loaded by Accevent.exe. However, if Notepad.exe loads
Event.dll, Event.dll will fail to link Foo.dll.
When Event.dll is loaded into Notepad.exe, the directory where Notepad.exe
resides is searched instead of the directory where Accevent.exe resides.
Also, Foo.dll will not be found in any of the other directories that are
searched. As a result, Foo.dll is not linked.
You can avoid this problem if you place Foo.dll in one of the System or
System32 or Windows directories ,or if the directory where it resides is
placed within the PATH variable. If the DLL is explicitly linked, you can
use LoadLibrary() to solve this problem.
REFERENCES
Microsoft Active Accessibility
Additional query words:
Keywords : kbAAcc kbClient kbHook kbSDKPlatform
Version : WINDOWS:
Platform : WINDOWS
Issue type : kbprb