How can I delay-load a Windows private assembly? Is it possible?

511 views Asked by At

My project is a plug-in (Windows DLL) that is loaded by a host executable not under my control. My DLL wants to load some additional libs. I do this with private assemblies; there's a great answer at how can a Win32 App plugin load its DLL in its own directory for how to do this. But if I add /delayload dependentlib.dll on the main DLL's link line to avoid loading the assembly til it's needed (I have to do this for various reasons), Windows no longer searches my private assemblies -- seems like it ignores the manifest I compiled in. Instead it looks for the delay-loaded DLL in the usual search path. (I use sysinternals procmon to check this.)

Is this a known bug, or is there any other way to delay-load an assembly? I'd rather not go the LoadLibrary + GetProcAddress route where I have to know all the symbols I care about in the dependent lib.

2

There are 2 answers

1
Chris Becke On BEST ANSWER

Your problem here is, when the first call to a delay loaded function is made, the applications default activation context is the current context.

What you need to do is create an activation context: CreateActCtx pointing at your own manifest (hinstance+resource id is possible I think).

Then, wrap all, or at least the very first, call to the dll with ActivateActCtx (and the corresponding deactivate function) to ensure the correct assemblies are searched.

In theory you could just embed the code to activate the appropriate context in the delayload helper function.

0
Peter Ruderman On

This behaviour is by design, unfortunately. Essentially, when you specify /DELAYLOAD, you're just instructing the linker to insert the LoadLibrary and GetProcAddress calls for you. As a result, the behaviour when delay loading a DLL is the same as loading that DLL dynamically with LoadLibrary.

MSDN describes some of the consequences. On the plus side, you can override the default behaviour. I'd recommend writing your own delay load helper function.

FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd, FARPROC * ppfnIATEntry)
{
    //...
}

The linker will insert calls to this function whenever it needs to resolve an entry point in a delay loaded DLL. Your version could implement a custom search for your private assemblies. Here's additional information about the helper function on MSDN.