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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
1 Y, j* P" L% P% k+ T7 n! ?& f  X9 EEmail:   [email]sinister@whitecell.org[/email]
0 N, f' l/ z1 K! @Homepage:[url]http://www.whitecell.org[/url] : j3 w. U- }2 K/ I/ \; u4 T- O$ \
Date:    2007-02-26; Y% v8 z4 a3 `' a4 E. `$ e, N

# N+ g( s' D2 n' e" U, e' V8 d8 d* S1 C& e9 O& h
/*******************************************************************
# M6 ?; m: M9 ~# q3 t# L$ v3 w% R* v! b8 A5 m$ K1 l! x' k
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
( s5 S8 }8 ^) \; C* ^: }- s写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
" ^/ N5 r$ @  ^, S0 \; F功能要求如下:
9 t3 R) m8 v4 c) u" b/ ?
5 O  O/ e9 H) Z: o% |+ s1、强制锁定键盘/鼠标。
$ N) Y" e- R9 l$ h! \2、可动态加/解锁
$ }$ h% U8 h0 _5 }2 z4 p3、兼容所有 NT 系列的操作系统。
+ _2 W- u4 L' b7 Z* `8 ^3 y) c$ h2 j3 v" s
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
6 Z2 I: G2 U  g& D0 p. f现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
; H; ~+ Y7 S/ ~3 o何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
: ]( s4 V7 f, K# a* w! A上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是+ T1 w0 [1 k; `
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
% S) H; U! {5 v6 L1 o就来看一下我想到的几种实现方法:
* T. P3 x  D1 V* u3 E7 b4 r( ^) w
1、全局键盘/鼠标钩子3 \( u1 V) u5 `* b' l
2、BlockInput() API
% I# t6 Z. X" A3、使用 setupapi 进行控制
) p- Y! `- m* X  s/ ~9 B4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
% e, x3 z) K: o' n9 j# A5、拦截 win23k!RawInputThread() 函数6 ?. y+ `( k/ O/ b( H2 b6 p# \9 P" G+ G
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动6 ?9 `! l; X) z# l* O! L: d! \
7、拦截 kdbclass 驱动的 driver dispatch routine) ?; i  n" A# s$ c) m- b; Z. g4 w
8、实现一个 PS/2 与 USB 键盘过滤驱动
* d- o- ^+ ^) c) M- m9 }" d3 j9 e5 d/ d5 w7 t
$ _. l. [# _9 X
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
  J" l9 @4 R( h! x% ?9 d* ]/ t  Z之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
) w, R2 }. R, A: E4 i  Q案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
* t2 x5 t/ Q' k  {" P兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
  G2 _# W( h1 M8 J; @素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
2 P  h  b& w% A6 i# \+ F$ ^; C- R问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
$ W/ [0 k; w0 |载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我' z: z9 G1 K9 ^3 l/ R
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
8 p4 k+ ~6 T- @. ]5 o也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如/ B/ ^. C: m" a1 V% O  [0 d
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有5 t! l. Q3 y% [  i9 ^6 Y, N( }* [1 U: F
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截' P8 t0 U, R1 n. `
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 8 Y: R$ \& n2 S. k; E6 d6 g
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键6 O* p0 u. z* I2 S. Y
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方7 D  ]" }2 t2 w( A% H& k3 ]7 E
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
$ [. ?: e1 w5 I+ l) K
0 p* o/ Z5 s8 ~' |% q# ]! ~
$ j& X; \  v5 j& \' ^我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
/ R( v8 ]% o: V滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进! q! N6 A: Y3 Z: w0 {
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是& W" r1 X. w8 u+ g' X5 {) V# _
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
1 O: K" G3 f! ]8 Y# ^来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从1 {- B2 W/ k" {, P
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB# ^, Z# N; G8 g+ y9 o4 B6 o: R
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
* `$ b; B% C% OIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
4 U6 e# D; c: Y: E. K我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题' @$ o& i, m0 V+ q" p
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的0 V0 x! W9 l% A
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
+ C3 H+ q  ?, C8 K( }( |用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通0 @8 G& |! q& w- T
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
7 w# Q" G) R3 W/ j/ Q& e屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
9 u) E7 h: `+ b- |& Y过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb, S0 Q' j* w: m# Y# b3 B- k3 U' N
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid ( K& M+ T& b5 v* j# R6 N1 O
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
& q$ W0 }0 e: o( t2 W味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。7 |4 u; s- I4 d( j
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们' u$ n2 O5 s% x* i) T
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利- ]5 }) r0 j$ V1 I% p* a
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
5 {+ w& B" K9 Y2 a& I) _: z的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致( \! `1 m! }" V' c5 f
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,; J2 I1 p' {/ e( B
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
. U4 |: f9 X; _' a见下面代码。2 C& F- k; @$ D7 z3 Y
8 H2 O: g( p  A% C/ @1 i/ J
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程% ~" o: {7 s1 G1 a/ f5 O
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键) \' B* E: N2 ]& G$ ?4 V
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
+ c: C3 F* l/ p3 k4 d6 H! t  E上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
! B5 d! V  A3 X$ V, {; g完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可/ M: M  E: g' M& Q  N
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
6 v7 B6 }( O" T* M; z锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
* H6 R7 P9 P2 K4 }: X7 f: {键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
+ o2 E: c: }+ K/ M& f4 ]5 h0 b, L; \

8 \. ^- y5 d" x完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用/ _( [; Z- l0 _' ~
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
9 J4 L9 j! \9 @+ O/ U1 p9 f可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
+ T) L- ^8 L4 ~6 |3 s的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
$ P3 S* v+ B5 o8 S们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我2 Z9 L! ^/ B0 e/ B5 n% }) E
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension; I  a4 `: ~5 C: Z
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。/ o% L! n: i, y( X/ u8 ~
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
% j3 J  e4 a& J; m6 P进行操作了。这个问题有待大家来完善了。7 Z" Z. n$ i: A) {" D$ j

# S$ H; P: z5 R' j& \
9 ?* ?$ S. J5 a要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
+ P" D* s0 N0 O& f: m( x来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
5 Z1 s0 w- P, Q' J分析做个记录而已。我更愿意把它看做是一段注释。0 e+ U) o% A' p& i

: x# C# K0 M2 F( B最后在此代码中要- S- W" c# b" W$ `  o
- }: g) o/ W8 \0 T4 Y; [/ u* ^
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。  p* @5 I( a" D) W9 b
+ s$ o! K. o8 ^0 j, \- G- s
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
5 i, S- j% g, Y6 `  L/ a  F
: P4 w8 q9 k2 ~+ `& R5 n感谢:齐佳佳,过节请我吃好吃的。
  W, v! O& k; J3 w* Y! H% p" S
) k1 Z; S' }! x" k+ f5 C  `" x7 |
******************************************************************/4 c# g6 h- }0 G' K

7 N  Y  x6 T4 t5 f. V6 U0 m( M5 ?7 ~0 c
/*****************************************************************6 A* F0 Z3 S  I
文件名        : WssLockKey.c0 m% z1 ?0 n4 G0 I* W- K" m% A
描述          : 键盘过滤驱动3 W- }' T# J/ p
作者          : sinister
3 [+ J% u0 [2 a9 P  K, [ 最后修改日期  : 2007-02-26
  u& v: l) _3 B$ S, ~( m7 h*****************************************************************/
( f: \" b6 [' t( |6 Y2 P1 g3 D. v1 l" I& s( D7 g

6 b7 x& [9 ]: z4 `# h( l) e#include "WssLockKey.h"
! W; [+ g4 Y4 I4 k7 a* V$ n7 k$ a( q8 v% i
NTSTATUS4 S% Y! N  g8 x. z1 {5 c  r  P
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
' @$ O/ j6 K  A2 U3 V2 Z- m% C$ |             IN PUNICODE_STRING RegistryPath )( r3 l* P0 O7 o8 ^' y  e# F" h
{: _9 k( A+ Z6 a" j6 X3 @
  UNICODE_STRING KeyDeviceName;
' p  R8 }; ~: Z! t8 ^$ k" ^  PDRIVER_OBJECT KeyDriver;
6 {. u+ q# C. Y+ B& K  PDEVICE_OBJECT UsbDeviceObject;
" w8 q. u1 {- d- ~9 Y0 F  NTSTATUS ntStatus; - S; p* S  `$ o
  ULONG i;
. `  I6 B! q- O; d% E  v+ q  ~+ I/ T+ V+ P& ^9 ]
  //
* X: X/ g* U$ D# F9 V/ @) Q  // 保存设备名,调试使用
* H. p* Q6 O! f" v/ M' E  //
" ?& x9 |+ |: p+ ^1 U  WCHAR szDeviceName[MAXLEN + MAXLEN] =" w$ _4 A* a# l1 i8 s; f, C4 f
  {
) `- k1 \  L4 |  G, F    0
  {/ A) W6 n* i8 M) }  };
+ y% Q6 D$ ]: W5 @1 n5 P1 q, I4 h# ~% a- a
  KeyDriverObject->DriverUnload = KeyDriverUnload;
  T9 ]/ F4 v- h: P
" _4 b; g0 C% \3 r7 K$ E  //0 O9 H0 H3 x0 [8 o* X# p8 W
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
" h( f9 B1 i3 u% I  //
6 f9 F, q* k) r! k4 M  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法  M4 q4 L$ q9 t( V1 X7 t
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其0 j; x2 v% U2 D4 B
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
0 m* ]6 q! d9 t  n3 @! D  // USB 键盘设备来进行挂接# X6 \* h4 t3 q; \, r. O3 M
  //
7 q0 G0 d0 _5 E6 Q. u* B  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
8 P$ n% b! K' |, Q  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )9 u: }$ m2 a* N& y- a$ h7 Q3 Y
  {2 Q" t2 U5 |3 T6 m* {9 B4 e9 ?
    //9 K) @% R& w! g0 L: c0 t
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
/ L, m+ @0 r% |  l2 G    // 所以这里打印为空
' e* u9 W$ \( M' S+ l8 u    //6 R% W& }, M' D, j4 W) j/ P# b' o
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
  J7 s6 g; Y; h" B* t    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
: G$ h: ~7 m- M( V( G8 w4 C/ |( {8 W
    //" I+ B, x0 p# m, @. q; o
    // 挂接 USB 键盘设备
0 ^* H7 Q9 P7 c9 c; J    //0 s- G2 m( n; x0 ?: G# ]
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
+ r8 [& k2 [* O1 D1 u  I    if ( !NT_SUCCESS( ntStatus ) ): B+ f+ H! I7 k: k# J& {* q( K6 n
    {1 M  G; v" H, I/ L3 h$ L$ C  ~3 @
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );3 [" J8 |6 a7 |( Y& t; v* L5 g1 \1 l
      return STATUS_INSUFFICIENT_RESOURCES;9 e$ q0 C* Z( R  h# b
    }' r7 ^6 n+ S3 g7 d' ]' F
  }  _3 U& f% W9 J; J+ _, H
  else3 O- b# |; d$ b0 ]" _# y
  {
% Z! F+ Y7 ^6 j    //* D9 M4 M; y( k. P& P
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备5 \$ m5 U; ~; L
    // . v4 t2 k& p5 O+ m5 h$ B+ U
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 0 K5 J2 k% ~  o$ b) j
) c, r8 p% i  {" r* U8 D
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
3 ]0 \/ O0 l8 v7 |2 N                                        KeyDriverObject,
+ _- u% r" I8 g5 P7 L+ F0 z: v                                        &KeyDriver );
4 P" r- }6 [7 K/ B) p- e    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )0 h+ g, M( r3 Q4 w) d
    {5 F3 }1 o) t! b: X' L$ X
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );- ~, ~- l" i' ~" e8 l* E
      return STATUS_INSUFFICIENT_RESOURCES;  T, k! Y) L$ @) T0 }( b& _
    }) e# d( H: t  A1 S4 x  a
  }
* d: x3 d6 }% e
& ~9 h/ ~* q2 e# p& M3 ^  //7 G& u, q) |# o
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止/ T- a% N4 v- F8 k$ i  b5 i
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
) |( S2 {+ B4 l6 Z$ @4 Z, v  //4 v, _) q# o2 P4 B& g2 B4 c
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; ( D& p9 Q2 y- R
# K4 T" }0 |$ Z7 e- d
  return STATUS_SUCCESS;# u. j; s  ^& [) o) c8 H
}
% Z* G- f) J) H1 l8 z
" p" B; N6 @# R! Y$ d/////////////////////////////////////////////////////////////////7 ^2 d% C4 N! o+ b
// 函数类型 : 系统函数  A$ O4 ]  h$ l- Z$ }0 G
// 函数模块 : 键盘过滤模块
- `/ D+ j2 W; f  Y0 h8 G9 \////////////////////////////////////////////////////////////////
7 m/ u+ a  v+ \9 F// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,; T  z6 \* m+ [0 c- I" G
//        卸载键盘过滤驱动
8 K) {8 a6 I1 _' i' H// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
6 B4 Q/ }( n& `8 @- Z//        则需要等待用户按键,以后有待完善* X4 U& T' A( ^
/////////////////////////////////////////////////////////////////; u3 U: W: ^( g) V7 W
// 作者 : sinister
3 m+ K* B/ s0 h1 B9 L6 z// 发布版本 : 1.00.00
3 }: Y" s1 H+ H9 a. J. U9 [// 发布日期 : 2005.12.27# A# L) f3 K, B9 K( L
/////////////////////////////////////////////////////////////////
/ y2 U1 c$ D  A# ^" {// 重   大   修   改   历   史
- s- W; H. i! `0 \////////////////////////////////////////////////////////////////7 a# A0 J- l! v) a
// 修改者 :& Y1 H- Z2 J# O& P2 I$ E9 M: j
// 修改日期 :8 F+ i* g+ B/ o. G
// 修改内容 :
7 i( Q; M4 g, F- t/////////////////////////////////////////////////////////////////
  z/ N" A1 [6 p$ Q) x" i  v, R* _2 T
. O4 |; X- C. s0 IVOID
; j) U+ P# P. VKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
7 @5 K6 _5 v, x# A$ t{
1 H$ \; M8 ?- X  n  PDEVICE_OBJECT KeyFilterDevice ;      
' d) s( X  {6 F' q  N  G  PDEVICE_OBJECT KeyDevice ;
" n1 |2 D  O5 @, e2 n  PDEVICE_EXTENSION KeyExtension; ( X$ X0 L; z1 x1 U
  PIRP Irp;
1 e$ b$ c6 y0 m; {  NTSTATUS ntStatus;% w# N4 \9 i6 b

, Z" I# p5 |7 V" \& s  KeyFilterDevice = KeyDriver->DeviceObject;
. H% X5 w( V$ ?) B' f% \. ^  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
8 a: s& s* D7 Y$ C  KeyDevice = KeyExtension->TargetDevice;
' v! m0 H6 f; z( a1 x% a% |( Q1 l" N4 B  ?" L
  IoDetachDevice( KeyDevice ); 8 p- G% k8 D6 G% S
+ [! s9 z9 {! Y0 Y
  //; d/ c  k" A/ f) K- C6 i$ b
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP3 K4 c6 W+ Z8 Z0 |. E9 O  V; \% O
  //1 M+ H$ K6 H1 B0 ?+ O1 l
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )6 o3 Y. b% }# B. F$ A3 r! Z
  {% A0 F0 R  j' V  Z2 w# k
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
( B1 Q2 u1 E# p! b$ R' `8 s    {* j$ N/ J$ ~) p* O4 n" H
      //
4 d' P) E" x& |9 K# _      // 成功则直接退出删除键盘过滤设备7 l  O6 ~. {' b4 n) Q
      //
5 j- ^4 B$ d% d9 M; @% k8 o      DbgPrint( "CancelKeyboardIrp() is ok\n" );
9 z+ g3 }0 C/ s      goto __End;+ T1 Q/ i+ B. @/ D/ |+ y! ~
    }
7 i& N3 F2 K8 v. y! g3 h  }) m' G1 L: \# U4 b- B  M. x

  X( v9 N9 L' J- X' J7 E  //
+ d$ n2 `  H8 ^7 r  // 如果取消失败,则一直等待按键: }% O1 N% @7 U$ F2 O
  //
1 z' m% K* J; ~- A, p4 o- [  while ( KeyExtension->IrpsInProgress > 0 )
" L9 k# J/ _/ K+ j  _7 a6 k  {9 o. Z: T) m  i# k3 n
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
) ~: |& t4 Y" {' a  }' c( s  A8 V$ S! o& ^) _  |+ X
; ~7 B8 M' u5 s) v( |8 |
  __End:. n4 X" T( ?. S! c# b) [- M! b
  IoDeleteDevice( KeyFilterDevice );
7 T3 g: u. J8 s6 S0 T1 w" {! a+ j; m9 d- J
  return ;; i, A1 |$ I1 L: b2 c) |4 f/ E
}
+ K3 m; ?3 X" N! U# T
8 l2 b: H+ x$ R; h9 z: H1 Z/////////////////////////////////////////////////////////////////1 Y* d8 `3 ?, Z5 `, C- I
// 函数类型 : 自定义工具函数" B) U+ ^# `" J7 G$ ^
// 函数模块 : 键盘过滤模块
0 B8 B) ?- S0 p9 j; Z2 d/////////////////////////////////////////////////////////////////, z/ \' v; F% f' H: _
// 功能 : 取消 IRP 操作3 h, I- I8 N( V( A+ [
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
  O+ r# y) v( E/ q& |5 w//        使用此方法来取消 IRP8 d% X$ f4 A% D$ ~  D7 ]
/////////////////////////////////////////////////////////////////. j  ~6 }/ s6 J- |' Q
// 作者 : sinister$ z7 M$ h5 j3 n. k
// 发布版本 : 1.00.00
6 G1 a% {4 s5 q& a3 H8 p/ t// 发布日期 : 2007.02.20
& Z8 G$ E- U& h3 g- T# V+ F; ^/////////////////////////////////////////////////////////////////7 l$ @5 d( {' f6 G5 X7 V
// 重   大   修   改   历   史" m' P) }$ {$ m& t  ?8 l, d/ X
/////////////////////////////////////////////////////////////////
. @" p, X' D2 `7 p2 \! X% W// 修改者 :
$ J+ w1 ]! d7 M+ Q// 修改日期 : ' u  s, I2 L8 T1 E0 w# Q
// 修改内容 :
9 \) U2 T4 _. J/////////////////////////////////////////////////////////////////
6 }4 t; _2 O! {
/ W" ^3 k0 u) |- l/ u7 KBOOLEAN
2 _- y- `. \! c' L* x+ T, }! J4 Q& r* H: B( UCancelKeyboardIrp( IN PIRP Irp )' u, `4 b7 Q2 P, g7 n% a
{
) h& k! V( \* a; i  if ( Irp == NULL )" G/ }2 U% e8 U2 Q( T% u/ b
  {
& z- r4 P; ?$ m" n- m) i    DbgPrint( "CancelKeyboardIrp: Irp error\n" );& M2 q% `& W5 z4 c6 R
    return FALSE;% }  p, N9 d+ t
  }" v, @2 t3 ~, O4 r. j+ U
9 \! C4 N% T( x3 O* e. v/ V

! u# b! X0 z' R. u$ ^9 X$ P  //
: t+ e4 [5 U" Y: J9 v- |# B  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
3 h2 g* d! a. C7 H. U  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
5 {. R( p: U6 a& _+ L, l2 J: r  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占( P# ?* U' f) ~' o6 M- _4 z
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD; g- y7 n$ u2 y' ~0 d2 g
  //
* S% r2 k8 H/ Q; u0 |
) ^$ G! B. H  N/ v  //" r- X/ ~4 s+ j$ C
  // 如果正在取消或没有取消例程则直接返回 FALSE
0 l  a! a: |6 h  //9 u) j: b4 w$ y  R+ r9 ]# d
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
6 B% d+ Y+ @' G, D  {
+ d% ~. E9 N) m' ^; A6 R    DbgPrint( "Can't Cancel the irp\n" );" g# }$ k: ~) ^- ]  A) a; r
    return FALSE;
7 R% I1 Z5 X+ @( Y: a6 e9 Q  }, F7 {; o: u- F! \- E0 O

, b+ Z# B# A# p  if ( FALSE == IoCancelIrp( Irp ) )
, ~; [- B% h- Z) A% H  {) f8 q# t5 a' Q4 d+ l5 ^
    DbgPrint( "IoCancelIrp() to failed\n" );
7 d# z8 x5 K2 t    return FALSE;9 O( D0 \7 Z6 X8 Y' p9 ^/ F
  }
, X+ t3 i: b& v0 \) Q* j9 ?9 s! s! r% H' f) W& [1 \
  //
' W! r% {$ [4 o  K' X  // 取消后重设此例程为空9 T7 S$ ^7 @3 o7 U4 h9 \# {
  //; Z3 d5 @5 [7 \4 u! K
  IoSetCancelRoutine( Irp, NULL );
8 T8 r3 V* R; X
+ R+ H# I: M: }2 `  return TRUE;
+ R/ W3 r/ S0 E* ?% z}
: ?. C; y1 g. A' ?/ B  ~1 \: W) M9 x6 w# c# r& x" i# e# H( j+ M
/////////////////////////////////////////////////////////////////5 q/ u5 @* `3 c) x& }. K& E$ ~
// 函数类型 : 自定义工具函数
- P0 I2 V. u, T// 函数模块 : 设备栈信息模块
5 B6 |  Z$ {/ ^( r  p" a/////////////////////////////////////////////////////////////////9 r+ o# C' S( n' V* b
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
( c3 [) [7 [) t. \9 D) `7 O//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
7 ^* e* |' q: T* n% |// 注意 :
* \6 |7 i  x% M/////////////////////////////////////////////////////////////////
* }' c: L! w7 K- {" Y# i& w// 作者 : sinister% P8 J% t8 |7 x, U1 _2 {
// 发布版本 : 1.00.00
8 [* H* P" d2 J' Q// 发布日期 : 2005.06.022 F# h1 v/ ]9 Q) W
/////////////////////////////////////////////////////////////////
$ m' L6 R- i% v/ o+ |// 重   大   修   改   历   史
' D7 c" B3 R. R9 l1 t. u% S/////////////////////////////////////////////////////////////////8 j" v. F4 `6 v* J; f5 A* Y9 C6 D# B
// 修改者 : sinister# F2 F; C3 y% ]1 n" O
// 修改日期 : 2007.2.12
( A6 U- y1 J, U// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改7 z& H* C) V/ ]0 h: l
/////////////////////////////////////////////////////////////////
- V0 {% T3 |$ W7 e5 B! I, F" S
BOOLEAN$ t# N7 q" S& n
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
8 o# {8 D! C6 }# F{2 @2 S% I  k& l5 J5 c
  PDEVICE_OBJECT DeviceObject;: A9 z. x+ U9 m9 e, ^
  BOOLEAN bFound = FALSE;! y) u' h4 R1 G( x' R  m/ f' A

) `+ \0 J- X  j) _4 u  if ( DevObj == NULL )0 Y+ U% _8 ?  j& K& Q
  {# a/ F1 D3 ?2 S5 M. l
    DbgPrint( "DevObj is NULL!\n" );) d; d0 E4 U6 }! F2 z! E+ u
    return FALSE;
4 M, x3 s5 Y; o2 c! s: g  }" r6 n" T! t) @) }
# j7 A  S) J/ p; e5 K
  DeviceObject = DevObj->AttachedDevice;$ K0 k" Q' i8 Q- w! j; t# T6 y& G

0 P  ], R' ?+ X1 V1 g0 {- I  while ( DeviceObject )! g% U, C' c! w
  {
  l( e9 M, ^& x& `5 p    //7 H9 Y/ n) l6 ~& i) W
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
0 R$ C: C6 q& R$ Z- o7 P6 |1 z) b# R    // 有一次足够了。这算是经验之谈. p6 x( t5 d+ E; Q4 J4 ~+ _- {
    //
. w9 ^! x4 C2 _    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )8 P( Q2 r7 w8 I( s
    {9 j3 [) w: [7 w  b  a
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",1 I; b- Y: A' K( H4 b
                DeviceObject->DriverObject->DriverName.Buffer,
* `1 e6 e5 p! `/ x' }                DeviceObject->DriverObject,' q% V# B2 y7 z" i1 I; `! c7 y8 s: j* b
                DeviceObject );
7 A( s! J* a" Y9 H
# K. Y. y: q! i' K- I+ M% B      //0 d* ?* C' t1 q
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
5 y/ z/ {- x" J$ z$ J$ c      //
# E) l, I! v& L4 ]5 A$ G      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,* e* \# E/ x. z3 g
                      KDBDEVICENAME,
& q" ^6 ^5 M3 h6 Z# j- u! Y                      wcslen( KDBDEVICENAME ) ) == 0 )  P& P5 E; e' K2 X) O
      {9 r$ A) q0 e. G. }/ a+ I
        DbgPrint( "Found kbdhid Device\n" );
- m& y/ d/ a) ]8 H5 x# @        bFound = TRUE;
: J* g+ K3 j; }        break;
5 F5 S( R9 f' x( z1 W      }
" b0 ~& Q" A4 x3 r    }3 |3 f( O  y+ o# y2 X1 r$ j
+ n4 k5 V/ x  u* u3 @/ j  F/ p
    DeviceObject = DeviceObject->AttachedDevice;
: W3 T- v; Y) B  }2 V. g1 h2 L! J3 w

% t" O2 ]3 F( K/ k1 s( U& A  return bFound;
4 Y9 i/ Q2 E, y/ s1 i}
, r/ J; q# ]2 i
5 F8 j/ u9 P: s3 z" K7 N/////////////////////////////////////////////////////////////////
! y% ~, P# v: `/ t9 x// 函数类型 : 自定义工具函数& ]5 M) N$ @# ]/ y& N- M
// 函数模块 : 设备栈信息模块! c* V, ]. Z, \7 |9 |0 R
/////////////////////////////////////////////////////////////////  p- S- n1 _- [4 Z, ?' l5 S
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
2 P1 \* |/ ~8 w1 a// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
9 A! |% h$ E( N" H7 o/////////////////////////////////////////////////////////////////
/ }" l3 k) o$ G( X( q4 ^) j// 作者 : sinister
8 v4 U& U( k0 u; k  C, R// 发布版本 : 1.00.00
6 h8 c6 Y- S7 B' N// 发布日期 : 2006.05.027 e* \4 s9 q: V, m* s  _
/////////////////////////////////////////////////////////////////
9 q% ]; o7 u9 Q& p6 r9 ?+ Y// 重   大   修   改   历   史
. M- F8 H4 {8 Q/ K6 W/////////////////////////////////////////////////////////////////# U& X; J6 v( n
// 修改者 : sinister6 T6 `- l/ q+ |, B' Y" O! @1 }
// 修改日期 : 2007.2.12
& B, b7 n/ R) g// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用4 c8 Z  X5 u& \* J. f' }- V
/////////////////////////////////////////////////////////////////
" J0 E4 v0 {6 @/ ]3 y) l
7 R$ E. ~4 n* K7 F5 d( V; D  f& DVOID
: X: x$ w* b8 C% @8 n* HGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
! y% h% k, {+ h# {, q. \{2 [* t2 g3 j4 V! d: J% o
  POBJECT_HEADER ObjectHeader;1 k' T2 W( @1 D& A9 U
  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 2 u" j. p/ d! c% v2 M

& i5 k% E* J1 _, C) K  if ( DevObj == NULL )+ _9 \0 }2 S/ p5 \
  {
# m, g$ j7 E7 H; a) l! x    DbgPrint( "DevObj is NULL!\n" );
: T* A8 L" ~9 _% b    return;2 Q8 j5 j' j+ K# P) x( ?7 c9 ^( ?
  }2 }7 y0 X3 q, N8 Z% B+ ~
* I( L) V: t4 A+ ~7 h1 |
  //
5 o% N0 ~: L% F& y. C3 I  // 得到对象头* |/ D  H$ j/ G0 @
  //* B) T' L- O8 e7 O1 `
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );! [7 |7 S: h2 Z

6 }* q* [% `8 o) t* s  ^! v8 T  if ( ObjectHeader )$ o2 E+ o* `! }) ~3 \
  {' R  w" j6 R4 B
    //
9 ]8 ?7 G9 e. r    // 查询设备名称并打印7 l6 I5 q2 O1 v
    //" C+ Z1 q( R1 c+ v. Y
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );* J. Y: i1 ?# U* ?3 D
0 S) Y+ y/ ^& [3 m  C. n* h
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
9 f2 j& |) h4 E  b4 c% n& l" B    {
' Q! a6 l9 Z1 n, g/ ?3 O5 H      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
+ p* N, }5 J4 y                ObjectNameInfo->Name.Buffer,* m- e7 j: D7 v) c3 O' ]
                DevObj );2 n$ m, J" G4 i7 k. x4 j$ e0 }
0 S$ ^" p; V7 Y2 V) @' F3 F- H% C
      //8 V( `' m! J/ K# t) S
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
# H( W8 w+ k: w5 a' m: G- }      // 用,没有实际的功能用途
" [/ J+ b' {! v1 |      //
$ M& G" z* D% o# x% G      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );( g) v. t( C# q* n
# y' h2 l( f! R. J
      wcsncpy( szUsbDeviceName,9 z: T/ F6 B6 E- P' S+ j
               ObjectNameInfo->Name.Buffer,
2 i# i% \6 e7 V) W+ y               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );3 o! D2 r! P8 L0 r/ T
    }
9 G9 g5 s2 x* ]2 t* I  G
! \% J8 ]1 }, p0 ^% Y- x" b2 @& B    //2 A& e3 v  w; S5 m7 c9 x0 P
    // 对于没有名称的设备,则打印 NULL
* w2 v* b3 c# M+ i8 y7 N    //
( r, n: s" \; S. i8 i8 j, C+ r    else if ( DevObj->DriverObject )9 z, P: Y$ ?- K/ y- V1 e0 o
    {
% }" m* c/ E: s. _/ S/ l+ @7 H! g; t      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",5 u. b9 s3 q! q* g3 P1 I5 P
                DevObj->DriverObject->DriverName.Buffer,( {6 t& ]5 m* T6 {0 u( F3 }
                L"NULL",
7 {# n5 k" ]+ v2 z/ I) b                DevObj->DriverObject,
. w0 Y& ~6 s! Z# o# r1 B                DevObj );/ f2 m9 D1 x* r" ?
    }
, h& A4 Z* Y5 F, ^( z2 s  }
0 g; f' G2 j2 _# |" |0 ~$ h- W}! J( y3 r, F* `1 P. k

$ m" x8 }, k/ k1 ^4 L' U1 R' _1 s3 D/////////////////////////////////////////////////////////////////) a5 \: M1 R6 j% B$ r6 T7 O2 T
// 函数类型 : 自定义工具函数
2 ^! R: h, C1 H// 函数模块 : 键盘过滤模块' ?* o1 E! W% z  e- F' ]; e" K
/////////////////////////////////////////////////////////////////; ~7 a* _' ^" x
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备3 F+ ~4 a1 z6 C* F2 Y: X
//        对象,过滤出 USB 键盘设备,将其设备对象返回
: M! G( z+ E- ]2 j// 注意 : % r0 R% V; }  a! v2 I- H9 s
/////////////////////////////////////////////////////////////////1 {5 L  @$ g# `& j5 n( o
// 作者 : sinister- u. Z6 j/ x) ^
// 发布版本 : 1.00.003 J# Q; x6 d+ M$ ~* X
// 发布日期 : 2007.02.13; F4 Z+ ?! _2 b  u; S
/////////////////////////////////////////////////////////////////
) D8 e, t( i: r, w! L// 重   大   修   改   历   史
( Z8 _4 \' k$ H, q& [5 n/////////////////////////////////////////////////////////////////
+ w8 f2 z* R4 x; j1 Z% u( R// 修改者 :
4 J9 z+ x: d: r% z4 s! p// 修改日期 :
7 ~% o7 A  @5 U// 修改内容 : $ b6 i; a6 B4 i5 M
/////////////////////////////////////////////////////////////////
' K8 i5 M  j# b% ?1 c2 J
& i9 `) }: f. dNTSTATUS! @) V0 Y$ H0 s
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )# I# F; s3 A/ R
{
+ B! [+ C2 q* D9 ~  UNICODE_STRING DriverName;0 h$ c* Y8 h3 M5 p
  PDRIVER_OBJECT DriverObject = NULL;" r% ]1 x) m% |9 ^8 W% f+ t
  PDEVICE_OBJECT DeviceObject = NULL;
' L1 V1 q$ m% x7 q7 B: y  BOOLEAN bFound = FALSE;
  C* ~% _9 R! P, M  X
7 j& K2 X9 {! K; K8 _* c5 c. I; u  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );3 p  d& X, @2 F7 R/ L/ g7 [9 h. J

$ x1 V. Y5 f7 \0 c, R& Z1 u  ObReferenceObjectByName( &DriverName,
- I$ H, M& X8 d: R5 W, G                           OBJ_CASE_INSENSITIVE,+ ~0 o, B) w" I$ v9 P
                           NULL,
7 g8 L% P) F8 Y* X                           0,1 F; F: ]7 r* C2 z7 J% j; M
                           ( POBJECT_TYPE ) IoDriverObjectType,
; V4 P7 J2 C9 j                           KernelMode,
1 o* I4 ?/ J" |$ F& z                           NULL,3 x1 w$ U7 l* V9 ^  l
                           &DriverObject );: ]9 K4 l- H/ y& I! u2 r4 U

3 j* `/ @3 z6 h8 T  if ( DriverObject == NULL ). T$ R2 |- {3 O8 d6 a% w* A* G
  {
( J% ~  U  [: Z5 M8 h5 b8 ]    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );: a" @9 w6 p& [$ h
    return STATUS_UNSUCCESSFUL;0 R9 [( A" _  n; ]( K
  }
# I# u, c8 s; c  @. d
* \+ E( i: G% g/ i' o; ]* n  DeviceObject = DriverObject->DeviceObject;
1 @, I5 S. S/ @5 Z6 A: P1 a
1 ^1 N0 B: k9 O6 E; C$ H2 @9 r0 x  while ( DeviceObject )
& ^, V1 k# Z# g3 d+ F. a  {
; Y' u: b' z6 Q7 y9 E    GetDeviceObjectInfo( DeviceObject );
* W( I/ A6 F% |+ T/ t
! r, F# J/ |% T) X$ M: g    if ( DeviceObject->AttachedDevice )$ }: Q6 `- I( o
    {
3 p, w5 ~( @" ~* Y/ S! n. [  ~+ C      //3 Z$ V  K" }4 s; X5 L9 x4 p( k
      // 查找 USB 键盘设备! }# v  n% Y' B6 `' q  W  n
      //
/ z" K  B" \  s9 W2 g      if ( GetAttachedDeviceInfo( DeviceObject ) )' g8 r( q6 ^/ O8 r% U2 V  _4 W$ x
      {
( |  F8 u9 d/ i, c' L* B        bFound = TRUE;
- @8 ^  }4 S7 e6 ?, M7 l: _( f        goto __End;& y5 I; k" R: e5 w4 \( j: I- g& {! E
      }
! A6 {# n' b- [) i    }
* d  U2 ], P$ a9 _+ S- w1 J
" e0 m# z4 M" a. ?( ^+ b    DeviceObject = DeviceObject->NextDevice;
8 I& ]! K4 O/ _" w8 Q! Y! Z# p  }: f# j' N, w+ t2 Q

' ]" v4 }2 w7 x  T# O  __End:
" ?1 N9 [* p" K3 Y# N# g
+ ^9 g8 t) K8 \. C$ f/ }7 H  if ( bFound )) G6 j* G7 b0 W1 s
  {  s9 O) k8 u5 v3 L4 @* o( y3 y
    //
9 B; F" k; P9 _7 K' Y1 a    // 找到则返回 USB 键盘设备对象) H. L) L+ D, T$ Z
    //
& S* m- y$ y+ {& e. Q9 K+ o    *UsbDeviceObject = DeviceObject;
" t) o8 N( y% d" J, ~  }( [3 E9 Y2 k) f
  else: p& P! [, f# ?! H" ^6 A" D
  {
. b& r' |2 Z9 f3 K. P    *UsbDeviceObject = NULL;
4 E6 k8 e, J! Y" h  }
8 K3 r5 l& u9 h! n+ ~
5 t$ A. M9 G7 O, y* v( I' h  return STATUS_SUCCESS;
0 E; L' z/ |! Y}: P/ s( J: H  J  D  r% @( l$ t( W
, V  g9 n  {  ^) V$ H+ B
/////////////////////////////////////////////////////////////////* @7 f2 Z5 n0 w+ w% v
// 函数类型 : 自定义工具函数
3 j9 l6 G9 S2 R/ e* X2 O// 函数模块 : 键盘过滤模块
7 ^0 t. B, {5 F, b* {////////////////////////////////////////////////////////////////. h* Y% y' a  u% M# w
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
/ r8 I/ z5 G/ p$ d. b! ]! L//        信息,返回附加后的驱动对象- `. H( J. C6 M  {8 ~: d4 L
// 注意 : 此函数仅挂接 USB 键盘设备
1 M7 {! @# ]/ T/////////////////////////////////////////////////////////////////
8 ]  k: L: `# Z1 |/ I( y* K: R. P// 作者 : sinister8 {$ ]8 W* R4 r4 J# e! j
// 发布版本 : 1.00.00
3 C: ?+ g4 n  E7 Z7 @6 T5 c0 j% ?// 发布日期 : 2005.12.27* @1 k% `0 v/ P% [' f
/////////////////////////////////////////////////////////////////
0 {; Y0 P3 j/ b  K6 [// 重   大   修   改   历   史; c4 `4 D# ]: x' V1 p
////////////////////////////////////////////////////////////////
2 i: k6 u. B. O5 t4 b2 Z1 d5 L# v% @// 修改者 :
1 _" i5 Q6 z. f$ {1 t  a// 修改日期 :
' Y% e/ b0 b$ t6 w* l// 修改内容 :# ~+ v0 k  f6 V. t- h. V. f. c
/////////////////////////////////////////////////////////////////
1 W/ y) S# V) l6 u& K- x% N
& q& j  i3 w! Y) s: Z! WNTSTATUS  f  A5 G6 p1 [1 r3 h( @( v/ t* Q# l
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
$ {* u' C+ f; C4 U4 ]                         IN PDRIVER_OBJECT  DriverObject )) ]  X1 _. y+ Q+ t+ [/ u- }6 f
{; O; |! q+ M) c/ k( g" [2 s
  PDEVICE_OBJECT DeviceObject; 9 J1 B( Y) g' x
  PDEVICE_OBJECT TargetDevice; 6 W  v, t0 ~  Q3 S
  PDEVICE_EXTENSION DevExt;, \/ J9 n! Y) b
  NTSTATUS ntStatus;
. Y" ~: o5 K2 m: X5 S; H9 m- V: A; }; \8 `: O/ X
  //
# K8 p- a  ~. V" u+ ?  // 创建过滤设备对象3 ^) D% S! K. z: q' V7 m8 Q9 R; o
  //
+ \* r8 d; z# `, v  ntStatus = IoCreateDevice( DriverObject,+ n& r- v9 C, v
                             sizeof( DEVICE_EXTENSION ),
8 N8 r1 u* |  M" Z                             NULL,
7 u2 S! ~% t* o, D- n: n2 m                             FILE_DEVICE_UNKNOWN,
# f9 |! L5 h. {6 k! ?( {1 m* |                             0,' V8 g9 U, w" \9 Y' a! @
                             FALSE,. X' n  M7 u! |& K
                             &DeviceObject ); 5 h6 M" W8 c% [! \' G' `" K6 _

2 {: i8 I+ V7 y* k3 A  if ( !NT_SUCCESS( ntStatus ) )
- L% t( s# c' w& R  {" a0 E. T5 F. w  V; ]9 n* X
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
( J, D5 D) s+ ]/ d. E7 f: W2 O    return ntStatus;& p1 H6 J' h- \5 R5 R
  }
# H) p/ Q: W- |4 d$ i  g4 H  z! r. D: _9 t: z  @( Y
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;7 _* J9 }0 {# o& z$ y4 @

) E. }$ ?$ m+ {, t0 w# h  //
8 x( z! R3 A; i  // 初始化自旋锁
: v( k- t+ P! w8 T0 q2 Z1 o0 m  //- g) ^8 w$ l. M, E- n; E
  KeInitializeSpinLock( &DevExt->SpinLock );
0 @# c1 n" X) y7 J- T4 m* k  B  w$ r# R* N% v3 {4 y
  //
- z+ G, t6 \+ J& t+ ~  // 初始化 IRP 计数器; \+ B5 ?4 w% K
  //
" v1 y. J8 l; B. O- q  DevExt->IrpsInProgress = 0;
0 ^9 z) j2 Q% T" d2 `0 j+ {3 G5 l1 M
  //
4 Y2 i* n& N6 X* B$ B- v) @  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象( u" S7 K. T/ d4 ~+ w+ m
  //
8 Z2 f( d, s; V/ H, ~# k" }- C2 v8 C+ f4 H) C
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 8 P) {+ C& {7 X* ]) D
  if ( !TargetDevice )$ Y, r3 n$ w# A
  {
% f( I; P6 s; R* }9 [( W! s    IoDeleteDevice( DeviceObject ); 4 J6 l7 r! ~# l& ~
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
) \- e. y  F2 A- G) |    return STATUS_INSUFFICIENT_RESOURCES;
% l( C: O8 P8 f) H0 N  } + n+ H  y3 M- V+ @/ J/ y- t( J

- S( J% D; [- U! J! Y  |( m$ l" s  //& p$ {4 A7 V0 _! |. g" e
  // 保存过滤设备信息
$ h& I0 C5 O4 o1 X% @  //
- G0 u5 M1 m7 z' a& v. M  DevExt->DeviceObject = DeviceObject;
. K- Q- k; @5 a* I& I  DevExt->TargetDevice = TargetDevice;
% J+ q8 K8 n' |3 c2 t3 D, W
: ]& i5 a4 \1 @  //
1 W& ?4 s1 {& }4 d+ h  // 设置过滤设备相关信息与标志
0 J5 A" {4 _5 I7 N6 n* ^, C8 a  //) k2 Q  W. u( |' l
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );8 L4 }0 {5 j% _; X' L/ Z
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;; n3 F" I9 z2 d5 o. W* a! T

- e0 _* @# f  c: _
/ J6 g9 a8 p% u! M  return STATUS_SUCCESS;
2 U/ t8 @/ G  z( L) c! v}7 `6 Y4 l1 T  j
1 N* m0 z3 W: Q5 ?! d5 N
/////////////////////////////////////////////////////////////////
& H" U5 r# L2 m; t( M. w6 F// 函数类型 : 自定义工具函数
, a* a8 i" A: u" ~. K5 O0 u  x$ m// 函数模块 : 键盘过滤模块8 _' C! a# W" f$ F. f
////////////////////////////////////////////////////////////////# U1 b& u8 o2 q  v
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
, x: b0 V4 F3 L1 B: |/ I//        信息,返回附加后的驱动对象" |" d1 m; o) w% k. v  q0 F
// 注意 : 此函数仅挂接 PS/2 键盘设备* U1 S% A4 y8 H( A
/////////////////////////////////////////////////////////////////
% v9 G9 i9 T* S1 U* G// 作者 : sinister
/ x1 C. C5 M) L2 h7 c+ b// 发布版本 : 1.00.00
" t, K4 x- G# l// 发布日期 : 2005.12.27
, e* X! U' H) w2 K/////////////////////////////////////////////////////////////////
1 ~$ Q! |+ ]) l0 J// 重   大   修   改   历   史: f4 n0 \9 r# Z; `: F
////////////////////////////////////////////////////////////////4 O+ G) a! h& q
// 修改者 :1 E( {4 e9 ~: x' @. w3 H' R
// 修改日期 :
* }5 `4 \1 M; h3 k$ z# ~// 修改内容 :
# ^# i  w0 j" W# F1 T* {/////////////////////////////////////////////////////////////////
7 z! S  X& j. G/ G) R8 z- ~2 W$ M; L2 s% t3 O8 z. ~8 [5 x
NTSTATUS" g! t3 O, `. W" x& _
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
& a2 y3 D" [! F+ Q                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
: _# ?* p6 B7 }/ Z2 c, E6 \                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
% `5 q& Q& F: C9 n{
, C. g/ s: y6 B" j, \! h  PDEVICE_OBJECT DeviceObject;
& O3 ?0 h5 m$ {+ A% Y5 T  PDEVICE_OBJECT FilterDeviceObject;; G" i; Y: a3 ^( t1 ^, ?$ X* ^
  PDEVICE_OBJECT TargetDevice;
$ U" g: O2 y: H/ e- t& z5 R  PFILE_OBJECT FileObject; * @# ]; Z0 n0 \' ?; K% S
  PDEVICE_EXTENSION DevExt;
$ Y* b) O' V' X' \1 x: S- h9 U8 w1 {/ v3 }- W- e3 b* M% }
  NTSTATUS ntStatus;
* O( @5 R. d& k7 x' j/ x9 u* q  l" Y4 U
  //
- v, t7 P+ q4 j# s7 G  // 根据设备名称找到需要附加的设备对象1 h; O1 g& E) @$ x
  //
- g& B4 Z" M  [  ntStatus = IoGetDeviceObjectPointer( DeviceName,
5 x, w: s+ |) J. F9 O0 K" a) V                                       FILE_ALL_ACCESS,/ i. Z# \: r. M% o2 T
                                       &FileObject,/ I$ s. i: A% k# y, d5 o
                                       &DeviceObject );
7 Z5 X; s5 W1 l+ i: L3 e5 X* i+ u; U* [, s5 u1 l5 w
  if ( !NT_SUCCESS( ntStatus ) )
4 W% O+ h0 [2 C  {
* C+ K0 _+ {  v9 ?2 i: T" j/ x    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
* J+ f8 t" L4 K" E    return ntStatus;8 K0 C' M3 t  G3 V/ o; h
  }
& |7 M  G; M( o6 a& o
" N1 c! q/ j1 Y+ }  //. {4 K- u0 Q4 o. L9 `2 ?- I
  // 创建过滤设备对象
/ E! }8 n& j1 H, H9 t$ k" o7 q  //3 w0 B# Y: z3 e
  ntStatus = IoCreateDevice( DriverObject," y5 W' m: L' b5 d3 f
                             sizeof( DEVICE_EXTENSION ),
$ \7 S! [" M6 x. j# I9 I$ f                             NULL,
6 X! h: O8 z9 ?                             FILE_DEVICE_KEYBOARD,( z$ i+ `2 \9 ?
                             0,3 q) b8 K# E- ]' g
                             FALSE,
  v1 G. [2 ]$ B8 }7 m8 ]* {/ @1 r                             &FilterDeviceObject ); 7 D7 j- C; G; G

* G8 ^+ r8 @1 s, u  if ( !NT_SUCCESS( ntStatus ) )( J$ }- g6 E4 G  g( h* D! Y
  {7 b& ?  O9 T" R$ J8 q
    ObDereferenceObject( FileObject );
# s/ ^* P5 g2 `# }9 K    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );8 w; u! v) U$ f* I+ g. u
    return ntStatus;# i$ v' j4 F  Z! {' {
  }
- ?$ G$ G& E5 t* p/ Q  b# h9 M
9 J, D5 Y( r8 f9 I. H; F0 V  //
$ b, C' K: }% a! ~  // 得到设备扩展结构,以便下面保存过滤设备信息
1 z! [# Q" g4 ^" `  //
: @6 m8 X: t& I& I& O" v  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;' J$ r1 f7 I2 r/ ?4 v4 u: s1 C, ^

& |4 s' U' p$ h. \8 C; r" D+ w& ?0 P% Z8 p. B
  //) E6 u* k6 u% \' E6 a4 C. D0 C7 s
  // 初始化自旋锁
- Y  X7 N9 m$ F  //
0 ^: c4 {) a; M  I4 z: h! |' u4 r  KeInitializeSpinLock( &DevExt->SpinLock );
3 k+ g  M  N0 R: a$ q! \# a0 d2 O" ?1 W- n
  //
% V3 V4 G: x! w  // 初始化 IRP 计数器' s) @5 O8 f6 K2 n
  //: E# v6 J% O2 A
  DevExt->IrpsInProgress = 0;7 Z9 ]) A. F+ J+ U) j' x# ^/ O4 v3 |) i

1 a: I4 C3 d5 N4 c/ l1 B  //' k3 e& P: ^$ ~8 [/ _
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象; V2 ]5 [+ ?% Y& O7 s
  //
8 w7 R; U8 p6 \& N+ z3 f5 q8 v+ J  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
$ @0 U# W% k6 x4 Y+ N. ]                                              DeviceObject );
/ P; K- a5 H( `# N; O2 h  if ( !TargetDevice )/ N) H6 b1 q8 o8 m2 I, E
  {8 @- h- j0 m0 U7 P+ m
    ObDereferenceObject( FileObject );
/ }! ?8 g/ W2 l2 N$ b! c    IoDeleteDevice( FilterDeviceObject ); - S4 i  v# }* c% v
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
( b/ G' \  ^- ^7 b/ V# u) C    return STATUS_INSUFFICIENT_RESOURCES;
( J/ d2 `5 R' p- F& r% r' ^* ?' N3 k  }
* t$ x0 J# F0 V
; t' @4 r% k3 X( k( f2 _  //
1 o. n) {: ~7 u  // 保存过滤设备信息
' \1 g& Z' @0 c! y6 F( P7 F; ^' Z  //' e/ P+ C; W! _
  DevExt->DeviceObject = FilterDeviceObject;
1 e* d, x$ c" J6 n+ A; G- [  DevExt->TargetDevice = TargetDevice;
8 k6 Y! ?: o, i- E3 n% q0 F9 a7 }  DevExt->pFilterFileObject = FileObject;! e# N; c3 L% v5 t2 _

" j' q! v0 v0 [! f# f6 r2 l% i6 |  //  c$ v0 Z, T! n/ ]- o
  // 设置过滤设备相关信息与标志/ S# c: u; R6 Q, @
  //
; D9 ~: o1 B4 _: z, h  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
/ [/ B( n9 z0 h. @  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
5 `: w# d* n$ v* R) j$ D: Y  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;# h9 X' {1 M$ b" w% c! D# s$ V! `5 D
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
/ u1 F$ h. B" N% M: P5 `% F6 y3 Y                                                         DO_BUFFERED_IO ) );
3 P+ @6 q& I( V/ Z1 @" e
( s) r  d( E" a6 g  //
; \( V: l6 l+ |, ~6 e1 P  // 返回附加后的驱动对象/ }! V: f9 L- H" m
  //( |; r2 g3 K6 ]! E9 l
  *FilterDriverObject = TargetDevice->DriverObject;
, Z2 V9 [; N8 b. g* @: O$ b+ I  P! ]. X5 @0 Y) X
  ObDereferenceObject( FileObject ); 2 N# b+ l! c8 z4 d

7 K) P) u: O) G% O: L3 p  z  return STATUS_SUCCESS;% }/ `3 J7 [3 l! q, B) c9 W2 s% c* K
}
9 `# T9 n- u, M' g
4 M& b2 N" z) ]! |4 X/////////////////////////////////////////////////////////////////
  p! `) i- n4 ~- x// 函数类型 : 自定义工具函数
% d( d. m+ t0 I9 K: i$ h2 f) T// 函数模块 : 键盘过滤模块( x4 }- {' E- @2 d5 O' r; U
////////////////////////////////////////////////////////////////
8 I7 I! v: h+ @$ L% O// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
2 v. o! D! _/ S: I1 y0 c/ j+ s: m5 }//        这个 IRP 的完成
# ?$ \: t+ q2 X1 h. K! @// 注意 :
2 y; m- H- f2 X( v: |3 d9 v/////////////////////////////////////////////////////////////////
, t0 O, N7 @6 N/ h// 作者 : sinister' k8 p) G) M0 _4 \% y' X9 P) I
// 发布版本 : 1.00.00
: _! a$ s! H3 R4 e! s9 v" }// 发布日期 : 2007.2.15. B  Y: M5 W- `; f1 c$ i
/////////////////////////////////////////////////////////////////
, m3 v3 ]% e! W0 V// 重   大   修   改   历   史
* M3 _1 Z+ h! r) e* }0 D& o: {& M////////////////////////////////////////////////////////////////
# s7 H! s3 b% M6 n) a  A// 修改者 :
! x5 `( E3 T8 ?  O& P// 修改日期 :6 a* ^( ?2 j' R7 ]5 x$ u: v
// 修改内容 :$ n. y) @7 D; r5 A7 r# Q
/////////////////////////////////////////////////////////////////
/ f) H# b2 P8 _/ d1 {! a8 q# y
. v( t% |$ G# h8 }  p9 x$ T/ BNTSTATUS) m6 S! t5 Q9 B; e
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
2 a( o: I9 k1 G& I7 [/ ]{5 n3 ~; }# ~% P0 y0 l
  NTSTATUS status; . r; b4 J* ~" l" O! W5 ?
  KIRQL IrqLevel;
8 _7 X" V3 C% [! h; W
  @! _- [, Y/ A) y8 {8 B. O$ J8 y  PDEVICE_OBJECT pDeviceObject;9 W, J, ]4 c6 ^+ n! a% o9 O, r
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )* U" X3 ]$ D' g6 ^. I
                                   DeviceObject->DeviceExtension;
2 J5 H; t) ]" }7 Q, ^1 w, [/ D
5 R+ R9 ?8 v0 [0 F- k6 b1 Y' T3 j: `1 U" a9 D: M+ |5 O) |3 S
  IoCopyCurrentIrpStackLocationToNext( Irp );
' _  ^2 a" E$ ^0 T" F
! b% w& U# w  Z# T% K5 ~  //
/ ?6 _4 H7 O7 S& m; V, F  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
0 n8 Z; Q+ ~  I5 d  //
4 {& W# \. P. l  B- Q* F- _% H  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );1 L# N9 _! N' H+ Y/ r' @6 M
  InterlockedIncrement( &KeyExtension->IrpsInProgress );2 y, F" O" @. f
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
# b- ]! l' e+ O6 j8 d+ ?8 M3 N
$ S: O+ J1 S* B+ i2 s  IoSetCompletionRoutine( Irp," Z0 i4 t5 k7 ?
                          KeyReadCompletion,
: l, {: a1 s$ f0 @" l" _9 t                          DeviceObject,9 q! h2 @& m. q; m4 f, L
                          TRUE,2 N( X: i" j  m! X8 u6 p
                          TRUE,+ h; E& {% S" r  D9 B
                          TRUE ); , Y' |0 L2 A6 G8 c

, x. b5 b/ ~# C  return IoCallDriver( KeyExtension->TargetDevice, Irp );
3 n7 o7 S9 l0 U& U" T}
- c1 n9 x) c* ?* J! z( @
& ~3 ?3 {; I1 t- G2 d; u/////////////////////////////////////////////////////////////////
4 @* ?" x- ]) w, u' X// 函数类型 :系统回调函数
, f8 E% L0 d, S// 函数模块 : 键盘过滤模块
# T: q  p; G" Y* i, \9 m) v////////////////////////////////////////////////////////////////
8 s: Y7 Y" @$ s/ h$ S* r/ _- l' m// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
% S/ D0 `4 P6 G# c. a// 注意 :
4 W* f1 S( ^% W) B/////////////////////////////////////////////////////////////////0 |/ Z1 x: x# Y6 u+ |$ F
// 作者 : sinister
  [4 S+ ~0 Z* d6 q// 发布版本 : 1.00.006 P% `- R) D9 U% J7 Q6 g
// 发布日期 : 2007.2.12
, o- F0 R# R* O- l$ M7 p8 j/ y/////////////////////////////////////////////////////////////////
% t' L/ C* R( g; V// 重   大   修   改   历   史
& H9 z7 R1 U( n7 A1 h( Y9 i////////////////////////////////////////////////////////////////
4 R& @/ T7 z) [// 修改者 :
" H, Z. l1 ?* D+ @, W$ ~// 修改日期 :
( D) O# w/ p, D! q// 修改内容 :0 X! {) p5 A  q+ P6 \  c( R
/////////////////////////////////////////////////////////////////- Q7 i# V4 M3 ]* m) z

7 O, [5 _& ~* Z9 t3 l- ]" qNTSTATUS$ o; w+ q* h6 }5 D
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,2 J6 t* {5 s" |6 ~2 h
                   IN PIRP Irp,! X+ R0 G0 v# C; C6 R
                   IN PVOID Context )
/ p4 i6 }5 `/ J{" t# M# X5 v# Y( P: m7 ]" u
  PIO_STACK_LOCATION IrpSp;
2 F9 M4 [6 ~4 G4 a& A9 l. A- s  PKEYBOARD_INPUT_DATA KeyData;6 r4 w/ U+ p% o9 D3 N4 S0 y' T5 I
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )' \) A% P* S9 R5 u6 i
                                   DeviceObject->DeviceExtension; ' m- G$ \; }" @1 E1 M9 @- ?2 M4 @
  int numKeys, i;/ L' c6 Y/ E9 [
  KIRQL IrqLevel;: k2 z# _5 P! h
) \; o& v: w: p8 R2 @" u
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
. z8 _0 R4 Z; `# l" d* v3 e, J6 I" \6 b) Z$ p5 C/ f$ i
$ x+ U6 P$ H. u5 j7 S, u
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
6 M; U$ L& v$ b3 W# @6 `; b1 V* @  {5 e$ [) I  U# j, G; A/ T5 i
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );( s" t1 [& K. I3 ~6 E
    goto __RoutineEnd;
0 ~% D  A* k7 Y, Q% J$ U  }
1 ^: t4 z* ~% R- F( U! b) G
! H2 L" y7 j& c4 ^  //
- b# C2 b* V" K% \- r  // 系统在 SystemBuffer 中保存按键信息2 n, A8 w& Y1 h5 i. R
  //6 U% r) [3 o% P# A6 S6 ~' T  Y5 H
  KeyData = Irp->AssociatedIrp.SystemBuffer;
4 i: n" b7 }: L5 u  if ( KeyData == NULL )$ M- A, g# a9 }- i* F- i- p
  {. k9 g$ q" N9 x2 o. s1 E5 y/ r4 U
    DbgPrint( "KeyData is NULL\n" );
; D4 _/ K  u- M- {6 [7 ^1 C: g! ~    goto __RoutineEnd;
: O5 W' i0 B% Y& S1 E  }
/ S' \: \2 I& w7 B
  J* l. p$ C) I5 E# h; ?* {  //0 x+ q- G3 A; ?+ i
  // 得到按键数
, ], g) k+ K0 k  //; d9 A9 d% [% B( g, s* A! W
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
; m# l* n, M0 u& Z( R7 o) G) \  if ( numKeys < 0 )+ \* W; ?: ]# r7 P& [
  {
' b# _) |! j5 ?: [3 {    DbgPrint( "numKeys less zero\n" );4 p  n4 L; M. d
    goto __RoutineEnd;6 B, s; S; M: e& G. ?
  }
3 P- A* U) x' r* q' F# ]& J+ m
; ~% F" p, u+ n) |& S5 B/ ~  //
8 U% u% \; X# Y$ S  // 使用 0 无效扫描码替换,屏蔽所有按键
, a4 p3 t* p5 D8 d( b  //
! ?  E, v3 q9 U  for ( i = 0; i < numKeys; i++ )
0 T: p5 K- U- U: e; z  {( j+ I  [& B' m, C
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );4 z4 p2 C* |8 f7 F- P( ^- Q
    KeyData[i].MakeCode = 0x00;& f/ C/ ?! v' O
  }' ]+ X' c# k  h+ l

3 D7 t. R+ D. \9 L/ f
- H! V  G' U' Q5 Q6 k' }  __RoutineEnd :
5 I% B- I* s. z1 Q& t3 ?
# I2 r' p5 {) `3 G; `9 t  if ( Irp->PendingReturned )
; }2 R1 J9 _9 D5 G* v  {
0 ]/ e3 j2 `; t4 f2 i3 O    IoMarkIrpPending( Irp );
* U6 l% x& ]  t/ A. O9 C8 k  } 5 }! e1 `3 O: W* m. D
! p5 {: @3 J2 ^0 u# h+ z9 Y
  //% N- ?' {9 e7 ?% B% x
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
7 `# c2 M) F6 Q/ U& Y& V9 R- }  //  s% Y- ^, D3 F) |) E) Z
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );: x; S9 q5 o$ C0 l5 r( h& c
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
. x# G+ r+ B# ^7 c! x# L  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );" b1 k; r( C' a& W! \  ~; K' F1 H* G

) B! |0 W3 r2 H3 E  E( b/ Q  return Irp->IoStatus.Status ;
' z" N1 \; |8 h}
6 M3 A5 j7 _8 i. X! k! w1 g
' W! M' {" M: h# w; {5 U; q3 }+ b2 C  b: R
/*****************************************************************
" x2 b# a3 \' `. [  t1 v! o 文件名        : WssLockKey.h, d: }( x5 j- V- n9 q! d
描述          : 键盘过滤驱动
: r, L! J4 N5 B) w( S8 Q& E3 m. J; ?0 A 作者          : sinister( f! r7 M9 e6 r/ z, G( e. e
最后修改日期  : 2007-02-26
* ~8 o- |% M" j8 Q*****************************************************************/
& v6 r, P* U( q# Q0 S0 Q2 W1 B
0 D' c8 l" a  K#ifndef __WSS_LOCKKEY_H_
0 A4 y0 R! Q+ Y+ c#define __WSS_LOCKKEY_H_5 t) q" n% e' q) s: K% `, ^/ i
4 p0 A* E9 r3 m6 [  ^+ a; F
#include "ntddk.h"
- j! ]- L- K$ k. e#include "ntddkbd.h"! I0 m4 }3 b8 d) J. a8 Z& |+ J# t
#include "string.h"# O. u+ L2 F' D( R8 N
#include
$ s# z# @8 d7 [- y4 l; ~5 U  d4 x8 O& }1 N& w9 G9 I: ~' G
#define MAXLEN 2569 R7 [( K& h! b. N

1 @( c# H; [9 D+ Y- K5 c#define KDBDEVICENAME L"\\Driver\\kbdhid"  O! v$ c( G# F  ~0 w9 s, ?
#define USBKEYBOARDNAME L"\\Driver\\hidusb" # ]: g8 ?0 E8 h) T' A2 F5 b
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
! W9 J( Y- }- i+ a+ p4 H9 F) p  Z
typedef struct _OBJECT_CREATE_INFORMATION( D/ @  o- g" Z$ K% ~
{  V0 @: D6 T9 b$ m: E6 R
    ULONG Attributes;
* D+ ~+ M, \% H- V3 O) T0 j    HANDLE RootDirectory;
: I8 T4 f$ J8 S    PVOID ParseContext;! C# [3 ?' F" _8 l
    KPROCESSOR_MODE ProbeMode;3 @+ P! f" I! G+ i
    ULONG PagedPoolCharge;9 I* M9 n3 T# U/ x3 [
    ULONG NonPagedPoolCharge;
4 l, N9 A/ p- o4 g8 N    ULONG SecurityDescriptorCharge;" N5 i* H: H- i! J
    PSECURITY_DESCRIPTOR SecurityDescriptor;
* d8 X4 f  g9 F/ Q    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
9 _; h4 a( e+ _. d/ h5 V/ |    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
5 h8 O0 K* D* |$ U} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;$ ~3 h& t; y( v6 F$ K" p
* K/ H2 m  b* ~0 k
typedef struct _OBJECT_HEADER( a3 M1 Y. V* A* w
{
3 M1 A" {: P% ]0 y& C; k( I% q+ K# I    LONG PointerCount;! E( g( y% N2 O+ h1 Z7 n
    union
6 p) _% q5 A4 r+ j& D- l6 h    {1 Z6 D+ P- T' i% d) p# [( p/ u
        LONG HandleCount;
$ p7 s" ~* L, d! _* J        PSINGLE_LIST_ENTRY SEntry;
5 A2 o( A/ ~3 T    };
* V" [6 z2 d' p5 c$ R6 {    POBJECT_TYPE Type;
. J' x2 f& y8 @6 e+ f7 {    UCHAR NameInfoOffset;
4 F* [7 o/ f  ^0 o7 e    UCHAR HandleInfoOffset;% L- u- ~: t, ]7 b/ X: q3 G
    UCHAR QuotaInfoOffset;4 s: Y& Y8 [) K5 s- z4 B: r
    UCHAR Flags;: g8 L' x; c# w5 V4 X6 W
    union
, c% x* N8 L  r' L    {
. t% r$ d: z6 J        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
# [) t/ G+ B. Y# z# y1 p4 A        PVOID QuotaBlockCharged;
: @+ w  J- ~. ]( ~& W5 l3 \( q    };- m* M( T+ W! a5 H

: M4 t3 C! \: Z; \, j9 w: o) z$ [2 Q    PSECURITY_DESCRIPTOR SecurityDescriptor;
. W4 K) O# b0 ?7 i: {    QUAD Body;- W( f+ Z. y8 ?# D$ E! Q* o+ i
} OBJECT_HEADER, * POBJECT_HEADER;. |( G) V9 H' Q2 ^$ ~
4 [4 }7 z# I: {6 W' T$ Z
#define NUMBER_HASH_BUCKETS 37
* U: H* M1 C/ G  A# G$ G
5 O* u: a: H+ p: Z. Gtypedef struct _OBJECT_DIRECTORY
: C7 U. R- g7 H: _$ f2 ^{
8 |% c$ c# a8 z! M( W% d    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];# `' Q# l* A) r, Y: p
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;$ s! n& g# D, G: l2 [& E7 l/ d0 J
    BOOLEAN LookupFound;: O0 s+ e+ x" a! l+ e
    USHORT SymbolicLinkUsageCount;
( K! v1 l1 @; G( q0 r    struct _DEVICE_MAP* DeviceMap;
- q6 w7 l" ], C5 {% [} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
' ^9 V2 S) q+ \2 V
2 o# [- ]1 |1 Z4 L* x: wtypedef struct _OBJECT_HEADER_NAME_INFO
$ E$ x( ~3 a  x+ v- H  T, j{: h. H7 D+ g, X9 \2 P
    POBJECT_DIRECTORY Directory;
" O# _7 t4 d! {    UNICODE_STRING Name;
" w; Z1 ]1 X) n5 ]- m1 Q: q    ULONG Reserved;
4 d- y2 `! [* a) h/ z$ p#if DBG! X2 ~" b( A. u4 w3 ?7 C$ L- s
    ULONG Reserved2 ;- @0 T$ I$ p7 Y& T5 _3 Q0 u
    LONG DbgDereferenceCount ;% [+ U5 K8 [' R: t% Y3 |2 }" F8 d0 G2 e
#endif* e/ D) _, h# `
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
: Z5 v. [0 [- a# [
  I( N2 X: j+ P* f& Q7 O( K#define OBJECT_TO_OBJECT_HEADER( o ) \; [: s# c( o! r9 ?
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
' k- k8 l* q" s; L2 F* i* X( ~9 d; z$ C% \
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \2 i- J8 t0 m% \4 ~
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
5 g, k3 F9 ?/ O* l* z" O% J
7 K2 o4 W$ d9 ?6 C  \typedef struct _DEVICE_EXTENSION
0 b3 Q$ l- S5 E" M" B0 V{! x8 C0 R4 a' s/ V  V/ z. b, F# E
    PDEVICE_OBJECT DeviceObject;- Z  d0 s& {" d) D# L& `2 M" A3 S
    PDEVICE_OBJECT TargetDevice;+ t/ R1 I! T# n/ e$ P5 C
    PFILE_OBJECT pFilterFileObject;
  a# M9 G  ?  ~- A$ l6 Z9 `8 z    ULONG DeviceExtensionFlags;
% \6 V  f; \1 y, ~) u* E0 X( S    LONG IrpsInProgress;% S3 K2 T6 n- \: y6 p
    KSPIN_LOCK SpinLock;3 ?# P2 I5 f5 y  A3 p, {1 o3 _
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;$ g0 m/ c% u+ |' d0 D, S8 C

5 N, U- e8 \; c7 U5 Y/ d. M$ [7 c, p6 w; y  u
VOID 3 x/ c. M' v1 f  J9 H5 i! X! k
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );, f6 ~" g! Q# \3 C  r4 H4 _
' {) r- A% t1 B
BOOLEAN
  n8 I* {+ B: b3 }+ x8 R! K' JCancelKeyboardIrp( IN PIRP Irp );5 D& H; U5 R5 c

- `# x* \8 \6 Bextern POBJECT_TYPE* IoDriverObjectType;
$ J* i, J0 V5 m2 }! b/ }
) ^8 w# b" w: |NTSYSAPI
2 v- H7 G+ @0 N! uNTSTATUS# u5 f0 R3 P2 Y# Q# }' o& M
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
- e; r8 Z& Q+ _) u0 S' s$ }                               IN ULONG Attributes," g! D8 m* D* v- T4 q8 L2 ~! u
                               IN PACCESS_STATE AccessState OPTIONAL,
" g! ~  y, J- i6 w; ^( ^+ l: u                               IN ACCESS_MASK DesiredAccess OPTIONAL,3 [& E4 K" d# w% A' {8 x
                               IN POBJECT_TYPE ObjectType,9 u4 I  p# ?, w* l- r
                               IN KPROCESSOR_MODE AccessMode,
- u6 X( U- V  P( c6 K                               IN OUT PVOID ParseContext OPTIONAL,
! o3 N$ h9 t0 a                               OUT PVOID* Object );) \- U5 ~: S+ m

& L# m8 I5 `& t* WNTSTATUS % V0 F! c8 m7 I) X, c5 D
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
, G) ^0 U1 E7 R8 F# j
! |: A% _' V& T, o0 SBOOLEAN + C3 }( d, D# [7 M
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
+ b/ |  x8 o& t$ y5 p( p9 }
  c, V, G$ M" ]% hVOID $ }3 m. l, Y) {6 N# _- D- b
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );( M% B- `% z. \8 G9 b5 ?
% H# O2 e) ~: E" w! B
NTSTATUS 7 l. N4 G! g7 ~' D7 R) v) @" {
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,! D7 {( o  ~6 b& p
                                  IN PDRIVER_OBJECT  DriverObject );# Q! U3 ^7 h# {6 _! S& O
# s, T) Y' e- Q  j0 T
NTSTATUS
) u: F( B( Y. q" NAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,) l& I% |! y# G* a, y8 a; G0 r
                                  IN PDRIVER_OBJECT  DriverObject,
8 j- B) d% `& x7 q1 N* \                                  OUT PDRIVER_OBJECT* FilterDriverObject );3 n" E0 C( a' K  f- Y0 }1 Q

7 z/ x$ `2 \# V. ^% _NTSTATUS % R$ v! o: ?6 u, F* i0 C# j
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,, E8 ?* c! v/ D6 X
                            IN PIRP Irp,
. E3 {% L: @% ]# P# u) c                            IN PVOID Context );
4 l$ N& A# W1 T6 I5 e7 s( w4 dNTSTATUS
; Z( \7 H# A5 V7 x2 Y, PKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
6 I+ A  X7 g6 u9 V- L1 V: G- {
& s6 x, b; [  Z% R0 _0 U* _WCHAR szUsbDeviceName[MAXLEN];
5 K& p9 r3 Y- b& j0 G+ A) i
" C- q6 B$ o! ]: C, s: M#endif
  b. Q  [9 [; f- h$ k5 q' H
5 J# I) D$ S6 x" e
( b, y( N+ w. |3 T
' Y6 p+ `9 O3 c; g3 @' Y
% u5 K: S% N4 @- b/ E4 M2 {
7 u) o1 S6 m1 LWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
9 y$ \* \& Q6 a8 V% JWSS 主页:[url]http://www.whitecell.org/[/url] 7 n" k7 L2 I* I) ^* d; a, Q
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-7-20 08:46 , Processed in 2.702392 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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