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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
/ _% V1 t% t( c0 m  \5 aEmail:   [email]sinister@whitecell.org[/email]
- I. ]( F$ F) B0 F' u2 GHomepage:[url]http://www.whitecell.org[/url]
- p: L" |) T4 A* I2 hDate:    2007-02-26
- h% s, H1 C1 L! v$ [5 G1 j) ?2 K( Q  m& U* b/ }6 S

. {' O  V3 s% O$ y. @7 Z. G/*******************************************************************
3 p6 Z6 A+ ~' V% s
( T# i5 G# `' H( |/ X5 Z% t" v这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx4 U2 ^! x6 V* C1 b# W7 [3 }+ W, h
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的3 q; t+ g/ l  a* s. ~
功能要求如下:
6 {# _, v% ]# ^
$ z+ `1 c: ^) g* W. O1、强制锁定键盘/鼠标。# k! `4 s% i$ H% l1 Q3 X- @8 k
2、可动态加/解锁
6 X1 K; D' v! h) H3 w3、兼容所有 NT 系列的操作系统。
* z$ @7 K- q( o' H1 p1 q- E' o, P" |- n$ f* L
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实) U% W+ R8 h) b7 j+ T0 g/ f6 Z
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
3 r+ ^% I9 d  k7 M  p2 u7 J  R何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
3 _( q6 s$ B) i: X  c上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是9 i# u1 l: V& w3 u
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面+ G- c& {- T8 E; l
就来看一下我想到的几种实现方法:
4 o) Y- E( _* m. i, ~+ N. Y7 R, L  p6 X5 w
1、全局键盘/鼠标钩子
5 F+ h0 p. `' @2、BlockInput() API
3 W4 A7 T# {3 C# H/ L2 I9 s3、使用 setupapi 进行控制
1 h( ]" ~5 s0 i; y: I2 L$ h: e4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL! ^8 R6 U6 b' U9 \6 \" G7 t
5、拦截 win23k!RawInputThread() 函数: Q: o/ Q( O' c2 ^* \
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动" H9 }' Q: V. {4 r* A+ q9 u: M; f# x2 x
7、拦截 kdbclass 驱动的 driver dispatch routine* y( c( E$ N) v3 x6 \
8、实现一个 PS/2 与 USB 键盘过滤驱动4 i, f; R! A. W  }3 S+ m* _

3 S* \4 U1 F( M' l6 ~* c, l% k& W5 N% t$ {( K6 Y) i, G- T) z& P
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
9 |! H  {9 E, T$ @2 C之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
0 }& [0 b# b+ q) Q案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在$ q- Z- J: T$ n" q. [/ C; A  p
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因2 P. i) i. ~+ b0 E
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性. M6 y, Y) ?& z4 E8 V
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸. C. A! @% Q' ?7 [3 A6 ~" M2 h: ^
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
, Z+ ^* M0 X* a的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来& j9 ]0 G, D" ?
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
  f4 i9 B' _, w- S' Y果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
( m1 R, @( S5 g. z9 J* j* G障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截, u1 w6 J4 l6 V$ v. G
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 ! W* p( l# N9 l  C6 x
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键6 p8 ^. J8 N9 B; d* L  o" V
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方3 W2 G  T) b7 W2 Y
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
1 m( H* k2 l' H
+ L% B" D0 r/ T7 t  L! `8 Z6 ^* H! _! W0 q
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过/ \/ x  ?# ~1 }2 @6 Z/ d8 e; q# b& X
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进6 f4 W$ i. X; ]! A
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是7 v' ^+ I. l" U. t% D
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越9 _! A- Q, I+ y# g$ Y& E: B# `9 V
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
% [* b4 c7 a* l4 C$ AKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
2 L. m  s: q- Z2 i+ U! q键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
: L3 j- k3 z9 J3 W: MIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,3 v; e" u+ Y* I) b3 m' @
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题5 ]: C: y6 Q1 t) ~
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的  e5 a1 z4 G2 n3 R8 b* e' {% r
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
. j# `1 [/ M6 X5 j( e1 y用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
$ o- q4 h6 L  S! E4 \3 D* r过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
; d$ i0 c9 f2 ^4 |屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
7 k8 A; Z) O( W5 Y, o( Y6 O6 y3 H# p过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb; Q" ]- M) y' ^% ?0 Q
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid ) \" W- B% v3 X& O* O3 u$ h
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
! V# N1 M5 Q0 f6 Q" s, H味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。$ j3 j/ V& u, B9 C( I( k  _. i
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们% Q& s+ }  ]& x
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
" D1 Y" ?  Z' t的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo0 R! f1 l: t4 }% f, W0 A# Q' S; c
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致* R; w/ A) {6 O1 T! B
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,$ N% `7 l; S5 K
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
+ B; @* ^+ j* X$ U5 s2 S见下面代码。8 i4 r9 ~7 D$ ~9 w: B. a
9 X) o* S) T5 }+ G+ M
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
$ N9 N5 l: P8 O/ G6 f# `# E8 ~里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键2 K; v0 _: m! ^9 w* k6 w- X- H
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
* C. I' J  g! n1 l9 c: s' }上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
" f! ?; ]4 M3 H7 I7 G2 c* P完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
  u3 c) H2 A+ B" `继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个. d$ B% x' h' f5 Y/ a- d5 G) C
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按9 f6 I7 T, ?! k/ ~& `. P6 Z7 N  ~
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。' Z4 Y1 F- C+ H" D" I

" a" `2 L# g  l: G. v: m
& z4 q% M8 V/ @5 C! a6 W完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
0 n/ b: O3 D9 L" b" k; o, w的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是2 W$ ?7 W- |" x6 B6 C
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
; M* [3 b  {* o6 N的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
+ L8 z8 P- w, j7 m" b3 o) d, t们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
; ]% d" _  I+ L) I5 R# q$ s们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
) R) I( w8 x2 W2 r->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
6 t) E% }6 ~; N, d如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
: Y! @) b- H3 l% v/ C进行操作了。这个问题有待大家来完善了。1 G1 @  ^- m" C0 M
5 ]. g  f6 I; R  O7 Z7 V) j* h
2 O: I4 s5 w: b" T# D  _6 d% m
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出; a1 X; H3 p: n1 ]' H1 h7 |  P- {
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的4 O" p) I& q& l& f
分析做个记录而已。我更愿意把它看做是一段注释。
3 g0 I$ I- X$ A2 x. r$ _
% q4 [7 e6 f" N# p3 c最后在此代码中要
8 o3 i3 |2 `( N" d" o( R0 @
% W7 S0 t9 O: Y感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
6 l' h9 Q, b/ `" Q8 V$ L! I) s9 s3 `) t8 e( T  c- q
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
. t+ Q, P8 f- b# `# M8 Z0 d3 l! Z' X% }7 S3 a
感谢:齐佳佳,过节请我吃好吃的。% X, b* g/ K2 z" H7 K5 y
" a7 O. u% \* o- N
- ^5 Y8 ?5 I; _0 X' K6 F9 l
******************************************************************/
$ h3 D! o% }/ D  M
: N4 K9 L) S. D" r9 R. [, D: e
6 c" x: K! o) T5 Y( u3 r! Z/*****************************************************************: J" c: V$ D3 c) x" [( v" s( |
文件名        : WssLockKey.c
$ U' L# `$ W9 B/ y 描述          : 键盘过滤驱动: _( Z# `/ M$ ~$ S# t
作者          : sinister" L' ~2 Y$ Y% D4 l9 J
最后修改日期  : 2007-02-26
( r: L( `0 J5 m- O*****************************************************************/: B2 t1 S" K  x+ r8 {: e

" A8 {. J# R' L- p' c
% |# B3 A" a$ K, B#include "WssLockKey.h"% j9 j7 B4 U' C) q$ a2 Y- f, J) ~
( e7 Z. _- X/ x6 x$ x+ q4 d0 l
NTSTATUS! @! Z2 u7 S+ `# @2 t1 _& t( P' c
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
9 u/ q% W; z+ S- k4 X             IN PUNICODE_STRING RegistryPath )
! J& }  \' Q7 ?& R" ^{- K, X% o5 E0 x: T; n7 t& D
  UNICODE_STRING KeyDeviceName;
) ]7 q2 n4 m2 B* D6 s0 `/ g6 P  PDRIVER_OBJECT KeyDriver; 0 ~. G+ ]: `% S% ]
  PDEVICE_OBJECT UsbDeviceObject;
" w# X6 A( A" k- j! E2 _9 k" o  NTSTATUS ntStatus; 0 M, \; K( w! O3 T
  ULONG i;
$ {4 k, A) |0 Q5 C2 W( {) E, N5 m7 W7 Y8 s
  //. @  c% `0 J5 j7 `4 B+ G0 ?6 A* m
  // 保存设备名,调试使用
/ [  |4 `* `7 ?* P- v0 J. O  //
" [4 M, D8 z$ s) i: e  WCHAR szDeviceName[MAXLEN + MAXLEN] =' ]8 B) P. `; S* u! y
  {  G- I1 p5 A/ n% G8 C
    0# [# L/ H9 E0 h: `9 ^+ p* u
  };
. T+ }3 e( g9 o& j+ E1 T( a$ R) @  F* a
  KeyDriverObject->DriverUnload = KeyDriverUnload;
7 S% ^2 }- |: y/ @
1 G3 Q# s- s/ l, [  //
& D0 W2 W1 _' {) w( o+ n3 v  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
+ v# C6 M8 E+ {" O" w  //  r; I$ m& ^, E9 F
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法! c/ y7 X" G( S! `
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
: I. N0 |7 W5 s- m* v' w6 h% p  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
; u! K8 |  K- m2 i3 ?8 f! i  // USB 键盘设备来进行挂接* {. N! d) W) w8 Q' C/ k
  //
- w5 E1 w2 {# K- n8 \3 P4 @( x  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
% ?, e0 ?4 w1 i: p4 I1 \  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )3 h$ m0 y; K$ d6 r
  {; K) E+ q/ u  n0 ^+ V/ w. ^
    //& T) R, u& f. p9 ?
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
$ b0 Y7 {! @9 X    // 所以这里打印为空7 g# M0 G) W5 q$ D5 @
    //$ Q6 B9 o; q6 R4 F
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD# g, U2 V" ^0 K2 i& y+ e
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );( q7 M5 e$ [9 V' m( c

  b  D8 @' x! }7 B    //
( d5 F& P& o- t/ y2 I    // 挂接 USB 键盘设备
0 _. c- U" a2 ^1 Z( T0 e$ \7 C    /// t" s3 W: K) `5 A0 f3 m
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
' q& V% N. F! t1 e/ {3 C, D- t    if ( !NT_SUCCESS( ntStatus ) )- E. `$ k4 F& [3 l2 b
    {6 T) _$ H+ ?) a8 V9 P
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );! q3 n0 J8 \! o/ v( b
      return STATUS_INSUFFICIENT_RESOURCES;# g; Z- G* @# `4 C: a0 w5 |; d
    }9 R- c: D; K8 ]- {) n0 F$ N' s9 _! V
  }
/ M% m  h6 [1 ^9 o  else
! ]$ ?# s. ^3 F/ P  p  {
) R3 ~2 F6 P+ d6 l, b; G    //
6 F, m2 v+ v) v+ K1 C    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
& z6 K! p+ J0 g$ K  S( U    //
3 e9 K- O  J: O4 y6 g    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); + g* y4 \/ [" P6 r( X# L6 {) I9 M

# I: R% p9 k+ `: y$ ]8 r5 B    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
4 P1 `; L( }$ K                                        KeyDriverObject,$ t7 X) p5 j* y  B& k% K5 P! p# h
                                        &KeyDriver );
" ]5 H, D* d0 |) _    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )+ N4 j2 n# a8 Q" D
    {
8 c3 |, P% z" T* X/ v( s) T      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );: F& H- e7 @3 @0 h* K
      return STATUS_INSUFFICIENT_RESOURCES;
7 c  @3 \7 D$ G2 `: o    }
: c0 W) m4 Q) J2 L" A, g  }2 L  q& F2 }$ v( X- z
% b$ u+ R2 w+ r" s0 z2 o8 l
  //6 R% D+ l' P+ C
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
% V* S# E- ]; [" E  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
# i. f$ y/ U9 p( ~% h# B  //- ?* w/ m1 W: Y
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;   s! Y- ]' H& {; ^
0 ]3 j3 X/ T3 n/ r( u
  return STATUS_SUCCESS;
& k. |5 y, A2 m8 N} 4 f2 {* s5 q1 A- y
5 c2 q. ~. w, m
/////////////////////////////////////////////////////////////////
* I% x( [7 i2 T, _- y// 函数类型 : 系统函数2 g# T, J* c$ k' E* |
// 函数模块 : 键盘过滤模块5 `) P9 l; v3 C6 [* G& T
////////////////////////////////////////////////////////////////
7 z0 }" v' O  ^, _) z% L  _// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,  n0 M. N7 e6 e$ t+ U3 X. L. ~0 L
//        卸载键盘过滤驱动9 `; \) |! i8 x+ U9 F% |& z# ^
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上0 N. e4 s5 g' ~8 f
//        则需要等待用户按键,以后有待完善1 z, g1 c" ?+ Z' J$ B. `0 R1 i, @
/////////////////////////////////////////////////////////////////8 L" b3 Q  Y+ w. g3 z! o
// 作者 : sinister7 C" f; ]4 D' d4 ~+ S
// 发布版本 : 1.00.00
7 v+ t  C* m  }5 m// 发布日期 : 2005.12.278 ^2 I8 {8 l: e$ `1 a! J& \2 ~
/////////////////////////////////////////////////////////////////& I) R! C" Y9 z, `( E& L9 N6 a0 k) q
// 重   大   修   改   历   史
! m1 U2 Z8 T& s4 u4 e////////////////////////////////////////////////////////////////$ {$ O( d% A& D1 o. x  L% |
// 修改者 :
  I, \  @2 Y) [. n% u6 m8 f8 o// 修改日期 :
# @7 f) U" S! C2 k* r, s5 v2 A4 Y. k// 修改内容 :4 g- y2 y% y& M! |
/////////////////////////////////////////////////////////////////( v6 N; c5 m3 P) P! S; Y2 T0 ^

6 R# ?9 z9 m. n6 |VOID
" `, q3 B1 M2 X8 H  `- D( p5 J9 kKeyDriverUnload( PDRIVER_OBJECT KeyDriver )7 q* G" p" _3 L  x' ?
{; I6 Y5 O9 L) q5 l
  PDEVICE_OBJECT KeyFilterDevice ;      
6 b5 O& Q  E5 D& o  F  PDEVICE_OBJECT KeyDevice ;* r" P0 o1 A: U: X6 M
  PDEVICE_EXTENSION KeyExtension; , z; n/ y# }$ t0 m5 D/ A1 M3 k
  PIRP Irp;
/ j$ j- f5 Y  N  NTSTATUS ntStatus;/ T2 U; n( ^( j& V0 Q  K4 W% `
( R/ |5 A0 W) L" [: Y! B
  KeyFilterDevice = KeyDriver->DeviceObject; ( ^3 G0 a8 h* L& [2 R9 @
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
+ q2 e- X- d1 X7 o% ~- D  S8 v  KeyDevice = KeyExtension->TargetDevice; 1 e# m- ?3 D. K1 |

) E3 X7 }$ f* h& n" E( Z  IoDetachDevice( KeyDevice ); : I/ V) D/ Q/ F/ W5 G0 `

& p% W$ l+ M) g  //
2 j' x  G$ f% t( s! T  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP' t6 ]5 F3 q' m* M7 p- h( b
  //* L0 i' Y4 x7 j! \" [9 X, W0 \4 p
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
+ }) x  M* c6 D' @  {3 x! p. v2 z7 R5 o. o
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )# M. H, h( P  f* ^8 K9 _8 }2 t  b
    {& m! n8 L! T" H0 T8 _7 S* R
      //
) U: G, v* K, V# Z      // 成功则直接退出删除键盘过滤设备3 O6 n. G" T: p3 Y; O$ b+ `$ L% ]
      //1 K1 T1 v! {# Z# Q: Z
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
/ ]& I" Y) g# ]0 i0 Q8 a      goto __End;& L- m$ ?/ r- D$ R
    }
) \1 m: b0 g9 P. a# m# E  }2 f; b* o$ g6 j# m% x( ?+ F

, ?2 ]/ w2 E/ C9 Z0 _# o  y* I3 G9 Q  //
/ M8 ^9 R0 D0 x2 |* u  // 如果取消失败,则一直等待按键( l% k) J& q: s$ g, [
  //& y- P. F" ]& @$ U7 S/ O
  while ( KeyExtension->IrpsInProgress > 0 )8 y; k0 R& f7 p+ w
  {
% g3 x' m2 K7 ]6 _2 q1 S    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
/ J0 c5 W5 K8 H! U  }8 K! D6 Z+ U! @8 a2 _7 V# m

. @4 R/ A9 ], C1 h) ]  __End:3 q6 b0 G7 O  u
  IoDeleteDevice( KeyFilterDevice ); 2 }$ ?1 k# @; b# J

- I4 e6 l) V- A1 k! p7 R  return ;
; s& U6 I/ l& x} ) ^9 v1 g  Z0 W% f8 d$ i

$ a0 R* b5 T  g! o1 K1 `& ]5 ?////////////////////////////////////////////////////////////////// f5 v: A! W+ J6 M% H
// 函数类型 : 自定义工具函数
! [. s: G# n8 Y/ b, `3 x// 函数模块 : 键盘过滤模块* D0 M' f% O7 q' [% Z+ O3 P
/////////////////////////////////////////////////////////////////0 D! G, T( S9 J9 p
// 功能 : 取消 IRP 操作2 v! j; A: a3 K9 M) x7 h2 m
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
- |% E! c2 B. g5 T//        使用此方法来取消 IRP
( r. i; e( ?6 ?  K6 Q; v. F: \$ z/////////////////////////////////////////////////////////////////
0 ?0 O& ?! F% f// 作者 : sinister
9 R/ l5 Y2 y4 m// 发布版本 : 1.00.00
- n! g& V8 C$ i  g  I; [% I$ _// 发布日期 : 2007.02.20
' M0 U$ M1 P  ~9 Z/////////////////////////////////////////////////////////////////. u# [2 J, W0 ~/ j% n
// 重   大   修   改   历   史& z, G' y0 f( @, H) h9 l: V5 R1 ^
/////////////////////////////////////////////////////////////////
' z8 |% z3 y+ B$ L$ u8 r// 修改者 :
; E8 N8 v) O+ ^* q4 g// 修改日期 : / Y% T' C- o. B+ n: l' Z+ J
// 修改内容 : , M2 S; L2 Q+ M' E
/////////////////////////////////////////////////////////////////- I: D$ B; m& s+ v6 r& D  x3 l! R* j

- P$ g" c, e4 a% v% G  ^6 \BOOLEAN
3 X" @) w9 |) `( d3 }0 g' `CancelKeyboardIrp( IN PIRP Irp )8 a( ~) `% L( i" {! k! [+ ^
{
% a" r& o" T, J4 l6 B  if ( Irp == NULL )
' p# f8 _: M6 |. d1 e5 N3 _' \  {( s3 q2 b$ e. x! k
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );% g. I4 N& }* n. ^7 I  H
    return FALSE;6 `1 L1 N" o1 }. }" U! ?8 o
  }# s- l2 r3 f7 l# i! s4 a% j

- m) v& L- ~2 e8 y. C9 a7 h6 g. Y% Y9 @# v2 H" d4 u9 V7 J" F+ h
  //, ~3 U: A9 }+ H8 ~7 _5 F
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,$ ^* A  I7 a7 d$ j3 F
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。7 m" A& h4 v0 a1 P- d1 C! x# _
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
% `5 R4 t" i7 A; G# H! A  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD: L  t! j2 g3 A$ p3 Z; Y8 y" v
  //
. _3 |) _8 C. a* A% b9 p3 |* ^* {5 N# {
- ^, u) D! T( m2 ?, U  //# Y% ?8 X7 n  s5 r( R) o6 U
  // 如果正在取消或没有取消例程则直接返回 FALSE
, b) @: k9 j& k  b$ R  //
0 G2 E  q* ^) x! v$ N, T* H* r1 z2 C* \  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
9 J5 @, X; d2 B4 d2 z  I3 Z  {
: g1 N1 m0 w( N5 T" o' G$ L0 [    DbgPrint( "Can't Cancel the irp\n" );7 P0 f; E! M9 _/ Y! z
    return FALSE;  u9 O. }' G3 j
  }$ U# \2 b" G. E  s  }: q
( S/ _+ T8 V7 d4 F* \" N- K
  if ( FALSE == IoCancelIrp( Irp ) )
. P0 E2 o3 P3 R  {
4 v( D# e, q9 z  l& [    DbgPrint( "IoCancelIrp() to failed\n" );
3 w+ V' ^9 b0 e* d  W! p1 x% @    return FALSE;: z6 N2 c( o( s3 H5 }! h
  }
. Z: A$ v5 Z9 i' _2 b$ v
; n( S! x7 U- @: Q  //+ Z$ l3 O8 }- S% m' e
  // 取消后重设此例程为空
) F+ o3 [5 G7 y. Q9 s4 i0 m9 a  //7 C& v  p4 x- k) @) G7 M5 J9 t
  IoSetCancelRoutine( Irp, NULL );( L: z2 Z2 m& a  ^% D
: Z' ^- Y* \/ x) {) |
  return TRUE;
  A' y7 R  p6 o; I* d}: o9 R# x: k/ D
7 P' {2 ~+ u# N  q4 m& f" `6 N
/////////////////////////////////////////////////////////////////8 I* \$ h& P6 K/ ~$ E8 _2 M
// 函数类型 : 自定义工具函数
5 _7 R0 U" L" l// 函数模块 : 设备栈信息模块
% e: w1 u5 p# x* i) ?& F" {, l/////////////////////////////////////////////////////////////////1 ~% {1 S" r; J) P6 y" ^
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
/ C& d! }, |( O/ Y, p//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
8 D5 }- N  C; c. `# C// 注意 :
  E  y! v8 K* O, ]  ^/////////////////////////////////////////////////////////////////
! _3 `4 _1 d8 P" L+ S- `// 作者 : sinister
! g% M$ d' \- V; l9 n// 发布版本 : 1.00.00
0 e1 t8 G% l4 M3 P// 发布日期 : 2005.06.02
8 L. I; B/ ^( }: L# d- ~/////////////////////////////////////////////////////////////////
' H& u) F$ v( a0 q8 L4 r/ t// 重   大   修   改   历   史
# C& P0 [3 r1 J$ f1 H5 v% R2 Z/ U0 r/////////////////////////////////////////////////////////////////) Y' ~+ o) r  A7 [) a
// 修改者 : sinister+ R  t: M! L* n; j' J
// 修改日期 : 2007.2.12
9 i' [- p7 x' |- V. O! m7 H// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改% o& Z3 \8 J9 a3 h4 {7 O9 W
/////////////////////////////////////////////////////////////////, @( B' F& p9 y6 w- o; s' K7 r$ s

* z7 N$ z1 F! X* G; [# r+ E3 ?3 T9 {; qBOOLEAN
* D2 U4 U% V- u  f7 X/ v8 d& m$ xGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj ). i0 a$ r  s. {' x) U; q( A8 K- J
{
6 B% _+ s% ~% e1 Y7 U- |  PDEVICE_OBJECT DeviceObject;
, o7 m9 x& g* ]; y5 q+ ]+ m/ A0 d  BOOLEAN bFound = FALSE;
  B  X- A) j9 J: N, D" `, g; Q& f( g8 C) C6 l  d2 n2 Q# Q
  if ( DevObj == NULL )6 U" @" W+ b7 ]+ U# z3 P/ i
  {6 I$ C$ P( l* a
    DbgPrint( "DevObj is NULL!\n" );' F, g: ]' m# A. j# ?! L' {2 k
    return FALSE;( R9 N# N# G- [) W, B) \
  }: i" G$ ^7 H' I* K2 D" l
. x& v' ]. Q+ W5 V- W" T/ y* w. V( R: k
  DeviceObject = DevObj->AttachedDevice;/ w% P" ^$ s6 o& a) v6 w
$ {) `6 I/ k% |+ _2 g
  while ( DeviceObject )
+ m# s2 v9 r1 |: G" u  {. @# t" g: X! g' d  s3 u' N! n
    //% r+ b. i5 a: E- t- j3 i
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但9 \$ o' }! N, J/ Y
    // 有一次足够了。这算是经验之谈
: c6 j. O) Z- r& X, j8 x1 P3 V% K    //
) q+ Q3 Q& E' \6 M; k, v8 z    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
9 P2 G1 [8 B" W# i  j, a) P  _3 e" w    {2 J7 x/ ?- z) }" F
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",3 `, v* j: L' a
                DeviceObject->DriverObject->DriverName.Buffer,) D9 j8 {- I* Z0 w, h
                DeviceObject->DriverObject,
% ^2 ^; B  @8 Y$ Q0 O) u+ O* T                DeviceObject );+ O" L. V" N# ]& m# i  }+ F
! ^; y9 s0 f! q2 j& o$ l  c5 l4 l
      //
$ B' x0 C4 r- \0 E# b      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了) p( u; c4 R6 h/ O/ U. ~
      //& p/ V+ ]* x0 F1 @( t
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
! L  a! J1 c1 o3 F5 G: j0 _: ?                      KDBDEVICENAME,0 L$ J4 \. M8 F( t  o
                      wcslen( KDBDEVICENAME ) ) == 0 )* D4 ]  [. j) {0 u: y9 b" h
      {; p, V( @5 G( T. x1 h) j6 j* i
        DbgPrint( "Found kbdhid Device\n" );
, h" J. p/ d  R4 o+ f/ W        bFound = TRUE;
  W# N/ w( G4 @& `) `/ f$ s3 U$ F' H8 Z        break;
4 }  P# l& n' ]7 @+ g      }
; V: Q8 A* P0 o; Z. b7 U9 u    }$ ^  d1 c" b9 |+ z4 j

, T8 V: }' ]; i" p    DeviceObject = DeviceObject->AttachedDevice;% v8 \& }5 Q# k
  }* {, Q/ w+ I. a* t& d% O- \: A
1 e) `  ^* Z' Q) c
  return bFound;
. \# f  a1 |* d9 g}
  y2 \, S3 M6 R$ o2 N
: y% g; Z) Z4 O2 U: g( \) ~* C/////////////////////////////////////////////////////////////////
/ _) L  A* Y" G3 A0 D// 函数类型 : 自定义工具函数
: [: I1 V6 A8 H9 V+ R// 函数模块 : 设备栈信息模块2 \+ c% c5 ^* d2 K6 U8 W; O; _
/////////////////////////////////////////////////////////////////, E. j# c: n5 C! u& T
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址+ H) X) l' {& q8 }5 x+ Q. S/ A
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改# A- }0 m% @' v
/////////////////////////////////////////////////////////////////" r) ~) h: f3 G3 N- Y6 f
// 作者 : sinister
! e- B+ T# p* C: R0 L// 发布版本 : 1.00.00. R. o1 D% e( ~4 T" W( A5 Z
// 发布日期 : 2006.05.02
6 p% Z( w9 {: l! r, O  E/////////////////////////////////////////////////////////////////1 w4 O6 q0 C2 U2 ]1 Q8 ~
// 重   大   修   改   历   史& Z8 \# A( M% q  s6 f4 a$ W. u5 V
/////////////////////////////////////////////////////////////////. J# o5 o1 i0 A
// 修改者 : sinister" a4 X5 R' T% _# }8 P
// 修改日期 : 2007.2.12' g# _: T" J$ y+ K, d
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
* u( L* z2 T5 {4 F/////////////////////////////////////////////////////////////////
+ n7 c- h2 \: J6 j
; g2 m$ Q0 X! E5 SVOID
5 h: {8 J+ F! ^! v5 _- R# q6 xGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
# J3 K+ I. f  y& x& G" a{
$ m7 s( \9 `) @8 X0 |* T( a$ M  POBJECT_HEADER ObjectHeader;- T: J; S( W" w9 _1 a3 L* C3 L
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
! Q5 J$ K9 W) v( j! B% g" S& @1 D6 y2 B2 q: E! b) h
  if ( DevObj == NULL )
. r+ W1 d9 S1 N/ r  {
9 n' m3 E7 a- |6 D0 K    DbgPrint( "DevObj is NULL!\n" );
. v+ l% @7 F9 t( _* E    return;  q5 T, |. r* T/ z
  }/ Y! \+ K% I) _, _) K
5 @) K  @5 |1 j, b  |
  //' Z+ W) G4 `; w% q
  // 得到对象头' o. c, v5 E3 o0 P
  //
, Z+ H1 B# s' k3 X, C: g  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
% q. p4 z+ m2 i1 ]! p  S2 K6 p1 C% V4 j/ y
  if ( ObjectHeader )/ h! `, K$ g8 [) l3 I+ `" @5 r
  {
" f# P! M6 G7 x& x9 _+ Q7 B    //
, G/ r7 M& S3 U' Q  O5 `$ m    // 查询设备名称并打印
4 \7 ^8 o5 |- Y/ ~7 X    /// A$ A- H# h/ e( [+ y3 a' \
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
' d: s# R; ]& x$ j2 Y" H+ f
  {* [$ q1 a, Y: ^, V: j    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
: c, S0 u* e- _+ `1 a( C) V+ g3 {    {
  D1 e* C5 u' O9 ]% W& h+ {% p0 s( \# Q      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
$ G, T2 X, S; t                ObjectNameInfo->Name.Buffer,  B; U( v, a0 G' n
                DevObj );  v7 _# o! N6 d1 ?" A! {* ~: @

6 b; I' r/ O3 k: h1 r" y2 V$ |/ D      //4 x9 L, b9 E2 D- d3 K) F
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
4 g3 j4 h6 s& O* P      // 用,没有实际的功能用途. H; B% X! e( R
      //
& M  _' X, U+ c3 d3 {9 |* Y( L8 J, a      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
( v$ j  c2 W; U" z5 @  K' D. V4 |- \  k" m# {6 x" J
      wcsncpy( szUsbDeviceName,/ L8 `% }, D* |: @  u
               ObjectNameInfo->Name.Buffer,  t! }' ?% s& g6 i2 Z6 L$ m, J2 [
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );3 l( s3 Q; c8 m8 w; @; v* }
    }
# c; y1 f- M4 k# A& }. b3 y5 N- U4 w3 B$ _- s
    //. o2 k1 F, E. h' M  Y+ e
    // 对于没有名称的设备,则打印 NULL
7 ^! Z7 M! T: K1 U* a; A# O    //
* o1 R, k) h5 j/ B* h  O8 D6 |    else if ( DevObj->DriverObject )
  B  G3 |- O' ?' o- J    {; d/ v$ s" p$ Z/ v# o0 B+ k" x; e
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",+ G* b& K# O4 D/ |" p% _
                DevObj->DriverObject->DriverName.Buffer,
9 Q1 c/ p6 e& A( f+ F" r. Q5 m6 ?                L"NULL",
0 y: g5 \3 B; \& c! s                DevObj->DriverObject,
3 A+ t( @' B; O, T" q3 p                DevObj );
, f" J2 ~1 w) A2 K  \    }
6 ~) [$ r9 b/ M0 N  }
* U9 K* H) O- v; ]}' E" F) w, }& L$ o- t% w  b
. a8 [, ]7 x. n7 [+ }
/////////////////////////////////////////////////////////////////; K8 r; ]. H% m, B- Y! r
// 函数类型 : 自定义工具函数
0 I& N1 N+ ]& _8 f% F# E// 函数模块 : 键盘过滤模块6 Z4 S7 {) V, u/ Q4 l
/////////////////////////////////////////////////////////////////4 C" |! m8 O1 q7 X% i; R2 h
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备! c4 N' K% e9 r7 L$ w7 a' _" P
//        对象,过滤出 USB 键盘设备,将其设备对象返回
9 r% d2 r' G& j' j// 注意 :
' d" o0 b4 J" h( v/ R/////////////////////////////////////////////////////////////////+ l. L( p7 q0 H; r  ^4 `$ L* b; T. X
// 作者 : sinister2 {4 J, ^1 B: J3 f  q/ e
// 发布版本 : 1.00.00
- y/ [9 v: O  Y8 ]0 a8 R. z// 发布日期 : 2007.02.13  w# T# _. C% H6 Y3 q1 [' }9 d2 K
/////////////////////////////////////////////////////////////////8 ^2 {3 ~7 Q6 \
// 重   大   修   改   历   史
7 `# X6 ?. U% l+ e. O2 [6 A) g/////////////////////////////////////////////////////////////////
2 M4 d+ b$ ?$ T1 ]1 ?0 B; }: ^// 修改者 :
: x, x6 R; p3 E: Y) ]// 修改日期 : 6 ^# Y* S8 B% d$ u
// 修改内容 :
  R. c) N$ y2 ^/////////////////////////////////////////////////////////////////. q9 Z, O2 m1 h3 _6 a
4 h3 y* C  ^# w  v
NTSTATUS4 e# V6 D' I1 i; p: }. O, z
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
5 r! j+ X4 u9 \; k' ?9 _{
2 a! S- W3 \& O) }  R% B/ [, [3 f  UNICODE_STRING DriverName;
. W, W4 O8 \# ?% h  PDRIVER_OBJECT DriverObject = NULL;
1 A2 B! `" D- E$ N" V% [  PDEVICE_OBJECT DeviceObject = NULL;1 H$ `; f' h0 f/ x
  BOOLEAN bFound = FALSE;
& e& X- D/ ?& O5 W! @8 w8 c$ X& Z% _1 s1 o1 S7 o2 F1 f
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );& t9 B) c1 P; h; j

' A9 ]2 M" ]  @: ~2 O  ObReferenceObjectByName( &DriverName,- ]" l% }. i9 h+ E8 ]+ \3 U
                           OBJ_CASE_INSENSITIVE,0 h6 U- Y9 F2 b+ T4 |/ R
                           NULL,
5 u7 q; ^, O6 C; f5 F( v                           0,
" ?" d: W9 b  ?* S' H6 \1 ]                           ( POBJECT_TYPE ) IoDriverObjectType,
+ r6 z! E3 |: _5 S) ]5 [8 p( J                           KernelMode,5 ]2 d) H( p) A! N8 l
                           NULL,4 ~9 s1 F1 }( g* L
                           &DriverObject );1 @6 T" X* A- P: |
) W9 g7 C6 D* |1 ~8 k1 o) K
  if ( DriverObject == NULL )6 `  J1 \, s- u
  {
4 e. x6 `) }! h: s    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );' q% R5 B) o% M' p5 p5 J
    return STATUS_UNSUCCESSFUL;; a# E6 O, ~& }
  }& n7 E+ {, Q+ i
  C3 x4 @2 ^, s7 N
  DeviceObject = DriverObject->DeviceObject;/ R- a2 M' _( \. G. t9 K% i

4 {& s, e8 v. N+ z8 y/ M  while ( DeviceObject )
7 h, O; e( v5 j: Z  {0 k) c; ~* Y. l, L6 l7 z
    GetDeviceObjectInfo( DeviceObject );: J' x/ K1 J0 M* Q' h5 C
9 @" @5 K- j/ V, K! D0 e% Y9 M' Q
    if ( DeviceObject->AttachedDevice )
1 _1 t7 j; Y- a; _7 p! Z3 }    {, O$ X8 k; H: a; t5 a3 ^
      //
; y' v- F7 }. f9 b( I; \      // 查找 USB 键盘设备5 g! H3 E6 b2 @" y  J
      //" E3 t8 N, Z0 ?  \, Q; c% B( a7 {
      if ( GetAttachedDeviceInfo( DeviceObject ) )
% \7 c7 ~( w( ^$ k      {8 R$ o  N; M2 |1 ?, z) ?, y) g
        bFound = TRUE;# g7 G5 n0 m- p5 f
        goto __End;
+ j. @$ A9 H9 j      }1 I* @, l9 W' v: t( @. F
    }; n, R! q- r9 Q) ?) @; K( ?% D

4 x/ t' X' g: r    DeviceObject = DeviceObject->NextDevice;: {. c# M/ a% h" _
  }4 B4 X8 E% o2 e
  H# W- q$ G2 j, c7 a
  __End:
1 L1 w+ D. A& r* w/ h8 D$ H. |4 ]; m* R; G3 m4 U  b) @
  if ( bFound )+ o7 ]/ Q( D. F  g) S& g
  {
9 G7 x3 J& p7 z+ X4 `    //" f; p& r9 |* J6 G" g
    // 找到则返回 USB 键盘设备对象+ P9 e* q0 j& M2 b& K/ u2 I
    //
; ~3 d( }% t4 A1 ~5 ?    *UsbDeviceObject = DeviceObject;
' S0 R. `) s! l% ~- L  }
' L4 q. J# x! J5 ~) Y+ T# V& v  r  else  S+ _( c5 L( w
  {) F, ~+ k0 U+ r5 j) Q) x
    *UsbDeviceObject = NULL;; z" \8 i0 a' ]: h" _
  }
* I8 V5 G5 A: A3 M3 \4 d  l) m2 H! y$ N/ n  t
  return STATUS_SUCCESS;
6 d# ~. {; z1 U}
0 n# v( _( R' b: }% J+ q+ n' Y9 x8 z  g7 W& F$ W  v5 T) v" E
/////////////////////////////////////////////////////////////////
$ t3 H9 D& e( C" N/ G+ ]: e7 }// 函数类型 : 自定义工具函数
, e, Q2 _1 _/ r2 s- `// 函数模块 : 键盘过滤模块
" d8 E$ `3 Z4 o& p" q3 X/ e3 H////////////////////////////////////////////////////////////////5 I+ K2 c5 s6 o( [& B% m  q2 \0 X3 {
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关  x/ Q% V% [+ Z$ j' n9 T7 H8 x0 X
//        信息,返回附加后的驱动对象
7 T+ o6 K: a1 l8 f5 G- J" w// 注意 : 此函数仅挂接 USB 键盘设备
# {# k- ~& L" E8 I/////////////////////////////////////////////////////////////////" @/ K, H* o1 ^0 z6 N
// 作者 : sinister
$ O) X5 {+ J: d. Z// 发布版本 : 1.00.00
, X8 C; k1 e$ t4 V2 P1 T+ p// 发布日期 : 2005.12.27
' N" u+ z9 e% a# t; u/////////////////////////////////////////////////////////////////
: Z( g0 C( {. t" `) `8 p// 重   大   修   改   历   史
3 ?: L. ]$ O! E& K////////////////////////////////////////////////////////////////$ y2 N9 ?# X, q4 @3 x# d
// 修改者 :* l# R5 z) W8 ^8 t/ d
// 修改日期 :6 T- C! u; O* H* ^- w0 I( J2 M; l
// 修改内容 :2 P" i! e9 `4 `) B
/////////////////////////////////////////////////////////////////; i- }4 Q& X8 ?- X0 P5 W% _! f
2 `/ w/ \$ `6 Q+ C$ N
NTSTATUS. J' n( e; @0 n/ W* M0 z7 Y; u" }
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
, i# ]8 J& J: k' R$ Z! Z                         IN PDRIVER_OBJECT  DriverObject )$ c' H0 `6 C" R+ G7 g
{* x. K$ g8 j; N5 g$ C( v) s! O
  PDEVICE_OBJECT DeviceObject;
: x" D5 |+ [, @9 w6 y  PDEVICE_OBJECT TargetDevice; ) \. c8 p8 O# T) F0 y. m
  PDEVICE_EXTENSION DevExt;
  w7 U/ x0 ?( ~$ [& k& ]& h- E  NTSTATUS ntStatus;1 k7 X( l8 H% p

" F" ?2 a3 R) S/ `3 k$ P3 m  //
; M) g: O3 F5 ~) S' X6 h  g  // 创建过滤设备对象! u; M7 n6 n- i. F/ F' ?
  //
+ A8 e2 D+ D9 ]+ g5 C: |  ntStatus = IoCreateDevice( DriverObject,
1 a1 }& B5 Q1 y( h                             sizeof( DEVICE_EXTENSION ),
6 Z3 Z$ _' _7 Y: S                             NULL,
  J* W0 V$ ]  f( @: ], o                             FILE_DEVICE_UNKNOWN,) h/ j5 a) H, t' V- j0 Z
                             0,
* p! T7 }  }1 e( Z9 i4 f                             FALSE,3 h) {# U( U$ F
                             &DeviceObject );
2 k* m; l6 V) O! e7 a7 g
( C" d$ y7 s. i  if ( !NT_SUCCESS( ntStatus ) )
. t" {5 w: p6 t  {
- B! j8 d- x! q. k  x9 P2 c    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
) q9 G( n& F( c1 G0 j, {, m& i; e    return ntStatus;4 T4 _1 A% C+ Z7 O
  }
5 s3 m3 Y1 t3 c0 t# d  t1 E9 h- o0 w
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;  G/ Y4 ^1 p+ E) z$ U7 d

! A& U0 ~+ ]/ g/ C/ L0 ^/ L6 D, ~0 k  //& R$ |  o! d- y2 r" a
  // 初始化自旋锁
2 b& l: W' H% K  l9 A  //* A& P" Z; K1 {1 Q( c
  KeInitializeSpinLock( &DevExt->SpinLock );
. b6 t+ e9 [9 V; t9 K
% b. j9 H: \; M# P9 p  //
& v: v$ g9 u# T2 m4 q  ~  // 初始化 IRP 计数器7 A, c" x4 [) i! K- e
  //1 L0 }8 ?. Q1 f: q" n5 h
  DevExt->IrpsInProgress = 0;
/ i6 A5 c# @7 r. g/ K, M% Y+ ]' g* b5 h; Q  I0 P
  //
; w7 f! p& B; d( a2 o  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
6 q8 B- Y+ ^. B0 m# b* c  //
4 q* w3 O8 ]' V6 b* C
; s+ _/ x; L' w. s  r  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
9 p  x. B' R% ~) k4 y' ?7 v  if ( !TargetDevice )' E% @" ?$ n9 P
  {
4 m7 F! a. A! R( K    IoDeleteDevice( DeviceObject );
9 B& d0 h' r1 s4 }+ v& ^    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );) Q. h7 V- y" O) ?3 b. ?7 \7 w/ ?
    return STATUS_INSUFFICIENT_RESOURCES;# G% t" P# C$ q) M
  }
1 W4 W! |: S1 [/ Q# @/ n3 H' }, b- [+ S0 P- e& X6 `; |; s
  //
1 T1 V/ {1 {; b& H5 a  // 保存过滤设备信息
& V5 x' S1 n9 M* r" |  //
2 |8 X/ O$ h9 {/ h, c- ~. B, |  DevExt->DeviceObject = DeviceObject; " K7 k/ K2 b& C
  DevExt->TargetDevice = TargetDevice;0 m; O$ X. K* Q2 U4 c* f6 A, E

% q' n. D/ F: @3 |  //
5 B( B) A3 J; a% d3 c+ f  // 设置过滤设备相关信息与标志
0 O$ G: y9 d, d& O+ i' z  //
: F5 T0 {: |3 ~7 d. \  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );: ^+ A9 i* |1 u* f; `
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;' x  w8 c+ I/ d- b! K6 R8 m* ?, j9 G
9 r' s  q  X& ~& E2 o. ^

( n4 o1 Q% ^) a/ ]  return STATUS_SUCCESS;: Z. P0 [6 k- i% c2 t( L' T
}& G& n/ P  l5 w; G9 J, M3 \
: z/ u( s& J6 E0 V5 W
/////////////////////////////////////////////////////////////////  r) T; r9 i" @/ n9 D( G
// 函数类型 : 自定义工具函数
$ R- Y! v; `; P  i# w// 函数模块 : 键盘过滤模块
- ]& `* y+ ^6 f////////////////////////////////////////////////////////////////
9 Z4 q: r/ Z/ s+ L& ~// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关& a4 M! p' _( p
//        信息,返回附加后的驱动对象
) C6 c. Y% ?6 D) Q  p( Q// 注意 : 此函数仅挂接 PS/2 键盘设备
! I) U) A' ?7 m, Y6 A0 q/////////////////////////////////////////////////////////////////
( H+ K# @% U6 ?7 j$ f// 作者 : sinister- s% y5 ^+ D* s; J: m: ^
// 发布版本 : 1.00.00/ O# A( q- |9 ]" I/ E/ n# O% [
// 发布日期 : 2005.12.27% d8 u3 ?) F& J: V4 Z
/////////////////////////////////////////////////////////////////( m( q/ x/ A2 o- m/ `
// 重   大   修   改   历   史
: U( F. A8 o4 h" A////////////////////////////////////////////////////////////////' N! \& R: V/ M
// 修改者 :
! [( t6 @2 F# k// 修改日期 :
4 U) l5 y( C! V2 W0 `7 }// 修改内容 :
0 M) m. g) [) k0 `: x, Y% M/////////////////////////////////////////////////////////////////4 Z1 H0 [" ^0 ~

- P5 G8 ]- k" F. YNTSTATUS
6 {2 B& i: z4 L2 \9 x( J) JAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
3 S6 f/ m1 M8 Z+ w. X4 A                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象5 |) H3 @0 }  ~" \
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象; K& W; y" R5 {4 l# i6 r. q) S. V6 V
{/ {8 A( K4 N$ k' W: e" a4 ~
  PDEVICE_OBJECT DeviceObject; . b/ X$ U; w' @
  PDEVICE_OBJECT FilterDeviceObject;, e" F$ ~2 M9 Y' ~, f( z( {
  PDEVICE_OBJECT TargetDevice;
8 b" ?6 ]( F) w  PFILE_OBJECT FileObject;
% C9 d& J# f8 X; ?  PDEVICE_EXTENSION DevExt;1 {, j4 D5 p& t! |( e! ]
) @7 E, F; Q3 w2 o2 `
  NTSTATUS ntStatus;
9 D$ K: G* A1 F& }3 D4 }
% e6 N2 Y& F" K+ o  //4 M) {' n6 D$ D
  // 根据设备名称找到需要附加的设备对象2 v5 n8 G, \, A' }/ |3 B! u# P
  //
- ?' F' N7 E3 j9 q7 z3 h. f# ?6 M3 K  ntStatus = IoGetDeviceObjectPointer( DeviceName,
8 {, k$ G* ~1 u                                       FILE_ALL_ACCESS,
1 U6 {& \" x# r                                       &FileObject,  \# r  K+ b  @3 s& N6 |  f2 \# Z
                                       &DeviceObject ); 1 l9 b! Z3 M3 H7 p7 b, U
  i! f% b( v' G8 _) ~
  if ( !NT_SUCCESS( ntStatus ) )
5 }; M- Q0 ~  m& d4 d9 D5 R5 O7 ?  {
0 ~6 j  c! a+ M7 Z: G    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
' g1 S5 d' P6 z( P* v; w8 B) f9 Q    return ntStatus;
4 F4 z3 o& L# `  } . I5 Q6 }, a6 Z: ?7 p
' q& e( y/ R$ v
  //
' I% U- R, q/ h2 b1 z8 {# v9 x  // 创建过滤设备对象
2 R- E' D/ f$ J  //
& K8 }( E: F7 f: T  ntStatus = IoCreateDevice( DriverObject,
- h! z( j6 |. M; k" ]                             sizeof( DEVICE_EXTENSION ),
) V- L4 o/ U4 k( [# ]; ^6 n/ T                             NULL,
+ x) T# I* d/ ~                             FILE_DEVICE_KEYBOARD,7 C, @3 [% Z: ^
                             0,1 O; D8 O- q( |# r  L5 e
                             FALSE,: B* q" u6 }' X" @- [
                             &FilterDeviceObject ); 7 O' f! i% y3 H9 i8 a

) w+ ^3 ?2 `1 [$ ]# X4 e7 R  if ( !NT_SUCCESS( ntStatus ) )
# E, w7 V; ~  o- X% |" _& l- ^7 L  {
0 b# k0 _$ t6 B, S) |* S    ObDereferenceObject( FileObject ); # |/ s, Q+ m- \8 W- y
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
* Z* c0 R9 ~! \+ t4 x/ E    return ntStatus;
; S1 n3 }; L1 h) D& W' E  } ! h% T* e8 P. L) G1 L, b' d
; o9 S8 H1 ~2 g: w6 k% w7 I# M/ O( h
  //% d4 e; ]( K0 ~- m
  // 得到设备扩展结构,以便下面保存过滤设备信息( U* k( x7 ?; b' W
  //) G& `) o1 k1 K" ]
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
' [5 {( G. c* |# `+ H/ }- c! n4 N% |' I

5 j" I) p0 i# D3 ?$ @  //
8 J6 M& Q/ X, @  // 初始化自旋锁
! {* q, H4 R+ A. d4 x  //5 h! Q, m4 {, x
  KeInitializeSpinLock( &DevExt->SpinLock );( z* x* h. b% h) r* S  T

! E% v& u2 b+ u% y7 S" B% S  //4 R6 l) Z/ z! g' U, X6 a. w
  // 初始化 IRP 计数器
% K* X0 n5 C" I3 r- z8 ?  //0 \0 s% m. d7 L9 F+ T# K1 P2 A! g8 J
  DevExt->IrpsInProgress = 0;
( G9 z1 E8 p7 U# u0 _2 X$ g! {2 r
* l5 I& |" r0 @$ o" h2 g' _  //* l) Y% c# Q2 a8 q0 ?0 z
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象* q6 Q) ?: Z4 p! ^- ^/ e1 a3 s% }( Q
  //. e. l- C! h+ K  A
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
2 f) k$ d9 Y. W" [                                              DeviceObject ); 8 l2 ~) p. I/ n& o4 K+ A7 S" v; M
  if ( !TargetDevice )
8 _2 p5 t& ~; W2 D  {
1 E. X) H# r  s! I    ObDereferenceObject( FileObject ); 7 \5 E4 |/ r/ |; e( b+ C
    IoDeleteDevice( FilterDeviceObject ); % ]; f6 D* p# Y
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );/ Q$ r1 y5 t. E5 q
    return STATUS_INSUFFICIENT_RESOURCES;
; M, x0 Q# S3 g8 H# p5 F5 T; M  }
" K& H9 Q: u* _- U6 j  E5 m/ [4 ~6 C, a+ X
  //$ u4 l& B. Z' q- `" I
  // 保存过滤设备信息
5 E- u- L2 j; ?) T- D8 s; [0 ]  //
' F! v' [( m0 q$ N. Q) {  DevExt->DeviceObject = FilterDeviceObject;
0 e+ n# ]6 i. l6 m1 ~3 j4 P+ v  DevExt->TargetDevice = TargetDevice; 3 k+ ?4 A- Y2 z/ B  @3 z2 m2 }% A
  DevExt->pFilterFileObject = FileObject;" W5 Z5 {- o6 v/ L/ Y! ^  X

; f; a$ F% N8 ^3 @- R; U( x. t! T/ w  //
* N# }/ `* t. s  // 设置过滤设备相关信息与标志
/ Q" X6 R! V4 {' \, A3 w0 z' f9 {  //
' |7 o% y! q- x0 Z$ }% e9 [; B  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; : P* C2 n: l+ O( u$ V
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
0 W2 D3 r5 j. Z. z& B0 U  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
9 q; i& }9 R  ]% N9 `  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
; v9 h* b: {$ T$ k$ J                                                         DO_BUFFERED_IO ) ); + u5 E. j& p( o4 E, ]  X# e5 J

' ]/ _/ G& P- s0 D# \$ y4 I5 s  //; S  C8 H' b+ \2 @$ D1 r3 ]& u
  // 返回附加后的驱动对象
: {$ w# \8 x3 i  //8 e- A  Q7 w9 |6 @& K7 c+ k# R
  *FilterDriverObject = TargetDevice->DriverObject;, m5 n! j- C& u' |; J/ D/ `, N" E

. U- \! i( B8 S  ObDereferenceObject( FileObject );
, l9 v2 b, v5 e$ R
. Y# V% C3 U4 S  return STATUS_SUCCESS;0 G- m/ @: m! A" X/ F/ u. O
}
" Q6 |' i9 P- K7 L* r, b0 w. Z1 s/ S( }
/////////////////////////////////////////////////////////////////
% W1 \/ k5 G+ H// 函数类型 : 自定义工具函数
* o, k  Q. F+ J7 y1 Y% k// 函数模块 : 键盘过滤模块
4 _- r8 u" q- a7 O; B4 u; Z////////////////////////////////////////////////////////////////- g: z+ j2 W# p, A* m. O9 c5 l1 O0 o
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发9 p+ m# A% T& h1 n. I
//        这个 IRP 的完成$ V3 H8 d/ H# Z# @2 E1 W$ R
// 注意 : 8 f/ d2 e$ W7 F. W2 m& n# ^4 Y& J
/////////////////////////////////////////////////////////////////2 Y4 h  m" x: z; e& b
// 作者 : sinister  U5 K. A$ t1 d8 R
// 发布版本 : 1.00.00* H" N7 T) U; Y" w- E9 ^
// 发布日期 : 2007.2.15
" ~; M! W4 Q$ s2 c/////////////////////////////////////////////////////////////////
/ k: `. I8 f2 X0 U/ ?& F! N// 重   大   修   改   历   史# J* T: r7 u+ V$ E: p$ H
////////////////////////////////////////////////////////////////
+ k& g4 _3 c+ t2 Q// 修改者 :
5 b! Z  ], G- K) @. B5 }+ d: [. s// 修改日期 :
. L4 u' @: t8 J+ m, k: @// 修改内容 :5 _4 _  P0 D0 b& Y: p
////////////////////////////////////////////////////////////////// G( ^. V0 [' M2 G" G

5 L2 B/ O. a# R5 u5 t$ ?, ZNTSTATUS1 i- x, Z$ G1 A# f8 m
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
; A9 |9 i1 W1 q+ g{9 ~- k* E3 n$ s& o8 c0 V0 M4 ^7 f1 |
  NTSTATUS status;
; |- R/ K6 O* G# h1 J4 m  KIRQL IrqLevel;7 e& x/ ~8 D5 U) O! \( k: }

: M. ~, e# f) _/ Y0 I  PDEVICE_OBJECT pDeviceObject;
. F5 a4 b+ ?+ g) s/ C, }  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ @& Y/ J6 l. S& J                                   DeviceObject->DeviceExtension; # c0 Q) _# k$ W) |, T- N( d3 e$ C
: }1 f( B1 h5 N3 S
) D! b' x' `7 [! ~+ t
  IoCopyCurrentIrpStackLocationToNext( Irp );
" y) E- @/ F1 Y- W: O$ r' R
  G6 K; \& j9 X0 a: a0 F% e  //% w8 b2 Y/ V; [* u8 g, H
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁  Z; j3 \: L- Q; q. E, |
  //. h* P+ |0 F" ^! V6 s4 d
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
8 L6 L8 N; _) ^& l5 C  InterlockedIncrement( &KeyExtension->IrpsInProgress );# A$ ]" J: o; I/ P( \
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
  m7 v! @" o3 Q, C+ O# h3 y3 X6 |
: a5 l4 N( \0 |. c  IoSetCompletionRoutine( Irp,4 E: H+ B) z& [# y) Z, e5 z
                          KeyReadCompletion,
) H. A8 x/ D8 s3 W& ]" Z, }                          DeviceObject,1 ^" {, g* U  z3 @' j+ c" b
                          TRUE,3 ~9 c$ |3 c+ F; s: d
                          TRUE,
# A& c4 I; k3 M& e                          TRUE ); / ?% P+ J. n/ j, _$ J& y3 `
3 l# b  F+ h* }0 V. \
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
. b9 E* e" g6 A/ n}
" y7 L3 d& g6 g3 H$ `8 F" H) X. V" r; X7 }! ?
/////////////////////////////////////////////////////////////////6 L2 l9 D5 }3 h1 e# H/ e0 W0 q
// 函数类型 :系统回调函数
3 h8 H+ K  F( C4 v2 w% L// 函数模块 : 键盘过滤模块2 u; m5 @' C% p5 w3 i8 ]3 C0 V: K
////////////////////////////////////////////////////////////////
9 t3 q% }# O" u8 b' b- b1 A// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的6 T. N! B* \2 Z$ I7 o/ u
// 注意 : # ~) `! I: [8 t8 c* C7 s
/////////////////////////////////////////////////////////////////
0 h1 V2 T' ?9 U5 {% b// 作者 : sinister
2 F) ?- o8 P5 k8 y7 C// 发布版本 : 1.00.00
  {5 j2 r& V4 C6 |3 d// 发布日期 : 2007.2.12) |+ d2 ~0 k$ s/ e1 `8 g
/////////////////////////////////////////////////////////////////* M& z( p; j  g
// 重   大   修   改   历   史$ I* k- M; s6 d
////////////////////////////////////////////////////////////////& g( f5 m% A0 B6 I
// 修改者 :
: k8 T! f1 m3 X4 r4 y/ y- ]// 修改日期 :& B; D  O3 V- v; P6 z* y; ?, L9 z
// 修改内容 :
% @, m0 |  x/ `7 ]; Y  F/////////////////////////////////////////////////////////////////* `% w4 e1 _1 D  j

" n" }1 N  o4 F, r* j9 P' m& NNTSTATUS
: a( U" }7 I) }KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
0 t1 l1 V/ p1 O: ]2 v8 P                   IN PIRP Irp,
$ ?, E* w% m  X8 {+ L! f- o                   IN PVOID Context )
! N1 d; D* j) B2 H{% v- Y% D& ]$ q' O# @) {% n
  PIO_STACK_LOCATION IrpSp;
4 J" p6 N0 s: M; O  n  H: }" v  PKEYBOARD_INPUT_DATA KeyData;
3 [) m( S6 G0 f& k; q; X  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )/ S: E- A6 {6 y+ ]8 E
                                   DeviceObject->DeviceExtension; # Q/ v0 K$ B, s: [; k: y
  int numKeys, i;/ C1 Y% A: ~8 N  U7 ]# c
  KIRQL IrqLevel;
9 X( E1 j. T1 r) w$ v9 E0 B% {) {0 X% @
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
6 y8 b6 E" m' x9 w6 B! r; y' q# N* x; B

# R6 j. I) T8 R% G$ V  if ( Irp->IoStatus.Status != STATUS_SUCCESS )" a: V$ [. e/ v' K- M$ [2 m
  {1 n* a  v# O: a6 X6 j; _
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
' h$ T, m: W1 I% H5 {    goto __RoutineEnd;0 ?8 I4 X0 A. Y# Q& I  ~
  }
; a) k5 H% t4 M9 H
3 h2 G0 P9 ]5 ^/ i  //
% T, \9 y: C4 ?+ Y, S- C3 c% ~( H  // 系统在 SystemBuffer 中保存按键信息1 i7 w- a# ~2 ~1 \
  //
6 k& ]4 o% L' S' p3 A  KeyData = Irp->AssociatedIrp.SystemBuffer;
$ \4 s% a  L! Z! U  if ( KeyData == NULL )
" _- b. B  J. r1 ^  {2 W" x2 g8 D8 @; u% d
    DbgPrint( "KeyData is NULL\n" );
' U9 o" _/ ^0 ^) q: b2 t! h* O    goto __RoutineEnd;
" U, R/ j: ^" h9 ^2 p  }
8 F+ Z* |  P& w( k4 k) i9 R+ u) O. R9 {; @, T8 w% \% e0 l
  //( C- ?( T0 Y1 O* g( J  l
  // 得到按键数( ~4 g0 D) O  J4 W
  //
2 ?! c; B$ `4 c" r1 }, c  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
) g; x, Q+ X. ?" u1 r" `/ a4 ^  if ( numKeys < 0 )
6 y8 R9 u1 g( K8 E  {
3 ~' k9 c/ W# ?    DbgPrint( "numKeys less zero\n" );% e+ Q4 K' o+ G. p' \5 N
    goto __RoutineEnd;" s0 e6 q( E  h) ?0 m
  }4 y* ~+ @* H7 a$ z; G; k0 Y

& ^$ a) Z) z( F8 u0 |  //
! c, \( o4 C/ p6 g9 n- f  // 使用 0 无效扫描码替换,屏蔽所有按键3 [: M/ \9 A3 I' |
  //+ y) f' g; }4 |1 e2 {$ }# E
  for ( i = 0; i < numKeys; i++ )0 d6 V; A) R/ J' q! t+ n
  {; `2 y7 e" }: I- b# r6 L
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
, v) X! h" z! c- P0 u8 G    KeyData[i].MakeCode = 0x00;7 D, H1 ?% b5 c- W8 N  p
  }! f% u5 _/ m/ r6 l- W8 d) O
+ y/ `, ]& M; M% J8 Z
5 W$ K/ @( Z* O- @* M. ?
  __RoutineEnd :
6 M6 _$ d! z% X, B" k. j: D0 G& b1 }: B4 Z( |
  if ( Irp->PendingReturned )8 h( T  l! c! l- j) m
  {
0 p' P1 a6 y( a- s7 |/ Q" m    IoMarkIrpPending( Irp );$ S% ^, D* n9 M7 C; }9 C
  }
& x8 z3 Z& u9 _. [# _3 t' u! g' r, F% ?8 |
  //
( |9 r1 ]* L3 I8 A5 [7 j, D4 c  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁4 ?8 F% S( t+ y0 k0 D5 U
  //! F. e7 M' `1 W
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );0 D2 M+ k1 u" C
  InterlockedDecrement( &KeyExtension->IrpsInProgress );# j7 q$ j8 w( v4 v8 J
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
) X/ C0 u  p  \0 g2 R
+ M2 I: l. Y4 j0 L  return Irp->IoStatus.Status ;0 R9 K7 q  I: J! F. `& C7 G
}
: r9 X$ \* n5 N$ n8 f0 M% `" D: R8 {0 N# K: c# T
) a  e6 G, D: o, \
/*****************************************************************4 s* M$ t1 ?, I# r& l, \9 h3 G+ P
文件名        : WssLockKey.h
$ j0 k0 C  F3 W% O' i 描述          : 键盘过滤驱动
. ^3 A6 L9 p( _ 作者          : sinister
: _3 d' ~' N. D 最后修改日期  : 2007-02-26
  S4 F" i) \' A% K- g; M/ _+ E5 |*****************************************************************/
) X3 y- `- ~( R. t# I' V0 E2 W9 n2 o
- G" I: \2 D1 z" u0 D' h#ifndef __WSS_LOCKKEY_H_
+ s- Z9 t; D, e, x" M#define __WSS_LOCKKEY_H_+ S( N+ z6 G" i# v/ b
  p% L. [: p3 q4 z1 l* L
#include "ntddk.h"
( ?- @8 ^$ X1 @9 h1 a#include "ntddkbd.h"
. U9 k5 @0 J7 j#include "string.h"
! {5 q& A% a8 d' I9 n#include
; K3 N7 V6 g1 x4 q6 T
* |& m# a7 Z; t6 O" z0 C- c1 N#define MAXLEN 256/ G/ a: N5 v! U- O, s% w3 @. r$ }; @

  J7 o8 _; ?8 u% g" z#define KDBDEVICENAME L"\\Driver\\kbdhid"5 @  K: x0 H& |: v1 F% m: u
#define USBKEYBOARDNAME L"\\Driver\\hidusb" 8 j2 v" t% }6 A. I4 S
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
+ b2 x) e+ ?6 X: Y3 g
. T, F1 m! X2 j3 c, c8 D. [typedef struct _OBJECT_CREATE_INFORMATION
- B/ c: G4 m' X+ F* J* W0 T, F- ~{% b8 @7 W! T9 l# T8 Z
    ULONG Attributes;
1 d( q) ^+ Z8 W9 q/ \3 M    HANDLE RootDirectory;
. l$ @6 Y% d' ]) k$ ?7 h    PVOID ParseContext;1 i: x  ~9 R0 Q
    KPROCESSOR_MODE ProbeMode;
4 A' f7 R! p1 ?& ^    ULONG PagedPoolCharge;$ L$ {# E# m, z. ]) K* m, l
    ULONG NonPagedPoolCharge;
$ w( H2 y0 z# k0 {7 R  s    ULONG SecurityDescriptorCharge;( S& A; H  d3 g$ u: z- q. K
    PSECURITY_DESCRIPTOR SecurityDescriptor;2 B: Z, u0 U* Q- [2 t8 j. X
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;6 |) L! |" b& J3 p* N& A. t
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;4 @) u/ J6 R6 t( C
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;3 P6 V9 T2 \6 g! |* c' V7 V
3 t' t& |/ k- {
typedef struct _OBJECT_HEADER
6 j% X- `/ d0 N7 L{- q9 J* [' {1 q; Z2 s
    LONG PointerCount;
: D* Q% `/ q7 T% T    union) w, O7 C5 V) e
    {9 l' c$ `/ r  v% Y
        LONG HandleCount;! _% [7 m6 o, \& E8 L% a
        PSINGLE_LIST_ENTRY SEntry;
" T/ a* s4 e; Y7 e    };
3 n$ B0 o8 T  {# W    POBJECT_TYPE Type;2 t3 h1 m3 q$ M7 u- {6 l* R6 f
    UCHAR NameInfoOffset;
+ Y) E: ~9 ~4 h    UCHAR HandleInfoOffset;
. y& @. ^3 ?6 K( p& P    UCHAR QuotaInfoOffset;' G8 Y6 E7 H/ v4 o$ o
    UCHAR Flags;, d+ A7 [" \3 Z2 W7 Z- v
    union
0 P) I9 T9 f+ I( O    {( X5 f$ {( U' S' U4 e0 F: s
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
% P: ~0 ^, N2 x) ^        PVOID QuotaBlockCharged;
& c! F& ~5 U; I: W    };/ `# H$ Q$ M: Q$ E- j$ X( u! L, C
8 {3 a0 b; D' `1 I9 F6 h/ r, F: Q
    PSECURITY_DESCRIPTOR SecurityDescriptor;
- M) L% N" T- Q" R7 u5 v5 R    QUAD Body;6 {, G& n+ {/ j! _6 v0 a- J: K
} OBJECT_HEADER, * POBJECT_HEADER;) }+ {) [  l( L# [
9 H8 q  w5 @: E- x4 W
#define NUMBER_HASH_BUCKETS 37
5 ?5 x6 p+ \  g' U# k& S/ P, S$ g. A; k& o) O$ i
typedef struct _OBJECT_DIRECTORY& J3 v: f* q% a) b3 u8 [5 ~
{
* m  A# j8 m: P9 z$ }  E! e0 N    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];5 j) J4 q4 M9 b, j  |" |
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
3 O6 U, q8 _; {1 D, L- @/ N8 I. c    BOOLEAN LookupFound;' g! f7 [; e! F) n2 t5 J
    USHORT SymbolicLinkUsageCount;
% k' {/ @( F7 v* j6 \    struct _DEVICE_MAP* DeviceMap;
( Q8 w# E. x5 [) P} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
! e' ?+ l5 i" @8 G/ x9 J6 Y) C! w+ G* a! \( R
typedef struct _OBJECT_HEADER_NAME_INFO/ g! b# k7 \; b+ C( o0 E" Y
{
! ?) X) K6 I' i- R) k0 _, `    POBJECT_DIRECTORY Directory;. ^7 O9 I: f6 D: r# r' h* b
    UNICODE_STRING Name;
' x$ ^% r6 y; G# o    ULONG Reserved;# `  [; U7 t# a% b: y
#if DBG% u- ]. F6 E. L
    ULONG Reserved2 ;% x: r( m& H4 P  B& y% h
    LONG DbgDereferenceCount ;
0 s: i* C; q: @2 l* r#endif6 b. W, M: K: [- \4 K
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
( T% Z( }) x( ^/ t# a+ P2 |
) N. U) y( s! ]; p% \; W#define OBJECT_TO_OBJECT_HEADER( o ) \1 N0 Q! V5 I% l& ?
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
1 ?- q# D% e" v0 t. w' Y* A& Y
- N: y$ R/ n& i% }5 j1 c# R9 P#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
8 p+ ?: ?6 J; @$ L* S4 ?    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
2 q1 a# d9 s( P0 R/ p8 T7 V. @4 S" K3 a1 d. b9 z% Z
typedef struct _DEVICE_EXTENSION
( w" X+ b/ d1 n; F( r6 ~" w3 \{
. X7 v% L. w' o) c! B    PDEVICE_OBJECT DeviceObject;" H2 _5 R5 @' O+ R% ?
    PDEVICE_OBJECT TargetDevice;
5 o, Z& \  j* k! f0 F, W9 m    PFILE_OBJECT pFilterFileObject;; P1 H& M: j4 h- I
    ULONG DeviceExtensionFlags;
  t; q2 D: W) [' _) I" N- M/ F    LONG IrpsInProgress;
: B% V! v! [, C% _) f    KSPIN_LOCK SpinLock;% U) g7 q* r/ W7 [4 w
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
* m! c. W# Q; j( K, }9 @4 w+ L9 {& N8 a+ m/ s
: e0 |+ C+ D1 u, ]9 ]  y$ L: s$ Z
VOID
! M8 ?/ t! j# x( i5 E1 qKeyDriverUnload( PDRIVER_OBJECT KeyDriver );; B+ i6 t# u$ n" T3 {
4 L' C) }: w2 L: s, f
BOOLEAN7 R( S% e  ~1 t6 n
CancelKeyboardIrp( IN PIRP Irp );4 R  {" E" r- |

/ c* Q- z3 ~9 [$ H. m# Zextern POBJECT_TYPE* IoDriverObjectType;
, O- F5 s, x( Z. f6 z6 n2 h5 a, ~" l
, g2 o5 i& Z2 d  B* @- GNTSYSAPI- X+ S2 ^' ?/ Z2 B$ s8 _* U* e5 i
NTSTATUS  Z  l- }1 s9 v. D4 l
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,. @% G/ G- c( \/ Q. G0 T, G
                               IN ULONG Attributes,7 v. z) C( n; f
                               IN PACCESS_STATE AccessState OPTIONAL,# P8 g' N1 ]$ W
                               IN ACCESS_MASK DesiredAccess OPTIONAL,
4 G! y& O4 O9 {                               IN POBJECT_TYPE ObjectType,, k' f8 d) L! w+ g+ p& c
                               IN KPROCESSOR_MODE AccessMode,
* P' B' x3 N' k% z' X0 G! M% A1 ?9 r                               IN OUT PVOID ParseContext OPTIONAL,' C: z% u8 t9 W( l6 w8 P
                               OUT PVOID* Object );
9 x9 @: s. E+ O: v4 u* D8 ?& p- {6 a/ v/ i) l) ~/ h5 o2 G
NTSTATUS
' n  D; @2 W( s: U& k+ G* }GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
6 N& }, E6 ?2 T. g2 }
9 b) D  T5 `! f: R+ ~) w( M* jBOOLEAN " H2 V- I+ h: I3 n
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
6 W( O1 T; \3 u* H, M9 x+ _
; g/ S4 b1 p# r& U( ~; yVOID + Q) x( S" f* A2 i, i( T; r
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
; U, M0 Z5 F4 B. j( Z; |
* O* E: w$ x+ V* U, R) i4 U0 Q0 _NTSTATUS & e( l4 `7 l8 |; {
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,6 F; z; O4 k! @  I4 e; {5 ^1 L
                                  IN PDRIVER_OBJECT  DriverObject );
( K8 P" |2 c7 m1 y/ \% B$ I# V3 q3 [
+ V2 U$ P% ?# Z/ `NTSTATUS 5 x& e7 I( _! w1 }( W* o5 c6 g/ z
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
6 R( ?- Q/ z5 C, y4 v                                  IN PDRIVER_OBJECT  DriverObject,. O& ^- e9 W4 [& q% e8 k( x
                                  OUT PDRIVER_OBJECT* FilterDriverObject );9 \+ O, E5 }- e, l0 n* |% f4 l

5 E6 e' O6 O2 U! W- B: ZNTSTATUS
8 o2 [- r4 B; o' r0 o: mKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,: _5 o7 h  z) z3 C) E4 {  h- A
                            IN PIRP Irp,2 m5 Z/ {/ N* G& l" q. H
                            IN PVOID Context );2 \/ ~# q$ P! d" {4 T! O2 k" U7 q  n
NTSTATUS
* `6 Y6 j9 N* v" k' ]) L- TKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );# _  e$ a, d0 v$ y& Z& a) v2 c
: [$ f2 R! y. h) G8 {. v% Z
WCHAR szUsbDeviceName[MAXLEN];6 F. ?( R" \! n  `- Y! p6 e
. }; G7 N' D% B9 e+ V
#endif
/ o6 B% u2 J, [- l! G# [0 J7 g8 Q6 P+ v  K+ i& y% u

3 \3 m. b) s2 n# [1 `# o7 A& m8 B
& ^, H5 o& l) q- T# h5 f! |4 N9 A
$ w" o4 q. i  o8 [3 D5 q
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。/ B, u4 [, c7 S" R) L1 O5 {8 S
WSS 主页:[url]http://www.whitecell.org/[/url]
1 S  I0 y" V2 |( z( T6 a& WWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-4 15:05 , Processed in 0.451081 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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