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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
7 k2 z8 u* D' J; P2 hEmail:   [email]sinister@whitecell.org[/email]7 U& a$ u% R5 w( ]! H; p
Homepage:[url]http://www.whitecell.org[/url]
* |8 G% F7 _3 u3 E; B' n8 gDate:    2007-02-26
% A2 _. c; M3 ^1 T* i
, U8 q+ z. W$ {6 f
% F4 T2 u7 Q  v# n$ v( u" \7 [0 O/*******************************************************************
9 z  B, I  y. K! y! }, c$ q# U' f8 c5 Q3 O9 V* v
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
8 ^& K. p- ]4 L3 d8 Z) u写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的5 \8 q/ E' C8 T6 @* \
功能要求如下:
, j4 F8 f' }* H8 b- g; f2 U6 B6 E9 {2 t7 A4 c" y
1、强制锁定键盘/鼠标。* q" g+ v& n8 x/ p, I4 ]# v  s) K( ?
2、可动态加/解锁
; W/ p4 C2 R' J3、兼容所有 NT 系列的操作系统。( N$ P. e9 `/ f5 Z4 }/ s) \

' ]) T* Q! T! T0 @就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
, e, I, E1 j! ^现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如& q6 p( l! H$ X$ H+ }4 {1 @
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在+ J6 T+ W( }, l1 y  y$ J3 Z& ^" j: m
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是2 x2 l' R3 R" J& N
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
7 C+ {- ]6 H, @9 U+ d. ~就来看一下我想到的几种实现方法:
! l9 v2 L) c7 T3 {' W! k1 d  ]& F& ^1 V$ Q2 X+ y/ {
1、全局键盘/鼠标钩子  q) l; E. Z4 D0 r$ S/ Y, K6 W; m7 m
2、BlockInput() API8 w2 Y1 A2 d4 u' m' N* P
3、使用 setupapi 进行控制  P( `: O/ q" z% m$ y5 z
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
7 ]* q, O& [1 T4 q7 j( {5、拦截 win23k!RawInputThread() 函数
; _7 ^: `8 o- Y1 Y, O4 T6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
; r1 G) N: c# a" V; L7、拦截 kdbclass 驱动的 driver dispatch routine
% m0 p1 @0 H' c: L! p; n8、实现一个 PS/2 与 USB 键盘过滤驱动2 b" }+ [) ?. W7 w2 _
' [& j  g" L$ Q% m0 h9 [
5 M! |  \& T7 t$ @& c' V
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑. I2 M5 p2 N: f0 J' h# J3 U
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
# j! u  L9 q; p  U+ R案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在0 z' W$ Q9 l) _3 x1 v  {
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因8 ?9 \* U8 o# w' J
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
6 Q4 [: S3 a* e2 d1 d* c问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸6 J: y  t; ~: _9 x% A  N
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
  s4 Y; ?& c! N% s* I  C的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来8 ~8 k. v( F, V" _+ s
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
; g; x9 z5 n8 d. }果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
& ]! \* d2 H3 f: G/ C- [  c0 p障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
) I  m& r5 E  y# F5 i" S( z0 [) qIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
2 d5 t6 L# p) \1 n+ B  dUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
2 o' |2 l% c+ L4 D4 O9 q  _  [盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
6 {, ~6 `0 }1 t; l/ d3 B案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
5 C4 h, \. Y$ l. I/ ~: G2 o% @6 d& b1 H8 I& c) n, G( t0 `" T
$ h8 s  ~8 `5 M6 S% e" A
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过7 }$ l) d3 H4 I  ~
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
* u8 }' y" g; C- t行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是& U+ @; n( K. Y$ ]; n
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
' Y' z7 ]$ W! m4 D* ~. m; B/ q来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
5 `1 @9 h- V( r/ a" i) BKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
: ]" q/ g- [* ]8 e3 y% b键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用; H& U$ P* o" f7 o
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,! p3 _, s8 Q2 Z/ r" l
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
/ ]" n2 ^; P& ], F+ }就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
2 I$ g# J' N$ N而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
, R% q: x* m: c% Y用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
  w% z1 ~  V' w- V9 T过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来, R" D1 O" @, x' ^2 R) B
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通  O) N7 X. z" r1 q
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
; d! o+ N7 q3 Y4 H  n& Z上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 5 p4 l7 L. h8 O' h
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意8 m3 t/ D+ E! V
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。9 K- g; \" {4 M5 C* {4 q
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
0 s. y2 ?; P, l% d8 a4 `! j% R来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
) K( J$ P5 P4 {# c的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
7 x( Q, A9 T$ a' X: _的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致& u, y& y; O8 t# _' z" e" y
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
$ w' ^& z$ }+ C& {根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程! T7 Z3 F/ b5 T" M, Y
见下面代码。' ?! A" x7 f( W$ o" A9 W0 n( i

, S' f& I. W2 s2 y$ U# }2 @这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
# t0 m( B- b0 v4 i; N/ h7 s里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
# o* b) m  e) m% g盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20036 X, E1 P& Y$ A% K* V" k1 }$ {
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有. E4 ~  V; m1 l% p
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
" u" ]" i2 n1 ^9 t1 g0 I5 N继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
# a4 _. t- ]" F锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按6 a! _: j" O+ N- |" m5 j7 k7 J: U  S
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
0 ]7 [4 V* A4 q. ?
3 J" f6 C* _. i3 a$ I5 b- j' b% R6 e# O# O0 n% |3 g
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
: r% C5 s) b- W) K+ e的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是% J: T% x3 ?7 p3 C( c
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
4 S1 c& [+ t. i( ^的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
* Z: @( y1 B! j6 i们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
# |4 ]" j- \5 l! Y, T- Y们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
" N1 H8 A5 U8 H/ n9 @9 B. L4 }->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
" Z0 q& \/ S! @1 M+ H8 N如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager# z% \9 A, m' l+ F4 O
进行操作了。这个问题有待大家来完善了。
# N$ s  g/ ?5 [& ^8 U
. Z5 h* _' J, R+ u
1 X; s/ k- b' C7 y% m, p要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
# h4 E8 G" W! b% d- r1 H( _4 Y来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的  H" m) B% w- i6 i: _
分析做个记录而已。我更愿意把它看做是一段注释。
( s& ]$ ^" H% ?6 y% w2 Q5 }( @  U0 u6 `% d
最后在此代码中要9 ?- Z8 D) W% X5 ^( C! a4 {, W
. h7 o: j3 P% Z0 e( u4 e: H: W% k+ E
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。4 T/ i, M0 i8 Y4 M, r2 r% e& T

2 g( r  u% e7 K& l' X. p0 W) h感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
- U1 x& p7 s5 \' I5 D
- \  ]6 |2 p7 k/ j0 R) o8 l感谢:齐佳佳,过节请我吃好吃的。
; _2 {8 j* V7 n/ }/ ^+ o5 u8 z
/ p% u& p8 [& M( t  w% f' u
# b) @" t# t1 U! F3 X******************************************************************/
2 B+ u. A. B8 k8 [% M, Q6 W# T* D; h% N3 r3 W. C. u  Y4 a

# |" f0 D1 T, P$ V7 P$ }9 E% d/ G+ r/*****************************************************************" ^& Z0 c2 g# o' [$ g0 ^/ b2 N7 Q
文件名        : WssLockKey.c* j: {) @& J- s3 q5 y: |
描述          : 键盘过滤驱动
( s5 g" Y' c' L 作者          : sinister
: }! O$ C# a  ?  ^6 ^ 最后修改日期  : 2007-02-26
* `! Z; F4 e# Q# M8 Y* B*****************************************************************/
4 a/ d1 T/ G! K, @& f  |6 G7 `3 ^, g( L, U9 C
3 s' S: A) U- u9 a, E0 W" w: w3 o
#include "WssLockKey.h"3 @; J0 u5 o* N
0 I6 S8 ]) a3 F$ S
NTSTATUS3 @3 I0 q+ V: r$ z; B( S1 S
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,) A% Q  L+ @- J/ G- y
             IN PUNICODE_STRING RegistryPath )
3 f3 e& m0 }1 {{
4 p3 H. b. Q4 W" g: S% S  UNICODE_STRING KeyDeviceName; + x, N9 F" Z3 z2 `& U2 N
  PDRIVER_OBJECT KeyDriver; ' h2 B# M* O3 ?5 b
  PDEVICE_OBJECT UsbDeviceObject;4 P" w) N# D/ C' c1 c
  NTSTATUS ntStatus;
4 E5 P7 e" ?& d4 u5 Q1 w' o# V  ULONG i; * p, D* |- c/ C2 V* \

- [% c9 s5 G* _0 p+ I, M1 [  //
4 X  L0 S6 |* [4 Y/ `8 C! ~  // 保存设备名,调试使用
2 [/ b; f9 V( b, V  //
/ }& B& b- p5 x' N( Y7 B4 q  WCHAR szDeviceName[MAXLEN + MAXLEN] =
+ c! N" `; M2 g2 O" b; ^* i. S  {
. ~4 a: w( _8 t, x* ?    0
+ ^) F* V: ?% @6 W2 L  };
! W' s+ R1 I" s; h7 X" F6 k  r* Z; ?6 C+ C1 z
  KeyDriverObject->DriverUnload = KeyDriverUnload; " L0 X& W( l) p5 }3 r; s6 T+ C

- |) f, G! g0 S9 Z, x5 {. d  //
5 F0 Y6 r7 E) L, A' i- v8 S& A  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘  n! d% a: X: {
  //
" z1 s4 ]7 ^4 H) y! m1 {  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
1 o  C. f( u7 H  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其+ l2 q% r6 S1 z
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
6 M: ]0 w6 S# a* L% q" W0 ~4 T  // USB 键盘设备来进行挂接! R0 @' `2 X; P* A+ p
  //
$ Y, a8 Z) p) |+ o4 L  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
1 N$ d' b$ H% b  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
6 s. b& }1 e( a  {  ^- s3 j2 s7 D  h) H1 _! A
    //6 D  Z5 P5 }. u' H4 p! W
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名3 F" L9 k) y: Y# F4 [4 ?* u- W2 N
    // 所以这里打印为空7 @* E+ b3 Z% R
    //5 p. D" C  `1 k# {$ l
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
* t5 P$ q0 N) Q* C' U7 a    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );! K5 B5 F, d& _6 z
* C% d/ y' C& d  w! d# k7 y
    //
+ @, S8 Q# Y6 D& w. A; c# [0 i: b    // 挂接 USB 键盘设备1 `1 j- v% `5 O5 C" ?, c2 Q
    //
# {! Q( P' r, N! c% n+ Y    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );4 f6 a/ H1 k( @6 L/ y% b, n4 R
    if ( !NT_SUCCESS( ntStatus ) )3 ^  O, @( i' X: e/ t
    {  e* @8 a* P/ p7 a% ?: Y* J
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );: m: u, f# W' p! ~
      return STATUS_INSUFFICIENT_RESOURCES;
. h0 [. A" y9 g0 u    }
  d0 ~& r- P$ l( l' k# T  }
4 v7 Z3 a! S+ H6 m3 E  else7 X  `# y/ L7 u: e& b
  {
: N6 l! f& n# \    //* \) ~& e( p& [# @! e  y
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
4 V. q8 I4 j* S, B    // / J! A* I8 i% s3 W: P: S
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 7 `1 x" J5 J4 L% ^
+ \# M9 v4 ?) y# s$ `
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,1 z8 c( x; N3 k: L* C( j* F* ~
                                        KeyDriverObject,
) ]' ~( Q1 ?# a' Q" p, P                                        &KeyDriver );
* k. ?! r3 b7 S& u$ Q- Z. @3 f    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )/ R% j. z7 ^4 j# |. J
    {/ H2 w7 O; ~: k. \% u
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
; R2 j  c, l8 [2 m9 T      return STATUS_INSUFFICIENT_RESOURCES;) l& B: w3 ]+ W9 s2 i# h5 R" O
    }
' j. T0 S# @* v: k% A8 b/ b5 b  }, R; y. r& m2 ?! v' a

" w# Q1 \( r# G/ j: y3 g$ E  //
: I6 E3 F1 o  k% e  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
; p% J: E# R$ ~4 Q/ ~8 ~  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
; v( M+ z. a, y- O: L: H  //3 V* g! _( g% t
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; * f0 v& }% r; i; N: Q

% Z$ u5 j4 f$ {# l. N4 N  return STATUS_SUCCESS;
8 x8 W: |' s# Q9 f; J; z0 R3 K} 9 Y# ^1 l  U, v
) E0 `3 }4 V, d% ]
/////////////////////////////////////////////////////////////////
& D8 x  b: A4 N2 a! p* n3 g# ~1 z// 函数类型 : 系统函数4 x/ d1 Q$ A! w# Q3 H
// 函数模块 : 键盘过滤模块; `& ]* d3 k- i) k9 L4 U3 k
////////////////////////////////////////////////////////////////$ o* b, v3 Z+ y- s$ w
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
3 Q- V/ G6 Z7 O, M% x0 Y//        卸载键盘过滤驱动
% r1 ^4 A# ^. P. C7 F8 ?$ v: e' x// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上+ C7 ^( K: E: q7 R, Y
//        则需要等待用户按键,以后有待完善% c! e: P! e8 ]- ?! E. n
/////////////////////////////////////////////////////////////////$ y0 b( o. a! L3 q5 X6 q. K
// 作者 : sinister
& {) p. D9 R/ ]! p  p( f+ Q// 发布版本 : 1.00.00: }6 L+ Z' g! X
// 发布日期 : 2005.12.27
3 f! p3 T. n$ O5 p$ F0 `/////////////////////////////////////////////////////////////////
  x6 n- V! u- [// 重   大   修   改   历   史, T. ^0 e1 G9 J3 q- X9 Q* v2 `' J5 A6 M2 i
////////////////////////////////////////////////////////////////
$ \, f& [2 g( h" d: B6 C. }// 修改者 :
! `/ e8 ?3 o3 I, m! W1 U) p// 修改日期 :
: W  `0 c$ o8 T/ G// 修改内容 :2 @4 E) N0 P1 t& Y, r1 J' P+ H
/////////////////////////////////////////////////////////////////5 i1 S6 s. b" i* B% b/ \

7 x4 a0 ^1 U  E) R8 ]: YVOID/ B+ ^- L! b1 A$ ?2 g! B
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )* x8 B! ^% |, R+ K( ^& u4 d5 `
{
1 v+ N2 a9 i# G  q. ?  L  PDEVICE_OBJECT KeyFilterDevice ;      
  ]! X# I" T2 V; C  PDEVICE_OBJECT KeyDevice ;
' j* ]- s* c: u$ w0 B- z' b; ]  PDEVICE_EXTENSION KeyExtension; 4 @  n3 q2 m. C  E2 v- N& [
  PIRP Irp;
9 W: I# y* j7 O) K3 ]  x% P% j  NTSTATUS ntStatus;2 U5 d' {4 U/ ]% p

' U' h! y% O* U7 R  KeyFilterDevice = KeyDriver->DeviceObject;
/ m: G: Q2 P* ]. Y. M9 F  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
8 v- b+ t5 L1 |5 I( P  KeyDevice = KeyExtension->TargetDevice;
  R" q+ u" s* J' ^7 M4 P7 E, k0 W6 c0 e$ j# A% F4 D8 e
  IoDetachDevice( KeyDevice ); 5 @& B. P- u* `5 I# b' R2 [

5 Z6 z+ a+ k, N& u  //
$ ^' F2 o7 ], f5 T  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
  |% P- P5 _2 V- V; d  //
. H4 l( L# [5 l, |  v+ H  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
4 F* S3 S) _; C, Q  {* A3 Q' k, o" Q8 K9 C- q" ^
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )( q5 G) k; G$ H6 W
    {
$ h8 t7 |5 k- ^8 @$ {      //; |* c# K0 ?* U
      // 成功则直接退出删除键盘过滤设备
" f9 K# O9 ?$ V0 P, V1 z& x7 ?: a      //6 s/ [7 P$ r4 n5 X- b: j7 |
      DbgPrint( "CancelKeyboardIrp() is ok\n" );. M9 X. `1 i( b. L3 i
      goto __End;/ ~3 B& {3 o  k5 t2 f% `
    }
- u, D4 j) L/ y7 Y  }4 {4 x) [) M9 G6 {% I/ A5 `* }- h

8 G! D, P0 D# c  //% \+ y/ o: Z; s, `
  // 如果取消失败,则一直等待按键
! e' z5 O% M+ _2 n/ R  //( E$ ]% G" v0 f/ s) L
  while ( KeyExtension->IrpsInProgress > 0 )
/ s+ r: ]& `* }- D0 I5 ~4 T8 U  {
5 B1 w, _+ S. w3 a7 o$ r    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );  U2 ~6 }! s5 b
  }3 `/ g0 z+ p) A

  i: p2 z+ u( y/ i  __End:# f1 h0 J/ Q" ?% z) D2 L+ n
  IoDeleteDevice( KeyFilterDevice ); / Z: M4 u5 P4 i% z

# i0 s" w0 R4 Q) N- b4 I  return ;
  p3 @) A" y/ H6 F" w0 O  t( B: w}
% ?( v5 d' z" ], t  @4 M" F# f$ p* M. b* W3 M+ A) e
/////////////////////////////////////////////////////////////////- [7 k3 P% G; W" ^
// 函数类型 : 自定义工具函数  h' a, D3 Q$ A% @3 b3 b
// 函数模块 : 键盘过滤模块7 f' g  Q" H' O% [/ ]7 P. E' B
/////////////////////////////////////////////////////////////////
! j1 M+ W3 Z. E2 A2 b' ~// 功能 : 取消 IRP 操作9 G/ D* e% F! x
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能; [& H/ r! ~7 `  y
//        使用此方法来取消 IRP
) \$ Q2 \" D  G/////////////////////////////////////////////////////////////////
* P+ `& K6 p( i5 H// 作者 : sinister
+ X  T" a, a* k4 G// 发布版本 : 1.00.00% S4 J8 a' L+ \, k" m2 x
// 发布日期 : 2007.02.20
' J& M7 Y( W& \: v# c/ t. ]9 q/////////////////////////////////////////////////////////////////! n; f+ V$ W7 `, J
// 重   大   修   改   历   史: u6 A0 ^$ \  m+ a' f
/////////////////////////////////////////////////////////////////
0 {3 n. f2 r# f% h( I// 修改者 : % b7 X% {+ {* c: g1 Q
// 修改日期 : 1 n$ s. n( W5 H9 h
// 修改内容 :
) r6 \  Q/ ~0 k7 K* Z4 M# n/////////////////////////////////////////////////////////////////
+ r+ r. K& Y' w* a+ a' X1 f
6 e' ]- i( |5 {6 h5 M. UBOOLEAN) U3 y, {6 c: P: r* ?
CancelKeyboardIrp( IN PIRP Irp ): M# m  N% ]5 U, _  m: G0 I
{4 T8 m5 i( @4 W; I" U$ M9 W
  if ( Irp == NULL )
5 @9 E. q. N; k; U# ]2 O  {
, j& D" O6 U& ^8 }; T& b. q) |    DbgPrint( "CancelKeyboardIrp: Irp error\n" );; Q9 ~. Q$ K3 I
    return FALSE;: R& `( y! C$ d/ V" ^" p9 M, V1 q) i$ _
  }
7 x% o- }5 o( ]- M1 t  E  C6 S! K) q! o2 w, c0 D7 y2 W$ i: Q7 {1 s
( V7 i4 N& u8 s; R
  //$ @* d& V" ~7 [+ {/ {) e
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,3 q( u0 w! ^0 i9 D+ S+ S
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。: {4 {  f7 r% F: y. i; K( Z# S) w( a
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占5 \/ P  [6 [+ ?: p& C# F
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD. e6 P2 y1 k" o5 J/ P' `( c# t% `" q
  //
$ l( i% x6 @9 R7 |
" i( \6 n$ s+ t) M% k  j& _  //2 Y5 h. {+ _; @
  // 如果正在取消或没有取消例程则直接返回 FALSE
2 Z2 L. }  b0 d  I! o4 s( a! j( @* m  //
: z5 O, J, ]* L% _  if ( Irp->Cancel || Irp->CancelRoutine == NULL )* ?6 X5 V( n( j  y3 b  O' ]
  {
" f( e. k9 u  Q. z    DbgPrint( "Can't Cancel the irp\n" );
& p" I8 C2 C/ ~0 Y    return FALSE;8 N- C( G2 p) L: j
  }
3 @5 W" h( d7 w# d) U: L" p/ g$ G2 g+ o0 m2 P  V6 S, P
  if ( FALSE == IoCancelIrp( Irp ) )
- w, P1 A/ q; R1 N5 d* o. a* F  {
3 i# v& ^( t' V( R$ V7 }& e2 P    DbgPrint( "IoCancelIrp() to failed\n" );
/ f9 \) V7 C- k+ J    return FALSE;
9 T# |) V" A. k4 A& b, s* O; ]  }
' i5 o: S5 g+ n+ x  r3 b( Y7 v( b( k3 C: e- N4 A) Q+ @% r# y
  //3 q* Y% `. q5 ]( I) b
  // 取消后重设此例程为空
  V+ D4 e4 e( o& n; k$ `1 g  //+ r9 ~3 K& N' d, i4 ]
  IoSetCancelRoutine( Irp, NULL );7 O$ i0 B. x5 o
( J1 u# ~1 i1 E8 u% B9 o
  return TRUE;; [0 g% t" I$ H& k  y+ h& ]
}
2 V: W# C( @2 D7 e3 r; R- Z
( ~$ Z2 Z/ D. I6 j$ J/////////////////////////////////////////////////////////////////) a5 ?) s; D2 O! w
// 函数类型 : 自定义工具函数/ y2 N. @* a; E1 D5 Z$ g8 n7 r
// 函数模块 : 设备栈信息模块
. L4 ]$ U. k& J/////////////////////////////////////////////////////////////////: A7 G9 R4 M: f6 X/ V- f7 ~* g
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘: _0 i0 \% r+ S, Q# G/ J
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
! P6 ]4 R9 p7 y4 e2 u6 }// 注意 : 5 e9 c0 S. z1 Q& @
/////////////////////////////////////////////////////////////////3 x6 {: V0 l* j- r
// 作者 : sinister
+ ]7 k) d% m3 I- t. {7 x: t& R// 发布版本 : 1.00.00+ X5 [4 c3 s+ ~
// 发布日期 : 2005.06.02
% H) Y$ f* q& P! |$ ?/////////////////////////////////////////////////////////////////
; s1 l' V( U: S' j* w, L// 重   大   修   改   历   史/ y2 M- u& D+ F, F7 }) N
/////////////////////////////////////////////////////////////////
  Q" D3 {' W: A' X- w3 H// 修改者 : sinister
+ r6 v% z% \  m8 G// 修改日期 : 2007.2.12
7 w3 v5 B7 o4 B/ n- o9 o3 D  k3 S// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改, ^) ^) V4 l; F0 q$ z
////////////////////////////////////////////////////////////////// g- Z3 W: U8 A* P3 Z2 ?$ n! r* u

- l' a2 I! i+ l  r% yBOOLEAN
0 U7 `; ^! u4 ?" e# OGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
3 f2 P" l  @! z' P{! t# h  q! A6 D
  PDEVICE_OBJECT DeviceObject;
$ l+ j' t. c- N% t" b1 [  BOOLEAN bFound = FALSE;1 _: ]& ?/ m1 s" s* \

5 h6 \# Q  |8 C8 v' ^: p8 y! Z  if ( DevObj == NULL )
; m& E4 N; ]! d6 V  c  {
# o% T# l; o, g$ G    DbgPrint( "DevObj is NULL!\n" );
: h( M0 R0 Q4 p    return FALSE;2 m( O( L, }# \8 C: G' n
  }
) y7 Z' m$ J4 Y
# W/ M2 x& a% ?. z& I6 o9 p) Q. k) T# l  DeviceObject = DevObj->AttachedDevice;
! M2 i! O) N. ^/ n  F! M/ w$ |8 J- i8 Z' |
  while ( DeviceObject )0 f6 Z! _  o4 y& O+ F0 d6 ^
  {
+ @0 i7 z. `: n  m4 C5 x    //
. @4 N; ?) Q- m# p% A0 q    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但, I' s: ]! N- x5 I, E
    // 有一次足够了。这算是经验之谈
" r  n" H5 ~6 Y    //
  w1 S2 C/ ^" M- m    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )* J3 P3 V8 D. ]  k) W% m( _: e
    {2 ]/ p) s( W" B! J
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",$ Q+ j. Q: j' w4 E$ i
                DeviceObject->DriverObject->DriverName.Buffer,6 R, j/ i6 T8 {0 a. ]: n  ]
                DeviceObject->DriverObject,
  Q/ _6 P& j) ^1 s& ^/ J' ^                DeviceObject );
3 w7 E2 s: O; w: X% f: C
+ s- t% ?) l; I" r3 ?& _* ^9 w      //* a1 `/ l1 B# y' @2 j
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
2 x' z5 A9 d6 R5 |      /// y& z. _3 E0 _8 b3 L! u
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
8 U; E' [$ _% [0 y$ ?4 I3 Q1 q* H  B                      KDBDEVICENAME,
$ L; S9 j) J6 O2 I& A8 c; n                      wcslen( KDBDEVICENAME ) ) == 0 )+ b! r4 m# _1 I$ Q
      {
- w; [# Q! R' J" Q1 B  }        DbgPrint( "Found kbdhid Device\n" );9 C7 q' V$ Q' U# u
        bFound = TRUE;* B9 L/ I& L$ J. [6 P; a/ h; Z; @, @
        break;" g+ h# U9 W+ S- l8 x/ H2 T
      }
& e  e' e3 e4 \    }
' v9 W9 C0 m+ q$ N9 ]
  W" ~' R, W. n' `    DeviceObject = DeviceObject->AttachedDevice;
  n6 |1 ~* A$ r/ |7 H  }; W. Q% {1 O4 o7 K# _( S! A5 ?
$ Y' X9 r1 v9 o0 z/ c3 Y
  return bFound;0 Q1 R  k4 @, W- w' G
}
$ ]: _% S8 i, T/ k, Q* V3 a  t. M9 c( M! P7 _6 n# R5 g% Q5 W) t; a+ e
/////////////////////////////////////////////////////////////////
, o0 J+ j$ R5 U8 M. x$ H* Z// 函数类型 : 自定义工具函数
/ f) O& j1 A# q' M! G// 函数模块 : 设备栈信息模块
% Q. _3 x- D+ i/////////////////////////////////////////////////////////////////' Q) `/ Y% _* S
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
9 D, ~4 H* s, @# n' l* l// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
: O) l+ V% s$ s/////////////////////////////////////////////////////////////////' h& n* p  S3 K% o' b; `. Q
// 作者 : sinister
9 _9 O9 {7 [0 f. H" o- y// 发布版本 : 1.00.00" r( E/ S5 b& s: s
// 发布日期 : 2006.05.02  q% l7 _2 L& u4 }5 M: X
/////////////////////////////////////////////////////////////////; A( o0 U; I, N# _5 ]! x+ h9 C
// 重   大   修   改   历   史# W4 L0 `5 }6 r! I* k8 t1 Z3 U
/////////////////////////////////////////////////////////////////9 A# c4 t5 W/ |" I. p
// 修改者 : sinister7 q, F4 k6 B4 G
// 修改日期 : 2007.2.12
! ^+ e3 a' A- ^0 o7 A// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用, S. O( G. J- N( B6 [
/////////////////////////////////////////////////////////////////( n# c' k" t9 |1 A  u
* K# p- c5 n8 [8 |
VOID$ |: @0 M& n$ F8 p! j1 b5 Y
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
5 T5 Q; O! V9 T0 @7 Y4 h9 x{' z0 Z" A5 g7 q" P8 _/ Y: {
  POBJECT_HEADER ObjectHeader;
7 P2 G) c8 n+ S: I( H  N: p8 i$ `9 E# l  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
6 ]0 ^% f8 s; x: A
- ?4 d% `' ]1 d2 `) M0 r" }& B  if ( DevObj == NULL ): }0 r3 \1 ?+ X+ c7 ]! W$ g
  {
5 m6 B/ D1 A' m5 n    DbgPrint( "DevObj is NULL!\n" );* }1 @& d1 Z5 T* @8 w9 T  ?
    return;6 n; q' i& U$ h  W% I
  }2 W0 T! V2 t1 S$ r8 {
! X* m% A9 k1 N/ R4 D! N
  //2 j. u+ {, i3 c6 a/ y
  // 得到对象头/ @& Q' H: G: p  n9 e4 ?0 r# F5 }+ I
  //2 b- B# Q1 ~( |* g0 R- M" u+ p9 v
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
1 g6 L4 ?+ {: [+ z! N6 r9 u* d9 E5 l; e  D* g' M
  if ( ObjectHeader ). A& C. Y4 D$ M( Z4 a
  {- S; y: [5 K2 S- V- {
    //; z  ~1 k( u# \! K) |# `, s9 ^5 j
    // 查询设备名称并打印: i) K8 S4 `3 ?3 h9 _) e
    //# j2 M1 R0 f5 l/ P
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );' U, {1 D9 c+ N8 H  f

% B, Y, b# e  S# i  _% R3 E' i    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )8 m; m- N; c) u6 s
    {
9 n+ W" U1 \1 a4 t7 x! C      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
2 X4 w( ]$ Z! G4 J( A* K3 D                ObjectNameInfo->Name.Buffer,
/ [% E! ?6 W5 n* D                DevObj );
4 W) ?9 W8 A+ J- e, f5 t, S
$ T1 I5 l6 ~- b+ Q      //
' ?  V: {/ n# o0 v      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
$ E7 l$ L1 ~  Y* a( u, V9 ~      // 用,没有实际的功能用途
3 m1 X5 F* m8 _; {2 D      //
! R" L: U) n1 M- h& h  q* d      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );( M/ g/ ^2 J  N! d* X7 b, f
  J0 D* E5 j- V% ?
      wcsncpy( szUsbDeviceName,( L8 d* ^/ u/ y# ^4 C
               ObjectNameInfo->Name.Buffer,
, [+ ^0 d: g& m               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );( X; h  q' h3 B) s( }1 a. A6 x! V
    }
" {9 r! A4 @  t$ V- u) {7 U8 g  {) a7 G
    //
. f+ ~7 l0 e  {2 a! S, |    // 对于没有名称的设备,则打印 NULL
/ t7 z! }* d3 F+ ~    //9 m1 D7 ?" o' \
    else if ( DevObj->DriverObject )
8 R. f7 ]0 J& ?8 n; \' U( J0 R- Y% ~    {6 @% T0 h" A1 C* ]
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",- `4 P$ X* D) R# N% e' ^1 F. C' @
                DevObj->DriverObject->DriverName.Buffer,
+ n  M: m& d2 V! R; M1 I: Y                L"NULL",: q4 _' _" ~" ]: m' a0 a9 l4 c, c& R) o
                DevObj->DriverObject,9 X: J' d% s  r) Z% w
                DevObj );/ p8 c8 }# A" y5 U  L! a, x
    }1 H0 x# G/ p8 N: H# v
  }3 v( p% D& w5 P2 Z) `
}
+ U7 g  P1 i" l3 |6 T* b  n' x4 P4 n* c% _
/////////////////////////////////////////////////////////////////$ v' N5 z! j# o+ x- y$ p) t
// 函数类型 : 自定义工具函数. E, G& q& I# H' W
// 函数模块 : 键盘过滤模块, x. Y7 A/ [) G- V! o, G; D
/////////////////////////////////////////////////////////////////9 {/ c, d+ U0 h# Z5 |' B# h$ a- U/ _
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
; ~  k9 t" \. \5 J7 b4 L//        对象,过滤出 USB 键盘设备,将其设备对象返回
% g8 T, L1 F8 w: H" A# m// 注意 : 0 n4 e5 l, Z2 Z
/////////////////////////////////////////////////////////////////4 K1 i+ U- S) G: f
// 作者 : sinister4 S8 p* V% g: |- G& n" d
// 发布版本 : 1.00.00
  ^. y7 t" ^6 S2 Y. E6 e1 B* i// 发布日期 : 2007.02.13
7 m" y5 @$ \* |/ K  [/////////////////////////////////////////////////////////////////' r  p/ |! q% P% L6 k/ o4 X1 h1 q
// 重   大   修   改   历   史! K9 D2 K4 E( o
/////////////////////////////////////////////////////////////////8 N$ O6 W; @/ b
// 修改者 :
6 q. v) _4 h6 `* D3 K// 修改日期 : & ~% @! V! K8 W
// 修改内容 : 4 V$ N4 B7 p- e' L
/////////////////////////////////////////////////////////////////
5 C9 {  I  R! ~8 \& A# v9 U  ]4 a. E% ~% h- p: _/ }' ?4 z7 |
NTSTATUS
( k$ O: }1 N# w) ~5 Q# LGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )6 j5 _; z% e. f: u
{
2 L9 J1 y7 R1 t* [& r7 o  UNICODE_STRING DriverName;
* B& \  ^5 c6 j; z  PDRIVER_OBJECT DriverObject = NULL;
' x* z# ^' o; @: e( f5 O  PDEVICE_OBJECT DeviceObject = NULL;4 x6 {. w# b+ _/ ]- c8 k
  BOOLEAN bFound = FALSE;
1 L7 x$ w" K& l3 c
/ M9 V0 x. w/ z% ~7 e  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
- [  [+ i9 J8 ]
% A* r4 @) M& n  ObReferenceObjectByName( &DriverName,
7 ~1 }" U  R1 W, M# E9 i                           OBJ_CASE_INSENSITIVE,) T7 E5 w3 K( H+ y
                           NULL,. U: ^" r/ X4 S5 I$ V8 G/ J
                           0,
5 O9 |& w8 l4 N* m& W* `- e                           ( POBJECT_TYPE ) IoDriverObjectType,! e4 L  L- b' w8 h# c
                           KernelMode,
* j% G7 [" m: V- ~' W, S                           NULL,
" n- w) i& c- r# C7 E                           &DriverObject );5 \- ]! q' Q: h4 H
2 x' \7 i) k" ?) J
  if ( DriverObject == NULL )) K- A( L; ~, r0 X9 @! X* w
  {
' O! ?& F+ l/ `" q5 E  E/ d' y    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
) _+ V' P4 a8 k  S( j# n2 s3 _    return STATUS_UNSUCCESSFUL;  F  F- Q) ]5 j1 r
  }
" N* ^- m& K. ~9 D" Q, i2 L/ P! t9 Y8 [5 _( G0 G  W
  DeviceObject = DriverObject->DeviceObject;% c' Q- I& ~9 i! M
5 `6 f# [  @; X& s
  while ( DeviceObject )4 D4 \0 t. b; G/ e+ C$ y
  {1 l( S8 R1 [2 h  N( r
    GetDeviceObjectInfo( DeviceObject );
: ^$ Z# m8 V" r  e+ x3 |$ V% D+ t' g5 t/ q" Z
    if ( DeviceObject->AttachedDevice )' N' b5 T* _; R
    {
3 r: L$ w# ^+ j6 p" W8 S      //+ w4 Q" D$ R& e% i
      // 查找 USB 键盘设备
+ u; e' `1 g; e/ M      //
2 ~# T8 g4 a+ Y      if ( GetAttachedDeviceInfo( DeviceObject ) )
7 W8 g: O3 p8 d$ \$ y) h  }      {" j/ v" Q- z6 k; y
        bFound = TRUE;
) E9 Z# U4 w2 D        goto __End;
+ b  S/ p; F6 q+ y4 x0 p$ M      }9 O2 O) k( V+ V# J3 ]
    }3 E& O; ]# }* p  [8 O/ G
' w. D7 {7 X4 a+ K
    DeviceObject = DeviceObject->NextDevice;, f4 x5 T7 a) x0 q6 R: e1 U- a
  }/ W# T: ^0 b( V) V- t  w
0 Z7 b6 t8 ^/ T0 g
  __End:/ H0 P& A. }9 E: B2 `& F4 k. @8 V0 s

5 ^3 v1 D+ s& M$ E# z8 V+ D! L) j  if ( bFound )# a, o4 B. p/ C  `
  {
2 C5 b$ w6 A+ G/ h8 h+ k    //
' r; E/ w2 o  Q. R0 K" R2 C    // 找到则返回 USB 键盘设备对象
3 @6 G9 O0 @  ~4 i" m$ }    //  U7 @  {: r0 ^0 I9 I- _
    *UsbDeviceObject = DeviceObject;
- M' s$ ]& l/ V, ~* C  }1 l" K* c# ~, N9 j. t. L0 J: V
  else7 T& N" n1 F3 ~8 c5 Z
  {
' x6 u2 }+ x2 t$ P9 _* A% C    *UsbDeviceObject = NULL;; L; W) Y  }+ H* l& ]
  }% ]! o% `& C& y4 m

. j1 E) A, v5 A% k# e+ B! D  return STATUS_SUCCESS;8 Q3 _+ g, N8 K( ]. T
}' l$ ?( A  b- A6 G

" I+ Q# D4 x2 T: h5 e9 ]+ @/////////////////////////////////////////////////////////////////* ~" T- @. H5 r  i
// 函数类型 : 自定义工具函数
+ b2 e" U' A( W8 i) f$ q) @' c// 函数模块 : 键盘过滤模块
8 Y1 n' T# C* w////////////////////////////////////////////////////////////////
! @0 f5 {7 x4 y9 i1 I" \// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
) U9 H$ L# F  Q. I/ B//        信息,返回附加后的驱动对象
% U1 |4 t2 Q+ t, I/ H* a// 注意 : 此函数仅挂接 USB 键盘设备) `! P* @4 o6 f9 p
/////////////////////////////////////////////////////////////////
5 m. k* J; }, R, O// 作者 : sinister
7 P/ v; z: t% O% g( e1 s; y! q2 Z// 发布版本 : 1.00.00
0 Y" a' l2 n0 q/ o1 n" R) s// 发布日期 : 2005.12.271 F1 N& u9 s9 i
/////////////////////////////////////////////////////////////////* a- q, E3 j, _% {+ o
// 重   大   修   改   历   史
8 S0 S+ y, [, K( n! F2 @9 U6 T////////////////////////////////////////////////////////////////
4 d4 I: _+ ^) R) I+ V6 z' u. f// 修改者 :$ [$ Y& K5 D4 t' ~- [$ t& @" w
// 修改日期 :
8 L8 q/ r, I8 t6 t9 G, e// 修改内容 :# P$ u: Y) a  i$ S) E# G2 h0 s
/////////////////////////////////////////////////////////////////
1 D' L- O9 m, S1 I$ F6 Z0 h! e
6 R8 N/ x7 X* ?, X  kNTSTATUS
) `- W! H2 m( Z5 uAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
; Z! i, a. l$ Z7 c4 `3 H                         IN PDRIVER_OBJECT  DriverObject )
2 l% I3 L3 }  {7 N! m% h/ Q4 e{
7 \1 V; p1 a- `& H  PDEVICE_OBJECT DeviceObject; 8 q$ P" m. |1 x+ ?, S% G
  PDEVICE_OBJECT TargetDevice;
+ _: a) V7 N1 b8 c( G9 k  PDEVICE_EXTENSION DevExt;* ^& j5 Z7 S  K$ n# R
  NTSTATUS ntStatus;
  U% S1 p) A7 R  m5 V
8 d3 i0 G! z4 o& i$ y4 a  //. T+ h5 K/ T4 k- v( u  X: }1 y
  // 创建过滤设备对象+ I9 S- w. L& w  E
  //
. F2 I4 T! A/ |# C1 O! l# c% q  ntStatus = IoCreateDevice( DriverObject,
9 X% l4 v& F7 G5 W0 P% d% A, o                             sizeof( DEVICE_EXTENSION ),  o; _4 ?; R4 @7 f" _+ ]' U) o
                             NULL,) D9 ^7 l( |. ^0 K. c3 H) d9 v
                             FILE_DEVICE_UNKNOWN,6 D0 W8 ?' \- t$ s* |
                             0,: m1 ^5 @( _' U( J
                             FALSE,3 \# j2 Q1 }  a) |6 [9 x
                             &DeviceObject );
' Z7 d0 p# @# M9 B6 b
7 v* E( e6 n9 `1 _3 B7 @  N  if ( !NT_SUCCESS( ntStatus ) ); j: W7 n; L5 V
  {
8 s2 Q' e& x- R" }    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
: ^4 u( q- b" t: V    return ntStatus;8 `. H) Y: [; p. E! v% s. z/ n
  }
8 r! Q$ v# z: o- s" n' ~7 H" w* d8 K' \! r% ]4 `9 t
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
% P; P: V- M' u. \2 |
( L* @  n! C& I. d  /// D) J4 [3 B0 \' G+ W
  // 初始化自旋锁
0 P  r  c: `" J8 d  //7 [9 v. U) f# i: M. d  I
  KeInitializeSpinLock( &DevExt->SpinLock );" Q4 W6 C+ n( u2 T
6 X  a& [2 ?6 p- @
  //
, i) I; @5 O( d/ U5 D( g/ j' ~  // 初始化 IRP 计数器
. q: N- _. Q# J  M! f" p1 I8 v  //* D0 O8 a" I1 t0 j' ]4 q) l
  DevExt->IrpsInProgress = 0;
7 N# G" g2 L+ s( Z% g
: k) k1 H7 D8 K# L9 U/ p  //
, L+ i! s. W% C9 h  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
( ?. f" S. g+ ~( d  //5 a* }' U( P' Y8 u

2 [" t5 v# C+ K  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 9 }( s$ J2 U5 x% H3 g
  if ( !TargetDevice )
: ^0 E& k/ [: e$ Q9 y$ i# `  {
) o4 A$ a2 ~: z+ Q    IoDeleteDevice( DeviceObject );
" B! }  Y4 }2 H+ a    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
1 x1 c3 `+ X. b# M7 k    return STATUS_INSUFFICIENT_RESOURCES;! g( Z6 Q) G# I& o
  }
! b" Y6 i2 f' Z
' U$ C# S/ ?1 b4 a; `1 j  //  k$ \9 A4 O6 c( m. W
  // 保存过滤设备信息
! C6 D3 s8 w. J: \  //
, t4 s, L: ~* M* ~4 e  DevExt->DeviceObject = DeviceObject;
5 q# }  ^2 M6 a" N9 p( F/ x  F2 |  DevExt->TargetDevice = TargetDevice;' \" c# M: P3 I; R2 i; O
8 k3 Z) y. x5 D! i0 ~% h7 N
  //* D" _) @; v5 _# \0 V, n1 i4 }* E
  // 设置过滤设备相关信息与标志$ r4 E4 z! u7 m/ O6 p3 U! o
  //
+ Y" y. ?$ F* o; p  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
3 }+ B# {3 L) g2 N  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;/ {( ]6 B; o( F& E

. l0 R- |% b8 E& R9 r" W
) e. f" A  M+ D4 k6 i  U- t3 j  return STATUS_SUCCESS;  a  d) v% n6 V* [: F1 D
}
$ V/ I, X! \3 A3 I6 K1 D; H0 P( Z$ h$ P+ u( C( c. a8 ^% _
/////////////////////////////////////////////////////////////////
/ u. A; [9 e) O7 X  d// 函数类型 : 自定义工具函数
. `, q/ V  t8 I! C) }// 函数模块 : 键盘过滤模块, ?$ t& a- u9 g
////////////////////////////////////////////////////////////////
& E8 s$ t- O+ }. Q1 Q// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关  }" b8 f3 `" Y/ p( G
//        信息,返回附加后的驱动对象, g' C7 ^, Y# |& m/ X
// 注意 : 此函数仅挂接 PS/2 键盘设备
' c7 q1 z- d" x* [6 Q2 k/////////////////////////////////////////////////////////////////0 |. F! _1 W# e
// 作者 : sinister7 @- y1 k- ?5 \
// 发布版本 : 1.00.00# {% A6 w6 u5 l, a
// 发布日期 : 2005.12.27* b% S; T( {- b( E0 j& R) b
/////////////////////////////////////////////////////////////////
3 h  {7 s' l" }7 a8 I/ N// 重   大   修   改   历   史& `# b& R0 R4 p9 ?8 z4 a9 z: [
////////////////////////////////////////////////////////////////
4 ~1 z+ n: u( r* \4 e// 修改者 :! \$ F* _. b7 j$ R5 Z$ j  O8 A! E
// 修改日期 :
$ }/ ~) f: R6 O8 D% B9 U// 修改内容 :
6 Q7 C' I+ A2 t# ]+ _- m, t" x) T/////////////////////////////////////////////////////////////////. \) `5 l  s3 h+ ~  O4 \: \

9 s& m2 e1 \5 `: I9 y- @  FNTSTATUS1 Z# _1 O1 A, F5 r9 o; h7 D/ F9 v
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名# d# |/ A8 W( F+ S- p
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象, I" {8 o6 g5 ]! Z
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
" B) D6 N; W! {) P1 [, H{% v* m8 A$ O6 x5 d& C
  PDEVICE_OBJECT DeviceObject;
4 a0 K1 t8 [6 n  PDEVICE_OBJECT FilterDeviceObject;
$ Q4 ?5 A. |% c) T  j  PDEVICE_OBJECT TargetDevice; ' [% m! X, P; B
  PFILE_OBJECT FileObject; 8 ?$ O' s8 e7 v+ j1 J# |) {# d$ R. ]
  PDEVICE_EXTENSION DevExt;- R% ?  K- v4 f/ k& v. [/ J

, U  E& N/ ^! x5 I/ T# W9 U  NTSTATUS ntStatus; " ?; o: _  ]8 i( Y# X9 N2 ~
# z  C/ l& Z3 u0 {5 U4 v$ A! c
  //
( u6 H; L7 o) J, u6 H  // 根据设备名称找到需要附加的设备对象; v% G7 H7 Q9 f) Q7 t* i
  //- b4 q2 ~8 F7 Q3 X
  ntStatus = IoGetDeviceObjectPointer( DeviceName,: i- ]- r) d! x" t$ ~' n) N
                                       FILE_ALL_ACCESS,! b( t; R: V6 S; F- i- J  D
                                       &FileObject,
2 r/ X% k3 p* d                                       &DeviceObject ); + {5 j* T" m- y1 K& Y0 V" X8 `
# V) F% M( G- s+ S+ i
  if ( !NT_SUCCESS( ntStatus ) )
: o# F  c/ T: b: e, }1 _! d7 I" u  {
/ P5 ?  b( F% A$ u' k    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
& b) D# r- t" s; @% D1 `( [    return ntStatus;
3 @' ~$ T. N0 K) W# ?' w% ?  } % E+ @3 Y, f) S

( ~+ t7 G. S# W7 d0 L) w  //  r" O. z( h) k; x$ |  S! I2 T
  // 创建过滤设备对象: c1 C) n* |  }! U1 z4 Q
  //9 l# I' m- |  ?( h6 E
  ntStatus = IoCreateDevice( DriverObject,
, s' l: o0 P4 o* ]1 U. ?                             sizeof( DEVICE_EXTENSION ),
. E5 W, j% M% x8 J# ^' a/ f                             NULL,
/ R) D, Z' |& ?7 m9 |                             FILE_DEVICE_KEYBOARD,
- V' C  [7 t6 D1 `/ F. E; r9 }0 X! o                             0,
) T; e! o! [" b, M                             FALSE,
( J' _- V: x) T( [- E2 G                             &FilterDeviceObject );
' B% E) B2 t$ u, g! u
5 z% O' O  N& G! Z' i. E/ \; @  if ( !NT_SUCCESS( ntStatus ) )2 W6 T, L& q& [0 D
  {$ v) V' K2 d6 x2 P. B7 M1 Q
    ObDereferenceObject( FileObject ); " _% `, k. D# {0 p- I
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );$ z% q4 g. B) |( U( D9 y
    return ntStatus;
* s! h5 l1 u) V0 U  } ; \" u# A7 o5 z
: e& \2 i. b5 s
  //, n4 z0 U( P  M! E" y
  // 得到设备扩展结构,以便下面保存过滤设备信息
0 i1 Y. c+ ^, N8 ]" I  //% x% m. A# U( H2 e1 b& ^' s
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
# ^( E5 G. \3 }4 D6 }  f
$ p# X& x+ M' t/ b# _5 r5 @& ?2 E. r  q+ J# H* O) S
  //+ f9 C, t( D* c$ c* O: l# I
  // 初始化自旋锁5 O, n; e- ?% b* t* V$ {. f/ r
  //. f3 y3 e  J! C1 V' h* F  w
  KeInitializeSpinLock( &DevExt->SpinLock );* w+ y9 A- b, I$ P

) g# Y4 ]4 Q2 e, c) T. L! J0 j: ?. I  m  //- h* Q: `* M- k! B+ {
  // 初始化 IRP 计数器
# W2 A2 f1 i' L6 G# y  //
3 }9 d  g) a. g$ z0 j6 u2 f+ G9 Z  DevExt->IrpsInProgress = 0;2 w6 h5 X% L  l9 P  Q

( Y; V" r/ L' \/ W2 \  //
, d3 \7 F& j+ C  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
$ ~; f" C0 d( C  m  N" x) w: Q  //: R# A1 r) o2 ]. |# ?% k3 V5 Z
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,3 I) M& W; N( a
                                              DeviceObject );
) K1 F1 ^6 V" X+ v$ r4 l4 I  if ( !TargetDevice )
7 p9 d8 a' T, D5 E6 e. e' c  {3 H& z4 I$ h2 A% f, g
    ObDereferenceObject( FileObject );
$ \; m# @% o  ^' x" t+ ^    IoDeleteDevice( FilterDeviceObject ); / U5 B. z( Q/ m
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );. i8 s+ B5 {0 K
    return STATUS_INSUFFICIENT_RESOURCES;0 s/ F$ H  u# b& Z0 y1 v2 C
  }
4 y0 E$ r2 x9 W5 G
& D+ y/ i4 p$ I1 z! D9 ?' {  //
4 n0 i; X) ?# L. Y  // 保存过滤设备信息
% d6 a) s" j$ _: ]2 d  N6 A3 o9 B  //8 M1 K3 l8 E/ {+ x! |) f0 L
  DevExt->DeviceObject = FilterDeviceObject;
; ^7 h; D% `- ]% z' X8 B. j: a  DevExt->TargetDevice = TargetDevice; . V& _  N4 a& S* W. I
  DevExt->pFilterFileObject = FileObject;- ?+ x1 |/ b7 v- M( r, p3 c

& c; r* P1 ]7 m: \# e5 @3 Y/ F/ A  //8 p& p7 b8 v& b5 R" O
  // 设置过滤设备相关信息与标志2 b( U0 z4 Y4 e" o" G" T
  //
: T" q& X# ~# B+ w2 \! n+ J* B/ ^  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
+ p- N( Q) g7 B8 n* w& ]& I  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
  _' v9 j" P8 X# D) b  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
5 Q, F0 R) m" F- V+ t& Y* X  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
: @" T% a5 x. r5 Q                                                         DO_BUFFERED_IO ) );
0 }* [$ F: E8 h' U2 x
; M  ]9 i' }0 l& {+ N  //  z1 u$ @1 M( r1 B1 x
  // 返回附加后的驱动对象
4 I4 @, M0 R+ k9 Q  //
+ p( ]: k: C' H+ J" |5 E  *FilterDriverObject = TargetDevice->DriverObject;
7 w. J- q- g0 ~8 }  K$ X/ i
/ q; W. `+ l1 f( X( f) K  ObDereferenceObject( FileObject ); $ r  R( D& |* \1 v  y. o% `( g
) G! W1 \- E* s# @2 M: I/ |+ V* d
  return STATUS_SUCCESS;
6 h: ?$ K0 Y7 C; H- o}
6 D. k) c3 L7 f! f- a$ x8 u: P+ e& P* F& W( i& |* Z
/////////////////////////////////////////////////////////////////, Z# j2 I  m- s1 n* M
// 函数类型 : 自定义工具函数! s% w8 z- d# d! x2 B5 n3 e
// 函数模块 : 键盘过滤模块
* A( b- [* t; M3 K) J- S/ c////////////////////////////////////////////////////////////////; U$ K. n0 X6 _9 j
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发# h0 E. @0 }9 V. Z* x
//        这个 IRP 的完成& `1 o4 z$ T' L9 C. V* [
// 注意 :
' o" V4 R5 R( @5 J/////////////////////////////////////////////////////////////////9 y) N) H2 [1 @
// 作者 : sinister
. C! V& {; d+ Z. D% ^. J9 P// 发布版本 : 1.00.005 u/ J3 J9 n# j5 {+ w
// 发布日期 : 2007.2.152 }8 H' w" O0 x6 P+ h2 C/ A, v
/////////////////////////////////////////////////////////////////4 w3 _) |1 @. {1 w9 Q
// 重   大   修   改   历   史" d* `! e; @5 ]' l& t$ @
////////////////////////////////////////////////////////////////
8 A/ _2 p- l( E' s% ^4 Z// 修改者 :: x* Z, R& A$ L, V+ w) a( H4 g9 u
// 修改日期 :
2 {2 r# ?" ~1 `5 P- ^// 修改内容 :
/ z7 C) l0 L8 A6 q8 u/////////////////////////////////////////////////////////////////+ A1 T; n- M/ _, j: ^( N, f1 G

; P* g6 v( T6 c4 iNTSTATUS! H+ Y* m$ Q* i# L9 y
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )1 p7 y  N3 B. A# l" ?4 U5 ]8 Q+ E
{
% v5 ^( O1 s! }. h: e; D( L  E; d  NTSTATUS status;
  E: c) ~4 ?3 l  KIRQL IrqLevel;* x8 `8 }4 g6 s0 \! g8 `/ Z7 z. F

, M7 B8 ?* G( X* T0 o9 G" X+ V  PDEVICE_OBJECT pDeviceObject;& X0 P! n5 c" u; D$ e) Q3 |
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
) Y& @) j% U$ F. b7 g                                   DeviceObject->DeviceExtension;
; _# z3 R& {% s5 o
$ u5 F  J- Z7 Y# c
9 T6 t9 s; n$ j  IoCopyCurrentIrpStackLocationToNext( Irp );
: _" W; H8 T3 `$ P( R1 j7 j% Q" G1 P' c, E0 V
  //
; N5 w( {5 Q# F, F  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
. }# b$ F; t# I% O  //
! X# a4 y5 z( K  k( s5 J8 z9 i+ Y, e  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );7 Q9 B: y  t+ _
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
1 G# ]5 y$ G8 u: U* u4 v  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
' i3 F  z( i" l7 ?! R; b. [
. t2 B1 G. S% @8 J5 F4 {  IoSetCompletionRoutine( Irp,
8 O; g8 [; Y0 m                          KeyReadCompletion," D( O/ f) B8 D/ G
                          DeviceObject,6 N5 q' ^$ Q, A/ p0 ^
                          TRUE,
& n0 t7 B3 T9 Q+ ~# J9 S                          TRUE,
7 G+ }: R4 t) P3 @  T) @) ?                          TRUE );
/ T, g1 p4 U5 W) ^" S: u% K, \7 M0 r& K* ~
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
/ }- H% A2 b9 p0 H} , N; f5 ?! y: B2 c$ p) H

! {; I9 k. \, ^) `( r+ r0 r! j/////////////////////////////////////////////////////////////////
0 Y2 A4 A2 V5 J' ?: Q7 z// 函数类型 :系统回调函数
9 {, ~% H/ N# X, \( D! Y  k+ p// 函数模块 : 键盘过滤模块
9 R+ t+ e& U, z& h$ |! s////////////////////////////////////////////////////////////////
6 v( J& t: r( c// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
" `7 D- M+ ^8 w8 d8 c// 注意 :
; P# O  F( ?* F+ Z/////////////////////////////////////////////////////////////////
7 J  }) F- \( v# L  ]// 作者 : sinister. Z7 J: r3 r& @
// 发布版本 : 1.00.00
* ^7 }4 E, _" p+ t! a; L* T// 发布日期 : 2007.2.12$ H& m, W/ A4 E0 |) ]1 C5 x* R  d  j9 X% f
/////////////////////////////////////////////////////////////////& A8 V+ h: ?! H( Y
// 重   大   修   改   历   史
1 n$ w4 |$ x1 S8 c0 G0 c7 N3 ]) E1 F: U////////////////////////////////////////////////////////////////
4 {3 }7 |# }+ g) j5 L+ Q// 修改者 :
# a8 R6 `7 b0 T/ `// 修改日期 :0 _; A  I( d8 K3 N
// 修改内容 :: O2 [6 N' X+ a: w
/////////////////////////////////////////////////////////////////3 j6 {( M7 B( x' N7 N1 j

4 P- }3 N3 V, W  H1 u& |; [0 n* W+ gNTSTATUS  k' p- m) y- Y
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
/ G, B! E' J* d0 {$ [9 `4 [                   IN PIRP Irp,, L6 v0 H% u3 G4 ]& b
                   IN PVOID Context )
; j* \  c" F7 E, Z6 E) h3 \8 K5 v{
) N+ z* n! I' g8 m! A% `  PIO_STACK_LOCATION IrpSp;" u" K$ W/ P1 f4 [1 j
  PKEYBOARD_INPUT_DATA KeyData;
/ A" x! i+ G) C. b# P- R7 P  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ y" X. s; ~' ]4 h# N% `1 t, B                                   DeviceObject->DeviceExtension; ( y; @: w) x+ \  m
  int numKeys, i;
; l" ]/ M7 B% P( d  KIRQL IrqLevel;4 e) p: f3 P) l: c* ~
8 I( s$ i/ Q5 [) E. X
  IrpSp = IoGetCurrentIrpStackLocation( Irp );* K& ^4 \7 P$ ~3 n. j( {

% m) q% p# Y/ B& E  Q0 F* G4 A- X# p% F
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )- s) r4 x* T/ d0 v9 k  L( G
  {3 s  e  _0 ?9 B5 E
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );) z; L8 \) t8 I; A  q
    goto __RoutineEnd;4 C0 J; s' p1 @1 r# f
  }6 K) ~2 e- N2 {5 i/ i5 B* p

4 }! n6 p9 Y) G. }8 }$ l) c  m8 E  //
5 u0 K9 n) n3 Z# l  // 系统在 SystemBuffer 中保存按键信息7 B, y; R! E- v6 R$ r4 A9 z
  //
3 g: p; z0 [0 F! U; ~* X. a; O  KeyData = Irp->AssociatedIrp.SystemBuffer;
) F- s* y% o5 V2 ?9 ]8 u; O  if ( KeyData == NULL ), O# @6 A, o$ r( S1 o) a$ g5 p( }
  {5 M+ ~" {2 f9 ]$ ~
    DbgPrint( "KeyData is NULL\n" );9 y+ ?7 y: x+ \( D2 E$ r
    goto __RoutineEnd;8 q. Y0 X7 ?5 P) _6 R% M  r# r
  }  c# d8 _1 V# u' [( ~$ R& Z

3 {' h& T. o- ], R  //
) V" K6 O8 P6 t: i: M  // 得到按键数
+ ?4 G! B4 @7 U, Y1 `  //
) ]8 J& A9 T! p4 K! ~/ S  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );4 L3 F4 j5 Z  g6 Y9 }& ^+ S
  if ( numKeys < 0 )
7 |' g$ [2 r8 j  {# Z8 ]% o/ r' H) B8 z1 g+ {
    DbgPrint( "numKeys less zero\n" );
4 H9 R3 K' z7 H    goto __RoutineEnd;. _' m$ ]+ O9 \, C
  }# F0 X4 _# N, O. W0 v) n' X

. h; k8 j) ]8 t: ~) K9 v2 f+ R  //
9 n* i& \4 ?8 i0 x0 ~  // 使用 0 无效扫描码替换,屏蔽所有按键& Z4 D) A1 D. z0 p6 s+ r, L
  //' b$ i# C1 O- d2 @$ _# J
  for ( i = 0; i < numKeys; i++ ). U* z. N. _" {5 P' C- E; G7 K
  {) |: f4 H$ e! O
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );/ z& V3 {# g1 y; y) a* c  P
    KeyData[i].MakeCode = 0x00;
' {2 Z( z+ N. k; \& i9 i4 T  }
" t5 e) g  `# ^4 w+ D
9 k/ _" ]* R  l4 H- X1 k
, p" ]* B  i- ?. Y( H5 U/ d  __RoutineEnd : 3 T- w& T& _! M

8 o5 K# D0 h" a$ w( Y. m7 t1 ?  if ( Irp->PendingReturned )
" v" {3 P8 C  K8 P9 ?  {  `, q! ^9 H! `5 P' r( g
    IoMarkIrpPending( Irp );1 Y  |# ]5 |# D3 I9 u2 g
  } ' K# T* o$ {* a' z2 D2 k: D3 h1 a2 a; P
6 i5 I$ I) f8 g' o$ o4 q7 f- T, `
  //
/ t* K0 |3 C# \& K$ I; o. ?# W/ o  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁7 y7 E% u5 `; v
  //( ?( q, C& L$ }3 ?; k) j+ p
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );3 [8 v8 Z6 E( h% I8 \7 t
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
6 T# g# V% {1 _% i: j( o% j6 b  G  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );6 S. Q: _- L- l1 J$ h* @' W/ u: |+ u

7 C. J& F, u6 [$ H7 {* F  return Irp->IoStatus.Status ;
' Q# W7 ?! x0 c0 X} 9 H. D* r3 ~1 D' H1 n8 G' F! B4 p

2 ~6 D; m  I; |8 i8 Y
% |1 z; Q' u9 S; u- z/*****************************************************************5 ^0 O. _- v8 n# |
文件名        : WssLockKey.h& N% D% y: D) r
描述          : 键盘过滤驱动$ g2 [- D& ^& [
作者          : sinister' a, {! g& j7 C4 o6 I
最后修改日期  : 2007-02-26' ^* R- |6 r8 t" S+ \! s# a
*****************************************************************/+ \, q7 U( D# }: z$ f# U* X
) T) I4 N) p5 |! b0 K
#ifndef __WSS_LOCKKEY_H_( n" a$ V" O* p& k7 D3 a0 o
#define __WSS_LOCKKEY_H_" v" H9 y5 i% N/ ]. t! D" Z
, j! i! X: c; M5 Z: `6 V
#include "ntddk.h"
7 @+ j( V/ m% @- d* S9 }#include "ntddkbd.h"! Z# Q) j3 F1 N
#include "string.h"
1 D* @! x4 q* |6 |: d#include & r: F( d) X) |1 z; O
0 ?8 O/ i$ Q% m/ O9 G8 K
#define MAXLEN 2565 Y$ j7 r* X, [9 ?  @2 S
- [, {! I0 K( i
#define KDBDEVICENAME L"\\Driver\\kbdhid"
# D, K  x% U. l0 r) O5 o8 p#define USBKEYBOARDNAME L"\\Driver\\hidusb" . g: d, t: y, k  A
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
4 ^0 L/ d" v' v6 w0 w& k7 o: ~  {6 s/ |, `
typedef struct _OBJECT_CREATE_INFORMATION
* U3 t+ ^" `/ u6 k; Q3 K) c{0 C. x/ x! S5 A2 B" W. G' @
    ULONG Attributes;# k/ B! v6 ?9 s, q
    HANDLE RootDirectory;2 v  \6 W9 }* }- z3 [
    PVOID ParseContext;9 q. `7 [, a. X8 N0 _
    KPROCESSOR_MODE ProbeMode;" ^) M- n% X; J; [9 h) `; Q
    ULONG PagedPoolCharge;) J( O4 u6 R' G* Q: e% ^
    ULONG NonPagedPoolCharge;+ o) S' q- q* u3 ]/ W
    ULONG SecurityDescriptorCharge;
  z$ W/ {! [  u4 H    PSECURITY_DESCRIPTOR SecurityDescriptor;: V5 r! I. R6 r# r& a
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
, Q! r5 K4 O, g" f9 G    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;: e* r' \: B  O# u
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
! F1 q! l5 g! B6 w; I
) k8 d& E- c+ atypedef struct _OBJECT_HEADER
0 I, t3 K3 `0 T( d{; P- V9 l" Y4 B3 H
    LONG PointerCount;
& F) W3 e: X/ ~7 b    union! e3 v- G$ L& i$ E) R
    {
& z, u! r8 J+ `( Z        LONG HandleCount;% |! ?1 h3 N# T; h$ J
        PSINGLE_LIST_ENTRY SEntry;
3 c, c* w8 T# ^( s    };: Z9 ~& u6 U. W0 b: Y/ Z
    POBJECT_TYPE Type;& o" n( i/ R: `
    UCHAR NameInfoOffset;
% m7 I5 C2 \7 I7 c    UCHAR HandleInfoOffset;
" F$ I& i2 S6 q    UCHAR QuotaInfoOffset;# B' k! K' s4 v
    UCHAR Flags;7 W2 C1 ?( k: U% i% i2 T
    union$ X9 n/ ^* \& F! M
    {
! h1 d3 T5 O5 t' a1 q        POBJECT_CREATE_INFORMATION ObjectCreateInfo;! [6 Z; c& i. w) Y$ V
        PVOID QuotaBlockCharged;3 }8 ?" W) U6 A, M
    };+ {( B: F& m$ F& v

3 `+ c0 S$ E" y! N3 U    PSECURITY_DESCRIPTOR SecurityDescriptor;
: k; H0 F. }' x3 X5 G    QUAD Body;0 ~9 ?9 Q4 E: x( [' N7 p6 }% n
} OBJECT_HEADER, * POBJECT_HEADER;6 q0 q4 A0 g: t* T2 r) w
/ A3 o5 ]) n* W' C( m
#define NUMBER_HASH_BUCKETS 37
: N- d% ?& y6 l; p: l% T$ j1 x7 b
typedef struct _OBJECT_DIRECTORY8 F% V/ c% r1 x  X. r
{
# a+ y6 Q6 Z0 E2 r    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
0 Z/ U6 [$ C- G' j. H8 ^    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
) U  S: ^$ M- [- j( y" S    BOOLEAN LookupFound;: q! G" g5 f2 R$ i. ]8 v+ t# \
    USHORT SymbolicLinkUsageCount;
0 Y3 J7 H, J7 d8 u0 a( Z    struct _DEVICE_MAP* DeviceMap;, \1 `( K& R4 E, a- l3 e
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;  q& U% o/ |4 d: S8 ~' Q
5 p5 r) j. i( K/ I7 j# X) n- u
typedef struct _OBJECT_HEADER_NAME_INFO% }  h1 L8 O7 G# Z8 u8 m
{6 B  U5 O; c7 |  R4 y, ?# z
    POBJECT_DIRECTORY Directory;7 [; W7 l3 j* T( z$ g
    UNICODE_STRING Name;
7 ?6 l& S+ J! ~$ Z9 I& e9 c    ULONG Reserved;- `' l# g1 k) O6 e
#if DBG1 ]5 Y  E0 C# M, K; P/ F) y
    ULONG Reserved2 ;) E% h/ s) B. ^1 O$ v- Q* u
    LONG DbgDereferenceCount ;7 n+ N% i5 v) N& M5 j' w. A
#endif
+ g+ V7 p/ v# g: R# v' B} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
6 s2 W2 Z5 ^& [/ |- M, r# X  U
$ r, n( S, ?! A, D# ~* |8 R1 X#define OBJECT_TO_OBJECT_HEADER( o ) \
1 Y% l( T5 M& S  K/ n  C/ G! O8 c    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )/ y. |1 {  M5 V  f6 L4 v

8 k0 O1 R5 q* S; g' {#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \: \! B/ o* O- B9 R) t* r
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
" j+ |' O8 x. Y. l! P6 q( a& `
& J8 B4 a6 ?: \, |  }typedef struct _DEVICE_EXTENSION( U3 P& B5 Z1 P9 ]+ [) ~" r
{7 [: p- n5 l2 M/ _' A3 E
    PDEVICE_OBJECT DeviceObject;" O5 F2 C  S  @8 x( w/ R# w6 C
    PDEVICE_OBJECT TargetDevice;; s, [. v' m! s2 R% a4 d5 Y
    PFILE_OBJECT pFilterFileObject;$ `4 c1 N$ B! N" i! i+ N+ M
    ULONG DeviceExtensionFlags;
1 y+ {( D3 s, I/ T6 J    LONG IrpsInProgress;
7 u; K" S9 d8 O+ P9 ?    KSPIN_LOCK SpinLock;
. o/ p1 G* M+ n5 A}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
2 L: g( b8 ^1 S# y! H& o
, |4 L/ K% V- k. P: h% Q* E# W5 z% d! Z  U
VOID
% w& V9 S& R: i# U3 J" m( EKeyDriverUnload( PDRIVER_OBJECT KeyDriver );
2 @/ ]3 d" I7 d" ^* i' u4 t  t: ^( g: o0 n0 H+ Q# v7 C( g( R
BOOLEAN
& P( X: i. L& T$ D- a7 O3 UCancelKeyboardIrp( IN PIRP Irp );& B/ M9 Q% v- h. Z' x$ ]5 w

# F- D' ]+ g" ]4 oextern POBJECT_TYPE* IoDriverObjectType;
8 C& }+ W2 l$ ?9 m5 G, Q
& Y- A3 C  I6 g, T# ~! L0 ^NTSYSAPI
6 q/ B7 R. G$ H3 J9 U) p6 xNTSTATUS2 X% x- a& C* W( N5 e% M
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
4 E2 f$ a- `  t: f3 o, W, H' }: G& d                               IN ULONG Attributes,; W* N# r3 E9 R4 S
                               IN PACCESS_STATE AccessState OPTIONAL,
, b: D. |7 |5 {                               IN ACCESS_MASK DesiredAccess OPTIONAL,
- c  T. I% X. E/ O9 P                               IN POBJECT_TYPE ObjectType,) C' g' E7 k( Z- m: G( G+ S  c
                               IN KPROCESSOR_MODE AccessMode,
. {( C% ]# \+ }; O( o+ R/ Z- u                               IN OUT PVOID ParseContext OPTIONAL,
( f- \" l3 H. s3 t8 N: i                               OUT PVOID* Object );
. P# S  G/ }4 n8 P- u
! y. R) Z+ j" [NTSTATUS # P/ {# c6 m& g' g/ I
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
2 R: O! s% _  z. ~* A; L
/ E" D8 u( e+ H/ l" ]. HBOOLEAN ) a! \# F1 O" z7 J" y. t1 p
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );8 t/ `2 Y5 j, F2 j# m& t
5 @! Y' {: p' c6 X
VOID % ?" ~* E( s6 X6 J6 A' Q% C
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );  C# C( i- }  p: O* f
. s. X: P+ T. m" o: X& b( G, [. u
NTSTATUS ; U7 F! v; @6 T9 A
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
7 y1 Z6 {/ l6 o5 n7 t8 H+ y                                  IN PDRIVER_OBJECT  DriverObject );
5 o: w  s$ o! v! z- G" Z; u1 h% v% w) D1 o" g
NTSTATUS   ~+ J) g7 ^+ d
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
( _. K( w4 M8 a7 P; z, \' p8 T! o                                  IN PDRIVER_OBJECT  DriverObject,
: X: k9 p! U2 [3 y( q& p                                  OUT PDRIVER_OBJECT* FilterDriverObject );$ `# Y1 |2 Y/ h9 j4 ^
% p7 a' ?3 P. s2 b
NTSTATUS
! p1 f9 W" h& OKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,5 j( W0 V5 ], ?6 E8 t
                            IN PIRP Irp,
$ w! O3 K4 \0 X& H" ]                            IN PVOID Context );
" B$ f( ?# g7 Q2 z: wNTSTATUS 5 p  j' y. K7 |; {* P0 m
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );" F" H8 b% E0 L# l: O. I$ |! [7 N
6 `& p# x+ ~1 @% ^" t
WCHAR szUsbDeviceName[MAXLEN];) U% x- y$ s4 {

) O1 Y0 b! G" x5 r( |+ v2 S! U( z#endif3 Y* v$ E; ^# Y

# P2 ~" O, o; D- m4 b( w7 O( Q* C6 `6 l( Y, `( v; |5 _
1 N& E4 A6 A- b3 }7 J
6 y* }6 X8 o9 ~8 O' U& o$ @. \
, A9 ^! k6 ?& D9 X1 {, B0 x
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。$ c- g- g% u5 x9 h' r2 k& \3 R7 r
WSS 主页:[url]http://www.whitecell.org/[/url] 5 u$ ^2 `3 t( \2 `1 Z
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-5-20 10:49 , Processed in 0.038988 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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