Фиксация страничных секций кода и данных в оперативной памяти
В некоторых случаях имеет смысл применить обратные манипуляции, то есть зафиксировать в оперативной памяти фрагменты данных или кода, которые изначально (при компиляции) были размещены в странично организованной памяти. Это может дать положительный эффект, выражающийся в повышении быстродействия драйвера или снижения времени реакции на события (например, запрос пользователя). Например, при неблагоприятных условиях задержка вызова странично размещенной процедуры обработки IOCTL запросов (по вызову DeviceIoControl пользовательского режима) может достигать десятых долей секунды, независимо от быстродействия самого процессора.
Фиксация секций страничной памяти данных и кода выполняется при помощи вызовов MmLockPagableDataSection и MmLockPagableCodeSection
соответственно. В качестве параметра этим функциям передается адрес, указывающий внутрь интересующей области — адрес элемента данных или адрес интересующей процедуры. Возвращаемые этими вызовами дескрипторы следует сохранить — они потребуются для последующего системного вызова MmUnlockPagableImageSection, используемого для восстановления прежнего статуса соответствующих областей виртуальной памяти (уменьшения числа ссылок на такие области).
Применение вызовов MmLockPagableDataSection/MmLockPagableCodeSection
повторно к одной и той же области является расточительным приемом. Поэтому, если драйвер вынужден использовать эти вызовы повторно, то следует использовать функцию MmLockPagableSectionByHandle, используя первоначально полученный дескриптор. В противном случае, рекомендуется вести учет вызовов функций MmLockPagableDataSection/MmLockPagableCodeSection, чтобы не выполнять лишней работы.
Для того чтобы программно контролировать отдельный набор данных, можно поместить эти данные автономно, как показано ниже:
#pragma data_seg("MY_DATA") <описание переменных> #pragma data_seg()
После этого контроль можно осуществлять по адресу любой из описанных в этом сегменте переменных.
Применять приведенные функции для фиксации в оперативной памяти буферных областей, поступивших в пакете IRP, нельзя — для этого следует использовать специально для того предназначенный вызов MmProbeAndLockPages.
Все упомянутые выше вызовы следует выполнять только в коде, работающем на уровне IRQL равном PASSIVE_LEVEL.