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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister& [9 i7 s! y+ |
Email:   [email]sinister@whitecell.org[/email]: J" ?9 B' T* N4 H2 v2 W
Homepage:[url]http://www.whitecell.org[/url] 2 x* h( T! b. u8 J! u/ ]
Date:    2007-02-269 {* B! S5 w' q" T
# O4 V4 {, u8 }0 z4 `# w; n! S2 H

) x7 `9 \' g( Y( t/*******************************************************************
( j$ `! r4 t3 [9 H  I; _% A5 @  F$ ?
4 P; y/ ~3 G+ o) F1 I$ C8 t这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx$ v" m, f! y9 C6 Y) c) j# t
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的" M1 A  w- |/ D: B' U2 j
功能要求如下:
& f6 t' C: F0 ]9 ^8 T3 W4 V! d/ ^) c/ i* R1 M) _
1、强制锁定键盘/鼠标。' |$ ]$ X2 \( O9 X2 L/ ^# W
2、可动态加/解锁
6 G, b. T) Q) p$ i3、兼容所有 NT 系列的操作系统。1 F, ?: A& J, _
' U0 W& E7 x6 `; V0 }
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实0 S9 a0 Y+ n, R
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
/ T# ]- A" U$ s3 }' O% y何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
% ]- F+ q! t5 U9 l. f" v- w: U上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是+ |$ S, S4 b3 ?; C# M7 d
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
( @$ I7 p0 [% |( O- @5 P就来看一下我想到的几种实现方法:0 g1 Y3 m2 V2 n  s
: k8 I, M0 m2 O7 Q3 F" ^
1、全局键盘/鼠标钩子/ F" {1 a5 |1 F' N- E0 n; ]' [
2、BlockInput() API! j* l3 J* b- [
3、使用 setupapi 进行控制
8 g/ `' ^" ^6 G2 S, H* d4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL6 E( Z8 o; V  `! H) N! k8 n) d
5、拦截 win23k!RawInputThread() 函数
- |- f% D+ J5 w  i6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动9 h, k  N9 N: G' n1 i3 {/ ]7 t
7、拦截 kdbclass 驱动的 driver dispatch routine
/ \+ z$ i4 o% t3 b) Q: V5 _# o" ~+ F8、实现一个 PS/2 与 USB 键盘过滤驱动* ]! ^8 q0 @. W
$ w" }3 \7 n2 T9 D: Z
0 F- P8 \+ V8 P, |$ E$ n* K
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
0 v  v  L* a0 k' ^9 }8 ~之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( d; @" m3 R4 n8 q
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在; M9 R/ N$ X. ]; {' y
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因  Q1 ^7 Q9 ^- G1 ]
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性5 b+ Q! Z. H6 e# U$ e* w
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
. b7 h- R6 t: n4 o载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
! [, ]) V% J9 r; K) I6 @; q6 _的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来0 A2 Z8 P) o# Q$ V" f
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
* j6 I4 E: T# D/ }# L果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
: Q) A. Y* P' e" P8 C8 G0 L' d障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截- p  C! i4 x4 \# D8 o( Q
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
& k7 h0 R  [9 Q, X" JUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键! W" l3 e0 q) y, E+ U( z
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方* e1 L: H9 c, J- @; @$ I
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
1 Z# B, J- p( A! E2 I0 `8 j- T1 @" D3 H- Q

, L" j( }# d, {  f9 H' Y# ^我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过8 \/ N1 v7 p% p% O! C/ a6 \
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进& [" ^6 R" p$ r- f
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
. K8 v, t; E( {! X只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越5 W6 T' k8 p  Q+ G7 w* W8 i
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从6 U; I# v) x) v. b
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
( J7 v( Y: E: a4 C$ w键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用5 e1 b* t1 X9 u- p
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,6 R) U0 [2 `) j+ f, C
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题) v# ~; G2 Y* s, s3 S! \
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的" w3 r- C, F; j) E$ r0 ?1 \
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使: \( N* v  J' X, B) O0 v# j
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
1 r0 X3 t0 d& j6 [- `, d" `过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来5 d, ]% P' f* c' C* X( L' T
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通* r/ o% @. V( {- t3 Z! T/ T1 a2 N
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
4 A' F: M! {4 e; T+ \3 f1 q上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid ; b9 E' U$ C- V- h2 A- x8 B# b
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
2 P0 |, V3 {2 f" w0 q( a+ _5 V味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
; C+ }9 n, e5 ~1 `# |经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们8 u- p* e) M" ~
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
! S: W- y' p* s# Z8 A的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
9 I' \( f+ k3 O) Q的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
4 m6 [6 ]0 Z( I5 i  _& }0 l8 j8 ]2 u敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,/ E- N# j) R, z
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
* C! w4 m: m3 O0 a5 N见下面代码。
/ [; O9 d3 Y# \% x: p6 Y7 Z! K
4 N" @! w& P* j4 |3 O+ Z2 a这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程, a$ X' q) J) y$ K8 ?# G7 |
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键  Z, T2 V+ a3 V! |8 e# ?6 I7 ^/ H& g
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
3 @# q3 r' f6 U. b; h1 d2 V8 K上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
1 l! D) d% y% J$ Q% k2 K" m$ v完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
5 V3 N6 ?  t& z0 P6 r继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个- E# U/ V# J/ R4 C" r- m1 P
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
  u! l+ [- k/ |键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
2 ~8 _7 i4 F6 w& d$ i1 ~' [6 I/ j6 D

+ v. M5 p7 {$ d" V9 ~7 a9 ]# f完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
" k- l1 R0 c" V( S) [/ U# f: n* _的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是. N( X! E# a1 W/ O7 |
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣' ^! n0 S3 S* d
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
7 L9 }$ G% x$ _) }( f/ V们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
1 k: \' C) ^( ?3 d# n们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
% {' l- A* i8 G+ l# Y/ z  W$ t->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
$ J" ~& V5 k$ J0 u如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager' m6 z# f8 T$ P% i4 ?+ S
进行操作了。这个问题有待大家来完善了。2 Y4 l; o6 t2 {# {( [4 h
, ~+ W1 c* E; H% v+ t

; U  E; w. ^& J6 q要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出8 F, }6 t+ H3 g8 L) E3 M( o" C
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的5 Y1 D( d' z1 h9 K% q+ c
分析做个记录而已。我更愿意把它看做是一段注释。9 |7 N! v9 K# D9 \

2 [( K, q' N* L6 |/ k1 F最后在此代码中要. v2 d; G- n! ~( L# D* ~* j

3 @/ R& @  U! U感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。3 m* z& `& `4 G1 J
, F* i# ?7 o3 \
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
' m) R1 o/ U) `) `
/ I; ?/ \8 D: _+ s感谢:齐佳佳,过节请我吃好吃的。
7 B7 ]  @( r$ E8 H. d* ?  W
4 L  f& w6 n0 g. |! Z0 A  v
! S/ h' N% U  W( b9 J******************************************************************/8 _4 ]& s; Y7 e

" f3 F& T% w! a& n4 ?- w
7 N8 ~0 R1 K1 @0 r6 R) e$ k  E9 }/*****************************************************************
& z. B3 E1 i6 M$ D' ? 文件名        : WssLockKey.c
9 m( b& j9 E) W9 p4 x 描述          : 键盘过滤驱动
/ u6 Y3 f9 n3 ?# q6 T2 ^ 作者          : sinister( v# J$ S% Y/ r+ {
最后修改日期  : 2007-02-26
5 F( i" d: Y( w/ f0 h1 Y. W*****************************************************************/. A7 |' a, m: l- J/ _
1 _4 V; g; ?9 S
* Y5 Z( c1 u; R6 _, @
#include "WssLockKey.h"
& d8 c; R# O" u2 Y# Z6 r. e+ Z7 o  f! d
NTSTATUS
' r$ a" G8 v6 E4 y% }3 CDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,% b- }( {) T/ W% w
             IN PUNICODE_STRING RegistryPath )
' g. b/ s! A# m4 s/ R1 |" {{
9 ^! z; N! }1 C0 J  UNICODE_STRING KeyDeviceName;
/ a# i/ C" q/ k9 s: b/ ?9 d" D  PDRIVER_OBJECT KeyDriver;
; w& y5 Q! H5 V' ^0 {8 I" Y; P  PDEVICE_OBJECT UsbDeviceObject;9 v( Q- k( \0 O3 R
  NTSTATUS ntStatus;
8 h9 N8 P+ i8 ]  _" E; d0 i  ULONG i; 1 q( t8 F8 [+ z, z6 ]
6 g5 L5 Z- U3 W; w
  //
7 q1 U$ h: `5 m4 N- g' x. C5 O  // 保存设备名,调试使用
% ^: P1 s/ Q4 }  //9 C* U' S/ C" _* B% D  b
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
- }& ], u' G2 B  {
: e6 t/ G3 J9 |3 q    0
- V. N& Z& q8 x  };
: A5 ^  [# `+ n& ^+ p) }, A9 s) E2 b7 f: C: t* G, A7 U! r
  KeyDriverObject->DriverUnload = KeyDriverUnload; 6 ~3 i* e- _* ~0 T
  d- ^" `9 e1 K  L% D. V: d
  //, a: P; Y1 Y0 |- P! F  i1 [
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘2 N: l, J/ R. h1 D6 N+ T  t; Q
  //0 q5 l4 M- I/ A7 B
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法& |0 ?4 f* Y8 k( V- T$ _3 `7 k) k
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其' W9 p1 j# B" c, a1 H, G  u
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
  p* J/ J% ^4 x! l/ }+ ?, _, V% Z; z: Y  // USB 键盘设备来进行挂接  F5 r5 s3 `# h7 a9 d% _# i3 n
  //
( N  [$ Z5 I" G0 g! d  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
0 `- p7 u( T$ V. J0 F$ V- a  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
" y+ B! K+ s# V0 n  {9 |8 l1 {  `! R2 M: [- K1 ~
    //
" D/ q9 H2 N( j' ~    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名1 z  j) O. Q* I! J+ l. ^
    // 所以这里打印为空* x& @/ x0 J5 q+ T5 c
    //4 w9 {8 s* F+ D6 o2 Z6 T8 m& r3 N
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD" a: k- z* S8 z/ \" g% h1 d0 I
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
$ r1 L! q% ]) D( r1 A" ~" Q; P3 [) Y2 r+ ~+ Q. P
    //1 F/ ~: i$ k% t9 ^$ v4 X: H& e
    // 挂接 USB 键盘设备
5 _5 a6 B8 Z  Q9 {' X' b' p    //
9 r5 R' p; @' B& u1 r    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
/ n9 ^- x0 ~1 M) x$ Z    if ( !NT_SUCCESS( ntStatus ) )% y1 I3 h5 e% N5 i( ?: \
    {
% ~+ N) g# m+ R      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
, w. u7 X. X* q4 g3 B# E+ c      return STATUS_INSUFFICIENT_RESOURCES;% t. }8 G' r: u+ }( J  W2 y
    }
3 e5 r$ L$ C% G1 _/ b6 n, |  }
( I+ }5 ^* g) P7 w  [! [  else
4 m% P& l5 p' P4 N; V( S; Y6 @  u& |  {1 C  H( w# r, l; _
    //. @& ~' I& ]& l2 R; \* A6 P$ s0 S
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备; a  w2 `" S( K, R* f
    //
* I' Y* @( ~& V    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );   z6 b$ C$ [1 ]0 g& `( D+ f3 b& ~
) `! c: G% v: z6 ^" Y
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,. C: q# h2 w7 z* I1 G8 V) ^
                                        KeyDriverObject,
& T$ F8 W3 R* y4 \  t: q                                        &KeyDriver );
) A! p1 R8 b; |4 n# b2 p0 [    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
8 H  e& g. }' l4 ]" a  Q" m    {
+ Q( M) c" m# R7 i0 x      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
) J) ]0 a: G7 I0 B      return STATUS_INSUFFICIENT_RESOURCES;8 }+ y) G4 T$ S+ W7 I0 `& b
    }
7 v. s! Q+ O( {. m) q  }; _; e$ X* u* t( r* \$ U- P1 T) l
' S0 X! f( m6 R4 H
  //9 v+ C+ a- E; R' E
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止+ A+ W; V3 z( e6 q
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程! P" C6 X# s$ }: O; ]8 v4 {3 ^7 {* S. ?; U
  //
. t3 w# Q( P  K" k+ L: t- _  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
0 U1 ~1 x0 q7 U4 B) ^9 Y7 k0 x9 g1 H6 T+ \4 C! n& j' X
  return STATUS_SUCCESS;6 C1 h9 [  ]# M! w. X. ^3 [
}
: G0 ]  n( J# e
( R$ j' v8 y8 U' D7 I/////////////////////////////////////////////////////////////////
3 L6 p# Q" j: n0 X* B) _0 f// 函数类型 : 系统函数
* F' p9 p" J0 `$ y! t$ Q6 q// 函数模块 : 键盘过滤模块
# e9 R$ U, Q5 O+ ?////////////////////////////////////////////////////////////////4 X3 X  J4 ~5 P' o/ L2 o+ X
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
8 ^3 x( |1 M. @//        卸载键盘过滤驱动
; x" v# P6 p$ N; {: R6 a// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上4 K+ g% z/ n, |  L
//        则需要等待用户按键,以后有待完善6 W0 v8 y2 w' U: u4 _' ?
/////////////////////////////////////////////////////////////////
5 {1 Q4 D: T  R  B// 作者 : sinister
- o9 \) k1 u" T  A9 H2 b* K. {// 发布版本 : 1.00.003 W; R6 }  b3 ~% |6 b  h
// 发布日期 : 2005.12.27
7 `2 L: ^$ `$ x4 C8 c, Z2 C0 K/////////////////////////////////////////////////////////////////
  h% [" W: r8 A& b$ W: v8 u// 重   大   修   改   历   史% k0 }* Q: |0 V4 C, X
////////////////////////////////////////////////////////////////( F5 J# f6 }. G# M
// 修改者 :
" R/ w; F. u7 l1 E3 ]. l, D/ e# ~// 修改日期 :# Z$ Z0 \) e. d$ ~
// 修改内容 :- M" p( G" m' [1 {
/////////////////////////////////////////////////////////////////! D% W4 S5 ?  D9 l: f4 E

9 G3 o' y7 Y" H4 T5 X- QVOID( v8 k' b  |- U/ h! \
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
. @- u+ x2 O- g' T8 W8 k/ d{
1 l& N* c1 R$ M, P2 |1 V  PDEVICE_OBJECT KeyFilterDevice ;      
- Y  t1 s: N  e, A- U  PDEVICE_OBJECT KeyDevice ;
3 \% J! C+ R. f* p1 f  PDEVICE_EXTENSION KeyExtension;
  v% X# C9 ?. t8 F2 P& ~/ v) l  PIRP Irp;! r9 ]; ^( I6 B. ?3 N0 U
  NTSTATUS ntStatus;* ]+ O" j; d' W$ [# m% u+ h
. `4 s9 J$ ~3 z/ X
  KeyFilterDevice = KeyDriver->DeviceObject; & P8 c% B. @: X1 O4 ~& T1 G& c) b
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
" E6 e% x6 C1 E# B( o" s  KeyDevice = KeyExtension->TargetDevice;
, f9 q6 K9 [. ?  i) J0 H$ F% r
  IoDetachDevice( KeyDevice ); * j7 n, i% x7 ^# \# C
5 C$ H4 o$ m/ W0 H9 \! x# j, L% L
  //  S# E, G: O( H+ K
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
  X9 ?3 L  `% P. p+ r8 p  //
2 |" q; |4 J. N6 Q  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL ). i5 l; M: E; P/ @8 l
  {8 C: T+ q5 x; D! J
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
6 Y9 k) a- w9 _    {
7 P7 ^8 f: m2 z$ G$ p5 |% y      //
, Z: J: e3 g. L( Z6 K% N+ [! a      // 成功则直接退出删除键盘过滤设备
9 h9 V4 H" x2 _8 ~- z; r      //- ~4 M, M; V: o8 s3 |* D" `& |
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
" Q. ?# A3 }2 D      goto __End;
. O; z9 Z' N9 z) y( c. C( M/ o    }
2 M) C" j6 E: w  A) b: Q) w, P9 t  }0 u5 _4 ~0 H* S# [8 H# ?

1 P2 T# A, \/ l- u  //
+ ]! F& _/ w0 H5 Z0 b/ n  // 如果取消失败,则一直等待按键
3 F6 {6 I7 V' N, L6 P  //
  F% B1 N- r; r/ U7 M0 K* e  while ( KeyExtension->IrpsInProgress > 0 )
$ S- X# L8 W4 Z3 _% y/ H  {. x& ]" \; u' ~# C4 v
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
1 }( C7 I3 p) e0 p3 c( I  }* m' N0 N+ p: z7 r, ?: D! Z

" M2 _5 y" g' w! B  __End:( o8 l9 G& d% K+ l- J
  IoDeleteDevice( KeyFilterDevice );
( e$ G, c, a4 @
) t# E- c( u& C) E4 b  return ;& t5 ~, S( [" Y1 C- R' \
}
7 Y% Z" a! _) H) u# D2 v/ r$ N6 G* q* Z- Q/ a1 l9 [8 {; Z
/////////////////////////////////////////////////////////////////) p- s; {' C& j; v' p4 O: p$ F
// 函数类型 : 自定义工具函数
6 }3 K- Q( y( s// 函数模块 : 键盘过滤模块- ^5 p* B* g: }+ P3 i
/////////////////////////////////////////////////////////////////$ f  J& S  s+ z0 y- X) E
// 功能 : 取消 IRP 操作# a  v  a% X! c1 i  R
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
! h" M" o2 Y9 t% j; j+ H//        使用此方法来取消 IRP
! T3 R/ F6 \5 _  G/////////////////////////////////////////////////////////////////2 Y+ \9 Y# f9 _4 R. ?4 B. b$ ?& L
// 作者 : sinister
5 m3 G4 j# w  |: |2 f// 发布版本 : 1.00.00
9 `# V1 _1 `( |, [& D0 H- V// 发布日期 : 2007.02.20, }+ S$ X# F" p& V; _
/////////////////////////////////////////////////////////////////) k3 C: T+ a  g8 i
// 重   大   修   改   历   史3 T$ x  i, k* {. ^. Y/ T
/////////////////////////////////////////////////////////////////
3 u( z( k( V* V: b6 k" P// 修改者 :
6 V+ e, E( J. _! ~0 ?// 修改日期 : 5 g, B8 A, c% k+ \! t/ \
// 修改内容 :
' s4 K3 }6 u" T. f# W. s. W/////////////////////////////////////////////////////////////////
$ |0 X: ~& J( R# B& q0 K  m0 I0 A( C! n' {! z
BOOLEAN/ O% [& Q* q# X/ U# ?
CancelKeyboardIrp( IN PIRP Irp )0 Q$ {' H5 S' D" S
{' S" p( K+ i0 Z0 {  ^) {
  if ( Irp == NULL )
# i9 y- H5 a. g! e8 B4 Z  {. X; H4 K4 m# y  U6 r
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );6 ^& }# L6 k+ E1 B
    return FALSE;
- s, i, i9 c6 E; q% e  |  }5 C9 ~% Z  r' N9 R8 J
1 E5 T, [7 y$ P# A
! z) p3 |2 E' o7 m) G7 u7 T
  //
2 t" m8 R% p' j: x  r% u* N  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,( M) k1 d" ^8 {
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。2 C$ m. F% r) L6 H& t" ~5 G
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占( ^7 _/ {! \/ m+ v* b
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD( f9 Z" y* K8 ^/ u' T
  //
& v' O; Z1 E9 J6 L( @! j2 |, y/ `  ~' Q1 r; Z% R( i
  //
. S9 k0 c) c" R  // 如果正在取消或没有取消例程则直接返回 FALSE
* Q6 ^( p2 Q2 G* {& I. o  //
' W% L. Q  J+ B) Z! S6 v. r  if ( Irp->Cancel || Irp->CancelRoutine == NULL ). y6 s& e9 O! s6 e- Q$ s
  {
7 \5 w' Q: z6 V, H. x) y* `    DbgPrint( "Can't Cancel the irp\n" );
8 A6 ^+ k/ U1 Y' O4 V7 m    return FALSE;
8 }/ g( \9 W: }: f# O  }
6 L! q; \# e$ D# }6 B
% m/ ^5 J9 P8 |. q4 K3 }  if ( FALSE == IoCancelIrp( Irp ) )0 i' O* }: ^" I( h7 m4 }4 u+ |9 V
  {
$ E; H! Q( ]5 }8 h4 L1 r    DbgPrint( "IoCancelIrp() to failed\n" );8 I" i/ Y7 Q) g; y
    return FALSE;
' x8 e6 P4 a% h4 l5 X  }# N1 S5 I+ d5 {4 b, V; a: D% |

4 [- r5 t! n2 n* C4 U, `: G  //
  z. Q* M: s2 c% [) f8 ^  // 取消后重设此例程为空, c( _7 |* s1 y% U# U& H" Y
  //
% f8 c5 a6 M( \9 K' D6 F2 f3 }3 b  IoSetCancelRoutine( Irp, NULL );
  ]+ a9 A1 m, r# o/ a: \
& X5 `: h0 l: ?* _' ]+ D9 N  return TRUE;' j, m5 m2 I+ e1 A% `2 U5 P+ o
}0 ~+ j, T1 a7 c. G. K# T2 z
( |! D9 {6 _. e+ A6 |
/////////////////////////////////////////////////////////////////
- b$ i# o* L6 X1 \// 函数类型 : 自定义工具函数
7 u- r# d/ ?+ t  v// 函数模块 : 设备栈信息模块& `, I) G& N; x/ {: |# R4 X- p
/////////////////////////////////////////////////////////////////& k4 l7 G. s. Q# j- B% ?
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘6 l4 w% T" M+ y3 L; ]' M
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
2 X2 L0 o+ y6 ?// 注意 : 5 Y" v" j" i* s& D8 F
/////////////////////////////////////////////////////////////////0 ^9 Y" P) _1 y4 `6 ]& \3 ?
// 作者 : sinister
- v# O; @; i& j% y+ O6 w// 发布版本 : 1.00.00& X; p) ~- Y# p) ~( X) Q0 n$ w
// 发布日期 : 2005.06.02$ s. ~% H+ T8 w" s2 D: |
/////////////////////////////////////////////////////////////////
$ _, v5 s9 B. L: w8 k9 |# I* e// 重   大   修   改   历   史2 |" X% Q, ^1 N! V  g
/////////////////////////////////////////////////////////////////+ ~8 y) B. ]% i& }1 Z$ t
// 修改者 : sinister3 v# u- T+ S* B9 n
// 修改日期 : 2007.2.12
( a2 s; ^  }( O8 Z; V; ~8 h// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改- m4 w  z7 e0 e* ~  P2 W0 @, b
/////////////////////////////////////////////////////////////////
; n/ v  l4 @# x7 e$ t
$ l& x& w0 x4 `5 Q- l" A2 LBOOLEAN
0 C  D2 q, w" y; f. aGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
' Z# v1 p9 g) l8 Y. t{
& Q: a  f! f6 h" ^, v" L) U% y  PDEVICE_OBJECT DeviceObject;
: R& h; S. Z% W6 J* }  BOOLEAN bFound = FALSE;
6 ?0 S* L7 l% D
4 o' i, k6 Z/ J8 l# g  if ( DevObj == NULL )0 U; l% M5 U; V1 e
  {8 y( w. \  C: @9 C( a5 E
    DbgPrint( "DevObj is NULL!\n" );: o% {2 I) d4 W  V) \4 f
    return FALSE;
2 H$ K; @4 H: Z3 \/ c* G2 M  }3 \2 i1 ?1 k# s" r$ R& w. F2 X
& m$ A9 r3 \2 O! e5 ^7 i& y& X" c
  DeviceObject = DevObj->AttachedDevice;: i( W% X/ j" s+ Z8 ]: N

1 b* i" x; s$ J( K) k4 U0 D0 j  while ( DeviceObject )
2 P* [6 w+ W5 l5 f7 z+ @  {3 G0 r6 Z9 V, W* I% a3 N
    //% Z7 a7 C2 A" [& J( n
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但: r5 k& H$ O) D+ U
    // 有一次足够了。这算是经验之谈
8 n' d4 K3 y- i8 Q; K1 }3 q    //
. J) [8 o. L$ C- j3 N2 G0 `/ a    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
0 x' c% u, Q1 f4 j1 w    {3 j* f2 B; f( f( E' v3 _4 ]4 ^# C- c
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
$ Y2 S0 H4 S2 F' m+ M& }                DeviceObject->DriverObject->DriverName.Buffer,
! f# V- [4 h9 j( g# X  r) V* J                DeviceObject->DriverObject,
0 U, I& A9 ^- i' A' |                DeviceObject );% k- n' E. k* U" O- N: Y  G+ g
3 o2 w9 N% F+ Q% L1 u. U
      //
7 v. {! T, Q/ m6 y: y2 Z' j' a3 U. v; W      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了3 b: W) Q2 t# c& d- }# X+ H
      //, g! R6 W6 z( i. }9 @
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
- ~; D' o  ]- o% R8 H5 \7 G% Q: m                      KDBDEVICENAME,' e  \, U+ D4 _* X1 T/ _0 [2 D
                      wcslen( KDBDEVICENAME ) ) == 0 )
1 g5 I$ [! }# u& a) Y& ~( H1 o      {7 R! m9 {2 w" L( W6 S& F; A$ Z
        DbgPrint( "Found kbdhid Device\n" );, g+ Y% m( B! t3 R5 v* N# ~
        bFound = TRUE;
  D4 ^3 Q; f& P. s$ g        break;- P& e0 G: v9 Z4 V
      }
6 r0 G+ S) K, k4 F/ }* Y" O    }: a6 y( f! h% a/ }
6 P' @2 p' Y2 \; x5 A: L
    DeviceObject = DeviceObject->AttachedDevice;
7 K6 w" q& U4 F2 l- r# |" a  }
- g7 k/ i: V7 o& `2 t( |3 d" S
  return bFound;/ |+ D. F) l# b; l+ z
}
: s: m) ^" X" [3 ~8 A: `( S
$ _% v6 ^1 |5 b" l3 z/////////////////////////////////////////////////////////////////
* _- H. X8 K' G// 函数类型 : 自定义工具函数
% y; A0 T! C: R5 D2 l8 x+ Y6 b// 函数模块 : 设备栈信息模块4 N! I3 @/ s) X( P
/////////////////////////////////////////////////////////////////
+ y0 X6 r: v, u# [9 @3 n// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
' r; Y0 v. y+ ?6 [// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
0 h9 q9 y4 H% |9 f. l# g- \: i/////////////////////////////////////////////////////////////////
5 A' ~4 N- ?3 }( d' ^% `// 作者 : sinister
& @9 w- e3 z; K3 g" c0 n1 `! i' b, z6 Y// 发布版本 : 1.00.000 u' x' J- [) d7 U7 }
// 发布日期 : 2006.05.02$ W& y4 w- R* z% S0 w- l" t1 l
/////////////////////////////////////////////////////////////////
$ o" Y& I2 o; I8 R5 d- h- ~& R// 重   大   修   改   历   史
8 @- k, c9 D6 L9 k8 O& J  T$ Z/////////////////////////////////////////////////////////////////
* {1 g% F- C; L2 @) x6 [// 修改者 : sinister( j2 P/ [6 W, x
// 修改日期 : 2007.2.12
" T2 T! w# w( Q$ C9 ^5 o5 ^3 W// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
4 |' u* d  ?% I( U6 H/////////////////////////////////////////////////////////////////
# d( W# ^  X' h( {6 k& V% _* P# s8 Y
VOID
; R2 O; B. c4 J' t& M% sGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
( B* D4 U1 Z" O5 P{" \6 Z# ]2 k) i
  POBJECT_HEADER ObjectHeader;0 J: w/ u1 q: m
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
& ^0 A, l5 S4 c$ Q* r: D. ]) x% b
- _8 [4 P+ D1 N3 g2 Y& o  if ( DevObj == NULL )
( i5 p0 I: \- v1 Q, g( ~; o  {
0 l8 h+ s% b* `1 ?    DbgPrint( "DevObj is NULL!\n" );
# ]" G; X0 d2 V+ B; L% ~, h    return;
0 Q" X4 x. D/ P3 Q9 M  }
0 k6 G5 N3 m( w5 f
# j. Z4 a3 s+ ]1 k  //2 e" Z! Q$ ?: y* b' N0 R) x
  // 得到对象头
9 Q% y7 Z9 `8 ~8 P: M8 p# z  //7 X, l, G- L9 j3 }. t$ C
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
7 |  b- G' S' Y' c7 p
( @- o$ v: e6 F- Q; M# L& |: v  if ( ObjectHeader )
' u! i1 |" N9 l$ H+ f* F2 u  {: U$ Q) H% d( z" @1 X, c
    //
7 h# F, j8 R) M* z    // 查询设备名称并打印7 G: P( V* w+ \8 h1 h+ y
    //# M+ z6 ^- K% O8 T" t" v; a
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );* r9 X; M, L- z0 E- w& [" u
; @9 Z5 R5 P+ y/ r. Z
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
8 {& k9 P8 Z' n    {
7 B+ G2 v8 \9 y7 c9 C      DbgPrint( "Device Name:%S - Device Address:0x%x\n",0 A2 J0 g5 S6 D2 j
                ObjectNameInfo->Name.Buffer,
- e* g8 J: d0 K# N4 C% O                DevObj );( x( O  [) W; [8 w$ k9 y

8 y/ I4 F9 c& b4 t9 K7 q3 U      //
3 e( A( y! g+ i, [3 v      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
7 [- t* D3 J: `+ w! p      // 用,没有实际的功能用途. P( ~. P" z4 O7 L) A% ]
      //
* k6 j" Y3 v. O& L- {& F      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );* W& l$ e7 W; c" m

: D6 B0 s0 x. e& X2 A5 N4 T      wcsncpy( szUsbDeviceName,
$ F: G9 v6 s; h1 ?' @) \               ObjectNameInfo->Name.Buffer,) l# W1 }5 G4 V# \6 Y
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
5 w0 E+ t' ~% l. t    }
3 p% f- k& R" _2 K! T' f* V/ [( }0 {, ?
    //! S5 E* D$ \0 a; o: @
    // 对于没有名称的设备,则打印 NULL
* C9 v' I2 k" q- Z/ G$ z+ V: S3 R    //1 ^$ P5 G3 `. Z8 M
    else if ( DevObj->DriverObject )
6 L" G3 C4 w1 f* j/ W( x% ?* N    {4 {6 i! }8 O4 @
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",  f/ d% ~# W4 d1 d* |
                DevObj->DriverObject->DriverName.Buffer,
7 `- L# }' B4 v- d% A0 C                L"NULL",
+ ]! M2 }' k, ^/ f! z  F                DevObj->DriverObject,2 J1 I) O7 s) ?+ I2 p( I( p. ^' d
                DevObj );5 F+ L1 K0 d$ L: @  e8 h2 Q9 p
    }
+ j* J" h( }3 i0 P3 w# y7 d5 P  }- h8 i- E2 e5 K! u
}$ W$ l' Q* }  J& B; W

8 a" l' U- E; e6 R! q, s9 s4 T7 t/////////////////////////////////////////////////////////////////
% K+ k/ q  C& v' W# k// 函数类型 : 自定义工具函数
* p  ~3 z- Q% ^- C- Y0 A0 p5 y$ w// 函数模块 : 键盘过滤模块7 F: v5 {9 H( @2 Q6 p/ b) j! ]2 Q
/////////////////////////////////////////////////////////////////! J( S& H# J! }8 z1 J2 a0 S* x+ G
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备7 Q3 T5 N$ c" I& w7 q
//        对象,过滤出 USB 键盘设备,将其设备对象返回
- Y- ~; u7 \( @( l// 注意 :
  t. x; {/ q5 `  @9 k" [/////////////////////////////////////////////////////////////////
7 P: V# j! ~8 o" |7 k// 作者 : sinister& T4 [( ^! U4 Y
// 发布版本 : 1.00.00
! z' j1 W: \1 [1 U. n// 发布日期 : 2007.02.134 c1 n$ U$ L3 S; f
/////////////////////////////////////////////////////////////////
( @7 w1 J: \7 B- M+ M+ V$ e// 重   大   修   改   历   史2 ?* t9 q# y9 m' ?; _1 n4 W1 E, P
/////////////////////////////////////////////////////////////////& C# O' Z& L+ B7 p
// 修改者 : 3 i* o& ~$ D, j. o& `; N7 s" I. v
// 修改日期 :
- _0 s& u; W6 f; n" X// 修改内容 :
' }2 E1 K- o; b' j4 i5 C$ u/////////////////////////////////////////////////////////////////% v$ E- B2 U! G8 ^/ n, q
# b, t! F/ @. m
NTSTATUS' `5 u; h! J8 \/ J
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )! B" {, ~" J4 r  n6 j! g1 G
{% u& K: t/ ~# P) l2 \* {
  UNICODE_STRING DriverName;
0 j! Q' y7 }, o% w  PDRIVER_OBJECT DriverObject = NULL;
6 M9 E1 w" n  Z  G. [  PDEVICE_OBJECT DeviceObject = NULL;
. `/ M; y3 K2 n7 c# a/ B8 S) p/ W  BOOLEAN bFound = FALSE;
; i- p) y( X8 F: K# T) F9 ^( u; d4 B+ g
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
4 x  `) E. @9 i* r1 e3 z& Y3 u
7 W. I& O# y( l0 F5 G" Z& y6 S& s  ObReferenceObjectByName( &DriverName,: a# A; R8 N; w5 n
                           OBJ_CASE_INSENSITIVE,
3 E! R5 ]; M# y9 Z$ O                           NULL,
3 @) J, f8 m' |) i                           0,
& J  ~9 D9 k- n8 |9 }! ~+ U                           ( POBJECT_TYPE ) IoDriverObjectType,
- S$ b6 N  p4 a) G" \3 s0 ^) b                           KernelMode,9 v* f" g0 S( E
                           NULL,
3 j* G4 m+ @" ^# Q                           &DriverObject );
: {* U& @" L- |6 ^9 {( \) _' ?1 \3 Q' X" C/ k5 t9 w9 R
  if ( DriverObject == NULL )8 G" t2 E* I& Y, \, _- H/ _" G* e, {
  {
. _: E0 m1 p# j" j7 p. b  |: L    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );2 ?: A- i+ j  m6 F* R
    return STATUS_UNSUCCESSFUL;6 z( E3 X% ]1 i3 u* z
  }
$ e5 R4 d& ~- ]. l6 ?
0 F: t: |( n# R8 `  DeviceObject = DriverObject->DeviceObject;; r- |( y3 }6 ~7 M, X- M

1 \' \$ V. F# e( s. L  while ( DeviceObject )1 B; }, l# V2 ~; z
  {2 H! h+ Z2 x$ B# `
    GetDeviceObjectInfo( DeviceObject );
1 r: {+ }; b! c2 N4 S! v$ u9 T) E5 y& T. \* \
    if ( DeviceObject->AttachedDevice ), i, X3 d( n$ W1 s# \
    {
) Q  s" S* z( W      //
" Q$ W7 R8 `  k& F9 b      // 查找 USB 键盘设备
& G1 ^  ]) E) ?6 w2 ]2 P      //
7 x) J) T6 H  u$ {      if ( GetAttachedDeviceInfo( DeviceObject ) )
$ C$ ^% E' j& l" G4 ]4 v  ?      {
# S! T/ j4 j9 z: Q        bFound = TRUE;
" ]9 w9 H, Y, f2 ^        goto __End;' @4 \+ e) I3 w8 [2 G1 N: L; x) p
      }
6 a9 \7 ?2 q0 |, T! K7 R0 I0 L$ k, n    }1 l  v- K. Y9 g0 j
( w* q6 X8 R* {& K& L" O8 f6 Y0 s
    DeviceObject = DeviceObject->NextDevice;
: O; v0 H. s( s) ]: y1 ]$ V$ a9 Z  }
' A- R$ E; {# R) H! M0 B( ~. K+ d7 q6 J& k6 p: {) N
  __End:" E, z# S/ b! @# E, Q( K. Y4 }

) g, C5 q9 U3 f6 J8 S. B  if ( bFound ); I/ L/ k( b+ }& p
  {
5 P5 E8 f5 J/ `# D6 Y    //0 l; E/ u. l+ \; X7 K3 d1 h# @
    // 找到则返回 USB 键盘设备对象& p% U/ c3 n2 Q# ]+ H3 }
    //1 l2 c- i+ R  [3 L
    *UsbDeviceObject = DeviceObject;; T, B8 m* {/ u0 i6 r3 R6 q. z1 W$ R# q
  }5 v& S/ c, d7 h
  else5 S3 y( i+ z: v2 ?! z
  {
6 ^3 _+ d4 l. ?    *UsbDeviceObject = NULL;) y/ n$ D' Y/ _4 K+ W5 m$ [
  }
. y7 i% `6 t6 m# T& U5 {+ a, n. X" c3 R3 T4 Y) j0 [9 Q: r
  return STATUS_SUCCESS;
- [' V' C% k& e}/ n) `" _# o% G5 C
; t* w' m0 n  q; X" C
/////////////////////////////////////////////////////////////////
! X+ Q& q/ H( h* ^// 函数类型 : 自定义工具函数
& W' j" T3 R3 q9 x, @// 函数模块 : 键盘过滤模块
( B: K7 o. _) r0 _////////////////////////////////////////////////////////////////
. u1 }6 R% e) m! @' {& d% l$ x// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关3 H  [* a! K6 f8 w  @- D# L7 I
//        信息,返回附加后的驱动对象: H8 I' C4 h+ M' j
// 注意 : 此函数仅挂接 USB 键盘设备
, C: w7 `- I# [6 {: j4 r/////////////////////////////////////////////////////////////////& _- h# r( _( c, a
// 作者 : sinister
3 _# f& i1 v  o" X/ p// 发布版本 : 1.00.000 @0 }" Y! z8 e4 R
// 发布日期 : 2005.12.27
1 J8 L6 ~+ n6 I1 ^6 [2 n$ t/////////////////////////////////////////////////////////////////
& N9 k1 [) |5 D1 \% Z. y// 重   大   修   改   历   史- N8 g. T! {' t7 A! e! ]
////////////////////////////////////////////////////////////////& ^' N7 u4 F' L& g# H) S" ?
// 修改者 :6 [* S1 B1 Q8 Y  D
// 修改日期 :) L1 V3 h+ p1 V9 C" S  r
// 修改内容 :2 m' ^# l0 c) H$ Y
/////////////////////////////////////////////////////////////////* r8 }+ r+ U- C9 O- a

( o+ s0 U9 ^$ E7 w/ l$ h: g( MNTSTATUS. ~; [: C3 M" E) z8 ^0 s+ t6 u
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
  R2 a' B% W. `                         IN PDRIVER_OBJECT  DriverObject ); ^9 f% ]! v! N6 f5 @- y, c; h
{0 ?4 S% e, a, @
  PDEVICE_OBJECT DeviceObject;
( d! j6 }  ^, }& N; K0 Z  PDEVICE_OBJECT TargetDevice; 3 b' _* n/ J6 r2 _9 s2 E" P
  PDEVICE_EXTENSION DevExt;. i5 T# R9 S, L* ?7 J
  NTSTATUS ntStatus;) |2 Q0 T  ]6 ~
/ T( k7 N  D( a( s
  //
- t. Y' B; i" w4 a6 q  // 创建过滤设备对象3 X/ K* b4 g$ J3 H# s
  //& [1 z9 Q. H! [8 K1 s  y2 d8 C9 r* n0 a
  ntStatus = IoCreateDevice( DriverObject,
+ a5 K7 h2 z2 [' S0 D1 k                             sizeof( DEVICE_EXTENSION ),
& j# K0 Z0 I' |2 M8 F4 l: f5 _                             NULL,0 G: o$ `8 Y2 o# [! I  E7 H7 q
                             FILE_DEVICE_UNKNOWN,* }5 ~! l& f7 I
                             0,
& d: ]# t  l9 @4 I9 D6 a- n                             FALSE,$ S7 t! ~+ j" ]  g. u9 i, I
                             &DeviceObject );   ?6 p: ?; J; p  F
5 P2 b, H' r* u4 Z2 g! ^" k3 v+ v8 s
  if ( !NT_SUCCESS( ntStatus ) )
/ b4 m3 J3 Z* {) f" p  {
. V) Y2 E# U- l    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );, a* p9 m$ V- i5 j
    return ntStatus;7 ?8 C3 ^- i# N. q
  }
) w4 }9 o! n8 |2 I# y( z
4 z2 z8 p7 ^& Z  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;) W( e8 P: c$ J; j

2 R( i4 X; h- [% |" v! a  //! U$ O9 X3 |8 N% v
  // 初始化自旋锁' c) |- j! b8 }; J9 x3 P
  //% E6 d: K; L0 N0 E4 ~) w
  KeInitializeSpinLock( &DevExt->SpinLock );( S  @- ~7 O2 m' H. I
1 K. }; o, ?! M6 H# J
  //
2 d+ |# W% H5 ?" y" e* v% T; d  F  // 初始化 IRP 计数器
. R& a' ]# @. M6 S' {! |" ~  //9 m% X5 U1 k& N! D  c  W; E
  DevExt->IrpsInProgress = 0;. Z; \0 u! z( [$ b6 s4 Z  V

. A8 n5 a" M, x' q5 C  //
1 J7 q, c; T8 o' b3 n: r/ E  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
' F3 h1 d1 I/ c7 t  //. `0 b$ @$ _' J7 b9 L* W( V
8 R$ I. Y7 X4 s4 |% b; J0 d
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
- T& U4 n2 H5 J6 U7 e  if ( !TargetDevice )' _: y" e5 b. i+ }3 t& _' F
  {
1 Y5 y# @; E8 [7 |    IoDeleteDevice( DeviceObject );
) Q% d; n1 i/ Z+ n. Y" q    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );# P& K+ o# ?6 y
    return STATUS_INSUFFICIENT_RESOURCES;% x1 j/ p' Q4 J) N- G
  }
1 |+ h5 }% ]/ B1 j9 N- c/ [9 \8 d
  //7 m0 r; G8 Q8 W) T
  // 保存过滤设备信息
- G" o0 Z+ u. D3 O& Q; W  //
. x9 O+ Y. c4 ~, R  DevExt->DeviceObject = DeviceObject; , k' s! }- r/ E) ]" n: a9 B0 _
  DevExt->TargetDevice = TargetDevice;
. @4 d  N, v: @* c  w" N: |- ~
% [# ?* Q# d% i0 G+ ^$ Q4 v  //7 q" Z5 C! b# q0 H$ c
  // 设置过滤设备相关信息与标志
+ u2 _! H* c6 W- t2 q  //
$ O* w2 v& w3 \. V$ ?  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );! w0 K4 V/ y8 y: }5 f/ t
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;8 ?- G' d+ r4 i
& s; p$ v' u9 x: F9 Q' D  b$ n9 Z
4 r9 e' t/ w# @2 T
  return STATUS_SUCCESS;2 m+ y5 ]2 _- X; P" W# k
}
9 ?1 R% z- o/ z1 ?% `4 E# c2 m  {5 o/ E5 _9 v$ O
/////////////////////////////////////////////////////////////////
- m0 u/ w# \# P$ J4 H! H+ M3 ]// 函数类型 : 自定义工具函数* r- `4 J) P4 z4 T! f6 n% d
// 函数模块 : 键盘过滤模块
8 W' _" t% E) V2 }/ E, t6 y////////////////////////////////////////////////////////////////3 m- P- V. N6 w/ y
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
/ U9 U! F7 r& P2 f, G1 B$ n//        信息,返回附加后的驱动对象
2 d8 x# h/ L4 J; g+ L5 N7 S// 注意 : 此函数仅挂接 PS/2 键盘设备
) r  W! d5 N: j) c, T/////////////////////////////////////////////////////////////////
! Y- t" i1 w4 y! j2 a7 z// 作者 : sinister" I; b1 l! f% ?0 `$ ?
// 发布版本 : 1.00.00
' V# u( E8 p& u. ~& E" K// 发布日期 : 2005.12.275 U; y% i8 k$ B  t) y% k7 T
/////////////////////////////////////////////////////////////////& g  P! _( W. s8 g
// 重   大   修   改   历   史! `+ h3 K" H( m3 ~" p- o3 [  e
////////////////////////////////////////////////////////////////  I6 ~# |! p  ]/ E% x. q
// 修改者 :
; y5 W& d+ n! ^$ ^( b# S. x( b// 修改日期 :
: u1 n9 }; T& o% s6 Q// 修改内容 :
# J. [* V7 H+ [3 z6 R5 G' T/////////////////////////////////////////////////////////////////
: h% R  |( }$ L; e* a' f( u& P7 N* J* M( P0 [/ w
NTSTATUS
) T6 E5 D/ H& i) zAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
& M5 e( a- w, I  J9 K. F3 ^: ^7 `                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象! n/ z# h2 q7 k! K- A; ^& o$ P
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
* k$ {1 F/ N+ _" o+ k6 g9 X{
" n# @4 R: U8 f0 Q2 y5 `3 k# @* v  ^  PDEVICE_OBJECT DeviceObject;   ^3 v# d& ^+ t7 W
  PDEVICE_OBJECT FilterDeviceObject;8 I  r2 c3 z6 i7 D
  PDEVICE_OBJECT TargetDevice;
0 L5 Z% E; V9 d6 ~0 ~0 h, B/ a+ q1 h  PFILE_OBJECT FileObject; / M1 s  Z/ d; B; n) K
  PDEVICE_EXTENSION DevExt;/ h7 ^. W( c& S/ v5 H/ a- w

0 g& Q1 b. \! Z; N" \; P$ n3 G  NTSTATUS ntStatus; ) I* }' q8 G# r0 u4 \0 D
. {, c1 }3 e* q( A! I8 T
  //' Z+ |) H3 D8 G9 f3 Q0 l
  // 根据设备名称找到需要附加的设备对象& R+ F1 g6 T! P: u
  //
. E% r+ m) }/ a: @) V3 x) E) g& S  ntStatus = IoGetDeviceObjectPointer( DeviceName,
+ `" i$ l+ ]6 F2 h# s# Z0 U                                       FILE_ALL_ACCESS,
" ^* j" `  X& y* a: k) r8 B                                       &FileObject,
* w) ~* I- E) S1 c: |' Z/ m4 d# ~                                       &DeviceObject );
7 L$ x) m4 E) B7 N- X7 ?
9 @3 `, k6 Z6 P% p4 F  if ( !NT_SUCCESS( ntStatus ) )" h2 s+ O- f* Z9 w( @
  {
. ^, m; n* b- }$ f! V8 \    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );7 W" E9 H5 R( M$ V! D6 w
    return ntStatus;6 r+ H( O% d) g& U
  } - p! |: r9 Q/ e# \: n" f/ ]

# C, S) N4 W$ ?; k; h( M  //7 u# v" f9 X5 Y9 X" c0 Y0 J
  // 创建过滤设备对象
" ?- k5 w0 T- I. \" X. [7 J# Y  //! f* i' h8 Z- Q( {9 F7 i* I
  ntStatus = IoCreateDevice( DriverObject,
9 B; g% {8 ?; b                             sizeof( DEVICE_EXTENSION ),
" y. i8 ?4 F$ J( u# ~7 T                             NULL,
7 z5 o! J$ I  c9 I% h. {" G                             FILE_DEVICE_KEYBOARD,$ z+ Y% I$ V: T8 ]7 l
                             0,1 D7 G, E5 D+ R
                             FALSE,
7 U. r! j$ F/ S' {+ p% i                             &FilterDeviceObject ); 1 l8 O: w. Q5 Q+ r+ t6 |

4 z2 B3 {% `3 D% q. U1 p' w' s  if ( !NT_SUCCESS( ntStatus ) )
' _4 c6 c" l. Q; n* u5 K4 \  {( ]8 T3 h) D1 c+ r9 l6 ?
    ObDereferenceObject( FileObject );
/ c2 c4 z- L" a6 _2 P" i3 m    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );% Q; T* V) ^  [7 v: b
    return ntStatus;
( i- Z- _  Q8 d( a! j8 S2 Y( }% M  }
5 z0 ~& f7 T) i' s3 r3 }: ~7 B& j2 x7 y* O
  //6 s/ |( `& n% v+ q' {
  // 得到设备扩展结构,以便下面保存过滤设备信息7 h2 x4 p. T) d+ I
  //
8 Q, Z$ m/ |3 N. R, N8 K2 j  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
8 B# o5 k9 L) f# c. o0 v  I0 s
: Y) Z4 w' K' |: {+ @0 ]7 P+ t* i- G4 I
  //2 V& A7 ?. I7 G
  // 初始化自旋锁
8 ?3 [1 {; w; M' @5 O' f1 e  //7 O: p; A6 I* d/ n+ a- N
  KeInitializeSpinLock( &DevExt->SpinLock );
3 r; w! \5 Y# c$ _% K, ^" p
9 p, ^' M4 `, x& R$ R" T2 t+ W  //
3 o( x& _; `  {/ H6 N# k& s- O  // 初始化 IRP 计数器
1 ?% w$ ]3 [9 |, k. o  //
" O$ {% Z& A  @: K5 |" }# m2 l  DevExt->IrpsInProgress = 0;
1 ?' I. z: c$ f% W# U( s7 V, j
7 p8 i* P3 O- v: V  //0 h1 A. y8 o8 l0 t
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
0 s- ^0 h0 o( J$ k: S0 M* K  //% Q! s3 Q/ T1 Y5 I6 A- X# _5 l
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
& v: A4 u5 t! {5 J7 s" N8 K1 b                                              DeviceObject );
6 u" `6 o2 y2 \) X# E  ^  if ( !TargetDevice )
1 h2 K/ m2 d3 ?. Z  {
' q1 Y- X5 W" ^. E    ObDereferenceObject( FileObject ); 8 K; X: _  v9 W
    IoDeleteDevice( FilterDeviceObject );
9 Y/ H. s& X( x2 O1 D1 r. i# c" s    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
$ U& h& J+ L; e3 V, k    return STATUS_INSUFFICIENT_RESOURCES;5 N- x4 A$ @8 u. ^, Q
  } / L( b. z' [3 \5 t) ?
" J$ ]. {! O0 [: s9 f/ [
  //
8 i8 k) u' @# U. Y1 p, y  // 保存过滤设备信息; C  v9 V' N* t# N8 s
  //) O" `6 p; b1 f4 `- L
  DevExt->DeviceObject = FilterDeviceObject;
9 \0 j' ]9 m( W  DevExt->TargetDevice = TargetDevice; . A$ |. D0 h  Q
  DevExt->pFilterFileObject = FileObject;9 O) b2 j# q6 P- U. ^! y

# s% \, m3 e3 z  //
7 v+ g- t- N/ r, I1 [  // 设置过滤设备相关信息与标志3 _6 p2 b& a! a
  //
; C) \0 K" G0 X% i  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 8 Z/ p3 }4 Y  S& z" e
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
% S) A3 U) y( ]1 L8 f: m' ^1 ?2 }  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ Y# p: }& H5 f+ p  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |7 d; G$ i: P( u3 r# @
                                                         DO_BUFFERED_IO ) ); 0 @, R' R. z* [0 x6 w% `

$ r2 `/ \* u3 }" t2 n  //6 C. d0 z! v" w9 q3 Y
  // 返回附加后的驱动对象: e" g* }9 o0 t$ t
  //* }# v& O( a5 G/ N& k
  *FilterDriverObject = TargetDevice->DriverObject;
* t( e# a+ f9 x& a/ A3 y" K6 n$ o( n" l7 F% k; d( e9 n# H
  ObDereferenceObject( FileObject ); 5 A' \0 Q& |* \: D9 C9 P( t* l
4 z1 l4 q( ~4 X* K, `. {' p6 m( a; n
  return STATUS_SUCCESS;
5 N; o2 J' S) O" \}$ o% v3 @6 u2 k4 }
! L8 z6 G) h. [3 n/ X! g8 }
/////////////////////////////////////////////////////////////////
' c* ~/ X& c) H5 Q2 o: s+ }// 函数类型 : 自定义工具函数
( J, l5 k6 B. }% O) g3 c0 E// 函数模块 : 键盘过滤模块" N) R$ ]+ L) p
////////////////////////////////////////////////////////////////
! k( W' h: M5 l- W// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
3 T. j2 }$ A( ~4 B7 p//        这个 IRP 的完成7 ]9 W) g/ e* m( T4 r! u7 _
// 注意 : 7 }# `" ?. R; x$ r6 J2 F4 v8 U5 m
/////////////////////////////////////////////////////////////////
. B: W' V8 M& o- o" }% h1 ?5 ~// 作者 : sinister3 H# o! r2 U2 C
// 发布版本 : 1.00.00' Z& v) w$ k, E+ n' e( ^
// 发布日期 : 2007.2.15; \" J: b% v  C8 P
/////////////////////////////////////////////////////////////////  g# g( Y( e9 Z* L2 d
// 重   大   修   改   历   史
0 U8 Y/ S4 W3 j8 [////////////////////////////////////////////////////////////////3 W; i8 _" p! E' h  T
// 修改者 :3 `  w, m& P% B1 W  Z
// 修改日期 :
1 l, l: Z: g9 p  Z  k/ ?// 修改内容 :
  ?8 Z4 w4 [3 g  P' ~% T& `5 s; L/////////////////////////////////////////////////////////////////
+ Q+ S$ j) o1 g; z7 L3 i2 B
2 r- A: M/ A8 ?/ ]+ JNTSTATUS# f7 Y3 z* A# Z, k- d) D
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
1 z) G' I! y: P4 u{4 |) m2 V# |9 ?6 F: d: ^: t. r
  NTSTATUS status; 7 ^1 o0 `2 C  b' D
  KIRQL IrqLevel;
- S  l7 \2 j  [4 j/ f  U2 Q0 ~+ D5 |7 p/ _$ N9 g# z# |
  PDEVICE_OBJECT pDeviceObject;
. i! J' q6 m3 F5 G  X3 L" L  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )! ^3 Z9 J. B! T# d% |5 X. h
                                   DeviceObject->DeviceExtension;
2 [: P( A& ?! x. y9 x: x
. W2 K% J& c4 X  Y' Y% u
  Y' r, h8 r& }' ]4 m4 @  IoCopyCurrentIrpStackLocationToNext( Irp );: w: `$ h  c, d" X7 |# ]1 V
& `9 n9 g$ f/ g
  //
# T; ~4 k5 l* I1 K. |  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁) l# |6 Q. R% A' {% J. Q5 K, b
  //( g5 o; l8 I% A3 B
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
. p: S+ f* u* K( v( [  InterlockedIncrement( &KeyExtension->IrpsInProgress );- Q7 a: o7 E3 u: V; Q$ D
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
3 r8 n0 n, o+ x) J. k
! f" L7 {' w3 _  IoSetCompletionRoutine( Irp,
! i$ ?9 N7 s* L' S. |* G                          KeyReadCompletion,) Q) f5 l' v# J9 B+ i7 ?
                          DeviceObject,
4 M( N; ?0 L$ U' u2 M& i" c                          TRUE,
2 X/ j# t* P* S0 k5 w1 O) |3 ^& ?% o2 U                          TRUE,
( y" V+ y* L) j# J5 J                          TRUE ); ' `+ e. S$ N: u' ~1 c4 J; B9 I) d5 A

  d% c: p- V$ Y" H0 \; l  return IoCallDriver( KeyExtension->TargetDevice, Irp );
: A$ V* o5 y3 z& s* s1 q}
" I. ~6 {& O6 j* i1 y1 o8 I" q- W% W, B" S/ E' ?( d) v2 X7 `
/////////////////////////////////////////////////////////////////
# z4 ?! }# l* W1 x// 函数类型 :系统回调函数
. F7 t+ R; w7 V2 J// 函数模块 : 键盘过滤模块9 G# l5 L) W, i5 Z
////////////////////////////////////////////////////////////////
# h1 i+ e- P6 P4 c/ M// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
$ B. z3 s$ B7 w' c1 W// 注意 : ; h7 E+ m; l5 ~. A) _2 v
/////////////////////////////////////////////////////////////////0 f$ H8 Y* _* p, }5 R, P0 D
// 作者 : sinister; W4 g- M+ @- P# M3 {/ {
// 发布版本 : 1.00.00& {" K/ K9 \7 @% J/ T
// 发布日期 : 2007.2.12, O; t$ n) W+ l4 K
/////////////////////////////////////////////////////////////////
0 e4 Y$ s+ B( x; G' _# Z2 @// 重   大   修   改   历   史  y4 J: c4 h! t) R
////////////////////////////////////////////////////////////////( C# D$ p9 J: t- o# v4 D
// 修改者 :
$ i  f: x  I( C2 z// 修改日期 :6 N9 d8 f# a: z
// 修改内容 :
3 S. U6 S7 {  [( h8 W/////////////////////////////////////////////////////////////////; |  S- n) g; G
4 S$ g9 E( E3 o% d) D# t! ?
NTSTATUS& Z( _& u  \7 S$ s$ \5 c/ _7 s
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
3 A) v" i- C( C( e% G0 z. Q; Y                   IN PIRP Irp,. G: y% {' l$ U9 B+ v
                   IN PVOID Context )4 ^" U# y) S  B, Z! Y
{
( f" `7 n  I0 J# p  PIO_STACK_LOCATION IrpSp;& @8 k0 a4 C$ q  U2 E: q5 {
  PKEYBOARD_INPUT_DATA KeyData;8 l7 \$ a# {- O2 ^: `5 Z( K
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
" ^4 L" p+ Q' A% m                                   DeviceObject->DeviceExtension;
+ U) j: Q1 i, ?# K  int numKeys, i;
8 E0 d, Y$ s/ U0 _  KIRQL IrqLevel;
5 ^5 A4 r) J  s, z& ^; |7 y% L. O) u/ T% E9 E
  IrpSp = IoGetCurrentIrpStackLocation( Irp );% {: j, s" H- o/ w/ o. E
3 }3 J* v" e! O4 i% M2 ~
# M; r, Q$ T- |2 j. b
  if ( Irp->IoStatus.Status != STATUS_SUCCESS ): a& o, a! g; z- s
  {
4 I) s  k0 O. Q" M    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );: g( q; B  u5 D) t8 T9 n8 x' G
    goto __RoutineEnd;
# C8 T2 L9 j' _1 o  }
2 l. u1 [$ T( s; @, ?: C! A
3 h% D, u- h/ W0 m* |; L  //$ I0 _3 O/ v+ L% q
  // 系统在 SystemBuffer 中保存按键信息' B- Z3 M# ^  w9 Q
  //
% [$ ~2 [' W: a9 _" g  KeyData = Irp->AssociatedIrp.SystemBuffer;3 W4 z! R7 z4 X+ G% A
  if ( KeyData == NULL )& ?$ L" y  I+ ]" z$ k
  {
4 |$ ]1 O9 a! Q4 c8 s    DbgPrint( "KeyData is NULL\n" );
/ s8 ~& _5 f9 t5 k" Q* O" h3 C    goto __RoutineEnd;) G$ E) H2 }' L
  }# g! o5 g8 k5 B/ b

$ Q; B2 M% R  v% B  //
; `7 n& f; ^: b  // 得到按键数- U0 z, \  G& ]0 K2 p' ^8 A
  //; l3 ~$ W7 M1 z2 m# D4 L
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
  \8 G7 B( W# v" U6 s. {  if ( numKeys < 0 )
: V: d2 `4 Z' F* p! ~! N4 d, A# u  {
, A7 v1 o0 B, c6 ?2 R4 W    DbgPrint( "numKeys less zero\n" );
( d7 d& t' ^8 ~! V# V- w4 @    goto __RoutineEnd;8 o+ J; z, H: G0 O1 ?
  }
4 p: C$ ?# U4 M$ b+ R+ [0 P& v) ~8 {& G. }
  //
: X! W* ^$ I8 F: }2 D# a. `  // 使用 0 无效扫描码替换,屏蔽所有按键
8 f# h8 S3 D1 `/ S9 N  //' l# S+ W3 e# x
  for ( i = 0; i < numKeys; i++ ), m/ ]5 E& V9 S' j
  {
2 l. z& T4 ]9 G    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );7 z" p; z' g) T& P. V: U* e$ y
    KeyData[i].MakeCode = 0x00;1 X, w( e" F- g. ]8 t
  }
* K' m& J/ b0 L
+ R! R$ s+ R3 M1 V5 q3 a( M( b7 E3 H9 K, c2 }# o
  __RoutineEnd :
/ w6 D* K& G: @& s; {; H( j$ R% V9 @2 G9 ]' |  b* f
  if ( Irp->PendingReturned )
& S  q' {1 D' e& z+ C3 t0 h  {
& t% X  ]" K5 e) z    IoMarkIrpPending( Irp );0 ^- m( k  M" J( M
  }
4 s) E, `7 @6 ~: G% P+ ?* _0 \$ U- z
  //, V$ }. U# e! Z& p/ z1 o) q
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
9 X2 _, t( T+ n$ y  //2 U; V- [+ W$ D" K% U: g
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );+ V! d, X2 C# d& {% k& H+ u# j
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
9 D8 E% t  Y5 w, [0 U- \3 P  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
1 X; S) R8 b! `  O: I+ H; @; T0 k6 V$ J/ s9 a4 D; S
  return Irp->IoStatus.Status ;) j" k4 x5 v8 J% F. z' x* F' B
}
8 h6 w- q) a) C! d# r  X/ H" J- k' ]
0 |) s1 w" r' C5 Y) u8 i# T2 {- Y7 H7 i* u1 s+ B! h
/*****************************************************************7 K5 Q' [/ \' h+ y+ U* a$ Q3 k# \
文件名        : WssLockKey.h2 B7 c, M8 \6 {
描述          : 键盘过滤驱动
9 ]4 J) d( H& x0 C; r' M 作者          : sinister) w% u) y% L1 m' H
最后修改日期  : 2007-02-26
3 K' h& {8 P/ s& \& t*****************************************************************/
7 Z8 `" }/ C) N# F" p" m/ X
+ X& P9 l" a1 X1 B#ifndef __WSS_LOCKKEY_H_8 H5 k. L% I! _* I0 C, u
#define __WSS_LOCKKEY_H_' ^  A5 _8 b) X- \  H2 l8 {

& v: |5 u) o* [6 [6 y* @#include "ntddk.h"
. A; z' U2 M  T#include "ntddkbd.h"" ]+ u0 d$ h' q7 o% Y
#include "string.h"
  Z  a4 e  L& f! G; u$ F  A0 l& x( ^' O: G#include
# |. y5 E8 j. p
& U7 M9 z- `% k2 d#define MAXLEN 256
1 G/ ^6 T- O# n, S
% A; O5 C# c& a+ \#define KDBDEVICENAME L"\\Driver\\kbdhid"" Q  g: k9 x- M
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
6 K, ]# m9 k$ U7 u) S#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
1 l5 p  d: e; P% _; T# e4 x+ J: `. |3 p
typedef struct _OBJECT_CREATE_INFORMATION
' y. G* k4 A& s8 D{
; ^/ h9 P; L! D1 p8 t* l    ULONG Attributes;
; S' `2 R0 I$ j( e6 K    HANDLE RootDirectory;
. F1 }' \, w; f* x* g  E/ ?  w; t    PVOID ParseContext;
3 W, E" H5 |; L' f; [    KPROCESSOR_MODE ProbeMode;
8 D, g5 w1 A9 }1 f    ULONG PagedPoolCharge;
+ p; a/ h" [5 J) k    ULONG NonPagedPoolCharge;
2 h; h% {. {' N$ _% F' c    ULONG SecurityDescriptorCharge;
( |7 f- Q$ Z' s8 i. X- ^    PSECURITY_DESCRIPTOR SecurityDescriptor;
% o$ F" g* q7 x; Q& m, P    PSECURITY_QUALITY_OF_SERVICE SecurityQos;7 C9 |2 h+ j5 @
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
1 y  h3 O' K+ p} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
* h! {5 f# @4 X; Y$ [+ j  H6 }+ J% F( T& s) u
typedef struct _OBJECT_HEADER
  w3 I5 C) M5 S* v9 e{0 \& f# ?* y9 y" Z+ x
    LONG PointerCount;
/ O. }, Q) c9 L3 G% X    union
! |* j" }- C4 e. Q4 D% P    {
! ~' J; F$ B5 M        LONG HandleCount;
7 b1 Q  \/ f: z3 l        PSINGLE_LIST_ENTRY SEntry;! ^; A( ]- T+ }8 M! s5 H& Q$ r" B
    };; ~& h% e; J/ W4 M3 W: t
    POBJECT_TYPE Type;
7 v  `8 A0 B& Z  ]$ w    UCHAR NameInfoOffset;
. @$ P- D; x3 Q3 U/ [( A    UCHAR HandleInfoOffset;
. ~. ~) q  a/ y9 S) V    UCHAR QuotaInfoOffset;# k- R* D* a2 R9 G' u
    UCHAR Flags;
5 J3 h/ J  S' y, q" b3 v" n    union
% ~1 [& F* a+ {: e) w9 g    {# s# I, ~) e1 z: r! A
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;8 R- u: ?: \* v  S
        PVOID QuotaBlockCharged;
  G  f5 G7 I/ [  m4 m( X; ~( D    };
  |" n2 s0 w- o1 V$ _# x' Z) d2 R
+ S8 [, N" _  H# M# Q    PSECURITY_DESCRIPTOR SecurityDescriptor;
! l& r* V" ~' l9 U1 [1 X" e( u' `    QUAD Body;3 s/ E2 G; G8 ^; s1 @
} OBJECT_HEADER, * POBJECT_HEADER;; G4 z) G; M/ ^; K* |

) u% q5 Q3 P/ n9 z* p# t% l#define NUMBER_HASH_BUCKETS 37; U! [8 z. I+ F0 [  \( [& Q7 t

8 }8 Q: b. T$ L: atypedef struct _OBJECT_DIRECTORY' [; ^% s, m+ `1 }5 |
{  |' ~# O7 X: {9 K+ k, f( f# E( B6 l
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
1 I0 e  P& T/ D$ C/ D6 P2 w8 e4 w    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;8 H& @7 j8 U6 x' L. P3 i9 `6 _
    BOOLEAN LookupFound;
5 X- f( n' b* l! O+ M. t3 [4 F: k5 s    USHORT SymbolicLinkUsageCount;- N% F; V9 a) T# A
    struct _DEVICE_MAP* DeviceMap;
% f* x6 i% C! h/ j) m0 B} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;+ a+ |8 Q$ Q! e' B9 M# A

2 q# U2 m. @- G7 K' |2 m8 F# ~typedef struct _OBJECT_HEADER_NAME_INFO
+ H) n6 q$ N% e5 E1 {% [6 O! k{2 i8 x) @; h7 J
    POBJECT_DIRECTORY Directory;
, U1 X& R3 s8 J6 y2 ^, I" v    UNICODE_STRING Name;
( h" L$ _2 i% d  n    ULONG Reserved;
' T% H5 f+ y4 h#if DBG; i% C. Q: ~3 L8 w/ y8 W( V
    ULONG Reserved2 ;
) V; Z, B) A4 T3 n' ~) S6 O7 @    LONG DbgDereferenceCount ;: A; p9 r8 ]5 B1 X0 n+ a
#endif' y7 Z3 H$ M+ u; J- ^
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;( S. {1 y( d2 O! z* G, d- F+ m
' J* B9 @/ m8 D, L" @1 C
#define OBJECT_TO_OBJECT_HEADER( o ) \
, M% r. }0 [" P5 X2 T7 W! X- @- _    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
4 P$ f. u3 R5 [% m2 d  i2 ?( M/ a3 X# l4 y
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \4 E3 ?! }+ ]9 K. W4 u/ o1 B
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
9 l  `$ q& R3 z, A2 M, \
. o) U1 W; v0 Y7 S# A+ Q/ y* Ntypedef struct _DEVICE_EXTENSION
. E6 d1 x3 Q8 a0 I( M7 ?{3 F- U! S8 E( X2 O0 R$ I
    PDEVICE_OBJECT DeviceObject;
9 Q# `  N5 E4 d5 h    PDEVICE_OBJECT TargetDevice;
4 u4 b7 L5 m8 R! I8 _    PFILE_OBJECT pFilterFileObject;
" u# `; t. P) c2 }    ULONG DeviceExtensionFlags;/ \5 h4 o, J0 ?7 ^; s8 V4 E
    LONG IrpsInProgress;1 Q2 U$ u0 T' O7 d9 S  M  A1 V
    KSPIN_LOCK SpinLock;
' j) b! n$ M' \  O5 d; j}DEVICE_EXTENSION, * PDEVICE_EXTENSION;, }" P) O: ~( i' B$ g1 n' X

: Z. {$ [6 N# y9 x' v) M6 P6 \' ~1 C  O
VOID 6 h" [5 q# j4 Z1 T5 Y
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
* e9 |! C8 B: e# ~. S
9 ?# l. o8 e* a- l* A4 hBOOLEAN# p9 H1 S3 r1 n. n% L' \% N: ~
CancelKeyboardIrp( IN PIRP Irp );9 k: n7 j7 d5 x( j8 c" m  S

; v2 D' x) e* ^4 w5 z0 [) V& Mextern POBJECT_TYPE* IoDriverObjectType;3 t2 Y5 W: K- M' V1 i

( i& c3 q2 j* a" I( G. @! k& BNTSYSAPI' M2 B; X, C+ X) z8 m8 ^, B0 g: s' d
NTSTATUS) B5 c) U& o% m% t( t; S; Q
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,6 f7 G3 H8 x6 u/ S
                               IN ULONG Attributes,2 b( B4 h- ^8 `! j4 A" v5 e
                               IN PACCESS_STATE AccessState OPTIONAL,2 i) p" T# c& G0 ^* d, h, W/ Y& j; S
                               IN ACCESS_MASK DesiredAccess OPTIONAL,2 e" e/ [' _1 t- R
                               IN POBJECT_TYPE ObjectType,
6 ~4 e; ?7 [6 `! w9 P, G                               IN KPROCESSOR_MODE AccessMode,
5 H4 S1 g* H; O! l8 L+ l+ P                               IN OUT PVOID ParseContext OPTIONAL,9 }+ F/ C% u8 c& O' i
                               OUT PVOID* Object );, a, P" n6 z7 G: f  l3 ?8 b
6 q/ o+ V. e% ]6 }! N
NTSTATUS
2 B) b( W; l  aGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );, Y* Z* C! g0 J) ~( Z5 j
) G9 A: q% y2 C1 V! W6 L
BOOLEAN
' I  q- o) ]9 |) j# K! G/ ]GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
# o" J3 o; Z4 t7 X+ V1 O7 f( w, B7 N
VOID
+ o! V3 P4 P. k7 z; dGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );. \) b+ v/ b6 [% l7 o
  K5 i+ P% Y( g* Y, |" a0 g4 m
NTSTATUS
, q# [# P( C0 F7 T9 X9 @AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
: M, H; r. o$ T- B" F& j                                  IN PDRIVER_OBJECT  DriverObject );
& z$ B( I7 J% G, T
' z' D3 W4 }/ V5 B7 v$ B  X& \NTSTATUS
. l7 t' i; W4 G5 PAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,0 @2 V7 D: ?" h$ f
                                  IN PDRIVER_OBJECT  DriverObject,, \/ g& }$ s# M$ g4 q2 N; t; u
                                  OUT PDRIVER_OBJECT* FilterDriverObject );6 {, [/ l# J4 d3 L
+ D* }, g" P  n9 D0 g' W0 [. `2 |
NTSTATUS
- u4 x" @# Q; ?8 b4 O# d' kKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
: B- x" @7 l! Y& p! r                            IN PIRP Irp,) k3 Y, j: _. w5 x; i/ w
                            IN PVOID Context );
& `4 `. c4 I' _8 K. MNTSTATUS 9 d% i# t' g2 P  C0 X7 V3 E$ j
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );: z7 w7 [+ o. ]. r: i* y

1 {. V. m6 U+ T/ Z/ ~) g) j! dWCHAR szUsbDeviceName[MAXLEN];
* O. c3 x. Q- m/ T) L; o6 t. z
" H+ j2 g* j1 v3 Z  [$ A#endif
9 W/ M$ n8 h6 B/ C# ?
, {+ X1 b1 r4 q2 b6 }# ]* q% U/ y  J
# j" p( S# s: |" t$ g 6 ^3 R+ |( P* Z- e- g

+ ]' I' f2 z9 k5 z- X4 q/ K# @1 M; y
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。7 h- x1 K* W3 n7 D
WSS 主页:[url]http://www.whitecell.org/[/url] 9 W4 I# ]# U4 |3 T$ j
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-11-15 14:34 , Processed in 0.039212 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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