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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister% G: ]: k1 v8 G0 j! J7 i+ V8 Q9 U9 b
Email:   [email]sinister@whitecell.org[/email]
& p$ g) W! u: X" z, e7 ?" }Homepage:[url]http://www.whitecell.org[/url] % D1 E1 a! d4 L0 M) X7 H
Date:    2007-02-26
5 h$ h4 Z( b3 ]- [; m6 l% J, I3 x
# V1 a# D( Z, Z) R2 u) h
9 D6 G8 Q2 O1 B7 U( [/*******************************************************************
* h1 Y- ?2 c3 h: x
- `. [/ B5 m% K, L7 e这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx0 M3 \  ^  Q0 n, j
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
, K' |; @, ?  T% X$ d功能要求如下:
+ ]2 g2 b/ p3 S' C, b, H) V7 z& b9 i4 p' v  _# S* U! d
1、强制锁定键盘/鼠标。! W$ I+ S* Q5 H7 p" W, b6 }" @4 X
2、可动态加/解锁
- H4 K5 Z3 m9 v4 L3、兼容所有 NT 系列的操作系统。+ |7 t% Z2 _8 @& L6 C

  {4 n+ R/ o4 Q就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
, r+ L1 |9 k  o% S, {; p/ x; e现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如7 o3 g# G* k3 m+ T1 m
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在7 v3 ~5 v" G8 C! x# S$ ?! C  m4 e
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是! G3 X4 _8 \- j6 ]
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
4 \: M; X# \: @6 m" H& z1 T就来看一下我想到的几种实现方法:
7 i3 |6 w% ~% }4 D- U
; g6 V: A/ |7 J2 H( C1、全局键盘/鼠标钩子  p+ l5 p, q# _+ E5 b/ A9 B
2、BlockInput() API* p4 f4 w7 P( D0 ~* D
3、使用 setupapi 进行控制
7 {2 ?7 `, E+ u4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
' U8 C  z$ H. a$ Y( c: I5、拦截 win23k!RawInputThread() 函数
2 a8 B% K, v4 C+ W2 J6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
- `# J* w+ t6 h7、拦截 kdbclass 驱动的 driver dispatch routine
1 w* ]' f& X9 S3 U8、实现一个 PS/2 与 USB 键盘过滤驱动# j. t% n/ W) o/ N/ b

6 i3 m. r# W- N
( n0 O! Y$ W# V% Z& f我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑# O- d1 i$ j! }' |
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方) X, K, J) R1 e: S$ _
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
; ~4 R  K8 A- l- B( q, z兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因7 Z  M  @2 v! s, j+ x
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
9 M7 H) z5 W( f2 W+ g问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸! D$ S" u! [% k  b  r' k! l- S
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
1 Q. }- z( L8 m* I的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来0 |' P0 M7 k; ]* U
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
9 q- E# r4 W9 x5 y3 Y0 U果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有% i$ D4 t% f8 K# H) e/ \
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
4 V; n: ^) I! lIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 ; t7 F' j1 |. B. b" ^! |: U3 l9 Z
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
+ |3 i$ X6 }- {! _盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
" a0 D! l4 S: E1 H4 d案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
. Q: G% v5 U" k# D* @6 b/ N% [; G
8 {/ @  k. a/ X2 t* p* O9 C- H$ A1 Z- {' [  s1 z) R* G
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
0 n& c1 h4 z8 x2 @2 Y1 n滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
( Z. _' v8 G6 V& S; M2 m3 Y% P行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是$ e0 q  Q1 k! ?5 _
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越2 m. ~3 l/ c9 U% Z* }6 j+ c
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
/ L* g! P. `5 a; v+ h) F8 I; M/ pKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB0 p5 A: C# ^; {  Z" Y7 r0 v) }
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
$ |% l5 w: M$ l4 w" EIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
, W% y4 s" r, W" \我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题$ I' |/ u! }' x( `
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
1 K7 ]& f( n# j! k( R3 [而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使  }2 [% u/ w8 r' _) m
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通  h/ [  c9 ~. C
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
  l8 g0 N6 E! ~9 J" [8 D* n% L屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
# f- P" X- f0 K7 s4 @过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb$ P) d* M! c& U% m+ u6 p+ j
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
! i. \5 E8 [' y3 [5 J的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
7 F3 f! a5 u3 n+ J味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。6 x  Y6 K6 M4 E/ m
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
1 B$ X' I' {9 M9 Z7 U8 R0 i来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
( O: I, a& y' d9 s$ R  J( x5 j/ e5 Z的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo! _6 K" I: X/ @5 G' F; n" P7 o
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致6 G! R- ~( L# W3 P9 I# t+ W
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
2 f5 O% U8 ?: B1 h7 [3 m; x# D根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程3 y1 Q! A5 M/ L
见下面代码。  e' L5 a1 S- a; x' W6 S0 w

) V' Z1 E7 M  R5 T+ R% |. p+ n这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
& ^  Q' o- S: f( x- R% ^0 B里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键) K# B/ W' w$ c9 g
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
) \% ]( J+ I2 w! r4 s上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有" T7 Q9 [/ j# ]
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可8 `) c& G3 @; _+ m3 g: [0 H
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
" H7 }' p! d/ N锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
) M; I5 y9 v; \- Z键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。9 |% l% J  q, m$ K5 n3 K- Y$ {

. p; i" x0 D5 V3 x+ s( r1 G5 g% V& c
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用9 ~' X: y- a7 Q* F; e
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是  y" l1 c3 N/ p6 d9 G: Y
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
# Q7 _! }5 k- Y' r7 n3 J3 _的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我0 K- p1 l( W1 ~
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我5 C" i5 r1 R  W
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
- R3 Z0 V0 a# x' t+ ?( l->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
* f* m0 c' g3 v5 l  O如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager, g$ x# l0 t+ [8 m
进行操作了。这个问题有待大家来完善了。
! A) T6 g" H8 s: A  g- ~( f9 D
; ~0 z( T6 E8 p! N! K' A% w# M5 T1 w' ]2 ?. _
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出" N/ c: ^- _+ {7 F+ Q7 C
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
/ A" R7 s) ^$ a& X* y% \分析做个记录而已。我更愿意把它看做是一段注释。
5 B3 M9 Y5 U9 a& g8 A$ r
5 B5 Y5 \: s) s( ?最后在此代码中要# {9 P5 r" u# G  x5 u) N- G4 O0 N4 A
" C) C# U  L9 T9 a
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。& ^' R; |' L2 Z7 g5 Q
4 x, S6 S+ y  G8 U
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。; \8 u& v( a) M5 W: n0 k

( _" L( M  ^. x( w感谢:齐佳佳,过节请我吃好吃的。5 `2 }' r4 w* k- Q5 {8 `, u

! B7 a& R! O$ `( p1 R# J  [
- [7 Z- n7 J- V: u1 J4 ~******************************************************************/. {! p4 ]: W2 A; h
' A2 ]! N1 \% B+ u# |. |8 _9 @

+ Q8 o) ~& B3 e# }3 E' `# j3 Q2 s! X/*****************************************************************
# m0 W4 G3 T( Y7 w# E 文件名        : WssLockKey.c) K& L7 y* B& ^& o
描述          : 键盘过滤驱动. m4 w" {3 I. G1 i6 @* K% W' _
作者          : sinister
/ d+ x  X! r$ L8 x' W 最后修改日期  : 2007-02-26
) W, K+ `/ l* s3 O+ d*****************************************************************/4 l  N; z! ~! M) w9 h/ u( F
, M/ a7 P7 L* C# B% e- z

( a. H  V+ s% g#include "WssLockKey.h"
: h2 o& t( ^6 I' g
7 d# F% o! v2 c  T: J2 s; iNTSTATUS
# ]" u6 k, z; @) d9 Z- X9 L& JDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
5 D1 c) j' F9 J# b  ^4 B             IN PUNICODE_STRING RegistryPath ), A; M" G" ^" a: V( }
{& {" o/ ?5 N# H8 ?! A: s& a
  UNICODE_STRING KeyDeviceName;
6 `1 ~# R3 \/ d( p& z  PDRIVER_OBJECT KeyDriver;
! I) d4 D% l" m% K  PDEVICE_OBJECT UsbDeviceObject;
# m, z7 n9 e; U1 S7 r. K  NTSTATUS ntStatus;
! C2 m( ]; V+ r0 k  ULONG i;
  Z& D. _; O8 E+ Z
0 {4 P3 b' m0 Z1 B' D  `* S5 j* m- w  //4 E0 U; d" |" b8 q$ B
  // 保存设备名,调试使用; ~- O9 {2 b3 f% z* J2 ]# `, r9 i: J
  //# l$ _/ V9 s- O* s1 W( ]- q
  WCHAR szDeviceName[MAXLEN + MAXLEN] =7 a' t) W$ X/ v; w4 G6 Z
  {! q7 ]3 r) F; X0 ]: s, h! i
    0# I' e/ p& r& ~. V; y+ q
  };& \7 X: M9 \& Y' J1 g$ x

+ l3 m0 \  W- _% E  KeyDriverObject->DriverUnload = KeyDriverUnload; * s. a& |& `- [
- }, v1 s8 R* L* u
  //
- U6 s' ^$ b8 ^* P1 E4 M  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘7 B0 e, v" b% l5 v
  //% E2 f: ]! b( n; o
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
4 F8 l  K1 F% A; C" Y5 `, N4 i  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其9 J9 D4 t6 Q* W. a
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
1 _9 X. y9 g1 b' O6 W  // USB 键盘设备来进行挂接+ r" f# q+ l# H
  //" \$ E- H- ?0 H0 E5 |8 ]: `3 R
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
- }0 ^5 N( U/ T* P6 k6 \$ R  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
" Q" S) g0 g# i( b$ Q2 Z6 d$ F  {, Y- [0 l* V& G5 w& ]1 B+ @
    //( h- [$ j  N& b3 c: Y* ^2 F) S: b4 J
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
" d7 a% @2 V- l3 w    // 所以这里打印为空
' Y1 x4 |8 V. d3 Q& D% E+ ^    //5 v5 O# |" i/ x: D. l4 C( }
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
% {& D% t1 U2 W+ H4 R9 L8 F4 a2 p7 k& P    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );# P0 J: k; w) M! u
: t' W* O/ g! I/ Z0 \& p! M
    //: n; c& V5 c, e; I  x1 J" y
    // 挂接 USB 键盘设备
" p' _' U! J9 ]# o    //7 t) |( r! h9 p8 z0 w& U0 b1 f
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );$ z; C) z4 a3 n% d, F
    if ( !NT_SUCCESS( ntStatus ) )) O; o( c1 f( |( C3 K
    {/ ~4 j# B. F. t- u; Z' w/ E# f9 k5 f
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );9 [) K+ d/ \+ ^+ L# [+ k: L7 i
      return STATUS_INSUFFICIENT_RESOURCES;
7 A- {. G- ~+ v& A# N    }
2 A! y/ \$ f) p) k8 `$ e1 a0 k  }
' a7 Y0 C2 h7 V$ F4 m  else
) }7 T; g2 R' i( E6 T- S( v8 ]  {
  U& g! i# I, f1 e: u- q; W3 `    //; m& p$ K3 d7 A4 n. m
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备7 }$ o9 h  |# r8 |( u& Q& X& W; ~
    // 2 J# |7 P& l$ a7 W
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
3 z5 }) f9 y0 B. I& h
( F/ b; b. r) r  q: C* V& B    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,; _2 B4 x3 |  s$ _, f
                                        KeyDriverObject,
4 S. o" Z* l  K# \                                        &KeyDriver );
# T: G, d8 z2 h4 Q. l    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
$ ]4 Q# H2 b) [, R    {& _: {! z& d; R8 U3 S, t
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );: F# U1 j' |& l: n1 D; Y
      return STATUS_INSUFFICIENT_RESOURCES;1 {4 N# c' m& R2 E: m: Q. ]
    }/ o7 x3 J3 ^0 k1 W+ g1 Z. n
  }
. o; z2 T& o" b& f! }; Q. v
9 S- }: {: ?" G, p+ u, t  /// a4 b5 `' q( d& m: z9 T8 s/ a
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
/ c; F9 p3 `! q, u/ b/ x) Y' d- i" ]  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程& u& I- f0 c! J8 U
  //
6 \6 U8 D- m3 P# ^4 C" V  q( k0 Y  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; ( h% s: x% ^# p7 Y7 ]; l7 E: s

3 y( h9 d1 X, R  return STATUS_SUCCESS;
" o0 x; K# z) K7 w} 8 V+ p3 P- F3 c" R6 l7 t

0 P8 P5 C8 f4 Q* H/////////////////////////////////////////////////////////////////
# F" ^* E5 _/ K// 函数类型 : 系统函数
) m# F+ Y7 z! Z) r// 函数模块 : 键盘过滤模块
( D7 b7 X  q0 {4 e, g////////////////////////////////////////////////////////////////' K) E; e- Q, B8 ^) i
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
# H! {' {# m- p) M//        卸载键盘过滤驱动3 u% _! ~( Q7 |8 B8 O0 {& |
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上* L, }, N( P! r7 U* V; _2 B
//        则需要等待用户按键,以后有待完善
3 D% y4 ~. Q) c/ y/////////////////////////////////////////////////////////////////
( S1 z* b9 ~' `8 v& r/ g! I9 i// 作者 : sinister
: M4 F" l# m8 n// 发布版本 : 1.00.00/ }5 G+ S% A; y! P0 t: I5 ]0 k! i
// 发布日期 : 2005.12.27$ x* p7 e. J9 ^5 t0 t: Z- Q+ {
/////////////////////////////////////////////////////////////////
3 u$ N- J8 A9 I) L// 重   大   修   改   历   史
) \; k! o9 x3 z, p+ l4 \- w////////////////////////////////////////////////////////////////
& {" N; l7 J, t! Y, t" k* Z// 修改者 :* {/ y  f4 j0 ~" ]+ a, `
// 修改日期 :
( O! _, s& F2 U4 @, B1 n/ o// 修改内容 :( [/ j; m) m+ L3 N( D
/////////////////////////////////////////////////////////////////
4 u3 f& u" C7 t* k
/ R* _2 X0 u4 A0 RVOID/ O7 [5 ^+ a) o/ w5 \6 F  b
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
1 g  y. n, j  n) W+ i" u7 q{  f3 M3 k4 D( M7 e
  PDEVICE_OBJECT KeyFilterDevice ;      . {) j. M3 A5 N6 y5 X! B) H
  PDEVICE_OBJECT KeyDevice ;
& v4 b! U8 ~+ k1 E. @' M3 M! p7 H1 m  W  PDEVICE_EXTENSION KeyExtension; / O8 O* m' b8 t7 D9 _! b. C' x7 i, z
  PIRP Irp;! N% @6 ]# [1 Y: M! m8 j
  NTSTATUS ntStatus;$ D( V: s' r  L0 n& I) i( m2 F4 p% x
) K3 ^* t+ c& n
  KeyFilterDevice = KeyDriver->DeviceObject; 6 w5 f( l$ p6 G$ e4 b
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; 6 g8 U+ N; F: Q0 }+ Q) ?, d, }% d
  KeyDevice = KeyExtension->TargetDevice; 4 \. j. C/ @# V$ f. k" Z- @  W
- Z, G" b# c6 U! u6 D$ y
  IoDetachDevice( KeyDevice );
( P+ E* v+ i  B" D
: {" \! M; p, A  s: e& i& D3 K  //- X  V" Y" r; b0 I
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
  Z. _9 @+ }1 a  //
- [8 i/ T9 o; D: W1 B" H  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
) I) Q  T( C0 P/ R  {% b4 [" n+ Y" v$ D
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
3 c- i1 P; [: @9 B! B* Q  y( H$ X7 Y/ B    {1 E; B$ D8 E+ e* j
      //
; B6 [8 j/ o6 F3 r) n% f# ~% i! v      // 成功则直接退出删除键盘过滤设备8 K4 B9 o( `2 Q: |4 _
      //
8 a+ K4 a1 g' V  `# [      DbgPrint( "CancelKeyboardIrp() is ok\n" );
8 s# ^* T% _8 d) x! G3 v      goto __End;
, E/ p% e' l7 A9 ^$ }! k4 |    }; L7 |* v. }! I
  }
' h3 ~0 I0 b7 G+ b6 X) y1 x
0 D9 ^; g7 A, o5 s2 u3 W3 c  //
  j' c- l: m+ C7 q  V; U  // 如果取消失败,则一直等待按键! d1 h3 K% r1 ?- H
  //. M% W# Z2 M0 d: v4 ]" u1 r& q
  while ( KeyExtension->IrpsInProgress > 0 )$ C' M! h8 u  t! B8 Z
  {2 V; _  l/ m$ C6 e/ t7 T. f7 l" v: ~
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );; T9 E4 {( H" _8 O4 B
  }+ r3 @; V3 k( z! A5 s4 L

/ g3 C% f* d& L, I( N  F, X  __End:' l' m0 z( @: o# |- r8 J% ?
  IoDeleteDevice( KeyFilterDevice ); / R; e) c5 U. V

: B7 ]7 m5 ?. L  return ;) T, V0 B4 Q5 o9 J7 }" L3 M
} 0 i1 a% X1 I- Y/ R0 i

1 h6 ^. n3 h: d# w  a/////////////////////////////////////////////////////////////////
$ b+ F$ a6 e/ x% ~// 函数类型 : 自定义工具函数
- c5 j7 |1 v- S9 O: ^! I// 函数模块 : 键盘过滤模块8 B; C/ w. |6 e
/////////////////////////////////////////////////////////////////0 Z, j& j% A# y1 K- g. S
// 功能 : 取消 IRP 操作- K* j  g* W5 g  \- |' V
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能. X& R1 r) g: B3 p* A& Q( E3 X
//        使用此方法来取消 IRP
/ E% l3 e  W/ w' F' t. B; I/////////////////////////////////////////////////////////////////2 P, B/ q" `7 V( a  ^
// 作者 : sinister
% f! u  o1 Q* c& Z1 b// 发布版本 : 1.00.00* b! A; e$ T( t2 M; t) m* S' z
// 发布日期 : 2007.02.20
) H; l7 P* l8 h1 B/////////////////////////////////////////////////////////////////
. N8 n4 X6 M- R4 H& ?( T, F// 重   大   修   改   历   史  L8 _' v% ?3 M8 _: F+ V0 @
/////////////////////////////////////////////////////////////////  G. B- n6 k5 }' p+ V% D7 l
// 修改者 :
9 Q! z7 i2 `& P: R$ ~// 修改日期 : - [% D. B; N* Y6 v8 `* L: i
// 修改内容 : ) k7 V$ q  A: e' s0 H9 @& r
/////////////////////////////////////////////////////////////////4 Y( @+ d8 e' X* H" `0 N" x
+ d0 `8 i" @5 Y- ?' ^
BOOLEAN. S: K$ ?  E& u& F% m% X" i
CancelKeyboardIrp( IN PIRP Irp )" z- ~# |3 {0 {
{# s+ p/ z- N; J" @4 x$ O
  if ( Irp == NULL )
9 `& K4 r- q! y2 Q  {# e- i; r' o9 F" I/ l9 Q# g
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );' `+ ]2 V0 F: i7 t' }4 {1 L
    return FALSE;
. A4 C) y- K( g- G8 u! o  }/ n8 o6 {+ ^9 O, N) ~. }

# e& ?4 s; h0 s" f9 L+ N. ]" e& U- F/ r0 G9 L/ ]' o! B+ ^
  //4 Y" i' F! i! N( I/ Q1 A8 Y( i
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,6 F& s* }$ j% t$ n
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。* a4 m6 |  K, \. B6 E
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占5 f) S- W% f9 u( j3 [
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD6 u7 L5 i4 F9 Y# l4 Z
  //% T. a+ C1 P# C( x

  A1 t* ]# ~$ W  //0 x4 B# p: |' O
  // 如果正在取消或没有取消例程则直接返回 FALSE
$ v5 o# o" s) o$ S4 }- k9 r! D: K  //9 K9 d9 C5 N- ^' `  T8 `9 l) g
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )# E$ s) i  ]# h+ g1 X2 V; U
  {: P, n  R+ G, W6 E+ z, D
    DbgPrint( "Can't Cancel the irp\n" );# D0 e6 G& ~% P# x: ]% T
    return FALSE;
$ Y' C+ h* }; a( O& G  }- P/ k0 j2 c7 Z9 _' i6 u& u

. f9 s) Z) _7 t2 r7 M* r$ b$ Z  if ( FALSE == IoCancelIrp( Irp ) ); L0 w$ K# @: _1 M$ O& b7 A5 ~
  {
1 h/ A% I  m+ u  s6 G    DbgPrint( "IoCancelIrp() to failed\n" );
3 m3 S/ a* T" Y    return FALSE;
/ n6 A' M1 O/ r* a  }
7 _9 y/ L: w$ z( n9 I: F$ J: `! O& z9 a' L5 x
  //4 ?7 U- M! I6 J
  // 取消后重设此例程为空7 i* v. L" I. g$ F! }$ l
  //
0 u3 h: |2 N. a2 r/ Z, C1 P- C3 z  IoSetCancelRoutine( Irp, NULL );
. s) p" u( E: [& g6 H: k5 R) x! v: A7 I& Q) l
  return TRUE;
( H$ [2 n+ \" \/ l3 Z& H}
, V  [; T6 @1 P$ o, L, r1 ]( L0 [4 I( q' Q3 S2 q
////////////////////////////////////////////////////////////////// W# ?" ^! j. @( F: x! V8 l
// 函数类型 : 自定义工具函数( v  C0 c+ R. x* c, d3 j& ?
// 函数模块 : 设备栈信息模块
" ]  P* J. }" \3 \$ f/////////////////////////////////////////////////////////////////3 H; p% Q6 s  V5 A( c
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
2 Q9 {. J. R2 }) D//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
9 `  X3 b4 Q2 \/ X6 R! l# A* R// 注意 : 2 [, v  Q$ P( [, u6 r  e4 g5 @
/////////////////////////////////////////////////////////////////
5 R; B5 H4 B; Z- h// 作者 : sinister
: o1 h$ n, Z1 N- N& x4 w# m* D. y: j// 发布版本 : 1.00.00
4 V9 b1 x9 |+ W& S// 发布日期 : 2005.06.02
* k( N# J& i/ c+ a. d1 e2 ^4 W/////////////////////////////////////////////////////////////////
& d: M/ P  M% j4 @// 重   大   修   改   历   史
6 Z( d- }$ Q% o- d- `2 ~+ a+ j/ c/////////////////////////////////////////////////////////////////1 P6 z2 d1 }6 k( L, ]; E1 s1 Z$ R
// 修改者 : sinister* k/ z2 O/ T( v: L4 q$ D
// 修改日期 : 2007.2.12
+ Y$ u6 Y9 s$ b; X. v" A6 t. E// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
6 R1 X1 w) M5 z/////////////////////////////////////////////////////////////////& _) ~5 F9 j% B1 z3 Y9 L( w: l) z8 D
# {8 m1 v4 x, `$ S
BOOLEAN
1 X. E+ _: X7 X4 c9 \6 \( hGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )0 [3 h. }# f5 B' Y' U4 C. b
{
% }/ L! }: z  ^# s0 \  PDEVICE_OBJECT DeviceObject;
3 x' I! j$ W+ I/ V+ G  BOOLEAN bFound = FALSE;6 M/ P  }# d8 [
/ o& J# Q, q# }0 _9 l' ]
  if ( DevObj == NULL )
3 W! F6 L3 j7 G+ ?  {( N% w/ R0 @8 y6 ?
    DbgPrint( "DevObj is NULL!\n" );! V# I9 q* x6 l7 ~- }; A% [
    return FALSE;. C. R9 L( P. c6 B( V' a- }
  }$ U. W9 n0 r: F1 i$ L  S
2 E. J7 S# e7 P6 n, |+ _& D
  DeviceObject = DevObj->AttachedDevice;6 u2 x& `# ^  ^% S; S* a! `1 ]6 u
5 |9 O8 f& y* `0 n
  while ( DeviceObject )( D7 F+ g/ k& \" R/ [3 r% m
  {
; e" w# m% Q, ]$ }    //
$ \2 |, L0 \+ O" k  z    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
' [. J# Q7 p4 H# a    // 有一次足够了。这算是经验之谈
9 Q% e/ }; ?; I" c    //
8 V/ i3 t' E# J0 V+ [" o& z+ {    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
/ c2 k) V: z7 Q$ D    {
, @( [+ C4 n" ~      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
7 n$ e( i" @0 X( {                DeviceObject->DriverObject->DriverName.Buffer,, W9 r! b: _" u5 m5 y5 _7 Q" L
                DeviceObject->DriverObject,
. z. {- C/ R2 K3 M                DeviceObject );9 S. }4 h6 R, D- L$ P4 a9 R; X  F

7 c* F& T+ m& v      //
! M: E" }6 w& W% C* K! I4 v      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了( N7 l8 c, k! [
      //) A8 A( U4 A: b! v) }( ]$ L! h0 [* h* n) Y
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,! y- f1 y1 H+ O8 L
                      KDBDEVICENAME,
! U; q* `6 d1 n                      wcslen( KDBDEVICENAME ) ) == 0 ). Q0 [3 V0 o; K& E7 E% f: D4 W
      {
- {( a, F4 l. Y1 X: j9 d3 B. J) K        DbgPrint( "Found kbdhid Device\n" );
1 ]9 G( r: i" ^5 N6 w        bFound = TRUE;
( q4 `/ Z$ w: a: f5 W        break;8 h6 S! i8 E% a" L$ O* }# l
      }
: X# V! e$ G2 O8 i1 j    }; `9 g' V9 j; K) D# T8 Q* D
3 C+ _6 S0 U" v. d7 z- N) Q
    DeviceObject = DeviceObject->AttachedDevice;
$ e1 n' c( q# ?5 x1 ]6 I  c* Q  }
9 t4 a; v$ q; p( F8 @' X& M+ J6 M5 u# H
  return bFound;
: h1 k) L) K. J" l8 [8 a6 K) b" l2 y}
8 U4 e7 G# q+ _- [9 M- ]: Q: ]0 T+ A1 R' z1 o, y# `+ a! L4 H
/////////////////////////////////////////////////////////////////
0 }8 m4 ^1 {. {$ I// 函数类型 : 自定义工具函数! E; U( i7 _: Z7 P( ], M7 e3 s
// 函数模块 : 设备栈信息模块' `# F$ Z. w* R8 v" l
/////////////////////////////////////////////////////////////////$ J' J9 f0 O9 m/ u
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址$ w" n$ f3 ]2 W8 K4 }
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
- f$ m4 |5 k6 Q2 G- Q7 O4 s# }) ]/////////////////////////////////////////////////////////////////
6 v7 `( W. T! M9 \( o( w8 M// 作者 : sinister
3 O# a4 b, _6 c7 y' G: I9 I0 b  A& s// 发布版本 : 1.00.007 k% ~! M8 f" @  F) F6 {
// 发布日期 : 2006.05.02
( R& V5 H  k# W% T( d  @/////////////////////////////////////////////////////////////////
# d1 E' w8 L7 z6 n- Y( [1 B// 重   大   修   改   历   史/ }5 C: {6 H" I
/////////////////////////////////////////////////////////////////
7 V) E4 X5 ?0 I' v3 o+ A; |. V// 修改者 : sinister
5 R( m8 r. X/ z: f( N: r; L// 修改日期 : 2007.2.12
5 g/ m+ K2 v- H// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用& y0 c) p, n3 m5 z& `- s0 X8 U
/////////////////////////////////////////////////////////////////
7 B5 D5 U! r0 V! t! u
/ p4 l; i# k2 o* wVOID! J8 b; f; h' k- _6 N, I
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
1 O& a% e1 ~2 g9 d$ G1 b{
6 q1 }1 R/ @, ^3 }5 h  POBJECT_HEADER ObjectHeader;
8 k- Q5 M0 ~) n/ T  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
# a8 f& z  R6 F9 n* ^& J
- `7 x/ y( {, h' q5 O  if ( DevObj == NULL )! h; b1 \# L1 l" r# R! x2 F
  {! P' g; l0 K/ |/ i( P0 Q
    DbgPrint( "DevObj is NULL!\n" );6 V8 a1 K4 B. v9 s
    return;
' U5 }, w( _9 l; _0 O  }. [  E; T0 N: P8 j8 G# M! ^

8 J: L) `1 G: Y. y' m  //4 O1 D% O& p( r6 S3 I- H
  // 得到对象头! S# |& l9 z- w5 F" `& F# w6 f
  //  j' f, x3 M: c' e6 W
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
; f8 @  R" d3 j4 K
# i7 q7 d6 G+ d7 B$ f6 r. X  T  if ( ObjectHeader )
  e* k4 f& I" h; c2 ~6 {  {
$ L  W9 k0 `  O1 ?. D, W6 S4 {    //
9 j  y5 R; m6 d2 j9 h    // 查询设备名称并打印
* U, h% [4 A# S! ^# l" E0 w    //! i  t9 ]) a/ o# u
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
7 Y/ G+ ?. }8 Y0 a4 T* y5 P- |
' T4 d/ n& ]4 M' J' g    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
' o8 D; ^- i4 M    {
* I' R, x, s4 s9 P      DbgPrint( "Device Name:%S - Device Address:0x%x\n",' ?) p5 m" u) J2 y8 k# M& Y8 W
                ObjectNameInfo->Name.Buffer,
! h4 C$ H# n; p9 M                DevObj );
) @+ }% S$ [, x. k- W, ^
) i- d3 F/ T5 t+ \0 n  Z- p- G      //- ]# X/ k$ z0 n
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
, a4 f$ L/ t8 b/ W' x$ w      // 用,没有实际的功能用途
- |8 {  W7 i2 P# D* R) n      /// x$ N: \) a9 V5 |2 I. Y
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );" Q" G7 m/ Z8 w+ v

" w6 ]" q0 N: U% ^  T' o# _      wcsncpy( szUsbDeviceName,
8 n! L* o& ]% t2 N$ g: v$ {5 }               ObjectNameInfo->Name.Buffer,
: E  `; a0 E& J               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );% K1 L8 ]4 M: T& Y8 |. v
    }
8 ^7 c3 i- U+ W; M; q
  Y  n2 k0 O# s, f5 L/ V- v: p    //2 P# D, D$ C! p
    // 对于没有名称的设备,则打印 NULL8 t' N, L, I$ U2 p2 _6 ]0 L) U
    //$ u% d; k4 X6 F: C+ k
    else if ( DevObj->DriverObject )
) J9 J1 Z# y1 ?8 }6 Y5 C5 M    {
4 x0 j* ]( z( y2 u4 s      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
# z" m  {0 b% x8 j                DevObj->DriverObject->DriverName.Buffer,
- |, W: C& Y. I5 @                L"NULL",
" B2 f8 q: @% ~' C. N) Z5 Q+ G9 p( x                DevObj->DriverObject,
- w" ?; }4 S9 A                DevObj );* \. g. d* K$ {
    }
+ N* D# n9 s; \5 Q. ^  }. \( x) Z( I& T4 M
}2 }, Z1 L7 H! U7 y* j  U
  z  \! Q2 l3 t3 ?( {
/////////////////////////////////////////////////////////////////* q% `% Q' |1 [
// 函数类型 : 自定义工具函数
) y/ B+ g" `$ G* w1 v// 函数模块 : 键盘过滤模块
7 h& n4 l% G+ l/////////////////////////////////////////////////////////////////6 R7 ^6 T" P3 [3 D4 `
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
* }: w; z7 V6 c2 z//        对象,过滤出 USB 键盘设备,将其设备对象返回
* p; t9 H( e. k// 注意 : + U1 v+ n, g2 |+ L; r
/////////////////////////////////////////////////////////////////1 J2 W1 _& w8 O  Q! w3 I2 c
// 作者 : sinister
& n: i( P( r* Q- q; U. |" S// 发布版本 : 1.00.00
# o" `# r) e0 R// 发布日期 : 2007.02.13
4 j8 ]( ~" h0 }' x1 u/////////////////////////////////////////////////////////////////6 B3 Q6 Z& P7 U* X/ H3 ]6 b; B. j
// 重   大   修   改   历   史
, g7 X2 e% O6 U# k+ @) a/////////////////////////////////////////////////////////////////
' G1 z7 w  W7 O- o  [// 修改者 :
) x( |7 q1 H; T7 e// 修改日期 :
: D+ m# O/ i2 _9 w// 修改内容 :
( o; |) d; Z2 d$ N/////////////////////////////////////////////////////////////////
9 y: b3 b, r% i! S) K) O' J* U  \( `- O/ O- L
NTSTATUS! X4 g2 n5 `# V5 V) S5 f# d: `3 L2 B
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )/ ?6 S. f- o" D' e8 G
{
$ ^, w8 t$ }% u4 A( ]  UNICODE_STRING DriverName;2 j" V4 M5 l, s
  PDRIVER_OBJECT DriverObject = NULL;' y3 D9 W* }- A- n2 O4 g
  PDEVICE_OBJECT DeviceObject = NULL;
% Z& Z0 {' B$ ^  BOOLEAN bFound = FALSE;3 a9 R  z) o" i/ v3 S  l

# S8 P$ V  O; T. y# b& p8 U  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );/ c& V) k' G' q+ r( l, n6 o: }

# s' F" p) \; b( ^  ObReferenceObjectByName( &DriverName,% |5 S3 C1 b" k( w
                           OBJ_CASE_INSENSITIVE,
3 f) p: s, ~3 T2 h. Q9 D. p                           NULL,
7 H+ C) h7 t0 E( C                           0,6 u; j, o0 E- o( }( z' k
                           ( POBJECT_TYPE ) IoDriverObjectType,
# z, D4 `7 X* M" |1 {+ P                           KernelMode,& Q* f9 }0 X8 X$ B2 m$ j$ m
                           NULL,
  h, F* d# o( X$ m$ @7 ?                           &DriverObject );& p9 U) ]7 b6 A" |6 }5 ]

: Q: k9 z4 M$ W- C0 D  if ( DriverObject == NULL )
( R: Y* d  {" H, ?5 d# X$ N  {3 ]+ H; v3 ^0 P1 y% h3 f6 n( L) _
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
( ~' }& c1 y3 E0 J) u    return STATUS_UNSUCCESSFUL;' q* ]" z9 o4 C, _  j
  }6 H4 P- t% `9 V) i2 ~" r$ `
) q, @& m; l. c* i) D% b
  DeviceObject = DriverObject->DeviceObject;! k) u: m$ q2 n& _& c8 }4 R

" V0 ]- c' l: o8 B  A8 m0 b) X  while ( DeviceObject )
& Z4 l0 U! K! B& ?, ]  {
* a/ @' g( J; z  v    GetDeviceObjectInfo( DeviceObject );
7 ], z1 l8 u/ w0 o$ o7 s
+ O! F# O6 T6 D. z+ q* Z; X/ y    if ( DeviceObject->AttachedDevice )
" t  n2 V( {+ d! v- Z% l    {. |+ F5 z! U5 R2 l; [3 t
      //$ f. e! B$ ?- Z/ p! `1 W$ r! }
      // 查找 USB 键盘设备1 }5 y; u( Z" C5 V( k1 N* x" m& b
      //- J- u6 T- u9 w7 m' H. O& ?
      if ( GetAttachedDeviceInfo( DeviceObject ) )# Y$ K: D5 E- c: s* @& b0 n7 w; {& k* S1 ?
      {
- O$ N) ]# ]. D4 W        bFound = TRUE;% L! L2 ^. A, @/ }
        goto __End;
% ]3 s) S  ^5 w1 A      }% H% G/ X# U- N* X0 [" ?1 ~% T, f) n
    }
/ v; W( o$ U' m& |+ ~* U7 I3 T
( I: H8 L$ |" J) T6 G    DeviceObject = DeviceObject->NextDevice;5 u& ?8 ~# E7 ~* r
  }1 x9 n9 z5 H2 A

1 H8 e6 U; [+ j% r1 n/ a  i# y' L  __End:
5 e" u* `- g( v' {4 u" C
& p% P9 M1 }) [/ h6 W  if ( bFound )1 p! S$ G' j) y4 A; ]- u- n
  {  t6 X7 [0 J% ?" Q
    //. K; P- V( R: K
    // 找到则返回 USB 键盘设备对象' a3 j8 t- u+ E
    /// g3 q4 P9 L! Q( \( p. ^8 ?
    *UsbDeviceObject = DeviceObject;
5 x( r8 H4 r0 i* m. `: t5 G  }, O7 Z9 z2 y! x. E
  else+ c. T0 t+ Q) _, J$ q" {
  {4 s+ \6 v0 c( p$ F
    *UsbDeviceObject = NULL;+ h: d0 D+ O8 U
  }- V: f% i2 N& }
% A+ B9 o$ F: b% ~1 [+ T7 K/ v
  return STATUS_SUCCESS;
/ m( m, F# O. L6 u; p( T}
7 x" `8 z' c" P' Q$ b7 Y% r4 X& t" d7 W# q8 ]1 F) a9 y, |4 N
/////////////////////////////////////////////////////////////////
1 D) E$ u- S1 U* R- n1 f5 o// 函数类型 : 自定义工具函数2 T( h" {  t/ W! s
// 函数模块 : 键盘过滤模块
, T$ |+ F: j" k8 E////////////////////////////////////////////////////////////////: y. b0 s$ Z( e1 j, E! {7 t4 }
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
% x2 V% f, h8 B* y- l1 i% t: |//        信息,返回附加后的驱动对象
' o* n* D( x( a( @* a// 注意 : 此函数仅挂接 USB 键盘设备0 I( k: U+ l  ]' U# ^
/////////////////////////////////////////////////////////////////  D1 ~- s5 F3 E/ l0 {1 {- }
// 作者 : sinister# X6 ~8 o3 g7 e6 j/ L( g
// 发布版本 : 1.00.00
' u/ h: u7 g4 K// 发布日期 : 2005.12.27
1 H0 a9 t0 o6 D( P7 G2 a/////////////////////////////////////////////////////////////////
$ u( z* l) l0 [2 F* z// 重   大   修   改   历   史
# i( U  c$ t" B////////////////////////////////////////////////////////////////, c2 K1 G* {. H9 J4 e
// 修改者 :
( q0 R8 Z. R( K// 修改日期 :
0 y; P5 }1 S2 M: ~) \! d4 }// 修改内容 :
( h: O" G; v' K7 }$ q" O* Y/////////////////////////////////////////////////////////////////7 Z3 t% {0 e( N, {* g1 P+ N5 ?
1 e: S/ c8 ~& Y1 I7 x
NTSTATUS
  e& S! ^" d* J& r; m: H4 C  tAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,3 I9 U) d6 Z2 a: [" G) q" g
                         IN PDRIVER_OBJECT  DriverObject )" A- Q4 I6 C9 v( q
{' C  W. m- |5 W  M1 f2 o
  PDEVICE_OBJECT DeviceObject; 1 J/ J& q- v9 h: ]: m
  PDEVICE_OBJECT TargetDevice; 9 {8 m/ K7 ~2 u
  PDEVICE_EXTENSION DevExt;8 U5 U7 S" }/ }2 X2 D7 h- G
  NTSTATUS ntStatus;2 D5 @, M. L  @

% c; x0 t9 P+ e* `! t  //2 W8 |2 B0 \  L$ d" T
  // 创建过滤设备对象
% k* H8 x; l( Z, Z: w% V7 y: x7 F7 ?6 B  //8 C0 |7 [3 A7 e% V; ^2 G. K/ I5 a. L
  ntStatus = IoCreateDevice( DriverObject,
( N% A/ b! y( J+ W3 k                             sizeof( DEVICE_EXTENSION ),
# j) p0 f; f) n- W2 d* E" N5 X                             NULL,
# j9 N$ t4 I1 g" [# X- V/ P- S, z                             FILE_DEVICE_UNKNOWN,
. [7 J! j, K6 o2 ?9 X7 T                             0,
/ u9 S0 N! j5 I  N- v) i& ^" ^                             FALSE,
  `- Z9 X5 b/ l2 D7 o" c                             &DeviceObject ); % V1 [3 g. U( s) |6 n. y
. h, F( \9 H6 p4 l0 Q; m  \" C% K7 ]9 s
  if ( !NT_SUCCESS( ntStatus ) )
$ r/ B5 r+ m% f/ F9 T* i  {
: Z, {& z$ t7 l% _/ p% K    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );% j, g" m) a" h+ |$ S
    return ntStatus;6 V" S7 V7 R# ~* s3 d) k) D4 W
  }   v7 L% q9 ?) W# ~
6 n! \2 o: j  v* J
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;/ D9 M! ?1 _; k; k3 R

% _, s9 @( a& e% a& M2 `% D  //
+ I3 i- q) D( z. r& C% X% s  // 初始化自旋锁% Q" F+ v, {! B+ U" U
  //6 [$ l' @, @( X0 o9 m1 w) j
  KeInitializeSpinLock( &DevExt->SpinLock );- s% _. _1 l; }3 M
6 T% P/ U; {. e
  //
  S; a2 J7 X6 ]/ `- U. l$ {  // 初始化 IRP 计数器
9 I0 C& M/ O9 m1 u* t4 {8 A# r4 O  //, L* f0 r+ c% ?
  DevExt->IrpsInProgress = 0;. c$ G* ~! J: J/ A% R, _
5 L  G1 p1 u! k; K; Z# v( a
  //
6 {  Q1 S! \, ]0 C% x/ w  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象  b, U( I# p! t& k9 d- O( F5 H
  //
, ]( ~- W& L' @
, ]6 m/ l1 B! R  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 0 D) H) f/ T  G9 `& s$ Q7 N" w( a
  if ( !TargetDevice )
4 A4 k+ A8 V4 q" p# I  {6 {' D! l) s; B5 K+ P/ v
    IoDeleteDevice( DeviceObject );
. Y6 z( G2 X0 w' g6 p7 f3 C    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
) D  q; \5 i2 s& p! L" v# {    return STATUS_INSUFFICIENT_RESOURCES;, I; v2 v+ X- t+ |+ q& t
  }
0 S% d8 \+ }; s* T8 u5 e8 f1 C# c9 P9 n3 V
  //
. r' \1 \- Y& w' e# L, e" N  // 保存过滤设备信息
3 {, \( v; [! @3 X2 w1 S  //
9 ^6 R4 ]7 X0 _4 L  DevExt->DeviceObject = DeviceObject;
. S+ }% T% `& Q9 \  DevExt->TargetDevice = TargetDevice;$ t3 J/ {5 I5 c6 f& f$ B% K- c+ b

+ Q2 @1 S! V( e' J  //
$ k2 ^3 H, |* l" k* C+ Z0 {; h  // 设置过滤设备相关信息与标志3 Z+ c' \+ k1 @3 V
  //- \  i( c- _6 t$ M$ b# B. A$ a
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );/ O+ B( I7 e! U3 {6 h! Z
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
% ^8 q9 e4 l( @  K2 A9 Z2 V6 A0 E$ p: F. P# T) G

* `2 f: ~" Q8 ^# ^& I6 ]  x  return STATUS_SUCCESS;3 F* G0 x3 Y1 O/ c# K9 E3 h2 U
}
, j$ k, Q+ R( r$ F; t( q9 f1 W0 y+ f7 H
/////////////////////////////////////////////////////////////////4 s6 ~: @9 D! o) A/ N6 Y
// 函数类型 : 自定义工具函数
, F; T3 ?  z3 B+ r6 s2 H// 函数模块 : 键盘过滤模块
6 O  D5 z# d# Z- J' w/ C////////////////////////////////////////////////////////////////. f) w9 }& e; M# s& Z9 ^" e( M
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
7 C! t( B( W& o, h# S. S5 V//        信息,返回附加后的驱动对象
: m5 ^3 H3 q+ _5 m; a// 注意 : 此函数仅挂接 PS/2 键盘设备
3 b1 j; h6 p9 H& l" A+ V/////////////////////////////////////////////////////////////////
% i1 \7 a$ |4 u// 作者 : sinister
! J5 M9 V  M4 t9 X// 发布版本 : 1.00.00/ R. i* C4 ?& F+ z  l( H2 t- }4 ~
// 发布日期 : 2005.12.27
) \6 r* }7 m: d2 C) f# J8 o2 W/////////////////////////////////////////////////////////////////
" I/ t, N! H1 d// 重   大   修   改   历   史
$ H9 Z5 a1 J' x. C////////////////////////////////////////////////////////////////
" Q6 V- ^) U* Y5 d% p0 t// 修改者 :" G1 \: T  T$ X. ]" P
// 修改日期 :
0 u) o- U5 W. @# }+ V1 Y% v// 修改内容 :; ?9 K8 Y* a* O
/////////////////////////////////////////////////////////////////- ~  J; W" l- \, E; R" {
) x# a# {& t5 d& [/ G6 v( Q0 x
NTSTATUS
* ~% h+ p7 c' O3 d" L8 W) PAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
( q: q' a& ]/ X8 i+ `                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象1 @, Y. y0 \& p
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
6 R' _' d0 G5 W3 T% y6 X{
6 c0 S: \3 O: k  PDEVICE_OBJECT DeviceObject;
4 k  Q8 n, h2 C% U6 G. _( o  W: D  PDEVICE_OBJECT FilterDeviceObject;
- a) g& P! N( S- ~1 k! R9 w2 f6 b  PDEVICE_OBJECT TargetDevice; ) ^7 p# G5 P8 c3 Y1 D( [/ o; S
  PFILE_OBJECT FileObject;
( W5 Z: @! T7 D8 C. \  PDEVICE_EXTENSION DevExt;
+ D: u- c- V* S/ K( G
! @* h6 J, T0 i  NTSTATUS ntStatus;
. ]# y7 z( H9 g  j7 d
2 T3 F: u- X; e: [3 G3 s/ D$ v  //
0 i; |9 F" |0 x& C4 {8 s  // 根据设备名称找到需要附加的设备对象) a- x5 ]2 a0 ?3 o$ z
  //+ p- p" S1 d7 w/ B  `: e
  ntStatus = IoGetDeviceObjectPointer( DeviceName,6 m/ s& j( z) l1 {
                                       FILE_ALL_ACCESS,- W( t) A# ]! o+ [* \& a9 Q. I
                                       &FileObject,
, |) W* D) ~/ ^5 c" g, M7 F                                       &DeviceObject );
7 o/ Y/ t, u# G! t& E6 t: t" c
  if ( !NT_SUCCESS( ntStatus ) )3 |' \( f+ M5 C8 y3 b' {
  {" W7 e; b9 ~) B; b9 J+ u6 M
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );4 E5 u) t7 w5 {  T  D
    return ntStatus;3 w9 H# Q- K: A
  } ( w- z$ R% ]% R6 p

+ w: m% J. [' g$ T% d. S  //% Y0 G- q& `4 I4 z
  // 创建过滤设备对象0 j4 b! r* M  u) S7 B' h* n8 ]# \
  //
" H+ {  d( x) }# ?( s6 L, N  ntStatus = IoCreateDevice( DriverObject,6 F( `5 _% T' J! r( w9 F
                             sizeof( DEVICE_EXTENSION ),$ W8 [6 J( X, ?% E# M0 L
                             NULL,
- ^# g- M9 w0 M. _. W# w                             FILE_DEVICE_KEYBOARD,
$ F. h3 t9 X: v% Y% s2 P                             0,  ^, K2 w5 n+ ]/ T. D8 ]  c
                             FALSE,5 |& }+ z3 ?- z% p: i5 P) K) p9 E
                             &FilterDeviceObject );
3 l# {$ g! d" r; v  }7 x9 P9 c, Q' E1 ~
  if ( !NT_SUCCESS( ntStatus ) )
  v$ U9 n* Q2 z$ R9 L1 ^3 H! M  {
8 Q8 g: m+ \% W( o& ^, y& @) n    ObDereferenceObject( FileObject );
; b6 ]! x9 e+ L    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );0 S  |7 B  y# Z: D( _, `3 w; m! Y: b6 J, V
    return ntStatus;+ c1 F* O: U7 e9 R! g4 h, v" w8 I
  } 3 N. s- g0 H- H& k1 ~. ~
1 r* |- N) e8 [
  //+ s$ E" |2 C9 b- y. ^
  // 得到设备扩展结构,以便下面保存过滤设备信息" `0 f  m( ?  O0 G9 O; z' ^! Q. \
  //. y. N5 K- U6 ~% E7 f# H
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;! v, G/ ]0 A0 @& G

5 n* v7 {# P+ a; I- I" W7 U
1 d5 x3 N0 a# E& Q7 F& f  //
( [" A' [2 g- o4 P# S- `& j6 s& `  // 初始化自旋锁4 b+ ^  I5 m/ k) I* j: e
  //
+ \7 }1 X  E2 ]3 Y3 d9 H  KeInitializeSpinLock( &DevExt->SpinLock );$ j9 a' a, ]# e+ n

, t; Z- y  c& Y! ?6 C3 P2 O  //
7 Q" }0 }. y) k  // 初始化 IRP 计数器3 o9 m# z1 w6 g4 s
  //
# l! c5 U7 t/ \/ F  DevExt->IrpsInProgress = 0;- d; }& L# l/ J6 C% M
8 z" y8 K9 c" V6 D, V7 p
  //
1 B) ?2 p/ B" a  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
4 S6 N% d+ X$ F8 {* N  //
8 h, H7 P* ~4 p- v  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
* A  k9 z1 u' w                                              DeviceObject );
- k4 w" H5 Q2 r  if ( !TargetDevice )
2 p1 {" g6 d! o: x6 v; U& A3 Q  {. G% L$ D! e8 d# |) K% Z2 q
    ObDereferenceObject( FileObject );
" u" ~" {! j: w6 w. N9 V4 u    IoDeleteDevice( FilterDeviceObject ); 0 ]$ z1 E1 a: ?/ T2 a# G3 u
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
, ]2 C1 n$ w* e0 {) Y  K( P    return STATUS_INSUFFICIENT_RESOURCES;
7 q8 a% l, [& e9 |5 _- x, {6 l% x  } # U0 r  v% a! }+ Z" ^4 b
* T# h5 ^6 ~- c% S2 h( m. ~  b
  //8 t: d. Y  n) U( E0 d$ ^
  // 保存过滤设备信息) m( f' [: Z0 M/ m
  //: f- g) k6 D2 C
  DevExt->DeviceObject = FilterDeviceObject; , U8 r9 V$ z. u" r
  DevExt->TargetDevice = TargetDevice;
& F& ], o# K! O4 x$ I5 |  DevExt->pFilterFileObject = FileObject;
) r$ D0 `0 [1 P( {( n% g
* _  J6 {4 v2 L/ D  //
3 J+ _0 R5 z/ L% m0 `' |  // 设置过滤设备相关信息与标志
5 H! j7 ~% v% y2 B; x  //' ]6 H. v. B; I, L/ }
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;   u) c7 k4 z9 S# ]8 V2 h
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
! d, @( V0 Q; w* z0 u0 f4 V+ t  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
0 {9 Y7 l' U4 c; v( ]. ^/ c  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
$ ?  x4 w5 O& O1 S                                                         DO_BUFFERED_IO ) );
6 I0 |' [* N4 b( N' [* u5 y* [/ U( Z  {" R: z1 V
  //% ^2 G* W6 ]% B, m
  // 返回附加后的驱动对象
& O/ D% Q" s4 V  //0 e: O1 m; M& g2 X
  *FilterDriverObject = TargetDevice->DriverObject;; {5 \. i1 H  G9 b6 f# {* R
6 h6 }9 L7 i0 p' u/ Y1 i
  ObDereferenceObject( FileObject ); * R7 F1 _. _, \

+ ~. n) ?  \* g" k3 H  return STATUS_SUCCESS;
8 {" P" b' c! `4 p6 p5 B# j}# D1 E* _9 Z2 y4 O
% N0 G# ]# I- p. U$ `
/////////////////////////////////////////////////////////////////$ T- G4 Y" |$ G" M/ D: K! m' F
// 函数类型 : 自定义工具函数
9 y5 `4 f$ s" _4 Y- t2 d// 函数模块 : 键盘过滤模块
, J/ `0 M1 }8 t////////////////////////////////////////////////////////////////
1 p" ^- q$ e/ u' l. m3 w- x2 T- f+ f// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发$ H& k  q% \: d3 }1 P
//        这个 IRP 的完成+ X  a. I8 }+ E* G; u$ p( q
// 注意 : 3 D/ x. t& m* ], g! k: H3 D8 Q- C
////////////////////////////////////////////////////////////////// L7 s1 P' L- ~" L$ |
// 作者 : sinister
: l5 Y/ s& m- ~: D, \// 发布版本 : 1.00.00
. E2 ^% g' I) q" i// 发布日期 : 2007.2.15
- |7 Y1 [# f3 e1 A2 B/////////////////////////////////////////////////////////////////# P% g! B( j0 W2 f) |+ h
// 重   大   修   改   历   史6 f6 I' Z  @4 K$ Z9 ^6 ~
////////////////////////////////////////////////////////////////8 r. B6 x4 e: b2 a/ Y$ A7 V
// 修改者 :
8 \% @6 |3 @8 a* J7 l  D// 修改日期 :
2 h* E: k5 @$ N// 修改内容 :
5 S: e8 h0 e9 d5 v/////////////////////////////////////////////////////////////////
" l% U6 x+ m- V. ?
' o. H% I# q( h( q5 o& T1 ^9 pNTSTATUS; }( r9 b/ ~1 v
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )7 s0 T: o( R1 w, v- Q6 n
{
- T. y0 T* M" g2 p1 f& W  NTSTATUS status;
6 Y8 [+ c( v7 {- i  KIRQL IrqLevel;
- T4 O3 R5 s- T0 W, }0 `. c
1 Z+ z0 |7 h/ ?$ v5 @9 _& c: d  PDEVICE_OBJECT pDeviceObject;
: \4 x, ]7 I* p# z3 C# N6 m/ @  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
" V% x2 Y) |3 F3 Q                                   DeviceObject->DeviceExtension; - |* G0 R. S; Q  {6 I6 Y
3 P( @( z: i, y  P

+ r; E; o8 W1 m' t- z  IoCopyCurrentIrpStackLocationToNext( Irp );
. p. `5 m( S# s7 \
7 S7 y. _. N$ S  //* s3 f5 n4 d7 L& _' v. Q
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
) l1 f; {. V3 ^! ?0 o; {  //
  q# [+ x/ l/ d  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
% p& ~1 ~. T% m4 P/ e  InterlockedIncrement( &KeyExtension->IrpsInProgress );. a9 n# o$ K5 J( R: X
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );0 o9 q2 J' u# g  j4 U1 k0 v
9 A& l, }  v$ k$ c. m5 g1 l; ?
  IoSetCompletionRoutine( Irp,  U. H; z- ]% R
                          KeyReadCompletion,8 b' b! s. v) B% |: F  B# m+ A
                          DeviceObject,
% M& J% w% i6 _6 L: r8 n# q! F                          TRUE,2 u% \( L) b1 u' r( z
                          TRUE,
9 _+ O: k- L5 j2 v# r. `  @) E- ^, c4 t                          TRUE ); ) W' |( Q- e( l' y* o
# L/ E3 K2 ?* K
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
. ^. P# L; }. x% m) p- w5 l# [' O& ?} ; h- ]" e2 p$ I

) f, Q+ b3 g3 l* Z0 B- ]/////////////////////////////////////////////////////////////////
, E$ B" ~; p: i0 d, F( A// 函数类型 :系统回调函数
1 T6 @/ Q; H+ P+ B% v// 函数模块 : 键盘过滤模块4 r' n9 r4 d- |  ~; t! ?
////////////////////////////////////////////////////////////////
8 w$ D  F% v5 e  h+ b; S- J+ B// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
9 t* X/ J9 O. i- |7 a// 注意 : ; M  S; a6 E3 G  ?$ Z$ K7 S9 W" T
/////////////////////////////////////////////////////////////////
% \6 t. n2 R$ `// 作者 : sinister+ y4 p" _1 x: t/ J! L: P
// 发布版本 : 1.00.00
/ p2 O/ ~& z. i) Q$ ?# s// 发布日期 : 2007.2.12
) a% O& X5 u& D/ v# p" d9 g/////////////////////////////////////////////////////////////////7 P6 `$ B! s, N  g  ~2 N8 ~, b
// 重   大   修   改   历   史' `7 T7 m  z4 D- x+ h; y: H) m
////////////////////////////////////////////////////////////////, W# O8 p$ B: v5 e
// 修改者 :2 P3 _  ^" F; O& l& |% K
// 修改日期 :# d& L0 V; u" R% R2 y# y% h' W/ ^
// 修改内容 :2 M- F. S9 p0 @2 P$ O7 R
/////////////////////////////////////////////////////////////////
0 J) e" s4 E, b; W* C6 u/ ~" v; k5 a
NTSTATUS% b" m) r6 N# G, C; I7 r5 P
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
+ W# [# B' }/ ]; r' g6 ^8 ?, H                   IN PIRP Irp,9 L. N( f2 s2 m, j$ S
                   IN PVOID Context )
2 A2 h  `5 @; M; e5 A9 |{; u/ u7 N* f/ f9 e) a" @/ F
  PIO_STACK_LOCATION IrpSp;" j, M; G. ^1 z" ^. B7 n
  PKEYBOARD_INPUT_DATA KeyData;7 u# a& i! B$ q& S& B
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )6 T$ F2 d% r7 A: i: ]1 C) D7 t
                                   DeviceObject->DeviceExtension;
, i% s) e- ^! S$ @+ D" z( W  int numKeys, i;
6 M* z& H, ^5 U3 g# ~& j  KIRQL IrqLevel;/ t/ F' o3 W9 E# U8 O7 |! c
) T) ]1 P4 p4 }% a& h: W" d
  IrpSp = IoGetCurrentIrpStackLocation( Irp );8 U; L3 J1 ~7 X' g

6 q% a7 i* P+ Q$ `9 B- B6 W8 B3 i# e; t6 }1 B
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
) U9 c7 J( h! K' Q' t4 v' Z7 N  {* D! ?' Z: s, t
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
6 \$ I+ h0 L) F' u    goto __RoutineEnd;
4 u. K) h, {* w0 J3 M  }2 J& D4 R8 L* Y  \& d  R5 S# P9 m% g

& A4 Y8 o/ j8 Y  //
9 _0 A+ U6 X- Z0 y  // 系统在 SystemBuffer 中保存按键信息6 O3 P+ \! g4 P+ n& x& H/ Q
  //
' C4 T8 C- e; O  KeyData = Irp->AssociatedIrp.SystemBuffer;% ^7 i6 }2 D) k" S( V
  if ( KeyData == NULL )
0 K# ?" F0 Z# f  {( w  W+ _2 h' M  Q/ l
    DbgPrint( "KeyData is NULL\n" );% j# M% f. J: A0 }
    goto __RoutineEnd;" e; ~- }* a) \8 ~% V. W* o5 g2 A& }" j, T
  }
1 N- ~* t7 f" v7 |$ z% \$ R
2 ?9 Q5 t" n. u7 P3 k  //
: S( K. Z. N! A2 `% n  // 得到按键数) v# ?7 ~7 C; E( O& Z
  //
5 s! C2 ^/ L+ ]& j2 V7 z; H  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );; u% U/ |/ [' }  j% l8 U& R" `
  if ( numKeys < 0 )  g. @! k2 Q$ e8 N5 q3 m. [
  {
( y9 ]* l- Q- l  c9 m    DbgPrint( "numKeys less zero\n" );* v5 f) o5 j; p( a$ i: y7 V
    goto __RoutineEnd;
2 S- Z2 ?' r  v$ Q  }
! S7 e4 S+ ]" b4 Z0 {: L6 q1 a) F( q. x
  //' ]( u, N$ E; R
  // 使用 0 无效扫描码替换,屏蔽所有按键0 x( O; A0 S) i% V
  //
9 k/ R" O- k! v/ }+ A0 m5 Q" g$ I  for ( i = 0; i < numKeys; i++ )
' A/ i! K; ?1 P' h  {* ^8 q6 |; D. q
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
% M; c6 Q' F; A$ c* J6 X6 E: ~    KeyData[i].MakeCode = 0x00;5 Q0 V3 W! I6 d  H/ R
  }
( n8 k/ S! ?; ?6 d0 W% M5 p; j# j- O0 @1 B, H
& P5 p  {7 b. u+ q# L7 _
  __RoutineEnd :
1 p" N  D- V/ m3 ^6 o: ]% [+ a% F9 C; y5 y9 B9 a
  if ( Irp->PendingReturned )
, s  |1 j2 d( F9 x2 ^* D( r/ Q  {% F  c) L7 e: f# m& Y! C* y, ^
    IoMarkIrpPending( Irp );
0 D, f) a! h# A6 \  } 4 x# @! B1 G! x, F* L8 f" F

9 F9 w1 A' Z7 W: g  //  S3 g2 D! d# V1 w
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
2 L) q0 y! ]; d1 g+ s) m  //3 f6 j0 p. L7 e" u5 P
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
1 j9 P- K% w; R, S  InterlockedDecrement( &KeyExtension->IrpsInProgress );( [8 f- q, N& _) v. ?2 N' D
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
/ ?9 {0 B0 B) n' `4 V6 P% i- n+ o) |, r. K6 c* j
  return Irp->IoStatus.Status ;
2 I' ^2 E2 e+ k# [: \; N+ n: @$ m}
, j0 D% p1 |& |6 j. p# d
- z0 \1 z. _2 `: b* ^  o3 f# J# g  i& {* m& u; v2 W) ~" l
/*****************************************************************
1 z1 I) V8 b- c- q2 N/ Y5 G7 F0 L 文件名        : WssLockKey.h
+ E' S+ j% {, i5 G1 Q) L' y5 d 描述          : 键盘过滤驱动2 m6 u* z8 T' _2 Q* Q1 J5 v
作者          : sinister
6 f, B, o1 U& o( W. z4 t  _/ a+ G 最后修改日期  : 2007-02-26) P6 P7 W/ J% }+ H" o
*****************************************************************/
* X1 i  I# e: M3 [% Q$ t1 s. D
$ E& I; u4 \) l6 B#ifndef __WSS_LOCKKEY_H_' s0 p! R1 `* T; ]
#define __WSS_LOCKKEY_H_
: J' G5 y! r3 n% H7 m7 l( H: ?" E4 @9 L/ p
#include "ntddk.h"$ ^1 K8 [# O+ `1 J1 C& D% U
#include "ntddkbd.h") m6 H& p+ @- X0 e
#include "string.h"
" `9 U% B1 }9 `2 E) u! X& x#include
& W- j2 q, @' w+ ?' a& H5 l" X3 _6 p# {
#define MAXLEN 256
5 Q. O5 [% e1 @8 H- g  y
4 M' Y  X8 N) O& {#define KDBDEVICENAME L"\\Driver\\kbdhid"$ p5 d" Q8 i; S3 _) ]
#define USBKEYBOARDNAME L"\\Driver\\hidusb" * ~& ?7 S: X* I& c
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
9 L! D& O9 j3 v# {. Z8 ]9 L: E1 J9 j3 H3 F
typedef struct _OBJECT_CREATE_INFORMATION
8 |( R/ u6 H) A& k, Y& }{# U# k; z+ A  s& G
    ULONG Attributes;% N+ H2 ^; A* l& R
    HANDLE RootDirectory;
  [7 [" g) b& ~: O  }' C/ z# C    PVOID ParseContext;
. E' K6 ~/ T# y! ~( E    KPROCESSOR_MODE ProbeMode;
$ z* ]/ q4 T4 i3 J- k    ULONG PagedPoolCharge;/ f' ?" G* n4 j# u9 x! c% E1 c
    ULONG NonPagedPoolCharge;
6 j. Q; G0 @3 [0 ~6 u( e( G! p  U    ULONG SecurityDescriptorCharge;8 U( k6 `/ g' s' `
    PSECURITY_DESCRIPTOR SecurityDescriptor;8 Y- T* ?  E  G! g" x
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;0 F+ q7 s6 F9 M9 g" b
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
1 G% E, Z. H  P# \: F} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
. U1 W: o5 D5 x3 y2 B4 H2 b3 l
5 ^- m3 T& D4 R- R0 R' etypedef struct _OBJECT_HEADER* ]$ B& y) w0 ~8 @/ f6 J& M# H) b9 A
{
: C- e/ f* Q2 X& a, a    LONG PointerCount;
1 ~! E' ], g: W3 D    union% L* t/ N* ]) x: }, _4 B
    {
3 w1 V/ `( r( z        LONG HandleCount;, m9 c; ^7 X' v% l- V# j! n
        PSINGLE_LIST_ENTRY SEntry;  Q% V7 L0 G: _" a" F$ m$ h. ^
    };
  J; r! w% K+ k0 s3 M2 q4 p    POBJECT_TYPE Type;/ t2 Y# @# a" d3 P; ]$ o, l
    UCHAR NameInfoOffset;
) k7 q% f. P4 n1 Q0 r    UCHAR HandleInfoOffset;3 z; P# y/ b+ _3 B6 Q
    UCHAR QuotaInfoOffset;
+ _; b' C/ i$ v' k! e    UCHAR Flags;" l3 z9 x) r7 F" _2 |; M+ L
    union
$ r. _* I6 X# f" _: b) }' q    {% F6 j  i& H  z2 t7 C  R: R/ _
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
/ F9 W4 Q( F* e* j7 O        PVOID QuotaBlockCharged;# L" a4 R/ ?+ L5 o
    };
+ j9 ~9 T6 Y7 }& Y+ I- G( B$ K2 u0 e# T6 v
    PSECURITY_DESCRIPTOR SecurityDescriptor;: j8 _0 X  \$ K0 |" s! q
    QUAD Body;5 N9 \  M% f9 p2 J6 _- X
} OBJECT_HEADER, * POBJECT_HEADER;
7 A* R% l2 ^; A/ a' T. l- s/ D$ r. S& i- @9 H- F# Y- x
#define NUMBER_HASH_BUCKETS 376 g2 y$ V* B3 U$ ?9 V
% }; K" p9 I4 `  D
typedef struct _OBJECT_DIRECTORY
/ f1 J. q' V9 V- v0 C{- p" |% z: y6 v; K& r$ K" }) r. b
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
8 ?3 W& y( u+ p; r' e# G. E    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;0 M3 f# }# E6 S& R
    BOOLEAN LookupFound;
3 C# ^6 i: v- }* k) S; j    USHORT SymbolicLinkUsageCount;! S" s4 d2 P9 ~3 ]* c4 ^- W
    struct _DEVICE_MAP* DeviceMap;
) O% e$ P" `& [5 \" g9 q3 b} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;/ j( I8 @) R5 N
$ ]- {: {9 [5 r( U- K2 n
typedef struct _OBJECT_HEADER_NAME_INFO
  J6 `" B7 H" d4 _# `& P, A{  g. z# i, l4 N$ z& m( U
    POBJECT_DIRECTORY Directory;
1 D$ C7 L; M$ F  g    UNICODE_STRING Name;- b- W& y  ]6 q6 i
    ULONG Reserved;
7 w+ u/ H" Z5 T$ r% @4 d3 }: H#if DBG
- ~2 S& Y$ b0 c- f1 j    ULONG Reserved2 ;
2 U* H9 X) F2 o  o/ d; M) q    LONG DbgDereferenceCount ;
% e; k1 G4 e7 n  j* i; Z' U#endif, T& d) m! e) E7 E9 S) y" V' n
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;4 W; q$ U: Y! t/ h6 \5 j
" q/ s4 q# a( ^8 s9 f" b
#define OBJECT_TO_OBJECT_HEADER( o ) \
) N* h! C- ~, R$ l: b/ \! i+ H    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )5 S" a+ ^' ~( X2 W2 ]
! m2 {7 [4 r( f
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \8 {6 X5 O! n! }' n, o- k1 ~
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
8 ], ~7 V! _) Y" A% b$ a0 S8 I4 ^
  {( r! w+ h3 g: K& W5 Otypedef struct _DEVICE_EXTENSION
, e0 m/ ?6 u0 [) Y$ N  B{
# g: i: ?! n+ x- Z( I    PDEVICE_OBJECT DeviceObject;; f! [* F8 U! ]  ]8 v( l% R
    PDEVICE_OBJECT TargetDevice;
0 O$ }& ^9 N* g7 M! Q4 b" s    PFILE_OBJECT pFilterFileObject;& D& S6 Q7 c/ w# o! j3 q8 i' j
    ULONG DeviceExtensionFlags;
, a9 K4 I) H$ P1 j" e% J    LONG IrpsInProgress;
+ ^; F6 x3 }' i' v+ V% ^    KSPIN_LOCK SpinLock;3 l7 k# X6 a5 m# k: r# k
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
7 o* N9 K$ C( U3 u
3 C6 }( _" t! s
5 u7 {5 Z8 [9 I! L+ sVOID
7 u! S6 ]2 t7 ~# K( ?KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
5 t4 w; C0 l+ @, [. x/ C
# i* r  N  K! J# B; e' {8 A: fBOOLEAN
. D: q- W8 q9 k& xCancelKeyboardIrp( IN PIRP Irp );
  ~0 e. j3 }4 u* u: r' N0 d& ~) ?9 y0 g6 r
extern POBJECT_TYPE* IoDriverObjectType;
3 o3 Z  a+ g$ o% \
6 I7 N- M" U# F1 l3 o* RNTSYSAPI* ~2 b* A% T' G9 A1 L' F! @7 Q
NTSTATUS
! O& w7 M6 ~' S! kNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
0 t! G8 I$ k% S% a+ S7 s# \                               IN ULONG Attributes,
7 ?. M( p0 v& B/ q* Y                               IN PACCESS_STATE AccessState OPTIONAL,2 j  g% q) J5 E5 C8 \
                               IN ACCESS_MASK DesiredAccess OPTIONAL,9 t0 y  M' ^7 E# u  ]/ }) o  I
                               IN POBJECT_TYPE ObjectType,
! Z# B0 i; n) R$ m                               IN KPROCESSOR_MODE AccessMode,: A& w9 g, V9 D3 X* q8 b8 y
                               IN OUT PVOID ParseContext OPTIONAL,) v- w8 s+ G/ b6 H
                               OUT PVOID* Object );
3 g" v7 e+ S/ F
& ^) D' @+ }/ U6 R1 L" O  r! JNTSTATUS
4 p0 v9 ~+ @' L' P7 K9 e& sGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
9 ]" N% I* l1 B+ f
. h4 J& p$ m5 v5 D/ ~+ UBOOLEAN
+ q, t! C, C: F3 kGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );5 I& q3 y) [0 o0 x2 u
  R- z2 Q4 u/ v; ~! i9 ]4 F
VOID
4 M4 V/ X0 \2 L- gGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );' `( |9 w: ^" Q3 B
7 j! I, Q4 t1 x
NTSTATUS
, t. v$ I7 }5 H" W% F7 D1 yAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,4 h3 G. m4 P: U: Y/ k
                                  IN PDRIVER_OBJECT  DriverObject );
' I% s) D+ E- D0 k, E. e. p5 k# U7 F
NTSTATUS 5 {1 w7 y1 N5 ]! q! J0 T
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,- h& v7 k& @8 V; u
                                  IN PDRIVER_OBJECT  DriverObject,1 c3 W& o# c0 U+ f$ U4 U6 u6 w8 H
                                  OUT PDRIVER_OBJECT* FilterDriverObject );
$ B# p! R2 C+ m+ A" M$ c3 O0 C- A* t( U( `: U
NTSTATUS ; Q4 ?3 i: q; P
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,, S3 r) f! C8 G; [
                            IN PIRP Irp,
) m% l: R( F! L" Y* s" G8 Q                            IN PVOID Context );
2 r2 ^. _. T8 l2 ?! ?" LNTSTATUS , v$ g9 E: ]$ k( P
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
$ N+ l( F+ n! n0 z0 e9 }, y6 N; p+ t" _, S# g. J
WCHAR szUsbDeviceName[MAXLEN];
7 m- U7 _& f& V$ A( {/ X6 |. ~. \$ |- p$ m
#endif
( r3 q$ u8 s4 c5 l9 ~! G+ g7 R' H3 k' p5 a

1 K$ D$ b2 {( a; @5 |: T
( j; v0 \, j+ l4 R  R" Z9 e3 K/ [! D  G% _0 |, C

6 i$ S& N1 _) w8 k4 R; BWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
; g4 G: Z0 D  v2 d! t5 ~WSS 主页:[url]http://www.whitecell.org/[/url]
# t& W+ F! M1 P. y% @$ _: K* G& U7 OWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-5-2 10:35 , Processed in 0.101588 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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