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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
0 o+ E% ?/ H' q0 W$ zEmail:   [email]sinister@whitecell.org[/email]1 c- N2 a6 {# h. L# I
Homepage:[url]http://www.whitecell.org[/url]
, L4 ^" x; b2 @4 _% L4 ZDate:    2007-02-26
9 O0 p, D/ C4 e/ v$ [4 |
. }/ u2 g+ F% q6 h
- Y1 }- g+ ?- k8 I8 h2 P# ?3 N( z- P/*******************************************************************; `0 `+ S9 L- G1 c! w% _9 e

" P. m' r6 H( j6 n4 r$ W6 R这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx# z/ y3 D& _; o
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的# T! g" b( L8 O& c6 A3 W
功能要求如下:
% H, E$ X0 j2 e! w
$ B# V% W: O- o6 O  E( w1 i# D/ ~1、强制锁定键盘/鼠标。2 d9 x* Y2 n( y3 p) I4 B5 |
2、可动态加/解锁8 b/ c/ x4 \# I3 a5 X; k- q
3、兼容所有 NT 系列的操作系统。
1 o" K1 O: a9 [
, J9 P- b* O$ Z, l/ y6 Z就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实# y4 Z7 p# U9 Y
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
+ K: A0 z2 X. o! H' e- q何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
4 z! O: S, I  Y5 l上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
3 {7 V& t( T0 \, [怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面, M' x: O0 N! ?
就来看一下我想到的几种实现方法:/ u# p+ }0 N9 Y1 f
' J  h+ W: n1 a
1、全局键盘/鼠标钩子3 E, F! j" n! ?; `
2、BlockInput() API
5 k8 I2 @- Q; N& c4 ]3、使用 setupapi 进行控制1 o" j4 K$ ?- u: G, L
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL5 Y  @* O" z" M& x6 F9 X; j  G5 M
5、拦截 win23k!RawInputThread() 函数1 M% y( ], B# C/ u* y3 g2 L% u$ L
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动) @; |0 N; D1 B7 f' _2 r
7、拦截 kdbclass 驱动的 driver dispatch routine4 N) d5 r% m8 F( C! `
8、实现一个 PS/2 与 USB 键盘过滤驱动
5 u! e9 G- A# {+ P
( @  I1 F* m1 L; k5 }/ n7 e( H* A0 g& t. Y. N4 ?7 k5 N' x- j5 Z
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑# S" m3 L2 v/ n: ]6 \/ g
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
2 I2 O9 a% c6 N" j7 Y) `案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在0 w( I/ [- n/ n* F. J
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因. {8 G6 M1 C; g5 O% j% l8 |" `
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
+ F+ [1 X0 F8 ?3 o+ u, @问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸3 n) q2 V3 ^& S! q% G
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我. l$ ]3 @! B8 x7 O+ b9 Q6 m
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
: K4 J- ]5 r, ~& c$ X% C也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如+ M( ?8 J. i9 I$ R% Y  g3 E, X0 s5 X
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
3 t( p; A& [* r  J, w( r障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截: `" L% s# Z  o6 P8 X% z1 l; s7 F
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
& V' }* w6 `4 |! `; fUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键& O9 A! `0 U7 i! L3 N2 f; R  _
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
3 n" T# u' A0 O) u. N案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
5 X' p# h9 H+ B' X  {3 f4 O& G3 S' F7 l
' ~) m. t+ m2 k- _" K
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
( V8 [: j9 k: \9 B  r  \# B9 L滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进8 ^. D- o. ^% ^; |- z- P$ G, G
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
/ z2 s5 }( @% R只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越  h# \) k$ s; D, Z
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从" e  Q4 e; P% u/ I, c' v2 U
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB4 W* Z! X7 I: ]4 T3 F; M, z
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
0 R# V, q, D+ c- T% \& IIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
, N7 f8 h& Y" A( u我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
2 `/ i8 N  @) ?0 w5 m就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的1 U; W& @/ F: O% h
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使0 P' K8 `* y- \8 j3 Q% }
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通( }2 A* `& E/ c/ D% b( i/ v
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来8 A9 F% m& q! J' J# R# S
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
/ e) _# n' f0 b过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
2 e/ X! _1 j( a7 ]. ]- W- c上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 3 |: [( e8 {- K
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意& {5 \- N+ _/ E9 w& X) V
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
$ Q* D7 o: h% f# `3 E经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们4 o% F( h5 o9 y1 B2 T1 l( ]# U
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
4 l" k; l6 T/ j. h6 I的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
; H7 A; w0 q. r/ g  f8 u  o# L( N的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
# j4 i/ Y& I8 c5 s  p敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,6 B: V. {4 z. \4 V3 N
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程# Q5 l' Y: @- r
见下面代码。
  C2 g! H$ _+ H" J7 k/ k2 Z6 e) P
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程' ]; I/ s7 z9 v
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
! `9 l1 v$ }8 C* ]% j1 W- J盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20031 e+ T, [8 g6 u3 D) H
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
9 j$ L% [  E! d6 l; I. b8 F% A完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
5 h5 {  v: |$ J4 ]8 |& i继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个( s, }5 W0 H; q; z$ U  N
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
& o" [# x# i. M" z键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。+ \8 c/ |( F3 k* x) z2 R) m" K2 K

) x  t2 {2 ^9 D% n: G) i8 [. @% G- E* a& b) c5 w: v( b
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用1 U* r2 |/ f7 A5 ^* ]2 S
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是1 `: ]4 t9 ]3 K9 ~( n5 \/ u) j
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
* _! W6 X! f' r* B  p9 K1 Q$ K的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
. X" R, q0 Q& s* T  H. @. N们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我, r" e/ s$ r2 V" ~* v; J4 R1 b
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension& ^) |7 K. q+ w- m1 I
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
5 C* K' ~0 s4 l& n5 i9 p如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
* P9 v+ f$ z! _1 C进行操作了。这个问题有待大家来完善了。
. }5 P" ?: Q  o( v( a" i- B
. I/ N: \9 m4 K  w% ^  }: K3 G7 W- F8 v
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出1 X( g/ U- o) g8 v0 o$ `
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
; D/ x4 I% g" Q3 A  W" V分析做个记录而已。我更愿意把它看做是一段注释。  U1 }! h; r) T: U. [

8 I$ x9 _* x2 |! o- T最后在此代码中要
" y' F" k% [: Y1 e4 R9 H( ?3 j+ ^  \! M5 q" D7 G. d
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。1 ^$ I" S* {& u5 O
* @  K, L( d. l% J+ A
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
9 @7 V- R2 M4 C# K" U" }1 l7 e1 x
' t5 d+ C* o3 k( T7 \8 i感谢:齐佳佳,过节请我吃好吃的。: p/ U; S8 n2 g' H3 L; k

. x' i+ W% Y  X5 D9 q5 |3 T0 B( e, V2 c' U- E2 v/ \
******************************************************************/
& Y. l' E) b! S8 [* i, S* j2 m) W: t* \

6 E! O! w3 b9 @% n& G0 T7 W5 f/*****************************************************************8 R" F* L& T6 K9 |- x4 k) i9 Z
文件名        : WssLockKey.c. w# w* A3 _$ i2 ]) J* q' ^# E
描述          : 键盘过滤驱动! o( Q1 p! U* w  ?% [
作者          : sinister. v; s% c& n6 G( |. V
最后修改日期  : 2007-02-26( [8 F. Q; S  p9 n
*****************************************************************/
: F3 _4 \. @1 t6 {, z5 K# Z/ J6 {
& d9 v* |. D# N; ?3 G+ f( k2 W8 \
7 v, V% N4 C0 e7 G1 n2 \! t#include "WssLockKey.h"
, ?4 G: K) e' D  H- v+ o
. L* p' ?7 r' s- {0 J3 {$ vNTSTATUS5 Z, J' c- V- I$ m* c
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
6 \1 a2 p( E$ W" a4 X             IN PUNICODE_STRING RegistryPath )
" a) X% I7 S3 t' O{' }# e& l9 @, t3 B4 ^) m
  UNICODE_STRING KeyDeviceName; 0 j, _! @+ R7 q, J* L8 u6 J
  PDRIVER_OBJECT KeyDriver;
) R5 J' S0 z# B# X5 b% {  PDEVICE_OBJECT UsbDeviceObject;3 H2 M/ e$ B5 g  B6 O0 P
  NTSTATUS ntStatus; 4 B9 S0 Z) h+ N) j# T
  ULONG i; & h8 }" r" q0 A
7 v6 a+ _& F" {1 w2 y
  //2 o' }3 C; z; ~& G* B. A9 W- E
  // 保存设备名,调试使用0 H3 L& e9 r/ u9 _$ v' x
  //- l7 I- P  F) j; W( M
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
" f( r+ H  P8 R" z! z  {
/ H5 w' m& [. q* w  S; C9 P. R    0( l1 c+ U! U; k8 S
  };( [( [' a$ D& g. c( S* \

( }0 u6 t' |+ g7 r$ P  KeyDriverObject->DriverUnload = KeyDriverUnload;
" R, A+ Q' w  W3 G4 `
5 Q3 m; J9 w8 t4 d7 D6 I+ W7 w2 x& C6 A  //
7 p- U8 @# s5 s0 w: \5 w' H  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
4 W. p2 Q6 V+ t# f: X5 J  //
$ }: T7 O0 D5 F) Z6 ~  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法, t2 Z, o# [3 w3 b- P
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
- c9 R8 p( Z' |5 u' M+ k5 ^# d2 z  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到  U/ O& @. G% Y0 A* |& E0 U
  // USB 键盘设备来进行挂接
  \9 u# |1 E! B$ G5 R9 \  //
4 |2 V0 T& w6 m  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );2 Z3 c: ~2 g" m' l4 {8 r8 ^/ W
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )$ N. R% R8 e9 m" N' B$ `
  {" L: G4 e1 V* O. {
    //
/ M; d0 D6 g) c, l# j    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名& R$ `) y9 y) E6 B" @3 R6 @: Q! T
    // 所以这里打印为空
9 n) T4 x* Y7 j. `/ _$ j& z. a    //1 U7 ?7 L. a' G9 G1 Z! U4 o
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD8 g3 h" G6 k; s6 A
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );- k0 g* M: `! @
7 q, ^7 m# P9 z2 n3 N( N
    //5 r9 o/ w  K# Q$ I0 L! f
    // 挂接 USB 键盘设备& W7 b8 v6 P; U3 _
    //
" A  m- o# n& ^) |% }- R5 f; j    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );4 f% Z& r# G/ z1 N2 O
    if ( !NT_SUCCESS( ntStatus ) )
4 t3 e: ]* c8 L' }$ i6 O    {8 G* Z1 z" B, l6 Q6 V% v
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );6 s! L  p  x. m6 p  a3 H# z- e1 b
      return STATUS_INSUFFICIENT_RESOURCES;" c: [7 x# E8 R& g& L" r! F
    }" \0 n4 b0 y& o# @
  }! a: g' \5 H" P% ]
  else% K  U5 k" i% R8 f3 R. U( H' ^1 [1 U+ g
  {
* P) B; q5 R& G0 ]/ [    //
8 q6 `# |$ B) Q    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
( Y5 H% h& G& h: d+ R# z# w1 r3 M    //
8 k/ h8 u+ M6 g  y. S) F, U  c0 t    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); " K+ U) ~2 N+ R: R

8 Z/ R* |+ y- q$ J    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
. X1 B  h; j3 i" p                                        KeyDriverObject,4 {' h5 |) V0 q- u) L5 }
                                        &KeyDriver );) l4 u8 I" p8 c" E- X7 q
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )7 G4 j( e4 E2 l9 d* g4 H4 y
    {. l6 B( T) V, e
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
% \$ y8 w4 E6 v. j+ P% r      return STATUS_INSUFFICIENT_RESOURCES;1 Q% E" E7 J- @, M6 N( S
    }0 X( J5 M! W7 n
  }+ B6 w. ?0 i" n0 j% P

: j5 X/ _" M7 f6 d5 g  //3 P: T! }2 }& y' B: a
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止( {: X1 {" T( t& M. b7 l* B% t0 A% `
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
1 p3 y. K! O6 |7 i8 q* B  //: B/ o4 a8 t* C5 X) r- g, l0 V
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
2 o/ n# ]( i" U4 Z. ]& ^+ k& @, @  V; h( ]3 m1 ]3 B
  return STATUS_SUCCESS;  q3 C! B4 M9 y6 V; {3 U
} ; O! B- d. R4 @2 I+ E: T* h9 w
$ U' k/ |5 g) B4 p, W! S
/////////////////////////////////////////////////////////////////7 [' h! F( r  q# O4 L. {9 U4 Q
// 函数类型 : 系统函数. V4 v& ~3 s2 E! e7 M% Y$ V, G0 f& C2 I
// 函数模块 : 键盘过滤模块0 T0 ^" \/ ]0 ?' h. G4 A# n& O
////////////////////////////////////////////////////////////////! l& n5 I- ~0 D1 ~, {
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
6 b; D2 h0 L: E//        卸载键盘过滤驱动- G9 I  R9 f- m; b) v
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
& W& J5 G* c) n//        则需要等待用户按键,以后有待完善7 B! }* |6 ^- Q+ j( Q2 F
/////////////////////////////////////////////////////////////////  k/ q4 h1 M( h+ _, z5 V9 H9 y! a4 T( F
// 作者 : sinister; T9 n2 H2 h5 S2 F' N" v
// 发布版本 : 1.00.00
4 C) u1 v) D. B// 发布日期 : 2005.12.278 U7 e1 ]' |# p6 G
/////////////////////////////////////////////////////////////////
2 Y8 N  b% }8 d7 K1 N; V// 重   大   修   改   历   史' s6 j; v/ l) z$ G  [
////////////////////////////////////////////////////////////////  D( Y- |9 m1 y$ E4 Q3 V6 p
// 修改者 :0 I) g/ O$ G6 z
// 修改日期 :
% L: ~& t5 b2 }7 s// 修改内容 :
) r# z9 v* d; l/////////////////////////////////////////////////////////////////
2 k& ?) O) z9 r
7 A" k& e1 h  |. b1 \0 }VOID5 v! O) A4 V5 P6 {; h, j( q
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
- p8 O+ r( ~1 r2 w{0 L' a. J; G3 u5 E' n
  PDEVICE_OBJECT KeyFilterDevice ;      : ?' t8 S5 b3 Q6 _8 C, a. j5 j
  PDEVICE_OBJECT KeyDevice ;) ^/ ^2 x. l0 |
  PDEVICE_EXTENSION KeyExtension;
' h1 k; g; p9 k$ a. }  PIRP Irp;7 c' A$ v0 G& x  S" k
  NTSTATUS ntStatus;
% `& u# Q+ V( A$ \
2 V5 i' o, X- z  KeyFilterDevice = KeyDriver->DeviceObject; 5 M+ H# _- Q# @0 X3 I
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
6 g% s5 _9 ~( A9 b  KeyDevice = KeyExtension->TargetDevice;
) N4 ~. u4 B! Q0 |1 J0 G/ n% ~7 a- H& H# q8 j; g; e* }) \
  IoDetachDevice( KeyDevice ); ) m* R% c# V5 E2 I7 @7 ~, ~
9 ?& y7 k  L3 S3 u5 Q- _: R+ \- }
  //: i$ J7 t+ I* i1 R  z5 _) O
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
2 ~2 R8 L' u; Y  //- \- }( y& ~# e. S& E
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
# _, F/ U) C5 F7 Z* Y9 a  {6 L, f" N. R3 I! C
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
- e. h9 B( @* |) H    {
; S- x$ [' z( `$ l$ Z) g) {      //
  I' o" Q3 @2 Q/ U2 |8 q      // 成功则直接退出删除键盘过滤设备
9 V4 G" R% @6 j+ ~6 y. W  _      //
7 L- o; p1 j) @$ p* K) V6 O) I      DbgPrint( "CancelKeyboardIrp() is ok\n" );/ A' \( K! _( j' m" v
      goto __End;0 K& g  J2 _* \* Y" A
    }4 h4 q: A2 U) L
  }
3 ?4 m" O" a" g0 C  j3 L5 F0 g5 j. D/ j# k1 _
  //  q6 J! G8 f) ^" r6 u  D2 g
  // 如果取消失败,则一直等待按键' l  b% Z0 j7 Y' W
  //
" j. _8 n0 K+ E. r. @3 |1 r  while ( KeyExtension->IrpsInProgress > 0 )2 H: d' x" n* M+ ]
  {
) \  m! T$ K5 f0 ^    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );" F  n: b+ ~+ _8 B  D) S
  }5 y( ], j& C7 E# U# P8 I

1 ?1 {. ~9 z5 n2 \5 p6 |6 N7 V  __End:9 h# J/ R3 T' C4 W1 [3 h
  IoDeleteDevice( KeyFilterDevice ); ! Q  f5 x" v# a0 O+ B& J

; h2 H+ ?9 ~4 r3 M9 J8 Y  return ;
6 x2 J: K: X  ^- \  M}
$ ~  h8 a( y6 B- f' J6 u  `- q) W- \# S+ M; x! K$ Z
/////////////////////////////////////////////////////////////////6 c6 E7 E9 G9 g. t$ {+ H
// 函数类型 : 自定义工具函数% N9 V- f3 r$ w1 }) e: l
// 函数模块 : 键盘过滤模块
& O6 ?/ e( q, C1 p) N/////////////////////////////////////////////////////////////////
' \; T4 c" P6 G2 \, l* d// 功能 : 取消 IRP 操作0 t8 c) j6 R7 X
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能  R) t/ E# a9 e0 x5 C9 r
//        使用此方法来取消 IRP1 y8 a4 l* k6 R. r4 K. r1 F, T
/////////////////////////////////////////////////////////////////& U, o3 U1 h# v% G/ c" s4 v
// 作者 : sinister+ e3 k# ]8 `6 K5 g
// 发布版本 : 1.00.002 o) R& p& G0 A+ K$ X* `
// 发布日期 : 2007.02.20
: K& f7 l; P/ O7 ^* `# i; ^/////////////////////////////////////////////////////////////////
* U$ f, D/ a2 D// 重   大   修   改   历   史; d6 Q0 `8 Z0 K' M
/////////////////////////////////////////////////////////////////
  [( e5 h$ F+ G0 ?9 Z% S4 p// 修改者 : $ a; U! z! J# [/ G; f4 K  }
// 修改日期 :
- @9 o" n5 z4 Z" _8 d// 修改内容 : " p% E, O5 Q. t* L8 I8 L9 p3 u$ P
/////////////////////////////////////////////////////////////////
. _1 k* e9 N! O) K) i
" v  ~# R/ T8 W, P3 EBOOLEAN! Z  |: P1 S! z4 f# m5 y8 Z
CancelKeyboardIrp( IN PIRP Irp )' H2 |  \; i6 q2 p
{
( |- W( `  q4 K0 \  if ( Irp == NULL )" }$ `1 T! M/ R# H( |5 g
  {8 b/ Y4 \1 n6 J
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );$ }- h& W8 S, l% f0 z
    return FALSE;/ K* O7 v' t. a/ k- m, x
  }
/ J7 f( q8 }8 C" M
" c  U3 r1 m  {  b$ W* p* x7 X% f: ?. ?# u: I
  //' E; }  E2 z4 o: E  @
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
( K6 M/ m% v& G# {8 W7 d0 d  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
- o" Z0 ^% b) d* u* W+ [  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占+ {+ a. b3 C5 B/ ~, u- \) c
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
2 `- {% @& v" a' _5 P: ]+ Q/ Q" C  //5 c" F" [3 X3 W) g

! t) i  L! E  ~9 }  //
  }4 b3 R) b$ ^  // 如果正在取消或没有取消例程则直接返回 FALSE
9 Q, ~! D' M9 Z& |# r0 H' e1 M  //0 N! ~$ n) @' f
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
. }' e# u4 V7 k( b/ @  {
2 L  Z7 [8 E: L( V    DbgPrint( "Can't Cancel the irp\n" );
- ^% E0 e1 i* ]* W4 y    return FALSE;
1 j7 Y9 n- Z4 ~5 s  }: d0 U3 _9 D' T/ N8 M
6 S2 k7 i! U) n4 M
  if ( FALSE == IoCancelIrp( Irp ) )) U3 v' F' l1 t% ?( S: p
  {/ ]/ f8 I: N2 i: ~1 k$ z* t0 m. T
    DbgPrint( "IoCancelIrp() to failed\n" );. Q9 e, s+ ?! n/ o) y- ~: _3 v( |
    return FALSE;) d( C9 D. u, C' o9 R
  }
/ F$ t& T- _1 M! {; ^, Z! f# T* B" b
  //
' V0 O1 c. \, [2 C  // 取消后重设此例程为空
1 K) q$ D! U5 W  h9 q  //
( O$ A8 _. W) j6 X8 ?* u  IoSetCancelRoutine( Irp, NULL );
, d8 h# Y7 j6 _- K7 r1 Q
9 I# I, S" u; p, W$ P3 G: W  return TRUE;; F9 g6 j3 j4 |1 Z
}; z: D7 M$ ^4 h' I
) U  w7 |1 i/ L3 D2 i  E+ K1 a
/////////////////////////////////////////////////////////////////
% s6 q& }5 ^9 g% E1 Q5 ~// 函数类型 : 自定义工具函数+ C/ M9 G2 D  u& J; J; y) F
// 函数模块 : 设备栈信息模块
1 j: P5 M4 _, F" C( q/////////////////////////////////////////////////////////////////
' t8 n/ N( A8 l! r+ _) F  O// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
7 g! D/ j! v: B  A//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)' p' v0 O) Z; \8 H: _7 V; o
// 注意 : " t! v* l0 o3 y) M6 V
/////////////////////////////////////////////////////////////////3 D7 I* T- P" G0 _3 R) P6 x$ k
// 作者 : sinister* v& ~9 O& t$ g# a% ?; ?
// 发布版本 : 1.00.00
# ?& |1 {; Q! I# ?. G// 发布日期 : 2005.06.02- C$ q$ o# a+ K$ p
/////////////////////////////////////////////////////////////////
- h+ e6 x& e! I- o8 B9 H4 l0 k- Q// 重   大   修   改   历   史* _: Q  n. ^' ^8 b- K; y- S% e0 J# R/ m
/////////////////////////////////////////////////////////////////# N8 }0 _" f/ K- u
// 修改者 : sinister
* h3 c# U! w+ q# i+ v/ U: S. m6 }// 修改日期 : 2007.2.12; G$ t4 w6 D6 s* n
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改0 @! c3 M! m1 n( q+ y+ X
/////////////////////////////////////////////////////////////////
3 I! x2 N  f# Z+ F/ r/ V& B! }/ U' k0 G9 }# K
BOOLEAN
8 Q, `9 j6 [( u; L- B) U# BGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
4 t& T2 I  S- u( o: D{
3 ~# [. @) V. e! l" o8 |  PDEVICE_OBJECT DeviceObject;4 g! p# m% w6 H( S' Q
  BOOLEAN bFound = FALSE;/ N% }6 v) a8 A2 C0 x1 D- ^$ ]
% k, l' |. [. a! J. c
  if ( DevObj == NULL )
- P( |2 C8 z$ S& Z! E6 R0 l. y  {- H3 N) G% u: ]& Z8 T! E; q+ {5 n
    DbgPrint( "DevObj is NULL!\n" );/ q/ Y: X2 h2 r
    return FALSE;
7 l/ W" O' c9 Y- r9 t1 K( ^: ]  }* s' h2 G+ Q+ D+ h: V

9 t" b9 m3 p" _- H* w, {  DeviceObject = DevObj->AttachedDevice;* R3 k5 M8 A7 M

& `2 |, z$ a2 ^9 \6 Y0 R% q- {% B  while ( DeviceObject )0 I/ r7 n! e! ~7 G
  {
/ ^0 H8 J  w! A) L5 ~& X; B0 @    //
) ?- H* j- S" V2 p9 B* [/ P* F! l& H    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
; n, N% ~3 Q  S* B3 W; v8 Y    // 有一次足够了。这算是经验之谈
3 f# M$ k/ m8 O: N7 v/ F    //
/ V, w$ u" c& e- x' M    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )' a* s, `/ h- {, ?
    {$ S4 d7 A% e7 e% ]0 A2 g
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",: `  m; u! p. z! b' E# Y
                DeviceObject->DriverObject->DriverName.Buffer,& W  p" j0 b6 x2 q
                DeviceObject->DriverObject,6 E- X, s$ h" T. m
                DeviceObject );
( @* f6 g. P" h0 R; g" x. I
/ r# M; [. G! [2 A3 h7 a% b      //1 N) o5 @0 Z. U( T, i. l
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了& p. k8 u) N. I! J" C
      //4 I8 W/ b3 l9 \" _
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,+ k% Q( u, F6 k4 w) a, @6 v5 W# o
                      KDBDEVICENAME,9 Q, S1 g8 X, q2 Q$ a! u1 U5 o& ]
                      wcslen( KDBDEVICENAME ) ) == 0 )' r- e, A0 C" ?, _. v5 O
      {
) s7 ]/ k, D% J" b3 J, q) ~        DbgPrint( "Found kbdhid Device\n" );, e4 o! ]1 |, B9 b; L5 T# l
        bFound = TRUE;
* V2 b5 X/ e9 ~/ |$ n        break;* s7 F3 `- \8 O$ N3 a, Y8 h$ w% U
      }9 z( O4 T: k: i
    }: f3 [0 [4 N; ]* _* \+ @4 q

" O( v+ E$ Z% a$ L6 U% d    DeviceObject = DeviceObject->AttachedDevice;, l3 c" k7 m/ ?' f
  }# c2 X- w( ^$ [5 J
. d, W, ?# ^% i: P
  return bFound;
: t$ x- N$ W  c}7 k, _' d1 x5 h# W/ M

2 n# \* Q) t0 D* H0 T) v/////////////////////////////////////////////////////////////////
; o% E  ^& s% t) w) Y// 函数类型 : 自定义工具函数; @7 {2 V$ H! K0 T# t! m; O6 m. ?
// 函数模块 : 设备栈信息模块
+ n( k, }/ F  y/////////////////////////////////////////////////////////////////  i5 t) C6 M% @9 @
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址8 q# b0 P/ X% j
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改8 b* S5 k8 v" ?* Y
/////////////////////////////////////////////////////////////////$ e: J$ C( }! Q
// 作者 : sinister
7 m# A1 |5 _' ]/ V* j# j// 发布版本 : 1.00.00, W8 H6 q- n& T+ E& U6 a. Y% ^9 t0 t
// 发布日期 : 2006.05.02
5 [& ~$ y; b" M* x8 |$ f* G$ p' @/////////////////////////////////////////////////////////////////# V2 S6 J* R( X2 j/ ]; b
// 重   大   修   改   历   史3 f; f! X6 S( U9 D# o
/////////////////////////////////////////////////////////////////
! l$ o8 H' d, n/ r/ N' c1 {! g2 r4 j// 修改者 : sinister8 A1 T2 Y$ t( D5 [( n% _
// 修改日期 : 2007.2.12
# K* }& ^! a) f8 V8 h: |// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用5 p- O+ M- u, f+ M: k' |# b
/////////////////////////////////////////////////////////////////
  J# E0 e4 q6 e3 g
- {4 @- x9 I# U, SVOID
. D4 ^7 A; O  S, l% \* G' |GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )# I/ w, {+ n4 h4 G" i3 J
{" _/ m" ]# M7 }  s1 I" O5 |9 Q
  POBJECT_HEADER ObjectHeader;
1 U, d1 ?7 U% D% K  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
9 }& ^* F4 N6 K; {5 ~" _8 q+ Q' H7 B4 n6 p
  if ( DevObj == NULL )
6 N- b" ^5 \7 P  v* N  {3 }# c! W, {2 C3 |, ]
    DbgPrint( "DevObj is NULL!\n" );8 t2 w7 K7 r9 u0 F' d
    return;5 H4 l- _+ c: V6 c- O
  }0 [' G. ~$ f4 b

% V; U+ A0 i. |  //+ K+ ?' }+ R2 L. Q! J
  // 得到对象头
0 |3 _# k" s1 R( J. |  //
; Z* K4 ?; Q0 X0 B  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
- p) Z; Y) }# A$ U/ V
) a. H  F/ n. d* r  if ( ObjectHeader )( |. u' x& Z9 G' F
  {1 R8 S) _! {3 S0 l& o: _; u) s0 `
    //
3 q  t: b" a3 U& J    // 查询设备名称并打印
0 s$ F, P& @& ~7 V; A    //
4 y- L$ ?% \) |9 y# j    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );0 r. f) Y  f6 X
, V' Y) g) d4 d9 ~0 |
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
2 f9 K/ p9 K1 a    {% B+ e  W2 V% b) ^5 I
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
3 L/ W: I5 U: l! `7 x5 b+ p$ Q                ObjectNameInfo->Name.Buffer,
8 m! L! }6 M; I% g2 i                DevObj );
; X; i' U8 o9 k* t4 K) R: R" U, @/ `6 `3 a4 e5 s7 A7 N3 r7 \, w# G& b
      //
+ A/ K8 {: e" C      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示' Z% q) l% v1 _# u/ h' ?
      // 用,没有实际的功能用途
; K& t, [/ \6 h3 s% j/ v) p- H3 h      //- B6 t! K4 E1 H% q6 @) u
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
$ L4 K1 z5 `! f: G8 R& c- {+ P  r7 A2 }) s' o
      wcsncpy( szUsbDeviceName,
5 s1 R8 C. g7 f; [               ObjectNameInfo->Name.Buffer,
( E1 Q: |/ N, L( e" H               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
" ]4 s+ C7 e! c' r% B  Z4 g, Q    }/ @& ^! ?- W8 S

9 X  T+ u) {  q  ^0 {9 |" S    //
6 j  L$ k  z% S7 U$ P    // 对于没有名称的设备,则打印 NULL! c2 u) i1 z: P) i# u7 P/ V( E( J9 w- @
    //
* s' t9 j+ Z" }# e    else if ( DevObj->DriverObject ); D) _0 u% X; Z5 D$ H7 z
    {
/ I4 a' N9 P6 M% x' E+ E& Y+ h  p( X      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",! @0 R3 W6 V; z9 v8 W6 j/ {4 U
                DevObj->DriverObject->DriverName.Buffer,
* }% ^# O/ y, P& X& R8 L9 C                L"NULL",; `4 Q/ \+ D+ {: t7 y
                DevObj->DriverObject,8 R$ R: Z. n) H
                DevObj );$ e% P, ?9 r4 @& O4 C
    }' s2 t. z; P: d6 B* c
  }$ ^1 F' W' C' F$ {
}
% B) v% Q: T# A: H4 o- H0 o- `, O0 F6 d" A: s8 @
/////////////////////////////////////////////////////////////////
7 z+ z3 e; I( D, V// 函数类型 : 自定义工具函数8 }, Q6 S3 h8 w7 G
// 函数模块 : 键盘过滤模块# F5 M' f$ l& }, I% q  \
/////////////////////////////////////////////////////////////////. k. {3 K  m+ L, Q+ M1 z
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
+ c+ n2 U" G$ B2 p0 S/ U' R//        对象,过滤出 USB 键盘设备,将其设备对象返回5 }( Q% j2 Z% `: z. H, D
// 注意 :
; e+ E) }# J( B+ u: f! ~/////////////////////////////////////////////////////////////////
# `; f4 K3 h+ X9 E) |// 作者 : sinister; }' e- F. }1 P" C# I- I
// 发布版本 : 1.00.00
) @5 o  ~7 C  N8 ]/ b+ W// 发布日期 : 2007.02.13% i- `! T- ]1 @8 e6 \  V- e) u
/////////////////////////////////////////////////////////////////# A9 I$ z, x& j# k1 E/ _8 ?" A" S
// 重   大   修   改   历   史
$ m- [; ]! C4 d% Y/////////////////////////////////////////////////////////////////- \! G& }/ S" H8 H, ]
// 修改者 : " v3 m. Z0 R1 u  o
// 修改日期 :
5 T) x1 j. I' [// 修改内容 : / a$ `0 j+ _/ T8 f% [
/////////////////////////////////////////////////////////////////$ H% p, h. d: D! k' l# `; E

3 l+ P5 G8 ?; q. c* s6 R, X: GNTSTATUS/ T3 s& L. q) b* |9 `) U$ [
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
$ i5 N: h" b+ E1 h" D  o{
+ N, L! U* V% ^( O- b  UNICODE_STRING DriverName;) x/ o2 v: e; [6 O7 L" u
  PDRIVER_OBJECT DriverObject = NULL;
, h7 q# S( G$ y7 }) u  PDEVICE_OBJECT DeviceObject = NULL;
2 D. @8 H% _: \8 A  BOOLEAN bFound = FALSE;3 s$ s3 q; z: _; p6 e4 @) V
# L+ w$ M4 V" w" S, L# [
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );  J; m. `/ s& C1 C' d

; b' t: ~1 O* ^% ]5 {; k  ObReferenceObjectByName( &DriverName,, H, i9 g" U4 y2 A% H7 S5 \. t
                           OBJ_CASE_INSENSITIVE,
$ C1 F" l) q1 y& A* g9 G  N                           NULL,3 L- p' I. y0 M' v" f# [
                           0,8 @. ]1 m% V9 g2 f# M0 ]( q
                           ( POBJECT_TYPE ) IoDriverObjectType,$ y8 A2 Q2 n% w9 C3 b+ J' E
                           KernelMode,# e- [! @2 t' c9 f. z( P
                           NULL,
8 S9 Z; a$ p; I! q7 }/ M1 y                           &DriverObject );5 `0 {1 Y. ~+ x+ O: q, H& V, k
" P' H0 K" A5 e' u6 j4 p
  if ( DriverObject == NULL )
& R4 F/ w1 o2 Q5 J. o; W4 }  {7 S7 Q9 D( b8 C* e3 U
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );: Q. R0 j2 C" R: V! ~( I
    return STATUS_UNSUCCESSFUL;
3 _: Q- V+ M& i# k* ^* [  }5 x) z; X  F& t, J7 v2 q* ~
' g  T/ p" s$ Z! F+ D# H
  DeviceObject = DriverObject->DeviceObject;; x$ n& t- [, V4 o, L9 B4 |0 A
' @1 [& B9 Y+ n' r& i/ {$ [
  while ( DeviceObject )# Z* H/ K1 Y+ `% G# w
  {  r& Z: v. W  o8 {# i+ j7 S5 c
    GetDeviceObjectInfo( DeviceObject );
3 [$ y" f9 H( G+ y9 K7 o6 w
9 r& |8 z: k. B6 e, N& B6 S    if ( DeviceObject->AttachedDevice ), f$ t# F* T# t/ {1 ~2 y& _+ G
    {
6 P) C% O2 i+ A) E9 |$ b7 W      //
' T% ~* F8 D$ s) F4 [9 R4 x3 b      // 查找 USB 键盘设备
$ `( D) d) B5 _4 `1 E7 S      //
# n! l7 Y2 q" ~- B4 u      if ( GetAttachedDeviceInfo( DeviceObject ) )
# O: \5 l, Z. |' C      {; Z% `; Z8 O1 ]- T! X1 [# J
        bFound = TRUE;
! T+ p1 m7 ?. G; X! t4 Z        goto __End;) V4 Z& Q1 L* e9 C+ _2 k' k, R
      }: p* d5 p+ z1 d8 [/ P
    }
+ d& e1 Z/ \" r$ m- T6 l
4 n- c  T& s. V% J8 H. ~& g. o* \    DeviceObject = DeviceObject->NextDevice;
* w" K% q; j8 ~) q0 z  }
  V5 M' `# R0 I* }- v; m% ^$ h2 F+ R0 W' X9 P3 D
  __End:  {  |' R6 P& |3 j
8 _9 U& O4 ?! i3 n* p1 u
  if ( bFound )3 \7 ^$ H4 K+ o7 W/ Z+ [
  {$ P4 U% K/ x' u; _5 {
    //8 Z: {9 x% v7 k% p" j
    // 找到则返回 USB 键盘设备对象
, b# J7 g0 S0 H2 ^- ]6 X    //8 M1 O0 k$ _6 [; q: F
    *UsbDeviceObject = DeviceObject;
2 ~6 h" H* g/ I& E  }4 z6 U  k9 f( D/ d8 P5 \. O
  else( }- o+ s. F, A0 T$ z
  {
* U% ^0 t  V1 h    *UsbDeviceObject = NULL;) b  t5 h; o" Y( _; [+ w2 h
  }+ @9 r' w, l; }5 ]
* r% H6 g4 k) Y1 \1 ]! j
  return STATUS_SUCCESS;; |( o- u& ^) g) Y' K
}, A0 m3 u' E- n! Y

  a" a- y2 m- d; L/////////////////////////////////////////////////////////////////- _, R" G8 H. b, }
// 函数类型 : 自定义工具函数
% v9 H: v  k6 f// 函数模块 : 键盘过滤模块8 l6 ~$ v0 |4 h3 @4 p
////////////////////////////////////////////////////////////////
% a8 Y" ]' X! h' o# E) t// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
$ ~& Z. E& _8 y, O/ g//        信息,返回附加后的驱动对象
  a9 |3 O5 z9 J: ]. C// 注意 : 此函数仅挂接 USB 键盘设备; h/ D) T6 u) i+ G- E+ {9 l( D
/////////////////////////////////////////////////////////////////
' ?+ I! N2 g0 {7 h/ j. ]& E// 作者 : sinister% ~% ~0 N& i, G3 q0 [! T
// 发布版本 : 1.00.00) c* W' t* O. k7 I
// 发布日期 : 2005.12.27
/ D1 A' H2 G( t8 |8 k7 u/ F5 e8 Q! c/////////////////////////////////////////////////////////////////: ?/ |) S# Y  B: ]
// 重   大   修   改   历   史5 Y9 t' `8 n$ e# s! z
////////////////////////////////////////////////////////////////
$ P: W& _" ^* ?: y5 d  z% K- r// 修改者 :7 J' _8 ]6 ^$ z1 ]" x5 l, p( _5 F
// 修改日期 :
% a; b9 t& m  l// 修改内容 :* [2 m6 h" p2 r  I+ t4 e, [
/////////////////////////////////////////////////////////////////
+ H0 u* N; I* h: ~6 E8 {: f! ~" O" o( w+ `% ^) j
NTSTATUS
- h2 {8 S! b7 m3 T4 v2 [' ^+ lAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,9 r: _8 Y2 H" y! G3 Y
                         IN PDRIVER_OBJECT  DriverObject )0 f! v5 Q/ J) C( u
{! i5 a' I" Y, a
  PDEVICE_OBJECT DeviceObject;
3 ~9 G+ D0 W4 |2 l  PDEVICE_OBJECT TargetDevice;
8 Y; l) D; _6 E& ]- c6 q8 _) d  PDEVICE_EXTENSION DevExt;
8 Z" k5 p( a# o  NTSTATUS ntStatus;' ^! d: U7 q9 T1 Y$ m" p

. n2 g. S* `: d: l! E  //
3 f) e* J# A+ a/ K( r/ l5 W5 g  // 创建过滤设备对象
& }- W5 t# W2 e" a! o1 u  //' n8 T( ~: v( g; d: J% ]6 H
  ntStatus = IoCreateDevice( DriverObject,
  \3 \8 ]  F3 R9 d5 s                             sizeof( DEVICE_EXTENSION ),
+ f' n% G4 g% k  Z                             NULL,/ v% {2 r4 O$ L- T% G7 t  p
                             FILE_DEVICE_UNKNOWN,
' q+ M8 w% B. |: }, F                             0,# E; d3 Z6 n$ h3 Q
                             FALSE,+ C; L& S: T9 b: B: l7 }, `
                             &DeviceObject ); # }+ A, w& r/ F7 N
% z1 ^2 ^; a1 o3 h+ L) v
  if ( !NT_SUCCESS( ntStatus ) ): R) i' D* O% Y. G
  {2 l5 F, Y5 o7 q
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
: H* t2 k& G6 M$ }3 j0 g8 m    return ntStatus;
4 L( }: g6 y1 C9 U  } 0 v% d) X0 u' M6 I) V
- m! ?7 w5 ^! R; |, \3 o
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
: M7 M9 q& ^1 n' z0 @# u- X+ U7 a4 A/ P# }
  //2 |: s3 h, R& b: [. f3 U
  // 初始化自旋锁" r! M$ x6 s4 t* ~0 W- r
  //$ Y8 w2 e% v  n' F6 q# E
  KeInitializeSpinLock( &DevExt->SpinLock );
# l( |' W4 D" n8 q/ f, ]* q0 y, ~0 k0 O' Q$ r
  //
7 v9 A( }! A$ A& O3 _  // 初始化 IRP 计数器
+ j0 t: o1 k' j% S8 E  //. K; Q& @& k, \( u/ W
  DevExt->IrpsInProgress = 0;; T/ E- k+ J9 Z9 Y9 Q  Y
+ C1 N* ?* P% g3 r4 `
  //7 P( u' Q1 z) ~/ c$ |
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象9 }0 Z" K7 }1 r( R/ V
  //
, p& v5 `7 E1 H5 L$ a* |& J4 e
" I# t- E4 A- ?4 f. G  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
. \" ]) G" y( [) C" ^  if ( !TargetDevice )  t' j+ T. U! }# [3 r! f! b
  {
4 ~; D- w4 T, ^8 G% r    IoDeleteDevice( DeviceObject ); * }, \# O8 R) O' B1 B: w
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
3 b7 B1 ?7 c5 w  b& ^    return STATUS_INSUFFICIENT_RESOURCES;
/ z$ C8 l4 e+ M+ n  } & _# P& N) C, k3 d7 F6 t6 Q
2 ~. q# s, q- Z# ?, o& f
  //
" A5 \, U! p. q; m  // 保存过滤设备信息* t: R4 I! d. X* k( g" ?/ @
  //
! S% ~! i. E) |% e  m2 X  DevExt->DeviceObject = DeviceObject; - C+ @# B: z7 w  l! t+ ~
  DevExt->TargetDevice = TargetDevice;
; ^* u3 I0 r6 i) I1 u3 G
0 B, V# @9 k* L: u9 \  //
  Q; p5 j6 A1 f+ ?* m9 a  // 设置过滤设备相关信息与标志
/ x0 q' k7 b: z  //
' M5 c# B+ `, t, }5 J/ P6 S  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );% k; V: p: E3 s5 z; n4 \3 c
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;8 S9 A% b! v3 X( u
- _9 a; U, M( `9 E" W

3 D* T) _% ?; a/ N  return STATUS_SUCCESS;
/ i, R- V- K) }- l& Q! z}
& b6 P7 I# A$ w2 L6 M$ Q7 ^" ?- q- K6 I
# T- m" R' |. G# f4 b4 X  [/////////////////////////////////////////////////////////////////+ y* L5 t5 Q: T
// 函数类型 : 自定义工具函数
, C6 D7 }/ i3 F8 Z- E& M; X' m; u// 函数模块 : 键盘过滤模块
$ s+ z5 I" d% G3 E5 d////////////////////////////////////////////////////////////////
  n/ l: f' \5 _$ g8 o// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
- {4 C. L' i! n! P3 W4 P//        信息,返回附加后的驱动对象
% d& P" ^* P7 K7 ]// 注意 : 此函数仅挂接 PS/2 键盘设备# a  r' ?; `# F$ S( f& p$ G; A
/////////////////////////////////////////////////////////////////
6 P2 x. p, W8 O, C// 作者 : sinister2 y' r1 I# Q% u8 }! K
// 发布版本 : 1.00.00
0 D" z% u& ?+ ^$ N+ s, V// 发布日期 : 2005.12.27
$ C. [' }; A6 s- I/////////////////////////////////////////////////////////////////
( r. l$ m  m( `$ V" I' a2 N# n5 r/ q6 e// 重   大   修   改   历   史
4 o. \1 _% e# L, k  F6 e////////////////////////////////////////////////////////////////4 ]+ V5 r( |* X
// 修改者 :
3 r" @' X' J+ b5 p# `// 修改日期 :3 D3 T  G% p7 D
// 修改内容 :3 Y1 [5 V, {- I
/////////////////////////////////////////////////////////////////
5 v( q4 i. h7 d: E) Z1 P  |9 n* }6 p# }- K8 }
NTSTATUS
+ m% r5 _( y4 H7 l! U% q: iAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
2 Z, [" a; `8 W% r2 `4 m8 n3 \                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
* [7 Z3 @: z* U" [9 D. s; Z                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象! C8 B! Q# ~/ S9 V4 e/ n- x
{
9 J8 I9 w7 Q. l* d( w6 S8 R  PDEVICE_OBJECT DeviceObject; & i, s; u: d" l# r# X$ K) J2 ?
  PDEVICE_OBJECT FilterDeviceObject;1 x* S" Z, _1 f; n
  PDEVICE_OBJECT TargetDevice; ' N) p+ h, w- n9 i/ t2 T* k
  PFILE_OBJECT FileObject; 4 G1 ~- ~" \' ^; l( ?5 a$ l# O
  PDEVICE_EXTENSION DevExt;
2 H0 Y& q$ E1 F" \0 S5 `# O  g1 K: T, j  |8 x1 j, K
  NTSTATUS ntStatus; $ g0 r3 S$ o/ ?  N/ ?9 M
7 v+ S" h, C1 g# Z3 B) b, C( o
  //
9 o: z  O( C" p& o, }( _4 W  // 根据设备名称找到需要附加的设备对象
# _7 }- N& |, {) ?/ v- f9 _' X( g7 W  //
& z. l& Z3 Y& q% L, J  ntStatus = IoGetDeviceObjectPointer( DeviceName,: o8 t/ J% r  a7 v) E/ z8 v
                                       FILE_ALL_ACCESS,7 C) a9 a7 C: S6 g5 `
                                       &FileObject,
+ q5 v2 W# o- Y! e& U                                       &DeviceObject ); ' N3 S: I; Y1 @: Y& N' }

0 Q$ x& V. z9 [- l9 S) v  if ( !NT_SUCCESS( ntStatus ) )& `, d7 P, c( {6 d
  {- B# c) R/ T  C3 t8 i
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );! p, ^6 D4 l" X
    return ntStatus;% q8 r/ m% O( |
  } * P2 U* n5 D" M" _! i
# L# U/ e' x: X0 a
  //" G/ N% \6 I0 p, f9 e8 I6 W& o
  // 创建过滤设备对象
1 Z( L* x! {& \) L  W6 P  //7 l, O3 f; @$ C8 R5 y
  ntStatus = IoCreateDevice( DriverObject,# Z' ?" c' s1 e' F( F  K, `  U, Y
                             sizeof( DEVICE_EXTENSION ),* z" h# ]' v$ M& B- e5 N8 c- ^
                             NULL,
4 z. T. A& s: p6 U, \! u8 Z3 V; q! I; q                             FILE_DEVICE_KEYBOARD,
( X" E* R* y9 S                             0,; l9 l% i) ~) a1 L5 V
                             FALSE,
/ l* r9 [# L& W$ c5 ^" D                             &FilterDeviceObject );
7 J- \' f( C  D: c5 j0 v
+ A  F- K. |& v5 ]2 [# k6 b  if ( !NT_SUCCESS( ntStatus ) ): o, z/ _2 V( \: w5 r7 o+ j( G* `
  {  e% n0 ~" M; Q! M
    ObDereferenceObject( FileObject ); 9 N9 z0 J4 ^% \! j
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );" w; y, h+ d1 m5 O4 j0 ~+ C
    return ntStatus;6 W2 L# E0 ?. z- o: J6 N
  } 4 y! y, M0 x: E+ g) u
- ^6 P) l  N; V5 B
  //% h( O/ X, q' W" @! v
  // 得到设备扩展结构,以便下面保存过滤设备信息
+ q6 C$ U; \# O2 G0 v  //7 v  G1 f# K9 e9 d# B
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;; o: D: z* h% Q4 k; A) A3 e; u

1 o1 F5 m, V; |7 p& m/ z  Z- r( V
  //
- k; V. Y7 k( m6 e) S0 m' m- b% F& h  // 初始化自旋锁
" b* t! c: i: L6 ?$ a) r  X! v5 u" l# j  //2 K; D. b9 H) J, h+ [5 T
  KeInitializeSpinLock( &DevExt->SpinLock );
' D1 ~( s3 _1 i) ?8 L& D5 w+ }
  //
. b- E4 V8 y2 u9 J, \" ^% W0 u! ]* X  // 初始化 IRP 计数器
, P8 E( u, X& A  //
, ]4 U; R% Q" z5 X  DevExt->IrpsInProgress = 0;; \: ^8 L, Z* U* y

" q0 z  l" f; R5 A; z( G) u  //
# f: i2 \3 e+ g( ?5 x" V  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象# m: X/ D$ W$ K- W
  //
5 L! K' ~0 Y$ f9 X- F$ n9 A$ T  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
, A$ B* r# A- h5 X( O# ^& i                                              DeviceObject ); 4 Y& P; ]+ m- t# I
  if ( !TargetDevice )) l* C/ B8 P  [
  {
3 V6 L$ F5 l9 W    ObDereferenceObject( FileObject );
4 b. @, W( B4 _2 |    IoDeleteDevice( FilterDeviceObject );
: @4 M0 t1 @# Q6 q    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
- n! I" ~: x( I) n    return STATUS_INSUFFICIENT_RESOURCES;6 N1 |5 n' i+ O! _) X
  } 7 A  }! e; f( V& Q9 h

6 \, h/ L0 |# G& a3 H) y  /// R" \. j* f( |6 H" `
  // 保存过滤设备信息5 D9 o' A4 r1 t4 {0 J
  //5 D& v1 p/ i1 v% T" T2 w% U
  DevExt->DeviceObject = FilterDeviceObject;
6 G% N5 v4 x& {- b/ o. P6 M  DevExt->TargetDevice = TargetDevice;
3 D. _. u0 q, M* X  }, F6 T  o  DevExt->pFilterFileObject = FileObject;
$ e9 M5 s0 Z! t5 t
- }3 }" J: A5 G5 H  //
# {+ E5 @4 D- Q- Z; [! o  // 设置过滤设备相关信息与标志5 t9 J- K: S! P. g& c5 h6 M# @2 w  X2 Z: o
  //$ H6 B* b( `9 y2 T
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
; s6 E4 A1 ]; E# t$ _' Q' ?2 e  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 0 g8 I- j7 z9 k" u* A: g
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2 k1 }: P; \& t  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |8 N" O$ d  G# [/ V, ^
                                                         DO_BUFFERED_IO ) );
- ^6 C4 F$ X; K4 D+ K! O0 i6 b" V* j9 d5 ~4 \$ R
  //" @- E# S$ Q0 J
  // 返回附加后的驱动对象
4 P, c" _( Y+ \& C' C; j4 H: b  //
+ S: g2 ~( U% i0 K, c3 g; H  *FilterDriverObject = TargetDevice->DriverObject;
% Z- O- W. ?  V) |- |: _! ^0 N6 j! Z- e1 l9 B8 a' K
  ObDereferenceObject( FileObject );
6 V) g- M4 Z1 R  W2 C- \5 @9 |6 A8 m8 F% P! ]2 o' p$ D: W" M
  return STATUS_SUCCESS;
- e3 c( g- W; d4 T3 C* y}
, L  w# g: [7 }! m- u; V" J: Z. ~2 |% Q  ^: l
/////////////////////////////////////////////////////////////////5 }% e' l, p" r
// 函数类型 : 自定义工具函数/ K% M6 A5 R7 u& J) e  q9 T
// 函数模块 : 键盘过滤模块
( m) O1 j$ b- F////////////////////////////////////////////////////////////////
7 F; f1 {# `: U) D6 j4 A// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
( `( G6 q9 J3 \- h2 Y% g5 d+ M' h//        这个 IRP 的完成
. O& Q$ h3 [$ n5 d! o// 注意 :
% z. h  g6 J" D6 M  F; C/////////////////////////////////////////////////////////////////9 p+ D! f! G2 i; j+ ^4 U
// 作者 : sinister6 e/ l# D8 N, b. r. g  w. O
// 发布版本 : 1.00.00
/ B5 u+ n5 h+ l// 发布日期 : 2007.2.15
( C2 p& v0 e& }  ]" O/////////////////////////////////////////////////////////////////4 m" W5 L: d# C9 F9 B$ _0 ^
// 重   大   修   改   历   史4 C- V% V/ d! m5 N# l  V$ ]
////////////////////////////////////////////////////////////////
) U; l: K8 ~2 ^$ b4 q9 y// 修改者 :
: c' n: r  ~% U& r' }// 修改日期 :
! Y  S* b2 V0 U# O// 修改内容 :
/ q6 H  i8 V! n////////////////////////////////////////////////////////////////// Z7 K! M0 _- b: P% W& {
) |, n" [0 P( ?0 w/ V! r
NTSTATUS
! R& |/ e3 W3 v  X* JKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )* @/ K; z4 u4 ?$ R; d" ~
{
, B$ S8 t; z0 d8 q/ s: D( I! e3 S  NTSTATUS status;
6 ]  m* l; q- t5 i- Y* o5 h% `# y  KIRQL IrqLevel;5 W! w$ s5 Z% ]" [1 E7 c
8 C5 v" m6 I* W: r! `/ {5 S
  PDEVICE_OBJECT pDeviceObject;
7 }. S6 V- n# L3 c) l  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
4 F4 T% r6 X0 ~+ X9 G$ I0 L7 X% U                                   DeviceObject->DeviceExtension;
2 _( _- l. ^( C! {7 g9 g" b: a

  Z7 M/ A) w& Z  IoCopyCurrentIrpStackLocationToNext( Irp );3 }% h( ], _6 k3 q6 H: v$ Q7 H
* d$ H( n4 {+ M
  //
( n& C. E# F6 X7 y) K" z  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
: B0 N. q  S; O9 H0 p3 F  //  z# X/ [) `' U
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
! d; }: A6 U5 U9 a! P  InterlockedIncrement( &KeyExtension->IrpsInProgress );* r& W) ?6 r# H9 C
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
) ]: ~5 F8 ~6 |( p# a0 N, Y0 I5 c( A% h" D
  IoSetCompletionRoutine( Irp,
% d) _0 D& W9 `1 X3 }                          KeyReadCompletion,( k$ u# h9 H$ w" V5 t; d
                          DeviceObject," ?" o, M; h8 [
                          TRUE,
* A- I) S  `4 {0 w5 r* Z/ A                          TRUE,
2 f' S1 o0 q% b# P  k                          TRUE ); " {1 G7 P* A* ~# r
9 o: _% C+ N9 H3 A/ ]
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
8 Y% W! T  }! s2 m* c}
  K% U' _5 }3 l# m0 k# V0 l0 T0 y/ b5 G3 S) C" w/ t+ i! @2 @, K
/////////////////////////////////////////////////////////////////1 z# r; ]3 G  h  G7 P
// 函数类型 :系统回调函数- c3 h0 n" h3 q
// 函数模块 : 键盘过滤模块
- R3 h8 F5 X3 M. ]1 _////////////////////////////////////////////////////////////////; r1 Z1 Q4 j, h) j- h
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
, Q0 m  e7 N' [) @// 注意 :
4 J1 l3 P+ G/ u5 A& f/////////////////////////////////////////////////////////////////
) q% j9 G; d# q% V  X& N% L// 作者 : sinister  {: }" d8 g* K, ]0 q, F. A
// 发布版本 : 1.00.00$ u7 c7 Q! Q5 M9 R" M
// 发布日期 : 2007.2.12
" F/ @9 `: R  u8 S- i2 p/ `1 d/////////////////////////////////////////////////////////////////
2 w! n5 t( `1 J) `* P! K// 重   大   修   改   历   史
7 K) s  V" C2 J0 q( W" e. x////////////////////////////////////////////////////////////////' J" m; _: |2 c( e" j4 J' @
// 修改者 :
4 G7 Q5 M3 z) i, [8 w// 修改日期 :
# v; Y( }7 g' u& \2 `// 修改内容 :
  V" r& p; r' _, t( z7 r% `- J/////////////////////////////////////////////////////////////////
# G1 K+ ~5 S1 C) S1 r  p: C' Y& s" a. l( {
NTSTATUS
$ W' W( m+ ?9 ]* `9 w  B1 `KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
& J7 }) w& O( M! [; j8 a- o                   IN PIRP Irp,
2 a7 ~3 K+ Q$ ~; ]                   IN PVOID Context )
. `& o) ?' @# D$ N- u, T  ~. m{9 l) G  ?% Z, D+ P" R
  PIO_STACK_LOCATION IrpSp;
. r/ |* c. f" L- a! Z, @) w  PKEYBOARD_INPUT_DATA KeyData;3 B7 L) {4 Z1 A* M2 q5 |3 a3 z
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ G! o( J! V5 u# e  V                                   DeviceObject->DeviceExtension; / w3 }- d) J$ E3 t# i8 Y
  int numKeys, i;
2 k" _0 Q9 I+ L. X3 E2 ^  KIRQL IrqLevel;$ E5 M3 W. ~& t
4 z$ n9 R2 T+ _! M# B
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
2 k7 D( u0 n# Z( D( q; K
' p0 Z9 b) I, Q1 K/ d% \" n" H8 i! {" H9 e" M- |
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )0 _- }7 A% y7 M7 _0 P
  {
4 I. B" c2 o& Y: W) i. I- J, w5 n    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
' }# X7 E, R. ~' ^- Y# q/ R    goto __RoutineEnd;
: e0 w& I/ f; g" m$ t  }
  C( G* B. C- V  ]
2 P  X& a% d! g4 z# T5 b  //  ?( v( d! G, @- e  M) U4 M
  // 系统在 SystemBuffer 中保存按键信息
/ c+ i* |4 a4 Q8 [7 h2 t# {  //6 G9 G  h/ E) X, [3 I. W% |+ Z
  KeyData = Irp->AssociatedIrp.SystemBuffer;$ x) a/ `% c  e5 g/ M8 I$ z
  if ( KeyData == NULL )( s$ K( E8 [0 D$ X
  {
# o) H7 {+ P  p7 S    DbgPrint( "KeyData is NULL\n" );
% {3 [, W9 l. J8 g7 {2 H    goto __RoutineEnd;
2 z- r5 n  f% {  }4 x% }" _+ p1 ~6 O" ?  q3 l8 j

1 j- A( u$ o* d( G9 I. r: e  //7 ~0 e  E( U/ e2 d# y/ p
  // 得到按键数- G& i8 h: _# j% Y( E. o9 p" Z
  //- G) Q. H8 X5 h# E
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
3 }* |2 `$ `+ t# y/ f6 i  if ( numKeys < 0 )+ V" y' W% d7 q$ `! P5 j) f
  {
4 n0 M/ G% k: X, o  W    DbgPrint( "numKeys less zero\n" );
4 {& Z. Q  [0 r    goto __RoutineEnd;% ?) j1 _9 s6 n1 @) \& w
  }9 }  i* D1 W& m3 O/ L8 X
( o6 c2 R* v) M6 b8 s5 G3 Y
  //
; ~+ c8 e/ Q* k  // 使用 0 无效扫描码替换,屏蔽所有按键0 {9 K  N" C; N$ [: e
  //, K9 }8 G7 ^: H
  for ( i = 0; i < numKeys; i++ )& d% e* w! @' S2 o
  {
+ Z/ {! n* n0 N    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );# G! @$ J, e' g3 U) a
    KeyData[i].MakeCode = 0x00;
7 p# A+ Y- v8 n  }
2 S! |$ c8 _. i$ X& s6 b" C9 |
4 F* z+ h! _. F) R' t, A( D4 ~/ m7 }1 b. R. j
  __RoutineEnd :
  b) f& K- N; `) T" X& v" Y+ t. P0 ?9 q3 `, ~
  if ( Irp->PendingReturned )
7 }; [- p- K+ u& d- B& R; G  {
) y2 {7 W2 a, y- b6 i0 W0 ?    IoMarkIrpPending( Irp );* [% d0 g' L* l+ }; h
  } " n% b4 y! ^: ~4 f( G; u0 L6 Q
% P% d# w: }$ {! U* ?5 G" ^
  //$ t% o/ k$ B& O4 q
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁+ J+ S' U, C3 d# w0 o: X8 V
  //
- U) P+ d) e4 z$ p  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
$ K9 m% ^" n  w  `" `2 r  InterlockedDecrement( &KeyExtension->IrpsInProgress );
# _/ J/ x$ \) @  ~& M  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );# [2 q+ n, x, y* {+ K
2 Z; v4 o) \3 G+ _2 U% [
  return Irp->IoStatus.Status ;6 K' E: }0 `: U6 h- r& w* r
} 0 i! G0 q+ i9 D& [+ f: R
2 f/ K3 S' v: L! D8 K

. j/ ^3 d* ]! i5 ^( B/ E$ _/*****************************************************************
4 n5 I) T# }! G+ N 文件名        : WssLockKey.h3 d3 a$ k( i; d+ I. }! P, D9 X" g
描述          : 键盘过滤驱动# j$ G, h* K# G# Z5 ^- ]/ d2 G
作者          : sinister
# l' ~* P* t# s+ z, A, D$ e 最后修改日期  : 2007-02-268 T9 o6 T- L( g
*****************************************************************/
6 w. |2 ~1 y7 b
8 ~2 R4 W- B5 `6 y#ifndef __WSS_LOCKKEY_H_( f7 i, ~3 \. z7 ~) c, b
#define __WSS_LOCKKEY_H_
- Z* @! J/ q! N) a9 E( u% N3 n0 H% H2 |8 M; o
#include "ntddk.h"
0 I; [' O! N* z% i4 a/ o#include "ntddkbd.h"
) f1 Q( `7 `! s' H: k1 i5 S2 g% p#include "string.h"
4 l- g6 J6 {/ y5 g! v1 a#include
2 k- F% I  i# v% J$ [
1 D8 c, U0 B" n% X% Q8 V#define MAXLEN 2560 r. i3 J: N: j2 F$ S
% s/ H( J- T, v
#define KDBDEVICENAME L"\\Driver\\kbdhid"
! T6 R4 Z! D4 y/ ~/ i2 z6 t#define USBKEYBOARDNAME L"\\Driver\\hidusb"
" K% T0 Z5 y8 t! p" }#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"% j' y7 j# i4 m1 z, g% q
# M- x% J" ?7 u2 s8 N/ |( g
typedef struct _OBJECT_CREATE_INFORMATION
, p: O5 Z( F$ H{
) J8 s3 r' V2 ]5 @7 r- n+ b    ULONG Attributes;! v5 q. ]0 j% v/ k
    HANDLE RootDirectory;+ b" Z& s1 R+ `. q
    PVOID ParseContext;
2 r& F8 q3 j! ^    KPROCESSOR_MODE ProbeMode;0 W( w4 k9 S/ d7 z" X3 e8 Q. p7 T
    ULONG PagedPoolCharge;
8 r9 _( Y' D) G0 T9 U7 W    ULONG NonPagedPoolCharge;. y1 X+ F' t" k& B5 w! V
    ULONG SecurityDescriptorCharge;
" C, A7 O: r# _' b/ O4 y    PSECURITY_DESCRIPTOR SecurityDescriptor;, _$ Z5 o/ d  e& R, B3 l
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
( ~! f* ~+ `. J; Y5 H" T    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;& M. L) t: I; |8 u: T- w
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;5 }: Y" F4 T2 ]. X* e: T
% e& @$ y4 Q' t" V  j! n" \+ R
typedef struct _OBJECT_HEADER/ q1 F$ R8 |' v0 ?
{
# }% v5 B" J: g$ p* K    LONG PointerCount;" c: T" I( t% @" j& ^+ U
    union4 S+ n, \% j6 H1 x6 v" `" _
    {$ u4 u+ @3 f/ S; }# ~) l4 q# c- @
        LONG HandleCount;4 r$ n3 m, x. G* _" [& u3 ~+ [; ?
        PSINGLE_LIST_ENTRY SEntry;
' d+ i2 T+ i! b8 T    };# c) f; T+ e! ?% y3 y% |
    POBJECT_TYPE Type;
  T' N) E" B" p7 z1 h0 F) b    UCHAR NameInfoOffset;2 M0 p! G4 \4 ?- p& T2 M' P( V
    UCHAR HandleInfoOffset;0 n% `7 j# q0 n6 h' x4 a3 _
    UCHAR QuotaInfoOffset;( r$ R& t8 d: m' ?0 m
    UCHAR Flags;
4 I" ]- f# K% h, _& o8 W    union
% i5 J1 `# y1 n0 s3 r. z( t/ {    {
: X) m5 _1 N3 H5 j: t7 B        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
* x$ d+ R1 B5 ?, }" Q0 c        PVOID QuotaBlockCharged;
6 f3 q0 r, F) s# I% u# k/ D; S    };. }& ^* O7 B+ w) [: G
% W: E' v! e% ]
    PSECURITY_DESCRIPTOR SecurityDescriptor;
! y  s0 u0 X' R# I8 e5 }) q    QUAD Body;
6 W+ T1 ?( k& }& P5 k; E} OBJECT_HEADER, * POBJECT_HEADER;
/ @5 z$ l3 d" _! `8 j
' D. m1 L9 m% `9 w  [" N#define NUMBER_HASH_BUCKETS 376 F' s! U5 I* t% a
3 J- Q) j1 W. R1 o' S9 H* k" A
typedef struct _OBJECT_DIRECTORY
0 O$ _# N4 ~/ K{
, V' \$ T: d6 F6 z7 ~    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];: Q& B+ h: u5 K* w( n, m1 y8 a
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
4 x$ m0 P5 h% V, \. w- a8 f    BOOLEAN LookupFound;5 M( w% W! Q" t
    USHORT SymbolicLinkUsageCount;4 f( F& b$ W7 O
    struct _DEVICE_MAP* DeviceMap;3 o0 u) h$ r1 Q* f' ^
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
/ n+ u; h" D# M3 H1 Z& \9 ~' ^, K6 [  P' Y
typedef struct _OBJECT_HEADER_NAME_INFO6 ^, ~# F  r3 p( a9 F, l
{
; l/ ^6 ?4 b) v1 G; w6 M    POBJECT_DIRECTORY Directory;
- |, b. o2 c+ J$ e2 i5 ]    UNICODE_STRING Name;6 ?/ ^  t$ E( U8 {! {9 y$ j
    ULONG Reserved;0 b# k& ]- m+ o/ l
#if DBG: F: s( n, l1 o* ]
    ULONG Reserved2 ;! U6 O9 ~" N' ~' [, v8 ~" ]9 m0 f
    LONG DbgDereferenceCount ;
" X6 x$ ^; H& ]! t#endif' i) a$ r) h. p
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;- ~4 v5 R" G9 w7 `

1 W9 P, N7 x# l7 I#define OBJECT_TO_OBJECT_HEADER( o ) \( [5 m. C+ S) y: F0 O
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
& k1 y; A( p! d( L. {$ K
8 P2 J" }, m: b4 P: T4 y#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
8 N+ ~- x" E) y6 S    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
$ {5 V. Y! e1 B+ C. ^
4 O! @6 ^1 e' G7 C$ m9 Gtypedef struct _DEVICE_EXTENSION
5 ?* z% W+ o) f1 z' r6 _2 H/ ^, z{
1 Z( A0 k3 c: E, Y    PDEVICE_OBJECT DeviceObject;
% U) I: A% v7 b    PDEVICE_OBJECT TargetDevice;) J3 y- a0 T; ?8 f3 C7 t
    PFILE_OBJECT pFilterFileObject;
3 L& b' g- C2 T, ~4 J9 _% A    ULONG DeviceExtensionFlags;
; d1 L) v5 P2 l* G. B8 Q5 `( t    LONG IrpsInProgress;0 A+ w) i# f# v( N3 A
    KSPIN_LOCK SpinLock;
+ C1 ^* W- w5 [, T3 ^6 o}DEVICE_EXTENSION, * PDEVICE_EXTENSION;) d9 W  L1 K; j( p5 Y0 @5 x

& P2 b% r3 n  r1 i8 V
% \# h7 F- {+ S8 ]4 V; {VOID
' T: M& d* _. F! }( |1 VKeyDriverUnload( PDRIVER_OBJECT KeyDriver );
1 K+ H/ H" I5 n- X0 t) N. _( Y% O* X3 U$ L) J( s9 |0 t8 i
BOOLEAN
5 @4 @* m# s* |CancelKeyboardIrp( IN PIRP Irp );  B; ^- T" t  H' N$ G+ _" h& ?
8 t2 J0 x% J+ t3 k3 w4 B
extern POBJECT_TYPE* IoDriverObjectType;
$ Q. ~. W& F1 V' i; K% v8 \+ I
; i" Q+ @6 D2 w, CNTSYSAPI7 V" G- ^* ?6 Y, g( n5 \: z" t1 I
NTSTATUS
' k: Y/ Z, f8 D% C1 `2 kNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
, \" {- r$ ]$ z0 a                               IN ULONG Attributes,+ K4 ^% j0 k8 O' i
                               IN PACCESS_STATE AccessState OPTIONAL,
6 W; S& x+ D$ G. j6 T                               IN ACCESS_MASK DesiredAccess OPTIONAL,
( k- n5 h2 t. y9 K                               IN POBJECT_TYPE ObjectType,1 [8 j! Q9 t% I7 P4 i7 W
                               IN KPROCESSOR_MODE AccessMode,
2 C; `! Y/ b/ [5 o) ~% l                               IN OUT PVOID ParseContext OPTIONAL,# ^3 I0 R# X( T9 D
                               OUT PVOID* Object );: H# [9 C& ?9 Z' s0 J$ v
& W4 `  @8 k% g4 N
NTSTATUS % r$ D- p7 b! R% \' x0 @, N
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );1 ^( M# H; J7 O+ P) t$ j+ s/ T
$ u, y9 Q& H; F
BOOLEAN
1 w; b4 C! v2 P8 _6 M4 u7 LGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
, F" T$ T( U- O3 ]2 Z7 q! `- V4 B
0 W; F' I6 z. y8 U6 L8 rVOID
( {$ R2 c( D6 \4 p1 y0 F$ T2 HGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );2 x( `# }  B2 n# c& P9 T% y7 E& z

) p1 ]; w) `- B1 r. [5 B* `NTSTATUS
# g3 A* ^3 ~: FAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,! K9 g6 e8 {8 O0 q
                                  IN PDRIVER_OBJECT  DriverObject );" Z1 k4 d3 O! n: O1 l

8 ~: O9 ~: U' p/ N0 `' F7 |NTSTATUS
' i. H3 b+ X  x0 m& YAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
( O: p/ t' _( M# A9 j                                  IN PDRIVER_OBJECT  DriverObject,
& R& v) F' b$ B  I3 f% g                                  OUT PDRIVER_OBJECT* FilterDriverObject );2 H1 n8 y! |( O# N

& G0 y" l  F+ L% Y, c5 l. MNTSTATUS
6 l. Y4 M& ?6 o0 D- X* a& lKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,, M# M- b% _) P: K# p1 i% H2 L4 `$ r
                            IN PIRP Irp,5 U( i" c7 G2 O! `6 ~
                            IN PVOID Context );6 N6 K4 d* F  n" H7 M2 {5 d
NTSTATUS
  n( \& x; @, |' }KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
1 ~" O' y/ S/ ]9 g  w$ X- T5 Y: h4 c' k5 u! V; l9 d
WCHAR szUsbDeviceName[MAXLEN];
+ a7 W5 n. b, n, ^
8 c% y9 C4 _' C% Q' F$ U4 E, v#endif
5 V3 g3 c2 h5 O) q  t1 y
! f3 E3 O! H8 a4 a, W  G9 ~
0 a' b& h- {' j6 }$ B5 ^" z 0 r/ a% u* V; F. H! p8 f

( e1 ^% }$ |1 z; j& T7 f
% h, s0 k& u' tWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。6 [! f' v! k1 N3 q* l; B
WSS 主页:[url]http://www.whitecell.org/[/url] : }+ y+ I1 ]" `+ }# T% O/ q0 y! G
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-8-11 17:05 , Processed in 0.050887 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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