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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister9 j; ?2 ]2 P8 [# Q( ~
Email:   [email]sinister@whitecell.org[/email]
( ?* o9 b; J- ~' h$ J" THomepage:[url]http://www.whitecell.org[/url] 9 `' r' F6 O7 ]; i+ b- D; g
Date:    2007-02-26! \! S3 X. a+ b9 T% P1 o0 r# n! g) l
: N6 y7 B. D8 Z+ i" _
7 @: Y4 e, b1 o1 l
/*******************************************************************
; ]9 X! e* F0 b/ Z% Q* d: |3 y
; X6 M; A8 |0 Y这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
& {6 F) s& R/ Q, V$ [写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
1 i0 d* U- M; r: m. D5 Z功能要求如下:
, @5 ]. ]4 r; m7 X# j
8 w/ d; a3 n0 q9 P1 s5 }  d1、强制锁定键盘/鼠标。
+ W; F2 {/ S" c* Q" G/ R! X2、可动态加/解锁% q, D' A/ K0 T3 f+ Y9 J
3、兼容所有 NT 系列的操作系统。
) a- l2 @6 J$ [9 t. U6 ^+ ^
, l: Y/ r# R# L" H. b3 H* Y5 C. P就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实5 E8 \, o5 s9 q( S) O8 ~
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如- {* b* v1 S+ n8 B) N
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在* L9 I8 k5 F. i
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
& h6 {) V/ ]8 @, D& R$ F怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
5 N* ~5 ~% Y9 h7 W就来看一下我想到的几种实现方法:3 P! q$ t* E7 u/ y; o9 i

# \$ ^; u$ j8 [2 A' \/ ^! B1、全局键盘/鼠标钩子
5 o$ k, m! Y. }1 e! b, z: R2、BlockInput() API% h9 x# T4 @5 a& @: s' p
3、使用 setupapi 进行控制
5 n# l+ D( e! I% f4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL/ l, q( c! W/ I% p9 S0 u+ M4 _" k
5、拦截 win23k!RawInputThread() 函数# N8 E) I  m2 x- o! B. D
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
$ K  @  t6 J% T5 e) X7、拦截 kdbclass 驱动的 driver dispatch routine
. B7 q) u6 Y# c* d+ a  l8、实现一个 PS/2 与 USB 键盘过滤驱动/ S# b- p) M, h  l' I$ H7 n
) `, F7 Z& ^' \, B* R- p

& b! k8 t6 ]7 Z' M; \我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑1 O5 ]( \6 C1 e1 u) M9 t- |/ _
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
& @* Y  k6 H; r" ?/ \案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
' [% ~& J/ c+ E2 B; I兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
( q5 X+ }% ^6 M' h% J5 _2 R  j3 B素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性; c6 O2 P, T. ^9 k+ e
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸4 w; |% E7 q  z7 [
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我5 _2 J- K& ~' V  f1 K* ]+ i- M% n
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来9 N% k: D% a9 D6 r0 s
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如- E; w3 X) w6 ?. `/ O2 |4 j' l6 ~
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
( f1 S6 b" B+ F4 t: e6 Z障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
$ j5 p* d/ \: e: [. w$ D5 P: E- DIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 % g5 N" D, z; N5 G. Z3 b7 o2 K3 _
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键: z1 X* J$ w' k* n' R) `( ^
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方8 J! s; B. ~! u2 F9 g, m- o
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
' ^8 I0 |$ R$ t7 }; n3 c1 S1 W7 C
$ G1 {2 U, Z9 i2 F4 B; c9 H1 z( l
* e" Z# E! }% l6 f( q6 Z我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
" Q5 L, O* V" O6 q滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进+ k3 Y2 w- w" N8 O1 M/ {
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是8 G. V) j" y" S" h5 t6 J# B- o
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越2 U" g! A7 ^8 G- C
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从- G: Q+ {- W* m% U" a' J
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB, d/ f- p& I9 z3 H6 [6 b
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
5 R7 M7 V5 b" P( S2 oIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
; U+ Q& l& [8 |: T# x% G我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
4 M9 r) w) u! M就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
. G9 n( q2 M' z# v* a, o而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
9 K& Z/ T! r7 U用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通0 j& Y6 ?1 J2 E, l. H# e
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
' d8 r$ `+ w& N( d屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通" w$ T/ X+ J' K4 v
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
; B' f' G" M- F* Y$ G3 {上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid : p7 s4 a+ m7 o
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意, N& y+ o5 e* J7 c5 V
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
+ y) f" t" U+ g) J+ b6 K3 N经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们% E! f6 F) I- b2 \
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利9 [2 E9 p) c4 x
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
2 [5 [& n7 t4 n9 e1 |的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致5 f: t/ c* f9 O5 L/ f
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
3 h5 r: r4 ?; N. a8 ~根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
/ w( c' k7 ]$ ?% z& D见下面代码。! ?5 Y/ f/ x" l' H* j

  T3 E1 f8 c8 F这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程; k0 L* y+ h. b
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键; p6 g( E  s( ?( H, [* I
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003# Z$ W( |* e* J* ^4 \
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
6 y+ S* F: A. y完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
" A$ D7 H% t/ n继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
9 |0 b6 X; ]9 S* J1 p2 l1 S锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按, t0 k. g. s: v# |  n# v- k0 _3 J
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
6 F* N7 |+ i2 ~* _: D
' o  w! b+ ^  ?; [+ |/ R" V
$ R8 F' J9 L# ~完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
4 h0 B/ }1 `/ D- V; J0 \3 e的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是4 Y7 L/ i' @7 B5 Q9 H" {. p, d
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
! w* s9 G9 V  i+ P, @, r4 X( d: ^的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
. _( w' A+ n) T2 ?7 o2 P2 k们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我( d& |# u# X' H8 y
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension& d  B% ^7 V+ V3 {- Q1 ~$ l
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
' u% }3 i7 i4 K' a如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager( G6 X, f- d  [# Q+ X* q! A+ M
进行操作了。这个问题有待大家来完善了。
, ~' E+ g; C6 u% X
3 x2 A# E" F) c' O4 `: x5 V7 }$ P9 \1 P8 q- M' V
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
4 s/ M; |( a0 O) Y5 c5 d来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的& [) {9 `1 G4 c3 I& {
分析做个记录而已。我更愿意把它看做是一段注释。5 w+ R2 e4 _& D1 B2 B
8 J+ S' d$ g8 j7 U
最后在此代码中要
# l2 D# a' r# N: V- ^% K& d1 S5 r; E4 U& p9 Z% b4 ]4 H9 Q* }
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
( R' o( Q8 h1 m- [8 v) \( [/ G* \) a& L% I5 M# ]
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。' L. k3 t/ S# e3 L% t
. H! s1 U/ Z; F8 S, K& H1 q
感谢:齐佳佳,过节请我吃好吃的。
1 r; V1 o  {+ O# A
* E+ E  T& |4 L, P5 }7 t8 |. e. C& Z) E
******************************************************************/* f- F- z4 l( ^1 s8 {" O8 V

- x4 N! \: ^1 ?+ o6 g4 W
8 g/ L% D3 Y; t! e% s' {3 C) G% b! I/*****************************************************************- U5 G" {3 E" k# ?4 u
文件名        : WssLockKey.c& e; U  l& M$ ?
描述          : 键盘过滤驱动
) k6 Y9 O" v) G) @; X9 N9 A 作者          : sinister! o( E* T  D6 K9 o! g; V  A5 k' ?8 J
最后修改日期  : 2007-02-26* ?5 z' Y: Y- m1 l9 [# ]
*****************************************************************/+ F% h6 ^4 s9 V, W

: v3 b) N! M4 L0 d' O7 G. V/ }* c
) V/ V9 |' q4 _  m#include "WssLockKey.h"
& M6 b1 h2 W* I  C
4 n: c- _. V6 j4 Z, j- o$ ]NTSTATUS7 d$ d" C8 z- r
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
7 p* C* M' @. b4 r             IN PUNICODE_STRING RegistryPath )# _/ Q# S9 R. f) M" p& P
{6 j( x1 @0 r0 M  z
  UNICODE_STRING KeyDeviceName; 0 g# u2 h& u, |3 t) ^
  PDRIVER_OBJECT KeyDriver;
+ z' l$ c/ A. Q* f  PDEVICE_OBJECT UsbDeviceObject;
, K' v' e3 g; N! {( n6 U3 m" @  NTSTATUS ntStatus; , b8 i; a1 e7 v
  ULONG i;
# l- \+ ?; j# ?+ _) Y/ N2 f, D( r: u! x
/ Y9 u- ~, j; o& _; x# u9 @  //
$ ?2 H$ S2 G& g% u5 U- W0 h& J+ z8 s7 ?  // 保存设备名,调试使用
5 V3 J, V5 u9 {* l. X1 ^  j# X+ a2 x; H  //, V: r+ C) E* x, @9 F
  WCHAR szDeviceName[MAXLEN + MAXLEN] =3 E9 L( O( y9 n. T9 `- e/ j
  {
( I1 N% f2 T+ j: H# h& ~. D    0
8 r& P& }' c  x' B6 L+ f2 L. Y8 n) A  };. f: Z6 Q# o, v+ H8 F6 {
* B2 E2 i1 Q# {: M2 M
  KeyDriverObject->DriverUnload = KeyDriverUnload;
8 I# Z% _3 y9 {/ C5 h! v6 W% M. u, v% l1 a0 z6 f
  //8 V% e, M, [! B, v" {' Q
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘; G) y! Q! C; B
  //( a  y; l  k/ e4 U% S& Q! M+ j
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
1 x; v0 `% B% A3 }8 q  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
3 f) }7 Z5 I2 W& F2 }6 @! n  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到* g" p: b- U7 D% u% W4 S' y
  // USB 键盘设备来进行挂接* E6 D3 r3 F: ]% H  g& u9 S7 x
  //2 {$ z7 X! W1 f) d
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );" L8 F# d2 P' K7 S: K$ T
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL ): Q# P1 k, s6 A4 A, K' ^8 r
  {
/ Y; l+ L; A; r, W    //
- b/ d5 x9 L; D. \    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名" E8 @% e- H& Z3 Q3 D3 w
    // 所以这里打印为空+ k( v: M( y2 y$ Q3 e5 K
    //! u9 B8 ?* J7 s# y5 e- u, `4 X7 B
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD; G: j, {2 t8 U0 O2 L% |4 y
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );+ @) p  m9 ?; Y3 l

2 E/ U6 Z1 O( {9 Y% k4 _    //
1 X5 c8 b) }& b! N  N9 M8 p- ~7 j9 s    // 挂接 USB 键盘设备
9 A- \& W! `, R& A  O    //
# R8 g" L8 b: c/ L  W+ m! T' L    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
0 E$ _. V* j/ a2 W1 d    if ( !NT_SUCCESS( ntStatus ) )9 L8 A/ u: d8 Y( F. t2 Y- z! Z
    {. {1 j- ?5 ^. t
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );" O3 `" G( M5 y
      return STATUS_INSUFFICIENT_RESOURCES;! i* W' _: P5 m( B" _5 }* F# X
    }
% a$ d9 n  z3 b1 c  }$ a# b. t$ L7 Y! G* d; y2 P
  else
' p4 X" u0 q0 c  Q1 h9 k  {
9 {6 c1 s4 U0 ?# s6 m2 C    //" F# ?( U9 e: S
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
* W3 W* \. [* I0 G) c2 g    // " V( v, ]' R9 g$ t3 j4 A
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
! [& v9 A% o/ |* ^
: R8 i3 t) N; P* {% H' ~    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
1 |5 P8 \) x. x                                        KeyDriverObject,7 j# n: R" F: o4 X" o) [+ Y
                                        &KeyDriver );/ r. N. A: G0 k4 f* U; D: P
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
- K5 Q5 ?) X4 h    {
3 Y5 J- M7 q3 V, V1 ]      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
) a2 y; J3 u4 g6 C3 A- y      return STATUS_INSUFFICIENT_RESOURCES;
- N  t4 d: L3 l" {: A7 Q% D: N9 j    }6 x; G4 S" y3 F
  }
, h( [; R: z* g/ Z+ o
, m. X$ ^  e4 V7 x6 C  m6 P- b  //5 A  T% ^' d5 z  N) |  x7 w
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止0 E+ V1 s: u) W# J
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
5 k* h7 n1 y7 p8 P; c6 R  //  w6 p9 X* @3 ~3 U! A3 G. j
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; + E- B* O/ n( ~( x8 \
- q: V& n, |4 t! e3 F
  return STATUS_SUCCESS;
" |( Y- P( |/ M# v1 w} ( e. p8 Q& z  T' C8 d: I

! G( r" v! b* M, F0 [+ N4 q2 k/////////////////////////////////////////////////////////////////3 V; d* \& }. O
// 函数类型 : 系统函数; V1 _* u& k0 ^7 A% S" e
// 函数模块 : 键盘过滤模块
+ X  Q9 |( x7 j0 ]& O////////////////////////////////////////////////////////////////
: e9 Q& O0 k7 d// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
- X8 y7 ~% t3 L1 a" u% U% {//        卸载键盘过滤驱动9 M/ B$ A6 ?4 M/ r* Q
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
6 Y! H; `+ W9 p/ I//        则需要等待用户按键,以后有待完善" U+ T  [# T' G: a* Z/ W: `
/////////////////////////////////////////////////////////////////
' q8 [5 m/ z% D: l' Y; {6 h// 作者 : sinister
0 e' S9 K( ]" m" H// 发布版本 : 1.00.00
) ]& l7 V$ n! ~" s1 |& ]. y1 B// 发布日期 : 2005.12.27
/ }! s4 A& F" ^' T2 i/////////////////////////////////////////////////////////////////3 i' T3 _3 B% l3 V+ Q5 }* @$ l: K
// 重   大   修   改   历   史
. ]3 e2 ^( u2 K! r. G6 w5 y////////////////////////////////////////////////////////////////" t  P7 r/ c' I, r) H
// 修改者 :' T8 B% {: U. d2 V6 N3 ]
// 修改日期 :
  M* L. J, K# r2 Z- _// 修改内容 :
/ l/ Z+ k; n8 W/ w) K/////////////////////////////////////////////////////////////////
" a' o# `7 Y; A7 Q6 f4 ]9 t5 h, p. {, h- g5 o
VOID
6 \7 L& G- o" \( j3 E9 E% z- pKeyDriverUnload( PDRIVER_OBJECT KeyDriver )/ Q) ^6 X. @4 I2 r
{
2 K7 y/ ]! M* ], r: g3 i( ]$ G  PDEVICE_OBJECT KeyFilterDevice ;      
; n1 R- t7 b  z2 \  O  PDEVICE_OBJECT KeyDevice ;
+ W9 m) p1 Y$ m) }: ]  PDEVICE_EXTENSION KeyExtension;
4 h* g6 k( e+ w- R  d% E/ ]5 J+ {4 O' E# W  PIRP Irp;
. A; Q. q& ]0 i0 L. I1 J  E  NTSTATUS ntStatus;
3 Z9 @; F8 y+ D5 K# P, m* F2 j2 `
  P4 `( p1 t: o( g! n) V4 c  KeyFilterDevice = KeyDriver->DeviceObject; & B* ^6 X; p/ x& ^
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
+ B% o8 P! b0 ?* S  KeyDevice = KeyExtension->TargetDevice;
8 j( g; \6 |( Y8 ~5 ?* C) C0 D2 n6 p, F
  IoDetachDevice( KeyDevice ); * u8 k$ Y  {9 k6 y8 q; F4 U2 X

0 Y; W0 p, d6 y* a% s% d" ^! J, Q  //6 n8 X7 U* {! F& P, ]8 u; G  l
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP1 D9 L1 a6 y' w( s# H1 D/ |9 H
  //
! f  q0 U* x- v( ~$ D8 [  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
  |. F7 x, q' ]; t0 z  {) U+ F# i) O8 X% x" I1 T
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )( ?+ ?' z; ~7 V' A
    {& n) f. ?% P5 F  \) d
      //# X. V/ v- R3 _8 x. e2 D( l" k
      // 成功则直接退出删除键盘过滤设备
3 E! n8 V8 U0 p1 U3 \8 n0 u      //
: q4 }" X; P" c2 |& e* u  O      DbgPrint( "CancelKeyboardIrp() is ok\n" );
* N" F! x& v* R7 }      goto __End;' j/ \3 R( |3 p0 |4 c0 Z% x
    }; Y9 J% m! e# s8 d" E; v
  }4 r9 I2 z* M6 y2 x/ b1 C" N
8 q' ?7 V, P3 a% s
  //
" q0 {% O0 c5 l( Q( x0 y4 V  // 如果取消失败,则一直等待按键. n' s; S: k: @: M+ y7 A
  //# n, c! Z5 E: t0 N5 g' C
  while ( KeyExtension->IrpsInProgress > 0 ). w: S  q, _7 s# @, O0 z
  {9 M3 \& l9 M9 c5 ?5 [+ e
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );0 v$ K. Z: [) a9 o* m; Y) u; H
  }
9 [2 y, m. @4 {( z% J/ J- W% Q7 K, ?- `( _4 g
  __End:
3 R0 h- {) [. S9 |; w( x- J& G( F  IoDeleteDevice( KeyFilterDevice );
7 S0 x/ p# `$ `5 _+ }, S! s5 m$ }* K0 R. d" d, q) m7 W
  return ;
. `: t0 i4 M. ?% l* ^! S} , _- d1 f6 D; F* F
; \/ r) |1 {, r: z, R
/////////////////////////////////////////////////////////////////
" H6 H* }( r/ S5 j* B) M; O/ ~1 p// 函数类型 : 自定义工具函数
; j. r6 g" t) C5 I9 I// 函数模块 : 键盘过滤模块
" y( V* A' Q9 y  I1 n/////////////////////////////////////////////////////////////////
( H8 O- n$ h! d( y// 功能 : 取消 IRP 操作: o8 F+ W% A6 z  Z/ t2 E
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能8 P+ U, G# R! }
//        使用此方法来取消 IRP$ L$ {" Z. J2 f9 G. ?: p, v
/////////////////////////////////////////////////////////////////- f2 E  i3 I! I- k6 p
// 作者 : sinister& u- |1 T  R2 ?* U1 n: E. }4 i' K
// 发布版本 : 1.00.00; D# Z; v  Z+ t$ k$ R1 P; T
// 发布日期 : 2007.02.20$ e9 Y; z4 N8 }3 A5 \$ t; w& y
/////////////////////////////////////////////////////////////////8 s8 J. Z# `5 D$ I5 G$ p& C
// 重   大   修   改   历   史5 ]6 u/ T! k  t! X& H' A- b
/////////////////////////////////////////////////////////////////2 \2 X( w# ~# o
// 修改者 :
8 k# A/ C1 y( u// 修改日期 :
- ?3 k# y# z. o! g: ?1 l// 修改内容 :
  {* B2 e- Q' u9 n; L. k/////////////////////////////////////////////////////////////////
3 N; x  \' z0 q# h0 H. F0 E- t" r& {# P
BOOLEAN4 m$ C1 d# x3 G6 P9 ?! d- V$ k
CancelKeyboardIrp( IN PIRP Irp )( J. p  K" G- J+ @- e
{
8 `  O& ?$ O; G6 b" E8 k3 v, R  if ( Irp == NULL )
0 F; T: p  a* n/ X, O  {
3 l% |1 G$ X( x    DbgPrint( "CancelKeyboardIrp: Irp error\n" );% J* g2 A1 H% L9 S% R
    return FALSE;
5 B& k4 P/ j" j3 R( w3 q# \  }
1 f" }) i* w4 T! v* Q! K
  D% k1 H$ w6 T! I+ {
1 p1 ?/ ?' r. a. ?/ G6 B  //
# B% p* T$ ?* X7 V9 K" g  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
3 z  w* V' t, \& ?+ K  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
  m4 {' s4 [% u7 G  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占9 z3 G0 Z8 h# L6 W* A& d$ O1 C4 b$ N
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD5 ]/ y+ W+ L' K& X: l. E
  //6 F# H- z$ x! B" p( f, ]' h: t' [
+ ^  L4 c! Q$ q$ [% d% v
  //
  o* F' \# n, z; n' U" N3 |  // 如果正在取消或没有取消例程则直接返回 FALSE- V  K3 K$ v. R5 ?9 j
  //
0 H- X4 ?9 i' A9 F5 Z9 r1 P  if ( Irp->Cancel || Irp->CancelRoutine == NULL )5 M' `/ E- \/ K$ F; M; d7 x" ^1 I
  {
- _( ]7 g6 \) z- r    DbgPrint( "Can't Cancel the irp\n" );
8 h; U6 N) l& W1 B2 D! m" v, ^    return FALSE;
/ r! N/ }# [3 d% A8 u  }
8 m2 h: j) i" f0 O8 @% Z  N" v; M5 O6 Z2 O" c* u
  if ( FALSE == IoCancelIrp( Irp ) )
( e: a4 Q2 M& K; D  {3 c. ]' K: _9 k/ a0 T% m
    DbgPrint( "IoCancelIrp() to failed\n" );
- k( K& [; w7 C/ e( I( ]0 g) Z    return FALSE;& w' M/ j5 X  K1 ?& {
  }
; _% j: w3 w3 [5 n" `( f% e
7 G0 p/ @' c! q5 o% V* I  //
* F5 |& m* N6 W% T: n& X  // 取消后重设此例程为空9 g4 {  s7 r' Y% ~
  //
2 b( Z: l5 u- {6 I( T" x* B) p% h  IoSetCancelRoutine( Irp, NULL );6 L  B5 Z4 }6 v

3 A* k( C6 O7 v" N4 g  return TRUE;9 W, P( F) I/ Y5 {
}) ]0 J- p2 v# h' l6 \. u9 R

( V/ |4 t9 |6 i9 \/////////////////////////////////////////////////////////////////" a4 T& L: q( ]9 C( y; e
// 函数类型 : 自定义工具函数
+ D7 Y7 o1 c+ F+ y7 M. s! a// 函数模块 : 设备栈信息模块
; b0 H6 s4 p# c5 t( E6 W' e0 P/////////////////////////////////////////////////////////////////7 Q0 K# A8 u( a8 M/ q
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘$ i. P7 W. i2 ~% Q, f! X
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
! k% ~5 H) F5 S) ?, o1 d- |6 P! F// 注意 : 0 `) q, d" B- _
/////////////////////////////////////////////////////////////////2 z$ Q/ ?  y% M+ Z1 {1 D. S
// 作者 : sinister
3 |/ P9 x5 a* E: u# }2 J// 发布版本 : 1.00.007 R9 ^2 {9 K- o$ N+ [' D' O
// 发布日期 : 2005.06.02& V0 b/ X1 H1 t4 X2 f
/////////////////////////////////////////////////////////////////) f+ K6 M# J! y+ o# r6 {, t
// 重   大   修   改   历   史. l2 c( n9 U/ ^& g+ X2 r
/////////////////////////////////////////////////////////////////
2 z. O- @, A$ _' z/ B9 a$ s// 修改者 : sinister
: f( @" f; G1 Z3 [6 [// 修改日期 : 2007.2.12
: D+ B$ w2 Y3 L: I. U: b// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
. ^2 [$ I0 D7 J: ^4 I) R/////////////////////////////////////////////////////////////////8 [9 k1 S6 T/ Z: r" {

7 B/ ?1 {8 O- h0 I. M. m9 Z( TBOOLEAN
' M+ l: [) l; n6 _GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
$ ~1 y! m, C' m, X( v) I. h{$ O- K! k1 x# b# O8 V, z
  PDEVICE_OBJECT DeviceObject;
; J. y/ e3 B/ {) V& p0 P  BOOLEAN bFound = FALSE;3 A! i9 U" F$ G3 f; G: P

0 Y6 w( |/ C5 H- B5 t. f  if ( DevObj == NULL )
3 M% X. B6 k$ a2 n+ T" y2 n+ K; ?( X$ Y  {
( x$ p6 v" n* R' ?5 }0 l    DbgPrint( "DevObj is NULL!\n" );
$ k# ^9 c, M9 a& d3 _) Z0 w+ u    return FALSE;
6 A$ N3 A1 t! n7 n  N6 b7 F  }
# {- e  x3 D" z  }4 U$ {( W# x; L/ r3 B4 p; }: x
  DeviceObject = DevObj->AttachedDevice;  J0 `* ~& x7 a, e* C
" T" h& |7 x; Z
  while ( DeviceObject )" R8 f+ v7 y7 Q2 P
  {! i; `* [' f0 w' O2 ?5 @5 n  E0 Z2 N5 n- y
    //
( G* q$ E4 F: g7 p6 S    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
, J* _8 c$ d+ h7 d4 h+ Q& w    // 有一次足够了。这算是经验之谈
* w6 h- v* k1 A$ G    //
2 l7 j" H4 X+ _& e    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )) `" c0 {7 v# v
    {: S$ i! y2 a: J3 Z
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n"," i' D& v4 O  {2 |8 W# e. n% M, _
                DeviceObject->DriverObject->DriverName.Buffer,
6 Z; t- j2 w  r                DeviceObject->DriverObject,* c; f. L8 R% i
                DeviceObject );
# r' M/ e+ T3 N! ?3 s0 O# {( n8 S2 n3 L' j
      //8 v, l0 t9 \7 t+ E: t; M8 p6 _. Y
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
; [" T) V4 U7 X/ _5 R/ E      //
# a' o3 M: h- x  A. Q2 B      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
/ y0 h& K; d" [6 ]; r5 J                      KDBDEVICENAME,
" m! T- V5 F8 |7 `) T2 `                      wcslen( KDBDEVICENAME ) ) == 0 )
. \) w$ P- X5 J: w      {
" x" |/ [( T$ |        DbgPrint( "Found kbdhid Device\n" );
/ `  t3 M+ c& W& K        bFound = TRUE;/ l' M% k1 P& O3 ]. O# a
        break;& r4 D2 a2 U  l* l, ]! n5 z+ A
      }
8 [- a) H9 M9 ~6 P/ h; M+ h3 f    }
+ V* ^9 Z/ S1 ]2 t- S( G- Z0 B$ V3 _7 R. d# u) j4 ]8 k' t
    DeviceObject = DeviceObject->AttachedDevice;! M& V6 L- d. {0 E/ M+ D
  }/ d. K2 u' |2 `8 G* u, v

# w. a2 M5 `8 q& g8 N7 |  return bFound;; \* i5 `0 E! i9 q1 `8 d! w5 C
}
, L! Z7 Q! w0 G8 M1 c
! s( o1 D/ I  L$ ]. _/ k1 C; `9 a) ]/////////////////////////////////////////////////////////////////  T; g+ z3 i9 ^/ [) g5 _1 w  Z) X# `
// 函数类型 : 自定义工具函数0 V2 C% ]( B' a7 O
// 函数模块 : 设备栈信息模块
7 `, [& I$ c( l$ x2 B+ p/////////////////////////////////////////////////////////////////
) W( g2 D/ h, e4 g" M// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址$ h! ]. X, V0 S. W
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
0 q7 C3 y" M3 R0 V7 }' R* b3 N) H/////////////////////////////////////////////////////////////////3 `! a' ]0 g; l
// 作者 : sinister. W$ w& |! y" i* K. |1 I
// 发布版本 : 1.00.00! G, M/ M+ s" w0 e0 P5 A+ z/ E3 u
// 发布日期 : 2006.05.02
( l- ?9 ?  Q9 X: U" x/ @) Q6 Q////////////////////////////////////////////////////////////////// r* m: r4 Z( }. D6 N$ \. V
// 重   大   修   改   历   史. }3 w% T' n" F
/////////////////////////////////////////////////////////////////
% L  S/ y: V& N! ]// 修改者 : sinister
" n6 _  q( g9 n4 d9 ?// 修改日期 : 2007.2.128 m$ l5 y: {' x
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用  E* k4 I7 a, L
/////////////////////////////////////////////////////////////////4 {' U8 x) c: @1 a! u/ e; \7 f
# y2 g8 O, Q# z3 M4 {
VOID8 b4 l# s7 M; }% n
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
6 ]# h1 |4 T3 {. ^- X- C( L{+ e& I& N8 u) P9 i9 J$ K. P' s3 d
  POBJECT_HEADER ObjectHeader;
7 P0 w" c: b1 `6 U( }  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+ d: G& p3 z! k0 @8 D
0 n" W, w# n" `( X, B+ O  if ( DevObj == NULL )
% ~8 u3 n5 S" o  {
( ~6 Z. R# j: |    DbgPrint( "DevObj is NULL!\n" );  b5 |9 ^) y( a- k" w
    return;
0 d* v- i7 b3 V' a4 o  }
9 l- B" e' X7 p( O9 V! M3 W3 u" g& l
  //- n9 M+ \! |/ m- w( g' [9 I2 c
  // 得到对象头
- n$ `+ F) D/ l0 Q8 c/ _, C( b3 m  //. U+ W0 f8 }0 E- l  n1 Q% U
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
% z6 Y% j' w- `6 i2 y6 b8 u% R; W, z
" l6 R; ?4 ?! f. D7 {6 e' z+ P  if ( ObjectHeader )* l/ c; O) H$ G; w; ~5 t8 U+ F# r
  {! m1 G4 s2 [! O. O* o
    //3 p) D$ t' @. |6 c+ q* q
    // 查询设备名称并打印
5 w) E# Y4 s5 M& T: m. x7 H    //. h+ I9 g. Z+ t$ |- S" C
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );2 j+ u& L, b7 n3 K+ j* l

8 M7 Z6 g2 ?) y    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
! A) P& S2 |" J/ l- I    {
# h% B) o" b( L      DbgPrint( "Device Name:%S - Device Address:0x%x\n",7 @5 W/ B5 Q, \/ R, T
                ObjectNameInfo->Name.Buffer,
4 ?3 D4 \: `6 q1 ]! P& |- w% b                DevObj );; v! y% ~3 h! g/ c& R7 @7 t

8 p6 L8 b9 A1 S& r      //8 ^/ H) s/ g) h" K0 }7 J: \# U! d
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
; S* D' _* B3 L+ _' r% q      // 用,没有实际的功能用途
3 s7 G" z1 ?4 C) D1 U/ P- ?      //) \3 D' p4 I. L; k' M
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
/ U5 Y  [6 }/ U" j7 t' Y; J9 E7 @) X( G  M
      wcsncpy( szUsbDeviceName,, S% o* _) _& f  P
               ObjectNameInfo->Name.Buffer,8 V/ h1 k; o2 b2 `- P$ `/ H) s: s$ T
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );$ k6 ?9 d) y2 @, z
    }$ m- d% m$ o8 v( h

( Q2 o8 n0 ^3 d    //
) n: R" e' i) ?    // 对于没有名称的设备,则打印 NULL
) s. ^7 ]" t/ I: {/ ~8 L    //% P- i  r3 V9 l. e5 A% L& ?3 ]
    else if ( DevObj->DriverObject )4 U9 e5 ~% I% T( z  d
    {! ?$ [: l! @, G! y
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
; H: [! c& R* v+ f  O& W                DevObj->DriverObject->DriverName.Buffer,4 X* a$ P$ Y8 f1 V" o
                L"NULL",
" v6 `% n+ x$ e/ O  _4 q; b                DevObj->DriverObject,
0 q3 G& ]% e- _4 [% g* b                DevObj );! j" g1 \4 ~" d' J
    }- q! G7 t- o9 h5 X# L  G( o
  }' q) R" L* {$ ^1 G! d
}5 L) Y" L& W( ?% r' m

, Z* u% U9 e; y  e6 J% p- l& _/////////////////////////////////////////////////////////////////
* H* P' z" M, X1 \: x3 Y8 \1 P// 函数类型 : 自定义工具函数
, {  V" m3 d. N8 [+ j, `// 函数模块 : 键盘过滤模块& P: E$ p, H4 p
/////////////////////////////////////////////////////////////////
: Q5 o  T5 c0 e// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
8 y7 h- \$ \, J# r9 u% z( r7 S. q//        对象,过滤出 USB 键盘设备,将其设备对象返回0 U9 [+ C( G1 F, q' c! R9 Q  o
// 注意 : 3 W  J8 n& I* M0 \4 f
/////////////////////////////////////////////////////////////////4 o: l# ]0 d' u; f
// 作者 : sinister2 H5 |) G/ n7 x% _; J' e
// 发布版本 : 1.00.00
: D& z/ ^4 K# r+ x( F/ Q  b// 发布日期 : 2007.02.13! D8 v) {6 G8 W8 d
/////////////////////////////////////////////////////////////////1 K& S/ p' |( C
// 重   大   修   改   历   史
. x0 z1 ?! F+ M& t/ }/////////////////////////////////////////////////////////////////# ?, t2 h( @/ i0 Z2 y# n8 h$ e* \
// 修改者 : 5 \# H( i8 {, e/ Q0 j, m& d" v
// 修改日期 : 9 R. y& x5 e7 _7 |3 X* C
// 修改内容 :
, M& A2 G6 t. A6 C/ L6 u/////////////////////////////////////////////////////////////////  a2 }) u; l3 v9 o

, j+ i& M4 j& `  PNTSTATUS
* U$ L1 Y6 z9 j( P) r0 OGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
7 @! g- q/ n  ~{9 q; `8 ?" ^4 R% \5 K% Z9 k
  UNICODE_STRING DriverName;
1 G! O! {7 F! ^0 Z2 c3 ]  PDRIVER_OBJECT DriverObject = NULL;7 ]4 j+ f" q" Q# T  o
  PDEVICE_OBJECT DeviceObject = NULL;
0 q, ^" u, ]( Z+ h8 V: g  BOOLEAN bFound = FALSE;& g' h3 J* {) A; D6 @- c

" ^0 F* [9 C! d- q  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
) T* E1 i) A; W  o# i
8 q1 ^1 f5 _7 b$ b( a4 q. `4 g  ObReferenceObjectByName( &DriverName,% `; e# J- o6 M- i) k; D; [3 L
                           OBJ_CASE_INSENSITIVE,2 v! J, c" E0 ]% W" f
                           NULL,
- C6 Q' m0 B9 O2 G/ W1 m+ i- p                           0,
, x2 l) Z/ U& M. a' K* }                           ( POBJECT_TYPE ) IoDriverObjectType,
& A. l( \  k& a! z% l                           KernelMode,- q/ z; w# b9 }, {: ~7 W( t8 q
                           NULL,7 s; m* P( x; D, p1 K( M- }: p
                           &DriverObject );" P9 _6 g" c* a

: [' \! n  S1 \& }$ U/ S& H- N  if ( DriverObject == NULL )3 n! a+ c& u1 p" w
  {1 |+ D& Q1 i$ D7 Y: }$ ^* h: f
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
! G4 c" H) M1 D; O    return STATUS_UNSUCCESSFUL;
6 E; {2 K( y, @2 g4 I( g8 g, Y  }
# u1 {6 ?5 Q9 G3 k5 ?& m$ q9 W$ R4 y; j% L* r9 k% J$ |
  DeviceObject = DriverObject->DeviceObject;. S, m+ r9 W: r% X

& v  W% I6 F- E! ~  while ( DeviceObject )3 V# b3 P- u: A& t8 u
  {
! ~6 z4 o! [3 G- x+ p    GetDeviceObjectInfo( DeviceObject );
9 g+ ^7 O( w8 |& H# m( m" x5 ]; R) [3 R8 M% o* M
    if ( DeviceObject->AttachedDevice )
5 _( t$ R+ ^/ t& @1 z* Z( \. X: k; Q    {( R( R  n' E7 G3 a; b, i: i. q
      //
  n  `0 ?3 H7 P. c# T      // 查找 USB 键盘设备
! m! `5 U6 ~" B% _      //! ]2 W# h6 H5 }8 z
      if ( GetAttachedDeviceInfo( DeviceObject ) )
8 n& G& u" b" G" O/ v1 c      {3 ^3 z6 o0 h) R( d& B0 |: W
        bFound = TRUE;
3 Y) w7 k2 P0 G. y1 r        goto __End;+ D$ l( l, N+ s8 X0 ]
      }
5 H$ O; H5 s7 X: k7 }    }. \4 D: {" U, X4 r" Q3 t, M  K
" r" h% @% ?, B7 K
    DeviceObject = DeviceObject->NextDevice;; t7 L& W0 L5 ]2 T7 ?
  }4 Z3 c5 J; Q' N, u
8 U- j# A7 N/ G+ h
  __End:- f' W: ]4 ?0 u

: W8 ^- \! i3 K& j" S4 }0 L3 Q  if ( bFound )& l; M  I9 R7 X/ q. F0 j! `
  {
# g7 H  [& f2 q6 J, D/ L! G    //
- o, f  h, ^& s1 l    // 找到则返回 USB 键盘设备对象
) ]8 N9 t* B5 ^0 {  B    //( P0 Z( \( n2 C
    *UsbDeviceObject = DeviceObject;
) u0 {- C  E# I! n& I7 \. K3 C7 d  }
) j1 W  r. z% e5 z6 V; o! k: Q6 @  else
* a2 m/ N, G! h. z" r  {
$ A2 E2 t, P" p1 Q5 p3 X    *UsbDeviceObject = NULL;
8 q; }: \3 Y! R2 f5 b  }
* ^% ?4 n1 _- S3 y* z  e! C6 X1 A2 H7 J, h3 K" c* P
  return STATUS_SUCCESS;3 K- A7 {2 l, O7 d3 O9 f: z! ^
}
1 P: K8 n* X' P: @  I; ]& N- n! K5 p* L. Z+ |' \7 z
/////////////////////////////////////////////////////////////////
( G7 o! y- t8 L/ \/ q7 v// 函数类型 : 自定义工具函数, t4 F' B( }+ N, N8 l, ~+ \9 Y
// 函数模块 : 键盘过滤模块
7 Z% I. {4 H- u////////////////////////////////////////////////////////////////
! L- g% f& T3 Q* L9 L+ o* E// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
, k9 W- v6 [- p) {% G2 O" `% r//        信息,返回附加后的驱动对象
' W2 f5 D5 ]) d% x9 a// 注意 : 此函数仅挂接 USB 键盘设备
5 W6 p) C7 v% Y8 m% S) _8 j/////////////////////////////////////////////////////////////////
' @  [5 A- [5 }: O// 作者 : sinister5 C  `; `5 g* C. M
// 发布版本 : 1.00.00, ]/ G' E* Y! ?$ r! g/ y
// 发布日期 : 2005.12.27
' D% {% c7 o& {4 Y/////////////////////////////////////////////////////////////////
7 Y2 A2 q: R/ f' D* }// 重   大   修   改   历   史! L5 h; I1 h4 P7 D( Y
////////////////////////////////////////////////////////////////* T9 O1 I( x1 ~5 c$ ]+ W) g3 `
// 修改者 :
4 y7 e+ x+ [$ b1 u3 |// 修改日期 :$ x/ _) M+ m1 C3 O7 e. Q  b
// 修改内容 :6 V" I" o- x; w2 w( D
/////////////////////////////////////////////////////////////////6 e2 F$ S/ r/ Y0 Y
4 V8 p/ n: u! e  r% w- w! ]8 L: _
NTSTATUS
. C! l1 }8 O* U! D3 k$ T, Y7 e) WAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,' u) G5 Z; U3 W" ?4 O8 F6 u
                         IN PDRIVER_OBJECT  DriverObject )5 q/ Y& g0 s' B' E
{
& ?0 H& I2 H+ L+ E" f& O0 k) y5 r  w  PDEVICE_OBJECT DeviceObject;
  M% H+ R/ ~/ w" e& W  PDEVICE_OBJECT TargetDevice;
* }7 I1 A( z2 }4 _" T+ D  PDEVICE_EXTENSION DevExt;
( u" W5 @. @3 p5 M5 |& x  NTSTATUS ntStatus;
+ Y2 m2 L+ D& d! r: I- y4 T
, m  L( {; r: e  //
9 H# y2 k2 k: |' G1 d  // 创建过滤设备对象
8 l" k, A7 p! c. l  b' {  //+ X  o" d) _# U4 {. a2 |
  ntStatus = IoCreateDevice( DriverObject,
5 n( u5 e  R8 \! j( g2 |$ d                             sizeof( DEVICE_EXTENSION ),
" s* N* ^( X; w8 l                             NULL," U2 u* H2 m. r, g, v
                             FILE_DEVICE_UNKNOWN,
7 {& a0 r4 k7 s! K" o                             0,9 L. r3 f6 r) u, q' ?3 H4 z) W
                             FALSE,0 @2 r) y/ t. m) ^
                             &DeviceObject ); 6 A: V1 P0 C" @6 q5 T  g8 Q% I
: V  q* r) r* ?" \' u& n- ?, n3 ~+ Y3 Z
  if ( !NT_SUCCESS( ntStatus ) )
  \" w" S/ O' `, ?: W) C  {* N6 N) b  n, d. j. d
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
+ C) n0 M. B# s. F2 H2 T    return ntStatus;
8 [( E3 W2 d: |* a, o# k1 b  } & G, v" H2 N5 C9 [9 v* g6 T" C: }! U

: h* l6 C+ S6 w' b$ V# g  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
6 Y% z8 b4 H6 K7 ?/ U. K# c
8 y9 v5 u& \, a3 r. K  //; V) B) W& D  J: x1 F' E
  // 初始化自旋锁
( U% A8 b9 f9 r5 t1 O' [7 `  //
0 ^' Q1 _$ {8 T" e& J6 j  KeInitializeSpinLock( &DevExt->SpinLock );- y* U9 J0 c" C* _2 X) u

" Z- z& E/ I; j2 [' N  //
' j9 h: T0 ~/ D* b- Q- U( a  // 初始化 IRP 计数器
6 X: \2 E% g) @5 U+ o, G  //: ]  y! E, M) v' b/ S+ E) a  i5 _
  DevExt->IrpsInProgress = 0;
4 D4 n  F! @, t: X& e: O+ `3 A4 O1 p
  H- k) N# p( M/ d5 {1 S  //
6 X; v0 h0 Y6 O: k* b6 |  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
/ |; B# R/ P3 Q8 B  //7 c7 R; J9 M- @& P

- [/ Q3 ^; M  C5 i6 |  H  E  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 4 N% f" t  y1 d! ?8 x  n5 n6 I1 O" }
  if ( !TargetDevice )# @. g5 z& H4 ~4 \
  {
* ~+ g# O0 p5 t* Z) C0 w- [! {    IoDeleteDevice( DeviceObject );
4 X- ~2 e  J0 A: U1 w/ f    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
- W9 }; x7 M; Z8 q1 m    return STATUS_INSUFFICIENT_RESOURCES;
4 c/ y* R- B' D8 z  }
  P' d' w( Z2 q& @% {. R# |. b( a% p9 {: v4 f3 H
  //- p1 }; t+ V  M8 J. N, |, D; k
  // 保存过滤设备信息! E& i, q. Z1 q6 J3 Q
  //
" t0 {) _7 l- r" g* ?  DevExt->DeviceObject = DeviceObject;
$ y; W5 q* x0 J8 H  DevExt->TargetDevice = TargetDevice;  z' m0 O, K% `8 H$ E; i

6 N0 b9 B; A( e$ W$ m6 `7 P  //1 s  @- b6 A1 M* {+ X1 C5 Y7 O5 D
  // 设置过滤设备相关信息与标志! c' h& U/ A! e8 ]
  //' h1 D" v2 ]% A
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );  W* I, S$ w/ F  ]$ Y
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;' I2 m2 p, w. ~- `/ k: M
6 j: g- h, ]( X& d0 R/ c& Q
! M$ ?2 [+ C. ?0 {
  return STATUS_SUCCESS;8 d# ~6 Y* B* K8 `- G0 D% J2 U
}
+ M# @! U" I. e
6 U$ _; L4 D  Z+ j) W; j' f( j, A/////////////////////////////////////////////////////////////////
5 [: M4 V5 ]1 m, K// 函数类型 : 自定义工具函数
" C; y9 X* W/ {, `// 函数模块 : 键盘过滤模块
; \9 b& r/ q* U////////////////////////////////////////////////////////////////* {1 G/ ^; X1 l+ |& k( U) _
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
7 k/ H. E9 C! V//        信息,返回附加后的驱动对象
5 E! n! d8 J/ C/ v+ t// 注意 : 此函数仅挂接 PS/2 键盘设备6 |3 [1 k, A8 k* n6 t
/////////////////////////////////////////////////////////////////
+ ^3 h% v3 n6 O. C4 q4 {// 作者 : sinister& F) {4 X+ ?9 t- `/ a
// 发布版本 : 1.00.00
( w2 K, T  X: N7 ?// 发布日期 : 2005.12.27
6 T2 U0 i& F+ F* r5 \! I/ G: l, y/////////////////////////////////////////////////////////////////- {1 Y6 q$ N- U. |0 u
// 重   大   修   改   历   史! I& @: ?: h! J+ `7 ~$ J
////////////////////////////////////////////////////////////////! b0 z+ g# R- I; d. c  g) K
// 修改者 :
, f: i6 V( a4 s6 C$ M$ |- @// 修改日期 :
4 `% f! s# ~/ I2 P( q7 `// 修改内容 :: O% u/ m5 Y% x1 S9 a/ q$ t8 M
/////////////////////////////////////////////////////////////////
  F8 g5 ~: Z0 ~6 F$ N! t, t9 I$ Y* M! _
NTSTATUS8 L8 p2 F" I/ v3 a. K2 {
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名3 k% Z1 _1 n+ t, a! Q2 J0 T) E8 J
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象/ d) f: E8 k; g; w  T4 c% }$ y
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象( y3 R9 \9 p( b. `  c) G
{9 C$ L; I0 }3 [; v# Q! B
  PDEVICE_OBJECT DeviceObject; 0 o  N3 N4 ]8 m7 O& X
  PDEVICE_OBJECT FilterDeviceObject;: E# ^6 D1 p/ p3 r3 w/ p
  PDEVICE_OBJECT TargetDevice;
( P7 r0 y; y( H0 e- c  PFILE_OBJECT FileObject;
+ ?' x: o! W/ ^" l  PDEVICE_EXTENSION DevExt;
* M+ D/ n% [; N% {/ d0 e3 k0 e/ F% V  ~) B
  NTSTATUS ntStatus;
5 [2 H" P5 \1 k4 S6 r1 `$ V3 L2 }- F9 u/ n6 n$ J, c5 Y& G
  //
/ D0 d& ?% u% {& r* [) U; R  // 根据设备名称找到需要附加的设备对象& E6 _3 h! t" {) b8 c+ @
  //
  m6 a; G, ~3 F, g/ i. k  ntStatus = IoGetDeviceObjectPointer( DeviceName,0 N9 K6 ?( f' K$ `
                                       FILE_ALL_ACCESS,; k: q% L' r& {5 S3 S
                                       &FileObject,
$ L; Z6 L# L- Y8 G8 W                                       &DeviceObject );
& G% i4 @5 s3 U
+ F# n2 X* l5 N( Q  P/ I  if ( !NT_SUCCESS( ntStatus ) )1 [* M5 f# ]/ X8 G2 l. V
  {
6 f0 g& l8 Y3 d1 u9 @* d/ U# G" w/ w    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );& s0 u# t/ T/ w% m. ?
    return ntStatus;
9 y8 r6 C5 ]$ X% D" D  }   Z, g1 x& i) U% S1 J6 c& b0 t
, d, {3 d3 w7 u, E- t5 [
  //* r  K* H+ l3 S2 R5 G& D! [
  // 创建过滤设备对象
  o1 u. V/ w& `  //
( [6 o" `9 L: L- u4 j  ntStatus = IoCreateDevice( DriverObject,
$ C! d" A7 i( N3 ?: c! ~0 K                             sizeof( DEVICE_EXTENSION ),8 }) `: Z+ p! r: N
                             NULL,4 w" n; p1 J+ F2 k" s& V
                             FILE_DEVICE_KEYBOARD,
. w, v! L7 [1 s- ?) r                             0,
, m+ L# U  e+ \2 P3 }9 Y                             FALSE,- q. q8 |4 y8 X7 R; ~9 l$ F
                             &FilterDeviceObject ); 3 P* \' _" a: ^9 W- F/ F

( ~% I8 _! r* h) d- n% Q9 B  if ( !NT_SUCCESS( ntStatus ) )
0 f5 m; |$ J% q4 p/ L  {
7 C+ x1 _+ _0 [5 }& @" p) T6 Q8 x    ObDereferenceObject( FileObject );
) Y- j. \2 B" V) u' L3 T1 N    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );7 h4 `: H+ |" ?' H& |- T  p: e% v
    return ntStatus;* J# a( A# v! f& W. Y/ h! q
  } $ p  I2 P8 j8 B/ [. y

! {3 o7 W0 K3 Y4 K1 M  //
2 ~: i& H4 `6 y: ]9 S  // 得到设备扩展结构,以便下面保存过滤设备信息: L" J% V5 U8 A# }* A  V- b
  //, t. [6 u( ]9 x; Z$ r& a
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
2 }6 y3 p4 t% }) [9 W9 y0 f: G0 u
3 Z- _( S2 z6 T% z9 z
  //  l4 z/ R% `! l0 G
  // 初始化自旋锁$ h, i! K" G% v
  //
% g6 }6 N+ j, f0 X2 a  KeInitializeSpinLock( &DevExt->SpinLock );
& n0 Z4 m9 g: x; V3 [4 D( G
/ s! Y8 _, e! @- @/ D  //
  u4 X* e$ C' F" m! B; o  A  // 初始化 IRP 计数器3 s+ |, b( ?& T: a- E9 _
  //. p1 Z3 a. f9 j8 w- i
  DevExt->IrpsInProgress = 0;
  b1 ?6 w9 _% N8 b& ~3 D5 m2 h2 s+ l  w! w! f1 K+ T
  //
5 F2 Z$ V+ L+ E4 K  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
: G3 T* m! A& q2 S7 P! J8 k9 ?+ Y  //5 `' i, M/ f8 Q; P& B
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
0 A: F+ e- M, ^' s( p- ^                                              DeviceObject ); 6 v* I: f, s$ ?5 C6 H
  if ( !TargetDevice )# f: E4 T2 ]& B, i
  {' h3 w$ O$ V8 n$ B8 }# H
    ObDereferenceObject( FileObject ); 7 Y9 C3 x( Q% _2 E! d  N4 ?
    IoDeleteDevice( FilterDeviceObject ); 0 R* v5 `, D. m1 m! h3 q( J
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
. a' _; A( A! h" q8 A    return STATUS_INSUFFICIENT_RESOURCES;
% V. ]9 R& M+ E( ~$ j/ A; j  }
+ w! I, y$ x( X. ~" y
0 Y' z8 j* b* v4 l$ R  //% Y) m& R; B/ I% j/ M* u
  // 保存过滤设备信息
- v6 M- l' k# i. `  //
, x1 n6 m1 [% M0 ?4 O  DevExt->DeviceObject = FilterDeviceObject;
4 g9 t; e' f5 G5 R  DevExt->TargetDevice = TargetDevice; - {2 O# z2 c! f% b
  DevExt->pFilterFileObject = FileObject;5 S8 V# P+ Q/ A: o+ A1 t/ ~4 U$ f& S
) L  `9 t  P1 o" c3 }6 b- G7 N$ {
  //- n6 Q6 b7 E$ b# v7 l' g( t* e4 q5 J
  // 设置过滤设备相关信息与标志
7 F, m& l. ~0 I2 l  //9 g. F, s5 `' s0 F0 `- x# }2 g% v
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
$ b/ a. g2 U! @  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 6 p+ [+ |0 Q) l' a7 E- ?  _6 d
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;6 r& P- r# ]. i! h$ p- A8 Z
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
( a1 c1 U$ x5 w                                                         DO_BUFFERED_IO ) );
4 z8 n# c1 K/ ~) _5 A# U  c' D- x, {2 z. |8 A! V2 Y# W: ^" S
  //
6 m! K9 m0 E/ j) B* Y  J3 k5 i  // 返回附加后的驱动对象
7 g& {: s. L6 |" H* l  //
( M" S3 f: Q. f# o" J6 D: d" o  *FilterDriverObject = TargetDevice->DriverObject;
: X4 w: m! ]- Z# p2 r6 k5 l2 Y2 F/ E' q: s" d: @6 L2 R3 D
  ObDereferenceObject( FileObject ); 1 C* c7 c7 V6 ~# P2 U

9 _3 x  `7 x2 K8 f: T  return STATUS_SUCCESS;
2 D. I5 a" N& Y( d% K}
( V3 L% y0 ]0 E. O* M8 H) A  k! a( Q! u2 J
/////////////////////////////////////////////////////////////////
; X2 Q# j" T- r9 W! y% n// 函数类型 : 自定义工具函数! D8 A  t8 s$ t+ u/ @6 A' D& s8 b
// 函数模块 : 键盘过滤模块
- {( s+ N5 \+ |# v" S////////////////////////////////////////////////////////////////0 ?$ t2 T+ O  Y* `* I4 M
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发7 W: h  y/ O2 o5 |& G: \( V
//        这个 IRP 的完成- l# R0 v) S$ g: Q# B/ u- T
// 注意 :
- J( n0 i6 W3 U  A" c/ o3 Q) t/ K; s/////////////////////////////////////////////////////////////////% ]) x2 ]/ v. [/ S
// 作者 : sinister
. Z1 Q: V# s  [! `// 发布版本 : 1.00.00. D2 t- f- ~" W6 O1 m9 _
// 发布日期 : 2007.2.155 J  {8 ]& Y$ M6 a* s
/////////////////////////////////////////////////////////////////
) I  f/ g, u. T; {2 U3 Y" O+ C& A// 重   大   修   改   历   史
; ?$ A' r( u7 O7 r; N% c////////////////////////////////////////////////////////////////& ~$ l: j# l7 y
// 修改者 :
% K( X0 M  h+ @- G9 |* x) u// 修改日期 :
8 A5 Y% h. u9 P' X# R; v5 C3 g; W// 修改内容 :
  j) i6 e- U% R# i5 s1 {1 G/////////////////////////////////////////////////////////////////
( `# x/ G# ^7 t3 H9 H, J  z8 n! C* I. f! u5 X0 V  Q, @
NTSTATUS
; v9 A' d$ I7 E. l: O+ iKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
5 V% x$ L' D2 W8 Z9 L3 C: U# l{
3 I# g' c, O8 n3 @4 {5 n1 G; o3 G( p  NTSTATUS status; 3 e+ {; M) {: U5 R
  KIRQL IrqLevel;% k$ Q5 ?4 g8 [+ i% [
+ ~! M9 X" q" d( _
  PDEVICE_OBJECT pDeviceObject;
" M4 B# R# n) w) i  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION ); H2 }( P* m5 K7 f4 t
                                   DeviceObject->DeviceExtension; 2 r' B2 T% y$ T  y2 g" b( g& M9 l, ^

1 l* g% o; b3 O  y' N
$ s; Y) I' d% k, h  IoCopyCurrentIrpStackLocationToNext( Irp );
, n* {9 Q; r, j1 o7 {8 P" V! Z7 J3 N
  //
8 O, N; c$ P. B% B! K  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
9 p0 i; p9 v" i) w" D; W, S% |' v( A, o7 G  //
2 N0 W3 N8 T( N+ a# o  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );/ I; z; O' y0 T3 k9 j! q  b. k
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
3 P" O/ D0 W) `5 T$ E/ Q4 l# Z  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );0 T2 I! k$ S! [  A5 N' P3 W

9 t0 x4 H8 Q0 p4 B  IoSetCompletionRoutine( Irp,
$ V5 y% a5 [/ }                          KeyReadCompletion,
8 Z- @# g8 C% i, P) n8 f                          DeviceObject,
2 Y  ]. h1 K$ a5 |( G                          TRUE,' `0 j, O4 `4 g5 w  F
                          TRUE,* z8 @) s1 M6 U2 S4 k" A  i
                          TRUE );
% h% p3 A1 B8 G. }+ ]+ Q* d/ S9 u5 G0 X/ x, X! X
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
6 B5 D) x( a/ d9 N! j} ) ^; T3 b2 R$ e+ Q4 n) X& F
# d& s  L7 W& C  y
/////////////////////////////////////////////////////////////////: T7 v  ~8 m% r* K
// 函数类型 :系统回调函数
3 h+ Z7 \, o6 Y& g' R( g4 E+ Q$ B// 函数模块 : 键盘过滤模块# O. s% r" q) v6 D6 L
////////////////////////////////////////////////////////////////
# ?; m# N5 o& P+ f5 U( ]// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的- @* S, z' m1 E& \' K, g
// 注意 :
7 S8 ?' u2 F) M* E. B/////////////////////////////////////////////////////////////////  p& S& k$ N, _- B
// 作者 : sinister
: U9 A+ n/ u- ?" I" v! P; i// 发布版本 : 1.00.00; K& f: c# j8 f
// 发布日期 : 2007.2.12
$ a  ~% \% P! L- m. D0 P( C/////////////////////////////////////////////////////////////////
2 o% Z0 B& i5 p9 _// 重   大   修   改   历   史
3 V6 G* `$ s4 D! l, D////////////////////////////////////////////////////////////////
# a) Y/ M' y; y  g// 修改者 :
$ n0 |) g( j9 @5 z" y2 h// 修改日期 :, D8 d  Y; C7 W9 z" T7 O
// 修改内容 :
  x. x5 i, a) m$ k/ r% C- v  B  [8 l/////////////////////////////////////////////////////////////////
0 ~9 L. p6 I: r% v, l2 m/ r& M& V6 c
NTSTATUS
$ \: S. T7 i* R- n8 T6 EKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,2 h/ E& t9 Z' w' s6 v& S' t3 D
                   IN PIRP Irp,9 D% P$ m% G* i9 q
                   IN PVOID Context )- B. X2 ^' E3 a+ d2 I
{
6 X( S8 e" Q2 |4 ^" b( k" M  PIO_STACK_LOCATION IrpSp;
) Y* C4 j2 X: G0 m! l  PKEYBOARD_INPUT_DATA KeyData;
8 Q5 l% U& T# B7 ?6 O  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
, ~, H/ ^& V8 c7 y% m: H3 c                                   DeviceObject->DeviceExtension;
, Q) Z& J# h7 o7 k8 Z' ^  int numKeys, i;
8 n- f9 F- W7 j# b( q, ^" _! ~  KIRQL IrqLevel;
2 D; ]' ?2 w; w0 I$ |$ Z
# s0 V, K% U0 p- w) ^  IrpSp = IoGetCurrentIrpStackLocation( Irp );
6 ^# j5 B( L: l, F" A5 P& N
3 o( y6 U2 Q3 Y& s0 w: u# O# u! }% ]4 p! `
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )3 k% M9 L5 h( }1 H3 m# K/ Z; E7 a
  {
2 H* ^9 G5 ]4 q" G4 D6 N    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );7 P1 S( e1 c9 w8 |# `
    goto __RoutineEnd;  r3 O% P4 |) B3 o0 t8 g" e) E
  }) J9 I( A. y3 Z9 ~

* t* J. V& z! I6 d  //
. L( K4 l  ^& f  // 系统在 SystemBuffer 中保存按键信息" H0 S7 k2 ]/ W
  //5 G* }. t6 f, ?2 p- b$ y
  KeyData = Irp->AssociatedIrp.SystemBuffer;
2 y( _: B9 n1 E' Z" r9 X  if ( KeyData == NULL )
7 d2 S  e1 X% }  {; o0 j' _* p- E9 {& I9 N
    DbgPrint( "KeyData is NULL\n" );
4 o% V4 O7 O% p    goto __RoutineEnd;" e0 o# @! D9 y
  }& ^0 A, d  K+ s* r
; [$ W( q" ?- G( D
  //" s, b  _" M+ G; e7 O3 E
  // 得到按键数
+ e" i% v0 J5 C0 J. d2 B0 `  //
7 [  r! ~$ Z( Y9 Y. c. g  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );: U% o0 O# G, w( Q. u
  if ( numKeys < 0 )
2 X2 h' l0 t5 Q/ O3 G+ M  {* |1 w1 C0 L9 i' ]9 V
    DbgPrint( "numKeys less zero\n" );* D2 ~6 N' G& ?
    goto __RoutineEnd;
% g$ ~) H' D% x" E) [' ?; z4 ~  }
/ p2 ^7 u9 H+ }' a: {( b7 O+ K
1 Q2 j0 \3 C8 M) y  //
% z$ ^; W& o, {6 k# e- t  // 使用 0 无效扫描码替换,屏蔽所有按键
. A9 \7 p! J: f+ s+ }  //
, l4 B5 Y" _! v! L% Q5 A  for ( i = 0; i < numKeys; i++ )
* N, o0 a0 E3 @  k  {* S, D- V/ H/ l  j3 i: w3 X' P+ K
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
% {: ^. n/ e3 e  d3 u8 D& ]    KeyData[i].MakeCode = 0x00;9 Y9 n# g, H8 E$ }! t! {
  }# @: X7 s3 F: c  m: d

7 f0 T0 H# M. L# \  W5 t6 q4 m* l# y# e2 z2 {% n* @0 e; b
  __RoutineEnd :
/ v# f( s2 S: S  C  T
, C2 s+ g, l3 {" v) f  if ( Irp->PendingReturned )4 y. l2 }8 g. H- ?: u" L
  {
. N( f8 J9 o& A) n2 d$ H- a    IoMarkIrpPending( Irp );: b, w6 o1 e" a7 l7 Z
  }
7 A5 ~! F6 G% K
; h6 m. I/ n3 i4 R) c; \6 d% {  //
% W6 F( s$ |! X- G/ |  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁# k- v1 n: D/ q
  //$ M& }6 k0 y$ j8 v
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
- }" D+ [/ X; i) U2 E; M  InterlockedDecrement( &KeyExtension->IrpsInProgress );! m/ f' ]# H# s7 K; A7 a
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );/ p0 U  c, q$ r/ \
* n9 E+ P% E5 Q! ^* y: ~) z
  return Irp->IoStatus.Status ;
3 j9 h  a7 O$ c4 Z  y} 9 Z- {. N; o$ J/ B3 U- `: g4 a, N

: F! q9 s1 B# q! J1 F) m! O0 @" g+ N
/*****************************************************************: F+ u8 \0 C; s; J! t, ]8 W
文件名        : WssLockKey.h
$ h/ X$ [3 y0 |+ N' N; K4 y 描述          : 键盘过滤驱动
' _* O: n$ q1 l9 I- S: P/ e" } 作者          : sinister
# j7 I" `7 ]% A# p3 ~8 q( x 最后修改日期  : 2007-02-268 S+ c1 c9 T+ j& C! l
*****************************************************************/) F! P; @( f, g
* |& q7 Q3 Q- j; J' [
#ifndef __WSS_LOCKKEY_H_
% e+ J" o: b, O+ ~0 l0 H+ ]3 C#define __WSS_LOCKKEY_H_- E! H# z5 r5 A' i6 j
: k/ `* z7 r5 Q6 {. A4 [* m
#include "ntddk.h". e% A& L$ `, p7 ~; _: J
#include "ntddkbd.h"
% B5 `4 Q% q4 G2 W+ M#include "string.h"
/ h8 ]! {; ?; P% G3 y- N" s0 {#include
% X! u8 F: L+ f
: i/ `& Z! @/ ~5 ^7 i6 ~8 I/ h#define MAXLEN 256( i2 k3 |6 U; l! g  c" k- d

/ q% C2 h/ Q/ c; W1 g6 R# \#define KDBDEVICENAME L"\\Driver\\kbdhid") _3 d1 r% _& ], R0 j  R
#define USBKEYBOARDNAME L"\\Driver\\hidusb" & Y3 p8 X+ q5 Q$ B* _$ v
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"; B- C+ W2 l, b7 U

3 X6 J; X7 a! h: e* Ktypedef struct _OBJECT_CREATE_INFORMATION
, a% n9 F# m9 ^- d& M0 ~8 z{3 Y1 z  o5 v5 i; o; c  j) @
    ULONG Attributes;
- n* o% f) f) t    HANDLE RootDirectory;3 T% U! p8 W4 E5 j8 p1 U
    PVOID ParseContext;4 y! ]+ D* Z* |) z! u3 O
    KPROCESSOR_MODE ProbeMode;
, x- r& a; i# r: z+ U2 S, C* R9 Q    ULONG PagedPoolCharge;# b# {/ l5 C2 [7 G3 d# F( \
    ULONG NonPagedPoolCharge;
! u+ S3 j4 I, C    ULONG SecurityDescriptorCharge;" h0 o) }/ V3 q& ^) O$ Q5 G# \, G
    PSECURITY_DESCRIPTOR SecurityDescriptor;. O2 `* g& D8 [
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;, q# g- B. `. W2 s& b, T0 T
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
! {* ~& t  Q0 A7 i$ `2 c} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
5 h7 ]0 z# c9 q) \, t+ p" _
: E/ A' y# h& O7 Q/ U' Ztypedef struct _OBJECT_HEADER
7 l$ O( E. B8 m1 ^{  J. o. E/ N* i0 B- q2 V
    LONG PointerCount;
8 T4 L9 H- i4 g' D0 f5 G7 b    union
& d8 u5 x" |1 z9 e    {7 K& s; M( S9 }0 A, i$ P
        LONG HandleCount;
1 A$ c' ^: R8 s* h1 a1 M' T; Q        PSINGLE_LIST_ENTRY SEntry;
/ J# ^% O- q0 W" A1 Q+ z7 S    };+ L; _" A5 ?7 ]% L$ G
    POBJECT_TYPE Type;6 |( E( T8 F# i' |6 ^4 r1 B3 f, `
    UCHAR NameInfoOffset;
/ `+ T0 o9 d6 ]+ Q5 g! j: u7 T! U    UCHAR HandleInfoOffset;5 V8 V% _8 q9 |& v7 Y5 H$ a# ^
    UCHAR QuotaInfoOffset;( O0 d6 a- G% W( m+ I+ N! Y8 F
    UCHAR Flags;
! y; L* F! k/ H; s    union
" o. Q! T& O( Q& N2 \' W" S) P; c% b    {
' |( \! v; z  @9 v1 E        POBJECT_CREATE_INFORMATION ObjectCreateInfo;' b, c, p9 O! ]( _0 T
        PVOID QuotaBlockCharged;
7 W3 u& }* |( [! s    };
7 t& |/ e  ?2 d) N$ b1 m( I' `
' w% j( g5 l9 j$ {* ]    PSECURITY_DESCRIPTOR SecurityDescriptor;
" I1 O/ F1 E7 ^& {- e    QUAD Body;
+ Q, w0 C' }2 q  Z% \6 R+ t! R} OBJECT_HEADER, * POBJECT_HEADER;: ?# W& y) U8 j- F: j
. z( U9 K! X3 g7 M& }3 Y1 c$ A
#define NUMBER_HASH_BUCKETS 37+ c1 U& F4 {& Z& ~1 I
1 d& I' g" ~5 Y* M; G' P
typedef struct _OBJECT_DIRECTORY7 h$ d7 B  L; q5 p
{5 ~4 W  r  |( i5 O1 ]
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
/ }4 Z" q/ c" O3 F    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
/ c0 |: f; l# h: W; a1 S    BOOLEAN LookupFound;
2 `/ S3 ]8 s+ y0 A7 j+ Q& e  k    USHORT SymbolicLinkUsageCount;/ d7 C/ M7 P4 o
    struct _DEVICE_MAP* DeviceMap;! J5 L# o$ t7 h5 C$ q3 w
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
! _9 f8 R6 W8 ~1 r" l
7 y* G1 n/ n/ F* z6 s5 Atypedef struct _OBJECT_HEADER_NAME_INFO7 h+ P6 o% t/ x- n0 p
{
# x8 [  e' `' q3 \& G/ C    POBJECT_DIRECTORY Directory;- F1 d4 I7 O9 `. O- V% f
    UNICODE_STRING Name;
5 J8 x* A9 M+ W9 U. D* a    ULONG Reserved;. l+ e6 }% I2 O
#if DBG
( I. T0 ?2 \8 O  B! g    ULONG Reserved2 ;
" k! X' C' s: }$ k    LONG DbgDereferenceCount ;
+ N4 @3 O& E4 u#endif7 k) B6 n& s4 W- m( w' V9 a
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
. ?$ P$ B0 ]- U1 R+ m) j4 F
' m1 @. I  t) D- ], a#define OBJECT_TO_OBJECT_HEADER( o ) \' m& d. x- _+ k8 N7 b
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
9 B# ?" l- r- `9 y7 A9 G  e5 [7 q4 F9 c9 z* J
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
4 ]2 Y; l% B) B# m( f    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
' d; n# p) k9 m0 P: U% a. b
' H& `/ z& Q4 O3 ltypedef struct _DEVICE_EXTENSION
( x( Q2 I1 _: G{9 |3 M4 V" U5 u: ~
    PDEVICE_OBJECT DeviceObject;
! X  Q! l: X" \9 V# \! T9 U    PDEVICE_OBJECT TargetDevice;
3 z4 h) T( a, ~/ f    PFILE_OBJECT pFilterFileObject;0 y, g  l) ]5 O
    ULONG DeviceExtensionFlags;
% [3 b( w5 R, L0 R1 [2 F; G) X: _    LONG IrpsInProgress;
9 a- ^: Z2 n1 m4 Z( G  t    KSPIN_LOCK SpinLock;2 J9 y( j0 L. G, }
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
# c" W" [! j7 C& n8 x# b: Y/ E5 E3 o

- y1 T, T! m/ J0 _2 Y' U4 M) b  L% sVOID 2 `, k1 Y( ?0 }2 b" W
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
3 a& Z* D% j3 V* B0 Q
: `3 P7 c1 {% W5 X5 o' Z' \BOOLEAN2 m3 L2 w3 _4 s  f: ]9 g" O) L9 E
CancelKeyboardIrp( IN PIRP Irp );# ]( s1 ~; u% d, l/ H& y( Z0 ?
- d" t0 {. i4 w& w- T$ m: H
extern POBJECT_TYPE* IoDriverObjectType;
5 @. l% A/ X" u4 q0 u1 p# h6 \; B# [" Q2 S5 [  t
NTSYSAPI# q3 [! o5 r1 S
NTSTATUS1 R4 v" M& C2 P/ E: ~* S' \' x0 Z5 }
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
' T( i9 }$ u& ^                               IN ULONG Attributes,6 x2 t, X# S& T2 k+ y
                               IN PACCESS_STATE AccessState OPTIONAL,
; P: T: m4 Q  s6 q2 E0 Z1 H9 g, L                               IN ACCESS_MASK DesiredAccess OPTIONAL,
# s; f( ]) o/ V, y6 e                               IN POBJECT_TYPE ObjectType,
  P; I4 R8 x1 E                               IN KPROCESSOR_MODE AccessMode,
9 V0 r* S) r, p) X0 A' b                               IN OUT PVOID ParseContext OPTIONAL,4 V9 R% \& ]7 b7 Z
                               OUT PVOID* Object );; Z  t( I7 b/ h2 r0 o5 u( @
0 `0 w( H' k, U' t/ F
NTSTATUS
# A0 _6 U& B# Z0 j2 E2 HGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
: l  m9 `# I4 g* W* J  \9 S
$ f- u0 }, Y7 l; vBOOLEAN
  f. u, m* z! S% xGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
. \; ^. @1 m$ ~3 F6 W
2 \8 u5 Q$ K  R' i# V) QVOID
1 l* I, P" ?8 G; Q& l" {* X# zGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
. F! d$ T; E4 o' l' a6 h7 }' {* Q4 a  D0 W4 I3 Z
NTSTATUS + [2 F% o; O$ N# {
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
# ^. x& s: }( L7 s. o8 n: C" n                                  IN PDRIVER_OBJECT  DriverObject );* C( [+ L7 D9 |" h( o) ]' f
& R7 R* Z6 d9 S4 |! B% O
NTSTATUS 6 m( n5 k- F* ]# U
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
0 H1 w$ Z2 Y' M/ L, D4 R: M                                  IN PDRIVER_OBJECT  DriverObject,7 }# M# U( G& d! R2 L( z
                                  OUT PDRIVER_OBJECT* FilterDriverObject );  v8 K+ v: m$ {' d' {& J

  H, j5 t$ q7 p& M, H# r8 S: S- a- CNTSTATUS
( q0 l( x1 U/ ^9 o& D' YKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
9 f2 l9 `9 y1 S. I                            IN PIRP Irp,) t) w. S% i& N
                            IN PVOID Context );, |7 ]/ V+ e' [# C# D3 \
NTSTATUS
! X( r0 o9 r  m, j; F: I. oKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
4 N6 S; V0 _/ q. r7 [" t$ f% _8 j: o5 H4 u8 ]; h
WCHAR szUsbDeviceName[MAXLEN];/ G5 J. E! u9 V7 O/ g
  p5 I6 Q$ e$ X* S: p: B0 w& A6 k/ \
#endif! R/ @: ]4 C$ I+ N; n3 c

; Z% e3 K% Y: y' s
& M2 ~7 V% D# r1 b
# p: U9 V9 m2 Q% I- H# c2 j2 H
) c5 t: M; N5 D  B7 E3 @4 }& i3 ~  T( D0 \+ i  g: ]
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。' G0 h4 R5 [9 `
WSS 主页:[url]http://www.whitecell.org/[/url]
0 E% k/ A0 C# H1 e; r) O1 UWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-12-1 00:48 , Processed in 0.253856 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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