找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 14671|回复: 0

[转载]支持 PS/2 与 USB 的键盘过滤驱动(可卸载) -- by sinister

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister5 w  g4 R: w3 Q2 W/ Y5 W. g% x
Email:   [email]sinister@whitecell.org[/email]; T. [2 K8 S0 {9 m8 l# e+ h
Homepage:[url]http://www.whitecell.org[/url]
& B, J. f8 q) W& xDate:    2007-02-26
) j* @& `, \2 \
4 v, s  o, t$ M6 n2 ~% T- C+ L! k  _
. w1 _$ f0 N- D& M8 j( Y7 k% `! Z/*******************************************************************
2 I4 m/ Q" b0 D" {4 L, i5 ?5 @4 I( y8 [$ U
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx" u" _  I. C6 I4 q' s: b
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的' }# f1 C% d9 G7 f) l; f
功能要求如下:
; D; A3 e8 Z" A" @& b, k
$ D0 g# Q, O& R; J1、强制锁定键盘/鼠标。  ?; ?& I. U# |: g, E/ `
2、可动态加/解锁
& Y0 h) O5 @* o3、兼容所有 NT 系列的操作系统。
1 |) @, g  g$ D& x( W; y5 Z, |3 W1 j# n  Z3 r+ R7 U( p2 d
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
( c$ R5 K  p# B6 b* e7 B4 r  p. @3 M现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
0 `6 q! z* o4 g/ ?; }何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
: u0 e; W4 |  E$ G% a! H$ ~% A上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是, t  ~2 l. p, ^3 }& s; @
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面8 |% T& w4 N9 o. Z8 ~1 m* j5 ~+ W
就来看一下我想到的几种实现方法:
; Y0 I$ d' b( E" t( a. S) e0 i2 [# n7 A
1、全局键盘/鼠标钩子
: w9 L9 m8 g: t) m2、BlockInput() API
- {& T+ @3 n6 F: Y- I+ L( f3、使用 setupapi 进行控制9 F1 s3 I5 s" [* ^0 }+ F
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL) `1 V, c, w( y% h
5、拦截 win23k!RawInputThread() 函数# D) M7 [. \+ y% h# T: w8 w  }- ?
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动" [: i$ L( b3 ^) l
7、拦截 kdbclass 驱动的 driver dispatch routine5 X5 z$ O! l; m7 j; k6 p9 ]
8、实现一个 PS/2 与 USB 键盘过滤驱动, c# }3 _. c: g! l) x; J

$ w6 g, W/ K. s: H/ b4 W; A4 Y4 l! r
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑5 f7 o3 j% v8 t/ T
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
" b) ~" t& u: I; W7 Q案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
. E% i$ @2 J( m. n+ \0 _7 o' s1 x8 _兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因. d0 ~8 Q1 p- g# j7 ?1 E- d) K3 w
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
0 `7 o/ H- E. u$ N* n问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸" B( J, X8 E) |! B& _- d
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我% d5 q) Z5 L  X3 O1 P
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来. Q5 o0 g2 Q7 C8 a: {
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
8 k/ U! t2 H: @7 c6 A0 x8 N果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
" s) j. V! e0 V  G) |1 d7 y障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
9 i* n# Y/ m& \" A7 PIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
; v/ N3 Y7 l9 b4 `+ s' n+ N9 QUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键  y. i1 @% H5 s& k  W3 F$ A
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方* L  c/ p7 }( v  f; Z
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
0 @: l& s  ^  o1 ?$ h* |! f
' D7 i5 ^% G. i5 P/ Z) D% U: v, ]! N
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
. C: _" N2 t! W% ]/ P- I. I2 U# @: H2 @滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进; I: }$ d- Z+ k% ?
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
! X; \, K( V# _4 p# W只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
7 \  K8 U. [: P: H7 A  d来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从# f! ?# y( ~: _  `1 |; N% o
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB, G/ z! h& Q+ ^' B  l3 k3 h6 g* L
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用! [* T3 X7 @6 X- Y; R- G
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
) Y% {, S+ c8 M% X/ U我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
! j& S; O5 r9 t& q" z就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
) j$ W0 W  ~" ]* f5 [# O8 f而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使. O+ K+ w% H: _+ O' Q* M8 {8 [
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通0 S* |, d, U, b0 x
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来2 J! Q* c7 l" d% }. O
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
/ r9 M* W5 B9 A( \, c过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
# w1 B2 J3 M" N0 T上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 9 U- ~6 s- G! Q# I0 l& k/ B2 V
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
& Z8 N/ i( {' ]味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。" d/ @/ G5 c& |7 v: l7 a; j( _
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们2 w6 s, m; I; g6 V7 V: z
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
7 L& Z( u( e/ E! z) w1 s的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
2 i2 T- [9 t# A+ ]; ^的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致) v" U. {. A9 S, J0 A6 O
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
5 M$ Y4 O9 ^. g根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
( N( B, V. e  F见下面代码。
; D2 y0 @% G4 v3 J  m
0 Y( i! B, r5 L  q- A( F: u7 T- ^这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程$ E7 H# m5 D+ Q/ i7 |8 S/ G0 c/ J
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键9 |' B$ e9 i3 d
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
2 ?* z" a$ J0 V& W. O1 G/ p上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有. E1 V0 q: e  r- h( J' e. I
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
2 l9 z& }$ }6 V$ Q继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
2 p: ]' k! Y: Z, @锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
! N9 f: E; u* I( t0 j' I6 R6 p键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
# J$ u7 f* v$ \  H0 I8 p# q3 y
; q$ v. y/ Q/ |
8 `$ n3 B$ K7 G3 V0 R, d完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用4 {  ~# d- r# H3 Z  I- U8 ^
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
4 z( D/ A6 c9 Y/ Z可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
3 t% X0 o+ T* `- m8 P% I0 L的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我9 `1 Z( M+ k( ]( o/ Y
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
& T5 [% N! v! e# ]们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
0 Z4 L( a2 B" X' _5 j->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。, j) ^) b3 ~) T9 e- x0 R
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager2 V2 F: p5 U6 N! g2 w
进行操作了。这个问题有待大家来完善了。/ |% Q/ Q% R( q+ ~

( f* o9 O- z; }# ?- I+ o. M
3 s% {4 i( L4 [. S3 I- y( I: O8 }要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出+ I! Z* F) Y# r
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的/ _- k  V# ~( ?
分析做个记录而已。我更愿意把它看做是一段注释。
$ I6 T* ], c6 Y
: o6 {: e1 _5 n8 a# S8 S9 P最后在此代码中要8 q. X. [0 a* o$ v9 p# F
4 h. z: ?6 V- n1 y$ a
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
; `+ v% l) p5 C2 k" e! d; F  U9 ^# X2 T* X3 ]- }
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。& x, m) w9 a! o6 i
: ^/ U6 l, x4 H. r
感谢:齐佳佳,过节请我吃好吃的。: W3 S" G# W) g& ^

6 C2 n" k6 W7 ~8 x2 I- k) @; r4 B7 u. Z" K; D9 L; |  x
******************************************************************/
# O7 L+ W4 y8 r. |/ x' S
7 k: ~: t9 r' P% i6 i
2 W6 z6 {7 ?3 y- D) K/*****************************************************************
1 |2 U5 v$ @: R2 q1 ] 文件名        : WssLockKey.c
0 w0 [) ?; A. c% ]. m/ Y 描述          : 键盘过滤驱动' L8 \* ^& |% w3 q
作者          : sinister9 W/ Q) m& y: b9 d7 X
最后修改日期  : 2007-02-26& r" t7 E+ `/ }% p- U/ f5 T
*****************************************************************/
. o8 X* M. E3 x1 r7 G, W" T% k. s) T! m8 D
- F( ^" K2 t& K; u! x8 G
#include "WssLockKey.h"
; I& J! l. U9 `: U8 L9 [) i: J4 Z( @/ S
NTSTATUS
% Q9 m  Z3 P8 K5 d) R) R. z) eDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,% |" `7 `& y* q
             IN PUNICODE_STRING RegistryPath )
, W6 g% @. t- W: ?" u# ?; P: \{
! c0 ?! Z% g; h8 y4 s" R, X( ^" H  UNICODE_STRING KeyDeviceName; 8 B& D- a" p$ P8 V- h
  PDRIVER_OBJECT KeyDriver; " s% ^& P  j) I& ]
  PDEVICE_OBJECT UsbDeviceObject;/ ?1 @7 {* `7 c$ ]1 [: g+ O2 _
  NTSTATUS ntStatus;
$ A: S; J3 N8 C1 {+ Z+ E  ULONG i;
4 e5 J& m8 o* M" Z) H) v
4 w9 P) P  S, |2 D+ h/ _7 y  //
- P$ a: |7 A( H1 `! q1 ^# x3 o: t  // 保存设备名,调试使用
9 I8 u+ O5 W6 r  //: g  M! p) [9 ]5 U3 {
  WCHAR szDeviceName[MAXLEN + MAXLEN] =5 k/ f8 M+ D9 V) l
  {
5 x1 H' h  z( E) f- X3 n    0
+ }" z6 v4 a  g  };
" S) {8 k6 y$ B3 T- v7 J5 w. Z/ K$ ]2 T
  KeyDriverObject->DriverUnload = KeyDriverUnload; 7 t) _) Q0 R# |( ~

4 y0 `9 q* A2 Z, `  //
* |- ]( S" I' b5 f% `- E5 U, s  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘3 W9 Y2 O# R8 Q$ u. O. G
  //( N+ v0 \! i# C2 ~6 S
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法2 n% m5 B; w; N# _4 u$ m$ y
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
  c& W, l0 G& C% U; H* G  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到7 l9 j% [% r" |& M
  // USB 键盘设备来进行挂接
0 x3 m' h3 |# r5 X  //# [# `) s0 h# p( r
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );5 Q' t7 P2 b/ p! Q# p; C! O0 G; x
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
% r3 m: E: D3 R  {
2 x3 x1 U0 Z* C! P' h) I    //
) `) _1 P7 J; O( o7 J$ v# Z& t    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名2 f" z& D/ F% g% M
    // 所以这里打印为空: z& \" V( _; Q1 ?3 u/ U4 `: A
    //
6 I/ a- t$ V' [) s$ s0 h1 j* g    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD. y2 X6 t  w( Q5 A: ^
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );" y5 K: ^  ?$ n
) ^. W& G$ Q! i0 o* x, k
    //
& E/ J7 `( X/ p! ~0 O    // 挂接 USB 键盘设备
. p# q3 W1 x# a    //
7 W/ ?7 u) J4 b- K" a/ `    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );9 {6 u8 u/ y8 \0 m3 k" s5 ~* K
    if ( !NT_SUCCESS( ntStatus ) )
7 ^5 W) Y" C# d$ ~7 T0 r# K  c    {! F5 [; i5 A$ O% u5 K" `
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
5 G" g: X1 J! R: v      return STATUS_INSUFFICIENT_RESOURCES;, d8 j" S; z0 d, N# ~" B! X
    }6 G0 g1 l2 \3 ?
  }
; }2 T& u+ Y* L( W+ w7 Z& ~  J  else
# H. }, @8 l0 g6 J, y/ j  ]  {
$ F' O0 F! L) g3 r4 X8 n    //
  q# h6 A. }4 S, _& I0 `    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
, E0 w6 a* F  O, O) B4 B    // 1 U! Y: X/ n' ^1 V3 E5 D
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
$ j: W/ r3 b0 {! Q& T4 X
3 l6 t% [1 R( W, |! g: O+ G    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
: O& d0 {) v4 g3 B: H2 U) G                                        KeyDriverObject,1 d2 J0 u1 ~3 @( |8 k
                                        &KeyDriver );
0 s0 }! ]6 _# v/ B% l/ A% h0 y    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
" P2 v4 |+ `" w3 f+ Y% G* M    {
4 u& v" |0 y1 h# {. \      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
  v2 Q% l3 c6 {: x- Y/ x      return STATUS_INSUFFICIENT_RESOURCES;/ a* s, T4 z( X
    }
/ p$ S0 O, F  F+ n  }$ {6 M  F3 X6 Y# K
! H( @( q, i! J
  //
0 C0 L8 k5 H) G+ Z+ d) H0 O$ @  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止8 p8 D- j# U% v
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程* f" ]9 w  [: U. _/ Y4 [( d
  //
$ G6 ~) @: D! w/ \  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
) i/ K4 O% b; p; |2 B! G/ {1 M$ s: A9 ?2 C" v$ v7 G
  return STATUS_SUCCESS;
" w5 l1 R6 `6 T5 D/ ^, A} * N' e# L$ }- f) W- R$ ^; O+ |

- S, {7 V5 H) y7 i' u/ c( o/////////////////////////////////////////////////////////////////5 W: w1 z  u+ l& X9 R* ]. h
// 函数类型 : 系统函数
) d0 }1 h! J$ ^' G* t2 x$ V! B5 k& E// 函数模块 : 键盘过滤模块5 |; M0 M( t4 ]! V8 B
////////////////////////////////////////////////////////////////
; z1 ~9 m7 n" r! m. w# M// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
2 L$ ]# |6 [  m* E/ y' J) t; M//        卸载键盘过滤驱动. K9 o1 `* F. o% Y
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
9 E4 k& R5 ~2 v& i7 E* t3 T//        则需要等待用户按键,以后有待完善8 `1 l. ]6 U! f4 z# ?. h) A/ G4 v3 I) j
/////////////////////////////////////////////////////////////////
1 x: R$ Q' |; [* y9 f- ?// 作者 : sinister
  A% U; R$ ~! l% s: L( R2 w& M// 发布版本 : 1.00.00
! N8 Q1 A. J- h/ B# p/ D$ A// 发布日期 : 2005.12.27" j" Q5 D7 T# H4 P* ?( U
/////////////////////////////////////////////////////////////////# r8 A4 Z7 R  n7 h6 q: z
// 重   大   修   改   历   史
( G. z+ C/ i) A, g' m3 k8 _////////////////////////////////////////////////////////////////4 n) C- \; t! ^) f
// 修改者 :
& G1 c: m- G/ U$ G// 修改日期 :+ R* y; Z' i3 b  `( i) P5 T
// 修改内容 :% D, I% v" S  W
/////////////////////////////////////////////////////////////////
% q  u5 G( v5 {# r8 t# [
. s4 k$ ~- r8 p# ]VOID/ {( L; f3 |1 n$ k
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
0 x6 U, r. F7 Y2 ~0 b{) [7 J# u" e/ G4 b! k
  PDEVICE_OBJECT KeyFilterDevice ;      
; J3 {& h; M( z/ z: z5 `  PDEVICE_OBJECT KeyDevice ;
& @1 P/ {* [9 `0 ^  PDEVICE_EXTENSION KeyExtension; - g, m& u' F  i+ h
  PIRP Irp;; O# r. U" x9 R3 R) [; L4 V+ u* b
  NTSTATUS ntStatus;+ L' f7 j7 j! t8 M% H3 @
- N  N2 z1 x! V' i
  KeyFilterDevice = KeyDriver->DeviceObject; . l9 U3 @8 L7 s
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
  c1 N# Z  M: f4 J' {  KeyDevice = KeyExtension->TargetDevice;
+ @% K+ e' Z3 Z( h
3 z) k# F$ r* S4 T! ]* W  IoDetachDevice( KeyDevice ); % g& C$ K  J/ R: Q

4 Z6 F6 _( B+ @$ i8 s  L% P  //
( f# c! n2 p; Q* D  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
/ P3 v- H7 ?3 F  //
5 n/ k9 G8 b/ J  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
/ A  g$ c6 e9 J. e9 c8 u  {
) Q2 D+ @& W8 @8 r  X    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
' P- Q0 Q8 l5 `5 n    {
, m) n" M: h* l$ d. U      /// ]# g6 Q3 b7 C
      // 成功则直接退出删除键盘过滤设备0 s) i2 T' e: w- f# }. }
      //
% G- \7 s. Y8 y2 ]7 W7 ^; D4 a% ~% Z      DbgPrint( "CancelKeyboardIrp() is ok\n" );
5 W, U  ?" v: P7 E& a. W      goto __End;/ r$ B6 ^$ O$ w5 `5 P; ]
    }; w0 N) h! X+ t$ |/ v& u) d
  }% S& [, w6 c* O! K

) c1 \" U! _+ X3 V  //
/ D/ }! K  E" ^5 h+ |  // 如果取消失败,则一直等待按键2 c- L. p. G  P* V# U8 I2 Y
  //" X5 M' c  Y5 u; }, A" h
  while ( KeyExtension->IrpsInProgress > 0 )
: W; G& g% c& P9 A+ P' S( V4 x  {2 }3 Z2 X$ s! O
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
; J( n: ]) c& H; y  M. Y+ n  }% Y% u. X$ v/ j. x, b
% C2 E4 @! O% W$ c. s! q. g
  __End:7 d* V& q, B% [) i# M6 n
  IoDeleteDevice( KeyFilterDevice ); & ?  O' R, h. K8 v
0 ]' ]' J! [/ w& U
  return ;
# i2 |5 C) q7 n2 D/ Q# n) C* `} % r0 X5 y# s# ~$ G

* ~. R. X8 m; Q( A; T! i' D/////////////////////////////////////////////////////////////////, C" a: p8 B- W
// 函数类型 : 自定义工具函数
8 v5 c) a  Y5 D3 b4 i% Q* H4 H// 函数模块 : 键盘过滤模块2 R( n/ ?% \) `5 u/ l# w) P
/////////////////////////////////////////////////////////////////" Y' q% k' y6 j' \5 ~; a  M3 \
// 功能 : 取消 IRP 操作
5 f, r3 G3 h5 D// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
4 s: f4 b; c  N! x" b, c//        使用此方法来取消 IRP
6 c6 X) a% Q5 F/ C" g) I/////////////////////////////////////////////////////////////////
& M3 n# u5 ~2 L( M* O* Z! a// 作者 : sinister
4 G' V7 V, L7 s3 j% `/ N2 z0 V// 发布版本 : 1.00.00# E) o( Y/ M- e. P4 v4 {
// 发布日期 : 2007.02.20. B% k3 B: h% \+ h6 X9 u9 y
/////////////////////////////////////////////////////////////////2 r8 G0 X4 Y6 @- x. q
// 重   大   修   改   历   史
; _6 ~1 ]8 Y$ I2 v% \/////////////////////////////////////////////////////////////////2 V( [/ n- S' J+ ?9 E" R9 `
// 修改者 : ; R- I$ O. i+ A& C! S
// 修改日期 :
  ]$ I0 I/ q" ^! J: s// 修改内容 :
/ t' Y4 F8 ], H/////////////////////////////////////////////////////////////////; F( v4 |1 U& `* @3 I7 v

; Z1 k' U. \5 u( d! Q: R( FBOOLEAN+ G( Z2 [/ P; I( K- b# L
CancelKeyboardIrp( IN PIRP Irp )1 I! `. V# G: m0 Y4 i
{
3 v  T# h7 `( n: A  if ( Irp == NULL )  M3 }* ?' [5 }! D: c( R
  {8 V( o* i. K. n
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );' J: o% \1 A; j. D1 U9 @5 J  M
    return FALSE;
( t( C* w- O$ j4 j, L, b  }
9 k* o" \( N/ c/ O. w8 K& i% D
- m4 z. N8 Q/ M7 q" b0 W, Q" `( r9 z3 W. U1 y, A
  //
: t- d( i6 h. ^- j6 [% ^, S  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
% L! j+ i1 W# L$ v  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
9 {  j% r) u; q( }  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
' r; @/ z5 U+ M1 t$ N0 B  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD, w' l% p  V( u* F
  //. N0 \1 g$ A0 F6 Z' H$ i9 T
9 {/ n( q( f7 R1 m! Q; `  B- T
  //  R7 f+ S5 V& a: D. b  a$ _2 i
  // 如果正在取消或没有取消例程则直接返回 FALSE7 U; e7 D5 t( q, b0 k) b5 d; J! x- M
  //
( z+ k+ {: u) j1 t  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
6 {5 O% Y! j* L7 }  {% x' L1 R3 q: X/ F& z9 m$ ~# U9 p. ]$ Y
    DbgPrint( "Can't Cancel the irp\n" );9 Z! h# Q/ s- ?: e2 v* I
    return FALSE;3 |2 _5 q0 v3 W/ {
  }: \. V2 [# ]8 l/ J$ q% }

* B: h2 K* w: k; U  if ( FALSE == IoCancelIrp( Irp ) )) G$ s9 f% a4 T" q2 K/ C
  {
# ?6 O* f2 H; R    DbgPrint( "IoCancelIrp() to failed\n" );
5 V* Y; F3 ]) P+ O" y" t+ w    return FALSE;
, E' z) m5 t* K: K  {$ f! o  }
7 n' e6 \2 b3 n$ _1 K, q) ]' n4 {2 g  _7 }& w
  //  L, ^$ i+ R$ n6 u" {) A, s
  // 取消后重设此例程为空# e+ T0 |  `4 d6 ]" R7 [2 N
  //& S+ n! O3 o2 G/ T$ T' }
  IoSetCancelRoutine( Irp, NULL );
, {# C* e/ o/ u' d% M5 V0 s* g5 J) {4 t0 X; x
  return TRUE;% a& y6 _* S4 Q+ h+ n4 U, h
}7 q. w. C! P/ _# [! O9 ^3 P- ~
9 B( c/ k( y2 x1 v4 Y" k- Q, I  i
/////////////////////////////////////////////////////////////////
. \% c. x3 S  x0 [* l2 {// 函数类型 : 自定义工具函数6 i  p" ]- N1 |
// 函数模块 : 设备栈信息模块
7 M/ C7 x* k! |5 |8 @  [# q/////////////////////////////////////////////////////////////////- _" W+ \4 P( D) v) M1 R7 q
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
) |  C/ m. ?5 f: u* y//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)' O0 _: {7 `. u, d$ ~
// 注意 :
" d  a6 e5 g9 x: O" H/////////////////////////////////////////////////////////////////
% v! `9 k: C3 [7 `// 作者 : sinister
. I3 d. Z. u5 ]1 `! m$ g# t2 y// 发布版本 : 1.00.00
3 v  K% e# T2 J' Y2 |/ q% V// 发布日期 : 2005.06.022 Q( h/ @# L; j' B- }
/////////////////////////////////////////////////////////////////) x) g- j2 A5 j# P5 g
// 重   大   修   改   历   史
- ]0 F" ]" P' z* ?0 l6 j/////////////////////////////////////////////////////////////////
; X: U0 F+ m' i! p5 d// 修改者 : sinister% N% Q, J$ j2 B1 n8 e; C
// 修改日期 : 2007.2.122 T+ y" J" U+ F6 \
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改/ l) ^; y5 C8 T3 H$ e: x  ]+ z
/////////////////////////////////////////////////////////////////- |) o- F7 `7 u9 {. P. t; U
5 ^) ~: L7 o& f
BOOLEAN
% g) V! ~7 r2 tGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )2 S+ E- ]2 [( M3 Y% S  h/ W# P
{
; k3 B% |; Z, c7 d  PDEVICE_OBJECT DeviceObject;) F  H5 Z. L) h1 V" Z
  BOOLEAN bFound = FALSE;
! Q' \4 J) u7 q+ k# b
" Q  e, C' i: g  if ( DevObj == NULL )- C1 Y# i/ Q& [& w% l4 v* h
  {
7 N3 {+ b- r5 y8 I" E6 m    DbgPrint( "DevObj is NULL!\n" );/ P3 t# v4 c* I1 t& [! S
    return FALSE;
3 {8 ]6 Q4 f! k  }
) [! n" U3 {) T: h0 e, C) `; \* ?2 n$ Y9 R7 b  ^9 Q: b9 D5 V
  DeviceObject = DevObj->AttachedDevice;
3 e; j; x/ g0 A  c
0 J7 w# }: x5 p! T; K: @$ i  while ( DeviceObject )
5 O) |% e: V* S; }3 S% {1 |* @! N4 z' n  {
5 {( ?3 E7 W$ j8 I7 J* O4 r  I    //1 R1 H* _1 Q& i
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但: Y6 \9 s2 e! H' n& x2 j
    // 有一次足够了。这算是经验之谈
; t2 k$ Q7 f% H9 @+ {+ C+ J    //
6 u1 }0 Q# G) L3 `    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
' R' M5 c2 o  u$ l8 D" U' ?* f    {
3 R1 k0 e) Y2 _/ E: \9 @9 B- c, T+ A3 r      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
: v3 }4 V* P/ ]/ `* L, X+ G                DeviceObject->DriverObject->DriverName.Buffer,* {# o, }' B' T& u' q9 c
                DeviceObject->DriverObject,& _+ K! K; a1 \, j3 `
                DeviceObject );/ S$ B' `" k! Q3 A4 O

+ n0 b& a: A: p9 s      //
* o& V. Q/ ?4 a! _9 @6 [      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
' G3 e! J# ^  ]: P0 o      //1 S8 y! z1 S8 I7 ^
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,  Z, C: [; z/ V+ C- l
                      KDBDEVICENAME,! S* y9 V* X- r: V- L- K6 j" {2 T6 ?& \
                      wcslen( KDBDEVICENAME ) ) == 0 )+ P$ N5 e7 H+ g2 @* l
      {
. G( x0 E1 V5 V9 c( m, @. y1 U        DbgPrint( "Found kbdhid Device\n" );
  S) G* }  {1 k+ ?' K4 A% W        bFound = TRUE;6 c8 Y: Q0 o$ m! l; }3 R
        break;
4 n& J( l8 v& c: ]! ^9 D      }
+ F/ l4 g# K! D2 j    }1 l1 W; g/ T* O- i6 r; K# G
% y6 `" U1 A$ v* l6 Z$ U
    DeviceObject = DeviceObject->AttachedDevice;4 Y/ f$ v4 g0 j& @; ], \& r
  }
- y  C8 j: W" ^1 ?$ A1 I) B2 e# N% W8 M6 G$ F9 C
  return bFound;1 \- C1 F% W+ b! u0 m' @
}7 A3 h* V9 l& z# m* L6 s: N: p* F2 e; |

# x" G; R4 |3 @; i/ C( t/ n) O$ g/////////////////////////////////////////////////////////////////
+ b- y  Z; D) V* I( O8 c// 函数类型 : 自定义工具函数* e7 S3 A, u* r
// 函数模块 : 设备栈信息模块/ L& M7 S% o6 z5 o' u8 e7 J5 k/ n
/////////////////////////////////////////////////////////////////
; u$ R, G8 U3 N% h+ q// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
6 n) n5 {" m$ Q7 z! s+ F) s// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改% _' u4 G, n. Q' [/ T% @& A* m4 p
/////////////////////////////////////////////////////////////////( b; w7 D* s+ i  a* V) {) u
// 作者 : sinister& |& l- F2 L5 l  x! B3 Z
// 发布版本 : 1.00.00
9 I# v$ p0 }( O* K. L8 e2 o0 F// 发布日期 : 2006.05.023 ?1 c- J- F- f8 T
/////////////////////////////////////////////////////////////////! s5 G8 x. b  r2 M6 g$ I
// 重   大   修   改   历   史0 ^1 O% I9 z/ H% v9 f' V( f
/////////////////////////////////////////////////////////////////+ {% {2 X6 N" N" k. X5 D! r- X
// 修改者 : sinister
9 N+ S! F( m  s7 T5 c! J. @// 修改日期 : 2007.2.12
+ v; v! R) D' e* M5 Y! ?// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
  ?5 n: r# o) x! X; e! Q/////////////////////////////////////////////////////////////////9 ]& F+ b9 m2 e$ s+ U  v

4 I$ M6 R8 E* f$ D9 |1 W7 FVOID6 d: n* c, Z7 z* U7 N
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )$ _5 q0 I& A2 L- ?' R
{
( }# ^3 R7 h) n  c" `  POBJECT_HEADER ObjectHeader;* W8 t1 f9 ?. {/ ]5 I7 n
  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 8 K. k' Z& d! ]- ~

5 J' |6 ?6 q9 s0 l) m  if ( DevObj == NULL )/ E4 V1 y7 u. f( T/ I8 @
  {
% N3 ?/ N" D% u; T4 v& x* x* |$ T    DbgPrint( "DevObj is NULL!\n" );: @( |; P  \9 ], Z
    return;$ n8 u; K  _6 d- ~4 m
  }
& ^* d: a9 a6 m) k- _4 n7 E+ s7 g) R: F# d0 H
  //
4 M# \; m3 B9 c0 Z  // 得到对象头
7 \- q7 J; x7 _0 c1 ^# [9 y  //
1 q  b+ V2 F5 I! t+ ~$ e# e  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
3 y+ z2 _1 h# V2 j& w8 M5 M7 T  d& [3 t0 I" E! w) F& z( J% |
  if ( ObjectHeader )  S4 W& n/ n2 r$ E7 [) l0 B
  {
/ [6 ^1 ^* e4 ?9 a, S, j" C    //0 R& r; h4 n+ ^. q6 Z& A1 V
    // 查询设备名称并打印
& b* c5 E9 k- B& d; F9 M3 b    //
9 n  X6 m6 B/ o9 w( V' j( M" a    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );( v' ?! n2 P) w" q/ F& C3 v1 `
% {8 I# [2 U, s0 T( W8 \
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )( O6 N5 I, @" m6 }/ S* g
    {
5 O8 O1 \2 k* z8 f& z      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
" Z& n7 C& w; D/ {7 n, a3 P                ObjectNameInfo->Name.Buffer,
# O2 L3 w. G* Y. Z                DevObj );
) Y, [% d7 g3 ~* g$ b4 ]) g0 [+ R# L8 e8 u5 U" f9 z' ]
      //
& c6 A. l% c0 n5 s) J6 F$ Q- f. c      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示% M" x% B( A! F  u
      // 用,没有实际的功能用途; f4 F9 v8 w; O
      //
( b, l7 s  b7 m" ]/ O" C* a/ h- W. L2 i      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
5 q/ h) T; ?4 Y% t& a) Z8 C
$ W; o, _# d% F0 t) t0 {5 ?      wcsncpy( szUsbDeviceName,
) A; n; `! H  e. X9 Q: }               ObjectNameInfo->Name.Buffer,
+ J( l/ S  |5 _# a               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
- M0 h/ H. |0 [% N! |2 ?    }3 j) t7 ?* j; ]: Z* B: {7 n4 P

7 H& r+ L. Z% G7 {1 p" q    //
) u  \4 }+ s& C+ v. n6 c+ X( J    // 对于没有名称的设备,则打印 NULL
8 t1 X. g; O5 ~" M    //
, k" F7 m7 S! t; `5 S    else if ( DevObj->DriverObject )
4 p( w! L( Z. p# a2 ^% l    {. e9 B! ^: B! M$ {3 h  a7 Q
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",$ X- h2 Z% e4 ?4 O, [( b& C
                DevObj->DriverObject->DriverName.Buffer,8 n& {4 W: K, E0 {5 z! J
                L"NULL",
  [% ?- I1 p# a+ g. ?; u                DevObj->DriverObject,
0 ~9 ~7 i2 d; l" l                DevObj );- j' V& e! F( L9 |1 h6 E; C5 L" A
    }
% s$ ?8 ^/ p2 B9 y+ v% c. g' ]  }* ]7 A# U9 l3 D* @/ N: ~" l
}
. Y1 a0 `8 ^' x! M* D
. i$ `1 J3 {/ l. p: K/////////////////////////////////////////////////////////////////
+ L6 s$ D/ ]& b* x' r4 t0 p// 函数类型 : 自定义工具函数& j* E* P* O5 \. M# D% s
// 函数模块 : 键盘过滤模块* ]  D2 I" o2 _, l$ k* e. O+ x
/////////////////////////////////////////////////////////////////
& p/ f0 A6 ?, y: n. f. h, W9 @// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
$ Z  _1 b7 p+ `+ D( h  T. Z//        对象,过滤出 USB 键盘设备,将其设备对象返回* L+ W8 y6 P3 w1 f/ Z
// 注意 : " m0 I+ G- r% j0 J; m* _# Q
/////////////////////////////////////////////////////////////////. o/ }  s, L% [. ]8 ?1 z, l' d" j
// 作者 : sinister0 S2 f" L* A' j. k, a% S  u
// 发布版本 : 1.00.00
9 P2 J  h9 ]- q! r: J3 P/ ]4 s4 x// 发布日期 : 2007.02.13
  T! ^( r# J: j9 E% F/////////////////////////////////////////////////////////////////8 o3 N& l7 w6 Y; m* C* B5 w& b8 `8 j
// 重   大   修   改   历   史
+ _5 ^) d' F. {0 j/////////////////////////////////////////////////////////////////
) b; ~/ w; C. s6 O// 修改者 : $ U! t$ D6 k4 g  h4 t
// 修改日期 : % y$ \7 q4 i9 `
// 修改内容 : ( z. J/ K* J0 Z$ {6 \5 S7 K2 M$ ?
/////////////////////////////////////////////////////////////////
8 R$ m) R1 M8 F7 a2 |/ A1 `/ x
NTSTATUS
3 j+ D, H2 z/ [% P+ IGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
4 {: g! \. [9 E$ n9 W3 T9 W{
0 q: j* V, |! }5 J  }  UNICODE_STRING DriverName;
' k! \" g: \' ]" a8 J8 W  PDRIVER_OBJECT DriverObject = NULL;
  J3 C4 A8 c# L# i1 F1 X2 \  PDEVICE_OBJECT DeviceObject = NULL;- T( E% i+ x1 X0 q
  BOOLEAN bFound = FALSE;
8 K5 I' \2 _: a0 t/ Z4 |1 e# Z* P# i
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );% X+ f( j3 y8 O) @4 O+ C

+ w& L( k! R9 o( U! [2 x* _, ?: x  ObReferenceObjectByName( &DriverName,
3 x9 F: ^5 q0 [& \) m  ^                           OBJ_CASE_INSENSITIVE,
$ @! @  z3 h7 x1 X7 S9 j" z                           NULL,
* n4 ^" `% \/ k8 A! R( ]2 }                           0,! ?" ]5 f2 @! s
                           ( POBJECT_TYPE ) IoDriverObjectType,$ B: J" ^3 ^" _1 v3 w2 \
                           KernelMode,% ?: g, i+ j' |( x/ C
                           NULL,. X) [1 D8 D4 B  q$ q8 l( l1 |
                           &DriverObject );# x; ^( y+ J5 \- K0 o

: V8 }- n/ q# p) Q1 V  if ( DriverObject == NULL )7 m, K, j4 t: M
  {
7 S; ~5 \& U) }8 G    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
; \. v6 r  B9 m    return STATUS_UNSUCCESSFUL;' s# p/ |1 T4 a8 b6 H. X# d
  }
2 x7 N) g; e) K4 R5 x$ p* n+ N- D/ P  S, m: I$ e$ t$ q
  DeviceObject = DriverObject->DeviceObject;3 r* ]& `1 g* M8 ~+ }) B

8 o% v; j" }1 `  while ( DeviceObject )
8 d/ A2 W+ H; g/ J  {) v/ T7 Z  X: `- I- _' F$ D
    GetDeviceObjectInfo( DeviceObject );; U4 D6 W: J8 c& D0 o
2 r% p1 @8 [/ Z8 A! c
    if ( DeviceObject->AttachedDevice )' j* I# o, O+ G! e" j/ |8 {" U. o
    {
. @  s4 x4 _! a) f      //
) {- u7 d4 |% [0 H7 m: l      // 查找 USB 键盘设备# Y  @2 k6 \8 n) B/ U2 Q/ c
      //
" _1 y# j* a2 v! g! X1 a      if ( GetAttachedDeviceInfo( DeviceObject ) )  r# u) a$ V* E5 r3 N3 j5 n
      {
; J" u# d+ b* |% T. I) X        bFound = TRUE;
- e# P2 I. x& v1 E( @! \" e, c, N        goto __End;$ ]0 U) Q9 w8 g# @: E% E
      }
" V) v0 `5 _* r, t    }4 y, W' M- H, M$ L! w8 S
; S5 D, D( j3 A
    DeviceObject = DeviceObject->NextDevice;
- Y; T4 ]7 P/ u& V, P& T) i! G  }) O! C- I) z& M7 ?

6 T0 j; ~' x% _: k. O; n  __End:
* r7 ^( s, ]$ ?+ A5 D1 ~& T& f8 i- t; I; h# D
  if ( bFound )
, F2 r$ l6 `' F3 s/ m  {: g! P% p3 Q" v4 f3 E
    //
! R& F+ d/ \. M  B    // 找到则返回 USB 键盘设备对象
5 r0 z! z& e. U. X    //' u& }- T& ~6 [. @
    *UsbDeviceObject = DeviceObject;
) L& R2 f. h$ j& ~( n  }0 {8 k( ]/ k- t2 ]
  else
) u, x0 {0 E9 Z, Y( G' s: i  {
8 K7 V0 S8 v% K" D8 |/ _    *UsbDeviceObject = NULL;- x* ^9 _) o- Y
  }3 @+ x1 c+ t' z0 W9 w0 c7 Y# L" H

' T" v0 e; ~, G; ~. V* c% D  return STATUS_SUCCESS;- N4 x3 N( h8 g- d
}
% h1 E! e/ e! X% ^3 ?9 c
+ R- ]+ b" F3 k6 h- z) S" W/////////////////////////////////////////////////////////////////. p: v( i* e; o! o0 x- z
// 函数类型 : 自定义工具函数
1 B' z/ f. }+ m4 P6 f// 函数模块 : 键盘过滤模块
$ g$ V- o9 K/ h////////////////////////////////////////////////////////////////
, P' Q! F8 Z4 d7 ?4 \/ B// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关  H3 k0 z) A  i, Q2 l/ k$ C
//        信息,返回附加后的驱动对象- N' i9 ^# C, S1 D# [7 y
// 注意 : 此函数仅挂接 USB 键盘设备- m6 O0 h; X  c% X# k) R
/////////////////////////////////////////////////////////////////) q5 N  n& K/ }
// 作者 : sinister: x- d! F) K2 X8 I! c
// 发布版本 : 1.00.00, E. O* r  y2 u9 Z$ u6 s4 u
// 发布日期 : 2005.12.27
0 |, t7 O- j0 E  ]9 F+ B/////////////////////////////////////////////////////////////////
; f8 `0 O- g4 C; l% a. f// 重   大   修   改   历   史
  i+ H: A% Q; W  M6 u. ^////////////////////////////////////////////////////////////////
: N, p9 `0 H1 P. {1 @; |+ W// 修改者 :
% c+ @' z, d: f. V" X// 修改日期 :* A6 q7 T- m" R# [" P) ~& v
// 修改内容 :
$ C( f! h9 R6 g5 T  L/////////////////////////////////////////////////////////////////0 B7 m" I* `, b8 d0 N1 h/ J

; u4 y4 U, P( }' n0 QNTSTATUS
; R' f8 `0 n+ X9 I; D; P3 bAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
7 Q( L% j2 W2 V                         IN PDRIVER_OBJECT  DriverObject )2 C  @- A# M, H7 d
{7 {! ]+ B3 P: c  L  T: V9 q
  PDEVICE_OBJECT DeviceObject; * A# J0 C( l) h
  PDEVICE_OBJECT TargetDevice; - j) ^8 d0 ^3 f. q$ X
  PDEVICE_EXTENSION DevExt;8 G# @" t: p3 C6 r
  NTSTATUS ntStatus;
1 {5 h% ~$ \' T  p7 E% ?* x
8 E' k' |1 {4 z9 P8 S  //& Y% N& ]" a( W) o
  // 创建过滤设备对象' U4 i) J4 V2 J: t: x: k. b
  //
% s! ?( c) N' @  T% F! a$ L1 _6 c7 E  ntStatus = IoCreateDevice( DriverObject,
, Z* k' ?. M( W5 w- e1 O( G' W                             sizeof( DEVICE_EXTENSION ),% C0 o, N5 b* I
                             NULL,
( Y, F  U3 D' A9 j* M; a, R                             FILE_DEVICE_UNKNOWN,
0 L3 a4 O5 C4 F- K                             0,( ]2 d% j$ N5 q' ~! @. D) r$ f( A8 Q
                             FALSE,7 d+ f/ m/ E2 ~3 v( c8 K; F
                             &DeviceObject ); 8 c' p& r7 G) n% j' Q7 c. l# H
$ ~5 ?: Y( B& @, a5 x
  if ( !NT_SUCCESS( ntStatus ) )& }" i  ?0 y  N1 ]: I+ ], Q$ C
  {
  L+ `) |4 p- c4 M7 g    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );3 j5 }( R3 m/ J' `0 W4 y9 y
    return ntStatus;
" r3 V7 D& O! U6 W8 o; T  x) H  }
; n9 c; j' w5 H& S5 v+ `4 x4 f
6 h( I7 s' H2 J5 j% F5 m) a/ E. c' m& |# y  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;  ~/ x  n8 c, ]4 @% R0 K
+ C* W2 w& \  X. ~0 o
  //
$ Y7 z* l  c* I5 S6 @) [  // 初始化自旋锁
1 i6 C& I% m, O9 b$ m  //
- E3 Y3 j2 r/ P  O' M  KeInitializeSpinLock( &DevExt->SpinLock );
0 o3 x0 @! ?$ f- U/ d; Q- ^1 B. g. F  ~+ V4 q
  //
/ t4 t0 d! v8 F0 N- Z6 w9 P  // 初始化 IRP 计数器
- B  k7 J+ e3 E# ]8 i0 ]  //3 `- ?- j1 B% r: H, O
  DevExt->IrpsInProgress = 0;+ _  }/ I0 o' ~
4 z2 H8 b8 A1 W+ o4 s- u
  //- S- g6 {/ i% C/ f! s$ Z
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
1 u  j4 n- e8 `1 q  //
, G" `2 [7 A5 z: ^& [% r+ Q2 P3 U" p# E! |
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
* ~8 ^. ?1 K" K" q$ c  if ( !TargetDevice )" M  b* r2 U+ W; i9 z) @
  {
/ B7 }& l- s0 J% _- B# B* S- B( i    IoDeleteDevice( DeviceObject );
8 }/ T: z/ {4 I2 h2 M    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
3 d9 \+ c9 _" l* U5 U2 q    return STATUS_INSUFFICIENT_RESOURCES;
2 E6 ^! x/ K/ T3 @  } : [2 J8 M8 |1 A8 a3 Y4 c, r! P
7 _' T" n- G& p
  //
) {0 W1 j5 p  T0 w0 w5 F! }  // 保存过滤设备信息# b7 S8 e0 z. O1 W: B& T4 R# S7 V
  //; f( }: m" i! t
  DevExt->DeviceObject = DeviceObject; ; ?+ g, x2 X5 X# o% b0 s; q
  DevExt->TargetDevice = TargetDevice;
) y4 w. Z( p0 R3 R5 r) }6 j
: t, W8 K: a5 p: f0 F  //5 z9 _' P% B" P/ }$ }3 P
  // 设置过滤设备相关信息与标志, g; j1 |" o; n2 t0 M6 [1 u" j* _
  //
# R! ?! `: L9 _- x, F  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );: F7 d  a5 V- E
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
% T2 s1 U1 K. X3 W$ ^5 }% |3 k! b3 c# t" d+ X& K

* @; [# N" K' L/ L9 R- v' f  return STATUS_SUCCESS;7 s% M3 \" I$ M% q- A. w
}7 Q6 T3 x/ x+ z- |6 V

6 T# x" f0 O4 Q& v$ }/////////////////////////////////////////////////////////////////: i" y& l6 C8 Z! P5 H# x4 y
// 函数类型 : 自定义工具函数
. G5 E- V( S% q4 G3 s8 u; [/ K// 函数模块 : 键盘过滤模块& }& n# n4 ]# y, Y2 d
////////////////////////////////////////////////////////////////0 Z+ O; [- q$ ^( ~' m1 f9 }
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关8 Z1 H0 q! ^9 F+ q) \# u% ^
//        信息,返回附加后的驱动对象6 ]: x- q% G" |
// 注意 : 此函数仅挂接 PS/2 键盘设备$ f& _- K) N: `! Y) W. L7 N/ A
/////////////////////////////////////////////////////////////////8 Q( {8 l+ ^1 V! L7 l, \
// 作者 : sinister
1 N! l& n; N& K* w2 O8 y) t$ p// 发布版本 : 1.00.00
5 V! |" o. p6 a5 `; u, Q" J4 K. u// 发布日期 : 2005.12.27: L1 [8 j  {2 t
/////////////////////////////////////////////////////////////////! t8 U8 n2 u- M. P8 Z$ ]5 P
// 重   大   修   改   历   史8 w5 y9 f2 K& Q5 I
////////////////////////////////////////////////////////////////6 m' }& `  R: R, O# D) V
// 修改者 :( S$ q3 Z  K1 R4 Y3 Q0 f
// 修改日期 :( v' c4 K, R$ G3 \& c+ v- e
// 修改内容 :  I; T0 W. l2 }
/////////////////////////////////////////////////////////////////  Y6 @3 W( ^& S$ A
- u& J- E& c1 p; M) e
NTSTATUS
9 Z  t* M0 b/ w8 eAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
& D* f- Q  r* k+ _8 R                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
: l9 T- k+ S  ]2 i2 _3 ?                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象+ N% A& j$ c& E( I6 P' `
{
8 U: Z0 H( G5 [: \  PDEVICE_OBJECT DeviceObject;
8 ~4 e4 C  `- C- g6 p0 j) D  PDEVICE_OBJECT FilterDeviceObject;$ a  K& h. J8 z5 v- s# S
  PDEVICE_OBJECT TargetDevice; , w$ S4 p& o% Y/ B. u0 ~  V4 Q
  PFILE_OBJECT FileObject; ( ?2 V  k; N* O1 X2 W5 _8 h6 w
  PDEVICE_EXTENSION DevExt;: d" J8 c+ S: {' F
1 k5 ^- u3 d# c* \! r8 p
  NTSTATUS ntStatus;
: x) W5 r4 `  {) ]
1 U. O' {) G* l6 p# q  //
2 a5 w; ]8 v0 T  // 根据设备名称找到需要附加的设备对象
! |7 B6 @; E+ K' m1 \  //
; D5 r; X* |( c' b  ntStatus = IoGetDeviceObjectPointer( DeviceName,3 _2 ?7 j& j8 Q' D% {  j
                                       FILE_ALL_ACCESS,
1 O$ y" c! t# }5 o1 G  s                                       &FileObject,! l* `. O: F8 n! H( ~7 w" |
                                       &DeviceObject ); 4 @7 f/ \, W8 d6 R- Z$ A. `9 ?4 `
3 W5 I& H+ }$ ]: Q" z! [1 N$ Q9 J
  if ( !NT_SUCCESS( ntStatus ) )
  r% G2 `" b6 k5 n4 f# R  {3 b1 u  g0 x# R  }; L8 s3 m
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );9 b7 D7 M4 V" G4 p
    return ntStatus;* g/ R  F# c, p! K
  } 7 k% J# z  L/ N8 D% c9 C

4 R* H' K4 p) X  //; y2 u' J* {  A, Z6 \' n
  // 创建过滤设备对象
2 q% e+ |$ ~" ~8 m% D$ J& W" c8 I  //% e9 |7 R! S+ z1 k  R5 l
  ntStatus = IoCreateDevice( DriverObject,' E. C/ K8 a. h, f& s4 \, e4 [
                             sizeof( DEVICE_EXTENSION ),' k6 d" M& `6 U
                             NULL,/ S+ A/ h: f0 c6 l6 `2 v
                             FILE_DEVICE_KEYBOARD,
8 j6 ]; V( d$ m6 [7 V7 C. E                             0,8 d0 _6 K9 t" ~  l9 n
                             FALSE,
6 w3 M2 K* \/ p& q* d7 N+ Y                             &FilterDeviceObject ); - V% N& R/ y0 y  e

$ X+ W1 X+ x( F  if ( !NT_SUCCESS( ntStatus ) )
% I* B# V7 `3 M5 {: r2 |7 j/ @  {- t2 k4 ~, _" U% L% v( B+ v- y
    ObDereferenceObject( FileObject ); , b  {* X, n* M) u& C- ~+ X, y8 }
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );/ |; \+ k- K( T6 V& r5 C/ y; u
    return ntStatus;
1 U5 X" L. e1 J( H) T) n  }
* D% a: i: h. K% ]7 z1 x; j& N# l0 c8 ]3 Q7 x  r' f2 Y. z
  //) g! M9 F1 f" A4 i3 l0 R& n
  // 得到设备扩展结构,以便下面保存过滤设备信息
5 _$ ]2 ^6 v! Z' K/ k5 |  //
, M1 W7 n8 e- j: _4 `8 b6 f  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;  _# O. n+ a- G7 c
8 N0 j+ z9 ~$ I: O. |( ]5 w

7 T; o/ Z: K. J9 G* x7 }5 ^1 D  //  E2 F, c0 H$ w6 ]6 ?# H4 Q
  // 初始化自旋锁. g  B! [% g  }" e4 ?7 Y& P& f$ J7 g
  //
% `: {$ }, Y* Q( i) p/ F  KeInitializeSpinLock( &DevExt->SpinLock );
6 k: g- j( `6 o$ W3 u1 O
9 p1 _! l! W) R: y% v0 A  //
' ]3 W( |- ^& M& m: v, R! }/ T: p  // 初始化 IRP 计数器' B* n4 G' k$ N2 T7 @' ?( k
  //
" G0 a6 G; w  c# E) A/ y: \/ c  DevExt->IrpsInProgress = 0;% b& N7 G6 {  _- F

- G; O2 [- V) P5 P  //
& x8 \/ ~5 B. t: g1 @$ T; v  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象$ S3 N' O0 p9 K
  //
$ o. F# o/ k# t1 m  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,7 m  G1 h1 h; W, s1 q/ ~
                                              DeviceObject ); 4 t$ p, D$ d! A: c. [
  if ( !TargetDevice )$ z, W. D& A5 G- g( {2 u
  {
7 O/ E+ I) V  A* [/ C7 m    ObDereferenceObject( FileObject );   u! u/ e$ q& {2 d" G: D/ r
    IoDeleteDevice( FilterDeviceObject );
3 `7 }& c' E2 D6 K# Q6 _  Q1 a    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );6 c" ^3 l8 c$ ?, [4 f* j
    return STATUS_INSUFFICIENT_RESOURCES;
9 T8 Q- ], S7 {; i1 K" s  } & x7 }, t, l6 y

# F$ K! l/ y9 V/ Y; Q  //( e" f- D# V& p+ W( a
  // 保存过滤设备信息/ b3 m0 q: l! ?- {, e; V; [
  //1 }) b( v/ N7 `" C( f
  DevExt->DeviceObject = FilterDeviceObject;
6 I" I0 K& w4 S+ s. y  DevExt->TargetDevice = TargetDevice; 5 f' y0 W( h2 w% J. G
  DevExt->pFilterFileObject = FileObject;8 l7 V9 w2 e( O) X, j  ]& P7 F

& V( a. c2 `3 o% D5 T. h+ Q- t! A: X  //
9 J( j7 Q# b% d4 L" o, G/ ^  // 设置过滤设备相关信息与标志
* d# Y$ c/ b8 h3 X9 l  n# j: j& e  //
8 |5 q& {& Q/ \; t7 ]- L0 Y2 y/ b  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
: r5 Y4 u5 }2 f: J* X  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
# `. Z3 E$ E9 s5 l7 Z! j6 u. m  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;2 y; ?$ \) ?, {4 {8 r) b" S
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
( T. c, Z  m: U2 I& s  y, U                                                         DO_BUFFERED_IO ) ); : X9 Z5 w$ D1 h/ {1 u+ L

6 u5 }3 n  c/ a6 U7 N/ U; \% b  //# Z9 z1 n, ~, b4 a0 F- W2 _
  // 返回附加后的驱动对象
" E+ K" q1 W/ h( W  //' }7 h8 H8 p& D8 T
  *FilterDriverObject = TargetDevice->DriverObject;
: v" J! {. C: d0 x9 W/ o+ [2 T/ T  L
  ObDereferenceObject( FileObject );
/ T" D( o. j+ \) k8 g* B+ E6 F( Q4 W/ E$ v& ]$ V6 j* h
  return STATUS_SUCCESS;7 V$ m( Z  @1 N' P# M4 J  F5 z
}$ {2 z, W' d5 ~+ v1 i5 I
4 _3 x9 p4 r. U  c' v5 I, b# J+ a' X6 `
/////////////////////////////////////////////////////////////////7 J8 [# h- \1 i. h  I. U
// 函数类型 : 自定义工具函数
* \1 X* F1 N; B) M. A/ S  ?// 函数模块 : 键盘过滤模块' ]6 S6 I3 d0 Y3 X. A
////////////////////////////////////////////////////////////////9 w( B% @% Y) f- h' W  l$ M
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发) D/ p: N# I( K# I+ X# r7 ^
//        这个 IRP 的完成
7 A3 D& @, Z) ?' D+ P) z( Z" E// 注意 : 0 f$ y0 T% P! H' y
/////////////////////////////////////////////////////////////////
8 m- o4 x, Y! _; G// 作者 : sinister5 o  r9 v, Z. c: o* z. C# x
// 发布版本 : 1.00.00" `8 z. G; i4 R9 Y
// 发布日期 : 2007.2.15- L# {7 v9 ]3 P* U/ o
/////////////////////////////////////////////////////////////////: f" B& ]. T3 y. M7 b
// 重   大   修   改   历   史
4 x# x8 G; Y8 |# }! d////////////////////////////////////////////////////////////////
$ _+ U- i( \( ?* t// 修改者 :
! o0 }+ d( J+ g) x+ ^, L' }// 修改日期 :/ `4 h! }8 d6 S6 n0 ~$ a* F
// 修改内容 :
( g# m* J, x+ \/////////////////////////////////////////////////////////////////) x  H2 W' d- K: N4 j- a" p
8 S$ M9 R: p4 t* H
NTSTATUS" q" Q. A) S% q! M
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )# ^) N7 S2 a, v1 k" M
{
* S6 H  g8 G: a) _; q  NTSTATUS status;
+ h; O" l+ `$ d: V& B5 B$ J  KIRQL IrqLevel;
. R. _: x( u, l% {4 r6 ~  t. X( M2 B$ W4 p2 o: f: T+ X* u  b
  PDEVICE_OBJECT pDeviceObject;
# A4 J9 k! }; G. D* v* E; j0 D7 U* X  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )9 u3 m0 I9 z2 Y/ z" K* X
                                   DeviceObject->DeviceExtension;
! J/ b' N- z0 H; }- k. T4 I
6 D) O8 O+ J" g9 j6 W4 R/ J4 f( k' ]5 d8 L
  IoCopyCurrentIrpStackLocationToNext( Irp );6 x% x2 B+ ~- `. v8 \& T' q

! _# L1 K6 w2 u6 }( y  //+ g1 o) h. Y1 j, R5 K
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁4 w% O  K/ G. W' P6 F
  //, i# S- X0 B( G+ s: p7 j
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
1 F. c5 C7 ^3 o6 [  InterlockedIncrement( &KeyExtension->IrpsInProgress );
) l3 F9 y) A; Z, K4 U  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );) d2 s+ W5 a6 v1 s% m

" @: ~+ l1 N$ d, y  T& u4 C  IoSetCompletionRoutine( Irp,4 n; t5 C3 x: q1 i1 R
                          KeyReadCompletion,
4 `4 [2 x% M, ~                          DeviceObject,
# l# t# g9 R9 c2 [3 P7 t4 R8 m                          TRUE,
0 g3 ?9 u% v/ a                          TRUE,
9 _9 j- c! I1 i) z9 l. V+ k                          TRUE ); . {' Y- m: T! Q2 Q# t0 ~

1 K" q2 {% o8 f5 s' B0 n  return IoCallDriver( KeyExtension->TargetDevice, Irp );
: ?& p% W! g+ j+ ?# h}
3 z& F2 v/ ~8 M
7 p/ O1 q. h2 k' D/////////////////////////////////////////////////////////////////
: U/ F' n0 m7 s- C% s// 函数类型 :系统回调函数7 g8 L2 G7 q/ `
// 函数模块 : 键盘过滤模块
8 T/ P4 \. T6 K8 M$ \- u$ i# O' ]////////////////////////////////////////////////////////////////
* E9 V/ K6 [$ |! @2 O5 A// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
0 }$ n% G4 X" }9 z/ O4 T, m% E9 s// 注意 : . L) O2 N7 A' \% N, H
/////////////////////////////////////////////////////////////////1 [8 ~! q+ ?4 ?  D
// 作者 : sinister
3 X& _" ]. C- @7 C2 [4 K0 k// 发布版本 : 1.00.00* q1 j% _! h+ C* T( R
// 发布日期 : 2007.2.12
; m) j" [  |1 X& D/////////////////////////////////////////////////////////////////
2 q- D& v2 X7 a# r+ `: N1 C// 重   大   修   改   历   史4 B& W1 O4 @' C  P3 K4 f3 T
////////////////////////////////////////////////////////////////# Y: a8 o( k3 w  d4 v
// 修改者 :
( K+ \& o$ P! A# [$ ^, N// 修改日期 :7 X; Q+ W9 ~  o- r; a
// 修改内容 :
8 V" q4 H/ l$ ^/////////////////////////////////////////////////////////////////" K3 G# }+ L* |6 b9 i, v. ^" v! u

9 X" m, P9 N9 [1 |+ H; TNTSTATUS
/ b& S. i; H3 xKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
/ k% ^( s% {; Q/ Y                   IN PIRP Irp,
- e  y+ K8 q! x( [                   IN PVOID Context )/ t, P; I8 v% L/ I
{
4 l( ^2 W; g" [4 {4 N  PIO_STACK_LOCATION IrpSp;3 {* k2 c/ V/ J& o+ \
  PKEYBOARD_INPUT_DATA KeyData;% S5 k' g  {) q" d
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
5 c- a6 i8 K8 B; ]) {4 q                                   DeviceObject->DeviceExtension; & l! y3 F, j- @
  int numKeys, i;
- Z( {' O& a& K2 o8 t% p( W  KIRQL IrqLevel;0 J0 g5 s: N1 ?

6 ], s5 F/ Q* f3 f) T+ w- ^$ i  IrpSp = IoGetCurrentIrpStackLocation( Irp );& |1 H, A4 T+ L. ^* T& |6 v
" e& G' {, I9 }4 g' F. _

: B- L% t* c2 j1 l7 `: W! C/ P  if ( Irp->IoStatus.Status != STATUS_SUCCESS ). R5 {2 a# A8 r, t* _- I
  {
8 q4 w" i$ _$ o    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );$ a/ r+ G8 X2 T* I. Z  z
    goto __RoutineEnd;
( H$ J9 k. B9 o8 i+ X6 I7 g  }
6 j/ j, A, u) p3 g5 v9 T( u' U6 Q4 a/ i0 I6 @5 d3 K& c! ?
  //) k8 A! E' _# ~& l
  // 系统在 SystemBuffer 中保存按键信息6 q+ n; _1 S6 ?+ Z' m
  //* Z9 M- M" v. A5 o$ I* n- |
  KeyData = Irp->AssociatedIrp.SystemBuffer;3 ^  N3 C4 e/ z) f+ S4 u, w
  if ( KeyData == NULL )# W. M% f2 `* o7 B
  {% b  h+ b6 r8 T) ~/ m
    DbgPrint( "KeyData is NULL\n" );
% p1 D( V; n# Q. Y& ~- A7 {  D    goto __RoutineEnd;
$ K) s2 J, v; f5 H3 l( x& c* w  }
& M' P3 }2 w9 {6 \, I+ R. P4 j8 g* N/ ?/ K; Y
  //- O7 y- x6 f5 S/ t/ D
  // 得到按键数' q% Z0 Q0 Y9 i! w- p# k0 B9 b
  //
3 ?' H/ ^+ r8 O) B3 J2 J  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
4 o, @+ F& ^+ q5 {  if ( numKeys < 0 )) D8 E3 S. c( V  S+ T# ^
  {3 Q2 `" A% T( @+ i1 b/ w% [$ `
    DbgPrint( "numKeys less zero\n" );8 F  g( S+ a4 D: x: F. @# e9 V
    goto __RoutineEnd;
) f) C* d+ c' {  q& W$ v2 Z  }
* ?" G6 x7 f; g4 K9 ]8 L$ n% Z0 K: y8 @$ R
  //8 n, k4 b9 a) Q( g* c3 x, T! M& Z
  // 使用 0 无效扫描码替换,屏蔽所有按键3 g  S1 L* W  o) z9 z- u& m/ X
  //) N( y3 E" u- w$ L, Q
  for ( i = 0; i < numKeys; i++ )& Y+ a2 o% K9 c( c( j! j3 H
  {
9 d7 {1 ^. {, ?4 X    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );0 S! P' }! c$ F* n
    KeyData[i].MakeCode = 0x00;
) e) q' Q/ [/ k# _  ~2 g' b" A  }
* e) n, i& Y# s1 a; V( o" H2 ^/ Z

' ?+ {4 i% h8 M# b' R. u9 F  __RoutineEnd :
" H# y3 D% s+ ^  x7 _$ J1 k4 A* r* b6 o" u% r' B
  if ( Irp->PendingReturned )
9 {& Q8 o3 z) E: j  {; y: O3 D( u# o2 A2 E9 C( \5 y$ ]
    IoMarkIrpPending( Irp );# P; N9 E# B' M% X  O# h
  }
  r3 X. D" H0 M# b  V6 C- a3 k' w/ L# u
  //
/ `" S! N) U( K& o5 H% I  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
3 ]) m+ D2 h  @/ l8 w  //( g( i4 {" e0 c! L2 o
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
. j  V$ _& s2 S  InterlockedDecrement( &KeyExtension->IrpsInProgress );( z/ }9 p4 V& t5 Z
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );# b0 x! w0 K4 O2 ~$ K! s2 D7 |
2 O% s5 j& q/ g4 }" F6 b
  return Irp->IoStatus.Status ;1 ?- Z  N# y- G# b3 G1 K* g
} - w; g$ e: c2 [' b5 p
+ R5 l3 a: n( D& {

) A$ h8 D0 c( @. j/*****************************************************************
+ X! ?4 k$ }) S, h4 a0 u7 b 文件名        : WssLockKey.h
, E* ]3 z7 l% W3 k 描述          : 键盘过滤驱动3 R; o7 [, x: E2 s# Y. o
作者          : sinister. I: }+ ^" Z; |4 T' d
最后修改日期  : 2007-02-26
3 G0 \9 A% m7 U) a3 z8 \0 e5 r*****************************************************************/
. b2 d4 p( W6 t) u" i% v; z' B# {6 u4 ?& c
#ifndef __WSS_LOCKKEY_H_3 H' I, Z# f. Q7 k3 J5 i  M
#define __WSS_LOCKKEY_H_2 d- w) o& \' t/ ~9 r  a

, J( c' ^& X6 F& z" e#include "ntddk.h"# h% `1 g8 M& N" b' h1 v# \
#include "ntddkbd.h"4 P3 G* n, Q; j2 ?7 N1 [0 i
#include "string.h"7 g' C2 I" o) M( o+ u$ Q8 `
#include
8 e& [( v% d# Z7 M
0 P; E% U, ]* Z& x2 D#define MAXLEN 256
& u4 ^: a4 U3 ]6 Z5 p8 q
0 ~8 C# G9 r. ~  L  {9 V" p% k& r" s; [#define KDBDEVICENAME L"\\Driver\\kbdhid"+ T3 L5 g( T( I. ?' f/ R+ m6 ~
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
2 U$ C$ O3 @8 w7 C' x( K' F#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"9 O- j# a) I; J4 ~4 v
" }$ o/ p/ M* N6 S) L* |
typedef struct _OBJECT_CREATE_INFORMATION
( J& L2 U' K& _* d7 ], F0 ^{) z0 K+ n& x6 J
    ULONG Attributes;- y* V0 c5 t; ^
    HANDLE RootDirectory;
, @% s2 v8 [( x$ A    PVOID ParseContext;
& @  ]: P$ g- v: P% w    KPROCESSOR_MODE ProbeMode;# B) j8 }. j9 V+ n* P
    ULONG PagedPoolCharge;
/ g  v. D& m2 h. l7 @# M3 w$ x    ULONG NonPagedPoolCharge;! D6 ~4 Z$ m+ i; `" _
    ULONG SecurityDescriptorCharge;7 r) N7 Y: o7 a- Q% {' l
    PSECURITY_DESCRIPTOR SecurityDescriptor;
4 T+ R. N, g6 y/ d! C+ b    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
1 w' q0 M# ~$ f7 Y3 F  ^1 m' b    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;" b7 \0 y# [. g7 d2 z; u
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
) Y0 i7 p# z4 h2 H
! L$ Y; F, J0 X  l0 r- utypedef struct _OBJECT_HEADER3 A  L6 z2 ~. L7 [, {" a4 x
{
+ L5 o/ ~- T! u; z    LONG PointerCount;0 ]4 B$ h* \! {7 b/ K% l  O
    union
4 p5 H7 c' b6 j& w& G' c' K    {' G* Z+ L5 R: @0 O8 T5 g1 g* g
        LONG HandleCount;% ?$ X: B$ e+ k* c# S/ M
        PSINGLE_LIST_ENTRY SEntry;
9 C8 ]+ e9 K& K; K; K3 F    };
$ Q7 P- c. g; {9 @" O    POBJECT_TYPE Type;
5 j/ ?# l1 {, X$ r+ p    UCHAR NameInfoOffset;
0 O/ X! B- g6 v; g  P! W    UCHAR HandleInfoOffset;& j: [8 s5 u' C* T8 n7 R; R
    UCHAR QuotaInfoOffset;
* ]& i  M* R2 t0 Y( f1 t    UCHAR Flags;
; P5 b5 i; _. F3 u5 N# o' c    union
: P2 D" c- i& F  m1 e( u" `, e    {
1 D5 G" ^6 k- w1 F        POBJECT_CREATE_INFORMATION ObjectCreateInfo;. G/ f9 x. J9 S$ K( B  a; P/ n+ R
        PVOID QuotaBlockCharged;
8 y6 |+ }. o! D9 A2 ?    };4 p; O7 P$ `* B0 O8 P" N' x4 O" e

* ?6 k& L+ O% u' ~& Y2 T7 J2 J% D% E+ A    PSECURITY_DESCRIPTOR SecurityDescriptor;
: p4 g* [& `' X! S  q9 v  M9 }8 b# x    QUAD Body;
) E1 }" j3 c$ j0 `$ [5 ~" c} OBJECT_HEADER, * POBJECT_HEADER;
6 Y, J6 ~0 L9 ]. I& W6 P& a. q* z9 o+ T/ y& j4 z) t- ?
#define NUMBER_HASH_BUCKETS 37( n) f( c8 K1 {. y( C4 ^* b$ |+ z

8 |' v1 q, Z0 N% i; x% [3 L* R0 Ptypedef struct _OBJECT_DIRECTORY
( s# Y2 `8 L4 r5 o{* D, T! F+ n$ S
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
& ^3 N2 x* X- A8 B6 I4 M$ V    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
+ k$ O  x: c( y2 s    BOOLEAN LookupFound;
  [& O( q) r  i    USHORT SymbolicLinkUsageCount;' T6 q3 A- R" G5 s- V
    struct _DEVICE_MAP* DeviceMap;3 I* ?1 {# M6 `. e; H' _
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
9 l( Z3 D1 X* ^0 `" p6 @8 _& ^3 C' d2 ?, e1 \; z. K- g
typedef struct _OBJECT_HEADER_NAME_INFO! v$ u7 Q$ z' h' R9 c: I- |& z& J# ?
{; s7 d: ~8 l' X8 V/ N/ N
    POBJECT_DIRECTORY Directory;
" K) }1 D4 F# k5 s) H7 V) N3 R7 u1 M# P' ?    UNICODE_STRING Name;
8 |7 B4 a- H: a/ W    ULONG Reserved;! @3 `4 ^  ]: L8 x
#if DBG8 E1 r  ?7 }" h- F. L. K
    ULONG Reserved2 ;- q# M" O) I3 M# `/ }9 }
    LONG DbgDereferenceCount ;9 J6 m5 l9 y2 P- |5 t3 d  Z, M
#endif
6 {) Z7 V% y0 X} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
# K3 }% O6 g  m  u& H' \/ }9 x/ e6 F; j) V7 u( Y: @' t  U
#define OBJECT_TO_OBJECT_HEADER( o ) \
: b2 m6 t- n7 o& }+ _$ P' S    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )6 M7 \3 c% j6 d

) Q. w" }1 h2 q8 x' m' \" E4 c#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
0 v- |* V# ]) Z; Z( n' l4 Z+ r2 [$ a    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
8 C8 ?8 K9 h2 X. N7 Y9 h2 n* O4 W2 l3 ^# a+ \1 ?
typedef struct _DEVICE_EXTENSION9 J1 a. ~2 B6 k; v/ V7 b/ d, l
{
+ }) v* O4 V& y    PDEVICE_OBJECT DeviceObject;
1 a4 o& v" \* f# A- X    PDEVICE_OBJECT TargetDevice;2 P1 F2 S, H' z% B' n3 B( V; t
    PFILE_OBJECT pFilterFileObject;( S( {6 z# L- E7 W& O* k
    ULONG DeviceExtensionFlags;
- V/ e/ D- [1 h0 x9 d    LONG IrpsInProgress;8 ~! a% B: X& w0 e  {
    KSPIN_LOCK SpinLock;% g2 I+ q. Y% W& M
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
# I( {/ O$ s2 O. n
5 t7 p, q* W+ _# o' b2 ?
. n) X4 }# P: o- O  m* uVOID 4 d. J5 [' S  C
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
8 B' V( `8 b% l# L& v- n% o2 \+ q4 O; l+ ?# `2 z
BOOLEAN
) J+ n& m: k' A5 q4 mCancelKeyboardIrp( IN PIRP Irp );: p/ R' x* A5 x: A

1 w& z. i' L3 y) B$ rextern POBJECT_TYPE* IoDriverObjectType;! o% Y. W  T' q% Q

$ l' J$ [  Y# a: RNTSYSAPI
/ {* A3 Q( s% B- A# fNTSTATUS2 p% E* ^4 }8 {3 _# U5 q3 t0 D  g
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,! \+ u( y; p6 |' e, h) H9 a
                               IN ULONG Attributes,
3 |% Z" V' M( ]1 I; _5 h  D                               IN PACCESS_STATE AccessState OPTIONAL,' u7 k  Z/ G" T
                               IN ACCESS_MASK DesiredAccess OPTIONAL,: `3 X# L2 E' _, Z, O$ s
                               IN POBJECT_TYPE ObjectType,
3 o! T* Q' |+ ~( r1 I' W/ s                               IN KPROCESSOR_MODE AccessMode,
- I6 U; C: k: I' }( I. f                               IN OUT PVOID ParseContext OPTIONAL,5 k; o7 m" j, {; i, B9 {' z
                               OUT PVOID* Object );! c( \8 p3 r3 `
/ h! |. v9 a$ ?! V6 ]3 S* ?* E% G
NTSTATUS ; U% T) R6 `+ x5 o( F$ e% N! U
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );1 L4 n0 {7 W& [

& d3 G; F$ f* p% ~# r' j) a) S: S4 mBOOLEAN
1 P. [0 n) b( n% P; D& yGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );5 o! S/ p" e" _: U- Q, ~

9 V4 ~- F8 _. @VOID $ k; D& Z& [: a6 ?/ d
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
+ z' ^; w% T- O4 }: |8 }1 J* o1 N: t3 Y  m3 ^, h9 A
NTSTATUS - }; Z3 a1 e' x& t3 L* q
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
5 v! C2 g+ B" {6 a1 h* q                                  IN PDRIVER_OBJECT  DriverObject );
$ f: g! C+ J9 Y
; H& v+ f' N4 Q. g4 ENTSTATUS
- U+ b$ t& B, _) l& h; n+ h0 IAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
6 \# F# d9 r& b+ Z) y2 L# l                                  IN PDRIVER_OBJECT  DriverObject,- J3 W3 ~2 K* [/ G& j/ Z
                                  OUT PDRIVER_OBJECT* FilterDriverObject );
3 ~. n* V" m( ^$ U3 q8 k# h( m+ x5 `; ]3 [4 S. v) Z, p" o
NTSTATUS
; m. g% y& A. d7 N5 s) B9 nKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,+ m5 b0 e6 ~& ]
                            IN PIRP Irp,
, h# {2 U5 j8 n- ]/ n( |                            IN PVOID Context );
! @$ x8 A# _& z3 r4 gNTSTATUS
4 }4 ?! g) Y2 }KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
  n1 m8 a2 R7 h5 z
* {- \7 e! {9 d( s/ aWCHAR szUsbDeviceName[MAXLEN];
" o' a) v7 I/ b' d
  m" V5 Q; h% g  ?( v* ]#endif3 B0 p8 J. A# t1 [+ D  |: e# p
! d' Q4 e( a# u% `, V8 F& Z. v$ F9 ?
8 ~& H% Q; G1 v; c* U& ~9 l

4 C* _/ d, v% R+ h4 `8 }7 p2 E6 F$ J

2 }3 f5 N( ]5 N( K+ h2 FWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。$ {3 d/ `( |2 l* J# u
WSS 主页:[url]http://www.whitecell.org/[/url] - [2 T+ i7 @' T! S0 j+ r8 F! Z
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2024-5-20 07:44 , Processed in 0.022323 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表