開發鍵盤過濾驅動實現模擬按鍵過程中遇到的問題

2021-06-07 04:49:09 字數 1833 閱讀 8025

如何動態御載鍵盤過濾驅動

要做到動態御載鍵盤過濾驅動,明白其工作執行的原理是很重要的。首先必須要知道鍵盤過濾驅動是工作在非同步模式下的,這一點很重要。為了得到乙個按鍵操作,首先需要傳送乙個irp_mj_read到驅動的裝置棧,驅動收到這個irp會做什麼樣的處理呢?它會一直保持這個irp為pending未確定狀態,因為其實現在一直沒有按鍵操作,直到乙個鍵被真正的按下,驅動此時就會立刻完成這個irp,並將剛按下的鍵的相關資料做為該irp的返回值。在該irp帶著對應的資料返回後,作業系統將這些值傳遞給對應的事件系統來處理,然後做什麼呢??系統緊接著又會立刻傳送乙個irp_mj_read請求,等待下次的按鍵操作,重複以上的步驟。也就是說,任何時候裝置棧底都會有乙個鍵盤的irp_mj_read請求處於pending未確定狀態。這意味著只有在該irp完成返回,並卻新的irp請求還未傳送到的時候才會有乙個很短暫的時間。由此我們想到,我們按照一般的方式動態御載鍵盤過濾驅動的時候,基本都是有irp_mj_read請求處於pending未確定狀態,而我們卻御載了驅動,以後按鍵的時候需要處理這個irp卻找不到對應的驅動當然會藍屏。

以上分析了動態御載鍵盤過濾驅動藍屏的原因,分析到了中間存在乙個短暫的時間棧底是沒有irp的,那麼讓我們想辦法來解決它。

網上乙份e文資料顯示,只有使用ioattachdevice掛接/device/keyboardclass0(or others)才可以動態御載,而載入到upperfilters的卻不能。以下是該段的原文:

讓我們再深入分析下藍屏的原因,棧底有irp為什麼我們的驅動御載就會有問題呢?這是由於irm_mj_read是非同步的,對於非同步的請求,基本上我們會關心這個非同步請求的結果,如何得到完成後的資料呢?大家一定想到了,設定完成例程。對,就是這樣,由於我們給irp_mj_read設定了完成例程,該irp完成後會呼叫我們的完成例程,使我們有處理返回資料的機會。在這樣的情況下,我們動態御載了鍵盤過濾驅動,也就是說完成例程已經被我們御載掉了,而以後的再次按鍵在完成這個irp後會呼叫這個根本已經不存在了的東東,結果藍屏就可想而知了。

那是否是不設定完成例程就不會有問題了呢?答案是肯定的。可是沒有完成例程我們就沒有辦法處理到返回的資料,也就在很大程度上失去了鍵盤過濾驅動的作用了。如何做到既能設定完成例程來處理資料又可以實現動態的御載呢?這裡我們這樣想,當有irp_mj_read到來的時候,我不為這個irp設定完成例程,也不將該irp向下傳遞,而是建立乙個我自己的irp,並參考前面的irp_mj_read做對應的設定,然後為我自己的這個irp設定完成例程後將我的irp向下傳遞,並設定原來的irp_mj_read為pending狀態。當有按鍵操作時,我的irp返回觸發為它設定的完成例程,在這裡取得返回的資料填充前面的irp_mj_read後將該irp_mj_read完成返回。相當於我們使用了乙個**,而這一切都是透明的。到這裡我們實現了完成例程,也就是有了處理資料的機會。下面該說到重點了,那就是這樣處理後又如何實現動態的御載呢?

假設現在我們收到御載的請求,讓我們看看當前所有的irp處於何種狀態:

(1)乙個我們儲存的原本的irp_mj_read處於pending,注意它並沒向下傳遞,也未設定完成例程。

(2)乙個我們自己構造的irp處於棧底,並注意我們為自己的這個irp設定了完成例程。

基本就這2個irp,由於我們自己的irp有完成例程,所以直接御載會出現和上面一樣的情況,導致藍屏。如何處理呢?這裡注意到是我們自己構造的irp,所以我們可以將其取消,這樣並不會有太大的影響。可是取消後棧底本來該有的irp_mj_read就沒有了,注意到(1),我們不是還有原來的irp_mj_read嗎?對,就是將原來的這個irp_mj_read向下傳遞,這裡千萬注意,我們自己的驅動馬上要御載,所以我們傳遞原來的irp_mj_read的時候不要給它設定完成例程。向下傳遞後御載我們的驅動。哈哈,成功!!!

當然,這裡還有更簡單的辦法,使用計數器也可以實現,還簡單的多:)

驅動中實現模擬鍵盤按鍵

標 題 驅動中實現模擬鍵盤按鍵 作 者 luocong 在ring3中實現模擬鍵盤按鍵有n n種方式,比如sendinput keybd event 但在驅動中要怎麼模擬呢?1 寫埠 define defi8042 data port puchar 0x60 define defi8042 ctrl...

驅動中實現模擬鍵盤按鍵

標 題 驅動中實現模擬鍵盤按鍵 作 者 luocong 在ring3中實現模擬鍵盤按鍵有n n種方式,比如sendinput keybd event 但在驅動中要怎麼模擬呢?1 寫埠 define defi8042 data port puchar 0x60 define defi8042 ctrl...

鍵盤過濾驅動快捷實現

最近在網上無意中看到一段 主要講述的是windows 下鍵盤過濾驅動的實現方式,這段 很有意識,是一種比較好的一種方法,主要將獲取的鍵盤驅動物件的所有分發函式替換,然後另行處理,具體的 如下 獲取鍵盤驅動物件 status obreferenceobjectbyname unintnamestrin...