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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
, g" g7 q# g+ vEmail:   [email]sinister@whitecell.org[/email]5 [6 m% X0 q2 [- x
Homepage:[url]http://www.whitecell.org[/url] , m6 w9 e& g$ t# X: j9 Z) R
Date:    2007-02-26& H; S" i# K- X2 Q- g( H: u
8 K. E, _* i. b( L1 }
' H: {( l& L9 L: ]1 ?6 p
/*******************************************************************3 \- k1 c9 m  U6 H+ j$ L3 F  Z" Q; K
2 S4 p1 w8 w0 W8 `' s
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
7 N5 i: v. e8 x- V9 Q6 m写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的$ l9 S. p4 l/ ]5 k8 ^. T
功能要求如下:
6 M' F0 U: _4 D# e- ^, z; i/ f, a7 s$ v% }
1、强制锁定键盘/鼠标。
9 a9 Y' ]" d, r/ k$ z8 `2、可动态加/解锁& A# L% `/ Q# H! m+ m, a$ H) D
3、兼容所有 NT 系列的操作系统。
/ t( h6 i! c4 S0 A
1 F$ \- H. k8 B4 G, Q就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实; {. _4 V) A/ Y& g! g2 V" I$ M
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如' q) w& t! s7 P! w- v7 h
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
1 }: b! E8 i1 K上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
9 }9 Q5 H+ u7 a& O4 S4 |怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
; E2 y5 R! @. Y$ I就来看一下我想到的几种实现方法:  X, P# Y! w. U; [/ H. P9 w
1 n* X- v; O$ Q6 v5 S
1、全局键盘/鼠标钩子, X# Y  `) C9 r+ t: ]( z
2、BlockInput() API
( I- e7 I& i* ?/ u8 m4 {3、使用 setupapi 进行控制: L5 A6 D8 G" [: R9 j8 Z
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL8 I/ T, T. g% x" Y: g9 n
5、拦截 win23k!RawInputThread() 函数
# p8 k- p8 k& F  m6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
9 t7 R1 V# q6 E: C7、拦截 kdbclass 驱动的 driver dispatch routine
/ j; s; ]! ~: S. ^! h% I2 k8、实现一个 PS/2 与 USB 键盘过滤驱动% R0 q7 s9 @$ y( @2 p3 C! t+ ^) k" g

; w. m, g9 r5 u/ U" B! {
4 E* Q$ M0 f+ h* W% n3 c: W# f我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
1 g) ^% ]% K0 t$ Z6 W之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( \2 l0 {; T0 p
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在+ R" [' n+ [$ j6 v  m8 Y
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因2 k0 q  h, \+ D
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性  o) F) m( `+ z
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸1 V: O! D0 ^. u# |
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
/ @& Y8 N7 }) N" K( R3 n的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来) J! m# T5 U; |: x7 E
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如# o9 H+ e5 {8 ], }  q
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
5 S! |9 b0 M5 m7 p" B, ~* Q. k障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
% \) M8 b8 G# w- u  VIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
% E0 K; j. {% y/ }8 qUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
8 U" K  E* G( l4 S6 d' _+ o+ M盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方- |. w2 l- C9 k' g" k$ V
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
0 S6 }1 B  W0 w2 {; T4 o$ M$ {8 ?/ Z+ U' J
: j' t( T% y5 O$ e/ O
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过. O; p# ]& g7 }" u
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
2 e+ u3 A. `! ?% c" p行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
" u, H& {( f8 N4 v4 \" K7 z2 n只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
! W+ q- i7 M8 v& ]$ T来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
. W/ `9 C$ `! }' J$ PKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
8 V$ P* X* \* [' m+ y6 ]/ [+ U键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
3 Z% d1 S4 J; B9 JIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
% u& O  Y  z; C* G4 M- y# X我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
/ p# S" K. a' X* ^就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的8 |) r$ m2 a. ^5 q; @2 ?
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
4 D, F0 N  ~0 u' w& c, k4 @用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
: K( ?$ I' b" k4 L过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来: q5 V5 f8 ~: r" K2 r
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通+ O' ~) n5 N1 D5 ?7 ?# ]
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
9 [. h* W  i& @% R5 m4 p" `. d上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 1 t* Z* n% w' @
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
& d0 x4 j, g5 s) X9 Z* O味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。" g% X# R! k0 j0 m
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们2 W8 }9 X5 ^: F
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利, D( ~9 g* ]8 N  u( E
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo$ S" Y2 `% C! A
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
. S0 A2 S1 G" S, Q2 s敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
/ \4 B5 e) p1 u; g$ j3 C- @根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程) I' {) i1 z( I. U, ^
见下面代码。
6 {- m" T) |' x' w% t- h. t8 |+ T# m
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程% t  y: u" i3 h' W( x
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键; w' j4 v. E+ B8 u- |& y
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003' X* G; a3 D; L6 R
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有+ \. i2 P. \* p
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可  A7 c. e7 b: s! R/ n
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个( q( r5 j5 p( i4 C$ R6 V
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按: _8 u; o! q) b/ V" v+ `' j
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
1 G" t. G1 `& h; ?3 H
& m8 Y" ^; D9 ]' m  N
1 q1 K3 N7 c! G; n9 U4 V完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
1 E" y1 ~) x: ~- ~6 a+ B  `0 ~的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是9 D& v$ ?: c& O4 |$ `+ R8 w
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣  Q0 |; `! z# f' F! n
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
8 p' ~! V( \+ }. l. _5 n" A- n; k, y3 A们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
7 @' L- j, i! v$ Z- |8 k) U们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension9 _( ^! a# d. u( {7 M! b, p
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。7 J4 @) \1 r/ w# o0 ?/ N
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager6 F" Q& X; N4 d. s) K$ M0 {
进行操作了。这个问题有待大家来完善了。
* a  v# i" {- Z5 x/ z2 B. q( f0 T( i5 I! x" ^( J
8 D3 d! j( H. j& B& \5 f0 e0 t0 w
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
- q4 l- a+ V0 m来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的1 p1 a7 o4 Q; W3 n% v. O+ e
分析做个记录而已。我更愿意把它看做是一段注释。
' I( J! O7 j/ j
+ F7 U) F6 @) h, u9 ~最后在此代码中要
' f% v! ]4 E3 v; \" g, h% `  A4 D: M1 i9 v* }! K: J. C
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。# G3 e" M' c/ g5 s1 u, h* @5 ^: l, L: M
, _: w2 @8 f. ~! B, ]' ^
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
3 j- q2 n; G7 J% m; `# P  m# o! L8 u9 b5 i9 [
感谢:齐佳佳,过节请我吃好吃的。* C9 m4 H/ a1 P  p) q8 D/ y" n
6 A, V! \# b8 ^$ A

( M& V9 m0 E* n* u******************************************************************/
" t% u$ g% l# r4 m
( c! C( y) n7 z  |& U# g' |
0 U! ]5 I" s+ C* ^% z/*****************************************************************; g& w- S% @" f& g0 n
文件名        : WssLockKey.c# a& {0 g  m+ r  W% X
描述          : 键盘过滤驱动
# B0 j( F5 ~7 a, e9 c: a 作者          : sinister: ~# \! G7 j- Q# @# N
最后修改日期  : 2007-02-26
# m* J9 ?: M& j*****************************************************************// }  A  y- P8 J7 v9 R. _& g
3 G0 ]0 s: R8 e+ J
" [$ ?% A6 p5 E9 P
#include "WssLockKey.h"
1 N0 O) ~1 Y# q6 g2 C0 \3 |9 @) h) Z/ l) u+ W0 ^
NTSTATUS0 s3 I( `% b, o. H+ b
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
/ P( v+ R( t$ l( B7 c             IN PUNICODE_STRING RegistryPath )+ ]) L, e) v4 w; E9 g3 x; s* n
{: J! Z2 F" }1 J6 O
  UNICODE_STRING KeyDeviceName; * X* c$ V" B  K4 S, O! r' @; ?2 k
  PDRIVER_OBJECT KeyDriver; 9 p5 {1 [5 V6 V" Z8 \: o
  PDEVICE_OBJECT UsbDeviceObject;& \! }* I) U+ _) e1 I) w
  NTSTATUS ntStatus; 2 ^  Y5 Z* N9 I6 l9 l& ?6 |9 s
  ULONG i;
6 m% {; Q/ Y; U
) p9 K! H- `5 m+ k" K# C; f  //$ c/ y2 G7 w8 z. Q
  // 保存设备名,调试使用
3 ^  f; N% C$ \  y# x  r- [: w2 ?  //
& I5 H8 V1 _( M  WCHAR szDeviceName[MAXLEN + MAXLEN] =1 L: V7 A/ A2 d8 K2 O# x& T
  {
& }- J  z2 W# I- e, W5 Q* Y! ]" e1 E    0
4 `5 J7 x9 F, y9 v. m& ~2 d  };1 s6 m: s4 s. B) O* m& }! Y% m

. U  `0 q4 v' [6 b; M% g4 d  KeyDriverObject->DriverUnload = KeyDriverUnload;
: J' I) Y2 M$ o, Y* S, `# r+ g" V3 v# {5 T
  /// S/ C& h6 q& z( K: ^
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘4 ?0 t1 y2 w4 l
  //6 k. d4 E& ~$ p" ]
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法2 _0 o! {7 K  j/ D: P9 r. }
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其7 ^7 A5 P3 X* ~# C0 y
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到& `  L0 v% k5 R' Y+ d$ y
  // USB 键盘设备来进行挂接. M% V" R$ T; d5 K) i$ i
  //
1 n' ^  |; ~$ U, x: n2 V0 z9 h$ ]4 ?  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );* M3 P5 a* U. ~& W
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )( k; n$ L$ q$ n, V3 C
  {7 q1 _# L5 u* m
    //
* T+ q( b. z# Q/ ?; e1 \    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名) o: `* w; F+ P& D/ p
    // 所以这里打印为空8 ?2 R' [# a, `
    //) C% ~0 r# G3 I) c0 V- I
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
4 V. ?! v; Z) I  s4 \. ~    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
0 B/ W& F. f6 k7 x1 ~5 Y! `! u& Z0 R& ~6 e( }
    //' P  ^- M$ e7 {' Z6 K0 ^5 b; R
    // 挂接 USB 键盘设备
0 {6 P: X1 e& z) l: }* H. _    //' i# m9 K% Y2 ~1 x" k6 o2 G2 R& U, b- i4 |
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
6 n+ @+ s( }6 r7 K0 w4 A% D# ~. y7 ^    if ( !NT_SUCCESS( ntStatus ) )
5 {% y! g0 `( F6 k4 L" x- z    {
% y, J/ J) Z/ l0 S) ^* U6 ?: I: D      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
% h! }+ H5 K5 {" Y/ G      return STATUS_INSUFFICIENT_RESOURCES;
( b" x3 T, o' _6 z; }    }. c8 i  V3 X0 H+ p" `# j( t0 M
  }
" O. o; V; P1 C6 B+ ~. \  else) S: h! v1 e: j( O& F/ \: e" Y$ }
  {
' r, i3 C$ M6 U6 D( c    //
5 \- j/ Y5 Q; c5 _" D5 w- {) i    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
) K3 o1 J: M: v. g) T7 M5 k    //
4 K* ]! j6 ?# b" H0 P. f    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
4 C/ ]9 i$ r7 g4 B7 a2 O) k4 T. t/ I" |# V! I& o( n# b, E  v- B( r
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
0 c" ]1 U, A3 J# s; G                                        KeyDriverObject,
) ]1 |" K3 Z9 Y' b8 m4 z. `                                        &KeyDriver );5 T6 L% `" }  k) A1 ]7 k
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
' [+ u# `9 _! ?9 h' T% {* G! ?    {5 `6 ~- O4 B) r" N0 ?& P
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );# d3 v! `# }) M4 F
      return STATUS_INSUFFICIENT_RESOURCES;
- ?: G+ B7 b4 h, b) X! g    }& }5 w0 z. n) Z  b0 t2 M
  }
( O; U- u* m) l6 Q* y; i! ^! M5 |) z1 s. y8 B& m0 }5 D: Z
  /// o/ \  C  X  f4 ]
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
5 M& g( m/ I$ ?  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程9 T8 t* A- O6 a) R" ]: n
  //; L; z8 k' Q" E6 T3 h0 d: X- G
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
- S" o2 Y* p9 v" w5 n1 e: u( e9 D1 E' a) m0 O
  return STATUS_SUCCESS;
  J+ ^* x4 J6 G1 I$ v1 T) u9 O}
" A* ~* i( H: k& X8 D# k; b& B
* G8 l: B8 }( i- b/ C/////////////////////////////////////////////////////////////////1 [, ~* L' I6 p! j1 i2 Y2 m" d- F
// 函数类型 : 系统函数- `( Z! n; g: H( b9 z- q
// 函数模块 : 键盘过滤模块! J8 u% h2 m& e( `( G( M
////////////////////////////////////////////////////////////////! p# O: f; d' H
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
: \7 e  m, F6 ~! b& O# V$ e% K//        卸载键盘过滤驱动% ^* L8 e' s8 C! t: A2 F
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上* [6 {- R/ y: n& f8 C) D
//        则需要等待用户按键,以后有待完善  X/ t7 h0 E; m5 l+ i
/////////////////////////////////////////////////////////////////
' D6 J5 D7 T& s4 O" |* b2 J// 作者 : sinister
0 N3 ?% T! Y% \7 P+ N% ~( h) f. T// 发布版本 : 1.00.002 J( ~& }. [4 L! [7 x& u+ k' {
// 发布日期 : 2005.12.27
5 i  v1 y* y. u& c% W8 Q$ Y/////////////////////////////////////////////////////////////////
. M* E" w4 |! ~# N) {' T' `' U3 p// 重   大   修   改   历   史
. U, G, B9 t# u$ z////////////////////////////////////////////////////////////////
! v5 l" i2 `, h8 B5 u// 修改者 :, z9 w2 z4 @: w' Y$ x  X/ o
// 修改日期 :
& p+ O% q: p" K) K9 k// 修改内容 :
: J! ~& g, @; A( Y2 ^' q- l/////////////////////////////////////////////////////////////////; ]; T: J7 i, [' ?4 ^8 \
7 J8 H* g) \! n$ G
VOID# S, a+ n! S$ N
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
1 c7 R5 q0 s+ p. p2 o0 K{! S9 S2 o0 ~% D
  PDEVICE_OBJECT KeyFilterDevice ;      
8 Z1 U0 |% z7 y5 K/ M  PDEVICE_OBJECT KeyDevice ;
: N; ^1 Q0 L! \8 n' N  PDEVICE_EXTENSION KeyExtension; & z" a( G- g- v8 `3 U1 m
  PIRP Irp;1 l$ Z) C. o2 O" o7 V
  NTSTATUS ntStatus;
, s( b2 W; V% F4 w9 X6 h$ B
" ~0 m! d# ^, S. L, t/ o) H! Q3 ]: R  KeyFilterDevice = KeyDriver->DeviceObject; & D7 s) X+ p. A2 n6 A( r9 e" V
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
2 L4 y) F! J0 a/ n5 ?! h' R8 o* @. B  KeyDevice = KeyExtension->TargetDevice;
. \' s0 |5 D- A0 H) W( K& K- H
  IoDetachDevice( KeyDevice ); " I( G+ F; Z5 p
1 `3 y' g$ q, q9 Z) W9 L7 B5 `1 m
  //
: X" y  s( f& v/ {, l7 M  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP( ^9 \! @  G# `% m, I+ J
  //
2 I1 W' S" J1 k, O# X2 @  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL ): d1 @) f6 u( V  b2 Q) n
  {- _, j. A* d0 \5 o
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )$ z7 I4 M! E$ v- X
    {: x9 `+ r9 M, p1 z" W
      //
5 Z2 a, i' _! V+ \2 j      // 成功则直接退出删除键盘过滤设备
! F" r# e9 ]5 r7 a      //
. g8 z6 E2 i( A$ E5 q      DbgPrint( "CancelKeyboardIrp() is ok\n" );6 H0 W  l2 A$ _1 O' p
      goto __End;3 v0 F4 V9 x# ~9 F, p  \0 ?
    }. G, j! a( m  \4 v/ H% d
  }: Z+ v& w. d9 `! F6 i
& e+ y6 z& H% M+ U
  //
  I! C4 |8 r* J6 z  // 如果取消失败,则一直等待按键/ Q$ V# G/ |- |: R5 A4 a; ~  Y
  //' E- Q! N1 O( E
  while ( KeyExtension->IrpsInProgress > 0 )4 T( _; U5 V" m8 p- C* o
  {6 ~4 @# x' b) y$ D3 B
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );3 B5 K% |3 n- x9 f) \$ c
  }
2 g- [3 d% k: o4 w
* h0 j0 _" N/ L7 N  W3 z  __End:
' U' N' f$ I. C, B9 l) x# E  IoDeleteDevice( KeyFilterDevice ); $ c7 H; P4 L4 @2 {

$ F% S! J; C; w- X" t- ]2 r: W* H) t  return ;
( u4 H6 S  x( K: |0 t, C} 5 ]) ?% p% W9 P' e! Q) [9 _
9 g+ H6 j$ E4 \/ x, Z
/////////////////////////////////////////////////////////////////
& r. v: D" E2 T& U) y& Y// 函数类型 : 自定义工具函数
; F; H, k5 D+ ^; `% @9 [$ U, B// 函数模块 : 键盘过滤模块
: D# i3 Q( J/ C/////////////////////////////////////////////////////////////////
* v$ Z" i3 }) G$ _// 功能 : 取消 IRP 操作0 i7 C, N1 ~' G
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能2 _8 A% N' o2 u' C' f1 K! v% Q
//        使用此方法来取消 IRP
( [. e0 n# X3 N5 `- d, Y/////////////////////////////////////////////////////////////////$ V' C2 h1 d- p1 U, f$ k0 y4 V
// 作者 : sinister
# `) ]4 d( a7 H// 发布版本 : 1.00.00
5 ^) V+ X  j1 d; x7 B// 发布日期 : 2007.02.203 u2 K0 t; l9 e9 J$ f
/////////////////////////////////////////////////////////////////9 a: L% f2 N  Q( ~+ @
// 重   大   修   改   历   史
# I- e# x2 Z: E7 v+ F4 Q/////////////////////////////////////////////////////////////////6 O$ u6 c6 \2 V! `4 o" f/ H
// 修改者 :   C) f8 @- j1 }! z0 T0 N
// 修改日期 :
. }) N9 E, z. t+ t+ E2 ?8 w+ O- K// 修改内容 :
6 i+ z# z! Z: j) Z, S+ X/////////////////////////////////////////////////////////////////
% _: B6 b9 c4 x  A' _
, A5 O+ C/ t. p6 x- W1 G6 XBOOLEAN" `( c  @6 X/ Z7 [/ D1 N+ s
CancelKeyboardIrp( IN PIRP Irp )
5 `/ {' F. c! B" N$ I{4 W% v  ?' h% A( V. V0 d: e, _8 S2 C+ m
  if ( Irp == NULL )2 }$ U% j# F) |+ W9 P4 X
  {; {" s/ X' m: j& g3 N8 s
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );* B4 `; n* Y4 B4 p% Q" q4 ?- h- o
    return FALSE;5 B+ ~" n+ @' g6 L( s0 W
  }+ H# ?& i: H# S% v6 I
# J7 Z# {$ `) J% D8 v
4 A3 [2 R5 D, Z8 @
  //
4 c( q- e+ _& F. f$ i  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
2 Y) t1 u2 d) \' j+ h! D& W  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
9 W" c/ i) |8 Q9 r  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
6 `/ f4 v9 w+ E9 U; C  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD, s! P9 A$ }- V% `' }! B  @
  //
6 q7 Z  p! \$ m
% _' \- ~6 e6 p2 Z" C. V0 K  //" c0 l$ M  a- ^* X, Q
  // 如果正在取消或没有取消例程则直接返回 FALSE& |% V/ W# ?5 g5 `4 {
  //
( O$ B/ s) \1 o* w0 I" G2 i  if ( Irp->Cancel || Irp->CancelRoutine == NULL )! j2 ?8 l+ s4 s. Z
  {0 u" Q. e3 Y0 d& p8 r2 {# n) F
    DbgPrint( "Can't Cancel the irp\n" );1 z% @  }, U% A
    return FALSE;
5 n) k- S4 Z7 h- A8 K' n- @  }
* W2 v8 v1 r" C: _9 m# u& Y: ?$ h3 y6 Q1 S5 ]& d, n
  if ( FALSE == IoCancelIrp( Irp ) )
$ |2 T8 U3 ?# p, r# M  {2 T7 b; z; m, S) f$ c, e! ^
    DbgPrint( "IoCancelIrp() to failed\n" );
3 _" w( H  w' L# Z: c8 ~    return FALSE;
- d6 [. y* y" \8 t$ Q( A  }
% U+ C& K8 |# |% X) e4 v: B" f) o
1 R6 K3 f" Y: C$ [/ D) \. d  //% _4 C6 j/ ~$ _  Q& V1 v
  // 取消后重设此例程为空
, m) l3 R2 K) h. O7 _% M  //
+ V, o" ^9 g! b/ X, E  IoSetCancelRoutine( Irp, NULL );. J$ n- Y4 B7 h- D' t% T

- z: h4 p3 ?4 F  return TRUE;2 e% o# [6 s0 u
}
4 x9 s+ v9 e& k1 B2 e
" y  A- {' i$ ?) `/ a! ^* P/////////////////////////////////////////////////////////////////, O1 i: ?& f" Y# v* X+ e6 u7 [
// 函数类型 : 自定义工具函数
3 n% v( q4 N+ I5 g" ?; R$ k0 R; l// 函数模块 : 设备栈信息模块+ T/ }% C7 N! R& o
/////////////////////////////////////////////////////////////////
6 r7 b" ^* A2 Z/ @/ `# u; p3 u  F+ \// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
! N% P( |. b* `6 |: a$ r7 i//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver): u2 R: A7 Q/ n! m' Y. V
// 注意 :
' L$ E2 L1 v5 J. g4 T3 q/////////////////////////////////////////////////////////////////$ y  `. d. l3 @% X" @9 V( d
// 作者 : sinister
. k4 j4 Z1 s: y( @' ^// 发布版本 : 1.00.001 `  L3 ?# J# c
// 发布日期 : 2005.06.02
0 ~  V9 o' P# t0 [  c& a/////////////////////////////////////////////////////////////////& O% Y+ d7 p" e7 a9 X) q: t
// 重   大   修   改   历   史
' c( X; e9 v4 R////////////////////////////////////////////////////////////////// ?2 O6 _1 ^% m6 S% Q8 ?! h$ V
// 修改者 : sinister- B. t$ E! X* Z
// 修改日期 : 2007.2.12
' k# H2 z* y* G) i# p  K// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
- P" p7 h. J' o6 K; |! \/////////////////////////////////////////////////////////////////
, v' |% x. |& E* D9 J6 B1 ~6 `6 X& y6 ~$ C2 x* X, [
BOOLEAN
, q+ H# M* ]$ P2 yGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
7 n7 f0 N) S/ r9 c, b8 V{
8 u- C; c! y* w. G4 U- K( H- o& R  PDEVICE_OBJECT DeviceObject;$ |# Q0 w, E) d" P/ z
  BOOLEAN bFound = FALSE;
( v/ Y, F- u/ o" g; d% U2 a7 ?" |; N6 K  H9 i' c
  if ( DevObj == NULL )
0 N- [2 L" k5 l% Q4 w  {* o9 l) Q: k2 V5 p& B
    DbgPrint( "DevObj is NULL!\n" );
# @9 ~7 [4 @8 ]; T    return FALSE;- D; g! Y; T( w' R. g+ v: J- i
  }
/ z$ G6 w7 ], F* h- S" @  u% j& W$ H7 x# T
  DeviceObject = DevObj->AttachedDevice;
9 y" Q0 S# B0 U! f# G6 u. M# Y4 v
6 n0 W& p' e! g& R" T6 B( J! Q  while ( DeviceObject )) p% q$ V9 v8 O4 e
  {
: n0 X8 ~) ?8 S% m, j+ [+ s; U    //
' P& B5 u' n) m. F! i; n2 w    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但$ h- F7 \! c- g
    // 有一次足够了。这算是经验之谈
: Y. z6 e5 D( t0 k% C8 |! _    //
4 Q  g$ [9 p/ Z) \9 ?8 M    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )( U) M0 ]1 P# j9 d
    {
- ?% w6 s0 C! ]* U      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",) Z' K/ U$ W$ f! i/ P" s1 z2 M
                DeviceObject->DriverObject->DriverName.Buffer,; {7 P, U& o9 |1 A+ r
                DeviceObject->DriverObject,. u: ~$ G, T0 z: k2 x* o# m# C
                DeviceObject );$ I" [2 r) k9 d0 K& j: e

6 v. E: i2 u3 V      //3 ^# a- t6 d1 B. _7 U
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了$ K  [, M. q0 Q
      //, ?  \; o: x' J, G/ z9 u. j
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,& e& }" C8 v  z: t
                      KDBDEVICENAME,6 F) a+ w! W5 [+ s
                      wcslen( KDBDEVICENAME ) ) == 0 )$ f; e  g8 h- d/ [0 u8 L' n
      {
. C2 P) R: ]% U        DbgPrint( "Found kbdhid Device\n" );9 J. @5 G6 ?5 r
        bFound = TRUE;8 a! ]/ c7 s( `
        break;
! q7 Y! h+ o: `& p1 A3 m      }4 \( C) s) q3 F; Q3 A* S, N5 g% Y
    }) g) ]0 M% s' K# D) x, d

/ \5 m& c) W0 V0 @    DeviceObject = DeviceObject->AttachedDevice;7 @# l" e$ ^# e7 m9 ^
  }3 M) O; i6 B) u4 o

' m5 a/ [/ o( q8 J$ v+ d0 O/ _  return bFound;
9 Q4 A; X9 u# a( g  V}
* _' t1 q" [6 K
+ v9 u' k. w, |# b" }& V: P' X/////////////////////////////////////////////////////////////////
# E5 {" O' \* U) m// 函数类型 : 自定义工具函数
. w4 q: Z# ?( [// 函数模块 : 设备栈信息模块& |9 J, v9 \  _, E2 l
/////////////////////////////////////////////////////////////////9 M" j' ^: h* b9 P3 F! s9 P4 {
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址: h/ p  u% ?; |; V2 O
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
$ ]* Q! z- [! }0 I/////////////////////////////////////////////////////////////////
2 F8 I- _0 u! _// 作者 : sinister& E# l  J- q, I% V$ Y
// 发布版本 : 1.00.00+ e5 a: h/ C* f! V1 r0 a* u
// 发布日期 : 2006.05.02
" `- N/ [$ M; ^3 H5 v/////////////////////////////////////////////////////////////////+ b$ y# {* f6 }3 K2 l+ Y/ ]" k
// 重   大   修   改   历   史
' e# Y3 ], V+ s4 B9 L. I* R2 g4 k/////////////////////////////////////////////////////////////////7 U9 H0 ?' r5 j) Z- d  K: B; h$ P6 `
// 修改者 : sinister
* {# I7 E% s" S/ ^% Z) T' h: V0 N// 修改日期 : 2007.2.12
5 i2 |0 P, m9 F* v2 q/ ~0 [// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用9 @% l) R$ e+ [' U# w$ h
/////////////////////////////////////////////////////////////////0 l) q% b) x* G' h% ]; m7 U
2 ~4 w& z' z) p9 c
VOID
2 l0 _: d( j* {$ W! c  ]$ O  d8 ?GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj ): W+ e6 m" q* `+ G9 u+ G
{
6 N  [1 E" F: U$ Z  POBJECT_HEADER ObjectHeader;
; _6 \8 T$ s& [$ M% G  H  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
( L7 u% s% g* b8 H2 ?* W3 X2 W. q! M4 k. l8 m! y
  if ( DevObj == NULL )3 L% M! ]7 r$ |
  {
9 R( T( l& u, G. i& Y2 b8 \    DbgPrint( "DevObj is NULL!\n" );/ `: T. ~$ V' U
    return;: e  \' A1 x* U' n9 [
  }5 f% G* [, N/ g  ^
1 S5 F; ]* w: K3 e, H/ X& K' }5 i2 w! K
  //
) H1 e, v+ v% |8 m+ [. s5 l! ?" o) J  // 得到对象头
% \6 m# j7 C, S; d  //: h1 s& V6 ?, |# b
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );* {  ~; L# z1 B1 T# w8 l- O
- |( r: O3 P; Q4 Q3 \8 q3 S
  if ( ObjectHeader )0 x6 O# N) c' C0 s
  {
6 U4 l6 x( h9 N6 E* l    //1 c# g: z% E- C! f2 N( x4 @
    // 查询设备名称并打印
0 h: b2 i# F8 E( }/ n    //( i* h3 ]$ t: W% I9 x+ R! @  L
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
' T0 D1 G) I; y. v8 D7 F" P2 s9 P6 }! S3 {/ u: R
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
' m/ ?' v  l  J& E    {& e# F9 ^) Y6 \
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
2 h' E8 y. u6 }                ObjectNameInfo->Name.Buffer,
9 ~: L) W! x2 d                DevObj );
* H' ?, S: e: ~: x( @/ \* F; p* o! @, \7 @) @
      //' x& r; Y6 S: R2 u
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示5 z- {" R5 [3 K8 O4 D
      // 用,没有实际的功能用途
  n* }9 l& i+ b& L      //
7 j* w& {+ {5 O3 I8 E/ w      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );. f( T/ T, y6 Y/ b6 Z4 K: g; x

" |9 t8 V0 I2 k- |& E      wcsncpy( szUsbDeviceName,
4 L! U. m* C' k$ G5 d5 z: l  v               ObjectNameInfo->Name.Buffer," q/ X: d3 @0 x; Z
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
( g2 f1 m' i2 T! H1 _9 }    }$ Q* C7 P" y0 f/ w) X4 j3 z$ v/ m- Z
+ f9 a' w9 s: @3 F  V& F3 W
    //
% b+ v3 W: i# h( B% s1 K, @    // 对于没有名称的设备,则打印 NULL
& g8 A2 v* p4 m) [$ _    //6 z. w( H, Z1 w7 t$ ~: d' A
    else if ( DevObj->DriverObject )
; p# V$ f. b) W3 L! V! Z( |5 R    {
  z  G& J6 Z; p      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",  f8 `' g0 P3 |- _
                DevObj->DriverObject->DriverName.Buffer,2 Q8 D& l5 P7 V% B/ Z! p
                L"NULL",8 K4 D* w4 q9 n* K3 I) R
                DevObj->DriverObject,
! _7 v. U/ z; y. S                DevObj );
& n6 d% M7 y/ z    }
1 c& U& n& K7 a7 k. N0 N# W4 q  }
- m' u- \0 P, f: M" _' @}5 v4 k- @4 }' k3 @9 w! c) `

5 r- J7 k" Y; Q: q/////////////////////////////////////////////////////////////////- I4 H) ?6 j/ p
// 函数类型 : 自定义工具函数
+ k* E. p( [0 }6 _// 函数模块 : 键盘过滤模块
  z# g9 A9 |* O/ O& k3 ]" j. K7 r/////////////////////////////////////////////////////////////////
$ f  S- x/ [# Y: v; |! P! y' M// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
9 x2 R0 I# o0 c# L! H7 |" j6 b//        对象,过滤出 USB 键盘设备,将其设备对象返回
7 s8 _5 ?9 g- s/ B// 注意 : 8 b6 p( s& Q- v" Z% ^
/////////////////////////////////////////////////////////////////6 d' I' |* G3 N& @1 D( y# E
// 作者 : sinister
+ W# f; v+ S* `) {1 E# Z- m8 b// 发布版本 : 1.00.00
: K! |# L0 `; d& B! ]* ]// 发布日期 : 2007.02.134 k5 W. X5 o( Y+ s
/////////////////////////////////////////////////////////////////
! [3 p, t1 c. m& O0 D& t// 重   大   修   改   历   史- A# v5 M$ C4 [* b9 u
/////////////////////////////////////////////////////////////////
; f  i2 ]0 I2 ^; {" H// 修改者 : 9 V8 u* _. n0 c, w  e0 b
// 修改日期 : 3 G2 P0 ?. r: X6 b7 M
// 修改内容 :
) n/ f* P9 I, d! w7 f3 n# Z) y/ P/////////////////////////////////////////////////////////////////
$ C7 o0 B6 m+ ?! @8 L* J( x. Y2 A
NTSTATUS
5 {. c* m+ Y2 |2 X0 OGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
5 n$ A( Q$ H: k) j1 \{
  x$ u: Y& B" i' \) U  UNICODE_STRING DriverName;
- j7 C8 y9 C* r, S# ^. `- L  PDRIVER_OBJECT DriverObject = NULL;
. r3 e8 L8 [/ \2 o  PDEVICE_OBJECT DeviceObject = NULL;
) A4 L5 ~% ]- [2 W) C  BOOLEAN bFound = FALSE;: u. C0 T) t! p: L# C3 H
& O3 h5 r$ q0 [% b" o5 ?7 K+ R: G  }
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );8 u6 y! v3 H2 S9 X

' o$ M" G2 D$ F  ObReferenceObjectByName( &DriverName,) q0 l" O! Z& O0 z6 g! D/ L% B6 i
                           OBJ_CASE_INSENSITIVE,
8 f) G" S) T5 c- Z9 N0 \0 A4 H8 P# j                           NULL,( {* p5 M. e# R6 g9 P0 o
                           0,
0 U/ w( T7 h+ U/ V1 V* j- ~3 |                           ( POBJECT_TYPE ) IoDriverObjectType,( n! ~3 x' D% p8 T7 O
                           KernelMode,
6 U+ D, A6 B4 H" b9 l                           NULL,# M' j6 T% a: K( |. E
                           &DriverObject );
+ i8 a7 \3 w% y; u
% \) [+ k% R3 O  if ( DriverObject == NULL )
( O5 |4 d! C5 P$ ?+ H  {
! }4 |1 Y1 ?9 y9 b2 l' i    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
$ i( x. i! L# U+ W) f: A1 _    return STATUS_UNSUCCESSFUL;
  z+ L4 A5 G( c2 @  }. b2 k9 B  s, ^0 s; a

$ }% e5 c2 G0 }1 [  DeviceObject = DriverObject->DeviceObject;
4 V/ B% H9 P8 L) L2 y* f; P- v
  while ( DeviceObject )
$ t0 h1 D# I! g5 M+ X) M4 g  {
+ d4 z! G# [8 V9 ?3 {1 ]    GetDeviceObjectInfo( DeviceObject );
1 j$ N3 M& J- }3 K/ g% H8 j( J7 h
; n, a8 Q! b. {7 b0 Q    if ( DeviceObject->AttachedDevice )
# @/ M. ]3 Y& M% u/ {    {6 R- s( X' Q$ ?) k% ~
      //4 l' O& o3 Y+ ?4 h
      // 查找 USB 键盘设备
. ]* |5 O0 c' T, S      //; M, K) P1 k3 S9 c# G
      if ( GetAttachedDeviceInfo( DeviceObject ) )
' p. Y- i# f1 o8 _8 u# d. L% `      {
9 \5 O) W" B# {& C# j        bFound = TRUE;" ^9 @5 [. k  ~& f% F) n
        goto __End;
; h# b' V9 [0 w8 a7 v+ ]+ M      }
* G" I9 \: w( u2 ^0 Y" a* u- e    }9 {. f( y+ w( C) b  q, x! A

# K/ N) G, h/ H    DeviceObject = DeviceObject->NextDevice;
0 G) \; Q" J0 w, s3 c0 C# u  }7 J: L5 n' H& \+ S

& V9 E- u, q5 f  __End:! b3 W. k# v, d$ ^7 @; Y2 W. @- V/ [

9 V# j1 y9 ^5 `! E: {  if ( bFound )
. d; H" ~1 _5 m6 J) m  {" e+ ~7 R. M1 G; w7 l
    //. C) |  i; b* W/ o, E* e
    // 找到则返回 USB 键盘设备对象$ s( [3 B/ B" O1 c  R  b& U
    //
: B7 s! ]  O6 `% o    *UsbDeviceObject = DeviceObject;
; W8 R( v; \8 z+ c' E8 e  }
* z' D: E) d7 \5 b, Z0 p; D  else
& p, k/ j( v- ^' o  {
; _- c7 j0 j4 I" e4 \    *UsbDeviceObject = NULL;9 f# D2 J' a3 {, |# E
  }
* `& X  [/ k9 h' {( Q. K
. F& x6 m0 F6 @  N1 f. t  return STATUS_SUCCESS;0 X  k4 W2 F: f
}
% z) C# z  n$ w* T* Z, X7 t- g2 P8 f, `
/////////////////////////////////////////////////////////////////# X( _5 a0 t2 @, n- z$ y
// 函数类型 : 自定义工具函数) Z& i( Y  q/ V* A: I
// 函数模块 : 键盘过滤模块& h+ I% ^1 h/ m% }
////////////////////////////////////////////////////////////////7 K( f# t. z; r5 e" t0 M4 v
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关  O9 q9 i, Y- S1 j+ z  Q8 X' u
//        信息,返回附加后的驱动对象: D. q, g/ P& k: z: |9 r5 h
// 注意 : 此函数仅挂接 USB 键盘设备
4 p" G9 H$ p' q( h- G3 H, R/ m/////////////////////////////////////////////////////////////////, O2 f) |4 X( t& e8 X7 h! S- a) K
// 作者 : sinister
/ {3 @. G/ X# c! Y0 ~// 发布版本 : 1.00.00* J" Z- r: u8 I  m0 b
// 发布日期 : 2005.12.273 j. `: V( Y0 z2 X
/////////////////////////////////////////////////////////////////; s/ r) X" Z2 ?1 _$ {/ \. O7 ^: S
// 重   大   修   改   历   史
9 u& W& [% t$ m1 O7 m0 H5 o////////////////////////////////////////////////////////////////& [6 W: @2 m1 T6 @+ ^7 V. }) |
// 修改者 :
5 D$ Q1 V2 m# e# G. T, ~2 j// 修改日期 :0 g- W& s* x! V
// 修改内容 :
, Q5 h& y3 U+ A, G% P/////////////////////////////////////////////////////////////////
, J  O7 W# g5 |3 M  e
& M7 K3 {2 Y2 c9 E7 T5 @NTSTATUS+ w8 q) }: \( u, ~. M8 W% V3 s. C
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
4 C' _1 q) h' d. O& T1 w                         IN PDRIVER_OBJECT  DriverObject ). }6 [; k, {: d7 ?) \8 w8 u
{
* B: B& Y1 \0 F+ p. \6 W  PDEVICE_OBJECT DeviceObject;
3 i& b" K- a1 m* `' u  PDEVICE_OBJECT TargetDevice;
" G3 ~2 q+ F& _, _6 F  U/ o( T  PDEVICE_EXTENSION DevExt;
2 F# z6 b6 W8 U2 m4 l! x  NTSTATUS ntStatus;4 |( B9 o9 i" N+ u2 P* o7 R
6 c, p- z& q2 n2 D/ K9 [2 h
  //5 C9 T0 I9 s! z% [. R0 E
  // 创建过滤设备对象
( x* l. o0 p- w  //
# n: R; t/ E; y0 g  ntStatus = IoCreateDevice( DriverObject,
' f. g4 E* V8 i( D, I& Z) J( u                             sizeof( DEVICE_EXTENSION ),$ V1 W2 g/ z4 ^; V
                             NULL,. ], h9 m* ?7 w1 E! _% S. J
                             FILE_DEVICE_UNKNOWN,% a1 B$ C7 S2 H! h, W, }  z- L
                             0,1 b* a3 j0 Z) V
                             FALSE,
$ [9 X1 R; A9 x2 k8 Q# P                             &DeviceObject );
4 Y% D, \! L  ]3 V% T7 |
6 n* G* C' H2 R' s" o4 a  if ( !NT_SUCCESS( ntStatus ) )
( z( ?/ b7 y  |7 ]" Y9 x9 u  {, k* Z% C+ t9 q5 I6 c
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );8 v. g: o9 p, G4 y$ K! r5 y
    return ntStatus;
6 W9 E1 h" X& U: }  } + _$ q: G! C, v% S8 X9 V3 Q

- B. e0 k1 H5 Q' Y  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
( d. X* U2 \& d; `0 m8 ?+ y& g) s  F5 `4 V
  //" M- V5 K: r) Z$ h- v- s, v& e
  // 初始化自旋锁
( g! Z* d; U2 A; [4 v  //
! }& S. o0 L0 A( Y5 Q4 Y( U, ^& z  KeInitializeSpinLock( &DevExt->SpinLock );+ e7 ?( R% X. {2 d
" t9 o7 s8 Q: a4 N2 [
  //: U# u$ O2 d+ ]# s8 f& Y5 |
  // 初始化 IRP 计数器
0 a& o/ c- A. h& r# V, L$ p9 f  //: F9 z, Y9 o7 C2 R) F7 ^+ w9 B( b
  DevExt->IrpsInProgress = 0;5 Z- S3 x5 v7 U1 o8 y
9 c$ u/ r/ |/ h/ J
  //
- x; _) h2 T. Z& s# c6 O  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象9 y$ ]- q/ }" Z2 J  U: t3 L% E. q7 a
  //
5 P' k- M/ H- S  o  M) B* {$ q
; O1 J% x; e; h  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
" }6 ^* c% |8 U; J  if ( !TargetDevice )
- [% ], z7 |/ Y  {
  a1 V* R% ?  ^+ J( Y" n' a" D+ U% {    IoDeleteDevice( DeviceObject );
# r+ f% A2 u# C1 ?' V& l+ f    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
9 a3 p4 Q; J) ^) {8 A' w; [    return STATUS_INSUFFICIENT_RESOURCES;
+ G3 E2 f  `% K1 I, r4 E; I  }   ^" Z$ H0 V0 w4 _# U
* H8 l% ?$ J$ h- b$ H5 p, t9 g
  //
3 f* y0 B# |; I3 g5 x. u! L% C% W  // 保存过滤设备信息( p2 Z6 m& p' a9 }9 T; @
  //
7 T* V3 a$ q0 S( L! N- y- N  l  DevExt->DeviceObject = DeviceObject;
! `1 |  ?6 H% ~: q8 `" S  DevExt->TargetDevice = TargetDevice;& Z$ [8 x; Z: f- S* p: i. m, I
) x. D5 n1 S& N5 R
  //
2 k! N+ X. d3 J6 S# o0 Z  // 设置过滤设备相关信息与标志
: U/ _$ j3 Y: f9 o" ^' d+ @" A9 a  /// E' P9 [7 Y% `8 c2 {# w
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
5 \: _, L. ]% ?$ U7 Z8 Q  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  T6 c3 L0 ]" E; }' H' R5 ^" d* b" R- V1 }
# n/ Y) E  `5 X6 h5 F6 E
  return STATUS_SUCCESS;, M% v, K" `! d8 }
}& ~# [# R1 M& H$ O

) H* z6 z: V* _4 m/////////////////////////////////////////////////////////////////
. r/ G. s* n) h# b9 ~! }0 k- U// 函数类型 : 自定义工具函数
7 @4 Q8 S+ k( ]3 c  B9 P& p// 函数模块 : 键盘过滤模块
0 }! P  t- g, K8 I# @////////////////////////////////////////////////////////////////0 _- Q; n. _7 v  @
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关- `, T7 ^  E" X- m
//        信息,返回附加后的驱动对象# g3 Y# B8 V( c9 u
// 注意 : 此函数仅挂接 PS/2 键盘设备6 v4 r5 W: u! _7 Y% Y  B
/////////////////////////////////////////////////////////////////
7 ~2 f2 P0 L" m8 h) l* D// 作者 : sinister3 ]. u( k7 D# a
// 发布版本 : 1.00.001 B" _* F7 G. ^5 h1 l: G9 o
// 发布日期 : 2005.12.27; p3 A% x, a% j5 P( g
/////////////////////////////////////////////////////////////////5 [+ j/ ~# p$ Z9 ^
// 重   大   修   改   历   史1 B, {, J/ B- V/ x
////////////////////////////////////////////////////////////////+ _* |; Z: o/ g
// 修改者 :$ G% L/ F/ e. v% l; F6 B9 {
// 修改日期 :( p0 @* }( W: y7 j
// 修改内容 :
3 W+ i$ Z* K; s' Y& b0 d: k. `/////////////////////////////////////////////////////////////////
$ s) r& j6 V6 x. q& `" w# F1 {+ X9 |: d( \2 `2 n0 x/ O4 w
NTSTATUS) b3 K' X8 J% F+ ]; v# Z% k3 a
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
, n" r  a) ]' Q% ?" v/ _                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象8 |" m, m& Q9 c( t- z; Z1 N
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象0 X3 b, R. j: w" C( k
{
) J* t" t; t. v' J: U  q) w  PDEVICE_OBJECT DeviceObject; 0 `" b5 v' m$ {7 M: _4 s
  PDEVICE_OBJECT FilterDeviceObject;$ b' j6 N2 E' q" L& m
  PDEVICE_OBJECT TargetDevice; 3 I3 r8 d" C1 C' U5 O  A1 Y
  PFILE_OBJECT FileObject;
. F  m2 B( t3 }( _" l  PDEVICE_EXTENSION DevExt;0 |' ^; x" `$ x! N8 Z
9 [% X% v8 C. }7 F/ f( @5 I' V
  NTSTATUS ntStatus; 8 o( X  d/ h4 d9 C
) J5 g# M/ z: M1 t
  //
: _) C5 c& Y; V6 B7 Q  // 根据设备名称找到需要附加的设备对象0 H( [5 p& q0 |1 ^# v
  //
- V' e( E" E, Z: z$ a$ ~  ntStatus = IoGetDeviceObjectPointer( DeviceName,7 J# w& f4 c- E5 F
                                       FILE_ALL_ACCESS,
, e; P' _% B* @9 F                                       &FileObject,0 R; ~& d$ q* G3 H8 R2 o7 m+ i; H
                                       &DeviceObject ); ) E5 e' U+ J4 {, K
5 h4 m, v. V; R
  if ( !NT_SUCCESS( ntStatus ) )
3 N, ^$ Z! B8 ^7 p' r& M  {
6 K3 Q/ k- |  J    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
$ V; ~: {- `' T1 P' o5 _, Q$ P7 Z    return ntStatus;
5 O9 q- \; `: q$ ?! {  }
5 n/ F/ q2 q+ }( {* z8 h1 C( X0 @
/ u. x! S5 ~& }& m  //1 f. Y+ a( d. O+ O2 x
  // 创建过滤设备对象
& H* U6 T8 ]2 s7 j6 v5 V5 p  //. A/ S: y) J  J) b' @5 p9 h2 v( A9 I1 H
  ntStatus = IoCreateDevice( DriverObject,
( ~# N- n7 I- y9 k: [7 w# j                             sizeof( DEVICE_EXTENSION ),
) t& P, R! m2 C* f                             NULL,) L- N# @& S  _# |
                             FILE_DEVICE_KEYBOARD,
. F/ W8 W! ~5 n- v0 l/ C                             0,
  c/ E7 P7 Q3 k/ [                             FALSE,, ^- `7 U7 X- c% l+ N& D
                             &FilterDeviceObject );
6 W7 j  l, p) V6 |
3 y" m; ^! e( D9 D  K+ k  if ( !NT_SUCCESS( ntStatus ) )7 T: S  p8 x3 \" ?6 ^% k$ k
  {& E+ M7 P% q$ [3 a* d7 @' b9 W
    ObDereferenceObject( FileObject ); ) d2 W2 t% n, d) g0 ?2 O6 o
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
1 |5 C& i) _8 w: T* G  T$ k7 w, ]9 A    return ntStatus;
( U% ^% m' ?0 m$ S  } * e( V! B) r) i9 e3 f% V

, g7 B9 z! ]3 H0 {- v  //9 C+ D( B0 H  C4 V: F4 s
  // 得到设备扩展结构,以便下面保存过滤设备信息
+ [% b7 V; A$ a. a2 P4 X* B8 q$ f  //
! l9 U( x( X/ `0 Q& Y4 h, i! p  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
7 n- D0 S4 `- f: C' Z. M* k* p) I" j

/ n: k0 R# |. B) g" i  /// N! S. [0 \) @: c: \" ?
  // 初始化自旋锁& u) u8 E& X+ b: R$ N& z. E- H
  //
" \% i+ E6 Z' a3 h, U8 o$ i  KeInitializeSpinLock( &DevExt->SpinLock );( `4 h# N0 V6 l6 G3 q

  l" X7 q4 p7 c% Z, \! M. U  //2 n* q6 E' _4 O, l2 C! D: }$ F: z% d
  // 初始化 IRP 计数器
' a+ X) u. d0 C+ M5 t0 q/ N# g& G" Y+ h; w  //
! a: j6 E8 U- ]9 [; _  DevExt->IrpsInProgress = 0;6 N1 M8 k5 j6 c6 _6 v* G5 z

+ r0 d; q1 P7 O2 \8 k& f; H  //
+ I7 E+ R$ J: v& P  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象; o- ?4 T3 f, [5 W& W( u7 _
  //
% M! |3 |8 w$ K4 ]8 ~9 Y  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
% ~7 E: }; f3 b1 s9 h/ D% k; ^                                              DeviceObject );
8 V% q' L# ?; P: P2 U) f  if ( !TargetDevice )
$ ?4 p( z0 Q, C: O+ t( ^6 n  {
: s& }6 |/ A5 u: U8 ?- T: q, _    ObDereferenceObject( FileObject ); 5 D9 `' b2 C' T; t  Y/ d3 }
    IoDeleteDevice( FilterDeviceObject ); , h) Q; b( d+ ~
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
6 C, z$ l/ `! x! F    return STATUS_INSUFFICIENT_RESOURCES;
. I4 `+ B% R; j, ~  }
+ f2 e1 B% l7 \; O% U6 n
. S- U2 s8 a! z! d- j: B  //
$ s1 @4 A# M5 p$ U$ L. m  // 保存过滤设备信息2 S/ Y2 g" e9 F, y' N
  //
# G, q; R2 }2 B  DevExt->DeviceObject = FilterDeviceObject;
9 Q) d$ d9 X3 z- {+ A6 g  DevExt->TargetDevice = TargetDevice;
$ }/ }* J- H0 y/ B. ~  DevExt->pFilterFileObject = FileObject;' W9 ^# k0 R! a. m* X
! L2 y& i, S1 \) }' |7 D, m, j8 K3 t
  //- t4 g4 F6 G' i" |8 d* p: O
  // 设置过滤设备相关信息与标志4 p! M0 v; r+ X; ]" h' J, H8 m* F
  //- Q% d% K9 U# B( C7 B8 t  @
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
1 S% W' p) P4 e+ q. h  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 3 G* {. z% c. n& C
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;3 {; |6 d% B/ C3 d: ]! B9 v. z. ~
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |( h' `6 t! v9 `9 e. f
                                                         DO_BUFFERED_IO ) ); " p3 N6 }+ H& \6 L; T7 z- Y
3 E% h) G2 r" [6 i% i1 ~6 R$ J
  //1 ^$ h) s( s7 R1 `7 X1 F* j
  // 返回附加后的驱动对象2 a" \; A/ k" z" h
  //
: o3 M6 x2 x# s0 Q  J% b8 ^  *FilterDriverObject = TargetDevice->DriverObject;
& H9 J% Y# V8 v
# U4 V$ y4 @- ^6 W  ObDereferenceObject( FileObject );
5 h& @- f3 K. b* V5 X6 s+ p; v; [" m0 t: I: p
  return STATUS_SUCCESS;' h% m/ J& J! N
}
1 u! ]/ @0 b! _& A/ C% t
  a. H6 m" p0 Y; i/////////////////////////////////////////////////////////////////* i* ~* e  _; M; T
// 函数类型 : 自定义工具函数
9 B" b  L8 P" g5 l2 j// 函数模块 : 键盘过滤模块
! m- v  u% Z$ |" L% O6 l////////////////////////////////////////////////////////////////6 t! \$ B3 h: d1 w% ^: f
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
9 F: O2 M+ R& X1 J) J) S% M/ S* T//        这个 IRP 的完成
4 ]1 d; S7 }5 f// 注意 :
( u% B  ^4 o$ Z/////////////////////////////////////////////////////////////////$ c. E! U! h4 p( E) J
// 作者 : sinister, k2 b5 l  J: s: R: l" u' V" E
// 发布版本 : 1.00.00
6 c6 n9 Y; `" Z: V0 A// 发布日期 : 2007.2.15
5 F7 U) x$ j8 n1 z- y) O/////////////////////////////////////////////////////////////////
" D2 {( b; \# P4 P7 C* u// 重   大   修   改   历   史
, G0 f: Y4 U- H+ {! r; {" \+ ~- j////////////////////////////////////////////////////////////////4 i5 q5 K1 z3 m" V6 Y
// 修改者 :
5 ~- D- v$ u& s// 修改日期 :
3 i( X) \7 ^3 S, c// 修改内容 :
6 {: M1 j3 ~- j/////////////////////////////////////////////////////////////////
. Q0 b4 ?* C) V% \# I6 n2 N5 m' @+ c: J8 b' z! I; n% Y
NTSTATUS
* L. b% r+ G# o8 u5 RKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ), f# P0 b, o6 n3 n( D0 L: E
{
/ q, M7 t- N! Z  x  NTSTATUS status;
2 t  Q' h3 N& n3 C3 L/ i  KIRQL IrqLevel;
6 P; I9 s( p5 z6 J  E. B- |# V( s( g0 |5 W4 p  }
  PDEVICE_OBJECT pDeviceObject;* c; [" X6 i; ?
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION ), D7 \" S* A: J$ \9 B! w/ J
                                   DeviceObject->DeviceExtension;
8 ]' D9 H/ s( D+ ~2 j+ Q
8 w% K3 J8 a( V0 \$ u* U: z+ j# x2 F3 C2 F/ o3 T
  IoCopyCurrentIrpStackLocationToNext( Irp );7 G* [  v" \& J

4 H/ c0 _9 A! m8 r( v. c9 ?  //0 W- m# _, f" [) m1 y% O  U
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
/ {) u! w8 m' ^2 ^* j3 e  v( `  //" B$ f+ g! e1 M) R, \
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
( _0 r4 o  h. e5 j  InterlockedIncrement( &KeyExtension->IrpsInProgress );
! v( ?5 U" p  k( m% z0 ]  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
5 F+ M9 Q7 g8 b% v6 u$ T
8 y: [5 A9 k+ R  IoSetCompletionRoutine( Irp,5 x4 }# d. w6 Y* f, C; W* w
                          KeyReadCompletion,; V, V, v/ @  |5 `; I
                          DeviceObject,1 J" h3 R: \3 D1 M; K
                          TRUE,- K0 V. u  ]' ]+ T# y8 R
                          TRUE,
6 p9 _2 v% ?. s: U                          TRUE );
' A( f1 j0 F0 `! Q/ p6 O! k% ^7 _5 b' s
  return IoCallDriver( KeyExtension->TargetDevice, Irp );) [( s+ x9 |6 G0 E0 D# b: y' b
}
8 ^% T, R. ?3 C# \0 j8 \6 e1 y/ {7 P( h( \0 b" T
/////////////////////////////////////////////////////////////////
- }0 [" j2 P& |! t  y4 t% A// 函数类型 :系统回调函数
" u/ q! L6 {6 x+ i  R- w: p// 函数模块 : 键盘过滤模块. V9 `- Q0 K  c# V, |* Z
////////////////////////////////////////////////////////////////
* f5 u! G: k$ I: Y3 c: o// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
* v7 s- @6 B3 O- u5 E3 q+ J2 n6 ^// 注意 :
; @8 b- f% ~' [" D6 d/////////////////////////////////////////////////////////////////
7 G3 P# [+ j' l5 l9 d9 P. }$ E// 作者 : sinister7 E* S( x7 [. p( ~
// 发布版本 : 1.00.00) Q! R% J( y  R
// 发布日期 : 2007.2.12
3 S( |7 A0 ?2 d$ x$ D" w) ~/////////////////////////////////////////////////////////////////0 J' L- W8 R" w/ @, S7 D; E) j
// 重   大   修   改   历   史
* E# H5 l0 J7 O* a////////////////////////////////////////////////////////////////
2 g8 W. x+ J, V4 u# {3 {// 修改者 :
  n. n" q6 U( E) b// 修改日期 :
+ P; _6 [: B: U! v6 C$ E0 ]/ |7 n// 修改内容 :
$ W; O) U/ ?# o$ f/////////////////////////////////////////////////////////////////; M9 ]0 Y* ^' `8 f. V- k

& \8 E4 A. Z: l6 O' L) \& CNTSTATUS- l2 ]6 I- a, I& O. m0 {# u
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
& z4 k7 C: H6 R  }$ c                   IN PIRP Irp,
1 `) O0 `% R8 P+ }                   IN PVOID Context )' H2 M8 b; o) V% Y/ C! p6 h
{
  ~+ `$ ?2 H: C, f* B& k& g! M  PIO_STACK_LOCATION IrpSp;6 u1 d$ O# ]( v; B3 L
  PKEYBOARD_INPUT_DATA KeyData;4 F. f! M7 ]' O+ T+ c1 a( s1 e
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ d; H1 }& n9 {$ @* K                                   DeviceObject->DeviceExtension; 5 t+ S8 k" J0 a
  int numKeys, i;- Y! V8 r  @! c+ |6 E
  KIRQL IrqLevel;5 H! Z5 [1 H* A: m  ?
( R: p( i7 }8 k2 k
  IrpSp = IoGetCurrentIrpStackLocation( Irp );. z- A1 y3 A& C" K% \; C

' X2 `# V6 S5 f$ y- M6 r( N$ n8 Y) s' G: a
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )0 q& b7 @+ o& A! v# z1 N# T+ A
  {" h9 U8 n# d) X6 v# i& Q7 k
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
, A! a+ A9 X4 c    goto __RoutineEnd;% j. s7 E8 N9 w& I; C
  }3 p) |5 ]& n: q; p
( e" O! o  B* S, _
  //
3 e4 h9 [  P0 X6 r* O5 N  // 系统在 SystemBuffer 中保存按键信息
' _5 X+ R2 k! ~, M$ W) l) d/ N  //
1 ^- l# R( ]" Q* O  KeyData = Irp->AssociatedIrp.SystemBuffer;
# h9 }) F- T/ k& r; v  if ( KeyData == NULL )
! ~$ k) E0 r/ s  q1 {! z& ~  {- L; ^7 e; i- b, Q6 `4 n3 p" H1 r
    DbgPrint( "KeyData is NULL\n" );
$ j# ^/ x, \# c% D) v4 e- R: [    goto __RoutineEnd;
- X9 C/ C. O- A: b2 C  }
9 o$ G) ^4 d0 }/ G# i# e  `6 b
& v* F' f2 p6 R: j  ]  //
7 w. f+ {) u9 _9 b) H  // 得到按键数
5 r9 L& e( \' ~5 d# q' M" @  //
  k4 y& j/ X  R2 C8 i3 P1 N  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
0 K& k, E5 t) M3 g" \  if ( numKeys < 0 )
2 P7 H  b% K. X- x* J  {' o2 i$ |( |& B. x/ b! Q
    DbgPrint( "numKeys less zero\n" );
& m& j* F9 T0 P) |# V    goto __RoutineEnd;; `' i) Y2 u+ e  ?# q3 p! d
  }
1 v4 w1 {% r- m! H
/ N. C# K0 X5 ]. L$ L/ m4 j( M0 t  //( m! p" N8 u* Z# g) Q
  // 使用 0 无效扫描码替换,屏蔽所有按键
+ [0 `- [5 ^: q, I% v  //
  N: C* C1 Z( h+ R! z6 R  for ( i = 0; i < numKeys; i++ )
3 ]+ {2 ]' C1 b2 n  {
4 f" D, U5 t( B( d: i- l    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );% n& n8 E5 J3 q- e  ^8 q
    KeyData[i].MakeCode = 0x00;  x- Y$ B) A% Y
  }( q/ B3 T1 X$ k+ D, Z6 Y, @

9 f4 ]: G# o+ k7 ~- g- }
' U" G2 ~$ E$ q9 c7 ]: ^& o  __RoutineEnd : 4 [  D% L' {! d6 X2 ^' r
% o$ V/ e& q& J9 m+ l
  if ( Irp->PendingReturned )
- X9 t$ z& ~- I  e5 G& M5 I8 O  {, h: D/ \0 Y+ z+ T- @3 @4 H
    IoMarkIrpPending( Irp );
3 }, L' T. x( ~5 v( s- h: H# {, p  }
7 n& h/ ~1 u' h/ R, r  X: G) U) ]* p# A" {7 Q! G1 j9 h9 T& A
  //& u1 x4 K! e( w; A* S
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁7 b& Y0 V) w% f: T6 `3 H% ~
  //
. l' p% q" e/ _9 i1 F' I  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );( s9 _. ^1 l: M3 C8 f3 k" U
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
- y. E$ t/ ?% l: Q5 k  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
6 q8 o" f" `) w
. w, Y( Q9 s  g) H7 L4 @5 s& Z$ q  return Irp->IoStatus.Status ;
! |& k% ?$ J- E+ F% G. H7 m' p% r% P* ?' D}
; B, ]- @( N; G* s% }" n' z# W7 `9 {. C: k
8 J+ G" w. S/ h6 o+ {! g
/*****************************************************************& X4 {# e6 X* [, k, o0 ~3 C7 {+ T1 c
文件名        : WssLockKey.h7 q6 b! s, B. z0 S) }, j, y
描述          : 键盘过滤驱动/ X8 d, L0 E, g, E8 @3 e! O
作者          : sinister, j+ h- e/ B+ R
最后修改日期  : 2007-02-26  r; W+ E) O: {1 m
*****************************************************************/0 O; B: z7 M/ v0 A! F5 J

! U$ B' @, M$ F" Q" K5 Q. x#ifndef __WSS_LOCKKEY_H_
' v6 w( }2 Q# ]4 [9 n#define __WSS_LOCKKEY_H_
# a% A$ ?) a3 L6 M8 ]% G  O2 A2 R( S4 q  U! J0 _9 u
#include "ntddk.h", `2 ^+ E& w5 E+ Z2 X
#include "ntddkbd.h"  D' O- f: H) z& S
#include "string.h"
: Z& i: _- w8 v- `0 e# Z9 n  Q: E#include
% b" p( v/ h' S  o  K6 m0 ~# y
0 B# `& y* x/ i  y- U6 O#define MAXLEN 256
$ x0 w3 L4 Y& c% x) o% Z# e- O1 L% F3 t7 H2 F" L9 t  w
#define KDBDEVICENAME L"\\Driver\\kbdhid"
& A& M, [6 ]6 S& R1 m  R#define USBKEYBOARDNAME L"\\Driver\\hidusb"
! R% J) K( n" Y$ R4 n3 I. O7 q#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"1 }/ J4 d; o! n+ E3 Y
: X% r, V- v: O
typedef struct _OBJECT_CREATE_INFORMATION
/ g; a, e/ u4 @5 k+ U{- A1 l# c+ T' N8 s# D
    ULONG Attributes;! j1 Q5 G2 r0 ~. P( `7 ^0 B  ]
    HANDLE RootDirectory;# \+ z1 v0 v  X: `5 r3 S& T& R4 H
    PVOID ParseContext;. M7 W5 o3 w* |+ l  i- X
    KPROCESSOR_MODE ProbeMode;
. Q6 `0 q1 S- Y8 i2 t    ULONG PagedPoolCharge;' {1 o( K% O4 k  c- N0 w
    ULONG NonPagedPoolCharge;9 A3 R) F, I; ]. i' g/ |% C
    ULONG SecurityDescriptorCharge;
3 x3 X! ^8 e5 T, H* ^    PSECURITY_DESCRIPTOR SecurityDescriptor;2 o+ `7 a/ y. M6 A
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
$ u: ?  `0 ]4 |, C$ G* v0 T* a    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;  G1 |# l6 m* L& s$ J$ Z
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
5 R6 p3 A& ]& G( X4 @
( i, H+ ?/ ~) q* B* ltypedef struct _OBJECT_HEADER8 N/ s& d% a, F% t& F3 x
{; [' Q/ ~9 N7 @$ m% f6 V! f' n
    LONG PointerCount;3 Z+ b5 A& x2 U4 O$ L# @
    union
  b2 D" h1 t: P+ |. {2 {    {, ~6 s: }7 E4 q  `. w0 R9 X6 _7 H  J
        LONG HandleCount;
- m- l. o6 Y1 W) V: z) I; q# C7 n1 P        PSINGLE_LIST_ENTRY SEntry;# w4 @" U4 V. |
    };+ Y* G  D/ \2 L# J) b
    POBJECT_TYPE Type;
+ w( ?; V/ m+ p8 J! j& I    UCHAR NameInfoOffset;/ I3 G. W* ^0 ]: ^! _! N/ ~
    UCHAR HandleInfoOffset;3 T, v0 Z% |* R8 z& C& z5 y
    UCHAR QuotaInfoOffset;# z2 I9 }1 b  o* O, D" L' l
    UCHAR Flags;
3 m( d3 d" S( b% i/ Y/ c9 r' k9 Y    union; r4 R. Z- @, h% z; g' g
    {
. F  z+ ?+ O( ]0 o3 x/ q3 p; ~. T' o        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
9 D' X& V& e8 J6 P# H3 |: r        PVOID QuotaBlockCharged;2 q! e0 p9 O+ A( a) Z7 u
    };
- }% @2 x6 N' j. n+ [
9 d# R6 D3 b  S: R# D    PSECURITY_DESCRIPTOR SecurityDescriptor;& l' X! T, W% P; `2 u3 v# d6 r
    QUAD Body;
7 ?  \# ~7 k9 D; X0 |1 I* E} OBJECT_HEADER, * POBJECT_HEADER;( ^% B6 n& j  I9 F9 G5 a

' T8 J8 D/ D4 F+ c% I$ F#define NUMBER_HASH_BUCKETS 37
# l% [+ X9 V' v/ [; }5 `" x! g& j1 k: N# G: a2 a
typedef struct _OBJECT_DIRECTORY9 N. n" r& T9 k1 t7 D
{0 A0 d+ Y# ?, _9 f
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];# l9 x' j( U1 D2 X" p: U; H
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
/ Z; H5 Y' {% \" [4 n  k    BOOLEAN LookupFound;
4 v" ?3 I0 v* X- b' w: Z6 C9 ~. [  f    USHORT SymbolicLinkUsageCount;
  d$ w; a7 X5 E# Q3 ?, o0 M3 b  T$ S    struct _DEVICE_MAP* DeviceMap;& Z9 Z: n% J4 }$ V8 G
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
+ T; `$ W+ F# e3 n
2 w! ~, q! j, V+ ~( stypedef struct _OBJECT_HEADER_NAME_INFO7 V" k7 z* ~- \* a2 x$ g4 u
{( M$ V0 P" N" B, i1 U& y
    POBJECT_DIRECTORY Directory;
+ u; i3 b7 g; {6 I- n    UNICODE_STRING Name;
$ g3 r: I' w* N- R4 x( C) v    ULONG Reserved;2 V/ w" W; F" A' Y+ w2 `" u
#if DBG
2 \; R4 `0 i9 Y. L& u6 N2 T+ s    ULONG Reserved2 ;; W! }4 s: @' H- ]2 s% s
    LONG DbgDereferenceCount ;
0 O1 ~# a; p$ m. ~) _9 B#endif
4 p) d6 {# o8 D% `0 p} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
& n0 r- W) S0 U# w) O$ d9 ]
8 I9 v+ E9 o3 t; m' d#define OBJECT_TO_OBJECT_HEADER( o ) \
% A& F& n. Q" N& ]3 s2 [* y    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
3 l6 J3 J) n6 c# c
* N! O, h" k7 `) [# F+ g8 V/ [8 z6 i' I#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
. r- }: E& x9 O  j. O    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))2 ]) |! {0 O: b! F9 M
1 A" u) k# j( g2 [
typedef struct _DEVICE_EXTENSION
) n8 ]+ V4 G' u0 x3 T6 z: b{
! h* m) w$ q5 d* n" F/ s. b    PDEVICE_OBJECT DeviceObject;
4 t3 D3 @8 @& ^    PDEVICE_OBJECT TargetDevice;
3 ^7 R9 g3 W! k; l: t" Z    PFILE_OBJECT pFilterFileObject;/ o" `# @. P: b' }
    ULONG DeviceExtensionFlags;) p5 N, j& t( t' }" J' @, [
    LONG IrpsInProgress;7 w; X, c  ^% i; F% A
    KSPIN_LOCK SpinLock;5 e& c( x9 T# Z8 G1 g7 r/ h/ v# \2 P
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
7 R5 C3 z& n) J( e7 N2 E6 ^- J
! q; z; I* C$ P. }, [( H* W- n
5 ]# i5 f8 T, z( H5 m% G, QVOID 8 s( ?5 T6 F1 ^& y, v6 C, ?% S
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
, R( }  k$ D4 N" X+ p5 Q6 O, }# m# j1 D, d
BOOLEAN
2 I7 W) S% V# D9 n6 h8 N) v5 qCancelKeyboardIrp( IN PIRP Irp );
9 Q3 u' O) \3 {: ^5 \* ~4 J) h2 R  _5 N5 w9 A, v$ q6 s0 L% R
extern POBJECT_TYPE* IoDriverObjectType;
6 H$ X- l$ \+ L( p; J- X7 J4 G( E2 S' H7 E, v
NTSYSAPI
8 N2 l: o4 y7 iNTSTATUS
# q9 S  O+ ~- u  f( aNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
, J$ ?* h4 W" i( C9 s                               IN ULONG Attributes,# c/ n0 B  j' ]9 X
                               IN PACCESS_STATE AccessState OPTIONAL,' j$ e2 E7 m6 ]% S
                               IN ACCESS_MASK DesiredAccess OPTIONAL,8 @; i5 H5 d, c1 I9 \0 [8 d. v# [
                               IN POBJECT_TYPE ObjectType,
' h, U: H" }$ r+ c! J                               IN KPROCESSOR_MODE AccessMode,
' v, {5 g$ x: z7 c; r                               IN OUT PVOID ParseContext OPTIONAL,& M4 z4 a) H0 N
                               OUT PVOID* Object );
( |0 k: e3 A1 _) X! [4 }3 j
/ w8 j0 y: j& N9 sNTSTATUS
/ M7 S4 `. s" ]9 s- p- |GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
$ h; _% \2 p- v# d, E  L2 E6 p( ?3 f: }, H- r: Y% ]
BOOLEAN & A6 W8 y5 i, |$ E) H
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );& g0 v, J8 S, g7 r

' q3 @2 d1 U0 Q7 G( rVOID
. }: Q- }' p$ C7 w) Z( gGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
. j' Y2 ]) r4 m- p8 i( K' t; y+ Y2 I# M, [
NTSTATUS
' I. E, l8 i; mAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,. q8 k9 S) w: o& G9 u
                                  IN PDRIVER_OBJECT  DriverObject );
9 o5 I) q& P8 m" ]3 _* w/ D, c; |; b8 i
NTSTATUS 8 ]: _" M+ P2 N' \
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
# s* e+ |% [% O, H$ _7 y6 g; \                                  IN PDRIVER_OBJECT  DriverObject,
8 I* v5 Z( K. q6 r" @3 z3 k                                  OUT PDRIVER_OBJECT* FilterDriverObject );
; s0 [( y) |! J- Q9 S: E4 W% r2 `- W$ O$ r  }. `
NTSTATUS 6 \! i* |  ~5 F+ T7 a7 z7 ]9 T
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,) ^) X( ^, ^; q- g, D8 F- s- R
                            IN PIRP Irp,1 p" z5 S  `( w3 x: W5 _. e
                            IN PVOID Context );# D  U5 ^0 U# _% o7 N8 d
NTSTATUS 0 e! ?" |1 N( N4 @
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
! X" d& w. I- x# T! e5 W1 m. r4 e' A+ A
& D$ I( B' M& T3 v3 UWCHAR szUsbDeviceName[MAXLEN];
9 c' G& |' x7 E' j/ s% C3 X7 D5 f9 D( ^! B% H
#endif
3 l' B. h& {2 ~2 {6 P5 X+ J4 ?; F) w' _/ _7 e5 A2 l0 A
: N* Z6 Y& s6 A8 ^- D* W' w

: y0 [) X+ `6 O( q+ ~7 H
, k+ T( v3 Q* G- R
- x, T& J8 m; ~5 N) bWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
0 W# r, F2 k  a) GWSS 主页:[url]http://www.whitecell.org/[/url]
9 Q7 z( ~; \. L7 o' \WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-4 14:31 , Processed in 2.723500 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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