Определение текущего уровня IRQL
Текущий уровень IRQL свой у каждого CPU. Код режима ядра может определить IRQL, в котором он выполняется, посредством вызова функции KeGetCurrentlrql (), прототип которой:
KIRQL KeGetCurrentlrql ();
KeGetCurrentlrql() возвращает IRQL текущего CPU.
Большинство подпрограмм драйвера устройства вызывается Диспетчером ввода/вывода на определенном архитектурой уровне IRQL. To есть разработчик драйвера знает уровень (или уровни) IRQL, на котором будет вызываться данная функция. Подпрограммы режима ядра могут изменять IRQL, на котором они выполняются, вызывая функции KeRaiselrql() и KeLowerlrql(), прототипы которых:
VOID KeRaiselrql (IN PKIRQL Newlrql, OUT PKIRQL Oldlrql);
Где: Newlrql - значение, до которого должен быть поднят уровень IRQL текущего процессора; Oldlrql - указатель на место, в которое будет помещен IRQL, на котором текущий процессор выполнялся перед тем, как был поднят к Newlrql.
VOID KeLowerlrql (IN KIRQL Newlrql);
Где: Newirql - значение,
до которого должен быть понижен IRQL текущего процессора.
Так как уровни IRQL являются методом синхронизации, большинство подпрограмм
режима ядра (в особенности драйверы устройств) никогда не должны понижать
свой уровень IRQL ниже того, на котором они вызывались. Таким образом,
драйверы могут вызывать KeRaiselrql (), чтобы поднять IRQL до более высокого
уровня, и затем вызывать KeLowerlrql(), чтобы возвратиться обратно к первоначальному
уровню IRQL, на котором они были вызваны (например, из Диспетчера ввода/вывода).
Однако драйвер никогда не должен вызывать функцию KeLowerlrql(), чтобы
понизить IRQL до уровня, меньшего, чем тот, на котором он был вызван.
Такое поведение может привести к крайне непредсказуемой работе операционной
системы, которая наверняка закончится полным отказом системы.