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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister5 g" Y/ Q2 ^( f9 O# ]6 K5 M1 k1 Y! F
Email:   [email]sinister@whitecell.org[/email]6 ~3 D9 _& R. p9 \: y) o5 y  g, X/ ^7 B
Homepage:[url]http://www.whitecell.org[/url]
7 j. |% ]. a1 P& V- vDate:    2007-02-26  }4 e6 S+ K. |4 R' }9 E: O

, c. K& M1 k: c( r/ {% i( W. c+ n
; F2 @, {" ]3 \9 c6 Y% u- n) K7 x/ Z1 ]/*******************************************************************5 H2 P1 H; h7 c
/ {5 {! P' f# i! N7 Z
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
0 u- x- [. A6 t& e* m2 ]/ b写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的2 ^" _$ J: \. y+ q# b  H% u
功能要求如下:
' ^/ k+ Y3 H8 o2 T3 R3 |0 f
2 W- n5 A. Q( Q2 Q3 |# j1、强制锁定键盘/鼠标。
3 T+ Y2 M( w, ]# v2、可动态加/解锁
, K" t) s0 n- Y3 A, A3 ]3、兼容所有 NT 系列的操作系统。$ R& ~' k+ F4 N$ }

' U$ [& e' B3 L- {" d6 o. x% q就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实4 S) L0 V4 r% u, k
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
) P% h; ^4 ~! w2 T何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在, u5 i  A1 s" `
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是" `: R+ w  x3 `0 ]; [" `# h2 W
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
, N$ o/ w/ N; }3 y  H2 y就来看一下我想到的几种实现方法:
4 }3 P: ?. \# {: x/ ^: _0 V
; v" u8 a8 _+ u4 b1、全局键盘/鼠标钩子
* i2 I+ o" c; Z+ g2、BlockInput() API
( o1 X" I8 ]/ m$ N! Q2 L3、使用 setupapi 进行控制( |# }! l8 l& D
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
0 R+ ]6 ~$ ^  d* w+ p5、拦截 win23k!RawInputThread() 函数
) x4 k) B! ?0 R; R6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动9 ^4 I2 T7 W9 a* [! R
7、拦截 kdbclass 驱动的 driver dispatch routine1 [. S+ D( b" |4 e6 P2 \
8、实现一个 PS/2 与 USB 键盘过滤驱动
; r& @( W% d1 F. `7 j! B+ u: ~  U  c2 ^6 N

) T2 E# L! t2 c8 i3 B) _8 ]. z我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑3 w, G) S( U1 M, h- Y
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方0 p8 W- r* r9 T2 ]1 G
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
" }3 g+ O5 t1 E8 l兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因" E: i) K, W: t# j/ T) Q
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性6 @! v0 C6 T; D0 {; P0 ^
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸1 j* y. P- b% p% C9 [4 E
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我9 q$ T/ s& r5 n9 @$ G$ k  d
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
3 g6 O3 P4 D! H  a3 O, F3 ^: f( m$ S也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
* {- B1 y4 p0 M' f2 c9 T% \* C2 y果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有7 N5 H% D' I1 H( a* K
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
% C: q! ~7 D6 X" x$ _IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 7 P& y7 o: r( T+ o0 m; }. {
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
# [$ H. V( D& w' O* }1 a' o# B1 U盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方& g; |) \3 K8 S
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
- V1 H, l- G, V3 E
5 p3 c- k$ P! N* Z7 j" ?" ~- k% s; n7 L
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过6 I; k) }9 b- m/ U0 b
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
( p$ C9 T+ P$ u# g/ H/ Q+ [* A行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
2 P! S2 C+ T' `只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
- C' `- \7 R- \+ ]; D4 a4 ?+ J6 c来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
% ~8 I5 N% `* {6 _KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB" l% A8 h3 C' }0 V5 L
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
$ i6 l; W4 S: ?% d: I5 w: u( T+ cIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,+ B, w) D% k' r# F0 k
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题: v/ u& q' T! @: X! M! d) u
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
, z! I) L; V, `9 U0 u) [而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
* _2 B- q! \. X3 E用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
2 r; j0 E. {; V* p6 I过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来/ I$ F: `8 u/ ~% ~
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
1 D( y' `0 Z' i  {/ i过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb  i% L' h4 O  [
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid & ?- T" X$ p' c8 G" Q
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意; }  H3 T$ X  i& s# n$ X" L* _& B2 u
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。4 [* q9 ]3 T2 r) `
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们& ]# |. D  S. h
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
7 B9 X9 N1 {1 K的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo! M, Q; i9 b: }; g% @  L
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致$ B/ b$ Q2 m4 t9 i2 u3 V+ g; F8 h: F
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,; b& C6 Y1 S8 [5 N( Z& n: O
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
5 `4 G2 u' u. A* m7 `见下面代码。+ G4 Z& c# j. A! H) s

4 D2 U: |  N6 z; [这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
& P* C; G5 \3 t% ^- x8 y里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键0 y' f: n, O) r) N! S
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003. a6 B5 J: g9 O9 D0 r
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有5 `" F! D! M  k
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
- r+ m( `2 F' D0 w# v* G继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个2 d2 m' n$ e7 ]/ L" L) Q9 T
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
( Y) J& M) G( b8 c' c, y0 o. {2 W键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。/ X& M9 \* i; J" G* {
$ n2 A( ?* r' o4 g4 P
: N: T" X. C" |
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
& q- l- W& E4 z: u的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是) q& g) n; I; T$ \$ t. O
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
+ j0 ]6 Y) Y. Q2 b- V. @1 i! W% A的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
/ D3 j' g' c: o) b们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我+ w5 a! e& m+ u9 t7 {+ X
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
1 R. m. d/ C( T- z' P9 S' Y->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
6 P3 k5 Z" {+ D, j/ b% k* z7 p/ R如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager5 C4 y1 V% A9 N& b5 R9 V
进行操作了。这个问题有待大家来完善了。) w" [8 d* A1 Q+ A  c$ t* B3 q
5 x* y9 i9 C) D, O, Z

; H$ X. f, W/ a要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
. U7 H8 R3 J" i; {来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
' N) }. }  A6 L  X. `" _分析做个记录而已。我更愿意把它看做是一段注释。% j& b9 f" r: P, P: `

( p$ |8 j5 d2 }" F& J最后在此代码中要; i$ N9 t+ I9 |* @7 S) F0 o
: T* v) U0 z+ f- R) T7 E' n
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
1 {! a/ f& T+ A% |) s: n( t+ ~- [3 v' y' f  `: y0 T
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
3 ]! Y0 p. J; M( G. j% I, g/ U4 a. r: F
感谢:齐佳佳,过节请我吃好吃的。
% V% E6 d( W6 ~; x
  v: P' ]: j% n" }5 `- a9 j0 b8 g. }$ o/ c, F$ V2 h7 N
******************************************************************/+ w4 ~/ i2 P' x( H! v7 l

5 W. z# i9 c/ ^. t9 Q
1 d# n" Y  i$ D( ~' ^* q/*****************************************************************
8 d9 \; f& c. M, \ 文件名        : WssLockKey.c, j- ]/ ^1 d/ D9 p% [
描述          : 键盘过滤驱动  J. b, a5 S" z9 N6 T# s: T
作者          : sinister2 ~( c7 m9 i, Y  P( _
最后修改日期  : 2007-02-26
" ^7 d- I8 Z- w+ M7 g2 @# |1 R*****************************************************************/# g+ \: Z* r* E9 x+ H; @$ o

) @' Q) Z( g+ K. C2 D' q- ^5 A  C$ v/ Z/ Q9 J3 s
#include "WssLockKey.h"- Z( I8 \2 V" j5 T; `
5 C) m( l3 [2 R! p- }0 Y2 T& G0 P9 N/ Z
NTSTATUS2 G. T8 @7 F( ]( A) b
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,0 W. g2 G( Y7 j; z# X, z6 J' \
             IN PUNICODE_STRING RegistryPath )
% R9 l- D# i- i$ s{. a, K( U" E. V6 f# O; R
  UNICODE_STRING KeyDeviceName;
5 ]) p& n, Z( w% l1 C1 f  PDRIVER_OBJECT KeyDriver;
5 |) N/ V3 }3 f  PDEVICE_OBJECT UsbDeviceObject;# c9 l6 S) R4 G* G+ w5 ?  H
  NTSTATUS ntStatus; , I8 {0 H) c. V$ F% o( w
  ULONG i; 4 t' W  q; A1 v* ~

: W" o5 h4 j/ j( W  w8 F  //4 N$ H  A1 B. {* b% ^" y
  // 保存设备名,调试使用6 ?. m! w; \& M6 K
  //" |1 |, ^! d1 P
  WCHAR szDeviceName[MAXLEN + MAXLEN] =$ b! h- ?5 T/ g- Z6 J
  {4 F9 {# f8 Y* i% [. k: a5 S# k
    0) [8 R- P( C. y; }) n* |( Q
  };
2 J0 D$ I+ {, }; |) k$ G% [* D2 g7 g9 N7 b, U# }0 C
  KeyDriverObject->DriverUnload = KeyDriverUnload;
$ ]( o* p' f! `( i( u* `
4 U. w2 F4 _& O/ _" e' E* |7 B  //
# \* n$ @- h+ q: Q  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘- z! j# u, y  ]7 |8 S3 v( {) ?
  //
$ A8 }5 b7 C  R; N6 P4 u  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法0 N2 P* m4 O6 ~3 v( w8 x
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
! C7 B' J3 D( j* H# l* z  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到: N* x1 a& A  d; S6 l9 S/ q
  // USB 键盘设备来进行挂接: c' V& c2 X2 A& J. a8 v
  //- E2 A5 n" H, G* i0 |
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
( M' `2 O6 U4 x; t  `  D, s- w  [  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL ); u& e" p$ G6 F5 N* A1 O. M
  {4 q! l: _! I7 M+ [/ k1 m
    //( C7 b: W3 q; Z+ P5 `* i
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
8 O( I  D' V$ i    // 所以这里打印为空
0 f6 z# V# L; z0 x8 {  T3 Q    //
6 X. M7 ~. X' g( X0 ^    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
9 P( U# K+ C3 T( O! \; x    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
8 X4 ~' s( M- F! r  x( p9 B2 Z. y! L( V, D; t; ^: @) y( J. ?
    //
7 W# j' @! H2 b    // 挂接 USB 键盘设备
4 E$ \9 n4 R7 R5 z) n7 Q) I    //
, n* G& X7 c6 f6 R4 l    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
: x  d+ Q# }9 s; |    if ( !NT_SUCCESS( ntStatus ) ). A1 K$ W7 o1 W2 L+ O
    {
! `: ^# Q. {* y0 D      DbgPrint( "Attach USB Keyboard Device to failed!\n" );& [' a* X6 t9 w, {5 I, T- \6 [$ |
      return STATUS_INSUFFICIENT_RESOURCES;
) l# i1 l5 O6 c/ ~    }
6 e% j4 M( D6 W( T9 Y1 K  }! d$ r5 d/ f! |. J
  else
+ G" z/ ?; r, ~( d  {% t+ D+ a6 p! z: y# _7 K6 D) i
    //
. O/ ^+ C" B1 S  [. A    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备# W0 t4 J% |6 [! j
    // ; |5 E: j% H9 o) l6 [0 X
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 6 U4 W9 B7 i4 j/ }  U# i

1 }2 h4 o  }) m0 r    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
; N9 X/ i# a5 R                                        KeyDriverObject,
4 C6 ]# ]% [/ P) E( k                                        &KeyDriver );: M: ?# l: \" ~4 ]" B, K6 F1 s
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
  [, K; H. S" u9 u: M9 W  t( Q    {
$ t3 D# ?- C4 T! W/ @      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
+ X2 Q# V$ A* R      return STATUS_INSUFFICIENT_RESOURCES;
; I% _0 x0 s3 Q5 |6 @' j% u3 ^    }
4 @5 d/ j' |8 ]7 X  }4 w+ I) b4 K1 [# q, a1 v% Q

& V( [! N% b8 J1 q' m4 P  //
) }; s5 x, T1 J0 M$ J& w4 n  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
" Q6 y3 ?) F1 n" C0 \* j' r  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
" e5 n4 A) u& m; _. G; W  //
/ R5 X( I- v% D, o' e  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; * ^5 V) N" e9 k  U3 e

2 M- K' [: ]. T( @! z; x8 F  return STATUS_SUCCESS;
2 ]  F. v* Q  R! H}
/ c7 P3 W6 ?) h( Y+ D+ m+ M" ^6 n3 n' n5 W. M
/////////////////////////////////////////////////////////////////
' X/ \5 o+ K* O6 @& N! _% X// 函数类型 : 系统函数
) R' v6 h: K7 c6 t// 函数模块 : 键盘过滤模块1 u4 Q& G, `: f, L9 c. F& k# N7 N
////////////////////////////////////////////////////////////////
- I( m$ M1 l8 u7 v: o4 w// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,# Q0 R8 u$ [: j- o7 C9 e5 ]8 K
//        卸载键盘过滤驱动8 k! o* Y& K; W: F' R) ^
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
/ @6 o/ R) T5 G* k//        则需要等待用户按键,以后有待完善
' c! O$ u$ H4 Z) w& x! V/////////////////////////////////////////////////////////////////2 B: x, A* n  Q5 u) d" {
// 作者 : sinister
; O4 g, a0 r: i! G// 发布版本 : 1.00.00  ~! T" q6 O3 ^1 B8 c
// 发布日期 : 2005.12.27# r8 i( E4 q. j3 ~* F
/////////////////////////////////////////////////////////////////2 W7 W/ A* Y1 g2 i# B: ^
// 重   大   修   改   历   史
/ q( {% D8 ]& p2 |0 F9 u$ {////////////////////////////////////////////////////////////////( l. b" Q2 c# o" u; d) i
// 修改者 :; u& n! N) U# u! H
// 修改日期 :
% X5 n4 d" d. v5 ?) F// 修改内容 :2 p0 r/ h" S3 x7 J) O3 b. ~5 ]
/////////////////////////////////////////////////////////////////
5 G9 w& X- o5 d: U
2 j* Q6 C. R* V' bVOID
4 U, r  r) W' G. `  O3 \+ HKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
: m; q, b! K/ n% g1 h% M7 V{7 w# V! e$ h9 D
  PDEVICE_OBJECT KeyFilterDevice ;      
& ?/ P" g' ?: g  PDEVICE_OBJECT KeyDevice ;2 v5 B* H( g' B, Y( T4 `
  PDEVICE_EXTENSION KeyExtension;
* ], E- Q* M# g) C- B; b+ f  PIRP Irp;2 I3 x6 j2 }  I
  NTSTATUS ntStatus;' F& O9 \, W3 O# L% c. U  @

- l) \2 {2 I2 S, o5 \  KeyFilterDevice = KeyDriver->DeviceObject;
3 t6 k; j  Q$ d4 v  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
0 O& B5 z' v  i' j* W) m! L" \# ]  KeyDevice = KeyExtension->TargetDevice;
/ G$ y- W+ U* a' e; h
* N- R* U$ ~. }& l  H8 \! A  c  IoDetachDevice( KeyDevice ); " s6 B0 f7 W$ R: _+ z3 |+ Z

3 E* i& h+ L, s- P6 f! W  //7 F7 q9 _/ s) B6 p- |
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP7 l! g0 S( _9 j9 q) M! y* ?
  //
: n  H1 q! P' f- Q' m5 T  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
3 T4 i( Q* |" A8 h: k* O9 w  {
5 b! R" G5 c( \2 g    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
# s9 p$ F6 \% s" r! [    {7 K  |! ]' r, {+ A. P2 s! a
      //, K; ]5 s$ L( g4 J, `9 Z: ^' M9 @
      // 成功则直接退出删除键盘过滤设备" U5 v# H# J3 T* B, k
      //" f" m0 ]% A: n9 j: y5 z
      DbgPrint( "CancelKeyboardIrp() is ok\n" );5 b4 @  W. Q; H" y6 [2 A$ D1 @4 g1 @
      goto __End;
: h# ]6 U: V: m- t( Q( E& d    }& _! P2 f/ I  |9 \  n1 y
  }/ t8 j( u7 h9 |! C
0 R$ P, W  R( D  G. |: d
  //9 B' b! j+ I: n3 s' r
  // 如果取消失败,则一直等待按键+ \3 ^* v# A$ J( X2 F0 w9 N6 {
  //
% y& h3 F" g$ t0 Y6 ?4 M  while ( KeyExtension->IrpsInProgress > 0 )
) X$ u3 d* s4 ^& l) r  {
: v$ I6 v5 s/ O+ l6 T    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );- }2 w8 j9 E1 S% t; n$ e) n
  }
! g6 u# ]; r: H" O0 `$ Y3 r
6 k& x8 a  ^5 W6 v% F6 A  __End:
0 i$ f, {% A* ?! u( I6 v  IoDeleteDevice( KeyFilterDevice );
# f* W) N3 ~4 ^% ?3 K
2 s, |# i8 p- j7 w6 d  y( J  return ;- L8 |3 o8 u* g" O" ]6 m
} % q3 o& [9 Q  F* @% V
  R/ {* s: T& C) o2 y
/////////////////////////////////////////////////////////////////8 r. s! k6 G. g) I4 d/ a  {7 e
// 函数类型 : 自定义工具函数9 d3 {4 A1 q8 Y& k4 C
// 函数模块 : 键盘过滤模块( `+ c/ j. ]: q, k
/////////////////////////////////////////////////////////////////7 [$ T" g  F' V1 [. P
// 功能 : 取消 IRP 操作9 C4 \2 U9 q# _4 s0 d1 x' M3 _
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能' U6 V/ c% H8 n2 }4 V6 y" `
//        使用此方法来取消 IRP
! ?! X2 _( t6 c6 [& [- D$ f/////////////////////////////////////////////////////////////////& P3 T' F. S# Q/ B3 n" ^/ E
// 作者 : sinister! D2 o" X) m4 J1 Q# D( ]! D) i
// 发布版本 : 1.00.003 [. N) s8 Q# M7 T; Q: U1 g
// 发布日期 : 2007.02.202 y; Q: D& X& @7 \& f  Q, [% Y* R
/////////////////////////////////////////////////////////////////
+ `# F. G, j' v9 [$ @// 重   大   修   改   历   史
9 b: T2 T: L5 ~( r. ]- u( J0 m/////////////////////////////////////////////////////////////////$ i# R2 r7 e/ u9 M+ d6 J. `7 E! }
// 修改者 :
. R: S  h. L( p// 修改日期 : ' P2 q2 {0 U- m! z  n0 x% k
// 修改内容 : 6 G( w9 P! k7 U0 n% r
/////////////////////////////////////////////////////////////////" l0 |7 ?. a( b
' D2 \- S, Z+ W
BOOLEAN" ]6 U* @/ O9 m6 L
CancelKeyboardIrp( IN PIRP Irp )
# t" _0 N) D  A, a' ]3 Q% |( |{: @1 K& V* x- t, w9 V' f2 {
  if ( Irp == NULL )
  e  V. u% Z2 u  {9 X2 a- i% t$ B1 x/ ?
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );  B, n- ^6 p' r1 O  p) D
    return FALSE;8 T( B& K5 @0 U6 |0 I8 |
  }
! B* {) A% F0 q' f; q
  u) x: ^: D  K4 c
5 y' ?! m  k4 C0 t$ L1 ]  //+ s! M7 d7 S* m/ S+ h
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
" t3 L$ i. G, j) p- e# y( U  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
$ y: {1 W- s+ |* }2 \  _9 b  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占% t& c4 L9 x9 P8 H
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD2 c, w- {' m# g7 L$ |! |1 R
  //
4 w% G9 F# N: Y$ N' ^7 |; A  |# R3 _- `+ f
  //
2 D# P- T) C! w' B  // 如果正在取消或没有取消例程则直接返回 FALSE
  r* J* A6 m) O# [, u, h' n  //- f# K5 n; b, A: [
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
% h. d) U# j8 [( E. \0 o  {
9 T! X! G: |0 w, e$ z+ N    DbgPrint( "Can't Cancel the irp\n" );( A0 k* F, e1 |
    return FALSE;
+ \5 ~" q; c) l2 T; {% k  }( m( Z% Q; t. ~4 T: i7 J: Y( b

/ A$ u3 \9 c: ~' Z# P2 L5 |# n  if ( FALSE == IoCancelIrp( Irp ) )
/ N" C/ h" o2 C8 \  {" ~! h8 m" r) q, r
    DbgPrint( "IoCancelIrp() to failed\n" );
4 e8 s2 h1 V, [: f4 ]1 S    return FALSE;# `+ X* a; E8 j: \' R( [3 ]! ~
  }
- `1 t0 k* [0 Z" ~6 U/ h8 e. }, b" J# k& Y! o4 r: Q! }1 `
  //
1 i9 V6 G3 d' b$ x3 }  // 取消后重设此例程为空
+ `  B) h9 C+ r8 e  //- Q2 g8 c; w- l4 w) g1 X
  IoSetCancelRoutine( Irp, NULL );0 z1 A1 R+ g% K
9 w# c  H4 A. F7 L2 m) R9 |
  return TRUE;
/ [3 t; s; b$ W4 |( n2 a2 A. [1 _}
5 s% E; S7 e4 S! i6 `5 t) g% W+ I: N* q. l5 m( h% [8 o
/////////////////////////////////////////////////////////////////
2 W. g+ W: D2 S5 c4 z* ?// 函数类型 : 自定义工具函数
( |! d1 P& i+ }// 函数模块 : 设备栈信息模块
0 Y- s% C+ x& q- Q. k' ]3 O% W/////////////////////////////////////////////////////////////////
2 s3 ]7 D$ W, [) a$ S// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘$ E* u7 r& B: W, Q, a
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)" i7 \9 E1 X* e. J  G% a
// 注意 : 9 |0 }: L' W5 c" Q7 V0 E
/////////////////////////////////////////////////////////////////
+ `' M* L  G, O// 作者 : sinister$ A; m- K- ?4 N$ v* X# P* U2 q
// 发布版本 : 1.00.00
4 I' ?# i1 {1 |' l" I$ w5 H// 发布日期 : 2005.06.02' m; S" u" l- P4 p
/////////////////////////////////////////////////////////////////
( F" F. g$ q0 [% U1 [// 重   大   修   改   历   史
8 h' h! x3 U- F5 q0 Y/////////////////////////////////////////////////////////////////
7 B8 o7 I! c9 @5 m4 F( o  n  E// 修改者 : sinister
" K: X$ O6 |$ h+ c// 修改日期 : 2007.2.12
; g5 e# S, J% u* `+ n// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
1 e0 r. g1 }# k2 x/////////////////////////////////////////////////////////////////
6 L, P3 E# d7 Q! d. }3 z3 v# \# e7 a7 E, z# |  l
BOOLEAN
7 B( a+ f# m' @5 F" QGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
& R: @8 b5 C( ^: ~7 h) B8 W: b$ Q+ ]{4 N7 U: V4 P1 p+ X
  PDEVICE_OBJECT DeviceObject;
* N6 g# l0 M1 W, D  BOOLEAN bFound = FALSE;
6 ~- |1 q# z' ?: I+ L4 f$ P
; {- a# e& g7 C4 Q  m  if ( DevObj == NULL )
3 a! [' R6 F0 \& g7 }  {/ S  D3 Z% F8 i7 }6 t- F
    DbgPrint( "DevObj is NULL!\n" );
  b, q, o5 x' Y6 C3 f( s  I8 V    return FALSE;
! k9 t1 U( h, Y* n  }
: j( O  Q  ?8 d
1 F5 _# j1 u( b* i) e  t  DeviceObject = DevObj->AttachedDevice;
# g, ~- \3 i0 X. ~( U* i+ V' ^0 T  c
. D" g  |% q, B) R  while ( DeviceObject )
8 {7 Y+ u. |$ D. ]: m9 p" Y; @6 d  {2 K5 Z0 Q+ ~* X/ R1 G3 E
    //
! W5 A& Y" _  R8 @% q  s    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
2 u: V; G% U, K3 d+ d    // 有一次足够了。这算是经验之谈$ H1 j5 Z2 @4 F$ b( k- j7 K  G
    //
! o9 s. t+ [/ i# g    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )/ i6 S- G& s0 l
    {4 ]* |2 K2 U  p. r9 J
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
! z# l/ f) ~) k* Q' [  b                DeviceObject->DriverObject->DriverName.Buffer,8 Z# B1 H6 `) \; `9 O2 `! f
                DeviceObject->DriverObject,7 O; @: n8 e/ a& m" S
                DeviceObject );; c; k( L, f3 ]4 e' C

1 K$ X* b: P% Q8 p% E/ g+ U/ T$ _5 J      //- i# l7 C$ k5 F: F
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了- ~9 `& I, L9 e2 r4 b5 a
      //  v% ^% r7 P/ Q6 H, }5 V
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
) w1 m1 L+ a2 E* M                      KDBDEVICENAME,# ]; c; B! g6 @% O
                      wcslen( KDBDEVICENAME ) ) == 0 )
4 L. S: h& }* w  [3 d) O      {/ d) s5 d* z; q# g" q
        DbgPrint( "Found kbdhid Device\n" );% c& D4 P/ a1 w2 ?8 g
        bFound = TRUE;
  ^: {& T: q$ U  s        break;% t' ]: B4 F2 K& f
      }
5 k/ A/ G! l: [/ G9 x$ X; U  y    }
- l1 h4 W% h' B9 e3 A# v' D4 h
# A/ ]6 D. `. V, q5 e    DeviceObject = DeviceObject->AttachedDevice;( _+ w' `* n: I( s8 l) D3 g. @+ |
  }
$ E! ]8 t  b5 ?+ O8 g9 F$ [+ ^- ?8 ~+ X  z- g* `
  return bFound;
, Q. X8 n. o; B. |' {/ q0 Z1 f}, g" e, V- F: H6 G5 U

+ v7 u% `' b. e4 T% d& G/////////////////////////////////////////////////////////////////
$ z; b4 T$ j' k' X* i1 m: o6 S// 函数类型 : 自定义工具函数
% X& w5 ^+ O8 N3 g// 函数模块 : 设备栈信息模块! a% W8 ^3 {$ l5 j  L
/////////////////////////////////////////////////////////////////
4 {6 _+ \! N1 C( C8 V// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址+ z9 r" u( g$ {6 a$ w
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改7 C& L' o( ?3 R3 x! P' e# T
/////////////////////////////////////////////////////////////////
6 H' K8 ~9 @4 q// 作者 : sinister2 R4 w; z: w9 U
// 发布版本 : 1.00.00
3 ?7 P% N( i( R" m: i1 v// 发布日期 : 2006.05.025 k8 o( Y' s8 ~2 Q
/////////////////////////////////////////////////////////////////; ?5 [) L: q* G! s6 R; g
// 重   大   修   改   历   史
6 E2 K% {  ~. V4 A0 C/////////////////////////////////////////////////////////////////
- ~$ s- u  T9 `// 修改者 : sinister* y' ~4 f/ i* U/ K$ L; }
// 修改日期 : 2007.2.12
/ _4 |2 d1 a( E' ~// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用7 l1 j: G# `9 g% @
/////////////////////////////////////////////////////////////////
2 U3 B: ?0 t& k% V/ ]
9 `* P% X2 T! @$ l) P6 B: p! l/ yVOID
: ~9 M* l& e7 M+ K9 {) j/ _% g) V: QGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )" c( m& }( z# I* e2 u
{1 G7 ~0 _5 U, [4 n  J( v
  POBJECT_HEADER ObjectHeader;  ?& j, P7 t7 S0 E
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
, S( F  V# W5 u
2 O7 R/ u5 D/ A$ K: R6 j  if ( DevObj == NULL )5 v8 n3 I% }2 `% P7 r# A$ Y+ e  j* u% @4 ?
  {
- [* B$ b* g8 }: L* d; h    DbgPrint( "DevObj is NULL!\n" );3 p& J6 h0 z& c
    return;' ^, \. Z' p# h
  }
% O2 n) B) A: S4 R/ J# Y+ i- ?2 \5 R) M
2 J4 M& z5 p# B8 k" n  //1 {# Q$ S- J4 H$ z& ?. x9 U; \
  // 得到对象头$ g- V' X! [% ~) F" N6 L) S! A8 D
  //
7 `3 s+ n$ A/ f; B$ D2 Y) J3 }  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );4 M! D/ z! Y1 ^/ x! x& U

$ Q3 e4 Q. G2 ^. @  if ( ObjectHeader )1 [9 B) B# O& [  o
  {  D9 d2 A+ h" I* h% n3 W
    //
1 R* C( Q! V9 h7 J. [" k    // 查询设备名称并打印
5 x7 k, p6 ^7 G4 }    //
2 j" H% B% m4 X1 O% X; E    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );# J  }" g& J' E9 x" b7 M
/ V0 i/ o  z. t" S3 M
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
- n' M2 E0 }: |" r3 C. C- }    {" {3 f- N8 `/ y: W" E4 E
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",6 [* A8 \, i! @, @
                ObjectNameInfo->Name.Buffer,9 Q0 l1 I# W% f
                DevObj );
, f; R) Z: V& f2 J( R. |  N' ]/ s" N( [: F1 n2 c
      //
- ?6 g6 R2 w/ e  l7 h) r& V6 _6 h      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
& c/ K3 w& a( ?2 J9 h1 {% S      // 用,没有实际的功能用途
* r5 s" ]/ b5 w9 m& W" x+ A      //
9 ]; d. y2 B( J: K& e. P      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );7 g2 M0 c: F( h! W/ h$ x

2 X9 T5 z. B4 Y  h+ ^& d) ]      wcsncpy( szUsbDeviceName,& A3 `: R: L1 N+ O$ e5 Z+ e0 `# x
               ObjectNameInfo->Name.Buffer,8 y/ P. ^5 |( M* ^; X8 [
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
" ?) P9 c6 L( K3 [  h  M    }
4 }  k3 h7 z- a7 x5 Z+ o
7 c* H. x" k! \+ Z9 y1 i    //
  Y5 l' b- w1 M" x# s/ A    // 对于没有名称的设备,则打印 NULL
8 L$ X4 F# {4 u    //
+ l1 S' S/ C6 f  y, _8 _    else if ( DevObj->DriverObject )
+ }3 C" r  L. l    {4 q( ]# b, t, q3 A/ Q! m* c! X& K
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
0 W, e  i4 I. t: F" `                DevObj->DriverObject->DriverName.Buffer,
1 ^1 u& C$ h9 o9 |  k                L"NULL",
) ^& R0 H: ?% c9 u6 p4 L1 j                DevObj->DriverObject,
, o4 c5 h9 f* g9 c$ }                DevObj );4 r# w6 H  W6 U% H$ b
    }
; U, j! v: v- K5 n1 p5 n  }. j+ L$ I/ X; Y1 m( C) z. s& d
}
; p6 V, I$ `1 h) e- }1 ?0 K3 S+ }1 H7 C0 e
/////////////////////////////////////////////////////////////////
- `, U) v5 l; w+ u: q// 函数类型 : 自定义工具函数
4 Q7 |  M8 z' j* e// 函数模块 : 键盘过滤模块
6 i% Q, n% k4 e/////////////////////////////////////////////////////////////////' e$ f$ l3 U* }" C
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
" N* z% H% A7 v//        对象,过滤出 USB 键盘设备,将其设备对象返回9 F, ]' A. W$ O' g' g4 p" ~
// 注意 : " N9 i0 G3 \4 b# ?, E* p
/////////////////////////////////////////////////////////////////
! z7 u/ c+ _, [5 s1 g// 作者 : sinister- p5 Y1 U; x" @; A5 U/ _
// 发布版本 : 1.00.00
+ B) t2 y- a$ z8 h8 l* U// 发布日期 : 2007.02.13
4 h6 L& E0 M8 t6 ?! l& O" \2 B; @/////////////////////////////////////////////////////////////////
0 g8 U' Z( R# I1 n// 重   大   修   改   历   史# k+ t8 G3 O7 R5 ~" m, _
/////////////////////////////////////////////////////////////////5 a4 A( Z1 u! w) v: u/ `& y: m& |( v0 ~
// 修改者 :
: h9 |9 C' x2 q! d; k: q  ^+ {// 修改日期 : 0 M' s0 M4 V" O, p/ `" i% P) Q; V9 n8 S5 b
// 修改内容 :
( O3 |9 o7 c+ B2 h  ^% g  d" \9 s6 w/////////////////////////////////////////////////////////////////
! `, |8 ]! Y& _2 y8 m
8 k2 m) ]4 r! g) W# |# {NTSTATUS7 ?/ j: X0 c! A( }
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
. C3 f) T' D5 f. Y  ]{% U. g, X# \' E8 L+ y1 z' k5 G1 R0 _
  UNICODE_STRING DriverName;2 x7 ^' o6 C* X4 B" P1 M3 A  g) V
  PDRIVER_OBJECT DriverObject = NULL;0 a+ l2 [% F; K- w7 l
  PDEVICE_OBJECT DeviceObject = NULL;
% B8 J6 O9 b- [8 O  BOOLEAN bFound = FALSE;2 V' e' |: \. Z' {
+ Z8 A2 O1 B4 {
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
( |  o, s# ]* R8 ?8 O% H: \% y. n  q' k5 `( O
  ObReferenceObjectByName( &DriverName,
$ S( h* l9 E; V" V7 k3 u                           OBJ_CASE_INSENSITIVE,
4 N+ e7 O2 s9 Q8 p                           NULL,2 @" J* ~- i# e
                           0,# D- g6 M( Q( p  x; d' }' i$ {
                           ( POBJECT_TYPE ) IoDriverObjectType,
4 o' ?9 g) n& |' D                           KernelMode,  A7 P6 x# C5 Q+ J) |9 z+ m' t9 \9 w
                           NULL,
, |. p2 L1 q( J4 j& d2 m( L                           &DriverObject );
9 b$ N2 m0 T2 |/ ^
' y' e2 F* ^- f1 W7 w- a& K  if ( DriverObject == NULL )1 e" L. C2 k6 t- F, |5 _
  {
* w2 S1 y3 u/ c    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );/ V0 _! Y$ a* F3 {
    return STATUS_UNSUCCESSFUL;1 R" o% s/ x; k9 o, W. H
  }
/ L- b: J0 k5 ?
! J5 B* ?+ E- V  DeviceObject = DriverObject->DeviceObject;9 N( O) ?. @" T3 Q
' J4 L) y/ ?+ a$ B! F& q. _
  while ( DeviceObject )
6 Y8 ~1 h1 M8 e1 T0 G  {( p% N# J4 ~, L+ F4 D
    GetDeviceObjectInfo( DeviceObject );
0 A, y$ C! n4 @$ ?" W: s% }# X( E+ Y$ j$ Y
    if ( DeviceObject->AttachedDevice )
" F% p4 @  N; z; z    {
  E  S2 p) C) p/ h/ w. k      //* r0 n* q6 d8 E' ~# n& n) o
      // 查找 USB 键盘设备
+ C- x/ ^" z9 o9 R- G1 H      //7 \( A0 x* w1 L2 U. N! c
      if ( GetAttachedDeviceInfo( DeviceObject ) )
1 ?) p: l  S& D; [# b1 U      {
0 f% ~$ @, a* w6 _9 {        bFound = TRUE;7 J( w! f5 t$ ~0 j6 q" o
        goto __End;
" k7 u& [4 T3 z  g" g  m" l      }' d4 \+ X1 j, K2 E& s
    }
* K6 m, K0 u/ E' n4 D3 q# j9 \* R/ p& |  C- Y$ H6 b
    DeviceObject = DeviceObject->NextDevice;
7 G" x$ b8 n4 Z0 W+ n5 n  }0 v: B( c5 f6 S
$ t. c' W* \3 B& M7 ?
  __End:9 o$ U, k& }. L; r
1 ^* K5 d! Z- y
  if ( bFound )
& _0 c) F& X- T/ ~" B  E  {
2 |8 o/ z: @7 p7 l/ p# C1 c    //3 U$ ~( c$ T  M' n6 ~/ X
    // 找到则返回 USB 键盘设备对象; a9 Z+ h' I9 X# d: u
    //8 m* \5 i. X. l" Y7 Q
    *UsbDeviceObject = DeviceObject;
" O9 |" M- Q2 P( X# M  }% c, H" h1 w* p* ?0 |. g+ n. ]
  else8 i/ A6 o: D3 I' g
  {3 o; t: ?$ @5 [3 A# [
    *UsbDeviceObject = NULL;
* D- a8 K8 |. e0 [; t" ]$ A: @  }
7 Q8 Y, U2 w* d: P9 Q5 S9 F7 M
  return STATUS_SUCCESS;2 o" q- `$ y6 U
}& V* r2 l& f+ `' ?) n- n
6 C' ]: y  x8 w8 P  n: d
/////////////////////////////////////////////////////////////////
) B, r3 b" ~) }& @( s( C// 函数类型 : 自定义工具函数
, g8 ~3 {' [8 t8 \. A// 函数模块 : 键盘过滤模块
7 ?+ p9 G( V2 ~; v4 H$ T( A- X////////////////////////////////////////////////////////////////! a7 P. e0 B) ?4 o/ b! r2 l  z# F
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
- Q4 j3 A4 ^- y; w0 Z# Q//        信息,返回附加后的驱动对象
. t5 P! q, M  Z0 L$ `' N// 注意 : 此函数仅挂接 USB 键盘设备
1 P, @" S8 S2 Z( E* q/////////////////////////////////////////////////////////////////
9 [  V( @/ K& M- t* ~1 s// 作者 : sinister; {& W' |, l6 S4 J9 {& S  G
// 发布版本 : 1.00.00
3 l. A; L) v9 P) [// 发布日期 : 2005.12.27$ x5 L  X) t$ I- h7 D& }8 Q
/////////////////////////////////////////////////////////////////
( t! D- _0 W' ^5 B- H2 e) A5 d# ^// 重   大   修   改   历   史4 i. g& _, k: t0 a$ q4 F3 V
////////////////////////////////////////////////////////////////. ~2 T1 a7 B: W6 e* E
// 修改者 :( q& E6 ?' ^! a% O. y
// 修改日期 :
5 o- w3 N2 L. `9 ?6 s! ~1 ~& O# _// 修改内容 :
& \  n/ _- j2 \* v2 P+ [/////////////////////////////////////////////////////////////////# S7 ]& }0 A. ]

. o; H6 Y! G1 f5 P3 qNTSTATUS
0 ]$ B" j# [- z3 r  e" R0 J( rAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,( H! _' I7 \5 b* N
                         IN PDRIVER_OBJECT  DriverObject )
+ B9 A7 R. {: x: D- [{
4 b8 P6 O/ H7 U9 u: j/ e# O  PDEVICE_OBJECT DeviceObject; 2 z: H8 F6 e3 K5 \+ ~
  PDEVICE_OBJECT TargetDevice; . x: ?5 Q/ d0 K9 k
  PDEVICE_EXTENSION DevExt;- Q& I7 u0 c  m, {7 i9 w
  NTSTATUS ntStatus;
4 \  V5 D$ `) i" o' U$ G; w
$ z" X' w3 x& s4 _, V+ a  //
' w) P. Q4 s( E2 q$ O3 u  // 创建过滤设备对象; d$ b0 [% F0 t' e9 O8 a7 ^
  //7 G& J6 M: f# X* x
  ntStatus = IoCreateDevice( DriverObject,* F" }  m" n' [! h0 O( Q
                             sizeof( DEVICE_EXTENSION ),
! s1 n7 k* x$ ]! T# W; y& }( d/ Q                             NULL,7 a+ N. o, V) ]- n. w
                             FILE_DEVICE_UNKNOWN,
6 j& O+ s1 c' ?0 n                             0,
8 v) w% `# `- t  t                             FALSE,
. H: b  R1 c( Q" {/ u3 ~" [                             &DeviceObject );
- L- v, p+ Y) b0 b
1 a* N4 b6 v0 r  f1 T0 g+ [5 t0 }  if ( !NT_SUCCESS( ntStatus ) )
; k( v  M& z+ R  {' f  i( T2 [6 f9 X( G
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
5 s( Z8 y# s/ I! }/ U, A( k    return ntStatus;7 j& I8 T" ?+ X
  }
# v$ G! G' O- @( C* e' ?" o0 U) I/ U  L6 K, n* ?
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;  h+ G! c$ ]1 K

5 P% F  z) z  L& J6 n2 \6 d1 i* T  //1 S( p- J% P1 g) g+ h5 h
  // 初始化自旋锁
/ O: j3 D5 S" I& L4 u  //
; A3 K8 E3 E# Q6 I$ A5 b$ D( r  KeInitializeSpinLock( &DevExt->SpinLock );, |0 Q5 a7 g. B. T

, }$ l7 R: a" Q  R  //
, l+ k  `* B# i" A: b* p* e  e  // 初始化 IRP 计数器3 \% b1 r' A  f' L0 _
  //
# @. `% W6 H: o4 J# z- k( r  DevExt->IrpsInProgress = 0;; Z. O, g" [! a3 ]0 _! l/ g

+ L& W4 X# \- V: |) S6 ~  //
, L( W/ A1 v8 B/ y7 f% D8 p1 }. P  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象0 a9 }+ O. _( n9 }, a
  //
9 C; o$ d4 }8 r9 s4 H1 F) g: k) y" i3 |% q. R, ~( ~% L
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
3 w! _4 S5 o; ^0 \* Z8 j' C  if ( !TargetDevice )
7 L, R1 m! ]- R* A7 g  {
0 w; o. |* ^; x, W0 B( U    IoDeleteDevice( DeviceObject ); ! h- Z$ T7 Z; _; \
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
" Q0 ~2 I% o, W6 Y8 U( k4 y8 c' t    return STATUS_INSUFFICIENT_RESOURCES;
8 s, c$ d. A0 O! c# u5 C( R* ?+ h  }
8 F* c  ]" X+ _0 h$ e' }9 h) v; F% t" f/ V
  //
5 Y. s4 R2 H0 y# J$ x! {8 V  // 保存过滤设备信息
. d1 b8 H. U8 s' W  //8 F+ l; Z- h  I( k+ \, v. O- {$ l6 ~
  DevExt->DeviceObject = DeviceObject;
& i# m* t' @& F5 x3 q  DevExt->TargetDevice = TargetDevice;% W. w! b6 Y9 R. H( t8 e5 g
* |3 l' f2 ~& v3 K; n$ m/ O
  //
* \: O8 X* q* B  // 设置过滤设备相关信息与标志* I( p" m4 |5 X# S, }
  //
, y& x' E2 _! Y$ u  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );/ Q0 M4 _7 I  c6 ?. m% u: \
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
# E+ Q: A1 p/ t
0 U/ P- L% [9 b' O) ?0 i
: |% Y' a' U' A. I9 g5 D/ [  return STATUS_SUCCESS;
0 R9 t& R: u  [( n/ ?. Y}
, k0 d  m; F2 L/ J' I7 x& u* m5 o0 G  Y( g  C* ]% O1 W+ m
/////////////////////////////////////////////////////////////////
3 H; G' n4 G( ~7 T// 函数类型 : 自定义工具函数
' p- I9 @* O: Z// 函数模块 : 键盘过滤模块2 v; B8 J9 v" R2 E3 C1 ]+ T1 b
////////////////////////////////////////////////////////////////
% g6 p/ U4 \( S% K. l// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
; `6 }" M; Q! D//        信息,返回附加后的驱动对象
0 _+ X& o8 e1 y8 y/ q// 注意 : 此函数仅挂接 PS/2 键盘设备; S7 b+ {5 N+ e* g" A1 f- k
/////////////////////////////////////////////////////////////////
, ?' g  Y% k7 s% @4 a// 作者 : sinister9 |' w6 j7 h. N
// 发布版本 : 1.00.006 {( l2 \% s, ]  h& [, `
// 发布日期 : 2005.12.27
" Y' `( A3 V/ O; V/////////////////////////////////////////////////////////////////. {: B" p) `  x. g" B
// 重   大   修   改   历   史/ ~7 }+ f& d2 {; \# A
////////////////////////////////////////////////////////////////. I) {9 G" f$ g2 y+ C  {
// 修改者 :
" s1 c- }0 M* `  r// 修改日期 :7 r) D( U, V$ d) j8 X- f4 x. m
// 修改内容 :& b% ]" O  l" h6 ?9 y2 ^$ ^2 R& J& j
/////////////////////////////////////////////////////////////////3 \% C6 Z$ W, a& R- I3 y
  K7 l0 _8 s' f# z" u% m8 [' X
NTSTATUS, \% X* d  x( D+ q7 w2 {
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
% y& R: T; g5 `  c! H7 N                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象* P) M8 l: N, s+ j# B0 m0 v! M
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
7 \. x, h% q6 ~; s2 U{
) g4 E; Z' G9 g4 Q1 L' N+ s  PDEVICE_OBJECT DeviceObject; ; g1 N% X( T, j# A4 e% }  S
  PDEVICE_OBJECT FilterDeviceObject;6 o, `, n: v8 y- e0 Q! E# d0 U& n
  PDEVICE_OBJECT TargetDevice; 3 {8 C. r% a8 p$ h$ }/ y/ ?3 y, ^4 I
  PFILE_OBJECT FileObject;
7 r$ ?+ k( G) d$ r' n1 [8 W& l  PDEVICE_EXTENSION DevExt;
7 ]% R* |9 B9 ^6 H. M
6 M+ L  V+ m+ p+ T1 w4 Y  NTSTATUS ntStatus; " k8 m8 ^' b' j" Y( X* ~8 t
/ j1 X2 I) _1 ~- ~  v; d: E6 O
  //
" J% ?2 I+ L8 R  ?# q  // 根据设备名称找到需要附加的设备对象+ n7 l* R, ?1 C. U" D" w  y
  //% w5 r! B, J& |: t( P; M
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
$ h, h6 ^  \* @: I% f9 E                                       FILE_ALL_ACCESS,
! ~/ e  k5 @( g" \                                       &FileObject,* i' m. _  y* Y
                                       &DeviceObject ); ! S. |7 w5 [" r1 L: a# W  `3 L
0 w- X7 ^$ I; k5 E
  if ( !NT_SUCCESS( ntStatus ) )
8 E; f/ b% F# c$ e" r  {
- Y. s5 R8 y5 f4 j; J& U3 A    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
$ S, N# C! L8 D% u/ y3 }6 w    return ntStatus;# Y+ a' N3 a2 n1 b* p
  }
2 P4 {* {5 Y- X0 m; \% |! E* A, U, U/ b- ^+ i; Z, f
  //
( v5 p( @2 Y' v4 {  // 创建过滤设备对象
6 \( _4 H" ~8 b* e: [  //
4 w0 i9 G9 [$ [( k2 y: u  ntStatus = IoCreateDevice( DriverObject,
2 [4 ~: d) ?! s                             sizeof( DEVICE_EXTENSION ),
7 n& g9 b, M6 f" {+ R. l' x                             NULL,3 `' p* _* p! s7 Q" E
                             FILE_DEVICE_KEYBOARD,
* @. q( J. I% K& l+ K0 v                             0,7 O6 q, M; U7 l8 `$ Z
                             FALSE,& N" {/ C8 u1 d% W( [: O: t; P# Z
                             &FilterDeviceObject );
6 r; D7 K/ B! g; |* X( x1 J% t/ B! E& O& w  l7 C# \+ W
  if ( !NT_SUCCESS( ntStatus ) )* {' H% h4 y; U/ r: ?  J
  {- ~+ W# d9 s( D) u2 ~
    ObDereferenceObject( FileObject ); - q* k) t  M( H# U/ z& v, d
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );' ^4 p/ x6 u2 ]
    return ntStatus;
3 g' k% ?. B- a5 Q7 Q7 X2 M" K  } 3 j0 x" h" n* m& U

* a. T1 F5 D: B! v5 y  //0 |# w& N: {: {5 T2 X1 ^. j/ x
  // 得到设备扩展结构,以便下面保存过滤设备信息
4 O8 U2 |/ ^9 I" E/ C8 L$ {4 k  //0 e/ O0 r; F( g
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;; L" i7 b( `- D) k2 u, t
$ ]3 X7 z9 C& Z' p# X# F2 x
/ o- p4 Z, P# u/ G( M; w' P2 Z
  //
" @% Q6 C" {  L; i. F* |3 p! k  // 初始化自旋锁
) n* U& ]0 P+ V7 C3 A  //4 I0 n  r" ^, }" Z2 g0 ]* P( Z
  KeInitializeSpinLock( &DevExt->SpinLock );7 k, L5 f1 F+ Y! G2 q

( d9 C1 L0 w6 O* Z- A" f0 |  //
& O* a3 @2 ]- e- z" o- C" d- e7 @  // 初始化 IRP 计数器
/ c" }; C  e' G* z  //
1 w4 z& ^4 f) w- p/ U, ^1 _  DevExt->IrpsInProgress = 0;
& N0 G" F* y; K4 t+ e3 O+ a3 ~) M+ |4 t: }+ k0 z& E
  //9 z( {0 {4 {+ j$ X" e0 n
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象* R( U: M2 j& ]# T1 y3 ~) O1 s
  //* d" d' f2 `0 c# M) M4 _8 Y
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
+ j# {, ?2 s; I/ c4 G                                              DeviceObject );
" C  Z; O$ U7 F- x# K) O/ I0 u  if ( !TargetDevice )
3 f! ^2 B5 z! L0 w9 y! ~  {
9 L3 ^& c1 K% E1 M9 d3 j    ObDereferenceObject( FileObject );
; f, ?! |8 A' d8 ~$ }2 w    IoDeleteDevice( FilterDeviceObject );
  F5 m' ~4 i& V8 d" z# K6 Z    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
1 ?) Z5 M( Y2 n    return STATUS_INSUFFICIENT_RESOURCES;) C* z* Y& s; Z  d
  } ; e5 g3 v  Q5 K9 v

; S; w$ ^! e- E+ g  h0 H  //1 U. ^8 E" D" i! U9 ~" I
  // 保存过滤设备信息" }  r$ }! d& W- E
  //" T4 g( _* q6 h+ g7 [  n
  DevExt->DeviceObject = FilterDeviceObject;
6 K7 D+ P6 u: N5 b9 y" U  DevExt->TargetDevice = TargetDevice;
* b, S; _  B6 @0 N  DevExt->pFilterFileObject = FileObject;5 L% A$ o& H; {

8 s4 H; V0 u; y+ x  ]9 X. s4 [: P  //' d3 l( M- Q- k- F7 }- r
  // 设置过滤设备相关信息与标志4 h, G/ v8 d# J4 x) ~
  //
; c4 O8 ^5 I, H- e/ N9 s  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; " ^. j* k" L8 Q# ?0 @3 T4 }$ N- S, z
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; $ }# [% G& W6 P$ s! _7 a' j  L: T
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;" X+ `; N* E5 w' _# ^8 o/ {" U
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
/ U' B- l: `* N* B( g  m                                                         DO_BUFFERED_IO ) ); 3 X1 {4 ]& C9 ~- q3 L/ U

. u. e* S9 f/ k5 q# t- _  //: x' y# i) ]8 ?0 d; k
  // 返回附加后的驱动对象9 ~( X7 k9 a- M+ j9 t* H( K
  //
$ ]4 E1 K$ O' e+ N2 o7 E1 j  *FilterDriverObject = TargetDevice->DriverObject;7 x' L4 a  E/ D! p

1 M/ Q2 O- Y" q: P8 v4 q  ObDereferenceObject( FileObject );
# _4 z3 [5 ^5 _/ ]$ O; Q% q0 G0 J- a; @3 A8 v1 L$ a# G
  return STATUS_SUCCESS;! h) a% J& S2 j4 K) Y; W
}
) y! s3 g, a' h: H$ E# E/ W7 N8 {# |- I) J7 Z* t1 E1 ]
/////////////////////////////////////////////////////////////////
$ q; }& @. q1 u- e% G! J; b// 函数类型 : 自定义工具函数# V  i# |; e4 H  T
// 函数模块 : 键盘过滤模块
) R/ Q# _9 J, o. A) t) ^////////////////////////////////////////////////////////////////
) Y9 k! q5 A* a  s1 D. p' n$ w4 q// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发* g- w0 E: }6 L/ ~  \- P. n
//        这个 IRP 的完成
4 e  n  R" @/ S6 k// 注意 :
4 j2 ~- A3 c! f( O8 s% ~9 U" _# h( t/////////////////////////////////////////////////////////////////# I4 [9 z# [4 p$ s2 N' E
// 作者 : sinister
( ]4 |4 Z! x# t' h* g// 发布版本 : 1.00.00
4 g( P& D8 V# o// 发布日期 : 2007.2.15
7 U( _& Q' ~* k9 Y/////////////////////////////////////////////////////////////////
1 v; @: r, G: j$ I8 J1 i7 J: t2 [// 重   大   修   改   历   史
5 \+ `, i9 ?" C0 n7 X, K////////////////////////////////////////////////////////////////( E. n+ J; l1 B- p- b- l. E3 f! _
// 修改者 :
4 m4 A% P1 ]7 B5 ~# z; U// 修改日期 :
4 ]: S! v( E5 J/ |0 P2 }// 修改内容 :8 L! s4 _3 ^, ?8 b
/////////////////////////////////////////////////////////////////
, k# p. O9 b. D" M& |- S$ ]* n8 A0 o7 J) H
NTSTATUS, g6 R' J$ F6 Y3 a( N( J. c
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
# i$ A/ k4 ]+ ~7 L) I1 n{. A& y  {1 d$ |* Y( q
  NTSTATUS status;
# X6 o. Z/ Z" }3 E  KIRQL IrqLevel;
& z8 R, w9 Y( ]- j4 B  O
) R$ z6 W% P0 r) l) F& I2 w& v0 s& l  PDEVICE_OBJECT pDeviceObject;
+ x9 Z0 ]2 G0 O  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
* @( y9 M8 g6 E- g                                   DeviceObject->DeviceExtension;
0 N) y) S! j7 |3 n( ]4 e$ E' U& X5 h8 z+ t; L- P6 O
1 ^) t9 V; w$ U5 U8 v3 y$ @
  IoCopyCurrentIrpStackLocationToNext( Irp );  t8 z% L9 a3 M& M: t

8 ?8 E9 U6 _2 i9 C1 j  /// |+ |7 a' }9 l
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁, ^2 ^! v: [! e4 y
  //
3 t( l( {4 a! x7 W1 f5 c  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
- Y7 r. S$ |, R* I( b  InterlockedIncrement( &KeyExtension->IrpsInProgress );
9 \! f. Q: z0 _9 n  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );" n; d) i/ U' ?$ S- F1 j! K7 ~
/ N6 x2 E, ?4 K9 |5 Z  C
  IoSetCompletionRoutine( Irp,
- |4 u$ }3 q+ I                          KeyReadCompletion,
7 m; a) h- w* P) Q  Y                          DeviceObject,- o8 U$ u7 J+ z; w
                          TRUE,) h" N4 T5 W( ~* ^
                          TRUE,
" Y0 Z) }/ n0 o+ X, N% S                          TRUE );
( _8 Z6 V% v4 s) f1 u$ g, j3 Z7 r1 |0 W0 z1 V' t5 A1 E% L
  return IoCallDriver( KeyExtension->TargetDevice, Irp );  ]* b# E3 v4 P3 T
} ' p+ `  w7 ]# P1 f
* l7 F, v+ q! O  C
/////////////////////////////////////////////////////////////////
' _8 t6 J/ J& s, Z  h* Q9 x- ?, d9 u// 函数类型 :系统回调函数/ v* U) _& E( g* M( i5 D! J
// 函数模块 : 键盘过滤模块) H4 [3 d8 x: [! X9 N( e
////////////////////////////////////////////////////////////////
: X6 r; q) a8 K0 |// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的/ I! J. ~* O+ Y, ?2 x& j& I
// 注意 :
+ [' w' \3 u4 H$ L' O" J/////////////////////////////////////////////////////////////////4 Q, p1 j* Q. T# E( X+ V
// 作者 : sinister
7 v2 [4 y# K. w+ t1 a6 a# d// 发布版本 : 1.00.00/ M$ R8 k, A7 n) U4 f
// 发布日期 : 2007.2.12  A! s/ ~4 G9 E7 N$ f- `
/////////////////////////////////////////////////////////////////
' k9 o7 K0 m6 |2 E* X9 ?9 \7 ?+ \7 n// 重   大   修   改   历   史
" r5 T1 }: R& i% E///////////////////////////////////////////////////////////////// d+ `; ], B% C/ _4 J
// 修改者 :
" Z/ }$ V  Y6 A( M* l// 修改日期 :
3 e8 }3 M5 Q+ U  q8 }// 修改内容 :" X: e" |( @+ `1 c- a5 G: t* y
/////////////////////////////////////////////////////////////////
3 q' P8 g3 k, q$ y8 Y0 S- E% W6 T/ T4 D4 S( w
NTSTATUS
* _; L' `! t# a! bKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,0 F* b" _/ J/ B* m. Y: y
                   IN PIRP Irp,
$ _( I: O+ J2 R1 \' c4 O3 A                   IN PVOID Context )
9 O+ Z+ _' w2 _{
. H6 C( Q! ]# E! w  PIO_STACK_LOCATION IrpSp;7 L0 k7 ]' v- W1 J$ y0 J$ D' f
  PKEYBOARD_INPUT_DATA KeyData;
% C& j. y4 U, S/ I8 D7 f  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
8 J) o( r4 d2 M( ]: n/ n                                   DeviceObject->DeviceExtension; ! _5 A9 x) t4 S8 H- G$ J
  int numKeys, i;
& x1 C+ a9 V8 J5 t  KIRQL IrqLevel;
2 A" x  j+ D3 F& J7 T4 U- r3 [
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
/ _& x4 _! s& w8 \# H
2 q( N7 }: w: n
( e3 G- M) o5 c( p0 Z  if ( Irp->IoStatus.Status != STATUS_SUCCESS )# h. P9 M* ]' y. i$ B+ ?/ b3 ?' E% ]  G9 \
  {
6 `, x0 i$ T8 f/ k* ?    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );& ^7 s) g" V" n. A4 y% S3 f( f
    goto __RoutineEnd;
; \2 u. m5 q/ \7 ?  }
& Z( S" r9 t8 [& u( Q3 _
+ a7 y' D, Z& K  //
' r% t2 A5 l5 `$ Y" k2 u/ c- G  // 系统在 SystemBuffer 中保存按键信息
- y* U$ F0 F/ G1 E. s& Y) z  //
( M* p( X; `' {+ b* j  KeyData = Irp->AssociatedIrp.SystemBuffer;
8 W" |* g: |* R. I. ?  if ( KeyData == NULL )7 g( Y! x! F" V
  {
$ c) x5 f7 Y7 }* q4 {$ p    DbgPrint( "KeyData is NULL\n" );
6 }( n7 Y* P7 P    goto __RoutineEnd;. ?/ K/ e8 Y: H6 s0 ^$ ]
  }
4 q1 w( o  U( W6 `5 b5 ^! Z! U7 g. ~- Q3 g8 U/ l
  //; L7 ^& m% _) C$ p( B6 x* c# J
  // 得到按键数; M! Y: s* H8 d) ]' L
  //0 [$ f0 E2 i/ x
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );" r+ z" {, Y/ v1 D) K" ^& {( K) \
  if ( numKeys < 0 )3 j+ u$ ?1 O- x% T  V, Y' U
  {/ f  P3 y- ~. E
    DbgPrint( "numKeys less zero\n" );6 t2 Y8 L4 [! b5 ^
    goto __RoutineEnd;
" Y. g9 ]* N" l  }; p1 V- B/ y/ J  _
& b/ t6 M& z3 S- b/ Y$ c3 Q
  //
1 z, `0 J- a6 }  // 使用 0 无效扫描码替换,屏蔽所有按键
' m2 X% N2 _* _0 ?7 z  o  //
4 n! B' {3 h! e& y4 c7 v  ^3 ?  for ( i = 0; i < numKeys; i++ ); G5 v" Z, s3 i' c2 a: ^; a' r
  {
; n( y* A+ c/ g3 Z( ?    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
6 d% J3 D) _$ O! j. Y* X    KeyData[i].MakeCode = 0x00;* y7 T  R$ J1 p5 |! S: G- C
  }
# }- h6 T9 u6 |. h  K* i
# S5 v# A" r8 X1 D8 i0 m$ f% x. \3 O% L0 F7 i
  __RoutineEnd :
3 l) ?& q) d# a& }9 {- \* K, L
& E. W0 q( v2 J8 A9 j7 t  if ( Irp->PendingReturned )3 f% w5 Q. r. X
  {
5 f" U$ i! }4 B; ^9 y& l/ V8 |/ {% v    IoMarkIrpPending( Irp );
7 J0 _# k5 G1 }# x  }
* \- T5 {8 ^) e3 E3 n
4 w, W8 ^* F/ T' P, B0 A  //
, J. y$ D( `, y  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
8 ]3 Z" E& }- Q8 t! I  //: K7 H# G6 f3 h8 V$ }
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );# i, Y1 |7 M: b9 j. t8 j
  InterlockedDecrement( &KeyExtension->IrpsInProgress );9 Y: Y$ N6 W1 b
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );' o+ u6 W) B+ c, H# d$ ^" V8 Q

. o1 s. h3 R9 n- X7 @2 n  return Irp->IoStatus.Status ;
/ {/ N0 G" J  F& X. ^5 w: u) h} , L4 T" w3 V+ H- Q7 J6 h
6 w% U) C7 o# K8 z4 a  ]3 Q

4 T1 I) K1 U6 G2 t1 O+ o& {/*****************************************************************
8 I: e; I6 h, m2 } 文件名        : WssLockKey.h
2 H& x% J) Q/ \4 A 描述          : 键盘过滤驱动, k: p$ x3 E! `2 _0 e( r9 f
作者          : sinister
& Y# T. J( O2 r  f 最后修改日期  : 2007-02-26
9 {! p7 i* U# e*****************************************************************/4 r' W7 ^' m- O4 B, z

1 K4 \' _* {4 E) [#ifndef __WSS_LOCKKEY_H_$ S0 O! p% [, m& E& E5 t* [3 G
#define __WSS_LOCKKEY_H_
6 f& G8 b& j/ Q( g7 w4 ]% A  G! R; ^2 \; w; Z) N
#include "ntddk.h"& q( J, n* ~8 x+ O+ O
#include "ntddkbd.h"
6 m0 Q8 x* a  ^: t+ |#include "string.h"
# F' S: Z- a0 q#include
+ \, T6 ^2 I7 d0 Q: k+ k
+ U+ @* z" V% Q8 I' a, g, Z+ z$ E#define MAXLEN 256. I2 q% c/ ]: t8 e
- l  j' E7 W$ _3 C9 e6 j. J7 y
#define KDBDEVICENAME L"\\Driver\\kbdhid"
& {0 S$ d9 \7 b; A#define USBKEYBOARDNAME L"\\Driver\\hidusb" , E' z# k( u) K7 D
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"2 l+ h. p! \3 D% O' }, T4 {7 ^! Q

) O4 x% z& D6 Ttypedef struct _OBJECT_CREATE_INFORMATION  i0 b0 I; g( H, j: H
{1 C0 D; T: g# m3 G. n
    ULONG Attributes;
$ J0 [' ^7 J5 Z    HANDLE RootDirectory;. y6 ?9 A8 P8 R6 K% s" l. d. n) P( ~
    PVOID ParseContext;- i2 W( z+ k4 [6 |; r& L! f
    KPROCESSOR_MODE ProbeMode;
$ K. i! U, r* @8 [* h    ULONG PagedPoolCharge;9 L+ g0 \8 p; j5 E) G/ ^5 i& i* e
    ULONG NonPagedPoolCharge;9 S$ \3 a, b; ~$ ?# ]
    ULONG SecurityDescriptorCharge;! \' u. F3 D/ x0 q- }
    PSECURITY_DESCRIPTOR SecurityDescriptor;$ F2 U- ^- O5 B4 L( S+ b6 C
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;3 g/ H4 j& Q3 ~, J9 F
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;6 O. A  z  ?" R
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;' }. u- w# {* \6 r; l" ?

) i8 h5 [* B: ^6 }$ ~, htypedef struct _OBJECT_HEADER
- K" l2 o) p' Q4 |( M& }{
  u  l. E: |, J    LONG PointerCount;# d( i, m( G( l. @& Y
    union
9 V4 V! T4 D$ A# c- y    {
  G; V% h: P! e3 B$ D- N        LONG HandleCount;; p6 ]* ^! z# h9 o  Y; ^0 t" k
        PSINGLE_LIST_ENTRY SEntry;
; F, q9 D& {- e/ `& v    };
9 Q, s* [5 H/ C( ^! b    POBJECT_TYPE Type;
! m2 o  P. F) Q5 v% c    UCHAR NameInfoOffset;
- `+ U5 N2 z* f    UCHAR HandleInfoOffset;
8 ?! u1 w1 X  o8 n: S9 m, Y7 ~    UCHAR QuotaInfoOffset;) Z% H; E; n- \' U8 y
    UCHAR Flags;
+ |: ^0 w8 z( h: T: \* z1 D/ ^; g0 q6 p7 h    union
) x* Y& E9 _4 s) l    {
# O+ @5 y/ E( Z- u$ N        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
7 g6 \) K2 R  ~        PVOID QuotaBlockCharged;
6 d5 O$ }# P: u. L2 @; J) D    };
. ^3 ]: a, n" r+ x3 v- V
9 I1 w* w: e2 k& {3 T    PSECURITY_DESCRIPTOR SecurityDescriptor;* ?+ B8 M3 k  D2 ~3 ?- E
    QUAD Body;2 m# L9 L3 z# ?: C
} OBJECT_HEADER, * POBJECT_HEADER;
, |4 K$ q+ m" m! m1 p5 Z% S2 q3 Y0 Q; S* O6 {. `
#define NUMBER_HASH_BUCKETS 370 j( {/ k; {( |8 \

. b4 `4 W; i# a) O) |, @- Etypedef struct _OBJECT_DIRECTORY1 t+ M% B) f. V
{% R! ^1 h3 g0 k! q6 k
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
& t& b5 `9 _/ \$ f    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;! r+ f" t  U+ \  h
    BOOLEAN LookupFound;6 S$ a/ f" q) _+ I, N
    USHORT SymbolicLinkUsageCount;
9 \0 d% `) R5 X    struct _DEVICE_MAP* DeviceMap;# t$ M: k% \; o3 ]9 Z9 ^4 e& G* F
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
& t& z3 N2 d$ X- y8 ^& V* v0 ?5 a) [4 f! E8 m$ y2 B+ }
typedef struct _OBJECT_HEADER_NAME_INFO2 x. G: d+ C6 L3 h& P
{( E; y1 s5 G* c' q
    POBJECT_DIRECTORY Directory;- ?- O6 e' W/ N2 O2 ^* I; U* F
    UNICODE_STRING Name;6 X& a# N& o* ^8 A  v. a( S
    ULONG Reserved;
- d! P3 `- b7 J* d$ ~: B#if DBG
. d$ d4 z* _8 \8 X" ?$ Y/ g    ULONG Reserved2 ;
% f% M! q/ h3 P- U    LONG DbgDereferenceCount ;
# K0 d  ~6 J9 l#endif
# T7 q- ?0 K$ S  x% @} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
! i( v! \- l* i) l6 ]0 E( N
, q  m  y8 ~5 E5 o! A8 d#define OBJECT_TO_OBJECT_HEADER( o ) \' |9 W9 ^) Z; i% r
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )4 E1 _- H- S' q" F
% J# b( k3 z8 G7 \$ Z9 K) ^* l7 z- L
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
' I" C: b: q, B+ i# m& y0 {# \, z& b! Z    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
# S' @! x, d$ F4 g4 h8 F( F- N4 c. m9 w* }
typedef struct _DEVICE_EXTENSION
  c  Q) r( ~  k% n- y! z1 n9 b' x5 }{  T( |9 ^: \) R) {* c7 y
    PDEVICE_OBJECT DeviceObject;% N: U' E$ ~0 q8 I1 j0 e
    PDEVICE_OBJECT TargetDevice;1 Q  g% ~6 k, y# Q# f& h
    PFILE_OBJECT pFilterFileObject;
. v+ {$ H7 V% X- Z+ \2 d    ULONG DeviceExtensionFlags;) w$ I' c. b  Q, b7 B
    LONG IrpsInProgress;
/ E! @/ X# f+ A: g2 p: g    KSPIN_LOCK SpinLock;$ ]3 D- Z8 U4 h! p: M7 b
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;0 @' }% y4 L6 w  D  |0 v) S* @

7 h# }# K" Y' Y! H  D3 h$ R3 X, T/ ], k# t+ O) R
VOID : h  {* q9 ^. ?- K: O" g
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
  M) y2 K1 ?* d2 l& H$ o1 j: n
$ s8 l& |2 X' z' eBOOLEAN
6 o5 ~/ {' e% G* MCancelKeyboardIrp( IN PIRP Irp );
8 Q0 p5 g: o* b/ A# K' i" t( S3 U) I. `8 n. R1 b) \/ V
extern POBJECT_TYPE* IoDriverObjectType;" M  u$ R, o, m8 v7 V6 V
2 \6 _1 {4 E9 Q
NTSYSAPI
; T  Q+ I8 X& n) S$ c5 }& p7 zNTSTATUS
* T( G% s2 n$ fNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,2 |- h' U' c# {& W; Y
                               IN ULONG Attributes,
+ D  \1 c# a. `' v8 i                               IN PACCESS_STATE AccessState OPTIONAL,
; S2 J: p. k: x; B; l( [9 \; {6 ^                               IN ACCESS_MASK DesiredAccess OPTIONAL,$ x+ v) w9 H( U3 V" [3 v
                               IN POBJECT_TYPE ObjectType,
* I7 M! ^% p0 J                               IN KPROCESSOR_MODE AccessMode,
; V. G& O; e/ o% q1 A- v                               IN OUT PVOID ParseContext OPTIONAL,- A. j5 ]' ?# W% Y0 \- o2 j, `
                               OUT PVOID* Object );
  i6 a) m0 i' `
8 F% v$ q. P2 G, d  \  E  ]. NNTSTATUS 5 ~) z6 m1 a$ ^
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
$ F' P/ f; y2 ?* v  |) m/ z# L+ q* o) X& A
BOOLEAN ) L4 [1 W! s2 k
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
, v. [- C$ ^9 p
  t& A+ {8 f8 q, }2 |6 ZVOID
# Q+ u+ M! U3 Q" k  I* a0 EGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );. y: ]- S" i, U, c
$ f. V2 _9 `9 V: o3 w
NTSTATUS 9 X7 T/ |4 q" \$ F3 r5 r
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,9 A( @% A( I# f  ]# W: E! `
                                  IN PDRIVER_OBJECT  DriverObject );
& B+ G$ R. c5 ~9 f4 r& {8 X$ \& R, Z8 |
NTSTATUS
3 R% R/ Y- k5 {, F+ j8 rAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,# H1 I$ Q" @% a! S) A6 b6 G
                                  IN PDRIVER_OBJECT  DriverObject,* z  c1 t. r+ C% D7 y6 d3 a+ H( \
                                  OUT PDRIVER_OBJECT* FilterDriverObject );9 z2 \* a2 O1 O& a3 y2 m* g

# {2 ?" D4 l' r' O; N6 TNTSTATUS : s6 [& ?6 ~* Z, p3 Q0 w0 q% Z
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
/ p. O' d" ?$ ?6 s                            IN PIRP Irp,
- O* ?" L) H4 H* q5 m9 l9 M                            IN PVOID Context );
4 B8 ~" Z6 x% c& x! f; zNTSTATUS / g$ S+ J- s7 I2 z( j% h
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );" h4 J  R* J0 A( P
$ a* v2 s+ [7 Q
WCHAR szUsbDeviceName[MAXLEN];
/ @' ~3 a- c- e
) D  q) E' J0 K7 K% H4 O' t5 L#endif
( F) w% ]7 m8 W: U( z7 [6 P
) r& l$ V/ q$ F/ a" e5 q
( u! x1 p5 Z; j7 i
* A" b) x5 k, u: A" P
  V" a5 r2 T1 x/ w" a. b7 N
$ G9 H! ?* z6 u* I, ZWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
0 N( S$ F- g8 ?& eWSS 主页:[url]http://www.whitecell.org/[/url]
! D: d. L" u+ n! V3 i  K) PWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-3-5 14:26 , Processed in 0.182004 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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