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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister: q( o" N, p5 n$ {7 w
Email:   [email]sinister@whitecell.org[/email]$ P& P+ r) A; ]: Q$ }
Homepage:[url]http://www.whitecell.org[/url]
0 K8 D6 K, T( L$ J! {' O* y/ VDate:    2007-02-26
' F; m" M$ v7 x- {% i2 Y9 P0 y) P& p. {2 P

8 k, b- E% a# W4 h/*******************************************************************
# z9 D3 Z/ k5 S( c6 r! Y6 T/ e0 l, e( E
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
1 C( h3 f$ V" ]+ x写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
0 o& I' y9 W" O功能要求如下:9 G7 [4 Y" Z* _7 _4 x
0 r: w" A" `5 a' j
1、强制锁定键盘/鼠标。& P6 a. U9 O- k/ C) r8 P
2、可动态加/解锁
/ H6 B; _/ o- Y7 A6 y3 O. m3、兼容所有 NT 系列的操作系统。
) e/ C7 v: S1 A% h6 y+ U
0 p/ H6 |* R" R3 w! X就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
& e6 a9 H4 }/ G% i( Z' Z' E$ s现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
$ K. \2 h0 f9 @1 K何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
+ f0 A* t0 r) k9 H  F9 N2 G: m上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是% [5 v  y& Q! y$ v9 T
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
9 w5 C4 H: H* ~+ B  c就来看一下我想到的几种实现方法:- r" B/ t$ c; `9 m7 D
, a, \- b* S; K: q' x4 @
1、全局键盘/鼠标钩子1 p6 q2 t2 i* B, q; ]& f) @
2、BlockInput() API( E1 f+ J' @* n- e1 S5 Y% @
3、使用 setupapi 进行控制
4 [4 N. d# K, N) G# _; f' J4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
, e% C! K3 L% O3 u0 @/ @5、拦截 win23k!RawInputThread() 函数( C! J8 |; Q, y( D; b; H( k
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动. y1 i7 j2 k& I& ]. [
7、拦截 kdbclass 驱动的 driver dispatch routine2 E7 i$ \$ \+ j6 k6 o
8、实现一个 PS/2 与 USB 键盘过滤驱动
# s4 y1 }, N" F: z3 X: Z$ p5 C5 r9 j9 t9 ^5 ]# B5 u

0 e7 W$ N" V# g3 I) O我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑/ j% G# ^& O9 w8 X' L2 ^
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方4 t8 s. X0 D  n- c) j& E- m
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
8 N3 u( n- U. \4 Q兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
- w4 p/ p; ~5 b) U0 |. ]素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
4 f' i) S8 [$ n- p/ a; E' C问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
1 ^7 r5 g6 d6 k载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
/ u9 y- \- f7 h& q# _的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来' b& `6 Q1 |5 l2 v! B! f. U0 Y
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
4 b& t9 i7 _6 q# f0 J! a' q果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有( e$ C  F4 h9 _' H
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截# S7 Z; l5 {& F& O
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
! S# u& w' w2 z4 R; X& KUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键- c9 I. L/ ]( }
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方) G' C, V% l1 {) ~& F* l& w0 Y
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。% ^% _; p. j0 ?8 k* @& [

, f& x1 D* N4 ]% H* d0 t& e2 A
6 Y" ?; [: C& F# ~' N我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过0 S" w; p0 B" R
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
$ z; V$ H. [- u6 C  W! D' d. q行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
9 x+ \$ _2 y, o6 L  Y) @# y/ F只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越3 ?& W% [. I2 Z* J% n( @& `4 A
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从1 f' f0 c% g9 P; z5 f6 R" C6 e1 |; ~
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
' K3 \2 A1 _( N5 `% G5 a键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用& N2 I9 k" P! d
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,- F, c5 i' V: J$ L  m
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题. C. f2 f5 q& ~. g' O" w3 q: T8 o
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
" F7 y9 n7 m, g9 c/ F; i0 ]# O5 {# ?4 V而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
& z8 a' _# p3 x: X用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
: e6 f! k$ y& M过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
. j; r& D: G8 n0 L" S( t. [屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
0 {' Z  ~% b$ N# o' Z- C0 Z3 ?0 T) y过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb4 `9 ^) Q9 E6 A* v
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid % N; F9 _3 u) o) Z1 G$ c  d
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意- W- Y' b! p- K- B& n
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。. W: D# w; |! [; d, r" E0 M
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们& W3 d# P7 k' L' w3 m8 J3 k1 f
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利+ h. }$ s7 J% t5 Y- Y  j3 k
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
" S/ ?/ t0 ]. ~3 M) ~* M的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
% K2 p* B$ B0 v* n: J% W敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
/ i- _, Z" e% @, y1 I: u/ M6 ^根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程2 y1 m+ D' Q! K3 d
见下面代码。
8 l7 ]$ Y9 t# n: y2 f7 B' d0 H& B: k  p2 K4 K
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程9 I2 I; n8 G6 [" X: R
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
+ S9 E% ^1 Z( O, L$ V$ V8 C& a- |* I盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
2 [3 x/ @& z8 E( m7 |2 M上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有* o  G. w* I$ }+ x3 K
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
/ R3 A! x* W# E- }; O/ \: g继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个% E: G+ D3 G* S. w3 f7 ]
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按4 F4 \* n9 ?  x  ]$ s) W
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。9 a8 f6 n* V7 s0 p4 u2 U* x( L2 i
7 s+ D) r( @1 y! v8 f- o3 G1 h

( |+ l4 Q% S2 C完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用. [/ M/ Z7 g" |! p$ g4 \* t
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是0 S/ ~. U4 q  w4 v5 j+ x
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣5 V6 C; c4 v6 s. v
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
% G/ u, Z: x0 l! \% _/ Q* G们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
& |( X. |! a: L0 W5 D& O们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension# t4 G9 P' Z) s7 @7 N
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。8 P! S" ?  H2 t1 v3 H  P* s
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager/ S) S) }& ^# x
进行操作了。这个问题有待大家来完善了。4 z. n4 M" C& d# `3 Y. k5 ]7 n% C; c
3 z) [& B6 ^- e3 j3 C
& z$ C# j. m1 Y/ w
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
) ]: c( m, a: Z/ C7 W/ v6 Y7 |来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的4 A4 J1 j  k+ H1 D* g
分析做个记录而已。我更愿意把它看做是一段注释。
( ~3 W0 g, o2 F/ c! ~! R: W  V1 p( B% I" y% m* }
最后在此代码中要4 M3 F, R7 D4 g

9 M- p1 w6 c1 l. N. y: {感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。2 G0 T! e# @+ O  Q

& w6 C, x8 p% m. s, p. i$ n( ^( A感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
' D! T( }& l4 R3 j
  O) y8 [3 i3 s- o3 a# ~6 H感谢:齐佳佳,过节请我吃好吃的。
+ V% D+ y1 B" M
1 q" Q# |! e5 N; N3 m! A. [( z
" `' L8 P. C. \( h5 w******************************************************************/
3 J9 `/ Q$ z; n4 m% z2 a' A/ c% n' ]$ r0 O; e' U- T
- P3 Y, Y+ A  c
/*****************************************************************' F3 _) B& U$ A8 x5 X
文件名        : WssLockKey.c2 m8 l+ ~# [3 ~
描述          : 键盘过滤驱动3 f+ y4 I- g6 [' ]
作者          : sinister
! ]' \. Z2 o; S4 F6 @# q 最后修改日期  : 2007-02-26; `9 {6 O$ @9 z9 u
*****************************************************************/
* v' Y! w1 @' p7 P/ d5 d; P$ h, _4 }
4 U  B6 u% B' S/ ?6 w/ ]
#include "WssLockKey.h": `8 ]8 J# L9 D4 ~

! K1 Z4 U; {1 K* }  U1 T/ E& nNTSTATUS
3 Q- Z2 D4 H3 V  u7 T6 KDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
; g, H" G+ D7 \2 }2 j3 I$ v' h             IN PUNICODE_STRING RegistryPath )
! I% n/ b) H  N$ j+ i% q9 P. U& I{, t* H7 p$ Z5 h- [
  UNICODE_STRING KeyDeviceName; ; T+ a3 z3 w' ^) [6 g
  PDRIVER_OBJECT KeyDriver;
6 i% t) B- @1 W/ A" I2 W  PDEVICE_OBJECT UsbDeviceObject;
1 h5 A+ ?* r3 Q$ `# j% c5 v  NTSTATUS ntStatus;
& l, I8 |: \& Y5 E! h7 L  ULONG i; 0 k; ?1 K+ G0 z; h1 L: M+ U
+ Y; q8 Q8 J2 C7 x& z
  //
( A7 O0 ~% h/ w- h% v3 q0 p+ e% r  // 保存设备名,调试使用2 |$ u- b" J( _- w( Z9 |: u
  //9 K0 Y& X9 M8 L, s3 H3 L4 Z
  WCHAR szDeviceName[MAXLEN + MAXLEN] =+ o0 R/ _% I) r: _" V8 l
  {
  V0 F6 H6 o  D( i2 x# F- ?    07 q9 C0 W( c- h. v
  };
7 W' Q- F5 I' d5 P* @
2 }! ]; k( G3 m  KeyDriverObject->DriverUnload = KeyDriverUnload;
* @' `- f5 j7 @5 C0 ]' T) L" `1 u- R1 f- t! K
  //: V) r$ _+ |/ z. ~2 h& q( X( V
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
3 T! G( Y$ n. ^  //
$ W& z- l4 p% ~5 {! \# k# V  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法4 I5 d9 O. M7 A
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其) P6 m6 a2 t: j9 u) l+ }5 P# U
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
0 B* e$ ?  z# b7 h( [$ f0 E" }0 m  // USB 键盘设备来进行挂接
1 [# Z$ D/ T; V  //
% v! x# a# Z/ l9 N: c' ?; ]  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );& i6 S# t4 ~, B  X& r8 z
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
/ u. c6 R) F' n: @8 w  {
* Y/ s$ q3 e8 p; t& Y) q9 ?) i    //
5 \- q% `, [0 I& e! F3 V    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
  P0 H- f0 C8 k4 V! m+ ]    // 所以这里打印为空
5 ~' n1 O, W, h; D. E% k+ T    //
+ y" o7 k. v0 X% w2 z& A    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
, n, ]- ^7 k( Y4 {    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );6 l7 o3 h% p9 f2 y. h$ L

8 J& z, Q. D$ z    //
* M/ Z, X) M3 V1 K' O    // 挂接 USB 键盘设备. I  c% w+ C: u) \
    //
7 v+ D, l5 M; K  C    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );2 w1 R8 }# B  B' V, {" ~4 ]" m
    if ( !NT_SUCCESS( ntStatus ) )8 ]1 i* E/ ]) T9 N7 [6 L8 ~
    {4 m& `3 p' j5 F- N; D! y
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );- `1 g) G4 x' @4 M
      return STATUS_INSUFFICIENT_RESOURCES;/ a4 G) j; F2 _2 w
    }
/ U' ?4 D! b* A* ?; k9 V  }' e+ A; O$ F( j; ~0 a' M+ I
  else
5 D1 ~+ q5 Y3 b/ Z) i  {
; g0 t- S5 ~+ c/ D6 B8 B    //
/ G3 J: u+ \6 h( B8 M1 {    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
# k3 G( ?0 }* W) i) E    //
, f! S; u9 n0 V- X& e* S4 A. d0 K    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
' q) q, y5 |1 m7 B/ n4 }3 I4 B. f; r: h% n
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,, p! e& ?  M! o
                                        KeyDriverObject,0 C& o1 {( M& m' d. J( `
                                        &KeyDriver );, R; c7 E# N: U+ ]! g5 a
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL ); v' d! ^" h2 K3 @( y9 z  ?% V/ Y
    {
9 w/ \- h; A; C3 Z: ]) n      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );0 {  y$ R4 j; \& u  f
      return STATUS_INSUFFICIENT_RESOURCES;  Q; K7 X* b. `/ x* x
    }$ P1 `! y- @5 j9 D! j2 t- r, B' E
  }' @5 w5 o2 X3 I  m, K1 T6 `' D

8 y: b5 A4 C7 X1 H5 B! P  //
7 _) ~, I3 a0 @; y' U7 e8 M! q  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止: d  r" x# ~  E* |  J
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
3 j8 y6 @; U8 c+ y- i  //; s! F% P( a# l) Y# x! F% X4 _
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; : k+ p9 {% h3 d- H( ]3 j( l9 j
# E: W+ K7 F- L. j& U. ^
  return STATUS_SUCCESS;5 V) X0 H: M, m% }$ p$ @  f# D. u8 ?
}
! M( V5 E8 F: ]. Q6 o4 O" P6 `  x' R' ^  C# m  B& G& ?
/////////////////////////////////////////////////////////////////
( ~; q3 P# u! b0 {/ r5 @* D: N// 函数类型 : 系统函数
5 a; F4 l0 T% ~2 R; v- W/ m3 U8 s// 函数模块 : 键盘过滤模块/ h, L) G. c; k5 Q/ c, h# j' k
////////////////////////////////////////////////////////////////
' }7 C, a0 \" i6 @: n// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
& h" f5 B. _* h& O7 q//        卸载键盘过滤驱动& q1 _; C3 G- m
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上! e5 H5 X' G0 Q5 z% N: {
//        则需要等待用户按键,以后有待完善$ j1 u- G6 w0 G) V. c: F" A
/////////////////////////////////////////////////////////////////
$ x( f& @" ^* q- }$ f// 作者 : sinister' u* u. y0 B3 D! b! d+ B1 p: B1 Z
// 发布版本 : 1.00.002 J: Q2 @# l0 w' i& s% Q: C, H
// 发布日期 : 2005.12.27' P$ z6 r2 {/ f6 |. H
/////////////////////////////////////////////////////////////////4 o, C: X! k* V' r) r" L( N+ J
// 重   大   修   改   历   史
0 H7 L& b' `" Y6 K& h////////////////////////////////////////////////////////////////
' T/ u. ~! W" t* i7 `// 修改者 :$ D2 i( ?, F3 N$ d9 [
// 修改日期 :
$ O' }: s5 N! `& C! F// 修改内容 :- K2 {' N: f9 ]- \; O8 b
/////////////////////////////////////////////////////////////////: B0 h5 ]) f1 B  z. g4 V9 [

5 q4 m: s* u& z/ wVOID3 N$ b, \* D+ H1 G! Y; Z* k
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )+ U1 h$ r) i4 A  f% R
{( m0 \( @/ X7 t+ w( [
  PDEVICE_OBJECT KeyFilterDevice ;      
- l+ @0 Y2 Q) f6 Q) V2 C  PDEVICE_OBJECT KeyDevice ;
; O$ D0 _2 W0 Z5 j  PDEVICE_EXTENSION KeyExtension; ! e1 \& T; k+ r+ d
  PIRP Irp;
9 O. Z, k& t( D( K% {( q  ]  NTSTATUS ntStatus;& Z, h( j, Q$ a1 r) \

9 V7 m/ ?: V& i3 ]# n' }  KeyFilterDevice = KeyDriver->DeviceObject; 2 l& ^6 {9 {5 D$ _9 c& a- U
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; & o1 {2 U. R9 G
  KeyDevice = KeyExtension->TargetDevice; . z1 x: r' I+ v7 [+ t4 l, ?; m
/ C+ \3 u. l+ `" B3 Q1 i
  IoDetachDevice( KeyDevice );
3 E; e( g/ e5 R5 u
$ Z  p1 r/ w) Y. I3 J2 D" V9 o  //
: e6 \9 z( q1 X+ d" O1 m5 K  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
2 ~$ H. e7 ^' g& S& ]2 V9 u  //( B. G+ k) R- e- f# ]1 [2 D; v
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )- r7 S0 l1 d, ^7 M6 |
  {
1 ~+ K, F9 g4 O' @. X9 H7 f    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )% s* w( F3 \! t* W
    {' ]$ q5 S/ N/ R/ n( J9 q' p
      //
# I2 A$ E! S* a: p3 E      // 成功则直接退出删除键盘过滤设备
$ M) e( B) y- i6 f      //
8 v6 r- J1 ^3 ?; L' G      DbgPrint( "CancelKeyboardIrp() is ok\n" );' T7 A3 W& j4 G8 V4 |
      goto __End;( @: r" o" r/ j! E, H8 P; x
    }
( _( o8 G9 u* }) a; Q  }
! q9 M4 p$ h: V; ~
5 J) `/ Z1 j; R9 k! d8 j1 t  //
4 O1 K  n) x. A; i8 E8 m  // 如果取消失败,则一直等待按键7 _' a/ d! s5 o" p4 T- t
  //
1 Q% |: \& H1 p5 i  while ( KeyExtension->IrpsInProgress > 0 )
- o4 Y3 G* Q; E4 D* ~* B  h) [; U  {. T+ {" k0 h$ Q% S2 D
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
- V0 |! f/ E& o9 l  P4 t& a; E  }" p$ v$ G1 N. T

( g' K! s) n3 u  __End:" x8 ^, _. n6 n4 b: D% U" S$ i: g
  IoDeleteDevice( KeyFilterDevice );
5 N* z. s7 G2 W' j4 |) B( Z
, w* I( Y! R# ?+ C: [& Y. l: Y% Y  return ;( c/ r0 K4 Y- O- T) B& u
}
& b4 Z, R8 p5 B7 m
/ z% ?6 L7 B# D" V& Q) D  J! U! e/////////////////////////////////////////////////////////////////
6 W1 F  o* {1 D" @: ?// 函数类型 : 自定义工具函数: I- l+ k3 m1 B9 `
// 函数模块 : 键盘过滤模块- t* I: f" T' {8 F0 J1 v! \4 ^
/////////////////////////////////////////////////////////////////
8 \4 X8 b  R# W/ a% T' w4 H9 W// 功能 : 取消 IRP 操作
2 S) c+ n( s' i/ i& d  u0 q7 X; M// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
: W( V) ~; f  U4 V7 x/ a3 U7 x//        使用此方法来取消 IRP1 i* F# ^% J3 n" `0 `
/////////////////////////////////////////////////////////////////( l7 j+ U: t' w  d' m
// 作者 : sinister0 i% ?7 e- q' ~" ?8 p* ^  ~8 ?
// 发布版本 : 1.00.004 }4 E% h$ O2 f# P5 X
// 发布日期 : 2007.02.204 z. J+ x" c' |, v, Q# L$ d+ ]
/////////////////////////////////////////////////////////////////" y" @* m' _  V6 `: J
// 重   大   修   改   历   史& Q1 A7 l* r( {. T
/////////////////////////////////////////////////////////////////
* r5 S1 O. O4 B  x, n// 修改者 : . E% Q5 w# d+ o* {, b
// 修改日期 : 4 e% N( {- F0 v9 H5 E2 q/ r' _
// 修改内容 :
; N, v6 f; `; F# a6 u8 t. m/////////////////////////////////////////////////////////////////8 \  A2 n1 @* I- ^$ i" n
" M- i. Z+ S) ]6 F3 T# q+ Y& w' {6 B
BOOLEAN8 b1 C! d4 w4 I6 ?6 H3 C' v- T
CancelKeyboardIrp( IN PIRP Irp )
  E. i! D$ k% z9 n2 e; ^6 R{
/ ?! E- z+ }/ Z3 i* ?# F  if ( Irp == NULL )0 L  ^" f+ F+ S! r4 x
  {5 e+ u! ^) C# S* H3 k" `
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );/ Y3 H9 O: z8 v4 @2 u( _  C  O# i( m' x
    return FALSE;
9 Y; a3 Q) ~- }9 e" Q& H; J  Z  }
9 z+ P& L9 F( c2 y0 n' a# e$ Y3 c0 n9 P- A$ [7 Z$ V4 z" o# D- L
8 D/ ?5 S/ K! g& F1 Z; d
  //
. P( A- G( S7 T; r  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,, b; |* y9 q/ M
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。/ X6 \1 {% R7 ~, P& S
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
+ I$ w/ {) I7 h! V  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD/ ^7 U. Z( i# F+ }
  //
/ v7 s5 B& V4 S3 ^
1 y  @: V% ^+ c% q2 `" a( U  //
  {- G" y0 _5 s/ Q. h  // 如果正在取消或没有取消例程则直接返回 FALSE/ Q& p% ^% Q& s1 h: A4 X
  //2 x# ?  {/ ~2 K# X
  if ( Irp->Cancel || Irp->CancelRoutine == NULL ): H" U3 t) h7 [, g+ j3 O
  {
) E( h. R, ]2 q) l3 N2 `& \    DbgPrint( "Can't Cancel the irp\n" );
* {' @; E. M- s9 b7 L    return FALSE;
: Q- D: e) D( y$ m2 ~9 d# `  }
! o) {( L& P5 Q) q( w" i) c+ u! S" e/ X) H: P7 A
  if ( FALSE == IoCancelIrp( Irp ) )
; [8 b/ p  J  L' F  {% _9 ?  i0 V4 K+ ~8 o
    DbgPrint( "IoCancelIrp() to failed\n" );& S# ]( g; f+ b; x2 H: E5 p8 ]
    return FALSE;
/ K  g' ^1 B8 f) \  }
1 h; s/ [9 Z" O# @, ~
- e8 `3 E  Y- R7 `  //
9 s% u  w2 E% Q# Z" Y  // 取消后重设此例程为空; C" w, p% ~/ l" g( `) Y" f4 F
  //
! Q+ @4 \& u% b' J& \  G/ f2 w  IoSetCancelRoutine( Irp, NULL );
4 J/ g5 l9 u) b# R+ K6 k$ \$ N$ f2 R9 g
  return TRUE;
' d" O6 Y8 b! Q' d" V+ a& W3 K}/ n, r4 }1 }  o6 k8 d
! w9 c- J; C; t6 D! _( i
/////////////////////////////////////////////////////////////////
' A5 {# i- f5 a( y, Y// 函数类型 : 自定义工具函数
; K& b. ~4 Q3 V3 }// 函数模块 : 设备栈信息模块
7 d, ?5 z8 [; m9 w" L/////////////////////////////////////////////////////////////////
& U" |6 d- y8 F% g7 [7 G// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
2 Y0 c- U# O4 n//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver): e: |# K* I; V8 m7 [( u$ E
// 注意 : 7 _. h' b+ s6 v& j9 X$ R9 J! w! v
/////////////////////////////////////////////////////////////////8 r; n3 x9 @% v- e# X) z
// 作者 : sinister. T5 C" O  H9 R1 ~. f1 G# Y* X
// 发布版本 : 1.00.000 M4 P7 V( D3 i, }+ H3 p
// 发布日期 : 2005.06.02
5 E2 w+ l4 @9 ~/////////////////////////////////////////////////////////////////
# {% h6 X+ ?: v! {# B) m// 重   大   修   改   历   史- _7 I- P# b- u2 }2 N9 z9 |
/////////////////////////////////////////////////////////////////# p- [( ?- }1 \( V% N2 B0 i' k
// 修改者 : sinister/ F& Q5 W' K$ v5 V1 ?2 X6 e
// 修改日期 : 2007.2.12
* H4 r1 x0 E/ g2 v0 s: u, w// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改2 A! q9 S& n2 }$ t" L, J
/////////////////////////////////////////////////////////////////) I& m/ k& t% L. Y
, g$ I3 N9 j5 ]9 n
BOOLEAN; O# |7 z* y0 m2 O
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
5 K/ c0 l$ t0 B0 S4 H{- k& W! Y! u  J% @2 z8 P  I7 e
  PDEVICE_OBJECT DeviceObject;
$ ^9 ?2 o; V0 m) |8 I# F  BOOLEAN bFound = FALSE;
. @! p" y% p; c6 W
5 I5 p9 X: F+ H$ a  if ( DevObj == NULL )
+ d: m& R5 n# z) h  {
0 ?& `9 d2 p, Z( v7 q    DbgPrint( "DevObj is NULL!\n" );
3 ]6 c; ?6 V- `- H! ?- E- j! Q2 I    return FALSE;
/ \" ]8 |9 s* c- F) t! W  }
  T1 s1 ]- M: N3 m7 C8 B; D" z2 E' j& Y: ]+ Y5 w
  DeviceObject = DevObj->AttachedDevice;
" B2 U( K$ f4 Y- C! w& R1 ^  u5 N0 g$ @' Q
  while ( DeviceObject ); _1 L- A% z4 L2 l( D
  {
$ U/ I! v* H3 i& l! X    /// r& U* Q; e( B9 s
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
4 f( r) r: u# L, ~. o% @( T$ @    // 有一次足够了。这算是经验之谈
0 n, }; D% Q# p    //
0 l& F, S- ~1 e: R    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
. n# |: f& H  E" h  g    {
+ h9 o2 P  h) Q) w% ]      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
, |$ \6 ?; T4 R0 w3 X# V' ^4 Q                DeviceObject->DriverObject->DriverName.Buffer,
( i2 z) n  e1 k5 h- S                DeviceObject->DriverObject,
3 I$ h, n' R1 b9 x                DeviceObject );
# l& `7 m1 D" l9 n3 k7 U) Q* M, `6 x" U
      //
' l( T% N/ ?1 \7 p/ }      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了* j* c$ b, Q+ Z0 C6 k" E( X0 I
      //
/ q9 v% f# L* d" F      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,7 x; j& O4 o1 s7 z5 B8 L. N
                      KDBDEVICENAME,
% @1 n" S8 [. j! V                      wcslen( KDBDEVICENAME ) ) == 0 )3 \  s9 N8 Q" G2 _
      {# |& x! ]- @/ t. @! l( \
        DbgPrint( "Found kbdhid Device\n" );
( |# I( E/ S/ w+ ^  ]* I' ]        bFound = TRUE;% p, Q% G, c6 \$ E7 p* \, Z7 c" x
        break;/ j0 U# P6 ^0 ^( I
      }  ?3 D; Z, f) `  N0 s3 Y: e  a/ ?, O
    }/ B' z& p2 B- P+ l4 j
% o2 s7 A( h% J: C
    DeviceObject = DeviceObject->AttachedDevice;* }) C6 P- d5 Y! I6 j0 ]
  }
' M1 {$ f1 o2 I6 r1 g, q( R$ i) F& F/ g2 @0 U3 p8 M
  return bFound;0 @; K; m# ^3 v0 A/ G" h( P
}
% _+ m+ F6 Q5 B3 ^9 n& b$ E8 N9 n" n1 Y' n
/////////////////////////////////////////////////////////////////; Q0 p6 b1 O; E& m. {  ~
// 函数类型 : 自定义工具函数
. Z$ s4 V2 d( I) Y// 函数模块 : 设备栈信息模块
! b# L/ P( D9 ^/////////////////////////////////////////////////////////////////7 w8 k4 _9 V! }0 q. L
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址' E5 d1 |5 O9 J7 C3 G! E
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
; X/ P9 P  B3 A( U8 ]8 b$ f& l/////////////////////////////////////////////////////////////////9 h8 s/ y. z* g, e
// 作者 : sinister) }6 q2 y/ |4 G
// 发布版本 : 1.00.00
# g; J5 g& n) D8 D! x6 W// 发布日期 : 2006.05.02/ a% ^$ _2 H. u5 r! t5 X
/////////////////////////////////////////////////////////////////
7 B! ]; z3 Q- F// 重   大   修   改   历   史9 E9 I8 o5 f) z7 P( s
/////////////////////////////////////////////////////////////////- l$ A8 G$ Q8 ], ^9 P! h
// 修改者 : sinister
8 d3 f, K! v) b' S// 修改日期 : 2007.2.128 N2 a# ?; W5 L/ o, Y. t- n5 l
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
: J' I* w+ c+ ~, f  ^6 h/////////////////////////////////////////////////////////////////2 P# T# f% w. V3 i2 o1 W1 y% T
' D, _! \. C1 m% j% R( k
VOID
+ m7 \+ W; q7 ~GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
+ W+ g5 H! R3 G$ V% @& c{( r( {$ `/ r+ b/ T9 j
  POBJECT_HEADER ObjectHeader;
1 X: F; }2 B" ^$ Z2 ^; g6 U) B/ x; o  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 5 K! L1 e! j9 |3 C* t
7 q6 F  f* W$ w3 H: t
  if ( DevObj == NULL )
5 ^/ Y1 r; `  ~( m% d  {
4 c8 ]# x0 X2 k+ k- {; U& @6 n# ?    DbgPrint( "DevObj is NULL!\n" );4 W. d9 \9 p; w3 D* ?' @" z
    return;
+ q3 m1 S! G( Z! }7 C4 E/ u3 A  }
7 ]6 M5 o8 Q  a- D( |- c+ y7 i# D2 O. W  O5 ~+ k# I
  //8 Q, |" A% H1 u
  // 得到对象头" O: K9 O, u& ^
  //" r, |% `. m5 q8 K3 b
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );+ m: N, Y4 F% A" T, x
4 A* R0 S/ N0 y( {" J, ^% z
  if ( ObjectHeader )2 O9 ^+ V  e0 |
  {
  ?" a7 C* U* c& O    //0 C& v. f7 p4 R; p8 W% ~
    // 查询设备名称并打印- t# w& F, C) a( F1 i1 [
    //0 s9 G+ C9 Z. M* ?
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
/ s- ^, q5 a$ q8 Y2 ~8 }( P# a- E6 l/ B8 }  }* H! c2 W; I5 Z  }$ s' N
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )# {' Y; X, Z/ R# {8 h0 J
    {
9 A) S# i2 C. H9 K& e6 Q" q      DbgPrint( "Device Name:%S - Device Address:0x%x\n",  c* w+ K% q- J: r: U' `8 u3 \
                ObjectNameInfo->Name.Buffer,+ L! ?; `  }- J% K0 q, ?; U
                DevObj );( m# O" }" F7 L1 Q' a

1 C7 x. @% g. U) Y; ]" m; u      //
+ m5 D: Y+ E1 @4 D4 g$ A      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示3 k& K6 `8 e8 J7 A* J5 V0 y. g
      // 用,没有实际的功能用途7 H* H' I+ o5 D6 \2 ]9 A
      //$ {6 g. K4 l8 R  r3 o0 n& v; Z( Z
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
4 ]2 ?0 x0 y2 }- ?1 [1 F  f8 F% T+ O7 D8 N( _
      wcsncpy( szUsbDeviceName,
& t5 \- B0 W$ k. ?2 v. m               ObjectNameInfo->Name.Buffer,+ k6 V" z& @& }8 \/ L0 J) l
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );$ t& J  p7 T* p
    }$ ~3 J, M. {$ U3 {

- k' Y7 c5 U, D    //+ O' b. u3 U" n+ b- n" i
    // 对于没有名称的设备,则打印 NULL
/ `* e% `& ^0 _% s0 Z    //
# _9 R! H- N9 X4 s    else if ( DevObj->DriverObject )
+ F( `# x8 ~! V  z6 V. u! t4 j    {
1 k/ F6 c  x2 n* Q1 ^0 ]4 e* s      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
" Y. `4 }/ o9 h' F2 N, \; Z                DevObj->DriverObject->DriverName.Buffer,
+ b) b& E5 D2 m  X6 T/ B                L"NULL",4 j, x  \% b9 U' D6 f1 s
                DevObj->DriverObject,
/ t6 u0 l: j0 A& v& [) R                DevObj );
, U* D2 K1 B3 O& y    }
( E4 @7 j: \) ]! l* r2 w6 k  }
; B7 h8 U& ~% }) b}
( f9 T' q9 }* M7 W! @$ \8 V' K0 P4 R1 [$ R& u, L
////////////////////////////////////////////////////////////////// }+ p! h& y1 ^, o
// 函数类型 : 自定义工具函数
+ v3 q, r' ?9 s! J// 函数模块 : 键盘过滤模块
' ^1 R! D# z; ]/////////////////////////////////////////////////////////////////
; ], R  `/ k; v  j" D4 z$ J// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备3 A& A5 G  F8 w4 G
//        对象,过滤出 USB 键盘设备,将其设备对象返回8 g; V9 Q7 g6 N
// 注意 :
# T+ ^- u* y: V! [2 ~; z& h/////////////////////////////////////////////////////////////////
4 r9 F3 R1 h* T' L9 H$ ]// 作者 : sinister
: ~0 x/ k! C1 o5 L// 发布版本 : 1.00.00
5 L2 c: E! M6 x5 ^  e// 发布日期 : 2007.02.13% k; p+ M: L- L! i$ ]
/////////////////////////////////////////////////////////////////
8 {# P* n, ^1 Z& H7 \5 g* M! Z# c5 V// 重   大   修   改   历   史
9 V) ?% W' ^) }/////////////////////////////////////////////////////////////////* M) L: q3 S5 a
// 修改者 :
- b% g$ |: H) w& }1 d4 Q// 修改日期 : 0 P7 _6 y  W3 V- x2 f( }5 w; W
// 修改内容 :
. Z0 I: G$ f  B  D. d8 q3 `, [, }/////////////////////////////////////////////////////////////////, H$ C, V$ K" M
, C! Z. M  ~, ?( Y  w' _
NTSTATUS
' a: w$ q5 l) P' \% AGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
* W9 q) O, t6 P4 x& G9 I  Q{
! L# h6 ]; A% O3 P: m  UNICODE_STRING DriverName;1 G! b* L5 y4 ~
  PDRIVER_OBJECT DriverObject = NULL;
. s7 J6 q) T! k7 }0 `! ]7 m  PDEVICE_OBJECT DeviceObject = NULL;
8 D' c* Y1 ]- R) {) O3 X  BOOLEAN bFound = FALSE;
4 Q, b# n* S' j% E, j% N: k# r
; V1 b# T- c5 E4 d/ k# j  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
3 Z% X% S* m7 D% \6 ?1 p: p
' h! w5 B7 F6 z, f7 ~! D2 A  ObReferenceObjectByName( &DriverName,1 {& k: H* n+ I1 h: s; P
                           OBJ_CASE_INSENSITIVE,
# j4 E0 g# K% F                           NULL,8 F  I9 ~9 O2 l" E* Q$ m
                           0,
6 P& O' }8 F4 y! F3 T. Z: _! S6 ~8 r                           ( POBJECT_TYPE ) IoDriverObjectType,
: r/ \6 |5 }; A$ i& {                           KernelMode,
2 ^" m, L4 m/ g+ p; w                           NULL,+ }) G# a% @! G8 c* v  i/ T
                           &DriverObject );
& z1 W$ a" \' C9 d3 T, K9 J. }5 e- y0 _9 y8 l  g  ~
  if ( DriverObject == NULL ). L' c2 }2 e* j  K, X
  {+ _8 _. ?4 \+ z+ C2 X
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
5 ?5 H2 E3 {: x) W9 f, E: X    return STATUS_UNSUCCESSFUL;
6 z& o5 c/ G5 i2 S. W3 e6 z  }! x  G( s+ n, O  n" E0 E1 g% X
, W9 e$ A5 H) s
  DeviceObject = DriverObject->DeviceObject;7 Y- o9 j$ g; S" K
6 k1 v3 G9 b; `3 |
  while ( DeviceObject )
( k- _2 C" \/ e. F7 `; x% [  {
5 v0 N2 j! @6 C# {" A1 a. d    GetDeviceObjectInfo( DeviceObject );
9 J  y& g; h8 w" p; r
0 e* t% m% o8 |. l    if ( DeviceObject->AttachedDevice )
% Y$ K4 w: \% w2 H    {
3 M+ ]' _) ?" q# \7 s5 L0 q- E      //: _7 s% y7 N" }' E
      // 查找 USB 键盘设备
+ A6 ~9 Y! D0 `2 @0 ^      //2 B, d& R' e1 a  K: N
      if ( GetAttachedDeviceInfo( DeviceObject ) )! z% {. f. R: @4 q( U
      {6 s. N7 F% f4 Y5 L9 Z/ o; L1 ^) R
        bFound = TRUE;; G/ f  X; Y, V0 Z0 w5 B2 b: L8 }
        goto __End;9 w9 F( x' v) k( k' U" j
      }% R# u, a, j* {! F. Y1 C5 f+ ^
    }* j6 g, h6 q% _! C4 s/ L4 y
/ I" B+ _5 _9 S, h
    DeviceObject = DeviceObject->NextDevice;) F- @3 v( b1 |
  }7 `$ d2 _8 C1 [1 b
* T5 Q  c! Y5 `; a/ F8 v
  __End:
! `& S) z' J. q+ W  X. @8 S. g5 u7 m, k0 N  h: f
  if ( bFound )! ^4 m2 L7 Z# }/ D, S- w
  {
7 A: g+ E4 e6 o- x    //' [$ t" h+ e2 j1 @" N1 }
    // 找到则返回 USB 键盘设备对象# q% Q/ ~) a) r# ]
    //6 L4 ^/ G) ^2 y6 w# s* {
    *UsbDeviceObject = DeviceObject;
: Q& E" v; A/ m: |  }
$ a! x& u) R1 l9 `' ?2 i: X& A  else, Z* a( I0 y9 B& w# u9 w) `
  {7 R. r2 N7 ?3 r( K
    *UsbDeviceObject = NULL;
; D, ]% `7 K* a, L5 y, O  }
* y1 q+ L6 q2 a5 B$ {5 E
4 z* S: w2 i: J. _. u  return STATUS_SUCCESS;
& B8 t# ~( r# {* s! ~9 a: E}& T* z! j8 V% W/ a/ U
0 V* f$ j+ Q: D# y
/////////////////////////////////////////////////////////////////0 b; e3 |# r  ]) m0 g
// 函数类型 : 自定义工具函数
( C& R/ g- f# X6 O7 ^" ?// 函数模块 : 键盘过滤模块
- ?0 I+ C; A/ A. g/ ~5 f/ A$ J  A////////////////////////////////////////////////////////////////2 q: Y! q2 I& f$ ^5 D$ |9 K
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
. M2 t! w+ |7 t! U7 ?9 B. g//        信息,返回附加后的驱动对象
4 r. Z# q0 i! s8 G! Z// 注意 : 此函数仅挂接 USB 键盘设备
! I3 f" t5 [5 u" e4 ~0 R& R+ g/////////////////////////////////////////////////////////////////
3 M1 i( T' ~8 y// 作者 : sinister4 u- O) Q* c. s  }% Q4 i
// 发布版本 : 1.00.00
- C$ e1 u+ X1 o: c5 z// 发布日期 : 2005.12.27
& v; F  ^# B7 [5 q. s  I/////////////////////////////////////////////////////////////////7 ^- z; B% R& p/ y% y; L, ~- m
// 重   大   修   改   历   史
* ], L$ Q, W3 a4 y. X  E& z' J8 G////////////////////////////////////////////////////////////////$ t. G9 E$ J% Z" R6 D6 n
// 修改者 :+ y2 N4 d2 d' a+ d: h5 h
// 修改日期 :
/ N. v) q+ W* t// 修改内容 :
# X+ ^9 t" e4 d5 h! f/////////////////////////////////////////////////////////////////& O6 V) E5 J. b/ Z; \; z$ D+ U& f

- N* r8 v% h0 x/ D, y" fNTSTATUS
, `: r+ _, K- F9 YAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
6 [4 }1 U0 ~- F, Z# f9 i& n% k                         IN PDRIVER_OBJECT  DriverObject )
1 s; \- ^" Q+ u7 c9 U{
: L6 Y! e2 m! {. t% n  PDEVICE_OBJECT DeviceObject;
! V* L, `# w/ M' J1 i4 Q  PDEVICE_OBJECT TargetDevice;
. @) `' r7 v. |0 N  PDEVICE_EXTENSION DevExt;- H, {% R9 R* Z  }
  NTSTATUS ntStatus;) j; ^2 m2 z+ \6 @% N

4 W9 D$ o( u3 Z% |( v' p  //
0 y: e$ {4 F$ k  // 创建过滤设备对象+ d  j; z: d. @& G
  //
  l# W9 e- }6 t* P+ @  ntStatus = IoCreateDevice( DriverObject,
/ k; K8 S# p- ^                             sizeof( DEVICE_EXTENSION ),* u# n; x* ~0 a- E, W
                             NULL,5 z' v( t( b- J) d8 _& f
                             FILE_DEVICE_UNKNOWN,
2 k* X- ]  J" s$ q) J# b$ Y2 \                             0,
) @: Y" }5 C0 W2 d" V: l$ T                             FALSE,: j" z( v8 A0 o
                             &DeviceObject );
; H' X) ^/ x7 B6 x' e- D% n6 N
0 o! U' \- F2 e* c3 v  if ( !NT_SUCCESS( ntStatus ) )
+ H% ?- q- W8 U& `  {
9 f# ^( D4 m3 |    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
- j  t# M4 g$ l+ x" V6 f    return ntStatus;
( E1 Y* l+ G3 H# {! G; ?3 ]$ T  } 5 k2 I( \- @6 D  b% I
1 Q5 N2 @8 z$ v
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
& Y( F2 |9 G. X8 c0 z" U
5 A" L5 Q: B/ b# c8 ^% n0 O- A  //
$ f6 x  q0 @- F5 [$ V  J  // 初始化自旋锁- Q) H4 b$ @  u: T( D, h5 P
  //
- S  q; C3 H# g* ?" F  KeInitializeSpinLock( &DevExt->SpinLock );6 k) r- n2 _+ O/ U- F( q3 [' T

3 g# I: G. v1 ]  A% I$ N( n  //
9 V, D4 ?$ m' u8 B$ |  // 初始化 IRP 计数器
0 g7 q' E3 E/ i' u, Q% y4 F- f  //% B! m- E6 e" V. d7 r) ~
  DevExt->IrpsInProgress = 0;
- n/ v' d" A/ P2 z  M/ F* a
# o6 I0 @; w5 @  Y  /// V: C( r9 y; ^6 h
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
* Y; B8 U: I' K; m! |  //; N1 W( }. u1 |" Z( f, I

& k+ C  m8 w% |9 \: j+ c/ y- e0 O4 y  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
' q  ]! v$ k) T4 X2 U7 h  if ( !TargetDevice )
/ e5 h4 E4 F/ v$ k" t2 a6 Y) j  {  P7 }4 g$ }1 t" @8 }
    IoDeleteDevice( DeviceObject );
6 D8 a/ R% w. `% P9 S    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
# y$ K; z8 J) ^9 j' _6 ?    return STATUS_INSUFFICIENT_RESOURCES;
. M; I2 P; w3 z# H9 C  } / }  [) u* f5 S3 \! t7 r7 C

1 ^9 P3 C& ~/ X( \& B  //
* x- c+ t( y7 `3 N+ b  // 保存过滤设备信息1 p- @. n# x5 f3 x
  //
9 e$ g( P2 u1 b; y  DevExt->DeviceObject = DeviceObject;   n. P" W( z/ i! A# S
  DevExt->TargetDevice = TargetDevice;# f: a2 t. P7 L% I

8 _: @8 `8 U3 m' b% B  //
! l7 z. f2 w/ A7 T$ f6 p/ a6 U  // 设置过滤设备相关信息与标志( M! U; Q# E. G$ Y. X
  //7 B3 ]- E. h7 F- S/ [
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );: s9 B% a( I' ^0 @5 v6 H% q+ o
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
8 m* H' ^+ ~6 e- @# r4 ~; X3 W" x- }* L( q* C& B" ?

- x! k1 F( E8 \; `  X+ z  ]* e  return STATUS_SUCCESS;
% W% @( K, i; T6 H- B8 i( I}5 i7 r( s# j% ~0 Y9 h' ?

  g) f! r: x: \+ q8 f- Z9 f" f/////////////////////////////////////////////////////////////////3 A2 P& N* u5 n) s5 i& Z
// 函数类型 : 自定义工具函数
. h' w! O; ~% H: y// 函数模块 : 键盘过滤模块( g, ^2 _8 H4 Z, ^
////////////////////////////////////////////////////////////////
5 J' b. z1 N; b4 U/ H( ~// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关# ?$ D% B; \' u3 e. k
//        信息,返回附加后的驱动对象2 ]! j- l! Q5 }+ ?1 ~2 C$ q( }8 t
// 注意 : 此函数仅挂接 PS/2 键盘设备
% h( w+ `+ f: X; j! e# L1 Z/////////////////////////////////////////////////////////////////
% Q5 U* t" x  S" ~// 作者 : sinister
, I- B: H3 p3 b3 Y' J1 N* C// 发布版本 : 1.00.00) ?+ f: ^- o( V* m; I# Y' f* [
// 发布日期 : 2005.12.27; ^& M) M' F, H' G9 i) h4 q
/////////////////////////////////////////////////////////////////
4 u$ w6 I2 m2 ~" ^- ]$ F. r6 K// 重   大   修   改   历   史! A% P4 X- g7 \# g% m+ T& \/ ]
////////////////////////////////////////////////////////////////
: Y/ E6 x9 }$ @8 r// 修改者 :! Y1 Z) Q0 W# W  \8 _# l
// 修改日期 :# _6 r) _: {$ P4 E" [+ {
// 修改内容 :
9 b" f, ]5 X7 k! Z1 Y, R/////////////////////////////////////////////////////////////////
' d4 L6 i# b2 L: x0 h3 i/ [/ I' R& B: `# W6 \* z& c! v% x
NTSTATUS
7 B7 }% h" z  o: VAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名' }  X/ O/ x3 L  E( K
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
- S& J9 O6 h2 D5 `; q+ N# n/ C) d                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
% E* s, T3 D" W# Z% s{
3 _% X# X# P- h; k1 Q  PDEVICE_OBJECT DeviceObject;
( O- e, R, v/ }8 `! ~  PDEVICE_OBJECT FilterDeviceObject;0 }3 s; n, N9 v" J7 s! u3 u7 _! ~
  PDEVICE_OBJECT TargetDevice;
, ]2 |# P, ~7 i. W  PFILE_OBJECT FileObject; ( ]# l0 w' L9 P; Y' }
  PDEVICE_EXTENSION DevExt;' g- P1 K9 H: j+ c
" w/ W0 C5 H% i$ t5 g
  NTSTATUS ntStatus;
! E  v: O# G6 g4 A. D9 T+ l
( L7 B0 T9 L8 |. A  //. E% [3 F. D. }1 L5 l. }' e6 B
  // 根据设备名称找到需要附加的设备对象
# {4 s5 a2 y4 ^, R6 r  //9 U0 v) j% _' [+ r
  ntStatus = IoGetDeviceObjectPointer( DeviceName,4 _; Q) {! w- ^. ?
                                       FILE_ALL_ACCESS,
& _* h! c+ s- Y                                       &FileObject,
* w) G! T' P; A$ m% m                                       &DeviceObject );
  S7 u; A# |% M: X8 }) l+ R$ m
* X. K8 d9 s5 L* ?  if ( !NT_SUCCESS( ntStatus ) )
3 N0 l  Q  |0 r+ w8 F. F  {
# q5 C: q) y' \4 i8 }6 b7 T    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
9 E( `+ H% a; L& O8 p- W& K  X# P    return ntStatus;
0 \7 `8 [2 n2 t7 h" z  } ; Q; d# H7 _: ]% _, I% J, X( k

+ y. D" a" e) [. W  //
2 O  e! l% W; w  // 创建过滤设备对象
: a( ]( ^" v7 O  p0 u0 r! l: }  //
# z- [/ n0 [6 E( U+ i/ N) d  ntStatus = IoCreateDevice( DriverObject,
& x7 F$ `5 M# `  w                             sizeof( DEVICE_EXTENSION ),% Q9 o" H7 F& j( j# v$ n
                             NULL,% F) m& Y7 k; s3 `, Z
                             FILE_DEVICE_KEYBOARD,
+ }2 P/ A$ k2 K* T5 \6 T2 Y                             0,& j) T7 e9 T8 U1 k9 x$ W
                             FALSE,
3 m6 S9 v* N* q: S                             &FilterDeviceObject ); 0 R) e4 `2 h- ]6 D5 d" R! C* n

8 a3 y4 X# I# Q$ d  if ( !NT_SUCCESS( ntStatus ) )
* F$ r" x$ ?6 p1 l2 f  {
9 w7 _3 {( y& m  r0 W% ~( d/ G    ObDereferenceObject( FileObject );
- u7 I3 w7 M- g    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );, a- G. x+ i7 R$ o
    return ntStatus;
2 M7 C- F; C2 z1 t  } 7 U0 C8 a& |+ _0 X  \/ W- ^

/ e& n7 B2 ^! s; |  //! q; s2 s$ d8 C+ x2 _
  // 得到设备扩展结构,以便下面保存过滤设备信息
/ R" }! P. a5 |  //! H/ v) {0 H4 p7 {; w9 ]
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
7 h: l8 x+ X3 m7 [! K
8 w1 U; @9 g! M; N
& p3 [! G0 g( N1 s' Y4 r* q9 N  //
  C6 `! H" Q! v( R9 w  k  // 初始化自旋锁
7 |" ~& M( y- E  //- W( }5 x  {9 }; q
  KeInitializeSpinLock( &DevExt->SpinLock );/ z; B+ h) S; E: ?
- J, D- [* w( w
  //
  q$ \3 ?0 S1 K  // 初始化 IRP 计数器8 [& a+ V6 J# L; J
  //! ~6 i' J) Y7 P
  DevExt->IrpsInProgress = 0;
6 E) y" |$ t5 |4 I% i- I- I# W' ~& i! ~$ J" b, a
  //
; f& j0 A0 ~6 Q  N  ?2 O  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象6 W- a. d7 U, Z/ ^0 x
  //
3 N7 [, \! x" \! g9 T  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,. B. |" n1 [' m) `3 d5 M8 A- [( ~
                                              DeviceObject ); 3 `0 a8 F4 P1 H3 n
  if ( !TargetDevice )6 _2 l  @3 s& m4 @' q1 N+ |$ y
  {
( ]; X$ B$ ~0 R& ]9 [9 V    ObDereferenceObject( FileObject ); 8 R& @  J/ g3 F; u  X" r+ ^
    IoDeleteDevice( FilterDeviceObject );
4 e6 C( H( x) T" |4 H    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );! n# @* P; _" W7 s3 Y7 S
    return STATUS_INSUFFICIENT_RESOURCES;& Z+ T4 e9 a) M& j' F/ L
  } ( r% K1 {' L# S2 W8 N
+ u# k% M( V! x) C( n
  //
! F  n) g9 e# Q/ X  // 保存过滤设备信息
6 C  ?& m2 r6 N# z& f5 N  //2 ]0 i- a5 @2 S
  DevExt->DeviceObject = FilterDeviceObject;
7 n0 F9 w, P- H$ ?1 e0 G: J6 {  DevExt->TargetDevice = TargetDevice;
3 i" A( w6 h% m' I/ I# l7 S  DevExt->pFilterFileObject = FileObject;
' j! A4 @  _$ O4 ^, g& f* F6 j  K' ~" U; p3 U
  //" u& U0 B! J4 N
  // 设置过滤设备相关信息与标志
; U$ ~& J' R' f( y" k  //1 g! ^. J( q2 ?, v" k/ O# l; w
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
" A3 u: d7 Q) |, I  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
; b& x4 d) ?: L& s  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
: X- H' L! q8 }! x5 }/ f' p" A9 `  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
) ^* E- Q2 z$ Q                                                         DO_BUFFERED_IO ) ); 1 N; F3 n2 C6 {: X; ~7 y6 w

% t1 N- W# V% b' ^6 i  //) k, ^- X: R( X, d5 A) o
  // 返回附加后的驱动对象
* `; x! _! o( i  //
9 O1 l2 Z7 s! {& m( ]  *FilterDriverObject = TargetDevice->DriverObject;
6 V: P- e5 a% L8 j0 |; V$ |
5 u& A- B, m; K  ObDereferenceObject( FileObject ); ; E2 [" A4 S. B0 h0 v! d9 X/ |4 N

& ^5 v( d' e1 }, O0 P% x8 L! W  L  return STATUS_SUCCESS;7 K4 a3 K0 j4 M' v7 U, Q! y
}
: t' u$ P, o5 F9 h1 l1 s8 d( I# O6 k" I
/////////////////////////////////////////////////////////////////! Q, P) u$ g% z
// 函数类型 : 自定义工具函数
' n  h( _& m+ f5 B// 函数模块 : 键盘过滤模块7 b. p9 p% @3 X3 }1 l
////////////////////////////////////////////////////////////////% y; z# p. [$ M% f* V2 l. F6 i
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发- @6 [2 |' [9 q) D, j. |
//        这个 IRP 的完成
0 V* r) i1 T) @% e- d// 注意 : ! w) w" a6 ~& ~" e
/////////////////////////////////////////////////////////////////6 H: o: h. {$ L3 b
// 作者 : sinister. y" U# B3 T( {: \" l  G" n1 D
// 发布版本 : 1.00.00
* \; ]# l- I5 P5 P' @. E0 ?// 发布日期 : 2007.2.15' i/ u9 }: s8 O, Q1 o
/////////////////////////////////////////////////////////////////
% t9 t* z$ j0 M4 x, \9 P) S' `// 重   大   修   改   历   史
+ i  a9 t  M: T3 d0 ]////////////////////////////////////////////////////////////////; A# K& O3 M8 P/ p& j, U
// 修改者 :# X( @+ [% ]* Y
// 修改日期 :
  S; s: _, [, \- C/ A! t" l// 修改内容 :  I) X1 I& C$ [2 b* u
/////////////////////////////////////////////////////////////////6 B5 c& g' h$ p1 M- X& N3 F+ ]

" ~: f+ }6 k" \, lNTSTATUS
4 s$ l" D9 f$ C" T. OKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )/ l4 D. f+ c9 x  y  q1 A* O
{, m: x7 M- A: R0 \
  NTSTATUS status;
0 l5 q/ N" z* ?* t" j, R" @$ t  KIRQL IrqLevel;
" R( h1 t! m) U% G3 d$ O
% i' ]% G; K; c* r4 L. n3 w  PDEVICE_OBJECT pDeviceObject;
: [: A: T5 B- w4 z4 [  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )1 O/ R+ j% I3 C! I" K% `2 b5 ?6 r
                                   DeviceObject->DeviceExtension; + _$ I+ ~. L! k0 W

0 Z  v9 W$ p2 ~8 O0 F/ T3 R! M7 x2 x7 }6 h
  IoCopyCurrentIrpStackLocationToNext( Irp );% O2 ?4 w9 z: j5 Z3 L; ?. Q/ ^+ R

5 S. {  A6 B$ l- G& s  Y3 V$ E  //& b; `5 s/ c; q9 C: P
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁* X9 t& r) \; I- o, A  m! O1 R
  //
8 J: B7 {0 y$ ]( B, m  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );. ^- E; Q6 @- `, Q
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
4 r: S6 L+ q' S2 Y- q  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );  R8 D; P: K* F; p7 G8 c3 P' R
- r7 u  G9 e) O' W! o3 G1 b+ {
  IoSetCompletionRoutine( Irp,9 i7 B5 L0 W" ~$ z- e, K0 v
                          KeyReadCompletion,# g# U: g) X. S2 Z" T; t: A. }# V
                          DeviceObject,* a0 A9 r8 J5 p0 B3 W
                          TRUE,
: f# f' Z7 w  P' F2 u8 X; x: L                          TRUE,! }  e% @' m( k* ^0 \- n
                          TRUE );
; d% P7 n/ R5 U" W4 U
- B0 ^: [7 u+ o9 J; w2 V, e- l  O  return IoCallDriver( KeyExtension->TargetDevice, Irp );
, Q3 I# d6 U( L} 1 c; r* y/ U) u' ]

5 i0 T# ~& h  f9 Q2 B+ O/////////////////////////////////////////////////////////////////, K* Y% ^/ U1 u9 d0 z9 G
// 函数类型 :系统回调函数
2 d0 P1 I8 z3 R1 V( X// 函数模块 : 键盘过滤模块
& f9 e9 ?  O, |/ d" f, D////////////////////////////////////////////////////////////////
/ o- |0 m6 {4 |1 {& q// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
# p# \7 ^- [' w5 d4 A. a8 g// 注意 :
# T% T5 {$ g" c& X& J" F/////////////////////////////////////////////////////////////////) n3 _3 z9 W& }" d. X" S! x
// 作者 : sinister9 ~: W- V0 m4 s. x  [& z$ O
// 发布版本 : 1.00.00
' m# N0 k. I# w$ g  Y// 发布日期 : 2007.2.12. E5 [3 E/ G  e, o  p
/////////////////////////////////////////////////////////////////
" ^6 }+ w5 n7 G4 ?// 重   大   修   改   历   史1 ~% P2 w7 `4 j0 d
////////////////////////////////////////////////////////////////, I! @0 Z6 C8 `, y0 n% n
// 修改者 :8 a2 ~  q$ u; J8 K: r; L" q
// 修改日期 :
4 ]# {. s; K5 X' }# S' M, ^// 修改内容 :# n0 c* d2 F* s. M) w# M  ^$ e7 T
/////////////////////////////////////////////////////////////////
- u" e3 |# w% r( k' Z" q# `, G3 g! s5 ]$ y0 N; _6 g
NTSTATUS
" v7 Q  C5 `' b, S9 J* Q4 qKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
! l! l  U7 x8 _& q( c2 k( ?                   IN PIRP Irp,
/ g) l8 j( ~# }. R( t- q                   IN PVOID Context )9 ~+ L  M$ a3 N6 b. Q! }3 }/ ?
{
! O2 J0 y: q" p, V  PIO_STACK_LOCATION IrpSp;
7 S+ o8 ?, R' q) H: I) g9 k  PKEYBOARD_INPUT_DATA KeyData;
% v  |7 i8 N' O& v; i% w& [' ^% |1 Y9 m  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )% \, p7 R4 R$ A  U4 m
                                   DeviceObject->DeviceExtension;
' o7 c0 h7 e2 Q  int numKeys, i;
9 L0 d/ Y( M0 ^; c; O  KIRQL IrqLevel;" `0 [: u) x- g& m# n2 u3 F

6 M  h. \+ I+ g* K9 S: @# X  IrpSp = IoGetCurrentIrpStackLocation( Irp );5 _7 h8 B. Z7 ?; S) l( F
) B8 V( {. I+ g1 i
& g" F8 A2 V, j" Z+ ?
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
1 h, s: v  _( h6 v7 d% }0 k  {7 i0 _9 @3 x1 Z5 \
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );+ X1 _  U8 d% X
    goto __RoutineEnd;0 P, e5 d$ d+ c2 Z9 N( E: G" G, \3 |
  }
2 W( ]! Q/ d% z; r; c) N5 o
8 d) p' s' L9 L  //
7 D* g3 n8 V6 a* \  // 系统在 SystemBuffer 中保存按键信息! D4 C, p2 |0 s
  //* x6 [" L2 D  \; ]; [
  KeyData = Irp->AssociatedIrp.SystemBuffer;) N) r/ e! f1 q' }% U" F
  if ( KeyData == NULL )
! Z, I# v/ L- X' U% I3 P  {
4 }$ N& t% x& ^2 Y7 h% c/ ^$ x    DbgPrint( "KeyData is NULL\n" );
: O4 o) H. G& W; i) z; s7 [' X+ C    goto __RoutineEnd;* L7 N. y$ S: N9 F$ Z
  }: A) g: H: r5 k" `$ m5 C7 h& M
. H! S5 P0 p. z5 j; P, `+ V8 w+ q# ~5 y
  //
, T6 I- v' A* e9 a$ y  // 得到按键数6 ~9 L5 f5 q1 J; G* `
  //
* S" Z+ o# p+ J; N  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );, S  ?3 G  ?5 N& i% B
  if ( numKeys < 0 )
  U! B/ r3 l( V* A" n' }2 d/ c7 c  {
2 Q/ N# Y( W  @    DbgPrint( "numKeys less zero\n" );. W1 Y. ?2 q& W- W8 h; V  w* ?
    goto __RoutineEnd;
! @% M9 k7 T9 ]8 S* k& p( C  P  }
, b8 ]) V- B+ @3 H& Q% A; D' S5 D9 N: z2 m
  //* z+ a3 W6 A  ?+ \1 k0 g
  // 使用 0 无效扫描码替换,屏蔽所有按键
; h/ {3 N' x- m) v4 y- i  //" _6 b$ r+ H; A/ J7 u5 b0 [
  for ( i = 0; i < numKeys; i++ )' S! Y  E; w" E+ D/ q( ^6 {: C
  {5 a4 x! [7 ]4 c
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );. X" n) P! b9 o
    KeyData[i].MakeCode = 0x00;, ]" g( E2 F) B* y$ b) y) }
  }$ q4 E( _7 k- u, Y- T  w/ \

# j5 P% c* F" R! C( E; b, Z: @% @! h$ [
  __RoutineEnd : 8 U4 |4 m( i/ P$ v) @" m9 n

) w8 V6 [4 I/ z# g5 I; j# v; d  if ( Irp->PendingReturned )- P. y3 g7 H& ~% @: s
  {
% w: ]$ k/ W- L    IoMarkIrpPending( Irp );
+ H0 d, [1 P( V9 K+ S& E  }
) |' g. |5 d7 H& \( m3 r
4 g, N9 x7 {9 A) z7 k  //
5 d' M. M9 r9 e' i. V* A" z  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁4 k3 \& Q$ ]/ s; G4 d- U
  //5 L% a4 w8 Y+ p9 J: G4 O% v# P
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
- _6 ?. a9 r5 k8 i- R9 A* S  InterlockedDecrement( &KeyExtension->IrpsInProgress );3 s( g6 H3 f1 T9 R
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
5 h7 p- M: x( Q7 S7 {# z
% p& D& N' J9 [5 n  return Irp->IoStatus.Status ;+ N  T7 A6 m0 v: e2 N0 E
} 2 ?8 r8 \' S. ]
- e1 }+ w. R$ H$ I* n
+ i' ]9 f* \  J- g$ A7 Y
/*****************************************************************
# O% _, i+ A" `9 m: V# Z6 D) f3 T 文件名        : WssLockKey.h. R8 B& k0 z! o0 l" T: U* |
描述          : 键盘过滤驱动  _! G. m* ]( L6 Q
作者          : sinister9 c) r- Y3 ]8 F
最后修改日期  : 2007-02-268 w1 |/ K+ K4 V* y9 e( I
*****************************************************************/
# z; {0 Y+ J% t: B4 B0 m- a  [- `! p2 |- c) D- L
#ifndef __WSS_LOCKKEY_H_
, ^- b7 `( G% ]7 c& X2 H#define __WSS_LOCKKEY_H_8 H9 v  w$ z# G7 l' y+ Y) a* H

6 O8 g$ ^% O. @* s- C#include "ntddk.h"1 x$ T+ ~; A: b; f
#include "ntddkbd.h"8 S* S" ]: c2 Z! y9 G
#include "string.h"5 Y) z) b) Y, q+ Y5 a) C
#include 1 x  m" O) A. H2 _& K
4 `7 G7 `: q! x
#define MAXLEN 256
. z' n# o: v( J' k: n$ _# g( Z
( @0 c; g6 m# h- p+ }#define KDBDEVICENAME L"\\Driver\\kbdhid"1 {+ C7 _2 d+ s. m3 R) X
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
( E( |- O$ n$ Z#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"% J5 H9 J. _# v1 W! p- D

2 |1 A7 F; S; K3 Y" X* h& }) Vtypedef struct _OBJECT_CREATE_INFORMATION& L: F- H7 G% @- j( Z
{
  O& G* Q& Y  V1 d) F) S% Y    ULONG Attributes;% b8 C. R, z  y7 R. Z! z
    HANDLE RootDirectory;1 @0 ~5 T0 _3 |& i* T
    PVOID ParseContext;/ \- u1 i# e: H9 ~* q5 v& s& Z
    KPROCESSOR_MODE ProbeMode;9 A2 `7 J) k( Q* L1 D
    ULONG PagedPoolCharge;/ T& U0 @0 K3 d8 ?
    ULONG NonPagedPoolCharge;# Z( K& n: U% b2 G5 B
    ULONG SecurityDescriptorCharge;
/ g' _" z4 [6 f( F$ c5 p4 C3 }    PSECURITY_DESCRIPTOR SecurityDescriptor;
, S8 B1 ~! f; K/ Y6 O2 J1 `    PSECURITY_QUALITY_OF_SERVICE SecurityQos;% `" [1 }" \9 }& s! \1 k
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;' ]! j4 k: r- S: R, r/ _
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
; y; y2 p+ Z/ f& U3 D
4 U, K+ W9 L& p% R% x  B, B! Dtypedef struct _OBJECT_HEADER/ h& L8 Q; }" G# ~3 m
{* P( Q0 D, m# K$ U% F: B
    LONG PointerCount;
5 X+ A% R9 j! L' ]' i- N% A& m    union- x+ f) B/ J, u/ y4 c( m
    {
( B8 E6 R; `# W) A' w, f        LONG HandleCount;
( T/ K# M. v# o5 G6 t7 f        PSINGLE_LIST_ENTRY SEntry;$ ^4 c. |3 x" E0 X, _' d
    };5 q3 T. C& Q- Y/ \" A5 b% r
    POBJECT_TYPE Type;( X9 u! o' k% [
    UCHAR NameInfoOffset;* M3 ], x+ ~0 p3 ]: h8 M- M+ T5 I
    UCHAR HandleInfoOffset;
! G2 X' n' r2 X! I/ Q    UCHAR QuotaInfoOffset;
$ `7 ^$ s3 E* D1 ~6 ~) T    UCHAR Flags;3 W1 T) Z3 d: Z9 O% X9 |1 v
    union
: a2 c: _# d* w2 R/ `    {$ q2 f7 ^# I- d% S9 v
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;, L+ C# ]( |8 }% x8 \" w6 i
        PVOID QuotaBlockCharged;
0 |5 T9 i# A4 S* k9 z    };
5 c7 v2 q# D3 q8 {6 M5 `+ F; Z% |% o
    PSECURITY_DESCRIPTOR SecurityDescriptor;
/ V" u1 y! C0 S( _+ i    QUAD Body;
$ v7 W1 H5 l9 P: _5 O} OBJECT_HEADER, * POBJECT_HEADER;
3 `' r4 A7 w0 \% G7 M, B& |
; ~& m4 p& F2 `# N+ m#define NUMBER_HASH_BUCKETS 37' N$ V8 E% `& ^- v  A. O3 q
) l; m- _+ n) Y# P. n0 Z
typedef struct _OBJECT_DIRECTORY2 |( `6 [4 R* W$ u
{
( T. P. A( v+ L' W# g    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];3 I4 z: V+ |& v' l. _+ H
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
2 j. N. h+ P( g. H+ }% s) i0 R    BOOLEAN LookupFound;$ L) _# M' N* c* b! u, K
    USHORT SymbolicLinkUsageCount;
2 ]/ v* a8 w# L4 C8 d+ X    struct _DEVICE_MAP* DeviceMap;
8 Q9 @5 t5 f' d5 t} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
6 h. O. P. p! J" ^; r1 d  ^5 M; E! Q5 h$ L. J5 ~( r
typedef struct _OBJECT_HEADER_NAME_INFO
$ O; D6 N6 o3 j9 e+ V{
0 c0 |0 A3 h; D. v7 C* m    POBJECT_DIRECTORY Directory;
6 i! I. @- N5 i. P3 S( C    UNICODE_STRING Name;
  H. s% j, H6 M. [1 L, r5 l; K    ULONG Reserved;* N& G9 G% K1 f$ C
#if DBG
" X- V7 O1 i- ~6 n& O- |4 p& @    ULONG Reserved2 ;* f& k) d" M, [2 K
    LONG DbgDereferenceCount ;  w  b0 S2 H9 J3 f; p
#endif
  J& N" l* S  j+ K1 y} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;2 u' e" }. D* b
7 A% ~% P' J: _9 N2 M) Y$ I& q
#define OBJECT_TO_OBJECT_HEADER( o ) \
7 I# D& B' s8 a' C% W  d    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )2 V& E/ E, Q6 ]- u, f/ a; v1 c) V

3 w! W# j$ f6 D+ L- a$ t1 z#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
2 r1 y7 n! j/ S8 t; Y    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))  x0 ^+ a' z* C+ Q% ~- \7 C
+ I: S. K% H) N+ |1 \
typedef struct _DEVICE_EXTENSION+ T8 j; L" \" F% k$ ?9 e  l
{
+ h; W2 m) c6 r( `    PDEVICE_OBJECT DeviceObject;: x" W. j& V1 h% b( a/ q
    PDEVICE_OBJECT TargetDevice;
1 }5 u" w+ v2 b$ }" w. p, r    PFILE_OBJECT pFilterFileObject;
1 x1 Z- O+ ?9 x3 M" X9 b- s    ULONG DeviceExtensionFlags;
' R+ i  Q+ x$ t+ ^' f" n2 n3 f    LONG IrpsInProgress;
# E' A8 M4 t' E  M: Z1 r# S    KSPIN_LOCK SpinLock;" K( m/ m( J2 X
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
/ I  `. W4 ~9 L: i0 d! P0 t0 K* T

' P! S; C% F/ c6 Y0 x" K) h6 ~VOID
/ O5 Z1 ?) G  B+ QKeyDriverUnload( PDRIVER_OBJECT KeyDriver );5 a8 z0 p* j  E" @" d: m
! o# T4 s. o) [2 p
BOOLEAN5 {9 {( S- a5 n" H* z" R$ q2 A  j9 P
CancelKeyboardIrp( IN PIRP Irp );
6 P7 E3 U. N6 `( e) R5 Z# F: F1 p1 c  O1 F+ P
extern POBJECT_TYPE* IoDriverObjectType;
  Q( B6 y+ h( l& q3 l5 A+ F8 j
) d2 ]7 @4 C0 z! Z* r" e* k3 n* `NTSYSAPI! A9 p, s. B4 z' C
NTSTATUS, ?  I6 q- k  V1 }- H9 }2 W
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,9 y! G' C9 E' K' v% {
                               IN ULONG Attributes,
& o: H; j7 e& `  h8 v                               IN PACCESS_STATE AccessState OPTIONAL,
, x0 X9 Q% M! r, }2 W& S3 P                               IN ACCESS_MASK DesiredAccess OPTIONAL,
9 ~  T5 {! P$ F                               IN POBJECT_TYPE ObjectType,
6 s' r* X1 g+ [! X8 A9 [! v- x" N                               IN KPROCESSOR_MODE AccessMode,
% Z7 k9 @6 |( Q4 m9 V) m' g; M% k                               IN OUT PVOID ParseContext OPTIONAL,
" o( t2 f( I; L+ z" P0 `+ _                               OUT PVOID* Object );$ o4 J6 W3 Q9 `3 r9 ~: O4 T

, \% S  S6 c0 y9 q+ g. z% W9 ]NTSTATUS " I0 W! f8 _- Y' U; |+ x) ^
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
, D& h' \- u3 ^1 W* B# |6 _$ Z8 l$ E
BOOLEAN 1 s$ E" P( ~2 b3 A6 n$ A" `
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
% E+ ^% r  O; K% _3 J6 O+ |; M% r
7 o" t2 G3 m/ x; G' Y1 TVOID 5 y% P4 o# j) a, \0 g; r! g
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
- E4 Q5 i, k) F& V( B2 w. S
! T( m1 @: G: E; l* |& T$ W4 E! B) ONTSTATUS / `! Q+ w  h" G0 w
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
- i; }  L1 g/ h& i                                  IN PDRIVER_OBJECT  DriverObject );
% X. u, y3 W# M! w' K0 z
0 J; t2 U, N* j8 g3 m# c' fNTSTATUS
9 L7 z8 {* S% b7 A9 N$ F4 gAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,6 e: ]9 c7 r$ Q& V
                                  IN PDRIVER_OBJECT  DriverObject,/ c- D% l) J" c0 A4 ]4 n
                                  OUT PDRIVER_OBJECT* FilterDriverObject );3 Q' W8 S# O0 t- d' o- ~
/ H: y( \1 B0 ^9 W
NTSTATUS . f# q& r! q, }- [9 K) J
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,' u# l0 a8 U, C& k  l: Q
                            IN PIRP Irp,0 Y: l# Y" }+ A4 a' b6 c6 G$ m
                            IN PVOID Context );
5 A3 T, s* c) sNTSTATUS
) y1 J, O2 Z5 G; _% dKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
9 R9 o. E' ~6 A- m9 J" C, p! E
  X/ p7 S( b: X# c  Y8 T' n1 gWCHAR szUsbDeviceName[MAXLEN];- v5 S3 v2 X' N9 K8 t2 ]

/ P: X6 H, t) W7 o2 F0 T9 A7 D! _#endif* n; i. c+ m1 h( J

7 E4 E) z' g9 O- f/ [! N5 x5 q
6 Z6 ^& b; Y( X$ P( O9 a7 ` - ]) g* x$ }( P) r0 z/ D

8 {3 p) @* K" @/ Z0 }9 R' K( n- |3 Y1 N$ L- G5 m: k+ q
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
4 X! m4 U- C& @WSS 主页:[url]http://www.whitecell.org/[/url]
0 ?; d: |/ o; X6 E1 c3 xWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-19 21:52 , Processed in 3.830552 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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