Tyson
Tyson

Reputation: 1238

Delay-load DLL in windows: can I dynamically choose what DLL name to look for? (c++)

I have a library that calls functions from foo.dll.

In my MSVS settings, I delay load foo.dll and manually check for its existence before attempting to call its functions (so that if it doesn't exist on a machine, my library won't crash).

If the DLL-existence check succeeds and I call its functions, the DLL is auto-loaded by the windows delay load helper and everything functions well.

However, on 50% of my user's machines, foo.dll was renamed to bar.dll. Even if I call LoadLibrary("path\bar.dll") and it succeeds, my library still crashes because the delay load helper still tries to load foo.dll when I call one of the functions.

I used a hex editor to view the content of my library, and in one location "foo.dll" is explicitly named. If I rename that entry to "bar.dll" using the hex editor, my library runs flawless when bar.dll is the name of the DLL on a user's machine (and crashes where foo.dll is the name). So it seems the issue is soley the delay load helper trying to load the explicitly-named DLL inside my library.

How can I tell the delay load helper that the DLL in question goes by a name that doesn't match the explicit file name in my compiled library?

Upvotes: 1

Views: 1279

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595320

To tell the delay load helper to use a different DLL than what is linked to, you can use a delay load failure hook. Per MSDN:

Linker Support for Delay-Loaded DLLs: Error Handling and Notification

If your code needs to recover or provide an alternate library and/or routine on failure, a hook can be provided to the helper function that can supply or remedy the situation. The hook routine needs to return a suitable value, so that processing can continue (an HINSTANCE or FARPROC) or 0 to indicate that an exception should be thrown. It could also throw its own exception or longjmp out of the hook. There are notification hooks and failure hooks.

When a delay-loaded DLL fails to load, the hook is called with a dliFailLoadLib notification containing details about the load operation and error. The hook can recover from the error by returning a valid HMODULE for the helper to use, or return 0 to fail the load operation.

If the notification is dliFailLoadLib, the hook function can return:

  • 0, if it cannot handle the failure.

  • An HMODULE, if the failure hook fixed the problem and loaded the library itself.

So, if the error reports the failed DLL is foo.dll, your hook can load and return the HMODULE for bar.dll, and then the helper will load all of foo.dll's delay-loaded functions from bar.dll instead.

Upvotes: 2

Related Questions