Load-Time Dynamic Linking
When the system starts a program that uses load-time dynamic linking, it uses the information the linker placed in the file to locate the names of the DLLs that are used by the process. The system then searches for the DLLs. If the system cannot locate a required DLL, it terminates the process and displays a dialog box that reports the error to the user. Otherwise, the system maps the DLL into the virtual address space of the process and increments the DLL reference count. The system calls the entry-point function. The function receives a code indicating that the process is loading the DLL. If the entry-point function does not return TRUE, the system terminates the process and reports the error. Finally, the system modifies the function address table with the starting addresses for the imported DLL functions. The DLL is mapped into the virtual address space of the process during its initialization and is loaded into physical memory only when needed.
Run-Time Dynamic Linking
When the application calls the LoadLibrary() or LoadLibraryEx() functions, the system attempts to locate the DLL. If the search succeeds, the system maps the DLL module into the virtual address space of the process and increments the reference count. If the call to LoadLibrary() or LoadLibraryEx specifies() a DLL whose code is already mapped into the virtual address space of the calling process, the function simply returns a handle to the DLL and increments the DLL reference count. Note that two DLLs that have the same base file name and extension but are found in different directories are not considered to be the same DLL. The system calls the entry-point function in the context of the thread that called LoadLibrary() or LoadLibraryEx(). The entry-point function is not called if the DLL was already loaded by the process through a call to LoadLibrary() or LoadLibraryEx() with no corresponding call to the FreeLibrary() function.
If the system cannot find the DLL or if the entry-point function returns FALSE, LoadLibrary() or LoadLibraryEx() returns NULL. If LoadLibrary() or LoadLibraryEx() succeeds, it returns a handle to the DLL module. The process can use this handle to identify the DLL in a call to the GetProcAddress(), FreeLibrary(), or FreeLibraryAndExitThread() function.
The GetModuleHandle() function returns a handle used in GetProcAddress(), FreeLibrary(), or FreeLibraryAndExitThread(). The GetModuleHandle() function succeeds only if the DLL module is already mapped into the address space of the process by load-time linking or by a previous call to LoadLibrary() or LoadLibraryEx(). Unlike LoadLibrary() or LoadLibraryEx(), GetModuleHandle() does not increment the module reference count. The GetModuleFileName() function retrieves the full path of the module associated with a handle returned by GetModuleHandle(), LoadLibrary(), or LoadLibraryEx(). The process can use GetProcAddress() to get the address of an exported function in the DLL using a DLL module handle returned by LoadLibrary() or LoadLibraryEx, GetModuleHandle().
When the DLL module is no longer needed, the process can call FreeLibrary() or FreeLibraryAndExitThread(). These functions decrement the module reference count and unmap the DLL code from the virtual address space of the process if the reference count is zero. Run-time dynamic linking enables the process to continue running even if a DLL is not available. The process can then use an alternate method to accomplish its objective. For example, if a process is unable to locate one DLL, it can try to use another, or it can notify the user of an error. If the user can provide the full path of the missing DLL, the process can use this information to load the DLL even though it is not in the normal search path. This situation contrasts with load-time linking, in which the system simply terminates the process if it cannot find the DLL. Run-time dynamic linking can cause problems if the DLL uses the DllMain() function to perform initialization for each thread of a process, because the entry-point is not called for threads that existed before LoadLibrary() or LoadLibraryEx() is called.
Dynamic-Link Library Search Order
A system can contain multiple versions of the same dynamic-link library (DLL). Applications can control the location from which a DLL is loaded by specifying a full path, using DLL redirection, or by using a manifest. If none of these methods are used, the system searches for the DLL at load time as described in this topic.
Standard Search Order
The DLL search order used by the system depends on whether safe DLL search mode is enabled or disabled. Safe DLL search mode is enabled by default. To disable this feature, create the HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode registry value and set it to 0.
Calling the SetDllDirectory() function effectively disables SafeDllSearchMode while the specified directory is in the search path and changes the search order as described in this topic. For Windows XP and Windows 2000 with SP4: Safe DLL search mode is disabled by default. To enable this feature, create the SafeDllSearchMode registry value and set it to 1. Safe DLL search mode is enabled by default starting with Windows XP with Service Pack 2 (SP2). For Windows 2000, the SafeDllSearchMode value is not supported. The DLL search order is identical to the search order that occurs when safe DLL search mode is disabled. The SafeDllSearchMode value is supported starting with Windows 2000 with SP4. If SafeDllSearchMode is enabled, the search order is as follows:
If SafeDllSearchMode is disabled, the search order is as follows:
Alternate Search Order
The standard search order used by the system can be changed by calling the LoadLibraryEx() function with LOAD_WITH_ALTERED_SEARCH_PATH. The standard search order can also be changed by calling the SetDllDirectory() function. For Windows XP: Changing the standard search order by calling SetDllDirectory() is not supported until Windows XP with Service Pack 1 (SP1). For Windows 2000: Changing the standard search order by calling SetDllDirectory() is not supported. If you specify an alternate search strategy, its behavior continues until all associated executable modules have been located. After the system starts processing DLL initialization routines, the system reverts to the standard search strategy. The LoadLibraryEx() function supports an alternate search order if the call specifies LOAD_WITH_ALTERED_SEARCH_PATH and the lpFileName parameter specifies an absolute path. Note that the standard search strategy and the alternate search strategy specified by LoadLibraryEx() with LOAD_WITH_ALTERED_SEARCH_PATH differ in just one way: The standard search begins in the calling application's directory, and the alternate search begins in the directory of the executable module that LoadLibraryEx() is loading. If SafeDllSearchMode is enabled, the alternate search order is as follows:
If SafeDllSearchMode is disabled, the alternate search order is as follows:
The SetDllDirectory() function supports an alternate search order if the lpPathName parameter specifies a path. The alternate search order is as follows:
If the lpPathName parameter is an empty string, the call removes the current directory from the search order. The SetDllDirectory() effectively disables safe DLL search mode while the specified directory is in the search path. To restore safe DLL search mode based on the SafeDllSearchMode registry value and restore the current directory to the search order, call SetDllDirectory() with lpPathName as NULL.