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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
( l  e' q- |; m$ N2 nEmail:   [email]sinister@whitecell.org[/email]
4 W* b4 Q: h( E, m: W3 iHomepage:[url]http://www.whitecell.org[/url] $ r9 w# N7 R/ j& q# \7 A
Date:    2007-02-26  m. |2 P3 j' `% ]  Z0 j' O/ f& _2 D

# r/ l2 S" J- Y: a' l
( K/ Y+ I) g1 f4 m- A/*******************************************************************+ _4 M# I# e8 Z" x! K7 ^

. W+ B  {6 @( ?2 I6 B这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx4 P+ D$ y: y/ }* M
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
; w$ x( q( E5 P$ @功能要求如下:" i) e% J# c! w+ l
. ~+ r5 c: T. [$ f! n8 W+ z
1、强制锁定键盘/鼠标。3 D* A+ h( T" _$ {9 ]7 T( L% c' `
2、可动态加/解锁3 S9 F6 r2 }4 R
3、兼容所有 NT 系列的操作系统。  e+ U: I* U2 T0 O% G0 A
. i, f5 e( O7 ~6 C* ~1 ~* S* \
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实. M0 C& r  p, B* N7 n5 X- l6 |
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
) K3 y6 h, s4 |* x$ a何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
. M5 y* d8 w9 n3 `上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
  }2 l" k+ \- z5 n" @; A6 i怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面2 U7 j( \) J; O* m1 z
就来看一下我想到的几种实现方法:
4 I' l+ ^/ M: d3 ~! W
  g5 k3 S! Y: o1、全局键盘/鼠标钩子7 F( O7 @- i% @2 a, }3 v( G
2、BlockInput() API' S/ {  E! T7 r
3、使用 setupapi 进行控制/ v; S/ D& t; ~$ _8 _
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
# }. u# g" x2 o! `9 q5、拦截 win23k!RawInputThread() 函数# |4 g- O& x& V: i. |" z% q2 B2 t
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
" L" r( f2 y  M1 E( _/ Y# _7、拦截 kdbclass 驱动的 driver dispatch routine- f0 b4 Q, U+ q3 M" c" T
8、实现一个 PS/2 与 USB 键盘过滤驱动7 x# a+ v$ W. x1 I8 ^
7 w: Z3 d1 n+ L: [5 K

. M6 X# \, D6 L8 p我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
- c( D1 w1 S6 v4 i之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方4 [# V. _6 b2 w- e. y% T$ M; A
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
& T  F/ ~4 u) S2 h兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因6 N0 B  d( e. W% W1 N
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性0 }6 t$ O8 W/ N5 ^
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸" _0 V5 Q/ r5 Y9 V6 r2 w
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
( x2 e" ~; ~- \; o0 N8 p的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来8 g- e6 x) i- D4 n" P+ ^& E  T
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
8 D0 N1 |0 e0 ^1 ?1 u% N( `! o果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
8 Y2 O3 I, @4 J3 ?障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
, `( k% t' u8 h. H; ?7 `IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
2 {5 B5 i' P* l# q/ @) h: fUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
* w  c" D! ~. r, x盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
& `" e* Q' X" \% r0 Z* y案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
% W1 S7 P8 V/ P
  A8 \- e/ }  U: t+ X
: Z: d2 p# ]. y6 N我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过$ i2 G4 {: S7 x; n! n& ]
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
" i4 s2 t# x, N9 ?9 C' b$ ]行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
5 Z+ G9 [' W: l: f, p7 [; I: K只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
# F, U% q1 o7 I来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
. G" D* U/ [2 b+ K% F( ~+ K, UKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
* [4 L$ O) X2 i/ B# R键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
7 g" |. }( o8 b: |9 K) s$ g8 |+ ]. l5 yIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
7 ~* c& N/ G' q  t1 x8 x我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题& ]$ S$ Y9 B8 {0 O% `( l/ w1 T
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的6 g4 p) j+ ]; @( \. Y
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使& L- [# Q) @4 a0 @1 w+ x& d' i
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
+ c' ^) L1 ]( I4 R" d7 X- C% D" L" Q过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来9 H8 e! o& D1 q2 p1 M+ D
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通5 Y$ i% e6 L, J- u3 r# @
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
; ^) C" C, d; s上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
$ h: H& \9 R& B7 Z6 R0 ]5 l. n的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
+ G( o5 R4 F0 P4 h. L" {味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。, q4 r9 g- O4 _; o7 P  @
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们- p) j/ f0 e) Y+ G3 A2 X: O
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利/ [, X% ~- l) }0 O5 [
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo; \3 J/ [0 H- {9 ^8 y* x5 Z
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致1 l3 |* k9 T$ d+ w# X0 }% K: ^1 g& {
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
/ M. ?( R/ L% q# D5 v% J根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程3 L' T# f+ V' c* `+ v3 Z& f
见下面代码。5 X; [7 l7 e* G" J. _

) [4 P6 D3 V7 r: d9 ]+ C! r这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程$ D3 }* N2 t; F) Q5 j6 R& O
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
& t& I; A! Q% D4 l* N盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003, j4 J+ N) s, F( [8 f
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
* O' A# @" ~9 A完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可: |& v/ l$ |# }$ G
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
6 m. F! G+ r) l- |7 c- v) [9 s锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按: d1 B" v( {# t6 z
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
7 e7 U* ?; o  e. V# n# f4 S! J: ?$ P# V1 Q& F' V7 S5 |/ p
0 o1 i! [" S! [' K: x
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
. n* Z8 f$ g9 m$ v/ X  N$ ?1 D1 g. H的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
: y, P) b; c% e1 Q7 @可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣* p6 k( J7 ]# t9 k7 t, e4 m: U
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我. u- P, i% d" F  D3 X' S  A
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
# z0 v: X7 d; `; s; b! j们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension3 r! z3 O0 N( ^9 i+ x+ r# G6 t, ~
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。5 O: a, |! o( |8 P6 q) }
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager$ V7 L% i$ v' U" N
进行操作了。这个问题有待大家来完善了。- ^' z9 {$ t' a5 \

: G% Q6 t0 z8 ?* l
: x8 Y( U& ?$ i4 s# p0 i0 T7 X要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
, j5 G5 S# b8 x+ ^( C! ~5 m% D来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的0 v1 ~+ e! `8 |( K" v
分析做个记录而已。我更愿意把它看做是一段注释。
) e, A4 v# f+ j/ t6 G; Q4 e- s, u% y( h& m( Y
最后在此代码中要2 z6 k2 s; x" x2 X5 c+ g2 y4 X6 N0 O

2 }, t% `1 N; V0 L, d感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
$ c! g3 B3 u- u9 X: Y- H0 k4 H# Y- Z  E
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
& ^! v0 L) d) i6 ^( B$ |7 f" e
1 L" y% i7 E5 z# [" @! H/ J. ?% |感谢:齐佳佳,过节请我吃好吃的。
; X( O  d# ^3 c# ]9 s. K5 G" F2 M
) a# z& s1 O# c
" t, ~* }6 H9 p1 J; F7 g% m******************************************************************/
# F6 k1 h7 g+ r! Z; z! S: ]2 }% {( {% G
/ A& }1 s2 `$ V: |
/*****************************************************************& h3 R0 f8 g1 l% P2 Y8 p) g2 l
文件名        : WssLockKey.c. v  h# S8 a$ ]* E
描述          : 键盘过滤驱动8 S+ r( v/ F1 M! q3 ]
作者          : sinister
5 }0 c- ^* t, i6 g" i; z 最后修改日期  : 2007-02-26
5 o! ~& N, B+ i3 M; T*****************************************************************/6 e, o+ e+ V/ v) M; M6 d4 Z$ ^$ |

& c9 K6 y( [, f  m7 h# e+ r" U
7 D. O* I7 g& G#include "WssLockKey.h"
; g" `2 M( ^# t$ W5 k; l4 m; S% K, E! Y  m* L- X' ]
NTSTATUS
# m0 h3 R$ p- `  L& K2 ADriverEntry( IN PDRIVER_OBJECT KeyDriverObject,/ j. q. E" j9 C' b3 u8 Y+ s
             IN PUNICODE_STRING RegistryPath )
3 ^" F! k% H- f! ]. a$ v; c{- I' S4 i' z, c: M$ h
  UNICODE_STRING KeyDeviceName; % u' N/ d6 G! O% r0 Q+ j
  PDRIVER_OBJECT KeyDriver; 6 G' x; }5 p& M. ~' r! B6 b; t
  PDEVICE_OBJECT UsbDeviceObject;
3 E. @" W. I3 G9 e  NTSTATUS ntStatus;
, S2 S) s' S( I4 E8 {. L  ULONG i;
! Z$ ]) ~, b7 ~* ?2 ]7 `8 B6 ~
7 g+ C+ U/ ~5 y8 M5 o2 v& v& }  //
  V: t8 f" [+ E9 p, }9 U5 Q( I( v  // 保存设备名,调试使用
1 H6 k2 V8 i8 o% _' r  //' F7 u) l& X- @# l
  WCHAR szDeviceName[MAXLEN + MAXLEN] =; L* ^# W* i3 C
  {9 _$ `6 Z1 {# x" c. P$ B2 u( G% D
    0. u. t8 F' p# C, [0 F% a1 f$ ~
  };
% u1 L$ |) U( G: u6 M; U. ]% j0 k
3 t4 y$ j8 z$ G4 L  KeyDriverObject->DriverUnload = KeyDriverUnload;
7 @& }- c6 H, ^/ l- d
  F) I( \4 b  b0 }! h' K# J5 G6 K% {  //
4 L# ~, L& @) x( q  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
1 M$ i: |7 k: l+ O" _8 X  //
+ \! |' M/ M. T4 S- Q  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法9 u. U0 T, `+ H
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其5 v* U5 p5 I% @( b
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到8 {9 a1 U7 v/ ?5 l# y
  // USB 键盘设备来进行挂接
; ]: Z/ ?6 U) T8 B  //+ U0 T! T1 @$ g5 z3 Q& D0 j
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
0 j( X$ a5 `/ W- x3 u  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
! S2 V# \8 e- i, c. C5 u( V  {
) H. p  ?! L& m    //% Y$ o8 F9 o0 E1 ~8 O
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名" I$ k7 ^) A1 I# ^/ q1 v6 m
    // 所以这里打印为空6 K/ u: I" s( v1 P
    //
2 x) ~) N; O7 U    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
# g- C% [; U7 q6 U5 W8 x    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );" a* z1 d* a# d! @: g

3 s/ {3 j3 S6 d$ i: R+ f- o    //
' S  Q% A8 y  l" u    // 挂接 USB 键盘设备
. R7 `; L7 g( R5 {/ R    //
' M/ J' X7 T6 H1 d! S3 L    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
, s9 A9 N" B8 Q9 s& Y' k; D, K( `    if ( !NT_SUCCESS( ntStatus ) )
. d0 j) i9 s2 F; }    {
, x3 D8 B7 e  q8 H7 q7 v      DbgPrint( "Attach USB Keyboard Device to failed!\n" );3 Q/ p+ N- X6 p; o' s  ~
      return STATUS_INSUFFICIENT_RESOURCES;
% D# Q, E. `/ A; j! A9 k    }
, ?9 S7 l+ \9 ]  l  }/ j& G& m8 Y7 L9 b* n; R; s6 e" y& t
  else% R: z, O# s: R: ~7 ?, i0 A
  {3 s. [: \% X$ m% I) \  f
    //. C3 P$ ]# b; K
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备2 b1 p9 j! F3 K- \" ]" A
    //
! r3 S7 z  k  y8 k$ E    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
3 O& b# Q9 }: n! b, z* j/ u
) t- t+ p- K$ ?" i" y    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,6 L( B9 n+ q) [# E% Z
                                        KeyDriverObject,6 u. [  m1 _0 }3 V! @! y; U, w
                                        &KeyDriver );# R3 f; j. E; h! p
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )! `  i% Q+ M! X$ q4 f& M# ^
    {9 U- c  [' ]" y8 V4 J: O/ X2 S
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
9 Q' I" t) h) s& I      return STATUS_INSUFFICIENT_RESOURCES;* W4 j. X+ w! d4 _
    }, i/ h# b) y; u7 R" o' }' P
  }
2 A& P% ?2 U, |' F/ y1 }# r$ k; r# h# w9 s
  //
8 Q0 v0 r0 S+ i7 z* T  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
4 b% H: r. U9 W  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程- f7 g( `3 R8 a% Q0 V( M; f4 Q3 |
  //" B8 A: z; V; A$ t; g
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
' I7 I9 w: q& }5 W9 p. w" V; K" {3 N0 q% G
  return STATUS_SUCCESS;! `$ M" U, Q. h0 U. |0 k
} 3 N' g, F7 M) |& c1 M% I0 D
# I- N2 b" ^0 c( [3 k
/////////////////////////////////////////////////////////////////0 T" k) L) T, W/ G$ a
// 函数类型 : 系统函数
0 S% _+ w' X" F. Q! x- e// 函数模块 : 键盘过滤模块
, Y5 M" {1 D. [2 o1 U////////////////////////////////////////////////////////////////* }+ K9 w* |& o( o. g+ Q2 s, i. Q
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,$ ?; Y. s2 ]' Y7 G" m
//        卸载键盘过滤驱动
7 V( I! @1 |: K7 I" ]1 H' |3 N5 P// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
1 L5 d5 i' b- `; c& Z* [; K4 U//        则需要等待用户按键,以后有待完善
5 H2 ~! l: F1 l2 |( e( t/////////////////////////////////////////////////////////////////& }' U9 t4 U' n! }. t
// 作者 : sinister; W! k% M8 g+ ]$ Q
// 发布版本 : 1.00.00
8 S. r. W1 J* E% L- a9 M" {6 c9 s// 发布日期 : 2005.12.27
2 X6 d  c) o( }3 W/ @8 g" ^( V/////////////////////////////////////////////////////////////////- H/ N: l3 T$ w. h2 l$ ?
// 重   大   修   改   历   史
% `4 W4 c# E+ _" A$ g////////////////////////////////////////////////////////////////
; }  z$ L( |0 `// 修改者 :
! I/ g# W+ t/ x// 修改日期 :
1 N1 o+ O0 M( ?5 L! ]0 L7 n4 V// 修改内容 :* {1 N% q% O/ P- v- x% {
/////////////////////////////////////////////////////////////////
# j  b5 ?, v8 g- j& `& U- ?8 b: I
VOID& u7 r  e9 V3 z; P9 F
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )$ t" L5 p$ e  b2 V4 r8 k2 y1 Z
{
* `; ]: l/ ^! c& h1 G, q  PDEVICE_OBJECT KeyFilterDevice ;      ( L! V9 F) n* J) N* m$ T. p- d
  PDEVICE_OBJECT KeyDevice ;& a/ n- c4 A4 I" Y& Z& j
  PDEVICE_EXTENSION KeyExtension; $ ^) `" W  ]: z2 d8 |
  PIRP Irp;+ ^% ^# z8 M6 M+ N! o; z
  NTSTATUS ntStatus;' B* t1 x! g  j; q* U
3 d; l) x6 H" u! Q
  KeyFilterDevice = KeyDriver->DeviceObject; 2 s) N) \1 {1 T, X6 `
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; & R* O- t5 L$ G; r2 v6 x: h6 ]
  KeyDevice = KeyExtension->TargetDevice;
7 E" Z9 f' F; \8 f. K3 S' L5 z
  IoDetachDevice( KeyDevice );
# o# z. x0 `( i, F
! R- E9 a  ?+ G0 w  //
$ A; N( N; c$ P, R2 b% r# l+ h: t  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP7 D( h/ B' d9 U" ?
  //3 G5 S" Y: v( `$ c
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )! W0 D* e" d+ m- z$ N
  {
8 f2 ?, F" Q- p) _6 r6 a$ C7 V7 y    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )/ p  Z/ M/ P! D+ n- |
    {
/ J4 V. i% U0 }# T% S. P. g. ^      //
- S0 F" ~( m% _& l( n! j, V      // 成功则直接退出删除键盘过滤设备
7 r( o0 f  t1 L8 O  q1 W      //! c; p& J- J" u& n6 _# T7 [
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
* `: i! H1 X" n  O0 v      goto __End;8 V6 p/ p; t% Z/ d0 p; Q
    }0 ?$ i/ Q# [4 l# D$ `8 E
  }
5 h& m. q2 X& H8 i7 t' ]0 {2 S1 [/ j$ U! U* _/ L, W% ]% Y
  //% ~0 \7 F$ z7 B: s# C
  // 如果取消失败,则一直等待按键9 g: M+ D$ C! ], V
  //9 _4 n% n8 L% [& H
  while ( KeyExtension->IrpsInProgress > 0 )
( m, ^+ C) s7 E  D9 @) D8 R, I+ d  {; Y/ f$ q  R# q+ M$ }9 R3 a0 h& F
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );1 y' A- H" N. n1 I
  }
9 Z. A/ a7 i3 G8 A9 N5 t3 m" K) K% f- E
  __End:) ^. p: ^- b& d( Y; U4 S; J  P7 Y
  IoDeleteDevice( KeyFilterDevice ); 5 F: E1 Z) f. n0 `
9 f6 g  x2 X0 k
  return ;1 G; P, z+ K1 w* A3 s
} 5 X) G' Q2 V% g8 N) M+ `

& S) Z5 Q) L+ D1 h5 b4 Z8 s/////////////////////////////////////////////////////////////////5 T  X( a& z. E% r* p
// 函数类型 : 自定义工具函数
" y3 w! Z2 h- m- U// 函数模块 : 键盘过滤模块2 y" s% x. c/ D1 \) \3 z) \
/////////////////////////////////////////////////////////////////
- v; [  `8 H1 `: Z! V- N// 功能 : 取消 IRP 操作4 N7 U3 W" _5 |. L& p- X- M
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能0 J" M1 f! {  u
//        使用此方法来取消 IRP
+ `: K$ \$ d) J% \) k- x- _/////////////////////////////////////////////////////////////////' ^+ `' o) ?5 d. S7 w+ ?6 D) Y. W& V
// 作者 : sinister
% X4 V- o8 f. _& A2 e! m// 发布版本 : 1.00.00* x# e, S% \; u& K+ R
// 发布日期 : 2007.02.20
2 L2 g$ u/ p5 O# t& v/////////////////////////////////////////////////////////////////2 _1 u  S- J( D8 l
// 重   大   修   改   历   史
* i. t: k' w; _" f7 O3 a  i& w/////////////////////////////////////////////////////////////////
6 n) t; ^/ x/ i// 修改者 : ' w3 }1 I# J! b$ ~4 z
// 修改日期 :
+ @1 m( F9 T+ v! f// 修改内容 :
' O/ |8 I. J1 H/////////////////////////////////////////////////////////////////
9 Z" }" ]% Q+ C* l: @! j4 F
0 e1 f, d6 S& qBOOLEAN
6 V+ V2 K- n! r) J  V) ?CancelKeyboardIrp( IN PIRP Irp )# ~' G) M# E+ I  V
{
% @3 s% o0 x: M* Y8 ]0 N  if ( Irp == NULL )$ ?: N: w' x; ~! T
  {+ r  J7 \/ g+ @, }) G
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
% P1 z: t: J9 ?9 Z2 B2 G$ R    return FALSE;% H# o1 s/ \% U  X: X
  }. F: }- Y( E' x% s6 }; C
8 |+ n. \8 _/ @9 [* r7 A
  M9 O9 @7 ~7 a
  //% X9 t* d2 w+ r: a
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,$ k$ J; Y- Y; z* `
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
' {/ ^, t3 O8 _# m7 l4 W0 V  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占  U: c0 t3 a8 M. h
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
! @% L9 K! a+ }4 L8 L  X  //1 [) v: O- d1 l3 F' k! _7 x- n

% v3 l0 i+ N; y5 z+ _/ a  //
0 X! e1 t/ g0 W& \  // 如果正在取消或没有取消例程则直接返回 FALSE6 U1 X: i" b- C3 O# R
  //
) d' p: {1 X5 r0 L! U  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
, Y8 f1 x& o& V6 |( X  {
6 V, e9 q& F" Y    DbgPrint( "Can't Cancel the irp\n" );
& x* r# K- r6 ?0 Y+ E    return FALSE;
7 e3 z: l, ~/ P8 \1 `9 r, l  }" V" R- Y8 W% g8 ^6 ^- e
# f) `$ ~( N8 {0 U
  if ( FALSE == IoCancelIrp( Irp ) )8 ?2 p$ w6 m8 a2 o- [
  {( ~% X8 O9 G4 k0 d
    DbgPrint( "IoCancelIrp() to failed\n" );
7 {" u+ Y% s8 p0 b+ z6 f    return FALSE;
! u9 S1 [0 K( D1 q  }
" q: O- r7 ~9 }+ Q( y; {, R" A# V8 Y. d: }& D1 s5 P+ p. @  r/ l  U" C
  //0 \, g1 g; g- a* L
  // 取消后重设此例程为空+ t1 o# m' l/ R6 c4 z, ?
  //
& t+ y3 n9 B) P' j  IoSetCancelRoutine( Irp, NULL );& R1 T% P) C' f/ Q* h

( F% C% Y* M: ]- l2 y  return TRUE;! f2 e" Y6 t+ m' D5 Y1 t2 P
}! i7 o8 b" j* `; {& S

# W5 C# O& t3 T- {& I$ g: `/////////////////////////////////////////////////////////////////* x' ?! W% F' r. d* L; J. |
// 函数类型 : 自定义工具函数
' h+ U7 V2 w( R5 X* ]8 Y, s// 函数模块 : 设备栈信息模块
, I5 o7 I0 G0 e7 w. k- I/////////////////////////////////////////////////////////////////
0 `) i( Q" B; T- r. f// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘5 ~+ q& `1 v4 y3 d
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
2 ~6 ]* b% ~7 I  q9 y( h! Z8 z// 注意 :
0 Y; o: H1 a8 }6 S- g/////////////////////////////////////////////////////////////////
7 d/ q9 ~, K, o* o6 v: o5 U) v3 f// 作者 : sinister
& @: H/ F( V9 L4 a/ d4 Y// 发布版本 : 1.00.00
% O% L* I) w. l  R5 J) Q8 ?// 发布日期 : 2005.06.02
# }- j3 ]. }! y. R9 A/////////////////////////////////////////////////////////////////. u) H' \% a8 G9 I6 J
// 重   大   修   改   历   史
' l3 L" P# M& ]  O6 |4 U. Y& t0 O/////////////////////////////////////////////////////////////////
" D8 z: t; z8 S8 R: M7 G// 修改者 : sinister
- o, \# Z3 e, ?- z' f, t// 修改日期 : 2007.2.12
, w7 o7 y; l. P7 z1 b* ~// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改  q- t: Y* _. w. K' U
/////////////////////////////////////////////////////////////////
, A, e9 O" k3 Q; `
/ I# U5 x5 I8 z7 O3 G/ n. eBOOLEAN( d3 l4 ]; R6 M2 H) n& G. I
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
1 s9 }; ]% L6 p9 f1 O{9 p: D4 _" [: V& b* n
  PDEVICE_OBJECT DeviceObject;
* {' g0 x  |" {0 m+ B! b0 \  BOOLEAN bFound = FALSE;+ B& j- l3 F2 u" Z, F# y

+ ~. ~: T$ f& l2 q) l) s8 @  if ( DevObj == NULL )
0 o$ ?+ U/ {1 a+ Y) L. o- g# g$ ~2 G  {
7 D1 O1 l) @- t0 r8 o    DbgPrint( "DevObj is NULL!\n" );
, A0 j9 k- Y# y. K6 Q% a    return FALSE;
  C+ w" M% n0 Y. ?6 @3 P  }5 a& W5 @: I% |5 J" Y* ]
- X( X  s1 O8 h! T. D1 R+ y
  DeviceObject = DevObj->AttachedDevice;0 H2 e" Z% _& s

0 S+ P# C9 [% i1 P. U  while ( DeviceObject )
8 |' t7 C" ?* e8 M- U* J3 E, j2 c- C; j  {
' D* D( p- l" D( i8 S& M, W    //) l1 m; Z7 u( j: K3 X) m
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但2 |4 _2 T' y# @: ?2 N
    // 有一次足够了。这算是经验之谈. c" v, ?3 y, e6 O3 H! k
    //
' Y, L+ L" \& v0 |    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
* }0 B$ r' G3 c+ k+ [( \: U    {
2 D" u! ~% j& V4 T  p      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",0 Y$ i7 ^& T% l8 S2 k
                DeviceObject->DriverObject->DriverName.Buffer,
% _; ~3 I. ~% W' {                DeviceObject->DriverObject,- O9 c* u0 u. k/ O" L
                DeviceObject );
- P) \* }) z0 h& }" v% o
2 f! }5 _" w- q1 d" ~. [9 _      //4 t6 `) k( c' F" R1 e4 ~3 {2 i) T+ [
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了& P' c+ r( K  h4 H! ^
      //
0 a5 F" D, f* Z! P' m" P' |      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
( a& i( n5 B) l9 }8 W' i( G% S  o                      KDBDEVICENAME,) N7 b8 s' h( A: J
                      wcslen( KDBDEVICENAME ) ) == 0 )
* e1 s, {" @0 o      {
& A6 Y) X" N# k% V) T( i        DbgPrint( "Found kbdhid Device\n" );
+ ^! d/ w  w- S) `        bFound = TRUE;
8 E; Q" H1 R5 U, {: r2 U        break;
7 Z7 d5 e" R4 N! l' |( ?" \      }
2 v5 ^/ V1 @  B/ _4 X+ c+ N( U! Y1 S    }3 o( b% J9 f2 h0 |+ O0 ^, W! l% {* R! K

: {' U4 j2 Z1 w# E) H1 m. |    DeviceObject = DeviceObject->AttachedDevice;4 h/ B0 P/ M2 S1 ]5 _0 S
  }4 `, p- h' l2 S2 G1 Z5 o5 s9 \, W
4 q, Y3 g$ k! K# f+ D8 \- v- Z' E
  return bFound;4 S' Z8 Q" K* D/ r/ v% X+ A& o
}
7 m, n7 Q- [+ i0 p; y# p8 O) K& k$ _9 u$ Y
/////////////////////////////////////////////////////////////////
1 q; ^* f: R1 g// 函数类型 : 自定义工具函数
+ i2 P2 N- F+ l: E( @// 函数模块 : 设备栈信息模块5 L. b9 t3 v1 T! s1 ^7 z
/////////////////////////////////////////////////////////////////$ }7 U/ }* i4 p- S! A+ V. L- {
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址: [  A9 y( ^7 C
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
  r- U  C* ?3 I! ]0 a/////////////////////////////////////////////////////////////////
, L# v( r% S! Z& Q( p, |// 作者 : sinister
7 |8 v6 V6 E. p1 ^$ T" S. q+ q0 X' P& P// 发布版本 : 1.00.001 h; N& d* Y, M; E; {8 T9 b9 q" ]
// 发布日期 : 2006.05.02
, t+ R2 u" _) V  V/////////////////////////////////////////////////////////////////, R- L, K- P& v# S
// 重   大   修   改   历   史
& E: m$ D7 s1 b! e, _: Y" Z0 g9 G/////////////////////////////////////////////////////////////////& \0 C' x4 R$ h7 G( I
// 修改者 : sinister
/ I! S$ r/ z/ Q- s/ Z3 Q6 x9 P// 修改日期 : 2007.2.12
7 C0 _, @' a& {* v) {% O5 r1 a// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
% d9 D7 T* F4 J3 p3 X0 D, D! |/////////////////////////////////////////////////////////////////5 e. _6 A. Z$ V1 h8 n3 g) ?

2 n" ^7 g/ W3 o: b/ _" d- VVOID
+ n& C9 I# H$ ~! _GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )' a& g4 I$ c% Q) A; B( ?
{
1 f; i- m3 g1 m4 w+ d0 F  POBJECT_HEADER ObjectHeader;
. |3 ?) L$ f4 q' g; J2 P% d# K- ^  POBJECT_HEADER_NAME_INFO ObjectNameInfo; " y0 h' E( r# K1 I+ ~
5 n: r- v: p- |3 L( H7 }6 {$ r
  if ( DevObj == NULL )
4 N" h# z1 a8 q7 E) [  {
7 _. `* d/ L8 K4 J' d    DbgPrint( "DevObj is NULL!\n" );
) c2 L9 [! T. C! \* {: q9 t0 E    return;" y8 d6 g4 y" I* f
  }
  C% y: d; l. o6 e" O: j, X% l
8 X5 t3 z; i2 n  //. z- i% z* \- @& f8 H
  // 得到对象头( G3 F6 x' K* O+ K- Y' U0 A: z
  //
! A2 D, t6 x% D6 ~# l/ }; \  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
+ m/ N1 [( m7 i7 P4 Q+ T
2 G9 o7 y3 y- J4 w0 t% }% g" ~  if ( ObjectHeader )" W. m- A  M: d, M* ~" ~
  {. |5 R) Z2 k' G" z- u
    //
' p2 K- y5 h* N  E9 l6 w  V    // 查询设备名称并打印
/ D6 z" G! Q1 O! Y, [/ v    //( A. q3 y+ j7 _" d) j) d. N; V
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );  r2 Z; |. u: L2 |

+ g/ V8 J. H9 o, N, |1 M! q    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )  W$ p# ^6 C5 F! O  R* s$ \
    {2 q' i) p* X5 Y6 E: f
      DbgPrint( "Device Name:%S - Device Address:0x%x\n"," F% D- H5 E( T3 |* i" u; E
                ObjectNameInfo->Name.Buffer,
6 Q4 N0 Y% {+ a% U; Q: r' i                DevObj );
( r2 v9 C; O* t) Z' A6 I
- G& I6 O2 p8 H# h2 b4 e6 o      //" Z1 U: M. e7 Y4 ?4 A4 O. t
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
3 O- M( G3 {2 p      // 用,没有实际的功能用途) P- q  k7 ~% O3 i( A1 B$ Z1 ]3 U
      //% @: p( R7 w* [/ J- i! S. k( g
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );$ T7 Y: H, q' i+ e  W

. X- n& d, i9 O! ^; R$ ~$ z      wcsncpy( szUsbDeviceName,2 i: ?4 h# @+ A' x/ t
               ObjectNameInfo->Name.Buffer,
2 w4 ^9 H2 u9 V% C# w: T               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );3 x# A" C4 l7 u3 d, F
    }
. ?7 R6 q# g+ s4 f: @9 n+ ~
5 e% {5 r# f, x3 p    //. K7 C/ k5 O2 `& N2 @. l% w
    // 对于没有名称的设备,则打印 NULL: P5 L% C/ V( E% w) ]3 w2 U
    //
! K5 b6 E: y4 U" ^% M" _: i    else if ( DevObj->DriverObject )* W4 X6 [7 d7 z, F% A+ R
    {( ?: F5 c3 _- s
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",: L. c4 ?: m+ l& K5 L
                DevObj->DriverObject->DriverName.Buffer,$ A1 w. y; B, r
                L"NULL",/ ?0 i1 c# Z& S$ L
                DevObj->DriverObject,; B3 _1 w# E$ u2 v" `0 Y
                DevObj );4 ~$ X, q0 e( T! V- E
    }
& N$ ^6 f! y* {; j( A) l3 [" W' I  }
: l2 u; G, T7 U* R7 h/ l! J; F. \" d: ^}6 v. S% h. [0 I0 d
, b* F% C, m1 [2 Z: o
/////////////////////////////////////////////////////////////////1 J' |7 Q9 |2 x4 ?4 b3 b% s) h/ K
// 函数类型 : 自定义工具函数
: U+ p6 d5 D& Q// 函数模块 : 键盘过滤模块1 S6 q6 @( ~+ q2 L' M, E$ G
/////////////////////////////////////////////////////////////////
  d- T! z# m% l! C" L' u// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
- C, I4 p, E. A* u6 }$ K0 u//        对象,过滤出 USB 键盘设备,将其设备对象返回
7 a+ t6 Y2 @4 U// 注意 : & v; `$ Z9 e" p: l8 C
/////////////////////////////////////////////////////////////////# n% w  a: F' }- \% o% t6 {- ^' l
// 作者 : sinister
6 t: T/ y) s% u* l& C// 发布版本 : 1.00.002 N8 F0 E# @. }
// 发布日期 : 2007.02.13
% G6 c. u; q( |/////////////////////////////////////////////////////////////////  p* X; b2 N# {) l1 [3 O3 S; y6 W* q
// 重   大   修   改   历   史
9 w% M" \% _" G+ n/////////////////////////////////////////////////////////////////
8 L% u+ d( {" m& c1 F1 @# h// 修改者 :
% E  }  g# @. N) j" J& o2 b// 修改日期 :
- o' _& }% G: T7 x% x; x0 ~// 修改内容 :
1 j9 D+ \  k6 I; V3 V& F% f( P& T/////////////////////////////////////////////////////////////////7 ]$ }5 g- N0 y

. e4 B# U4 |+ ~7 u, C" r! g' F- CNTSTATUS  |' v2 J/ \1 P2 ^$ ~- v0 Z$ {, C
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )( s2 V, n/ E9 d' f0 ]3 L
{; E* p7 G$ z) i2 c
  UNICODE_STRING DriverName;+ ~. ~' `  q- x3 y1 p
  PDRIVER_OBJECT DriverObject = NULL;
1 E5 w2 R# ?; m. y% o! B- d4 H6 Q; x  PDEVICE_OBJECT DeviceObject = NULL;& v$ A2 _- s% S1 `8 |  `$ E
  BOOLEAN bFound = FALSE;
0 V& N8 D! m4 C1 K+ U% b) E. c
! {+ x4 F; W4 {; ~; a: x4 m  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
2 R; C" ~) s! d1 N) e! D: |0 ]0 O* `" Q8 y
  ObReferenceObjectByName( &DriverName,. Z8 m% T2 S# e
                           OBJ_CASE_INSENSITIVE,$ [# V( \& E# {/ \* V4 o
                           NULL,
" ?5 h% G! {' J3 |  q. G                           0,
% ]) m" m3 f1 c! z0 _" V                           ( POBJECT_TYPE ) IoDriverObjectType,
) u8 h3 i9 v- a                           KernelMode,
( Z, {5 Q$ m" a2 }                           NULL,
& m3 }  H7 k% [9 d4 w' o1 {                           &DriverObject );
5 A3 v" P; {0 i) J
9 J* Q3 ]$ \/ @9 P# |' s4 K' C  if ( DriverObject == NULL )
0 w9 S. E" ]# T4 f% ~  {
$ Y& O/ E2 A- [+ {% G    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
2 {6 w; H. W1 P    return STATUS_UNSUCCESSFUL;
  i: q8 g" x. k4 g$ l- G& y( ?  }
- U- u" P2 k( m
/ `( w1 I; {* L  DeviceObject = DriverObject->DeviceObject;+ F% Q  k3 j) Z) K+ A- j
9 W+ B% e4 T. M* p
  while ( DeviceObject )
0 z1 A3 p* ]; o5 d- R1 _& P  {
& W, R' }; V3 _& `8 o    GetDeviceObjectInfo( DeviceObject );
0 M5 Q; ~2 C+ g5 d
, |: K, F$ m) \  H  h$ E    if ( DeviceObject->AttachedDevice )- `' n  a2 E% {3 T
    {
7 x7 A; G/ H( V; \/ U. R      //8 c  t5 }: u7 w. b
      // 查找 USB 键盘设备$ F3 L0 _4 M/ ~0 ^
      //- }: j  U3 N2 K4 M$ q6 ~
      if ( GetAttachedDeviceInfo( DeviceObject ) )
  Z) Q5 ^. L1 y9 s  G      {
; g) x$ \! \, x        bFound = TRUE;0 v7 I- f, T% E0 J6 k: s
        goto __End;# C( h) t# M3 o& h# R
      }. Z! T5 x/ N7 U& m3 U4 I
    }$ t! _9 C5 r7 x, a  n

) @9 X8 p+ q7 O1 s) y    DeviceObject = DeviceObject->NextDevice;
9 Z6 l+ h. k; c! ~6 q* n5 H3 |  }4 t4 s' B( P' G+ h5 P5 O/ w
" ~& l3 X) l  H4 n1 [
  __End:" ?, f) R/ f7 ]1 y$ f

+ n( h3 Z% ?* x$ |2 \: `  if ( bFound )2 U* y, u1 X& R+ U6 f8 z  O
  {
" }; b9 {( _# h    //
- b0 P' [6 b# P% B- \    // 找到则返回 USB 键盘设备对象( H0 \8 g3 V2 U' k+ T: u
    //4 B8 s4 C: c* u9 _! l
    *UsbDeviceObject = DeviceObject;( v0 {$ l! V/ h; D4 v4 q
  }
* B: q8 @* N' `$ g7 _+ }4 z  else& T, p, c3 k8 o: U! b* k. ]
  {
/ J/ x* ^" R$ z' u    *UsbDeviceObject = NULL;: k! w) j& P! K
  }
$ f* C) P# L* c% D4 h8 |4 j( h$ Z: y: U* i+ m, V
  return STATUS_SUCCESS;% B5 O! [6 n* M
}
- J( c6 Y9 p: M$ @; r
/ g1 N. F" ^4 U$ d+ S/////////////////////////////////////////////////////////////////; U; H% H2 q9 |( S& O+ i
// 函数类型 : 自定义工具函数' Q5 `* `8 q2 S
// 函数模块 : 键盘过滤模块
& B9 C1 m( b: I! u" S////////////////////////////////////////////////////////////////* C' W5 y) H; ^, t* b. z/ `, W5 z
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关) }: G4 k. |; B" P% |: @/ a1 F
//        信息,返回附加后的驱动对象
' M& S# `, C8 z6 ]& J1 O9 m1 ]// 注意 : 此函数仅挂接 USB 键盘设备
2 u: b2 E0 Y. D1 w$ L" B7 y: y+ h/////////////////////////////////////////////////////////////////8 T1 X: O+ ?. G# v& }, t/ \
// 作者 : sinister* G6 s% h6 k, a2 N* ]/ O
// 发布版本 : 1.00.00$ u  k* O& S4 p  R1 R1 B7 @' W" l
// 发布日期 : 2005.12.271 N# _/ h' o7 Z" W7 \% D8 |% h* }
/////////////////////////////////////////////////////////////////
8 n) p/ O5 S4 V- P+ g// 重   大   修   改   历   史
7 G+ @* q8 \, w////////////////////////////////////////////////////////////////6 m/ V: T: |" s* Z# G
// 修改者 :
8 X7 R: \( w, _5 P// 修改日期 :
$ R* s; F. r+ d$ J// 修改内容 :0 c8 x+ c6 R! c* I& L" t1 k) e, J
/////////////////////////////////////////////////////////////////: }4 f0 N# m8 |2 V
, A( n5 a+ U: X5 [% @
NTSTATUS
2 w$ `( ~2 q' @( {& |AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
0 s$ q/ ]) |# N$ G  |+ V                         IN PDRIVER_OBJECT  DriverObject )% _% s: \* [: Z0 l- I( [
{4 x! H4 H: z7 T0 i' w: Y3 N
  PDEVICE_OBJECT DeviceObject; 7 l& M' z  S8 J% m/ m8 H
  PDEVICE_OBJECT TargetDevice;
& l- W$ ]7 V, r9 [6 {1 W) q  PDEVICE_EXTENSION DevExt;
, A$ B/ ^# e) V/ F  NTSTATUS ntStatus;
. F" F- `5 g+ k! J$ b7 s7 }6 J6 h* J6 z2 A' h
  //
: R# \+ T9 h- d) u, ~; R  // 创建过滤设备对象
# r( \% q  [' R! P# u  //
1 J4 R7 F' ^# v- D4 t6 ]% [; v9 K  ntStatus = IoCreateDevice( DriverObject,. j  V' _8 e5 {+ j8 P
                             sizeof( DEVICE_EXTENSION ),, L+ @% y8 u6 j: q* r
                             NULL,
6 x# w3 T, m5 Y" o% ^                             FILE_DEVICE_UNKNOWN,# ^! Z. L2 \; v4 [- W# ]" V
                             0,
3 @0 T8 J3 ^9 y: Q4 T* u$ i3 M3 G  v                             FALSE," X5 p; O$ {0 b
                             &DeviceObject );
; x2 E8 W6 x( e- T* g$ H: K3 L( z- T0 ~7 b$ `0 W! l: e: m" Q# a
  if ( !NT_SUCCESS( ntStatus ) )
9 n7 _4 N% b" j# p% ~$ B2 \$ @  {
2 Y# {4 l. `' N+ H. }8 y    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
% Z( T* m/ C- z) c6 L5 g5 D    return ntStatus;
3 a* Y0 n* o  @- ]0 s  } . {1 e9 N+ ?# J* y0 q

8 R1 L9 t. c9 N, n  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
, z9 I% ]0 ~% p, }, f; o, x* y. F1 _+ ~1 f. J! B* Y8 [4 y
  //
8 |. O7 a4 K( M" ]6 g' a: N; Z2 @  // 初始化自旋锁
3 ]. T6 |- P% @  B2 \# C  //
. ~7 Q' v6 T3 l0 p& ~) s: |  Z( q  KeInitializeSpinLock( &DevExt->SpinLock );
" Y0 A9 D! ~! w! D) c, {
1 @2 X! O) Q* n' |  /// g" [0 j4 y8 G% \" u
  // 初始化 IRP 计数器- A) B9 ?) _& m( X, i: R1 t
  //5 v- F% {# k* _" F' i. U
  DevExt->IrpsInProgress = 0;
$ K7 K' J; P' Z; z& m' R; a# p& J# n
  //
5 l9 ]' j  u7 A, a) ~8 Q) D  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象0 a+ Y; n3 D. `/ C' ?% n7 h
  //
: \2 W" E& v* @. j) S
& i( \+ f) U; H; \- ^0 o; m, W  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
5 c- D/ D4 x. }  if ( !TargetDevice )
" i# m2 f# B* I  {. `: Y! x( I, `9 G) _
    IoDeleteDevice( DeviceObject );
. _# ?) A* ]" X! s3 {" c1 R    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );5 S* X/ d# F* J
    return STATUS_INSUFFICIENT_RESOURCES;0 N6 b* W2 m+ p9 C; I
  }
6 R8 T0 G* f9 c1 t8 v9 X  r
6 s, \. ^  P6 j5 n- L' `; [  //
* o- k4 \4 H2 \) H  // 保存过滤设备信息
; s/ q2 W# \& o4 \' W+ U  //+ h- C( f: K; ^; N6 w) v: f* u8 ]* l
  DevExt->DeviceObject = DeviceObject; 5 B) o8 d% T4 V! Q1 u. F
  DevExt->TargetDevice = TargetDevice;# h4 |" s9 O( r5 c, k1 @1 `

9 x1 y) c6 o/ M  {$ s9 Q  //
% G# ]+ _& i! m4 y3 R  // 设置过滤设备相关信息与标志
. n& ~- C. y' V0 q, x- [2 k* Z  //
6 K  r& x1 \) A/ S9 ^% F, A  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );( M9 x4 C# ]( z/ W: O' E
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;- I3 R. N) K2 D

" e- `) ?. Q: F( ]( j
0 c6 V+ d1 P8 W3 A; I  return STATUS_SUCCESS;1 x4 ^- L% U  X0 O% |; W5 `
}6 Q/ A3 V2 \9 y' o+ i8 W+ y! y
% u! Z3 V; K8 z
/////////////////////////////////////////////////////////////////
7 w8 L$ [; U0 M# D// 函数类型 : 自定义工具函数
  x3 v9 N! ^9 t( m9 D// 函数模块 : 键盘过滤模块* E4 y/ s5 c6 E" ?: Z% O: [
////////////////////////////////////////////////////////////////
2 X5 D( a, n) Z6 |6 F/ N// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
6 t. ?9 \  s+ b: F% a5 q* t! P//        信息,返回附加后的驱动对象
/ D, i3 ~. ]4 `$ ]/ o& ]- ]// 注意 : 此函数仅挂接 PS/2 键盘设备
7 w( ]# o8 V3 z2 z# ^% U/////////////////////////////////////////////////////////////////5 K6 g  N7 H! _5 Y/ `: D: k1 Y
// 作者 : sinister. z" V9 I( c) j8 j8 L3 X; \
// 发布版本 : 1.00.00
6 r  f7 y9 u0 v" u( _) f, _% Q1 q// 发布日期 : 2005.12.27* n! e. `( x% \9 T: b  W, p
/////////////////////////////////////////////////////////////////
8 c4 r" n" X5 _# [# a// 重   大   修   改   历   史
/ O2 T' G4 u! I' |, q: i' z' `( ]////////////////////////////////////////////////////////////////
) I; x; E8 g5 E; O$ b2 a// 修改者 :
1 i7 R& E; y$ W) `8 r( Y! u4 j( S// 修改日期 :& j7 K  |( L3 K* n9 `1 F
// 修改内容 :1 n7 X$ J; e2 W! ^
/////////////////////////////////////////////////////////////////
# [. ^, H& `# _9 k4 J) s) W* J( R  F  h0 F  p9 Q1 ~5 t
NTSTATUS* P8 H5 d+ C5 N" X' F, ~% T
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名* a5 Y6 {. l4 }" ?# i% q
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
7 n% t! m- t' B0 X) T- I2 ?                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
7 F  W! m0 H* \# e{
& e5 w) G; D) l' p- E4 @: |  H  PDEVICE_OBJECT DeviceObject;
/ i: `  Y: B! _: b, S  PDEVICE_OBJECT FilterDeviceObject;. {. h$ s: }$ z$ b
  PDEVICE_OBJECT TargetDevice;   C+ B1 {* C7 x, k: M
  PFILE_OBJECT FileObject;
* I% u7 r4 w! j. [9 s' @  PDEVICE_EXTENSION DevExt;* r& H- N" \5 J+ Q* Q" ^
) f: u& M1 \) D& s5 Q
  NTSTATUS ntStatus;
! v& `4 v* F( P! ?6 v6 S5 \$ l: b$ F9 g3 {" A$ S9 f- s: x! p$ D
  //
7 H2 L$ ]5 e/ K( N, t- \# e, D% k4 j; v9 Y  // 根据设备名称找到需要附加的设备对象3 R' k, P" J( n! |1 @& u4 s! S
  //
/ _# y# O1 n5 q3 _  Q8 z  ntStatus = IoGetDeviceObjectPointer( DeviceName,! _0 |6 ]' G& X' e: n
                                       FILE_ALL_ACCESS,
2 B* \9 D( x/ |% b% W5 f, I                                       &FileObject,+ ]4 G9 ?+ z2 n9 a
                                       &DeviceObject ); ; n* Y3 u4 n8 M; d" ~' e2 |

2 ^8 F2 ^- K: o* l; X2 Y  if ( !NT_SUCCESS( ntStatus ) )9 j" R* C; F. |. v0 l
  {$ r. s/ b0 N$ U4 g# g
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );9 O' X( Y/ I" M% q3 @" S
    return ntStatus;) C9 J/ B) e4 }( |* D  Q7 l% Y
  } 0 y0 Z* d$ h* ~4 M0 K, ^3 b
# z3 E% y" \& h
  //
+ w' R! g0 I/ f, f  // 创建过滤设备对象
8 Z; }( \  d( k: R7 N  //
0 l' X! g9 V# f6 Z$ b. d& m  h  ntStatus = IoCreateDevice( DriverObject,  |4 X3 v! q- H- Y3 `) q/ ?+ T
                             sizeof( DEVICE_EXTENSION ),/ M* q/ K! e# i+ v1 j  m$ J' N
                             NULL,# A* b* ~9 m( {4 H
                             FILE_DEVICE_KEYBOARD,
$ ^. M7 j  z* y2 |                             0,
2 s3 [% \+ e9 q$ r+ f5 K  I! K                             FALSE,
2 G* K. d6 d: p- u+ p                             &FilterDeviceObject );
9 A: j6 t# x" Z! V" t( r- h& e6 F! C4 y
  if ( !NT_SUCCESS( ntStatus ) )
: u. P, \4 A# @9 g  {
( e3 Q3 H: v$ m: O    ObDereferenceObject( FileObject );
" }% A0 N  V3 }, z4 d$ j. r: l& P    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );9 x* j8 k, ^2 P! N
    return ntStatus;0 C) h9 p7 a/ M6 F2 H& D* w
  }
" v- f4 S# x5 i
: |" d9 I- R, I3 N% c! K  //
) U- _3 m0 R( p7 y  // 得到设备扩展结构,以便下面保存过滤设备信息
! y: o3 h7 {" {, f) i  //0 A4 l. Z3 |  G; u' P
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
2 B) }. r( Y% d+ x( t( Q! g/ P  F
: S4 S( J; E0 d' o, h7 }1 n, \3 U% a2 U
  //
3 T9 M" W5 y3 _7 n8 |, }) A! \# N' w  // 初始化自旋锁5 h& V& _! K8 c$ @- e
  //
& i. q: T( y( b5 [3 K! o  KeInitializeSpinLock( &DevExt->SpinLock );/ r- l- h0 [0 E
7 `: z  u1 ^3 _
  //& J. t. O5 O( q  z% e, o' k
  // 初始化 IRP 计数器
4 A* h3 d% H$ M# [1 ]  //
# t# R2 c. b( C: a, ~  DevExt->IrpsInProgress = 0;* G( H* C1 M& W+ Q

" a- [/ p! g6 H, e. a3 F$ ~4 \% i  //0 \) b1 c$ Q+ _
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象6 B3 D1 e6 G% |/ ^" [" J
  //
0 Z) y: L& v: o; u6 ~" W. h! `% f' L  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,8 O8 ~- I$ Y7 j, }) q7 |$ A6 x
                                              DeviceObject );
4 y' U+ o: P8 |8 r. \; i  ~  if ( !TargetDevice )
( `, }) I* c' ?4 r  {: m4 n# ]9 D, C1 \, R$ S
    ObDereferenceObject( FileObject ); ; ~0 I1 J/ P* Q. ^1 [; R
    IoDeleteDevice( FilterDeviceObject );
9 l3 l* p/ K. H2 N    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
& ]6 Y, Y# {0 }; P    return STATUS_INSUFFICIENT_RESOURCES;
$ ?6 O. R4 E8 v6 ~8 [4 k4 F  } 4 M. F6 U* E7 I: h* X& d, F: w8 f

8 n/ j! d; I* e$ @  {  //
& R9 z6 N0 a1 o5 R6 I- K  // 保存过滤设备信息- W1 o: `# L7 c' u/ u( \/ r
  //
: I: S/ y$ S2 T  e5 t: u  DevExt->DeviceObject = FilterDeviceObject;
8 e; a7 D5 r9 J5 r  DevExt->TargetDevice = TargetDevice; 7 B) M  f0 d& \1 y. Y7 U
  DevExt->pFilterFileObject = FileObject;8 h% l0 a7 r  X2 Q+ A

7 Z  W" Q; s: ]5 T1 N0 D  //3 Q& o1 m# i) S$ X, ]9 n
  // 设置过滤设备相关信息与标志
- \7 l; q2 P6 K3 F; D  W1 w5 J2 l  //% {& X( Z+ `5 S# \, W
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; ' t! m2 |) \( y" _1 O/ }0 ^2 c
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
  F: r6 I& Q* A$ `3 G, w* S* c/ A3 U  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;% n) v9 I& R$ N; }
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |3 ]! s) w( ^6 a
                                                         DO_BUFFERED_IO ) ); 2 D' m) Z: _7 v$ [& L% X' e

0 j( n- c: e9 e% G6 n- z1 f7 m  //( y1 C" y* I, `" V7 |2 D  w
  // 返回附加后的驱动对象
! E# C) s7 X  t" y; N  //  j! Y( v6 K) ?- n' w  c
  *FilterDriverObject = TargetDevice->DriverObject;# J3 Y5 u2 a, \4 b5 P: M

  _4 ^( ^8 Y  G9 ]  ObDereferenceObject( FileObject );
2 |/ o  h4 f$ o7 ?+ o! U' B
' B& L! C$ z2 v9 t  return STATUS_SUCCESS;
% Y7 }4 ?% O6 g! k& o+ C7 P  N' {}
8 c- ~. ~" [: ~# m# o
& F, q2 V! r( e1 F/////////////////////////////////////////////////////////////////
& I0 K5 t4 V3 e! I// 函数类型 : 自定义工具函数
# q1 d8 x9 o0 a3 D. ~3 T// 函数模块 : 键盘过滤模块) {" M2 z; S7 {# R8 h8 h
////////////////////////////////////////////////////////////////
- e; b* F1 k3 @" H// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
4 _5 E" s& z1 p; [- Y! f6 c% m( \//        这个 IRP 的完成3 {! Q+ V7 J$ m
// 注意 : ; h% s4 Y9 H8 U
/////////////////////////////////////////////////////////////////
' z( B/ p: c0 x' |// 作者 : sinister" g2 b8 N9 _5 m" C" p
// 发布版本 : 1.00.00
6 j" V. s3 E" P! I3 O% I: }% F// 发布日期 : 2007.2.15
% H8 T  C% U% {2 l* }$ b% ]- L& j$ D; B/////////////////////////////////////////////////////////////////. n" M' n* o9 `) C8 m" n* ?
// 重   大   修   改   历   史
1 D* x( X: d3 g. z////////////////////////////////////////////////////////////////
+ }; i1 L$ }# H( D! @! ?// 修改者 :- k0 y0 _6 o% s' J9 y
// 修改日期 :) D, n; h$ a. G1 }/ E
// 修改内容 :
0 t; M6 S. k0 o8 |: ?/////////////////////////////////////////////////////////////////0 ^' E2 a) G* z* J6 _
, B1 A# P2 o# K  X/ T' s5 p: |
NTSTATUS( Y, {2 q& Z/ ?' e
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
3 n4 E4 m6 e7 M; @- ^; K{
' S% z- g! X2 L# Y# o$ R( V/ u  NTSTATUS status; ! H2 ?; I; G" |1 L5 h& J4 c
  KIRQL IrqLevel;7 z( [; v' y- M9 U

! R' @6 U8 U% f: O9 t2 t- Q; f  PDEVICE_OBJECT pDeviceObject;
5 q8 A2 F( f: [4 o, |1 M4 H0 r5 G  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )3 a. g, ]; e  |- J
                                   DeviceObject->DeviceExtension;
' F. N5 g0 I3 m4 n7 [& p# i& q2 L  t0 Z: F

6 j' v' y  {, g' l! l  IoCopyCurrentIrpStackLocationToNext( Irp );
6 R4 J3 A! l6 s) Q2 {: S; ~% [) r4 U% m: N
  //! {* q" q& M. s, w8 M. }
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
$ R% ?1 u) P2 f, B5 q' k4 ~  //
2 O+ j7 M5 P) X7 h$ Y6 x5 x3 Z6 V" h  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
7 h/ a5 D) q+ p" Y6 }  InterlockedIncrement( &KeyExtension->IrpsInProgress );: W3 g: O& s  {+ k: C+ c
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
  ~$ e% F; u  B) K6 S1 S* s) ~7 s0 `8 }* C
  IoSetCompletionRoutine( Irp,/ u" g. B1 ^/ y2 o( |
                          KeyReadCompletion,5 y9 k- y5 a" j
                          DeviceObject,
( b( Q" z9 h! P' V! q4 f                          TRUE,% ^* K. V/ Y7 A
                          TRUE,
& _2 i& ?1 v- l. w. I                          TRUE ); 2 W* n$ l4 W" {9 d5 |9 L

) r- O  y# V- r1 Y  return IoCallDriver( KeyExtension->TargetDevice, Irp );
" E7 a9 }+ p3 G. j- {0 k, D}
# R8 s! B: p7 m% p0 Z
8 e0 a' h# V" K6 a9 Y4 P/////////////////////////////////////////////////////////////////1 ~) l% l" o% Y1 M5 n* s
// 函数类型 :系统回调函数
* S  W- R- M: M- O/ E// 函数模块 : 键盘过滤模块
8 g! G3 o! X8 ^- s% c////////////////////////////////////////////////////////////////
% Y8 [9 U4 A( K5 C// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的. G; T& a, ]! n4 _' F
// 注意 : ( k9 u) Q) T4 i" C: {6 [
/////////////////////////////////////////////////////////////////$ e* {% E; F+ d9 o0 D0 q( Q: _, i
// 作者 : sinister
9 s! b4 R" `. s% W: _// 发布版本 : 1.00.009 B- \" }4 Z% m7 `. L; Q+ g
// 发布日期 : 2007.2.129 t7 n' @9 A7 @
/////////////////////////////////////////////////////////////////9 |% C7 O. h) A. \3 \
// 重   大   修   改   历   史
1 Z6 X. e4 s1 |0 @: E3 p8 M////////////////////////////////////////////////////////////////
) B- t6 i- {& f5 @2 }// 修改者 :
6 |# h) ?1 c- w  P1 {& W6 ?3 o: t; [// 修改日期 :
# M( B/ e8 k; H& }6 Y  N// 修改内容 :
0 |" _$ W6 \" Q: g* A/ ^8 x/////////////////////////////////////////////////////////////////
" v1 b! S' Y/ s* ]( G% F, Q
7 S1 u1 P) V/ R; [' p+ t: tNTSTATUS
! ?7 ]- I9 @1 E$ kKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
" s5 A: F# B* ?+ a, m9 J                   IN PIRP Irp,; @  ^' k" u9 w# C: A1 @
                   IN PVOID Context )
' `6 s7 o6 ~' m+ c" s{
. l! r; g4 l! b" s: e  PIO_STACK_LOCATION IrpSp;9 j) J+ k1 o/ l$ v
  PKEYBOARD_INPUT_DATA KeyData;
# ~8 ]3 h, x$ {& @: t  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
0 |$ B  |( \; k5 m5 V% q                                   DeviceObject->DeviceExtension; . ^$ U* w4 \- G" s
  int numKeys, i;
- |  ?8 L6 u) L( u, B7 k  KIRQL IrqLevel;
* V' F  N) d/ C8 Q1 W+ A  A$ \# z9 t( J
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
( N3 l( f" o5 V' b5 F# s% d% e0 Z, a! a# g2 i9 ?. x
1 R0 P& }) y8 u" `6 V
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )6 ]- ?/ C. T8 Q5 j5 P$ i* F
  {
* l! F, N5 y+ L) i! |    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );& h. T/ t3 ^# w0 h& G, `
    goto __RoutineEnd;* Y: p% [1 n" L! z9 v
  }
; v8 n  V0 D% I5 ?3 i" |& y2 d7 ~; y, n8 ]
  //
2 |, ^! t; E3 q) l( a2 l  // 系统在 SystemBuffer 中保存按键信息# @# {. O, i+ Z: t$ l+ j
  //
3 W3 X4 V7 F" L) C' V  KeyData = Irp->AssociatedIrp.SystemBuffer;
( [! U3 u/ z" `' K, C8 u  if ( KeyData == NULL )
  A* ]' q  W+ t) b; \( K  {
% K6 V) h6 [9 I    DbgPrint( "KeyData is NULL\n" );
' \$ e5 e$ D) B' h6 |" `1 j    goto __RoutineEnd;9 f+ p) r% ?  k( L7 h
  }9 M8 A" s# L/ u" ]$ Z$ C2 a: H: {
3 W, V1 G" ~/ m- ^" |" N( W: n; p3 \
  //1 b! l: S4 ]& Q" o+ b$ ~, ^0 r9 k
  // 得到按键数% }& r2 Y1 v6 ^. ?* c4 Y- g9 N
  //
7 Q  i1 h& `+ t) {+ ]" f8 H% m  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );, R2 D& X, c( m0 i6 E, o5 b9 S
  if ( numKeys < 0 )
# h" Z3 F5 z: |: M: S3 y  {/ c0 ^9 r* g, ^, j
    DbgPrint( "numKeys less zero\n" );
4 n0 I4 e' T' Z- B8 ]8 J. Y    goto __RoutineEnd;
0 m! b( n! g7 j5 N  }# I' G8 R! A8 j3 X- Y

3 r# }+ p0 d# [  //
* ~3 s9 ~9 A% x! j/ x: Q4 b, Y  // 使用 0 无效扫描码替换,屏蔽所有按键
  l) {5 w/ e5 U6 u& V2 z# W& U  //
+ Q3 Q4 i2 j  m+ O- E8 {0 x  for ( i = 0; i < numKeys; i++ )
  h% _% |6 C. {5 F/ L  {+ ^/ s9 u% Q$ ?' j) i  ]
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );$ V, X" x& d( a* ?3 Y7 c$ S
    KeyData[i].MakeCode = 0x00;1 ?. N* n& b" s- w0 c/ q
  }
- x( t) {7 Y1 r0 M: X5 j
6 H3 ~* ]1 X) i! G# a& z! D
3 C5 u6 r3 J! a6 T  __RoutineEnd :
2 b- Z* s5 x6 @6 x' N) F' @% ~8 B# Z
  if ( Irp->PendingReturned )
4 s, F5 h. h) E+ `  {) A; e! t% S8 O
    IoMarkIrpPending( Irp );
" b, J$ N6 X/ |. K- d0 b  } 4 H: D( H% e* N! l6 y

3 K4 e$ y5 t0 G9 G0 S3 ~  //( z8 s' n, \# h
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁  r. c8 M1 H9 Y6 i8 t$ f
  //
& x! \: G. T+ A/ Q& N' M" k7 ^- M  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
% C% i! T% ]3 H( H9 O4 F$ a  InterlockedDecrement( &KeyExtension->IrpsInProgress );
3 W9 a9 V4 }; Y  ]  z5 w4 }9 X  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
# m! p& ^9 E1 w  C. |' V1 H
7 A$ b8 J! L8 A9 q& g7 }  return Irp->IoStatus.Status ;6 f# j$ ]) `- E0 S( }
} . q; ?7 u- B0 M! B

7 ~( d7 C8 h) B6 G% B# X# ?, `- w3 h# t6 s
/*****************************************************************1 p! p, a; D2 M; P
文件名        : WssLockKey.h( L2 L& V3 D7 z3 D0 c
描述          : 键盘过滤驱动
1 M- K  W  i- N! q4 _ 作者          : sinister: x9 r1 p. j3 c+ s5 D5 V# {0 i; |% I
最后修改日期  : 2007-02-263 A) H! l3 y5 G* {
*****************************************************************/
( G/ F2 U7 L- k% {+ X) r4 @& d' r$ `' c; |, F! u
#ifndef __WSS_LOCKKEY_H_& o  y* Q; n7 n- [1 U
#define __WSS_LOCKKEY_H_
. d, o9 X/ P, }# k2 @# J
4 n# D, E# r1 U" s+ l#include "ntddk.h"
! V& c+ S  _6 M+ Q; s# h#include "ntddkbd.h"
7 _& d9 V0 X) V% U5 r! X( Q$ f#include "string.h"
- p& M, Z/ X7 _" T1 [; M#include
# v- _% O, o! l
4 T: f0 @9 P* q7 i+ |4 U#define MAXLEN 256: Z* l* p/ ?8 m  k: G: ]1 R) |# v
. u" c3 X; F7 d' b7 y2 R
#define KDBDEVICENAME L"\\Driver\\kbdhid"
0 ^9 e3 @) [; H# e& x6 E, r3 t#define USBKEYBOARDNAME L"\\Driver\\hidusb" 0 L# F9 v# A. r! k: P& `& x# b
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
' _) K0 J( G5 s% X2 j$ I5 Y/ |: S; U/ F9 h
typedef struct _OBJECT_CREATE_INFORMATION
/ G9 Q& O0 u2 W  M7 C+ w{
! K% V" s1 ~6 ?7 ^9 k    ULONG Attributes;
  s  W$ l0 i! B# P    HANDLE RootDirectory;' k: |; S+ D# v  x
    PVOID ParseContext;
- n' a6 m% H& ^: Z+ W) U    KPROCESSOR_MODE ProbeMode;3 c- V- A7 }5 A' R2 ^9 i/ ~/ |
    ULONG PagedPoolCharge;2 H( V) ?* ~& T, d7 e
    ULONG NonPagedPoolCharge;
" q" [+ U% j6 H! E7 p. o, O: _- `    ULONG SecurityDescriptorCharge;! w2 f0 t! M7 a- [+ j
    PSECURITY_DESCRIPTOR SecurityDescriptor;
% o# C' [" I6 _! W! y. _    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
" |+ w3 N0 g& j# ]  [0 R    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;1 f# y  |& R* T" n  w
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
* S% x" j+ P+ J6 `6 \6 D
# a& D( e# O/ G+ d/ P: C, m" }typedef struct _OBJECT_HEADER7 t' V  z' U8 }: ^" |% R
{
8 W" a3 F' Z( r; J3 B    LONG PointerCount;; Y2 _- M; w! C5 i
    union" X' Y0 E4 I% I& B
    {
0 N+ w2 @4 l0 V3 W1 n+ x        LONG HandleCount;
# u5 A2 l7 I9 A3 R% R2 P( _        PSINGLE_LIST_ENTRY SEntry;
& ?3 g9 J* E9 `" V1 \8 Z7 H1 ^    };
, |+ G/ r! ?. I+ B4 c: _0 M7 U! x, ~    POBJECT_TYPE Type;) S+ q8 a! M& v. n# v/ k9 v
    UCHAR NameInfoOffset;
5 z& `5 _* W* x# f2 X8 C0 J    UCHAR HandleInfoOffset;
: D; U- Z- `' Q2 p+ }$ I    UCHAR QuotaInfoOffset;
, {9 A9 B4 M4 a7 k& A    UCHAR Flags;; Q8 N9 j, i* H, {# P# K: g) b6 y
    union
6 |9 I4 C, @* P4 n* e2 |6 N9 T    {* o& \5 }/ h4 [$ d7 M" ~' `
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
  S: _; y3 Q% B0 B! O; M  K        PVOID QuotaBlockCharged;
# G. j' Y, g' r    };
8 t6 R/ j; F% \! ]* p
5 S/ w4 C! |! c5 g! \    PSECURITY_DESCRIPTOR SecurityDescriptor;
! h* t- c3 q* d, z& d    QUAD Body;
1 n; r: ?+ Y7 [9 B3 P; V0 x} OBJECT_HEADER, * POBJECT_HEADER;
/ Z- a+ [9 A  F3 m0 S
+ P* _( z1 m& p& B; A0 x#define NUMBER_HASH_BUCKETS 37
- W! u; T2 p6 v3 q; y( y6 [5 c( Z9 D9 s  X
typedef struct _OBJECT_DIRECTORY
8 ^% T7 W# m  G1 p  J  A1 U/ ^! ?{4 X2 F5 T  k1 |/ P0 e* C
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
2 y, r6 d; i. c% p2 Y1 W5 \+ M* @    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
$ w( o; S" R: \( g0 B    BOOLEAN LookupFound;8 X7 E; {" X3 l3 r. B+ o
    USHORT SymbolicLinkUsageCount;
6 ]3 M4 p; p1 r2 u( I) B6 F    struct _DEVICE_MAP* DeviceMap;
9 x% z+ h2 }$ C- T/ {! X} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;8 p7 m0 T+ ^/ w9 E
+ ~3 h* \! _& t
typedef struct _OBJECT_HEADER_NAME_INFO
2 i. a+ n, [$ E8 {7 ]4 D{
* o) {9 V+ A7 s    POBJECT_DIRECTORY Directory;$ Z6 @5 E% M- u- `
    UNICODE_STRING Name;
/ k7 v; F. T6 v$ c; c$ D    ULONG Reserved;4 G3 C5 n, L( v4 ~3 f! b' @3 T
#if DBG3 o% E( i$ p2 e
    ULONG Reserved2 ;
! Q& B! J) l3 e' K+ }    LONG DbgDereferenceCount ;3 B" F8 P0 b  |* ?# |$ g
#endif6 S3 p* {& R2 O
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
- Z7 }( W# \9 J) Q( N6 @. [+ D7 Z9 E. L' B3 k' s
#define OBJECT_TO_OBJECT_HEADER( o ) \0 V; e' m* o" h# u
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
% D0 r2 S* T0 ]. C0 c6 X) B2 R, I; ]% U! l/ M
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
5 [+ y$ T9 E* M+ `    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
) H8 @" l3 P& |' Y2 W( u
3 Z! z" a! E# C- g4 S/ ktypedef struct _DEVICE_EXTENSION
9 X# \. K5 q- ?" ?7 e{
3 K/ e! Y& ?' h, C' x    PDEVICE_OBJECT DeviceObject;
: `' @4 E, T# H" ?- |, ^    PDEVICE_OBJECT TargetDevice;
' S9 n! I7 t& ^    PFILE_OBJECT pFilterFileObject;
9 B! m! B$ \* a6 n' J    ULONG DeviceExtensionFlags;. g$ v* D: y$ w+ q: J2 f
    LONG IrpsInProgress;  f  q  E+ U0 [" p& p$ D
    KSPIN_LOCK SpinLock;1 G7 |! i0 Q/ }- k
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;. U* Q  e& g  K( N1 Z: f
* [- ?3 K2 Q2 o

5 ]2 H4 _/ h) b) MVOID " }. x* o, ^0 s  ^
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );3 z) a9 R8 m) h) a

) [. Y, X( G( D6 }" w: {$ l% G0 |BOOLEAN  I6 f  r- Q* Q$ o
CancelKeyboardIrp( IN PIRP Irp );7 `" R" T% w: d' G0 ^4 j& v

1 v3 v7 @: Y0 [extern POBJECT_TYPE* IoDriverObjectType;# `% n* Z6 {: N

- z# u  \+ _: |7 T* \  KNTSYSAPI+ c: i! U- w) N/ b! p6 {5 G7 T
NTSTATUS" c) g$ M# u0 G% I2 O. g
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
0 v* n/ ^+ L) Q5 v" Q                               IN ULONG Attributes,6 E4 R9 Z2 `9 X, b& s5 w% z
                               IN PACCESS_STATE AccessState OPTIONAL,8 u" M8 b; r- d: s5 M4 O2 U/ Y
                               IN ACCESS_MASK DesiredAccess OPTIONAL,
. c( Y3 Q0 S* R' J3 m                               IN POBJECT_TYPE ObjectType,
, N; f" r- N: r0 c5 V                               IN KPROCESSOR_MODE AccessMode,' ^; b* I9 Z9 F2 J
                               IN OUT PVOID ParseContext OPTIONAL,$ X& |% u8 o% I( N" |2 t8 W8 J" j  V0 Z
                               OUT PVOID* Object );& k7 B9 f* n5 T) f' C
# Z9 U( H- H& U7 e" f
NTSTATUS
$ H* I* o8 ?3 V* k/ ?2 [6 {, L( }( zGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );  Y9 r8 b, x8 z, D

9 q- C" [. @9 F- P2 k" G6 FBOOLEAN & k  r* k. Z) x  K  a& ~4 u
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
% A: u9 d2 [; `2 i' f# ]: E
& n% L% P8 x, U& X# bVOID 4 l( f0 A2 S- i, i; |
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
. g+ r8 h' k. E& i( H5 }& M( `1 f0 p: c% D9 C* E& M  s$ z
NTSTATUS ! d- ]1 T3 G) x8 g2 u0 W
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
. G- O7 Z$ `9 J                                  IN PDRIVER_OBJECT  DriverObject );" y7 ~" W! t: W& `- g! p
+ g* V8 |8 L  L5 X2 m! a4 P
NTSTATUS
9 U5 ~* p$ |- ~$ ?1 ZAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,+ Z# M2 A- {% ]) f8 ]/ v* A
                                  IN PDRIVER_OBJECT  DriverObject,
  ?/ d+ v9 X: w: f                                  OUT PDRIVER_OBJECT* FilterDriverObject );
& W6 ~! x- ?: G
8 n6 k7 Z* r7 |) J' I( LNTSTATUS 1 P$ l/ h. u3 f3 a4 K) ~
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,8 u1 i8 P! `# D" q, Y: \1 w
                            IN PIRP Irp,5 y! p# A$ B. M5 ^. C& }& y
                            IN PVOID Context );
+ c7 v, l  m- f# ^# }/ x3 k, f4 {6 CNTSTATUS # l4 h0 z' }: ^( D
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
! n' H, d' }* y+ o/ b0 P
2 H8 ]2 W4 B8 m# j" D4 hWCHAR szUsbDeviceName[MAXLEN];3 J8 `: N. r) L, q8 `! m9 c, c/ W

- R8 a, M8 Z& S  h6 C+ U. y2 @( A7 J, V#endif
$ K, G5 y2 ]# S# C9 J
% _+ e% W- t1 J7 u  h5 U8 a8 D
4 d1 b7 R7 E# n% K' T
* E; n4 M  C! G4 `' a. m: M3 D8 P: t( l  o' \6 l; J3 A9 M
7 U& o3 N/ M% s4 P6 M2 X$ _6 w
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。0 p( Y- V/ H$ E- f5 D
WSS 主页:[url]http://www.whitecell.org/[/url] * g0 X8 v% o, g# i- p
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-4-11 07:31 , Processed in 0.030640 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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