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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister+ i8 B) Y5 L' m- p3 ?7 ?
Email:   [email]sinister@whitecell.org[/email]1 l: c' Q5 ]+ F+ I! t
Homepage:[url]http://www.whitecell.org[/url]
$ g3 Z/ o0 Z" \Date:    2007-02-267 O- g( ~% G, }* i4 j
& s6 @6 Z- y& }, `- D, Y2 M

9 d6 Y0 d% H; z4 c* C! A5 j, R/*******************************************************************" a  b2 R) E% c% H
& }  u" K# {% ~2 O
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
2 l/ E- F; N: H! S, O! `: F写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的- F# ?+ n, J% V! q7 y
功能要求如下:
! u0 S9 z/ m3 i5 t% ^  {0 m% u2 E- Q/ \* d4 v* N3 g
1、强制锁定键盘/鼠标。, f. I% q5 Y, B/ m; h- B
2、可动态加/解锁, h6 K( g  r/ z" |2 \7 C* o# S, b
3、兼容所有 NT 系列的操作系统。
' f$ ~$ w; I, a' ^3 X' z4 F. }  N, [. x6 e: d1 P
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实' g" y1 g! E' p" Z6 k; I6 s1 \1 C
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如( ~9 M7 u0 A: O2 x5 k* }
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在( d+ l; H5 M; _  r0 ~
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
! N5 O$ a- y" C, ?0 c: W8 q怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面) P; A9 K' ~. R0 \7 W# }* L/ H
就来看一下我想到的几种实现方法:  P) e' k8 z' ?9 }6 u+ U/ V

: L. E4 G  J% Y: N1 y! W) z+ w1、全局键盘/鼠标钩子
, S; {: f0 ^; J5 d) s" B5 |4 W0 ^2、BlockInput() API
, t) D' Y9 T  P" X! Y; m3、使用 setupapi 进行控制
; V2 L% b3 D9 o4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL0 r' w" a* a1 i9 ], N
5、拦截 win23k!RawInputThread() 函数
3 t8 y8 P4 B$ h3 c" y( U6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
/ M  b' |1 f9 W$ f  H# @6 L  ~7、拦截 kdbclass 驱动的 driver dispatch routine
1 r& l/ O; r& K- C4 }, l8、实现一个 PS/2 与 USB 键盘过滤驱动' n6 L; M& m* }+ r8 h; i
- e+ u+ i- ^% `" }) Y1 [/ B

3 I% `6 e* Y7 c我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
& E% i, i) `9 w# J# x, R' s5 h! K之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
* @) W0 M6 [) V" z案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
( H! w  z( K9 C- J2 O& T兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因' ^& z4 k6 L" A& Z" H. N4 E) H
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
! z" T3 Q4 r% ]* _" A& D问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸1 b4 X" h: q, I; z/ A& C$ G7 e
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
( O8 z) d7 ^. m7 y% \的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
, c; C  `/ B8 ~9 `) L& Z也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
9 q/ b* D1 `; |$ P9 J9 P果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
( ^6 U+ X+ r  d, z) {9 }障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
  n; {; }3 p& u) d6 S7 `$ }0 sIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
; f1 p3 c( f+ R& z( x8 {6 sUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键; o# c' Z# o- c6 G! u4 [
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方, I  A5 s# c5 i5 c, r! a1 l
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
& a# p* J( G+ ~( C' S) z' x( ~: U" k! p+ u/ E: W3 C

0 r3 q+ j+ X' ]: t7 W我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过' [# x, b2 _3 l& e1 b8 o, N
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
$ [# H& N" M3 U! A- t' }) Y1 L  D行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是" y) }# y. B4 e9 Y5 `: y- W) l
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越0 N( c; b; L+ n; j  Y
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
& D4 o) r$ S4 k$ H: h7 y+ ?" @KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB! L+ F6 l# Y! ^9 }# z9 r' i
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用  G* _7 a) ~( t# @/ Q
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
' I8 c$ @3 _' S9 z# Q4 P4 Q0 G/ U我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题. r# `& a$ a1 j( i+ w4 C) x0 H
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的# v5 r& @' H! V" x- ^; h* y- d- I7 ]
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使( B  D/ k9 t: n( I1 D
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
) Y" d% r1 R1 M: n3 m过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来2 v- j9 M" N/ h. ]$ _+ {4 l5 f9 E2 T
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
% U. C" T0 u5 H4 C+ M过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb- D" d" M, ]2 ?  e: y* R2 `
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
0 _2 l3 q( d: c& `! f" |的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
7 L+ Q/ C# g7 N, m. j# u味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
3 D! k! r  ?. H) n经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
# r5 O" ^/ q" N$ C来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
; P" p' J/ [; m/ C的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
# m, P* D" X9 G& ~6 H/ C% V的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
7 i. @+ G( E% s8 ]) d敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,; M; _/ ]; U/ a9 ]. h  k
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
" V; m. R5 C) f# s见下面代码。
7 ]5 Y2 i3 D/ s1 e3 y. @3 ^/ v
) l+ a/ n: R- N# p: g- s6 N这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程+ p, h- A/ Q& V1 r
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
, ]6 h5 R& Z3 m; F0 s* e& U盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003, Y. f, P. f7 q3 Z1 B+ ?9 ^
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
4 {0 W! N0 P9 D9 B6 J8 _  L  ]完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可$ c/ \* d0 q4 m
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个2 r& H4 o7 ]; Q7 z7 P5 q9 o
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按/ ~) S" Q8 I  M4 s  I% \) `0 h
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
2 Y) P. V6 R, U" W! ]0 {& u
' _* c) T9 B+ F2 I/ k8 ?+ K+ B; [% x5 w/ V0 U( [7 \8 p
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
2 C9 R+ B  Y8 q" e2 J的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
+ i% ~# q, B0 ~! d9 _- ^. H2 r, |可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
5 z1 \' L; c; b1 W6 A0 R+ y的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我6 ~0 c# ]1 E2 M, b7 G" h
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我2 Y# J$ k! r+ t$ _) k8 o4 n
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
/ O) b4 E4 q- e! F7 r4 j->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
1 D' O( v" E$ `7 a' s- o如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
4 K2 [2 m9 V4 l# I进行操作了。这个问题有待大家来完善了。7 w6 o2 a/ A7 ~4 |
0 w) s- U4 S( R# k6 H$ T
/ n9 S  F+ V9 @0 ?4 X0 y
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出' m+ e/ s; B: e1 w: |) V
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的' L) |5 N+ [5 F0 \& H! a
分析做个记录而已。我更愿意把它看做是一段注释。8 ~$ \' i* B1 ~9 ^  L
2 I; i; x3 I7 A; T6 J; s) w; g
最后在此代码中要
  J% _; v4 X, f- s% V2 j/ J3 X
/ U) _, x& S& o' B* ^感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。( P1 ^: O4 \0 |5 n1 ?- [

' c7 \2 ]( `  t1 V感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
# ^: c2 R" B/ ^1 L5 W$ J8 ~- L- s: {7 X
感谢:齐佳佳,过节请我吃好吃的。
5 b' q3 u: A, |* y2 _
3 _' e$ R  x4 K2 D4 ]( ?. {! h, q& ]% w$ i1 x" i5 f6 v# R: n
******************************************************************/, [, T) V" r1 L+ n
1 t' P8 \. j7 P, N% V  L
, A) m5 e- h9 |
/*****************************************************************
0 [) J: C' ]7 s$ n 文件名        : WssLockKey.c- U9 G; D# E) D' c; f
描述          : 键盘过滤驱动. N% A, d2 k2 h6 O! r% k1 A
作者          : sinister3 k" u  @  q" Q9 \
最后修改日期  : 2007-02-260 V" D0 h& v, g3 @3 P7 A$ U4 r
*****************************************************************/
$ z& S/ E. ~* u8 I
) _+ E  M7 f) _" P. _
* k6 |. }/ }0 H- P. n& c#include "WssLockKey.h"
, J  E$ c# L& @  M
1 P8 C- L6 v; I2 `) w/ uNTSTATUS
8 _, y5 B: _4 E: PDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,; e0 e8 ~; ?5 ~8 @5 M
             IN PUNICODE_STRING RegistryPath )) I& J: \/ T6 |4 r2 I9 e
{
' T& Y; G# c8 Z! G( @# e' }  UNICODE_STRING KeyDeviceName;
. {! I/ N- A( X# `  PDRIVER_OBJECT KeyDriver; 2 l. `0 `/ b' [" Q1 D" T( c
  PDEVICE_OBJECT UsbDeviceObject;' E/ j% B; ~; h; {. X* @  X
  NTSTATUS ntStatus;
" ~' @6 f" ?( b6 M# o  ULONG i; ; b0 |0 D* A; L! V

$ h) I# y! t+ D- V4 `! b  //6 Y# l7 D5 m+ X8 U
  // 保存设备名,调试使用6 g' i" a8 ^1 T" a- _, R& `
  //) {6 F! U: C9 N0 s: e# `
  WCHAR szDeviceName[MAXLEN + MAXLEN] =. l+ O/ X0 Q) _+ J9 R
  {
" f5 ?! O/ s6 a  @    0
, ~- M# l& I8 o  };
& }5 H0 ~0 o2 n+ _% V9 L% n( i# ~+ n
  KeyDriverObject->DriverUnload = KeyDriverUnload;
* O5 U, N: L& g3 d, X1 c& n8 k. v3 v: H( N" |/ c
  //7 s* o% ^  Y4 O
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
3 z! u4 }( S% J  //2 P5 @$ h! P& ]+ t, L
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
& {+ t$ ^* Z( a/ m  A  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
0 _7 `7 L. p$ _6 R4 _! G" e. B" q, a  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
) i( Q0 \* d' n/ f$ N  // USB 键盘设备来进行挂接4 {' \2 S  X! U& q& `4 W
  //
  n8 d4 y3 o4 k) m. \' e! c  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
8 t5 K1 U0 ?% Z. C; }& N1 z8 Q! _  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
, L  N. T& J* I, h% R  {+ j9 g5 y& e) b5 R; j9 S
    //
2 \7 ^9 N  b& R" ~, i" y6 _- H    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名% o& i! W% @0 m) S, E" R( ~" l8 u! ?, ~
    // 所以这里打印为空/ \* S/ I$ @2 c. \) y9 n/ }0 u2 b
    //
# q& O- P0 d" N( P; \    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD7 M9 \* q6 O$ s5 F5 |
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );; y) g% l: c0 U4 \
! U0 c2 }3 g8 H. @
    //
) ]8 V; p' ?* e$ }1 A, I) B    // 挂接 USB 键盘设备
. t9 V  X' m3 ^, f    //
9 z9 u% f, s1 `4 x# P: V* A    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
% M/ K- Y8 C5 m* P# l    if ( !NT_SUCCESS( ntStatus ) )
: ?, n- Q) o5 n2 b) {, R    {
9 @4 q, I3 H7 A$ l7 T( K      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
) ?/ }+ J, o+ [" u% n/ h      return STATUS_INSUFFICIENT_RESOURCES;: l' ?9 `1 o7 w
    }
/ T- \* _) p) N4 r$ \  }
; B: `; x. ^% b- g8 ~5 b  else% W8 T7 E/ V% {1 I
  {
; S( C2 I! e) X7 o3 d! I    //
3 q4 N& g  Z8 U9 m    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
, Z0 X" K8 p+ T- W& v2 F  F    //
+ B7 V: w8 [9 H3 ?0 H& E3 g6 F    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 2 W' a+ @/ k4 C& Q" n* o( l( }

9 i# Q  A# q, K& w: \* \0 S    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,  U9 L8 O4 e" b
                                        KeyDriverObject,
- K5 O( P4 n, _                                        &KeyDriver );& J  B5 `+ i7 G, n- W3 x6 L1 e
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )8 V5 h; i  @! D9 F
    {8 I+ W/ z7 f9 D' k4 g  ?+ g
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );9 a* T: m8 x3 Z
      return STATUS_INSUFFICIENT_RESOURCES;
/ Q  M' V+ p+ |6 |    }% e, P. ~0 B* U: d  H9 J
  }. [) g$ O$ A2 n# J
9 x: I7 h: m9 b+ p" G+ L) w
  //
) T3 Z! F2 W+ J1 g8 \1 D  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
. N) M, B$ H3 m7 Z4 e& S& G  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程7 E( |, B' n6 y2 e1 k9 t' X# X; R- g& K
  //
: I8 k. n' P; ~2 Q  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
& h0 ~4 E1 ~7 ?' N) Q+ w
  ]% p. e# U- p6 l, e  B# e- z: z+ t  return STATUS_SUCCESS;, c& S& Y. P7 M
} 6 `- g% I2 P" n) L4 c" j+ T

* s8 R0 N( D1 g2 Z$ E/////////////////////////////////////////////////////////////////2 s8 _) B3 E: y7 t
// 函数类型 : 系统函数
3 b9 l7 [% a2 X5 H9 u; {7 b! O6 |// 函数模块 : 键盘过滤模块. U0 ^: R- X) U4 e. J4 s
////////////////////////////////////////////////////////////////6 {+ y% P1 O* c
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
* {9 L$ D1 \, |2 Z% B& X: k//        卸载键盘过滤驱动. L! G  q$ `" N( k1 N
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
+ N- ^1 l3 {1 s//        则需要等待用户按键,以后有待完善
- p$ g' c* H9 e; q' |: }; n5 l/////////////////////////////////////////////////////////////////1 r6 E, K# V! I
// 作者 : sinister4 P  ]* |0 J0 D# k4 }
// 发布版本 : 1.00.00
% x! N8 S! n! m3 X9 F4 S// 发布日期 : 2005.12.27
( u8 F. @8 L, }( x* m/////////////////////////////////////////////////////////////////2 ?  j! ^- W- H' O
// 重   大   修   改   历   史
0 L; S7 E  J- d. \$ k////////////////////////////////////////////////////////////////
. U) q4 j3 Y5 G9 Z5 ?$ Q( ?// 修改者 :: g7 F- `! }4 c: W, A; n$ ^7 x! f
// 修改日期 :# t9 C, K% @9 v' i
// 修改内容 :# `5 `, ^! b, w" I% `' v! }; r. g
/////////////////////////////////////////////////////////////////2 ?) G; b+ W; T9 c2 Z% A: s

. E- g8 ~: U6 L& J) AVOID1 a: H1 N4 k5 L# `) D" e, q
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
. z# x7 X! Q" S0 ^% y3 X1 e{  l3 o7 {8 ]7 C! F1 r* q
  PDEVICE_OBJECT KeyFilterDevice ;      8 S: Q  O8 D. T- m3 A
  PDEVICE_OBJECT KeyDevice ;
* I& x; o5 m  _) ?* W6 f8 {. n  PDEVICE_EXTENSION KeyExtension;
. ?) _2 c1 ]9 U1 y  PIRP Irp;  q- E5 ?" y5 r% G  V
  NTSTATUS ntStatus;4 b* y8 b  U3 ~- q+ P6 ^
) u9 D9 `1 Z: J7 O+ @, l
  KeyFilterDevice = KeyDriver->DeviceObject;
: L0 _8 d) U9 d  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; ) I% `  \+ E& |: _7 e
  KeyDevice = KeyExtension->TargetDevice;
# ]9 k# R) d8 R1 }. p; _
' r& v* ?0 n% x# \6 A  H- A$ t  IoDetachDevice( KeyDevice );
! h! L; E9 B7 y, {) K3 q
- S. q% }' Q' j4 Z& a2 d: ]  //! T9 _7 `, p- g* C4 \
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP+ f4 K) ?. K0 x) D! I) I
  //
7 x' u2 j( b, m1 Q# v  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
6 C: B9 Q% K% Z- l7 n  {( k9 g; s# @6 i* F
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )2 }5 r  V; O$ X
    {3 S/ g, s) Y3 S8 z
      //% r% m% x1 m) Y# `7 Z% Y
      // 成功则直接退出删除键盘过滤设备
* U' j# M; h" V5 B      //, O( p1 w7 u4 j6 L: }
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
8 K) `, M6 L. [2 Q* Y      goto __End;* @, r* L3 s: F5 I: y& S% A
    }0 b% _5 Q9 w. e/ u1 h
  }
9 }: s# a$ S. m, q3 @) N" V! ?
' b1 \: z8 Y% i# ^9 v  //! f* C7 u! i" R3 W1 f2 e9 Y
  // 如果取消失败,则一直等待按键, y- K# q/ b5 v! L
  //
: S, U) T+ s& R: h" \  while ( KeyExtension->IrpsInProgress > 0 )
! H1 ~2 ?4 W6 E* [( ?/ e! G  {
# S1 H4 F9 i: @) `: a" A' n7 A    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );# `& G, b) |5 E! N1 r% o% Z! N
  }% \. N# P8 G" |6 k6 j, P

& C2 G7 ~* Z6 j7 L! ?  __End:
) [* f+ f& m4 I, @8 x4 H( p  IoDeleteDevice( KeyFilterDevice );
# k( {( y- g8 W- w0 J  t2 J0 f) e  W# S
! F4 J8 @- n. v* N! t* X  return ;
" G3 R! y& x' j}
  K9 B$ l% l, Z; b" ~4 A9 m/ u5 ?- W- Q0 X1 P! |
/////////////////////////////////////////////////////////////////3 W0 }& T! g1 f
// 函数类型 : 自定义工具函数8 _* A1 q1 |+ t
// 函数模块 : 键盘过滤模块
- Q/ C* F  q: I5 [# }' t/////////////////////////////////////////////////////////////////
3 S! N" X: U7 h* P& q// 功能 : 取消 IRP 操作
' n$ `# @; x& i! f5 }8 J5 B// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
7 O& V2 {, M8 Z9 U% i//        使用此方法来取消 IRP3 S9 [. m- Y) Z/ m
/////////////////////////////////////////////////////////////////7 P8 U, Y4 h: |! Q2 _
// 作者 : sinister: C* _% A' q3 j
// 发布版本 : 1.00.00
2 l  q' W! P( R0 p& }$ s& B// 发布日期 : 2007.02.20) s$ l! J% W2 V; {% g
/////////////////////////////////////////////////////////////////
9 t: m& p8 {+ f" N  n+ I9 y// 重   大   修   改   历   史
. Q( M: T& v5 U1 \8 _. h7 w/////////////////////////////////////////////////////////////////2 t; k) D9 Y+ z0 L/ W
// 修改者 :
( \1 y. d5 O- b3 _* y7 t// 修改日期 : 9 \: Y  L, I7 H4 E
// 修改内容 : 9 R9 `) X7 ~2 Z+ |, O- G2 y5 i
/////////////////////////////////////////////////////////////////
- e: ~$ |+ |: b$ ^! y
6 g- a. U6 ^7 }$ SBOOLEAN6 l7 ]3 m1 I8 `* X* u! z9 |- }; z
CancelKeyboardIrp( IN PIRP Irp )/ s. R; q1 i2 \! P* Z4 h
{! n- c0 \6 q; m9 g
  if ( Irp == NULL )
1 Z+ v" g/ v8 b8 ~: ~* ~) D  {' c6 ]  Y  W7 C2 T2 F4 M+ G
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );8 ]6 A% O: S1 {! L0 E
    return FALSE;
. U; u$ ?) k6 b' c) f& ?  }; X. M% W" J/ a; o- o
) w! s" o. m1 f' [3 r' V
# w& N. ?3 S7 B& H4 C
  //
5 J3 p" V9 H7 t  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,: I6 o% Y, I. I
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
& E& A8 f( Y) v9 [7 K$ f  R  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占9 L' N& b( n% f2 [( X
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
; {) a$ c9 A$ c( Y2 i  //$ k0 U8 I/ S$ s! v: Z

/ M+ n7 `. v# i/ [/ {( W/ C  //% o, j/ ^- }1 g
  // 如果正在取消或没有取消例程则直接返回 FALSE9 t' a, s/ T, ]* p4 J& S: U
  //+ K. K8 z! y7 w3 C; y% `& Y
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
$ B; N- M/ K7 X% G- \+ H  {# V4 i) X# a! @$ c
    DbgPrint( "Can't Cancel the irp\n" );+ V2 N6 M: e  g5 f$ r. A
    return FALSE;
% J& V% h7 s  a( S. S  }  d% t/ T6 o9 h* e  s2 t  q; _
0 }# L& y: J& _0 z, }9 q4 I* X
  if ( FALSE == IoCancelIrp( Irp ) )
: g8 C8 X/ x2 ?0 [7 ~  {
+ E: V2 {. s5 T    DbgPrint( "IoCancelIrp() to failed\n" );) X" J% [! P! R3 b7 Q" u# `% M# }
    return FALSE;5 F: X* B) H4 K
  }( G) A/ q2 f* @' B* B
) D7 H- Q" W% m& T6 @; m- k/ a% _
  //
" U. k6 m. u; H- D  // 取消后重设此例程为空6 F! E2 u4 J/ s* W  y: g
  //# C) x: Z8 y9 a* F8 s0 J
  IoSetCancelRoutine( Irp, NULL );
9 S  o4 P7 o1 \
8 z# M% v  k+ ]6 l9 Y" Y  return TRUE;
) B5 Q- `$ t/ a. e; l; }  Y6 @}: l! b4 V. G" m
+ `  v! A& C/ X% b# n) u
/////////////////////////////////////////////////////////////////9 P0 g0 k1 X. Y+ I* z% k1 Q
// 函数类型 : 自定义工具函数6 E8 D1 L+ z1 c  x! X
// 函数模块 : 设备栈信息模块  g7 x# F8 g0 \9 i  F
/////////////////////////////////////////////////////////////////' G& E4 r* {" g
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘8 U; X4 u7 {; C) C2 ^
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
  c* G) g6 n/ ^6 q; n% q) ~// 注意 :
+ J* r  x5 `8 h! Q' J/////////////////////////////////////////////////////////////////) B; m$ R# u! J( x" K( ~
// 作者 : sinister
' }8 |) M1 J% l( F/ [1 J// 发布版本 : 1.00.002 z1 N( V# o/ m) A
// 发布日期 : 2005.06.02
* I) U, z' A" P5 z/////////////////////////////////////////////////////////////////& j3 C8 h# n  a% V* T4 ?
// 重   大   修   改   历   史
, U8 f1 G7 w* X( c7 ?/////////////////////////////////////////////////////////////////
: x/ m7 _% `) X. y' W  I7 M2 F8 o$ y// 修改者 : sinister
0 N  e4 ?. U0 t6 Y0 h// 修改日期 : 2007.2.12. r2 O7 m( W( s. Y
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
( _, L/ A. E% g/////////////////////////////////////////////////////////////////7 x5 X/ H* o& P7 V: x3 [/ ~
" ]- j6 z, p; B2 O& a
BOOLEAN
  C( }# s5 _! y3 A. yGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )6 Z1 U$ d" k# S0 Y
{2 R8 e/ W6 f7 b
  PDEVICE_OBJECT DeviceObject;+ c& C1 O4 V/ @# H/ c; N* X% A
  BOOLEAN bFound = FALSE;1 r: N  L. R. u: i5 }- H7 |
" m/ @2 M, V9 `4 x* n9 S" L  t
  if ( DevObj == NULL )/ E- f0 u! K8 O& @
  {7 ^' f! I: {* \3 {( r4 o( b8 ^
    DbgPrint( "DevObj is NULL!\n" );. N; g4 i! O4 J9 q: e1 {, `; K5 _
    return FALSE;
6 d* M# |8 D# S+ `  d% z; K$ O6 n( Y  }
5 i/ b2 L/ l# x6 i& |7 f. D! Q
0 w: N. |/ \. k& w  DeviceObject = DevObj->AttachedDevice;
  ]+ N1 p$ a( }# Q: M- M8 U; F! y: K* ]. `' x
  while ( DeviceObject )0 R% T  q  i) l! \3 T4 I
  {
( I2 Z, b# n6 d/ ]    //! w; z! b" j% \3 H% X  b8 g- V5 T
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但: p6 h" C# v) g
    // 有一次足够了。这算是经验之谈, f4 K: f9 g$ ?& y
    //' I+ u9 i* s9 x  U9 P+ R
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )4 a+ v% B8 _: `0 }0 c0 w
    {" g6 [9 V0 _6 f- q4 d: a% B8 ^! W
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
9 S+ m/ M3 H0 n, Y) F" b7 E% D: s                DeviceObject->DriverObject->DriverName.Buffer,
4 n& q3 T7 q! q                DeviceObject->DriverObject,: T% r8 c0 O: A
                DeviceObject );
! W+ b2 Q2 ~) S7 {. L- k! W# m# T& d" r- _' [6 f
      //! X/ U0 u: f2 F0 E* H! n" m
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了" S3 j; i7 R5 s$ S/ F0 ~" h8 {, q
      //
; ?" k5 i5 a: Q4 w      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
3 K& A' d/ g' @3 r                      KDBDEVICENAME,, s0 I/ k5 D2 Z6 d- ^
                      wcslen( KDBDEVICENAME ) ) == 0 )+ n7 R. x0 z" [8 K. K" d
      {
+ E$ j# h' J4 s5 {/ _5 o        DbgPrint( "Found kbdhid Device\n" );5 w9 v4 i3 a4 u$ Y* p8 @4 D  a
        bFound = TRUE;6 N! m) t# K. Y9 s/ _4 D0 h1 f0 ^: Y
        break;' y' I. c9 l+ l+ k8 X* V, {$ q3 {5 G
      }+ G3 b) b0 M; w
    }/ d; V% `% L3 W$ ~

% w* P$ X5 T9 a    DeviceObject = DeviceObject->AttachedDevice;
0 D4 x9 L+ l% J. j* m  Y  }! a# b" [* v( p; Y$ p" v

* E5 j- R7 j+ {7 e( `  g  return bFound;
0 Q5 q) Z. y; H& U. H+ B3 _% U% ?}
8 _5 [" r* g+ M4 T+ ?: l3 H  \8 k2 ?5 \& M4 i& K- y: I
/////////////////////////////////////////////////////////////////
, l* w' F) k! Y$ y; X* o// 函数类型 : 自定义工具函数: \2 U) s3 I8 k2 f; G
// 函数模块 : 设备栈信息模块
8 c. N" v: B; [5 k2 q$ v6 k4 E/////////////////////////////////////////////////////////////////
/ u& F9 Z5 W' r. b# z$ f, R1 v// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
7 @4 j- h; m$ ~$ @// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
8 t- g7 b' S( {- ?/////////////////////////////////////////////////////////////////
5 f$ j( G4 _# w  h' G- n4 i// 作者 : sinister/ J. @' ]! H4 @, {
// 发布版本 : 1.00.00
/ p) g3 p8 `# m3 o! d7 p& T// 发布日期 : 2006.05.02+ u5 }, K3 c9 A7 ^0 N+ F
/////////////////////////////////////////////////////////////////
0 w8 _) E: `) |' k! F// 重   大   修   改   历   史
. J. H/ q% F6 i8 Y% \% A/////////////////////////////////////////////////////////////////. V% V; r$ @; g5 h' O' |9 t2 w
// 修改者 : sinister2 s* I5 y' n# m) g
// 修改日期 : 2007.2.12; u9 P1 ^# h! A: Z8 |
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用1 `/ ], C5 }6 Z( a$ w
/////////////////////////////////////////////////////////////////3 ^. M" A* M) N7 V+ E1 x, h% T

2 m1 [" o! W: o; Y7 X% l" o( E5 bVOID3 l; m( }" A2 J! ]7 z4 \' I8 e
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
: f6 |3 i5 M$ y0 O8 s- c/ T* r{
2 _: _3 c5 U: I0 Y* f' i  POBJECT_HEADER ObjectHeader;
' `) \: t) b3 v1 S6 L, i  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
, D/ n; }+ C0 A5 d/ B0 G4 q4 L6 z7 ?
2 K" p6 g2 J5 b% T) h1 D  if ( DevObj == NULL )# U' \3 X7 l7 O' ^
  {
! N2 K) S8 A! \- s0 G" t" Q    DbgPrint( "DevObj is NULL!\n" );
7 {5 Y6 U( H- F( v" H    return;
- z: A: \- U1 T- |  G  }$ g' P8 n" V- a5 q

6 [- w2 A5 ^* C5 ?) E( x  //
0 m% s) I( N) i( Z( G& F1 U: C6 M  // 得到对象头3 C+ H/ z+ a. l4 X: a
  //: P- F' K/ F6 C1 Z; r8 e
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
" ^! T+ W5 ^. ]# o. V/ P5 B3 _
  if ( ObjectHeader )4 e4 R( M1 P& E$ v: k, d
  {1 p" U4 d+ @0 M2 L* D& c
    //" i# ^5 _+ w( R# _
    // 查询设备名称并打印
2 T2 f7 R% K4 s  @$ z    //! U  [0 Q) P# V$ _2 `& n
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
5 r( x# P! E* |6 }
1 ]; I0 I, e6 [+ ?/ y4 @    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
; N& H# i! ]& g! s* f    {0 Y) O$ O1 Z! X; i$ H
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
% P$ _/ }7 q0 _/ `6 g0 ]2 s# s                ObjectNameInfo->Name.Buffer,
/ z# \0 J/ p- R2 \: ^" d                DevObj );
' [5 r2 ]1 q/ d+ p  r7 }7 I0 ], O3 k  a8 f( g  f' `' ^
      //
; N% V4 {) h, y* J  p: R      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示1 A+ }- \. m/ p$ g. F
      // 用,没有实际的功能用途( h9 m% N: r5 W+ V0 [
      //3 Y. h. F! x: P
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );- {. j9 l# h5 S( P) _

& S' {/ y) s; a, s. V; ]0 H      wcsncpy( szUsbDeviceName,
% }) h: K' \7 h( c1 e+ ]               ObjectNameInfo->Name.Buffer,
9 P3 Z) O" e! o9 C+ Y3 a7 ?               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
( S" y6 E1 S  F6 f6 m& ~    }6 u% J( ^9 k- P( y' n$ ~
5 z3 D# w8 g0 Y8 u" S, x# v6 \
    //! ]( D* K! E# [
    // 对于没有名称的设备,则打印 NULL, J# j9 z: q/ G9 a0 l' O
    //
1 @! w/ z+ C+ B% S    else if ( DevObj->DriverObject )9 J9 E4 h: G% f
    {3 M  w% D% F- R. I
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
% o( r( h9 M  S8 j. w# R                DevObj->DriverObject->DriverName.Buffer,
% R6 A% J, v+ V3 J1 @! K- y0 j                L"NULL",( I6 o9 c" G) ]
                DevObj->DriverObject,4 a( M; c, N2 U3 G
                DevObj );* i% v) w( W" ~7 s# ^3 z9 F
    }
0 Z0 O, m3 t  P0 N7 T  }
& x& q6 E4 p$ B}' K6 Y. [4 ^  @5 h
9 Q) ^- Y4 [# R% R
/////////////////////////////////////////////////////////////////, f( g* V% U! F4 Z2 F
// 函数类型 : 自定义工具函数
; j& G9 d1 Z" p3 K// 函数模块 : 键盘过滤模块+ z6 r6 N7 G* |, {$ l
/////////////////////////////////////////////////////////////////
% T' n# {5 H- D8 d! K7 W& z// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
; @: H* @- T9 |& ]) C/ i1 a//        对象,过滤出 USB 键盘设备,将其设备对象返回
! B2 R) ~3 ?( k( b5 i8 j// 注意 : 3 J3 d6 I8 A) U+ d
/////////////////////////////////////////////////////////////////  b  ^. j8 K) W& p6 P4 L
// 作者 : sinister' _6 L: G; L) E& m2 R, f1 E+ z
// 发布版本 : 1.00.00
6 p- g( R9 v8 J# H/ _" w4 A! _+ ~4 d( R// 发布日期 : 2007.02.13
. ?' y4 s9 Y$ k1 U9 [7 D/////////////////////////////////////////////////////////////////7 F; ^0 J/ F9 ~
// 重   大   修   改   历   史
/ {, y- S+ G+ U/ B) b/////////////////////////////////////////////////////////////////
3 {" K5 ?+ X& w( x  w& F// 修改者 :
9 Z2 F3 ?/ [0 `. w* _, i) {// 修改日期 :
# S3 [. O( c! S+ o: l4 Y5 j/ H& A// 修改内容 :
9 q. L) m$ j4 r4 t7 A9 D3 O/////////////////////////////////////////////////////////////////
/ i  t9 m5 @. m  z/ h. M: m9 n( I/ R' q7 r+ t; ^; C- i8 P; E
NTSTATUS
4 o8 `+ t! \9 kGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
2 }+ l5 u' \% F/ l. R" b1 o% @{3 S' Y! W& l7 F6 e& f1 c
  UNICODE_STRING DriverName;$ q7 N! g3 t$ s/ {9 m+ H
  PDRIVER_OBJECT DriverObject = NULL;
, I8 p3 n3 w" o4 X# v  PDEVICE_OBJECT DeviceObject = NULL;
" |* A8 F3 i! H% A" @  BOOLEAN bFound = FALSE;
( f) r2 v1 ~1 J, [5 E, _6 m
+ u! m9 L0 H; k- M' w% x  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );8 k0 e% O0 Q9 M& M. l; C5 M
9 O& ^$ \7 Q) u: G9 n& h
  ObReferenceObjectByName( &DriverName,' Z/ ?1 }' T9 b& D; L
                           OBJ_CASE_INSENSITIVE,  G/ q+ n; b) [4 B% ~9 W- x
                           NULL,
! l$ B+ [$ E* ^! b; E$ B8 x                           0,. D: L  W8 @; `" l# B
                           ( POBJECT_TYPE ) IoDriverObjectType,4 i1 K  A: u$ ^2 I2 C$ L; o: ]" j) W$ @
                           KernelMode,
; f! T* ^9 |2 |5 S+ h  ?4 j                           NULL,, F2 x$ `0 H. m# y1 C
                           &DriverObject );
' D, c, A% L- e% g+ X2 Z' F, Q- }4 P9 q. B
  if ( DriverObject == NULL )  L: H  H6 l3 |& h. U
  {( [& Q: }% U- V/ Q  @
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );7 P( r6 i. l& z8 j7 }. Z
    return STATUS_UNSUCCESSFUL;
+ k* H4 e3 N* p" U8 r  }1 }6 b9 l: x7 b# b9 P9 y8 ?9 f: ~9 b
8 w  f$ O- _, P& a) O. G, E7 }
  DeviceObject = DriverObject->DeviceObject;$ s8 Z# T- I7 m# d) u
8 B' ~7 t2 x6 o% k+ [$ G3 V
  while ( DeviceObject )% v* k5 C9 Z" s" {7 s6 _
  {
/ Y( `# v. n$ s. ~    GetDeviceObjectInfo( DeviceObject );
( z' l+ J. _( w: r' I  b
7 `! M% b5 @5 h" ~9 P8 v0 k8 ~) o    if ( DeviceObject->AttachedDevice )/ O0 V$ f+ h7 o# a% i
    {
) ^# ]* T6 X) M% X% x      //* b" H) ?% E; b5 c
      // 查找 USB 键盘设备
9 v- J3 M/ C' q& V% z) H      //& n+ }) D; e* D. N. Y$ V6 |: s4 _
      if ( GetAttachedDeviceInfo( DeviceObject ) )4 ~/ H4 r% G6 P
      {
6 O+ j8 a  I8 [/ L" q" _; e) \: V. F1 s        bFound = TRUE;
2 p. V8 N$ J2 V+ j+ o- [        goto __End;
! z: j: p0 q0 G+ p      }; A0 B% ~2 B! N8 K/ ?5 }$ N
    }
6 D4 D4 U# K2 D' \+ ]& z  C  [: Y, b* x- O
    DeviceObject = DeviceObject->NextDevice;
! K( b+ Z$ g/ k8 L  }- q9 }4 C* C: f
& Q) a( a) |, d9 l: x
  __End:2 I5 c, B  [/ R- J0 ~( V4 Y# n

* ^% a* S; ]  c/ x7 }  H  if ( bFound )
( K1 H# M; [. v3 g  }" e) c  {- P% d, o6 k8 w1 x, `: J
    //
- T5 _3 E: r% }1 p: T' \    // 找到则返回 USB 键盘设备对象" V4 @* |7 F) f+ T7 e
    //
' S. F2 E8 F4 ^! `- R; R9 @2 V/ M# G    *UsbDeviceObject = DeviceObject;
" Z7 o4 T0 t0 i8 x5 s, ~! b  }
0 H; k& L' V& Y8 m- S  else
7 e; F; ]; I* ?  O  {
7 W4 [( i* F+ [9 \5 L: v    *UsbDeviceObject = NULL;! X: H  k, z, X: ^3 x, w
  }
' N( l5 f  c4 @) W/ {# ~0 ?# ~% K9 Y
1 F( u0 Y9 R6 T$ n  return STATUS_SUCCESS;( f" ]6 h* \( |$ d' k+ [/ U1 p
}; |, b* e: w! k% l
! L' L+ w" f6 t: o
/////////////////////////////////////////////////////////////////2 W6 i3 N; g% s
// 函数类型 : 自定义工具函数. l" \, d! X6 W5 h1 S* @
// 函数模块 : 键盘过滤模块
& u5 _& a/ \/ d+ I0 X0 O////////////////////////////////////////////////////////////////
# t8 B9 k' ^5 L$ t8 K6 ~) H  o// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关, \$ P* V' @/ h+ Y) f- z: E
//        信息,返回附加后的驱动对象. G7 A- U- i  Y0 e& q5 _
// 注意 : 此函数仅挂接 USB 键盘设备/ \4 J8 o+ P/ ^0 i5 @2 [) t- x) p0 f, g+ ?
/////////////////////////////////////////////////////////////////. W, i4 P9 l. O% H
// 作者 : sinister
$ ?% M  P% o  q2 O: p// 发布版本 : 1.00.00
3 e) u& K' J: v8 o// 发布日期 : 2005.12.27' n5 f5 B" O; f2 Z- y% y
/////////////////////////////////////////////////////////////////
' A( [, g% \% O9 Q// 重   大   修   改   历   史# M5 Q# S% L5 L  @) Y9 V3 t% O8 j
////////////////////////////////////////////////////////////////
" T1 M6 g  N- ~# w9 O! O/ }// 修改者 :
  t6 x3 P9 C! g4 S6 K8 d4 s// 修改日期 :
6 q1 f" d; w" q- p7 R8 N/ J6 ]  x// 修改内容 :' z5 B: y1 a+ r" ^- v
////////////////////////////////////////////////////////////////// O; r( v/ e) e6 O! C
) B4 ~3 m& _9 ]9 G1 c
NTSTATUS$ ]$ |3 @( ?0 y! H& h
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,. ]% K$ q0 d1 Z. Y6 p7 a
                         IN PDRIVER_OBJECT  DriverObject )+ J. c2 d  F5 _5 K! _
{- r6 r# Z* V% a# Y; F
  PDEVICE_OBJECT DeviceObject;
' g: V. L& R( E; Q' I! s! k: N# x  PDEVICE_OBJECT TargetDevice; 3 y- @7 E1 e" v6 S
  PDEVICE_EXTENSION DevExt;4 o, O) P/ g% g. O  C7 I3 ~
  NTSTATUS ntStatus;
) w; L. H( P& K* C5 V
9 y2 j! P" |  A$ H( }  //$ `- Z& }: D' n9 J! W4 @8 ^
  // 创建过滤设备对象
( o1 q$ }7 K3 @6 m4 J6 s/ ]  //
7 N& O. ~) a7 a, N3 r  ntStatus = IoCreateDevice( DriverObject,8 b' U7 I% `2 ^  i4 f
                             sizeof( DEVICE_EXTENSION ),) b' r+ V& d9 e4 b0 R6 l: f
                             NULL,9 Y8 G1 d, {- D. U$ h: H8 q" G
                             FILE_DEVICE_UNKNOWN,: e9 y! t7 G/ d8 k7 {
                             0,
0 h# F9 V5 T$ i9 K+ S                             FALSE,$ c1 E* V! N1 ?5 x
                             &DeviceObject ); & {6 l% z6 }3 M; e2 u/ j% \- N& j4 C
9 ~$ _% `: g! e9 U) F9 K
  if ( !NT_SUCCESS( ntStatus ) )& ~4 p( }" k! @# Z
  {
: {! e. Q# b6 c/ Y" t$ e    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );* s3 f- n/ {2 u* T7 m0 O9 a7 G$ G! m
    return ntStatus;( x# \1 I% @) J, X) U
  } % w9 E2 P& K4 P# p. I9 p( E4 I
, v$ C) U# a6 G) J! ^6 i
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;. k3 G( @. u9 h1 d  g& i
; }$ c; y0 k) D2 R
  //
7 {$ D# a; _( J' i3 z# V9 c$ u  // 初始化自旋锁- B8 ]8 ]1 q9 p6 c" N4 s5 v+ V
  //* R6 u1 j! ]. H" W( G8 j
  KeInitializeSpinLock( &DevExt->SpinLock );5 z( |$ q' [. y' a2 e8 |: C2 E. A6 N

) H7 F3 _/ G, D- k) g' \  //0 M* j+ ~' K7 U
  // 初始化 IRP 计数器
& \. F, F" }4 d) m' F' I  c  //
- b" @% _7 L) e5 Z# z  DevExt->IrpsInProgress = 0;
+ {3 c/ {; E: K8 p: S& k9 G* ^2 r: b$ x" b
  //2 \7 ~$ F7 f# N* T) M0 k( j# B
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
, V! O$ v# x, m7 u- f6 |! k! y0 H7 ]  //
1 A6 u8 _* n0 l8 S% @
1 w* L, ]* A9 i7 |  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); ' M! M/ f0 m! L/ C( R/ Q
  if ( !TargetDevice )5 E. c* k3 B/ {7 ]- T
  {
" H2 I  d" T7 {6 C    IoDeleteDevice( DeviceObject ); 4 L- i: v3 H4 P( s
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
0 k& J1 p0 T5 @2 B9 Q    return STATUS_INSUFFICIENT_RESOURCES;) }- F9 o1 W! c8 g2 v
  }
* O* F: F& B  a$ o; u
, @. y5 [1 b7 i0 W  //# j, w, c# U# e" @9 ]  a
  // 保存过滤设备信息
7 u+ v2 O7 \7 r8 m6 ^, L) P" c6 D  //
9 z# z/ v! G  P4 Y  DevExt->DeviceObject = DeviceObject;
4 b; H% A5 a9 n1 p  O4 O' H( G! X  DevExt->TargetDevice = TargetDevice;
# D8 X. Y0 c" s  s2 O( w3 a  ]: I% s+ \% h' O
  //
" `( T2 N* b/ ~) s2 b  // 设置过滤设备相关信息与标志4 J9 Q. l  k- Z: Y5 o/ f; k: ?
  //
9 R' r/ V" M' e5 ^  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
, ~& n" Q9 `# M7 W; o! Y; R0 m  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
! a( N2 J. v5 U" ]# \% z: Y
& _+ P0 F. M( b0 C- i) p6 @; M2 c  q  ^+ p  w; o; o
  return STATUS_SUCCESS;, \1 A5 m+ [1 I* `6 O1 E
}
0 J: `; N; B" z# X3 S* N: k# u7 h1 _5 P) b5 |8 ~
/////////////////////////////////////////////////////////////////
/ m; `. ~0 i7 y% ?; B% W// 函数类型 : 自定义工具函数; H/ ~% ^' P9 O5 W4 Y5 `
// 函数模块 : 键盘过滤模块
& T) }9 B( y, P////////////////////////////////////////////////////////////////
* l2 |1 ~% b& b' V7 Z. p4 T! _// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关+ A# m0 |2 N" i9 \, c9 k
//        信息,返回附加后的驱动对象
8 E, o  ^% v$ p// 注意 : 此函数仅挂接 PS/2 键盘设备
  s! B1 F. X! u/////////////////////////////////////////////////////////////////9 e: s. v! w( [1 p$ D7 o- i( \  i
// 作者 : sinister" v/ J! T2 q8 X
// 发布版本 : 1.00.008 J1 R; F2 y" b. Z2 R' o# d
// 发布日期 : 2005.12.27
+ e  a, J& @( ^* ~" ]; N. J/////////////////////////////////////////////////////////////////
* V2 s6 d% ^3 V# v// 重   大   修   改   历   史
& a; c2 X( |4 A& u$ t9 H% h////////////////////////////////////////////////////////////////
! f( @) ]) M; ?$ O& v  Q// 修改者 :
8 n( C9 Y+ B" r# c2 A0 h; `// 修改日期 :8 d  R- ^! p& |! B( ]$ `
// 修改内容 :8 s- |. R1 |3 h2 V3 m9 i3 N
/////////////////////////////////////////////////////////////////
3 r; `9 {/ n/ v9 P& ~! ~
2 f& [! P8 E9 QNTSTATUS
; r9 x) Y6 W- G! o* e. ]AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
- c' C1 ?- _2 O2 ]: t+ w9 c                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
0 Y* p) \* |/ y9 b/ z1 Q, b+ o                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
# d8 }1 D1 E- h4 b! O{0 r, j+ `# O2 H# c$ ]6 m
  PDEVICE_OBJECT DeviceObject;
0 p0 J: Z/ q7 ]  PDEVICE_OBJECT FilterDeviceObject;" q: }! Z2 g) x4 x  C; c. ?
  PDEVICE_OBJECT TargetDevice;
, s  p% R- z: @9 N  PFILE_OBJECT FileObject;
; }, v- ^" h: z1 i6 M% p  PDEVICE_EXTENSION DevExt;. [! k& G% s/ V) @$ ]" I' m. f4 c
: g# g) B/ ^1 S% d$ a4 ~: K, w
  NTSTATUS ntStatus;
6 G7 k: W/ k1 {
7 A: l- E: B$ q7 Y9 Q) E1 M  //1 m4 r1 I: M. i# f
  // 根据设备名称找到需要附加的设备对象
7 S' |8 [) W# _$ N' J% K  //
% a3 ^$ s( l4 I" \  ntStatus = IoGetDeviceObjectPointer( DeviceName,
5 O# ]8 R* U+ D; Y                                       FILE_ALL_ACCESS,8 a3 Q& \; }' _1 x% m
                                       &FileObject,5 R2 a$ N) D( h
                                       &DeviceObject );
- Z& m, G: |6 a+ r$ c$ x) i3 U% w, l% I+ y/ v; r5 m# p0 G1 `
  if ( !NT_SUCCESS( ntStatus ) )
9 d0 c1 D( |( Q0 w' Y8 ?  {) @0 v* b) _9 ]7 B! a! o3 F5 |/ ~. \
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
7 M: O4 j7 p3 B" T( z3 {    return ntStatus;
' Q6 ?4 r* B- m  } 3 V5 Q8 W' f6 |9 b8 D& ^
; ^8 S/ j9 ~; o4 c- T5 p
  //( o" x4 ^* `; [7 o
  // 创建过滤设备对象
5 t; G$ y- r1 Y/ m" f  //
2 Y2 s" e/ ^8 n: q" \( O( Z3 [5 y- j  ntStatus = IoCreateDevice( DriverObject,
6 ?! c3 Y3 O+ Q6 n3 X9 y3 t                             sizeof( DEVICE_EXTENSION ),7 Q2 G- y% P' z6 x( Q/ a4 b% j" c
                             NULL,( x: s+ |. v$ ^, @9 J+ J( @
                             FILE_DEVICE_KEYBOARD,/ E: Z' f3 m2 ^$ l+ I" f$ z
                             0,/ t5 |7 }& j+ F, o
                             FALSE,3 y* p& }+ G0 ~
                             &FilterDeviceObject ); 8 \: O* a9 \, a* D
4 x+ P1 K$ \& a
  if ( !NT_SUCCESS( ntStatus ) )
7 Y' X) Q6 k1 I7 [5 u  {
1 y, r8 J: G" i$ z# F    ObDereferenceObject( FileObject );
1 Y( ^. c3 @# T- Z    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );9 Y5 e0 E' g8 H$ R' l& C& ~3 A
    return ntStatus;0 _1 j$ Z" A0 D2 g4 D, ~5 H  R
  }
6 c1 i5 L9 O( n5 e
1 p6 K$ _- p& J  //1 \1 ]4 L) L3 w7 s4 F6 y
  // 得到设备扩展结构,以便下面保存过滤设备信息
( i' b0 L0 N, K% ~  //
: @9 o  ~- b+ t% H4 ^6 u1 g0 h  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;! L) L8 T( ?* s$ P( @# L, V

/ b& s* c4 x# V, E2 H( C& i4 [' r$ g
  //
4 S( I' _! z, P1 c. H8 C3 I: q  // 初始化自旋锁
/ L# g, m  w" @  //: G7 `. v) }4 G, s, b; A) G1 t
  KeInitializeSpinLock( &DevExt->SpinLock );6 V  R* L8 b  U- M; A* ?! l# W
: r  {/ ~/ W' p) W; a6 r
  //. q! I, V4 D" q1 P$ S2 X
  // 初始化 IRP 计数器$ H" Q0 [7 r) w3 P. [+ r
  /// }; K: N* R% q# Y! P- @
  DevExt->IrpsInProgress = 0;# X/ v" r( |* I, S: I

( |  I, H! P. c) H  //1 {/ l+ Q7 [' T! l! [
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
+ p5 P/ B; E2 c! r& v- u$ m5 ~# I7 B  //) |$ R% Z" h7 r% V+ T
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,0 H. _, V, N1 b2 l
                                              DeviceObject ); / s* B$ _8 g$ [* f+ B8 ~
  if ( !TargetDevice )3 x+ P  L$ U$ V2 G( r0 o
  {) Y) q" V# B6 n4 _; M# b* ~2 x& i- E
    ObDereferenceObject( FileObject ); 5 W/ {! V+ F6 m6 K  k' z, e
    IoDeleteDevice( FilterDeviceObject ); % e5 r* {$ U. [
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );2 ]) P7 ?, ]+ n1 g2 ^
    return STATUS_INSUFFICIENT_RESOURCES;
+ V, p/ Q1 P5 J1 Z' K0 `$ q7 o/ U) }  }
( m1 R! X3 i6 x. U  J  i% z7 \. M; E, q! E' z( ~! `
  //: j' |: g- ?" W: I- i
  // 保存过滤设备信息
% X! F1 d/ T& S3 h7 {# t4 I! }  //& f  K/ `0 S" `3 A7 N2 d6 c
  DevExt->DeviceObject = FilterDeviceObject;
9 H; ?* \' K( L2 \: [8 u* ]  DevExt->TargetDevice = TargetDevice;
6 t( z7 b. `6 Y/ p" o2 U! a/ g2 ^  DevExt->pFilterFileObject = FileObject;; l+ R; m9 a6 [: T

6 R; g9 D4 i9 P' A8 S" X5 T* s  //
4 m& K( Y; y! ~& ~/ Z. ~  // 设置过滤设备相关信息与标志9 j4 _: G5 T% }7 ]
  //
: N. ^0 h! g. X4 x6 H  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; " f1 G) l" u2 O# r: k& p& A* l: g
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 5 `  n' @. P7 A0 ^, A: Q0 s
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;9 |; H- \$ L* O
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |# x" `0 F1 N& P8 b0 B5 I* y3 a
                                                         DO_BUFFERED_IO ) ); & D# R$ X  z. i7 y% V

0 O1 R1 J( U# y, a8 b  //
1 h  N" |, o- g2 O4 [  // 返回附加后的驱动对象
5 R) [& m3 |8 h; ]% _  //: h5 e3 W4 v5 b; |" K4 W+ D
  *FilterDriverObject = TargetDevice->DriverObject;
: [/ }& q# C# C5 ?% [$ W
9 X2 ]* h0 l8 p: w5 o4 x  ObDereferenceObject( FileObject );
. |& C& z% r: X. S3 e; }) P, K6 e8 U& |' P5 ]8 c' T' B1 e
  return STATUS_SUCCESS;
# I* i! g  c% w$ _  C9 a# p}3 p2 q4 U$ v+ t  U
4 `, h2 i- u' V
/////////////////////////////////////////////////////////////////
  r) {* p8 T- B- Y// 函数类型 : 自定义工具函数' d+ E: m- O4 U' i+ w
// 函数模块 : 键盘过滤模块+ [  P; s9 p9 C! C+ r
////////////////////////////////////////////////////////////////
3 \  c6 A, n/ g% M, f) `// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
! C2 X% n- S" q8 |$ I. @//        这个 IRP 的完成
, T$ P  U0 g  W/ D( I9 E3 X0 T// 注意 : 2 Y7 j$ C. L9 o2 w; G$ S2 S
/////////////////////////////////////////////////////////////////3 B* T3 C/ Q( o, V& T, ?. F3 m9 {$ r
// 作者 : sinister9 C# o  r4 Q  r& p# s9 p
// 发布版本 : 1.00.004 v* j5 {% V" s, I
// 发布日期 : 2007.2.15# e# t( l) m  ~0 u. ]: w
/////////////////////////////////////////////////////////////////1 F, z* h9 r! a
// 重   大   修   改   历   史
% ?& P7 N" A; o  ~/ Q% W////////////////////////////////////////////////////////////////! Q" u$ b" N6 O. g# b
// 修改者 :
) }; y$ d$ i% G// 修改日期 :
1 j. a( }0 r$ S$ A2 s// 修改内容 :+ u. t  z2 Q4 m' F4 n2 q9 E& S
/////////////////////////////////////////////////////////////////
+ w8 {0 N* j7 V. N  e/ u- q3 v$ T) l; ?  v
NTSTATUS& y! N- c' v( W" G4 x
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )9 e7 k+ V- L# E4 n+ Q
{5 o9 D- F- T4 O* L  L5 w1 c
  NTSTATUS status;
: C4 ^& ~, Y5 E  KIRQL IrqLevel;
$ N% u* S" P! Y
1 `% M8 V1 `! U7 Y5 a" F+ [  PDEVICE_OBJECT pDeviceObject;. @1 T) i9 p/ d  i4 `- R
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
9 I9 f2 }, C( v% {                                   DeviceObject->DeviceExtension;
0 i  M3 R0 A" F' ^$ C8 Z& V' ?% x" E8 Y9 ^7 u3 Y) w8 w
1 \- [: x& p& U! F2 ], K' w% E* v( z
  IoCopyCurrentIrpStackLocationToNext( Irp );4 C% l+ w! U# C9 g

( ^3 b, C: {! T/ C8 W+ k7 T; K  //
( q1 O" d; w, o# i9 s  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
* I1 }7 f* o+ o7 Q. T# o7 P4 o  //
; W& {) B" }$ X9 g, K# Y2 W  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );& D) M- A5 z1 D. L8 {
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
# N2 [, Y! g& H. o  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );) c, a2 {& [/ n) ]

1 ]% i: h2 y, O5 Y3 w  IoSetCompletionRoutine( Irp,
4 z% Q- v2 n1 _                          KeyReadCompletion,/ ~8 G  T7 b' P  A
                          DeviceObject,
; }5 |. V8 Z' x# `# G; J" {                          TRUE,
4 B/ u1 B( k" r  Q6 E                          TRUE,/ {; N5 T  h, W+ v( E( y
                          TRUE );
( K0 b  c. R1 n* _1 D3 E& R' W- N5 v. B- n4 Z
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
& H! F- H' l7 [- c}
$ Z+ R  W1 u- J8 x# R1 U5 W. `: E1 R7 k' X. t9 |& A
////////////////////////////////////////////////////////////////// q! f# o  \) q1 o6 Y2 \
// 函数类型 :系统回调函数
/ a) Q" C" \* P$ ~6 r// 函数模块 : 键盘过滤模块2 N; ~: y' ~& b- L$ i& I
////////////////////////////////////////////////////////////////
& C' g, V, s) F9 j. S  z2 Q& @3 H6 Z// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
# g4 n) z' v. S8 N( S) X// 注意 : ! f9 \2 r) n* r& H; o9 z; P
/////////////////////////////////////////////////////////////////
+ e  B% g5 ]6 m4 t// 作者 : sinister
1 V3 ?5 w7 ?- \. y. y; Q0 v// 发布版本 : 1.00.00
, v  l8 O8 M. \// 发布日期 : 2007.2.12* a5 M. l6 e% Y
/////////////////////////////////////////////////////////////////
. M4 }; V. [$ w, w, j' ?// 重   大   修   改   历   史  W7 h' R, O6 d
////////////////////////////////////////////////////////////////
' f! R9 ~1 }" l3 L  I// 修改者 :
+ m5 o/ r9 P8 s: B// 修改日期 :
  V( P) r6 f% E5 m- `  D) D// 修改内容 :. S' J, q3 Y6 g  g; d
/////////////////////////////////////////////////////////////////; Y+ q) V! [. J2 ?- E

; m9 M- }3 T# m) E6 ]NTSTATUS
; [7 {& P& [4 {# t% TKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,! ^8 Y% b' ?! [- a. b2 x+ E
                   IN PIRP Irp,
5 A/ H  A/ i5 l                   IN PVOID Context )
4 Z4 l5 Z) o8 o{! |. a+ q2 J8 I( b
  PIO_STACK_LOCATION IrpSp;6 W/ p; N) d& _+ k- Z& T
  PKEYBOARD_INPUT_DATA KeyData;
# O$ h: Z- F* b) S! s; H  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
9 [6 u$ |0 }( b) X8 A                                   DeviceObject->DeviceExtension; ; ]: p9 r6 R7 M% |: `& d/ Z
  int numKeys, i;' k' Q/ d  F7 k- }2 k3 s
  KIRQL IrqLevel;2 J/ b9 a& r3 P9 g: d

. B3 K# j+ a/ {* H; l  IrpSp = IoGetCurrentIrpStackLocation( Irp );$ p( {" w2 {# b  X% x. [9 Z# Y( g

- W# e% V0 v  C+ J
9 `4 B* a3 t/ Z6 g3 d  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
$ n3 q' g/ d8 S. \  {
1 ?- v& `4 z, l5 _# l3 n6 i    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );) r' n7 P5 ~' k; x" V( F
    goto __RoutineEnd;$ J4 t6 Q+ r$ [' C5 g2 m
  }
0 p( y2 i( i* }3 s$ Y& x" {. ~0 S' [* o
  //
( E, Z% ]! q! B3 R7 A4 Q& l  // 系统在 SystemBuffer 中保存按键信息
% D3 F2 e- z& ~( ~5 |- P, ]  //- L( t5 v% e' R5 G
  KeyData = Irp->AssociatedIrp.SystemBuffer;
5 ~; h8 S+ b' z* w$ _4 Z* W& D  if ( KeyData == NULL )/ d7 o$ L$ q. G0 ^/ X$ W
  {2 B) X! T, W* e) u9 L
    DbgPrint( "KeyData is NULL\n" );
4 x8 T& |. P6 k6 e) D$ e    goto __RoutineEnd;
& q) X  A+ }* M) r4 U  }
/ M" Q% G+ g! u* ?6 M6 R5 r* u% n" a1 D8 a0 ]4 q
  //
/ }4 ?$ {+ l# r. @. r3 t! h  // 得到按键数/ W, o9 ]+ x" m' b9 [
  //
1 d$ [, ]  V" K3 U! x2 N  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );4 R/ L2 p" A$ X. F1 l- g. H
  if ( numKeys < 0 )" J5 S- H1 J, J! ]& Z' A, W4 k
  {6 \( x$ W8 b, u2 i+ A  P, a
    DbgPrint( "numKeys less zero\n" );
6 Y  L) A$ b6 J3 I    goto __RoutineEnd;& [8 m. m+ a/ L$ n
  }
  B# T. Q" H9 i& g) ?5 ?4 V, s* R, |& Z: z8 x
  //
; R" z' r- [9 E9 p# a. ~  // 使用 0 无效扫描码替换,屏蔽所有按键
" i* ^( V" W+ e8 f) k6 ?  //
5 _* f7 U  f! ~3 w+ |  for ( i = 0; i < numKeys; i++ )
" q* @+ u/ Z5 A( E: K& P' q  {
; y, f# m/ |/ l5 _9 O    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
1 [! K2 f" w! l4 I  h    KeyData[i].MakeCode = 0x00;0 L+ e: M  V. t0 q) V
  }
  R7 E6 S3 K3 j* b
9 W7 I" \/ `8 O6 g& F! B% I  C; ^7 z
  __RoutineEnd : % o2 h. F  h' i
. e7 }- A5 O" }/ h6 \
  if ( Irp->PendingReturned )
' B3 B& a4 b9 w8 C6 n  {
4 J+ K. J0 x9 u7 N) n3 Q) g% y    IoMarkIrpPending( Irp );
  E+ H5 V0 k3 M  }
2 N; }7 S1 S& X# Q, F
8 F; A1 |4 a; `8 S" R  k  //
& T# v: i1 p7 {; F+ e$ {1 K  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁+ e6 q/ S2 n; B
  //' \0 i. D; `8 ?* ^1 y
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );: D7 C: v9 z7 D
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
; S& K  x3 w% k# J$ O' ^  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );/ y1 b  Y' B- B8 C
) X) d& T) j" C
  return Irp->IoStatus.Status ;7 x  }+ N" ^9 n
} & v0 j1 d) e8 e3 ?
8 h& @/ ^4 K2 Q5 m- C
$ Q6 l) h/ j; u6 v4 }
/*****************************************************************
) j/ e. d6 c5 Q3 W7 g 文件名        : WssLockKey.h* s) P: ^  X! _+ N8 S9 ?7 T) u
描述          : 键盘过滤驱动
6 f4 A% r. |4 F$ J- P  D 作者          : sinister
9 g6 z9 [1 X. r- k+ \* [ 最后修改日期  : 2007-02-26) h" D8 ^) z; \* o/ L: ^
*****************************************************************/
( I  [: T$ O; s; |4 o/ G; }: k9 R5 I/ G/ h4 r* j. O& P
#ifndef __WSS_LOCKKEY_H_
. |6 ?+ {/ r% L% G2 \# \#define __WSS_LOCKKEY_H_- h# O0 w) B) K
7 U& O0 t9 q& Y+ Z. S& J# G
#include "ntddk.h"2 U$ x- F' I! S  I% b
#include "ntddkbd.h"% U2 x: c+ Z. a% `# C& Z
#include "string.h"$ D( \4 v+ z, x" c2 C2 l0 r
#include
6 X/ _( Z( x5 ~% J& f; M6 k' i" c7 r# l1 s5 _4 k; R! ~
#define MAXLEN 2562 g: x7 g* j; }. O: V% i$ Z( i

3 w% X9 Z7 P  h" I3 {#define KDBDEVICENAME L"\\Driver\\kbdhid"
9 M& d$ Z, L  R  H1 y* s, u#define USBKEYBOARDNAME L"\\Driver\\hidusb" & a+ s* @/ n4 Q2 _
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
8 B" U3 r; j8 Q# m% ~( J4 n4 u2 u! w2 N! `- N, V$ ~( _4 K( i% {+ u( U' O
typedef struct _OBJECT_CREATE_INFORMATION
7 ^5 m) `5 Q0 O5 G6 m{3 t  k$ s6 T3 d. t3 k
    ULONG Attributes;: F4 ^6 G: F4 C/ o0 j
    HANDLE RootDirectory;
3 j! X, `0 P3 b. C" w    PVOID ParseContext;
( u# V  \+ I7 n& N0 L    KPROCESSOR_MODE ProbeMode;' v( ?" k1 [+ p( `
    ULONG PagedPoolCharge;
! f  s$ r8 Y3 I# h$ X/ g( A! Q1 T* V    ULONG NonPagedPoolCharge;
3 n( d+ V4 L  ~1 x; L- i& t    ULONG SecurityDescriptorCharge;2 }+ T& G3 R5 o# ?. }- U
    PSECURITY_DESCRIPTOR SecurityDescriptor;% Z" i/ O% G" s2 s
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
, V3 k  ~/ s; r, y    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;, D; ?, m/ W; N$ T
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;" l8 o# u% [+ B: k& i
' ?) y+ g8 F) e' r
typedef struct _OBJECT_HEADER
! F9 e- q; Q, k+ @) e{3 i( b# Z4 O+ l1 T  E
    LONG PointerCount;
8 n, E9 j, f. c8 a# {    union
* @; c# p( j- a    {
. M' F- i" g5 B# N( Y        LONG HandleCount;
8 ]! |, P* Z' }! p4 {  q        PSINGLE_LIST_ENTRY SEntry;# d1 Y: [+ X% p' x
    };
& t  H% D5 F& }" G    POBJECT_TYPE Type;( s7 i' G2 ^/ a
    UCHAR NameInfoOffset;/ F2 w1 o# Q. l- j( _2 \9 D+ w/ k7 P
    UCHAR HandleInfoOffset;
( L" V7 t" [& z% x3 V, s/ F    UCHAR QuotaInfoOffset;3 |/ a) E% j! w/ I
    UCHAR Flags;' F2 i# g, g9 b( C
    union
" h6 f( D% Y) y    {
( z+ H1 P6 z1 `        POBJECT_CREATE_INFORMATION ObjectCreateInfo;" {+ R8 M8 R' \+ N. L0 G( p
        PVOID QuotaBlockCharged;7 E- I2 t( K8 q, U6 P2 |* f
    };
% g" ^& H9 s% _% \# H+ \; Y+ T& O6 D  S& N5 q$ w0 k, S4 X
    PSECURITY_DESCRIPTOR SecurityDescriptor;
4 l9 n9 ?6 g* Y* n; Z' `    QUAD Body;
0 [9 {3 s7 G7 G3 Y} OBJECT_HEADER, * POBJECT_HEADER;4 z7 }- u5 v# ?- S
1 W( H1 o9 C2 Q+ W5 u
#define NUMBER_HASH_BUCKETS 37
: B6 W6 _" a) T9 B5 D1 y3 f+ z; b5 [' P7 k& o
typedef struct _OBJECT_DIRECTORY/ t- F! W8 c1 N, E) m
{/ m+ O; Q# M! D& h# u  }9 Z% T
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];3 k$ f6 V  }% q% h) B
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
2 E+ v  p/ `2 m# W! D    BOOLEAN LookupFound;
2 d" |' w5 E% B& z8 n8 V  T    USHORT SymbolicLinkUsageCount;
8 s! n& E6 i% [5 E1 J5 }( y* I$ J9 i    struct _DEVICE_MAP* DeviceMap;: z/ F' [5 [) O+ x
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;# G& {5 |" U* w- {' D) T

% m1 E- I( `2 D2 i9 u  D* E5 D& `typedef struct _OBJECT_HEADER_NAME_INFO8 n0 R& c. t% z9 k' \* Z
{8 F% X$ O" k4 q, |' N/ g7 k
    POBJECT_DIRECTORY Directory;
) H, f/ Q: V$ L- J8 f    UNICODE_STRING Name;
" h( O" m6 t9 `4 M9 n* J" h    ULONG Reserved;
/ `4 I+ _& d( D: Y2 g6 n#if DBG, ]8 O/ ^& x/ t
    ULONG Reserved2 ;* o5 n# ]# ^% ~0 ^1 R7 k
    LONG DbgDereferenceCount ;; T2 B& |: Y, z; r9 g  z
#endif
8 J6 H! z$ B8 u; X  z} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
- L+ m4 L" B/ j1 k5 V3 S
! F0 o. [) b& ~9 @#define OBJECT_TO_OBJECT_HEADER( o ) \" {# c% `. S: h
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body ): a6 ^9 [! L+ _; x- L4 G

/ `+ m6 m; G# J3 E#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
0 U- W0 p& y9 [" [; G    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))7 \6 w3 j, R7 c: H$ i
; ]# S  |7 ^2 T$ D
typedef struct _DEVICE_EXTENSION/ U6 s- v0 Y! A7 n3 y' `5 p
{  `/ g6 T) J  Q- Z. z( z+ ~/ i2 Y2 _
    PDEVICE_OBJECT DeviceObject;
8 n- _2 k% w+ e7 ]/ k    PDEVICE_OBJECT TargetDevice;/ M/ H. z  I0 n, d7 n! N
    PFILE_OBJECT pFilterFileObject;+ }& Z) Y- A3 ?) r/ Q3 }3 ]
    ULONG DeviceExtensionFlags;
+ ?: z1 t' k, {) u    LONG IrpsInProgress;8 Q8 P4 K3 k" Q" u0 p" ]
    KSPIN_LOCK SpinLock;8 |% z, l2 m7 C7 M5 f) k" e2 G
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;0 U2 E" D- U! R0 y& s

3 u% T% G+ g, i, K+ t8 I* @, T8 {1 G7 ]% M
VOID
4 `! h4 }. h% H( U  R/ ?KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
% S( i* T: q3 x5 O0 i+ A
' C+ _' C" w! F/ OBOOLEAN
7 d" p5 Q! g6 Z# \+ {; ZCancelKeyboardIrp( IN PIRP Irp );
) @% k1 ?1 b7 z" j* y
& `6 Z: u: r0 q3 Z0 {1 kextern POBJECT_TYPE* IoDriverObjectType;7 f) A2 l4 P5 g0 I) y+ ~% k* x

* W3 r9 K7 B4 t2 a3 d& M4 LNTSYSAPI
& y% s' v* r- qNTSTATUS
4 w! ~) Z6 {3 U3 m% G5 Q) o4 JNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
4 s4 u6 S9 o' q+ C, ^& A                               IN ULONG Attributes,
6 D  _+ r: {0 T$ T. g6 U                               IN PACCESS_STATE AccessState OPTIONAL,# H! n( r* C$ y7 l
                               IN ACCESS_MASK DesiredAccess OPTIONAL,1 o5 {% P; c0 U- p5 [7 W6 y, c
                               IN POBJECT_TYPE ObjectType,2 f1 J/ X- l9 b5 T$ `
                               IN KPROCESSOR_MODE AccessMode,
( S& \0 c6 m0 n+ E$ A: X7 ~  d                               IN OUT PVOID ParseContext OPTIONAL,; H+ J; O% Y9 v8 i) n
                               OUT PVOID* Object );
: F* }  i1 p* c8 i
/ Y( [( z* W+ [/ J# fNTSTATUS # m9 w- l% \: I* m/ t  z: X7 B
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );% f2 N; ~5 k' r7 [; a
! J, y1 y- a* i  a" }1 g; Z
BOOLEAN   x! o! x0 I; w; |9 m0 Z3 W
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );% `* k3 P# ?! V; B& z& r% H

: n! G* l5 z/ z3 O8 k0 g/ E" ^VOID
! h+ i* n6 V" C; m( T" wGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
+ D/ M4 W/ l: d# x& S6 t, j* {0 m# p: T1 d0 T. W6 R; ?  N8 z8 F3 z% y" t
NTSTATUS
; H( m0 R8 U# q5 gAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
- M: Y: }$ G  w7 V                                  IN PDRIVER_OBJECT  DriverObject );! x3 a5 x$ H9 @, r9 E/ m$ {
9 k4 b( Q' Y0 X% Q, x6 N
NTSTATUS
; O/ q3 C; O0 [! oAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
7 r8 S$ h1 q8 Z' ^. A) B                                  IN PDRIVER_OBJECT  DriverObject,
" G# y: L( E5 M% A* t# H, J                                  OUT PDRIVER_OBJECT* FilterDriverObject );
3 i3 p7 p, m, ]! p1 H
; s; E1 D& z1 Y- l2 j' qNTSTATUS - v* [4 j, G8 S9 U0 `  r
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,7 A( [# Y$ q. i" W" t' J
                            IN PIRP Irp,
3 }6 }- n- B( e                            IN PVOID Context );8 w% t6 B# V" G  U  v- V9 T
NTSTATUS 8 H+ W9 \$ O9 j- a5 ?
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
# Q$ Y4 f+ [& o( c$ z" I
  v- `0 B3 U! l+ rWCHAR szUsbDeviceName[MAXLEN];
' ~/ h% F1 e# w/ Y# C; _7 @: {8 M
#endif) P* y% C1 K: |7 ?
! ]* R6 E  H& [+ l3 g

0 ^( |( r, o: u! [: t, }; q ) {2 b! X/ o& ^) e
, J% W( A3 K9 I
* b4 _! ?! e+ P( D" e' @) ]$ p
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。$ N6 p0 k! |) h6 k1 m1 T( d! Z
WSS 主页:[url]http://www.whitecell.org/[/url]
+ r/ o; Y0 L9 a! w: YWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-9-1 16:54 , Processed in 1.774599 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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