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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister% l, y( k7 j/ W, {3 R
Email:   [email]sinister@whitecell.org[/email]
5 K: ~+ G5 a, Q# FHomepage:[url]http://www.whitecell.org[/url] - y! t+ r: K0 R7 m
Date:    2007-02-26
: P  d, V4 b' ]3 S# r3 x3 H" Q' x4 E
6 D& ^2 C& }; a7 t5 ]
/*******************************************************************2 l6 W; f* O0 {( C& i2 m

+ W* G5 m( ^' |) B8 T/ q这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx. G* s; |. H' V: ^
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的3 ~6 |5 U! p1 G9 {1 w7 T4 R
功能要求如下:
( F+ F  |% c- }1 s5 P" g2 T5 P1 @: `( ]) a
1、强制锁定键盘/鼠标。' j6 o" t/ X' k
2、可动态加/解锁
, z; U# |+ l6 l% P3、兼容所有 NT 系列的操作系统。; C6 g- C' h: y
! y( n3 g/ F8 J
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实# h) n! }6 d7 [9 N7 p
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
1 q, j- @6 ~+ {何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在" d4 ^. v+ R2 _2 a; V% ~. t3 H* ^
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
" x/ Y6 c  [) ^3 `怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面/ f6 j2 t; b: F6 y& k; c- a
就来看一下我想到的几种实现方法:; q3 W2 ?+ K* ~! ?8 {! @! E. ], y
* f1 |9 |4 k9 ]: d4 p
1、全局键盘/鼠标钩子% U- P, \& l2 j- ]4 [  b# n4 K; b+ F
2、BlockInput() API
( t, e3 n8 G  b: e8 d3、使用 setupapi 进行控制
4 S9 c5 Y1 F. T& F& c4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL  r8 `9 a! A4 a# o7 x) C4 y* \# }, K
5、拦截 win23k!RawInputThread() 函数. `6 g+ [/ N! [: J8 i7 h  ^. _
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动! B( J! _4 M! I: F* B
7、拦截 kdbclass 驱动的 driver dispatch routine& @9 i2 |& N" M
8、实现一个 PS/2 与 USB 键盘过滤驱动
- Y7 _4 K1 v, h2 L! [. b8 R6 j& \% E, C5 ]" y' P% `6 P
) |3 `% A& J) w: p3 g
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
  R5 S$ D! A4 d, x( [之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
5 I" c$ J" w/ [& F案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
4 |) R9 U2 p7 U! i兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
7 U  K8 q6 H4 I) W7 d! ^1 Y+ S9 V素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性: n3 H) I  }" L) }0 {
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸6 d; |% z' t/ R& U
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
7 a, _% R7 E8 ~: \的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来4 }! _3 r% ~; {) f# q$ D8 h; ]
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如# _: S, _/ \/ f) ~
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有; l, B7 a: C9 s1 K- {. K
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截3 ?& U6 u2 P4 P2 H% A
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 7 U: ^; c8 u+ ~7 O2 m
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键" s  B* o* e2 i4 m
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
# B$ M* x- n, `1 y- Q案的全部功能且不存在它所带来的问题,否则就没有什么意义了。: b' P" a! \4 u4 }+ l

: t6 Z8 L  E1 k/ q2 z9 p: F6 h' d( A6 v4 y/ \2 v# m
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过& n6 k; [" G) O/ ^3 w5 y& V
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进* j+ h( d0 e: f( m  j
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
' p5 o' b+ h  b" }) n. F7 k只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
% V# z  D% Z% v3 q$ s$ F来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
  X+ Q0 v; z: o# h+ E- BKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
3 U1 b6 ]3 q3 H+ V' T$ L键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
% C  x/ S& Y7 H0 x0 A% _; lIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,6 o9 N& D. ^6 ?8 l3 N
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题0 P; B$ ?" T/ B3 y3 p3 |2 [
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
  U7 p6 L) _, F/ x+ e而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
7 @  m) l* F/ W6 d9 R用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
, c/ l, Z0 q1 c2 t过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
- }$ ]' [: A3 I0 Z7 d屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通7 i6 `, d9 A9 E# ]5 N
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
" k  A2 z9 {4 X& C) |3 j' Z上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
9 r, R, W4 H/ J# _$ O- T1 B- \6 ~: P的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意( q( k- _7 Z9 b! k
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。, ?- [9 W* D: ^4 x( N8 ~
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们# ^/ J# m  o9 ]
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利/ K, V  k+ e+ D4 }/ E2 s( w$ v
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
3 {/ D( B! w3 P) |* \的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致4 m  ~9 A- S/ V' i, W8 F3 S! w
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
% A' p* K3 F' h& y+ u; F根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
+ `% M/ l* w; d& K' g' D  w  K$ k! a见下面代码。
* M& E' o$ B( d* H" b! G! n) ~; N6 V9 p% c$ g3 ~% c0 z) J* V5 J
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
; c( X/ E2 F# \里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
+ @: E5 T& o/ f3 j/ a盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
8 _8 i% b- w6 Z  k上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
6 c7 G  B1 {4 T完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
' P/ g7 y/ M& ~, ^' ~5 C. F! s5 G继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
2 S' u; N+ z' N% H锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
) P( K2 C/ p! ]4 c3 U/ t键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。0 X, P  V- _' Z' r$ Q. g5 o

( @) j/ r/ F/ {% p1 i
  V/ ^( g+ @- f" g* a完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用% J! @/ ]1 B& k2 n, T+ u' d' P
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是+ L: G7 t! Y% C6 i
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣, B' \5 [3 _8 j- U/ |- E$ j
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我8 Y& h  E, F* Z: ^0 ~% b7 ^3 _
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
# x7 A0 |' A# c' l们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
! ]. ]# y. w. Y5 u: l* m->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。; D  o! W* Q  d/ ^: R
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
5 o4 p$ z5 a# a进行操作了。这个问题有待大家来完善了。
& V1 q" ]) _0 ^4 `( c" u$ C2 X0 l! _

! V, K& ]5 \. @  b! s) P" a要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出! H7 x  @: ~) q2 o, ]
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
6 b) i& v9 x, n! I/ y分析做个记录而已。我更愿意把它看做是一段注释。
: f0 _" n  Y/ ]# R( Y( P6 o. _4 m$ z2 m3 @" B
最后在此代码中要' n; X. @) F5 C) E2 ]* B! C. r( m

- I+ J0 S" e( `  D5 Y+ g感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。& x5 |6 U% h# D9 ]8 s
/ p5 b: {8 z( d- W2 e" E& d1 h8 I
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。+ {- z& D7 S# W/ k+ a8 e$ Z9 i
. E( _4 K3 k9 i0 x1 Q  q" G( A* ]
感谢:齐佳佳,过节请我吃好吃的。6 B$ t) T6 o& k% H$ b
' [5 c3 h. ~6 t7 P' Z7 r
% b0 w+ C& {- f' e' d8 T- E
******************************************************************/1 L6 H7 o3 R7 U9 f0 R
, }: b7 b2 J7 M! w
4 Y  d5 u8 O- ~6 Z% G3 V
/*****************************************************************
: ]1 q9 R& }' |3 L$ x- q  I8 `; Y 文件名        : WssLockKey.c9 @) D8 }7 Q) m
描述          : 键盘过滤驱动
* e% N1 Z$ U) e" E$ s0 k 作者          : sinister
; y; Q3 }4 B( {- t' | 最后修改日期  : 2007-02-26
. _& c: V2 g* ]*****************************************************************/
$ L/ [+ W  U' V  h5 g  h
5 a% o) B. g% Q$ @0 Y) {  Q9 \
0 W' H% E% p  C! e$ `- u/ q#include "WssLockKey.h"+ A1 H3 R# A4 s! K9 p

6 a, I/ R& I# Y6 t8 Z7 XNTSTATUS& a! p& ?- R  v6 p4 R; h5 g1 z0 c
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,7 i+ a' l. D2 ~. ~4 i2 \6 v
             IN PUNICODE_STRING RegistryPath )
% G! k2 r' b* J: o{
' {8 K# r2 X: r3 g' O/ }, N. {  UNICODE_STRING KeyDeviceName; ' R# C5 ]$ B$ {) _, n7 H$ V* R' {
  PDRIVER_OBJECT KeyDriver;
$ I4 q) X5 s! }# \0 m1 j# ?2 H  PDEVICE_OBJECT UsbDeviceObject;4 _! n4 K1 M! n
  NTSTATUS ntStatus; 5 {6 B( G) U1 t  i$ n; [5 F
  ULONG i;
. ?. w" M0 G' A$ l- Y" {
& _# `% Z8 y( C8 ~  //
$ u% `! \4 I" F" X4 @  // 保存设备名,调试使用
. e* d0 O0 n6 s9 ]/ B" a  //$ J9 s' M" V, R5 H
  WCHAR szDeviceName[MAXLEN + MAXLEN] =$ O" a1 |5 I8 f; m4 Z9 e! L
  {
3 C7 O/ K2 _! c6 z* u7 q. \6 B" ~    01 ?  j" d, V- e/ L+ A8 }# A! d
  };
: [) g% J2 N: Y# e
, [- }! ^1 }' }' V$ O  KeyDriverObject->DriverUnload = KeyDriverUnload; % Z; M: J# k1 N/ J4 S6 N

6 X1 q! v6 v6 \/ c9 d  //* b- o1 s6 `* W5 t8 ^
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
. s5 y% t! s! ~5 h( I8 F  //; G: h! k2 b& k' m
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
1 l3 u# R9 e; X* k  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
- z4 Y& O1 B* t1 ^2 Y  F  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
; A1 L+ F2 c0 V( ]4 k  // USB 键盘设备来进行挂接1 |7 X& |% q. {5 a5 H
  //( \3 v1 z: s8 k4 a! H8 Z2 b( y
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
/ w( o! ~/ _4 o5 C/ H+ S  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
, y& ?8 B0 w! t3 c  |  {
- s5 J& q8 D+ T  Y& B    //. a* D2 z; V( {, F' I; U
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名$ D4 \+ n+ m9 u
    // 所以这里打印为空# k* J+ b4 @# U- i2 G' k7 h# [
    //
; y: Y& ?$ i0 b; l' p8 S    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD8 G' y7 |2 Z% ]
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
! [" c3 }2 o+ z2 y  [" G4 m
( I' s4 E3 ?2 u* R- f0 N    //: b5 ?, s# q% k" m2 @
    // 挂接 USB 键盘设备  y5 I$ k0 Z) U; \: e' {& F
    //- U6 L/ I+ S8 ^; _
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );: C% m! X3 R% I$ j7 @
    if ( !NT_SUCCESS( ntStatus ) )
9 c! S  H* @% b* j# ]" D, J. b    {
3 G; F& t! `6 t$ G1 o( W      DbgPrint( "Attach USB Keyboard Device to failed!\n" );  O( G0 s$ Y4 ]& ~7 L" T. x2 p/ R  h
      return STATUS_INSUFFICIENT_RESOURCES;5 N0 W0 Z4 T0 p$ `7 K: c/ U9 m
    }6 x/ q0 _, }' f/ V% g
  }, d4 l- V1 y% ~  H
  else/ X: j5 M2 x4 R$ v: Y: f8 D
  {( e+ @0 S3 P: E5 o
    //* E! t, C: C5 g" l, \/ L$ @
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备% s0 W$ ?8 j% h3 O2 ^- a5 f
    // . o2 n; P1 `. E6 L  U9 O0 P
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
: s: d- Q% B, g0 |# u) Q0 E! @/ W1 u8 e# K" q$ T7 W9 V6 W
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
4 }4 I/ f, X- g6 ?  U" a% j                                        KeyDriverObject,
. {; u' u5 [/ [( M                                        &KeyDriver );
1 a. |! V0 F7 Z+ i! z    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )5 i4 ~5 K) i$ }" y4 |
    {2 ~$ ~$ H- A5 T' W. @
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
8 g  O" C7 }7 M% S. X      return STATUS_INSUFFICIENT_RESOURCES;6 h1 B4 o$ i7 C3 Q8 u# }
    }  v$ o# r  t) ^9 p* I
  }+ U0 b& z& A8 y7 E
/ J& T+ @: _. @+ N8 v2 i2 s
  //
0 }- Y) [7 {6 a. ~2 }  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
" V% i4 F/ G/ k4 I! Q5 Q$ \% |' B! N  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
% q1 d" P: h. r" m- J9 O  //
# h7 X+ j( `. {5 V+ x  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; , o3 G  D  ~7 s. s( f

. _0 e2 G# M! j, C  return STATUS_SUCCESS;5 k9 l, r9 z% N0 z
}
) t9 X) U1 D! ~& N: J3 r5 h4 p8 ]! ~2 @
/////////////////////////////////////////////////////////////////& |5 _/ e2 |4 o( F; _, B2 E' X
// 函数类型 : 系统函数) ?3 G1 m8 a9 V& c
// 函数模块 : 键盘过滤模块5 h. I# d0 ~8 i0 h2 M% \
////////////////////////////////////////////////////////////////
8 p9 o/ t3 r$ L- N" r: j// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
  c! Q- J& C/ m" S# s) {: X$ r//        卸载键盘过滤驱动7 {6 Q" p$ Z* H2 R3 f
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上, M, T  R. J+ W% w% F* U' M4 S5 r
//        则需要等待用户按键,以后有待完善
' X  ^% Y# ]& r' j/ M/////////////////////////////////////////////////////////////////4 V; o: f# X: ]: b" [7 R0 J
// 作者 : sinister
; E* C8 f, A6 g& h1 R5 N* s4 q( {// 发布版本 : 1.00.00
/ }4 {  D: P3 M0 r// 发布日期 : 2005.12.273 A* ]' `0 m0 D3 f, K2 O
/////////////////////////////////////////////////////////////////
$ f+ U! W' O, M7 p// 重   大   修   改   历   史0 O: a" d; U, ?/ M7 e5 @0 K
////////////////////////////////////////////////////////////////
7 R, E6 r0 j- v& D// 修改者 :8 ^$ G$ b& v% I1 \- ~6 T
// 修改日期 :
7 B2 K3 ]% ^, s+ F9 j( Z// 修改内容 :
, _' x& e6 F0 N& V/////////////////////////////////////////////////////////////////, B3 B/ _* R! v) J

0 P- g$ i- A% K0 F4 FVOID
9 |; O- y1 H0 l2 Q1 KKeyDriverUnload( PDRIVER_OBJECT KeyDriver )) X: S$ Z' I+ j+ A
{, @) R2 c# m( z- C, E
  PDEVICE_OBJECT KeyFilterDevice ;      
1 T! \( E8 [% v0 }3 c  PDEVICE_OBJECT KeyDevice ;! ]' W) o: N+ y3 `
  PDEVICE_EXTENSION KeyExtension; 3 o$ {* D5 h2 ^6 y
  PIRP Irp;9 z( f6 t3 J; `$ X) ?4 \' J
  NTSTATUS ntStatus;
4 {! a- Z! k  i% `1 U
6 f# p# |+ I9 N  KeyFilterDevice = KeyDriver->DeviceObject;
  Z, y0 T& R* W: D  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
1 Y3 ^0 p3 V# N' ]/ H! ]# y  KeyDevice = KeyExtension->TargetDevice; " p" j; t/ ?- Q4 Q
# M( V# O1 H8 L8 a# Q- \5 I
  IoDetachDevice( KeyDevice ); $ e2 |+ I' G) R) Q' B0 g( i

/ _0 _! p4 {; F9 A  //
" C! x0 I9 t4 t  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
- G( x. g: D5 _- L6 Z  //% v/ C) A: @3 X; w  U
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
' n4 M7 `+ C% O, s$ M- m  {/ s. e6 Q3 C! ]0 p, P. v
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
1 e% i, J  q5 V    {) j  I8 h! z) }9 R, i% M
      //# v0 ^. U% P5 H4 S; y, w; q2 F
      // 成功则直接退出删除键盘过滤设备
+ ^; h* M4 X) P) i4 ?# V      /// _, U% J+ b6 i4 L1 Y3 k
      DbgPrint( "CancelKeyboardIrp() is ok\n" );2 R% R: U$ i5 J, c9 y
      goto __End;
& W6 w+ s) k' f! W% P    }2 T3 {0 E8 R; l  ]6 ]
  }
1 D" w% X8 h. o, ]* ^# x9 g6 A# `
$ Q1 Y2 b8 s  G! Y( I- l/ M0 G; Y! h  //
$ j  K  {* l9 m5 c' L5 m8 C) k  // 如果取消失败,则一直等待按键
9 P, G: \; D, [$ @! }. G  //
% e+ I& `% M, A; ]6 [  while ( KeyExtension->IrpsInProgress > 0 )! X- ?! ?4 O2 S. n
  {  `, r8 Q5 i7 f; _5 F
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );' l7 ?9 m& _' t* U  v/ o
  }8 {& }- ]( v7 d& ?  ~
2 Y& j- R3 Z. x+ j! [! _
  __End:1 j) l* n: w% d, {
  IoDeleteDevice( KeyFilterDevice ); 6 K  N. b* s' `. N+ Y
& ^! t4 m6 j; C- t
  return ;* }/ w& [5 A( j1 E- ^3 |4 U
}
& s. o; O5 N  e. O" E2 z
! @0 R6 U2 @" D, R" S6 h& R# ]+ c) P; k/////////////////////////////////////////////////////////////////
) D/ f7 s; s# ~; I! b1 p// 函数类型 : 自定义工具函数
8 m) _1 w% o+ d# F, V$ H# v// 函数模块 : 键盘过滤模块/ ~- s3 }0 n8 A; A9 b
/////////////////////////////////////////////////////////////////
  K  o1 u/ j( t6 _$ B7 h" m// 功能 : 取消 IRP 操作- L2 u6 ]* h0 T6 f
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能' U4 i4 t: X! ]
//        使用此方法来取消 IRP/ j' g1 H& l- L: ]
/////////////////////////////////////////////////////////////////7 k6 [. {" z, P
// 作者 : sinister
6 ~1 W  a- h8 S  h- w// 发布版本 : 1.00.00
/ Z9 q0 v6 n5 w; c& C* C// 发布日期 : 2007.02.20
( v$ Y+ ]5 z" l1 q* R* w5 s/////////////////////////////////////////////////////////////////$ E) r& X6 r3 T9 m/ j" u6 X+ h" M# P
// 重   大   修   改   历   史
* ?5 P; n2 A$ ]& s* R/////////////////////////////////////////////////////////////////
5 N7 Z8 t% ]7 {// 修改者 :
# Z: w- x$ c% [' S( h6 K  P// 修改日期 : 1 }! `* p# ~6 W5 u7 Y2 a$ U/ E
// 修改内容 : 2 j; w/ Q) J2 R8 n: i) L) ?
/////////////////////////////////////////////////////////////////. q5 C$ M9 m; f( |8 L
. @$ k$ N& u# [  @' V3 B/ P
BOOLEAN
- |' @. `7 a5 vCancelKeyboardIrp( IN PIRP Irp )# a4 F+ G8 d3 T% z; X4 b
{5 D* {7 k2 H6 m+ E( m. `. a5 K
  if ( Irp == NULL )
5 U6 K+ |! h  x  Q9 Z1 k; D  {7 K* j2 J; p8 R% m: R$ L5 O4 L4 G0 K0 W5 h
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );( F1 Y8 v2 o% D1 A2 D/ q) ~
    return FALSE;
: G/ ?  ^% ^+ g+ f* \  }
$ D% {3 V/ ^( K7 f; p5 }; ]- U
- e6 }# d: j9 O7 f, n: B
" n7 [/ K$ A' D# F  //
1 t# |$ C, v; O, ?7 J* {  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
8 H! N  G- @3 q& R( m  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
, r; c" n/ C9 `# x5 j4 e  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占5 @6 k3 L3 p. J# y! z' g
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
( _& `2 q1 B, ^! \  //
( |( A- L* `8 C* u' d! C
% I8 Q# v' x6 s  //$ C  Y% Z) {+ u" z5 [3 T% R
  // 如果正在取消或没有取消例程则直接返回 FALSE% ?1 C7 k. ?: c5 U2 l& E! j
  //
3 Y+ J1 |- A8 [2 E+ T, x" G  if ( Irp->Cancel || Irp->CancelRoutine == NULL )2 ]0 b  O$ V: C' |
  {) u( t& e7 t$ n! u0 G' E/ N
    DbgPrint( "Can't Cancel the irp\n" );
6 v% ]- f/ ?! M$ L    return FALSE;) v8 O- h( B7 j4 H- ~
  }; k) p, S% T0 z* |% D. B
  [; A. Y: z0 r
  if ( FALSE == IoCancelIrp( Irp ) )
# e% B) G7 h' x% q* M2 ^  {
! U" ?: b3 q9 j7 R" Q# K    DbgPrint( "IoCancelIrp() to failed\n" );7 k- n" D% k0 `9 d
    return FALSE;: k# }" \- M# F) I+ ~
  }
: {- r/ B4 m: k! i0 J
/ T. c2 `. |; q$ a2 a& G! ?  //
0 Z1 [3 e% `3 C! a; b. G  // 取消后重设此例程为空- G2 P+ n  z. h* }
  /// ^2 u' C# F8 K4 T$ P
  IoSetCancelRoutine( Irp, NULL );
& _# o! I; _& W; Z% w! h& q) B2 G5 \, c  M& J, e# R: Z3 N" X
  return TRUE;  I  y& F8 ~* {. ^" x0 R: _
}+ p7 f3 C) {! _$ f! \

5 Y4 q5 r( u9 }& l8 z/////////////////////////////////////////////////////////////////) y$ |  R3 d4 ^, A  G& E. K1 {
// 函数类型 : 自定义工具函数- ?8 r+ Y* ]0 G, d2 h0 Z
// 函数模块 : 设备栈信息模块& b2 ~) R% x8 @$ V; D. N% L4 G+ [
/////////////////////////////////////////////////////////////////
9 y' z! r+ z5 _( F  j; e" n// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘+ F1 z' S9 A2 b/ ~( ?# j5 |% C
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
. i8 ]& l) y: t/ `  _) `6 E: A// 注意 : ' i. a4 z5 S) }3 f: b9 ?# \7 W9 V
/////////////////////////////////////////////////////////////////
2 {2 _5 c1 i9 J// 作者 : sinister
4 n: P; c* {% H& ~3 O) R! O2 q4 r// 发布版本 : 1.00.00" V6 r8 C8 [# a/ u6 ^
// 发布日期 : 2005.06.02
/ C7 z, @8 j4 Q* n/////////////////////////////////////////////////////////////////
( D$ n3 I0 K* n7 X" q+ |4 O/ y// 重   大   修   改   历   史
6 F- a9 O4 b; D6 A0 h/////////////////////////////////////////////////////////////////
+ r# j" ]# E4 ], A, Q1 T// 修改者 : sinister6 D! W( \4 n; k
// 修改日期 : 2007.2.12# u( X- Q# B! I6 R7 v3 @7 k+ R/ j* ^
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
2 C" o  L" w% P1 Y: U, ^/////////////////////////////////////////////////////////////////
0 z. j1 [' d. o- j) ?1 u; z1 r1 h
" M" Y9 o$ _/ H- Y# tBOOLEAN
* u/ V# U8 m+ H! C6 d: v8 qGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )9 d) S% F# s6 M, m6 t' {, @% H' n
{
0 _1 A( x+ k" m  PDEVICE_OBJECT DeviceObject;
7 z. K# A0 L$ Y  BOOLEAN bFound = FALSE;/ Y- U  Z5 W$ B: z) p& K' d

: \: K- Q9 N: f) x# o2 W1 p  if ( DevObj == NULL )" Q& ?0 c+ f8 T( _1 Z/ q1 J% x
  {: s# z; l- o: a% G8 }3 [# \
    DbgPrint( "DevObj is NULL!\n" );
  O& |& v1 Y- m3 S    return FALSE;% j$ a, B/ t1 T* [- j- n
  }
! R! \* m4 L6 [  H! A( X
. {- R2 `% w" ~  z: \  DeviceObject = DevObj->AttachedDevice;, K: b5 b' Z: k- Z: G  ^

: C* o, b  E! o  while ( DeviceObject )  b# c; U  a, N  _. v
  {4 }/ W; t6 e" `# j0 D
    //$ Y( S* n! z/ s
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
" }7 y. p9 S+ |0 s    // 有一次足够了。这算是经验之谈
8 O/ ]" i% p9 s    //
6 r4 j6 ?. o: O6 v* H    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
% a1 A6 a/ _: T2 o+ \    {/ R9 r& S' o# H5 g
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
4 Z2 G( _8 |. R* J$ B4 [/ D4 v: m, e- Q                DeviceObject->DriverObject->DriverName.Buffer,% k( R1 p* Z+ T  _" ?
                DeviceObject->DriverObject,
' b9 T( `5 r2 U+ a8 W5 P( _2 O                DeviceObject );
" c2 a6 p3 i5 ~$ q& a2 m8 t* r, k  T9 h+ x4 Y, _
      //
5 {- i* B9 N( w/ n2 w8 @5 g7 u, M! m      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
( @4 I+ ~5 `- c# Z3 Z/ j      //
. n+ b6 \3 m& c# I, G3 m& E      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer," F! N( i6 V3 P0 {2 c
                      KDBDEVICENAME,
1 B; x* {3 m# Y& r, g' i* n                      wcslen( KDBDEVICENAME ) ) == 0 )
) E" v4 G# ^/ G$ S4 l      {
- l" d' v2 o  R! t/ K4 X        DbgPrint( "Found kbdhid Device\n" );% g8 s! ^; z6 B5 {1 {
        bFound = TRUE;
# D" u: x4 q; Q* q; O/ l        break;
, G) g4 \, \6 k4 B      }
& j  P  i3 x/ z0 ^* {    }
" z) w* p8 p. W7 G; r8 [8 o6 [% z
    DeviceObject = DeviceObject->AttachedDevice;/ q  ]5 c( A8 I
  }! q' y# p4 q1 M
, ?6 S' ^4 b2 S) M6 J
  return bFound;8 ]! P$ |9 u+ G3 b3 e
}
$ I0 k0 t5 E- H& k' W" c- V- z" Z9 i+ N
/////////////////////////////////////////////////////////////////  y; n8 M4 I4 j3 J6 t+ j
// 函数类型 : 自定义工具函数
# I  A$ M% z$ L/ J. R9 a  ~& l3 u// 函数模块 : 设备栈信息模块
! ]( X" k- h# g+ _# L/////////////////////////////////////////////////////////////////
; Y2 V' b3 ]# R+ r+ X$ K% }! f4 Z// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址+ b: S9 Q# E8 Z+ `1 X& @
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
$ k6 X/ \3 U* j  x! A7 c! E& \/////////////////////////////////////////////////////////////////# n2 @8 _9 ~! i- c
// 作者 : sinister  p3 o( w3 f, t) H3 M- H1 v1 ^) }5 u' c
// 发布版本 : 1.00.00% a: ~3 Z, C5 n; J; E; t
// 发布日期 : 2006.05.02) K' @8 j, ]4 V
/////////////////////////////////////////////////////////////////1 m. V0 G# a  O% O
// 重   大   修   改   历   史
  u& y* h& o3 F9 }2 B/////////////////////////////////////////////////////////////////% o+ W& `0 I  m
// 修改者 : sinister5 @2 D  H) o$ q& q5 d$ L% ?
// 修改日期 : 2007.2.12
4 h! F% N' X5 ?0 n7 z  S# R// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用/ X0 d7 c1 e) h$ A+ V5 {* P% k
/////////////////////////////////////////////////////////////////
- w" F- R, @$ s1 P5 w1 @. H
- u" |" K6 Z5 _0 pVOID
7 }7 W, P! _; q8 H4 q% @GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )9 B* ?' i: v* S- [% v
{
' [0 x! _& m/ p) l- t' A  POBJECT_HEADER ObjectHeader;
/ W- {9 O4 T% {# M  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
& P! Z& f) x% _) i& ~7 @/ v% A/ s  V! J; E
  if ( DevObj == NULL )
2 K0 L$ F4 s& @  {
( V5 T; z( \+ \, H    DbgPrint( "DevObj is NULL!\n" );
* q& U5 E% a. Z& K' K    return;! k0 h: u) W! W
  }) a# G" r, ^8 @+ A5 b

1 R( c1 B/ }: Q3 F4 c/ V  //6 h  f) Q! T& r: L7 t* J
  // 得到对象头
* Y, G$ w# D7 c4 J4 P1 A: z" I  //3 {) i+ n* O7 z
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
/ U7 l& Z) i, g  c+ R( T- I# X# A  L, l
  if ( ObjectHeader )7 v' |. m0 T* C3 H
  {1 [6 U/ d. R# R; |  U1 g6 \7 f
    //- ]1 a3 c: k" q4 x# L2 t
    // 查询设备名称并打印
% S7 z* q" H: f' y' [8 a    //2 g) p, d  N% V& F; O
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );+ x+ b7 I) ~# q+ @* _

7 a+ ^7 M. s, w8 \! R  h, C' d    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
% Q" }; x: Y& F5 |/ Y! _! m    {
9 ^4 C& d7 F7 o; t) z8 M, c      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
: B+ q, c/ B4 y! x' ?                ObjectNameInfo->Name.Buffer,
* Z, I! j& H/ n6 p/ P5 A                DevObj );
6 h/ @0 M' n1 m! A0 h; c! e. {4 @6 K4 x1 K, L3 y! d! a  `
      //- L3 e. P9 n' ~
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示4 E$ H7 ]: ^* t% q% D9 B3 j) W2 j! H
      // 用,没有实际的功能用途6 a1 e, X' j! @, |$ U+ D7 d' I
      //
  Z9 s. c% `( @: F, x      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );4 O; j- o/ g: P9 Z. M/ W& w

5 W- X1 m& O2 S0 x. |/ D0 `      wcsncpy( szUsbDeviceName,
2 H0 h' D  O- s% R/ M5 K3 t               ObjectNameInfo->Name.Buffer,1 U4 O( P  N/ E) W3 ~3 b
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
; b- n/ k' M6 S    }
! p( S# q0 W( `8 a4 h
* V# z# L- {) T+ k1 v+ `) ^5 b    //
$ v4 h& n0 v$ @* }" ^9 [% m" s" |    // 对于没有名称的设备,则打印 NULL0 |: B& u  W: C+ U0 u6 B
    //
+ P8 S( A3 p& w. H    else if ( DevObj->DriverObject )
1 d8 ^; [3 G1 c5 z% \# S* A    {
$ Q/ g' U7 F9 X$ e      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",! O# X9 D, C3 H: z% y
                DevObj->DriverObject->DriverName.Buffer,$ m9 L0 {3 J" E# H9 R
                L"NULL",
, a# r3 Z+ `5 w! Y. m                DevObj->DriverObject,4 u: |8 g3 f% K3 T
                DevObj );
( q0 z- K7 A! e9 E- E2 }  V9 a    }
% c. ~; w. I( @7 ^% ~& O- ~, {  }
' c. ]  u9 f( v* R2 S6 _}
# l% U6 V6 ^+ i4 o5 R+ _8 T2 S9 N
6 f* z/ b$ @2 r9 Z1 v/////////////////////////////////////////////////////////////////
% C4 a9 E/ {5 }5 @* B// 函数类型 : 自定义工具函数
4 \) Y' j" P9 w7 m: Q8 c// 函数模块 : 键盘过滤模块
) n8 h( G1 i. W. f. b2 Y/////////////////////////////////////////////////////////////////
( d2 E2 k( q" t3 p4 y6 X- g# r// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备0 a8 Q) {: W/ ?$ G. l
//        对象,过滤出 USB 键盘设备,将其设备对象返回$ j& e8 e; v; q( V) a0 J) l
// 注意 : ' U$ c- Z$ X1 h
/////////////////////////////////////////////////////////////////
) D& x9 g2 a* B" Q, v* T$ r// 作者 : sinister% A! u+ s6 g* Z/ u. _; M
// 发布版本 : 1.00.00
, x3 L# O8 R0 N// 发布日期 : 2007.02.13
  A: C$ v. U' s/////////////////////////////////////////////////////////////////4 T) j7 \  o: \" g4 A( w
// 重   大   修   改   历   史
) a( s( k7 o: Z, T! m& L) U- A/////////////////////////////////////////////////////////////////( m9 [& u- U$ A. x4 w9 h
// 修改者 : 1 F9 N0 P) I( r8 g# r  j" S
// 修改日期 : & T& O) D1 e# d" Q+ @1 ^
// 修改内容 :
4 S* U3 Z" B3 j. _4 D/////////////////////////////////////////////////////////////////& p: e' w/ ^: f8 _0 G( R! ?

* s3 Z+ ^/ H6 a7 @NTSTATUS; P1 E& x5 c* E" K9 |
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
2 \* R0 x0 s" x+ j8 \9 a2 q6 R7 L{2 l* k' N' D+ b+ L& n+ M! @
  UNICODE_STRING DriverName;# P0 U% W. `4 G% M! d6 I/ _! v
  PDRIVER_OBJECT DriverObject = NULL;2 y9 S( S. L% p& @! H; K
  PDEVICE_OBJECT DeviceObject = NULL;
; Y; Q( t# C1 ?  e2 X; O2 ]) ~  BOOLEAN bFound = FALSE;. M9 \1 E9 l# f4 v

/ q5 C: d: v: S8 A' A, X  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
% l# |& X* r, G) s4 I. C+ {4 |* k7 {3 w& Q
  ObReferenceObjectByName( &DriverName,# L: R0 c1 O/ B
                           OBJ_CASE_INSENSITIVE,4 _+ |" I3 q6 a3 e6 B1 P
                           NULL," p8 d/ b" Z7 w
                           0,
2 V1 n, U- y+ J' G                           ( POBJECT_TYPE ) IoDriverObjectType,
1 j  I. V7 }7 l9 Q4 J* {0 \7 }: M; H                           KernelMode,: U. ?! V4 s( B$ `
                           NULL,
- s+ ^: {2 b$ _3 [9 E$ w/ M+ |% a                           &DriverObject );  K7 C- o, v8 I$ Q" a) I
4 T4 L' L% K6 N& c7 I  U
  if ( DriverObject == NULL )
+ ?* z" g% Q2 c) N  {' y, s8 H% ^" ^% }2 O5 A
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );7 _: w9 b* i3 w$ c0 [$ G, K
    return STATUS_UNSUCCESSFUL;
' v, C! B# v  H4 X7 U% Z6 n- B  }
" y4 b. x9 ~& R0 p! ?; j! x
9 F7 b. Q" \7 ?6 k! Y$ y8 p3 z  DeviceObject = DriverObject->DeviceObject;6 E2 z, z7 n- I, R$ e: M# T) d7 y
" \2 Z+ o; V3 W
  while ( DeviceObject )
  T( i. r6 V3 A- R& O. ]  {6 g( F9 q; \) [, R& T/ Z
    GetDeviceObjectInfo( DeviceObject );
0 x! d- n; H6 ~$ I4 E9 N/ i5 O! u. d* _. ^" q- G7 k+ F2 F
    if ( DeviceObject->AttachedDevice )& y5 r$ ?( T: Y- A% J! v" }) j
    {; R: p7 a, M" Y+ A% a
      //
/ D( m# q; ?/ M: D5 f! ~6 u      // 查找 USB 键盘设备& J+ i  z$ k5 t2 G
      //7 I" J  [6 ~) r( r
      if ( GetAttachedDeviceInfo( DeviceObject ) )9 K( S5 Z  ^6 c! |  a3 [8 s8 s
      {
- J' @' ^* C0 Q        bFound = TRUE;
0 V. g/ s4 C7 M' v3 V* ~' g        goto __End;- B& X* s4 @+ a; V
      }! y' d- h$ E) g8 v
    }) H7 a# G8 D0 b1 T# Z6 Y' ^
# h  a( H0 J# K$ d0 S- T- |- {
    DeviceObject = DeviceObject->NextDevice;$ Q) E; f1 N6 X" Q& e
  }
( R5 X/ f* L) O  o8 p4 s( g; m
2 ]8 W+ Y5 W( ?) c% f  __End:. d% v$ X5 B. C- a# o& g8 y

( V6 _+ ^1 @. X" V2 V& p8 L  if ( bFound )
. p; i! }' A0 y' Y! f+ f$ p  {
; L. d% y; W, r) H2 O2 m    //  h, F: G1 s3 O5 E
    // 找到则返回 USB 键盘设备对象
; m* {. n6 v1 `) T& O$ ?4 o    //9 B( B/ o% B& a6 O; t/ ~1 Q- m
    *UsbDeviceObject = DeviceObject;
/ P" a5 ~! u5 K4 D  }
1 z( c3 X; h+ `$ }( ?4 L  else7 w: @9 y; v# R* ]& `' h
  {
) z2 Y# {  V% A+ r8 E- S# X& V    *UsbDeviceObject = NULL;/ R6 \7 p$ c- {. |" r- U
  }
+ s( z  C9 N  ]; q1 J8 ^( ?  F7 s' E7 Z( j0 h! E- t
  return STATUS_SUCCESS;
/ N  C7 R3 M, {0 s, h, o4 a/ C& N}" ?4 T5 g5 w3 M! Q7 D- R# b7 p
; m7 ^  }9 \' @( k/ f7 }; v# Z, _4 _
/////////////////////////////////////////////////////////////////
. b2 s# n. }: n* m. p7 x0 q// 函数类型 : 自定义工具函数
8 L5 i  H4 w) _) f* I) ?' H// 函数模块 : 键盘过滤模块! q4 B. S1 t+ Z/ p. ~8 K& B
////////////////////////////////////////////////////////////////
4 A* F; ^$ N+ B# D8 y+ k! U6 {; E// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关! B8 w) y- ~0 K4 h. F, B
//        信息,返回附加后的驱动对象* J6 u; T  b/ M% |
// 注意 : 此函数仅挂接 USB 键盘设备( i5 z7 ~( @- [6 ^  e( o) r3 N( ^
/////////////////////////////////////////////////////////////////! s/ J( M- B1 u# S4 S
// 作者 : sinister
5 {5 T% f! L( `/ G8 o// 发布版本 : 1.00.00, {) I  G/ {' V' c+ y/ G7 I. p
// 发布日期 : 2005.12.27- w& D$ a1 T+ ?: \
////////////////////////////////////////////////////////////////// X$ z4 _; A) [$ B$ z9 p4 [2 v1 L# N
// 重   大   修   改   历   史. b, ^8 D% |6 e" e& E- G
////////////////////////////////////////////////////////////////
& Z9 Z- m! q& h6 u7 j3 `// 修改者 :( j! X, l- \' }. W
// 修改日期 :
8 Q6 f0 M9 U5 \/ ]& [// 修改内容 :
) N* D( x1 z8 F" |+ L! V& p* ~6 |/////////////////////////////////////////////////////////////////
- A  Z& k# V4 k4 X) L+ p0 e# f2 t, n
NTSTATUS
# q, y& l7 b  B. y, S: CAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject," {3 [0 x, {  P
                         IN PDRIVER_OBJECT  DriverObject ): K) X1 p' s5 {9 f
{
. y  u5 r( c. |2 F4 C  PDEVICE_OBJECT DeviceObject;
- E* ^/ b: o! G( x  PDEVICE_OBJECT TargetDevice; # X' t& ^! z: {8 S* y
  PDEVICE_EXTENSION DevExt;
7 e& c7 e, j; x' P! W8 t0 m  NTSTATUS ntStatus;9 e# ?$ n) A# G8 v& D

" o* H+ ?. J9 J+ u: D  ~  //
- z5 o0 g/ ~& S7 {  // 创建过滤设备对象+ B) ]3 k: }- n7 U( h; m' _
  //! O6 a; `3 x& H+ Z7 w( Q2 w
  ntStatus = IoCreateDevice( DriverObject,- x$ d! m1 M# H9 a4 a* e- D9 C
                             sizeof( DEVICE_EXTENSION ),
1 T5 a- L2 t" A% _3 Z                             NULL,
& I9 j) x# h( B                             FILE_DEVICE_UNKNOWN,
9 ^, V/ y% L  w! u' G; j                             0,
' T4 l# z) `9 y/ w& [  @                             FALSE," [. x8 k6 Q% O5 S9 B, M, e
                             &DeviceObject ); 2 v7 X: h- E2 Q

- h* Y! K: l0 G4 A: j  if ( !NT_SUCCESS( ntStatus ) )
5 L7 i; N) I7 V: o% t- M9 K4 E  {
% Y9 c, [& a7 _% s8 a    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
! O8 l4 u) r1 F0 [1 Z/ z1 z    return ntStatus;
) F- y" e1 O2 A* L# K# s1 A9 C9 @+ T9 @  } * x# p2 |6 [6 |! b; g

' p& ?9 x' E' n+ h1 Q# F  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
/ a) i1 H2 \4 ^9 B! V) o( q/ H% r* Y
  //
' C2 @& f( c6 ^0 [' s; V4 O& ^  // 初始化自旋锁' P# ?' P" M1 k. T! G( T1 n7 Z
  //5 k* j" b6 [' n  q
  KeInitializeSpinLock( &DevExt->SpinLock );
0 A* h& M- b& y6 }) ^6 c' z) a' R6 c' |$ \/ t8 B! e4 d
  //9 k, N7 u& W6 N
  // 初始化 IRP 计数器
; C( M9 x+ Y- _1 \% {' ?+ j9 r, k  //" X& Y# X) I/ W
  DevExt->IrpsInProgress = 0;
6 F/ I% L8 l8 ~, p
3 t& q* K4 a; i  //9 f4 p9 P) @) o! L2 Y. d% |! K+ ]0 I9 ]
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
' f5 v, Y+ P7 w- f0 p" ?8 K! Z  //, @+ f! A  X$ Y2 Y/ K+ t! G

* \2 W4 X5 f; A% M# d9 [! V  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); ( X& l/ U6 h. e) ^" G0 b' W  T9 L
  if ( !TargetDevice )
, z. ]% B; X( \  {$ f; ^$ r( V3 _* @( }8 a
    IoDeleteDevice( DeviceObject ); - `0 W! G9 r( V/ D1 U
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
: ?9 d7 K7 l8 B5 m    return STATUS_INSUFFICIENT_RESOURCES;% Z; R* g+ ~9 g
  }
# H/ N8 @; i* ~2 D: _- F. w: K* b; [! Z4 N
  //
4 k& R, V+ O/ S. Y5 _  // 保存过滤设备信息4 F) X/ z' p# g% G( y9 z
  //
) W4 V) ^) \+ v& [  DevExt->DeviceObject = DeviceObject; # E6 \0 ^% g, ?* `2 R2 h+ k
  DevExt->TargetDevice = TargetDevice;# K. h9 h3 Z: V% \% z* W7 S

3 h8 \! m; ]' w0 \" v  //4 U9 ~5 a' N9 w! _
  // 设置过滤设备相关信息与标志& |, }. {& e8 N+ r8 q
  //! C6 t2 Z# _% R/ ]1 ^# k: @: K
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
3 _7 `- j+ I. S1 a5 n5 a- j2 t2 Z  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
8 W7 j% A. x6 l4 @- i! j0 z+ F- Z' P( v% ^, j) j

7 O- j" D! X' V9 I- M. F# S  return STATUS_SUCCESS;9 U. e4 B/ B: F8 U: @1 N  T
}6 V) T5 R2 Y0 r1 l$ ^' C

# V8 `  S- L+ L2 ~" \& }/////////////////////////////////////////////////////////////////
7 v2 e/ Z/ @! L9 t// 函数类型 : 自定义工具函数
! j- P  @# e& q$ y2 U/ a" Q// 函数模块 : 键盘过滤模块, w$ G7 P! [/ l6 s9 X* ~
////////////////////////////////////////////////////////////////% V3 I6 R/ {% U: G; Z! g  X
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
: T* h" ?) y" [- M9 d3 h6 o//        信息,返回附加后的驱动对象
0 e/ {1 U9 J# c. G$ m// 注意 : 此函数仅挂接 PS/2 键盘设备
" D/ v( S1 i& u5 L( E3 B/////////////////////////////////////////////////////////////////
+ y8 T& }. a: O. a3 L1 l) y// 作者 : sinister
6 n% Z8 ~" ~+ q  _// 发布版本 : 1.00.00
9 x4 P" N6 n0 ?+ N! p$ e// 发布日期 : 2005.12.27
* E: P! v  R$ T" _) n# W1 Q/////////////////////////////////////////////////////////////////
$ i3 V) a  ^3 G: i// 重   大   修   改   历   史6 @0 d& A* }  ~' N5 y) u
////////////////////////////////////////////////////////////////( z; N/ k- ?  k+ K& `+ L* B' v
// 修改者 :
# }: s1 x2 _8 W. g: p// 修改日期 :
! X$ f. ?. I4 K// 修改内容 :
8 A3 A2 `: M) ?! m0 v- j+ h7 `7 i  c/////////////////////////////////////////////////////////////////
8 u3 @7 v# f8 o9 i% [% ^( k: _5 C, i0 t) b# H+ W7 A
NTSTATUS
$ C  h1 v) X$ Z' wAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名1 Y1 ^8 L& Y* \# c+ w9 @2 m. E
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象" ?2 s1 E& y7 L1 u% Q! n
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象7 y8 y$ U  A+ L% G$ E
{5 z6 m. O: _! `; E! |( M
  PDEVICE_OBJECT DeviceObject; 6 y  k  q. [$ Q/ P' Y" a
  PDEVICE_OBJECT FilterDeviceObject;
0 O# w- x6 ]# L  PDEVICE_OBJECT TargetDevice; * q- _, a. Z5 R
  PFILE_OBJECT FileObject; " p4 ~+ {) q- Y. H9 ^- t
  PDEVICE_EXTENSION DevExt;
& l( i+ A& W' g% Z7 U' x4 y6 b3 w" P/ ~& s9 J# N6 `# y! K$ H
  NTSTATUS ntStatus; 0 r/ Z7 V, h5 a! T
; d3 ~! w  P, x+ I0 E4 E4 c, H3 N9 F
  //
! n" I2 o7 R2 n; n1 _& i0 q  // 根据设备名称找到需要附加的设备对象+ k% ?  |' M5 N8 n  P
  //* v; C  [0 A& t
  ntStatus = IoGetDeviceObjectPointer( DeviceName,( @- N! j$ ^; U9 `6 X/ @
                                       FILE_ALL_ACCESS,5 g6 u4 L+ O& Q$ }
                                       &FileObject,
1 n1 M  E2 ^; C) x: T" y( T; q$ |                                       &DeviceObject );   ]: O2 u( j; W2 U! Y+ c" f
& p" h% @7 Q0 D! {, l% e/ Z
  if ( !NT_SUCCESS( ntStatus ) )+ |. f" I5 E! J/ d4 r
  {2 b' {; t( v5 G/ n# `) S. V( a
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );; O+ @" z5 o9 X; F) H
    return ntStatus;
" V2 h& `3 X9 U6 a% @3 A# z: E0 V  }
+ P* n( k) \' W0 R/ y
% y2 W$ [2 a' P6 @$ J  D  //
% _9 v8 R8 j. h  // 创建过滤设备对象
1 u3 ^& |. K! v! ^! R4 W. |  //
& D/ ~. V  d; Z( s  ntStatus = IoCreateDevice( DriverObject,* A9 O+ W! q" ]2 w! Z
                             sizeof( DEVICE_EXTENSION ),
0 F& i+ \( h. s- M. q                             NULL,; K+ v: Q, b8 m& [
                             FILE_DEVICE_KEYBOARD,
- u1 k4 Y' @) C$ x- Y- H                             0,8 G3 c1 e$ R0 V6 m$ l8 V
                             FALSE,  j7 m7 \9 C3 p9 |- }0 e
                             &FilterDeviceObject );
7 [6 u% b+ S. _2 z8 v+ F2 E. W8 h/ \& e
  if ( !NT_SUCCESS( ntStatus ) ). n; C' `; `8 [+ t, z2 a2 d
  {
7 n! r" D1 H" f2 i/ Y5 l& k$ g: x    ObDereferenceObject( FileObject );
5 e' R! F# k9 h/ O! |    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );/ ~. P  s1 f4 S* H0 W1 s
    return ntStatus;: [8 l; B( [( Q
  }
& F9 N  m2 L* I- n8 D! h" E
% X! S: J" }2 V+ V4 w' Y  //
( c6 s# B- y1 {$ a6 G4 B, z8 k  // 得到设备扩展结构,以便下面保存过滤设备信息6 }8 }" y+ `# e: |* t7 X
  //5 }8 [! O! E0 k  N7 ~5 o; P
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
. R4 J4 K* k! z0 B  }) |' i/ m% M
' Q# u* Z# w* B* }
3 u0 Q7 B1 g2 x, y) K- r  //
( J8 \- ]' l: L; l9 e, W  // 初始化自旋锁. V  S0 J$ ~7 A
  //: \8 |4 q+ n7 A. c5 h
  KeInitializeSpinLock( &DevExt->SpinLock );3 Q9 r; H  d. T% T5 F7 B
4 x: m2 J# _( {1 l4 c( q) V: B. a
  //
/ G' {2 x& N: X, J2 c  // 初始化 IRP 计数器' E) Y2 C+ B8 A' Y
  //& l5 }; }3 |  y- |( y) v6 ^1 S
  DevExt->IrpsInProgress = 0;
3 Y; W! F& v3 t* K$ O+ b% ^2 ~( ~  d8 H9 x1 I9 G
  //5 M' y+ r" o0 {. M/ z. x
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象4 E* \1 ?, T7 E7 i) W* o5 e
  //
1 F* I5 n! I7 F; W+ m  b  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
7 I8 i  D# F) [1 e. I# V6 x& Z- _                                              DeviceObject );
; s+ q2 {: h" e; L  if ( !TargetDevice )
, k& u, W( M+ I, O* i; G  {
; }% `5 p* p7 {6 r7 m. P    ObDereferenceObject( FileObject );
- z. v' {6 ~! t# A) G1 `    IoDeleteDevice( FilterDeviceObject ); ) ]+ ^) m: b$ i3 Z2 N) ^* l
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
6 h5 Z& ?6 S! O7 N1 n. ^    return STATUS_INSUFFICIENT_RESOURCES;
: k4 m4 X' W! i5 ]  }
5 l% v8 A4 k5 `. J5 b: T6 e- a% n* B+ N: v4 U8 e) V+ d% `
  //& d7 b' l# p5 D7 m3 D: ~! c
  // 保存过滤设备信息
, _4 S  ?6 `* @6 L. h4 G7 T1 f  //
$ A1 y! H3 A4 L  `3 M  DevExt->DeviceObject = FilterDeviceObject; 2 @8 n0 k* g4 k" ^4 h/ l7 b
  DevExt->TargetDevice = TargetDevice;
% C% u1 e. g, n- p- D  u- V  DevExt->pFilterFileObject = FileObject;
9 |. R! y0 S) ?' A
" H! ^: \7 j/ {8 j# w  //
; W4 y5 P  h& u. L; f2 N  // 设置过滤设备相关信息与标志1 |. r  ^& a% o5 Y1 i* t
  //
) ?$ s1 b3 |" d9 v  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
% d6 b3 J' O1 J  S2 |4 x8 y' O  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
' y7 M9 |) {' \' N5 S9 y  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
3 e" n0 c; k/ W2 I+ k% I7 ~  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
9 i3 O! [. E) h4 c+ q2 P                                                         DO_BUFFERED_IO ) );
1 x4 d+ G% Z: m* F/ x) b- h, \% K4 s3 `" [7 U
  //
3 x" z+ y; ]4 y* ?" [6 ]" e  // 返回附加后的驱动对象
* }2 l+ l$ S! D' x5 D  //
3 g0 {% a; {0 W  *FilterDriverObject = TargetDevice->DriverObject;# j$ x. a' c0 A* ?) s; e7 N

* |) y  n$ O/ C: K; _1 S  ObDereferenceObject( FileObject ); ( h1 H! z' k; y9 v1 O- M
! k& e* x* a) I5 D  ]' H
  return STATUS_SUCCESS;
6 x* t3 ]8 I& x' O0 F. m( M1 e# N; Y}
- w8 W3 }0 l9 b5 q% X
( y8 K8 K$ K& V7 a- z( C- g/////////////////////////////////////////////////////////////////
7 {# R3 p3 }  B& x// 函数类型 : 自定义工具函数
6 d1 C. [- q! b- ?// 函数模块 : 键盘过滤模块' ]6 t, V9 Y2 T' _# N* V
////////////////////////////////////////////////////////////////
: X- X6 U4 j8 K( z9 [// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发3 R4 l& }' g! p* N' i5 P3 M2 M
//        这个 IRP 的完成
- e5 X9 @9 Z0 w: a7 P4 B  ^// 注意 :
  H# L6 f& q* [( C/////////////////////////////////////////////////////////////////
; |# v) y+ m) N, ?// 作者 : sinister- }8 O2 }7 ~$ G( Q( W
// 发布版本 : 1.00.00* P0 \) q" a7 X
// 发布日期 : 2007.2.15* @7 m6 z1 P# }) i
/////////////////////////////////////////////////////////////////, H, W# O' u9 n5 W2 K0 t6 j0 ^* I0 S
// 重   大   修   改   历   史8 z5 ^7 A8 K  }5 i- |
////////////////////////////////////////////////////////////////
+ b8 B$ }- N+ N; J7 v// 修改者 :
' `! d6 o* E- o9 |' a! R  h// 修改日期 :; _# N, }2 j5 m* ?) X
// 修改内容 :
2 W7 M8 c1 G; d' d+ Z! I9 [0 ~/////////////////////////////////////////////////////////////////
; w) Z2 [$ Z; M; `/ b& W! Z' {  `% i  H7 m/ A' [- k( h
NTSTATUS3 U5 O, ]) s6 N0 `  E8 I+ y
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
  F$ H/ x1 w0 Q  f% Z0 ?{
0 }+ o8 C! M* ]1 H' l. r% T  NTSTATUS status; 4 p0 s+ o' s! {: a2 a; @$ P+ V
  KIRQL IrqLevel;/ F7 r& M7 I! t- W- t( k. }

3 L, v$ |% u; H$ A; p% W" a+ H  PDEVICE_OBJECT pDeviceObject;+ i" S7 B- p' a; d5 ?
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )# L' Y4 Y$ Y0 P3 {5 N- |2 I
                                   DeviceObject->DeviceExtension;
% I5 I* y  T( s' b$ X' l
6 M  N- c1 l8 p7 @" U9 U2 x" L2 `6 S
  IoCopyCurrentIrpStackLocationToNext( Irp );6 e  E% Z5 h0 T9 B* M" t5 ?9 W

( P+ h2 C9 x5 O# f; F4 A  //
7 R3 _3 W/ U$ y' w, ~  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁# s5 d! |0 A, ~( @& H$ w1 e, {! U
  //
0 A2 \# `* B' ^$ O" m0 g  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
4 W( R, L, i- ~2 _' \/ I) A, V  InterlockedIncrement( &KeyExtension->IrpsInProgress );6 Q; x, r2 K, Q  E
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );% U% _: v" ~# U- t( Q5 j9 c

# l3 K% \) p. v  x2 z0 n  IoSetCompletionRoutine( Irp,
! a+ o7 f# j/ k* W( m$ m) v- s                          KeyReadCompletion,: e* P! \) O5 m
                          DeviceObject,
. o& B: g0 N# x" K% J: e                          TRUE,$ S& a4 N+ H' y3 A
                          TRUE,2 D1 p6 i* G( [2 T+ Y: Z3 ?
                          TRUE );
( Z2 M5 {4 v. t# n
) G; K. w  E. S9 @" C% _' c  return IoCallDriver( KeyExtension->TargetDevice, Irp );9 T8 _" k: l% @
}
, {, O5 |7 q$ k+ H4 S3 f% b7 e! t) z; ?' H
/////////////////////////////////////////////////////////////////) y' z! ?+ ?9 v7 ^3 Y( s; C
// 函数类型 :系统回调函数
' k) N  O& W% A! h% s# ^$ M// 函数模块 : 键盘过滤模块* Z3 ]8 A1 K3 u
////////////////////////////////////////////////////////////////
/ q9 Y5 F6 I3 G- K. u// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
) b( a9 D: U/ R5 Z# ?3 v// 注意 :
9 c0 u; `4 I! L+ Z/////////////////////////////////////////////////////////////////
5 o5 u4 Q2 L$ Y* P6 O& b) J8 t  V// 作者 : sinister
$ s- N- G; Y/ j9 u# Y# w, B// 发布版本 : 1.00.00
. n+ G5 Y7 |* Z) P* N6 O// 发布日期 : 2007.2.12$ e) X( a) U2 Q3 U9 F0 V  a
/////////////////////////////////////////////////////////////////
6 X' @" }7 `& D. C// 重   大   修   改   历   史
" K0 b+ g0 m% p* N////////////////////////////////////////////////////////////////- r% T9 U+ i: d0 E0 K- [
// 修改者 :3 l2 z( }5 B- w
// 修改日期 :
& e6 ^8 I6 S% s  d& g* c: k! @$ P9 a+ O; ~// 修改内容 :
% w- Y$ t! U' o3 R/////////////////////////////////////////////////////////////////
, y  T5 F6 h9 ~1 N! H1 U; M
; e! L6 Q# m9 B7 n: DNTSTATUS
9 _8 F5 B! x4 N) XKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,; q$ ~! ^: Y! p6 ^, C' s
                   IN PIRP Irp,
, {' Z( I5 ]$ c0 f! f7 I                   IN PVOID Context )
' q4 b; P+ |, S0 C{
* F/ m1 K5 x/ u0 P- d+ G  PIO_STACK_LOCATION IrpSp;
; W7 k, ]  p) l) N  PKEYBOARD_INPUT_DATA KeyData;
" W1 U- ?! ~( r  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
9 ^% `# p1 `* C% [                                   DeviceObject->DeviceExtension; 0 a3 u/ k+ c, }/ v6 B
  int numKeys, i;
! c' D- v+ R9 c! k! o  KIRQL IrqLevel;
: d% v" Y8 |9 {; r0 k, w5 `
3 H; Q! R$ y" V; A! \5 d  IrpSp = IoGetCurrentIrpStackLocation( Irp );
0 Y1 r) W8 A0 E4 p" E: O0 c
/ P3 e( }; O$ m5 N8 _
  w1 c6 r3 |0 D" y5 O  if ( Irp->IoStatus.Status != STATUS_SUCCESS ), E; H. ~) a4 t
  {
: |: F4 J& J; Q    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );! |4 I& a9 a6 R& y# ~0 M! U! S
    goto __RoutineEnd;
; ~$ R) D5 X0 k, o) l& `  k- J% G  }$ o, ^7 Y6 ~% m; _" X: j0 ]7 ~! _

: j) C( `' @/ \' ^" W) j  //
, R& e# e8 d  Y$ t8 k2 K  // 系统在 SystemBuffer 中保存按键信息
- J* C0 y9 O) B+ J, q7 W  //
& p1 q2 c3 ]4 q& X  KeyData = Irp->AssociatedIrp.SystemBuffer;1 ?4 [& X5 Q$ q* ~* A
  if ( KeyData == NULL )0 e% L9 A; ]9 z4 P; w
  {
( v3 x% x( a; h/ _4 r8 ~1 x    DbgPrint( "KeyData is NULL\n" );* E8 d8 w: W, o, W& Q
    goto __RoutineEnd;9 X% O6 k, |% n0 f
  }! W4 ?8 ^: w/ ?* J6 j9 K. T% Z: T
1 b( p, I# E, @6 K' ~
  //
# r7 h2 m9 D5 c/ X  // 得到按键数
: N9 D5 n( B+ f- A  //
: p0 a( `! z) n! f" h  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
6 q) F# ]4 b& H5 X/ s  if ( numKeys < 0 )
+ U. v- ?4 D# g' M8 p$ q  {% G" x  Z. P0 w  J+ a3 \: q
    DbgPrint( "numKeys less zero\n" );. J: M7 y. i9 l0 r' X- S7 c5 `5 M
    goto __RoutineEnd;& @1 }$ M& ?0 W" b% I
  }
* C' O; l: U) c
: S% s% L: l. t  //
$ _/ Z1 Q, s& N) N% L3 |  // 使用 0 无效扫描码替换,屏蔽所有按键% F/ ^1 j- I! t& o6 Z
  //
! y0 c/ q3 y1 d( L  L  J4 n  for ( i = 0; i < numKeys; i++ )
- s& y; a: |! f$ z  {
' J+ T( @- L; J0 i    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
! l" k- N. y' P/ N3 Q: I/ C    KeyData[i].MakeCode = 0x00;
4 c+ d% U9 S. B! q/ a  }7 f0 t6 U" j# z

3 r% e6 Y/ E0 c( D$ a0 `
. i8 A! P7 c- C1 H  __RoutineEnd : & h3 l( h5 u, N* t" k
) c3 H7 F  p, F5 W
  if ( Irp->PendingReturned )8 |. W4 _5 V) ?' x6 |* B2 J
  {! a$ }) n) V& _' }7 N5 r
    IoMarkIrpPending( Irp );% o: R, a6 T8 I  Q. G3 d
  } ) @2 O+ z% G7 c9 d1 _3 ~) s0 @" e

/ t9 `2 f( U+ O2 n: g  X7 G( r) e  //- W5 Q! u- X# y  W7 p
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
' [% C) H9 S4 y2 a: j  //
, P, ^) |1 m1 p, k' I$ [$ s$ P3 |, X  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
* ^8 {4 T  @- \  InterlockedDecrement( &KeyExtension->IrpsInProgress );/ Y7 ~  x* G+ p1 Q* V
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
2 j2 Q3 d# h" b; A# G
% O. i1 ?1 p% c5 l  w  return Irp->IoStatus.Status ;
  i  U0 h% A9 A( d/ r}
  Y* b- h+ [' R; n* U4 n+ z/ ^4 F  w1 a6 y

# Q6 V- U7 A4 i  W6 @/*****************************************************************8 J0 u4 S) o: a- t, r/ T% ^5 b
文件名        : WssLockKey.h: c" h$ N& Y/ |& a, ?/ s9 ^; Y9 s$ w
描述          : 键盘过滤驱动
. [1 N" F7 J% H. Z4 k; N" y) z2 } 作者          : sinister
/ Y1 [5 R  Z! X9 ~" e; @4 Z4 L: Q2 O 最后修改日期  : 2007-02-26
5 [  W- P3 d% c0 S; ^1 X0 K6 o7 r*****************************************************************/
" ~9 |; Y+ Q7 Q8 w' D1 A
6 O- @/ r) Q/ h9 d#ifndef __WSS_LOCKKEY_H_
6 t. p3 D4 [/ [: B. a, b4 p#define __WSS_LOCKKEY_H_4 U1 Y( x1 ?) u( B5 {9 R

( O, k  x/ P$ I/ e: f9 A#include "ntddk.h"
" {7 K0 R1 d! G% p' L#include "ntddkbd.h"4 `3 m2 q2 y. C# m
#include "string.h"- _- ^2 Y1 M4 H; c& l* R( @  e  A
#include 1 {0 L2 w; |, F# }/ N

' r* _  b7 v# \- s; p5 \#define MAXLEN 256
4 c# j. a0 d3 _# Q
, K. r) x$ B3 c4 \0 G+ I' X#define KDBDEVICENAME L"\\Driver\\kbdhid"
" H- L# g$ r5 o0 [3 V#define USBKEYBOARDNAME L"\\Driver\\hidusb" 2 v5 s$ r, F' v" c
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
' A6 k# U1 \$ s) S& C# h* f+ l. e$ P( C7 u1 X1 B  J$ m
typedef struct _OBJECT_CREATE_INFORMATION6 E( ~& l" ~1 S7 D7 J. m
{
& [! F$ R2 H5 l    ULONG Attributes;" N8 W4 b9 n3 X. F8 E* x0 B
    HANDLE RootDirectory;" t; n1 A5 ~/ T5 @+ g! p; Y
    PVOID ParseContext;  ?8 Y* h  Y/ L
    KPROCESSOR_MODE ProbeMode;
" [% G, `( V. N  r7 i! W5 D    ULONG PagedPoolCharge;
0 x9 d, F+ _' @% X* D  A    ULONG NonPagedPoolCharge;! @( M3 B2 w  P. c- s
    ULONG SecurityDescriptorCharge;( ~7 J1 A* r" t8 ]
    PSECURITY_DESCRIPTOR SecurityDescriptor;7 H" _3 x% s; P) K# `/ c1 z( V3 N5 x
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
9 n; k' \. g3 A# Q    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
5 n, h. p2 L+ x8 A( _} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;8 `4 J0 B* u. f1 S# A2 y6 w: {

0 `: ]$ E( J2 X6 c8 a6 R6 gtypedef struct _OBJECT_HEADER
, y9 P; }$ Z9 S2 u* u( E% W+ s{( ~/ W! J5 w5 q  H
    LONG PointerCount;- l4 V  h+ A6 _8 I0 b6 c9 J" ^
    union
' q0 h0 O, Z- O+ Q    {2 `. @1 v5 X) @( H& i6 C% q
        LONG HandleCount;! ~% E% i+ Q: a/ d9 o6 @- q
        PSINGLE_LIST_ENTRY SEntry;% x. o- S8 y0 H/ T" [+ j; g6 ]
    };! y9 g; Q4 t$ O7 ?
    POBJECT_TYPE Type;
, G* t) P- L( T' q" h* N+ F    UCHAR NameInfoOffset;
' D. W0 G0 w$ _9 \    UCHAR HandleInfoOffset;
, |6 ~) P! R: k7 j    UCHAR QuotaInfoOffset;
. h/ {6 r1 h8 O. j8 {    UCHAR Flags;0 t' M" r# F" F. ^  P
    union3 [- M+ u- V. S- Q2 W! [2 \
    {
8 {! P8 R  z& J5 }& B! c        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
$ h3 Z4 F3 Z5 L6 e" g4 q        PVOID QuotaBlockCharged;9 D" ]$ t# Q0 N' j2 Y
    };7 ?. Z6 L5 w0 I$ ]7 Y

) R+ C  Z5 R8 V9 s" U9 _8 G* c    PSECURITY_DESCRIPTOR SecurityDescriptor;; ^6 D0 t8 }, d( H3 Q$ e5 w- D
    QUAD Body;
9 i" X  r% [' g# D} OBJECT_HEADER, * POBJECT_HEADER;
9 k( ^3 q0 E2 ]1 n' y! |! P0 Q) ^& j# `8 S/ I& N
#define NUMBER_HASH_BUCKETS 37! E$ M/ r7 V9 ^8 x; S* Z4 }4 ~
8 t# w! z* i) z' G! R3 r
typedef struct _OBJECT_DIRECTORY& a" |  d! P. V1 Y" n8 y+ ]
{% H$ p$ [- K* N
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];5 b/ w5 G# P6 [/ d! V4 N  a
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
9 f: y! x$ Y( S/ _. b    BOOLEAN LookupFound;( q  `) s+ [5 p6 L- K; S, i- K
    USHORT SymbolicLinkUsageCount;. O, e% o& d+ X% Y7 B
    struct _DEVICE_MAP* DeviceMap;. F3 g; x" D1 l: z7 Q& \- A0 p2 U
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
6 ^/ E1 z. C& f; _7 v) R4 l  `$ ]7 Y7 t! v
typedef struct _OBJECT_HEADER_NAME_INFO
- G( C1 ~# n1 w4 \5 F: m1 ^0 ?' W4 x% c{  O7 T/ I4 Y# m& @; r9 V: Z0 j
    POBJECT_DIRECTORY Directory;4 G2 J8 A1 P6 Q$ ]
    UNICODE_STRING Name;
" N4 G8 A& G; x, W0 ]# z    ULONG Reserved;
+ f0 Z  q7 Z2 ?5 x#if DBG
) I. n9 }$ |7 r    ULONG Reserved2 ;  j$ |+ r5 `* y7 U1 g9 o8 n
    LONG DbgDereferenceCount ;
0 v* F) b+ ^) L$ E#endif3 ~- ]4 ]# q4 i& p, Q% d* U( k
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
! e: Z) V7 h) }; G* i& \1 {" G2 \3 b* h* K* n) q
#define OBJECT_TO_OBJECT_HEADER( o ) \
/ P- d" L( B3 }6 e7 ~9 f    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )3 n. o% w, ]3 G. ~% g) w
1 J( t9 Z/ Q. s  K; C* E" ~
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \% k- d$ {# q; a. ?! A+ F4 c
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
  `  k( @' q7 B% t' P6 Z+ _9 l. d0 R
typedef struct _DEVICE_EXTENSION' t4 V6 `4 G0 I- S8 @  g) k
{
: T$ j# q0 U, N5 F: i    PDEVICE_OBJECT DeviceObject;
+ k; h. Z) C# z5 ?  g+ f' u    PDEVICE_OBJECT TargetDevice;
* j  d$ l4 ^6 ]( p; f    PFILE_OBJECT pFilterFileObject;, U7 Q% f  E/ U9 ~* I- N
    ULONG DeviceExtensionFlags;7 G3 [/ e5 K, i) B4 ]: {
    LONG IrpsInProgress;, _0 B& t6 g2 R- Q+ @5 b; J1 H
    KSPIN_LOCK SpinLock;8 |: c% w7 e) ?  H6 R9 P
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
& |0 n0 g! }) |/ }0 @9 ^
( [+ u' W6 ]( \1 n" @$ r6 Q
# b, x1 X: N1 c# n& aVOID
3 y9 g& O  [* s2 S9 N0 d: tKeyDriverUnload( PDRIVER_OBJECT KeyDriver );
2 j' T5 G6 [( q0 \# Y
/ C; a. P/ F$ m7 s6 u' ?BOOLEAN
2 T( \4 _- a$ Z3 Y& jCancelKeyboardIrp( IN PIRP Irp );
) u) i, }% a5 u. t  ]1 z5 ~/ ~) e& g9 R$ H" e7 N
extern POBJECT_TYPE* IoDriverObjectType;
; E( \. j& F" a2 r  }! J
! L5 W( R) g( m8 ^: sNTSYSAPI
) @, r+ y- [4 G; G8 ~1 E; ]+ _! NNTSTATUS
& _/ L  B# l+ `2 L2 sNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,* E! r+ I$ I, ^- b/ N$ H, Z
                               IN ULONG Attributes,8 H2 Z1 r$ A8 y
                               IN PACCESS_STATE AccessState OPTIONAL,) r; r. Q0 j  X( |8 Y
                               IN ACCESS_MASK DesiredAccess OPTIONAL," E& B1 D* ]$ m6 N- ~
                               IN POBJECT_TYPE ObjectType,2 |% V" a# k# _) \! q) c/ k) y* {4 }
                               IN KPROCESSOR_MODE AccessMode,
2 h: ~$ k2 E0 W2 q# ^  A9 q  H( D                               IN OUT PVOID ParseContext OPTIONAL,& Q( u5 `. k2 K# `! N
                               OUT PVOID* Object );
# o9 a3 o+ i7 C9 Z& }" ~) L
& U# U6 ~9 |* D  f" pNTSTATUS ; l& j7 l: A* r( [# A
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );* U2 U9 j; b5 X/ O9 P! p- j7 s" I2 P5 I4 C

# G! O5 q% {9 q; e+ v$ K4 zBOOLEAN
+ ~9 J: x, E- f9 {) O5 PGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );, Q( O' k+ I! z  l9 M
: q6 h6 ^0 l, N0 q5 R
VOID
3 w2 f& T$ Q  t& tGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
* I% M7 L6 d5 V; m; B5 j
* Y9 n6 q% t8 F3 q8 `/ B  Q0 m$ bNTSTATUS 6 }1 B$ J+ t& Q
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
/ s1 {: H  w7 r! m9 b: X) [) a& P$ \                                  IN PDRIVER_OBJECT  DriverObject );
  E6 b8 g' }3 w- P* N, m
' _* J( A" V  e0 h3 r/ oNTSTATUS
+ W5 B8 r) K% A' hAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
3 r0 _2 g& ~+ u% |) E                                  IN PDRIVER_OBJECT  DriverObject,
6 @/ x  _6 r; Y' K6 S1 Y                                  OUT PDRIVER_OBJECT* FilterDriverObject );
. n" d7 R% G: D6 k. {
, h, S. j2 ^8 C1 e2 Q. P9 H& _1 QNTSTATUS 1 c  A/ ^; _2 e% M$ a- G. P
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,8 _. v" ~6 l# l: q# ]+ p6 l
                            IN PIRP Irp,8 C, S8 x9 W( a$ l3 K
                            IN PVOID Context );
( \; h7 W- g+ `NTSTATUS ) @/ E; n; f' k% A0 Q
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );- o4 B% `* p: i+ ~8 W  I

2 M7 y$ C8 [& v0 f3 CWCHAR szUsbDeviceName[MAXLEN];- c* \& C4 R/ C& c

, p( T% ]% W# q0 I2 ?: _- F#endif4 W$ K) Y: C# j1 ]
# }- r2 s+ S1 q' b6 R: ]  l1 B  o
& F4 E( ?$ [* Y% [+ y) `% R

' v% d+ P- w2 M+ s9 ]! P- ^& E0 n$ K2 X% c: {3 @
7 q6 \2 b  o4 r1 H! |- j
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。! i2 N8 m4 v4 w9 Y( L! V9 G
WSS 主页:[url]http://www.whitecell.org/[/url] 6 p0 @; o/ ?# r  c
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-5-19 10:11 , Processed in 0.024331 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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