GetModuleHandleExA & GET MODULE HANDLE EX FLAG UNCHANGED REFCOUNT - How should it be unloaded?

GetModuleHandleExA function (libloaderapi.h) - Win32 apps | Microsoft Docs

The flag GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT says we shouldnt use FreeLibrary function (libloaderapi.h) - Win32 apps | Microsoft Docs or the FreeLibraryAndExitThread function (libloaderapi.h) - Win32 apps | Microsoft Docs function.

It says

The reference count for the module is not incremented. This option is equivalent to the behavior of GetModuleHandle. Do not pass the retrieved module handle to the FreeLibrary function; doing so can cause the DLL to be unmapped prematurely. For more information, see Remarks.


If dwFlags contains GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, the GetModuleHandleEx function returns a handle to a mapped module without incrementing its reference count. However, if this handle is passed to the FreeLibrary function, the reference count of the mapped module will be decremented. Therefore, do not pass a handle returned by GetModuleHandleEx with GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT to the FreeLibrary function. Doing so can cause a DLL module to be unmapped prematurely.

If dwFlags contains GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, this function must be used carefully in a multithreaded application.

FreeLibrary and FreeLibraryAndExitThread confirm the above, so does anyone know how to unload a module when this flag is used?



The main feature of GetModuleHandleExA is to reference count, why would you prevent that? You only need to FreeLibrary when YOU called LoadLibrary, or omitted that UNCHANGED_REFCOUNT flag.

A better place to ask Windows API questions is on Stack Overflow.

Its for my loader class, I didnt know if anyone knew what it was for that’s all and I just wanted to check.

My loader class makes sure you cant use the wrong flags with the api and prevents other mistakes from occurring which seems to be quite common.

To me it sounds alot like LoadLibraryEx with these flags LOAD_LIBRARY_AS_DATAFILE , LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE , and LOAD_LIBRARY_AS_IMAGE_RESOURCE but with yet still slightly different behaviour.

So if these LoadLibraryEx flags are used and the module (exe or dll) is already loaded then the reference count is incremented, if the module is not already loaded then the reference count is NOT incremented.

In addition, it looks like when the reference count is not incremented, it does not make the module visible to functions such as CreateToolhelp32Snapshot or EnumProcessModules.

And I havent established the complete list of functions that wont see the loaded module!

So this might be a way of loading a dll using GetModuleHandleEx with GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT which would hide the module from other api’s as mentioned in the LoadLibraryEx webpage. In addition it might also be possible to load the dll and then call the code in the “hidden” DLL by passing its address using the PE layout. Havent tried this yet, just an idea.

But then further below the LoadLibraryEx page, it then goes on to say

Use the FreeLibrary function to free a loaded module, whether or not loading the module caused its reference count to be incremented. If the module was loaded as a data or image file, the mapping is destroyed but the reference count is not decremented. Otherwise, the DLL reference count is decremented. Therefore, it is safe to call FreeLibrary with any handle returned by LoadLibraryEx .

Which is different to what is stated in the GetModuleEx page about using FreeLibrary, or maybe the handles obtained from GetModuleEx are different to those obtained by LoadLibrary(Ex)?

Some API’s I’m using will accept a handle from both LoadLibrary(Ex) and GetModuleHandle(Ex).

So does anyone know, is all I’m asking, so maybe its best to ask on StackOverflow, like you say.