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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister2 g- k, a( c, Q, D/ |5 F
Email:   [email]sinister@whitecell.org[/email]
+ {) t) z# v. n' O6 I6 W6 yHomepage:[url]http://www.whitecell.org[/url]
2 ?( {' h6 Y. m" DDate:    2007-02-263 o2 ~. @$ r7 N- _# I& ?, f) l

' E! `: h  }2 m& u9 k, Y8 g* K* j' x8 i7 l3 }
/******************************************************************** J( r6 l: S: m7 [9 q5 m$ d

* u% A+ D7 S: _这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx- t' e2 _! O( A3 D9 C& d& Z3 p/ N
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
4 }2 F7 k. D/ O& L7 K/ ^功能要求如下:
4 t3 g8 L  r+ f
& n/ E. B8 `' ~, s9 C1、强制锁定键盘/鼠标。
9 c+ r/ g% U7 a4 j+ p$ v1 v2、可动态加/解锁6 {( p; O/ Q& a8 c
3、兼容所有 NT 系列的操作系统。2 q: s% p& K) z9 m2 R/ c! ^! Q

) [9 _( |- _! Q9 y' C7 x就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实$ E' C/ g' ^0 ?- f" y( c( c; |
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
2 ?' D* X2 |6 V/ _0 A' ^! C; v何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在. y# |0 K3 W# J3 t# e* @* e8 ~( o6 I* `( p
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是( ?* E# }9 U2 n- i
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
$ v, ^( K+ F  @! O0 S0 p! p) s就来看一下我想到的几种实现方法:
+ N$ t5 f5 g1 k: \
, ?: C& X& i, F# H& y& V& p5 R1、全局键盘/鼠标钩子% F; k- [) @3 j# q8 A
2、BlockInput() API
1 S5 ]# J, A+ I2 }; c& ?3、使用 setupapi 进行控制
9 G& q5 {) W& A" E! J1 b0 q8 l4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL* J) b/ Y, X# ]3 T
5、拦截 win23k!RawInputThread() 函数
  o: J) u2 q! D, X0 P6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动% N; p5 g, ?  b; |
7、拦截 kdbclass 驱动的 driver dispatch routine: z% S2 x  Z8 z" A3 _6 v( C
8、实现一个 PS/2 与 USB 键盘过滤驱动
/ O7 y1 \: C0 b3 k, W; n$ f
+ q7 P+ [5 T7 M" i0 C/ y7 V! N; m3 A& D
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
- U6 l7 L5 h! _# d" P4 G之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方1 j# h/ f* ?; S2 S, g9 a1 d
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在) `' D( r0 d9 O2 Y) P- X
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因% O1 U$ e- T& x& d2 s
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性# r" L) c( s( C) y+ W2 {1 d- X. |
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
4 |/ E- V5 b' n3 z载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
& m5 r  t3 H$ Q( x* h的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
& u7 G+ Y+ a, ?也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如' w. M; ^  \3 e& X
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
( }) l) ]1 v7 A1 ^& m+ q障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
( a# U" x4 Z( ^+ M+ mIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 ! V' Q, g1 @; ]) Q6 ~' F8 O$ s
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
& S  e* Z3 W8 R. p! P4 {1 s4 j# _: w盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
9 b( `- g' V2 b! n8 e, W. t' F- ?案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
# ?7 N) L, f" }- f
4 }3 r4 A% Q1 n# j: ~; j% n* N
& d# S  w1 j; g, L2 k我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
: P5 }* F2 |$ ?# J  h+ p滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
# D9 Y5 ^2 c! o' s7 t1 Z- p- u行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是6 R% q& t2 h7 ]; Q3 w# f1 O0 M, c
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
1 q0 W  Q  O% p; M来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从8 u4 P4 A6 b* o6 F
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB+ _2 t) N" [  Q  w% u) \8 q
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用( s5 O: X! w. [, C8 i; q+ U
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
  V, G# x; @% l) Y  O: v我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
- T& L5 ?9 v, G2 k: a4 ~# n7 q就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
8 Z4 l- r6 Q& \而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
+ |- t/ ^! x' I" r2 p用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
' ?5 r" O& y0 }5 U4 \# m过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
: j. D8 b7 R* D屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
6 \  V; Q# |  [4 ~过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
0 M8 ~8 \! f8 N. U2 g" p1 d上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid " [/ \8 H0 s. P& ]! I
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
$ V/ V/ t3 R6 B0 I$ e7 b' n! |味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
1 t" u" ]  I: Z经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
5 G* \3 P, @* N7 `/ s' z$ K来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利0 y7 P5 t; f3 ?  a. J( l- H
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo1 [6 W* I) d4 s
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
* p+ u+ K" W0 g" d2 d$ j敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
* Q. B6 E* q6 A4 `根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程" ]( S: ?6 `. {+ [( G
见下面代码。, V. z4 j+ Y- E- J% W! F, q) H; E5 U

( C. N* ~* p3 X这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程/ |) t* s$ r/ U
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
4 b# L7 b& _2 B+ o盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
8 l5 E, N0 A7 a3 k  j上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
& u1 c0 j, l/ R: i5 r4 [完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
& a( e& U8 Z2 u0 L继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个' i/ X2 k/ F5 i
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
" [6 ]( G, l3 z9 z% ~# L键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。0 L5 t; |* u! Q8 M

! d' F: e. M1 ^; K4 E/ {2 O" s+ Z- X; [0 J
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
/ E! F9 W6 _. X+ V7 m! m的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是' l2 O* ]  x6 B, U+ O. \
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣  i) ]1 p, \) {" p, q4 o
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
( P6 ~7 [. h6 M2 T9 c, w们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我2 [% `7 N0 M& Y
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension' q% T4 S9 K. _0 _2 ~2 l9 v5 i
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
$ \0 [( C" J0 |% R1 N1 o* e如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager" ^/ t# b( ?% w' }
进行操作了。这个问题有待大家来完善了。) J/ a% a! x' Q7 N0 ]
8 G5 @9 ^) M2 d) h( E
) t( J% ^. P. \; j1 V* S; y! d5 }. I
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出" f8 s- U$ A! f- G7 X
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的! G3 K1 b$ O' @* Q% T5 |, E/ m5 }
分析做个记录而已。我更愿意把它看做是一段注释。
- N& p" P" y2 y: ?- ?) H
$ |& @# e2 `" P8 ]最后在此代码中要
0 k# |# Y) Q5 n  ]" y( i( G+ Z$ ~. a5 e; K- f
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。* }3 A& ^  [5 O8 Q& R0 l
9 w% A. G( P& U% n0 u
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
, h( ^9 n9 _) g
7 h" D8 \! S5 Z; ?/ o感谢:齐佳佳,过节请我吃好吃的。
# J2 h& D. Z5 Y, S6 n: `1 ]  z
' [7 l7 ^+ C$ p  R& \
) u- H2 u" V3 }8 R! C7 i' D8 k******************************************************************/
7 I: d- g/ t6 Y1 p# S9 E- g3 b; S2 Y4 _8 Y4 }

4 }$ w& Z/ Y" t5 Z8 z. e$ ^/*****************************************************************2 @5 `2 x8 A  x. |3 c
文件名        : WssLockKey.c: p. d1 l& k3 y8 U  U" l
描述          : 键盘过滤驱动
7 K& d: S8 a+ ]+ D1 @2 V+ d- H 作者          : sinister
( Y5 m% N. T6 l! O7 k. t, y 最后修改日期  : 2007-02-262 y! t- y  ?* K) `; @
*****************************************************************/
& m% B; s. h6 v( x1 ^. Z) w, k
- ?7 s& x! W+ p- t5 _1 J; \8 e
: D, U6 l& Q% I9 L! i* m6 }#include "WssLockKey.h"* v8 P0 O/ M8 a# h
' v4 |+ B9 s0 M6 M- H/ z  W
NTSTATUS
" [! ^" \; o! D; S4 |DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,4 ~5 S. h4 t$ o+ b* P- Y, t! N
             IN PUNICODE_STRING RegistryPath )
2 g. Y! k; [4 O+ U) j! l{
- R3 H' _& ^9 n2 U  UNICODE_STRING KeyDeviceName;
' @1 P1 T+ a, g9 J: e  PDRIVER_OBJECT KeyDriver;
' d& f5 f; Q% Y% h2 d" W  PDEVICE_OBJECT UsbDeviceObject;7 p" `0 Q& H& `/ U! i0 Z0 Z; E( v5 L
  NTSTATUS ntStatus; / S* n7 v8 F& {, T
  ULONG i;
( {6 S4 K0 H. P3 m. g6 ]# Z; |, i  ?$ j5 F4 h) e
  //! [( k/ A. f- P. F- A9 }* b( U7 t
  // 保存设备名,调试使用
/ U! r3 B2 @( C2 E( }  //
6 S1 R& m0 o- P2 ]1 o8 A, U  WCHAR szDeviceName[MAXLEN + MAXLEN] =" \, S/ U/ |: O) ~7 H0 H
  {, A+ i9 J( B9 A, V( c) ^
    0. Y0 I; o5 ]5 Y+ O/ w1 X. G4 H7 H
  };. ?* W' D- I( S6 p2 p/ ~( f4 c
( g. i) U% J; w' d
  KeyDriverObject->DriverUnload = KeyDriverUnload;
2 X$ s1 e3 H3 t2 S4 _5 n, j' a
# M3 Z- ]; X0 }! d) L. _  //
  U% T  {/ y; E2 R! u" g' r' m* ^5 S  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘7 A8 s& m" D$ y6 ?1 `  e. ~/ I' O
  //' c2 j# V  R! ?# H
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法) \" p; Y4 g- D6 x0 U
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其  `+ v" ?& \* Y* q( p9 X
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
+ k* j( p3 s$ i4 _9 B4 r1 u* j  // USB 键盘设备来进行挂接
0 q5 ]# x5 X' E/ U; ~( ~- h3 o  //
  l4 e0 h4 K" T0 L$ B& Z  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
! o  n* S8 H. e8 I3 V+ }  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )5 h5 q6 g( U$ q/ w
  {# H, S' G) D5 a. {. M! d
    //
. d# T) @* R' K2 `  M    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名- o' Z& q3 D+ S) f( E
    // 所以这里打印为空2 H4 K3 _2 k# F2 Q5 F* \
    //
# Z- r0 c  n( j& K( d8 c    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
3 `$ h4 C+ A* i4 f    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
: c5 G/ Q  Y& k$ c5 F# A) B& H$ k
    //
, `7 i" P) X) q3 L8 D    // 挂接 USB 键盘设备
2 j8 F% I% h5 Y; ~- H' e  F& G    //
% }& i8 A$ q! N. o- F( J% W3 k- z    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
; |; z1 n, ?4 a; p" @    if ( !NT_SUCCESS( ntStatus ) )
9 n6 T2 z6 \  ?& a" k- q4 H    {
& D3 O# D9 p, r3 g& s5 q- G% c      DbgPrint( "Attach USB Keyboard Device to failed!\n" );3 a" n4 R: d9 ?
      return STATUS_INSUFFICIENT_RESOURCES;( E, i' G( @! [  h7 F
    }1 U) _0 z5 b& K
  }
4 i' i& H. f% G  else: J% l( r- E- w6 I' X
  {4 j: r4 ?9 P3 p% ]1 {$ a& P
    //
9 `; ]" o0 y* ]: @" b( y    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
, {; [' u3 n' ~! Z8 u- p    // ( H6 h$ i3 J. ]
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); ) ^; L2 K, V3 z4 ]1 x
4 h9 C' C3 b: [6 f4 ~2 p8 |7 H# l
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
  o$ u" q" f7 j+ G2 l8 l                                        KeyDriverObject,; i# V6 A3 @" {0 |/ j
                                        &KeyDriver );$ }7 N& [- U3 u1 S1 z
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )) @% r( ]6 ?' Y+ f
    {& i# z/ |  y% T
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );7 i9 c& y+ u* j
      return STATUS_INSUFFICIENT_RESOURCES;$ {5 K6 V7 }; n/ l+ J" n  m
    }' y/ |4 H7 p: o# r
  }
* g: O$ D6 |; j
) l4 u( K7 O8 y6 j  //) Y1 y/ q; a6 N/ n# ^
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止8 l: r  E: i% y# s7 ^: J( @
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
$ s. w4 u: J8 }3 A& u4 u# W  //& x* m0 E. J; X7 m
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 5 g/ _9 f" ?/ Y) b7 x+ [) g
* }+ e7 H8 _" K- B
  return STATUS_SUCCESS;8 b* U4 y- u5 q
}
  g; J% r2 C+ L
  |, k# h% s! r. j* [6 A, O/ g/////////////////////////////////////////////////////////////////
% u( j7 g2 D( o: c4 o- x// 函数类型 : 系统函数
  e' l: j0 ^! z% @3 x// 函数模块 : 键盘过滤模块
( n) U2 S" x) E* l- a- q////////////////////////////////////////////////////////////////
% p: f6 {( B; w9 t. z+ ^// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,, ~+ ?, y% z3 E$ O4 j/ ]* X+ C
//        卸载键盘过滤驱动7 e% N4 l+ E: k3 D
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上+ U' N+ A& e2 j( L- h- E
//        则需要等待用户按键,以后有待完善
# X) Y8 ^8 R: a' x4 _/////////////////////////////////////////////////////////////////
8 w( |; O, J7 \/ U4 H( D4 [3 O// 作者 : sinister* N9 ?2 ?- Z+ w0 q5 I5 ~
// 发布版本 : 1.00.00
- }9 n7 w" F! [5 a. h// 发布日期 : 2005.12.27. Q' ?" c) T! w3 U' {
/////////////////////////////////////////////////////////////////
8 Z2 [8 e3 |" b// 重   大   修   改   历   史
7 u7 b6 J% Q: G$ w+ V4 ~9 _////////////////////////////////////////////////////////////////
& l+ p& z6 F# _; p) X6 t5 v, @// 修改者 :  F( Q/ i% O2 b5 C$ _1 L, D6 H
// 修改日期 :, p: X! e$ |  L9 N9 E9 h. ~; T
// 修改内容 :
( G3 a. o3 A/ _0 z, g; ?0 n0 U: v. a/////////////////////////////////////////////////////////////////1 Y) |. g- `& D' c; p3 v  |* f

! d. N: Y1 o8 ?9 n( \3 pVOID
: b/ P5 d  U5 u+ j& a0 I. gKeyDriverUnload( PDRIVER_OBJECT KeyDriver )  ~, g& T; n2 Q! u7 x
{
( _8 F; G" S9 \) w  PDEVICE_OBJECT KeyFilterDevice ;      
0 u  t8 C9 `1 V  PDEVICE_OBJECT KeyDevice ;# S+ H( p0 T  i3 h
  PDEVICE_EXTENSION KeyExtension; . ?2 k3 p/ H8 {# j6 l6 o
  PIRP Irp;. N& T; `' ~1 l8 p
  NTSTATUS ntStatus;7 E, h6 T" B) b; v0 g# V/ R
$ I  D8 s7 j$ V! ~# \
  KeyFilterDevice = KeyDriver->DeviceObject;
5 c) R) T( d# P  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
4 u+ C3 V) V! H% C2 K  KeyDevice = KeyExtension->TargetDevice;
1 X- Z* x) T8 h* I0 N4 R$ k! d4 H/ {! D% ]# e
  IoDetachDevice( KeyDevice );
' v+ r3 Q5 U9 S1 m: q0 H5 V& Y6 l: f/ ~* \
  //% M! C( o  l  N% d# U
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP( G2 y1 y1 A8 W) e) a1 i4 `8 K' O
  //2 q$ z8 B. z1 G3 Z  v* n: f
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )6 Z8 `9 L) m2 _0 ^4 p+ ~- z2 P
  {
: A( W% `& u( m% N    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
; D" f  H$ T) @5 B    {9 \  t( w; v; B1 x- S
      //
4 B- |& L# S8 @1 |) y3 n8 G      // 成功则直接退出删除键盘过滤设备" ~, }, c* k4 H
      //
2 J) j7 P2 z" J" H- n  Z! g      DbgPrint( "CancelKeyboardIrp() is ok\n" );
$ D7 v, t" ^: s" H. f; z- u! S      goto __End;' J% T+ _0 J0 r, j$ g6 `
    }0 c0 {* K1 Q* Z& R, ]2 g1 n! S; M
  }
3 a% r4 j( z- I5 K3 D. D1 W0 _% I  S
  //( L% i: V$ C! M0 V# l9 g# X2 O- }
  // 如果取消失败,则一直等待按键
# _3 G" {5 b. Y  //- @8 s4 U; t% L$ \9 }
  while ( KeyExtension->IrpsInProgress > 0 )
8 H' E4 }, O; s  m  {
; F6 Y6 k7 ]. N    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );# F, ^4 O2 R5 X9 M( t( m
  }$ {! W+ N# c6 ?" d
4 w3 W6 M& j: ]- D9 e
  __End:5 u) L: v' ]% k- u7 V- j" ]
  IoDeleteDevice( KeyFilterDevice ); : {) Z6 u# F! Z3 i1 K7 k

$ s/ k5 A" }7 x7 V& U) U. w  return ;
1 r, S( R: _* O9 }; e} ! S; r! ?- ~# I; ^) M/ W4 F

7 u1 `% l  ~5 o/////////////////////////////////////////////////////////////////
; j3 Y# E. F* V5 b5 |// 函数类型 : 自定义工具函数
* o( u7 T# N6 g' s, w// 函数模块 : 键盘过滤模块
  s# l! b6 b1 i: g' L/////////////////////////////////////////////////////////////////# i3 z+ L, i% V3 ~8 D0 [
// 功能 : 取消 IRP 操作3 c& ?9 K; G- w9 m
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
" K  o  G8 ^7 r1 Z; d2 N//        使用此方法来取消 IRP! s$ F# i( p& Q2 g2 h8 V
/////////////////////////////////////////////////////////////////$ Z& [: X( L( `: B% M# t, i% a
// 作者 : sinister( p1 f5 b$ Y% A. n) y# n
// 发布版本 : 1.00.008 U5 H& j- B( H, ~% X3 O1 f
// 发布日期 : 2007.02.20% E1 K; h3 p' w+ D* O% U( r9 O
/////////////////////////////////////////////////////////////////) j: k1 {1 c3 k# g- ?$ p$ g8 U4 c
// 重   大   修   改   历   史. x+ ~& \. `; l+ H& h3 q, L% B( `' w
/////////////////////////////////////////////////////////////////
4 [4 k1 |/ u- B8 Y5 [// 修改者 :
4 E6 O) ~/ t) }$ j// 修改日期 : 6 J" J8 c# ?. `/ e+ }
// 修改内容 :   p$ t' z9 n" C9 @/ R* f2 O( c
/////////////////////////////////////////////////////////////////8 D  Z5 ~/ g" C$ t2 J  Y6 }
' O/ y( D$ w, }8 C' a
BOOLEAN
: r' O$ O7 H# S2 w8 d. N. _/ W* oCancelKeyboardIrp( IN PIRP Irp )
& z& D/ i: y6 X2 K2 _* b{% s5 e" e7 {( n! o$ l
  if ( Irp == NULL )5 D" e" L; m! s; f$ H7 c# c
  {
* @9 B5 \* Q. F) ?* ^4 G' T& _8 Z6 y    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
; g) Q& G8 U+ }1 ?$ A    return FALSE;# U, L9 B4 J" v! x6 G6 l) P9 ~2 [8 w
  }8 y0 o- c" M3 v0 q8 w3 {
) A+ K2 Y1 j: }: k& S

5 _5 m* e0 Z* d9 o0 G- i+ B* `, r  //
/ ]: O: L2 {) @/ K# z, f  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
) c' X/ T! z& O3 M  ?  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。1 L6 {6 r+ c8 ^; q: r( j# K
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占' B0 A2 i- H9 c( U
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
4 T& N; r' B6 v- B# S: r" E  //: c; I' l1 ]+ l$ U

4 ?# b4 ~" M, ~$ n: v9 D  //
# _, }# o: m* U# n) B  // 如果正在取消或没有取消例程则直接返回 FALSE5 Q% \  Q8 h" S& e
  //
: J8 f3 c0 b* \  if ( Irp->Cancel || Irp->CancelRoutine == NULL )/ e. i& l7 K3 ?& S
  {
( i1 k! X1 G( |; R1 s) Y1 C+ E    DbgPrint( "Can't Cancel the irp\n" );
+ J7 j0 _. y2 [    return FALSE;4 X1 f- ^0 I* V  Y
  }
- w7 _" \1 Q4 Y# U3 W( s1 d$ H5 A3 {# J. z2 w/ k
  if ( FALSE == IoCancelIrp( Irp ) )
" A2 O* t$ S# t+ C6 W  {
4 `$ b  ]. }& A2 G6 h1 A* a    DbgPrint( "IoCancelIrp() to failed\n" );
$ e1 Z3 Q" N1 I/ M; |3 Y7 m    return FALSE;) c! H' ?- {7 x% I. \
  }
, L, W. z% K3 _# ~. M! [  G& x+ a* z/ s! [  ~# D
  //
" `& G" M$ F6 B% j" q& ~5 f  // 取消后重设此例程为空
, ?7 S: {1 g* U8 w3 i4 z+ G  //
8 n* |4 E# C4 H: o9 J0 i  j  IoSetCancelRoutine( Irp, NULL );
: J, @% s! @' q$ O! n& Q
- b. I2 P( W; _  return TRUE;
. u, E4 N: S* ]# ]0 ?}4 s* p1 `% Y/ z1 E# {8 q6 q

4 A2 l$ z4 M$ X+ f/////////////////////////////////////////////////////////////////. P# A. e  g; B9 U$ X0 f3 i
// 函数类型 : 自定义工具函数! ~6 t& H; I" U
// 函数模块 : 设备栈信息模块
. i9 F; j7 G( ^" B; I, V7 {. z/////////////////////////////////////////////////////////////////
* m7 \! k# x4 R) ], X// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
- i* s! ^' `6 z$ n. y  j8 g//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
7 @9 J$ N5 q( ?5 _( K# S// 注意 :
* `" v2 H' M& ^0 J. k* @9 s& ^. n/////////////////////////////////////////////////////////////////& a4 A" H( F. L/ J
// 作者 : sinister
$ e! [  d) K, {5 C% A8 p8 D// 发布版本 : 1.00.00
8 X: Y6 M* C- E2 r! S1 E" |// 发布日期 : 2005.06.02
3 n0 V2 n/ q$ f- w8 Q0 ]  b/////////////////////////////////////////////////////////////////
( a9 D5 u/ Y- p9 h" [/ u// 重   大   修   改   历   史3 o0 K; y' z0 I9 c. {
/////////////////////////////////////////////////////////////////
' t3 l/ |/ T  \( ?2 F6 Q) M// 修改者 : sinister, L# F$ [# y9 u/ i/ ?
// 修改日期 : 2007.2.12) f: e1 x) e9 i+ j. a" E5 W, C
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改: B5 I1 ?* Z1 I$ _2 d
/////////////////////////////////////////////////////////////////
: ^) b! w: b& k9 x+ N
. s8 ]" [3 n9 d3 o3 F6 c& h( [& sBOOLEAN
# P" j" j9 @4 r) j3 }% P6 P1 Y( }! iGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )$ l) M7 C0 k- [, b
{  Y4 C7 h9 u0 q0 e2 Q( M
  PDEVICE_OBJECT DeviceObject;
, E  g$ K5 z3 H' m' U  BOOLEAN bFound = FALSE;5 k5 ~2 w1 F+ \9 }8 s' g6 Q! r" R
! T( `4 S9 F6 z9 N
  if ( DevObj == NULL )
9 M% K6 X: E6 S" H0 S+ a  {
& ]: _5 B) P* T0 O. \    DbgPrint( "DevObj is NULL!\n" );
0 {4 _2 T7 G3 [+ W  I! [) ?1 t    return FALSE;
- w. b' t! J$ R) B: |% Y3 ^  }  c1 b# j" r3 j9 E

- E, Q) e% `0 L0 Y, ]. }  DeviceObject = DevObj->AttachedDevice;
& `' ^0 K6 d  ^3 y$ F- V6 m4 m4 u% C
  while ( DeviceObject )- ?1 p2 Y/ p0 P) R& I. Y$ _( c
  {1 Y8 b: ~# l1 h3 x( t& i
    //  D# k7 Y0 c* X; g( G
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
0 Q5 c0 ?$ t% c' y4 L    // 有一次足够了。这算是经验之谈
: F* M% y+ S; l; ~! Y- l: E    //
* W5 Z/ I7 [' X& N" W+ A( e2 K    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )9 S2 l2 N& O5 I* k: ?$ i
    {
9 ?. ^( V/ i0 D; L, b      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",' ~! h6 m/ n6 b4 Z; j
                DeviceObject->DriverObject->DriverName.Buffer,
, g5 \1 X  T* w" S1 j  u                DeviceObject->DriverObject,+ O8 R$ Y$ p, z; H# L  t
                DeviceObject );
3 Y) a0 o, _. J- R& `3 C% W. U
$ k2 h; x- b' b6 ^  Z9 V9 ^      //
# s, x- h  e* @$ y      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
* Q" ], J# ^- `4 M1 k; s0 b& Z" H% \! g      //1 d0 C; m. \$ }1 {* h. _
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
/ k6 e9 y) H) E                      KDBDEVICENAME,
6 I6 e+ N. r6 E6 h2 J                      wcslen( KDBDEVICENAME ) ) == 0 )" M2 y+ o0 R0 K. P8 F7 Y, Y
      {( A# w* N* K6 T- k. D! C; d
        DbgPrint( "Found kbdhid Device\n" );
3 o8 {0 ?/ }6 S' l" n        bFound = TRUE;
+ j' i8 H6 y" |% }        break;% E& J- S. A; g0 o  K( T0 w" d0 L
      }
- a7 o! {# f' I& }$ n. B( X    }1 E, ^6 R; x; g* |8 t/ b% k7 {: U
4 t% o8 D% R; {/ B0 a4 C& n
    DeviceObject = DeviceObject->AttachedDevice;
0 l3 J# z5 R& E9 g% g7 ]# G  }7 j/ }& p. {% d
/ M/ t7 O2 ~) V; O0 f" y
  return bFound;
7 s( }+ _" o  F: q. E/ `& |7 g}' d6 s0 q3 p' F; K$ d3 r  B2 }

6 A, y+ M$ R! F. w, Z# i% {/////////////////////////////////////////////////////////////////* r6 v/ c6 q/ B$ r
// 函数类型 : 自定义工具函数+ R: f8 Q, M% h$ Q# x. k
// 函数模块 : 设备栈信息模块
( I; X6 ^7 D3 h/////////////////////////////////////////////////////////////////
/ G4 M3 N  M+ h' q; }// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址4 ^2 p: y4 G+ v( m4 `; l
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改2 d' ~" @5 S5 K  ?, u- `
/////////////////////////////////////////////////////////////////1 l* C% F$ b) J* A: z& E
// 作者 : sinister2 G" t  U+ _8 u+ S! T* \  t" V
// 发布版本 : 1.00.00
, r4 s( M+ K5 u// 发布日期 : 2006.05.02$ a! J$ j* p+ w0 m9 f8 i8 k0 I3 B% `
/////////////////////////////////////////////////////////////////
" t. {0 c% z5 C6 p  E3 {// 重   大   修   改   历   史; r0 K8 r+ P/ ]( ^: C
/////////////////////////////////////////////////////////////////1 r6 I: A  [# o6 t* o; x
// 修改者 : sinister6 m, o1 I$ a% d/ V! L
// 修改日期 : 2007.2.12; o' _0 S. q5 i, r# L
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用3 v" b1 N! ?9 n; w* Z
/////////////////////////////////////////////////////////////////( U( \) i9 ^# C1 @9 \- ?8 m
: i/ |. U9 n6 o1 R9 C2 n4 l+ ^* Q
VOID
4 S/ |" T. j7 C) f) iGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )5 J8 t5 q& O( q, |( y
{$ N. a: r2 p+ b' O* ~
  POBJECT_HEADER ObjectHeader;
5 E4 C  c3 Q- t  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 5 ^* c0 g$ ~: g

4 a  G* Z& R' \* s0 x2 J( N  if ( DevObj == NULL )9 Q( i4 W  i) J( j7 T% A
  {  @- O6 q: H( k; N! S1 T4 e. r5 _
    DbgPrint( "DevObj is NULL!\n" );; p! z- P- W  k* v3 \
    return;
/ c& t1 g9 C2 E# L1 N/ `( B" }  }- K8 z  u4 W6 a$ b! h6 ^

2 X0 Y  B5 `' }; _4 E* i% f: Y' @' M1 V  //5 z# n4 K9 ?) d( N& J2 m1 b
  // 得到对象头
- e3 D% s' T. X; D0 Z& Q' ^2 \9 C& K, Y  //
5 i1 e7 E7 Q# ?2 X  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
) R; f; c( ^; `  w' B$ t3 o, k
; ?. o' g) c3 b: v$ m  if ( ObjectHeader )
$ R3 a$ Y0 r* T/ a  {
2 Q* A1 W  b% [    //6 d* i! \  _7 D
    // 查询设备名称并打印% c3 U5 Q' R) L, w# \4 i! B7 O
    //6 q7 f, t/ v- V9 [8 j, X
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );3 F- }  y; ^1 a
4 T8 q  ~1 e  j6 x% C- N4 D
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
4 B# P7 Y; g0 R4 L    {
% s/ K0 y& \7 L/ z7 T      DbgPrint( "Device Name:%S - Device Address:0x%x\n",) S( I' z( Y* Z4 b9 q9 S
                ObjectNameInfo->Name.Buffer,! \- B) F. c! [0 a
                DevObj );! U9 D# \$ ]# y& f4 n& y
3 r. S3 Y1 S! {: x
      //
3 A. M. S8 D" [3 f" Z      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示4 T$ ?; d7 I0 ]5 R& }2 l
      // 用,没有实际的功能用途6 y7 a6 O, n6 w' O
      //
! ?9 k) f- V! g2 a; U      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
: V9 ~7 v, H& }$ J
9 H( M' S+ ]: p      wcsncpy( szUsbDeviceName,
3 T6 ]+ O1 ]) w: j( v# y               ObjectNameInfo->Name.Buffer,
8 K* @8 Z5 \' t" ^5 z               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );! w& c" D1 R6 ~, `3 r
    }3 _. U% O! ~5 }" h% u
. I( k8 X: a9 @+ _; l$ V
    //& y5 q5 I+ d, q; p; k, \# B
    // 对于没有名称的设备,则打印 NULL
) I' i4 B0 i& X; d# F! N" X    //
- C2 N* N+ o! Z    else if ( DevObj->DriverObject )
+ G5 E# z% c6 T    {
( t6 S6 I7 E5 }      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
! E, n7 h" b, w# k3 e3 R- g                DevObj->DriverObject->DriverName.Buffer,0 x1 T3 O& ~4 W" \
                L"NULL",/ {9 `! {1 P) c9 v  @
                DevObj->DriverObject,9 e9 S5 O7 e! V) _: `% Q* M
                DevObj );
# o0 _$ c6 l6 u9 i. y- o    }9 V: q& ?  H, Q
  }
5 l) [+ ~+ _5 t3 r9 y# `6 ^8 N0 b}# m  [" T3 V" X; q
" V) T) t; t, I1 y+ c4 o" E$ j
/////////////////////////////////////////////////////////////////7 O5 n+ o, l& ~- Y. Z* W
// 函数类型 : 自定义工具函数9 N# x$ S0 A6 k: q- |/ b, W
// 函数模块 : 键盘过滤模块4 f9 W+ E. r9 Q% P+ s
/////////////////////////////////////////////////////////////////7 B% b5 u: [+ F4 i* F0 u7 T5 k
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
# c3 A! c2 X% o. }//        对象,过滤出 USB 键盘设备,将其设备对象返回
/ H) c* p& `  R' y// 注意 :
8 `& S  \* [0 F( c" d8 W# e6 v: d/////////////////////////////////////////////////////////////////( Z7 w0 \7 F5 ]* w! w. X9 [
// 作者 : sinister
  m0 q- ?% g3 j$ g// 发布版本 : 1.00.00
3 m# c0 J& A/ `! p" U2 N// 发布日期 : 2007.02.134 ~# S# J/ @: {1 r4 x. `/ o! N9 P4 h
/////////////////////////////////////////////////////////////////5 P, Q: x% j& E+ J* f
// 重   大   修   改   历   史9 t) l; c; U% {* i6 U, S% I
/////////////////////////////////////////////////////////////////
* [0 ^# r' e% ^" l9 V5 L// 修改者 : ( V$ o' L: ]9 R& t  r
// 修改日期 :
: h' |8 H; r* g8 U  j; j/ ~// 修改内容 :
& z; D- B6 H( ^7 K+ F/ @; ^/////////////////////////////////////////////////////////////////
- T2 ]" f/ _1 [1 }# x! D# b6 }0 ~0 t" w3 j; m  H, j7 b
NTSTATUS" F! D1 T+ C. X
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
! S" y' O! p0 U' U: n" g{
. M6 @6 u3 N+ ?+ L4 P0 y6 r. [7 K4 i  UNICODE_STRING DriverName;3 K% m. {  ?( m7 M+ l
  PDRIVER_OBJECT DriverObject = NULL;8 t4 L+ g1 y+ P2 ~) I" T* |( D
  PDEVICE_OBJECT DeviceObject = NULL;
2 O, C* N) Z$ I' U' F  r8 j$ [" Y! ?  BOOLEAN bFound = FALSE;
  I( ]4 \2 u3 f1 M3 n# f. d4 p0 K6 ?% @- t$ v; _7 H# n
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );8 j. m+ W. N. i& m# H2 w4 q

4 O: m6 ?1 @& X  M  ObReferenceObjectByName( &DriverName,9 ^0 ~; |8 x( R4 V  m: \
                           OBJ_CASE_INSENSITIVE,
! |; X2 l# m& l! {7 J8 q$ `                           NULL,; ~0 ]9 y3 t: y4 E) u9 B
                           0,
7 \& h0 q. D3 O9 u1 @                           ( POBJECT_TYPE ) IoDriverObjectType,  ~, z. ^+ x: L2 _. h
                           KernelMode,: T- ?& k/ B4 Q
                           NULL,
: O/ d7 O8 Z1 I- ]% S! ?                           &DriverObject );
; o5 G' t, H6 l4 I3 |% z) d6 I* C& N( w. h: u7 P+ B2 b
  if ( DriverObject == NULL )
  C9 Y& W2 {0 k( O) H9 m9 Z* `  {
- R5 Z$ @2 z- Y" _5 X    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );% F, X5 R/ ~. ~
    return STATUS_UNSUCCESSFUL;7 s/ X0 O* k& K; A6 ]7 z+ Y
  }# w0 V2 I& R( `; @
6 j  E8 k" k, ?4 f
  DeviceObject = DriverObject->DeviceObject;
" M5 y5 M4 K; [( G
0 K! n% u/ \7 C( w1 p0 t  while ( DeviceObject ); S4 V6 M: L' f
  {
( o( c9 ]# r) \, P* n    GetDeviceObjectInfo( DeviceObject );
* b/ |% Y. ^5 J! o# d$ z8 w
. V7 a3 B7 n5 Q& ^( t    if ( DeviceObject->AttachedDevice )
1 O/ p# k1 `8 E/ A# q; w    {
9 {' T* E, w8 B4 _# M8 B* i0 D      //
5 G- v0 I! u' E2 k) v      // 查找 USB 键盘设备4 S  {  F8 P9 |7 u* ?
      //
& V  d$ t7 A4 C) r! `- A      if ( GetAttachedDeviceInfo( DeviceObject ) )
6 u3 Q( r! P! v+ ?      {" m# t: \* i' C# {+ z
        bFound = TRUE;5 F% }  [) Z7 y% L, r$ i2 w' D
        goto __End;
4 c! q6 }( i( s& G$ c      }
) w" L! }0 Z1 O; {. o& b    }
) D* D" r( P! V: H1 j  Z
6 e4 Y# i% P1 V3 U    DeviceObject = DeviceObject->NextDevice;8 j# [& v5 X* A9 T
  }8 X2 Q" `9 G1 t# t" l) j
) {' I" ?% C% n, R$ O
  __End:. n- S' B5 @; Y2 I

7 h) N. f- P/ u/ S; K$ o  if ( bFound ): L5 n, K/ V8 O0 m4 N/ W! V9 I
  {
0 I: C( p$ S" n1 u    //( D! Y; S! T" Q
    // 找到则返回 USB 键盘设备对象
+ O! p- b5 J! y- m( Q% @( y) i- h; Y    //
& R6 H. i$ ?# C: ?* N+ u    *UsbDeviceObject = DeviceObject;7 ]8 I* K3 r9 j, F
  }$ k& Z6 Q! b& ~% @4 j
  else
" ~# ~/ ^# s4 Z% K  {
6 q  C7 p$ E7 t1 D7 ^# o    *UsbDeviceObject = NULL;
. y- A" O0 f3 _# F. J( r8 N+ y  }) K# `1 o4 D$ M2 n
' j1 D; M2 p. E. y* n0 Z
  return STATUS_SUCCESS;
6 @1 o% z) t; J# H4 c- z7 F' s8 N/ w}
! m! ?! b) T6 y) D
+ k; G, B  i1 E* @/ U# H# U# k% [/////////////////////////////////////////////////////////////////
" g8 {% f% q5 _0 O5 v; S/ V2 i$ l9 _// 函数类型 : 自定义工具函数
' u  i2 {/ L- i( ~// 函数模块 : 键盘过滤模块' E( u, A) Z2 h: V2 l# Y, U, p# ]* ]
////////////////////////////////////////////////////////////////6 C% q& z* }  Y. e4 b0 V
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关+ E; o8 O# u' O* \
//        信息,返回附加后的驱动对象
: t$ x3 _# B, S5 c( `// 注意 : 此函数仅挂接 USB 键盘设备
3 D0 _+ _* V- P8 c$ @! x- f/////////////////////////////////////////////////////////////////
) I) f4 y& L9 J3 }5 ^- M" L// 作者 : sinister
: k1 e; n7 Z3 ?// 发布版本 : 1.00.00! s5 E% |5 m$ C) U
// 发布日期 : 2005.12.27
4 n3 W' ~6 e, ^: ^+ L/////////////////////////////////////////////////////////////////
9 G5 o% o/ Q" P! g- h0 U// 重   大   修   改   历   史
+ c. h# ]2 M) l////////////////////////////////////////////////////////////////
$ ]* K7 e$ |3 |. Z8 E8 f; ?/ v% Q// 修改者 :
6 b. A# f! t6 Q# p// 修改日期 :
6 s- }+ U( B/ m// 修改内容 :7 q. s/ P' _$ q0 f* ~$ r+ E
/////////////////////////////////////////////////////////////////& `3 H* b. K! g  y$ f  `

5 j2 Y7 u( m% \. q8 M) ?NTSTATUS5 U; \6 e- p) j8 [5 E+ q, S( g. I
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
6 C7 N' a) \- D% t" [( z. b+ G, J                         IN PDRIVER_OBJECT  DriverObject )
$ c4 I4 Y8 @9 h% b% e  _" S{  M/ H2 d5 K* L' ~. a! _: h
  PDEVICE_OBJECT DeviceObject;
  {4 J5 ?% ]3 N9 P. N  PDEVICE_OBJECT TargetDevice;
0 Q9 Y; K4 b1 q% ~  PDEVICE_EXTENSION DevExt;5 Z* O; n$ q5 H
  NTSTATUS ntStatus;
& X& _  H5 G: @7 D+ `* k! S; h  L
. y3 U! I) t# C7 P  //0 {% e  r4 S8 m9 d
  // 创建过滤设备对象, y2 L! d# Q' N
  //* ]3 I" C6 e6 I+ b& o  n& I0 y. ?
  ntStatus = IoCreateDevice( DriverObject,
: ]& R, v# f/ ^4 m+ k# [, c7 F                             sizeof( DEVICE_EXTENSION ),: t" t6 h) c1 n4 [+ z
                             NULL,' S- q9 ^( U# w' ]% t
                             FILE_DEVICE_UNKNOWN,
7 `0 \/ G2 t# |& y# U                             0,* s6 s8 u6 r7 G7 X+ U, v" h( K1 X
                             FALSE,
0 T6 i( l% E1 f3 R                             &DeviceObject );
9 S' p$ ]' m0 \: U/ `8 [5 n
5 I, I$ X; x- m9 l! D  if ( !NT_SUCCESS( ntStatus ) )
) Z8 j* f5 c  C( p6 b( N6 y  {
$ X2 t' t3 O6 t; R! f    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
  B9 O4 l0 P3 k" C8 i% p" G    return ntStatus;
+ r* J% E/ ?; R  }
0 L) @; U* \' b; m. @+ M" |
: r8 ?+ Z, B7 B  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
1 D  F1 W/ H4 m- O- `/ h) E5 w: d% v* M! s* p5 C1 d4 o
  //
$ V2 Z  M7 `' [+ J( G+ H  // 初始化自旋锁
: B- K* S% s3 t" y  X  //; X: m7 r' I: p" S$ @7 @! y+ {
  KeInitializeSpinLock( &DevExt->SpinLock );
! K  W  ?' u8 g& ]& R" L3 R; x9 R' l3 W5 D* S: r
  //
! P3 ^8 A! ?$ ?. u, F  // 初始化 IRP 计数器6 V  e% B. j5 v$ |/ L9 U- _+ b# ~( y
  //
6 u& ~# U+ H2 [' n( ^  DevExt->IrpsInProgress = 0;- ?- ]# I9 c! Q1 X; y

$ N9 B" _* |* a; o9 j2 U* X6 p7 t; V9 C  a  //
& M3 A2 U' u! ?9 d7 F2 f- Q) t  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
- t9 D' V: B9 s6 v% @8 }  //
6 q( @3 L  v1 z% O5 Z% O
7 I3 H% R6 S/ ?: |  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); % t* k% `0 z( E& t4 L
  if ( !TargetDevice )
- W4 @7 [; M9 t$ L2 d. z$ K) i  {  E) C$ ^2 z% @; Z, c, ]
    IoDeleteDevice( DeviceObject ); ; l  w0 P$ R; |9 m
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );$ o7 }) V% z% k* y& Z
    return STATUS_INSUFFICIENT_RESOURCES;( @5 f8 R0 a/ {' k
  }
- K2 A7 C2 K' a6 w6 L# ]( V8 h5 g: `- w/ R5 s( c2 G+ N3 ?
  //
& u) M8 g& S) L$ B/ K6 W7 D  // 保存过滤设备信息( M8 z& V' t# ^' @
  //& A, y( ~+ J! }: U9 r7 U: `
  DevExt->DeviceObject = DeviceObject;
$ a2 K, K- [4 `2 F  DevExt->TargetDevice = TargetDevice;
- n2 l4 N+ b- g2 b! F6 }4 ^/ w5 A5 @, S! V& x" F0 H4 Q7 ?
  //% N7 `$ M' z& ~) B3 a- ~
  // 设置过滤设备相关信息与标志
! S3 _0 J  t6 o* V7 }8 Z0 q  //) d+ V! c% O3 |8 x7 C5 c
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );! R5 A7 g( D  o6 S/ y6 z
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;7 j) g7 t" v1 M1 g% \- N
. \! p4 J4 x* e1 f/ W# M9 _! p

+ U" y* u. I. `6 _3 U% }: J' `  return STATUS_SUCCESS;7 a& Q: i4 r; U$ v" ?  z, {0 B
}4 @$ L% ?9 L- {7 z7 c2 J% @1 N

2 R: {$ n9 D/ o0 o3 z7 S% |/////////////////////////////////////////////////////////////////
# f8 q2 m3 I3 b& [% v- l- w* r// 函数类型 : 自定义工具函数) g( K) C* ]& O8 ]6 E  }0 A; J6 w! @
// 函数模块 : 键盘过滤模块1 p' U8 z# V) w  A$ N
////////////////////////////////////////////////////////////////3 X& |( M0 o. U5 d  i
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
& l8 o  ]* E; t0 [: A//        信息,返回附加后的驱动对象
. @% T8 s$ V" r* z// 注意 : 此函数仅挂接 PS/2 键盘设备  O% k: I4 @  Y/ K. F
/////////////////////////////////////////////////////////////////
. g$ V. u1 R# u* @9 o// 作者 : sinister: ^8 `* w, z$ s0 f6 q$ G
// 发布版本 : 1.00.00: _# D, h+ q% [, W8 j0 p8 @8 o8 E, u
// 发布日期 : 2005.12.27
& }! Y9 s5 E/ N% b/////////////////////////////////////////////////////////////////
& |" l" l& t9 J5 J( d// 重   大   修   改   历   史1 T4 Z  Y6 U; E+ r
////////////////////////////////////////////////////////////////! R- E' s) S- p
// 修改者 :
; t! f+ G0 ?9 z// 修改日期 :
; q5 r% t: T/ y3 l; C& ?+ k// 修改内容 :/ B0 ~2 t3 H' f4 K
/////////////////////////////////////////////////////////////////. w# _. X0 t6 y. `* P7 }6 l0 M

) f% W; D8 ]( j  f# h! P" ]NTSTATUS! `3 r) s% ?  j; Y. v
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名# ~# X. T  l  f& X
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象0 f& ?* z0 ?/ S+ Q! q
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象$ y9 v: M2 t7 n" E( V) I
{
) \6 O, o3 [* o( F' j% [  PDEVICE_OBJECT DeviceObject;
4 I! p" P, }+ f) Y. y; U8 J- ]/ H/ `  PDEVICE_OBJECT FilterDeviceObject;: f: `7 p3 c8 V7 e  P6 ]1 @4 K! z
  PDEVICE_OBJECT TargetDevice; $ D% h5 R# y- q! }& i6 |  Z/ A
  PFILE_OBJECT FileObject;
: F: |2 X6 ~" N5 l/ f  PDEVICE_EXTENSION DevExt;* B7 ]! W. k6 _) X# o3 F8 R

1 ?; s2 l8 C, T6 p. }  NTSTATUS ntStatus;
& v0 [, S9 z; s$ w  e2 z. p& T+ _7 ?' O
  //; J/ j- ~& k, ?+ x4 Q9 s
  // 根据设备名称找到需要附加的设备对象
7 f! _! w7 Q; }1 m  //
' W  J2 A" `; n: X2 G$ X  ntStatus = IoGetDeviceObjectPointer( DeviceName,
! W: D4 O$ q; V" G                                       FILE_ALL_ACCESS,7 D3 b2 J2 ?+ _: L+ ~: I& H, I! }
                                       &FileObject,+ m$ y5 S& m, D/ M
                                       &DeviceObject ); . g; _3 u% Q6 G

# J9 w, Y! A, E7 c% Y3 g5 U  if ( !NT_SUCCESS( ntStatus ) )
, H+ L: B& s. @% a* m  {& T6 j8 f* R8 O* o' q
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );) @0 _3 B2 O/ H
    return ntStatus;
* V8 U) l' }" {* I- S  }
7 R, ?8 o7 J/ S5 }! ?' y1 ?7 ]& C  k$ z6 V. x6 g
  //
7 R) [) C4 {% o. Q" i  // 创建过滤设备对象- N, a9 l, t3 L4 `7 S
  //5 c& ^) h$ Z4 Y" v
  ntStatus = IoCreateDevice( DriverObject,0 R3 \/ H6 t. k- `8 l/ T
                             sizeof( DEVICE_EXTENSION ),/ s$ e) S4 t) d& _4 \4 s
                             NULL,
. J8 ~, s; c+ b" _$ J9 _8 |  R& i                             FILE_DEVICE_KEYBOARD,2 E7 `3 U8 F5 B4 r$ ]1 n
                             0,
0 f" J9 @8 b3 ?( G  I                             FALSE,/ I8 S/ H$ P5 k8 Q
                             &FilterDeviceObject );
& ]5 r* S& Q( E/ e) Q# U, N8 a& b/ l
- Z. V2 O) j' @4 W! H  if ( !NT_SUCCESS( ntStatus ) )3 r+ ]$ {% @! E3 o8 E* B
  {
2 L7 E5 O( a% t, p! i6 ~    ObDereferenceObject( FileObject ); 9 |0 M3 C" {3 n5 ?/ C6 B
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
7 h3 |# q$ F' ~1 \3 C# v    return ntStatus;& A2 L# D& E6 l$ H6 J* O
  } # v5 ^1 h# `# E- ?0 @9 z* x
2 S" l! D3 S, ~) N5 [& _: s
  //
2 B7 d+ V) r3 k6 [+ }  // 得到设备扩展结构,以便下面保存过滤设备信息
' d' W2 n! C! A2 A0 ]  //
, \5 B2 m' V' o, O  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
+ o  M+ B1 l: c" r8 G8 O( ]2 D! N2 \7 W

% Q+ `/ e3 K: h/ M, B% T  //- f% p) M" z7 \& F3 L4 f
  // 初始化自旋锁) k3 k! k7 N% ?# Z; ]6 N
  //
& I( l, p3 m, U; V  KeInitializeSpinLock( &DevExt->SpinLock );
7 n' A8 g, R# K  q- U3 T& m, U0 Y% {$ A9 s1 z* i/ ~
  //. f6 V! x9 o% p+ ]
  // 初始化 IRP 计数器8 O0 l& k$ F' b
  //
( d( V& O3 Z2 a" x  DevExt->IrpsInProgress = 0;
0 }8 z( ?) W0 Z% e& m3 x
" x" b7 K7 Y( g2 e, U7 v: a9 ?$ d  //- \& N# ^1 a! i( w
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
3 n7 t+ k9 t9 [  //
: L. n) T* ~) v/ y  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
! U& V6 P# ?/ @! Q                                              DeviceObject ); 7 R$ W# ~8 g, v- @. N& C
  if ( !TargetDevice )8 ]% D! ~8 n/ C+ j3 Z
  {
+ W7 G9 G6 S; v+ f    ObDereferenceObject( FileObject ); 9 D8 S) S; {1 N8 e" W5 I! G
    IoDeleteDevice( FilterDeviceObject );
7 I9 o+ `& I) ^. i& j. v    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );6 X6 }# S* ?$ |3 u
    return STATUS_INSUFFICIENT_RESOURCES;
/ N9 v% p) e9 K8 ?2 O  } ' m; n# y) J8 U; b

" ?  T. q4 `/ j0 z7 G  //
( ^2 Z/ }& W' Q( K  t: }/ k  // 保存过滤设备信息; c5 i2 j' J, q6 s0 F
  //# r0 m* z8 y5 h+ n5 I
  DevExt->DeviceObject = FilterDeviceObject;
4 w6 A5 e8 l9 j" C, e  DevExt->TargetDevice = TargetDevice; 4 i& \+ {! {, m) f- G1 I9 z6 \! J
  DevExt->pFilterFileObject = FileObject;* w3 d& U7 `( X/ f; l; b" u2 e
1 i) S) }0 _/ T/ ~
  //6 e: y  T( r4 ~( C# j3 `- z/ S+ w, i) a
  // 设置过滤设备相关信息与标志* F! h2 o$ `) H" z
  //
) v4 l4 P* Y# y  s+ G- I5 g* U' [  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 0 _, [* b+ C5 K/ X
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; ' T9 Y; v( L/ o6 [" v& n
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;! ^* J  n. c: q- Q: G$ ^( Y
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
' t8 k/ l3 i! h( ~: Z# F+ M; R  h6 Q                                                         DO_BUFFERED_IO ) ); 9 A# l5 q0 |" h/ Y4 E, j

5 J4 s/ D- e  i8 A; F  //# v: v: a% p9 Q: O( \- J$ s
  // 返回附加后的驱动对象
: x" P: P1 k6 R5 V2 _  //& n7 V! j% P2 `+ `( L  s
  *FilterDriverObject = TargetDevice->DriverObject;
/ d+ J8 m0 Q* \) p" i9 O  z+ Y7 _; H+ _' ]6 Q! L, Q/ N$ y! {
  ObDereferenceObject( FileObject ); - D. I. ^. \0 M4 `

* h1 Z  g7 e* F* w$ Y' x  return STATUS_SUCCESS;
% I4 c+ f, l) u8 V* i0 B}* ^/ ^+ W" S/ L# c5 S

+ K+ `& y, n, `( E2 e/////////////////////////////////////////////////////////////////
, a  ~2 Y( A+ A5 x5 j) j7 C// 函数类型 : 自定义工具函数
& u6 T8 j; n& R; o, o' i8 E  _* Z# h4 t// 函数模块 : 键盘过滤模块
3 I4 t% Y' H" s0 b8 L. f* G////////////////////////////////////////////////////////////////1 Z8 Z& b- u' q; `9 F/ ~
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发1 O3 t; @- l+ h8 d' g9 U" l2 k
//        这个 IRP 的完成" u9 W4 f+ R) F7 I# t2 W; ?
// 注意 :
: z+ j! g' ^) G! H; q5 b8 ~+ E/////////////////////////////////////////////////////////////////
: o+ [% l! `; R) r/ \- \" I// 作者 : sinister
& z+ \) n0 {) G) b0 w: i5 s. O// 发布版本 : 1.00.00  g6 j' L5 c1 b" z5 V  e
// 发布日期 : 2007.2.15) g9 u( C: A! Z. X3 v
/////////////////////////////////////////////////////////////////8 j& a! c0 N/ ^, D1 J
// 重   大   修   改   历   史, Q8 T1 h# a' s6 o
////////////////////////////////////////////////////////////////
; U2 v0 G' c0 [" Z4 ]; ^// 修改者 :
$ w( Y3 g& c5 g: q8 `5 I9 J0 g! v// 修改日期 :
8 ?) n( {# o0 L4 H# c1 d6 ~$ ^// 修改内容 :
* M" |. y- _% x9 {8 X- u/////////////////////////////////////////////////////////////////: l$ H2 P5 q% q5 ]9 c/ R
+ O2 r3 B# C, o6 T, ~- g& o# i. x
NTSTATUS
1 Q3 P! d) a/ z7 u" ^8 o$ o8 N& R; bKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
  n8 i1 D- X( k; \{+ T) T. [, S7 B, W: v
  NTSTATUS status; & V6 h0 Z2 N$ U2 l: \5 }( X) }: S
  KIRQL IrqLevel;4 ]1 X% z& Y  a$ M$ ^

0 p# D$ ^! V+ n2 C6 ^6 s/ S3 K- p  PDEVICE_OBJECT pDeviceObject;
1 i8 H3 m9 {, E$ c  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )) M$ `2 @% Z) J) f5 a) t0 e4 E
                                   DeviceObject->DeviceExtension; 2 G8 X% {. N5 a/ V6 H
0 e. I. q2 |, G( C( ?
7 C+ M& I$ r- w" `! P
  IoCopyCurrentIrpStackLocationToNext( Irp );
8 d9 u$ n& P; c1 ~: e  y; D  G( L
0 y# P+ m7 H. _7 A  //* R- `; w! n  V4 e
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁. {, Z3 I+ w- Q$ o+ v4 w0 w
  //  J9 h% t' h# |, @5 N3 g7 [9 o
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
! b( E, h: P/ @  u: n  ]3 ?  InterlockedIncrement( &KeyExtension->IrpsInProgress );
* R. V" ^: M$ k( O  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
7 p, Q2 c# [9 N7 M4 m; K$ S4 {% q2 z5 C- m( N5 G2 k) d8 b1 A4 A
  IoSetCompletionRoutine( Irp,
* j4 N3 P* M4 ~+ o                          KeyReadCompletion,
3 p& \0 B4 Q4 N; m, f# |$ w# k                          DeviceObject," D' _3 {: C3 w5 ^
                          TRUE,9 u! q( d9 A- p8 A# i+ P! \/ {  N
                          TRUE,
$ ]  G& P% `+ D                          TRUE ); 6 ?, b( ^+ n# H' r. N$ ?
/ m5 G, t4 n; w; M# T7 @! d; o
  return IoCallDriver( KeyExtension->TargetDevice, Irp );+ k" b+ o  {. b( _: j: f
}
; q& D3 g6 K7 k
- r- q( G1 W4 y" P% m/////////////////////////////////////////////////////////////////
& j' y2 o9 K% T5 P+ t5 @7 ]// 函数类型 :系统回调函数5 N: V4 G5 u% V
// 函数模块 : 键盘过滤模块' Q2 m" o* C. d1 D4 G
////////////////////////////////////////////////////////////////
! I" ~6 v) v( Y3 M// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
2 q% s. W/ Q7 Z; Z3 q// 注意 : ' h+ j1 c$ f/ V3 [. n" j
/////////////////////////////////////////////////////////////////2 w6 I; E* u# L" p7 P5 c
// 作者 : sinister# t; M" Z/ ~0 h+ V* q$ x  V* K
// 发布版本 : 1.00.00
9 B2 o  c# t3 K' u- l// 发布日期 : 2007.2.122 w! k4 n9 _9 \) R) ~6 }
/////////////////////////////////////////////////////////////////
. E' n; ]$ O+ {// 重   大   修   改   历   史
' [& p+ Z* n( u( O  i2 J////////////////////////////////////////////////////////////////
* R* W: B% |* m+ Q. n' v1 J# Q6 T, p// 修改者 :
* y* {9 |/ A+ H3 t6 w// 修改日期 :" Y$ r2 n( J( Q( X1 P
// 修改内容 :
) i8 o/ e$ ]! |+ F/////////////////////////////////////////////////////////////////
! c8 @5 U6 a; t% J* {4 Z" B
9 g! U) F- X) z$ [5 i4 B  H* Y% M/ @NTSTATUS
' t0 M" W) m. v8 {# n# WKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,# \7 f) y! \, M. Q5 v9 f6 `
                   IN PIRP Irp,
2 y( r) b3 H2 {* N+ Q                   IN PVOID Context )* a  X, a( D+ H
{
1 U% B: I7 i- @5 K  PIO_STACK_LOCATION IrpSp;6 K0 |: o7 a3 }, ~: X7 B% @
  PKEYBOARD_INPUT_DATA KeyData;! C1 D9 W9 {* U  @# d8 A7 e
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )& T( H* y( y0 R7 R! V& P
                                   DeviceObject->DeviceExtension;
7 i) K8 A* w  u/ n  int numKeys, i;
5 x7 ?8 Q- ?$ _  }& m  KIRQL IrqLevel;
( g% X- q9 D8 W, |( b
+ Q$ e% g( l+ f/ o+ b: k3 W8 A" G0 P  j  IrpSp = IoGetCurrentIrpStackLocation( Irp );, U* \. C! g1 ~# h0 h" h  {
" y/ Q- ^: h# E  i

& L  |7 j' e3 x- d  if ( Irp->IoStatus.Status != STATUS_SUCCESS )4 g8 Y: g  Y7 ]: r
  {+ o5 D- l9 _% s, A
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );  E# Q/ }; F8 L' G7 B
    goto __RoutineEnd;
% X$ A) ?/ b  l( Z, h  }$ t" l+ E4 n, F* t( g; s4 X2 [4 H
" u; s% @( N" A' j( S2 e$ _8 d
  //
# ]6 N% S" |8 g# w6 {+ ?  // 系统在 SystemBuffer 中保存按键信息) {6 c* c1 L. j  z% K3 O
  //$ X$ N0 N6 D) m
  KeyData = Irp->AssociatedIrp.SystemBuffer;2 u5 O4 v+ u" E% C, n9 Z
  if ( KeyData == NULL )
. R- M) A9 k1 a+ g+ a0 r2 [1 O, X  {
& l4 x0 |  M8 V7 P  o    DbgPrint( "KeyData is NULL\n" );7 o. b( B: t) {6 y. A
    goto __RoutineEnd;: L  W& C* }" |/ ]
  }
( [6 M) k2 n: d9 B" _( T6 ?3 F  \* J/ Q8 ?
  //
8 B8 s$ j2 Z0 v0 q9 k) c  // 得到按键数1 P( ]0 ?; `5 u& G! W9 i, y& ?  |
  //, ~5 R# C( o& C! f
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
" k8 |5 g, z" I1 V  if ( numKeys < 0 )
" X# \$ h* x; @2 l) e  {( K, ^$ d* i' C$ K' F
    DbgPrint( "numKeys less zero\n" );
) J8 J6 _4 R- ~5 d+ A& w% W; v    goto __RoutineEnd;
0 \: O& K& c1 K  }/ ~% [( h2 T- f% a( c9 W

- W1 R2 c7 H% p  //
, X4 C# P% n* ~" n9 m$ \1 H& [  // 使用 0 无效扫描码替换,屏蔽所有按键
9 [; ^- Z  q) p, X$ o5 X% z  //3 ?  X8 ]* r" ^2 M( _7 {  s% e
  for ( i = 0; i < numKeys; i++ )+ C( F3 z$ J8 n! e: @+ K3 I6 K) t
  {& e2 j% ~, J) Q% }- M' o  |; ^: Q0 i
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );: R8 Y2 `2 ?9 V0 z
    KeyData[i].MakeCode = 0x00;
! m+ `0 b5 Y' ]. t: v  }* l) c1 |! Y* |. ?

- z. `1 A. J$ J% c0 F' u4 M( F/ {  T2 B
  __RoutineEnd :
- y2 p5 w& c- B4 w
. `9 o2 d& d9 ?1 m7 j+ b  if ( Irp->PendingReturned )9 H7 |/ a1 i1 H( c- v
  {/ v' l. Q+ d. z6 h9 v- c
    IoMarkIrpPending( Irp );0 |: B; G" z7 R7 G$ n! s! a
  }
2 @' |, p/ O+ \4 V% L
: e5 q5 O5 w# w7 ~/ {: L! l" `, |- n  //
, T8 I1 `& \* B& W( B% {: J  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁2 S+ A6 C, D4 O7 P: h
  //  b# F8 M) k3 N* F6 a
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
8 j9 E4 Q2 x9 b  InterlockedDecrement( &KeyExtension->IrpsInProgress );
# ~: r5 H7 M  U2 K8 C" S6 s  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );5 V/ z) k( \  d$ q1 ^% V

6 b1 K; Q$ e; v# u  return Irp->IoStatus.Status ;; g( X% y7 H: x% A, N/ \) R
}
7 A. S3 V7 R9 _$ h. ]6 F) [  e: G" \) v. i+ }8 M, h
* x, {: b. O- }9 i# Q$ C
/*****************************************************************; V7 T( P( N) }0 |. P/ P. C
文件名        : WssLockKey.h- l( l/ q. m( l. B. G1 b
描述          : 键盘过滤驱动0 ^3 C) @2 S% M7 ^; ]* p& s
作者          : sinister- ~+ @* l& {. I7 j) u- L# \" u  p0 U
最后修改日期  : 2007-02-263 T6 Y+ F, h: N
*****************************************************************/- O  I: o5 v! M0 J

! u5 b8 ?6 m" s  k#ifndef __WSS_LOCKKEY_H_8 H6 B+ b$ c9 P' P0 ^' e, P7 e
#define __WSS_LOCKKEY_H_& I1 u6 e! G/ o8 [

; U5 R1 J# Z& |* P& x#include "ntddk.h"
; K; ^- j+ G$ ?#include "ntddkbd.h"
0 `# o; U$ t3 S" U2 @#include "string.h". Y6 H  P2 ?- h  y4 z' o
#include % u( u9 S9 q3 `; B

1 r) |# z1 f7 X2 _2 a% Z# F6 E#define MAXLEN 256+ k  g( k' y; i9 Z. @9 m
+ R7 L  B+ ~' n* k
#define KDBDEVICENAME L"\\Driver\\kbdhid"
. t8 \6 k6 {7 V/ m#define USBKEYBOARDNAME L"\\Driver\\hidusb"
4 M% C1 q+ W% y0 c7 B# {" I5 a  v1 T#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
5 R0 X$ y( P  u2 O7 h" y: K: S$ N" v) k
typedef struct _OBJECT_CREATE_INFORMATION
1 z4 [3 R1 k; F. B  M( Z9 ?{+ [3 p6 R9 U2 b: i
    ULONG Attributes;: }3 J* P  J  W& M' Y: U- f: y
    HANDLE RootDirectory;
, W0 \" S& I) [# D% D+ D    PVOID ParseContext;- |0 G% @- W$ W- h4 G5 Z0 |
    KPROCESSOR_MODE ProbeMode;: c7 U% j* J- n# d7 V- k: L% m
    ULONG PagedPoolCharge;
" q6 }- k9 F. [    ULONG NonPagedPoolCharge;
6 z" N1 a" u, W6 X    ULONG SecurityDescriptorCharge;
' o1 S0 K4 }% z' M8 E- P; q    PSECURITY_DESCRIPTOR SecurityDescriptor;
+ T/ S4 e/ s: ^) C& k& G/ c    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
* i0 I6 ^. l$ j7 ?/ R, L% y% l5 E    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;0 q( a( H( G, [* ~1 C9 B- k9 {! f3 t
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
! m% D8 L$ d( W- Q' H- |# k
3 Q8 E, F# E( z  M2 Mtypedef struct _OBJECT_HEADER
1 b: }: e: x3 z; P{
8 O# S1 \& W' k+ V1 Z    LONG PointerCount;
" \* @1 }& |& p    union# r7 O& o% [+ D$ E# B9 U
    {* R4 h) b, U' Q
        LONG HandleCount;
+ u5 b4 |7 r! t" o        PSINGLE_LIST_ENTRY SEntry;# [9 N* v8 D+ a7 L! {+ _7 N: P
    };) i* b. X7 W. Z! @. b9 Q
    POBJECT_TYPE Type;: v  c* ]. g( m5 j5 o( j( i
    UCHAR NameInfoOffset;
7 D: X7 c' x% O( I7 f9 i; p7 j    UCHAR HandleInfoOffset;
8 _' P3 }0 u5 y$ s* t/ i9 ?& R    UCHAR QuotaInfoOffset;$ _8 O/ n* }( z* Q  @! H
    UCHAR Flags;0 ]# n+ T, W8 N7 x4 Y4 r8 z) J# p7 P6 i
    union
9 u  Y) @6 H, C. Q, W& B# ~/ k    {- q# Z0 a; v: h) f4 h
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;7 x4 C) P$ D% C6 j% o: [+ R
        PVOID QuotaBlockCharged;4 o& u: r5 G' E5 R
    };, a% ]$ y# V& u7 _8 k

8 O7 w* s7 l9 d  z/ `    PSECURITY_DESCRIPTOR SecurityDescriptor;
2 u# ^, Z, A$ O  u  p    QUAD Body;1 z4 h' |: H1 Q, R/ H' N
} OBJECT_HEADER, * POBJECT_HEADER;! Z) ^  [% g. g9 M# u

/ E" x4 S; Z+ x: B#define NUMBER_HASH_BUCKETS 37" _9 ~% M' h4 @' `1 [
% [  B0 B0 f( _$ p- C
typedef struct _OBJECT_DIRECTORY
  c' |" `( q, Q* V9 ~0 ^{
- }4 a9 X$ z9 u8 R. C    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
6 X5 d( A8 P# `% v    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
. s4 u: J0 Q$ u4 Z, s5 d    BOOLEAN LookupFound;
" A  F9 t1 @( y! o/ \$ Q! p1 _/ |. \9 A    USHORT SymbolicLinkUsageCount;$ c: r* Q6 L  C4 Y4 a* ?
    struct _DEVICE_MAP* DeviceMap;
6 b/ E/ z& T  i7 w0 Z9 b1 m2 T} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;" U) j9 E9 A  A# v/ l

5 u! m8 n$ e2 X+ d* ?; Ltypedef struct _OBJECT_HEADER_NAME_INFO# D7 @% G. B& w, J/ U
{2 O2 D2 B3 j; I0 h3 ?
    POBJECT_DIRECTORY Directory;
' p; l! X& H+ p& U9 t    UNICODE_STRING Name;
+ K* \, X& _, U1 X" d6 \0 Y5 g" p5 w    ULONG Reserved;5 ^0 j3 Y3 E# ?6 {1 z+ I
#if DBG
. {! ?( G  ^6 }    ULONG Reserved2 ;: C; |3 B( @1 M' o/ {
    LONG DbgDereferenceCount ;
! u8 S! R. R5 D1 h. ?6 j#endif
1 n& b3 F& i5 |' n0 @} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;2 Y/ J. f+ T- y' X7 g% i
3 b' K1 W/ M0 r8 n8 d9 X; z9 L
#define OBJECT_TO_OBJECT_HEADER( o ) \
; j$ b( v3 ^" B( r7 s8 V    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )+ X; ]& i1 [4 d& X/ v7 I& v! n

9 |" E4 a. y7 n+ R. ]0 O3 j' E9 \#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
6 ]% f9 _, U, {, H    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
4 R" D1 R! b# o: c7 A: B8 u5 f, P7 F( ~( H7 D+ ]
typedef struct _DEVICE_EXTENSION
; u8 \* T/ O+ X" _{# Y* y, E! ~/ q7 V" B  }# V! S6 o
    PDEVICE_OBJECT DeviceObject;
* _/ t6 C5 J" A) {2 P    PDEVICE_OBJECT TargetDevice;
+ B* J& Z9 r2 ?9 I    PFILE_OBJECT pFilterFileObject;
* ~) ?+ D) @& T) K5 Y    ULONG DeviceExtensionFlags;
$ H/ e" y. e- A2 X    LONG IrpsInProgress;
4 o. a- L" v' w5 S! r8 p, ^    KSPIN_LOCK SpinLock;4 W) e& z( I, R. e) \
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;9 I" I/ ?7 u# ^& ^: R

9 O3 e7 w& r% A$ I0 j( J7 }. v) e* U) f
VOID
% C" R+ p( d( ?$ E- {KeyDriverUnload( PDRIVER_OBJECT KeyDriver );! f5 L4 d6 E4 A5 n1 D8 ~( t
' d) y: [( v1 s# Z. g$ m) x
BOOLEAN
" c8 C* R; }# a# [CancelKeyboardIrp( IN PIRP Irp );
0 c6 {: f; w2 F9 C5 N" p. G8 m' c) B
/ B$ C" M4 v3 a. m, V1 y- }extern POBJECT_TYPE* IoDriverObjectType;' u: c1 X+ u0 g* k/ s/ G
' l4 t  M; `4 F% T& d
NTSYSAPI& c1 q. Z& C6 J; W( x" R$ g
NTSTATUS2 [- C) n/ o2 t! e3 V
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
5 C$ _& }  S2 P0 I( |                               IN ULONG Attributes,3 M, f& W# n7 n+ z) W
                               IN PACCESS_STATE AccessState OPTIONAL,- e6 Y; }5 F; ?; q! s' ~
                               IN ACCESS_MASK DesiredAccess OPTIONAL,& q$ g# t4 ?1 b7 T# j" X7 j
                               IN POBJECT_TYPE ObjectType,
3 _% a: t) }( a                               IN KPROCESSOR_MODE AccessMode,
$ |4 Z( y# D8 j& x7 n$ q$ I( F                               IN OUT PVOID ParseContext OPTIONAL,
$ M  _1 X7 {6 M9 l  [1 Z2 y$ T6 E                               OUT PVOID* Object );1 @# X  d$ V/ T, |+ X" W& U( f' k: n
$ G8 t6 D. l; ^( V- h
NTSTATUS
; ~% {7 j1 v# g' LGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );" K2 H  g' e9 i' X8 P
' r% V5 N* I) b8 R1 F2 E
BOOLEAN
2 [* j3 B' @* o5 E! P" R1 ^1 DGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );' k0 S. k: m' j8 G2 ]$ R0 t

3 N5 P* ?/ ^% }( yVOID
; V5 ~: P4 @2 fGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
9 K0 m% R( Q9 a. T* c) t8 i0 J0 K# |# P
NTSTATUS 4 C1 p: Z) V  T( T+ _
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
* @) [- m8 ^& [2 a                                  IN PDRIVER_OBJECT  DriverObject );2 e7 w6 k+ }& {. o! `1 _

4 s( |8 n5 C: d; d9 PNTSTATUS
3 R# v6 d9 F# {5 n$ u" s2 o- t& i) UAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
& H9 V$ t& w* |& ]# A/ Y                                  IN PDRIVER_OBJECT  DriverObject,
- f  u" v' x$ I; p/ `4 k8 ^; s                                  OUT PDRIVER_OBJECT* FilterDriverObject );+ K7 Y+ W7 M% m$ }2 e( Q; }: I$ H: G
: x0 k9 f+ H" _/ `" }
NTSTATUS
5 A. H& L6 y: ]% D4 u8 R8 y( |+ OKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,. S) H% q* I0 n! z9 ^  J: ~" T% P
                            IN PIRP Irp,
& K/ j: T: X! L. B" I: b: _1 M                            IN PVOID Context );
$ x$ [3 m1 s9 }NTSTATUS
4 Y1 m3 o7 ^- Y, FKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );& }5 S$ |' ]$ [7 f4 Q$ N; f& [

1 S+ r# V7 q& N- M- p' A1 fWCHAR szUsbDeviceName[MAXLEN];+ ^  a0 ?; U+ j# y% l  Y

) A# E+ E  q7 W$ p- s: r/ X6 E+ u#endif$ I* L9 F& y* T: a1 p

/ Q3 |/ p9 q- I8 y) r- E$ i
: d0 y' ]1 a0 e4 ?' r- g: z0 K 9 G/ y, C. R* M# o- D6 v  \
( {: v2 Y' f; P4 Q5 h$ Y; A

  @3 h9 j; v! Y3 R4 J9 u2 l  sWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。6 L4 U( O. r3 t' I. I
WSS 主页:[url]http://www.whitecell.org/[/url] ! J: H& j* E$ b' x
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-8 07:04 , Processed in 1.392770 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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