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
   80   81   82   83   84   85   86   87