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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
+ u6 W+ O  v$ M9 }$ b4 kEmail:   [email]sinister@whitecell.org[/email]! y5 y% Q; r; x$ S) k9 _  L- ?1 a. H
Homepage:[url]http://www.whitecell.org[/url]
) z+ _' f/ A5 I' VDate:    2007-02-26# b/ f+ I4 S9 [- w
3 b  d8 w7 e% f: T* D4 T7 N

; a9 g# E9 Q: Q, s; U4 L4 O$ r' O/*******************************************************************
" u% ?1 F4 E0 @7 \7 {8 ~1 D4 I2 g6 p! {% |3 }7 J- u& k
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx$ I0 m& @# Z- K. J% Y7 n
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
) w9 U: w) K# m3 g7 H. v, t& x功能要求如下:' E. L2 e" h" i' \/ W+ U0 r* z! Z
0 |" ]8 g. G% ]; P# p3 s/ `' V
1、强制锁定键盘/鼠标。* d9 i. _4 K2 l  g
2、可动态加/解锁- Z+ f; C2 l+ @7 |3 I2 ^- ~2 I
3、兼容所有 NT 系列的操作系统。5 v+ k7 ^1 c2 p+ Z: l

+ x9 |/ L1 W4 D) C就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实. s3 W% `7 s( q* j' P
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
! b  J2 K& s& P3 D6 u" q& V* E! j  l何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在# @& |  ^0 y/ W2 p2 o* e
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是" n" h( r- ?# U% r% x* F! T7 e
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面9 P. p+ q; q/ N% W0 ]! C7 o" }7 A
就来看一下我想到的几种实现方法:5 q& ~8 x# c4 d9 D
1 f3 g. |$ Z$ |
1、全局键盘/鼠标钩子% J9 ~! X! X) I8 t( C! s
2、BlockInput() API
1 c6 i% t( r9 D5 s8 o9 M/ P/ C3、使用 setupapi 进行控制
1 f6 B( K( {. v8 E. |' z% E/ `) @4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
7 T) Z& f, G4 W5、拦截 win23k!RawInputThread() 函数4 q3 W1 L: A. |! N" W" Y/ L
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
; N( j! o. R% I! m% A. U9 P7、拦截 kdbclass 驱动的 driver dispatch routine
4 j1 v2 P4 [. {' X  {& h8、实现一个 PS/2 与 USB 键盘过滤驱动
( s- c( W7 S; j9 E; @# Z) S" {+ l

# C2 `- w; C8 r8 z6 W  y% o& X我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑) b8 I6 i5 S0 j+ o! _5 F9 F
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
- c! S" i# u  H1 g4 W案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
* q  G1 x6 |% z2 B$ G, J- ?兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
! x/ m/ A/ ]( g4 G+ M# P; b素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性, N& G% {0 ~. Z( @+ S
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸# I  w; @. s1 M' q& S$ K( O( N7 E
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
8 a% l2 {- z* J' V! Y的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
8 [8 w" k: R# \也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
& V6 C" T  R% w8 s+ ^4 r# ~) v果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
( N! F* C7 ]" S  b  t障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
6 o% x4 I' L+ |6 SIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
* M& u# p# i8 E; U9 VUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
6 ~5 q, P1 b, b+ L盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方# {: P' W6 C" ]( W2 r8 K6 `
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
7 ~' {2 n4 d' d& J" `  D% F2 y& \) j5 U% p  a+ ], {2 W$ W

4 F9 Y$ B3 B8 b$ w- N- a' r我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过6 d: |( U1 O7 k! a7 v* ?% d
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进" E6 V! J& G5 j
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是4 N& _  k, }0 Y! t, L; S
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
. m7 y  H, ?8 ?7 M6 r来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
$ W, x, M# o! h; dKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
9 l  W4 `% A# E7 I8 y" Z6 Q# k键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
6 e6 E/ m$ L0 `! o/ J3 NIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
. j9 h' f/ n6 m  l3 r) u& {我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题6 p/ C8 w6 N. W) x9 ]! o
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的. E" q% c: ]+ Z5 r: I/ }
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
; ?7 N1 \6 h6 [4 S9 h  I) N用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通/ {: ^. C/ P! L4 _/ y5 B. `+ ?
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
  S* O8 x0 D3 _+ h% N) w% ~屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通* c8 V: L8 A3 J! [# O7 n- o4 O9 c
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb& g5 {+ p9 }. E! x' W
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid : a' [. H  ]  P0 k
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意% @, v2 N. Q( u; @* G$ c8 m  D
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
0 C( Y* f3 m& g4 I. k- \经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
( e2 g, C7 x) a# w5 H2 d来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
2 O& q& v, W  \2 {$ m& D7 S. h的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
8 k9 T( K1 J# u1 N的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致+ z* N1 D9 a( j" \* x1 F6 W
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,! X2 G6 \. `* y
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
) C7 Z9 l( H6 Q. e见下面代码。9 j; J+ }9 Q4 l* W8 y: \% i9 d; h
# q; H! s0 p6 _0 x2 [4 Y
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
) K' h% I1 |  e里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键2 I' I1 P! \+ n5 D" @+ L! d  F) _6 I+ K
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003) d' N$ U2 y7 m/ ]& Q
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
) M8 x% w- V. o完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可; J0 P2 L, W* e% U
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
$ b% x7 C& x: g. J4 u锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
$ Z3 P) z" T" R/ x& Z键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
$ y  ]6 g% R, {; B3 {+ m, Q# x. {
/ n, k7 W: k$ p* }0 M# ~1 j+ u+ b5 c6 j$ S, a2 d
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
8 W4 y" N0 Y0 ]) D! G, `( ?$ W的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
5 x8 y, P5 S% c- W可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
$ I% p/ X) K* G* Y( v& S/ O8 A+ Y的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
  e0 l+ m; a1 b$ N5 n5 _们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
+ i  p: e* s$ }+ c; t/ g$ |们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension4 F  C' Y' x- H8 p4 o/ K
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
2 q& A( M7 {+ {4 a6 V) ^8 R如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
& r* Q. t  ^$ o4 W5 a% `' D$ J2 O进行操作了。这个问题有待大家来完善了。
6 S% t4 n. ?+ m
8 D$ Y% T) R( Y) a8 k8 d2 T9 T+ i( f4 R" x
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
& y/ _$ T4 \) `7 Q% F来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
4 q  ^- p# `- |2 r" d; |分析做个记录而已。我更愿意把它看做是一段注释。
$ X. n) ]. |# k
' _, u6 r' P' d* b- O; ?最后在此代码中要
9 A: n* Y# ?# }' `
% a0 e3 m( P4 _& a. a感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
  ?- a( D8 _$ [0 w3 o" [( O! N" i) b" u9 W/ I5 A/ c) N8 X- O! I
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。- d) B8 X) i" m5 l, J# N
. _) g* [: n) A7 O
感谢:齐佳佳,过节请我吃好吃的。
+ _- V5 d% G5 C- x9 W$ Z* m
  @: F% }' o+ e) ^4 x) b. m8 n
******************************************************************/
6 X2 Z5 I: q) k
) g/ |' O/ w8 Q4 j# U* w% Q  \  B0 u* l8 [5 l$ j1 y- U
/*****************************************************************
5 {! T+ i9 }& a" i) H. l, y$ g 文件名        : WssLockKey.c
; I3 @% H8 g$ N! Y+ E  j- D" P 描述          : 键盘过滤驱动+ M0 z2 k% i* v- g$ ~, l: x" j
作者          : sinister) \: R% l. F$ H* m1 g. y- D7 a, j% T( B
最后修改日期  : 2007-02-26# p& T) V  q  M5 v& b6 ?
*****************************************************************/6 o7 ?; m- F" y' r8 e2 Y. }

2 k- b+ f' |5 m( {. ?; z- G" W' x' m0 ~
+ m  P! Q  p* }: W#include "WssLockKey.h"
5 s& o7 t2 c- z9 P: N& ]/ F5 K7 e4 h0 j. s" r$ |+ S
NTSTATUS
9 r4 D% P; ~2 w6 H  V9 }( B9 n6 FDriverEntry( IN PDRIVER_OBJECT KeyDriverObject," D: Y+ V3 D6 x% y' C/ z
             IN PUNICODE_STRING RegistryPath ); v$ h- E( e0 ]' Y; h8 s
{
5 v: w! M& r4 V: K, T5 o  UNICODE_STRING KeyDeviceName;
( y- t# T; s9 W1 d: I1 q( `  PDRIVER_OBJECT KeyDriver;
  w% F6 A- Z3 Z  PDEVICE_OBJECT UsbDeviceObject;
" [" D7 C! }# e8 k7 F5 r  NTSTATUS ntStatus; . o5 m: U$ d' n$ a& y
  ULONG i; : b7 @+ ]* Q8 w( j

# V# c6 m- M+ Z, R3 \3 L  //: z: q- ~4 Y/ b& K  f. d
  // 保存设备名,调试使用4 ]6 ^9 b2 ]( M
  //8 n$ J! [# J$ w- g) s6 g
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
* [6 x0 B) d* h, C" e  {8 k- x2 r9 j! J+ l1 V
    0  V2 `+ X0 Q3 e+ b+ i% q
  };0 L( X% K0 {5 ]& m  Y) e1 ?& A+ E

8 k* Q# _# y* _5 P8 l; R  KeyDriverObject->DriverUnload = KeyDriverUnload;
5 U+ T" a& X; |0 H; d7 @, |, D' H+ ~1 ^' ^$ `  t6 e
  //; v# e) B2 j. u) Y, X5 m
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘/ D; w2 g( w  h7 [: q
  //
. Q% c/ I- K, x; d: P- G5 C  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
3 j; i$ J5 m5 c! v* J  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其1 Y8 ~3 r. Q3 f( u  D- t* ~* y
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
7 g+ W* r& E! K  // USB 键盘设备来进行挂接
% O+ m7 O1 X6 R$ Q) j% S  //9 r( Y# _' {4 A3 f0 p0 A' |" f
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );: |+ r5 A4 e/ v4 n1 D9 ]
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )0 P+ \4 q- ~! n' v1 s4 x* z
  {! F- H. l1 b  K  K& H
    //, j4 U* k+ Y7 ]6 k$ L5 W& E: X- f
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名4 i4 ~" ]4 E0 u  Q
    // 所以这里打印为空8 s& }( n7 {, d
    //
+ Y% d) d" U4 Z- Y    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
' {6 c3 s5 q7 F+ A" @( {& _    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
" a% |- C/ N' t: K$ n5 s& b  O3 R, L& f7 J/ o) I6 K* A
    //3 G0 ]; a. ~! O* j0 v+ z& {/ @
    // 挂接 USB 键盘设备5 D7 A% _' h: i, G
    //8 [7 \0 b0 a, m3 _6 Y
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );3 r3 W; t, \7 i9 S7 p6 s4 F
    if ( !NT_SUCCESS( ntStatus ) )% U4 r2 d$ {& D  \1 H& N
    {  e$ y8 G8 D, U8 U
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );' c9 P1 L; A/ |  [; P2 Z6 A
      return STATUS_INSUFFICIENT_RESOURCES;, s2 l8 {0 K) c: G! C! \0 h) G; ?
    }
( Z4 }4 [/ t: z' a+ f  }9 T; g! k+ Y" O- U
  else
8 `$ B0 k7 l6 x  {
) d1 n0 K* ~2 i7 U! t2 b    //' }) f' ~! C5 r" B
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
2 b4 z( F0 j9 z! M* p; P    // 9 ^% q/ d  q0 W" P
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
2 X6 _7 _) R9 x, }) w/ U) ^$ |# s, T' ^' B; f8 y
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
  h3 q9 e7 r4 ^0 L' \$ @                                        KeyDriverObject,
2 V, W; U3 g+ w% }3 |* C                                        &KeyDriver );
" d  I) R8 l2 @4 z: L! Z' S    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
; S4 ~9 S& h; A9 _2 Q4 X9 D/ Z! Z5 W2 ?    {
) z; p1 d6 e; m1 H" \: x+ D      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );; B1 i6 u5 q; H. A
      return STATUS_INSUFFICIENT_RESOURCES;- s3 D, m- S8 x3 w2 {$ c
    }( K* \4 X( z' s
  }
- k7 F& l$ c' Q+ N& k4 ?5 c) H( m3 `7 H; N, i
  //
& y0 U3 I4 P/ q$ U  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止2 u$ x- B' E: w$ I" Y  ~5 j
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程  v3 l2 f8 s4 p5 z8 L$ w6 O* f( Z. y
  //4 |" v" O* b. v" A" Y
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
7 I! k6 o3 [% A9 Z; a/ p
% v! w, f3 p* [  return STATUS_SUCCESS;8 Z  s$ }* V) Q7 A1 Y
}
) i9 I0 l: g* w8 X' O/ H5 }# A
( c; ?, d+ E" t& P/////////////////////////////////////////////////////////////////
" K$ t% m0 N4 u: o. u& B// 函数类型 : 系统函数
, ~* z- q* P3 f7 V// 函数模块 : 键盘过滤模块/ n  {/ L$ E9 O# E4 g& S6 K0 ]$ d
////////////////////////////////////////////////////////////////) D9 D5 j/ W) K5 H' q; T
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,$ O  K+ g. E& C5 x6 T
//        卸载键盘过滤驱动  T+ C3 \; X( R1 q1 r9 h# N$ r
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上! e  g& u* r. D
//        则需要等待用户按键,以后有待完善
8 q: K, d$ C; j: t: D, [4 C0 j/////////////////////////////////////////////////////////////////; A( I  y5 j/ }9 g; D
// 作者 : sinister
! O; c$ T1 o' P& t* V0 z& y// 发布版本 : 1.00.006 |5 t2 _/ c  i' C# q
// 发布日期 : 2005.12.27
; g! r5 n2 }& f+ Z3 o+ L* `/////////////////////////////////////////////////////////////////
1 z3 `" [) d) n5 K; ?. G  \4 u// 重   大   修   改   历   史7 m" }2 K- L( m2 E$ {, ~/ O- Z# {
////////////////////////////////////////////////////////////////
& C$ q# W: Q7 }8 B8 Z8 s// 修改者 :
9 G% T' N. f+ N6 u, i// 修改日期 :. m0 o. D+ E3 l) @& q
// 修改内容 :  F6 w! }; L6 k7 b3 y9 M
/////////////////////////////////////////////////////////////////0 e9 V8 @/ g1 w# K  Z
5 D5 M( ]: X6 L; h5 g/ R4 y. h. ~7 c
VOID
$ y# ~) B/ ?* W' l3 X: h- \& k: uKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
* Y# y; K, j/ d8 F& r4 z0 X{6 p4 O8 }% d; `; l3 v9 B
  PDEVICE_OBJECT KeyFilterDevice ;      
5 T) Z6 G1 s: G  PDEVICE_OBJECT KeyDevice ;
' m; z% Y& N' |  PDEVICE_EXTENSION KeyExtension;
0 r# s4 `0 O- N  PIRP Irp;8 M3 S- L/ H$ S: d$ i
  NTSTATUS ntStatus;
" N9 V% |# G  d7 \3 r9 T9 ?% h
/ @& r/ S9 K6 V( j  t7 e# u1 x9 U  KeyFilterDevice = KeyDriver->DeviceObject;
- M) _/ l+ V: m1 p  x; W  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
' @3 |. c6 V6 U' Z; z# H  KeyDevice = KeyExtension->TargetDevice; ) j/ Z& r$ W7 e; j& D2 t

8 a3 }6 u) r2 D/ N; D  IoDetachDevice( KeyDevice );
4 M% K+ Q5 _. b1 f- r  W- K# r4 n/ m6 Y
  //
" }  b# @0 j2 @4 h  Z) O+ ~  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
4 |) b4 q0 L7 {/ H; M  //' C9 F% I/ t+ R$ {7 A+ }
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
2 _) J: x  h7 f* ]  {
4 m. ]# ]- B% ?4 ]% {5 s    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
2 N2 ?9 `# Y8 V2 a$ c, y1 u  J# C    {+ X4 P5 M2 c. m
      //3 R% @' i: y9 m, a
      // 成功则直接退出删除键盘过滤设备
* i3 H" H( W  c' ^5 b      //" d. [, N5 B+ c' q5 w7 \
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
5 P- |, e  h3 t4 k9 r9 g      goto __End;
$ V; e2 U) ]+ J, \* c    }$ U& ]7 b4 c* [
  }
: [) w; ?6 I0 B3 e# k1 n, a* u1 G- D6 K
  //) j- \* s; W: l7 V
  // 如果取消失败,则一直等待按键
( p* Q; O! Z+ `6 S: Y  //
! J+ @. b/ i9 z, y6 \  while ( KeyExtension->IrpsInProgress > 0 )
( s& W- W) L. Y4 h/ w5 x& R; h  {7 N7 s: s6 j6 a) F+ u6 X' N  c
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
# Q9 Q. {4 ?  S& C* c  }
9 o7 }4 ?8 q! {" Y: x, Y& O4 K! X8 |
  __End:( a! ~$ z( b+ A6 Y
  IoDeleteDevice( KeyFilterDevice );
# f& m0 }- {" a1 ~3 N
& t4 _+ |2 J. ?8 U* ?  return ;' y# m* ]; m0 g  B9 V0 s3 ?
} 4 f3 K0 a9 b1 T/ g
- b! t' N- W5 {: M+ I
/////////////////////////////////////////////////////////////////
& U; N) H' M0 W9 E! Q& e( c: e// 函数类型 : 自定义工具函数, L3 y& x; K1 o
// 函数模块 : 键盘过滤模块
* Y& {6 |7 z8 G/////////////////////////////////////////////////////////////////$ F7 V; V+ j+ i5 E
// 功能 : 取消 IRP 操作
6 O- P7 B3 M, ~. g+ `// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
. t7 k, h5 |) J//        使用此方法来取消 IRP
2 V; p; Q/ B9 d2 g3 z/////////////////////////////////////////////////////////////////( |1 [( k! z( X5 h8 _
// 作者 : sinister
  G' K3 R# n' T2 \, m// 发布版本 : 1.00.00
3 B2 _+ N( ^" Z+ M9 N6 X// 发布日期 : 2007.02.20% ]4 p9 E$ \# e8 t6 U3 x
/////////////////////////////////////////////////////////////////
6 _: ~5 ~2 p4 G5 `; l// 重   大   修   改   历   史6 B) n8 F" U( W4 u
/////////////////////////////////////////////////////////////////' V- o5 M9 o- H& A* D
// 修改者 :
9 [% z! ?9 |5 w7 D// 修改日期 : 6 a$ A/ O9 P% V4 A0 s  o5 f
// 修改内容 :   n7 [- S- f+ D( l2 z. B7 |9 d1 U
/////////////////////////////////////////////////////////////////
( `" D- Y) R8 Q9 b4 j$ }
9 O- X+ Q( m2 T/ j  ^BOOLEAN
5 ^3 f% P( H# ^. V) D: oCancelKeyboardIrp( IN PIRP Irp )( R9 O% F- u& ~! u* z
{. |  L! E/ z4 k
  if ( Irp == NULL )( I; U, I4 u( x/ r' n: e2 F
  {
; Z& a! q" @0 d5 K- E4 N0 F% [  z    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
. {- o' J7 x8 Q1 C( i    return FALSE;- N8 c/ n! t* H
  }: v  k( e: A/ r; s* `2 e* v

' B* q, w0 p. p0 ]  v
6 |0 v5 }, ?" j; t6 z3 q  //
9 ]/ @$ u* I4 d4 g  {9 o9 S* q  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
. \& o" M, b3 E3 @( j  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。- i" k! S, h3 h. s1 W, `: {) w
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占* r. f7 ?6 R5 P$ z2 P0 Z
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
) _8 X8 D: o2 v* f) N( D9 W# W  //
/ i  k- ]) K4 R) b  Y( ~+ i* @. a6 {  `) C9 F1 p% ^( u
  //
$ x0 a" p4 s" C* r  // 如果正在取消或没有取消例程则直接返回 FALSE: ?/ J, o* u# O2 q" [  H) u0 N% c% O
  //
% |+ o: V2 n4 h$ ~! i2 s  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
' T$ ?$ f4 b! [, s/ u- T! c! o  {
0 N: z; [! O" f! Q+ O! f* A* k    DbgPrint( "Can't Cancel the irp\n" );
% V. P/ O% p0 k* v  M; ]    return FALSE;
5 Q* J  a; `) {1 b" X6 N" c  }! {! J- C  g8 f4 F

; o! p" K7 ?- m' S* i: k* z( J  if ( FALSE == IoCancelIrp( Irp ) )
2 X# z4 h4 r0 d$ U6 P8 J5 B& O- X  {
: `7 b8 h1 I7 |5 Z4 J. v# W    DbgPrint( "IoCancelIrp() to failed\n" );
9 v, M( N; ~" W) g. ]% u    return FALSE;
0 S  W6 s( M# g4 J: X. C  }; y4 H, ]6 |- s+ _. i( J: }5 l
; [1 G3 N$ u( ~5 X+ c
  //
, c! @' p& v( H( G; u9 g  // 取消后重设此例程为空8 T6 n0 H* ?  N) d0 n
  //" D+ s- ^0 P  ?4 r8 q
  IoSetCancelRoutine( Irp, NULL );. }- D% {; v5 `- D2 Z* Y" x
7 O5 e5 [6 {* g( C" w
  return TRUE;
' Q( I, H5 {8 w1 ]! Z}. Q) {9 l! ?: ^( ?* l4 n

. [0 v0 h2 T6 z; F% o1 n/////////////////////////////////////////////////////////////////9 v( C9 A1 u$ \6 t9 s! n
// 函数类型 : 自定义工具函数; h9 k, {3 h* U
// 函数模块 : 设备栈信息模块/ V+ e/ K) F$ B5 X: k
/////////////////////////////////////////////////////////////////
2 y1 P% H, q1 `8 e. y4 K// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
, N2 r2 e5 I( U. t( f# _//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)6 x" D* I8 f) g2 h/ Y8 U
// 注意 :
$ X0 k" o. B( d/ o" l/////////////////////////////////////////////////////////////////
9 K4 Y* j' N- f  }# T// 作者 : sinister
& J3 U# T7 ?" ^+ V: G- R8 M! s$ T// 发布版本 : 1.00.00; e6 Y  R! z. d
// 发布日期 : 2005.06.02
% T# P# [3 B- O! n( B/////////////////////////////////////////////////////////////////
4 i8 ]7 U* b/ d$ C5 g// 重   大   修   改   历   史6 R) n/ P- K4 y+ Z: [+ d$ m
/////////////////////////////////////////////////////////////////
) q1 f) M+ b/ v# U// 修改者 : sinister
2 C( T' v' M! _' s7 |  y+ G% A// 修改日期 : 2007.2.12$ K* J# b2 g. l7 B3 P2 g5 f4 N
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
0 w9 G! r9 G6 U5 l3 B( V" F/////////////////////////////////////////////////////////////////4 D' P8 W4 I* p' G' L0 I) p$ S
9 Z3 b# C7 ~$ h( z0 x! j
BOOLEAN
) b( C# I- c' Y1 Y) z7 o/ YGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj ); x8 W) u7 T% w
{
6 z7 J1 B; T$ I: c3 b  PDEVICE_OBJECT DeviceObject;4 c- a; d# d8 _* }3 O  A  W# g& _9 K
  BOOLEAN bFound = FALSE;
: [# f, V8 x/ _1 ^+ [% {
, X7 m% j& l6 U; F/ F  T  if ( DevObj == NULL )
$ F' S# ?1 u$ [! b2 R  {
) G  p0 J$ V3 g" Z9 m: g& c: {) D    DbgPrint( "DevObj is NULL!\n" );
9 w0 |! p; ]8 N7 Y! A. F5 J    return FALSE;& r8 R. o1 @4 D% t  t2 y& I  l
  }
+ x* D* x1 v& I* S) d" Z
/ k6 K/ p( ?. G$ f" m  DeviceObject = DevObj->AttachedDevice;
, L# u0 {; i$ v3 b' S7 k* A0 T# Z# {# o4 t; E$ e8 N4 N
  while ( DeviceObject )
( G$ x6 ?: E% ?- R; f3 j1 j/ R  {! ~# R$ ^0 [% o8 g. }8 r. W
    //5 ]# L  G" K( P. U+ W$ Z
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
3 O8 J* s  z0 _0 d- @2 m4 D    // 有一次足够了。这算是经验之谈
. V3 r/ s& |& \; d5 m    //3 b' |+ j8 J+ n/ s
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
4 y# z8 ?. h9 U* u3 h    {) B8 k# h! t, R
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
9 g/ E, {: f( ?                DeviceObject->DriverObject->DriverName.Buffer,
- y: w& O! w/ h/ O                DeviceObject->DriverObject,
8 L8 {/ Y5 y! x& ]) q                DeviceObject );
, S' f. a# B6 O( p0 q% Z, S: `# J7 n0 u! Q  {( j, }3 w5 E
      //7 h7 t4 U* y  d0 p
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了! K8 j) y  w  Q
      //% [) L2 F- u  C5 P+ N4 F
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
  ]6 S1 _# B0 m7 ]                      KDBDEVICENAME,
4 f4 B% @1 ^' M* Q& r                      wcslen( KDBDEVICENAME ) ) == 0 )% h0 H; W8 ]* u
      {" p+ n# p6 u8 [3 X
        DbgPrint( "Found kbdhid Device\n" );
% X/ ~; a8 N7 A! Y0 [- l% d        bFound = TRUE;
0 ]2 R+ C5 b* B: v. B, W: J        break;) Z4 @1 J* J% m; ~' {4 k7 d
      }
2 H+ _3 b, W! g2 m    }
8 ]' _9 P9 T9 r! T. D9 d9 @
" ]! f" f/ a. V" T5 Y    DeviceObject = DeviceObject->AttachedDevice;
/ i1 ^5 J1 M# p, u1 x& X9 N) a) Y  }
  [( ?+ _2 q9 v( H7 g7 J: b5 j/ C1 B7 G. x, \+ A
  return bFound;
& ~$ D1 q# m$ L2 t8 c}
& {! s  E  d. f9 {  o$ `* ^2 X" j, v8 H- t
/////////////////////////////////////////////////////////////////
% I6 F* L# C  h6 R9 U& G// 函数类型 : 自定义工具函数3 q( `$ a- U+ s2 i
// 函数模块 : 设备栈信息模块) s- ]8 a% c, ?" U
/////////////////////////////////////////////////////////////////
/ _6 u$ Q, z& j// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址4 U9 Q5 o+ S/ i( ]6 \+ m
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改$ N# F! }& w0 L% D
/////////////////////////////////////////////////////////////////% x3 L& }2 f  W  t1 ]
// 作者 : sinister* ]* y8 M. u4 [- a
// 发布版本 : 1.00.00
1 v$ U$ _  H' N// 发布日期 : 2006.05.023 |! M" d3 S- y
/////////////////////////////////////////////////////////////////, O: z0 O) H1 ~  n$ o5 e1 i
// 重   大   修   改   历   史  X: m* h3 O3 |
/////////////////////////////////////////////////////////////////' y6 K) G  r3 |* o& X0 x# m
// 修改者 : sinister- z( e( ]/ {2 m9 S% k; ]
// 修改日期 : 2007.2.12
4 i' K4 c* i: _1 c  S& a// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
' A; G( U! L) _/////////////////////////////////////////////////////////////////4 H* \9 a) v* x$ l9 B3 T. W# q

1 b7 u( z& j& `VOID
. Y6 F/ [  N8 F+ I7 {: dGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )+ o9 h) f, _, `: w
{
5 E8 T+ z# S5 F( ~# J7 b6 l  POBJECT_HEADER ObjectHeader;
2 ?4 ^, S7 M$ S. W) ?  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
1 U  C3 ]7 X8 C* @! a/ S. j1 J. w! s
; B8 }$ E) t6 B8 s7 v/ [# T  if ( DevObj == NULL )7 a, O+ ?7 h6 o! s  L0 y
  {3 O+ I7 ?1 Z0 l* B) O; i$ D" g
    DbgPrint( "DevObj is NULL!\n" );6 D7 _& f8 o/ b4 U6 h$ H
    return;, v' m8 D' s8 M; q# R
  }
5 m" J# U6 n) k% Q0 a
$ P, }" K! W8 X4 a. ?& }  //) j$ s- f/ ]( b9 L: m- N0 h
  // 得到对象头
. p9 V' ]& _. t9 [9 z  //
- {9 e- j# U  a7 G8 P* W+ K. i  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );; L" M9 [- j1 o* v+ n
  D/ j2 ]2 L6 ~5 d5 o
  if ( ObjectHeader )
  k% z4 p$ O2 W' |9 l  {. g& Z9 \4 Z/ A; k
    //
6 s- ]! K! l+ |9 C    // 查询设备名称并打印
2 L4 ?) w" A' V6 p0 S7 ]3 O+ @    //# m2 y+ f, t* @* }7 n6 T" H+ b. p
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );- S% t4 U7 B$ J3 X8 |) Y

+ Z" A2 J6 u  X# J$ }    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
2 a# B' |' c, C' j    {" T+ y' J5 K, T$ V* O: y2 \
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",- R% ^* |- u) I8 p1 q4 V" R2 s1 E5 o
                ObjectNameInfo->Name.Buffer,  I8 o/ ^! ]( P
                DevObj );( P; W0 j5 h' c# z# m; H, O  T

. x' |" c+ {" j) O1 R' Z      //7 H' A) C9 h& f1 d$ o
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
: U: j2 _% K& @3 P3 w. q* G+ R, `      // 用,没有实际的功能用途
$ K( S" Y% q; w+ M, H) W2 {; C! H* j      //$ |* w) l/ Z! J# x' Z
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );; i6 p# ~5 N1 T/ h) L6 x+ x( Z  J

2 K6 n: Q( y/ i' b3 y8 U, `      wcsncpy( szUsbDeviceName,
; K1 k) M4 ^) a  e  _& u! I               ObjectNameInfo->Name.Buffer," K# T* H* U1 q9 e8 l& Q
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
) k  `: `( W! z0 d. b    }
& V1 E' p' O. o. C  L" Y" W4 D  ^+ r2 d; l1 \2 M7 F5 C
    //2 ~% r. U. C1 l. r+ T5 \
    // 对于没有名称的设备,则打印 NULL) c6 T8 j8 K3 M4 p5 U+ |% H
    //, R0 [* G* a1 I( D
    else if ( DevObj->DriverObject )+ o) ^0 b+ V/ t, b9 n
    {6 x0 L) ]2 M$ P+ L" z. b6 ]  g* `2 ]
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",: ^( `% Q- \& c4 V
                DevObj->DriverObject->DriverName.Buffer,' K, _) C  `0 [& V2 o
                L"NULL",/ D* u+ K1 B) h+ d0 k+ V4 F$ s4 H
                DevObj->DriverObject,: ^! f1 g" D: u' O) ~" q+ H2 _& w
                DevObj );8 R! @7 |  \) X* F0 \9 G" q
    }! T/ ~% `# _* f, N4 ^
  }
5 h& ^0 X8 j5 s0 q}* S, G* R4 _5 [2 j# z$ I$ c& s+ z

& ?" P2 O5 `( ^; a% d. Y" m( z( r4 h/////////////////////////////////////////////////////////////////" ?4 I2 H0 P4 H9 p6 Q3 b" J  Q
// 函数类型 : 自定义工具函数. ~- {6 {* c) ~- h
// 函数模块 : 键盘过滤模块
- l$ r; t6 v$ R/////////////////////////////////////////////////////////////////
& v% t- ?$ y2 r/ _( z. m( ?+ o9 N9 m// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备; I$ N# ^( G' [
//        对象,过滤出 USB 键盘设备,将其设备对象返回
$ N8 U$ S" S+ ^( a4 p+ k5 a0 z// 注意 : $ C0 \& U' b' X, H; P
/////////////////////////////////////////////////////////////////
1 C) w1 n" I+ x7 ?- D// 作者 : sinister( |& S" K' |; c5 ~8 ]
// 发布版本 : 1.00.00
! ]' A& U+ f2 g# s  x// 发布日期 : 2007.02.13
2 O/ q5 X# }* e- X/////////////////////////////////////////////////////////////////3 r7 N. x6 e0 y. ?* P
// 重   大   修   改   历   史
5 j* Q$ v! L5 Q/////////////////////////////////////////////////////////////////
9 C. u# v3 B3 k# [1 ?// 修改者 :
" s$ h  N$ {% O/ P! v6 s// 修改日期 : . f5 W' F6 H5 `1 R
// 修改内容 :
5 N" b+ |( {+ C- s# z/////////////////////////////////////////////////////////////////
# [5 H# y8 t3 O
6 t+ J! v: O8 k  ?6 \( sNTSTATUS
/ ]6 I2 G" q4 j# ?GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
8 h; w. `& l; o{
$ ~4 U" d. F5 B7 [  UNICODE_STRING DriverName;5 J3 ?" C) C6 K4 t
  PDRIVER_OBJECT DriverObject = NULL;
! {) }8 f  u& h1 ?6 K9 o' O  PDEVICE_OBJECT DeviceObject = NULL;
* I" H- q& |$ U" X/ M7 Y6 X  BOOLEAN bFound = FALSE;
3 O1 t0 O, X$ h6 G1 n1 g) \$ I& G  D9 Q9 N* N
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
- l& k% q$ r. s. ?+ y
" z4 O+ Z' U$ |& {6 f2 C% A  ObReferenceObjectByName( &DriverName,$ i! R3 l4 T' Q6 D% e) y
                           OBJ_CASE_INSENSITIVE,6 S' @0 o# Z4 y9 w
                           NULL,2 x5 C5 j( K$ ?: M' l$ Y
                           0,
6 W' @# m3 D* _5 A                           ( POBJECT_TYPE ) IoDriverObjectType,+ g. {" h% J# g5 V$ c3 z7 z
                           KernelMode,+ Z4 ~! J; a# |1 d- j
                           NULL,$ @6 I7 u% D! F  R3 G
                           &DriverObject );2 C* U( j" ?) K# b3 U7 d
$ [. E, e7 N" E" V8 k9 c
  if ( DriverObject == NULL )
, E6 M1 t% x  Q* u2 G! n* l  {0 o2 d7 ^0 ]0 C3 D
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );* m2 c$ u1 ?+ n& U
    return STATUS_UNSUCCESSFUL;
0 v7 z; Q, v7 L! [, P7 W  }
- B! j7 J& c# ^) J4 q
3 u1 I* H' H2 F5 {8 f/ e  DeviceObject = DriverObject->DeviceObject;5 F# F5 K4 H% Y" F1 J* E

" n$ u  P( K2 j) `8 o  z8 e  while ( DeviceObject )9 V$ l7 `8 V5 K" R" z
  {' y9 V, }* `& X
    GetDeviceObjectInfo( DeviceObject );$ z8 f% B* u3 n8 G1 o( T& K

1 q& `3 X7 h5 P    if ( DeviceObject->AttachedDevice )
% {/ K0 b. B1 f6 Z6 ?1 h0 G* k    {: M' n2 ?+ K5 @( Q9 y8 ?6 o  b( k3 H
      //' c5 _7 s2 A( W2 ^- u& o& D
      // 查找 USB 键盘设备
+ S' C& }" Z4 X/ b! n, ^  l- x      //
) x1 G2 Z" `5 l6 i$ |! q      if ( GetAttachedDeviceInfo( DeviceObject ) )" ~; h* X  N" o, G
      {
5 ]/ c* F6 {: R, `' |        bFound = TRUE;; L  n  Y0 F* r: g- b$ h
        goto __End;
/ _" H$ ]: r3 K+ {1 }+ z; Z" x      }
' n& W& ?) N+ J% g  E- I    }' G& h7 N# P) [' c" w

1 i" Y! C! @0 G! j0 n" ?2 m* m% H    DeviceObject = DeviceObject->NextDevice;
% d- N0 W8 ~$ V1 R& L- t  }
6 u1 ?: B8 v  [2 _# @( n" T
3 O1 [/ A  V0 M4 X; k2 K$ O  __End:
3 g  B7 L) D% v9 a- k, K
8 N, D! k/ o; J+ ?: B  if ( bFound )( L: x# d! o( _; V
  {0 x0 ~! L) g5 p3 Z, Q; Z
    //; _/ G9 L# ^5 ?% x- U
    // 找到则返回 USB 键盘设备对象# V1 P$ ^8 L- o) [1 F
    //2 c9 v/ Y" M5 [! R7 `
    *UsbDeviceObject = DeviceObject;* [  P, I8 p5 o1 q
  }
  X# g1 K6 _' \3 t; ?  else* h5 y) _$ F7 Q4 v( ]8 R
  {
6 p2 J. j+ {, e% f4 I# W+ x    *UsbDeviceObject = NULL;
! M, y+ u  x$ Z$ z1 n* I: @, d  }
4 {3 i. G: R0 B" f# q& c, a: s* D* o) r: a% [% s1 e
  return STATUS_SUCCESS;
3 m+ j' }% l  Y; F}; P: i: q/ u& {9 B  F/ T+ U' T

/ V$ N7 Z. H1 ?. y0 W( O) u" l/ M0 W/////////////////////////////////////////////////////////////////
$ j/ {6 v# N" U, \. d& r, c8 K// 函数类型 : 自定义工具函数
0 }$ t$ i  v$ k0 i" e( @4 G// 函数模块 : 键盘过滤模块
+ J0 p* i) A( k3 V////////////////////////////////////////////////////////////////
; d6 r  a1 B5 A5 w- d# }+ c// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关3 Z3 V% Z4 V7 u4 i1 N* k
//        信息,返回附加后的驱动对象
& ]. Z9 }% h: U" U/ l: ^// 注意 : 此函数仅挂接 USB 键盘设备: e$ ~2 _* V, w+ r/ L( k- A
/////////////////////////////////////////////////////////////////
. o* g- _3 H4 f5 o# d// 作者 : sinister' @, j; P4 N5 r- y
// 发布版本 : 1.00.00* M. w- K$ P# A
// 发布日期 : 2005.12.27* n$ E0 Z3 u3 z& }( |
/////////////////////////////////////////////////////////////////
+ {7 G' O" f: ?9 y, _// 重   大   修   改   历   史% K* A9 B2 v+ Z) @! h' o8 _5 X' V
////////////////////////////////////////////////////////////////( P/ `: z' o4 Y1 `4 K2 Z8 ~% D
// 修改者 :
1 |" j3 u# G8 i2 T9 v; F! q8 t// 修改日期 :0 ]( g2 B' u$ B3 |) _( S  l( D! @
// 修改内容 :
- c! [4 l" c5 b/////////////////////////////////////////////////////////////////
; C6 V& O* C4 x2 H$ `; ^
$ P& ]9 x1 C3 i% zNTSTATUS
1 [; C6 t) c( Q6 V3 ~AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
" D9 h0 L$ u+ I5 f4 p                         IN PDRIVER_OBJECT  DriverObject )8 [+ E* M6 F7 ^& A8 d
{/ @% [  G& W+ R! H( ?
  PDEVICE_OBJECT DeviceObject; ; }% t# C, e0 d& x/ \+ }5 w
  PDEVICE_OBJECT TargetDevice; 0 P! g8 {1 O9 a4 R9 D' C1 j
  PDEVICE_EXTENSION DevExt;
" l- K' D# d7 g  NTSTATUS ntStatus;
' f1 N( t* z( M6 i5 u9 h
8 {' A0 E, P5 C! p# `  //. e: N( i" P6 D/ P9 y
  // 创建过滤设备对象
# E8 R1 ]7 w! C* r" g# q  //
, o5 Y: }2 _! R$ m+ n) {  ntStatus = IoCreateDevice( DriverObject,
" E+ C2 X( S/ e& B5 D6 H* |                             sizeof( DEVICE_EXTENSION ),% H4 W! x% l/ n4 e! j8 b3 I
                             NULL,
+ M* J/ F& H/ D# G5 T5 V                             FILE_DEVICE_UNKNOWN,
& d1 @2 ~2 l4 P, `6 d# k                             0,6 l# L, x3 [4 \3 j$ k7 r9 p0 N* |, N
                             FALSE,6 i: g% z& b, Q9 n% f2 n
                             &DeviceObject ); ; S4 \2 k7 D4 d" _  s* v/ g9 q: u7 U
1 F- S7 b& N% m% T! v; h2 Z
  if ( !NT_SUCCESS( ntStatus ) )
- c5 B  u6 d" g  {' t' J$ U2 I* F! E) r5 q4 C$ ~
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
0 a! K' a# _& J* M; u. s4 h    return ntStatus;0 ~$ w1 P3 [; a6 L
  } % o) O! d$ w& ^& ~2 ^4 q6 a
) K# Q1 G3 x0 e7 f+ F8 _
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
# i( N8 i1 e3 q! D- n. S$ ?9 k: f2 I. {+ e
  //1 i1 P3 ?0 W. {5 [4 w& A$ W* ?- l: [
  // 初始化自旋锁
# V8 l+ c2 K9 c& ~9 U  //! ~' i. I# @! u& A: m: k$ R3 w
  KeInitializeSpinLock( &DevExt->SpinLock );
( m- t- c- h4 g0 W0 {
. s* w2 Y6 t  R5 m, S7 X; o6 S  //
; |: Q; d- p/ P* C  // 初始化 IRP 计数器
. @7 K) c9 E. f# y6 s" G& z  //
# m7 X  L4 V& A3 t  DevExt->IrpsInProgress = 0;
/ {+ m0 |( L  ?$ t
2 }9 b$ s* w% {  //
, n  _4 i% c5 V  Q  a4 t  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
: q" q, N9 u9 l" x/ }9 h& e  //( f% ]+ g# P" z: C
$ i7 Q4 M0 y' N. r6 J4 S( K
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); % J7 H: Q& R: p! P) d9 c5 x% w
  if ( !TargetDevice )
; R& w! L* ]5 E( U  {
5 k. q- t( d0 _3 d- E    IoDeleteDevice( DeviceObject );
, N$ f# P; D5 P  b' e    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );0 I3 W* K4 }* k( [  o- P' A# J( I
    return STATUS_INSUFFICIENT_RESOURCES;
3 r8 ?4 o* [* {$ a( h7 V0 n. J2 `9 u  } . Y! R7 C+ f, y3 @0 H: S3 s" o

6 M6 F4 @0 s7 y# n# M1 A9 L  //
+ }: O) W) r( H7 g# |. a  // 保存过滤设备信息* X, P+ z$ h' z% ]: `
  //
' O# d- e4 i3 k/ [  DevExt->DeviceObject = DeviceObject; # Y6 }- ^( z7 c7 {1 U3 Y' z
  DevExt->TargetDevice = TargetDevice;
/ C9 g- B; P- s% @- m
+ x) d# e( V! H* `  //
4 L) D; c# C! h! A3 I1 v* m3 h  // 设置过滤设备相关信息与标志
# E: i1 O. X" M  }2 Y: a- y  //7 m, j8 X* y6 b2 q0 o. C
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );: e+ S- b( @9 o/ M
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  O4 T1 W8 X6 r: e2 T8 J& W
& \1 `2 G* Q6 m2 ?1 {( w; M3 f5 |; N' l* W3 W( z! n% v
  return STATUS_SUCCESS;
% i5 Z' q$ K' i& J9 q% n1 k" }}
2 U9 f$ \/ h& o, c0 m1 `7 k* l2 c4 S; e+ W$ i& h8 C. C. }2 x
/////////////////////////////////////////////////////////////////
" T! s! }: j# T6 P// 函数类型 : 自定义工具函数4 \' S; Y. s7 w
// 函数模块 : 键盘过滤模块
- n* j3 t7 V/ u" B( z8 [1 g/ C! y////////////////////////////////////////////////////////////////
+ L4 M' E  a, e2 k5 r! t// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关! p# U4 h7 O# |; x5 O
//        信息,返回附加后的驱动对象
" W0 ~* ?$ A9 k6 s" [// 注意 : 此函数仅挂接 PS/2 键盘设备
1 m( M* R* ]# }/ d" ^$ z/////////////////////////////////////////////////////////////////
4 U( a( i; h, d0 K! }6 k# k/ K+ n// 作者 : sinister
; l$ R: s9 o( Q8 y' Z4 L0 t// 发布版本 : 1.00.00* S! _1 a) e- q- m0 Y8 r
// 发布日期 : 2005.12.27& r" S3 @6 I) ?; I4 B" u" d
/////////////////////////////////////////////////////////////////- E6 t+ _3 B1 _; F% j  N
// 重   大   修   改   历   史
, o  f- m$ n/ N( B) b# ^////////////////////////////////////////////////////////////////1 F2 ]* M) s1 q7 t" s
// 修改者 :
% h) e' H" g9 P6 h6 c// 修改日期 :
& n2 S* B" b. |6 F1 l5 p// 修改内容 :
0 f# W, A0 @4 o! g/ G8 u/////////////////////////////////////////////////////////////////5 T0 N+ a" f( R8 d

' e" j) E: t& h% R  R0 g, TNTSTATUS
# x& d" I4 P. F; t" [2 ~0 Q% cAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
* ], X" h0 _, @3 c5 z# y% {6 a                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
! ^! X# `( z6 X- C. J/ o5 @$ x/ _                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
. m. ?( u9 h8 S{
+ v2 X) Q3 y5 v! g" e' M1 ~  PDEVICE_OBJECT DeviceObject; 4 g+ M& R* E) n, v0 W9 \* f
  PDEVICE_OBJECT FilterDeviceObject;
3 G. c) L/ t* Y. y+ Z3 T% q  PDEVICE_OBJECT TargetDevice; ' g: S/ g- H) w, q
  PFILE_OBJECT FileObject;
  t- y+ W0 C  f# O7 J" \  PDEVICE_EXTENSION DevExt;8 l0 M! F* z7 G+ O+ j
8 Q  z& K9 q) i
  NTSTATUS ntStatus;
; @/ |7 y2 o& t( S7 a
+ v# o/ Q, U4 f8 c  //
3 y2 L0 i* |' G& e, H7 ~  // 根据设备名称找到需要附加的设备对象
" m. ?* N8 l, I) S! I0 Y$ ?  //& e  X. K3 m2 u: Q
  ntStatus = IoGetDeviceObjectPointer( DeviceName,- w. m7 y0 s* f1 i
                                       FILE_ALL_ACCESS,2 }/ P4 Q2 v( L) d
                                       &FileObject,
2 a! b/ {( u$ G8 ^) }* t3 h- f% R                                       &DeviceObject );
7 g% X6 k4 H2 i7 g5 c( h
; R1 A- i& V0 l3 {  if ( !NT_SUCCESS( ntStatus ) )9 D1 v* n8 w" m0 Q
  {" W- v9 X. T$ W4 ?% L  A1 r
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );' L( B5 N% i4 b
    return ntStatus;
+ @0 x& u/ x4 i7 h8 A  }
5 G" I% D! r2 }# Q& E
% ?9 r5 k& K& j  //
5 ?) P6 f" U7 r/ ]  // 创建过滤设备对象2 L7 s. |' h4 Q( t: A
  //
& v! O' C2 c) P" ~, }0 x0 P  d  g$ e  ntStatus = IoCreateDevice( DriverObject,# b: A' ^8 P7 V$ h# e8 |
                             sizeof( DEVICE_EXTENSION ),# J2 b) \. S2 q5 Z4 x& r
                             NULL,. ]: }. @: D5 W8 u/ a
                             FILE_DEVICE_KEYBOARD,
6 z' D2 i" x5 e5 l' G5 k# q7 e                             0,
9 U* L7 T9 d3 k1 V% V/ h7 D                             FALSE," q7 ]; m: w( q
                             &FilterDeviceObject ); ; R' ^& I2 Q; V( N. u8 _- O

, t4 j$ Y9 s2 P  _  if ( !NT_SUCCESS( ntStatus ) )  E$ _$ Q' F8 T
  {) h  f; x4 q2 C% [7 R4 j
    ObDereferenceObject( FileObject );
. K; g$ m( c9 P( t  F& J    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
& \2 H% k/ o9 J# j    return ntStatus;
. \+ Z  M# J+ z  } 7 p) I7 Z/ x' n1 b  s! i. {2 }

+ K' k$ Q4 |: P) u0 b9 J  //% X/ D  n& J5 b) }0 g* x
  // 得到设备扩展结构,以便下面保存过滤设备信息6 E$ P. B/ ~7 N- j4 }
  //
, n8 C- g' ?6 t3 {7 O8 _  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
: G& t9 i7 r  [2 ~; Z& f( _: k/ m- k' J
6 K2 q9 S% f. v4 ^
  //3 B" D: g; v& h% i& \, z* F* L; _
  // 初始化自旋锁( w; t2 L" s5 G* J) S
  //9 k+ n; ]  s  B  i
  KeInitializeSpinLock( &DevExt->SpinLock );
9 c# K. ~, K1 c: _" H8 Y9 {9 ?6 U$ [% D: u# i% N$ C) W% B# E
  //
5 F* q; B/ _" @2 X/ T6 C2 ~  // 初始化 IRP 计数器
2 ?6 h+ h1 p' {. j2 l6 o4 u  //
; x' P* \8 C4 h( O( ~. Y" @" V, C( L  DevExt->IrpsInProgress = 0;
4 i8 K+ G' j3 h
5 T' O% Z, }2 A& @  //5 H0 o6 D8 @" J( m. b
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
0 u: j$ }% \- ]; [6 m  //
1 V- T: e; @5 B3 T" e! @- _8 @8 e3 j  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
0 q3 R$ D6 R% A- `                                              DeviceObject );
) l2 k& ~# L' p2 g  if ( !TargetDevice )
! n* F* q) Z% c) H" O! d+ w, a  {
3 R+ _( e7 J$ n  e3 _) U! g) m    ObDereferenceObject( FileObject );
" e1 ^) }( j! C) `5 F    IoDeleteDevice( FilterDeviceObject );
+ w; o" h* @# Q: R4 F    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
# Q. n- N& o% h) C8 r7 K2 Y6 ^& U    return STATUS_INSUFFICIENT_RESOURCES;  z4 }3 q2 A- s1 O
  } : I$ V8 r6 L0 W" z, H5 e4 B* C

! n/ V$ x! x! g! L! L+ C, A  //
! o9 ^/ }) F0 ?9 J, `+ N' w  // 保存过滤设备信息
2 r6 A8 y, J" ^- s. O5 L% Z6 k  //
- a6 E- s  B! B& D  DevExt->DeviceObject = FilterDeviceObject;
5 X1 D, @  y3 W' |, i  DevExt->TargetDevice = TargetDevice; 0 Q# O0 F* ]- u: y$ U, C
  DevExt->pFilterFileObject = FileObject;7 e7 y% t% m) k# ^- ^2 \7 d0 ~
( @* G2 H, S8 Y" z
  //
! u( h3 {4 m; t+ n3 c( X, A  // 设置过滤设备相关信息与标志( ~! |* `6 L: d! ^; \
  //2 e+ k5 R, ^/ x  m* L' k) W
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
8 H3 m( ~& w6 j6 s: A  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
/ ]# T, s4 E4 s4 N; N  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
; d" `6 V3 [* T+ f3 L% Z4 z0 e$ i: u  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
& E, m5 D: b  L2 A) ^2 R0 e" B                                                         DO_BUFFERED_IO ) ); ) H) ?3 w" z3 \' q! C- C

" n- T! j  b8 v5 z2 W  //5 Q4 K( J  h: G+ i# W) B
  // 返回附加后的驱动对象
; D2 Z# |! ~8 ~- S# l. W8 I5 R9 A" X  //
% d  ]  `. @0 x% |$ f5 _9 Z  O7 G  *FilterDriverObject = TargetDevice->DriverObject;9 l" ~7 x% b! c3 A

$ W- _/ p# A! G- }  ObDereferenceObject( FileObject ); * S2 i  i, Z7 k2 t; \; r) `) m5 l

; X  q- I& Y6 e3 N0 n" c  return STATUS_SUCCESS;
5 r1 G# m  b. _}
1 t5 t5 W9 y$ J# _7 ^6 L$ z  N/ U$ A% q
////////////////////////////////////////////////////////////////// ~) D6 V9 Q! X, G9 @$ M
// 函数类型 : 自定义工具函数
8 _% l4 R6 s* D( a: A0 ]// 函数模块 : 键盘过滤模块; ~( a; d) g. x% F3 M
////////////////////////////////////////////////////////////////0 e4 I+ m% K+ y$ W) G' c3 D6 W" G1 W
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发3 R* z5 w6 `2 t# |2 W! D& f1 y
//        这个 IRP 的完成
; T- H/ W" ^" |! I// 注意 : + t( q( O5 q$ [( {6 |2 E* x
/////////////////////////////////////////////////////////////////( e0 B: _5 j8 ^$ H" E+ C+ {
// 作者 : sinister
( ?' |) x9 Y* X. u9 [. E" m. {// 发布版本 : 1.00.00  x. I& h1 S: M4 o' s1 u7 }! @
// 发布日期 : 2007.2.15- N! L$ a: C& W  W6 i6 M; X4 k
/////////////////////////////////////////////////////////////////
( J, P' o) @% n! R// 重   大   修   改   历   史
" V, ?# j4 y: h! \# K8 d8 s5 \! Z////////////////////////////////////////////////////////////////7 o% g3 U2 a3 D5 F) ^
// 修改者 :
# y. P8 d6 p% l+ t# y! A5 m  d// 修改日期 :$ K$ t* d" K4 N- T
// 修改内容 :
, ?& O  ^0 i8 ^4 K2 O0 }9 V) L0 \& @" a/////////////////////////////////////////////////////////////////6 x  _- B1 y# c3 Q- P1 L

  R' y1 w$ Q1 }" k  WNTSTATUS" M: X. i  ~8 `0 k' m2 e
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
, T# S/ W# T+ Y% e6 T{# f: S: A' n4 |3 y
  NTSTATUS status; ! {+ @7 M, M1 {; n! Q
  KIRQL IrqLevel;
1 R- X2 D4 J0 u7 J; K/ F* M1 r1 I% s1 C  y
  PDEVICE_OBJECT pDeviceObject;
( w7 @6 k4 ^* S, o- c4 P  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION ), p' I) |' V, a, [. e: p
                                   DeviceObject->DeviceExtension;
# W" ]- `1 S0 ^2 P% C! Y3 u
* n+ H& Z3 j" F# A  \% h# r
: I  H6 t/ v0 j% T5 m; ?- t  IoCopyCurrentIrpStackLocationToNext( Irp );4 E6 k% I! `% I: }
) o" k7 |  F( i+ U, \7 Y
  //
8 O# i/ g0 m2 o4 n  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁5 s% u$ k7 l0 ]' p2 L
  //
& W+ k8 J, r! x, x  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
2 e1 p0 y2 b& g, A% _$ \) K  InterlockedIncrement( &KeyExtension->IrpsInProgress );# p  {  Z9 M9 D: x+ x4 l
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );. v3 ~' S$ I+ e; w6 _2 W" P

+ v1 x1 U5 p0 @0 ]0 U  IoSetCompletionRoutine( Irp,
9 w* ?& R, }; y8 i% c( p                          KeyReadCompletion,4 ?3 }4 l  v8 `5 I& `8 ^
                          DeviceObject,, x! [  a% |1 e& Z; z: T0 q
                          TRUE,* o7 h7 O6 H2 d* k& v, H1 w
                          TRUE,- v6 q, y# d( F) R; u
                          TRUE );
& M4 `5 n' e( S; i$ Y5 i+ e8 m
- k2 f5 k8 t" [9 D# g% Q. P  return IoCallDriver( KeyExtension->TargetDevice, Irp );4 f4 ~. z) M7 f  Z3 x8 `3 U" ]
} 0 F" _8 t6 }0 I5 U- S9 Y, K

# g8 I& q6 m* C3 \7 }% \6 Q# D/////////////////////////////////////////////////////////////////
0 y6 x# o5 r% _6 ]8 a// 函数类型 :系统回调函数
4 Y$ X9 [. y% y' q, w// 函数模块 : 键盘过滤模块& e5 b  y# `) n! J* E, e
////////////////////////////////////////////////////////////////+ M5 t8 f. v. d; w( q( P5 x( G0 X
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
' V% J" m/ S9 }- A/ V; T// 注意 :
$ \8 i* e. h6 a, _/////////////////////////////////////////////////////////////////% a8 u$ m- `+ Z4 U6 g
// 作者 : sinister6 S: x1 g: ]$ a. y) a$ |
// 发布版本 : 1.00.004 T: _! ]& [1 y: ]: c$ f
// 发布日期 : 2007.2.12' l$ G$ S- |4 J3 X3 r
/////////////////////////////////////////////////////////////////
' X7 n& P. H3 `& f' R* y8 d// 重   大   修   改   历   史
+ ]: K; Y% [$ Y7 Y5 ]5 o////////////////////////////////////////////////////////////////( W% b7 A" k. c4 J. [3 |+ B
// 修改者 :9 r0 _8 I0 D: z! B' J
// 修改日期 :
3 x) v6 ~4 A$ D( \% D+ c3 t1 B// 修改内容 :/ Z- \8 q( L; f* E7 z- x% C
/////////////////////////////////////////////////////////////////
4 Q6 A1 v  f9 a: W. e
0 D% W# l& C+ ~' iNTSTATUS" M4 y( R' o0 a5 [* K+ h8 i! ^$ H
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
/ _' t& H! b$ x' V0 I; y                   IN PIRP Irp,
7 d0 ^8 D1 O3 k                   IN PVOID Context )4 o0 l( G/ w8 N9 q9 ^
{; h% i% u! \3 D6 W, ~
  PIO_STACK_LOCATION IrpSp;( `; C- x' @1 O, ~
  PKEYBOARD_INPUT_DATA KeyData;
. e  L' h2 @3 _+ ]  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
1 _) `; P" ?0 O% i- t( ]: r$ [) }                                   DeviceObject->DeviceExtension; ) B) ]7 j4 ?4 k* w4 M% T( A% P
  int numKeys, i;0 k- }, ?+ C( m
  KIRQL IrqLevel;! q0 o0 E- J7 W0 Q( D7 l

: k" c+ k0 q7 @4 F  IrpSp = IoGetCurrentIrpStackLocation( Irp );
4 }, Y3 a- W: ?$ Q% }7 ^) ?* n; e9 H7 V* U, _
  D( |4 ]& F% I+ b1 h
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
# {  \$ G$ x% ~9 O* e  {; D5 a4 F7 A9 R
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
7 t( u. b; W# e  m5 d2 C    goto __RoutineEnd;
- m2 @& Q. ^* D: }9 G  }
" Y2 X# r- m# C6 g) p" |! a- H- {% f: O  w( X5 L( E2 ~. g, K4 t# `7 \/ A
  //5 @8 N& H8 C; c# n) t
  // 系统在 SystemBuffer 中保存按键信息
& [$ y& ~+ g" [$ m  //
' l0 }6 ]+ \6 F1 K. A8 b: G! x5 ?6 V  KeyData = Irp->AssociatedIrp.SystemBuffer;. u) q+ i' }9 w1 Y
  if ( KeyData == NULL )0 y. f: D9 H! x2 u1 D7 B  L3 S& {/ l
  {
: u  P5 z) I- F    DbgPrint( "KeyData is NULL\n" );
; {! B( u2 I% b, ?0 _6 A    goto __RoutineEnd;
4 D; ?/ Q' F  B' T% N( M6 S; q5 }$ I  }
0 g8 m4 S/ X" o
1 C0 H# C+ m0 k7 }- {9 f  //
: j( N! T& z* g  ~1 t1 k4 \  // 得到按键数
$ ]. b' l/ T; P  //
/ e$ r1 @- ?- S4 _" z  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );% z8 m/ T0 D$ O* @
  if ( numKeys < 0 )
/ d# G: n+ B- t2 r3 F, \  {
; g4 C9 R+ Q6 y    DbgPrint( "numKeys less zero\n" );! ]5 U- t. @  [/ z5 k1 T% @; Z5 y
    goto __RoutineEnd;
. ~. X! L* e2 _+ }5 p  }
0 h' \& @% u7 V& ~4 E1 l  x2 {2 y  \  ~6 _' b2 N/ Q9 N
  //( r) V& u. r3 o
  // 使用 0 无效扫描码替换,屏蔽所有按键. e$ q  e; q) O( I* g  M
  //
% q0 b" \  g' E0 ]  K  for ( i = 0; i < numKeys; i++ )
  I3 h/ ~1 P, m$ ~$ q6 H; W$ s  {# ~* ?' S0 ?4 Q5 Q# g5 ?; w9 T
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );: M3 u, S& j' q- e1 M" Y: o! n
    KeyData[i].MakeCode = 0x00;" l) E& K0 N1 p7 m9 p+ S5 W
  }
+ I5 z7 V% \" i7 s
, X. h' ~- I: V# }% z2 c+ z' C# i& M: @6 G
  __RoutineEnd : + L6 z4 d% N& }* I! E1 p

2 T0 e' I- }1 i4 L4 C* b& b7 ~  if ( Irp->PendingReturned ): G) M' V2 ]7 \% i; s' e
  {% ~# z4 I2 d+ ^' W- A3 @9 T. s
    IoMarkIrpPending( Irp );
: D' X' W; Z4 F, g0 K; `0 b$ x  }
" [6 p* a9 ^; J* p, }
0 D$ {, c8 m8 t* h4 U& _  //2 b+ Y3 k* E' V  d6 g0 o7 }" M
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁9 v8 P, X  q8 X1 q+ ^
  //2 B" |# Q; _- c
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );2 }/ ]" S. i  M
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
' j6 x4 h5 j2 ?5 J5 E) `3 o  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );/ F0 `# d6 l$ @$ e

& M+ |( O6 v" e3 ?" ~3 w  return Irp->IoStatus.Status ;
- ~7 B, B0 P. O% m! ]4 ?' @}
3 h+ j6 F) x! d7 m. U" o
5 a( S; o  ]' W3 p4 X$ N5 t6 _$ j( P: q# F
/*****************************************************************0 y- r" f9 K7 L, Z0 @
文件名        : WssLockKey.h
8 ?% |1 A6 p* n# M& h& P- i' A 描述          : 键盘过滤驱动
" x. V# C( O$ V  [5 c$ ] 作者          : sinister
0 t# O4 s  {" B$ S1 ]: E 最后修改日期  : 2007-02-26
# y+ \- Z, [* e- y& q) j*****************************************************************/8 _. ~; b) I2 P9 e6 G
5 G+ W# I. w' c4 z2 W( D9 y3 D
#ifndef __WSS_LOCKKEY_H_) ^, M/ {5 w) H" k
#define __WSS_LOCKKEY_H_
3 z* V6 Q3 A0 l% l9 p8 d# K( b* \+ H
#include "ntddk.h"
& y6 k" I, L* {+ c. n' s/ u9 D. p#include "ntddkbd.h"0 z* ?& ?5 M, n! }& o
#include "string.h"3 ^  f- m$ D5 a- b+ [
#include & K8 O. {: h4 {+ s$ D0 ~4 i# t7 M
) e- Y3 c% H; j0 O' E
#define MAXLEN 256
% [2 B, \" N" K" r* D
0 d5 ]+ t2 y; ?" @#define KDBDEVICENAME L"\\Driver\\kbdhid"
2 [% f" V% P6 H% R# s: i#define USBKEYBOARDNAME L"\\Driver\\hidusb"
% L  q9 S: f/ V/ r* ~#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"  v+ T; _6 ^* F& n& |# p8 g0 r- C

% h) C# v; P3 Y7 z7 Ytypedef struct _OBJECT_CREATE_INFORMATION
; S/ I7 v$ E& d# s6 a2 l{
# n; D0 b- ?1 r    ULONG Attributes;6 J" ?8 A! G3 Z3 @& a2 g; G4 B
    HANDLE RootDirectory;
/ g+ N6 n* Z" O! I4 |  _' s0 n2 y    PVOID ParseContext;
& ^, \7 T, R1 q. z    KPROCESSOR_MODE ProbeMode;
- h& f, U' Z: e9 |$ \* u: Q+ _. J7 j    ULONG PagedPoolCharge;3 D+ {( f" T* K+ z$ Z
    ULONG NonPagedPoolCharge;
1 @9 N- }2 V! U3 g# d  @6 h5 J    ULONG SecurityDescriptorCharge;
5 z3 y, A4 T. x4 n4 P: t  H3 h    PSECURITY_DESCRIPTOR SecurityDescriptor;7 d5 `. J* R9 Y7 B; g3 _8 f5 K
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
, l: l1 T) l4 ^0 Y) n8 d    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
8 B4 X9 X& R( I. k( n  @} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
' m8 H3 ~& F- _( a' D4 P7 I  z& a4 \
typedef struct _OBJECT_HEADER( q  N, Q: B, v0 n* a" X
{
5 ]6 ]2 _) \8 b# M- h4 l    LONG PointerCount;
3 \6 U, h. E& x" x- o$ }    union
; w8 m1 ?7 y1 ?    {# X9 h  C4 b" f) j+ t
        LONG HandleCount;2 y" l- y( t$ w4 F- r
        PSINGLE_LIST_ENTRY SEntry;
; a- x% Y" i7 T  P    };' d' L: }% v" ?& i& C6 S6 t
    POBJECT_TYPE Type;
: @* \* q: c% R4 {. c* g9 z. v6 z6 R    UCHAR NameInfoOffset;
0 S* O: Q5 V  w6 a    UCHAR HandleInfoOffset;6 e$ O/ ^- v0 P- Z% ^" Z
    UCHAR QuotaInfoOffset;7 h4 e& w5 R) ]
    UCHAR Flags;$ L; ?  t7 d. V9 ]; A5 S1 |
    union: o5 {' n+ s- q
    {
. ?+ J. \$ Y8 S9 P' B        POBJECT_CREATE_INFORMATION ObjectCreateInfo;/ a* ?0 g) W" s# O
        PVOID QuotaBlockCharged;) `4 O3 W7 Y- m7 U7 ]1 o
    };& l0 d* {' }6 v! A& O* o' R
+ {0 |) \5 v. R) K, q
    PSECURITY_DESCRIPTOR SecurityDescriptor;
& n' o/ n1 x" ]0 i    QUAD Body;
$ H2 G) Y- a  \+ ]} OBJECT_HEADER, * POBJECT_HEADER;
1 L) {/ }+ C+ A0 X
6 j. r" v+ S6 Y7 k' ?6 ]#define NUMBER_HASH_BUCKETS 371 [5 X- s* k& f+ p

3 d7 ?( K. B  V: D" p6 ?& Ztypedef struct _OBJECT_DIRECTORY
- y1 p7 _, E. w{
4 N0 ~. c$ S6 a6 k$ O    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
4 g* x( G$ S* V    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
' G8 N1 A% H. h8 Y8 G5 I3 s9 q    BOOLEAN LookupFound;- r( B/ ~4 b! q4 Y" ^0 _* {
    USHORT SymbolicLinkUsageCount;# C; }1 n( D: k, J: W1 A) d( I/ O6 X2 D
    struct _DEVICE_MAP* DeviceMap;0 z  h- C+ I, [5 A! o: m8 r- m7 q
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
* D, ?$ k# o( \5 w
4 Y3 z; V) G1 C# |/ b' X& J8 gtypedef struct _OBJECT_HEADER_NAME_INFO$ e! z8 ~2 g" X
{
4 q# g9 x* K- O6 G    POBJECT_DIRECTORY Directory;
' w/ ^0 f3 s1 m! f$ b* s    UNICODE_STRING Name;
: Y/ q" F' E* f    ULONG Reserved;$ j$ J7 Z1 i# d# }
#if DBG
% I# r/ i7 Z' l$ m    ULONG Reserved2 ;
2 E! ?& o& q4 B9 T3 F    LONG DbgDereferenceCount ;
4 Y' N* y) n& c  ~; J3 V' e2 T#endif
: |2 k; h/ T2 _" g} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;- O5 _& G: f; U) Q* m. j

2 u- B5 {/ }" v1 k#define OBJECT_TO_OBJECT_HEADER( o ) \
$ Z; s) Z3 a4 n7 w9 F* z3 N    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
4 T) v! s: ]* q% d5 A0 j; D. V/ r8 r+ \& R6 D
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
- O9 ^5 B! ?* t: y/ X& ]    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))& f0 [. [) A( T  V
2 b& Y) C# b$ j2 a: |9 B
typedef struct _DEVICE_EXTENSION
% A. h% F+ \7 L+ `1 R+ D! ]{4 \, E2 J0 ^; Z
    PDEVICE_OBJECT DeviceObject;
8 x6 `3 q1 y; }4 h    PDEVICE_OBJECT TargetDevice;
/ D+ t" x6 X/ o! P    PFILE_OBJECT pFilterFileObject;8 I6 e. g1 P0 M' v4 Z9 F9 `! h
    ULONG DeviceExtensionFlags;7 P! b, [( J5 o6 O7 @
    LONG IrpsInProgress;
' |+ Y, M8 Y. t9 W' u7 g    KSPIN_LOCK SpinLock;4 P& {5 g, c/ Q
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
& ~4 @9 ^$ w4 j$ c% |. Z
! K& f& j  }- o7 \! Q0 `; S$ }$ |1 l- x
VOID
3 k$ [4 d& |# B& b5 dKeyDriverUnload( PDRIVER_OBJECT KeyDriver );
, V4 `! ?0 {5 S+ G# A7 ?/ Z1 K, R+ T* _1 r; `
BOOLEAN5 y  u7 Q% Q1 Y) Q  w/ y; j
CancelKeyboardIrp( IN PIRP Irp );9 a( N' q1 O5 b0 |3 U$ F2 I
% Q, }# }" u- l. D
extern POBJECT_TYPE* IoDriverObjectType;) e" L* x7 @& r9 L9 \

7 m8 \; y( \7 o% I2 S8 N2 ]* XNTSYSAPI- B+ m" |& @' B$ T
NTSTATUS
- s& @" Z0 `2 S3 w0 P% J: l& YNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,4 y2 k- n, r* E) h/ m- a8 U+ v1 D
                               IN ULONG Attributes,  U/ I$ s; V, ?2 o
                               IN PACCESS_STATE AccessState OPTIONAL,- g9 w' h' W2 D" L
                               IN ACCESS_MASK DesiredAccess OPTIONAL,
+ n3 ?. ?* j2 A% f$ F/ q! ^0 ^) G                               IN POBJECT_TYPE ObjectType,
- j7 h$ K- T  `- `* p) v' \+ @5 f/ Q                               IN KPROCESSOR_MODE AccessMode,4 N0 P2 L. Y9 _
                               IN OUT PVOID ParseContext OPTIONAL,# o0 g+ B/ }, S! [& k1 c
                               OUT PVOID* Object );
) ]0 z' V2 X7 i' y7 P( {! _  [( h6 f5 u/ Q- ~; H% p; [
NTSTATUS 7 Q# p: z1 h$ @+ x" B
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
6 D# P1 c3 L, a( r. c
$ Z- ?! T1 O) e* w7 |BOOLEAN % U+ H( L; Q) t8 H
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );& C# [4 x$ C( y) h# P0 `4 N8 ~. o

: T/ T8 @* i6 _$ xVOID : |: A5 K, t3 N3 E! ?) ?* i8 G
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );( [4 e9 d: t/ W! N! G1 q
* k5 V( f) c- ~7 b6 `; F0 V# m
NTSTATUS
9 Y$ q! k6 K' _4 x5 Z; k. AAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,; w# ?0 X* I4 V( [  v
                                  IN PDRIVER_OBJECT  DriverObject );' A$ I7 C9 v5 ]+ i9 t

& d! y" t3 e- Z: s+ y1 ?, FNTSTATUS $ L: P- i$ ?  y1 j* h, t
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
3 d# E) d' y: a/ ^. {+ F                                  IN PDRIVER_OBJECT  DriverObject,
% V) E5 i* }" s6 k; o7 O                                  OUT PDRIVER_OBJECT* FilterDriverObject );# g8 U; t4 o, q9 ~) G- ^
. l! l' @: E) C* m3 V
NTSTATUS ! A+ A# l) v, R
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,8 ]; X7 {4 [$ M$ X, F2 ]- y
                            IN PIRP Irp,, |& u3 e! K; ^$ M
                            IN PVOID Context );
7 e: T  w" Q( Y$ T1 d$ X8 LNTSTATUS
4 B' x9 F) x" Q& F# OKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
- f' ^# s) a1 M8 H- H% r  c/ U$ L5 [& q  o+ o/ d
WCHAR szUsbDeviceName[MAXLEN];
. B8 g# P4 k4 Y* E, d% r/ x- }! Q- R$ c2 A& [
#endif1 |4 M2 [4 }3 h* K
! e, D" F+ ^; X$ b# a0 c3 ?

$ U$ {: Y& n+ ~( H: k  x ; h3 h: u% M* z( c  g

6 T/ Z) L9 |' P! W9 f# w5 \; z
- D! G; Y" C; j) s! rWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
5 j$ v/ Q. q" l. @6 JWSS 主页:[url]http://www.whitecell.org/[/url] ) |) [5 |/ V) H# L" @
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-5-9 12:51 , Processed in 0.028181 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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