Page 85 - 4989
P. 85
направляє йому IRP типу IRP_MJ_READ. Отримавши IRP,
драйвер Kbdclass відзначає його як очікуючий завершення
(pending), ставить у чергу і повертає STATUS_PENDING. Потоку
необробленого вводу доведеться чекати завершення IRP.
Підключаючись до стека, драйвер Kbdclass реєструє у драйвера
i8042prt процедуру зворотного виклику
KeyboardClassServiceCallback, направляючи йому IRP
IOCTL_INTERNAL_KEYBOARD_CONNECT. Драйвер i8042prt
теж реєструє у системі свою процедуру обробки переривання
I8042KeyboardInterruptService, викликом функції
IoConnectInterrupt. Коли буде натиснута або відпущена клавіша,
контролер клавіатури згенерує апаратне переривання. Його
обробник викличе I8042KeyboardInterruptService, яка прочитає з
внутрішньої черги контролера клавіатури необхідні дані.
Оскільки обробка апаратного переривання відбувається на
підвищеному IRQL, процедура обробки виконує тільки найбільш
невідкладну роботу і ставить у чергу виклик відкладеної
процедури (DPC). DPC працює при IRQL = DISPATCH_LEVEL.
Коли IRQL знизиться до DISPATCH_LEVEL, система викличе
процедуру I8042KeyboardIsrDpc, яка викличе зареєстровану
драйвером Kbdclass процедуру зворотного виклику
KeyboardClassServiceCallback (також виконується на IRQL =
DISPATCH_LEVEL). KeyboardClassServiceCallback дістане зі
своєї черги очікуючий на завершення IRP, заповнить структуру
KEYBOARD_INPUT_DATA, що несе всю необхідну інформацію
про натискання/відпускання клавіш, і завершить IRP. Потік
необробленого вводу пробуджується, обробляє отриману
інформацію і знову посилає IRP типу IRP_MJ_READ драйверу
класу, який знову ставиться в чергу до наступного натискання /
відпускання клавіші. Таким чином, у стека клавіатури завжди є,
принаймні один очікуючий завершення IRP і знаходиться він у
черзі драйвера Kbdclass.
У даній роботі слід розробити драйвер-фільтр, який
встановлюється над фільтром Kbdclass. Оскільки IRP типу
IRP_MJ_READ є фактично запитом на читання даних, то коли він
йде вниз по стеку, його буфер порожній. Прочитані дані буфер
буде містити тільки після завершення IRP. Для того, щоб ці дані
побачити, фільтр повинен встановити в кожний IRP (точніше у
85