Microsoft KB Archive/195254

{|
 * width="100%"|

PRB: DLLs Used by In-context Winevent Hooks Fail to Load

 * }

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:


 * 1) The directory from which the application was loaded.
 * 2) The current directory.
 * 3) The Windows System or System32 directory.
 * 4) The Windows directory.
 * 5) 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:


 * 1) Use GetModuleFileName (using its own module instance handle obtained when its DllMain is called) to get the full pathname to Event.dll.
 * 2) 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).
 * 3) 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.