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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
+ t* Z! Z7 F" x) a: VEmail:   [email]sinister@whitecell.org[/email], K+ g$ n; d0 m" s6 ]4 }; z; S3 M
Homepage:[url]http://www.whitecell.org[/url] : O; I) A9 h% I
Date:    2007-02-26. t" ]  g! c$ W7 {
- n  }4 t) z/ Q  T

. f2 S, s4 ^; @. F1 W/ D* A/*******************************************************************
; h) j: Y4 X; P* a7 r: p: y, {7 n1 r) [
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
- T* v, V  ^+ j/ q5 b写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
; ^1 @/ V- E6 s6 f+ x1 `; w; Q功能要求如下:
# F# L: l# x3 r4 {+ F$ E- }! b" r: m
+ Q* T% R4 I7 s4 S( \* o: t) x7 d1、强制锁定键盘/鼠标。
; G. f( W3 ^$ C" [2、可动态加/解锁
/ }0 k" H# X. S: Z. e3、兼容所有 NT 系列的操作系统。
- |+ d  v) j" R: x9 i' q$ V: A/ L  B' u; s5 r' t
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
8 H/ k) i9 e0 B' R* L/ X现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
$ J1 p& B+ R  q9 M$ h8 v, X/ P何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在4 C( t, P1 n- d" P% Y' _: A/ d
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
. R: }0 k/ W5 D( X  |1 q怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面! q. O) c" K. P  I/ G1 E/ A4 q
就来看一下我想到的几种实现方法:
9 i6 d8 i0 e# w; S0 n
* J9 T; O( x  ~) h1、全局键盘/鼠标钩子0 h4 O$ M3 i: s+ Q$ `
2、BlockInput() API; A3 t; w- H3 O1 B
3、使用 setupapi 进行控制; i4 G, Q7 m, U
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
+ I2 h8 e4 o# q  {+ P! f5、拦截 win23k!RawInputThread() 函数6 b% t* P. X( y: }) |6 E
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动% x/ ?: E+ M) P& r
7、拦截 kdbclass 驱动的 driver dispatch routine' m7 U6 G. B! s' B4 I! j
8、实现一个 PS/2 与 USB 键盘过滤驱动
8 h6 e- o- Y% ]" K
3 v( J1 G$ q( x9 a- b3 M  z/ o% c/ U: y, v' }" F( n- e
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑" _  ^4 z8 r  C5 c9 ]7 K9 d
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
& r& \+ m9 ?* Z" E5 j. }案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在1 K& T: I, q* q" C( v  V( m) g
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
& t$ ?& u6 v; \4 _素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
8 Y& ~/ i: r* W) Z问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸3 f( `0 R% r* {8 a1 o
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我2 P8 {% T/ f. C4 y! a
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
1 f4 F' d% Y3 [, B' V  w6 ^, A6 H! e; g) c也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如5 @1 D, ~* R3 Q# O
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有6 w, ~' Q' ?" O- P
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
" x4 A2 V+ ^& aIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
, v" p, b, y1 s, I: J  DUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键( s4 m; W* C5 C7 z+ S2 f; ~
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
. o% ^  M+ v  j4 ~3 j' U案的全部功能且不存在它所带来的问题,否则就没有什么意义了。" w" d. r/ u& b  N$ t7 ]

. J) x. t& [3 ?! H4 m
) @( u& O- d% C- u% p6 D4 \我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
) M8 X9 r& K4 O滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进4 {! D& P4 \5 g
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是. X) z4 }$ Z$ Y4 {
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
! _- A$ K2 ?/ _' v来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
# U  y. q4 f+ iKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB! M* u  _) \/ L0 {
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
% l' \% S& i& R9 e: q% `$ \: MIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
+ q  ]- S! R' e1 s+ g8 A6 M我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
: \8 G+ P6 @4 p$ j  N$ \  w+ J& ?就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的% c, P3 w3 V8 a
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
8 J6 @% g- u" @- C: i( A用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通) \0 h( T9 B4 l
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来8 i  b  P1 J* \# [
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
5 H0 `3 I. I, S/ m- \过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
& L# d/ e1 b8 Q3 ^' C5 C) j上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 3 l. ]$ B% [2 r$ G8 Z, j, k9 R0 w
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意; F8 u* u1 ?6 F( a* g- Q
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。# K$ y7 Y9 F" f* Z% @
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们% N2 C4 U: s) P$ j9 G7 p+ n
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利) ]. E/ R0 Z' z! y; G. b
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo/ W! C0 ~- h1 p; Z* p' n& {" ~
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致& r. E# L! `* H+ B* K4 S
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,% Y/ q5 F- P0 M' b5 I1 |+ X/ {
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程' D% r! s+ U, B8 ]) |& v
见下面代码。# O. J: n9 p+ b) i3 p: y" q- t0 {1 Y

4 ~6 a* D; w% g8 h6 i这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程- d) k/ E/ Z& @) n( c
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
) |8 h( P, V" D" `/ s1 ^盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
2 q+ y0 u# J5 V% p5 K0 |上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有  p& d9 K5 W$ P: ?: h
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可) ]; C0 C: ]* L3 D6 c" ^0 `8 g. `
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个& C. q; H' I; h: f, }6 A7 \
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
5 ^  r, s- X  E; K$ v. z键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。0 I& p) b/ d$ }3 Q! B' r
5 J! ]5 T8 y5 b3 h% z

6 l0 ~' p  K3 G2 T2 X/ h4 M. s完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
2 y" o! Y: U( L2 j7 {9 w7 e的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
- ]* l1 z, t# T8 v2 i5 e; V1 K2 U" A可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
2 f5 D% o0 r  v  {的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
' z+ R# H* i  i0 y# i5 H" ~们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
& P* }/ ?2 ?  v; w们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
6 y3 O5 w% [  q- g, t0 ~->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。% i2 M4 e2 L4 E3 t+ `
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
! Z2 J' J. T! x; Z! R1 b0 W进行操作了。这个问题有待大家来完善了。& D- Z+ ?. G1 ~5 E* X

, T9 ^* d& d" B$ W( c! _' y1 @5 G0 g0 g! V9 u6 T; O% ?
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出- d' b. E+ G& }8 F; H9 S& i. _
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
9 {  y; H5 @8 X) {+ \4 K分析做个记录而已。我更愿意把它看做是一段注释。
9 [* \, p2 g+ k3 J" L& j% r1 K, _
最后在此代码中要
4 m$ H3 c  b5 g5 N: d
3 g3 K2 r- B" @* _' @1 X6 v. O感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
( A0 _+ R1 H' S* j# f+ g0 P/ z2 M/ n$ N) Y6 w
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
: O5 j9 j$ ?& r6 `; P4 Y+ J' E: ^- Y7 \$ [' K9 _2 G
感谢:齐佳佳,过节请我吃好吃的。7 g. }6 E! y7 o! B' i' a
! D  T. C; N4 `$ W5 X: ?
8 }0 H0 }+ x- b& ?; ^5 R- u
******************************************************************/
% z) m+ J" q- }/ u; O
$ Y" E4 s. o7 a3 r  `
& U: [6 s9 ?5 ?0 i/*****************************************************************+ `2 m) n$ F  t, H9 i
文件名        : WssLockKey.c
; P- w0 f7 y! O" L% x 描述          : 键盘过滤驱动
3 M3 i* E6 k! U2 [3 [' } 作者          : sinister
% F2 B8 r! v# I) I5 ] 最后修改日期  : 2007-02-26, i0 C3 b* y% k* O3 s# y1 Q5 }
*****************************************************************/* E2 M0 D: A, n. a) v- d, t* L
7 e1 f; F, M- q* g! A. |* W' Y$ [
8 h9 i" ?" @4 C5 ~( a* g2 H; I
#include "WssLockKey.h"( s. }3 C0 m7 U, ]# ^1 O2 l$ N  H
, f! ~; m7 }- |3 I
NTSTATUS+ @$ i% U+ i% i7 d
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,1 n* A# ^9 z1 n8 b' y- L* P
             IN PUNICODE_STRING RegistryPath )
5 W/ i) N' P( }4 b5 `2 r{, O* }& W' w3 {+ w) P, K
  UNICODE_STRING KeyDeviceName;
; r. }/ R: l& `: i9 _0 Y( m& V  PDRIVER_OBJECT KeyDriver;
6 l% Q/ L! r4 q: Y5 l  PDEVICE_OBJECT UsbDeviceObject;
6 J" c! Q) u! ~7 Q* M+ P2 R  NTSTATUS ntStatus;
: h& W$ n, O2 F2 N* i" R  ULONG i; ( ^' T7 T9 P5 A  c

# h, Y" T" Q! U( D! I  //( r, l9 x" j4 ?. B1 A9 m
  // 保存设备名,调试使用" @( {. ]5 Y4 y& [* G/ {
  //( [4 ^# R, o0 q% ]/ o$ O- t
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
4 x4 J6 u& U' D8 I" D# n3 ^  {3 {! q' k& _7 |. {( C/ O4 w
    0
+ O- o3 J3 y0 p' N# p8 i  };; |8 e- |& ]5 A% e. k' i

! G& \4 X1 h' i$ ?5 v  KeyDriverObject->DriverUnload = KeyDriverUnload; ; u- z" L0 I! e: i
" R# d8 b: R3 a* L# E
  //- Y' m' m* d2 t
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
, s" K+ k* V2 M1 K8 ]0 Z- f  //
5 ~$ f* t/ L; v; P4 S" s9 u  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
: w7 Y# i6 X3 l6 @  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
7 A6 |: W. H0 t& j& o  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
0 |( r0 V/ P$ S9 j0 i+ F9 K  b! r  // USB 键盘设备来进行挂接' X8 V. ?7 N7 Q% @- ~& V4 Y
  //
8 B! X# c1 L* B7 g9 `5 H- C  A$ b2 u  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );# Z1 F1 s5 P: H/ t$ _; T
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )6 G" d3 u% u! N7 t
  {
( f1 Z, l$ y! p0 M% b3 T: N    //
& G% o* L3 f* E( r    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
- W  d) }# E' [, f    // 所以这里打印为空' d- `( F. k- x' o
    //$ s2 U0 |( d. O# Z: w! e
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
/ j/ Z- g! c# q0 a    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
( e* ^8 U, h, x$ O+ S) c  D/ z' L' k% t- g
    //
5 l& z; s' ?; }, `* s& h    // 挂接 USB 键盘设备
. R- Z/ V$ O, X+ }% R    //* b1 L. G- y* B6 z3 w
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );+ M* S; p' o2 `) X
    if ( !NT_SUCCESS( ntStatus ) )$ w* m' U1 I' `" }
    {
2 T. |+ @$ F7 y4 S3 X      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
& U5 |+ F; \7 L! X      return STATUS_INSUFFICIENT_RESOURCES;
7 S% I0 M4 x  U+ U  }- W    }& y2 o: k" |( R2 Q
  }% H' j  n5 M7 x
  else/ H  Q6 K# j! f  m0 l1 u9 ?% ~* _
  {
' Q& P" ]) D. \    //- n3 Y1 D  Y& j) _
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备9 ]3 R2 W& w' y# g1 _) M
    //
$ c* J. S) }8 [% z6 n; j: V    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); : M2 ^/ ?1 h; p' S+ @
8 O$ {* F0 e8 [6 K8 N+ T
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
$ {; X2 h- a/ p4 F" {+ z                                        KeyDriverObject,
1 e  a, D/ ?' Y; k$ \$ u1 N                                        &KeyDriver );
& y& s$ o0 [$ ^% i; e+ F) _    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
/ m1 X. [2 Q7 n! f    {$ I, v5 U1 i- t9 _6 i2 ^- y
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );$ I0 U' r  E; K6 g
      return STATUS_INSUFFICIENT_RESOURCES;0 [. f# K  K3 G! B7 ?
    }
- C- @/ v* y  w# o& ^0 B  x  }
) X0 B* Y, x7 L5 C7 \0 L3 ^* T, D) Y1 T, F! W( L/ t# J+ f& R: I
  //+ r1 k2 _5 a4 v: C8 U" i" F
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
6 K0 p& s! c+ y2 Z6 t  B5 L* S  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
: q0 |$ n( ^5 Q4 J  //
! R$ O% \* I8 s# w& O2 I- y  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 4 I. R$ v( R% h( V# o1 w

, ]. P* F  v) r5 M$ v  return STATUS_SUCCESS;
7 O( K  r+ l  E# A! j}
/ `- l) L& g3 W' }7 ^. a1 v/ m3 t$ R# b3 D4 Z
/////////////////////////////////////////////////////////////////5 ?4 G3 N/ O. p' s5 i
// 函数类型 : 系统函数
; [: M. |( F( ?( s6 p! L8 {  }" s// 函数模块 : 键盘过滤模块0 R7 }1 E' k0 x! O0 y( G6 z
////////////////////////////////////////////////////////////////
" `, ?8 ]; a& m/ P( `+ q7 f7 {// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
9 h: {( G2 c' \1 m$ s) e! Z//        卸载键盘过滤驱动8 O9 n# o) v# }( [0 t( B+ R
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
" q5 G; F/ n3 ]4 r//        则需要等待用户按键,以后有待完善/ {9 ]/ C( p5 B
/////////////////////////////////////////////////////////////////
: A& Q, j4 B7 K# ?// 作者 : sinister
$ J7 F# B+ ?4 F- }% z. S// 发布版本 : 1.00.00: L3 f6 }+ ?7 ~( g; S" B3 V
// 发布日期 : 2005.12.275 [0 G6 S. `2 f. L2 Z% `1 o
/////////////////////////////////////////////////////////////////
8 ]- u: b% l" s2 M1 q8 s" K// 重   大   修   改   历   史
/ w0 J# |6 v1 T' E6 e6 g2 f7 B////////////////////////////////////////////////////////////////
  v, k' [6 z) T/ ^+ L// 修改者 :7 B2 L, Y1 h% t: B# T
// 修改日期 :
" Q0 j" W- Q6 ?( ^3 r! b. Q9 d// 修改内容 :
* q5 k! u$ l1 Y6 K; z: }' h8 V. x" z/////////////////////////////////////////////////////////////////
- X# `6 e: X& A& Y' ~) v" Z1 w' C( J+ L( F1 x& D* d% _& n
VOID& S- `+ x" O( F7 g- A5 E$ ?+ B* ^
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
: q+ D8 B. [) ]{
7 Q" E9 q) ?: Z+ w3 s0 E* [  PDEVICE_OBJECT KeyFilterDevice ;      
% W- p/ S3 y5 c  PDEVICE_OBJECT KeyDevice ;
  _1 e( y' F5 {  PDEVICE_EXTENSION KeyExtension; 3 }+ e" {0 x* C! J2 F
  PIRP Irp;
, f- C, ^# v0 B" r  NTSTATUS ntStatus;
' a4 _. a6 L0 c$ L0 \' `7 D/ @
; ]- d% M' H# K) \+ W5 `  KeyFilterDevice = KeyDriver->DeviceObject; * M/ ]# R1 U9 S0 X2 l# U8 L
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; . r. m" l  p& j) J1 f' ~- D1 ?
  KeyDevice = KeyExtension->TargetDevice; 2 r0 z/ N# Y( }

, `% f! D* l' f/ [  IoDetachDevice( KeyDevice ); . K: d! F; E) [) |9 ~2 A2 `; P

# B  o& V0 L* B, ?  //
) x* _6 B" u# X. P3 d% j+ o  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
+ l" u) m4 ^0 q- s! e2 c9 W+ Q  v* G  //% P1 d  A1 P; i4 b, x2 I* s
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )# \1 Z4 O7 N4 r0 `3 n
  {
' @: l, V9 L& b: |& A    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
1 H' P  i7 U" I: _3 T    {$ f7 L# @; e: o; m; w4 Z
      //
& A: |- \5 }! i! l4 `- n0 r% Q      // 成功则直接退出删除键盘过滤设备
) J8 B) t7 M0 G: w6 g      //
1 b2 {( C' r7 B$ |8 G# c$ z      DbgPrint( "CancelKeyboardIrp() is ok\n" );; p1 y9 q% V: C) [9 Z! w8 {/ ]
      goto __End;
1 I1 L7 K: i! y& @9 i    }
) k: \( b1 t& x  }
: y2 P+ w5 o/ s- ~5 n+ s$ [; Y% c& t* u
  //0 @- `# C3 H% k; y
  // 如果取消失败,则一直等待按键" h% Q; G# k3 h/ t0 \
  //- Q+ ~2 E: h& s
  while ( KeyExtension->IrpsInProgress > 0 )$ J3 H& x* ?- j  ^: V2 a* f; y
  {6 W! \2 ~* ^6 s* A( Z2 k
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
9 v5 }3 }! U. [1 X8 h2 ?2 ~  }
) N! }- L8 p4 E( s- q/ ?! q3 G" a5 Q5 u$ e3 K/ ?" N) S2 y
  __End:: X% \+ r5 l# H$ ~6 K
  IoDeleteDevice( KeyFilterDevice ); ) z3 h7 r/ {1 R1 b- X

: S; Z9 A/ T# \4 H1 q  return ;
) F* Z7 J9 a; q}
1 w) U* I  V: n  V# E" r4 h
3 V* h% U$ C4 Z( D" V5 M, Y/////////////////////////////////////////////////////////////////
5 O' I9 R4 F! N7 E" {! j8 Y2 o// 函数类型 : 自定义工具函数
; \1 ]$ s2 s; l// 函数模块 : 键盘过滤模块
7 X7 k1 {0 O3 N! t  W. W% C/////////////////////////////////////////////////////////////////3 d' n7 C1 {6 o
// 功能 : 取消 IRP 操作
! D  D/ Z) W) w3 L' H// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能$ z% [7 f3 J9 Y' P  a5 o5 Q  i+ g
//        使用此方法来取消 IRP
6 ]9 h, ]% y: E. l* g" z" ^3 o, W/////////////////////////////////////////////////////////////////
$ P9 F1 G) A5 i5 B$ f9 Y( [// 作者 : sinister
' B8 Y' M- ^, @7 d% t// 发布版本 : 1.00.008 q+ D5 A! Q, Y5 U
// 发布日期 : 2007.02.20
" t7 T- w' G8 x/////////////////////////////////////////////////////////////////
& f7 g1 b/ ]/ G2 H4 {8 [0 x// 重   大   修   改   历   史2 f6 l* e5 g; _6 X+ _
/////////////////////////////////////////////////////////////////# H' @8 M# n$ N/ p0 C3 {
// 修改者 : : F" B2 I) T  E' U" N( p# c
// 修改日期 : ) ~" {0 M, v# \
// 修改内容 :
5 P4 |( r/ C! [9 h7 s4 \/////////////////////////////////////////////////////////////////  s- i2 M$ [1 F; I3 U7 m# z& N, P
5 J, T9 H% _  |& _) y
BOOLEAN+ Y% A5 B/ Z; J
CancelKeyboardIrp( IN PIRP Irp )
; e" y* M$ n( E7 e: p$ J  [{% Q5 \4 c& n  l! L
  if ( Irp == NULL )/ F2 R! t! U% a9 G' E4 Y5 f" }7 s
  {# `" x! e: T" M" M3 N* s
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
8 e8 K& y* r! R& V7 J1 f  w    return FALSE;1 ^3 U- M2 y  ?. j, ?$ b; P9 ~
  }) i8 Q( p% i  W  O4 u6 _
: G5 N, ~& g, @5 T' T; A4 s7 n

- M* o, s- }$ k/ k  //
5 g1 A; K, I  c) g, S  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,: D1 V" C7 P- I/ E8 e
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。5 ?  `5 \, ?* I/ V# m
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占4 ]# B: x- a, B$ @  I
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
/ @1 N/ u4 g' M8 O  //
+ h$ i, }" y" N4 B. s. a( c/ D/ o! n  l0 y5 S& c- e* A/ r
  //
+ e% F! t. T4 k- u/ y! ?  // 如果正在取消或没有取消例程则直接返回 FALSE
  W' C& J7 x# e: e8 J6 ~/ e  //3 F- \$ m' G) f' `( D3 B
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
  T' F' M9 I& }  {: |+ l+ s) R: L* E0 ]
    DbgPrint( "Can't Cancel the irp\n" );6 f6 |/ J1 b1 Y6 t  ^
    return FALSE;
' {: O6 k8 o3 W. {% N9 C6 S# X6 W) S  }! o% n  r! n' q8 `; P
2 a6 \* l/ [* G
  if ( FALSE == IoCancelIrp( Irp ) )" }8 a- c6 w3 M0 F% l
  {$ J. R1 ^* O! B$ r+ e$ z8 Q
    DbgPrint( "IoCancelIrp() to failed\n" );
  f, ?' I# g$ V& v) B* l    return FALSE;
% d2 x! w4 {/ K8 S6 L  }
+ i6 d7 W8 A6 O4 F/ w/ R- K( `- q0 _+ l3 Q+ T
  //
# ]1 r/ n* ]. C" d" `  // 取消后重设此例程为空$ R3 [- b- G2 d8 @( Z; B! f; W# S
  //
0 Q# R- J- P9 [8 z. r# P/ P  IoSetCancelRoutine( Irp, NULL );7 a8 T+ \8 l5 F. A; K, e0 E2 y

9 C, n9 z0 M' V  l/ O% o3 T0 \  return TRUE;0 a( J3 O4 `' k
}
; J- u% [% `/ G
) Z8 k9 s. \4 @+ \$ J: N6 @/////////////////////////////////////////////////////////////////, g! O: V1 D" H& b  y9 S1 I
// 函数类型 : 自定义工具函数0 d3 _% d0 Z! \# c5 a4 ^5 u4 z
// 函数模块 : 设备栈信息模块
9 P" I- O, G6 [/////////////////////////////////////////////////////////////////+ L$ W2 R, B  s& N+ S" M% }+ }& m; y0 [% i
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘6 q! t  k0 ~( i( `
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)9 c* _5 P" X, O+ e; e' N0 u
// 注意 :
& ]; [" ^* f' x! Q! N/////////////////////////////////////////////////////////////////+ _6 _" C, d) ~! I2 {
// 作者 : sinister, y/ `0 T3 `: {! p/ C0 T& P, @
// 发布版本 : 1.00.00% t# n9 s: K! H3 d. o& H
// 发布日期 : 2005.06.02/ R6 |- S# {# r' h0 O( u1 u
/////////////////////////////////////////////////////////////////! L2 Z; ~. n4 n# U/ u2 @$ [' @, k# Q, g
// 重   大   修   改   历   史2 E# u# F  \3 Y
/////////////////////////////////////////////////////////////////
! [' U8 o' c6 M$ E; x: D// 修改者 : sinister
9 f7 I6 ?7 O  m2 {// 修改日期 : 2007.2.12
' s* V1 W6 u/ P" e8 ?9 o- u3 A# v6 [// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
+ S- ~6 Q, d6 `, O3 R( m/////////////////////////////////////////////////////////////////
  o. f' h( S' F0 a! D* V) X( ]% L$ E
BOOLEAN
0 I& q$ D5 K5 k# R( E- p3 @. V! mGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
* l& \* @/ \. @) n, L& g{
' S9 |& w' f6 |5 c, C# O+ ~) e  PDEVICE_OBJECT DeviceObject;
6 ?  w8 M; ]1 T8 Y% ?  BOOLEAN bFound = FALSE;
2 v# v) ^7 f+ x8 n1 d1 y! x$ d
" Y; |5 e+ P2 |* n  if ( DevObj == NULL )
9 ]  M4 ?9 J, v8 X$ G  {- q8 p9 |2 E4 G' e! L
    DbgPrint( "DevObj is NULL!\n" );
! O: Q" {1 d# F/ a% a    return FALSE;( c3 _6 f9 U  L$ Q
  }
3 A" w3 j; o( x- o& l2 m/ a8 G- n$ a7 _, \
  DeviceObject = DevObj->AttachedDevice;
5 t3 s& t4 l; [9 _% d, d! B" {' x
8 S. {8 K# ~- k1 _% S5 I+ L# L2 ^  while ( DeviceObject )- V( F) N& ?+ v# x% I( Z
  {
% K4 E6 @) v3 n8 J, R1 `' X9 t0 I1 B    //
# [3 m( r& ?" |6 v# w    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但. n3 Y4 s& t0 E8 e3 d
    // 有一次足够了。这算是经验之谈
7 B0 w6 V  i$ ^  V- P    //
. h4 Y4 l, R0 x4 o2 P) {. |    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
( V- `$ Z8 h2 G. n    {8 @, \! [0 N  N# Q' a
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
% n' ~, C8 F* _' X, H! G) B9 B- m                DeviceObject->DriverObject->DriverName.Buffer,5 F7 ~. F9 H0 E" j" r( U- ^
                DeviceObject->DriverObject,1 @# X( @8 a. J; ^. A* d
                DeviceObject );1 a+ j& D, G$ l3 f3 I# s
4 E! O3 n1 F; U" E
      //0 w( |8 v9 R7 P; l: J4 g
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了9 H4 {+ `, R; _8 `9 R+ Z
      //
! L% h) z$ S+ I      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
$ C8 o/ z, Y: W) e* f2 i                      KDBDEVICENAME,
# w9 J0 _' C6 ]5 }7 V                      wcslen( KDBDEVICENAME ) ) == 0 )
' T% \" F) a: C. U1 }      {2 o7 n$ m$ j8 F* A& |0 |
        DbgPrint( "Found kbdhid Device\n" );
2 w: `2 i1 p( ?) h  s! @; z        bFound = TRUE;" _) _/ w$ I; n. K! w! ]2 i
        break;
/ ^6 |5 R5 l& g  L) I; F      }
2 H8 r+ q" K6 P4 k    }
  s& d- \' z& u7 Z- S3 F  K; W
! _: Z  ^" A* R' T% ]9 ]7 P    DeviceObject = DeviceObject->AttachedDevice;
8 b3 I/ w& }  T, L, U" v8 u  }) m  y! [; E% T5 S9 S0 F
1 k; l7 ]7 V) N1 \! Z1 V
  return bFound;
" l% Q+ Q- H! F( i2 p  g- R1 e- a}
4 A; R6 i4 e; L- f. d7 o5 G$ u8 a
, w: R5 m% X* D- I3 f: x) m/////////////////////////////////////////////////////////////////
$ `2 k+ P9 H: Z/ c/ D! C// 函数类型 : 自定义工具函数1 P# w. h2 Z7 r( ?
// 函数模块 : 设备栈信息模块
* @) D+ x' a# H5 k/ n. v1 l# k3 G/////////////////////////////////////////////////////////////////2 q, n( i' T2 b
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址# x: B& V4 r" Y$ F/ X- N
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改# ^4 ]) U. @; x- i
/////////////////////////////////////////////////////////////////
9 E5 L/ X' D1 n// 作者 : sinister$ Z4 c" G( O% H! C+ t
// 发布版本 : 1.00.00
9 j0 g8 E0 C% J: _% i2 @// 发布日期 : 2006.05.02( R" x1 Y& `2 W" B1 a0 I
/////////////////////////////////////////////////////////////////3 K% J9 ?5 h" ]* }- D
// 重   大   修   改   历   史
2 y6 \# f; Y" s/ z1 K. ~9 _/ h+ [) J/////////////////////////////////////////////////////////////////: s  Q: Q4 L2 Z; g
// 修改者 : sinister: g2 s8 h6 c" Q3 F9 \2 S; H
// 修改日期 : 2007.2.12/ z. }3 S( N; R& P
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
" x, u" q+ [- u  L+ P( e& f; v; W5 P: j/////////////////////////////////////////////////////////////////
( {# Q* y4 S: h$ M
0 I0 N2 O( ^3 \( }& fVOID) z$ p8 w% }; V. b: l
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj ), o0 r" ?% T$ s7 h! H
{$ Z' ?' e) V1 S. V% M
  POBJECT_HEADER ObjectHeader;- w1 {: y" d" f& N2 |
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
0 r: z: r' ~; z/ Y3 {5 |( [0 i
9 Y) d1 \1 P8 j  if ( DevObj == NULL )/ `0 y2 U( p& t9 A/ c: c3 C) K
  {, j6 e- Z% d4 K) l8 d
    DbgPrint( "DevObj is NULL!\n" );. a4 ]' m& e) h- A1 R3 r% o) Q0 H
    return;; X' G' G1 }6 M6 X2 `- s6 e
  }
. X( \2 R9 U6 `/ _
* E. \0 z. o, I0 T6 u  //9 S, |3 f9 ~- L' m* V! G% }  q9 l
  // 得到对象头
% f  @# ^( j, j  //
9 G/ e4 b$ m' E9 Z. R/ z% B* t! h  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
; v$ y) B! q  i3 }: c0 ]/ b" l0 d, d: C: X% J) o- M
  if ( ObjectHeader )+ l) H* t, }- O& Y, m1 v
  {* x8 J. a7 |! S2 \, n* r
    //
& r7 D2 T2 U" T# Y    // 查询设备名称并打印# N6 W. H; k8 E1 R3 w- M
    //
) l9 q& {$ d- a    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
; \1 f" }  s4 u8 ~  q/ z7 G) [- g
+ _9 @! k: }0 d9 n: W% q2 a    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
1 Y. O: y8 C% f4 _    {0 }+ o0 ^: g: y8 |
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",% y" |& J  C' P' N6 O( R% q
                ObjectNameInfo->Name.Buffer,8 x% o; B2 x: u) ~; g2 {
                DevObj );- Y/ {! p0 ?/ T. I1 `9 C$ z5 f1 O8 O

( Q) [0 C% B( x5 r4 P6 V6 r      //
- H, v) z7 v; z+ Q8 O      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
- Z) J  \: W' c5 I      // 用,没有实际的功能用途, Y8 X6 G' y3 g6 K- m
      //$ n3 @- F* s! h% i. n& [: u
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );4 W; P& {8 E; y: {' ~
' b2 ^  g) v; ?7 p* R! W, q
      wcsncpy( szUsbDeviceName,( E( ?; z7 H4 {7 U% a6 Q% R( n
               ObjectNameInfo->Name.Buffer,
$ [( ]2 i9 Y, ~: H               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );6 i1 @1 ?2 E0 `
    }2 P4 j# d3 \, F# _0 `* }. c* s) X

* t. U' O' i/ }' K# \: @( z    //
: Y& N7 p" i9 q6 `+ Y% H    // 对于没有名称的设备,则打印 NULL9 v2 ]2 b* Y+ G
    //( m1 {, v8 y# Z* P6 |( ?0 ]: M
    else if ( DevObj->DriverObject )" {- S, @. Z! \- Z1 j# t1 u; o
    {
4 |- W' o" s1 l8 u5 {- u      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",# l2 q/ b" @- c6 `+ C
                DevObj->DriverObject->DriverName.Buffer,
7 o8 x) I8 k6 W9 p: m- f" ^- k                L"NULL"," V$ ]* v' J# J% U7 T" W
                DevObj->DriverObject,
5 q' l+ C0 y# H2 b                DevObj );- g- u4 m! G# H' s
    }
4 Y7 L9 I; Y9 f& @' B3 i) ^, m& Z  }
6 u5 n5 I2 I1 h) c  I7 \}
; p$ ]0 X) O$ t5 C' T4 A4 o* D8 G1 k7 [# a  ~
/////////////////////////////////////////////////////////////////
4 f+ O8 u4 \! Y+ n// 函数类型 : 自定义工具函数# p% r8 R' @: X& i. m
// 函数模块 : 键盘过滤模块; @' |8 w' R* f# v5 P
/////////////////////////////////////////////////////////////////" j( A. l4 b4 s6 V
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
6 u  ^9 a* V, L& r//        对象,过滤出 USB 键盘设备,将其设备对象返回' B: C4 _4 C' Q
// 注意 : 3 ?" |- W/ s% ?0 s4 p; f5 i* L% c! L
/////////////////////////////////////////////////////////////////2 B, ^, q, {- q$ @$ m0 _
// 作者 : sinister
' S$ z3 c$ C7 G// 发布版本 : 1.00.000 b/ U4 j2 I7 r) p
// 发布日期 : 2007.02.13' w$ B# ?* \  P: x+ E& A% s# s
/////////////////////////////////////////////////////////////////
+ V. R9 P/ ^" F* K9 c4 D0 M// 重   大   修   改   历   史% O* a$ @' \% H  g8 }' A( L
/////////////////////////////////////////////////////////////////. V" M( E* D+ t8 K2 a* S& B
// 修改者 :
* k$ f7 z' p- V2 o3 X// 修改日期 : 9 b4 F; ?: ?/ x6 t$ \; p2 E
// 修改内容 :
3 V4 I$ w/ b, ^5 {* X, y. t8 L/////////////////////////////////////////////////////////////////1 \3 u' j" v. M9 Q- F

7 e4 i0 I2 R. n& U: ]NTSTATUS
8 C% T1 m' Y3 {1 [9 r# pGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )& o# N* ]7 `9 ^# a5 O! a
{
7 L- k! w- L9 Y. B7 d6 t  UNICODE_STRING DriverName;
1 z( _- _) ?4 K" ?  PDRIVER_OBJECT DriverObject = NULL;2 A8 A9 ~9 E7 ^( f8 ]% J2 _
  PDEVICE_OBJECT DeviceObject = NULL;
, Z: }* V2 z; n6 W6 Y* g  BOOLEAN bFound = FALSE;
; T) z: X- T+ f: T7 A5 d
' ^2 l8 b; H+ _: {- b9 r  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );) q1 ~$ i! {5 ]9 C" s1 B- B
# }, c  F+ x/ z9 I
  ObReferenceObjectByName( &DriverName,
' o3 v! M- n/ ~0 I7 x0 F, W                           OBJ_CASE_INSENSITIVE,6 N; s% {0 {7 j1 V
                           NULL,
7 j! Y. M- b. s+ a% X: n! D" R                           0," T# L# `, f, Y' R' b
                           ( POBJECT_TYPE ) IoDriverObjectType,
: E) `: Y9 J% {9 I                           KernelMode,
# m2 `1 R; Q7 q7 i: M# [                           NULL,4 |7 q4 W, T: Q& c5 e, h- S* u
                           &DriverObject );- ?0 ?# W. O5 T: b0 ~

8 F* j  ]9 B1 H9 Q  if ( DriverObject == NULL )
. `' G. u. J$ e0 `" x$ E' G  {
5 s( z+ {7 j& d! O1 _# C, F  g( p    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );* G, J5 P9 ~2 Q/ Y
    return STATUS_UNSUCCESSFUL;
0 J6 G. l( i% g0 ~& ]4 [9 O  }6 O9 b4 C  F4 ]2 R# d5 A
7 m) Q. H! l8 G) ^
  DeviceObject = DriverObject->DeviceObject;
7 h6 \6 W1 p+ h& q8 B# x) E1 }/ K; o/ I& T
  while ( DeviceObject )8 P, p8 ?+ m( S+ ]3 A# ?0 I9 J6 a
  {
+ G. Z. c# i  D% [    GetDeviceObjectInfo( DeviceObject );
# w+ _. K' h  z
) e3 S$ {9 \+ f; z7 c) t    if ( DeviceObject->AttachedDevice )/ j4 Q4 |+ {* E8 x* R
    {( b8 n; \7 W+ c
      //
" W) j; L7 v) p" T* o      // 查找 USB 键盘设备
, p/ C8 |* H0 Q! A+ c" q      //2 j' [' l6 v# X6 y3 @6 [
      if ( GetAttachedDeviceInfo( DeviceObject ) ); m9 U1 a& y8 G/ ?
      {! r: w$ I6 ~- I: f
        bFound = TRUE;: q, |/ R8 t4 K. R" v
        goto __End;
+ w! z. |; j/ `; [      }' u' E1 ^+ P; z' ^
    }
* o; }: o; ^( \: P+ L# A/ R2 Q9 m
: A; P% ]3 D6 E$ f5 Y/ r    DeviceObject = DeviceObject->NextDevice;; g1 z5 w' \8 B( e6 A/ s% O
  }) r5 R; E3 }1 j

5 s  n. Y# m" Q- X" A9 J$ ~  __End:
0 T- a$ y; s1 q3 G, b( r$ k' Q# H
  if ( bFound )% f4 X7 K. y4 q# v- {6 f! Y
  {, w! R3 i  m* E9 j/ c$ o
    //* I9 V3 n( y) V9 J
    // 找到则返回 USB 键盘设备对象  [" ]6 o- F# |/ a7 {  X* ]
    //+ _' z/ M1 ?- Z: ]9 h
    *UsbDeviceObject = DeviceObject;
6 Z( d6 B" M* M5 I; m$ R- N% c  }3 H2 Q9 u% P' m0 E+ [3 Q. \
  else. `, t7 h1 g9 E7 u1 g
  {+ n7 _$ Z" \3 h5 X+ N" U6 I- I6 s
    *UsbDeviceObject = NULL;- l, G# t6 S4 {0 N& ^/ d" [
  }
. Z2 a9 s; b2 R. `2 N4 b+ m  k2 q$ w# F2 J. s
  return STATUS_SUCCESS;  `; p9 h% E& d& O* t# L
}  i/ }( R8 \) {- j4 I

2 U4 j/ v; F$ K! X. D/////////////////////////////////////////////////////////////////* _7 a$ Q# f" {9 \( c# P
// 函数类型 : 自定义工具函数! C& b0 n' \0 s4 z) o
// 函数模块 : 键盘过滤模块
+ X- B/ P9 s6 |2 ^, G////////////////////////////////////////////////////////////////
- ]- d4 c: `/ u7 |# r* r# _// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关5 w+ y- l$ Z- c4 L! ~
//        信息,返回附加后的驱动对象9 J$ \8 Y8 C$ l# w
// 注意 : 此函数仅挂接 USB 键盘设备6 d/ f, A' Q7 D( M8 b# d
/////////////////////////////////////////////////////////////////. b1 \: h5 ^9 L) l. L3 D* {+ h( [
// 作者 : sinister8 s/ M! b9 n  S$ l- G& ~0 }8 I
// 发布版本 : 1.00.00+ C1 j1 b' t, \( G& X4 D
// 发布日期 : 2005.12.27$ n0 X" h1 q% G
/////////////////////////////////////////////////////////////////
- p  I" `4 h& b' R# q  @0 y5 `5 T& n7 p// 重   大   修   改   历   史
" T/ i, M+ ]7 C) l9 U4 e////////////////////////////////////////////////////////////////2 p( ^. h' w, L4 {
// 修改者 :
, L6 c7 [* T6 E4 s9 Z, `, e# |( l// 修改日期 :8 v. q3 p0 o  |
// 修改内容 :
. j6 i8 i% h* ^/////////////////////////////////////////////////////////////////
$ m7 i2 T# P0 z/ l1 ^  g" u4 s
$ `: u- Z; _$ e0 ANTSTATUS' G6 d: x5 }1 k- _' E5 Q; r
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,2 H* W/ Z5 G/ F5 Y7 _, d
                         IN PDRIVER_OBJECT  DriverObject )
# b( ^) d, V+ X2 S0 ]{+ v# W$ P4 H! g/ ~8 V% F1 C3 I4 X+ Z
  PDEVICE_OBJECT DeviceObject;
4 }& v7 ~9 ^6 Q. H8 r( J- y3 d7 J  PDEVICE_OBJECT TargetDevice;
1 k. y2 a1 d. |4 j0 C, P  PDEVICE_EXTENSION DevExt;" d$ p) Y. W! S  u6 ~  W: [7 N
  NTSTATUS ntStatus;3 \; Y# b3 t- k# k# _
! U) p' k; T9 Z. f4 K! u4 i
  //# L9 L% L0 ]6 L% C  K
  // 创建过滤设备对象
: N9 I" ?! I% C1 r3 y: t! h  //
% c, ~; q9 N2 c7 ~  ntStatus = IoCreateDevice( DriverObject,! i, p$ i! s% U7 n0 t8 d
                             sizeof( DEVICE_EXTENSION ),! k' U. i3 L) s4 ^9 E3 a
                             NULL,
/ h; G7 ]9 U) k, c  B! y9 k                             FILE_DEVICE_UNKNOWN,5 U. J1 [  k2 S! H+ `. P9 C
                             0,$ r$ Z: f2 j# u9 G9 [; j
                             FALSE,
* c( X6 J5 v7 f, v                             &DeviceObject ); 3 u+ g+ F1 i- b/ S
* M8 [1 o: s9 d% Z; b8 o$ C
  if ( !NT_SUCCESS( ntStatus ) )" o/ s) i# q# Y: ~
  {
8 M0 {6 x3 ?: ?9 M. A. O    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
# p* R8 H$ [, B0 N! k    return ntStatus;
8 s! D  A2 d% V  }
* A- b$ v- V5 L! N# b) y6 j' _9 _$ R! ]7 N2 N
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;  N& J! ?8 _! @6 y
6 v9 R+ x9 V. o9 S
  //+ E5 Z+ z) ]* }1 B/ V; Q
  // 初始化自旋锁2 g, Z( G$ R. j% e6 X5 d
  //
* B) Y' W7 ?/ t% y# j  KeInitializeSpinLock( &DevExt->SpinLock );
/ ]& h' U! Q1 e9 j5 I' h: T
- W& E% }, X& z$ I  //4 e# |# V, S, x% j) D. u
  // 初始化 IRP 计数器) i: M- r: M' L8 o+ y
  //& E* [0 |0 Q2 h4 Q
  DevExt->IrpsInProgress = 0;
6 g9 U5 l& r" T, W2 n0 j) }* C
, {4 F4 m7 B+ ?2 v  //* x/ r- f4 J1 i) k
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
0 b* n/ o, l% X/ K) H  //
0 g" H7 G2 u; t$ w2 K1 u: v( N( H" x, X- z* e" j
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
3 s9 f# S) O3 d3 l0 S  if ( !TargetDevice )5 r& P  v* I/ j$ `
  {
' G9 D' ^. K% [* d% l4 a    IoDeleteDevice( DeviceObject );
$ P: ]% _; w! y1 y9 P4 E2 y* V    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );0 w1 d0 T9 v: N$ A+ |
    return STATUS_INSUFFICIENT_RESOURCES;1 z# T( z/ K7 q8 N$ E0 F
  } - B. y0 o% O- O- [

7 Y; p3 o7 a0 y% _8 R' _% `3 ~  //3 \6 z# R7 F: \) \# w8 P
  // 保存过滤设备信息8 D! ~& }( ^' V
  //7 q5 f9 F' h, V6 \" }
  DevExt->DeviceObject = DeviceObject; , ]- W, E) {& H% i3 d* R
  DevExt->TargetDevice = TargetDevice;) \% t/ P/ h) {6 h; Q" `4 \/ l. y

  s! V9 U' |0 Z" y8 ~5 s  {2 _! D  //
& q! T9 j9 P. e) I) @: Y2 G( s) L& n  // 设置过滤设备相关信息与标志
+ R$ J! ^( W) {) p$ i8 q  //8 _( P- e: O+ y, P
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
* G0 F7 B4 x, [4 h  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;2 |; t5 L- m) B0 [8 F
) Y; ]7 F$ U9 J" }/ M! y7 B! _

/ T0 k8 T2 o" v, p  A  return STATUS_SUCCESS;
* y; ]* t7 ^. ~! S! l3 v}7 P( |- ~: a9 j
) y. |1 w8 @* I5 e1 D1 K5 R
/////////////////////////////////////////////////////////////////6 d4 E. W" U) S5 |; g" V
// 函数类型 : 自定义工具函数
4 c( v7 c) i) P" P. l// 函数模块 : 键盘过滤模块
: r; F/ h& f! u, k2 E. ?- R////////////////////////////////////////////////////////////////
5 g3 f! W# u6 M9 f// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
" ], Z1 U' R9 p+ Q3 @$ A//        信息,返回附加后的驱动对象
2 H. O0 }4 J/ U  c// 注意 : 此函数仅挂接 PS/2 键盘设备8 S* D4 V" q, }% F
/////////////////////////////////////////////////////////////////9 `4 v# p( ^# ?5 M  z
// 作者 : sinister# T1 Z$ s1 o/ J' W0 P/ z1 l) I
// 发布版本 : 1.00.00) c: l  I9 @0 y$ v, u
// 发布日期 : 2005.12.27/ b. m' f& @3 U+ a# s% ^
/////////////////////////////////////////////////////////////////
. W3 S* u. ?$ F5 _/ w" e' ^. i// 重   大   修   改   历   史: U& t0 l1 J" e# n8 C
////////////////////////////////////////////////////////////////
- `3 `4 l' y  O# p4 C+ |/ J, d6 f// 修改者 :& \; ^4 K! p1 \0 a  ?$ p
// 修改日期 :
+ y' `0 Q% w; s) d( O. G2 H// 修改内容 :
5 _, y2 \3 R( M0 H6 K/////////////////////////////////////////////////////////////////6 X* k$ d0 ~2 N- E% Q' H2 o; T

. y- I7 n( h2 l2 E  x& bNTSTATUS+ R: ?0 [0 s8 H$ }3 K$ `
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
# J. w" d' y3 E& ]4 O7 s5 ^' }                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象2 s. ]5 D$ K. C7 Z8 e
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象4 N6 m* M' |. ]+ v9 P% V* P& j
{0 l2 X; J5 l  S4 y( U. w% d
  PDEVICE_OBJECT DeviceObject; 1 p$ G# P/ y, U
  PDEVICE_OBJECT FilterDeviceObject;, D3 c  X+ i1 m4 V, K- R
  PDEVICE_OBJECT TargetDevice;
% K* |4 N2 R' }3 _  B, l) V3 q  PFILE_OBJECT FileObject; " E; i6 V/ f" }7 K* O/ V
  PDEVICE_EXTENSION DevExt;! I0 c4 x6 v& b+ l+ O/ H# u

8 D: Y" j. a% v) b: V9 J% V- n  NTSTATUS ntStatus; 4 ?1 d3 I; C; P8 I. W4 Q" ^
- c& y5 I! Z8 B* b) s: }
  //
& X# N0 h3 o" g) G  // 根据设备名称找到需要附加的设备对象
& f- z1 F- C2 E! Q8 x) v  //% T2 }* h- P7 j( ?) ?
  ntStatus = IoGetDeviceObjectPointer( DeviceName,0 J* L6 k3 p* [2 k4 O
                                       FILE_ALL_ACCESS,  K; D- Q1 p, C( i$ {( B
                                       &FileObject,' m# h  [" c; d1 ~; c3 \' o: \
                                       &DeviceObject );
1 q: t9 O% m3 r. U8 v6 @( }' X: U0 N3 g2 q5 D* z8 S
  if ( !NT_SUCCESS( ntStatus ) )6 V  @# X3 ^, }- ~9 A
  {) r. S; J4 S* K) }# V5 {
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
# |# g, ^$ O2 D    return ntStatus;
: q- |& h, a; E: t  } % y- a5 }# J6 M, m7 w6 {0 j

5 ]$ g, T) O4 f9 G$ S  //8 @$ _- a+ n( p9 C& L
  // 创建过滤设备对象, c8 |. o4 b, @5 P( o
  //& D+ X0 E5 g8 o$ t
  ntStatus = IoCreateDevice( DriverObject,
6 `8 [7 W5 i7 N; B) Z, ?$ ~                             sizeof( DEVICE_EXTENSION ),9 O0 K. c& w/ z% Y5 A/ K7 b
                             NULL,3 K, d- _6 |  z, ^( R4 V
                             FILE_DEVICE_KEYBOARD,& b# n. g+ e: ^1 M" j6 C8 v
                             0,9 Y% L# N3 }: D9 K, X8 K7 G
                             FALSE,
  ?8 ~' f* Y4 ]                             &FilterDeviceObject ); : N& S1 o# C5 f" p

+ S& k6 A6 y2 x2 A5 B  if ( !NT_SUCCESS( ntStatus ) )* v; F( F3 O' D, B$ ~
  {
4 F1 ~) b+ d# W& t    ObDereferenceObject( FileObject );
/ F+ n' T' F0 X9 X' s    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
( c% Q- p; p( ]    return ntStatus;
% ?: ~5 S8 U- a! V5 L0 s  } ( G' B% N2 c4 ?5 C; Q: w& C

- k) W6 _& R' I: N6 [  //
, {5 V! r& ~& O8 v. {' w! J  // 得到设备扩展结构,以便下面保存过滤设备信息& D  ~, K4 j2 Q
  //# L. E( f' E  y
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
. T# W& z8 }& f# i: R5 @
- a. E1 _+ B5 @2 Q$ C1 ^# u( S
- o& G/ r3 b" H" n  //
& {; J- R" }  G; ?5 `  // 初始化自旋锁
: X7 H, R& G2 _0 n  //
0 ^: q3 ?; [: e4 }1 |; r' d8 W  KeInitializeSpinLock( &DevExt->SpinLock );
0 l. n' k0 j! ~8 t6 _0 m- y. s9 l0 E( W. e
  //
$ Q- [  h1 y; K0 C* C  // 初始化 IRP 计数器) a) W, ~) U5 G$ E1 G# `
  //' S' U1 X( d7 m2 g, z4 [1 d( {
  DevExt->IrpsInProgress = 0;: W. s- P" X7 e" G

! ~/ E8 b) h; f- A! t2 X* f  //" n; A$ E0 V# S  H% |
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
7 @) Q/ H( y2 a+ O" e/ y9 X& @6 l  //( w" M+ [. S& u% D: t" Y
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,/ Z& q' X! N% W5 D6 d* R
                                              DeviceObject );
! {/ a$ }( g8 b9 V8 X$ M  if ( !TargetDevice )
. r3 y5 d- I0 u( D  {
) t" i9 C2 _/ T4 K    ObDereferenceObject( FileObject );
# x1 m1 C; o- f  z' w    IoDeleteDevice( FilterDeviceObject );
; Y0 D( H7 x% i) [, j- w* c( \+ l" W! S    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );" m& U+ \) [6 n* a  C
    return STATUS_INSUFFICIENT_RESOURCES;
6 z  W6 a( p9 q! {/ |/ N  } ' s9 S. i9 t( l- N: u

; Y! D& I0 a% k' r" e* A  //( Y9 X" k/ ]6 F& F2 X  B" \
  // 保存过滤设备信息
- t; ^8 e# f3 [$ @: _7 g  //$ i6 V& c+ }* r4 D4 j) P
  DevExt->DeviceObject = FilterDeviceObject;
/ b8 H: s1 Y6 e2 Y  DevExt->TargetDevice = TargetDevice; $ E6 W  F$ @0 j3 u9 o* S
  DevExt->pFilterFileObject = FileObject;
9 Q* j1 ], b- w2 G( D# n  v! L: b& [/ k
  //
& Y% V  B/ m# C7 |( f. v8 U9 c  // 设置过滤设备相关信息与标志
. l0 c; q4 @  M/ Y3 }- y2 z! E  //+ q% L# {# N+ r& }1 l/ W5 h
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;   W. f9 x, b6 d2 ?% f7 T
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
  `( h3 A: R) C# [4 o4 m  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
/ U: d7 L4 y# q  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
. b! G3 q, b/ W                                                         DO_BUFFERED_IO ) ); 8 }" s- T! j& E1 |5 g& U
( E) Y  m! `. U) Z( T9 {
  //
- t7 m5 o' v5 C& z" E7 z/ p9 D  // 返回附加后的驱动对象. f# V: q( @' G- c4 a" B' |' M* l
  //# {7 j5 E" |! c
  *FilterDriverObject = TargetDevice->DriverObject;
7 t2 W3 L' \$ L9 I
5 R0 X$ y3 f+ Q* ]/ e2 V1 L! N5 z  ObDereferenceObject( FileObject ); 7 V- b; l" j0 C4 g0 w
) {0 P' q/ h- S7 t
  return STATUS_SUCCESS;/ `! A/ ?" I- b9 K. x- e
}
' y& `- t( ?  l5 d7 A* ^  A. r: n( q; g0 f& m# }7 \( c
/////////////////////////////////////////////////////////////////
& R4 Y% h6 V$ C8 K// 函数类型 : 自定义工具函数+ U7 n2 x# C8 A
// 函数模块 : 键盘过滤模块
# d* h3 ]# \/ c; M" T$ l$ w////////////////////////////////////////////////////////////////
' q4 i, a1 _$ }0 A7 z4 H) D' R// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
; t% U; @+ G! r8 V) M. Y//        这个 IRP 的完成
9 r0 G; ~! x; V4 t" N) n" t// 注意 : % R: `- M+ H" k: ~
/////////////////////////////////////////////////////////////////, @7 j3 s$ x; B, r
// 作者 : sinister
5 q; e9 H9 }/ ?" v1 W3 O) i* F// 发布版本 : 1.00.00! L' C1 G' n, ?# I, R; w
// 发布日期 : 2007.2.150 F& k) P8 ~& B  }
/////////////////////////////////////////////////////////////////* |. j# |- t8 T2 ~1 M9 Z
// 重   大   修   改   历   史
+ D. e/ d/ }0 J1 o% Q6 [////////////////////////////////////////////////////////////////& @- A' ?% y7 L# z1 W! i" q4 E
// 修改者 :
3 v/ r* {- a% a0 O1 E2 @$ Y// 修改日期 :" C. @  O3 B+ t; A. @! s$ z
// 修改内容 :
2 a9 \% F( ^  A) K/////////////////////////////////////////////////////////////////% S& z, o' D. c- n- f. U

- @5 X" e& a4 bNTSTATUS8 a  u, d, W. V/ g% g$ D
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ), F: ]: v8 Q3 _$ t5 v, ^
{* v4 \2 c' [' j+ e. z
  NTSTATUS status; + a, U# S, K, E1 q/ b% n
  KIRQL IrqLevel;
3 `/ I( B# [/ L% W6 D
' a  W3 F& \* n, f, j8 u% }- m  PDEVICE_OBJECT pDeviceObject;
7 ^* T+ p$ h% W" K9 F$ J9 i  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION ). F" L8 W- |$ Y; l' D9 k( k- r
                                   DeviceObject->DeviceExtension;
6 k$ o6 R: o4 l. ~& G' t% Q, x, u) w5 M, O3 V8 B$ e; z# x

5 F; K" i) v$ T) F  IoCopyCurrentIrpStackLocationToNext( Irp );$ M6 `  A6 p- f
) }% c1 K; l! S: N" i* N
  //
9 v1 F2 O5 y- s" r% {  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
$ ~* g' m' s/ g: L& q# I4 a% ?  //2 W' l: w6 S8 X
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );& v" S# [$ \% e1 y
  InterlockedIncrement( &KeyExtension->IrpsInProgress );, A, s, z: _3 Z3 c' P
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );) c: U/ W" I* k$ p* B- ?

4 }3 L# w1 U- w3 `- P  IoSetCompletionRoutine( Irp,6 g3 E/ P3 S) C* G% ?4 p" t
                          KeyReadCompletion,5 r$ _5 u/ I( q* G; Z
                          DeviceObject,0 e) T& [1 ~# U; _1 O' g$ r
                          TRUE,3 _  Z3 @+ r5 s$ A' [
                          TRUE,4 }; X$ ]* u! x
                          TRUE );
, v4 I3 j1 ^2 `% h+ X' |# _6 T% J; A1 k: I$ C8 o! @. ?
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
/ K5 G" ]0 r5 J7 M- j; v- }) x7 T} 6 i% g& Z. ~& T5 V% P
1 A! g. F4 m5 I# K
/////////////////////////////////////////////////////////////////
1 n/ i' j, H1 P/ H- s" r* |" V// 函数类型 :系统回调函数
( r* e5 r! f. [/ ^) x0 m// 函数模块 : 键盘过滤模块
0 V) X& F& x. ]6 L, n6 `. M8 ~////////////////////////////////////////////////////////////////
5 ^) d$ j# W. ^: Q// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
7 D) m$ X. c# y# q8 w& w$ d& p+ \// 注意 : ) e8 N, ]/ L' _$ `
/////////////////////////////////////////////////////////////////
2 N8 Z; b( k/ Y: U, ?$ O9 l" w// 作者 : sinister& Q1 Q0 ^( P9 {0 X8 @( R6 O, g
// 发布版本 : 1.00.00$ N" t6 N2 h. c8 J5 h2 E+ l, w
// 发布日期 : 2007.2.12. _- M( {$ p) g: T, _3 t) G( b- _+ @
/////////////////////////////////////////////////////////////////
: I& w6 b7 ~/ R3 Z( G// 重   大   修   改   历   史- \$ l! R% h# q  W; z  W& c! G
////////////////////////////////////////////////////////////////
4 Z+ ?1 G' y: ^. g: J2 h* L  @// 修改者 :
9 z1 t* U( V1 O& t5 f5 [3 K// 修改日期 :' u1 Z  d/ Y& O/ [. A, k
// 修改内容 :7 m) I7 ^+ I* d8 d) L/ M# @* D
/////////////////////////////////////////////////////////////////
' o/ [- Z) c& Z" `& p8 Z
* k( }: ^2 J( q2 L6 h1 z+ U4 FNTSTATUS
9 Y* X+ K0 K) \KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
' H7 G, n( s7 q                   IN PIRP Irp,
; i/ D9 W1 p: f" K9 a                   IN PVOID Context )# x+ T; h/ B* E( W7 {
{+ O' R( x' C* g/ \9 W1 o' c
  PIO_STACK_LOCATION IrpSp;- S" h, Q; v" f$ a- [, I4 V9 H
  PKEYBOARD_INPUT_DATA KeyData;/ G4 b# K  b( c# T9 ~" f
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )' H3 p7 _+ p! K' @: S* d- ?* X
                                   DeviceObject->DeviceExtension;
% s( o5 M" a0 K- ]  int numKeys, i;
1 X9 c5 ]% C$ t, g" b/ [  KIRQL IrqLevel;
) M5 D) B9 I2 x# L8 E5 `
$ `. a- t- i7 B/ ?  IrpSp = IoGetCurrentIrpStackLocation( Irp );9 t! R' y, I7 V0 F: f
$ D7 J7 N6 X& {, V. Y
( Z  {$ U6 w. ~6 l' P
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )0 {& I7 Y, K5 j; N* {5 V1 g1 @
  {
, B( `/ w) ^4 P- z* B2 W    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );$ V( I7 C% r* z. S; \
    goto __RoutineEnd;6 {5 f2 J( Y0 {$ }8 I' z
  }* k# ~( P9 a9 ^

: a6 {) h7 t; E& f9 ]8 D  //
/ y2 D' |5 \- m8 T! X8 _, \  // 系统在 SystemBuffer 中保存按键信息4 X2 c! T1 X7 I- P* h8 o& V
  //; K5 C8 L' s/ A
  KeyData = Irp->AssociatedIrp.SystemBuffer;1 P. |; s; o, z$ A
  if ( KeyData == NULL )
% M3 V9 v  b  J/ n  {
+ d# E7 e* o" w/ {# ~" _7 ~8 u    DbgPrint( "KeyData is NULL\n" );' T  U! p. k3 c6 ~
    goto __RoutineEnd;
8 A8 b, i5 H4 l% t( p4 N  }
2 t; z2 A5 O# _9 G: w. _1 e1 Z  M) H3 [
  //5 g7 z) d* X7 t4 G
  // 得到按键数
5 W5 d6 w: v% \- ?9 @; c  //
% s- c: }( Z! u( e3 W  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
. L+ N0 O% Q/ e& m# F( ?- a# Q2 j  if ( numKeys < 0 )
( \/ j1 m" C- z0 Q" K9 s* f  {
) a1 `9 e. R; w' c/ n    DbgPrint( "numKeys less zero\n" );
, ^% g. g$ F) N8 B' n    goto __RoutineEnd;
2 j8 c0 L) F1 L1 I/ V0 }  }
" F8 ^6 M- c" _4 }1 g! [6 D3 h. V7 z: I
  //, j7 c8 W# o1 Y7 j5 ?
  // 使用 0 无效扫描码替换,屏蔽所有按键
' ?: j. a6 z, W! f. C  //) \+ x- O) M) W8 v
  for ( i = 0; i < numKeys; i++ )
. G+ T2 ~& E5 `# _  {4 U% z" f, q- D0 e
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );2 C  p* v$ \' z. W2 k% s) u- Q
    KeyData[i].MakeCode = 0x00;
: ~6 s; c- _: A. G  }
: ]) n2 ^4 T4 O* x4 M9 H$ e% a1 T- g! ^/ `- R9 j) ~

7 i( d0 V$ T; u3 o7 ^  __RoutineEnd :
9 V! T4 E+ G; S$ y, a5 W& n1 W7 _+ U, m9 B$ _0 N* Z' ]3 g
  if ( Irp->PendingReturned )0 ^' q2 v# M; z; D6 q* H" R
  {! v2 h$ m3 T' [2 S2 p1 x2 m. W
    IoMarkIrpPending( Irp );
0 s* N& W' F- C5 I2 s  }
! h3 k: M0 F+ W* n* E8 ~% o; }
; p9 o1 g2 R. j3 A, k9 X: @  //
6 o% E; M7 R5 T  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁# k  q4 i! T& @7 W. Q
  //! m9 i- D2 H4 _! {
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
) w( H) @  |/ ~: b# k9 D# v  InterlockedDecrement( &KeyExtension->IrpsInProgress );, R+ {$ f) H0 h, I5 x2 j0 h2 i
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );+ N. ^4 l0 D8 ?

0 `2 D2 |3 u2 z9 q+ F  return Irp->IoStatus.Status ;
$ z9 h: ?2 ^7 y; n$ G}
1 v* g" Q9 m" I" B# S& C% u
2 Y& ?# J3 l( d! y7 w
4 Y  F/ j) R) a5 q2 l0 e( j/*****************************************************************
: [% ]7 n5 O0 ~5 f9 b+ d2 s 文件名        : WssLockKey.h
$ P5 C, ~2 b/ m4 g+ `$ Z 描述          : 键盘过滤驱动
- I6 ]0 w2 W; z4 [4 a+ D 作者          : sinister
. \8 Q2 K$ e: }. K' m% b 最后修改日期  : 2007-02-26
- g) k1 c& C( a0 ?: @*****************************************************************/
# R: K0 E) V" Q9 C3 Y; E% U6 L$ a! A* Y2 O3 b9 o% V) I
#ifndef __WSS_LOCKKEY_H_1 W( b; K' {5 D! ]
#define __WSS_LOCKKEY_H_
! ~  u, {& H, m! k6 U* {4 q% ^" u  L+ I  q7 L7 M. _8 H
#include "ntddk.h"1 E4 Z0 N! J! H' l, e) S
#include "ntddkbd.h"
% A. |9 C( i& O8 c1 F#include "string.h"
5 U, I4 ]$ Y0 ^1 w0 X#include " I+ B- V3 o, H2 y. s  C
% c2 h+ F" R0 z' G9 T; Z- b7 y2 z
#define MAXLEN 256; K/ ~# h9 }1 C/ b( w
; W* |/ f" ?% s* |5 k
#define KDBDEVICENAME L"\\Driver\\kbdhid"8 }  B+ M% }7 @( u; ?
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
4 V4 v, v# V6 Q8 {& r( k#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
3 ]2 c2 M% G3 Y" h; P0 B
/ q( _5 b/ }2 [typedef struct _OBJECT_CREATE_INFORMATION8 T5 G  i; d2 `% r9 w) ^( @
{% M  h# u) i$ P; w# t
    ULONG Attributes;7 @5 j3 }- S, q$ }7 C  b
    HANDLE RootDirectory;
  Z3 e6 n( s( J8 O    PVOID ParseContext;
' G' A7 t, x1 P' N    KPROCESSOR_MODE ProbeMode;
0 h" ]& H! U  \% i4 k    ULONG PagedPoolCharge;
9 K% q8 H# A* D  S- y$ j5 R/ b2 J    ULONG NonPagedPoolCharge;
4 O( M! Y* g* S! t- E! {. q! Y$ b    ULONG SecurityDescriptorCharge;
, J0 N' r; L2 J7 V8 O9 \4 }$ K- X    PSECURITY_DESCRIPTOR SecurityDescriptor;
3 _3 \8 h4 G# i; Q4 ^    PSECURITY_QUALITY_OF_SERVICE SecurityQos;# R* }) `* m0 x
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;3 z5 Z1 T9 _6 A0 n4 y3 a1 p4 d2 s
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
; m2 F; L. P, P5 {4 D7 x* V+ o5 I" I+ H3 b2 |0 Z. U& u; K
typedef struct _OBJECT_HEADER
# ], x+ [6 R7 W; D{
3 l3 A$ L0 Q, P; Z    LONG PointerCount;
5 A+ l; U% v& ]$ D    union
3 \8 i' w- W* @; U7 r8 [8 O8 U7 w    {( a) j& D" i, W: w. k7 X
        LONG HandleCount;
5 Y4 W1 s( ~3 i! g        PSINGLE_LIST_ENTRY SEntry;
( g! E7 F7 [( `, c! }    };* r* G- ~. M; A: ?* ]
    POBJECT_TYPE Type;
/ N  U9 j, _  m! Y    UCHAR NameInfoOffset;
+ T/ f% }0 Z3 l/ P, s# d: D* B    UCHAR HandleInfoOffset;
* R: N& c2 A' K5 X8 G2 A$ E$ f4 A    UCHAR QuotaInfoOffset;
* K+ F5 x+ m" e. a( k  |5 ?) N    UCHAR Flags;
* ~+ L. B$ b: W8 e    union
# e+ B, J/ |. O: z* [: f2 Q+ l    {# \+ R' t0 ]0 f
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
2 e  i* Z* @+ z2 i        PVOID QuotaBlockCharged;! O6 |! G% w1 G7 [6 W
    };
7 J  {. H8 ?# F' r
8 J- q* g' I: b$ [# n    PSECURITY_DESCRIPTOR SecurityDescriptor;6 T3 b4 h; w! ^+ ~
    QUAD Body;
+ }0 q3 K7 X2 l" A" f; \} OBJECT_HEADER, * POBJECT_HEADER;, V: {/ e# W% \- r9 s  E% O" d
+ ~1 y) }' y! V
#define NUMBER_HASH_BUCKETS 376 s# P4 V' }% K8 m3 _

8 C! N2 V' D. ]3 Ktypedef struct _OBJECT_DIRECTORY$ K6 ?7 s( h' g) ~! t
{
% w& P- y4 n! p% Y9 t$ I! o    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
$ X3 g6 [4 `3 w" A1 c, {. c    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
5 e" `) N1 D3 k( x) ~    BOOLEAN LookupFound;
* k8 v# S+ s! L" w& s    USHORT SymbolicLinkUsageCount;0 ]+ H1 l- l3 K6 N. m- ?; r! }
    struct _DEVICE_MAP* DeviceMap;
3 y" ]5 c( o: g1 b5 p} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;4 v3 s" c! ?8 M, ]( Q% ~2 g
. i7 W  R/ J& x, R. M9 p& D
typedef struct _OBJECT_HEADER_NAME_INFO) z$ A3 R9 C" x+ c: }
{
3 Y& I; Q# R- C. J    POBJECT_DIRECTORY Directory;2 a2 X# E: z5 H3 b$ ~3 j% n
    UNICODE_STRING Name;
6 }7 j" b/ m/ ?  ^3 b    ULONG Reserved;. O8 l1 I2 o# M6 {
#if DBG
/ t4 m7 d3 `5 s    ULONG Reserved2 ;
- d  p$ \' {6 C4 w- q! J5 t1 O, [    LONG DbgDereferenceCount ;
2 H& v6 d. @  p7 H#endif4 S3 E. q5 h; B9 I- A
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
' d1 g' m1 N+ k
# G) r# V1 j) b& \) L7 p#define OBJECT_TO_OBJECT_HEADER( o ) \# D( b7 j& i5 Z
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )9 C3 u% m6 m  V$ i) W* w3 T# t
+ }2 C7 z1 d: @; K( j
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
/ u8 v7 F& E4 V: L    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
$ ?2 A) |& s7 G. S4 m$ k
$ ~2 r3 g: `( U' u9 l# V9 }typedef struct _DEVICE_EXTENSION7 X3 s. z7 o' H8 I
{
1 Q+ \- N, l5 a, j4 q  G. j    PDEVICE_OBJECT DeviceObject;$ X8 L7 F- V0 l; T3 O0 S9 a
    PDEVICE_OBJECT TargetDevice;
9 p; D5 S- ~" X2 S* s# r: s! L    PFILE_OBJECT pFilterFileObject;
( L3 A" M$ a* h6 _* ?    ULONG DeviceExtensionFlags;4 F6 G- C: ~0 f; Q( l% D* `$ }
    LONG IrpsInProgress;
/ _% J' H6 i& m: d8 g    KSPIN_LOCK SpinLock;( U$ {2 r  |. J" o; [  p
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;  F% c1 `7 N. Y/ N
: K; h* ?1 d9 q2 s0 Z7 K" }  r, J
4 x1 f" N& Z: J
VOID
; k2 K# b: ]. b1 C6 Z3 ~KeyDriverUnload( PDRIVER_OBJECT KeyDriver );& V. s8 G9 o7 P0 E0 Y
2 O  M8 ~* H. R$ J6 Z) `
BOOLEAN
, r0 j$ `) t3 z6 ~CancelKeyboardIrp( IN PIRP Irp );
/ P1 y' O# E2 d) _) G
9 N9 j/ }; B0 f! ^  e$ m  Xextern POBJECT_TYPE* IoDriverObjectType;. n% z/ ^1 Z. `8 v: Z
, s$ X. m8 n4 V2 g
NTSYSAPI
5 X" B( W' ?, E  O3 K/ W7 @NTSTATUS' m3 z  s! G* {
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,! p# p* a- f6 K9 {* q
                               IN ULONG Attributes,% d- K7 {. H: P1 `+ w
                               IN PACCESS_STATE AccessState OPTIONAL,
5 z; i7 H$ Q! p+ H                               IN ACCESS_MASK DesiredAccess OPTIONAL,
* k+ O+ E; H1 q: c! i: q                               IN POBJECT_TYPE ObjectType,
; r/ {" N+ D# \+ c$ A3 y                               IN KPROCESSOR_MODE AccessMode,
  k' _0 X0 j. {5 s* M* I                               IN OUT PVOID ParseContext OPTIONAL,
8 u8 l  G0 ^6 C8 f" {" n/ A                               OUT PVOID* Object );
* B1 E; J) A; f
+ L% `, Q. d7 h6 A+ Q' }- {NTSTATUS 3 i* y# y  W. o& m
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
6 u; z0 H9 i4 |( [% p5 ~, e, z
: l+ {; c% x2 T3 a/ T2 X" P4 P/ F/ p8 h2 jBOOLEAN 7 C' x9 Y" m6 E6 Z" y) N+ `. T4 ~
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );- V; w( Z# N: u0 i4 t
; V! D/ ?* d3 L5 b
VOID # ^5 V" L: @" W/ ^7 d" |: O$ j
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
" q  J& H# S! K+ e
7 C- \( G7 N& n6 {, [NTSTATUS
. C7 Y5 s' n. Y, B4 KAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
# V9 m, R( q  Z4 `; u                                  IN PDRIVER_OBJECT  DriverObject );8 x% U$ ^3 U  E, s% t1 W
- a! a9 Z5 z; ^0 s7 O
NTSTATUS 4 ^0 j9 g, H4 P$ q3 d
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,  h: W$ K% n. U, [$ Y/ @$ \
                                  IN PDRIVER_OBJECT  DriverObject,
1 N* P' b/ ^$ @* i9 T( C% T5 O                                  OUT PDRIVER_OBJECT* FilterDriverObject );0 D- I- l6 ^! F
% ^* ^$ N/ G) J. o3 Q8 j, Y. b, [
NTSTATUS
  W+ e0 f% E% u# w. e+ J4 |KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
; H6 y. E# X4 n  O                            IN PIRP Irp,
0 [) f$ C( Z5 r0 y# F2 K                            IN PVOID Context );
4 p  |' b- h+ i/ t- T, WNTSTATUS
& Q% ~- }) a' C& _, D, NKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
0 b+ [5 v' \  Z0 h
# W7 m! `$ J. ~1 f* AWCHAR szUsbDeviceName[MAXLEN];, m; o$ R; Q$ d+ ^+ V
- ?4 `1 s9 B/ r9 c
#endif7 @$ M2 z; [% K7 o
. Z4 [; b- N3 r  H% |: t7 _
! ]% a- `$ I# h

- d9 B# F6 p8 p4 q) G3 y9 b" {. B" x' A

+ Y9 ~- R$ G& j4 H* T& rWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
6 s* r* ^6 l9 DWSS 主页:[url]http://www.whitecell.org/[/url] + C  q$ Q8 J7 z$ K9 J
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-12-1 06:42 , Processed in 0.082725 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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