Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Драйвер может зарегистрировать подпрограмму CustomTimerDpc , вызвав следующие подпрограммы, как правило, из своей подпрограммы AddDevice :
KeInitializeDpc для регистрации своей подпрограммы
KeInitializeTimer или KeInitializeTimerEx для настройки объекта таймера
Впоследствии драйвер может вызвать KeSetTimer или KeSetTimerEx, чтобы указать время окончания срока действия и добавить объект таймера в очередь таймера системы. По достижении срока действия система отменяет объект таймера и вызывает подпрограмму CustomTimerDpc . На следующем рисунке показаны эти вызовы.
Как показано на предыдущем рисунке, драйвер должен предоставить хранилище как для объекта DPC, так и для объекта таймера. Большинство драйверов предоставляют хранилище для этих объектов в расширении устройства или в другой выделенной драйвером памяти резидентной памяти.
В вызове KeSetTimer драйвер передает указатели на объекты Dpc и Timer , а также DueTime , выраженный в единицах 100 наносекунд, как показано на предыдущем рисунке. Положительное значение для DueTime указывает абсолютное время окончания срока действия (с 1 января 1601 г.), в котором должна вызываться подпрограмма CustomTimerDpc . Отрицательное значение для DueTime указывает относительное время окончания срока действия.
Поскольку срок действия абсолютного таймера истекает в определенное системное время, длительность ожидания абсолютного таймера не влияет, если системное время изменяется до истечения срока действия таймера. С другой стороны, относительный таймер всегда истекает после указанного числа единиц времени, независимо от изменений в абсолютном системном времени.
Чтобы повторно вызвать подпрограмму CustomTimerDpc , используйте KeSetTimerEx , чтобы задать таймер и указать повторяющийся интервал в параметре Period . KeSetTimerEx так же, как KeSetTimer , за исключением этого дополнительного параметра.
Как показано на предыдущем рисунке, вызов KeSetTimer или KeSetTimerEx помещает в очередь объект таймера для указанного интервала следующим образом:
По истечении срока действия DueTime объект таймера извлекается из очереди и переводится в сигнальное состояние.
Если каждый процессор на компьютере в настоящее время выполняет код в IRQL больше или равно DISPATCH_LEVEL, объект DPC, связанный с объектом таймера, помещается в очередь DPC. В противном случае вызывается подпрограмма CustomTimerDpc .
Если объект DPC уже был в очереди, когда истек интервал DueTime , подпрограмма CustomTimerDpc вызывается, как только IRQL на любом процессоре на компьютере падает ниже DISPATCH_LEVEL.
Примечание.
Подпрограмма CustomTimerDpc, как и все функции DPC, вызывается на уровне IRQL = DISPATCH_LEVEL. Хотя подпрограмма DPC выполняется, все потоки не могут работать на одном процессоре. Разработчики драйверов должны тщательно разрабатывать свои подпрограммы CustomTimerDpc, чтобы они выполнялись за как можно более короткое время.
Наименьший интервал времени, который можно указать для KeSetTimer и KeSetTimerEx, составляет около десяти миллисекунд, поэтому драйвер может использовать рутин CustomTimerDpc для задания интервалов времени, меньших чем рутин IoTimer, которая может обрабатываться при выполнении один раз в секунду.
В любой момент может быть в очереди только один экземпляр определенного объекта таймера. Вызов KeSetTimer или KeSetTimerEx снова с тем же указателем объекта Timer отменяет находящийся в очереди объект таймера и сбрасывает его.
Настройка подпрограммы CustomTimerDpc точно похожа на настройку подпрограммы CustomDpc с дополнительным шагом для инициализации объекта таймера. На самом деле их прототипы идентичны, но подпрограмма CustomTimerDpc не может использовать два указателя SystemArgument , объявленные в своем прототипе.