Создание потоков драйвером  
      В случае, когда использование системных рабочих потоков невозможно, драйвер 
        должен создать свой собственный поток. Для создания нового потока используется 
        функция PsCreateSystemThread(). В качестве одного из параметров функция 
        имеет описатель процесса, в контексте которого нужно создать поток. Чтобы 
        правильно использовать описатель, код драйвера должен выполняться в контексте 
        процесса, таблица описателей которого содержит описатель процесса, в контексте 
        которого мы хотим создать поток. Если описатель процесса не указан (значение 
        NULL), новый поток будет создан в контексте процесса System. 
        Для уничтожения потока из драйвера используется функция PsTerminate SystemThread(). 
        Эта функция должна быть вызвана из самого уничтожаемого потока, так как 
        она уничтожает текущий поток и не позволяет указать поток, который нужно 
        уничтожить. 
        Вновь созданный поток будет работать на уровне IRQL PASSIVE_LEVEL и иметь 
        базовое значение приоритета планирования равным 8 (динамический диапазон 
        приоритетов, базовое значение для класса NORMAL). После создания код потока 
        может изменить базовое значение приоритета планирования на любое значение 
        в диапазоне динамических приоритетов либо приоритетов реального времени. 
        Это делается с помощью функции KeSetPriorityThread(). Отметим, что это 
        не повышение уровня приоритета планирования, после которого уровень приоритета 
        постепенно снизится до базового значения, а именно установка нового базового 
        значения приоритета. 
        Код потока может не только изменить значение приоритета планирования при 
        уровне IRQL PASSIVE_LEVEL, но и повысить уровень IRQL. Для этого служит 
        функция KeRaiselrql(). Работа потока на повышенном уровне IRQL должна 
        быть завершена как можно скорее, после чего должно быть восстановлено 
        первоначальное значение IRQL с помощью функции KeLowerlrql(). Использование 
        функции KeRaiselrql() для понижения IRQL и функции KeLowerlrql() для повышения 
        IRQL не допускается, так как это приведет к возникновению синего экрана.  |