DLL Loading Rules in Win32

This information is compiled from the MSDN documentation. This page was compiled because exceptions, special cases, etc. were scattered through knowledge base articles, tech notes, etc.. This just compiles all the information in one place.

DLLs can be loaded in two ways, either explicitly, using LoadLibrary(), or implicitly, by linking to a library which imports the DLL.

When a DLL is loaded, either explicitly or implicitly, Windows uses the following rules to determine what DLL to load and how:

It's a complex subject. The part that is most confusing to developers is the Known DLLs exception. Known DLL keys can be deleted, but do so at your own risk. Some experts have suggested that doing so may compromise NT security. There is also a Registry entry, HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager, which has an 'ExcludeFromKnownDlls' entry (use Regedt32 to adjust this).


1 - In Windows 95, 98 Original Release, or NT version 4 or less, ActiveX servers must have an absolute path registered. This limits the system to one properly registered version of each ActiveX server at a time. In Windows 2000 (NT 5) and Windows 98 SE, the path can be a relative path, so applications will be able to use a different version by placing it in the application directory and registering a relative search path. See the Windows 2000 documentation and this article: http://msdn.microsoft.com/library/techart/sidebyside.htm for more details.

2 - DLL Redirection allows the administrator to override the developer error of loading a DLL from a specific location, usually the Windows System folder. This is a rare problem for ordinary DLLs, but a much more common one for COM DLLs. See "The End of DLL Hell", in the Microsoft Knowledge Base.

3 - Known DLLs are DLLs that are expected to be always installed in the particular version of the OS. The list of Known DLLs is short in Windows NT, and includes only system DLLs (except for a few DLLs linked to Known DLLs). In Win95/98, the list is much longer, and includes many DLLs commonly used, but not true system DLLs, such as MSVCRT.DLL. This is documented, but not under the rules for LoadLibrary in Platform SDK, only in the KBase. See articles Q164501 and Q151646.

4 - Side By Side is a great idea, and while I don't use it, the reports I hear back from people is that it works well. But it's not guaranteed. Implementing side-by-side requires that the software vendors follow the rules exactly. So far, most vendors have a failing grade in this, including the most prominent names in the industry. Implementing side-by-side properly in you components may mean making some short-term sacrifices in exchange for long-term benefits.

For example:

Remember, most of the work to comply with the new rules needs to be done manually; skip a step, and you may create your own private DLL hell.

More detail is in this article on Microsoft's web side: http://msdn.microsoft.com/library/techart/sidebyside.htm

5 - This differs from Win16, where once a DLL was loaded, no other DLL with the same name could be loaded. Win16 only retained the 8 character name of the DLL to identify whether it was loaded or not. Win32 uses the entire path and file name to identify DLLs, so two DLLs with the same name, but in different folders, can be loaded by a single process. Also, Win32 does not skip the search if other applications have loaded the DLL. It always searches, using these rules.


Known DLL listings

The following tables lists Known DLL entries for 3 key versions of Windows. This list may contain DLLs not installed on a base system; no documentation exists for applications registering Known DLLs, but I can't say this doesn't happen. I will continue to investigate; but as this requires wiping a hard drive partition on my test machine and doing a reinstall, I am not hurrying ;>.

Also, this list does not include any DLLs that are treated as Known DLLs because they are loaded by a Known DLL. Since these are more time consuming to check and can change unpredictably, I'm leaving the task for someone else.

Windows NT 4.0, SP4

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs - space between 'Session' and 'Manager'

ADVAPI32.DLL COMDLG32.DLL CRTDLL.DLL LZ32.DLL
MSRATING.DLL NETAPI32.DLL OLE32.DLL OLEAUT32.DLL
OLECLI32.DLL OLECNV32.DLL OLESVR32.DLL OLETHK32.DLL
RPCRT4.DLL SHELL32.DLL SHLWAPI.DLL URL.DLL
URLMON.DLL VERSION.DLL WININET.DLL  

Bold entries are -not- on Win98 SE

Windows 95 OEM Release 2

HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\SessionManager\KnownDLLs - no space between 'Session' and 'Manager'

ADVAPI32.DLL CHOOSUSR.DLL COMCTL32.DLL COMDLG32.DLL
CRTDLL.DLL DIGSIG.DLL GDI32.DLL IMAGEHLP.DLL
KERNEL32.DLL LINKINFO.DLL LZ32.DLL MFC30.DLL
MFC40.DLL MFCANS32.DLL MFCUIA32.DLL MPR.DLL
MPRSERV.DLL MSAB32.DLL MSNET32.DLL MSNP32.DLL
MSPWL32.DLL MSRATING.DLL MSSHRUI.DLL MSVCRT.DLL
MSVCRT20.DLL MSVCRT40.DLL NETAPI32.DLL NETBIOS.DLL
NTDLL.DLL NWAB32.DLL NWNET32.DLL NWNP32.DLL
OLE32.DLL OLEAUT32.DLL OLECLI32.DLL OLEDLG.DLL
OLESVR32.DLL OLETHK32.DLL RASAPI32.DLL RICHED32.DLL
RNAP.DLL RNASERV.DLL RNATHUNK.DLL RNAUI.DLL
RPCRT4.DLL RSABASE.DLL SHDOCVW.DLL SHELL32.DLL
SHLWAPI.DLL SHSCRAP.DLL SVRAPI.DLL SYNCENG.DLL
SYNCUI.DLL TAPI32.DLL UMDM32.DLL URLMON.DLL
USER32.DLL VERSION.DLL VSREVOKE.DLL WININET.DLL
WINMM.DLL WINNT.DLL WINSPOOL.DRV WINTRUST.DLL
WOW32.DLL      

Bold entries are -not- on Win98 SE

Windows 98, Second Edition

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\KnownDLLs - no space between 'Session' and 'Manager'

ADVAPI32.DLL CHOOSUSR.DLL COMCTL32.DLL COMDLG32.DLL
CRTDLL.DLL DIGSIG.DLL GDI32.DLL IMAGEHLP.DLL
KERNEL32.DLL LINKINFO.DLL LZ32.DLL MFC30.DLL
MFC40.DLL MFCANS32.DLL MFCUIA32.DLL MPR.DLL
MPRSERV.DLL MSAB32.DLL MSNET32.DLL MSNP32.DLL
MSPWL32.DLL MSRATING.DLL MSSHRUI.DLL MSVCRT.DLL
MSVCRT20.DLL MSVCRT40.DLL NETAPI32.DLL NETBIOS.DLL
NTDLL.DLL NWAB32.DLL NWNET32.DLL NWNP32.DLL
OLE32.DLL OLEAUT32.DLL OLECLI32.DLL OLEDLG.DLL
OLESVR32.DLL OLETHK32.DLL RASAPI32.DLL RICHED32.DLL
RNAP.DLL RNASERV.DLL RNATHUNK.DLL RNAUI.DLL
RPCRT4.DLL RSABASE.DLL SHDOCVW.DLL SHELL32.DLL
SHLWAPI.DLL SVRAPI.DLL SYNCENG.DLL SYNCUI.DLL
TAPI32.DLL UMDM32.DLL URLMON.DLL USER32.DLL
VERSION.DLL WININET.DLL WINMM.DLL WINNT.DLL
WINSPOOL.DRV WINTRUST.DLL WOW32.DLL  

You'll notice the list of DLLs referred to as Known DLLs is considerably shorter in NT than in 95/98. MS decided to improve performance on 95/98 for the average user, at the cost of stability for the advanced user. Known DLLs improve load time for applications, since no search needs done, and since the virtual memory manager needs only to map the DLLs into the new process, rather than load the DLLs (and possibly require addresses to be fixed up if the DLL can't load at it's preferred base address).


© 2005 Ron Ruble. All rights reserved. 
Revised: Friday, November 18, 2005.