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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
4 ~$ d. C/ x* P) @+ ~( a6 {Email:   [email]sinister@whitecell.org[/email]
. K% p0 e; s+ V, J9 pHomepage:[url]http://www.whitecell.org[/url] " \9 ?" a# {: c
Date:    2007-02-26
) A$ G( q# I' I- |# G+ a1 O
$ d3 a( ~& I/ n, I3 f' j+ D5 M; Z+ }, B& o
/*******************************************************************4 Q. c5 {$ h& `

& D: q' D4 g6 t% b这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
9 w0 y* i8 G- y2 K写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的' p) }" w4 y% E. k4 w) j8 G% Z8 A
功能要求如下:
  t/ [4 K2 |# E$ C9 k3 g7 [* W$ K: s7 D
1、强制锁定键盘/鼠标。+ G1 @3 ?) [0 g& t5 ?
2、可动态加/解锁
$ `( j, h" Z7 ^  U' q9 g8 c3、兼容所有 NT 系列的操作系统。8 |1 Q; J* k9 ?( Q, c4 ]1 k7 Y/ `
. d: }  |" v: r5 C' b
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
$ k5 H: Q+ z2 c. O5 W2 f* B% U现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
& x" o( h  j% O+ c何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在# c' E* i/ `8 @/ C7 e
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是! y* J4 p+ p3 F! T4 e) J
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面1 k, i) W1 ]- N2 D
就来看一下我想到的几种实现方法:# o0 w4 x; L: Z3 g
! ^9 l' e- a; i/ B0 P" [
1、全局键盘/鼠标钩子% a* Y. D: i+ a8 d5 L6 S& K
2、BlockInput() API
, j6 i2 I- p. F7 N. A: c: n3、使用 setupapi 进行控制/ j9 I0 G3 f% P4 _7 d
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
' O, U: I, Q* s, k5、拦截 win23k!RawInputThread() 函数
8 k4 v4 D% K% E+ c( H7 |9 v* e6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动1 v) X6 c8 g4 h7 D" v
7、拦截 kdbclass 驱动的 driver dispatch routine  G# s- L- @. X% g% C! S% d
8、实现一个 PS/2 与 USB 键盘过滤驱动. {3 F  g. f: |4 b, L: \
1 x" {  |. N$ |
. P9 @8 }) r  i1 d
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑6 c' S7 T' R7 {3 ?2 h
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
! w- V- t2 m2 U8 \案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在* S( F1 s# ~% j0 J3 v  y& ]
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
+ C$ K" I$ R) x- u3 i  y7 X素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
7 K- b. Z$ ^! c. P问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸6 P4 n6 I9 x& X
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
& u# G" T. G; J9 V的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
- u: R+ T3 ^* _6 h+ d也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
! {5 l7 {6 a1 F# s果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
/ P& H8 U9 r2 W障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截4 `" ?# T5 L5 B2 ~
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
5 W6 y4 n% Q5 c! O( X1 [4 D* B% DUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键7 ^# A& T" T! D$ N
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
  c! G. D) P/ b' n案的全部功能且不存在它所带来的问题,否则就没有什么意义了。$ L. d9 ~& L1 Z* g" j- z6 K
' U' Y7 }3 o3 l! i" f4 i8 |

! ?+ U% z1 C: T* g) m# H我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
' n- h9 g4 g4 D# _$ B" s& _! G: h滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
  f7 A" R8 W- K# y+ Y行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
8 `* u4 J2 K  s* t! @只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
) M, B2 q1 j. _7 |$ Q# Y来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从3 R8 a3 Z% j- l
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
6 w. {' O. E6 i; S/ D键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
+ T; B: {5 j) ]$ ^IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
9 Y" a! @* G9 Q( g4 y6 y# Z我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
1 L" r- \  j- A# a就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
2 ^" V' H; y9 B5 c% u* d5 v而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使( s0 T; c- H! P1 p
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通: L: b, I1 N8 U$ D9 G
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
# l8 R" q) q' @6 J屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通7 ?/ B9 C- Q7 U( P# S
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb3 T$ _- y4 R! a/ b" F0 V
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
6 J; {3 S: E: T+ ?2 Z, A; o的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
9 y5 O' Q- F$ d4 p味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
, F+ a6 k: Q: j5 n* r经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们$ n- g7 I8 R8 e
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利; M. U& @2 d% a# s6 J
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
8 o; [3 C$ n/ ~* A; O  K1 E/ H的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致0 O' [0 ?8 Y% u2 }! X
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
- _- f/ b/ h, P" m' E根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
' ?- Y) T$ Q9 ?$ h* y见下面代码。# N) l$ u3 W5 E5 d7 N+ S6 z

1 {5 \; c3 @) o( `! j. }8 x这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
) {# h3 B6 m5 @3 P5 r- i里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键, |, j5 @5 Q# I/ Y! U' p
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20033 z( y; M5 X# g/ x7 L7 W  @
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
$ l  a/ r4 o3 g8 O6 E; l& \完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
+ T6 T: J- ^) h6 |" W) u' @* y继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
. N' V8 `$ ]& p" \& S锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
" u3 E3 v7 d" g+ f% _键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
0 O- }# T- ~8 E7 Q7 `5 J4 g3 ]
1 s4 f9 R4 u( Y1 f0 g
9 P( ~( [* ~/ f& q* n% x完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
$ }  M& I: S+ J# }  ^的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是. ~! Y$ t5 _+ _. H5 K4 k% K
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
- N# }+ E, I  ~/ }  n的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
: D  J/ x$ z( f8 ~) g$ u们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我; [5 k/ x% b0 o2 `1 S
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension6 ~5 `, [6 x; ~. j; C
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
( e2 _& ?  P; F如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
% z. F; F4 }% K) c8 {, o进行操作了。这个问题有待大家来完善了。. E5 @' C8 s0 I0 E( f% h

* f7 {* C: B6 P
9 i# d1 R) M6 S要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出$ D2 B* o8 x& O' Z1 |' m6 O/ b4 w5 S+ L
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
$ m( D$ I. c- a' T+ m! t. Z5 i2 f分析做个记录而已。我更愿意把它看做是一段注释。
- \( E; Y/ J) `+ j4 ]4 K! k: h0 U  T/ ~1 y/ N4 Y# R# Q# g) V9 a% [
最后在此代码中要. N5 \+ ~8 I4 C3 u$ r1 _
7 m: D  U8 F5 i6 c2 `
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
+ t9 }3 K7 ^4 m2 q- u! F# u" c" {- w9 R& b/ M
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。9 x% h2 I% z/ @( j/ M7 ^
0 Y( Z0 z: U/ c& W7 O
感谢:齐佳佳,过节请我吃好吃的。. ]. V& p* Z3 n) S& b

# x: H6 {2 Z* Y$ F, [- C
$ ~! \. T/ r' ^4 Q, w7 K5 i******************************************************************/
; L" q2 A9 H! a* I$ t* s( Y' }( G; F; W; b! k9 F) c
4 Y2 |3 d+ p3 H9 J
/*****************************************************************
. g3 r: {9 o, P0 |( b2 O7 q 文件名        : WssLockKey.c
- ~$ l% B' n  t8 S 描述          : 键盘过滤驱动3 Q( m5 q' N8 o& ?- \
作者          : sinister
2 I& O* y2 [5 q$ {2 I$ `. z  _ 最后修改日期  : 2007-02-26
0 l4 k) o5 `! {( S*****************************************************************/
4 A( @7 I7 ~% `8 g
* V& [* K  \! r, y7 C8 O7 q5 F# G$ S' l
#include "WssLockKey.h"  v8 [% a# ]( c5 u

- ?. C7 Z& r% z' M+ Q1 w2 w: S. UNTSTATUS' f( S$ T% ?: t  ~/ E. v3 X
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
1 Y; Q: T: C2 s$ X             IN PUNICODE_STRING RegistryPath )4 [3 n# r4 D2 }( N) e
{
: z; |, q" T; D9 q: Y  UNICODE_STRING KeyDeviceName; " P( U) M; f8 I. S9 q+ F
  PDRIVER_OBJECT KeyDriver;
7 j' V) x7 N% O* W  PDEVICE_OBJECT UsbDeviceObject;
8 `! A. V/ S) j, m  NTSTATUS ntStatus;
. w4 a& @  i2 X1 y3 \* X  ULONG i;
8 J6 e9 n$ K& j
  L" V( |# o7 c4 E5 U7 T2 m9 ], \  //
/ K! d7 @) w7 u3 [3 S  // 保存设备名,调试使用6 y) Q! @6 J6 r% _
  //
+ j/ |# k1 {6 t) ^4 L  V' j% Y  WCHAR szDeviceName[MAXLEN + MAXLEN] =) V; v- m) R, g+ C0 `9 T
  {( w: _. b8 Z2 r- m* q
    0' [$ n! Q) P! Q, n2 p: |
  };
# n1 Y7 q, K. K/ u, r2 g! B0 k. k+ M$ q% m
  KeyDriverObject->DriverUnload = KeyDriverUnload; 6 F" V, L9 ~- r( c4 \
6 g( V; G! f' N8 s! }
  //9 ~& k5 m( ?% Z# x) e6 T- b! P
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘: ?" v& I& V' |+ `- W
  //$ a# J5 b% e& p, h; }5 [
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
4 W1 U% W( s) B0 |! ]* {' A  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
9 Y0 ]" f8 }6 J+ ], T1 p1 N  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到5 K, m. Y9 B, a# ^, z* O
  // USB 键盘设备来进行挂接
' C  T4 D5 z( Z8 e  //; h* }: \+ i+ w: |1 u
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );. ?' X; U" @& j8 g
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )+ A! K7 h, ?( i' Q! V0 `# ]$ {
  {
- _' |; c- {/ e  L, v    //
- Z2 \* t  s" _( J! t3 x& Y# n1 D( s    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
! ], |9 {  [+ H. ]' `1 a- c    // 所以这里打印为空
8 z, A" A4 w. \# P* ^* j4 v    //
/ G  D# Y* Q3 r3 Q    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
  J: m7 ^: A, h) `    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );$ ~' L# z' D4 x4 h5 w" z

' R5 C7 [# L4 n1 ]+ i9 }' A    //* f2 K9 q( f. z& I" A
    // 挂接 USB 键盘设备
5 {9 f* r! f% u% t# d    //
6 }' ?+ c0 F7 @( s    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
) O7 Y8 J' e2 M. [    if ( !NT_SUCCESS( ntStatus ) )
# o& b. {2 A% `, \    {
8 a  w4 k8 C  _      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
( C) v6 |& U, }- x0 i  r8 q! V/ v      return STATUS_INSUFFICIENT_RESOURCES;! t$ \7 x: y! C0 r* h# A
    }% j" p2 f# J$ k/ e" v2 R- m
  }
5 |# @- k4 |0 Q" @  else
: t# {. Y- i9 T/ J3 S  {  ?2 c+ _  s3 i% d
    //: y9 }# T8 h2 l, B  ]$ P& i3 p
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
, W0 W3 k9 ]$ @0 X3 t1 D    //
3 n& H+ Q% I1 O  c3 d& j' Z% K5 e    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); ! P$ z+ |. |0 w* z
3 w$ @5 S+ |; n1 P- r  J
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,8 Y) P7 C- u) b5 @, M3 g- R7 E2 a: z1 V
                                        KeyDriverObject,
/ t+ J5 L! `  Q                                        &KeyDriver );" G# G& e, f4 B' h* }2 ^
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )& t0 l' l4 s0 K
    {/ L& x. o: U$ o# j2 c5 m$ q/ i" d
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );# x1 S$ m6 ^0 l+ U; _. M$ X, A
      return STATUS_INSUFFICIENT_RESOURCES;" N( z/ P1 N% {+ V. z) U
    }1 m" x6 M1 |9 S; E
  }
% j1 L" u0 L3 d6 I
3 `: [3 n/ n. U2 ?  //
. j; @- L1 k) _; l2 _  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止$ r& y3 c& ^1 i. H  @0 U
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程) I2 x2 ]  o3 O/ N2 D, u' X
  //% v3 t0 N7 p, c' p/ P
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 5 U2 S# }5 r) d+ O5 a; Q
4 V1 P( l4 l5 m6 _! f. T8 _" X
  return STATUS_SUCCESS;  T( J& H& [8 g  q9 \
}
5 [/ v# \6 L2 G6 _( G1 S8 F3 T: [* J4 d' I
/////////////////////////////////////////////////////////////////
& v; z+ s9 L7 \4 i, i, z// 函数类型 : 系统函数
+ V: ?5 I, ]6 m+ v) g// 函数模块 : 键盘过滤模块; X. `2 a+ y+ a, W9 y
////////////////////////////////////////////////////////////////
$ Q1 J) v! e4 g// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
2 U2 U- Q( T4 N3 E2 e+ Y" X3 }+ J//        卸载键盘过滤驱动
+ i! F/ }; @7 s" J. Z// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上/ C* R. X; _2 W: p# b' w
//        则需要等待用户按键,以后有待完善; ^6 Z; a# {: D# t
/////////////////////////////////////////////////////////////////5 N* x4 \( q* D" r# s
// 作者 : sinister( z9 X! O' j! a: _$ X* U
// 发布版本 : 1.00.00
/ S4 E1 F8 |; }/ S- Z3 Y- {  S// 发布日期 : 2005.12.27
4 |0 H, \, Q/ ]/////////////////////////////////////////////////////////////////. _; z9 ^& x& S
// 重   大   修   改   历   史
4 w- }* ?5 T7 L8 V3 X" I////////////////////////////////////////////////////////////////3 s  Z( I1 g$ w) A: K
// 修改者 :. r( l" f0 Z$ l/ [! K# F: L) k
// 修改日期 :
2 d' @: o, e6 v6 H/ Q4 Z8 ]7 m! A( T// 修改内容 :8 K* {+ t, M" Z: w1 M
/////////////////////////////////////////////////////////////////% n6 U% x: O  O( c

" k; Y7 g: Z$ M% EVOID
) E/ x4 v$ C$ t& cKeyDriverUnload( PDRIVER_OBJECT KeyDriver )  S- v% y% w" [# o4 e$ m
{
8 R: b4 ^* w+ b  PDEVICE_OBJECT KeyFilterDevice ;      5 O& o7 {) \, V( T
  PDEVICE_OBJECT KeyDevice ;- J6 c; ]) Q6 @* Z0 ^+ L
  PDEVICE_EXTENSION KeyExtension; ! i7 B8 P$ \) R8 v0 S) j( o
  PIRP Irp;
+ l7 q& }( e" u2 y  NTSTATUS ntStatus;0 ?$ t# ]! i- d; o3 F

1 I* R0 x" s7 k# V  KeyFilterDevice = KeyDriver->DeviceObject;   N* A  S1 }) T/ E
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
. |7 H+ ~! X0 E0 K* a  KeyDevice = KeyExtension->TargetDevice; # o% D4 t1 L( C( _" t/ c

1 w; E0 W6 B7 o+ U  IoDetachDevice( KeyDevice );
- c. a1 b$ l/ @- k) a
! A7 K9 p# r/ j  //
# {7 k& x" t/ _) O  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP( j3 d* w. \* J4 V8 Z' ^! v4 Z2 P; ?
  //2 [/ w2 x8 M. M( [" `
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )1 ^4 s0 _0 E( C* N2 S: X6 I
  {; z1 W( \+ C/ n2 n  X( @
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
9 s) X- [$ `" l/ k- X    {
' u# x5 g$ i* u      //
0 v2 M7 h) {. P% T      // 成功则直接退出删除键盘过滤设备. y+ \$ r3 [1 I1 ^+ b3 I, d' y
      //
, w' g3 Q5 M; Q0 G      DbgPrint( "CancelKeyboardIrp() is ok\n" );
+ |9 r4 v3 N4 X) z( m      goto __End;
. ~$ P) O; V/ H, Q* C/ D9 ~) B    }
, n: S( G* {5 g& s! c6 M8 i7 w  }+ Q9 U1 b" R9 N* Q$ O

) E  W0 n" ^% Y3 z4 K  //- ~' l, O$ J; q
  // 如果取消失败,则一直等待按键& l1 n5 {+ I' |$ g2 T8 z  Y
  //! j3 H0 ?$ ?! X
  while ( KeyExtension->IrpsInProgress > 0 )
+ T) R  P8 G9 x- s6 X  [  {
( [2 M0 R. S! n6 V5 {    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );) H$ Z% M# W' O7 R5 M, T5 m
  }9 J& x9 Q% _$ r2 r
* l1 T6 ~( r! G
  __End:
. N4 Y8 h; Z. h1 |0 r7 |  IoDeleteDevice( KeyFilterDevice );
4 L5 g. J3 _; G/ ]4 }. D  p
: s/ K+ N; R' j) w& D; t0 P& ~  return ;
- Q; E7 M% k* Y" g} 1 ]; [* ~8 I1 v5 W

. I4 w! H% }  }8 G# h8 [: b% G/////////////////////////////////////////////////////////////////; \; ?$ Z% O6 S; f0 P4 A7 s
// 函数类型 : 自定义工具函数) o  ~6 b, b$ t3 r8 y( N
// 函数模块 : 键盘过滤模块6 k1 `% U2 r1 P+ L4 w
/////////////////////////////////////////////////////////////////4 O: \) o( Q& T8 O  C
// 功能 : 取消 IRP 操作/ Q" o; l7 P# }. X4 e1 p
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
) k4 g* P3 r/ G; ?! Z% B9 Y3 k# C//        使用此方法来取消 IRP* N0 \' P/ k' F/ \; a$ M) C1 @
/////////////////////////////////////////////////////////////////
8 E  E# @9 V$ ]- W/ a2 f0 n8 Z5 ^// 作者 : sinister! J1 J; }2 C& H1 w9 |
// 发布版本 : 1.00.006 z# L8 v) G/ g( e0 o6 n4 z/ V
// 发布日期 : 2007.02.20$ R3 n  [4 l4 [
/////////////////////////////////////////////////////////////////
1 o7 B7 u4 ]& s% \# T$ B// 重   大   修   改   历   史
4 d4 C1 h5 T) L9 n+ O/////////////////////////////////////////////////////////////////% ~, G: {4 l/ g/ d. k6 ^
// 修改者 :
' m* b, E( v: O// 修改日期 : % o' x% `; q& l& Z( F8 p
// 修改内容 : $ C5 V4 Y1 I5 a
/////////////////////////////////////////////////////////////////
  M+ n0 v3 M& @- B3 J* f
/ {, U1 @! a' j+ t* x  E6 o: ?BOOLEAN
8 Q! u% C# @8 X: y3 j+ N1 \9 QCancelKeyboardIrp( IN PIRP Irp )( l& w  }8 _$ F: x$ x' w. a
{
+ Z$ R% _! J) F7 `% u) g  if ( Irp == NULL )( W; R; R) Y, M$ Y% ^8 B# r
  {
& K) `8 H% }' b4 v% w1 ^2 g# @/ g    DbgPrint( "CancelKeyboardIrp: Irp error\n" );& [& F; U/ Y# c0 ~& H5 }/ R
    return FALSE;
1 X6 X' ~% I; X: C8 L% b  }
3 F! G, A$ k7 T4 R5 f9 ~
# B; o2 e+ v4 W$ z6 _" l1 |0 I' V4 c- E
  //
6 M9 V7 g, T0 T  j9 {" T' P2 \* g  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,, D" {; U* ~  x" x1 S+ S" ]
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。& S, I% v1 p9 `' m' s6 J9 `1 c
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
9 x% V' }& V9 p1 y+ e  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
/ Q+ q" V/ w! t0 U  //0 J( Z% ]+ A0 m

" e1 O1 n' |# u$ q3 ]) ^- X  //% ]" `4 `0 g! ~) B- ?# p
  // 如果正在取消或没有取消例程则直接返回 FALSE
0 h% W# k7 z- T* W: f* U  //
6 e2 n. K7 D, D: j  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
$ N# D1 r9 P( F, _  {
& E4 U, j; s8 p. G" h: j) E    DbgPrint( "Can't Cancel the irp\n" );
& w9 K( @5 F" ^) d  U& }4 f/ V    return FALSE;
6 f7 _, Q. S! ~  }$ l2 E- u" p* p) v5 W8 H$ @* U
8 D( I8 z; R8 G) \/ a9 g. o" w
  if ( FALSE == IoCancelIrp( Irp ) )  b& u. ]: l/ N+ }" H
  {5 C! T- D3 D$ Q9 j/ |  w2 Z) x
    DbgPrint( "IoCancelIrp() to failed\n" );
" _  r6 ~4 j7 X' p    return FALSE;
( L3 }' S( ~2 F- K  K% ]  }
! F/ p1 }0 p; u" b2 }) f1 ^! f: Z
- J3 K) k. |3 r  //
% u! I6 X+ Q4 L3 ~) b0 P% i  // 取消后重设此例程为空
0 G8 N! q6 H* G: a; ~, `% S  //
. K: [  w+ r! o: y$ F. L3 d' j  IoSetCancelRoutine( Irp, NULL );9 R; d1 E) V: x0 i! k3 m
  s) W7 J$ W1 Z5 e2 L, ?
  return TRUE;' H* A7 m% _6 X( n
}7 S; t% j2 r" G( h- v! y

8 d, v* D/ ]! q. l% H9 j0 G2 ]/////////////////////////////////////////////////////////////////" I% B. w& u9 J' c
// 函数类型 : 自定义工具函数* R; m  F  y6 m/ B
// 函数模块 : 设备栈信息模块
4 Z; |, T$ l$ B: T8 P& s$ [/////////////////////////////////////////////////////////////////
( s  n; |! l" o( T2 B+ i9 t. {// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘* j! [+ p; S3 C9 d0 a( V* s5 k
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
$ |+ Y  `+ ?2 r+ A// 注意 : , _) y; N& o$ w+ j0 {. ]& d6 C7 T( O
/////////////////////////////////////////////////////////////////
; P4 b5 f3 ?' Z! v3 c7 ]5 V6 b// 作者 : sinister# d* C% J8 a* x
// 发布版本 : 1.00.002 k$ f) |! w1 }+ T. ~) r8 i2 F" ~
// 发布日期 : 2005.06.02
$ Z- x1 A0 _, D) D/////////////////////////////////////////////////////////////////. j/ y1 w  |1 l2 I& p* u& s; ^: O! F
// 重   大   修   改   历   史
2 G0 ?4 X/ _3 Z6 N) I/////////////////////////////////////////////////////////////////! O" }% L( E1 T. B) S: g+ Z( r
// 修改者 : sinister
  G5 E/ k% U; S: ^// 修改日期 : 2007.2.12
6 J7 S7 L& k8 W4 D// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
, _. v/ _6 c* ^- C9 E/////////////////////////////////////////////////////////////////- ~4 ]) @8 c5 A6 h8 n1 ~" s  ]! n

% i: _% Z- x) _2 W+ KBOOLEAN
/ z9 a- w, C1 d! `0 [! }GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj ). R% i. v+ ?7 l' N' S
{
2 u  ^2 ~$ u& j* n6 y! ~# z# \) n5 Y0 ~& z  PDEVICE_OBJECT DeviceObject;
! g& ?0 a. m) W5 T; v8 T& S1 I  BOOLEAN bFound = FALSE;% j: u; p! g9 e

7 G! ~1 V( {, h9 C  if ( DevObj == NULL )
' z- M0 c" N0 b: ~* E8 s# p4 a# X1 ^  {3 @* O5 C6 h/ P' O
    DbgPrint( "DevObj is NULL!\n" );" n4 i5 H& v# r' ]4 Q
    return FALSE;
7 q( w( e5 g( w) Z/ ^- |  }% S! C: S; Y, ~: b4 j
+ F& z2 E9 r; K5 W  k; o
  DeviceObject = DevObj->AttachedDevice;
9 m+ n6 J) g# \$ J1 x
+ t4 y- O% c5 K/ N" F( {  while ( DeviceObject )
1 Q( g  B2 J8 |1 a7 @  {
9 I2 a" }' g& r; P4 {    //( q, t! V: f0 K
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
4 v% t# e* g: e5 `$ t: S5 ?# r2 \    // 有一次足够了。这算是经验之谈
& a% c# i9 L6 u# f    //
$ A3 p. r( V5 w" j8 q0 S* @; e1 M. V9 K    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
: [/ `) A" o" G1 I! P2 s. W# x6 R    {
0 s7 o  {; q1 A      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",4 r' @8 ~' c& L
                DeviceObject->DriverObject->DriverName.Buffer,) `- P$ G, j$ c& n) |* a' N: o
                DeviceObject->DriverObject,
+ k  l$ X; L" h                DeviceObject );  ]- p% n- j1 |9 p) [& ~

. y2 C0 w5 e* u) w! Z! q' J- V      //
3 R* S) z6 ?/ N7 j) H9 m9 |. \; m      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
( o; P+ X7 K# t6 i8 Y9 R- v      //) U  [; h4 p7 G& S
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,8 g9 B/ W# F3 j) F5 C1 K& D# p' h
                      KDBDEVICENAME,2 \$ O/ @* O! W4 g" W, u
                      wcslen( KDBDEVICENAME ) ) == 0 )
: B( V8 L- m- r* Z" q      {
% F- B% w! r* T2 t9 r+ B        DbgPrint( "Found kbdhid Device\n" );
, k$ g5 g' d! ~% c" H) m        bFound = TRUE;
! w( L2 O8 T  _  C- a8 Q7 Y        break;
& u. l0 i$ [5 A; y      }
% O8 J) w( h. H0 e5 L; V    }- Q! a1 Q$ c+ Z9 H4 _/ n! F' w
8 @- U7 |  b$ ]1 J2 z- e% c
    DeviceObject = DeviceObject->AttachedDevice;8 q8 u6 [: S4 \6 a3 J7 Z" G% R, E
  }
- O; c( U7 M+ i
( g: F( x7 V3 ^) I  return bFound;
/ Y6 `  \: d5 R}
) y0 D. U4 R  V1 G
9 S0 ?* O+ [% c/////////////////////////////////////////////////////////////////- Q' v0 ~/ M. t& ~
// 函数类型 : 自定义工具函数
* ^: j, ^" C' g  J9 H4 V// 函数模块 : 设备栈信息模块- b8 ~6 |: D: N) G
/////////////////////////////////////////////////////////////////8 q! Q* z0 r9 b1 k9 M% o
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
- e. Z* h. o3 e5 X// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改3 L/ X+ c, \5 M, P( o4 L" Q
/////////////////////////////////////////////////////////////////' i3 F+ |) N0 I2 h9 L4 r" E! [  r
// 作者 : sinister
+ ?. I! \9 c. u% Q- N! m5 C" I8 L// 发布版本 : 1.00.00
7 }: F* Z7 W; h: e// 发布日期 : 2006.05.028 u* c! r3 r  u% c) W- U1 i
/////////////////////////////////////////////////////////////////  G$ g; J2 Z! W0 A& @
// 重   大   修   改   历   史: G6 t$ a  |/ [3 N# J) E
/////////////////////////////////////////////////////////////////
& I. T% w. M; L: r" `* G// 修改者 : sinister' ^4 U2 z, `; I) R
// 修改日期 : 2007.2.12. H" }( X( |3 p! f' j! m
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用. {+ Z; }6 E. {4 _& m
/////////////////////////////////////////////////////////////////, b" A, F3 F' L( C
! ?; U% ^/ w1 j3 X
VOID
4 K/ W4 l2 z, ~* X' F4 gGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
5 ~  C# \/ g$ x) z, G: n, G{# U. @+ u8 B5 z
  POBJECT_HEADER ObjectHeader;& _( n5 V" g3 g: J, @! v
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
& S4 W$ B5 H! E- T
* P7 \0 C- k. {) {4 v; ^& f  if ( DevObj == NULL )
( T, i- p1 v8 m( c" W  F* {  {8 d9 f5 K5 i7 ^5 |" S1 H
    DbgPrint( "DevObj is NULL!\n" );
" G7 A3 Z7 `* K. r9 W! ~/ G    return;# ~; r# ^' [  i. z$ ~
  }
# u) W& {% w4 c5 S
9 |0 E$ F2 v  c& j$ t) C  //1 @! u. f6 p9 j. `+ @- B; A  h
  // 得到对象头
' m# g, {: t0 o, P# C+ ?  //+ W- K6 Y! Y+ ?: D
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
, n* ~. D& B2 x/ X7 j" x
% ~: ^! W: x' c# Y2 N  if ( ObjectHeader )
$ K% c  x8 k# \9 L4 G+ c  {8 G) n, A+ X9 d. p- v& v, s
    //9 J6 M. l7 x+ Z) v7 k  Z+ Q
    // 查询设备名称并打印
& u" E# K9 E. [: x    //8 W. J) }9 P7 b5 A7 H) x
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );; A' n% @. H3 b: w  N( K

( q4 d2 k) ^# N: W- z/ e    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer ), ]1 K! I7 S2 G. z  Q- n
    {! X0 |9 I! X0 y' u9 M8 P! ]
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
" r! U5 A+ D0 e# A* t                ObjectNameInfo->Name.Buffer,
  I. J! ]3 \. q" J$ t                DevObj );
/ L8 k/ H0 U8 |: t1 Q% W. {- f/ P! b3 V' q" k) c4 N
      //
) T/ Q$ o9 ~. j; x      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
0 L/ L- t3 d3 k' s/ _      // 用,没有实际的功能用途
- H# B; F' i# Q6 H7 U# @      //: X0 A3 z5 b8 _* }: e: q
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
+ X- p! z9 @% j! W- Q; l9 v: a4 c- I% l9 n
      wcsncpy( szUsbDeviceName,& d$ M. x1 M) `* l3 }
               ObjectNameInfo->Name.Buffer,
) g" x) H) W6 R6 P; @  p               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
! ?' v! D) T( W, o  D    }/ s( i% T- I7 E. \! w& P( I6 U
; n( _7 u7 B- P# [; O) p
    /// f. ?& n/ y* i( y6 C; `3 c
    // 对于没有名称的设备,则打印 NULL% {  s6 h/ `: s' x8 C
    //
- E* N* ~' v. z5 S/ t    else if ( DevObj->DriverObject )" l8 Y4 G  z/ l/ N: \  i7 W& E3 V
    {+ S& @7 b8 ~, k. v
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",2 |$ ]! m9 F' I( z- f1 P
                DevObj->DriverObject->DriverName.Buffer,
, {: S* C" u" m3 @$ M# ^1 C2 Y3 U                L"NULL",
) O7 I  T8 e" {4 U                DevObj->DriverObject,7 Z: f- G! i5 h2 P/ a
                DevObj );; F1 R+ p/ ], i% W8 r. J% E  v
    }
% i, N' V8 ^8 e- s% k0 K5 e% t  }& Z0 e3 o7 ~( ?5 U
}
& J* c, E- e  Q8 N! j
0 e- `* R" U+ h; ^5 q: k# Q4 e/////////////////////////////////////////////////////////////////" d8 V) f& v0 ]& d
// 函数类型 : 自定义工具函数
9 {! y4 }+ W1 f+ k2 p; o* J7 P# C// 函数模块 : 键盘过滤模块4 f3 t, S- }+ k4 K* z6 a  B
/////////////////////////////////////////////////////////////////  ?$ S8 S# `9 {& O4 V
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
8 W" _! P; o2 w  |" }% l6 i//        对象,过滤出 USB 键盘设备,将其设备对象返回
9 k% e. n% M+ h5 L4 C// 注意 : - {5 F- P6 U* i9 Q! r8 s
/////////////////////////////////////////////////////////////////! m9 t( E+ G/ T, Y* a3 N6 `
// 作者 : sinister1 u4 _: \$ n$ ^1 A3 j# i) E% J
// 发布版本 : 1.00.00
4 {( [- D* {) C" O// 发布日期 : 2007.02.13
$ V) Q1 L) i* _2 ~0 i( d& p2 o/////////////////////////////////////////////////////////////////! f& j! s( T) `! B) l/ E
// 重   大   修   改   历   史! i7 J1 T5 E1 S3 o9 X3 E1 i1 N
/////////////////////////////////////////////////////////////////  B9 g, a1 u' P6 {1 Z" n. E3 m
// 修改者 :
7 l& l( _& m$ f( X  f$ Y// 修改日期 :
0 ?5 K% @8 F4 z// 修改内容 :
9 P8 i1 |$ P& g# K/////////////////////////////////////////////////////////////////
; k3 ^: _4 J( }$ m6 \5 f5 e
& P+ @1 G3 |5 ~+ I7 N( Z- s% cNTSTATUS
8 N: z/ k7 G8 J5 tGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )" \$ h$ G& P. n" G
{  f7 j$ o* P, q& [
  UNICODE_STRING DriverName;
- p6 I) K" X  G, h4 r2 A  PDRIVER_OBJECT DriverObject = NULL;; i4 e; |/ O6 E. s- F
  PDEVICE_OBJECT DeviceObject = NULL;1 X2 u9 [% h0 [% m' ?2 |$ ^
  BOOLEAN bFound = FALSE;
5 O0 c3 p& R  L% t7 H5 T- L7 j: D7 v
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );& \2 q9 j' }# |: R

; B8 F: v0 T/ T7 w/ M0 H  ObReferenceObjectByName( &DriverName,  G2 ]- {! u; g4 Z8 m7 z' |+ M- H
                           OBJ_CASE_INSENSITIVE,; j4 f  [  c+ D2 ]
                           NULL,* u& E/ g) r/ D5 ~# N" `' ^
                           0,1 ?0 Q9 u$ M3 ?, s) U9 ^
                           ( POBJECT_TYPE ) IoDriverObjectType,
3 b* E: B- k9 T                           KernelMode,
3 S# N0 Q5 M# G0 U# ]                           NULL,/ K4 `7 T4 ?& V2 e
                           &DriverObject );( w3 y0 u! T0 V$ F  E
  O/ m- i+ H0 q. T1 J
  if ( DriverObject == NULL )
' X9 N" q4 T% ]+ f  {2 @5 i- g( x" D; o% J
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
" P: ?* o9 V8 C" }7 A/ z    return STATUS_UNSUCCESSFUL;  h/ n$ a, z# t8 `! I( D+ X
  }
( I- k9 M7 T: m+ _' ~* \4 v& Y5 V$ N. x7 B2 ^- l
  DeviceObject = DriverObject->DeviceObject;
1 ?7 B: e- o8 k% ~+ Y. Y& u3 {- ]# v1 V) [6 `
  while ( DeviceObject )
& V$ }/ [8 ^; x- ]- R  {
, f/ }" O9 E) i; D  }/ c7 {% K2 K    GetDeviceObjectInfo( DeviceObject );/ c5 ~# H: M3 s) V2 \6 }2 O7 [

( r7 g8 d: q  n5 R3 e( E# p6 p- d    if ( DeviceObject->AttachedDevice )% A0 g7 h. a$ q0 @6 E5 t
    {1 _- T# ^, {4 A, `/ h: R
      //- {5 {1 Z; A+ L- U, x7 Q& m
      // 查找 USB 键盘设备" ?+ A) Z+ k4 o: {6 Z  q4 U& Y0 }
      //
+ D0 k6 t* U" N+ k4 h) R* B" v      if ( GetAttachedDeviceInfo( DeviceObject ) )
* E- w/ c/ q. X# L* l" T8 j$ b      {4 x. J# f! x, d5 n3 ?/ z. |
        bFound = TRUE;
" y, F& Q9 b2 @! `        goto __End;
6 a1 n. P  n. N% b) c      }! \, I, q, w8 Y! \; }2 a$ X
    }
/ q7 u3 M4 V9 E/ G. W& R' G- ~: p# {% v3 Z1 \% E3 X6 Y% }7 y
    DeviceObject = DeviceObject->NextDevice;# W! T) X- d# W/ _
  }
4 f8 v# C* \! c, w+ y- p
; S0 N8 z+ Y: H% w  __End:6 |3 h. N- z; B. W
- G5 k9 C9 C6 ?. X
  if ( bFound )4 F" g; Z: ^. K
  {
# u) R. {/ j1 y4 [# \    //
  j1 `/ F2 a6 \    // 找到则返回 USB 键盘设备对象) I, T3 q2 k1 D8 A* a, Q" U: q
    //6 [' t: z+ K8 k- v$ o% |
    *UsbDeviceObject = DeviceObject;
( M1 q2 P7 H* C: k  M  }" @% d$ D. \  [) ^1 Y- n; s6 Y, o) u
  else
0 A: g* R8 J: G" Y  {/ |. L& g2 H8 q, y
    *UsbDeviceObject = NULL;& ]8 t0 u5 z( L+ s9 _1 b
  }  s& A3 _# {& R' \( ?" r

+ ^: B; W0 l' `3 e' r# R: R  return STATUS_SUCCESS;
+ W, Y0 }7 R. w6 {6 y' y}
- G0 _" S+ U9 v8 ~8 [
* u5 _0 k: a4 d/////////////////////////////////////////////////////////////////
: s# R$ L3 ~% {3 s8 Y// 函数类型 : 自定义工具函数8 N9 b2 ?% g( |9 U3 k! o- w
// 函数模块 : 键盘过滤模块
* U/ R8 O( V: W) h8 y////////////////////////////////////////////////////////////////
  f  c1 `' O6 S9 p  ?* M// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
& O$ N; I& [# E, a* n8 U//        信息,返回附加后的驱动对象
* V$ O& R: c! @: |5 b// 注意 : 此函数仅挂接 USB 键盘设备
- t. z% q  _! T) p/ l  M: O/////////////////////////////////////////////////////////////////; T. z7 U* e2 S4 ]# n$ Z
// 作者 : sinister
- |: f, L8 Y; X4 Q// 发布版本 : 1.00.00
* Z/ v5 H! c- f$ ^* s$ X// 发布日期 : 2005.12.27: t% }% J. J# }; @. T
/////////////////////////////////////////////////////////////////0 `9 `* d) }" m% _. X
// 重   大   修   改   历   史
3 n$ h; `. S, ?5 C////////////////////////////////////////////////////////////////
; @$ V! P0 g; p4 k' o9 G! X7 ^// 修改者 :
( z  G% |0 l9 R7 z) w// 修改日期 :4 v( `' @: V6 P: ?: J' h5 `
// 修改内容 :
) ?7 s3 J! V: X! F& z) O/////////////////////////////////////////////////////////////////* f; \7 O9 r' \8 K# p9 n

& r; {: E$ a' T: V8 ~NTSTATUS4 o4 b1 g) O- W' |0 Q5 u% x! J
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
& E. y3 J* w# s# a/ D                         IN PDRIVER_OBJECT  DriverObject )
0 V4 F: h7 }' g{
& `/ C$ Q: Q' c- x( A) Q4 V  PDEVICE_OBJECT DeviceObject;
* v0 K0 a0 B" j  PDEVICE_OBJECT TargetDevice; 4 z0 \4 x* M0 d9 A& o
  PDEVICE_EXTENSION DevExt;4 J! h0 V$ H9 N; N/ {( _
  NTSTATUS ntStatus;( k7 A  R4 S  I$ e3 N- T, }. ~
) u4 K( i. d3 \3 P1 \8 O3 T
  //
1 W4 ~+ ?6 T4 O6 `) o+ g8 K  // 创建过滤设备对象- U# M2 N( F# r7 b
  //) I# f# G& e, x, Z/ p
  ntStatus = IoCreateDevice( DriverObject,
  \$ Y" T0 u& ?                             sizeof( DEVICE_EXTENSION ),
2 `$ m/ m% |# ?2 F/ n$ R                             NULL,
4 J* F8 s/ o3 _/ w8 u                             FILE_DEVICE_UNKNOWN,& w+ n1 @/ d( F4 V
                             0,
% }8 z. ]# Y3 P- G- _' }                             FALSE,
3 i) J9 d3 e& H6 |/ p- H                             &DeviceObject ); & W, O1 m) [* Y& F/ P8 p) q2 e- Y
/ ]6 }- Z  j8 p. c" R+ h' l% T
  if ( !NT_SUCCESS( ntStatus ) )
( T+ L5 r! T; I. K  {
, c( R1 r; f+ S# y9 X) k    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
  O8 v& S" l$ ?$ H    return ntStatus;5 X4 \4 v, a% V+ ?+ y& A
  }
9 |& Y8 S, t1 T# r5 c
8 A4 S# W: I; e& K- a% ]; E  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
6 _1 @! ^3 N) e( c% y& H3 K) s! D9 V3 _/ S( l5 ~- L8 h$ M$ Y9 u
  //; f8 j! C  ~# g# `8 n% ^; d; V; N
  // 初始化自旋锁/ [* g8 g9 h/ D
  //
; K* ^% @' W4 [2 s& i! y  KeInitializeSpinLock( &DevExt->SpinLock );7 \3 ]- Q5 ~9 |/ J& A. M

5 F, e; w6 m  Z1 S: W9 M- |  //
* g: a6 K+ y* P5 k7 l  // 初始化 IRP 计数器9 V# E7 j- E! l5 C
  //
- _7 c" c9 {: t. ~' d6 Q3 ?  DevExt->IrpsInProgress = 0;
4 N+ u8 I6 E( f8 W9 B
) |+ l' Y# b) g* b) N  //. v( U/ Q" o1 _0 G/ V
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象, \' a2 y- \/ P4 a# |
  //# c$ s5 T+ t' P

  T- c7 O* }1 b  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
+ I4 A2 o. Q; ~' J: X  if ( !TargetDevice )+ @7 z' s2 h( i& A+ V" T0 O8 W+ h
  {* C( w! t  [1 j( y$ [+ A
    IoDeleteDevice( DeviceObject ); + {9 O" ]) v8 _
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
/ V; g) F0 y# g- g" J5 `    return STATUS_INSUFFICIENT_RESOURCES;
7 P  t! T6 x* P2 Y/ X3 c  } ! G4 @9 w! J2 S0 D
# J: X6 m+ s" ]' i5 ?; n
  //: u5 M  p1 L( W  V4 l
  // 保存过滤设备信息1 ^& ?; |' Z, |/ K, H
  //1 h0 i( l6 ^+ v, u- C
  DevExt->DeviceObject = DeviceObject; . F6 q% Q) u: ~" ^6 N3 o9 w7 V
  DevExt->TargetDevice = TargetDevice;  b/ R* c. @- E5 ^7 G
" Y1 A3 D) I! \( ?! M
  //
/ K9 n5 E' M3 R  M3 W$ ]5 u, O# R  // 设置过滤设备相关信息与标志
) x0 c) J1 f! s0 f  //
* t1 t2 V& b' T# H; O8 Z) P3 N% r1 I  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
* V/ c9 h' ~! ?; {4 q/ n: w: O  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2 V7 F3 R& B/ \7 I' Q& ?
# @6 ^0 G+ f: U! L, M
+ p" Q+ U, V+ x' N; V- l9 H  return STATUS_SUCCESS;: W/ b, C$ ~. `& r
}0 ?- B$ Q1 |7 [- P, U% J3 B8 M" t5 ?
( \  U; t; {1 t2 i" D9 `3 }
/////////////////////////////////////////////////////////////////
5 d9 w1 u9 L: ^// 函数类型 : 自定义工具函数! F, h! m5 a* t
// 函数模块 : 键盘过滤模块
. D" E3 W$ m+ m4 e! b2 _) @////////////////////////////////////////////////////////////////
' x, I! H0 [# b# D) }4 L// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
; w+ g. ~/ y5 L//        信息,返回附加后的驱动对象! D# O) i1 B! s; h+ d2 k8 ~6 b9 K
// 注意 : 此函数仅挂接 PS/2 键盘设备# B; M( o2 L) }# p! W
/////////////////////////////////////////////////////////////////
  h8 [2 ~  e4 [( A, C// 作者 : sinister6 ?5 f! Y" L% E* |
// 发布版本 : 1.00.00
0 J! h7 a. Q: c4 I7 g/ D// 发布日期 : 2005.12.276 R6 J; O, b1 k$ ~, d  W
/////////////////////////////////////////////////////////////////: W; \  F+ C+ z
// 重   大   修   改   历   史
2 I  e# @0 X1 B" [, c9 i////////////////////////////////////////////////////////////////
6 d& Z3 i2 B# a2 _% b// 修改者 :+ R* x# [& E6 M- X9 Y/ E8 Q
// 修改日期 :
- H2 v: z# v9 z3 |6 T// 修改内容 :
8 w6 p2 w: q; {  K+ M! J/////////////////////////////////////////////////////////////////& R8 x8 B( }5 O
  o9 k, Z+ z( l4 |) O
NTSTATUS
9 \4 m( w  Q' z/ l% FAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
1 `" U; Z1 N; n: \. I                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
. T! n$ @$ Q( J, q                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象" [" d6 ^+ A! u7 o5 ~/ I# c
{
% a; T5 _  `. u( a" x) `  PDEVICE_OBJECT DeviceObject; # X5 ^" ?8 f  [  F$ n" F3 J& y
  PDEVICE_OBJECT FilterDeviceObject;
9 Q$ d- @0 O# y  PDEVICE_OBJECT TargetDevice; 9 Y# @3 U, s# j! A9 s* L
  PFILE_OBJECT FileObject; + b2 {1 b. v1 C7 f
  PDEVICE_EXTENSION DevExt;, Z$ @0 D) Y5 K: [2 l( F

+ B0 F& c& {# r" _( u6 p  NTSTATUS ntStatus;
( l' \' L3 e3 o. s) ^8 }3 K# H. y0 b, j/ W, g
  //  d% p4 ~" m5 _8 n9 }; @
  // 根据设备名称找到需要附加的设备对象
) D( {. _8 R* l9 S# q$ W# G0 A  //' V' B! t! G6 e. ^
  ntStatus = IoGetDeviceObjectPointer( DeviceName,- C- k' i+ C; i
                                       FILE_ALL_ACCESS,
/ Q9 o, h  d- {2 v  ?5 ~8 }  |# d                                       &FileObject,, _+ J" M5 l9 @4 y
                                       &DeviceObject ); # r/ t1 p/ a( |6 r

/ v* _8 R/ J  Q: Y/ j4 h: U% r  if ( !NT_SUCCESS( ntStatus ) )) s! k& e# l9 a  ?. Y
  {( R& R" z0 }3 u5 D, J
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
' D8 a9 j0 H0 T    return ntStatus;
/ S8 B0 j) I7 X$ o, L" @4 {4 p  } ! n- {9 i$ d& p

* Y; u  Y5 d) a7 Q, O0 ^. u  //
5 Y$ h& `) a/ s1 U  // 创建过滤设备对象  ?, ]3 W" c6 E% t2 y8 N
  //& M# H. z; E8 f$ s* h' A4 W0 T  [
  ntStatus = IoCreateDevice( DriverObject,- b4 _8 c8 U4 |0 |+ J4 m) f
                             sizeof( DEVICE_EXTENSION ),
) `3 `: v4 \3 d$ i7 A" E+ T; S                             NULL,) ~( t- i( J" r' g/ z, u7 t) l7 w
                             FILE_DEVICE_KEYBOARD,/ r. O& w. X2 R
                             0,5 Z2 _  T) R" o1 s% u$ i2 x
                             FALSE,) Y" ^+ v9 |+ p; p% e0 L) |
                             &FilterDeviceObject ); + A' G8 \0 s( x% f, t

5 t: ?. M7 s$ K- Z1 M  if ( !NT_SUCCESS( ntStatus ) )  }3 m; C' n  ]& G2 e1 i
  {
8 i) A9 ?3 [' K    ObDereferenceObject( FileObject ); & k% k: \) i! D: K; L
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );1 q2 a: k& Z! k6 d
    return ntStatus;! _3 j& [+ @7 ^  ~
  } ( C2 i: o7 o0 ^
# q2 L- ~3 x0 n4 X- D( [
  //
, B' ~  q) q; r" R# K9 o  // 得到设备扩展结构,以便下面保存过滤设备信息
* g' k3 ]$ w  u  //
3 t; B9 s' h# W. O8 D2 Y  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
9 A# E& P1 G/ x# i- Z4 W
7 |3 w6 J. \* D% O* }+ F: D9 A8 D4 @% Y
  //
. Q5 Q% B2 e( v$ g- U) l& f  // 初始化自旋锁" c+ ]& Y9 v8 N  b
  //
2 y8 X% @& O! C* [/ v7 G7 |) W  KeInitializeSpinLock( &DevExt->SpinLock );" Y8 g5 E5 I0 z1 S) h2 I! @+ m. r
7 w/ ^1 J) s9 O8 a
  //
; Y5 c9 y) c5 t6 \+ L0 F" K; \  // 初始化 IRP 计数器! j. Q+ t: P2 `
  //
/ g; P% R8 `( \3 \" G0 n( D  DevExt->IrpsInProgress = 0;+ {  z2 e& g. q( Y

/ r* \/ Z! H8 m5 @: g. A  //
( O0 n" p" s0 }' o" T4 }  T& i  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
  p. i( z5 h  q! [4 }. L; j6 t" g: p  //5 x4 b, w+ c8 e3 v* t; w
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
9 j0 U0 C- O. a/ E3 O                                              DeviceObject ); ) M, F9 ]' ?" z* A
  if ( !TargetDevice )/ J# }( q- k5 U  {0 H& L0 I1 w
  {
; {0 j0 C2 d1 K  t5 k" h& J    ObDereferenceObject( FileObject ); $ l! W! f% J5 a
    IoDeleteDevice( FilterDeviceObject );
: b' B7 v- q, A* l- C- T7 a    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
3 k6 [; a; l2 x2 b1 S    return STATUS_INSUFFICIENT_RESOURCES;* M0 v" F5 Z5 D: G7 c- f' Z
  }
8 V, o: L. U0 q
$ D0 s8 ?2 e+ G0 Z  ^  //
! n' Z9 t  @4 F/ W" Y+ o5 x  // 保存过滤设备信息
9 z" d5 C  z/ b* i  //
( O& F$ X1 ^0 ]$ q, l$ {  DevExt->DeviceObject = FilterDeviceObject; " J' X3 s. Q! m' g3 m2 D
  DevExt->TargetDevice = TargetDevice; ; ?# }2 T8 ~, e% q6 C/ {4 I1 y
  DevExt->pFilterFileObject = FileObject;
1 O2 g* ]2 ^6 |+ l+ b
" Y9 c# M5 a% r3 C  //3 S% N# H. X$ ?  V# I
  // 设置过滤设备相关信息与标志7 q/ B) E, d, S2 K  W0 J
  //
6 q  [" [  s1 S6 I' p9 t  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 7 {8 s9 z! l+ U" a* h
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 6 B2 B3 I. ^4 |
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ k% `8 [4 D! g% Y- W* O& N6 O# l' [  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |+ [. E! F5 z9 g$ S# r+ r& r; E0 U
                                                         DO_BUFFERED_IO ) ); ! _; d6 `/ J- d' N
( e9 |' S% X/ `; y8 b3 d
  //' _7 j1 o' w2 N# k: p$ D4 v8 ~# g
  // 返回附加后的驱动对象
0 n# j7 |! P6 u5 d- L  //
, r& B) e6 O1 y6 i9 }! _  *FilterDriverObject = TargetDevice->DriverObject;( J1 d& K! }2 R* y0 e
; O2 s4 M0 M  E" }
  ObDereferenceObject( FileObject );
. o' e. B; K2 C9 C; e( J8 |2 T6 s+ e% d& X: x, d1 a
  return STATUS_SUCCESS;
/ r3 `+ n1 |3 s7 T8 {+ T7 |0 e) b7 R+ ~}% J( ?4 L3 O4 f, a

' R3 M/ G- h$ h# @- p$ \/////////////////////////////////////////////////////////////////9 Z6 \# {  P. H3 d( q) O
// 函数类型 : 自定义工具函数
; U' ?+ B$ @; N# j' @7 i& c// 函数模块 : 键盘过滤模块
; W$ Q/ @: I3 i: y4 y8 X4 K$ i) B////////////////////////////////////////////////////////////////
9 L0 k' K2 U/ p. ], V  Q/ N// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发& l3 Z$ [, I1 S4 q2 L4 U, u, m
//        这个 IRP 的完成0 D' u) k" t) Q7 O) z
// 注意 : : @$ r9 q9 |8 I% _: X* I
/////////////////////////////////////////////////////////////////
( {7 T' x% W0 F# w9 q// 作者 : sinister
& ^: u: |( X$ C! L+ l( k: Q" [// 发布版本 : 1.00.00( {0 v1 U, \, l+ O% S* X
// 发布日期 : 2007.2.15
6 J+ ~+ P% H+ L4 z3 t* X# j+ O/////////////////////////////////////////////////////////////////
+ p, z* m3 z# X/ z4 _8 n8 s8 j// 重   大   修   改   历   史* E  b/ b: w( L" S5 f8 j, K3 X* N
////////////////////////////////////////////////////////////////
9 a3 k, j+ h  m' l1 r// 修改者 :( [- s* P7 z/ G$ \% a6 ^8 {  X$ j3 B
// 修改日期 :
% I9 m8 q% b, n! c% _9 Q. @! T// 修改内容 :( G2 u% [1 r2 @
/////////////////////////////////////////////////////////////////3 g$ W/ _& }; _- V0 Y( z

7 M7 y/ `7 Q1 `% R; eNTSTATUS. U! t- ^4 O8 c! f, |
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )/ I6 \# X- h  ?
{
: e# U# D6 X4 [, i' K  NTSTATUS status;
' t5 E5 z; C; o+ ^  KIRQL IrqLevel;: o+ E/ p( G) d$ v

* Y+ @; y; Y; V  PDEVICE_OBJECT pDeviceObject;, i# t6 G2 y, {( o1 K/ Q( B5 i! `; k
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
* p6 S. o0 A# L6 c; z# j$ m                                   DeviceObject->DeviceExtension;
# U: U0 T2 G, p0 w# s- x
5 f- b5 C6 n- b  f8 \8 D+ u) }% L" M! Z& F" W
  IoCopyCurrentIrpStackLocationToNext( Irp );/ O* X1 f" l0 K/ U! \3 e; t

4 L8 |1 t! ?0 K  @& r  //
0 e# n, |+ |* [' Z0 v  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁+ o& o# K. P$ I+ ]% I/ b9 P
  //
$ }1 V! _9 B$ }  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );9 z  T/ @; w3 a( _  h8 g% c
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
$ k7 }5 N3 ^8 Y( U/ z  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
7 W: [1 @5 r8 N4 G' I7 H
: U0 X3 f9 @3 Q, Q6 k  IoSetCompletionRoutine( Irp,  a& Y% Q1 a' I2 ~9 p7 x2 i! T
                          KeyReadCompletion,
" O1 f- ?) u6 r                          DeviceObject,6 {. m; K1 N4 M# H+ W" `/ m" W
                          TRUE,+ h' V& O( K5 @, A
                          TRUE,* C8 p' x) }" ?9 }( `, T) X5 S3 p
                          TRUE );
$ x# n3 `" u' U  S* M
4 R8 F3 {: u2 U2 Z0 l* A3 K: X  return IoCallDriver( KeyExtension->TargetDevice, Irp );
% A5 s& A9 C4 s8 n} 5 T, u* H" c. q! \
" m2 w0 o' _* U- e! z  h
/////////////////////////////////////////////////////////////////
  e: J/ `% R& T" \/ F+ s  j- |// 函数类型 :系统回调函数+ r! Q8 ^  F' r2 ~$ ?4 ]/ U
// 函数模块 : 键盘过滤模块6 t, c  {( G' m* P" A5 I
////////////////////////////////////////////////////////////////* A6 ]0 f9 |! s
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
, s- S) Y2 l7 E  q' d% ^4 H' V* C+ v7 Q// 注意 : * V1 D) m& \6 w2 C# y: Z! q
/////////////////////////////////////////////////////////////////; q/ ^* u: N6 D, M$ ]# H
// 作者 : sinister* j( x/ i- V) s: N  _1 |+ v# F) u( W
// 发布版本 : 1.00.00' y7 U. ^6 ~$ ?  Q1 @) l( v- n4 |0 u
// 发布日期 : 2007.2.12; i, M4 n* P" ]" A
/////////////////////////////////////////////////////////////////) j" M. V: e8 l- D
// 重   大   修   改   历   史
+ \% w$ I. a5 R2 D# u////////////////////////////////////////////////////////////////6 F0 Q$ Q3 @( O# B* O
// 修改者 :0 a% b( p' t8 }* |% _7 c
// 修改日期 :' V$ _' y, k  i/ B# T
// 修改内容 :
+ q5 X! Y7 w! a: }/////////////////////////////////////////////////////////////////4 n/ k* U7 T. \% s  g4 v( s# G

9 u$ F2 N3 E# d: b! INTSTATUS0 j- U: Z, W& `
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,# b$ {4 j$ I+ u" s3 G9 z
                   IN PIRP Irp,4 r' J) g8 T' {& G
                   IN PVOID Context )9 O  n$ I8 s% ?3 ^6 I! Y
{4 `9 ^9 M  U* f1 A  o
  PIO_STACK_LOCATION IrpSp;) e: {  O0 z  _' y+ ]0 D7 x, P
  PKEYBOARD_INPUT_DATA KeyData;
; m% z/ e5 w2 H6 {- ~  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION ), v6 a; R; z; m: U! g
                                   DeviceObject->DeviceExtension; * J7 h2 E/ v5 S7 R  ?+ H! m
  int numKeys, i;
& M5 i# S3 c% W, Z" I% w  KIRQL IrqLevel;$ Z- }+ L2 W7 f5 @
  H2 m! c5 P3 i3 H3 d/ Q. @
  IrpSp = IoGetCurrentIrpStackLocation( Irp );6 Z3 I$ |; M/ ^6 W4 }, K; Y2 @

6 G# s! n# V; t1 a
9 D" i. `8 S% u" @  B* _" i  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
9 M0 R& m+ w% \2 O2 L! [8 z  {4 s/ p3 p% r$ |+ U% h! T$ Z
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
# r* f8 B( l8 }2 h3 x) ^5 t    goto __RoutineEnd;
2 H! X3 J$ n3 W# u$ m0 s  }
, a. k9 e: u2 o4 D3 K
4 q7 }* W" E  @8 {& b  //: a0 p$ V/ w7 G, K* q0 r
  // 系统在 SystemBuffer 中保存按键信息
) m7 Q  l' W. k  //
' `! t' B) D- t, j5 G6 x  KeyData = Irp->AssociatedIrp.SystemBuffer;
+ V0 U$ l) b, B# _  if ( KeyData == NULL )0 _* s# x3 a- J+ q/ \; U8 L2 x
  {4 d+ t. X5 c+ U; T) M+ o1 u- `# S! u
    DbgPrint( "KeyData is NULL\n" );" v$ Z) M7 h- k2 h8 \4 n1 g
    goto __RoutineEnd;& q/ Q+ ~$ O+ |0 b8 O
  }
% d/ u1 w2 X$ a* _7 l$ ^# U7 @
2 ?! I3 o* C: m. F0 P  //
; O  i% t. ?2 G- J: z  // 得到按键数
9 i; Q( _2 L: O# h3 f  //$ z) [" a6 Q: _% M% w, S9 v
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
7 F5 }4 H# `$ }  if ( numKeys < 0 )5 q6 S- }0 U1 ~4 v& z
  {
- ^1 |1 p6 s# ~- g8 s& [$ F) S2 n3 P' k    DbgPrint( "numKeys less zero\n" );4 q# s" L$ H$ Y0 I9 x% C3 z
    goto __RoutineEnd;  \/ `3 H% T4 u2 k( d; M- k
  }, U0 a8 h. u! m+ W9 U5 f& D! |
, k' T( G+ m: y
  //# z' l* \& A: r6 \! [
  // 使用 0 无效扫描码替换,屏蔽所有按键
0 K( z, B; h; {( G  //
3 r' B* l+ s) N( K, P/ f3 j  for ( i = 0; i < numKeys; i++ )8 b& K1 x. {/ A' f8 ]" d" D# w
  {
, R) P/ z) g, o( w( y( d8 @, |    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
/ w/ Y/ U% w9 R' T( _    KeyData[i].MakeCode = 0x00;3 }3 ~/ y) I: v1 d* [
  }
7 u7 t, J$ I( \0 H1 ^1 T5 j/ {9 f8 L4 G
1 v7 T) ?7 a- j- d
& u3 f! V8 }; A+ V& O  `, i) K# z& Y  __RoutineEnd :
) i! l! l6 l0 ]0 a/ R
6 K# _! N) I  s6 B  i  l  if ( Irp->PendingReturned ). g- Q7 v% {) y% I- k
  {
5 V9 s' A0 M4 W- V    IoMarkIrpPending( Irp );  z4 L7 s; D* R: D' y# R) Y2 [
  }
$ i* i8 R3 i% [6 I( w
; W* W) N5 |. k0 ~1 P) w# F9 F  //, Z/ u, d+ N! X5 l/ D/ p
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁/ X0 b/ a/ ~+ |3 l. S
  //  L# X' e, W$ h5 k3 a4 t
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );) \/ c* h2 `' E: g& |
  InterlockedDecrement( &KeyExtension->IrpsInProgress );8 E1 E' N! O$ Z" q2 x6 V- ~. [1 G
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );0 `9 ^% \" k. d9 F
8 e( t: H6 F  V- Q5 J
  return Irp->IoStatus.Status ;
4 ~6 W( ^) ~0 L* R1 d}
8 D+ }1 R  `' A& n. G* Z0 A' f2 W, D$ k
1 Y5 d' C$ y8 c! V' {
/*****************************************************************5 E! j5 Q- r) I! D' O
文件名        : WssLockKey.h" x: l+ c: W  _8 W: ]/ }
描述          : 键盘过滤驱动
: ?0 B$ P) m# g- n6 C: a 作者          : sinister
) ?% P0 ~. t1 m 最后修改日期  : 2007-02-26
. m- B: k$ H) h" L7 Z*****************************************************************/
) w9 W1 {; G8 ?" x4 ]! ]
$ a1 ^0 g1 o! s#ifndef __WSS_LOCKKEY_H_* w  ]- s$ I( M7 g" M
#define __WSS_LOCKKEY_H_, N. m$ q* x  J. |

. P0 x- Q% q& I3 \#include "ntddk.h"
; `/ A* l! e: G* L#include "ntddkbd.h"
' h+ ?7 A: b/ M4 [9 u#include "string.h"
% N+ u  ]+ `7 }# x3 @#include 0 f! U5 h; M$ O. F1 `; z4 m
& G5 z9 V6 a- ~2 j' B$ q
#define MAXLEN 256( j9 V+ i9 B: S, M) @9 f5 W
, P' G' I. ~9 l: o  Y; ]# j
#define KDBDEVICENAME L"\\Driver\\kbdhid"
) F! t0 W; g/ c( j1 q$ Y$ y#define USBKEYBOARDNAME L"\\Driver\\hidusb" $ v. F8 t0 J8 M/ }( w+ x  O# r
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"2 U1 [: j# P- b& |, j: d
$ H8 P9 H5 Z) o* s, L  f+ n% I- ?! _
typedef struct _OBJECT_CREATE_INFORMATION5 e$ l) C- F6 N& i1 E
{" G  z9 _2 M; H9 N3 o
    ULONG Attributes;
. |/ X1 q3 r9 z5 J+ F    HANDLE RootDirectory;) d" p8 A6 J7 H9 a/ ^: Z' p$ ~- w
    PVOID ParseContext;3 ~% Q' R' I1 k8 o. \8 z  c
    KPROCESSOR_MODE ProbeMode;5 o( X7 z  c" T  Z: h
    ULONG PagedPoolCharge;7 n8 Y0 i0 p# U3 I: P7 i
    ULONG NonPagedPoolCharge;
2 o( J& l. `3 R7 v: @6 q1 S    ULONG SecurityDescriptorCharge;9 ?7 q) q/ J6 X+ i$ A$ @
    PSECURITY_DESCRIPTOR SecurityDescriptor;
7 c0 _4 `% y" o  @    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
* k& k- U- _1 {7 t    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
6 t6 [2 k7 L0 ]} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
, p( v2 b$ H' ^' c# `0 ^/ s5 L7 B6 I, c5 [
typedef struct _OBJECT_HEADER6 a4 Y8 ]+ h" q8 b9 f# l" g
{6 _- Z% _4 a: ~; z" n& `  a
    LONG PointerCount;
6 ^/ |' i# |% n; U' ?  d  H" d    union% j! H3 V' i+ M! c. }$ ?
    {
8 H# t1 x# {% \" j* P' l        LONG HandleCount;
. p5 [2 V# @% S, l8 C3 I" L        PSINGLE_LIST_ENTRY SEntry;
% N5 N8 J& k/ S, ]* X/ x% k    };! z2 V* b/ u7 ]9 M" W6 |4 z
    POBJECT_TYPE Type;) d1 a: Z' ^6 Y
    UCHAR NameInfoOffset;: x/ P1 I  d' I2 m6 U/ z
    UCHAR HandleInfoOffset;8 {: [& H& Z  x% @" F
    UCHAR QuotaInfoOffset;& d6 z; ~. ^* M# E
    UCHAR Flags;% k  _) r0 J3 S4 a/ m
    union$ T7 B" L7 K$ @7 ^  u) A! F! \
    {
5 l: j. y+ T6 `        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
# U7 n! S! q: B5 A  f1 C8 l! w        PVOID QuotaBlockCharged;
# O: J8 t- Y# M6 e' O    };
. M" @8 K: o7 {. b
7 G) c1 O! ^4 N# i% @7 d# Z    PSECURITY_DESCRIPTOR SecurityDescriptor;
$ {7 ^0 S. f; l/ ~$ _0 H) T    QUAD Body;
# [) R- k, N$ P( r} OBJECT_HEADER, * POBJECT_HEADER;9 i- S$ q  Z* D- U

2 c8 L: u' W* c6 V#define NUMBER_HASH_BUCKETS 37
* f7 }+ ^: O& I( K2 Q8 K% p: Q( `/ |5 Z' g5 U
typedef struct _OBJECT_DIRECTORY. e: \' F0 M/ @8 E
{
5 h4 N# p5 U9 }" K2 i1 w    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];" p, S7 B3 o* ]8 s4 ^2 o
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
; v" F3 e- r) R2 x1 h; {    BOOLEAN LookupFound;
: Z0 M" ~+ o7 R  Z, m2 ~    USHORT SymbolicLinkUsageCount;
- y) H# N+ e& t  ~! E0 A# B    struct _DEVICE_MAP* DeviceMap;
7 V: b0 w7 H) s# U2 X/ m1 Q* P} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
5 J% z/ s( f3 |# }+ m; y+ j# ?0 K0 v5 h$ |2 X. m! z1 Q
typedef struct _OBJECT_HEADER_NAME_INFO* w# o+ Y5 n# |7 H* s! O$ I# Q
{
, j8 n  B! Z2 Y, g    POBJECT_DIRECTORY Directory;9 t! }& o) w1 c2 ]. a8 C6 j! Z* r9 h
    UNICODE_STRING Name;6 D3 q0 ^) B# v6 f
    ULONG Reserved;
1 k$ ]5 h! q% u; P$ k4 p2 }#if DBG4 G: }! g4 r! H3 `( f( W8 k4 o: \2 I
    ULONG Reserved2 ;: t$ T2 c& B7 x2 L1 c, U
    LONG DbgDereferenceCount ;
% S, t5 H. c7 l% ?) T5 H" d. M#endif+ V0 P$ S& K- e! ^! a# I$ F
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;9 T2 Y# e- X% ?! X+ p8 i  z
7 {7 c. E5 Z  n0 t  }7 Z
#define OBJECT_TO_OBJECT_HEADER( o ) \5 b0 B0 G. H0 A. l
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )' o  [7 m& a( o) ~0 B
7 T2 r4 R' P* x2 i# N
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
% M. t; o2 X& L! Z  R' A    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
- h7 [( V' {- ]8 i' b6 Y( \" s7 ^5 {8 A, ]* ]  V) G
typedef struct _DEVICE_EXTENSION
& `$ s1 N& s# T$ R2 T9 u/ `{& j/ F1 ?; R: H, Y& \/ I
    PDEVICE_OBJECT DeviceObject;
3 D" [0 K5 i5 c8 M4 ^  T    PDEVICE_OBJECT TargetDevice;
. M4 V, f+ I( ?! [1 z/ `    PFILE_OBJECT pFilterFileObject;
" J! z* n3 h. n  n    ULONG DeviceExtensionFlags;# ^* P) z4 [0 I2 X4 r) w
    LONG IrpsInProgress;
4 v* X/ o1 J( ~. E' ~- n6 J. M    KSPIN_LOCK SpinLock;
2 T, k: N% h8 |8 ?}DEVICE_EXTENSION, * PDEVICE_EXTENSION;: @* ~8 C8 u8 X: V
$ Y/ @- e8 q( x6 R

- i  ^& [- Q8 PVOID
3 u/ p( S5 a% Y9 ?KeyDriverUnload( PDRIVER_OBJECT KeyDriver );& ^: {3 c, f  g. z
% h" [6 O( B3 \
BOOLEAN0 T. l- K' J9 Q7 x
CancelKeyboardIrp( IN PIRP Irp );
2 B  X4 _" ~; v1 F+ h$ Y  m( E( @6 x/ O) J% z/ t2 L4 n! _
extern POBJECT_TYPE* IoDriverObjectType;
2 g& V; e  {, V9 |! {0 ?" c% X) S' |, P, |3 h
NTSYSAPI
' P& K! t1 O" H9 T) B) @: l9 \NTSTATUS
. ?2 n3 R1 _1 B& INTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,: [6 V& @" ]9 t6 k' P  F, [5 H
                               IN ULONG Attributes,( P+ [% r1 n" _" h' d  u% F
                               IN PACCESS_STATE AccessState OPTIONAL,
# o, p* {, W' q0 m' U3 n0 J                               IN ACCESS_MASK DesiredAccess OPTIONAL,4 T( [! z0 X: A, X- H' O+ S6 h
                               IN POBJECT_TYPE ObjectType,7 A: [* x; `' `4 |* C* U
                               IN KPROCESSOR_MODE AccessMode,
1 o4 E9 ?+ F' U9 [1 b9 `: s                               IN OUT PVOID ParseContext OPTIONAL,1 L. G' X, {9 P9 A$ O2 F
                               OUT PVOID* Object );7 E: ?/ x: x' I  g$ g0 i7 N# I

2 r- i6 @( h1 T; a, c  WNTSTATUS
/ K, B+ [# u' @! L/ XGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );3 x2 _$ A+ C: e( |" p

# ~" D6 |6 r9 [9 VBOOLEAN 9 Y1 ]: G3 n* X! {- j
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );: m+ y* U, L  Z3 W4 \
; }8 `& H9 m1 k
VOID / v: `4 ?! F! b. c2 q' T7 J
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
3 u4 I. J. q8 n9 S' h
' Y. c9 J2 |7 g# w' aNTSTATUS
( q! q1 l. Z7 w/ n" P2 Z. VAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
8 H8 j7 d; b" _# o                                  IN PDRIVER_OBJECT  DriverObject );
+ N/ i; S0 \( O6 |% H; h9 g  [6 h
& X/ N& R% H) A* \! M" ZNTSTATUS ' W8 _. Z6 Y, l6 U5 E$ D- o
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,8 o$ N. O  S$ H
                                  IN PDRIVER_OBJECT  DriverObject,! e* S3 V" a' D2 W( \$ U( W5 ]
                                  OUT PDRIVER_OBJECT* FilterDriverObject );
9 r$ g4 V) u- D2 F6 q$ g! p6 |& s( @+ b5 M0 M
NTSTATUS + T5 x* ?  A) ]% g( q
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,  O. ^9 `; V5 }* M/ _$ B4 }
                            IN PIRP Irp,
7 @0 F# u8 Q/ ^$ i/ u                            IN PVOID Context );. o- ~1 t0 b+ S7 p4 s, g- B
NTSTATUS " O5 ]; X8 e* ?8 K
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );5 _3 e$ z1 m! U. a: ?
9 X( H1 w$ k% h# b
WCHAR szUsbDeviceName[MAXLEN];
( v4 F1 T% @3 {5 e4 [+ J! d3 ]3 A6 |) x& W2 q
#endif
4 ]7 e3 `# ^( d# a/ k. ^
8 |6 P: b9 }# r! F$ f9 t% G$ l) a8 s+ {' J# |

( ?; u, q/ S9 v$ u1 E2 f4 J; h" `- C* @4 m  c+ r6 t! k& Y
8 h# V% \- I! T" n$ _0 _
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
: q: l( _2 I. N+ Z7 _- hWSS 主页:[url]http://www.whitecell.org/[/url] 9 V) T2 \( Q# ^! ~- e" e8 f
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-6-17 10:22 , Processed in 0.132770 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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