Функция 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
Если это значение используется, система сопоставляет файл с виртуальным адресным пространством вызывающего процесса, как если бы это был файл данных. Ничего не делается для выполнения или подготовки к выполнению сопоставленного файла. Таким образом, нельзя вызывать такие функции, как 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_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
Если это значение используется, %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 см. в разделе "Безопасность библиотеки динамической компоновки".

Примеры

В следующем примере кода демонстрируется вызов 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 или Юникод на основе определения константы препроцессора ЮНИКОДа. Сочетание использования нейтрализуемого кодировки псевдонима с кодом, который не является кодировкой нейтральным, может привести к несоответствиям, которые приводят к ошибкам компиляции или времени выполнения. Дополнительные сведения см. в соглашениях о прототипах функций.

Требования

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