Функция LoadLibraryExA (libloaderapi.h)

Загружает указанный модуль в адресное пространство вызывающего процесса. Указанный модуль может привести к загрузке других модулей.

Синтаксис

HMODULE LoadLibraryExA(
  [in] LPCSTR lpLibFileName,
       HANDLE hFile,
  [in] DWORD  dwFlags
);

Параметры

[in] lpLibFileName

Строка, указывающая имя файла загружаемого модуля. Это имя не связано с именем, хранящимся в самом модуле библиотеки, как указано в ключевое слово LIBRARY в файле определения модуля (DEF).

Модуль может быть модулем библиотеки (файл .dll) или исполняемым модулем (файлом .exe). Если указанный модуль является исполняемым модулем, статические операции импорта не загружаются; Вместо этого модуль загружается так, как если бы был указан DONT_RESOLVE_DLL_REFERENCES . Дополнительные сведения см. в разделе параметр dwFlags .

Если в строке указано имя модуля без пути, а расширение имени файла опущено, функция добавляет к имени модуля расширение библиотеки по умолчанию ".DLL". Чтобы функция не добавляла ".DLL" к имени модуля, добавьте символ конечной точки (.) в строку имени модуля.

Если строка указывает полный путь, функция ищет модуль только по нему. При указании пути обязательно используйте обратную косую черту (\), а не косую черту (/). Дополнительные сведения о путях см. в разделе Именование файлов, путей и пространств имен.

Если в строке указано имя модуля без пути и несколько загруженных модулей имеют одинаковое базовое имя и расширение, функция возвращает дескриптор модулю, который был загружен первым.

Если в строке указано имя модуля без пути и модуль с таким же именем еще не загружен или если в строке указано имя модуля с относительным путем, функция выполняет поиск указанного модуля. Функция также выполняет поиск модулей, если загрузка указанного модуля приводит к загрузке системой других связанных модулей (то есть, если модуль имеет зависимости). Каталоги, в которых выполняется поиск, и порядок их поиска зависят от указанного пути и параметра dwFlags . Дополнительные сведения см. в подразделе "Примечания".

Если функции не удается найти модуль или одну из его зависимостей, функция завершается ошибкой.

hFile

Этот параметр зарезервирован для использования в будущем. Он должен иметь значение NULL.

[in] dwFlags

Действие, выполняемое при загрузке модуля. Если флаги не указаны, поведение этой функции идентично поведению функции LoadLibrary . Этот параметр может принимать одно из указанных ниже значений.

Значение Значение
DONT_RESOLVE_DLL_REFERENCES
0x00000001
Если используется это значение, а исполняемый модуль является библиотекой DLL, система не вызывает DllMain для инициализации и завершения процессов и потоков. Кроме того, система не загружает дополнительные исполняемые модули, на которые ссылается указанный модуль.
Примечание Не используйте это значение; он предоставляется только для обеспечения обратной совместимости. Если вы планируете получить доступ только к данным или ресурсам в библиотеке DLL, используйте LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE , LOAD_LIBRARY_AS_IMAGE_RESOURCE или и то, и другое. В противном случае загрузите библиотеку как dll или исполняемый модуль с помощью функции LoadLibrary .
 
LOAD_IGNORE_CODE_AUTHZ_LEVEL
0x00000010
Если используется это значение, система не проверка правила AppLocker и не применяет политики ограниченного использования программного обеспечения для библиотеки DLL. Это действие применяется только к загружаемой библиотеке DLL, но не к ее зависимостям. Это значение рекомендуется использовать в программах установки, которые должны запускать извлеченные библиотеки DLL во время установки.

Windows Server 2008 R2 и Windows 7: В системах с установленными KB2532445 вызывающий объект должен работать как LocalSystem или TrustedInstaller; в противном случае система игнорирует этот флаг. Дополнительные сведения см. в разделе "Вы можете обойти правила AppLocker с помощью макроса Office на компьютере под управлением Windows 7 или Windows Server 2008 R2" базы знаний справки и поддержки по адресу https://support.microsoft.com/kb/2532445.

Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP: AppLocker появился в Windows 7 и Windows Server 2008 R2.

LOAD_LIBRARY_AS_DATAFILE
0x00000002
Если используется это значение, система сопоставляет файл с виртуальным адресным пространством вызывающего процесса, как если бы он был файлом данных. Для выполнения или подготовки к выполнению сопоставленного файла ничего не делается. Таким образом, с помощью этой библиотеки DLL нельзя вызывать такие функции, как GetModuleFileName, GetModuleHandle или GetProcAddress . Использование этого значения приводит к нарушению доступа при записи в память только для чтения. Используйте этот флаг, если требуется загрузить библиотеку DLL только для извлечения сообщений или ресурсов из нее.

Это значение можно использовать с LOAD_LIBRARY_AS_IMAGE_RESOURCE. Дополнительные сведения см. в подразделе "Примечания".

LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
0x00000040
Аналогично LOAD_LIBRARY_AS_DATAFILE, за исключением того, что DLL-файл открывается с монопольным доступом на запись для вызывающего процесса. Другие процессы не могут открыть DLL-файл для доступа на запись, пока он используется. Однако библиотека DLL по-прежнему может быть открыта другими процессами.

Это значение можно использовать с LOAD_LIBRARY_AS_IMAGE_RESOURCE. Дополнительные сведения см. в подразделе "Примечания".

Windows Server 2003 и Windows XP: Это значение не поддерживается до Windows Vista.

LOAD_LIBRARY_AS_IMAGE_RESOURCE
0x00000020
Если используется это значение, система сопоставляет файл с виртуальным адресным пространством процесса как файл изображения. Однако загрузчик не загружает статические операции импорта и не выполняет другие обычные шаги инициализации. Используйте этот флаг, если требуется загрузить библиотеку DLL только для извлечения сообщений или ресурсов из нее.

Если приложение не зависит от файла с макетом изображения в памяти, это значение следует использовать с LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE или LOAD_LIBRARY_AS_DATAFILE. Дополнительные сведения см. в разделе «Примечания».

Windows Server 2003 и Windows XP: Это значение не поддерживается до Windows Vista.

LOAD_LIBRARY_SEARCH_APPLICATION_DIR
0x00000200
Если используется это значение, в каталоге установки приложения выполняется поиск библиотеки DLL и ее зависимостей. Каталоги в стандартном пути поиска не выполняются. Это значение не может быть объединено с LOAD_WITH_ALTERED_SEARCH_PATH.

Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Для этого значения требуется установить KB2533623 .

Windows Server 2003 и Windows XP: Это значение не поддерживается.

LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
0x00001000
Это значение представляет собой сочетание LOAD_LIBRARY_SEARCH_APPLICATION_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32 и LOAD_LIBRARY_SEARCH_USER_DIRS. Каталоги в стандартном пути поиска не выполняются. Это значение не может быть объединено с LOAD_WITH_ALTERED_SEARCH_PATH.

Это значение представляет рекомендуемое максимальное количество каталогов, которые приложение должно включать в свой путь поиска DLL.

Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Для этого значения требуется установить KB2533623 .

Windows Server 2003 и Windows XP: Это значение не поддерживается.

LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
0x00000100
Если используется это значение, каталог, содержащий библиотеку DLL, временно добавляется в начало списка каталогов, в которых выполняется поиск зависимостей библиотеки DLL. Каталоги в стандартном пути поиска не выполняются.

Параметр lpFileName должен указывать полный путь. Это значение не может быть объединено с LOAD_WITH_ALTERED_SEARCH_PATH.

Например, если Lib2.dll является зависимостью C:\Dir1\Lib1.dll, загрузка Lib1.dll с этим значением приводит к тому, что система будет искать Lib2.dll только в C:\Dir1. Чтобы найти Lib2.dll в C:\Dir1 и всех каталогах в пути поиска DLL, объедините это значение с LOAD_LIBRARY_SEARCH_DEFAULT_DIRS.

Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Для этого значения требуется установить KB2533623 .

Windows Server 2003 и Windows XP: Это значение не поддерживается.

LOAD_LIBRARY_SEARCH_SYSTEM32
0x00000800
Если используется это значение, выполняется поиск библиотеки DLL %windows%\system32 и ее зависимостей. Каталоги в стандартном пути поиска не выполняются. Это значение нельзя сочетать с LOAD_WITH_ALTERED_SEARCH_PATH.

Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Для этого значения требуется установить KB2533623 .

Windows Server 2003 и Windows XP: Это значение не поддерживается.

LOAD_LIBRARY_SEARCH_USER_DIRS
0x00000400
Если используется это значение, то в каталогах, добавленных с помощью функции AddDllDirectory или SetDllDirectory , выполняется поиск библиотеки DLL и ее зависимостей. Если добавлено несколько каталогов, порядок поиска по каталогам не указан. Каталоги в стандартном пути поиска не выполняются. Это значение нельзя сочетать с LOAD_WITH_ALTERED_SEARCH_PATH.

Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Для этого значения требуется установить KB2533623 .

Windows Server 2003 и Windows XP: Это значение не поддерживается.

LOAD_WITH_ALTERED_SEARCH_PATH
0x00000008
Если используется это значение, а lpFileName указывает абсолютный путь, система использует альтернативную стратегию поиска файлов, описанную в разделе Примечания, для поиска связанных исполняемых модулей, которые вызывает загрузка указанного модуля. Если используется это значение, а lpFileName указывает относительный путь, поведение не определено.

Если это значение не используется или lpFileName не указывает путь, система использует стандартную стратегию поиска, описанную в разделе Примечания, для поиска связанных исполняемых модулей, которые вызывает загрузка указанного модуля.

Это значение не может быть объединено с флагом LOAD_LIBRARY_SEARCH .

LOAD_LIBRARY_REQUIRE_SIGNED_TARGET
0x00000080
Указывает, что цифровая подпись двоичного изображения должна проверяться во время загрузки.

Для этого значения требуется Windows 8.1, Windows 10 или более поздней версии.

LOAD_LIBRARY_SAFE_CURRENT_DIRS
0x00002000
Если используется это значение, загрузка библиотеки DLL для выполнения из текущего каталога разрешена только в том случае, если она находится в каталоге в списке безопасная загрузка.

Возвращаемое значение

Если функция выполняется успешно, возвращаемое значение является дескриптором загруженного модуля.

Если функция завершается сбоем, возвращается значение NULL. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.

Комментарии

Функция LoadLibraryEx очень похожа на функцию LoadLibrary . Различия заключаются в наборе необязательных поведений, которые предоставляет LoadLibraryEx :

  • LoadLibraryEx может загружать модуль DLL без вызова функции DllMain библиотеки DLL.
  • LoadLibraryEx может загружать модуль способом, оптимизированным для случая, когда модуль никогда не будет выполняться, загружая модуль как файл данных.
  • LoadLibraryEx может находить модули и связанные с ними модули с помощью двух стратегий поиска или выполнять поиск по набору каталогов, зависящих от процесса.
Эти необязательные варианты поведения можно выбрать, задав параметр dwFlags ; Если значение dwFlags равно нулю, LoadLibraryEx ведет себя так же, как LoadLibrary.

Вызывающий процесс может использовать дескриптор, возвращенный LoadLibraryEx , для идентификации модуля в вызовах функций GetProcAddress, FindResource и LoadResource .

Чтобы включить или отключить сообщения об ошибках, отображаемые загрузчиком во время загрузки библиотеки DLL, используйте функцию SetErrorMode .

Небезопасно вызывать LoadLibraryEx из DllMain. Дополнительные сведения см. в разделе Примечания статьи DllMain.

Visual C++: Компилятор Visual C++ поддерживает синтаксис, позволяющий объявлять локальные переменные потока: _declspec(thread). Если вы используете этот синтаксис в библиотеке DLL, вы не сможете загрузить библиотеку DLL явным образом с помощью LoadLibraryEx в версиях Windows до Windows Vista. Если библиотека DLL будет загружена явным образом, вместо _declspec(thread) необходимо использовать функции локального хранения потока. Пример см. в статье Использование локального хранилища потока в библиотеке динамической компоновки.

Загрузка библиотеки DLL в качестве файла данных или ресурса изображения

Значения LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE и LOAD_LIBRARY_AS_IMAGE_RESOURCE влияют на количество ссылок на процесс и загрузку указанного модуля. Если для параметра dwFlags указано какое-либо из этих значений, загрузчик проверяет, был ли модуль уже загружен процессом в виде исполняемой библиотеки DLL. Если это так, это означает, что модуль уже сопоставлен с виртуальным адресным пространством вызывающего процесса. В этом случае LoadLibraryEx возвращает дескриптор библиотеке DLL и увеличивает число ссылок dll. Если модуль DLL еще не был загружен в виде библиотеки DLL, система сопоставляет модуль как файл данных или изображения, а не исполняемую библиотеку DLL. В этом случае LoadLibraryEx возвращает дескриптор загруженного файла данных или изображения, но не увеличивает число ссылок для модуля и не делает модуль видимым для таких функций, как CreateToolhelp32Snapshot или EnumProcessModules.

Если LoadLibraryEx вызывается дважды для одного и того же файла с LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE или LOAD_LIBRARY_AS_IMAGE_RESOURCE, для файла создаются два отдельных сопоставления.

При использовании значения LOAD_LIBRARY_AS_IMAGE_RESOURCE модуль загружается как образ с помощью расширения выравнивания разделов переносимого исполняемого файла (PE). Относительные виртуальные адреса (RVA) не нужно сопоставлять с адресами дисков, чтобы ресурсы можно было быстрее получить из модуля. Указание LOAD_LIBRARY_AS_IMAGE_RESOURCE не позволяет другим процессам изменять модуль во время его загрузки.

Если приложение не зависит от конкретных характеристик сопоставления изображений, значение LOAD_LIBRARY_AS_IMAGE_RESOURCE следует использовать с LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE или LOAD_LIBRARY_AS_DATAFILE. Это позволяет загрузчику выбрать, следует ли загрузить модуль в качестве ресурса изображения или файла данных. Выбор любого варианта позволяет системе более эффективно предоставлять общий доступ к страницам. Функции ресурсов, такие как FindResource, могут использовать любое сопоставление.

Чтобы определить, как был загружен модуль, используйте один из следующих макросов для тестирования дескриптора, возвращаемого LoadLibraryEx.

#define LDR_IS_DATAFILE(handle)      (((ULONG_PTR)(handle)) &  (ULONG_PTR)1)
#define LDR_IS_IMAGEMAPPING(handle)  (((ULONG_PTR)(handle)) & (ULONG_PTR)2)
#define LDR_IS_RESOURCE(handle)      (LDR_IS_IMAGEMAPPING(handle) || LDR_IS_DATAFILE(handle))

В следующей таблице описаны эти макросы.

Макрос Описание
LDR_IS_DATAFILE(дескриптор) Если этот макрос возвращает значение TRUE, модуль был загружен в виде файла данных (LOAD_LIBRARY_AS_DATAFILE или LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE).
LDR_IS_IMAGEMAPPING(дескриптор) Если этот макрос возвращает значение TRUE, модуль был загружен в виде файла изображения (LOAD_LIBRARY_AS_IMAGE_RESOURCE).
LDR_IS_RESOURCE(дескриптор) Если этот макрос возвращает значение TRUE, модуль был загружен как файл данных или файл изображения.
 

Используйте функцию FreeLibrary , чтобы освободить загруженный модуль независимо от того, привела ли загрузка модуля к его количеству ссылок. Если модуль был загружен в виде файла данных или изображения, сопоставление удаляется, но количество ссылок не уменьшается. В противном случае количество ссылок dll уменьшается. Таким образом, можно безопасно вызывать FreeLibrary с любым дескриптором, возвращенным LoadLibraryEx.

Поиск библиотек DLL и зависимостей

Путь поиска — это набор каталогов, в которых выполняется поиск библиотеки DLL. Функция LoadLibraryEx может искать библиотеку DLL с помощью стандартного пути поиска или измененного пути поиска, а также использовать путь поиска для конкретного процесса, установленный с помощью функций SetDefaultDllDirectories и AddDllDirectory . Список каталогов и порядок их поиска см. в разделе Dynamic-Link Library Search Order.

Функция LoadLibraryEx использует стандартный путь поиска в следующих случаях:

  • Имя файла указывается без пути, а базовое имя файла не соответствует базовому имени файла загруженного модуля и не используется ни один из флагов LOAD_LIBRARY_SEARCH .
  • Указан путь, но LOAD_WITH_ALTERED_SEARCH_PATH не используется.
  • Приложение не указало путь поиска dll по умолчанию для процесса с помощью SetDefaultDllDirectories.

Если lpFileName указывает относительный путь, весь относительный путь добавляется к каждому маркеру в пути поиска DLL. Чтобы загрузить модуль из относительного пути без поиска другого пути, используйте GetFullPathName , чтобы получить нерелятивный путь, и вызовите LoadLibraryEx с нерелятивным путем. Если модуль загружается как файл данных, а относительный путь начинается с "." или "..", относительный путь рассматривается как абсолютный путь.

Если lpFileName указывает абсолютный путь, а dwFlags имеет значение LOAD_WITH_ALTERED_SEARCH_PATH, LoadLibraryEx использует измененный путь поиска. Поведение не определено, если установлен флаг LOAD_WITH_ALTERED_SEARCH_PATH , а lpFileName указывает относительный путь.

Для изменения пути поиска можно использовать функцию SetDllDirectory . Это решение лучше, чем использование SetCurrentDirectory или жесткое написание полного пути к библиотеке DLL. Однако имейте в виду, что использование SetDllDirectory фактически отключает безопасный режим поиска DLL, когда указанный каталог находится в пути поиска и не является потокобезопасным. Если это возможно, лучше всего использовать AddDllDirectory для изменения пути поиска процесса по умолчанию. Дополнительные сведения см. в разделе Dynamic-Link Library Search Order.

Приложение может указать каталоги для поиска одного вызова LoadLibraryEx с помощью флагов LOAD_LIBRARY_SEARCH_* . Если указано несколько LOAD_LIBRARY_SEARCH флагов, поиск в каталогах выполняется в следующем порядке:

  • Каталог, содержащий библиотеку DLL (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR). В этом каталоге выполняется поиск только зависимостей загружаемой библиотеки DLL.
  • Каталог приложения (LOAD_LIBRARY_SEARCH_APPLICATION_DIR).
  • Пути, явно добавленные в путь поиска приложения с помощью функции AddDllDirectory (LOAD_LIBRARY_SEARCH_USER_DIRS) или SetDllDirectory . Если добавлено несколько путей, порядок поиска путей не указан.
  • Каталог System32 (LOAD_LIBRARY_SEARCH_SYSTEM32).

Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Флаги LOAD_LIBRARY_SEARCH_ доступны в системах с установленными KB2533623 . Чтобы определить, доступны ли флаги, используйте GetProcAddress , чтобы получить адрес функции AddDllDirectory, RemoveDllDirectory или SetDefaultDllDirectories . Если getProcAddress завершается успешно, с LoadLibraryEx можно использовать флаги LOAD_LIBRARY_SEARCH_.

Если приложение использовало функцию SetDefaultDllDirectories для создания пути поиска DLL для процесса и ни один из флагов LOAD_LIBRARY_SEARCH_* , функция LoadLibraryEx использует путь поиска dll процесса вместо стандартного пути поиска.

Если указан путь и с приложением связан файл перенаправления, функция LoadLibraryEx выполняет поиск модуля в каталоге приложения. Если модуль существует в каталоге приложения, LoadLibraryEx игнорирует спецификацию пути и загружает модуль из каталога приложения. Если модуль не существует в каталоге приложения, функция загружает модуль из указанного каталога. Дополнительные сведения см. в разделе Перенаправление библиотек динамической компоновки.

Если вы вызываете LoadLibraryEx с именем сборки без спецификации пути и сборка указана в манифесте, совместимом с системой, вызов автоматически перенаправляется в параллельную сборку.

Замечания по безопасности

LOAD_LIBRARY_AS_DATAFILE не запрещает другим процессам изменять модуль во время его загрузки. Так как это может сделать приложение менее безопасным, следует использовать LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE вместо LOAD_LIBRARY_AS_DATAFILE при загрузке модуля в виде файла данных, если только не нужно использовать LOAD_LIBRARY_AS_DATAFILE. Указание LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE не позволяет другим процессам изменять модуль во время его загрузки. Не указывайте LOAD_LIBRARY_AS_DATAFILE и LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE в одном вызове.

Не используйте функцию SearchPath для получения пути к библиотеке DLL для последующего вызова LoadLibraryEx . Функция SearchPath использует порядок поиска, отличный от LoadLibraryEx , и не использует безопасный режим поиска процессов, если этот режим явно не включен путем вызова SetSearchPathMode с BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE. Поэтому SearchPath , скорее всего, сначала выполняет поиск указанной библиотеки DLL в текущем рабочем каталоге пользователя. Если злоумышленник скопировал вредоносную версию библиотеки DLL в текущий рабочий каталог, путь, полученный SearchPath , будет указывать на вредоносную библиотеку DLL, которую затем загрузит LoadLibraryEx .

Не делайте предположений о версии операционной системы на основе вызова LoadLibraryEx , который ищет библиотеку DLL. Если приложение выполняется в среде, где библиотека DLL отсутствует, но в пути поиска находится вредоносная версия библиотеки DLL, может быть загружена вредоносная версия библиотеки DLL. Вместо этого используйте рекомендуемые методы, описанные в разделе Получение версии системы.

Общие сведения о проблемах безопасности БИБЛИОТЕК DLL см. в статье Безопасность библиотеки Динамической компоновки.

Примеры

В следующем примере кода демонстрируется вызов LoadLibraryExA.

//Load the FMAPI DLL
hLib = ::LoadLibraryEx(L"fmapi.dll", NULL, NULL);
if ( !hLib )
{
      wprintf(L"Could not load fmapi.dll, Error #%d.\n", GetLastError());
      return;
}

Дополнительный пример см. в разделе Поиск текста для номеров кодов ошибок.

Примечание

Заголовок libloaderapi.h определяет LoadLibraryEx в качестве псевдонима, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора UNICODE. Сочетание использования псевдонима, не зависящий от кодировки, с кодом, не зависящим от кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.

Требования

Требование Значение
Минимальная версия клиента Windows XP [только классические приложения]
Минимальная версия сервера Windows Server 2003 [только классические приложения]
Целевая платформа Windows
Header libloaderapi.h (включая Windows.h)
Библиотека Kernel32.lib
DLL Kernel32.dll

См. также

DllMain

Функции библиотеки динамической компоновки

Порядок поиска библиотеки динамической компоновки (DLL)

Безопасность библиотек динамической компоновки

FindResource

FreeLibrary

Функция GetProcAddress

GetSystemDirectory

GetWindowsDirectory

LoadLibrary

LoadResource

OpenFile

Динамическое связывание во время выполнения

SearchPath

SetDllDirectory

SetErrorMode