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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister+ y+ p3 ]5 J  l" `7 V
Email:   [email]sinister@whitecell.org[/email]
  B4 q6 o' \4 u# bHomepage:[url]http://www.whitecell.org[/url] 1 l8 e( ^( P3 V+ `: p) C
Date:    2007-02-26
) ~4 H% I5 u% u' d1 m
. o3 w% S* v. G
# O& ^, ~0 K" G) V/*******************************************************************
9 S* f; b/ a1 E7 b8 D" }" d0 w- ^& @  ]& e
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
& [6 H, q1 D; D9 f2 W3 b# P写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的+ ]2 ^- C2 p* v9 ^% E
功能要求如下:1 s3 `% \6 \8 _- n/ S6 `( u* y
" @  J' f5 a0 j/ r
1、强制锁定键盘/鼠标。
5 e6 _$ e; b! n! ~$ `4 Z% C2、可动态加/解锁
) a9 l4 V& T1 m, a. Y3、兼容所有 NT 系列的操作系统。: _$ I3 @+ M3 w, h) n
( g% |, [6 _8 b+ e* s
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实% b8 P3 |; R- k6 D4 U6 f+ @# _
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如: G3 F6 w. @* p8 T$ m; F
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
: J8 R  ]8 u+ d  F1 o上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是! q7 c) D8 W4 b3 s
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面, E) X; c( d/ E7 d9 H- C
就来看一下我想到的几种实现方法:6 x4 Z0 Q# p+ ?7 d: e' V& a% C
" V3 n, G" a) `( L0 I
1、全局键盘/鼠标钩子: C$ K" H5 `& Y8 [! O/ {5 B/ `
2、BlockInput() API; d$ D" D& j$ v# c
3、使用 setupapi 进行控制
' n7 ?# n$ |, z! j4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL# q' H. K2 ~: ~( L
5、拦截 win23k!RawInputThread() 函数9 D1 {, [! p+ A( U! l
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
1 L% N# \8 Q3 q. H7 M( Y; W% J; s7、拦截 kdbclass 驱动的 driver dispatch routine3 A3 A" z" e0 p0 E/ Q
8、实现一个 PS/2 与 USB 键盘过滤驱动2 t. F* o# t8 S; }; O; ?: c
! N% E* P( L! {- B$ y9 \

% B& |+ {# s2 r6 F9 M我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑" ]  Y- M9 n- W2 [. ^$ N6 G
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方: h& Y  d: o" [" X0 d& }; c
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
/ t4 H4 m( _6 M0 W兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因3 E; r' w8 G# s9 Q' U& J
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性: ~; _' V7 e) B4 I  U  T& b
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
$ b( I$ w2 h; g: c2 V载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
  M7 C  `. [. D+ A- F8 h的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
+ V- e8 e( m) l! b9 G/ x; f也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
5 B. i, W% I3 V9 l" A8 p6 h  e% |果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有- D- G, x; V* R/ ^
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
' I- y3 x, p7 Q# pIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
2 X) R; g+ o/ r! }+ r) ?; NUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
) i9 Z. \+ p' ?4 i4 I6 i: m* A盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
+ H/ K! Y) L: ]! [4 N$ m案的全部功能且不存在它所带来的问题,否则就没有什么意义了。; `1 N" j. r1 ^0 I$ E
* g$ k, ]& M" B" r

* Y3 Z3 I' u' M我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
4 W& J/ v* Z. W" l+ f# U% x$ u8 ?滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进8 _) X; J5 @; p" h0 t0 o
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
  O0 f5 H6 L2 q4 y9 k只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越* s% b' h  P; ~8 N6 N* B
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从+ q4 h- W0 S9 \" D/ G3 i1 U
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB& G: D3 N; Z  |
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
1 X6 D( h, K$ {6 W0 h2 }! C9 YIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,, e# ~- Q, u$ ~
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
9 g; B) u- K% F2 n6 m. M5 r就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的% V6 c& L; N2 S# S1 j6 \
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使3 \) o  p. T& R
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
  F& _8 X4 t5 c9 f) g过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
1 I& V/ A! Y8 B6 C* }" `0 o6 `屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通7 h/ Z4 U1 \5 {) g! G& Q! s* z
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb4 e, f$ {* D! b, Y
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 3 c( ], |1 a; Z8 L  F
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
4 g% ~8 b7 C+ c3 b- u; f) L' h% M味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
* d( e$ s+ L8 K! D! u& P& ^经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
2 M- E7 E7 B2 O/ F5 d* w/ a来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利- L4 ]; V7 r: o* S  y% a
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo1 j; ]3 x4 J5 l3 S8 j5 N
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
/ y$ p& F9 A4 d+ |! I" A敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,7 T# r7 N( A) O( P3 N
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
' E& |5 z7 b7 s3 z' z1 m见下面代码。
  Q$ }+ I3 n/ M( B9 s: ^/ v; i9 o+ U4 N1 x+ r' E- t) n
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程# O- q4 Y0 H$ n' @. ~# b* O4 i) Y
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
1 ~' n7 ^- F8 M. v! e盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
; J2 M6 u! |' G8 |) `# A上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
/ m2 g0 i  a, [1 m" s% l1 g完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可5 J8 o. K: G' q& h+ I% k0 N! S& C
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
# W7 [; E$ D" j3 M7 t! [/ Q% r锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按* W0 u; K/ V9 ?5 y: Z3 b
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
; j. T5 g; n& {8 O+ i/ w' [+ T* [, Y( P. D; T+ t
, H9 A! A$ E9 o  X
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
0 q5 E' y( J2 L3 M- ]* \的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
: ~; u) D6 X( G9 l/ \可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣) [+ X, t# G$ f# e; a/ q- `
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
* [1 n6 _0 y- c们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我, ~8 b. Z) Y/ m9 k
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension. }& O; h. v; J* _  w' g5 M5 v2 E
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
. u  T6 M$ h, ?/ a! x; Q如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
" g% v. m: v; Y4 P8 ~- A进行操作了。这个问题有待大家来完善了。
8 L: u. S9 V9 G  U8 ^  m9 J! Q& S5 P& p, D% `5 ^
$ ]  A6 `! Q- ~" Q6 e8 J) F2 {
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
6 Q. ]6 i# u7 t+ v4 H来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的& _) d8 k4 e! V8 C/ j" S3 ~2 E5 h8 P
分析做个记录而已。我更愿意把它看做是一段注释。
- b5 {& W) `0 ?# Y
  ^; |2 Q" `2 |2 W- t. }) S$ a# z最后在此代码中要1 f+ H6 o9 O/ j: p4 g/ t# {$ \; ^$ C* e
6 o! [; w4 Q, E+ o+ E" _$ L# e* v! a8 T
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。1 L9 u5 g3 j4 ~

5 m" t$ k3 j2 L4 p8 B: h% k感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。% x0 n$ }! C% f& K; f
2 G$ S7 w% N+ f
感谢:齐佳佳,过节请我吃好吃的。
! n4 ?) {/ G6 L) a7 S6 t( O9 ]2 ]% |' T: }, a4 n
6 B! S4 z- c2 k: H0 L
******************************************************************/3 ~- ~9 O. c& ~

+ R+ R/ O. ~) h1 d$ [9 e3 x& ?  x# \* S* g3 j1 x, ~, D' \
/*****************************************************************
$ t9 P& |/ s2 @# B2 U  E 文件名        : WssLockKey.c
; W" a2 V+ v8 }* [7 l$ p( a4 ? 描述          : 键盘过滤驱动
; m2 @' c, ~1 z- g 作者          : sinister
$ w2 z1 P0 L  K+ T3 e! d: x5 w5 t 最后修改日期  : 2007-02-26
" B8 e1 N2 a& @! h*****************************************************************/
2 v5 {- ]/ k3 c; ^3 o
/ C- ^3 b+ F- E: q3 E8 c+ ~" \5 {2 V
#include "WssLockKey.h"' q4 z2 ?2 F, t# u- ]# G
+ K3 S; y, U% [
NTSTATUS/ v) m$ s) j- C& n, E% Z* ]5 H1 D* x+ W
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
2 y9 G; f' O2 Q; a% [) u3 V4 S# g             IN PUNICODE_STRING RegistryPath )
5 Z) S; ~" j, l9 k! J' e0 \{) }! N# M; M. d' h& x; q; Y: U
  UNICODE_STRING KeyDeviceName; ( L" C0 {# t8 Z: i; n7 Z
  PDRIVER_OBJECT KeyDriver; 6 P+ X: G& e, [" k7 d2 x2 k/ c" Z
  PDEVICE_OBJECT UsbDeviceObject;) J+ R8 F# {$ ^" G$ Q) E
  NTSTATUS ntStatus;
/ v' \& Z% f6 J2 \+ Z" _9 i* E+ n6 J/ r  ULONG i; , I/ ?5 s) Z  j5 Z
, B( u% ]- V! N9 J$ K3 D
  /// _# ~  y. y( e* \: u
  // 保存设备名,调试使用
. {3 `2 Y6 J* P: m7 F' t9 ]: p  //
4 H5 H2 K; ^4 ?# ^4 y; O# g  WCHAR szDeviceName[MAXLEN + MAXLEN] =
2 l( F4 m, _, D$ T! r6 t  {6 z* t( {: e$ V$ A3 A% r  y  E( E( P
    0
/ P" c$ E0 _+ ~0 w  };9 C# D. C5 d- Q- o8 J

, G! w+ ?5 T& F. \6 U4 v9 v1 i, Z  KeyDriverObject->DriverUnload = KeyDriverUnload;
2 h  U% v7 ^4 X1 ?: n
0 n2 Y7 K2 {8 g0 I" ^+ F) \  //' D; ]+ r4 U9 i- n* b+ v, g
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘0 {# h$ U9 c; `5 ?& a' x1 g
  //* P" @. E& Z% z$ _9 v, ]. r+ S
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法8 Y% Z: \( K6 u: K
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其- m3 L% |# X# S( v8 m; D# T
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到+ L% n( U- x8 B5 Q# v; z
  // USB 键盘设备来进行挂接
: m, ^& l1 [- M& I# V  //3 r, ~! W" O- ?, ^1 Q
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );* I* a: _+ k! e5 |$ z
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )/ b3 ]1 I/ D' w5 b
  {; U! x2 {1 f! n5 ^4 w% |
    //
( ?9 S. ]  r2 C2 ^    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名# b, ?8 j6 A- Z, U
    // 所以这里打印为空) Q; C4 c4 a) ^0 g, {
    //
* n* o* v* r+ _. I3 {3 ^% M" i1 t6 x    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD8 ^; s: T. m1 t
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );% y, `$ o' f' q, G5 H& V6 j
: _( X, o$ v3 X: y: ?
    //% _" U# D9 d2 X" m/ y1 d
    // 挂接 USB 键盘设备
* s. y2 V; i9 P6 ~: z0 P    //
$ d& o0 [" k$ C6 |$ U) {9 D    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );2 m. b8 {. o1 |1 b* E
    if ( !NT_SUCCESS( ntStatus ) )
1 s0 v5 s- t9 e; v0 m( [    {! j' q/ A( _: _$ v. m9 F) t& B0 V6 H2 v
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );% c: [$ Y) f) n" F
      return STATUS_INSUFFICIENT_RESOURCES;
! H! [. G$ I' F2 @1 m( \3 j* E    }
* p4 l" ]% D: \0 _  }) b: `1 c" {+ Y* p- I' [3 n* d8 q
  else
$ Z' y" G, ~& O- k" R  {% ?( s! m0 M, n5 {: ^- ]0 e
    //8 f, K$ w" D* t; q: R
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
% {; q! I9 `- W$ @    //
# b2 ~# R: F* F. b% _    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); : N3 }8 L) n7 R9 }( h. B6 J9 S

! `; c3 Q( J0 s) }  f% z    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,4 V2 b: c# Y3 m8 I5 v4 m
                                        KeyDriverObject,
, }+ O/ e% W3 r$ q                                        &KeyDriver );" {/ G* W3 l! s" b, y8 P
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
1 p) H; j1 C' ~1 C    {
/ F0 r, @+ V6 e! I  G" ~' ~; v      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );3 M/ x- t, z* g* X, A! y
      return STATUS_INSUFFICIENT_RESOURCES;
9 t- U/ i, j: M2 _3 L6 r- w    }9 U7 Z  w2 E* l4 _" B4 F# M8 Q+ n
  }& r, m! R3 u& R3 P: w0 k

* e7 Z' w* }5 v" ]8 R  //
6 T# b9 ?' q! V1 `. z1 ~% D- `  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止  S& i4 w) m- z0 L2 S8 S
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程! s3 Q7 k% N6 g4 K5 D6 S0 G! d
  //1 s8 o4 ^9 }! e: `: J$ L
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
/ t9 f! y$ y; j6 }
# G; A! k; F" y7 w6 x$ v9 D  return STATUS_SUCCESS;0 f' ?" c& Z% C
}
' B/ R7 P& n( Z+ j% X  I" `5 K2 r# w- n1 K
/////////////////////////////////////////////////////////////////
6 h$ T1 V; |" \& b3 Q! d1 D// 函数类型 : 系统函数
0 b8 e" D8 z8 T( Z' x+ U3 `/ l// 函数模块 : 键盘过滤模块9 B/ i6 k4 _5 i
////////////////////////////////////////////////////////////////1 |+ Q: J$ D0 Y: ]9 C
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
1 l- D. N1 T- w1 |8 _( n//        卸载键盘过滤驱动
+ J9 t/ y) j6 c4 u- Q2 R! [) y/ V' e// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
4 W$ w/ d9 h9 o% A7 v8 [//        则需要等待用户按键,以后有待完善+ q& G- a6 o1 H- r9 J, j# d7 m
/////////////////////////////////////////////////////////////////- h7 v; Y4 b0 K" ]  U+ B: M0 F
// 作者 : sinister$ M0 x/ t9 s) ]( C& w( |% a
// 发布版本 : 1.00.00
* P1 _% J9 X+ g' z( [// 发布日期 : 2005.12.279 _# B0 V, G! ~* ^+ P8 G3 c
/////////////////////////////////////////////////////////////////% u- v, y" ^/ |# ?/ V
// 重   大   修   改   历   史
- w5 X  \! V! Y9 P( A////////////////////////////////////////////////////////////////- m5 N* Y, l6 w2 Y! L% c9 ^
// 修改者 :5 K) H! g8 y7 g! K: p# u- n
// 修改日期 :$ ^/ H/ |" a/ j( n+ d1 B  t
// 修改内容 :
- s1 O# t( O8 w3 q' g: x/////////////////////////////////////////////////////////////////$ }2 c. |: R& _  B* x4 F4 f  s4 b

/ [( x9 |3 [% h& L; u9 n$ BVOID
9 N! g$ S- B; ^0 P- wKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
6 A" {( V) ^0 g* e% O{: W0 ~" a' [* T% j  q" ~; f6 r* L1 p$ o
  PDEVICE_OBJECT KeyFilterDevice ;      - W0 z& G; v" d9 h2 f8 R
  PDEVICE_OBJECT KeyDevice ;
0 l: a( n* |3 c, L: [9 l/ N- z' n  PDEVICE_EXTENSION KeyExtension;
: }9 I( ^# j. M" Z% K$ p0 v- R" V  PIRP Irp;5 T/ g, w* p. r( @; G0 x
  NTSTATUS ntStatus;
% S+ j6 o5 V5 R9 v2 E) {: f0 m1 Q& M8 _
  KeyFilterDevice = KeyDriver->DeviceObject;
: P( R) w7 E) [, {! u, Q( M% f  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
# ~- z+ U( `1 a: T  KeyDevice = KeyExtension->TargetDevice; 2 R4 [- p& o! z. Z. y5 k  X2 J- O

+ F# l0 }3 ^/ F4 i4 ?: Y  IoDetachDevice( KeyDevice );
8 t! ]0 D2 X3 _. b, q
; a3 x6 }" I" I  //
( P9 I- E! o+ x1 A- M+ r  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
& h5 ?/ r4 L+ u  //
5 H2 _- k% A$ |7 @5 _3 }  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )5 ?" B, g6 p' |8 e; Z$ e
  {
8 `, |* D. }. w' x    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
+ G8 j7 T( ^+ k    {
3 n2 N* u. D' u' A      //) T' }0 W5 k. b
      // 成功则直接退出删除键盘过滤设备; z  R: D) [0 [2 ~: v
      //+ K3 B1 x- }! V" B+ ]- |3 w
      DbgPrint( "CancelKeyboardIrp() is ok\n" );8 c6 w) q1 ~9 ]6 L1 t* P2 h
      goto __End;8 q' H/ T$ T! X
    }" I* F2 T+ t  J0 t+ l9 k$ x4 x
  }
6 P2 y( m- j0 M) [8 C6 Y
# Z6 T! z, Y+ D4 ~# l9 E6 w, ^1 F  //
( s6 E0 e0 m9 q. p% U4 n" ?  // 如果取消失败,则一直等待按键0 z, N  I+ x+ N# I# y1 z
  //- ~, {5 D- T  b& ~& E
  while ( KeyExtension->IrpsInProgress > 0 )
8 A8 A& q$ y/ Z: o3 Z! z7 C  {
; i$ y  _3 u+ j% B    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );+ V9 r4 v" l  a  [
  }) J8 u* V1 H# I. U  a% }3 H

7 @8 S2 h$ v" I8 }0 {" h# Z9 ?  __End:& y' ?" T& t2 p5 m- _+ F& }. N
  IoDeleteDevice( KeyFilterDevice ); 6 O/ l: {/ ~0 p; o5 W, h

: O* f# O# C" b# |' c+ M; E- H( v  return ;9 [& S( |% I9 X% [
}
. |% t7 A- `2 ^0 y9 J2 m( t
# C7 h' Q  J' B/////////////////////////////////////////////////////////////////
/ s2 u1 F- A4 i, \. e2 `// 函数类型 : 自定义工具函数
. T5 N& h# A9 @4 C& A1 _4 l// 函数模块 : 键盘过滤模块
% H) S/ N& h0 b/////////////////////////////////////////////////////////////////
# U, q, F& p' D" {2 B+ X# ~# Q// 功能 : 取消 IRP 操作
6 ]$ m( p3 O! p4 ?! f" Y// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能& G/ ~- S4 i% E7 K5 {' l6 Y
//        使用此方法来取消 IRP. Y4 W2 j4 f3 e3 g8 M8 n: B
/////////////////////////////////////////////////////////////////
+ A! H$ |: K' J) s. f// 作者 : sinister
- R0 n% W3 i, C* A' e# n; u1 y( P// 发布版本 : 1.00.00/ a9 l+ [6 b2 |5 b3 n" z
// 发布日期 : 2007.02.20
8 L. x/ x4 D' S: Y* B9 u; G/////////////////////////////////////////////////////////////////5 n; u. f0 C# V& N
// 重   大   修   改   历   史
( [& {2 s% S9 C( F5 Z/////////////////////////////////////////////////////////////////) c6 m0 k+ f. Y; q1 t
// 修改者 :
& Y5 e2 P4 ?! [& }// 修改日期 :
1 _, }$ J) |' ^: `. [// 修改内容 :
: z0 u0 `6 C& I) O- y/////////////////////////////////////////////////////////////////9 b- l# {7 V: {* ?. _' t1 q9 B5 l! e

# f# f/ ^4 F# vBOOLEAN/ r, b' a/ s! k: w) S
CancelKeyboardIrp( IN PIRP Irp )
# _/ C- s9 E/ C, B2 I' P{
6 E% j" M  ^6 G1 d  if ( Irp == NULL )( V: B' `! n! h  d
  {
: q5 }/ N& l  X- _; P) Y" W    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
* m$ |/ b# ]* I: @" b* _    return FALSE;
6 p& h9 W- ?8 _6 V, n' _/ x  }
# k9 l: c  `1 C( c4 m
# H5 ^4 d2 u; S" |* }$ ]& A, R- w4 B/ x: _# \; K
  //
- `6 m- B9 r! ^6 `& G% U6 q$ P  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,/ a# `3 a* h/ _  M# F
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
, m: c$ k3 S3 ^% q0 c/ w  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占4 Z: Q/ z  [; c0 c
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD/ o2 P" W9 {! c9 d- F
  //' z. \+ w: P8 I

- r+ R6 K4 b1 O( s' ?' X- b  //
/ _' a" Y5 Z& b& H$ R; t  // 如果正在取消或没有取消例程则直接返回 FALSE
) K% Y5 [# ]8 d6 U2 ]/ Z" h1 ^  //
2 ?2 M0 t# @" K* \  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
3 j' A# U/ A9 ^: a/ J3 }5 I' G+ U  {* \$ @5 K0 L- P: U8 n# l% w6 t
    DbgPrint( "Can't Cancel the irp\n" );- y5 p* y* v% @2 j+ {; s* z* @
    return FALSE;* w8 `; Q: \+ q. J
  }
6 X$ z8 |8 b9 A$ K6 n7 H# N
- Z/ O- B0 h: @% z  if ( FALSE == IoCancelIrp( Irp ) )
/ G( T& T# F) R% l) i3 @% V  {$ v) T5 G! S0 B' W
    DbgPrint( "IoCancelIrp() to failed\n" );
% V% M  [9 q1 _' k+ ]. r    return FALSE;
- a3 _0 c) e0 W, @% R  }
' G  p! Q' v* _: Q7 n$ s) Y7 d% e# c5 t0 d5 t- n
  //0 n# n1 V0 ?& N, B3 z. _
  // 取消后重设此例程为空
( l  w0 [. ]$ V. H8 v2 `# c  //
) M5 V+ Q" \- i( ~, R9 Y, D  IoSetCancelRoutine( Irp, NULL );
: R" G1 |. V( ]" `: ]8 c: g
$ D2 o# R6 T4 W7 T1 |  return TRUE;
. y! y. p' g: Z1 }}1 s: L( C0 M3 Z% \) X! N/ O$ |  ]
3 r2 ?- v" z5 ~
/////////////////////////////////////////////////////////////////) E. R' ]& g7 S5 u1 N5 A
// 函数类型 : 自定义工具函数
4 I  s: u% ]" Y) b1 q// 函数模块 : 设备栈信息模块
. @7 v9 Z" ~& B" D% e( ?////////////////////////////////////////////////////////////////// U4 p8 H5 T# I. R9 j  ?$ C( U
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘7 t/ i4 m, O; r( Z
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)% ?  b" P: G$ |. r1 i: r2 d
// 注意 :
& [/ }. n: q4 I, [" ]4 Y! O/////////////////////////////////////////////////////////////////
6 ]4 K- r3 i' J8 e6 H$ ]6 }/ P% U! ]// 作者 : sinister
1 O7 L- H7 x. V  i- H// 发布版本 : 1.00.00
6 E3 D5 j( o4 r" B# i: [// 发布日期 : 2005.06.02
$ _* w2 O. y0 x4 e8 J* {+ I/////////////////////////////////////////////////////////////////* `. n( m9 U' m/ R! r! P+ F& r& h
// 重   大   修   改   历   史
  o3 n9 h, S3 Z6 f) f/////////////////////////////////////////////////////////////////
$ k2 w0 b4 w3 e: l9 t# k0 k4 n// 修改者 : sinister
, y( _0 q( Q5 \4 U// 修改日期 : 2007.2.12
+ J% _7 b5 R  P// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改' L/ E- \7 d$ ?' ^, }
/////////////////////////////////////////////////////////////////
$ b7 d6 P1 t! C  t; r$ k% a, w2 x# z4 A/ X) c1 k
BOOLEAN6 Z5 o* i. q7 `6 ]" J6 @3 `9 G9 Y& P
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
  Z4 X+ O/ F# W4 R5 u/ O9 |; F{/ e7 r6 }6 R' n$ Y) n& J; I/ d
  PDEVICE_OBJECT DeviceObject;
; l+ w' Z+ G5 ]5 b" w! H  BOOLEAN bFound = FALSE;' @. N3 C2 P+ R0 f

; R8 ~; G0 G7 |' }6 t3 m  if ( DevObj == NULL )9 Y( w( j/ t  w! U  \& y! `
  {6 B/ k# S% h8 k# e7 i, Q. [3 B
    DbgPrint( "DevObj is NULL!\n" );
+ B' M% ^0 }  B+ S( F) Y    return FALSE;8 ]3 c3 L+ f7 h6 H+ s
  }
7 x. u% [3 s5 G0 m( E- p' S. r$ q: P3 ?0 u) s' b( b+ H# e6 d' }
  DeviceObject = DevObj->AttachedDevice;, U# Z. r6 s! ~3 C

" g/ m( x' E8 U" g! Y5 E  while ( DeviceObject )3 G! \+ Z' G  d- H: R4 Q4 v
  {
) E1 j: G8 i1 f( E    //
8 D% p: E7 ?5 {" o% P! E    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
3 X3 {2 ]3 U' _7 {    // 有一次足够了。这算是经验之谈$ W3 ~. U3 S3 m% H# W
    //' @9 ~) C* ~- u2 y/ a2 X# l, D( x
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) ): d$ U% u6 z4 S3 }' t& h9 w- W
    {
1 x5 q6 F% q' t: H! \( d      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",2 n, w- X$ R6 |8 q  B, Z3 m8 l
                DeviceObject->DriverObject->DriverName.Buffer,
, u  y  f( H  _) ^8 m6 u                DeviceObject->DriverObject,
2 z, Y) B/ ?. p0 X( A1 \                DeviceObject );6 ^$ b9 I! b; a  D# I7 ^

% U! u' X$ K2 N0 H  k+ s! l      //9 U$ k# a- e, C3 v! d5 V
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
& @6 \0 z, r) `      //
8 E: F: U8 W- |) Q      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,# F) t& c5 s$ P4 [9 ^
                      KDBDEVICENAME,
( _: n6 ]& Q6 a* F                      wcslen( KDBDEVICENAME ) ) == 0 )
' w/ l1 p$ ]& L7 y% u7 e4 J. T0 o      {4 T6 ?8 G/ o1 X4 [- g6 o1 A
        DbgPrint( "Found kbdhid Device\n" );
! Z; t/ Z/ o0 o        bFound = TRUE;
$ K7 x, w' K( \  s6 {5 J. y+ M3 X        break;/ a$ g+ N# ~8 z
      }+ |3 U, m7 `# h5 W
    }* p, V. D" q+ G6 v" j0 b
( ^7 u5 y+ u1 O# |. b7 O
    DeviceObject = DeviceObject->AttachedDevice;+ |0 E- \+ y) U3 R- U$ m) N3 Q
  }
5 M$ Y5 [, h0 @: F
0 N7 V/ r- c7 D; A/ z8 x* @& x  return bFound;
! j3 ?" a2 q6 \  E! C) S}+ Q& D& S. k) }/ ?
$ i" K3 \5 d. ~
/////////////////////////////////////////////////////////////////
) X. F- j. ?% v// 函数类型 : 自定义工具函数
# D9 l; u& U, W/ h8 f/ H! d; G// 函数模块 : 设备栈信息模块) w0 W. ?0 E2 L, v
/////////////////////////////////////////////////////////////////
! g0 Z! K; b& I2 ^3 n+ n// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
/ |2 ~2 a, L/ ~# Y: u+ |- @// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改$ u- Y4 c( [7 c7 _- p( k
/////////////////////////////////////////////////////////////////; F& F5 ~' L/ ~$ O, H8 W
// 作者 : sinister3 V1 |7 q+ S' v+ q/ J, E
// 发布版本 : 1.00.008 f9 }. U( a, f
// 发布日期 : 2006.05.022 X/ Z8 U& F) W
/////////////////////////////////////////////////////////////////1 y4 v$ O, y3 J3 i8 N. T7 I
// 重   大   修   改   历   史, U1 R- ]/ J: F+ y" s* D: W2 O
/////////////////////////////////////////////////////////////////
0 W, T/ X) A) {// 修改者 : sinister7 q; k. Z& K. o, I( p
// 修改日期 : 2007.2.12
# ^2 r& K/ ?9 g* P// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
3 ]) `- H3 i) u" [+ K/////////////////////////////////////////////////////////////////
# C% k: K: ?7 k% {5 m% J5 U
0 s8 Z" j( g, O" J+ z- V+ {VOID
' E2 b) @/ J3 |8 P: B# V6 sGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )" {2 [/ r" z; s) L+ ^8 S
{
4 u5 t$ E8 u6 d, B, t2 M! B: W  POBJECT_HEADER ObjectHeader;- t8 b  j9 x& c
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
$ M0 y6 ], v3 y5 Y4 u" e* w+ u; v' D: n; @/ ^2 {' J0 M' e
  if ( DevObj == NULL )1 B# F7 `' W# a5 [- c9 t  Z! W
  {
4 @  L: O  @, z5 X3 o& }    DbgPrint( "DevObj is NULL!\n" );
7 h# \4 c% M. W2 u0 V  Y* c# X    return;
- _) b! C9 J6 {* ~9 I" B6 c7 }% V  }$ }$ X. y* \% ^8 `' G: J( s: a

4 i1 Y/ u7 P: L" ]5 J1 W4 f& C  //
4 p8 e) h* B2 y  // 得到对象头
+ x1 y8 _0 [5 d9 t# ?  //8 P7 A! Z0 J: ~; m
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );  D* T' \  ^/ ?2 ]5 P
5 v1 @7 V; Y& `# }9 M( r
  if ( ObjectHeader )
# w8 U1 U- H# O& {  {9 A+ p2 g7 {  b
    //3 E# P) k2 ^7 c, A
    // 查询设备名称并打印7 S  c( }9 A9 s. e# {( ~4 K
    //
; ^! M$ o3 O! M6 m    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );9 @+ G* ]+ |. T) y4 c$ C
9 [, l) [" v# F! }6 _
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
# A0 v) v9 w  J8 F/ u    {
3 |2 `% w+ x1 {5 u$ {; T      DbgPrint( "Device Name:%S - Device Address:0x%x\n",' r7 A! I$ O  k4 W
                ObjectNameInfo->Name.Buffer,$ A4 E9 h6 X/ b
                DevObj );
+ c' U; c: _: |  r  R3 q* b3 D5 O0 i% U  ^  S0 R) j5 y: z
      //
1 l9 l( I  a& f$ z6 A      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
$ t8 z# c8 k5 }: F# @2 Q      // 用,没有实际的功能用途% V! t! L1 ?% J4 _
      //
7 L7 E. l4 ~3 E1 ~      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );4 T7 a! {% q. E& _8 r5 {

) M) Y$ z% K# ?* x4 t+ B, }  d      wcsncpy( szUsbDeviceName,
# e* B) u6 L2 S               ObjectNameInfo->Name.Buffer,
" k: A  s" w9 q1 H3 y9 m               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
& @" L) [: {5 L2 T" d3 p    }
6 n4 h/ N/ f8 c/ o" ^' k! j! T$ f+ Y( e; r; l- y( ]4 S
    //
$ n. v) I& ]8 n, h    // 对于没有名称的设备,则打印 NULL
$ p' @+ ]% q+ M+ L. y$ K2 I, N    //
$ s, _$ O+ v% _9 N7 O, q    else if ( DevObj->DriverObject )
$ [" \5 l: Q- H* [0 v  B    {
0 w# i9 b% M8 V) a+ O+ H1 c      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",6 o" y' P# i0 Y! e
                DevObj->DriverObject->DriverName.Buffer,# T, D+ t# P" ^+ {* ~
                L"NULL",
7 Z* x8 y6 j7 Z' }' K                DevObj->DriverObject,
2 _( [$ q% i( D* `" ]9 J' y* V                DevObj );0 p+ Y# `. O7 r( `
    }% `7 ~  n5 e& U# j% D$ Z/ o
  }
( f; @1 {& M- H$ `8 ]}
4 |3 T" L+ {1 p$ w% R) A. k0 [2 S" I2 _
' F9 e+ Q( ]& ^: X& a/////////////////////////////////////////////////////////////////. H4 E3 x0 g- _/ y9 w% k+ z
// 函数类型 : 自定义工具函数
( {5 W3 _# O3 P0 G6 q- ~. g0 w0 l// 函数模块 : 键盘过滤模块
2 @* ^6 U; \2 l. [5 T  Z# I/////////////////////////////////////////////////////////////////) o: b4 q9 T& C/ O- t: x
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备' A6 S. ~) k( D
//        对象,过滤出 USB 键盘设备,将其设备对象返回
2 b) j* n& M- c1 p+ n// 注意 : : `7 z1 z5 T# r* B7 ?
/////////////////////////////////////////////////////////////////$ H/ |) A5 H( Z3 j; [6 h
// 作者 : sinister( t; Q( d5 h2 k
// 发布版本 : 1.00.00$ c- b5 O& d( J$ @, t: F8 T) x: S) t
// 发布日期 : 2007.02.13% s$ P' h: C: i& d% ?" b# [5 @- }1 P
/////////////////////////////////////////////////////////////////) ?$ i9 _- D0 F% @; P( ~2 T4 f
// 重   大   修   改   历   史  c7 z* n9 R% O0 @1 e
/////////////////////////////////////////////////////////////////
. l1 ^+ k8 ?& |6 X: }// 修改者 :
. E+ u, l# e( b3 v6 {// 修改日期 :
7 B, }( z/ K( h; R9 _// 修改内容 :
) O  p4 ?, i" |# a/////////////////////////////////////////////////////////////////" @2 W( c5 g* M! z5 s) ^2 D) c
, O% {' ~" C# v2 z" z
NTSTATUS3 b6 x/ k$ M- S; q2 Q/ m% G
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )) m/ D7 z1 _" }1 R2 h
{% J( I+ G: }+ I
  UNICODE_STRING DriverName;- {) ]0 b& j; t) c6 b  l5 ]
  PDRIVER_OBJECT DriverObject = NULL;+ A4 C6 X8 B1 k8 \/ |3 N; {
  PDEVICE_OBJECT DeviceObject = NULL;+ J+ Y( ^. r. J/ v
  BOOLEAN bFound = FALSE;
" R* B3 l  r0 w% A
$ J' V7 F5 k2 q+ r  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );& q1 P" T# q; ^0 [( U2 y9 u
" {6 X( {; ]( I! t' P2 z, t
  ObReferenceObjectByName( &DriverName,
0 F% X& f2 T+ u" I# l1 R                           OBJ_CASE_INSENSITIVE," \' ?5 Y  M! H& ]& h) s# y
                           NULL,$ s% O8 M- a$ y$ V' m
                           0,  Q% ]+ k3 ^2 r
                           ( POBJECT_TYPE ) IoDriverObjectType,
3 F. M* ?. ~$ P+ ]* N  {" G1 [                           KernelMode,
: C0 o4 A5 q) k3 _                           NULL,
( b# l6 I7 |5 K0 p) ^! ~                           &DriverObject );6 f3 I6 S+ @" C9 B* u

" `6 f. S, ^# I$ a& }2 `) ~8 G  if ( DriverObject == NULL )9 H  u' D" D7 E
  {
$ [" }3 c: M* n, X4 m0 [! S; n    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
* ?6 B" M1 R$ l; v9 r1 o% g    return STATUS_UNSUCCESSFUL;
- e' ]0 F/ p6 }% ]0 F0 P) h# ^  }: F0 |. I7 Y% ]
8 @- Z# L+ A) d6 M4 \) \3 s# H; A
  DeviceObject = DriverObject->DeviceObject;
9 x# O( {7 Z/ D: `1 ?# t
8 R- J) O5 J* N. G6 t% }  while ( DeviceObject ), W5 S' M! w* f4 ]: I
  {% @7 e" T5 {1 ?' I
    GetDeviceObjectInfo( DeviceObject );- g$ ~& r7 r1 m1 h% e: q
% l2 {. x3 r  J+ }: `" i& \8 K
    if ( DeviceObject->AttachedDevice )
8 n2 S* K1 L; e7 O& v    {
2 J2 ^5 m  d- l7 S9 m' n/ g# q( y      /// k, Q! t, W3 ?( S& ~
      // 查找 USB 键盘设备
1 N3 T) h! S. H( h- s7 h      //
( ]- K2 ]% X9 [: ~0 V+ ^      if ( GetAttachedDeviceInfo( DeviceObject ) )
" @  V, e0 D9 ]5 g      {
0 m3 E/ M% r2 G. @# r7 k        bFound = TRUE;( B3 L4 `. j/ a% B% ?
        goto __End;
: N6 ^* g$ V9 f0 y      }9 P/ Y( [' ]* \) a) U! }
    }+ Q+ M$ T; g4 c) n8 N/ {
1 {6 ]. R/ [  L/ T
    DeviceObject = DeviceObject->NextDevice;
; A9 c$ K& d3 Y* U! i, g  }/ c5 Y+ w# f7 _# V+ j5 b, r+ d
! x) a5 Y$ G7 K
  __End:
/ F  z, v! Y( }8 K  f9 W1 x" n# C, B! e) m" O  |: \
  if ( bFound )
' b* u$ T/ J/ V2 [) x* m  {$ l5 L! f6 X9 z! x% \
    /// C: H/ z9 T3 ^( S; P
    // 找到则返回 USB 键盘设备对象# Q, @9 ~& n8 l! c
    //
# w" ^( _1 |0 M    *UsbDeviceObject = DeviceObject;- J& J* p4 g0 }2 ?; K$ G
  }
; u$ e4 E- B$ t; M- {( \: p7 ^3 L, {  else9 s3 K# j. Y1 s7 F& f
  {8 L1 J7 o8 D( Z( C& U3 Q5 m: W
    *UsbDeviceObject = NULL;6 z: b- S: @5 B# n% I
  }
' s0 c' Z9 [5 V& ]2 P& Z* G- m+ T2 h  y8 ^+ Z5 j' `, a  \
  return STATUS_SUCCESS;! p- X! z7 l: T+ B8 j9 B5 R
}
; v0 f4 w) N: d' m- ]
1 t3 {7 h2 @3 N2 Y. [( q/////////////////////////////////////////////////////////////////
+ b. [4 y& r9 l// 函数类型 : 自定义工具函数
) I1 L# x  v7 q' @! n* c' m7 T// 函数模块 : 键盘过滤模块
! m- W2 ?/ W' y4 |% H# b& p////////////////////////////////////////////////////////////////
6 y) z, K0 K' {# L/ |1 {8 j8 G// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
% y% _8 i5 s9 G2 O+ F4 I: n0 C//        信息,返回附加后的驱动对象
2 x9 k. w: r9 g// 注意 : 此函数仅挂接 USB 键盘设备3 o2 W7 i- M8 d; w$ v$ }+ X
/////////////////////////////////////////////////////////////////& t5 y9 q0 Y* V5 k
// 作者 : sinister
" B7 N, U, z9 l  [8 e1 u// 发布版本 : 1.00.009 m3 d2 i6 q8 T8 \2 B
// 发布日期 : 2005.12.27# R1 R8 k( U6 D
/////////////////////////////////////////////////////////////////, G$ d6 B$ S0 m3 N8 E
// 重   大   修   改   历   史
0 H& \% }$ h% t9 h% C8 ?4 a: B% q////////////////////////////////////////////////////////////////
- |% m( o7 a" r5 P// 修改者 :! D8 T3 C" t/ o2 v; b
// 修改日期 :8 H' W3 K7 B8 \, L8 g4 e
// 修改内容 :
! N' P* F- D5 V" O6 P0 r( e- ]+ ]; A/////////////////////////////////////////////////////////////////
2 [6 W' S% ]8 U' |, S8 [! U
1 O/ \; A) M$ F! V0 D* v% kNTSTATUS' ~' E1 b! u2 j1 C* S8 L
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
1 }* _! q) s3 w# d2 n- S( w! |$ o                         IN PDRIVER_OBJECT  DriverObject )1 I" E/ Y* {/ M5 R( u8 Z
{# i. H) L, U: v2 Q& s  r0 B4 G
  PDEVICE_OBJECT DeviceObject;
% y; ~- p" ]  B  PDEVICE_OBJECT TargetDevice; 1 z7 r+ s' {9 U/ i
  PDEVICE_EXTENSION DevExt;9 D0 z, {) [% t; ?2 u- Z
  NTSTATUS ntStatus;3 H8 H3 ^0 M5 x: A! c" N

6 T) h( Q( R* i7 ?" p1 i& c  //
! A& @+ F5 w3 Z! G  // 创建过滤设备对象
8 M2 a6 F$ Q) _/ A- P  //3 d2 `( c- ?" b# D/ I
  ntStatus = IoCreateDevice( DriverObject,
, \) U, |! B9 q% E                             sizeof( DEVICE_EXTENSION ),% F% R! m* e5 _- ?
                             NULL,
! P6 e8 w- e, q  I                             FILE_DEVICE_UNKNOWN," \2 O' n" @2 y, L9 ?1 S2 p
                             0,/ p5 J- p* K  L3 ~- u
                             FALSE,
3 c* r9 w4 s9 ~( g                             &DeviceObject ); % n* o3 I% X! S4 _6 v* f

" E  u0 \1 L: A+ \$ p* ?/ w% E  if ( !NT_SUCCESS( ntStatus ) )
+ @3 z6 p3 K# S4 j5 x3 Z  {
- j8 }1 A% a9 d+ F  R2 I+ R/ s    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );: v7 V4 J8 {! z2 u
    return ntStatus;* s" t2 L  T4 B: b
  } 3 B/ |/ f9 ]0 K3 j

# z& A* a+ V0 |$ o  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;5 F' Y- A' V2 B) v# k. q
1 [5 T, j9 o; g8 C8 u
  //
4 U+ x: b* n8 T+ ?  // 初始化自旋锁8 R2 ?5 z+ e  G7 c* H3 V
  //
" V  P1 ~/ w  m1 f) I  KeInitializeSpinLock( &DevExt->SpinLock );1 n3 S) _1 m1 |2 h: R
- {$ D8 a6 n1 d+ G/ m& }
  //$ `* c% \. D' i
  // 初始化 IRP 计数器
3 D5 S; O) b& O# G  J  //; |% b/ a0 }3 G8 |9 U& H3 k! U
  DevExt->IrpsInProgress = 0;
/ X. u; N! c6 ~, m  N
) F, k# m6 F  y. P  //0 z3 k' V6 ?0 n' p/ @
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
1 n: ~2 u1 h3 L1 T  //
" _! E+ g2 y; d8 M
0 Y  s  x6 b0 @) f  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 7 @' u1 z, q, ?
  if ( !TargetDevice )
0 Z; {! D( p5 v5 ^- R  {
. ^& u- _) w, o. i- H: `    IoDeleteDevice( DeviceObject ); 6 D2 R3 g! k3 c  S& s) ~2 X
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
* N/ |3 \8 x, S3 N& t    return STATUS_INSUFFICIENT_RESOURCES;; ?4 u$ e( n) R! \, G/ X7 O1 L
  }
+ ^  H3 h, B  w$ y7 W' d, P0 o# |5 l; T; S3 ]# Z4 ?
  //
, K- G6 Z  D  C8 R" J  // 保存过滤设备信息( O  f& F7 s* B2 k, Z% J: @
  //
1 R% o3 d0 g: e6 p7 @  DevExt->DeviceObject = DeviceObject; % o/ `2 ]# C% e$ _
  DevExt->TargetDevice = TargetDevice;
! H! B2 H2 v, c6 ?) E4 ?1 ?
- C: W+ e; Y) b! B* W% b  //
2 x& P0 Q* S3 r  p% Z3 q  // 设置过滤设备相关信息与标志
' u/ _( d3 T) R  S  c" W" `; L  //
- A: Z; f: n& x: S, i5 n  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );( @9 S0 p4 {7 q* p; k* J4 n- z
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2 ]5 s- N+ S. U( z3 M. g
8 R  q$ W7 j: b; n2 j
: b! Q' P, H4 v5 e- V  return STATUS_SUCCESS;
* n& s. o+ }! Q# \# |  j2 A}1 y) O; z$ q' G9 _
& Z) \1 A! O9 a. x( _% E' f+ Z
/////////////////////////////////////////////////////////////////6 Z- k% s5 `# G2 p/ T$ `. T
// 函数类型 : 自定义工具函数
" N- G4 @, z2 e. v) v, @// 函数模块 : 键盘过滤模块
+ N* W/ K5 O3 v) k/ ]////////////////////////////////////////////////////////////////3 ~; H' d$ V/ y) C
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关$ |5 ~2 \2 P+ Q/ A
//        信息,返回附加后的驱动对象" z3 S7 D1 H1 R
// 注意 : 此函数仅挂接 PS/2 键盘设备% ~) |7 o1 K6 c
/////////////////////////////////////////////////////////////////
* i: c4 d) g. p// 作者 : sinister
# H7 R( ~5 e! w" x2 y5 m* x2 r5 a5 O// 发布版本 : 1.00.001 k  a/ j- n: u+ R! U4 R
// 发布日期 : 2005.12.27! }; N9 H) j: y& Z- a# c" K! {
/////////////////////////////////////////////////////////////////
, |% `5 k, o( T0 ?$ K2 b// 重   大   修   改   历   史
# I% B6 t2 u0 f- k, c" Q////////////////////////////////////////////////////////////////$ a, Y2 C6 \7 e6 M
// 修改者 :3 \# ?4 R, Y+ ?) r) F3 }& i
// 修改日期 :
  q; E6 W2 T  k) a) ]$ R// 修改内容 :
3 E9 c7 K8 R3 }- W/////////////////////////////////////////////////////////////////
( v0 o1 g" B- q; U" U
, Y3 u# Z! ^% L4 sNTSTATUS2 l5 @! Q2 ~" w# q( @2 j
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
( T: I0 _8 u: }                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象, M% T+ v& \& W7 n+ q' z7 y
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
! |+ `9 K0 W. f{: @- F/ w9 s1 {
  PDEVICE_OBJECT DeviceObject;
0 `- V1 e8 G4 C5 g' g, [! q) e- a# r  PDEVICE_OBJECT FilterDeviceObject;" q" z' \7 o$ |! [* e9 y7 z/ t
  PDEVICE_OBJECT TargetDevice; 2 t1 W4 E* k# V* b! p  I! i5 H) |
  PFILE_OBJECT FileObject;
2 c1 x& O4 p3 w# l$ _  PDEVICE_EXTENSION DevExt;# L& K8 |5 ^8 d, I; |

  `& T  i! w3 W% J  NTSTATUS ntStatus; 5 P/ u, d# b& h& t. y6 d
) h% c3 Y/ }, F0 q4 w' T6 z
  //
  I9 }% n$ `0 ~- K5 s  G$ e  _  // 根据设备名称找到需要附加的设备对象
; ?: }+ K8 ]7 Y7 ^' `2 e7 M  //
, j9 r4 W, R8 k' n" B, z! Z  ntStatus = IoGetDeviceObjectPointer( DeviceName,
: Q1 H; o0 }* c                                       FILE_ALL_ACCESS,0 ^9 P1 Y8 ?6 T3 L
                                       &FileObject,0 i1 I; I6 B; u3 Z& w
                                       &DeviceObject );
- A) d1 v# w: F! Y; I) W
$ _% ~1 H" ~) S7 g7 H, H7 ]  if ( !NT_SUCCESS( ntStatus ) )1 T+ L0 |# \3 m4 ^2 v
  {. ^) _9 n4 R  a
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );# H$ K% V  E( n
    return ntStatus;
0 g8 W* W; _* \' [  b! H  } 9 D( ?. F" {3 ~; u
# d/ {- F8 `- G
  //( A. V: U3 R, N* V
  // 创建过滤设备对象2 Z4 I2 _: M& p+ W/ H; K: z) |
  //4 F* [. t0 D% |2 [
  ntStatus = IoCreateDevice( DriverObject,
/ Q% z5 z8 }  l8 I9 J7 S                             sizeof( DEVICE_EXTENSION ),: o' |* r# Z4 L+ p. z7 u7 j
                             NULL,
+ \! V& f4 e$ c9 Q7 k; N2 K                             FILE_DEVICE_KEYBOARD,, A1 G/ f, O5 r0 [" ?
                             0,
# j* w6 o/ S, t7 @4 V* \                             FALSE,
8 m# g, l+ {1 G/ }# p, r' P                             &FilterDeviceObject );
' ]' [4 E7 P9 o  Y- o8 B* X
$ V6 w# Y6 Y. w  if ( !NT_SUCCESS( ntStatus ) )
; \& O8 L1 M  v1 w  {: W& E; Q* A6 [" F
    ObDereferenceObject( FileObject );
- p1 @% l5 i) j5 l8 E    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
. ^4 h' N0 M/ Z+ x    return ntStatus;9 X8 @5 ^" W, |& l  w' m, d9 r
  }
9 q1 S7 g* J0 L& ]. L+ r. Q9 E: Y  R& Y0 z# i# E5 V
  //7 m' R% v  r( P' {9 r" s  {7 C
  // 得到设备扩展结构,以便下面保存过滤设备信息
/ Z1 G& F- Y8 [, S  _0 o  //  n; a1 S* N( E  p5 p# Y3 l; @
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
1 W4 M( s  T% ^8 w+ U& L: ]- X1 m. \, u! r6 d4 l
: |, ?. H9 F. ^; T
  //1 Q9 R% d. @; I2 D3 d
  // 初始化自旋锁
8 w3 x/ Q, D$ O. U4 A* U1 a  //1 w4 d- y& u) G0 {1 H
  KeInitializeSpinLock( &DevExt->SpinLock );
9 M# R+ d) M2 s) j: h9 O4 \' J7 N; P  l% t1 ^) g
  //8 m7 l1 i; ?( M* V$ v
  // 初始化 IRP 计数器
7 X/ m7 r" y1 z5 ~1 E# Z- j  //( H/ m' j, n" ?! G
  DevExt->IrpsInProgress = 0;( U' {8 u9 q& J2 x

! X4 s' o, }) H! m, f7 L9 B  //
  }# @: l' _# T+ P  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
. M8 h  v8 J4 n# _4 \) [6 h1 e' t  //9 w+ Y' B+ P6 i" n+ f. M
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
  g- b' \! B' |/ ?4 j                                              DeviceObject );
+ t9 h7 l) @. q- [  if ( !TargetDevice )
& O: r1 V' I8 C0 k* n4 K1 v8 R7 `  {0 t* j* o$ G$ b/ Y/ _
    ObDereferenceObject( FileObject );
* g" l7 x3 T9 T% c& e& Z$ W    IoDeleteDevice( FilterDeviceObject ); , K0 V( z9 U( ^  T& W5 m3 _
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
. ^. L. j9 S4 a6 S9 t0 @7 W- P6 o    return STATUS_INSUFFICIENT_RESOURCES;' r7 O, v) ]+ {6 ~2 ~
  } 1 K& t- W0 S; z" S' V( F
6 O7 i) r' `5 S
  /// P7 @/ P- i3 N; H# |; }
  // 保存过滤设备信息
2 [0 {9 e" ]/ b. _4 l  //8 T7 ~* Q5 L0 M1 P: B. v8 r
  DevExt->DeviceObject = FilterDeviceObject;   S" O$ ?& f) i) l+ F: o: ]) E
  DevExt->TargetDevice = TargetDevice; 8 E) [" a( E( E+ {
  DevExt->pFilterFileObject = FileObject;) @1 v- Z) n- v( t
/ C0 U! y; c- I9 C5 I) X" w
  //
7 m& _' j2 u. |. O- e5 N+ ^  // 设置过滤设备相关信息与标志2 r6 F) [) r/ z3 w0 `
  //3 [5 }. h" r( ?; ^( S; n+ S  }& W0 d
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
- T6 X' d6 ]. _0 ?5 o; m  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
0 Q9 I+ Q% U: g1 _6 F4 N  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
5 Q& K% Y1 V: J1 n  `9 N  W  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
$ U3 l/ N/ P* V! S) j                                                         DO_BUFFERED_IO ) ); 9 K8 J9 g5 ^' k' U! k$ |5 J/ V0 ]

. X. y; g, S! ~& F6 j9 p  //
4 Z- l6 }3 T1 p8 [  // 返回附加后的驱动对象0 X, e1 J6 c. ?1 \1 q& O
  //" H+ O$ h  t9 M7 T: l6 H
  *FilterDriverObject = TargetDevice->DriverObject;3 }: A5 }" G: w3 @

8 R& h4 u+ v/ \* U8 c  ObDereferenceObject( FileObject ); 1 J6 o  O* D* u9 i, y7 n6 F
! u. i  E9 f6 h# u
  return STATUS_SUCCESS;
( J* S. [5 k' M. m. Z: c* h}
! `0 _7 u0 B  s& r  F. l$ D
7 ?* d) A" Y# ~1 C; x/////////////////////////////////////////////////////////////////9 T+ ]( n+ i5 ^9 D, r+ I4 B+ P  |( T
// 函数类型 : 自定义工具函数6 o: p* E1 k& O- k/ Y3 d+ `! i
// 函数模块 : 键盘过滤模块# C8 m9 w3 e" \9 I
////////////////////////////////////////////////////////////////
/ O, p4 I! x6 ]% D3 U) I// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发, `" S, u$ b4 r( M
//        这个 IRP 的完成$ Z$ @# d! H/ P
// 注意 :
( y. M; w3 B7 O- H7 ], ~' `( s! f; K/////////////////////////////////////////////////////////////////
3 p3 Q# j$ h( `, `( K" u& T5 D; i// 作者 : sinister
. ]. {2 N+ F# Q( T3 ~// 发布版本 : 1.00.006 b7 }9 l9 U' _; `1 R4 F
// 发布日期 : 2007.2.15$ L4 P7 ^- p# G! N
/////////////////////////////////////////////////////////////////' o9 C( X# m7 `
// 重   大   修   改   历   史9 d) z7 y+ ^& E  u# B
////////////////////////////////////////////////////////////////
0 K( b6 i7 ^& T& I' @) w) e// 修改者 :
; x6 O* z% f1 I2 e, X// 修改日期 :" n" U6 k! d2 ^* J
// 修改内容 :
6 V3 R! g+ W$ x& z. y2 G2 ~/////////////////////////////////////////////////////////////////
' r) P/ U; m$ r9 J0 v9 X0 Q5 E; Z. I4 M2 T1 ~
NTSTATUS
$ M" W' p  @$ q& YKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
3 R* k  R5 w. M8 f0 }{
. d; |6 D, M7 ~  NTSTATUS status;
5 v  M! t' r" p5 p8 T9 z- b) s7 f) p  KIRQL IrqLevel;
1 `9 p; x* F6 s! j; z$ P& i2 z( q" U+ s  W& [. B
  PDEVICE_OBJECT pDeviceObject;% v! E& H$ h7 I  t
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
' D9 f  ]" e9 j! s5 t                                   DeviceObject->DeviceExtension; : u8 t; M! l$ b& M, b

+ s5 t) |: i: _; C+ q5 N9 r9 ?# |# S! C7 R$ [
  IoCopyCurrentIrpStackLocationToNext( Irp );, y# ~  p% T9 m3 |0 ]. B. N4 E! D
4 H5 a: M# q1 Z6 t( v" K, _" v. M
  //
6 P4 \8 _: M' D5 t0 E& X  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
' {. u& i0 C9 o6 F0 E  //" N( O+ E& Z8 l6 ?+ c
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );9 Y  A" @3 n4 Y* r9 S3 f  _1 @
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
! P; d4 x3 ?8 w' p" ~  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
" s. K+ K3 A! B! v; X0 `1 U4 I
% y* ~% S3 O& o% H! b& h/ u  IoSetCompletionRoutine( Irp,: y8 C  A9 O9 t, b
                          KeyReadCompletion,& t3 U+ y8 A# K0 c
                          DeviceObject," {4 Y7 R/ Y! ]# O* Z
                          TRUE,
; z+ S! H& W) @- o0 D6 t7 U                          TRUE,
8 y6 P/ Z. i, N' X: {8 |                          TRUE );   R* i; A4 A- a/ K! X
& w, W% u+ M$ z" D" x
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
- r8 D! b! }3 n: v# X& N5 u}
: d3 F0 h& L+ `
8 s3 G* {7 q6 T2 I5 f) e& L% U  ]/////////////////////////////////////////////////////////////////1 Z' o3 o& `! y$ q/ ~
// 函数类型 :系统回调函数6 Q! \3 ?+ A, A
// 函数模块 : 键盘过滤模块2 r# D1 U$ a( I3 z2 t0 E
////////////////////////////////////////////////////////////////. z7 F' D9 ]: Z7 m
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的/ O8 h4 w0 ~9 Q+ X. H
// 注意 :
# n' L$ `. n. G1 a1 _5 x' ^/////////////////////////////////////////////////////////////////
* T/ ~& T* G% L- s. k  z+ s* x( l// 作者 : sinister/ U+ o2 O7 ]1 G( l% f* L' [
// 发布版本 : 1.00.00
+ b; J8 I" `6 D5 m! R& v// 发布日期 : 2007.2.12
' f2 C$ W& y0 L/////////////////////////////////////////////////////////////////' z/ |" Z* n: h6 ?0 f! Y5 V
// 重   大   修   改   历   史
1 C& \1 _* H# {( w////////////////////////////////////////////////////////////////& J  ^. c; D( f5 R6 S$ O7 e
// 修改者 :1 J. X% |& E6 e$ ~3 R2 ~
// 修改日期 :0 F* x. D0 `! s
// 修改内容 :
9 Q0 B9 H0 k( z/////////////////////////////////////////////////////////////////0 S* p/ P+ B, i1 x& Y

$ d1 S3 X8 {6 M  Q' q4 xNTSTATUS- M& z9 M! H: v8 F! t
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
0 q& {6 ^7 ]6 ?                   IN PIRP Irp,
/ C# r! w6 Y# @9 i                   IN PVOID Context )
2 x8 F7 f# k: D2 L- {{- V3 N  o2 y- d" C0 [4 D( p
  PIO_STACK_LOCATION IrpSp;
# u  P8 s' C$ c  W& L. D8 [  PKEYBOARD_INPUT_DATA KeyData;( R! O( Q! M6 ^4 `
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ X4 a1 g8 n/ @0 B/ X8 N6 x                                   DeviceObject->DeviceExtension; 6 q+ Z" E) B! }) d* b( B) g4 V
  int numKeys, i;
* Z8 k# c0 X3 F7 Y  KIRQL IrqLevel;
3 R- ~. @( l- Q; O9 I, u2 u
8 U+ L( L. s  z1 C1 a5 Q$ h  IrpSp = IoGetCurrentIrpStackLocation( Irp );
% V6 ~0 D5 @5 T6 h
1 D: F" }4 N6 u8 B
. T% [2 {- J, y, L( k  if ( Irp->IoStatus.Status != STATUS_SUCCESS )) _2 }- L) {$ _( t
  {- w2 q2 k6 |4 i' U$ P4 s! r! x" m% P9 T
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
; t: ]1 H! }, o& L, r    goto __RoutineEnd;* {9 Y  N0 o4 F+ Q! A$ T
  }
0 {  c5 d. \, y8 [2 E* u- M( ~1 Z7 ~! @5 g
  //
; ]& i: z) C* Z9 e) T0 g7 q# s4 ]  // 系统在 SystemBuffer 中保存按键信息/ W# P) f: f0 O; o  n( \
  //" T* O: i% L$ w$ y1 a5 T4 A
  KeyData = Irp->AssociatedIrp.SystemBuffer;
( b- z5 K2 }( [# |  if ( KeyData == NULL )& m# J& u! z7 `6 w$ E
  {+ F- a+ i+ k# _9 m$ @6 }5 u6 v' {0 r1 q; @
    DbgPrint( "KeyData is NULL\n" );
" \9 n. d  }7 m$ w4 y$ E* D- W1 [, K5 N0 M    goto __RoutineEnd;
* t2 k( m0 G% t& D+ d9 G9 x# c  }
; P' L: F* h- Y$ W6 g" W! H. [4 q1 E) N' x1 p2 ^. ~
  //
* y/ F9 h9 K5 [6 p$ p+ y, r" _  // 得到按键数! `' L( r" ~% \" s* G; c! A
  //
5 I% o9 N, {+ f6 g0 o3 B  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );" T6 x1 C2 g( }& w2 Y
  if ( numKeys < 0 )
: `7 m+ T6 @* E: a: `0 X  {, w7 B. i; |7 o! l3 Z
    DbgPrint( "numKeys less zero\n" );$ u7 T1 W9 }! h8 A1 c
    goto __RoutineEnd;
  j* J# L3 p9 a; G& H8 K! q  }
6 ]  `* m% c2 \. R
# ^8 D! E' C2 A( k6 D8 ?/ z  //
* r7 Q8 T" _) a: Q  // 使用 0 无效扫描码替换,屏蔽所有按键- L6 x5 r. K" j9 c
  //
: H, }' k1 }6 D0 k" o  for ( i = 0; i < numKeys; i++ )
1 D! Z8 ~% G/ U1 \! q% f$ E  {
, j# X2 A. q: g3 r' d; I6 g& Z/ O% K    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );% |% T2 _) h3 @# A: `/ H
    KeyData[i].MakeCode = 0x00;, _% q* L; s+ u7 R1 G
  }
0 C6 t. M7 \+ Y' s# Y" G% y3 A
' f) `, R4 n4 V8 ?
  __RoutineEnd : # }5 P1 j4 T8 O3 r/ t
* u! V$ t+ [% d" I8 t9 N* b
  if ( Irp->PendingReturned )$ s; V/ E0 p4 D* E* T6 N% q
  {! c+ }1 x* g7 T; P' L2 i* `
    IoMarkIrpPending( Irp );+ I  H  t4 G% e( @- @7 y' [. f
  } , \* E( T7 X, M, w2 J  h- e
7 e' @) I0 L- m
  //* m0 E+ n2 e. m6 z9 W
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
* y2 n; q4 _4 V0 w0 z1 ^  //% _; Q( y. t& b# x/ G/ |: n- S
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );3 l0 l- O+ v) h
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
# D8 l+ \7 _, m6 W) `/ z5 w  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
. u8 z  Q3 i; l; B9 T0 j% ~# v) y. e$ k) Y; R' m9 @0 a
  return Irp->IoStatus.Status ;8 M. _2 ~1 S" a2 X6 ]1 t
}
: M! o; K; E9 o; P; w4 w3 p& f0 x; g0 B: P* V) r% \" j8 o

$ `7 n# F$ e7 e1 Z9 K/*****************************************************************
- q) {( g9 S3 h# J7 V& c 文件名        : WssLockKey.h) N8 n3 `9 f( f( L; V5 s
描述          : 键盘过滤驱动+ |* I  K  v6 k+ _! c/ q
作者          : sinister0 ~8 a4 g% t4 M7 }! t
最后修改日期  : 2007-02-266 c+ `1 Q: u$ T( o
*****************************************************************/2 C9 O4 Q+ A5 y
- _7 U$ g% G1 U: z
#ifndef __WSS_LOCKKEY_H_
: s0 O7 o+ X( j9 [- e#define __WSS_LOCKKEY_H_3 d2 m. m% I; l; L. r/ z$ F
3 K& ?" g( E$ t2 T* ~+ x
#include "ntddk.h"
6 G+ w" w& `- P7 v/ q# B#include "ntddkbd.h"- m) D! o4 g/ v4 W4 A' Z# B7 i
#include "string.h"
. ]0 d+ y5 Z4 F% y. O#include
  ~) n# ^& D' r
( s/ {! }, u- g7 r- W#define MAXLEN 256. F& c+ n2 s# g* N

' o* d! X( b% V) e6 Y4 E5 d  d#define KDBDEVICENAME L"\\Driver\\kbdhid"  c4 `5 ~5 C" z- g4 m3 U
#define USBKEYBOARDNAME L"\\Driver\\hidusb" % s( J% n# O+ E
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"/ \, S  K+ Y. w. B

: L. ~3 \/ v: X( X, Stypedef struct _OBJECT_CREATE_INFORMATION* E9 c0 w# {* @( G" L7 L
{3 O- ]/ r1 U1 Z6 z
    ULONG Attributes;
9 }2 [( ~+ P, V/ [  i9 c    HANDLE RootDirectory;
- |6 j" P. n% g% |    PVOID ParseContext;/ C2 Y$ b; v$ }$ h
    KPROCESSOR_MODE ProbeMode;2 H( P1 i+ {; M
    ULONG PagedPoolCharge;
& D* a4 ~0 b1 B# P    ULONG NonPagedPoolCharge;: q7 j6 W7 G1 Q! i
    ULONG SecurityDescriptorCharge;
1 ]0 D, X# D4 s; S( b    PSECURITY_DESCRIPTOR SecurityDescriptor;
, p# B3 p- C) V! \    PSECURITY_QUALITY_OF_SERVICE SecurityQos;2 w- p  D; H  s: k8 l
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;  s2 F* k$ I% p0 G; j7 {3 X
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;9 q" g( i$ ?9 u$ }; A3 @
4 T5 a& Q0 l, \' e9 Q6 y
typedef struct _OBJECT_HEADER0 G/ y3 x  z0 |
{
7 j7 a9 J% E, v0 `( L6 r" {    LONG PointerCount;3 ~# H9 j- q0 @1 Q' H+ R6 a
    union) u! h" Y" ~& f  O
    {+ |, ^- F# }# E, i% ]
        LONG HandleCount;
4 J: b( P2 G# O% B6 y1 y2 ]+ a        PSINGLE_LIST_ENTRY SEntry;0 G* n( V8 n9 O: R7 G. w
    };
  ?2 {: W9 c  c- F$ M& H    POBJECT_TYPE Type;
1 Z6 S$ `& a' @. a    UCHAR NameInfoOffset;5 J3 Q" O+ q; F; H; o  q% a1 G
    UCHAR HandleInfoOffset;( \$ H& W/ ~$ x; k# C9 D
    UCHAR QuotaInfoOffset;
6 ]! ?3 x- e7 Y9 N8 U5 J    UCHAR Flags;
0 o" s7 B7 S0 [1 \    union
6 e, p- A: y+ L1 q* H! z9 J& R    {  w' a3 _  a1 G/ u% ^- S( S% K- ]* _
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
9 l; Z4 f( P- \7 e' n        PVOID QuotaBlockCharged;
+ g. O8 w' f% r: k    };
6 W7 W6 _# ~: g  S
3 ~! u0 H0 k0 w7 R% `, b    PSECURITY_DESCRIPTOR SecurityDescriptor;9 `- R- U9 A8 M  t/ h
    QUAD Body;
7 ^+ i$ b5 @4 C( n4 i! t} OBJECT_HEADER, * POBJECT_HEADER;; l1 D" r+ O' ^- s$ M6 n

" y* }- i, _, O$ M& C$ ]) M! p#define NUMBER_HASH_BUCKETS 37% }; Z( E# q+ H
" l4 ^; N/ p( ~" q9 o+ |
typedef struct _OBJECT_DIRECTORY
& V' ]$ O! u0 L! G{! O% \% m" o  z
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];" @, h1 `* M8 ], u
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
" Z1 q% N# `7 F) g: e& O    BOOLEAN LookupFound;
" x2 h( ]! j9 s4 ?$ v    USHORT SymbolicLinkUsageCount;
* W* q! C  y/ m  A$ a* V    struct _DEVICE_MAP* DeviceMap;
6 j+ o# Z, o- N8 d4 t0 l6 P: Q} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;, M  R6 `4 ?, ~" D6 k
$ l4 W% T* \; P4 E. Q
typedef struct _OBJECT_HEADER_NAME_INFO/ H; q- M7 ~; Y  f+ h1 H
{
1 y" ]# Z) t4 J    POBJECT_DIRECTORY Directory;
: L. i3 L4 e, N9 P$ |    UNICODE_STRING Name;
6 W- V8 a- o# X    ULONG Reserved;
2 v. Z- x% d+ W, P; b1 ~5 o#if DBG
6 Y  p# Y: _8 U. X3 `    ULONG Reserved2 ;  q& r9 U- C+ G+ T$ W, b1 }
    LONG DbgDereferenceCount ;
- }# D5 j- x8 I+ z/ S: W#endif
% d) [- G; b/ c6 y0 M. X} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
# l; l, w6 G( w4 C5 ~$ j! B6 R8 X: ]( S, N9 S
#define OBJECT_TO_OBJECT_HEADER( o ) \% J$ O; K1 X* B) q8 D% n/ f$ [- y
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
) R: ^# F3 |2 q4 t: G- Q' ?$ x6 G5 {' R& N# p' L; j$ c! Z: k" c% T
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
: g) p8 }/ k0 g    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))% E8 T# K# X- p! V2 [

+ m, P7 h! k, N' atypedef struct _DEVICE_EXTENSION" {- R( \- e2 z, u3 i% f1 u. _
{
" ~: a8 w  J9 O" W9 F. |5 }    PDEVICE_OBJECT DeviceObject;* Q- J. A& }# t
    PDEVICE_OBJECT TargetDevice;
! p$ Q3 b% z' A9 }& E    PFILE_OBJECT pFilterFileObject;
# I) M3 B0 W/ ?% [1 W( r" D' D6 Q    ULONG DeviceExtensionFlags;
6 J# [1 p2 w! w6 r    LONG IrpsInProgress;
( O2 y0 {! b" o$ V; i: N    KSPIN_LOCK SpinLock;) E9 H0 J. e, |  {/ A# e; y1 G
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
7 z5 s- f, E; x* D3 X: A  ^  L) W1 Y; A' Z
* S; X* j" A2 D7 T/ J0 H9 ~5 ]
VOID 8 ]' j; V% p# B
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );8 |' v+ ~  ^' J, ?2 d
3 b( U, {5 O8 e( r
BOOLEAN, _" D8 Z4 S4 X- {+ V
CancelKeyboardIrp( IN PIRP Irp );* f# O% ^2 ~9 R' K" ?
) C4 J( j9 R% g7 c5 J( p. y* c
extern POBJECT_TYPE* IoDriverObjectType;
0 P0 Y  L# j( d3 H0 g+ r
- Z) x! n2 ~: Q: o: i' z% N) mNTSYSAPI; A8 s, K5 X7 i; S
NTSTATUS' q7 W/ b) p1 H
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
1 F. x* }" C& \- T, M, a                               IN ULONG Attributes,3 m4 e2 y, P7 Q) x+ d8 A. t+ G
                               IN PACCESS_STATE AccessState OPTIONAL,
1 _# k' Q9 P) O0 E, t                               IN ACCESS_MASK DesiredAccess OPTIONAL,3 V# {/ c$ v) ?
                               IN POBJECT_TYPE ObjectType,
4 E8 D. ]% H8 T% N- F                               IN KPROCESSOR_MODE AccessMode,& _  \- {* ?8 x% Z. E6 z
                               IN OUT PVOID ParseContext OPTIONAL,
, P* q% C( x' I+ y                               OUT PVOID* Object );
) Q4 g( n: z! j! e# D! }8 ]: w: j$ p8 c. I6 {+ @+ R! B9 ^- K
NTSTATUS - H1 x! i/ Y& ^2 e7 N
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
: m* r* O. L/ _1 H) |3 A# O% Y/ W0 u& D6 C! M1 I
BOOLEAN
8 j' X* E& l* ?, B7 d1 w/ nGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
2 L! Y2 s6 W! y- m/ q5 r: e+ O, w* r
) C) ?# ?* e3 FVOID
& F* n0 H: i+ |% G5 ~! W) G0 XGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
& b/ M# ?) c5 ~) g2 ^/ \( u4 A) ~' N4 g  Q; z
NTSTATUS & {6 b0 e& k) ~5 M- ^; R3 c$ X6 B
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,4 I- y1 ?5 V# d
                                  IN PDRIVER_OBJECT  DriverObject );! S3 h# w5 V% c0 K& u

4 t6 e& Q  a6 c8 ]NTSTATUS
/ w5 J8 L7 _) J2 _AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,+ d1 _2 \0 H0 b( w( y
                                  IN PDRIVER_OBJECT  DriverObject,6 |, l1 L% l/ F$ i# a
                                  OUT PDRIVER_OBJECT* FilterDriverObject );
. o6 [: q$ v$ a( y( A( G* I: w
  O( p5 W2 J& c, X3 P5 NNTSTATUS - r. U8 ]& l  m; v
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
+ r* ]* i) ^# M7 K" g8 f7 G                            IN PIRP Irp,
& [0 ?. E- A2 x! S                            IN PVOID Context );  }  }" A( L1 ]+ O5 ^
NTSTATUS
1 k$ p$ M9 Q' d( O7 tKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );& U7 A. G, k. z1 J  Q

; n, z: g9 }' q6 KWCHAR szUsbDeviceName[MAXLEN];1 C* o, i2 {2 i0 L

1 c. {% V+ [% ~5 C3 X3 G#endif
* u" m8 B6 _2 e; q$ ?9 ~4 Y: g9 ?4 O0 E3 |
) L5 A0 t2 l' `* U; ?' R

5 {! M, f# A9 ]! }3 @
# w# O# o  A" i$ X* s& u5 A) o( `; {! P* r9 R- R3 |9 M
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。  t5 I4 a+ H' y0 j) M  N- y- L" |, |4 _
WSS 主页:[url]http://www.whitecell.org/[/url] , A2 Q9 o. |+ I1 Y" t4 W
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-3-15 05:22 , Processed in 0.604242 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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