Макрос MmLockPagableCodeSection (wdm.h)
В MmLockPagableCodeSection подпрограмма блокирует раздел кода драйвера, содержащий набор подпрограмм драйверов, помеченных специальной директивой компилятора, в системное пространство.
Синтаксис
void MmLockPagableCodeSection(
[in] Address
);
Параметры
[in] Address
Указывает символьный адрес. Этот адрес обычно называется функцией драйвера в разделе кода драйвера, помеченного как #pragma alloc_text (PAGExxxx, driverfunction). Все функции в разделе PAGExx гарантированно будут заблокированы при возврате этой функции.
Возвращаемое значение
Никакой
Замечания
MmLockPagableCodeSection возвращает непрозрачное значение, используемое операционной системой для идентификации этого раздела кода драйвера. Это непрозрачное значение можно передать впоследствии в MmLockPagableSectionByHandle (если драйвер разблокирует, а затем переблокирует раздел) или MmUnlockPagableImageSection.
Подпрограмма MmLockPagableCodeSection и mmUnlockPagableImageSection (подпрограмма, выполняющая противоположное действие), поддерживают драйверы, которые могут выполнять следующие действия:
Отложите загрузку подмножества подпрограмм драйверов в резидентную память до тех пор, пока входящие запросы ввода-вывода устройств драйвера не позволяют обрабатывать irPs.
Сделайте одно и то же подмножество подпрограмм драйверов доступными для разбиения по страницам, когда они завершили обработку запросов ввода-вывода, а дополнительные запросы на устройства драйвера в настоящее время не ожидаются.
MmLockPagableCodeSection, MmLockPagableSectionByHandle и MmUnlockPagableImageSection предназначены для использования устройства и промежуточных драйверов, которые имеют следующие характеристики:
Драйвер имеет пути кода, которые могут не потребоваться во время выполнения системы, но, если они необходимы, код драйвера должен быть резидентом, так как он выполняется в произвольном контексте потока или в IRQL >= DISPATCH_LEVEL.
Драйвер может точно определить, когда нужно загрузить страничные подпрограммы и когда их можно вывести на страницу еще раз.
Например, системный драйвер отказоустойчивого диска поддерживает создание зеркальных наборов, наборов полос и наборов томов. Тем не менее, определенный компьютер можно настроить только с зеркальным набором, только с набором полос, только с набором томов или с любым сочетанием этих трех возможных вариантов. В этих случаях системный драйвер ftdisk уменьшает размер загруженного изображения путем маркировки подпрограмм, которые явно поддерживают зеркальное отображение, полосу и наборы томов как принадлежащие к страницам кода. Во время инициализации драйвера разделы кода, доступные для страниц, создаются только в том случае, если пользователь настроил диски на зеркальное отображение, полосу или наборы томов. Если пользователь динамически распределяет диски, драйвер ftdisk блокирует все дополнительные разделы кода, необходимые для поддержки любого зеркального отображения, полосы или тома, которые пользователь запрашивает.
В других примерах системные и параллельные драйверы имеют DispatchCreate и подпрограммы DispatchClose, вызываемые при открытии определенного порта для монопольного ввода-вывода и при освобождении дескриптора открытого порта соответственно. Тем не менее, последовательные и параллельные запросы ввода-вывода являются нерегулярными, определяемыми приложениями, которые в настоящее время выполняются конечным пользователем, и какие параметры приложения в настоящее время выполняются конечным пользователем. В этих случаях последовательные и параллельные драйверы системы сокращают размеры загруженных образов, помечая многие подпрограммы как относящиеся к разделу кода, который DispatchCreate подпрограмма делает резидент только при открытии первого порта для ввода-вывода.
Обратите внимание, что каждый из предыдущих системных драйверов удовлетворяет обоим критериям наличия разделов, доступных для страниц: драйвер имеет пути кода, которые могут не потребоваться во время выполнения системы, и драйвер может определить, когда должен быть загружен его раздел страницы, и его можно вывести на страницу еще раз.
Так как это дорогостоящая операция для блокировки раздела, если драйвер блокирует раздел кода для страницы в нескольких местах, используйте MmLockPagableCodeSection для первого запроса. Выполните последующие запросы блокировки путем вызова MmLockPagableSectionByHandle передачи дескриптора, возвращенного MmLockPagableCodeSection. Блокировка с помощью дескриптора значительно повышает производительность драйвера, так как диспетчер памяти использует непрозрачное возвращаемое значение, чтобы быстро найти соответствующий раздел, а не поиск в загруженном списке модулей. Заблокированный раздел разблокирован путем вызова MmUnlockPagableImageSection.
Каждый подпрограмма драйвера в разделе кода с возможностью страницы должна быть помечена следующей директивой компилятора:
#pragma alloc_text(PAGExxxx, DriverRoutine)
где xxxx является необязательным четырехзначным уникальным идентификатором для страницного раздела вызывающего абонента и DriverRoutine является точкой входа, которую необходимо включить в раздел кода, доступный для страниц. Ключевое слово PAGE и суффикс, определенный драйвером, который может быть до четырех символов, учитывает регистр; то есть PAGE должны быть прописными буквами.
Один вызов mmLockPagableCodeSection, например в подпрограмме DispatchCrea te, вызывает весь раздел, содержащий все подпрограммы драйвера, помеченные одним и тем же PAGExxxx идентификатором, заблокированным в системном пространстве.
Некоторые типы подпрограмм драйверов не могут быть включены в раздел, доступный для страницы драйвера, в том числе следующие:
Никогда не выполняйте страницы ISR. Драйвер устройства может получить спрогнозное прерывание, даже если его устройство не используется, особенно если вектор прерывания может быть предоставлен общий доступ. Как правило, даже если драйвер может явно отключить прерывания на своем устройстве, isR не должен быть доступен для страницы.
Никогда не создавайте подпрограмму DPC, если драйвер не может управлять очередью DPC, например любой DpcForIsr или подпрограммы CustomDpc, которые могут быть в очереди из ISR. Как правило, подпрограммы драйверов, выполняемые в IRQL >= DISPATCH_LEVEL, и которые могут вызываться в произвольном контексте потока или в ответ на случайное внешнее событие не должно выполняться на страницу.
Никогда не делайте DispatchRead или DispatchWrite страницы в любом драйвере, который может быть частью пути ввода-вывода системы. Драйвер диска, который может содержать системный файл страницы, должен иметь DispatchRead и DispatchWrite подпрограммы, которые находятся в системе во время работы системы, так как все драйверы уровня выше такого драйвера диска.
Обратите внимание, что подпрограммы в разделе, помеченном директивой компилятора #pragma alloc_text(PAGExxxxx, ...) отличаются от подпрограмм, помеченных директивой компилятора #pragma alloc_text(INIT, ...). Подпрограммы в разделе INIT недоступны для страничных страниц и удаляются, как только драйвер возвращается из его DriverEntry или его повторно инициализации подпрограммы, если он имеет один.
Диспетчер памяти поддерживает внутреннее число блокировок в любом разделе, который можно использовать для страниц драйвера. Вызовы MmLockPagableCodeSection увеличьте это число и взаимное MmUnlockPagableImageSection уменьшает количество. Раздел страницы драйвера недоступен, если это число не равно нулю.
Дополнительные сведения о создании разделов кода, доступных для страниц, см. в разделе Созданиедрайверов для страниц.
Требования
Требование | Ценность |
---|---|
целевая платформа | Настольный |
заголовка | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
библиотеки | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <=APC_LEVEL |