2011年7月15日 星期五

PS/2 Mouse Filter Driver and Hook Procedure

PS/2 mouse driver 的 stack 如下:

    Mouclass (mouse class filter driver)
    (Optional mouse filter driver)
    I8042prt (function driver)
    ACPI (bus driver)
    -----------
    Device

I8042prt 為 function driver, 透過 IRQ 12 及 PS/2 mouse I/O port 60h/64h 收發資料. Mouclass 為 upper-level class filter driver, 負責與下層串接, 重置滑鼠裝置, 並將下層送來的滑鼠移動資訊送至作業系統. 在 I8042prt 與 Mouclass 間, 我們可以插入更多的 filter driver, 以攔截或更改滑鼠移動資訊.

Windows 載入 driver 的順序是從下層至上層, 首先 bus driver 會回報 device 資訊, 以讓 Windows 掛載相對應的 function driver - I8042prt, 接著依序掛上 filter driver. Mouclass 為最後一個 filter driver, 當它被掛載後, 便會開始進行上下層 driver 串接的動作, 如下:

  1. Mouclass 往下層送 IOCTL_INTERNAL_MOUSE_CONNECT 這個要求以建立滑鼠移動資訊的傳遞路徑, 並夾帶自己的 device object 與 service callback 指標.
  2. 下層 filter driver 收到此一要求, 便將上層的 device object 及 service callback 存下來(之後用來將資料往上層送), 並將自己的 device object 與 service callback 指標取代之, 然後繼續將此要求往下送.
  3. 重覆 2, 直到 I8042prt 收到此要求. I8042prt 一樣是將上層的 device object 與 service callback 指標存起來, 以在有滑鼠移動資訊時呼叫.
  4. I8042prt 完成此次要求後, 主動往 Mouclass 送 IOCTL_INTERNAL_I8042_HOOK_MOUSE 這個要求以建立起客製化 ISR 的路徑(譬如修改每一個收到的 data byte), 並夾帶一個 INTERNAL_I8042_HOOK_MOUSE 資料物件, 其中包含了 IsrRoutine, IsrWritePort 及 QueueMousePacket callback 等, 在此 IsrRoutine 則為 NULL, 因為 I8042prt 的 ISR 是第一個收到 data byte 的 callback, 資料傳到 Mouclass 後, 不需再做一次, 否則會造成無窮迴圈.
  5. Mouclass 收到此一要求, 便將整個 INTERNAL_I8042_HOOK_MOUSE 資料物件存下來(特別是其中的 IsrWritePort, 可用來送資料到 device), 並將自己的 device context 及客製化的 ISR callback 取代原本資料物件中的 Context 及 IsrRoutine, 然後繼續將此要求往下送.
  6. 下層 filter driver 收到此一要求,  也跟 Mouclass 做的一樣, 並繼續將此要求往下送.
  7. 重覆 6, 直到 I8042prt 收到此一要求. I8042prt 將上層傳來的 Context 及 IsrRoutine 存下來, 以便在自己 ISR 被呼叫時, 在其中呼叫 filter driver 提供的客製流程.
  8. I8042prt 自己完成此次要求.
建立串接的路徑, 就相當於將整個 driver stack 的資料流串起來, 如何去處理收到的資料, 就又是另一回事了, 可參閱 MSDN.


更多資訊:
Standard Keyboard and Mouse Driver Stacks
Operation of Non-HIDClass Keyboard and Mouse Drivers

沒有留言:

張貼留言