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

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

Синтаксис

HMODULE LoadLibraryExW(
  [in] LPCWSTR 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
Если это значение используется, система сопоставляет файл с виртуальным адресным пространством вызывающего процесса, как если бы это был файл данных. Ничего не делается для выполнения или подготовки к выполнению сопоставленного файла. Таким образом, нельзя вызывать такие функции, как GetModuleFileName, GetModuleHandle или GetProcAddress с помощью этой библиотеки DLL. Использование этого значения приводит к тому, что операции записи в память только для чтения вызывают нарушение доступа. Используйте этот флаг, если вы хотите загрузить библиотеку 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_DEFAULT_DIRS.

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

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

LOAD_LIBRARY_SEARCH_SYSTEM32
0x00000800
Если это значение используется, %windows%\system32 выполняет поиск библиотеки 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_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(handle) Если этот макрос возвращает значение TRUE, модуль был загружен в виде файла данных (LOAD_LIBRARY_AS_DATAFILE или LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE).
LDR_IS_IMAGEMAPPING(handle) Если этот макрос возвращает значение TRUE, модуль был загружен в виде файла изображения (LOAD_LIBRARY_AS_IMAGE_RESOURCE).
LDR_IS_RESOURCE(handle) Если этот макрос возвращает значение TRUE, модуль был загружен как файл данных или файл изображения.
 

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

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

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

Функция 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 для изменения пути поиска по умолчанию процесса. Дополнительные сведения см. в разделе "Порядок поиска библиотеки динамической компоновки".

Приложение может указать каталоги для поиска одного вызова 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 выполнен успешно, флаги LOAD_LIBRARY_SEARCH_ можно использовать с LoadLibraryEx.

Если приложение использовало функцию 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 см. в разделе "Безопасность библиотеки динамической компоновки".

Примеры

Пример см. в разделе "Поиск текста" для номеров кодов ошибок.

Примечание

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

Требования

   
Минимальная версия клиента 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