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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister7 g; i. ~: c5 m$ O4 c0 s
Email:   [email]sinister@whitecell.org[/email]
1 f4 E: [. v( E3 n# Y1 [+ {Homepage:[url]http://www.whitecell.org[/url]   U  l, {) C  ^7 w7 f# _
Date:    2007-02-260 F: \* K! J2 R- V4 k3 J

6 p" i# n- j: Z7 O$ M7 l' L% u) H. [% ^5 q5 j' t; z
/*******************************************************************6 }+ J% u4 F# D: {% \; i' v

+ x$ a, G* z0 h6 A! s$ y3 y- z这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx/ k4 L, d! j, _# b& v" x& g
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
# S0 `' D* V# }! t功能要求如下:
$ F& _: t) A- I- i8 |8 p7 `7 h8 L2 n8 ^
1、强制锁定键盘/鼠标。
) [) q* b9 \- Y! ]. I+ ~2、可动态加/解锁6 v3 m: w: ]; b
3、兼容所有 NT 系列的操作系统。
% `0 P" w! ]/ @7 t6 C
) q% j# O1 g8 K( n9 [& c就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
  _- n3 G2 ?* c9 \. O现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
% V. t9 r1 e3 \' e! [: T6 a何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
! n3 t  {( t* Q6 o上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是2 P' A/ Y! j" j" R5 ~& v
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
+ ?( N- d' Q6 d  F就来看一下我想到的几种实现方法:
. Y( I! }- y) u4 e/ H0 U8 L; q1 j7 J& K, I( e: a
1、全局键盘/鼠标钩子
; W) r/ J& h+ x: M4 \2、BlockInput() API0 H4 T1 ]  n+ ]& T3 y0 ]6 I+ U8 y
3、使用 setupapi 进行控制7 j! @$ w) l( Q% T' D2 x6 {$ t
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL$ ^6 H% u1 P- A) J" U1 K* F2 L. w
5、拦截 win23k!RawInputThread() 函数
5 I& ~$ a+ n; v6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动+ N- Q/ w* e* G: o
7、拦截 kdbclass 驱动的 driver dispatch routine
! @/ a& V. `4 I% Y8、实现一个 PS/2 与 USB 键盘过滤驱动
) Y8 W; n% y; e8 o; ~6 `
: [7 [* t8 E( v: P& Q' k, C- y* n$ L. u
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
* m2 \0 @6 k: O$ Y之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
. M: l$ `+ S9 J案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在+ U) S0 E% j/ Y/ Y$ e  g
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因* V& J' Y. i$ i: Y: x
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性; Z) q" c+ W# B# w1 U' c
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
; A6 v. v5 w$ G6 ~) b% w7 y& V载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我7 z$ ]% E) d2 i
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来4 H+ c6 Z" b7 E5 q! E
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如' e  `) }8 j; s% `- L4 N
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有; M5 o4 \2 f1 K; l7 r
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
" j, z- [# t# o+ a1 a! g% |IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 * L( B! _8 y# F, _% j
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
- j' j" t5 G( L4 P$ z9 Q! O7 P盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
! Z# U, ~) J7 P$ b: @1 X& b& a案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
! f5 \' y1 H$ K/ M$ u! M3 ?/ t% q" I
- a! |0 f  ~2 B
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
8 ]' K5 I: ~4 T6 C7 J滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
7 W; \0 N9 g) z$ R3 d2 \  a/ O行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
. f/ M1 A4 R, F2 M只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越0 A" B8 Y$ E( y# k
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从. h& H) m# B1 l7 C3 Z& ?
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
" }$ v$ e% c) V0 K& f! F/ P1 L/ T键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用, K. j: u4 o, a3 A. }
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,( U( ]: D2 r- w. Y" h: W) n
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
8 `6 L' Q5 u1 Q3 @5 v2 E' [就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
. R7 y; R6 g& w. L4 O( X而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使" g. N8 r, W0 }  Y) y$ B1 Y5 z; b0 M1 w1 ]
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通# M3 D$ c7 O1 b& V( }6 G! x3 b" F
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来$ L3 [) P3 m2 R3 y1 T6 e  h
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通& S% B7 _1 V8 _% J6 s, o5 l/ l
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb" @. M* s$ N, V& p) @
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
7 {. T# |4 x* [: E" D+ v5 J的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
0 Z) }: Z- \3 I* U+ Y6 I味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。4 p: H3 \% Y- \3 w' K- x
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
( X: p7 d/ ?0 A6 @. z- a, r: o来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利; C  X& w3 @4 k
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo* j3 q- U! @" `% {1 R
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致% n1 u3 l" `  g' h8 s" Y$ I) E
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
9 `: Q5 z0 M2 c# b根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
4 V3 c. H9 R! I# ]5 H见下面代码。
8 i* R8 p4 h# ?% X
7 }6 `9 ?# T7 }. m+ r" o这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程$ Z+ S1 O8 Y7 q/ x
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键- U- l3 ?: t1 g, l6 |
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
) H! Q/ X5 p0 E- ~1 I上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有- j6 V) S; y0 j( T
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可. k/ H- _! c5 j  L0 z; A0 L; ~, f0 T
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
+ }* m" d& |8 K" h锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按) V. Q; E' c  `# Y
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。% g( b1 V- y! q5 a

0 u7 ^' A. Z- |! K3 e& G& O# z- S9 P4 i2 ]$ E0 j  E8 @
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用4 N0 d0 o+ v4 V/ o7 c6 H
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是8 U/ V- I3 K* [: F9 b8 \8 A
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣" i( K7 d8 h. ]( ?0 |
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我$ M7 t. O: b$ L* G' G, r
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
: E# x2 D- ~: q3 z" D4 B! D! g( z们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension; u; _2 `0 d9 u* h! l# N8 V
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
0 s6 U2 a( x3 \6 _如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager* O5 @+ a! {# S  r9 H' ~% w
进行操作了。这个问题有待大家来完善了。* p5 {% o  l6 `3 r7 [2 A& A4 m; M

4 H& L7 D/ \% |2 R7 D$ G* N* c- {* j! r* c* U; F
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出5 M+ i2 {& s; u5 S; Q
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的' U/ P/ j$ g7 Q: n
分析做个记录而已。我更愿意把它看做是一段注释。
) p: u) j8 K. Q; z! T5 B9 [" i+ r( I
最后在此代码中要( u/ T! R- ]( S; y9 g

3 O8 d0 B: [9 z1 D0 x( P6 m感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。2 p2 K4 i% z- E' u- S

& A$ [" ]3 |* b7 Q! t( ^. n感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
. _# `9 l6 X' X7 L8 K; V4 x
- {3 |+ k' F. [& i' ]1 j感谢:齐佳佳,过节请我吃好吃的。7 s' X" i9 |$ Q$ l8 e: s

5 n7 J  s! Q: S8 s! r1 f' ^
8 L1 R# {+ j2 c! h******************************************************************/5 z' J8 x4 [* @
8 v" c% n& }8 M, i

$ h) }8 t& h) d: y) s3 \, m- C/*****************************************************************% x4 E; d+ V) Y! M
文件名        : WssLockKey.c4 u) }' k3 a3 s) h3 W. l8 v/ A
描述          : 键盘过滤驱动
( ^7 Q8 b  E  t: a 作者          : sinister
4 o0 k0 \% X# \* @3 ~, r6 J/ ` 最后修改日期  : 2007-02-26# X. P1 D) z0 E/ l  E3 a2 v% l7 z/ K
*****************************************************************/
8 r; o# |! c0 F% S( v8 w8 i# f
& P3 I, f0 @% \# a; j0 @% \9 j! f
6 f: s0 @' M8 W( f0 {+ ~# p# S3 z# J$ z#include "WssLockKey.h"
* T' t6 r" ^8 x$ H* q' ]. B% z$ l7 J4 n6 ^+ q% |
NTSTATUS- r4 G. i  Y, h) B
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,. _8 d6 m% ^( O9 r
             IN PUNICODE_STRING RegistryPath )
+ q& o+ W% R" v  N  a. S{
" n6 L% E' V8 e9 |  UNICODE_STRING KeyDeviceName;
) t3 `' I8 w7 c+ @8 P1 p1 O( T% K+ Z% S  PDRIVER_OBJECT KeyDriver; 9 \- ^) `; u) [) @6 {+ q
  PDEVICE_OBJECT UsbDeviceObject;4 u. \) d% f8 b. l7 b8 T
  NTSTATUS ntStatus; 6 H1 v5 S9 r# D6 u: Y
  ULONG i; 3 n: u$ I8 T. u  V. {& Z9 i  }

+ a; B/ Y( r( J  //% d# C. R  m& q$ `( v
  // 保存设备名,调试使用' ~/ U: s$ ]7 E, Y8 Y& n* x
  //. o+ D4 u1 a) ^5 z+ E* b1 a: B
  WCHAR szDeviceName[MAXLEN + MAXLEN] =- }" K) U& R' J7 g9 l1 \/ r' q
  {% ~8 p3 T% y" d
    0
* U$ B8 T! I: w9 F4 _! Z  [  };7 m( C4 t2 L- p, \' p# u& O+ T5 F- V( Z8 L
8 j- ^/ t/ l2 i( h5 C
  KeyDriverObject->DriverUnload = KeyDriverUnload; " H0 o) }( `& w: Z& _7 ~

: s7 ~" n$ U* N9 m  //% C% z3 {- C1 E7 T3 N6 W
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘, x# D. J4 H. D8 S5 T
  //: X8 Z/ |0 _1 x9 c+ w& I
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法! T9 n0 J$ n1 ?  ?1 ~* z
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
3 J3 ?6 d3 V8 W! R" D% V+ |% [* C  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到8 I3 S# K% t( p; n
  // USB 键盘设备来进行挂接- u' C- D: U0 Q' P4 r% B0 K: {
  //
: ~4 m% H* B; L5 p1 L  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );" K( j9 @2 f# t; W% u
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
7 {- h1 j! u% P5 D2 H; b+ @0 N; a  {9 l$ n) q2 i0 N! ]: i; T& ~
    //
2 {5 k& _; h7 \: `    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
2 s( D* D& A8 @0 k+ F; x/ @$ H    // 所以这里打印为空
7 U7 x  h* w+ g& B9 Z    //
% Y6 p% `" g( n6 l5 P( x    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD! m$ V9 D! v4 J/ P9 C  u' P
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );1 N! z5 z+ Q( B" T
7 ^  n4 _1 }+ y5 z
    //$ x" x8 m% l9 w7 {( w' A4 |: ^/ }
    // 挂接 USB 键盘设备% M8 Q* W* t$ q/ o0 j/ x1 g
    //" q' |9 |! J5 k, [
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );; o9 A# O6 y. o' a: H+ s' ?* f
    if ( !NT_SUCCESS( ntStatus ) )8 Z* M6 v, [. ]3 ^
    {( L3 x) a5 p( t1 M; C5 o
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );: O3 d% J  K- T+ O
      return STATUS_INSUFFICIENT_RESOURCES;
' U7 X5 ~# j$ M7 y( f( Q    }; G4 o* T& s; Y5 F9 w5 h
  }
  E3 r* L4 x( I; ]- u2 _  else( ]# U# n3 R. Q3 m
  {
+ j+ ]1 ^0 n7 X: d6 F* t4 w" Y3 {    //
/ |! H6 c& }' t9 a" ?; g4 j    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
  F) a# x. c- ^- B2 c    // 9 ~4 d! }5 j' t
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); ; R; L& I9 ]+ S* d
0 s/ j) l2 |' `
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,9 w3 s  t# f- H  B; V
                                        KeyDriverObject,
; k' B4 r$ `3 V8 y4 c. A                                        &KeyDriver );& d$ C, U, ?1 Q/ Q  k0 q% i) _
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )& j6 U2 T9 I' R
    {
; h# s  K: ~; S- r4 G  g      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
" N8 C1 ?8 K0 _1 r9 Z8 b      return STATUS_INSUFFICIENT_RESOURCES;
  Y6 M3 B+ Q0 t    }
4 T+ U# l6 @  S" [  }/ B/ J4 O, x0 R- ^
; V9 i7 e! u) K% }* ^  c
  //
$ E6 B# T" \! a1 a  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
# X" |, W$ Y* h, M  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程5 t$ m4 o; ~6 e2 F
  //
5 U8 F6 V' Z( `2 r- E/ s  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 4 S) y2 p6 E$ Y0 u- G( U
4 W1 W0 c: X) ]8 _: i
  return STATUS_SUCCESS;7 q/ c2 |; N5 e
}
/ Q. ~7 F' u, h
7 m8 r8 C* S  I( o/////////////////////////////////////////////////////////////////
! w! W7 s. x+ j) [# Z9 [// 函数类型 : 系统函数
& H& B1 N1 f1 v4 A8 r// 函数模块 : 键盘过滤模块! u5 U; ]* V" [; L4 O
////////////////////////////////////////////////////////////////# X0 P! k6 Z+ i  W* `) }4 P7 z
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
! N4 ]& C) x! Q5 H- w//        卸载键盘过滤驱动2 e# d% j+ `4 P
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
2 _  Y1 d- l' c4 r' ]9 L//        则需要等待用户按键,以后有待完善$ }: D! O* p8 |$ ?1 x$ M) W# @. w
/////////////////////////////////////////////////////////////////( W3 F1 q% t% G
// 作者 : sinister
5 j: R9 m3 G& c! O# m0 L" o  q// 发布版本 : 1.00.00
# D# T; E; K( W/ C; u4 s+ p// 发布日期 : 2005.12.276 V7 I  ]& s, }9 Y; r6 B
/////////////////////////////////////////////////////////////////9 U8 h# ?6 J9 w$ X& Y* H
// 重   大   修   改   历   史
) m5 f  g; K- B  l////////////////////////////////////////////////////////////////* q% ^& {9 ]; P+ n) |
// 修改者 :
  ?* l9 r) H# _! X. Q7 h// 修改日期 :
; O+ J: ?% W' W. ^. M8 B1 {4 X4 d// 修改内容 :
) s  E5 G4 r& n: H! ]/ s! n/////////////////////////////////////////////////////////////////
; z4 m# Z1 N; ?+ U9 B, ^" A: ~+ Q8 {" C# F# c
VOID
2 E; @9 y, }2 S8 G* h0 IKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
; Z& x& @, p2 k# f3 m7 i' n9 k, Y$ `{# M. w* J. K6 [
  PDEVICE_OBJECT KeyFilterDevice ;      " T+ {. n, w# E+ ~7 D3 Y( Y' r
  PDEVICE_OBJECT KeyDevice ;0 I# q; v3 r. o7 b
  PDEVICE_EXTENSION KeyExtension; + N2 ^2 p  F' B1 M* _& G- K
  PIRP Irp;" u; W1 |. m4 V5 k+ L1 ]0 b
  NTSTATUS ntStatus;# V- g; P* q( z1 U

5 C2 L* k% a, {  KeyFilterDevice = KeyDriver->DeviceObject; 8 ~. z% p3 T5 p3 g. D4 c; |
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; 1 W( a: K  Q% U/ T6 \. d; l: ~/ O
  KeyDevice = KeyExtension->TargetDevice;
  E$ U. h- {& A% P& e& g) o4 ?" |9 E1 z' f5 }( X2 _& V
  IoDetachDevice( KeyDevice ); 7 K9 h( I) g( j$ {' J# E2 n
5 v) C' t3 U1 I" D$ L+ N' E6 L  `
  //
3 o7 d8 z2 v$ z$ |: D% X  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP0 ?. S' i: m) C+ w/ s( p
  /// Z' _3 j; ]% S6 f7 V4 \
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )6 ]% G7 G0 n; \: }; e6 z1 S' O
  {5 N/ z7 t1 F! W4 p. K8 t4 y7 ?
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )2 K2 C+ F3 K2 P% w) z& N
    {$ u; W  E( i; K/ j: I6 N$ a
      //
3 Q0 O1 e" R$ k6 T; L1 G      // 成功则直接退出删除键盘过滤设备
  F# N+ l# d' D, _- e+ T      //+ Z/ d# S$ F. P7 U* `5 X1 p6 O5 Y
      DbgPrint( "CancelKeyboardIrp() is ok\n" );6 q9 K6 N- l( \' I3 H# O  O
      goto __End;6 N: Y. v  j4 J. O; }- X
    }' g; k+ l2 d6 e, P0 S
  }) H! U$ n. E! {  V, f+ G5 H

/ T% f& G3 E  B7 h# G; T  //
; w) F) B5 |+ w! X- N# V/ X  // 如果取消失败,则一直等待按键
- ?6 v- g3 z& M& I% m: B3 G" v& K  /// J' D9 Q9 k4 l; [
  while ( KeyExtension->IrpsInProgress > 0 )
  Q9 K( o5 k: R  {
4 v( g; }  b: v/ i& r' ~+ u    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
$ F$ S  G8 y( S9 d# I1 j  }
3 l1 ]2 b5 i" d& ~9 _6 E1 M' A* e/ y" m/ D# w5 h1 B/ ~
  __End:, j% p1 j# g4 s3 A# K: F$ i
  IoDeleteDevice( KeyFilterDevice ); + O7 C. A% |7 \: V% h) T
$ N+ b# x# D' {7 V
  return ;
9 N0 a  \+ L, V} 4 M3 k5 n1 {) e3 \4 _
) m: x/ S# e; g5 e, P% }7 A# Z
/////////////////////////////////////////////////////////////////2 \! b# n2 \/ k
// 函数类型 : 自定义工具函数
. Q7 z/ a2 k  @' a" `- `% Y// 函数模块 : 键盘过滤模块9 c: [9 J9 D) E# b6 S
/////////////////////////////////////////////////////////////////
( Y/ _$ t* B' d8 `4 ^2 g# Z// 功能 : 取消 IRP 操作
# d1 S. F: U; l' x: u% Y// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
, k5 G1 R% L" g; ]* a/ @6 K4 b//        使用此方法来取消 IRP
0 |( H9 R0 r8 `$ M/////////////////////////////////////////////////////////////////
0 b' i& O. P8 X4 |0 u// 作者 : sinister1 n7 V6 q6 t2 P7 O) n$ J
// 发布版本 : 1.00.00
9 t! ~$ V' L  d9 F+ @8 D9 S// 发布日期 : 2007.02.20# o) g/ E$ t: U* W
/////////////////////////////////////////////////////////////////6 J9 m/ [; l8 J( E" ^0 j- f7 |4 c
// 重   大   修   改   历   史5 |$ Z& Y' N! }; T% |0 A: Z
/////////////////////////////////////////////////////////////////
& W( A. R5 ?& o: c" a* C' _/ g// 修改者 : 6 _) a' V! i2 s( w3 v
// 修改日期 : ; K5 {/ q, O9 c. ]- C
// 修改内容 : . q8 N5 Y! x8 w4 D2 p7 ~7 D' i! K/ c
/////////////////////////////////////////////////////////////////
+ J$ B# l5 s0 i7 Z2 H: N( G
; F; T; a2 M4 I6 [7 c+ {) s/ ZBOOLEAN
! o# w* J& U$ XCancelKeyboardIrp( IN PIRP Irp )" m/ _7 T. \4 p' P; \
{. [5 M) e% [" o) Y
  if ( Irp == NULL )  s4 g1 U; A" ~" P
  {
) O- H1 q9 ~& h    DbgPrint( "CancelKeyboardIrp: Irp error\n" );3 T& y7 P9 L' ?5 e1 K+ j
    return FALSE;
0 t* v$ i: x8 f  J1 d! x  }
* H/ u) _: ]- x( ^# ?9 J% V4 Z; H" A5 |% k  O

! J2 ]. V) q7 q( Q: E; K7 A  //6 _( f' O7 }" A/ h# j% z& X9 _6 c2 D
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,# ]5 h, B. H( d( P4 Z7 a9 E# y
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
* u0 ?2 A0 c) b/ a2 D; F  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
' s8 F+ m- O3 T7 [+ u, H  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD( k  _2 f! d% S! X+ [3 V
  //
" @1 }  [2 y- K$ p8 V7 T* ~7 r+ u1 l4 ~( c7 U% n* o/ R
  //
5 v5 t9 E& z9 U  // 如果正在取消或没有取消例程则直接返回 FALSE: J3 v2 `( J/ f$ I
  //4 F* ?+ r0 O: ^: f9 u
  if ( Irp->Cancel || Irp->CancelRoutine == NULL ): n" D0 f' o* {
  {: r0 r- W6 b7 g$ K( k2 {
    DbgPrint( "Can't Cancel the irp\n" );
  ?# G; @" _3 |/ R: r    return FALSE;
! ^- D: Y! i4 D: M/ B3 {9 s: |5 R  }
7 H2 G9 W6 H5 J4 {" G0 J; F. o. W0 {: w6 }
  if ( FALSE == IoCancelIrp( Irp ) )
/ k- j" H3 q# l! I4 S% {  {3 ^$ s) V" F4 {; h4 o. H
    DbgPrint( "IoCancelIrp() to failed\n" );
8 r3 D) T+ l# w; [: O    return FALSE;% T' h4 C0 H, Z" |" W/ x: m
  }: H- f8 V7 N+ \, V5 k$ B. v3 X

# M9 ~; ?! f. o/ @  a. F  //0 X; L6 v5 Y% {: d
  // 取消后重设此例程为空9 f8 f1 y3 t- Q6 g
  //
  |, X! T; l9 S  IoSetCancelRoutine( Irp, NULL );
2 i( T/ d0 S+ U- n  N$ F3 ~" f' e* O) t* U
  return TRUE;
- ^5 X  }) e- \4 n}
) N0 _$ [+ a' u2 w8 S! X4 K( m6 O# p3 v( `5 R8 u7 I* h. P- _6 C
/////////////////////////////////////////////////////////////////4 a* d% F; L2 h( I" M* k8 R+ j
// 函数类型 : 自定义工具函数
, n: I1 P; s# M' G5 Y) Z// 函数模块 : 设备栈信息模块: M/ [( t) B: ^& m9 T, V5 {
/////////////////////////////////////////////////////////////////
2 z4 v) g, y6 p  {// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘7 p& G6 b- q, \' g2 c* Y& j
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)0 h6 M2 y; D. F  n$ m! A9 v
// 注意 :
( Q! C( [2 ?# g/ _0 v5 t/////////////////////////////////////////////////////////////////* ]# x7 \( p4 O  ^( K) F5 s) p
// 作者 : sinister
( ?. [! N1 Q! O- u/ V8 u7 e// 发布版本 : 1.00.00
9 B  S0 W- C# ^" [: S; `// 发布日期 : 2005.06.02
! \: c5 \) }* o3 v+ B/////////////////////////////////////////////////////////////////% h' Z8 v& o: M) l
// 重   大   修   改   历   史& M! o' t7 y* t& d1 A
/////////////////////////////////////////////////////////////////
% s2 _; f8 @5 p+ S" m9 {  t// 修改者 : sinister
* O& P" R# n/ P1 E  ]// 修改日期 : 2007.2.12. I( c; Q  o# B+ I7 K- f2 x
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
! j- o2 T1 x8 P, @* L/ A6 _/////////////////////////////////////////////////////////////////
# ?9 \. h+ a, s6 x, H3 ^
3 X2 E$ a' x' b& J# j+ [BOOLEAN' w3 }; K  N1 Q0 G# s) R
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
+ R( l4 d/ B9 p% K" v{
" A  v6 D3 `- c3 X( b! @  PDEVICE_OBJECT DeviceObject;
& c" `' a' ~" }& O* s, b  BOOLEAN bFound = FALSE;4 t. p' a: a0 F) ?7 F1 j3 ~$ \; v$ P

% |% u' L% p7 V! ]8 H9 P* N4 R; S  if ( DevObj == NULL )( ?4 d9 z. c! L4 x; p! S2 B
  {
; t# n3 m- f2 N+ f6 v    DbgPrint( "DevObj is NULL!\n" );
3 k" C' j0 d& N' c" f    return FALSE;
' l2 o1 d( z, V- e. e, k  }
2 L: A6 |+ l! b; I
6 B+ b2 e/ I5 t  DeviceObject = DevObj->AttachedDevice;
8 }& v3 F* |4 u4 [
2 @# f) ~  F4 `9 o2 f  while ( DeviceObject )
. d/ `. S6 j4 _% T# [* v6 N  {8 P7 [) T8 v8 f: A5 R5 u2 S* ^
    //
; r2 M% h  n. S3 o# u5 J5 c; g    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
9 W+ m* G+ F  ]    // 有一次足够了。这算是经验之谈
- |1 I( i/ i+ o2 g0 k- G    //
; O% l: u/ W9 H( `. s    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )9 A' }# B! ?) ^
    {
. {  p" Z/ [) C6 @- J      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",9 k4 F2 d$ Q: N' O: S. P
                DeviceObject->DriverObject->DriverName.Buffer,) @! Q, q. T# E6 Q! c; E
                DeviceObject->DriverObject,
; G. F( c; F7 I                DeviceObject );
" e; ~4 l8 Y& u+ Y' A- |$ x
3 V% \/ }. m; j( m      //" O. Q+ D6 c- T7 B
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
" t  ?+ w+ g4 d! ]! ^5 x      //, p" Z* v+ i# V: J& A7 {
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,1 E, j5 ]% _' ]# J# y  ~" a
                      KDBDEVICENAME,
" B0 h9 ^# @4 Z& y1 ~( A- l3 H. V! |                      wcslen( KDBDEVICENAME ) ) == 0 )$ J8 v+ a* C5 F, Y$ E
      {
% c, O8 o" l$ V$ T        DbgPrint( "Found kbdhid Device\n" );1 P: r+ V8 n3 b& ?
        bFound = TRUE;3 a8 o# |" T# j7 b* A
        break;
! n3 i$ k6 A# }) f1 g$ K      }- W* n; f. V# s# A8 P) ^) l
    }
# a) k2 q$ z- t, M! ^; p+ @) A. x" b5 w$ [+ `1 y$ ~1 C
    DeviceObject = DeviceObject->AttachedDevice;
8 C1 q) g: }" a3 o  }
& x1 D( ]1 o' d& w" J# U
0 G# Y: V2 B" K  return bFound;% V- `: p4 Z' s7 q5 c; X
}. e7 w, J$ g7 u1 r% O8 K2 F
. Y# |  [1 p- k4 p5 Z2 R) Q
/////////////////////////////////////////////////////////////////
2 |  y% q* T9 N* E5 m" z// 函数类型 : 自定义工具函数/ i; q. q9 p( _
// 函数模块 : 设备栈信息模块1 d( c2 Z/ T; H" u
/////////////////////////////////////////////////////////////////- G, A& a2 Z" W6 f; F  b
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
, ^: T0 n( }1 E" j+ Q' `: Z" T2 T// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改; P4 z7 Y& O$ m: j2 T4 k6 U* f
/////////////////////////////////////////////////////////////////
' b9 T7 ]2 T8 Z* Q! [% N3 n// 作者 : sinister
  R! a( [/ @  h$ @% o// 发布版本 : 1.00.004 b( r. D! M! n0 [$ x2 s
// 发布日期 : 2006.05.02
# d6 {; a4 Q  Q- U7 U2 |' @) V( q/////////////////////////////////////////////////////////////////8 u' W' `  U% |
// 重   大   修   改   历   史
2 |$ ^3 @1 v8 S7 h! A# S2 s( Y/////////////////////////////////////////////////////////////////; t* x' \1 l/ j4 g. [4 F
// 修改者 : sinister$ I4 R4 @0 \$ T" D
// 修改日期 : 2007.2.12
6 R: m% z$ N+ K7 G5 r6 ~$ t// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
& Q* H) M4 ?( Z/ O5 `3 x/////////////////////////////////////////////////////////////////8 {/ K* u9 m  r7 q. W
# D) j# v  {1 H6 [5 Q5 k3 z
VOID
$ x! j  I9 |, P8 }2 F& A/ aGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
0 }) ?! f2 x. i1 U5 }2 i& M{, J  a4 i8 j& \" u' ^0 P. Z
  POBJECT_HEADER ObjectHeader;
# `& u: j, i( t3 N+ l( B) W  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
3 J& U9 t& D* B% K/ L7 W! h, g/ P5 c- {
  if ( DevObj == NULL ); S7 c9 \8 c4 m& _+ U7 ?
  {
& {* S- Z/ q4 J* J! D    DbgPrint( "DevObj is NULL!\n" );
$ I# {4 ?  `" }! {" w    return;
/ C, n. H- r% b: O0 |: Q  }& d. E6 k/ V3 E0 L- c$ @8 A; [7 a5 A
# b# Q; `1 S" N7 z
  //
! P* y: Y% O$ u" Z6 A  // 得到对象头3 [% C0 k$ s4 u; Z3 ?% n$ _
  //
( r# K& B& \- O& ?7 ^8 G  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );4 B2 I3 G) p2 L: F& {) G
" R" i' k9 P8 K% F% P
  if ( ObjectHeader )
6 V1 e* u3 `& ^2 U! L7 A4 V  {
: _. Z3 i! w$ I# E% _5 C, y! B    //
( N9 P/ b7 Y- m( Q2 o    // 查询设备名称并打印2 t: c) ?; M: B! n! \% Y9 Y' o
    //, S) `9 o! j$ E! o4 X
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );7 X; Q& E3 w# L

4 z+ |& t7 K- [& e. P% K* l' P" M    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
; t: c2 u5 ^+ C, F; O    {& x& q1 U0 ^- X3 c. l- d
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
# C8 ~8 }# N. X( t  G+ j                ObjectNameInfo->Name.Buffer,7 r2 T$ V1 ]" \" N
                DevObj );7 Z, }, s6 ~% }2 b3 A6 x

/ t( Y( p( ^6 }0 ]5 O- v      //
( r0 S" l  `9 i" g* |$ j      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
5 c& Y, `+ I; _, t8 B      // 用,没有实际的功能用途/ [* B: T2 f1 @2 c/ {' l( Z
      //, V0 o4 W4 l9 i& l* ^8 e% t
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
8 W) V7 A1 D, H2 f) Q: ?& M
5 F. l3 L+ Z6 E4 @* N      wcsncpy( szUsbDeviceName,. w! f* F. R3 c4 n+ E, X" D# E3 x
               ObjectNameInfo->Name.Buffer,
) ^" c9 z7 K' D5 s               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
% ~9 K+ N2 u. n9 L    }% U+ w7 {7 s, }$ l3 |
  Z: `* T) s' Z& {/ h0 Z. O7 O
    //
+ d8 j4 r6 }& E; h+ n- _. _5 [* [    // 对于没有名称的设备,则打印 NULL& T- q( }6 E7 l/ [1 v* `! Q
    //
3 i) b8 [& {$ S7 V3 F    else if ( DevObj->DriverObject )5 z& d9 X- S( G; A
    {( r  u  I3 D. k& R7 @
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",/ u$ P8 H" m* y1 o/ X# I* W
                DevObj->DriverObject->DriverName.Buffer,
  s  T: M8 I& C$ ]3 C& I                L"NULL",/ F9 t8 @7 b. R- k) g# \
                DevObj->DriverObject,
. i7 S, x4 w5 ~5 O( w* e& E4 f                DevObj );
! t  m7 E1 \% R. n    }) ~8 G0 S& W/ B( Y+ _  x
  }
3 G$ T0 b+ z+ ~}
( H5 u2 y7 Y! |2 [) m% [0 I! \% C7 t% o1 ]: m7 L% [2 h" M, M
////////////////////////////////////////////////////////////////// M' O5 W5 `! h  S6 |
// 函数类型 : 自定义工具函数
' @  y" m: m% B$ j// 函数模块 : 键盘过滤模块
2 A% }7 a: J8 X9 N/////////////////////////////////////////////////////////////////
# o; O8 A% n' `! T0 K" J// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
8 T, v0 x% [% J* I. u//        对象,过滤出 USB 键盘设备,将其设备对象返回- M$ ^" F: j( E; L! i
// 注意 :
) n/ _9 X) g* e  ?/////////////////////////////////////////////////////////////////
& a/ e% @2 {0 ~+ w5 K- H// 作者 : sinister
( L& @* d. D( G/ S  N// 发布版本 : 1.00.00
/ Q9 O3 Y. J  y. T" J  L: W// 发布日期 : 2007.02.13: K) ?2 G$ `) G# j
/////////////////////////////////////////////////////////////////
0 s8 l7 {7 s# h/ U0 a7 y// 重   大   修   改   历   史$ W; y. N9 ?6 ^4 h
/////////////////////////////////////////////////////////////////
5 w  }: A- _8 G  @// 修改者 :
' k  M  t. a( b' m& T- p2 v8 P7 N// 修改日期 :
4 _& M, ]; z* a1 l0 ?/ N// 修改内容 :
! f( i7 Y1 n7 g. E( s1 U////////////////////////////////////////////////////////////////// f* p$ E/ C5 c9 Q6 |: D( e# }& y

7 d% D/ e7 b: D: cNTSTATUS
3 l/ u! \0 Q% p0 b1 I2 xGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject ), t7 w& T1 C8 ~+ b- D: N+ h: z
{
8 w& u  h: U9 y  UNICODE_STRING DriverName;
! b  s  X7 ^' U% C) i  PDRIVER_OBJECT DriverObject = NULL;( _; U6 `5 x8 C# U' s
  PDEVICE_OBJECT DeviceObject = NULL;- U: m0 F* V7 D1 b: B) i4 z! A# ?2 r: Z
  BOOLEAN bFound = FALSE;- k$ M0 Q- m! Z$ F/ h2 s

* V* i; h% e8 O3 I" t  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );$ J8 I7 V2 t5 f2 y) ]% I% z
6 ^+ x0 v1 B9 j
  ObReferenceObjectByName( &DriverName,4 l# L" u* }# X2 J9 A) [
                           OBJ_CASE_INSENSITIVE,
4 m, J$ w+ U* U& k+ @                           NULL,3 C/ C, U2 w  g! `- v
                           0,
7 ]0 @1 J- `" v' ^6 s. I                           ( POBJECT_TYPE ) IoDriverObjectType,2 ?% D. B$ G! k; u! ]' g( M
                           KernelMode,
! t9 N( X' b" Z; S  z                           NULL,
; e; f% q7 t* D+ M" y0 C                           &DriverObject );! a: Y/ O: E* `& s4 [) N1 O( \* T
, T. G; U8 t6 A0 t
  if ( DriverObject == NULL )2 v+ G5 j- t( l1 J: ~* @5 h
  {1 }; U6 E; {% Q6 M9 U* U& \
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );- z- T2 q8 _; G( y
    return STATUS_UNSUCCESSFUL;6 b+ Q7 _' U  @, {: |7 H: ~5 F
  }% t) e9 b2 S4 G3 t# x! P
" n2 d  N) |, \# m& |/ L, y
  DeviceObject = DriverObject->DeviceObject;
; G! Z' f1 @( @# a) n3 M0 u6 Y: B7 I/ x5 H0 _  q+ C% o! g
  while ( DeviceObject )
  J* e7 g; ^% c1 O- }  {
1 g1 a8 r2 p) p    GetDeviceObjectInfo( DeviceObject );  u5 Y4 x8 |7 o( z+ b! ?: Y
% w6 o" p$ a- i; e
    if ( DeviceObject->AttachedDevice )
) c+ i  F0 w" q! Z    {; B: M% ?! z% Y" d
      //- z5 k6 }& s' {$ p! Q
      // 查找 USB 键盘设备
% b# J) a4 s/ D4 h      //. w2 J5 h# P+ ?2 C
      if ( GetAttachedDeviceInfo( DeviceObject ) )* w' W) }0 r5 |2 k& d
      {
8 p6 W6 |$ D4 o! m6 [4 c1 M        bFound = TRUE;, M. B( k! Q$ y
        goto __End;: t7 Q. i; U6 r4 w1 [
      }; y& y' u) r# y3 U9 H
    }
; e4 W3 Y9 D% p* l# m$ M3 M- W; Q% k/ c
    DeviceObject = DeviceObject->NextDevice;
3 i& l7 X( t6 V4 u( a) c+ X  }
* P  M/ i8 |1 L! J! Y( q1 c$ |! X, U9 _9 b- T2 B/ P& ~" u1 o0 s7 r
  __End:% ^& |& k7 J) {6 b' h" x" L) F

4 Y* I9 E! _4 L: r6 T' _  if ( bFound )
; u; b$ r& G$ \; i  {
2 \& O; A( ?  e* N6 m    /// p+ _/ j9 I! {! M4 E7 K9 o7 a
    // 找到则返回 USB 键盘设备对象. r  M& b+ G5 j  o5 Q" ^9 l
    //
# Z7 P$ d. N, [5 f    *UsbDeviceObject = DeviceObject;
  t' `; V" H. H( k% I# @  }' W8 Y; o  o+ A( H" R* V& k
  else
# [# L6 s. u4 a  {; S4 `) _. e4 Q  r
    *UsbDeviceObject = NULL;
3 m9 Q; G7 `4 s9 y; u  }: o( W8 T# u+ G" A, S
& _; F$ x8 [* g! @+ L8 I
  return STATUS_SUCCESS;
+ y4 y( ]6 ?( S0 q* l5 b: |}
' Z( Z/ V+ D# O+ V( t
) @( ?) q9 N3 O. p7 n" U8 p1 |* S/////////////////////////////////////////////////////////////////
3 m8 Z+ @# }% J- A// 函数类型 : 自定义工具函数
6 o! J: T; j7 e5 ?// 函数模块 : 键盘过滤模块- s, g+ S# \! V' Q  g" M
////////////////////////////////////////////////////////////////4 y) [' ]4 f4 e
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
+ r: r: j8 {, `: y1 z$ |/ e//        信息,返回附加后的驱动对象$ {( W1 E, C$ H
// 注意 : 此函数仅挂接 USB 键盘设备! b) \! l$ D2 P) G
/////////////////////////////////////////////////////////////////
1 l) x! B. X8 `2 V// 作者 : sinister
3 p& w- o3 i1 P// 发布版本 : 1.00.00
  S* z& x6 \  ~4 h* s( K// 发布日期 : 2005.12.278 Y1 U& W) N$ F# [0 Y( `, F
/////////////////////////////////////////////////////////////////$ {, g0 P6 Y  J( O0 `* a& Z* z
// 重   大   修   改   历   史4 G4 K9 d5 h7 ?) s: Q. b: W6 N
////////////////////////////////////////////////////////////////
& N6 N3 _+ ~% D& p' t. y// 修改者 :
7 v( Z1 C8 l8 j8 {// 修改日期 :
  H; ]* c( c5 O+ X+ H// 修改内容 :
' Y4 R% z& M) I2 L/////////////////////////////////////////////////////////////////" [! d+ y+ |. P. ]. o

( Y! v1 V, P; W9 l( G/ BNTSTATUS
# L4 {/ p* d, ?3 @AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,3 J. \3 c, o' ^! x
                         IN PDRIVER_OBJECT  DriverObject )0 z6 m; n0 J' `4 V
{' g6 H. h5 A& s) o; j. D
  PDEVICE_OBJECT DeviceObject; / {5 r9 }$ J4 Q0 C9 k
  PDEVICE_OBJECT TargetDevice; . n% H! {9 G# q' K
  PDEVICE_EXTENSION DevExt;* c- A! ]/ c/ @" h9 V( j  N" ]
  NTSTATUS ntStatus;
1 W% q$ P+ ]8 L- r7 u9 w3 H& A& M  B( Z
  //. u9 Z0 Q3 s2 t# q9 S+ S' h
  // 创建过滤设备对象
5 L- I0 [6 D9 F( `: O3 w" X  //% [* K' k4 x& m9 p
  ntStatus = IoCreateDevice( DriverObject,
' d* [9 H9 D+ I, E1 L6 W7 t                             sizeof( DEVICE_EXTENSION ),: h& _( e* W1 Y( ?+ T& c
                             NULL,
" r& f; h# s* Z: r- e                             FILE_DEVICE_UNKNOWN,. ]; O' r$ J$ f! m/ e/ ^5 ?; A5 O
                             0,3 L8 t4 |; B: @! u7 C9 q1 K# g
                             FALSE,
7 W6 Z6 k1 w9 ~+ {% a7 P                             &DeviceObject ); 8 Q0 T# Q; Z$ c: H$ G( n$ ^

# z1 W7 s# i0 O9 ]  if ( !NT_SUCCESS( ntStatus ) )5 d' L; ~) T& `, ]/ q3 j8 u
  {
3 i; [; n3 i& J# F# ~" C+ O3 r  U    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );3 q7 e( h9 b6 W0 Z# s
    return ntStatus;
# I0 a7 j- t' }$ V" ]3 h" D+ f  }
9 p7 L: n* L. l& d8 v
$ S6 z6 G: r# z) B4 `5 |  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
; K! T1 J' s# L4 n2 T  ~5 i, @% o- O" H7 U9 O1 {
  //* B3 _8 X2 H4 s. }+ H- N$ b
  // 初始化自旋锁; a% i1 E! W. @# V
  //
, x; T: x: ]5 y( Y  KeInitializeSpinLock( &DevExt->SpinLock );$ N) }& L. d' @! J+ X; H" L
9 N3 X; H" K* @5 C: X9 J
  //
& o6 {; p% T8 `1 j% a; o$ y  // 初始化 IRP 计数器3 F! }- e) C4 V5 P
  //
* a$ ^( @0 @. s% d  DevExt->IrpsInProgress = 0;
5 z$ X  T2 p& C# b
! b' D4 Y+ H" q# y8 `0 N. u; G: F  //
8 z4 q( ~& U6 ~7 H& ~- g7 o  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象5 u4 _+ Q$ @% U# l
  //
7 }) }7 q# k' s$ J  M6 a3 L
+ z! f+ U3 d, Y  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
- `$ U( N' |8 M  if ( !TargetDevice ). y  o8 @3 c4 e; p  Y
  {" U! ~7 g, U0 v' s2 v7 @
    IoDeleteDevice( DeviceObject ); 9 f6 x3 Q# _6 R4 ?5 H
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
4 J7 p% ]/ N1 T) k    return STATUS_INSUFFICIENT_RESOURCES;
$ L% t8 e9 d  U, \6 G7 l  } : x/ [- Z4 E0 D, D2 h& d  f1 Q" c
5 J6 @: s) S  ~- q6 }; b9 @
  //- _- w5 `! O) D2 O
  // 保存过滤设备信息( g) [/ Q" `/ B1 g0 p6 W; `& U
  //
8 {5 v. ~$ H5 [: a  DevExt->DeviceObject = DeviceObject;
/ i; C& G( E, A% f+ c* h3 v  DevExt->TargetDevice = TargetDevice;
2 b" [, p( F& r3 e% ]5 [- @6 [+ l
  i4 p" m! m8 l' f" L& q5 W) d  //
* A1 H$ A0 _9 Y7 r' S  // 设置过滤设备相关信息与标志
! P0 O& w: x" j" [0 a+ T( _7 H  //2 F2 K  M+ }0 {5 E
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );; U4 x" \1 E. E4 X# H/ V
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
" j' Q; j8 e" s  O3 S3 e2 ?: s$ i, g$ e7 q& p8 U

) [( |" a: }  ~) `% i  return STATUS_SUCCESS;  H4 B" e! C$ x, N- X9 J
}
7 K0 g) S" Y; r/ Y& e$ E2 [' O; n9 v: u
/////////////////////////////////////////////////////////////////
; e' h: M- p7 f  \4 ~// 函数类型 : 自定义工具函数  Y9 y+ N& P+ ~- d  O5 K+ H3 I
// 函数模块 : 键盘过滤模块& H7 [, z2 z7 J  H! A" R7 h
////////////////////////////////////////////////////////////////+ p" f: l0 F8 Y- J
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关2 p3 @8 P$ H% E/ b
//        信息,返回附加后的驱动对象
2 z3 j5 |3 J9 T' i  v" \1 l// 注意 : 此函数仅挂接 PS/2 键盘设备
* X/ ?; y! n$ b2 X/////////////////////////////////////////////////////////////////
% \7 k/ I' m% o2 [: s// 作者 : sinister: Y) I0 l! {# j
// 发布版本 : 1.00.00
4 G; v# i1 K8 z: o7 Z; B6 X// 发布日期 : 2005.12.27
8 V) N% f+ T  ^* Q# z4 L) z- N////////////////////////////////////////////////////////////////// i2 R& I$ [7 u5 t8 a6 F
// 重   大   修   改   历   史  }4 f: w" E& ?( m
////////////////////////////////////////////////////////////////! h- X" s7 d+ Q- D  L
// 修改者 :
& R5 [/ t! j; w* Z2 G. P" t// 修改日期 :" F- p* c3 m6 e( ^/ v8 Q
// 修改内容 :
# D7 P5 I0 V- s2 F+ F/////////////////////////////////////////////////////////////////2 _0 Z! X5 ]) @4 E7 N
/ {% W6 y" I3 V' ~
NTSTATUS
! c# n& ]/ F! p" ^. P8 uAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
) g9 N) N2 ~  P3 m, f                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象4 s- r7 b2 l, G& ?3 U: ]3 ^
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
: c- O/ K% Z3 z{4 c/ m+ l) _3 W' N3 s$ q9 c2 b* p0 Q
  PDEVICE_OBJECT DeviceObject; - n* u$ s4 w' O* [8 m& ]
  PDEVICE_OBJECT FilterDeviceObject;7 v; Z" l$ p8 c! y( _' y" c+ l' h
  PDEVICE_OBJECT TargetDevice;
2 m9 N; ]: T) R7 \$ D  PFILE_OBJECT FileObject; $ k; b3 H  x% {1 H0 M0 e( @+ ^- [. r
  PDEVICE_EXTENSION DevExt;
: _& v5 S. a% A$ b+ S7 R
4 `/ W8 q0 E7 e/ _. e# ?! Z& _  NTSTATUS ntStatus;
( }  D- z4 z8 f0 |+ g" e3 d4 K# {3 ~1 f8 h' G
  //
+ i8 L7 n! @; v- m. s1 G  // 根据设备名称找到需要附加的设备对象7 D0 S8 M* n! e1 A3 a3 L& R- J
  //% h5 R- M  p% x
  ntStatus = IoGetDeviceObjectPointer( DeviceName,* b9 c. y: I0 o3 M9 c4 k
                                       FILE_ALL_ACCESS,
) y" M! W# t9 P8 G0 v$ W, u! c                                       &FileObject,  X: t1 z, O- e  W; Q4 \+ g% V) I
                                       &DeviceObject ); % x. y. H: D* ^3 M+ E
+ ]7 F# X+ Z5 h1 u3 E- z: Y$ @
  if ( !NT_SUCCESS( ntStatus ) )
: B  z$ n% {! o, @/ i  {, l/ L2 X, f0 ^; K
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
; J5 s# [9 G9 [" ]7 b) F    return ntStatus;
8 `2 Z3 i0 C9 w0 M; u4 T  }
: t5 |# z, j) U
" }/ G( F3 t4 w3 L3 _0 d  //+ C" e; j' I" L# ~0 s) d9 D
  // 创建过滤设备对象
; H# ^7 _* c. T8 ]2 |  P+ B; O  //
6 y7 v% a& j! h: ^7 i  ntStatus = IoCreateDevice( DriverObject,; R) g8 s* F4 Q
                             sizeof( DEVICE_EXTENSION ),
* t6 t2 s" C# b                             NULL,
* z& [, L( n& m1 H  b& K                             FILE_DEVICE_KEYBOARD,
5 x& l2 h6 L/ {4 T1 I+ c                             0,
( h; F" h) ~, t( t: G3 N                             FALSE,
6 {2 f$ D, n* ^, Y9 a: x                             &FilterDeviceObject );
& [8 i8 s, I  S/ }6 y0 q
; {4 I1 _( \( Q; B1 Y  if ( !NT_SUCCESS( ntStatus ) )& P% ]! R% B, j" b" c7 F
  {6 ^8 o( X" Z3 r6 ]3 L) S
    ObDereferenceObject( FileObject );
! R5 O: ^; B9 h2 F5 M  {! |/ L    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );" e1 x) C$ ~4 }9 }2 ?3 U+ ^0 o
    return ntStatus;
& {- ~- B, e- ?4 B) I  }
" t7 U4 x& C" g2 k8 S9 r. G9 v/ @4 u$ N
  //
! i* l9 ~  Y7 d6 d+ f5 S  // 得到设备扩展结构,以便下面保存过滤设备信息
0 @/ ~% y) V, P2 J  //4 Q+ x6 x* ?+ e
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;6 f! G8 ^$ y1 @; L, Y
4 ~3 J  y/ H# t/ P* }

. ]1 ?& L* e6 a( b1 J  F  //* y# e' p% j0 n& d) Z
  // 初始化自旋锁
' r3 u( w6 c: U* |$ I7 Y0 t. {# ?  //% x( a% e, S# c" t  T8 O
  KeInitializeSpinLock( &DevExt->SpinLock );) b% h6 Y. M3 }" X( C9 x" Q

4 ]' O0 v* @* q2 O' |" Z) e  //
. d" ?, I5 I: F) C5 q  // 初始化 IRP 计数器
! K5 {, D- a2 V% T- [; _  //
1 L% g4 i4 |" q( u( j  DevExt->IrpsInProgress = 0;+ `3 g, q% S5 ]8 W1 x1 _

& o2 O4 B1 n3 y  //
4 o; b# K- b# M  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
3 o6 _1 ^8 c' v$ L' Q& w  g$ q/ Y  //. d% {. d: I, h* N9 w6 Z6 F6 o
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,4 c" V9 \+ D" D8 H
                                              DeviceObject );
1 \4 Y7 ~1 o$ w' h, E9 U  if ( !TargetDevice )& {8 ^  o6 }( n
  {
2 g: k) b0 ]/ J    ObDereferenceObject( FileObject ); 7 R: X- B2 _9 I6 V7 b4 [; W) p5 W6 D, v5 x
    IoDeleteDevice( FilterDeviceObject ); 8 y6 A( `1 t; ^! W5 A* @; X7 y
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
  V8 q% \4 i  I5 a2 H    return STATUS_INSUFFICIENT_RESOURCES;
/ z' ?9 Y4 i: ]6 f& G7 u  }
  _7 a4 a6 L  |& Q- b+ h+ N. M! V! f  I8 [: |; k
  //
1 ?2 w" h4 [) j& U$ _  // 保存过滤设备信息
* _$ p4 q9 t6 w0 R& X; Q: n  //
3 I8 P- E4 K% Y: v+ [# D  DevExt->DeviceObject = FilterDeviceObject; 8 e9 C; ]* C/ ~% t% Z
  DevExt->TargetDevice = TargetDevice;
: W2 Z) ]8 G3 s1 n0 C  DevExt->pFilterFileObject = FileObject;% Z0 ~) Q4 h1 y
- J/ g4 F% {1 L
  //
9 E( g; A/ A6 p. ?' G  // 设置过滤设备相关信息与标志
# h8 \+ E* w0 f5 W! g3 N' [  //& ]/ ?# e5 `+ i* K6 M$ j
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
* O* b) G' v3 x1 S. f  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
. T! j% m8 L; w  t6 y& z4 l! I0 _  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
. d! X& b" o: v  W9 P2 U  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
$ f' E* P4 [& ]                                                         DO_BUFFERED_IO ) );
  Q% F+ a$ b* p: K2 x
: f* b5 p! _$ U  //
: L2 y4 x+ I/ I0 x: o- o5 u2 w  // 返回附加后的驱动对象% t2 M1 W4 P- B7 F0 G: l
  //
5 p0 I! k2 T) N% H7 A  *FilterDriverObject = TargetDevice->DriverObject;
( B! s# Q+ a3 X# G+ C) j
( }7 x7 l' S  J' y  ObDereferenceObject( FileObject ); 5 E% T& M5 s. C8 S  t
7 k% c, f$ h8 u5 e7 ]
  return STATUS_SUCCESS;
+ E3 t+ y& [9 c( `}
1 Z7 L3 {# v' l; c- J$ }
1 t" Z7 V( I5 D3 L5 P! i  P/////////////////////////////////////////////////////////////////
- d+ F+ M2 I( a  m+ Y7 o- h// 函数类型 : 自定义工具函数
) T) i; `  {" ?5 z' w2 h" H// 函数模块 : 键盘过滤模块7 X- j; `; \" ^. ^1 T  i& U
////////////////////////////////////////////////////////////////
+ r  R1 K. `* W/ t7 `( w// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
2 P7 ^0 u0 Z/ U. s$ E/ w- t! R//        这个 IRP 的完成
; _0 O) ], d. j: D, @// 注意 : + s4 |6 D0 J$ I  e
/////////////////////////////////////////////////////////////////" u- D2 z+ T) t, {; r2 Q
// 作者 : sinister
: `/ P, V4 s; e/ U// 发布版本 : 1.00.00
* s! [$ U/ t1 T" j// 发布日期 : 2007.2.156 G4 u) @# Q, B; L: ]! T- T4 Q) S3 l* D
/////////////////////////////////////////////////////////////////# U3 |6 {2 s5 S; V, |1 h" V. M
// 重   大   修   改   历   史" M1 W+ R  ]- V2 T8 q0 {: [
////////////////////////////////////////////////////////////////
7 @3 U1 m: W5 W" l// 修改者 :
% s5 A/ |1 G* {8 T. T5 E0 ^2 d. O// 修改日期 :
2 I4 h2 Q, c0 |- b2 H2 K( e5 r// 修改内容 :
/ s/ p+ T7 }4 q) B/////////////////////////////////////////////////////////////////
; N: J# C) e" [8 V8 k
) _7 x5 H9 E0 M5 }: u4 @: HNTSTATUS
# E0 R6 E6 o$ G$ B, n/ J8 KKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
" c' y: z% p& M# O$ f2 f{
9 f* [: |0 `5 P# b' P  n; S! D, t  NTSTATUS status;
1 C" T* g3 y" M& o  KIRQL IrqLevel;; F9 V" X. L. I9 e
3 M9 U# h2 e' u
  PDEVICE_OBJECT pDeviceObject;+ C$ s0 G* k' A- g
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
2 F# t4 i2 P: Q$ D* }1 G                                   DeviceObject->DeviceExtension; 2 j4 S$ Y8 |6 Q9 X, V8 @
% Z5 L7 @, |/ {$ \' l

- f# C* E! g. g7 R' j  IoCopyCurrentIrpStackLocationToNext( Irp );
( z" x% \! y1 Q7 s
# A4 U5 X; E/ J7 x  //0 F3 d4 G2 L. y6 T
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁. {. _9 E& v2 h( k7 Z( l
  //
: }8 i# Z* |. |- T( s/ Z" F  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
" X) |/ ~" c$ @2 D; |, o# A3 Y, ~0 g  InterlockedIncrement( &KeyExtension->IrpsInProgress );
. Y) X$ O* m9 I# P  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
/ C7 M  @1 _8 X  q, G( i, Y! }6 R( h: B* Z# T4 r
  IoSetCompletionRoutine( Irp,1 ]. B3 H$ W  s' C  O3 l# {
                          KeyReadCompletion," U/ U3 w+ N/ s0 K% o$ _
                          DeviceObject,8 {: A- C; _2 r$ N8 a! i7 U
                          TRUE,
$ f' g6 D. S# j" j7 I2 e! F: ?" Q                          TRUE,
! k7 O1 m; Z; l& `6 i3 L5 F                          TRUE );
6 C6 V- W7 T2 w& J! M
4 g4 c- r3 R9 q( o  return IoCallDriver( KeyExtension->TargetDevice, Irp );
, l, |/ B; {. E6 Z}
3 }. @* p& y; B& Q6 p
2 Q/ |, D" k3 l. @" c/////////////////////////////////////////////////////////////////. y& b" z, X% k2 H, ]* Y" k
// 函数类型 :系统回调函数, ]7 j% v% h" }- L- R4 w) z3 {
// 函数模块 : 键盘过滤模块
1 s6 e9 M/ q& P+ }. j- e2 p1 ~/ j7 \////////////////////////////////////////////////////////////////
3 X& H) s1 p* @4 w  z2 a8 I( p. O// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
( `6 G5 j" H2 \1 @% w1 F. L// 注意 : $ W% Q2 D' u* D6 C+ h5 t( f
/////////////////////////////////////////////////////////////////
+ L% X$ [) e# k+ _* F3 u( U// 作者 : sinister6 F$ A! u! _" p. O
// 发布版本 : 1.00.00& `( ~; k" }( Q* V
// 发布日期 : 2007.2.122 {- J' }$ w3 r/ x% C
/////////////////////////////////////////////////////////////////* ~0 q& P6 r# k: e
// 重   大   修   改   历   史6 N9 G% @/ u) M, W. @
////////////////////////////////////////////////////////////////3 b" x1 Y) V3 @# t# V1 l
// 修改者 :
2 g5 p) s; v7 P5 g// 修改日期 :( F) o# F' z  M6 z5 ?$ n" W
// 修改内容 :/ F! n" N, m! ^/ g2 Y# @
/////////////////////////////////////////////////////////////////  D1 z$ B1 {9 ~+ I0 ^  l( I
2 d  B* Z+ g. z
NTSTATUS
5 q/ B9 W5 N7 U; ~! f9 P* S) g# `( HKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,3 f/ w; H( J) K& |" y( _
                   IN PIRP Irp,
. ~" ^, D  T. M% W7 G8 ~                   IN PVOID Context )
: s- r) C* n( b. P9 u, ]: M{" E4 g2 j0 B  f9 s# g1 E  `& l
  PIO_STACK_LOCATION IrpSp;
. V0 z+ }% x- E6 [* }  PKEYBOARD_INPUT_DATA KeyData;
' |( A% L5 ~- V# q9 F1 R; t/ q  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ j$ t& t9 z; }1 p/ N                                   DeviceObject->DeviceExtension; 2 r4 h( M" C1 ?' q1 Z
  int numKeys, i;6 h3 B" k" j2 l# `
  KIRQL IrqLevel;
. O2 K; D5 g' J, W8 b. n: w
- T3 [( p; y  f1 c! O  IrpSp = IoGetCurrentIrpStackLocation( Irp );4 l' a. i( w/ i3 W/ @

8 q: C$ u: M6 B$ g' A
8 h+ I! C6 q, c  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
$ @  c  [) q' ~/ V- l) t  {# k" D2 a) E% @- t( h) G
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );+ S& D% F8 T2 Z
    goto __RoutineEnd;
& i( A5 Z+ p2 R5 s) |7 _# @  }& \! S1 @2 J9 y* a0 X1 J. I
* _3 A. ?  W# E
  //
6 P; g6 c+ W  g+ \& Q  // 系统在 SystemBuffer 中保存按键信息! k6 j- S9 L/ h* i+ o4 G- \1 p# J
  //5 P" S1 e9 r! }$ K
  KeyData = Irp->AssociatedIrp.SystemBuffer;
, Q4 P5 B( I+ [( P  if ( KeyData == NULL )
- e. r* o3 t- X+ u  {" s' m% p$ M! O2 f* O6 ~1 R# e. ^3 B# B
    DbgPrint( "KeyData is NULL\n" );( v$ {6 C; S* G; P5 K7 D9 a, o  o
    goto __RoutineEnd;0 L* v( X1 I2 S! X: D8 E+ H5 E
  }6 Z6 k, N: k4 ~2 C- G& j9 K
% Z* |7 W1 t' l* f1 ]5 u0 C
  //" E4 i. s  S$ @# K7 ?
  // 得到按键数
- e& X% p8 _# z" n' T/ L5 k. r! V5 ]  //6 @2 w, _# {! q4 D/ Q
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
6 O2 w( `! I$ A! w* v  if ( numKeys < 0 )
9 G' U. \, m5 v, t. `8 b; ]6 E) }: a  {/ o0 b. P7 m- y4 Y0 D
    DbgPrint( "numKeys less zero\n" );0 E& [$ R7 u1 L6 s- d9 C6 p- H+ t. C
    goto __RoutineEnd;
4 v/ h$ c+ M4 b9 w. a1 I# S  }2 |- S2 L& o) T$ j5 z: c

& a1 G8 r' E$ `2 Y$ T; |4 p  //3 `% ]/ T2 @) x) A" x
  // 使用 0 无效扫描码替换,屏蔽所有按键: z% M2 D4 g3 h* n; \6 `, R( S( A" ]
  //
- z, L  D9 V* X/ v: m1 ]  for ( i = 0; i < numKeys; i++ )$ x2 P' _4 C* ]: d
  {+ c' ?1 F9 R9 Q" }
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );( o7 K# a$ Q2 F( n6 q
    KeyData[i].MakeCode = 0x00;0 ~+ d9 p7 y2 y1 M+ p
  }
/ S8 n$ G1 T, H/ ~1 Z" \
+ O( ~1 Y/ q+ q) b$ C
# N* b7 `& }9 e: ~+ k, d  __RoutineEnd :
' G+ J' u, z( B8 l% i7 `7 n( U
/ d+ p1 _- O5 J1 \# u  J  if ( Irp->PendingReturned )
! O$ u6 o8 a  X3 ^  {
- e  g; T. p* [* g4 |: z    IoMarkIrpPending( Irp );' Z) D6 T9 A: I) t
  } ' q; R; [% u% ?! F

/ X3 u& M1 i9 d7 l5 `  //( u: |; l6 \% G6 S
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
& D+ ?" L# `7 o) ]7 N  //
7 W; J2 Q' a7 Q8 \6 t* G  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
$ E" J, y/ c( H9 @  InterlockedDecrement( &KeyExtension->IrpsInProgress );0 I7 @0 F" q4 t9 o# e, Z2 L
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
1 p& K6 g8 Q$ p" F; j9 a- q; b- F3 J2 _9 a% k" y) b* f
  return Irp->IoStatus.Status ;
. ?/ O7 \1 A. p# `}
  P3 E* Q& |1 g7 \3 W4 x3 E2 Z2 p5 p4 G8 b

/ d( {% ~1 \- e( x  Q+ t/*****************************************************************
' w0 c# e% F1 d! L( X; ?) e2 L 文件名        : WssLockKey.h
$ @( N2 P- {- g; n4 n. {7 t 描述          : 键盘过滤驱动; j6 w! e  W+ I8 g* l; U
作者          : sinister
$ d) o9 |7 G7 R  q8 t6 E 最后修改日期  : 2007-02-26
2 c" {; Q0 X; l0 ^2 G  b$ {*****************************************************************/
; i) \1 G, [" l# b, b8 D' T* Q3 s1 e, Z. I
#ifndef __WSS_LOCKKEY_H_
, ~9 ~( ^' |4 d. _0 O: z3 D: q, h: \#define __WSS_LOCKKEY_H_  {3 G0 _6 D5 z

/ V: d% M1 J* f/ C5 l6 p0 |#include "ntddk.h"! K6 R3 I- ?2 U2 W* B
#include "ntddkbd.h"
3 U9 B! t% G0 u#include "string.h"/ O5 X$ \$ E# C' f" O
#include ' K/ |" T5 a1 C9 R0 R) P
4 A" y# M( n. ]4 ~
#define MAXLEN 256, L# E! g% Y; o9 D

# N. |: d* i9 k# z: ?  ~#define KDBDEVICENAME L"\\Driver\\kbdhid"
0 D( V! \) ]( ~- |#define USBKEYBOARDNAME L"\\Driver\\hidusb"
4 k" q; }+ z# E# X* M#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"3 X7 @8 s  {' I, w

: ~  k' ]$ I1 Etypedef struct _OBJECT_CREATE_INFORMATION% w+ A2 k) v' g" {/ p  p" N
{
9 P+ I2 J3 q+ X0 R" z    ULONG Attributes;- m) _  y; M- Q0 N% r5 j. c
    HANDLE RootDirectory;9 s+ {2 s& T( G3 O* Y
    PVOID ParseContext;$ A/ L0 D% R! X7 ]3 b
    KPROCESSOR_MODE ProbeMode;
4 u7 B0 j' d, `7 r8 y. O& P    ULONG PagedPoolCharge;4 Y6 W+ t6 X4 i; W4 v2 w- `# W4 u
    ULONG NonPagedPoolCharge;4 _' S) v* Q" K; X4 U$ ~- V( q
    ULONG SecurityDescriptorCharge;
7 s. T' E% ]; f$ C/ H/ ~    PSECURITY_DESCRIPTOR SecurityDescriptor;
8 ]" \2 s/ ~. ?1 l    PSECURITY_QUALITY_OF_SERVICE SecurityQos;/ b4 [4 e" _' @9 X$ M; U% M" m: \
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
+ h- O' O1 s+ @% M, W6 j% V: G} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;( A% J+ }" i7 o4 l
% @# }# K+ s: Z1 ]( {* X9 ^# k4 i
typedef struct _OBJECT_HEADER
5 k/ {" ]) p* `' |; g{
* `# K! {) {/ x6 w8 w( Q    LONG PointerCount;
/ d3 f. O: J3 ^& q0 T7 d% V    union
) P/ u" C% k* R2 e0 s; \* P    {
$ C+ y2 b" w) [( d% p% E8 y; n        LONG HandleCount;
  |- q% [5 |9 N7 U        PSINGLE_LIST_ENTRY SEntry;
5 K0 w$ o% `  T' {( V# e8 r    };* G6 N3 ]* k' Q8 p/ g
    POBJECT_TYPE Type;
4 T% U# o& }9 v, ]: s/ T1 y2 W/ Z    UCHAR NameInfoOffset;- B- g( H3 @  P/ T6 f
    UCHAR HandleInfoOffset;
4 C6 n/ O' h) u. F* \; [    UCHAR QuotaInfoOffset;9 Y8 `5 y& X7 r  E
    UCHAR Flags;
: i  c$ N2 A( k! n% I# A3 n/ Z% H    union
5 w& Y# v, v, p# p# v1 ~3 E    {
+ U2 m6 z) B) p" J# }, z        POBJECT_CREATE_INFORMATION ObjectCreateInfo;( A/ T7 N9 Z% e0 ^$ T( e! g( l: U/ I
        PVOID QuotaBlockCharged;8 z. _0 r& d( O* Z1 F6 {& t" b
    };) y3 w. I! y8 f0 J9 H2 B

! h/ ]7 W% ?3 Y7 @7 ?0 {7 ^    PSECURITY_DESCRIPTOR SecurityDescriptor;1 G0 r/ j+ K- J4 u& I1 S
    QUAD Body;5 ~& e& O6 c( t" u) N/ W) P
} OBJECT_HEADER, * POBJECT_HEADER;; Y5 n, o+ x. A+ |/ e& G# a

  H1 ~# B3 m! U# f. B#define NUMBER_HASH_BUCKETS 37
# t# a5 V: s3 C; K- @0 B+ H; L" F5 B! z0 s/ i
typedef struct _OBJECT_DIRECTORY; ?5 J* |' l/ ?* J3 Z- [# K
{" `* ?; F# m: E3 Q8 x
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];' h+ Z$ D# i& Z; L# a. v
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
. x* l! M# l$ ]    BOOLEAN LookupFound;8 X' L1 o, B6 x0 W% i2 r
    USHORT SymbolicLinkUsageCount;) E, m, K5 f- z2 _
    struct _DEVICE_MAP* DeviceMap;
, K8 U3 a( o9 Q' E- c) j) u% m} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;: ^' A5 y3 a. Q6 }* t; c! i
6 o  g0 E9 f8 e$ k7 V, N% n
typedef struct _OBJECT_HEADER_NAME_INFO
! ~  S& r; k( v6 A" \{
0 E, _! K- H5 j0 p: ?) a5 _    POBJECT_DIRECTORY Directory;
4 _+ v2 I7 I6 N/ k& `7 L    UNICODE_STRING Name;3 M( E" x- o% Z7 p
    ULONG Reserved;
0 O1 p1 H+ Q+ Z, T' E#if DBG
. E& u2 R  P; W4 P. g. i2 ]+ v    ULONG Reserved2 ;! k$ @7 H. ]6 K  l7 L, M9 `; ]4 G
    LONG DbgDereferenceCount ;
) b+ ?2 |+ O1 ~9 E5 ]+ f- p#endif
1 D4 j6 I2 _: c5 r} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
+ A9 E8 g& n; ^8 e+ H" y2 h! g9 \6 \" V5 ?
#define OBJECT_TO_OBJECT_HEADER( o ) \$ G# ]- p7 b, _. {) ~. s/ m5 c. z
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
/ y6 ]* b0 L2 T
$ Y- P5 W* q- {' U2 |#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \+ a( ]8 j# q$ a" a6 y* i
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
! V5 s9 N' F) N+ ]$ i2 }- o& ?( V" c. e; D1 a, h/ @1 q
typedef struct _DEVICE_EXTENSION
7 j+ D3 m$ ]. \{+ E8 M! H2 _. X& h
    PDEVICE_OBJECT DeviceObject;- G% w% i( \" ^
    PDEVICE_OBJECT TargetDevice;7 H3 K0 R/ O' ]2 `" y( ^: H+ \1 c
    PFILE_OBJECT pFilterFileObject;2 g- ~5 W/ f* D2 s% l, ]' m8 \
    ULONG DeviceExtensionFlags;( U- x: y5 _. }: s" k
    LONG IrpsInProgress;
( R' n0 f- C5 p. H5 D: K+ A    KSPIN_LOCK SpinLock;
( o! W7 F% Z. S7 {( `; A}DEVICE_EXTENSION, * PDEVICE_EXTENSION;! a' X' D) m. T. D  ~

' }! j, G5 H5 L+ s7 U" z
  O5 Y2 B4 M) M8 m# o! \8 w  h. hVOID
( ~: c# s$ i) S0 D# k( c. ]KeyDriverUnload( PDRIVER_OBJECT KeyDriver );" f# g/ w# e7 R- y& Y9 x# x

, m. W. G( a1 q0 _* Q& W! VBOOLEAN- _; [( p' i6 f$ q; N5 |7 V
CancelKeyboardIrp( IN PIRP Irp );' ?9 f- h( s5 c9 q8 Z( v5 n6 w
& U4 D5 z+ \) @. M+ J% ]  ?: ^
extern POBJECT_TYPE* IoDriverObjectType;
* C" J+ x8 R* m/ ^
$ I' p9 W6 m0 f. N, `NTSYSAPI
0 x& k& A# M  e( ^% \  J" J6 NNTSTATUS, M8 j( e3 ~8 @+ d8 q$ ^! S
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,  i$ W" [5 _' V
                               IN ULONG Attributes,' b" V+ U% T5 S
                               IN PACCESS_STATE AccessState OPTIONAL,) `# F6 ?1 i9 u4 s2 Z3 C
                               IN ACCESS_MASK DesiredAccess OPTIONAL,. P. x/ u: N$ N! y$ p+ C/ |
                               IN POBJECT_TYPE ObjectType,4 O0 n3 n0 t" e
                               IN KPROCESSOR_MODE AccessMode,. n" X, d* z) b6 T. v7 k0 N
                               IN OUT PVOID ParseContext OPTIONAL,8 c3 Q* O$ W" S& x" _
                               OUT PVOID* Object );
* W! V6 w) |' Q4 P7 @
3 z6 X4 ]( W9 @$ m0 UNTSTATUS ! B3 l8 H6 s1 M' E% o- [
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
% K9 \) e5 M  D8 K1 @' i
& _* W- s, e7 O7 @+ E2 LBOOLEAN 7 s1 z* l4 s& G3 i) ~+ O- H
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
( Z! y- J  {3 ]$ @" v1 M/ M1 c7 r" ], _  @+ i
VOID
' i* o8 D! |/ X: tGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
8 d6 R1 `2 |6 T. f0 a" o# n& J' D
NTSTATUS 9 A& j. b& ]) s. u4 N! f
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
- W7 h" p3 n* S2 ^; S& h                                  IN PDRIVER_OBJECT  DriverObject );
. B- S) v1 M2 {) J1 V6 l: U; y  ~4 I. n3 s( M5 h
NTSTATUS * h4 Q4 @1 D" K4 Z
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,3 G$ n. g" ^( `
                                  IN PDRIVER_OBJECT  DriverObject,# m. _' E8 n; a- n! `( {7 N
                                  OUT PDRIVER_OBJECT* FilterDriverObject );. e- C( E; T# W& c8 d  j

$ m, u6 W, n9 A. }6 X# X  j' U3 mNTSTATUS + M9 J2 I8 Q, `3 A) Y/ `
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,2 r, V% Z/ d1 M" F2 r$ t% U
                            IN PIRP Irp,- |, C7 V% r$ |/ |* \1 J7 {
                            IN PVOID Context );
2 ~( B* t6 H/ \9 T. t( FNTSTATUS & z8 U1 e  X) o& u6 N: v" O
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
1 v" T  |: u+ m1 }& q, `0 f1 Q) S5 N( Z
WCHAR szUsbDeviceName[MAXLEN];9 Y; J% M8 r$ i8 b$ G

& E, ~" S' x# q  G8 ?#endif
, H/ y! x2 Y: _! I$ a! a4 e# _4 g7 A' g/ B. Q

; R, ^! e* Y# D0 e8 F4 u ) I5 v) F0 \3 C6 T( \
% C; e2 B, \. q& }* W9 t% \
( L0 s; i+ U2 D: s9 q1 f8 t
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
4 R/ N; t: t) U, {4 v4 DWSS 主页:[url]http://www.whitecell.org/[/url] ) ]: p7 g. Z  c; o1 t6 Q6 ]
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-24 22:37 , Processed in 0.045269 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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