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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister. W4 D' g, [" L* y: o
Email:   [email]sinister@whitecell.org[/email]6 q  M. Q) r0 K4 u. ?# z
Homepage:[url]http://www.whitecell.org[/url] , n) k2 p: H- I
Date:    2007-02-26
+ ^0 q0 z2 z: z* l3 h4 E: Z, w, k8 v

/ c6 X( `  d! H/******************************************************************** H+ Q0 n' _$ c9 @/ H/ s  x9 @

" F5 ]/ W3 }, C5 R& M这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
" n1 s8 N0 T+ Q9 J- k1 M写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
; p2 ?. `# g4 g8 I+ u: m功能要求如下:
) Q" v( {& ^, I' D# U3 Y7 n1 W% @, M9 U3 n0 O
1、强制锁定键盘/鼠标。
( k' z. Y# z: C: B5 _- r2、可动态加/解锁
6 g* o" g. c* G, t* }5 f) {) r3、兼容所有 NT 系列的操作系统。  @. v- u1 `1 A: T
, C+ i1 d* ~6 G# z; y3 p
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
  ]) B$ k! S( W- r' s4 W现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如. Q6 `0 L5 [# V( j
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
; @* R& j# e+ a, H& w! P上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是, T8 V, C. d( h' A$ J* l5 C
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
' G; b. ^( n4 i3 A8 b就来看一下我想到的几种实现方法:
; Y6 ]3 C% N. k& R: i: V- j6 U3 M2 t! v1 {) a& L
1、全局键盘/鼠标钩子
3 y3 d8 z5 {" J2、BlockInput() API5 k& c( K6 ^; |0 c+ P' C
3、使用 setupapi 进行控制3 Y" K. B3 Z/ q* @; c/ U  v
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
! N$ C) i. M9 u5、拦截 win23k!RawInputThread() 函数$ P- \( t5 ]* S- A% f7 O( h
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
/ ^8 K; ?& w. l# ~6 o4 o% s7、拦截 kdbclass 驱动的 driver dispatch routine* y- `" s4 j( B6 v- \& E" W  Q
8、实现一个 PS/2 与 USB 键盘过滤驱动
# c7 t+ }2 E: d: f- T, w/ u% Y: k0 p0 E  m& X
! y/ M/ w2 @/ g. f" `
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑5 n' q; W: r, X) B/ e3 |% U
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
- r9 d) J) O: P/ m/ {案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在/ E  K$ y2 K( E: n" B
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
# A3 K+ n+ D* i8 f素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性: O, M& G0 [5 I$ y0 c  o$ q
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸2 T2 Q3 D9 B. _  ]" M* f
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
: S. T, a- h- x的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来5 p) \( A2 |8 I" z2 ?
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如1 R. V5 k4 I; K9 p9 N
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有1 }; H2 a" k' o7 s* D
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截0 E) R* [' F. L
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
# V' ~8 s& Y# I2 m$ l1 v3 G$ QUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键. H' [5 o5 e6 N$ r; K6 m: ~1 ]
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
( I" c' @# n! V" \# x! r案的全部功能且不存在它所带来的问题,否则就没有什么意义了。# ?" E5 O4 g' e5 L% x6 s4 B& }
( B  n: c, z4 e1 p' @
! h, s$ B) x% u' `: |  s# Y& u
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过/ X, [5 G& I) g
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
6 B3 h) T! ^# S& H2 M9 @' e* r/ k行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
# S+ a4 r& M! i; l- W$ I! T只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
  O4 Y- o& K' s- u来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
! D( j9 A  x9 z1 I+ q( tKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
4 c; V4 X3 K$ M- a; u+ J7 t) Q6 W键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
* v8 J3 f4 F$ S$ c3 HIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,: Q7 D  I  A: U$ C2 W$ x; v2 r
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题9 p1 v. e  E/ {" j) Z% W
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
: T* x$ T7 v* v# X6 s' U而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使, ~) |2 s+ ^& w$ c8 }
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通2 a4 ]& \% u7 p, v, B2 T
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来2 E8 L6 }8 p  G$ v. Q! d
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通7 X$ S& l- a1 q, k' S: }  D
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
, X3 y# _! x, D% |, l上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
* i9 O; H* d$ E# }! I, ~& j4 n  J的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
- D7 q: q& I; W! ~7 g: k( K7 |味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。3 I* W. U4 m" K: ^- g
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
# I$ l% w$ M4 Z- A0 ~来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
- r# \& D4 w- {. @4 o6 m& M6 q2 e7 U的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo7 R: B4 f# ?/ h5 G6 H$ D# g
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致( ~2 ]& s* P% D. b6 [# S4 g& |! J
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,+ I7 r$ n2 P( j4 d# |
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程5 {1 j: l/ Y- P: O1 r. _0 l% m
见下面代码。
3 u9 \3 {8 X3 L* l- p/ q8 d! _1 M2 U5 j+ K( ^0 K
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
9 ?% `+ j; u" q9 Q6 |" o9 Q里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键% R; i) R2 _* x/ n0 X* y9 V3 L
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
+ `" o) N, q5 G7 M9 {( s上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有3 @" F1 @8 I. f9 j; u$ L
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
& f! K" B& L, q5 y" a3 M2 X继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
0 x1 N7 u5 g+ E- Q2 K锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按$ M5 O' [; E, H- b
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
# I9 X% p0 O  K) T4 b
+ S# k! ?+ h8 {6 \& ?5 t; G; B$ I7 y, X
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
4 @8 j& D# k0 t1 @! C5 K5 [的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是- V5 p7 b7 I. m* l( {* V
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣, h+ t9 B# I2 H8 f! s
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我% O- u! v2 v, a7 a  L
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我3 A; a, a6 k; [
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
8 L& f. R% |7 ]! f7 l1 ?2 |2 s0 l/ ?! s/ Z->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
: r2 x- H9 f4 c2 P2 }; F如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager% F+ t+ l. D3 N/ p
进行操作了。这个问题有待大家来完善了。$ y- |4 J: S) x# m, `2 ]9 p

  @# ~$ l4 F" }- P1 V% p
  P( c# m3 W; l2 w' G9 R8 b; T要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
3 f$ M) b/ j! Z来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的6 F. W* n7 K( X) V! h+ @
分析做个记录而已。我更愿意把它看做是一段注释。
2 H0 z! g! |* c) a5 k! g2 q6 P$ o: B
$ J1 X& a& V, Z" K最后在此代码中要. x3 _; e. d0 P
# P3 B) y3 _8 [) C; f7 G9 l1 N
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
, q0 q* V6 O/ ?0 ], W/ R$ v6 \( S
. M2 Q' [) o, J5 a; G  A1 c: w感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
# d9 G7 E( z; j. W1 V& n7 c4 m# c+ G9 x# R
感谢:齐佳佳,过节请我吃好吃的。
5 ^0 h$ n$ A: J. O7 X: O/ p3 v
& }/ t1 T% e% ]4 C0 H/ e
+ K) ^$ i+ j% x******************************************************************/$ f& z8 M. G5 m+ ~+ t7 J

# ^& |4 A2 r3 T2 e0 Z8 q4 h3 M3 V. w1 I) s' W$ g
/*****************************************************************# m2 k. @, [4 L
文件名        : WssLockKey.c9 L3 c$ [, D3 }' z' k
描述          : 键盘过滤驱动
' G% y5 I! Y8 U$ | 作者          : sinister
/ i# F! r* k- L 最后修改日期  : 2007-02-26" e- u) e: B/ u- X; ?; W1 ~/ [
*****************************************************************/
# r5 a: [0 ?# {+ J' g
3 D8 q' Y  o8 K; P, b8 \5 W$ d9 X  l: X' L, q
#include "WssLockKey.h"" [; b8 N9 ~: k' |( v
5 ~" |: a; D. Z7 M7 R
NTSTATUS
# Y; }8 j0 t4 f( Z; MDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,' q! J8 H. i+ F+ J% D' }: ^
             IN PUNICODE_STRING RegistryPath )( M3 i0 [0 l6 t" W7 _" x$ |6 {
{
3 A3 _& L" j2 Z. z. t9 u% K7 h; h# \  UNICODE_STRING KeyDeviceName;
! Y: h) X& _5 X  PDRIVER_OBJECT KeyDriver; ) B' h2 a4 }* o, \
  PDEVICE_OBJECT UsbDeviceObject;
* c: e% l# n$ L' [" f  NTSTATUS ntStatus; ! x% E( x9 F0 u0 r
  ULONG i; 4 G- o9 S* g5 I/ _2 t( ]) M4 u

3 B3 q' p4 Y! j6 F  //4 y: ]3 E& l( U! |0 I" A6 n  A
  // 保存设备名,调试使用- K7 O3 B- g2 X0 V4 G0 r
  //
- {3 {; {# P5 k; G) k! m  WCHAR szDeviceName[MAXLEN + MAXLEN] =; v" B( w) z. H3 j! u8 b# {
  {) `1 M6 V" Z" a4 a5 }4 q7 D: T
    02 k. ?9 N/ n( z  r6 j8 d2 M, o
  };0 k; z+ \5 w) n$ K/ y- D
3 s) t3 M7 v* H- B5 L& ]
  KeyDriverObject->DriverUnload = KeyDriverUnload;
) L8 T1 z& V% D; y, p- R& y! X' u" {3 J
  //' @. z7 Q! H' V. x- e% Z* ?5 o( B
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
. f6 h3 }7 o$ q' c. D6 t6 [1 w* J  //
" q4 B. m0 M' a3 X- L1 C  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
% Z5 H; \" N  Q+ X* o. }: v, Q  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
" {" L4 N9 l: A" ~* n2 L1 G) T  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
$ G. ~2 Y7 w# G6 D+ ]  // USB 键盘设备来进行挂接& P6 ^7 b. t4 Q5 X
  //
1 n- g2 j& a% s  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
# P6 z2 ?& h+ z3 E5 p: |  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
! |5 N9 X; s! S6 K  {
. ?( \4 Z- a  q3 r    //
: N3 p; d1 R( p8 D% \    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
# N3 g& ~$ N0 l9 b, x/ P    // 所以这里打印为空
# I  S( G, n" |5 D6 E    //
+ e& u: x% H6 E! G4 `8 ^2 B    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
4 S. |7 J' r8 o; x& ~: z; o    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );- v8 t3 b' x. D2 g$ i1 |/ @
: C* N9 b1 _9 T
    //
/ j* v+ q6 x3 j5 k2 W* d4 p8 K    // 挂接 USB 键盘设备
) b! i6 {( N6 `! D, _0 f. t    //
2 k" x4 B& X! M+ s    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
, v& x7 w* j' a/ Q    if ( !NT_SUCCESS( ntStatus ) )
7 _( y! }6 l# F. O/ Q, f- i    {
/ M" N7 _  \- |: b- Z! M( A      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
6 I5 C/ W+ l( V% ?3 }      return STATUS_INSUFFICIENT_RESOURCES;4 m- F/ S( V. ?, p2 H( u0 q0 M
    }
: z' D) Z9 d+ F$ p& M  }
9 x' j' {0 U; b  else
8 X2 ~4 i* d. M- g$ g+ v  {. ?9 e. e4 M, S
    //1 s8 z& L7 K' E  L0 }
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
* E: R- j! j6 y0 u0 W# O. m, Q  J2 [    //
7 {6 `8 C8 g9 p3 y! ~' @$ L    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); , b9 {! b+ A4 j4 B
5 g5 j4 D: V$ i9 ^) O5 n+ j
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,: K# h+ M$ q4 [% ~
                                        KeyDriverObject,
; ^8 a4 N6 K8 \+ q2 [: ?* r! t                                        &KeyDriver );
. x3 _8 Y% {7 G! m2 l    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
5 J& i) f; G! W/ v& f' I    {
4 b: H( @. q  b6 R/ C# ]      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
  i  E% ^7 L. Y3 B1 T7 O% W      return STATUS_INSUFFICIENT_RESOURCES;
0 N: C6 g4 [. O' v, k- i- }    }
) |  p! f6 X3 ^% D( t) ~* }  }
* P+ E$ X( p! g' }" D; K1 w9 }9 y8 ^& F$ c2 a% a! B
  //% c* v1 p1 i9 _* e2 U/ E+ A
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
2 V1 a8 B- {+ y  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
- W' u- O5 ^8 \8 [  //; |* B' W: g6 y/ Z, D1 [) n
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; / o6 k9 I( O: H' v! C  N

5 ]* ]0 B8 r+ R. Q" _- D% s  return STATUS_SUCCESS;
1 \  ~( L) W* q} 3 N0 w* s6 |) z. d" w0 f# k; G
) D' {4 i( n0 I- D! n8 K
/////////////////////////////////////////////////////////////////) W+ z2 z2 a( b2 D* q/ J0 A' e
// 函数类型 : 系统函数
, y+ h- L# p" z: S% G1 j// 函数模块 : 键盘过滤模块9 T. W3 [; q$ [9 u
////////////////////////////////////////////////////////////////
: Q* H- A# g! r$ `% n( M" Q6 d// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,* E' Y' S- z5 L( N. Y6 ~
//        卸载键盘过滤驱动* s; o( j3 D% n8 G& I
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
1 H$ n4 [& m. E, |7 d9 O0 ^/ j1 y//        则需要等待用户按键,以后有待完善
1 P& F5 ?8 z7 ]. _$ l! H/////////////////////////////////////////////////////////////////' Y( ?: X. w1 d/ i. G& U- E1 d
// 作者 : sinister  Y# A1 ]! @: W- S
// 发布版本 : 1.00.005 I6 }0 H2 D6 h/ x
// 发布日期 : 2005.12.27* [) d7 [: s+ A* v# I9 b7 T/ m
/////////////////////////////////////////////////////////////////2 u1 R0 S: e( S0 ^$ u5 k
// 重   大   修   改   历   史
1 T  P9 P* [  Z3 V0 a6 N8 x1 S////////////////////////////////////////////////////////////////
% R9 ]$ p; v& f4 l// 修改者 :2 t. q; f" G7 Y1 e4 r3 ]
// 修改日期 :4 d& R0 N2 P1 T- [" I4 s$ E
// 修改内容 :3 I1 N& S* |2 m- S- R3 H
/////////////////////////////////////////////////////////////////) K0 |9 P4 j3 v2 C

9 Q6 t! t* Q" p1 y( _# I& c. FVOID; N" g6 p9 b% o; I% `  x# I- n
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
9 T% w3 n+ ]7 g, v) }( l) N{
5 b. D" _6 ?" @0 v  PDEVICE_OBJECT KeyFilterDevice ;      
) h% S( F0 @: j+ ]- ], s  PDEVICE_OBJECT KeyDevice ;  ?: u$ j3 Z$ t0 n
  PDEVICE_EXTENSION KeyExtension;
1 K) B/ Y$ k2 r1 T5 M. t8 P  PIRP Irp;- k6 S" q0 w% Z* q* O0 r3 i
  NTSTATUS ntStatus;
1 g1 Q$ l# ~3 A% {: O/ J2 o' e; g5 K( W* T0 |, F7 Y5 J/ y# ]7 \' g$ O1 h5 g: G
  KeyFilterDevice = KeyDriver->DeviceObject; 7 I3 }. A" y+ C6 B) v0 K' A+ W
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
/ X$ K& j. I0 y! R0 n2 r/ n  KeyDevice = KeyExtension->TargetDevice; # N8 _. ]% H% V. t" Q: a
" U* o0 c( q9 G. W& L; m% B
  IoDetachDevice( KeyDevice ); ; d- ?( j9 F1 T2 w$ e2 r- |

8 V9 U! u! {! @% t& N8 e  //2 x5 \5 c+ q( a. ^' l( W8 z
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
4 r4 @1 o0 I0 m: `/ }  //
2 k# n3 o. Z+ I& c3 z6 _  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL ): e- X) L8 Z* z( a& }
  {
/ I+ _9 }$ }- J5 `    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
) I% a: ]8 Q0 R2 q- Y$ Y' C    {' ~' h( q/ l' v' p3 N
      //
) b2 B. A0 [. J3 g      // 成功则直接退出删除键盘过滤设备! {0 v& A0 V- E2 l
      //& s3 S" k4 d: C) p
      DbgPrint( "CancelKeyboardIrp() is ok\n" );# c! `! A1 e* x) Z8 V3 L0 [
      goto __End;/ |$ ?) {6 N* Q/ v
    }. D8 A3 w  e  l' _' B) R/ C
  }
/ K' d% r7 b$ ?& M* H$ t5 [9 w5 S1 q
  //' z; o, ^: s$ x# @9 h# f
  // 如果取消失败,则一直等待按键
' T, ~+ k, b  O# u  _0 S* ]  //
" ]8 q" f- _& b: I. z# T  while ( KeyExtension->IrpsInProgress > 0 )
7 ]  L4 l+ y& ~# W0 x- u( f3 D3 w  {
' u8 L7 _, R' ~5 J    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );" ]5 T. z5 V: y2 L+ R' j
  }3 r0 x2 l" }0 Y# t9 v) x' P) s
8 h$ c, p3 @0 b! d. o
  __End:0 ]4 \6 {# `/ X- F% ?
  IoDeleteDevice( KeyFilterDevice );
7 r  s) j5 ?' y
" r3 W) m( l7 o* ^* e  return ;
3 K: A7 ^3 {7 p7 h, f! K} # e6 X6 T( o0 V" R9 _0 L
; @5 c. }5 O+ ]
/////////////////////////////////////////////////////////////////2 ~% U: s$ c0 X) D* F/ p% _1 e
// 函数类型 : 自定义工具函数5 \$ y6 G, J" _# E, |2 g& Q
// 函数模块 : 键盘过滤模块
3 i/ `# C$ z9 ]* _5 j9 j: Z$ {+ _' g/////////////////////////////////////////////////////////////////
4 u: E' v" \7 ~& h// 功能 : 取消 IRP 操作' E% v7 T' [' m
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能$ a: e9 K9 G% n3 ]1 u
//        使用此方法来取消 IRP4 A2 c' e, U0 o  M+ s' \8 z
/////////////////////////////////////////////////////////////////
  c$ G3 }$ w3 t" P5 n* e4 \// 作者 : sinister* c3 M* J! _1 P( y. O9 F. J6 E3 T
// 发布版本 : 1.00.00
1 O( s. S$ A% D7 ]& p9 q// 发布日期 : 2007.02.201 f* y( m: x* h
/////////////////////////////////////////////////////////////////
) \  K. S* Y# F. e1 U// 重   大   修   改   历   史8 l6 J" e' L3 Z7 b" h0 P& B& I) n4 `. T+ U
/////////////////////////////////////////////////////////////////
( m' f. e( g) N% T) U; T// 修改者 :
# M3 R! D5 f3 O// 修改日期 : / X. D" ~0 u+ v  F# k9 N' {% k( o
// 修改内容 :
4 d0 ^6 i* Q3 \2 x- X: m; e* h" X* k/////////////////////////////////////////////////////////////////% n! r. E" L4 ^2 r

: P2 D# x, Y7 M8 PBOOLEAN
) P3 D9 E3 ~- y% ~CancelKeyboardIrp( IN PIRP Irp )
9 x" P; a. d3 n% @{9 d, g- H8 a6 A. h
  if ( Irp == NULL )7 D5 a7 r3 H9 a. Z: Y$ `( ^' x
  {
  C; Z1 N( T4 h( n: n$ I    DbgPrint( "CancelKeyboardIrp: Irp error\n" );: C" ?8 P0 P; t' u* G4 g% p
    return FALSE;
/ v: U0 B( N2 F' W* v0 f  }& @9 ?1 q( b6 r& X) y3 s
4 n+ Q" e. X, c
8 J8 O2 F4 @- n/ j1 Q, a
  //  q/ \% `. \3 {3 T' j) A3 q1 \4 R
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,9 C: f( ?5 V: C$ e4 n/ U9 o$ u
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
/ @. ^7 g) ]( o' b9 ~) I2 C5 z  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
5 ]. z3 D. E, D6 I' p, V' T- V  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD5 k0 e4 u' C8 U7 `2 x
  //
0 \! g& q3 V+ E' }5 r' p0 s& h# c& ^" \# J; g8 K2 w9 j/ d& b
  //2 g$ P2 @# \8 W8 z( b/ X
  // 如果正在取消或没有取消例程则直接返回 FALSE
% _* V2 I/ {7 w, ?. d  //
7 K( M- A3 o1 Y1 o8 I$ e* _  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
5 D4 m* Q; |! u7 x+ ^- S+ d6 v. [7 t  {4 L' N: j3 s" t
    DbgPrint( "Can't Cancel the irp\n" );
! b: F# a7 {& l    return FALSE;, k8 u# y5 g. F4 D& X' t
  }. P% ], ?' X3 @. Y( i+ K7 S

/ l& G: W1 |) z# d6 J  if ( FALSE == IoCancelIrp( Irp ) )/ D6 V& m3 V) V
  {
" D) `  ]2 A  X. ?) h( l    DbgPrint( "IoCancelIrp() to failed\n" );- p, M& T" P  k: }
    return FALSE;; U% a( i' u) b/ H8 n1 v! C8 o
  }
' G, M3 x8 C6 \$ m6 v! a% c0 ?0 H) n+ h/ `( T7 @3 M% W
  //
, q6 B* B( L$ U: L# h1 P. N  // 取消后重设此例程为空0 r; Z- A9 S& D. _9 B- h+ o. s6 h
  //
: N! V! M0 L- T. X) U% X3 }" T  IoSetCancelRoutine( Irp, NULL );
& n9 g. U0 E: J1 H; T  g$ {0 K; G
# g) k1 N( s. \' j  return TRUE;
9 \$ g% ^# R8 T$ l' l9 R}8 Q+ O# Q$ r: ^) O7 p, |# W

& I% G/ N2 i0 W0 w) L  Z7 k; H( w1 x/////////////////////////////////////////////////////////////////
  h# d$ C# c9 V4 ?3 L// 函数类型 : 自定义工具函数
+ }; Z' @. V( B! l+ M5 s5 w/ h// 函数模块 : 设备栈信息模块
8 ?, x, Q8 ?* h4 l6 w! ~! r/ a/////////////////////////////////////////////////////////////////
9 n) j/ u3 i8 ?4 o// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
: Q; j/ x7 Y% T) A/ {) j//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)# I0 d8 c4 }6 B+ B9 G; u2 ^
// 注意 :
+ b" Q2 f/ ^7 y' e! _. Q( L/////////////////////////////////////////////////////////////////
4 f) t. {. F  S8 z& f( R& T* ~( Y// 作者 : sinister: e  n9 [3 Y) I! @
// 发布版本 : 1.00.00
1 N4 ^' o4 J/ f! l# ?5 l0 K// 发布日期 : 2005.06.029 }; L* n$ d& c( Y4 |9 a' t
/////////////////////////////////////////////////////////////////
7 I$ E% V' _0 v1 E9 o// 重   大   修   改   历   史
1 U! Z, d. G# ^7 Y* _/////////////////////////////////////////////////////////////////
. x$ K) q9 d4 `  Y5 t5 h// 修改者 : sinister
" [- q5 ^9 f7 g& ~  q// 修改日期 : 2007.2.12# y. o/ I6 g2 |3 `
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
* o" _# F) a# N1 v, E/////////////////////////////////////////////////////////////////
" z! R) {0 Y8 O9 R  k
7 u- ]- y- @3 U' Q& GBOOLEAN
6 @# A9 T3 Z% N! WGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )# P0 h! z# o3 m0 H
{+ Q9 J: M5 h+ w1 A# \3 v. w
  PDEVICE_OBJECT DeviceObject;
+ M1 I4 p- D3 l0 U& I3 P  BOOLEAN bFound = FALSE;+ [! v0 I2 E6 F/ d- S- {/ L

  _- L7 V* y6 ?+ N( s8 u  if ( DevObj == NULL )- B/ _& ]- E5 |6 K: \1 \- U( g
  {
8 E$ j: b% G) _  M1 E+ b+ ~* y    DbgPrint( "DevObj is NULL!\n" );) K/ s# T/ {+ C  {  O' P
    return FALSE;3 v6 l9 n" q: P( X7 g# ]" |) j; @
  }
) s0 j3 k( z5 n, y; g, K6 |# t% `; Q, ]9 u
  DeviceObject = DevObj->AttachedDevice;* j: G* ]4 H. a% w
. Q) X. w+ }/ v, K- o  l/ K
  while ( DeviceObject )6 X( z4 e2 g% F1 [1 U0 V
  {
4 ^+ N( u% @% \, p' g- b    //
* q( U! \" l6 R) w3 l. b1 R    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但0 o1 w; E1 t  f/ e0 M
    // 有一次足够了。这算是经验之谈
5 B! R' p0 F8 a* e4 @    //9 v- Z) K, K6 {2 a
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
; y2 y$ v5 Z7 k9 P  S/ `    {" p* A6 X" D6 k2 t! z# l5 @2 \  j4 d
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",- d# P! X5 _! h$ R2 P( K  V+ j1 c
                DeviceObject->DriverObject->DriverName.Buffer,# o' ]) S, {4 Q% a
                DeviceObject->DriverObject,
4 L; H- j$ x/ \9 H5 v5 m                DeviceObject );8 J. {' ~  |. r( `$ l6 i: e

0 c' V9 \( `# M0 t      //9 _8 R( p- F/ C# Z6 j: l$ t: V
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
. [* J5 E$ M8 n" E3 X      //
* R5 o% f, F) y& F      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,) F; @) s+ D6 U; q6 E
                      KDBDEVICENAME,
3 I& c& w4 Q' k0 C6 V+ X0 O                      wcslen( KDBDEVICENAME ) ) == 0 )
3 B. Y0 i( Y0 l! h2 R/ p7 g6 `      {* E3 R' t7 W( E  T7 J
        DbgPrint( "Found kbdhid Device\n" );8 O1 t* ^, a7 c) s
        bFound = TRUE;
/ k7 R7 x# B; _- Z        break;( V" `, U7 X1 ]7 H9 K/ [6 z
      }% X# ?  t7 w2 a7 [2 o
    }% e0 b8 L/ ?2 h
6 |, F$ R7 Y. m! y/ z. B. K3 l
    DeviceObject = DeviceObject->AttachedDevice;) F+ B- _& k3 u5 q
  }/ ]  o# m  J! k+ v. |+ j

  U: n1 B2 r5 v1 I4 C! k1 w  return bFound;& o1 s- ~% Z$ t4 l
}3 X) L  g% C* m, a( L% \

5 n7 T+ i6 w( U/////////////////////////////////////////////////////////////////
/ O  z$ @& W/ A! d. P( t. ]; X  |; V// 函数类型 : 自定义工具函数
+ O9 H; _3 Z. e  w: b2 _  U! x// 函数模块 : 设备栈信息模块
4 ]6 x" i  \0 P, x5 p! j9 ~- U/////////////////////////////////////////////////////////////////' b2 v1 ^6 F  O- l0 L
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
' D$ m6 y  Y' _) M" i! W// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
% x) N, S1 m9 e7 Q( o/////////////////////////////////////////////////////////////////
+ `$ K* K- I2 m& s// 作者 : sinister" ^4 Y( {% L4 [! r$ B4 \) G8 A, O' v
// 发布版本 : 1.00.00
- k& d  P7 \0 ~// 发布日期 : 2006.05.02* m# m& b4 v. u" h/ f7 `
/////////////////////////////////////////////////////////////////% F+ \( }$ E4 w" x- o4 R1 {3 E6 L
// 重   大   修   改   历   史
0 ?% q* g$ z3 Y1 k1 [" I/////////////////////////////////////////////////////////////////
  |: p0 B, w& O( g4 T  A; [// 修改者 : sinister: j" ^  Y( f* h# R& x. z
// 修改日期 : 2007.2.12
9 h9 _8 e; h0 _// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
" x$ \! R- a2 N, h# S  y/////////////////////////////////////////////////////////////////
8 R) U2 @! \! L7 z& y9 R
5 |4 @) c4 k2 IVOID
! Y) \& d. P8 K% o+ K6 d* _, n" ]GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
6 D% s+ a$ e- v) I; W" N% Y$ e{
2 u* h$ ]. @9 k' a4 C+ h( z  POBJECT_HEADER ObjectHeader;3 p- K9 s- q% N; T5 h
  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 4 a+ D; {1 ^; v0 X2 l- u

/ Q5 a4 F9 b$ h% j, X  if ( DevObj == NULL )" u; v, z# K* w4 C
  {
, m5 b: ~1 T( n6 @# t8 Q( M9 G    DbgPrint( "DevObj is NULL!\n" );" M6 c+ r$ [) P1 {) u
    return;
* ~1 b7 ~9 u% L' v0 G' r. l  }
6 Q1 [" C, m3 I. X
. p7 X3 l% @! A4 G  t6 C& A  //& E" x9 f2 g+ p. f- }
  // 得到对象头
! T) L0 V; B% M  //: }+ N: p# ?. W; L
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
- w" p; P( _- i1 G% V  t2 i+ `5 S
) B/ b# a- @* R1 W  if ( ObjectHeader )% }1 f/ o% X3 u  g$ g" g
  {
) ?# l) d4 T1 I$ C* r' O    //
* A9 a, {$ k0 Y    // 查询设备名称并打印6 x4 Q- D# n! g) o
    //8 ]! O7 d* p* f& x1 s# C% g: U
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );$ H& \- r& R7 X9 n) `: q0 Z
4 ?  J' n! F! ?% Y3 `
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )( ]" Y" K9 X) l. T9 n
    {
7 }0 r6 ]" Y7 J. |$ M# @      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
' ]- T8 t# {& U  _) K2 ?$ S$ q: v                ObjectNameInfo->Name.Buffer,2 j9 _$ @; C1 |8 O8 f( M1 C
                DevObj );# v" j8 y2 O" a6 E9 G% N
6 C1 A/ I' U7 D2 }7 B0 v! p
      //
/ I- A9 @) Z2 |  K      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示; `! x2 T8 d% b- a& a
      // 用,没有实际的功能用途
; O7 a+ F5 i( G      //# k1 |5 ?* v$ b" }3 @
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );4 g$ q, a: _! e

8 K9 {/ W. B; [0 m4 S0 ?% Y5 F  m) ?9 f      wcsncpy( szUsbDeviceName,0 U& v; \- {. x) ^/ s
               ObjectNameInfo->Name.Buffer,: ?7 W, ~) a+ O
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
, b0 |# [6 i/ h% R9 A; q% ~    }
; q1 L" v# o: C7 h$ l* C* N. y  F, t2 u
    //
5 ~7 P- L5 A. `4 a1 g% F    // 对于没有名称的设备,则打印 NULL
. P  q5 S0 w! T" T    //
8 Q0 N  M* B! r& |  W$ N    else if ( DevObj->DriverObject )
) f$ K6 D* s( ^6 y+ K: C/ B    {1 \. c2 L9 m, q/ [
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",; D9 H, u$ V; [4 g4 ~
                DevObj->DriverObject->DriverName.Buffer,
, I3 v/ B: r, a3 |7 G                L"NULL",
. ]6 ?/ w  U! ~- r3 K# ~- _/ I                DevObj->DriverObject,0 {1 Z5 c6 ]- W9 u* k1 W
                DevObj );
8 Z6 c4 u$ b3 t/ m    }( z0 }' o+ B/ c) \
  }
* W! r0 {( h" h. ~4 m( d4 G, w7 M}
- r1 F" [2 q+ Z; J8 ~! e& `# q. V7 n4 Q, E! Z9 r+ ^
/////////////////////////////////////////////////////////////////% e! o# s: O% `- h+ `' r5 c
// 函数类型 : 自定义工具函数
$ p) F" ~" Y5 c: U// 函数模块 : 键盘过滤模块
5 ^# n* M! U' G/ |1 S; m  J4 H) E/////////////////////////////////////////////////////////////////
* V- J  K: b6 Y- B, F. C  M9 j( }  S// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
( [4 W4 E% A% w$ ~* _2 O1 Q% T4 k7 N//        对象,过滤出 USB 键盘设备,将其设备对象返回
: `5 s5 E0 {, M2 D; Y// 注意 :
2 E: n' X" ^. E* `  d) z# T/////////////////////////////////////////////////////////////////
  V* N5 n; }+ w, {' Z8 G% V0 F// 作者 : sinister. h2 o0 o) K  w) A6 t5 j$ C; P
// 发布版本 : 1.00.00
" G" z  Z" c' ~/ A6 L0 V4 w// 发布日期 : 2007.02.13
; i# D, k. _" ]# N4 ?/////////////////////////////////////////////////////////////////0 ?2 ^. w* b4 p. t, m
// 重   大   修   改   历   史
5 K+ d0 T3 j+ V! d/////////////////////////////////////////////////////////////////, H3 a$ m" q/ B% t7 D2 V' {8 B
// 修改者 : $ N1 U$ w5 X+ n, U. d7 z* `- b, L% Q
// 修改日期 :
7 o( ~$ ?& {4 r9 b, F// 修改内容 :
0 s# Q, I+ `: e- l* W: K/////////////////////////////////////////////////////////////////
( O& ]1 K+ F, M5 K
1 f+ T6 t2 Y* {0 LNTSTATUS1 G7 o' \/ R" s( x& [. O: h. v
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
8 p0 |9 O) q8 ^0 N1 W6 t1 x! `3 i2 {# A" {: n{2 d5 v) s+ T1 k9 a, n8 O6 W1 C) j
  UNICODE_STRING DriverName;
9 {& [# z0 J$ R  ?  PDRIVER_OBJECT DriverObject = NULL;& k5 c$ U3 W# i  F9 c* O1 b
  PDEVICE_OBJECT DeviceObject = NULL;
2 z; l- Z( Q' E& f5 l  BOOLEAN bFound = FALSE;2 y& S4 V4 s2 L

) A0 h) }% K4 V, t3 t" n  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
1 B! i2 K$ l9 D6 X
1 {& Q4 |3 g4 S+ b" Y0 w, _  ObReferenceObjectByName( &DriverName,! Y3 p9 R# V" J" _/ s& e! Z
                           OBJ_CASE_INSENSITIVE,
" `9 k# m# Z4 p5 C/ g- `# e                           NULL,
' {! K5 U0 {! w* \) h7 l: r! C9 g                           0,
3 m: I4 V/ p. ~; E. O5 b: k" F! Z                           ( POBJECT_TYPE ) IoDriverObjectType,
0 Q2 ~6 l+ `' \) t' U8 ~  Y                           KernelMode,
! i+ |3 h& I* p( ^                           NULL,
0 H4 {" C3 y* @* l# ~* K                           &DriverObject );
1 h' k4 ?( J9 Q; j" b1 ^. W0 k: i4 @$ K6 {5 o, |: N* E
  if ( DriverObject == NULL )! x( S' T$ s* X, ]) P: {" l
  {" _9 c* ~( o) W5 P
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );* s# J' E' F! I
    return STATUS_UNSUCCESSFUL;
5 k5 o1 N% [- _, r: X  }, j) J1 K9 J9 L
. v" M0 J# ~+ v: {( G
  DeviceObject = DriverObject->DeviceObject;
- C/ Z( [9 l1 k" X! q8 J3 g
9 I! g7 Q; Z/ u' l. t  while ( DeviceObject )
% Z5 t# T) \) |; T& {0 R  {
- O& P- o. L: k( Q    GetDeviceObjectInfo( DeviceObject );
8 a4 v0 a, N8 ]1 n
- t: l$ x& Q0 {5 }) C% @    if ( DeviceObject->AttachedDevice ); ]+ W9 `# V' d
    {/ W8 N3 N9 S0 B6 T. e
      //  Y2 h& S% y( g( c4 K; M/ B! S
      // 查找 USB 键盘设备
( a, `$ T" L) a/ S# I: y3 x      //
6 [, x! w- U# X, S1 v      if ( GetAttachedDeviceInfo( DeviceObject ) )
3 }6 {+ [" H* X. e      {
8 [3 b0 m& ~) c5 u4 k" u, x        bFound = TRUE;. Q) U& g+ i; j2 F
        goto __End;. f4 D; k0 O* F/ N
      }
( P! V: N: N% |% K    }
. z. ^4 s: A/ d* ^7 X, H$ W7 m1 V* D; |. }5 g. [
    DeviceObject = DeviceObject->NextDevice;! K2 [+ F2 c. b
  }* f/ Q; ?# x9 S' K, ?7 Y
8 o* u  q  o" H* m
  __End:/ v" ?* U; s& s
' {; Q! l5 Z: w# p, n
  if ( bFound )& x, {' [& N% C$ ^  H9 g
  {
, Q$ C9 M% G5 [9 N3 Y    //! C4 g* Z- z+ X+ G4 v$ v: d3 \$ f
    // 找到则返回 USB 键盘设备对象- N. g( \1 u+ R) D. y
    //5 h$ R9 I5 N! N: h
    *UsbDeviceObject = DeviceObject;: t. J+ g8 l4 C% d& e
  }
4 }4 X# Q9 ?1 d  E3 C6 T  else. p! B8 w6 b. z  z
  {; K1 `( S. c; g$ M
    *UsbDeviceObject = NULL;
; y' n5 z) ~" p, r6 c  }, p) }/ M9 _* Q# b. t/ O+ _
+ {) W* G3 \, `$ H4 D
  return STATUS_SUCCESS;
3 v# Z6 L0 a' h}
  h- `# b8 H; d. t1 e
) T, v  P( ]$ q4 `& d5 k////////////////////////////////////////////////////////////////// ^& I, A2 Y# V8 `$ R* z3 u
// 函数类型 : 自定义工具函数( p# x1 e: O! H% w
// 函数模块 : 键盘过滤模块
# m" W( u: G0 x; P) F7 f////////////////////////////////////////////////////////////////
2 A" Q7 N1 {5 K# U+ p0 }) T$ ?// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
' s/ V  F$ k7 C0 y1 N# Y/ i9 t//        信息,返回附加后的驱动对象
8 @6 z" m, B: f" C% ~// 注意 : 此函数仅挂接 USB 键盘设备( ]( X% x5 @; {5 b; y7 @; O! @
/////////////////////////////////////////////////////////////////
% L9 Y+ W8 ]. t2 I; c& v6 N// 作者 : sinister4 k; U/ _, Z6 r+ D  U
// 发布版本 : 1.00.00
, m- f, I. ~$ l. j, d: r// 发布日期 : 2005.12.27
$ {) H* k! k4 }/ B% L- p+ a; A/////////////////////////////////////////////////////////////////& Q( C6 z5 Q: g# @
// 重   大   修   改   历   史
* _7 Q$ @  P5 c/ C9 P- ]% o////////////////////////////////////////////////////////////////  f) p2 B, o, ]/ ]2 a
// 修改者 :
- A) p/ J3 t, B. T0 e" ~* J% z// 修改日期 :" t# r( m2 n* R& e1 u
// 修改内容 :
7 h. q5 U0 G9 ~6 O9 ]+ s8 X9 o  s////////////////////////////////////////////////////////////////// S9 b7 ^4 Y( a! ]: x2 X  h
* \9 ~3 W, P- \' t% p1 m/ s0 Z
NTSTATUS
2 r  I5 ]- c! C! i! U* KAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,$ j+ N# n, M" y7 j6 h. n- w
                         IN PDRIVER_OBJECT  DriverObject )8 \% U2 P' W( g0 x0 _
{6 ?" _6 R9 {5 e
  PDEVICE_OBJECT DeviceObject;
, }! S' m7 y- }. @  PDEVICE_OBJECT TargetDevice;
  C9 h. z; r: S' w( J9 D  PDEVICE_EXTENSION DevExt;
3 c( M9 q" l+ U1 X) `, u0 p  NTSTATUS ntStatus;
/ |8 H" }* t  a7 W3 G1 ^* u! V
( S, T( H" T) I  L7 W3 e  //$ J6 p$ a1 h$ H4 `
  // 创建过滤设备对象
( S% Y4 a* H! d% Z9 q  //9 c6 F& H6 K% j4 Z  z) g
  ntStatus = IoCreateDevice( DriverObject,
- T- J. G2 [3 r& k2 ~' b# d                             sizeof( DEVICE_EXTENSION ),
' ]( e2 ]# I& a4 a+ ~; g                             NULL,
5 }9 j7 M, o0 d7 D+ U                             FILE_DEVICE_UNKNOWN,& r- g3 z& I% {3 z
                             0,
8 f3 W0 m: u: _* A7 r7 L                             FALSE,. q. d) W" h* e, G
                             &DeviceObject ); 3 L. U4 p/ r- }% y3 F) ^% k4 R, J7 Z

& U7 [  j$ L2 t# c4 m- O) S  if ( !NT_SUCCESS( ntStatus ) )! R2 }8 N0 e- C. N3 X
  {
0 F( c. i* q0 C/ P2 X3 ^    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
2 e6 @8 g# W  [# F    return ntStatus;
( L& _3 z0 C  v0 l2 P7 B  } 7 \& E9 U0 k& k& l( i4 S! P2 D

# [( y1 I4 |& b5 o% c4 |  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;4 J3 t! U' m: P' ]- m

8 w3 c/ K( g( t2 t* T  //
, _# `2 f7 P4 h  // 初始化自旋锁3 Y7 Z# v+ c( d( N+ @
  //, e1 ^- d0 c8 C0 s9 `3 V
  KeInitializeSpinLock( &DevExt->SpinLock );
0 k# _' K- P6 d0 ?$ S( f4 k$ l! Z5 R% y+ @1 Q5 F
  //% U/ G& ^! i9 p* c/ A& w
  // 初始化 IRP 计数器
  P9 q/ D& _. D# V& @" {0 d4 o  //
3 T( }/ G' A: G5 x6 u& o  DevExt->IrpsInProgress = 0;3 L) n7 c  e$ L. J* {  S# G* \  T
* g* \1 d/ |7 b# V7 e; v
  //( Y8 [. {1 h6 }1 w! i
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象# J% e9 P2 t  o8 U% e, N
  //% N* t$ A, A8 m" F6 ^) k: x1 n

- I" c# h5 P# k3 S# W: Q6 g  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); $ g+ f  H: K; t; t9 U  a+ ~
  if ( !TargetDevice )
' {1 {0 j$ K6 `) H7 O7 p5 g/ @0 `+ u9 l  {
$ p1 y0 u" }6 N  f. V    IoDeleteDevice( DeviceObject );
1 T2 s: |0 M7 M+ w    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );* F: l! {; _. M9 N8 R
    return STATUS_INSUFFICIENT_RESOURCES;
- ^! a9 N6 w3 Z( c, b  }
4 U% e7 N9 r% I; ?* c( S, k- g3 o# f. j9 b" B& g1 `
  //
; ]' V, l: l0 Q8 T1 z$ E7 o: a  // 保存过滤设备信息8 p) A( x7 s; L6 T# M
  //
8 g0 L$ o3 L$ \# d  DevExt->DeviceObject = DeviceObject;
' k% ^8 B9 N) {. S5 g% G0 ?- ^+ }  DevExt->TargetDevice = TargetDevice;8 @' q7 l, Q) {  `  s

+ R- d) c" p" o+ K* ]; u6 p. Q  //
! C* _* O6 {+ I! M" y  // 设置过滤设备相关信息与标志4 Z5 O! ^: _5 n
  //
# G( G+ i1 y% u# F6 d  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );& W& N/ c5 y. [; s! i# A
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
3 y9 e- Q# Z: [5 G
' x3 v; `! R* i. h2 |' P5 F. I; M& s3 _
  return STATUS_SUCCESS;* t; ~6 g$ z% H# n. a& e0 s# z
}
4 Q2 E5 ~; b6 R- Q  l5 @+ Q" \2 m5 M# G9 B7 b
/////////////////////////////////////////////////////////////////# F; J7 s  K3 t, y
// 函数类型 : 自定义工具函数$ O/ n6 _$ X, F6 m4 l! D
// 函数模块 : 键盘过滤模块+ x: ]) @: q4 D
////////////////////////////////////////////////////////////////
( M$ X; q' m4 y; g// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关& G3 y3 P% ?; r! E: r
//        信息,返回附加后的驱动对象* _  T+ d1 z- H: \8 l/ k
// 注意 : 此函数仅挂接 PS/2 键盘设备; ^8 ~' A1 O$ f; p2 }
/////////////////////////////////////////////////////////////////+ H! T! o! @& g$ J% o9 y& Q; l
// 作者 : sinister
+ i) M) w% N6 Z/ |/ C, W// 发布版本 : 1.00.00
: S! R  C! s1 a- ?// 发布日期 : 2005.12.27$ Q) y3 E3 r. q$ j
/////////////////////////////////////////////////////////////////0 \& G7 q7 w" b0 Q  _- R/ s
// 重   大   修   改   历   史: p9 X9 G" M' s# l7 l) K4 d
////////////////////////////////////////////////////////////////
) j6 `+ I9 r. c% I8 q// 修改者 :  z- {3 ^' |& m: {( ^8 g
// 修改日期 :0 C+ L4 U; b# N
// 修改内容 :' M* ^8 {: {9 e  ~' o. q) {) z
/////////////////////////////////////////////////////////////////
( N) U& f1 j1 ]. G- G# _" X2 g" k7 a& B) L- N1 Q3 ~
NTSTATUS
- v; I0 t* M- f5 D' q" \7 PAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
' S; T2 I2 m$ H6 n                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
+ R" R+ K2 U8 j) ?# b/ g                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
6 s% q' z( v3 @. x! f' H{8 N# J3 Z8 i% B5 Y; k8 ~' i( g
  PDEVICE_OBJECT DeviceObject; 9 P, i7 K: z7 L5 X4 _
  PDEVICE_OBJECT FilterDeviceObject;
# `& K9 n! ?1 V- m  PDEVICE_OBJECT TargetDevice; - W4 T+ T9 u% b! `4 |6 D2 B
  PFILE_OBJECT FileObject;
" v) U2 h; `( y* y/ D! g2 ^  PDEVICE_EXTENSION DevExt;, N3 k+ }, C6 e; C% h, @; c) H

+ O; i$ |  }+ H  NTSTATUS ntStatus; ! P$ G  G) Z7 G2 ?1 s
2 y1 P& u0 i- _
  //: p. h4 S! D1 n7 w
  // 根据设备名称找到需要附加的设备对象9 r6 S# L4 N" e' H" y
  //- |# @. H' K8 M- d, J7 L
  ntStatus = IoGetDeviceObjectPointer( DeviceName,  Q# A5 d0 U7 s: c* w( A+ s
                                       FILE_ALL_ACCESS,) U' [. u: m5 m( u) ]
                                       &FileObject,
  y. X9 N" @0 m3 d" o. b( m) w                                       &DeviceObject );
7 M7 p% p2 `$ d* L2 A7 g) x5 q( n2 d" o/ I( y! I( c" p5 w  X4 e
  if ( !NT_SUCCESS( ntStatus ) )4 r' ~0 U/ V  i3 u
  {
% M/ z: p! ], o) M2 C$ R    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
+ K8 l8 g4 d% N) c6 _. s6 Q8 @# s7 t    return ntStatus;
& W8 S6 `/ V( c( a  }
8 G/ o; I8 w6 b" l; i( |9 Z- O+ u) G% G! W  @# U
  //- f" k; ~/ a8 T4 R5 o; o, `0 I$ z
  // 创建过滤设备对象
" q2 U2 V+ M! C* @8 S  //' e5 a0 d5 s4 i: q
  ntStatus = IoCreateDevice( DriverObject,
! c' R8 P! g' K6 N& d9 G                             sizeof( DEVICE_EXTENSION ),4 S9 Y  n) u$ L! O$ \( N/ G
                             NULL,& `- q7 I  m8 p+ _+ r. r$ R
                             FILE_DEVICE_KEYBOARD,
" ], j- ~& Y$ m: L7 q                             0,. H- U  n. [% J3 X) \# m
                             FALSE,
" Z5 k) F9 F8 m) u6 X9 q! J0 m& c4 j5 M                             &FilterDeviceObject ); 1 }9 i' W" x4 m1 |, i

: |2 v3 a6 [# b3 b+ L/ N  if ( !NT_SUCCESS( ntStatus ) )# n& x4 o! x# L' r5 Y
  {
7 L! L: h# b/ v. l$ c8 [9 Y/ @1 p    ObDereferenceObject( FileObject );
' e. l  w% e6 N7 a; I8 a    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );2 E8 Z( r3 @4 [9 l
    return ntStatus;! m- H* ?" Q! G) X
  }
3 j' ^: T' ?; H. L* z2 v$ v& Y  W+ m7 w% b- m' |9 n! ~
  //
; j( H+ n+ v7 X& F  // 得到设备扩展结构,以便下面保存过滤设备信息+ q* A4 T# m0 l  C* `4 D
  //
% ^  C. j. w" v  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
4 X* o# C( v. }! L6 Z; X; l! a
' ~% T& ^1 p- p) Y: V* p
8 o1 G+ W" K& |7 g7 g  //
; j! f9 q3 i& O4 I+ I  // 初始化自旋锁8 ~) I- [  [6 ^; ~
  //: k+ G$ y# K3 l
  KeInitializeSpinLock( &DevExt->SpinLock );
2 `# @5 ~# P6 S' H) ?
6 k: J5 T' ?9 V4 A  //8 Q# y! z/ g8 j' J: z& r3 S
  // 初始化 IRP 计数器
+ h# M. H5 M1 U# j# b  //4 d  }$ {- ?' G( e$ l
  DevExt->IrpsInProgress = 0;& s& t* c$ R* L
+ y+ j2 B( T; j$ Y4 n: f
  //1 p& Z) l% A# h. c
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
- ]$ m# `! Q0 q. |+ Y5 ]: v  //: Q0 p2 ^9 a+ E% x* B  q2 D
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,# m# t* [6 {1 e1 B9 n/ S: p
                                              DeviceObject );
0 I1 \7 I5 |  e1 ^  if ( !TargetDevice )) i7 ]/ I! z5 W+ `& {: P% K
  {
' _+ J+ {) F0 h2 D3 a    ObDereferenceObject( FileObject );
1 [6 C5 U: |+ C* u/ x8 S    IoDeleteDevice( FilterDeviceObject );
& o. h' w' x2 w% t/ f    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );' }  [! i: p4 M9 k7 Q% p
    return STATUS_INSUFFICIENT_RESOURCES;
8 P& B' Z2 \. G# u5 O  q  } 5 k) r9 ?+ V! ]6 s3 N2 a6 c; g
- R5 N4 n, J5 j: g* |: c7 d! w
  //
; H' U  t9 L4 |2 j* k- ^  // 保存过滤设备信息
2 @! f3 \5 K. i4 T3 I6 H9 u  //
6 D9 e8 h; d( Z1 l$ Q  DevExt->DeviceObject = FilterDeviceObject; ( Z/ p2 g! E! J1 D6 f3 N  B- x5 v
  DevExt->TargetDevice = TargetDevice; ) ?8 s2 y7 [' S! F! I# e; C1 k- q: i
  DevExt->pFilterFileObject = FileObject;
5 X7 I& |: x1 ~* p4 N+ y; c" ]7 S. B1 ^/ z0 P( W
  //1 O: K# \5 v( X5 W" _3 P2 U3 `
  // 设置过滤设备相关信息与标志, b" Z) {) f, \) v) C
  //2 W9 z: J. e# p. `% M: w
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; / j5 ]* M3 O: N9 A  ~
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 7 ]# w7 P% t8 b0 u% m) z1 {
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;" ^1 F; L( x7 _
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |2 `. O& Z0 n; \" Q6 g  c
                                                         DO_BUFFERED_IO ) );   M( z) R8 e9 w) N) ]8 r6 |" F

. c4 I/ e/ R3 e  o) ~) f( L  //" m, c8 I  u4 o& ~# i
  // 返回附加后的驱动对象
' h4 q0 I  u: [" X  //
: r! _( k$ Z  S( W' b5 v  *FilterDriverObject = TargetDevice->DriverObject;
8 B% g. @) f9 A+ K3 A+ v! b7 Z5 g- Z7 ]& M" ~2 P$ l
  ObDereferenceObject( FileObject );
3 b) [  f# P! _! R
& f+ k; f. ^8 Y; T+ l6 S  ^  return STATUS_SUCCESS;
. T; x8 `2 N* V}
: }9 r( H( d! e: {& \- A
6 o0 ]/ m' Q. d8 h) q/////////////////////////////////////////////////////////////////
9 {# }8 w( p/ j, [, }- B// 函数类型 : 自定义工具函数" |  _2 b, X1 Q& B2 n! s
// 函数模块 : 键盘过滤模块
3 M& X% w# l# {; l8 t, `, I& I////////////////////////////////////////////////////////////////
& _/ q9 e, O" _& k! Y// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
) G% F8 w8 }! [5 c6 T//        这个 IRP 的完成
8 G! w- K' r* ~// 注意 : . X( ~2 S& {! V3 w* I4 Z
/////////////////////////////////////////////////////////////////
7 C: |! i/ w  S2 M4 F2 i// 作者 : sinister
' ~. G- [) P) Y& c4 ]- ~# E// 发布版本 : 1.00.00* \9 z. \) y0 q
// 发布日期 : 2007.2.15/ T! n  f5 w% V; b
////////////////////////////////////////////////////////////////// E3 I: T+ J2 n; E! ]1 N
// 重   大   修   改   历   史1 g+ D. \4 {$ d5 z
////////////////////////////////////////////////////////////////
0 c" `( m( Q% V// 修改者 :
9 f3 C& x; Q! B* v9 B// 修改日期 :
+ o% l0 u/ q# W& `/ {( B+ _6 g// 修改内容 :
2 J9 J: W7 B) y/ ~4 d& Z/////////////////////////////////////////////////////////////////
+ Z4 C2 U: L4 N; ]4 u* N) X& Z4 b4 N4 G# {1 o1 l& n. M
NTSTATUS  _$ G# E0 c' E" U; J
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )% N" I" n0 ^0 ^+ Y
{6 N5 H+ D* `# O2 y4 \) p: \7 o
  NTSTATUS status;
1 n# E. N3 J. e  KIRQL IrqLevel;
# u. X5 w# d/ |2 ]
6 l* P" G9 W6 ~: L! N% G* I  PDEVICE_OBJECT pDeviceObject;6 L. m& Q" I+ K0 s5 D8 L
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )/ l- E" L; f, D5 N7 w" l6 `& G9 U
                                   DeviceObject->DeviceExtension; 9 W3 k; ?! w: x1 T# z+ U" ]1 ^

- R- {& o# K8 N! ?! ~: c" k' \! w, Q/ F- [8 v/ K* x
  IoCopyCurrentIrpStackLocationToNext( Irp );4 Q' t5 k+ k8 E

, ?+ s1 X# `1 `3 w2 q2 w3 y  //
# i# T8 t. R; a3 v  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁; j6 q" Z7 l# o! V: u$ E
  //
% j# I) `: n' ]  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
; U/ _, G1 y$ y6 `' V' h  InterlockedIncrement( &KeyExtension->IrpsInProgress );5 z* [' ?& K* m4 H+ Y: M7 F- |
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
  o8 t8 X2 \  |! Y
/ V6 s  g8 k4 `  IoSetCompletionRoutine( Irp,( |) U& p- B9 M8 h; [. R/ ~
                          KeyReadCompletion,2 Y6 L+ e9 Q6 y, R" Q
                          DeviceObject,
! _6 F1 L, n. U& j- ]# w                          TRUE,- h  d% I  j$ Q4 @6 F; F$ ?
                          TRUE,
8 w) z+ W4 U" N6 k$ A: C* J                          TRUE );
+ E( C& \% b- U' V" g! _
* X- C* i& G7 J. u) l* q% c  return IoCallDriver( KeyExtension->TargetDevice, Irp );- u0 Y5 D9 Y2 g5 [- B+ t
}
7 E  M. U2 m$ W: L8 L5 S# q; q$ Y4 V  U( S9 Z
/////////////////////////////////////////////////////////////////6 K. k9 k2 i% Z0 Q/ G
// 函数类型 :系统回调函数
9 H4 `' f& A9 q0 }) ]% A6 h3 |// 函数模块 : 键盘过滤模块
- D3 f; W4 I( K$ {9 e! m1 f////////////////////////////////////////////////////////////////
) F: P6 n" B/ s% }9 ]$ M/ o// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的' g9 p1 Q% ^; X2 r
// 注意 :
4 x# O. S4 J3 A+ y1 t8 e/////////////////////////////////////////////////////////////////
. g8 p1 ~' \+ y5 @5 b! L- J( k// 作者 : sinister2 e6 Y) \0 y: |, @! d
// 发布版本 : 1.00.00
% k/ O. {) N1 C; [% x+ @, j2 E// 发布日期 : 2007.2.12# S* `: A( i) N+ s. S9 u
/////////////////////////////////////////////////////////////////' h, u1 m9 `" M1 E! `
// 重   大   修   改   历   史
, t3 U, `- V: o& ~; R7 @2 ]////////////////////////////////////////////////////////////////
4 n- N$ \% g6 e// 修改者 :( A6 z  Y5 ?$ n2 ^+ n8 T3 F
// 修改日期 :0 B) u% Y* E( C0 T" w, x7 ?
// 修改内容 :
5 X, Q* f! o! T$ T- m/////////////////////////////////////////////////////////////////9 M' Y+ q6 m5 L( f
* z% e. v2 J0 o, t3 }& G
NTSTATUS2 ^, w1 F0 l" E0 W/ r
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
% X) V/ p) @2 w4 `8 I1 n                   IN PIRP Irp,$ x1 b+ d3 S- F; _) O" H
                   IN PVOID Context )
% w1 p8 `3 {" |: u- r' `- _{
4 p" ~  o7 S4 z$ |: l  PIO_STACK_LOCATION IrpSp;
, H* @' O- ?' x: m+ M6 i  PKEYBOARD_INPUT_DATA KeyData;9 p, [! [# u! o2 U
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )5 X* S( G! B% g1 ]) z2 J3 M
                                   DeviceObject->DeviceExtension; - h# X8 s+ ~6 }) d
  int numKeys, i;& r2 n( n2 C& i& @, X) A2 O
  KIRQL IrqLevel;
' v: ~# w/ {5 A3 d& X% v, w5 U
/ t- N- t( f9 j2 s  IrpSp = IoGetCurrentIrpStackLocation( Irp );/ j/ r+ ^' Q2 ]- f0 B1 Q0 k

/ L7 A6 N) ~- F, \5 \& q+ }# V1 x3 ]6 [* e; m
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
: P# I: q4 }% X( T9 o0 d  {
) |! n2 I) V" S7 y    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
, V% Q+ @7 Z. \. E    goto __RoutineEnd;
; D4 j  H( i" j7 Z) x  }
$ U6 @: Z* r. A6 \$ W/ O' D
' M  M# I! s* i! ]  //7 R3 H- g. S' a8 L  T
  // 系统在 SystemBuffer 中保存按键信息& v0 y2 r- n: m+ `9 m$ Q
  //- e5 o" a; o; @. l" n- G/ v6 R! W
  KeyData = Irp->AssociatedIrp.SystemBuffer;! w+ D3 Q& L1 m& E4 P( x
  if ( KeyData == NULL )
$ t4 O5 {# [3 R* y  {+ }! N" W5 G  R( I% g. x
    DbgPrint( "KeyData is NULL\n" );: w2 ]. t& I; h  m
    goto __RoutineEnd;
" t6 {! G2 C+ b  }
2 ?7 n4 J9 S* ]) ~
3 ~) b, B, p  m0 L6 X  //! A9 W0 G* a4 Z7 x: E$ r
  // 得到按键数
$ t9 \; Z# h) C8 h# n2 c  //
, Z" B4 K* |  L9 A. K( {: [  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
. R3 o! b" P0 R  if ( numKeys < 0 ). Q  ~2 [# c' F$ t# I. G1 @
  {4 k% M! Z0 H2 P; q: ?, H) G: t
    DbgPrint( "numKeys less zero\n" );6 ~2 \: u0 G, q6 j6 H$ ]+ h
    goto __RoutineEnd;
2 p9 d# i- U( r0 y5 L. V  }6 [8 B% \+ m9 q, g

/ U+ z$ L5 L1 G% _  O' H; _  y  //0 e! J/ c. N, s" _' C
  // 使用 0 无效扫描码替换,屏蔽所有按键6 X+ Q  m- _! @3 f: F/ P
  //
. _; e' _2 G) @( M/ X2 S3 V  for ( i = 0; i < numKeys; i++ )6 z  e# b! y7 u6 g3 ~
  {
- z0 R& h. |% R/ \7 q5 Y( H    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );3 @% b9 }8 |1 T' X; L7 k1 |& }. ?
    KeyData[i].MakeCode = 0x00;
5 m$ v  K5 ~/ I7 @  }/ M( F$ V. ]" J$ v+ t# G+ a; N
* E7 ~8 L7 s: O( m/ k: N

" j, V. W( ^" `  __RoutineEnd :
; s( V" \9 j; m2 S, J, `4 E. H$ y+ t
  if ( Irp->PendingReturned )1 G  R( l+ T5 X
  {
6 ^# z4 {' f! q5 X    IoMarkIrpPending( Irp );
: Q' t; l/ C; Z. d  }
) l2 H4 f' h7 {% H' v. A6 M& Y' Y) E5 |1 I; I
  //
3 @, e- M& m, Y. g8 p- D1 l4 {& w7 X  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁; R' R; U1 A0 @. a
  //2 M; A6 [3 p! [2 ~. N
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
9 h9 K3 B# _9 q/ P: o7 }- T  InterlockedDecrement( &KeyExtension->IrpsInProgress );1 z; X4 {- r; O, \7 W
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );& l4 _) E% u  w. F) F$ v2 Y
5 ?* \5 Q+ I) k5 M, j
  return Irp->IoStatus.Status ;
# X) @2 p" \7 E; x) B/ Z5 S}
& P( R5 b9 k& l. M" P( G
& S" u) B$ s5 j/ G/ L) `* a& V* I+ z' G8 M2 j" T: ]
/*****************************************************************
* @# h/ M, i7 G$ E, X4 q+ I+ o 文件名        : WssLockKey.h
+ L/ o6 {. {% ?3 H& h! [ 描述          : 键盘过滤驱动
  Q5 b; X2 j+ ]% [/ ~$ }8 @: M* E! I 作者          : sinister) \& x7 E3 t3 c7 }3 {8 O
最后修改日期  : 2007-02-266 y; W2 F; W! r2 j; B1 R
*****************************************************************/
6 [# U; K& z  v, L* @1 v+ e
6 ?2 w- e+ T, G6 C  K' {  a#ifndef __WSS_LOCKKEY_H_
) J6 }# F5 L1 I. u9 P' Z% s% x( z5 z#define __WSS_LOCKKEY_H_9 f2 l) a) v& e9 H

- d* y$ I0 p2 l#include "ntddk.h"
, W  ^6 o5 F7 C* ~#include "ntddkbd.h"
8 Y  O: k) }$ N# H9 P( I#include "string.h": m, K& Y* e5 A
#include - q% }8 |% W0 Z; j2 ]! E5 Q, r9 O
9 _2 E& h/ r0 X" m$ \. B
#define MAXLEN 2567 Z; ?1 m1 D2 R( @0 Q( T: F
2 ]: i7 ?1 a0 ]* P# I( v2 f
#define KDBDEVICENAME L"\\Driver\\kbdhid"% g9 ~  [3 j& v1 O" n; D" k6 q
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
6 s3 z0 i6 R# N! f* h#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"' e, ~4 u/ X( {, C, c2 S# f- a. ~
, [+ g9 H8 `/ o: S
typedef struct _OBJECT_CREATE_INFORMATION5 H5 o) N6 \% x: {  Y
{0 ^! V4 x* G5 v. q
    ULONG Attributes;& w# c5 o% X+ s  n/ N3 f7 E* Z
    HANDLE RootDirectory;$ [3 ?: `* s5 R3 I* n
    PVOID ParseContext;  c$ F+ T0 {6 Z+ S0 y
    KPROCESSOR_MODE ProbeMode;
- E2 U  r; x6 Q' w    ULONG PagedPoolCharge;* s5 S; p8 `$ ~# S  r* H
    ULONG NonPagedPoolCharge;
) I- R- C+ W2 n; p4 E4 R* j/ z' v/ o    ULONG SecurityDescriptorCharge;( b  ~3 h0 S. K& X. T) @
    PSECURITY_DESCRIPTOR SecurityDescriptor;* X' h6 c+ \* l& r2 h/ x
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
/ t* d' J6 w3 q, Y    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
9 n$ J# n4 w) w0 ~0 t, k$ v} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;* Q& a9 Y& q  N# n% S* n+ e! }/ R2 t

8 V6 U- P: @! Wtypedef struct _OBJECT_HEADER
! I' \8 o$ d- x9 Q6 u{
% l2 i- `4 B  U6 I    LONG PointerCount;. l4 ~, b9 w2 T9 f: q- I6 A
    union& {% M1 ]0 [* t' i( h
    {
7 p) v- S6 p7 V4 M9 D        LONG HandleCount;
+ B0 Q. b' Y9 C  x" w6 r3 ~! K# G/ ?        PSINGLE_LIST_ENTRY SEntry;; N4 W/ c# @/ }8 ?9 K. _6 t
    };2 v+ y- m' Q' ]1 _% f, R. T) C
    POBJECT_TYPE Type;% t; [, [, @8 V) |/ f3 l
    UCHAR NameInfoOffset;
7 ]# K" t- _8 F6 k    UCHAR HandleInfoOffset;
' c4 S; V! ~* z/ {4 ]# A    UCHAR QuotaInfoOffset;# s( k$ I# l& M" g
    UCHAR Flags;
2 _  j( v  {0 A7 J    union+ ^+ y2 T  I9 z  X- c0 k; G5 Z% X
    {) x5 N1 F* I  {* B
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
# U5 {9 }2 l) R: z        PVOID QuotaBlockCharged;9 l; D1 H: i5 W& W. P' ~, f
    };3 `9 ^) u& P' j6 i. ]) U
) n" K: x( E* `, _* W+ O
    PSECURITY_DESCRIPTOR SecurityDescriptor;* p/ Z( Q* l4 R+ t1 X
    QUAD Body;& O" f1 F; v" Y! z  k! Z
} OBJECT_HEADER, * POBJECT_HEADER;9 w( @% W) g9 A) b& U$ L; f! U
' V' h& ]: x" t% ~+ `+ o; Q+ t( ]
#define NUMBER_HASH_BUCKETS 37
$ Z6 s8 Q5 `# I
$ O8 o: }+ T, K" e2 X4 o$ D2 Ptypedef struct _OBJECT_DIRECTORY+ c! V- y3 ^/ L" m1 B# }
{
4 ?( ~2 ~4 }7 z5 m- v/ ]5 n7 I' @    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];' B: _, D1 M$ P9 R; x
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
3 M9 t& A) f. D3 t/ a" b    BOOLEAN LookupFound;
  s: D" D- p/ i& P' q( j    USHORT SymbolicLinkUsageCount;1 n+ P) ]# g. o# H0 p$ `9 b
    struct _DEVICE_MAP* DeviceMap;
3 ]% ~8 r% }$ B, K8 s0 D} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
* B1 X$ U) j( ^2 d8 p+ m: v4 y5 s$ l7 d) a% I3 i( M1 N. y& G
typedef struct _OBJECT_HEADER_NAME_INFO" B" N$ d$ r8 w6 x7 h
{, ^, h8 z8 W* g5 {/ m0 w( T
    POBJECT_DIRECTORY Directory;, Y1 F8 ]' W, M& x4 Y7 d! i5 {
    UNICODE_STRING Name;. x: }! D1 h+ A9 Q9 F' _8 {
    ULONG Reserved;% X6 R: ~9 L5 {) t: T) H% b
#if DBG
! u. a9 Q" _  Y! Y3 G6 l    ULONG Reserved2 ;
- g* r5 e( a4 k9 v9 C    LONG DbgDereferenceCount ;0 d4 S* F9 M; e& q3 R7 u9 U
#endif
: Z: T9 z4 N8 I} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;' u/ p) u% x1 A  Q: |" D/ |  [

. Y1 q& C" X9 k6 v' X#define OBJECT_TO_OBJECT_HEADER( o ) \
4 q7 K5 U/ I" }  b4 C  l    CONTAINING_RECORD( (o), OBJECT_HEADER, Body ); _+ Y0 k" }# U/ T6 z  O  \4 V3 d
0 n0 E7 `$ x- _- ~' k" s
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
4 {" g6 v7 b2 l" Y* c) A    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))0 N4 Q, J7 a1 `4 w
; p/ ]' r. f2 F  @7 ?8 N# p
typedef struct _DEVICE_EXTENSION$ t  o4 P2 c0 l. J" A
{
# X% W! f" O( x4 l2 ?    PDEVICE_OBJECT DeviceObject;
& D( r/ C0 V: x; n1 e) |    PDEVICE_OBJECT TargetDevice;+ P9 [" F+ Z" z" I" K
    PFILE_OBJECT pFilterFileObject;
3 T! k) ]. t& P1 `2 k) D9 [" }& c    ULONG DeviceExtensionFlags;5 e7 `8 q+ t, l
    LONG IrpsInProgress;+ ~" Y& G: F  i
    KSPIN_LOCK SpinLock;
6 \3 l5 k: Z, |2 Y}DEVICE_EXTENSION, * PDEVICE_EXTENSION;# ?0 {% W+ ^) p  g7 t0 ^

, Y+ l2 V5 p" [7 b) ~: W3 x) i( ]/ y  X' _
VOID
0 }4 j7 w! z7 t3 UKeyDriverUnload( PDRIVER_OBJECT KeyDriver );
3 `. |4 {5 S+ _
) r, \6 n$ ?# b8 N' T; g+ y- QBOOLEAN# J0 l* O# [, A
CancelKeyboardIrp( IN PIRP Irp );9 y0 \0 Y. \2 z$ h

+ R+ C. N+ M( v' Oextern POBJECT_TYPE* IoDriverObjectType;$ y1 Z/ G5 ?2 Q

8 m8 O! h  V6 y  a. F- ~1 Z$ tNTSYSAPI1 L9 B! H/ L$ d- g, X: O
NTSTATUS2 @! N/ s" E' B! s0 K' {( J
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,3 U0 i- E# F* j6 z8 e5 r
                               IN ULONG Attributes,: `: X) O! K! O1 i
                               IN PACCESS_STATE AccessState OPTIONAL,
2 \+ G$ R0 z8 a" M1 A  A7 P                               IN ACCESS_MASK DesiredAccess OPTIONAL,
( ^# F& O3 r$ w  E! \4 }" T                               IN POBJECT_TYPE ObjectType,- Y2 d0 v& @. g' E# H5 f* c
                               IN KPROCESSOR_MODE AccessMode,
8 H4 V- j7 ~7 C7 _                               IN OUT PVOID ParseContext OPTIONAL,
* N( G# d6 q, j                               OUT PVOID* Object );
* F3 O6 P; _6 |# {7 O; h3 I& R$ c. T2 u: I
NTSTATUS
+ B: w* h- B0 H0 K1 B/ [GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );! I" f3 V% J, N; _
/ j& k0 S5 Q- g; W7 c
BOOLEAN ; c# L8 w% E3 Z+ l% ^0 p# C
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );3 z2 k- @9 ~3 i+ n3 g& q1 \' Z) K0 L# S

/ H/ m% ^: i; ]8 ZVOID
: Y' K- @) T1 U7 ~! NGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );7 H) C0 X+ S+ n. ]' [1 P, [+ ?
" d  m# b5 m+ F
NTSTATUS ) h7 h/ m3 u/ j# _1 x  Y+ Y- Q
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,: r- O8 i# [9 l0 u/ }
                                  IN PDRIVER_OBJECT  DriverObject );/ F) x: z) ?: I9 V) ~+ j+ ?

$ h8 ~1 E# \$ U6 yNTSTATUS
  r% ]+ ?( f( `4 b+ d; wAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
- n, P) R0 ~% X4 i: k3 I                                  IN PDRIVER_OBJECT  DriverObject,
$ H' l: ^) ^% a1 v' ?! E1 U                                  OUT PDRIVER_OBJECT* FilterDriverObject );5 \" ^% h* E4 D! F

/ q  Z% z" H+ T$ b' i, ?7 JNTSTATUS
( _; `5 Y  |0 b4 e( w( @KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
/ k6 H# R! J, l/ H8 _                            IN PIRP Irp,- W4 C3 @9 J2 a) z" P
                            IN PVOID Context );, Z* E5 x/ E; {! x
NTSTATUS ( L1 r: V3 T! A% M2 Y& e# P
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
( y# \* o4 l7 h* A: N8 W1 H2 c+ z! a1 e& r  n! J( s
WCHAR szUsbDeviceName[MAXLEN];3 H) B' Q, U' Q* z* H6 f* L, ^; B" z
: q' g2 H/ u7 s! a0 Q1 `
#endif- L, x( E& G0 S) v

, p  Y/ m& z$ h9 a; Z# J/ v+ h! A
- ?" h/ J- ?. U- l
3 g+ \5 s: [, j6 F/ ^- C; Y& [+ Q
3 S- r+ n; X4 v4 Y3 H+ }
' i; o. h& i; u& w" R/ e+ E6 D8 v1 s- KWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
, i; F9 G4 F$ F  R+ hWSS 主页:[url]http://www.whitecell.org/[/url]
  h- c, B# S# Y0 n$ M9 q( nWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-5-16 06:51 , Processed in 0.041893 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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