Unloading a Delay-Loaded DLL

The default-supplied delay-load helper checks to see if the delay-load descriptors have a pointer and a copy of the original IAT in the pUnloadIAT field. If so, it will save a pointer in a list to the import delay descriptor. This enables the helper function to find the DLL by name to support unloading that DLL explicitly.

Here are the associated structures and functions for explicitly unloading a delay-loaded DLL:

//
// Unload support
//

// routine definition; takes a pointer to a name to unload, or NULL to
// unload all the delay load dlls in the list.
//
#if defined(__cplusplus)
extern "C"
#endif
BOOL WINAPI
__FUnloadDelayLoadedDLL(LPCSTR szDll);

// structure definitions for the list of unload records
typedef struct UnloadInfo * PUnloadInfo;
typedef struct UnloadInfo {
    PUnloadInfo     puiNext;
    PCImgDelayDescr pidd;
    } UnloadInfo;

// the default delay load helper places the unloadinfo records in the list
// headed by the following pointer.
#if defined(__cplusplus)
extern "C"
#endif
extern
PUnloadInfo __puiHead;

The UnloadInfo structure is implemented using a C++ class that uses LocalAlloc and LocalFree implementations as its operator new and operator delete respectively. These options are kept in a standard linked list using __puiHead as the head of the list.

Calling the supplied unload routine will attempt to find the name you provide in the list of loaded DLLs (an exact match is required). If found, the copy of the IAT in pUnloadIAT is copied over the top of the running IAT to restore the thunk pointers, the library is freed with FreeLibrary, the matching UnloadInfo record is unlinked from the list and deleted, and TRUE is returned.