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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
, ^* X# i5 R- {0 Y6 i2 EEmail:   [email]sinister@whitecell.org[/email]
5 s5 L  P3 \; K* uHomepage:[url]http://www.whitecell.org[/url]
( P% [' ?) I( K6 Z5 sDate:    2007-02-266 z2 J+ d0 z5 q/ b! U+ n

/ h6 S6 b# O! g! D( E1 y1 g- U8 r  r# w5 @6 {  d
/*******************************************************************# G# u9 z/ I0 c" f

$ L: d' I6 S( @9 _4 f9 E这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
6 b9 ~# @9 K; c! v& a% p写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
$ x  _# P$ I) L+ b1 w& O功能要求如下:
! ]4 b* F8 k  ^! ^
3 O1 n2 H# {  r3 g, y1、强制锁定键盘/鼠标。: M7 b3 l1 f1 G1 j. G
2、可动态加/解锁
% X3 ~+ `! f) B  R3、兼容所有 NT 系列的操作系统。- Z5 w8 `! K5 k/ W' w7 R% x

: M* }& a7 K, v: [6 a就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实# c* a5 X0 H$ B
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如, w  a3 d: f7 d
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在2 E. I" q9 f: p4 K# R4 J1 x+ q2 L
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是9 S. ]7 N; |5 c# a6 S) d$ C8 U
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面% V2 w/ Z. N6 C" q2 U
就来看一下我想到的几种实现方法:0 L/ ^4 X! {  B# b* a/ a

( d. m% W6 D5 G, a  L, x1、全局键盘/鼠标钩子
& m- \0 W! U7 A2、BlockInput() API, B$ Q2 b/ t- }7 a6 W
3、使用 setupapi 进行控制1 e4 A  x( P+ S4 k
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL4 w; \8 h0 s. a4 v
5、拦截 win23k!RawInputThread() 函数
! ~  c# C( r! T0 g4 |$ J) m6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动' A" R; o8 Y. J" s+ r# u" x3 D7 C
7、拦截 kdbclass 驱动的 driver dispatch routine6 s+ Q. l: Y& q7 h6 {
8、实现一个 PS/2 与 USB 键盘过滤驱动! b" `" `# }3 [4 x/ U! ^! P
! p; s, @# D/ l6 X# y! p
* ]- J0 W8 ~! f# v  i/ r
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
( Y6 \9 e" o$ b7 g$ p之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( `; H6 W  }0 Y" z) M
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在0 U  D% e0 g- S
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因% _/ f/ R2 K" d1 W1 @9 j* T5 c
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性! l( h6 B! c+ a3 X- N
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸$ Z' S7 e' E& J9 M3 Y1 z3 B
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我8 v4 _6 R6 J- B, G, W. X6 z
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来; b# z7 O" j" v
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如( I" y$ f0 {- h4 C7 X( M; Q2 V
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有. t3 Y! I: Y" ]3 u( Z5 Y% \' ?9 P
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
2 F, J9 b" J" [$ }5 x6 A. v- [+ ^IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
1 ^& l% n& _' x* ?4 O; k9 p3 V- Z3 eUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键* F) e. E) b: j9 V0 O
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方1 S$ w9 W; |- z6 @/ O; g8 R
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。' E: i; v. r1 i1 r
+ e+ T1 r. e5 f( s

3 m- @( ?: V' s; `8 Y我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
8 `$ G. u; n+ i5 B8 m" D滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
6 B; i" O! H6 d9 [/ A. U, c5 j行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
6 n" M  B* |/ P& Z$ F: z9 Q7 t5 O只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
. i, g1 M! K) y( ~/ t8 K; C( L来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
& K' ?; J0 {+ W3 gKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB* o5 @. e7 v# E
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用3 ~8 X7 l! d9 K5 n
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
+ d5 w! M) H+ R- H我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
% H; [) B% v" Y0 r7 n就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
$ p3 S4 {  v( k而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使3 {) ^) ~% x, K8 a
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通7 N  K5 w8 Q# C4 x! @& r. V
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
+ e& ^' y- ~& N# G( u屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通5 U: O4 {5 o* K
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb  b! u5 a" G& t7 e, K: H6 o
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
6 E4 J2 T5 @; s; Z; D的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
1 U) y4 L$ V) Q: L$ f( I4 ]味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。$ c# s' z5 ~9 ]6 k8 G: M
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们* V1 Y' _; d6 P6 v
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
. R3 h) ]2 }" o: w& O* J0 }; N  O的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
4 h% l) _3 S! m$ P的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
8 R$ C9 @) y, ~: m6 f7 F敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
/ X4 y7 s$ y+ S4 P根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
1 \9 H; Y8 \, K0 H/ B/ R见下面代码。
8 C. h! m4 T6 b: X! R2 P' |  M9 |' g8 X7 c! z
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程  ~2 f- h& {1 H) J- U8 z" h
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
7 d. U2 ?  [, p4 X& c, d9 v) E, Q盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20038 s, a/ B. Y5 l' B, {5 A
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有' N6 A" k" u# p' g: C. C0 `
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
9 l4 X" u) ?" d8 N2 `% C# I% _4 ~继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
. P: U/ [! u6 U+ m锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
, b$ N' |) c6 |5 S; ~键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。  a1 V: N2 J' X5 F; H9 Y% W
  m% j1 ~6 @; g  Q5 h
- Z* f! V; M& e$ r7 u) _+ ]
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
' ^+ ]3 j9 D% m% Q7 \/ I, [+ C的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是. {& r8 U/ M- o6 S2 A) m/ N1 ]
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣( C' v3 n8 S( j. J
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
, Z- F# Y2 D# {9 a) j/ _们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我" j; l4 |0 S. ?' h, W/ k
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
* F4 V3 ~. [. ]/ m5 r! ^->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。3 E  S% O, p" M, y$ I
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
* ]  W" z7 V! \. q5 _进行操作了。这个问题有待大家来完善了。5 g1 Y5 p$ R# ?0 l1 q( s
7 p2 Z: p6 J3 {1 j  t

3 h/ U! \+ F7 j# C8 Q/ ^要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
: o) A" O1 {" s) x& z来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的" s4 H0 e0 Z) u4 d) j
分析做个记录而已。我更愿意把它看做是一段注释。! N2 B  i# `' I

& |2 R) j! G% X/ B! i最后在此代码中要
3 x+ S% n. C0 r. N
# ~; b2 @3 p' W/ N6 O感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。$ H0 O" U: y8 n- a$ `4 V
' p1 F6 N. b$ [& F& F; W% e
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
3 d" y, N6 D9 w! r3 b1 G2 h( j9 ?$ \# X1 m
感谢:齐佳佳,过节请我吃好吃的。8 V0 m, x8 G" Y- \. {6 F

0 E$ a2 H2 }6 M$ Q. [. T9 n
' y. _/ l5 ^' W1 V; J9 T8 I******************************************************************/- F' p2 {. {' E$ o: N* E( z# Y! X5 h7 h

6 B' E) @+ {% l9 C* d, v- J
, E+ t2 ~# G3 [5 L' h9 @& a- H/*****************************************************************  l9 w) W8 p9 z. H
文件名        : WssLockKey.c: h, d( ]# |6 V- \4 X9 h, p. D
描述          : 键盘过滤驱动' {1 z' V5 y. U$ e
作者          : sinister( V8 C# U8 w  i8 b$ ^
最后修改日期  : 2007-02-26# C6 ?' B* \- i  ]5 a, b
*****************************************************************/
- F# W0 d  t% b& w# Q2 V2 z. n. d8 s. g% y
# n* h8 s: Y* i/ D. p+ Y, y- u1 {
#include "WssLockKey.h"
2 [3 w8 A3 Q; @, ?% ?8 P, u* B6 W: U4 \$ d4 Z+ c- H
NTSTATUS
! @) P4 D2 V9 N; b% rDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,' B) ?1 M- Y+ G; ^) c5 p! _7 x7 n
             IN PUNICODE_STRING RegistryPath )
/ Z3 A/ z9 k0 A/ H8 i, h{. a9 w! g" |) d
  UNICODE_STRING KeyDeviceName; 9 h% w$ g6 o0 n$ p8 l
  PDRIVER_OBJECT KeyDriver; 2 j* B0 k" A5 F3 J5 q6 K& J/ ~) f3 M
  PDEVICE_OBJECT UsbDeviceObject;
! [% p- u: J0 @7 G# p- K: ^) F  NTSTATUS ntStatus;
" a- j3 g" j) b# Z  ULONG i; . \* H( r) J9 J+ x( N, I9 l( c
3 B/ Y" u5 I) e. u
  //, O, g: E' a% `& ]0 c) o/ U
  // 保存设备名,调试使用
7 R7 o/ `6 _4 }0 A/ o  //
% O( R" H6 ~" _7 @+ j. N4 S  WCHAR szDeviceName[MAXLEN + MAXLEN] =( {7 o/ _1 D! r( F
  {
0 W8 @2 E) |# D    0) B1 R) M4 Q. k( ~- ?& K, p4 I
  };& M, a  ~" C1 G

- s* x6 {- @5 |# z) t) r0 ]( {* t  KeyDriverObject->DriverUnload = KeyDriverUnload; . }: }# o$ M+ f3 v+ G, p7 `' o

7 o& H* T  N, J9 C0 n4 o$ _' [  //6 e) |" u4 v+ ^9 ^
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
  g$ I, m, w: z% F3 \) `  //7 L: W2 s. h* B: i
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法1 S5 {( l$ E% \
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
/ Y9 ^* g$ c. X; s" P5 h8 A5 O  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
- C$ L( V2 `7 J8 R; Y' e  // USB 键盘设备来进行挂接
1 s! e$ k1 H2 ~9 y: \8 N6 k6 F  //
) p) j6 x4 R$ U8 v5 ?3 @, t: Q% ~  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
6 T; S9 c/ n% {/ }6 b  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
8 O' I# O3 Z3 q, b) R4 X7 z  {
2 k6 z0 \5 X6 N, z. W( d7 t5 |    //
, J0 T5 W/ Z" s+ f% o! O) ]" r    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名- g6 q5 _5 r# D8 W& i3 M# [
    // 所以这里打印为空
; ~5 P1 Y% F/ ?$ H* M  q! H    //
- `3 P" j6 u: c  B9 \% Z6 N    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD7 X8 u- m/ O6 f- p- Z/ h
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );9 S& `% @+ T2 ^2 _5 R7 v) V* h% h

) i" }" c  B4 W! A- B% H1 ?    //1 Q2 |5 r, E5 }# T; A
    // 挂接 USB 键盘设备
; p3 l" z7 \2 ^# ?+ x' O  D* K3 [' D    //  _4 V; c  N, O" h) n
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );; x' u9 ]2 u: ]* f' ?
    if ( !NT_SUCCESS( ntStatus ) )
( c4 e9 V' U4 Q0 \    {
! o+ f9 ]- b3 [( N2 H6 Z      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
+ Q2 W+ [, J$ `- w      return STATUS_INSUFFICIENT_RESOURCES;; @/ M: O9 q$ B7 r  |
    }
$ D" G- |. m1 [  f  }/ A: H, a/ I# e4 q* P. f
  else8 V1 d+ g; f, W) e
  {
% _  I; e/ m/ p. K/ L1 V4 Q    //# k) W4 x1 x+ i& M8 c# `5 h
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
; M9 b* \. X0 B) h9 {$ ~2 n" `$ E# L    // - X2 q1 U( r* l0 w( O' \: @
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); ' f) R. z0 A$ r0 p# v; m+ g
. `1 Z# U2 c6 V' w' f6 Y8 g
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
7 \+ K/ i6 N( m! S0 \, a                                        KeyDriverObject,! ?! R+ |0 E' N* I- R
                                        &KeyDriver );
: e# M. K5 Y2 a: G9 F* J8 u. A# r# k    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )" q6 }! J# u0 O! G0 r2 Y
    {7 N4 I# ?) {) I& ^
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
. L9 f! f! D. Q9 N( q! n) F4 J      return STATUS_INSUFFICIENT_RESOURCES;
) \7 m7 L0 X$ X2 z" c! W* N, v    }  J! k7 y0 P% A5 }6 Y' D$ e! y$ H
  }& Q) y+ ^7 U+ h" R
: U# w9 ?3 {& g0 o) I$ [; k
  //& R: c. V) Y+ q
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
) U' G4 V8 ~% V7 E5 {  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程0 X7 Y# k! I6 k2 H8 E" T
  //; O: Z# g' f9 r: d
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
8 _. v, }+ W! R. w% N4 x1 L  o2 O* _5 j+ C
  return STATUS_SUCCESS;
2 {$ C$ b! K0 O2 k4 a3 L7 B/ b$ o6 G} ; ?% ], y6 }2 @
. D* ^$ c9 @! p2 I- f
/////////////////////////////////////////////////////////////////7 g& Y* w: F3 g! A( H; i
// 函数类型 : 系统函数
5 K7 s4 R1 x! }$ T: V* c) G5 m// 函数模块 : 键盘过滤模块3 q: H1 l' A3 f, h3 n8 c
////////////////////////////////////////////////////////////////4 c5 I1 t8 r7 j
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,, p$ P6 v; z0 h& j2 v& t) x0 ]
//        卸载键盘过滤驱动8 M, P& ]7 ?& H0 n8 S) P, s# g
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
. ^! c9 U8 ?- {) {2 [//        则需要等待用户按键,以后有待完善
* d; y8 Y" j, K2 t% u/////////////////////////////////////////////////////////////////
" `$ a4 S! m; n" F2 r& D// 作者 : sinister' k  O! \6 ]. d9 K
// 发布版本 : 1.00.00
( c% j: a. Z! S$ k: f// 发布日期 : 2005.12.27/ G9 x; O3 b1 m/ @& [6 f* U3 l- h
/////////////////////////////////////////////////////////////////
/ H) X+ f# O! E// 重   大   修   改   历   史
$ Q, B6 n/ v+ e) N7 K2 V' x////////////////////////////////////////////////////////////////
% O5 {$ M) _& Y- x* R2 u1 b// 修改者 :5 A3 \# c2 Q% ~/ X+ j
// 修改日期 :/ V" o& }. i3 i2 ^- g; m# u! w
// 修改内容 :6 M; E, K5 @3 r- y: H
/////////////////////////////////////////////////////////////////
: ~, d8 Q( P! }+ d8 r* c8 G; y
# O; o' C2 H7 @" Z9 `: P5 qVOID
! g. P* }: K; ]' PKeyDriverUnload( PDRIVER_OBJECT KeyDriver )) A2 Q3 V: _( l4 v$ f9 _0 j& n
{
4 n2 D: ?) K% a; j2 V8 B' R  PDEVICE_OBJECT KeyFilterDevice ;      ) @. J) k& H; t
  PDEVICE_OBJECT KeyDevice ;, w; ]9 E! e  j  i' G6 s
  PDEVICE_EXTENSION KeyExtension; 9 X; Z8 e& y! H; n# y
  PIRP Irp;
! @: m4 A( e6 @. n4 C# S! b/ l8 D  NTSTATUS ntStatus;, ?3 p- w8 g( K, K
! `; e8 [6 t' W, E9 K  V% Z+ l6 G+ }
  KeyFilterDevice = KeyDriver->DeviceObject;   }6 I5 L0 V1 \/ O1 V; B! D
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
/ ?$ b! Y* n) W  KeyDevice = KeyExtension->TargetDevice;
+ I; j# ]1 w# m* T- ~4 N3 {+ P8 u( [2 P* w( l1 `5 @0 b2 H) F
  IoDetachDevice( KeyDevice ); 5 j! M$ P1 S7 w* E

8 t  y  a- s3 Z9 f# n% T  //
/ ^' E/ j' t/ W3 |  A& c# o. \$ K  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP5 z! V- e( z* E
  //
- X2 ]% C9 ~0 w2 _; G  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )8 r9 Z. k2 a) L5 V! }0 E" a
  {
. w$ r, P3 s: J' B/ e. a0 L' F$ l    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
8 N( E4 Y+ u. C6 R( z8 D/ ?    {/ i. G( Q9 c# a- D1 K
      //
: U( A0 m) _1 o      // 成功则直接退出删除键盘过滤设备
3 g$ G7 H7 ?8 J* m( H6 J" g/ c7 @      //" a- J3 B8 a. n- j" V
      DbgPrint( "CancelKeyboardIrp() is ok\n" );+ T' y3 t1 w7 ]  V6 X$ D6 W6 k
      goto __End;) c* V! v/ l4 U* t! l
    }- a$ A/ ~+ B/ ]4 z
  }1 {; G3 g+ t, R8 R# |  O
" z) {: o: d/ E- @1 \1 N- @) S
  //: N6 ^6 G  _4 B8 y5 Z
  // 如果取消失败,则一直等待按键
- P* u6 n8 ?4 E4 K$ h  //" B+ X7 a& `& r: R- w7 V+ `" m4 C5 Z
  while ( KeyExtension->IrpsInProgress > 0 )6 w6 A: v9 R/ s4 b/ G% d. R  C
  {* @- v8 H- u; D# P% f' F6 S
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );; H1 }+ r' r) c7 K
  }
  T% z6 G1 {5 j* t0 ^4 K9 C5 _& @: L& X! m3 @( N' ?
  __End:% v) T5 J: P( S. O
  IoDeleteDevice( KeyFilterDevice ); 8 K% P2 S1 h6 e

" K, e3 S  ~6 C+ h$ F, X7 \2 B  return ;
3 Z8 U9 U; D9 R$ y}
3 E6 G- N- B/ s) P; o2 g9 v; Z. a$ v" e+ g
/////////////////////////////////////////////////////////////////6 }& Y, K7 ]" q
// 函数类型 : 自定义工具函数7 @* ?  i* Q; d, B7 E% c" T
// 函数模块 : 键盘过滤模块
6 y3 H) t/ v/ m7 v( L) T/////////////////////////////////////////////////////////////////
- _- n3 H7 I8 T" u* b; g1 D# B  b1 t// 功能 : 取消 IRP 操作# J* k; Y/ `6 s( {$ p0 p2 T
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
" A2 d5 L( Y$ K/ `5 Q3 i//        使用此方法来取消 IRP
/ j, b: t- f( ]/////////////////////////////////////////////////////////////////1 r0 s+ v" o  Q- m+ a; r
// 作者 : sinister) \' n1 n7 W6 o7 b
// 发布版本 : 1.00.00
0 ~% M2 N0 D$ y; d  x8 y1 _// 发布日期 : 2007.02.20. F# k/ Z$ u9 R( ?$ }$ R1 I1 v
/////////////////////////////////////////////////////////////////
; t* e: x0 u7 o9 V, d) E// 重   大   修   改   历   史& b( Y% o; N$ {. u& m: m
/////////////////////////////////////////////////////////////////6 w$ j+ |& Y: t7 `3 T9 e
// 修改者 : 9 r) h- e9 S1 s4 |
// 修改日期 :
2 j( a# d7 a/ t$ A4 \// 修改内容 :
' E* E  j# F+ a2 r4 v/////////////////////////////////////////////////////////////////& V: g% ~% B7 [/ z9 w% }9 c
+ y$ S) N9 ~3 F2 ^9 P
BOOLEAN* e* x6 K+ K, Q& e
CancelKeyboardIrp( IN PIRP Irp )& b' S, q" ?. I, W9 j2 O. S+ h
{
9 ^6 I4 v( W. A1 U* ?1 X- D  if ( Irp == NULL )0 D" }9 U! E% {5 n& }3 ^
  {. h7 ]+ p$ v+ |6 `
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
8 L5 a# k* f% j$ G2 Q    return FALSE;
( s: s2 V0 A# x7 L2 |9 t8 ~  }
6 D! m5 Z/ E' s6 K6 i' v& P/ }! w+ i: E5 g9 F& P6 V
, x4 U$ V  y7 p- _- e5 Y
  //
5 z0 t' s5 S1 b' i6 M9 a. T+ T  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
. q- Y3 Q0 P( G% K/ E! A  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
+ s0 A  E# j$ b; w  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占, q; H" `% a! H7 p- X! o+ R' B8 w
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD9 R6 R5 I: Z+ q
  //6 |) N4 l$ H  t4 k3 B3 {0 X0 ?
9 W# S0 y! O2 }8 I( i
  //$ B* b, [8 R; ^5 q" ]- U
  // 如果正在取消或没有取消例程则直接返回 FALSE: f  g+ P3 }0 d" N2 u; c* X  h
  //2 b; C0 a1 q' M& s4 O& K* f
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )* e1 c5 N  w& o5 j. j
  {# U& j* G6 D& C8 P8 I6 d7 T
    DbgPrint( "Can't Cancel the irp\n" );" G% ?9 n5 O1 j3 B4 L
    return FALSE;
' p, w4 O/ b; U- R4 @  }# F  E4 D/ N0 I
0 w& g& V6 \. Q, X+ _( D! y5 l. y1 B( E
  if ( FALSE == IoCancelIrp( Irp ) )  l4 e* L, W/ Z
  {% T0 R8 S9 U3 I4 }- T& E2 T
    DbgPrint( "IoCancelIrp() to failed\n" );: x2 x; O3 F) g6 _. G# U2 s
    return FALSE;
3 _/ `1 _" ~: e2 \' M" Y5 \% P- j  }
3 j7 O6 D- ]: R3 r& k# p/ J. K' c$ \0 R( n9 K
  //! Q; a: _4 {. q% `) _& H
  // 取消后重设此例程为空- p3 h$ O; h/ E% E- ?1 e/ y
  //
7 s* \# T* ~% D0 E0 `+ Y  IoSetCancelRoutine( Irp, NULL );
- s- \; m7 ?5 Z+ M1 V8 z5 n# w8 s% P/ r* |
  return TRUE;+ g' |6 F# T+ b+ _. H
}
; z# D9 o* s% E) g! A% b1 [& R9 ~  e
/////////////////////////////////////////////////////////////////1 R- I" T" T5 r& g
// 函数类型 : 自定义工具函数
+ u# G1 W4 J! R: Z& R// 函数模块 : 设备栈信息模块( d" g( I2 E+ X. \* E
/////////////////////////////////////////////////////////////////
" z& l- H. n$ t0 ~" ?0 B$ m// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
1 w8 G) R+ [$ M* M3 ~5 E/ c5 u8 ?//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)- ?0 L7 K3 j0 S# u% U9 G
// 注意 : ) x- ?8 K) `0 ?  D8 G5 x5 i
/////////////////////////////////////////////////////////////////3 Q0 L1 v+ A1 J' ~* |
// 作者 : sinister$ I( y  _+ ~, p3 C) Y( x
// 发布版本 : 1.00.00+ y$ ~8 S! c# E  D
// 发布日期 : 2005.06.02
, D2 K6 l& G  i' U/////////////////////////////////////////////////////////////////  J  J- R. X4 a' S; i6 _
// 重   大   修   改   历   史# y8 ]( x. ^+ v9 p+ f3 Z# r/ t
/////////////////////////////////////////////////////////////////
, N& J; @: x9 H/ H7 K! j9 ~// 修改者 : sinister
$ ~4 i- Z( }& Q/ A9 N% m// 修改日期 : 2007.2.12$ T2 v  Z: B. ?+ q5 O' G- w- A
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改( |& H+ L1 y; N
/////////////////////////////////////////////////////////////////
& L& s& w/ L2 Z. Z. g* K+ B5 |7 f" ]1 C. x- y2 p6 T7 Q6 ]( w! g( |6 Q
BOOLEAN
8 J/ t/ R# P2 Z3 c+ m2 }GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )$ Z  q0 F( a5 P0 B4 N
{* H6 L3 D! N3 f  h1 p/ j$ B
  PDEVICE_OBJECT DeviceObject;
: r: u8 R- h/ m' t# S+ ]- x1 N* W  BOOLEAN bFound = FALSE;
: h2 w# C. l9 n( x
4 w, i' N6 C6 p6 g( V  W* I0 i  if ( DevObj == NULL )
3 [3 B+ e9 G# D  {
/ e3 X8 f* m" j    DbgPrint( "DevObj is NULL!\n" );
$ a( e2 Z8 t$ `! {9 |8 F    return FALSE;
/ |: j" Z. A! E1 m& n  }
; ^! r9 L; Y3 `' D; j5 J. Z! O
" P( ]# J: b9 O, [0 V8 b' A! w  DeviceObject = DevObj->AttachedDevice;
! _3 e% A5 {( ^6 A- v- Z' }! K/ S( ?& K' D
  while ( DeviceObject )
/ ~1 Q+ ~* X3 ^" i  {) x0 D/ ?/ {8 K8 C" n9 F
    //: n# G/ E) t# K9 I1 Z' H
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
# k0 \+ e- C9 U- |- [8 {    // 有一次足够了。这算是经验之谈  J% d0 B: u8 [- |% D! @1 f3 N
    //
5 u# t8 E, L" M% a$ q    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )' q# j3 R" j" Q9 k
    {  S( r% E$ Y( [8 w5 S
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
* s* E9 [/ F! B2 W! w9 w                DeviceObject->DriverObject->DriverName.Buffer,6 I0 J4 e' Q5 l1 w) h9 N
                DeviceObject->DriverObject,$ B0 S0 d" L- g* ~" a7 M1 `0 G! m' r) s8 j
                DeviceObject );
1 p1 h4 U8 d9 T4 w# n9 K" K" {4 D# P( W3 Q8 z
      //
4 q4 g6 H# [, ~4 [; w6 _1 @4 l1 U      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了% ^( ?( J6 B* |8 ^
      //2 ~3 Q  y: a/ [
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,! m9 D. l0 g; Y, P. u% @
                      KDBDEVICENAME,
- Z+ M1 G* V3 u- r! l                      wcslen( KDBDEVICENAME ) ) == 0 )
- s/ J/ E. x8 i0 g0 o      {' u6 F/ D7 q, j7 B6 i8 q. H
        DbgPrint( "Found kbdhid Device\n" );
" G( A: {, @5 ]/ Q0 h        bFound = TRUE;
9 ?3 |% M' I( J. `/ }5 ~! W        break;$ W! s% m  O# r- ^# b
      }+ k" r" e/ v& [# J8 c8 ?7 A
    }
. d( o6 X7 p+ X& f6 s3 H! Z& b# Q1 h. G' y
    DeviceObject = DeviceObject->AttachedDevice;+ M/ Z" C' b4 ?5 D' t9 l2 x
  }
# h, p+ h( i/ I( \/ D# `3 i( w' i
2 ?, t  ~9 ?8 T4 R) J$ [0 m4 d! [2 g0 r  return bFound;. y0 F& X6 Q# x. M
}0 p$ j: Z: t' B& z4 F: B0 G

5 w7 B4 h/ u9 r$ y+ c/////////////////////////////////////////////////////////////////
4 K" G$ V$ _8 N$ }) |* J// 函数类型 : 自定义工具函数
1 `, a6 E  z' d! M// 函数模块 : 设备栈信息模块
$ S1 T4 e. o+ z0 C/////////////////////////////////////////////////////////////////# a. z' ]; B0 I. s, d
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
3 v* w5 W) p: I% c// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改6 p* p2 e! ?  l( ?% E
/////////////////////////////////////////////////////////////////$ \0 J6 Z8 X. r* _4 P# Z3 H
// 作者 : sinister; W* I2 \# m" @1 S  A5 t
// 发布版本 : 1.00.00& v4 N; |4 I1 |) U* E" d
// 发布日期 : 2006.05.02# x" W7 p5 x, u0 \
/////////////////////////////////////////////////////////////////
# ~$ p% s; f  q  t5 H  j" n// 重   大   修   改   历   史
0 B  A0 B: y3 N* T% d: G" B/////////////////////////////////////////////////////////////////0 I& B# d9 X8 ^1 s& c% u/ r
// 修改者 : sinister+ \$ J0 A* a% O2 }9 G1 l
// 修改日期 : 2007.2.12: K) H+ F8 N8 [
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用% O# ^% ]4 U+ m1 \# X
/////////////////////////////////////////////////////////////////
, [. s6 k. d$ R
  `  B+ D( Q0 L9 rVOID: F* \+ K  M" T9 \; i+ @
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )7 }0 x9 E- X  P6 }* p3 [/ {
{
& J. R- z# @: y  POBJECT_HEADER ObjectHeader;0 w- e7 F3 Z7 j, F
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
) j& S5 o; D! B: h9 ]/ E
, m3 @9 C5 d( f  v4 W; w: }  if ( DevObj == NULL )
: f( u5 H: E8 L) T+ Q7 T1 u  {% p3 w, P3 I5 T0 r0 u: l
    DbgPrint( "DevObj is NULL!\n" );
- E0 M7 R: |5 U    return;$ r/ {. D# ]: C- p1 @
  }- _2 ^/ R! O, v% r% J9 Q

; z  L1 ?' J8 f9 Z9 M* v) _  //; f8 _0 E" u: G9 I1 n1 K9 x9 J. r
  // 得到对象头2 _: S3 C7 b; s: z/ F) R
  //& ?9 t$ U  [- `
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
( I  a1 z* o$ f& |7 N' ?5 O
# O5 }' q# A5 ~3 L( }0 {  if ( ObjectHeader )9 S- Q  J- Z# r5 e
  {
$ Q" u% v# e5 }. x! G/ r2 F" \    //
2 D/ g% t* M5 Q7 A) M    // 查询设备名称并打印: A; ^7 Q4 S! M( z
    //! Q" ~6 Y, b/ G5 h/ |
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );, x! a- ]7 G- @3 j7 m- ]1 n

$ U+ H% g: Q- P6 T    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
5 v4 @0 e( s4 \. O    {
3 W) C0 f& c- V- V9 B( }      DbgPrint( "Device Name:%S - Device Address:0x%x\n",' X( g( P7 C: Y$ v2 ]1 _; x# f# \- r$ G
                ObjectNameInfo->Name.Buffer,3 E' p& j! ^" T! ]: G
                DevObj );
9 k" S: `9 b- u5 M' L6 Q; C9 p$ h3 l/ w; p& y5 X4 x
      //- |* n2 I3 j* n: l2 F
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
- o! D+ O1 X. Y/ D4 `$ C% D8 H      // 用,没有实际的功能用途
" C4 E4 s2 N1 _' H* T      //
0 O3 |% ]  J# a" f% B% q: t$ g      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
& c& s3 C# ~9 j
2 m) e# Z! `$ G2 z  Z1 S* D) Y      wcsncpy( szUsbDeviceName,
# M  e7 ~0 k! `1 }1 ^3 }               ObjectNameInfo->Name.Buffer,
5 f/ g& P& r0 m7 W  v               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
1 Z# u7 `) x5 v4 y& T) _5 Z    }+ \3 W" W6 x: b! ^2 {

8 q! J  r; U. T) p2 @( u    //7 B" ?0 ~1 i" o' v6 A
    // 对于没有名称的设备,则打印 NULL
4 ~% c  y0 l3 Z! a3 e( h8 m    //! J0 @( s2 K' N) e+ C2 E
    else if ( DevObj->DriverObject )6 P" X8 a+ A! S6 p% M& m+ q/ S4 [
    {( q( q" \. K* R4 o" i# y4 w' G$ |
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
. E) B8 W- r1 }5 x% r$ |5 g0 w! O                DevObj->DriverObject->DriverName.Buffer,, U4 Q* d: t# K  f5 l+ I
                L"NULL",
0 Q5 c+ a7 E# g+ d- _  F6 M                DevObj->DriverObject,
, ~4 _. D* _& Z+ l8 G; L8 v( k+ ]                DevObj );
& Y1 d" }' v" [' N6 k: o    }
% H9 d, i- M0 [7 D5 a2 I6 v6 a* Z  }! n  x, J: d7 E; `9 T2 t- j
}
6 Y9 f$ P4 J) V) \6 d% a: \/ t' W
/////////////////////////////////////////////////////////////////) ^* I! d. o* C' @
// 函数类型 : 自定义工具函数
* l8 [- j3 o% h6 x1 [' K# M// 函数模块 : 键盘过滤模块. X# V, B- x1 y' {  v) M! [# k
/////////////////////////////////////////////////////////////////+ y" o- \& b6 T" p* T2 f4 T0 M
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
3 j. G, @, E3 w! P1 A//        对象,过滤出 USB 键盘设备,将其设备对象返回
# u( z& g( [! q5 S// 注意 :
) y. T% V. \, n% l* }1 X# ]/ h/////////////////////////////////////////////////////////////////
' D; T0 |$ z. D// 作者 : sinister
3 R& ]3 V! F. w! X8 I// 发布版本 : 1.00.009 i+ f, j! C# {! Z# n
// 发布日期 : 2007.02.13% R6 O3 ~6 ]2 n
/////////////////////////////////////////////////////////////////8 M9 |/ W6 ~& t7 L( D9 X6 U
// 重   大   修   改   历   史
$ P" [, R& O5 r/////////////////////////////////////////////////////////////////
3 ~: Y- O1 s0 A// 修改者 :
& d. {& T$ s$ @/ V1 S+ J! H// 修改日期 :
6 V+ j0 H' n* D9 `# q% A9 p// 修改内容 : ' U: q" c$ ]3 Y
/////////////////////////////////////////////////////////////////
( l' o, o% q( m3 G/ `* a. F  E( z
NTSTATUS  y! r  c: J0 c, ]. `
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
$ X/ X- N6 U0 R+ a$ |- \( M0 f8 x{
2 Y+ m4 i+ ~2 v9 n  UNICODE_STRING DriverName;; f/ t' I( B% V5 R
  PDRIVER_OBJECT DriverObject = NULL;
, l9 B# E/ G6 x# U  PDEVICE_OBJECT DeviceObject = NULL;
) [+ ^3 f  m9 D  BOOLEAN bFound = FALSE;
% u% S! K- s: m& p4 C6 N" i3 v+ ^. v9 T0 F+ u: M
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );' l% N7 m, A  d4 t. g/ Z
9 Q" v4 X. G/ r, M% ?& r8 s
  ObReferenceObjectByName( &DriverName,
* K. E" ?1 M4 k2 |6 S                           OBJ_CASE_INSENSITIVE,6 j& i/ X) {3 v) r1 Y# B
                           NULL,
6 j' o% `4 j( Z, q2 i- v; E0 i% V                           0,$ @0 t5 M* O) @! n$ t1 K
                           ( POBJECT_TYPE ) IoDriverObjectType,( m# V: t& f5 J' [
                           KernelMode,7 h8 w2 U% I& e& Z
                           NULL,
3 p. _8 c  C5 [7 C/ ]                           &DriverObject );. O" o8 x  D3 |
0 f5 U6 W% E# Y8 t
  if ( DriverObject == NULL )
! @9 N2 K1 z1 R7 J! c2 j  {; p2 u" ?& L( a& W2 c
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
0 _8 n0 w- v! @  @    return STATUS_UNSUCCESSFUL;: c- n* D/ D1 F, l! R4 S
  }
/ h# u% t/ ^) G! c+ M, k
  z6 B4 `$ D0 F' v) E! \0 b  DeviceObject = DriverObject->DeviceObject;1 v0 |! e" u+ F: r( y
3 ^  `6 e' E7 v  m  ~7 {, u2 o* J
  while ( DeviceObject )4 L4 v- V/ `; v3 t! \
  {
1 B- v# O; V4 }1 l3 u* N" n    GetDeviceObjectInfo( DeviceObject );7 J, i/ u$ H1 K* D5 Q( }

/ b! K; V5 u' m( K; d    if ( DeviceObject->AttachedDevice )/ u- _# S9 z! ?" t, m$ p/ Y* X
    {
: V/ e3 B# U2 {1 q, M0 S      //5 P$ C$ h$ T3 ?8 r
      // 查找 USB 键盘设备
7 M6 R; }' R& x* T; C/ f( e      //# r. q! v' K8 r6 k/ d7 M7 A
      if ( GetAttachedDeviceInfo( DeviceObject ) )2 K8 ~2 ~1 s) |
      {
0 f$ Z2 X  k8 m. Z* ^) R) m        bFound = TRUE;
) U0 F% z) }9 q8 l; c6 E5 @+ H        goto __End;: B3 q$ ~0 e9 a  W* C4 v$ H% E
      }
7 R- I# A6 C5 a8 Z! n0 w    }# G) h1 U  W! t! e
* {6 l- L  T% E2 C# T
    DeviceObject = DeviceObject->NextDevice;$ I' Z6 L% C2 Y7 ^
  }
  X' @* p$ r4 V+ {( F' c$ I' K7 C& A- ?% a  s7 g: I
  __End:( t! r8 m& H( |

; X" `. @( h! d9 ]" S1 Z2 w4 n5 F# V* I  if ( bFound )
& J9 N- W/ E6 U3 n6 G  ]6 A  {
7 U  ?! D8 T" \* f4 h  Q9 A- W    //
" Y2 w2 t. O( k/ K: u4 g    // 找到则返回 USB 键盘设备对象
1 e! U7 Z$ `6 d" T8 J; @, Z; O; ]    //5 m+ }  \8 n& v8 K; M8 T' H
    *UsbDeviceObject = DeviceObject;
( m  I4 v. U9 `: k+ m  }
3 T& H* N% }4 m  else2 f- G( x8 F  L' e5 E$ p' r
  {
% w  A# ?+ U* O4 @3 O5 b9 K8 _( i4 s    *UsbDeviceObject = NULL;
9 n7 g; w8 u% q1 t" O  }' o2 h/ s- l( j+ q. ?7 T( f$ _# w1 b# E
: M4 F  X; d$ f/ W1 ]
  return STATUS_SUCCESS;: Y0 Y6 c. _$ P4 E
}
7 j1 O- p& X! P' R
$ R% G' l' o2 r- {# [/////////////////////////////////////////////////////////////////
/ f: S/ l( Q0 H& F// 函数类型 : 自定义工具函数
) F9 E* j+ d3 z9 N# {7 O// 函数模块 : 键盘过滤模块$ D1 }6 N1 h! T4 p/ \! C* ?& n
////////////////////////////////////////////////////////////////& A% r$ h2 m, q7 P/ o% N- ~: h/ P
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关0 s% i9 ]) K2 E- d" F* C4 m- R
//        信息,返回附加后的驱动对象! o0 |+ ~3 r! |
// 注意 : 此函数仅挂接 USB 键盘设备8 n6 X4 Z+ Y. I& E) A
/////////////////////////////////////////////////////////////////( q5 d, g, a" u; X8 B* m* g0 H
// 作者 : sinister
( m# t1 P' w  b8 I7 ^1 o4 g9 ]* R// 发布版本 : 1.00.00
: f- T( z! A' q; Y// 发布日期 : 2005.12.27
. e# D3 z7 g6 o! w4 m" x/////////////////////////////////////////////////////////////////" ]/ J5 u* q& I. u
// 重   大   修   改   历   史" d5 B# S# ?6 O7 `- {6 f
////////////////////////////////////////////////////////////////
( M  D# H% W8 V* \// 修改者 :
9 E2 @6 R/ g% r6 u8 P2 @3 L% @// 修改日期 :* Y) f$ u9 w' V1 W4 J
// 修改内容 :, A& w; {, q; l+ ?
/////////////////////////////////////////////////////////////////
) p. N" u3 K- m. n5 c) A1 R
/ V2 f, @5 t) v/ {* w" b) D* ]NTSTATUS
8 s$ D8 w5 r; iAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,4 @" p8 a) y2 Y" i" U0 \
                         IN PDRIVER_OBJECT  DriverObject )
! T$ h$ t2 K/ _( ^# ^6 E{' Y8 ~4 c. T! H& c3 @
  PDEVICE_OBJECT DeviceObject;
5 _4 c2 Y3 G. N: ^4 C6 `  PDEVICE_OBJECT TargetDevice;
4 K  F* g8 }6 V  PDEVICE_EXTENSION DevExt;
& G" x- ?6 l2 A  NTSTATUS ntStatus;/ ^* A: U' A& t) r
- e  `- |9 X6 j0 C! e3 i
  //
& L" O& P. A4 o" i: U  // 创建过滤设备对象
! _( j, w, A2 G9 l# Z& L$ O  //
5 z2 }/ D# @( I( Z/ ?3 m  ntStatus = IoCreateDevice( DriverObject,
% m. f! c4 g5 w* a# s+ ?2 F: Z                             sizeof( DEVICE_EXTENSION ),
! I* ~8 }0 n) ]; P, s3 c                             NULL,
" R8 x( b& }% K- j                             FILE_DEVICE_UNKNOWN,
8 ?( u8 L; r: q+ f5 N3 _                             0,
8 p5 }* r4 a) J2 F4 l                             FALSE,0 W! |) L4 ^& U6 q; `; E
                             &DeviceObject );
$ G5 A. W1 \  ?" G
! [. y! K7 e% b" S- _6 Y, z  if ( !NT_SUCCESS( ntStatus ) )5 h& \6 y  b6 S7 y4 I9 n
  {, N4 ?) K$ W5 q" P- i" G3 p6 c0 S* F
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
5 v; J" ?  s3 s9 _0 g: v  L* z    return ntStatus;! [$ S7 p- P$ o/ Q4 }. m7 S+ n
  }
  l' u5 ~- r& c7 I4 K* u. s3 f* c; I" P
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;$ J, N4 d" K* }% b" m) R3 Z
/ w- v+ L2 G  Y7 P6 {) [  o9 D
  //- Q' `( ?& s3 w, L5 p( @8 K: R
  // 初始化自旋锁
( O# o# @( j2 Z+ ^: v1 o  //
! z0 u9 t0 x& J! p  KeInitializeSpinLock( &DevExt->SpinLock );5 B; i! U3 c3 ?3 l% u( e) J# A
$ ]" j  ?% Y8 |5 {' k
  //# O4 g) _  ^; T* L
  // 初始化 IRP 计数器5 o0 {/ ]$ W" R9 k. J, H: w
  //
3 K! N1 n/ q6 Y. f; w: B  DevExt->IrpsInProgress = 0;  p5 m) H# `6 f+ G1 v8 C1 z8 d
/ {0 k0 r0 u$ |! U+ P' r3 e, @7 ~
  //9 Q$ m- M) S" ^
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
( g, F& E) e( U3 D- P  //
& e/ {  T. A6 J; r" f; H! [+ p! O: i% Z7 ^# `. F
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); : G/ j5 y2 |5 b1 a
  if ( !TargetDevice )7 B4 _% g9 W+ L; Y
  {
& \- n4 x* z/ e% `7 Q9 o    IoDeleteDevice( DeviceObject );
, J/ E' c4 n6 z) e    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
" [0 W4 Y3 C1 J5 d2 y+ f    return STATUS_INSUFFICIENT_RESOURCES;
& q) ~# v. ~( `) Y3 o2 {. W- I  } " a0 K5 V* q& Q

( W. m1 B, w. F6 M" l, P, k7 R( V  //
7 O8 `7 x; J! b2 Q7 E, H  // 保存过滤设备信息
' A  v+ Q* \) D% f) r/ Y7 {/ e  //
" v% w5 j, C7 r5 l3 [+ p+ N  DevExt->DeviceObject = DeviceObject;
5 _1 k: U  B+ Q& O! r4 T  DevExt->TargetDevice = TargetDevice;
" [4 k5 W5 p# X! f& |* p: X. y/ D% c9 @  r( S" x! A  I2 u- N1 `8 L
  //
+ g2 N. i/ h) Q4 j6 d* ~, \  // 设置过滤设备相关信息与标志- N7 X7 ?# p: O3 b! D" S- Z3 x
  //1 `% a+ L1 W5 I, E: G# W6 |
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
6 I0 V  R# l: U4 m6 A/ Z& D2 S  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
% F, x! |7 c% n
1 [! D7 D4 F/ T; k, B" m: }1 }
: U5 b& L4 ?( B6 i  return STATUS_SUCCESS;$ w5 @* q4 }, g+ K; z
}# G  R! k# q4 \, O3 s

% {( ^- c* m0 X" L& K' a& i; ]/////////////////////////////////////////////////////////////////: M& A; W3 W; s' m0 v
// 函数类型 : 自定义工具函数
0 C2 {0 x$ {2 ^, t7 `// 函数模块 : 键盘过滤模块
: D' X$ y; M) o+ x1 g////////////////////////////////////////////////////////////////
* S* V$ G( j4 ^7 w, L6 `// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关2 @) b+ n( s- P7 f$ h; y* l
//        信息,返回附加后的驱动对象$ R* D* k9 M$ |2 V, b
// 注意 : 此函数仅挂接 PS/2 键盘设备# Q+ n- C* G2 Y/ f$ P# P
/////////////////////////////////////////////////////////////////5 K  Y( y5 H' D& o- W% g
// 作者 : sinister
* k! d( g1 d0 w8 m2 i$ J1 T// 发布版本 : 1.00.00
. H) j0 v# x# @6 t: B! C# E// 发布日期 : 2005.12.278 p7 E) F' A* z8 B: u. W# P
/////////////////////////////////////////////////////////////////
9 X9 A2 P$ F3 K4 v8 m// 重   大   修   改   历   史
7 |9 C/ W& [% B. z) T////////////////////////////////////////////////////////////////
% \, [- j6 y& E9 z8 S// 修改者 :- W: L9 |  G" z( y1 M- @1 j
// 修改日期 :& Y  O# Y# O- e
// 修改内容 :1 f; i5 c, c8 |
/////////////////////////////////////////////////////////////////" m0 X1 ^0 e; z) |5 e9 X" v
3 x- }  }3 ~9 a" I+ }
NTSTATUS
0 x6 m6 e! ?+ F# I4 s$ ^3 DAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
" d7 f1 j" `: H9 l                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象. r  z- h; e' \( H* E; e. k
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
4 L8 {* a/ o+ n/ f! k$ J, ~{
  f6 h! s: O% w9 a- ^3 \  PDEVICE_OBJECT DeviceObject; $ S4 }8 q1 t3 I7 S1 y; x. ?3 s- E
  PDEVICE_OBJECT FilterDeviceObject;/ b- l" h5 H6 q( k
  PDEVICE_OBJECT TargetDevice; 8 i. U! n+ z/ D3 c. ^  }# N3 s
  PFILE_OBJECT FileObject; $ [% [5 O" M; k& d
  PDEVICE_EXTENSION DevExt;
2 n. J* N& B) h8 b+ j& Z: r4 t- G2 H( L1 E( q+ _2 p
  NTSTATUS ntStatus; ' Z8 @, R5 d4 F0 K% u. X6 V7 ]1 B

5 R$ X& b6 `1 c+ L5 M  //! d- _2 p0 T7 ?( @" u
  // 根据设备名称找到需要附加的设备对象
* V2 j# j. k/ d; t/ U, C  //
; {! O0 q! q/ c  ntStatus = IoGetDeviceObjectPointer( DeviceName,
) l4 ~% M$ A3 P" w+ q- c4 S                                       FILE_ALL_ACCESS,
! ]8 U9 D- g/ R                                       &FileObject,
6 R2 U+ R. z' o: _                                       &DeviceObject );
1 T$ P- U9 w8 H8 Z8 c8 u2 h- N2 x6 `) w6 G+ F- V1 k2 K/ S+ [6 y3 L* L- Y
  if ( !NT_SUCCESS( ntStatus ) )9 N, ]) J: U' e' |
  {
9 G5 K& B/ j0 }3 Z$ d    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
5 u3 ~! Q0 N$ Q2 X- P/ t    return ntStatus;& P* D1 D$ }4 S9 r) Z0 q0 p
  }
8 {0 E& x$ \9 ?- v/ H: E' ?, Z- U" f! [4 A' G
  //
% o* A3 M: Y8 ]  f  t  // 创建过滤设备对象$ x+ e7 o+ {5 T* w1 x- V' n
  //! ^8 \" H  ^, W3 C2 \
  ntStatus = IoCreateDevice( DriverObject,) p# r& O! I- \  b8 e1 L
                             sizeof( DEVICE_EXTENSION ),
) u( t0 F& x) v, `, X$ R" |                             NULL,
3 `, v0 z: ^& a% z8 Z                             FILE_DEVICE_KEYBOARD,
5 x  d- ?: J% C; _* ?                             0,
, o8 f& s9 M5 @" k                             FALSE,
5 x( W8 ~: i3 E                             &FilterDeviceObject );   B) t9 z- k: s3 U9 d) S' V

$ k- X% ]* S$ Z& @- _6 x  if ( !NT_SUCCESS( ntStatus ) )
5 T7 b7 J7 J' K3 N  {) H4 }& t; C! P: \- h8 n8 f
    ObDereferenceObject( FileObject ); ; t1 p: p. j: u$ P6 b! B
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
- a3 J  t# c8 u  Q    return ntStatus;
0 l  U6 b- q* J  T  }
3 W* _" ?1 J2 }; A4 r) l. m9 n5 l2 P5 c7 s
  //2 h/ i8 h6 t: ~! i* A; |1 U
  // 得到设备扩展结构,以便下面保存过滤设备信息  X- b( n* Z( _% a: _
  //
- t3 m* O/ C/ C5 ~: o  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
  H9 V- q2 x$ R8 m0 o, b
$ E/ Z4 c- }1 K5 ^! Z/ q; H( k3 q& m: }. X; z) @1 N
  //
4 N8 S. H0 v% h9 N  // 初始化自旋锁5 ^& o: A4 v$ R" ]" o
  //% k2 t% t1 x5 h+ q& x
  KeInitializeSpinLock( &DevExt->SpinLock );2 @& M* L- D* d) N7 T
4 z  Y4 t$ [: A& y: b3 z
  //7 }! `5 P" z( g9 n
  // 初始化 IRP 计数器
+ m: x# w; F$ {, k$ h  h' Q* B  //
( m) k, m1 a, Z% {  DevExt->IrpsInProgress = 0;: Z  C7 m  Y2 M: I$ c
0 i, L( H/ I; y! U
  //
( g  i' n7 N) B2 [+ k$ s! u/ o4 m0 ?  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象% B: q) D. @5 Q/ c" e; S
  //2 A0 s4 a: v- y
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
$ r% w, H1 H! O                                              DeviceObject );
  Y" C5 A# W1 ~) g1 c+ r6 J  if ( !TargetDevice )
& f! i, G1 n; q2 h  {& M/ y8 b) f; j
    ObDereferenceObject( FileObject ); 0 f; f' P. R3 H! z' j! E: N. \  ^
    IoDeleteDevice( FilterDeviceObject );
0 _! @8 ^! r9 I9 T" }* U) U5 ^2 ]; z    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
: ^. u9 t+ D) H7 s; K( j8 |+ T    return STATUS_INSUFFICIENT_RESOURCES;# Q2 _) N* m% p4 s# @
  }
  l. x9 m0 v# `# A
9 d7 x& n  [# o) f! [  //! M' n$ E2 Y' B% |) L
  // 保存过滤设备信息1 u# T( V- g3 M1 j$ g" f
  //
2 {( [* K! S( P, i- P! S' W  DevExt->DeviceObject = FilterDeviceObject;   _1 i6 G& U  Z3 i: w/ q4 @. [
  DevExt->TargetDevice = TargetDevice; % K3 ]% g6 ~  {
  DevExt->pFilterFileObject = FileObject;
& V  o3 s6 k6 k) ~. N3 b0 X8 W9 ]- K. r; z' {
  //
  C5 {' T1 a6 n6 D% M  G- D  // 设置过滤设备相关信息与标志' I9 V  X. ]$ h, x& v. V' [
  //; D6 F" ?0 W# z2 N; J% r! [, K# x
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
' }1 _; u: c) h( O; ?3 T5 S+ ]% O  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; ) A0 _7 U9 y0 k  V5 ]  ^0 S) H3 W
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
8 ?# O. P0 q  W/ ^  X" C1 l/ {  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |+ Z; _9 L5 Z6 L( y8 \: j* }, Q5 H
                                                         DO_BUFFERED_IO ) ); . C* H$ [5 \" [1 ~1 B
3 Y" }% y( c% k/ d& r( ^! \
  //
, g/ C3 }' d: }  y3 `) R$ G0 e  // 返回附加后的驱动对象% N0 I* s- [0 v8 ~2 m
  //
) a; E( g9 a3 j, D  *FilterDriverObject = TargetDevice->DriverObject;4 J4 F1 I. z2 S3 M& n

; C9 X7 N  r% C0 X; R  ObDereferenceObject( FileObject );
" D0 Y% a9 c# Z7 _# P6 D4 u* s+ @( i/ @) G3 W
  return STATUS_SUCCESS;
* b! V- Y/ O4 X2 R1 T7 G0 U}$ N7 E. [# M5 [) D7 ]& D3 @( A9 [

0 F! F( b. p, n( a7 \: [( @/////////////////////////////////////////////////////////////////: c! N& W" x, Z; c4 g
// 函数类型 : 自定义工具函数
6 W! A. U9 T$ N, g+ F" ?// 函数模块 : 键盘过滤模块$ K  u3 v  u& f) u
////////////////////////////////////////////////////////////////
' u! B: M- m: I4 \3 x3 m2 D9 E// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发8 {# P, q3 n$ q6 H: g* ]: j# v
//        这个 IRP 的完成# B/ i8 P7 L6 u8 ?; D
// 注意 : - [& a$ h" x8 J3 r
/////////////////////////////////////////////////////////////////
' B0 F4 C7 `/ Z! y// 作者 : sinister( v% Y% M) i2 E% `+ e
// 发布版本 : 1.00.00. @( E0 N0 d; x% h
// 发布日期 : 2007.2.15
# V* B& Z' A: ?. Q/////////////////////////////////////////////////////////////////
1 I6 I" o0 b1 Z4 r7 c- a. C/ K// 重   大   修   改   历   史
2 F# [/ Y9 h% J. H2 b) W////////////////////////////////////////////////////////////////: p9 @. z, a7 g; C2 q
// 修改者 :
3 X0 X- z" f2 v6 x5 O: V6 B$ i// 修改日期 :
) m  r9 T$ b- g/ M: B8 W& k// 修改内容 :* e; m: S+ p3 L1 f
/////////////////////////////////////////////////////////////////
! i5 D5 _/ N# Q
  {) ^6 @; o' O9 C+ d: |$ KNTSTATUS
- `4 P7 ~* s" N9 B3 _KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )0 B7 M- L# b! c% S# L
{" O# Y. o* I3 `3 u+ K- f
  NTSTATUS status;
# e+ B3 f% H$ x3 X/ O7 a  KIRQL IrqLevel;/ F9 D  Q* @, ~& ^3 P
. t# h: {( d/ `7 A
  PDEVICE_OBJECT pDeviceObject;9 B" O3 ?- u5 A5 A
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
- Z9 k, t0 {. l                                   DeviceObject->DeviceExtension;
% G" j. ~9 T: F' n8 e0 {: Y2 J, j: k) A. n8 H; K$ M# p' ]
3 h4 Y  z5 X4 U! j+ j" B
  IoCopyCurrentIrpStackLocationToNext( Irp );3 P$ O8 Z6 a9 S6 W- v
8 L& x9 i8 _7 {* g
  //
% `0 b; g  t9 a/ h. w2 a3 l% W  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁! w7 y# x& {, {. l
  //
4 _+ {5 v8 F! a) n5 f* O! k  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );3 g4 }& U& s( T+ \3 K, D
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
4 C# s  I5 K# M+ J' F4 q  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );, l8 c0 u. A; R& m3 B

, d" B. a( b" T1 b+ M! v  IoSetCompletionRoutine( Irp,2 }1 g! _7 f) c3 K) s/ y4 F, ^5 d0 N
                          KeyReadCompletion,
. R! k: Y2 V. I3 d                          DeviceObject,8 t$ B+ i8 A- P- W5 x* L) T! V# x
                          TRUE,9 v- w- s  M, z7 E: l& B
                          TRUE,( n$ b3 n* w+ B. }8 p# O$ `
                          TRUE );
3 t- p( q" e6 |8 R# m
/ m/ F1 K) k/ f- t3 R' I  return IoCallDriver( KeyExtension->TargetDevice, Irp );
: [& V) ?- f6 j4 G! \  d, {} 0 r- p2 m/ l0 d' U7 g) Y# Z

) Q* ~* Q4 i" z) ?2 u/ O/////////////////////////////////////////////////////////////////$ B6 M, R; _: m8 a
// 函数类型 :系统回调函数
2 G+ H( m  m) y& d) r% h- r// 函数模块 : 键盘过滤模块
" Y1 j. c2 z( x9 ~////////////////////////////////////////////////////////////////
; s. k6 V+ h' G// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
/ n' Z. I$ R6 ~6 S% @// 注意 : " S8 Q5 w5 K6 A/ K' y6 F5 L$ e
/////////////////////////////////////////////////////////////////
) t- x) k5 n$ \/ A( ~// 作者 : sinister) e  T7 t$ P' |; a1 m7 g
// 发布版本 : 1.00.00
9 V: P$ F5 x" R// 发布日期 : 2007.2.12
! J. a& S, n' Q0 [/////////////////////////////////////////////////////////////////
9 U9 O3 Q* h/ q3 T4 H/ n// 重   大   修   改   历   史
' o8 r* D* i$ G2 V- N////////////////////////////////////////////////////////////////
1 @  o1 P6 K" J$ w* R// 修改者 :9 N- |5 q2 x! L" h: b3 [) @
// 修改日期 :0 a3 ]# h# j3 g3 E0 N
// 修改内容 :
/ m- i$ o8 Y4 C; P2 z/ v% G2 Z. O/////////////////////////////////////////////////////////////////
3 j: Z: N: s4 Z. o$ p
* y+ O* n+ ?. WNTSTATUS
4 S. Y+ p+ h  Q$ \* j% l8 C0 o* ^KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,9 H+ D# h9 A9 U. ~. f
                   IN PIRP Irp,6 h$ Z% g5 V2 {7 ~' k7 f% o
                   IN PVOID Context )
" s1 w2 q! d% |+ S. \! h{8 {! }3 p9 U4 E
  PIO_STACK_LOCATION IrpSp;: ?" ?  l; l- o9 [; ^$ S6 s8 y
  PKEYBOARD_INPUT_DATA KeyData;
2 O: A! o% ]2 K3 ]; K  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )  |5 ?) y7 e, N
                                   DeviceObject->DeviceExtension;
; }" ^5 ]% D$ [) ^, W' M2 _  int numKeys, i;6 U( g1 J8 Z$ k
  KIRQL IrqLevel;5 w9 q; X" B8 ]: O3 j3 h
9 Q" b3 s2 n7 v4 b% K. O! Y7 D
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
9 E* [7 ~5 T( Y& x. f
+ q# [8 a& J# `% d  c5 }. s0 C  b' r- y, b& H, R) t
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
) c$ G& k5 a; ~5 I; K* M) ]& E4 p  {
& F. j! e; J7 c! C$ @: P    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );% b  \# a" p: i2 ~' |( ]! u
    goto __RoutineEnd;
- k5 n1 t2 e/ R# d  }
* @; w5 A9 Z- m- R; _) O
- l6 r4 @- `9 {: ~  //
+ z3 J1 R4 }, S0 m$ C! [  // 系统在 SystemBuffer 中保存按键信息
4 X5 v3 z- m! _3 ?! E  //
! {# q' A. W5 _+ r  KeyData = Irp->AssociatedIrp.SystemBuffer;
3 w7 z: g  o1 a) R2 u9 T* Q  if ( KeyData == NULL )
2 R! o8 k3 F$ T# [7 e, K: ]  {, M1 d4 |6 E5 c( o" Q& D5 F
    DbgPrint( "KeyData is NULL\n" );, |2 l% u9 x- a/ H. ?
    goto __RoutineEnd;( F4 V' o# P7 N: Q8 b: S) K
  }
- v: i  }  p4 [1 E6 ]  I
: X. i) E, \2 |0 I  //' E0 v; {; V6 P5 ]0 q
  // 得到按键数8 V( G9 ]* z9 @' {. d# v+ S7 M9 \
  //
# \2 v! X0 y1 Y7 V' X9 d2 j1 F  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
' e# s6 ~+ @6 h0 Z8 ?4 N$ \  if ( numKeys < 0 )4 T$ j% r! C0 U% b0 j+ ]
  {# I, m+ n; ~* k9 P$ j
    DbgPrint( "numKeys less zero\n" );
' h9 V6 \, m- L3 d7 u  @    goto __RoutineEnd;8 P4 t  e3 f7 v) B8 p. a
  }
& B  w3 p& H8 b' l7 x* E. Z
$ P) z$ r  R7 W7 e/ a3 l  //, h6 i. H. U4 N% R* t/ Q' b
  // 使用 0 无效扫描码替换,屏蔽所有按键
. P0 F2 m" A4 z1 ^; u0 ~, t" F3 X  //1 Q" x' K# R+ |( Z1 m( O
  for ( i = 0; i < numKeys; i++ )6 g9 t& o9 {7 ^1 t" n( w
  {
! P' k% B* C9 [$ m$ L+ o' P    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );$ U8 C+ ]  Q( ?
    KeyData[i].MakeCode = 0x00;: A; w5 u' c* Y! o- U! S
  }6 {% W, O5 L9 i  A9 K/ x
1 T+ {# h# k& o0 o+ @5 o
* b8 ?) b1 d5 }! e- w: _
  __RoutineEnd :   r2 F9 C) ?9 d* q7 E1 S9 f
7 y4 U: E7 |, i- g4 r! o/ ?) {
  if ( Irp->PendingReturned )+ X+ Y- g) s  j) Y$ Z
  {
: m$ V& u7 C& R5 _' g) c    IoMarkIrpPending( Irp );
2 b" k/ _/ ]" J8 ^$ h5 j/ \  }
1 u" ?) C8 j' p
9 Q) T( H  [, R; @' H  //
$ l4 P' A6 y- L+ z1 B& a. P% `. V  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁2 N7 x$ J5 [) o) w$ h
  //0 Z. ?, l, }8 N
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );' C# y  v7 X1 m) N0 P: L
  InterlockedDecrement( &KeyExtension->IrpsInProgress );3 n. H4 Z2 I- _$ e+ s! C' w
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
3 }2 E2 L* m2 W! ?; V8 N3 k- o/ M' s! G/ C! }5 D* |
  return Irp->IoStatus.Status ;
4 t0 L; v: a# u& z- K} . r0 ~  ^* \- _( u$ _* h

( W; u" c1 w* {4 B  D* [* H2 g
/*****************************************************************
5 R  n4 }. Z5 ^1 i) b) O; H 文件名        : WssLockKey.h7 J1 U. D5 G4 O2 N: p4 U; U
描述          : 键盘过滤驱动
) A5 C- C( q( G6 S. W2 ~ 作者          : sinister
0 D* q1 ~' z0 _- g1 o6 J 最后修改日期  : 2007-02-26
4 ?# }  ?: ~8 J4 [! F  t*****************************************************************/
  k. z- H, i- A" j/ A! S
5 ?0 g, k* @3 V8 }) w) T#ifndef __WSS_LOCKKEY_H_( W# w8 y; `8 ?) K
#define __WSS_LOCKKEY_H_
; b* u2 m  }( p6 B8 `# _$ ]- K( h1 |+ W  v" \9 K* b
#include "ntddk.h"
( T3 G6 [9 i- O9 \#include "ntddkbd.h"
7 j2 ^. c- k# w* L#include "string.h"# J5 O+ N* S" v2 B5 \; }
#include ' e7 n$ ?) q7 s/ \8 \

! x. i! q! x0 K& v- l7 g0 Q7 ^5 L#define MAXLEN 256
  c$ M# w5 u) B" Z* T3 E2 |( g6 m
#define KDBDEVICENAME L"\\Driver\\kbdhid"
- c0 }- x* n0 {3 M- G- @! U#define USBKEYBOARDNAME L"\\Driver\\hidusb"
8 @. j# L+ [, Y8 }* M" k( `1 @  O#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
$ o- k) X/ X- E# Z+ _$ U+ E6 P' p# R+ X  w
typedef struct _OBJECT_CREATE_INFORMATION, A. I! ]! u/ _3 d0 x" s% ]% z/ F
{% Q" M$ L9 p' w( Y
    ULONG Attributes;' p3 j9 }; F, u/ d. L% [
    HANDLE RootDirectory;  u; h8 b, ]) \( g4 w! }- V
    PVOID ParseContext;/ A6 B% @# r* T! y, i
    KPROCESSOR_MODE ProbeMode;$ x6 _, s: w( Q3 ?7 W
    ULONG PagedPoolCharge;: t' I: }# S& o2 E' p/ f- i& ?
    ULONG NonPagedPoolCharge;* E# F6 n/ m- [; z6 e
    ULONG SecurityDescriptorCharge;6 L; E1 t2 g5 o( \! Z3 s# ^/ o
    PSECURITY_DESCRIPTOR SecurityDescriptor;
. ~$ ]6 N/ [; v) ?4 Z    PSECURITY_QUALITY_OF_SERVICE SecurityQos;2 I4 h' D9 X7 C0 j1 Q: c
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;8 x6 C2 O/ I7 r& |' ?/ r# m( n
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;, Z4 ?5 f9 k  n( i# G' _
( z5 k' ~% \2 L2 o
typedef struct _OBJECT_HEADER& F8 L6 I9 f' |' d( A" ~* r$ b
{
/ _* n- }& |& l+ `1 `3 U2 l    LONG PointerCount;
0 x4 y) t" C2 V& c7 F9 t5 k& g) d/ C3 ^    union
* ]$ u: \/ m  I% [" G- D5 |( v    {9 S5 u7 |. C  s
        LONG HandleCount;
+ ?% |5 T9 |+ e/ u1 w        PSINGLE_LIST_ENTRY SEntry;
: c0 a0 L. h: b& I    };
8 v+ {/ y; @! l3 B" P( X/ P' e    POBJECT_TYPE Type;3 V! l+ q; h, u& E( T0 C
    UCHAR NameInfoOffset;
. W) K; P5 S+ C" Z" C    UCHAR HandleInfoOffset;
$ F# \2 X0 A' |5 Y; s* ~    UCHAR QuotaInfoOffset;
" R  h: C- x6 J9 W/ @    UCHAR Flags;* [0 C4 C6 C% Z; |
    union
% X3 v+ z( H/ f" c7 T    {- j1 ^  m9 V& m( G. v
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;  B# ]! Z5 M; B
        PVOID QuotaBlockCharged;1 t9 k, _% [7 W; O/ y+ i# x+ ]
    };
: M9 Q6 o1 w- {! ^& S& e* B4 {& @3 g' ^0 |
    PSECURITY_DESCRIPTOR SecurityDescriptor;
9 ~) ?" w" i% _' v7 Z    QUAD Body;
0 u; F- }# s9 q/ w6 S# B  j} OBJECT_HEADER, * POBJECT_HEADER;6 Q  E+ V2 x0 l3 I

3 O! g+ a" d' V8 x$ t, l#define NUMBER_HASH_BUCKETS 37' _: V+ a7 T/ V2 J4 s4 E$ A  V

1 K7 c1 x; A! L* Ktypedef struct _OBJECT_DIRECTORY, ^7 [, B1 u4 A% ^) J9 u
{; J! G. ]. M: Y* ]4 Y  R
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];. p) z; K/ p. W8 r& s' z" a
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
( t, k+ n1 y0 l" q    BOOLEAN LookupFound;/ [' p+ Q* C4 v
    USHORT SymbolicLinkUsageCount;# l( C/ \0 g- n6 E: C+ Y* L
    struct _DEVICE_MAP* DeviceMap;
8 A: A6 }( |- e0 ?} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
& T- I# \7 l( {8 U2 `- b+ r
( k, j7 K9 X( W6 |7 r+ e; Wtypedef struct _OBJECT_HEADER_NAME_INFO' U2 u* f2 y& ~
{5 v4 K9 e2 S4 t: Z9 ^
    POBJECT_DIRECTORY Directory;
7 X% i! d7 T, @' y, I    UNICODE_STRING Name;
# L8 U7 j1 L+ V8 j: W+ C  i" @    ULONG Reserved;
2 k7 ^: {7 b, w#if DBG
! j/ I; Q* X. d- ^    ULONG Reserved2 ;7 T0 i3 G2 S' l( v' Z8 r4 p
    LONG DbgDereferenceCount ;
$ @* Y5 v0 ~; f3 S#endif
) u& ]& g# h9 v& Q} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
4 W3 _- h  k3 U! r) o; Y. s$ [
: M4 _* E# V' X9 s9 m& N8 Y6 Y#define OBJECT_TO_OBJECT_HEADER( o ) \& L- M: u1 r0 V/ l  U3 ]4 o
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
6 E6 o, D6 v7 f6 e9 F
! z% Q' Y" g3 |' `#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
; {5 S& [' h: E6 J$ ]( m) T    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset))), J0 V0 u" T2 A9 P) G  a) A

, D& G0 y: v4 D4 m  K! xtypedef struct _DEVICE_EXTENSION- s- w$ z1 R" h( U6 d
{" F; }  K: F* S0 L# I9 W
    PDEVICE_OBJECT DeviceObject;0 o- \. D7 H2 Y4 w  A2 s
    PDEVICE_OBJECT TargetDevice;
2 e+ G5 J7 I$ k  M4 L    PFILE_OBJECT pFilterFileObject;; I% ~: L; K# t4 g. v" r
    ULONG DeviceExtensionFlags;
/ ]6 r# W/ A& y% p! P0 c    LONG IrpsInProgress;1 Y, S9 Q  F/ o0 q; d* {
    KSPIN_LOCK SpinLock;- l" o) ^; _% f5 }0 w. ?. I# ~
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;( j/ s: h: k5 @5 V1 e+ ?
5 Q* N; B3 K& k" o; b: }
/ h- v4 e. a/ \; t
VOID
3 `9 w# ]+ [; \8 K  v! \/ G. YKeyDriverUnload( PDRIVER_OBJECT KeyDriver );; b8 H$ V+ k9 s! m* {% ]! q
; C9 s. t% V' t% u) c/ B
BOOLEAN
5 V) V$ S0 u8 Q4 X+ S) Q' FCancelKeyboardIrp( IN PIRP Irp );
+ e5 I: e. a4 q& L6 P% c
9 i# w9 J' X! ]7 ~8 Bextern POBJECT_TYPE* IoDriverObjectType;
  Y7 m, I: l( y5 i$ g, E# i, C- u) e' R& u
NTSYSAPI
  j& r9 f  Z3 ?: [( A( nNTSTATUS
7 a" `6 ?  a: e3 A5 ^% cNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
% b2 d4 d# [; x7 v7 Q                               IN ULONG Attributes,
, I* `( n2 }9 {. h, P                               IN PACCESS_STATE AccessState OPTIONAL,
& d- U9 H- V6 H1 n; H; h; ^                               IN ACCESS_MASK DesiredAccess OPTIONAL,
3 {- l! i" T, T( R$ M9 f                               IN POBJECT_TYPE ObjectType,
! W1 I/ m% ?$ F$ r3 c6 e                               IN KPROCESSOR_MODE AccessMode,2 G* V: [5 \- h6 P7 o- U& R
                               IN OUT PVOID ParseContext OPTIONAL,$ B# V, p6 v3 S6 H
                               OUT PVOID* Object );
, h/ J6 w, f% T4 @! |$ w! j# c, e$ t8 o( c$ F0 V
NTSTATUS " b: u  x; k9 Z: D- I" V
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );3 m6 V+ g4 s4 H/ Q1 X, Y# L( `
* h3 o# r8 \9 q% j( n
BOOLEAN ; M# n* m8 A9 L/ @  O' f3 q
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
: s$ p2 p6 s- b5 W. _- \! U3 D+ z
6 }! d5 i" u3 Q+ |7 k  V# \4 nVOID : X/ ~& ~4 {9 f. a
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );8 u1 R5 }  R7 V1 U- j4 L5 [. {' h

. ^" p2 P$ A. D2 ~1 ZNTSTATUS
$ A  V7 B0 e" q" ~, DAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,( w+ l) e0 h% w
                                  IN PDRIVER_OBJECT  DriverObject );
' ~# L, V+ s% t# `0 ]6 b8 m
$ W/ Q$ f" y6 ^3 P$ jNTSTATUS
. o* A1 c2 }* j: t) e+ j4 pAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
6 u: f8 s9 K' z) {9 R9 w3 |3 V                                  IN PDRIVER_OBJECT  DriverObject,$ Q# D3 f$ F/ J
                                  OUT PDRIVER_OBJECT* FilterDriverObject );4 c* l- K" k9 H, |& G: P
( ~4 x3 `% _! I6 Y3 e; g4 H/ u
NTSTATUS
- B" I1 p; Y* o/ F  V$ j1 `KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
+ M5 H- h- E3 E9 a                            IN PIRP Irp," H4 f0 ~$ P4 ~
                            IN PVOID Context );% D0 p# H, `* }  `8 g1 g
NTSTATUS * S* O) I  c$ v7 y1 a  r( Z  B
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );3 M/ t7 N0 F5 ]3 F4 N

: q2 w. l# b" i) l1 {; PWCHAR szUsbDeviceName[MAXLEN];+ l- z: K3 @- m5 F- j8 D, X
1 M. r, g6 b7 }  _6 A) g
#endif
+ \9 A/ Z3 B7 v) q% m6 z' }
' M$ ]0 G: X7 ?
+ e5 T, m- [9 I5 r3 r+ [
$ d/ e2 X' n; P' k6 H( V' q4 a, t
8 Y8 Y& I6 T  {  [& V' l0 X( A# `$ J3 i8 G* H; [! Y  x
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。# U! N4 z1 I7 Y) v- _- T9 O
WSS 主页:[url]http://www.whitecell.org/[/url] ; x! j; e* X. e' k- k
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-10-12 06:52 , Processed in 2.559258 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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