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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister/ u. k2 }' t5 S1 [) v; ?# I
Email:   [email]sinister@whitecell.org[/email]
$ p, s, g5 A% U8 a. c! V5 j& cHomepage:[url]http://www.whitecell.org[/url]
" \& j  C- F, p# xDate:    2007-02-261 J; V# R* ]1 U3 |8 B' }" x4 B* |
* ^: W1 k0 B, e& d2 J6 M

4 w' y3 z, R5 H/*******************************************************************: @/ C) \5 j& t

* ^& \+ |3 L- Z这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
4 ~+ y- P/ b9 u( c# t: F写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的+ [# H4 O0 }. }5 ]
功能要求如下:
) {& a; ?7 h! M4 V$ {
# [" G' u+ ^9 P2 n1、强制锁定键盘/鼠标。
' s0 {8 I" x# o' ^! _2、可动态加/解锁- D/ U0 i0 K- j! @5 u- E3 s+ f
3、兼容所有 NT 系列的操作系统。
; x2 d& K  u( e* g$ m7 V) e$ \$ K& |4 L! C1 A# q; e
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
* S+ l  |: [( G" e# C( S现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
* {9 i# r/ F3 ~) l5 v; ?4 O3 J! \何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在" @3 m) P4 \! R0 N: [
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
" W7 _0 p  `2 {4 X& O  J( |5 W怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
- A. w- ]5 O& o, L: |' I+ _! E( v就来看一下我想到的几种实现方法:8 h" M+ ~- u3 e5 E  ^

9 z+ D+ t+ f: P1、全局键盘/鼠标钩子6 q$ Q' v$ n% U8 h! [4 B9 }( f
2、BlockInput() API
* |5 x" F3 s) X& i' i/ n3、使用 setupapi 进行控制* m% r3 C0 C( Z; B
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL0 z5 \, f( `& x$ n
5、拦截 win23k!RawInputThread() 函数
! a4 h5 \# F: F. s6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动5 F, v# [* U4 s2 d9 p; Y) ]
7、拦截 kdbclass 驱动的 driver dispatch routine
8 S7 U/ l1 r3 H, d% D# m8、实现一个 PS/2 与 USB 键盘过滤驱动
, E8 ]+ w3 L( Y- {
$ K. ?3 c6 G0 [3 x0 @- `- G% `4 _9 c$ q
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑: A, Z" z. e) y" F* W
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方4 N7 U- d! f- W' |- E  x7 Z
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
: I  ^$ `# e; ^6 B% m  Q$ ^兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因9 `' e; g+ p0 n  g& s" s/ C
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
, T. U) I) f: M8 g# D问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸: B1 R) T+ L, A( a
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我  G* c2 j, [; o: G& u- x' w; w
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来/ A: o: r+ t* B( ^, H& m/ L
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如6 D% @: L8 m6 K# G& P
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有2 U5 A) }9 f) n; w+ f
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截: j2 c, |* r: f# k7 L7 T; ?
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 & o5 @5 ]( q1 g) k; @
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键- ^0 N* H7 e( ?
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方0 k1 ^" A) p5 t% v& w% E0 K
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
5 J0 h' J5 }( t7 k  e; U: F: ]4 X2 ?4 ?

. Y5 l& q3 _0 X1 _5 `我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
9 k6 }$ |- k* W" X5 N- C# M2 s滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
7 F% S8 Y. Z9 K: V+ Z5 T行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
( P' A8 a6 o' X( C& ?6 N只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
2 r/ N/ h+ a8 n6 u9 I: N2 z8 X, O来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从/ {3 R; O4 z( Y& r; o
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB( e7 f( e3 p6 t8 O+ b
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用" p  h$ O( i2 O; j: [- q- s. G6 P
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
& l: a( O9 @6 M) A我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题3 K2 _. ?  i7 d9 d; V( M
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的4 f$ `5 q1 _5 R0 ]0 x
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
9 ?2 i7 Z% y8 O* p; s用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通# |2 y% ^) K, _: Z7 V( `. R
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
* j* k8 w& B7 I( s$ ?: D屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通3 x+ {. ~: y/ O; K* z
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb! ]3 `+ I9 R- Y4 j7 E; G2 I
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 0 S% _7 B9 _/ n$ l  }2 B
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
0 ?% g1 ]* j2 V2 ~味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。/ I/ y: g4 M9 `, m) X& ]' B/ s
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们4 c( W- N5 [5 c  p7 Z' Y
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
& t8 V  E9 C1 \$ c的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
4 P* c+ w6 t/ W! Q! x8 b6 Y& R的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致# ?; C4 N0 D" ~5 W, g  _
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,: s4 ?, {9 m; [8 [. p$ p0 t7 @
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
% ]+ @4 G  @0 w2 |* h+ B" }! L见下面代码。
: x) H6 h7 v0 ]+ I1 x+ }  {4 @; U( l$ ]% s* y
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程* c) Y% M7 f, |  }: u& m
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键5 M! e! s8 x6 f% i7 U
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
  O7 {4 J: ~5 x8 b# U上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
3 M, V& S( F0 {完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可9 D) z) v4 G- `; w7 i, F# G1 l
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个6 x4 E" w0 X& K. A: Y0 k$ I
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按) n) s$ ^' D* T& H# Q! o
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。+ V0 V4 i- l4 v: T

/ L8 P* D0 _8 C1 p  x8 z
: Z( S! P: i7 R$ p0 k8 Q) o# A完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用  j! @& f0 S( s% J! q# ]/ i
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
, V9 N; H  f8 r8 i; v% e4 @; Y可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣$ _; _2 v3 g- p6 [0 @2 F
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
3 f/ h+ c0 v! ?' Y- `/ P  H4 l( d; t% `们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
: _( h" G# k, K! ^3 v0 A, E1 y们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
. i% X! n6 X/ w, ?9 o: j->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。- m3 `1 l& O7 \
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
& N# ~- B, S6 ?0 }; p进行操作了。这个问题有待大家来完善了。* l7 J* k$ e$ {2 v7 Z" \

! U- z- M1 l3 J$ c) d+ W( g; r7 s1 O( g. H/ q; Y
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出, @6 p" O. k8 u( Y& Z
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的1 H- W# \0 \9 e/ j+ M2 a$ f: k
分析做个记录而已。我更愿意把它看做是一段注释。0 X6 E8 V, l! v4 F
$ X( G; b0 w) ^& E) o( ^
最后在此代码中要0 R: j& M7 g1 G7 F' |

4 Y6 F  h0 A3 g: q' o# j感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。/ C% Q1 ~- h9 x! ]" O( i" X
4 p- p+ _- p9 r5 j( `
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。4 {2 ]; H+ B+ Q

5 S# M8 Y( ?, c) D, Z7 I; Y感谢:齐佳佳,过节请我吃好吃的。) Z$ S$ ]- }# W
* w. A8 K" w3 c7 e

. o, ^/ B7 R# o$ v$ Q4 G******************************************************************/9 I+ T% l: f5 C; B  l+ F

, T8 R: s( g( J
! l0 ]& ^; U9 D' M5 P' s: Q/*****************************************************************
! V9 w6 l! R3 m  C* d* S6 |) V 文件名        : WssLockKey.c6 O) J  D$ O% E- M; r( ?
描述          : 键盘过滤驱动& Q9 D& ?" J) y' p4 o
作者          : sinister
: I6 z' j' u3 g/ Q" z0 H 最后修改日期  : 2007-02-26  J. P% \! v' x1 A) ^: |* f6 N
*****************************************************************/) n5 b, M) o1 o! w! U9 s
, o3 {; k" x; T* x  E! h& m

  Z. }! i# n* [7 U#include "WssLockKey.h"
$ L& O2 H5 T; N! y$ b
0 Y9 ?' @, U- h8 [  eNTSTATUS
! L) T4 r$ ]. K4 uDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,  ~7 P( ?; h: W+ X4 L
             IN PUNICODE_STRING RegistryPath )
1 P5 g0 X3 Z4 d9 A! U8 y{2 W0 Y: {4 m/ V; l* N' `
  UNICODE_STRING KeyDeviceName;
4 c. n/ w  f9 h" ]% p  PDRIVER_OBJECT KeyDriver; " ?6 j& z3 G6 H! ?
  PDEVICE_OBJECT UsbDeviceObject;/ E& e) D, G4 {
  NTSTATUS ntStatus; - g/ `6 [" W  o; z+ z  S1 i- F
  ULONG i; % @# e$ Y9 U+ L) h! b, Z

$ A- Q7 F- v2 A- t, [6 |/ \/ @' ]2 h  //) _  w+ G: N9 {9 h; v* |
  // 保存设备名,调试使用
* p+ M* W( Y' o1 @, B% o3 m3 `  //6 z3 W: _4 C0 P/ |0 w
  WCHAR szDeviceName[MAXLEN + MAXLEN] =+ V; v) C! ?4 s/ u8 D1 a- }
  {
' R6 g8 a9 C4 l    0
* p1 U3 n' [4 q$ Q  };% y! ]* l3 x4 z. K& b  q

* k8 f" Q( y* ~1 L1 S* I  KeyDriverObject->DriverUnload = KeyDriverUnload;
! P! A6 X/ Z. ?7 r* s( ^; ~2 }, v7 p9 p* {
  //: U: x: O0 |* i" ]/ H8 Y) U
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘* e' s- y9 G1 _" l
  //
" D( v5 {: e# s  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
2 c* ^: ^6 [; A; R. L/ B% B9 }0 l  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
$ @2 t6 C5 s2 V, v/ c' U, w  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到8 \, D% e/ d1 x+ B) C# j
  // USB 键盘设备来进行挂接8 H* F1 c% Z+ I' i$ L
  //
) _+ P1 j& k$ G  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );0 |0 }) M5 j( U+ |' n3 a
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
  D! E+ D; Z# S4 \5 W; u, k) |  {
" B) c- c- c  n/ H$ C    //
! C& |; V: B: G' Q  N1 W% Q    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名8 ]# R$ Q6 M4 l, o& G, g
    // 所以这里打印为空
2 u4 C% n% U  \    //8 {1 c( w! S: S
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
" S% p3 a: z7 N3 p: V; ?3 G. @    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );0 C, ]/ r) J$ i/ d

6 b; V% T) j8 W    //
2 ?: [1 {! A) p: c9 l' ~    // 挂接 USB 键盘设备: s$ X4 G' B* t  I! P0 [5 j; K& B
    //5 h  e/ |5 g& c# D8 U$ D% ]4 u4 q
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );% I- {7 Q: T0 M" q' b, o" x
    if ( !NT_SUCCESS( ntStatus ) )
) e. `7 P3 [3 W. T8 j% A4 w- F& s    {
% V  R% M1 R. D      DbgPrint( "Attach USB Keyboard Device to failed!\n" );" I- S7 v* A- P/ k1 |* i# I
      return STATUS_INSUFFICIENT_RESOURCES;
! F& f& @) s4 j3 p, D    }
# r) @7 V0 S2 P  [  }# a" b- i$ I$ j" p/ z  T
  else
0 p" z: L: G: l; v/ A2 b; Y# }  {
3 }4 o- b2 C/ x7 S: j    //
& ]5 v! X/ k) m    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
" q' h. k7 I# I1 g) X    // & c' a* L$ b! Z* l
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );   ?& }( X, v% E% O

4 U( d5 o' U  I* ?+ Z% v" W    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,) k1 K" }9 J) g
                                        KeyDriverObject,
& z6 R* c% A/ i9 F+ b  U                                        &KeyDriver );8 @& M' `% ^/ |% u2 t7 q
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )/ O) d/ @. f9 O0 B& b$ J4 V$ h& N
    {
0 N" M' k9 q: s) Q  F5 r      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );5 k  _& _0 ~8 u
      return STATUS_INSUFFICIENT_RESOURCES;
6 H2 ]% f; i0 H( E    }& `! B% q! a4 o! y% ?
  }
* s* n8 ]( N/ y7 ]9 a+ K2 A' X8 m/ G9 p- ^
  //
1 ~3 t; T& j8 s" T  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
! y3 h, j: P, Y2 B2 b  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程6 F' [! C0 F9 Y( Y: U
  //8 G7 s) \5 T- F. j; b/ M0 Y
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
: m. h( e, M2 _3 h$ F' f; V% Z0 S; j1 r% f0 P) s. `2 h% e) A
  return STATUS_SUCCESS;
0 `- O  N. j% r% ?; \9 l. ~} ; k" X( j4 R; f9 o7 U" u

7 r* w3 k+ W% T+ `+ @( G, x/////////////////////////////////////////////////////////////////
. ^9 q# X1 l3 F// 函数类型 : 系统函数/ |9 t( @. H, z- N
// 函数模块 : 键盘过滤模块
8 V, l  i8 N" R" }& J2 o" u! w////////////////////////////////////////////////////////////////6 ]- @# L% ^2 o8 ?4 F+ U0 Y& y$ Y
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
( ^1 O2 `9 Z2 g4 X( ^& F4 P" b//        卸载键盘过滤驱动
; R; Y* v/ l0 p5 Q& X/ @* K: e$ m- V// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上. E. R! c! K/ p2 c1 I4 L
//        则需要等待用户按键,以后有待完善
+ ^" {) _4 |' L5 m  k8 T/////////////////////////////////////////////////////////////////5 I. y+ E% c: q8 J" R- z8 T* S) E
// 作者 : sinister
1 |, q1 A9 ~' `( d// 发布版本 : 1.00.00% h( C2 x) X* y& [. C
// 发布日期 : 2005.12.27  I( k$ y$ M, J2 R5 l' A: d% q
/////////////////////////////////////////////////////////////////
- Q5 o8 Y' B! j* V" T// 重   大   修   改   历   史
( F2 V  M- u( y2 G; y  {) F7 M////////////////////////////////////////////////////////////////
* {0 [* j: R  ?# a; z! ^// 修改者 :( q. M" O- x7 I5 d
// 修改日期 :
: |9 K5 g! F) u5 J// 修改内容 :/ R0 F2 b, ?" ?7 h: Q
/////////////////////////////////////////////////////////////////
: w: o' ]( Y- S0 |$ l1 }, s6 u, z+ e% y
VOID) n% c) d: }. T# G6 B3 ?+ m
KeyDriverUnload( PDRIVER_OBJECT KeyDriver ): @: h, B& T' W7 W
{7 e7 x  Q) T8 _9 a* r
  PDEVICE_OBJECT KeyFilterDevice ;      
  o% X9 _* Y" {/ c' U  PDEVICE_OBJECT KeyDevice ;4 i1 T! l! E2 L, _0 t/ f! S( c
  PDEVICE_EXTENSION KeyExtension;
& {, ?# }: R1 R  PIRP Irp;( K2 @, r9 A3 Y: K& v
  NTSTATUS ntStatus;
+ }3 |1 v% W  W6 ?: E+ i3 k; ~# x4 e! g( d
  KeyFilterDevice = KeyDriver->DeviceObject; * R9 X# l) `  X% u$ Y- |8 u
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; 5 ?. O6 V3 n" n* \; ?0 X) W
  KeyDevice = KeyExtension->TargetDevice;
: c2 i0 @+ B9 n- {, D$ T8 k
- n# o8 ^- U3 _5 V" o0 Y  IoDetachDevice( KeyDevice );
1 N! d# w* S$ r& p! l  W; a* `# X9 K/ j  u
  //
# |9 ^, ~' z5 |) c+ z  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
4 Z0 y! h$ P4 Q- Y8 E4 t- q; Z8 }9 Z  //
, g. ~, r8 J4 }  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
+ t* }, @) F& l( H& X; u9 y  {$ r( c  V( U! z- b/ _) N7 P
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
, f- B3 A9 O" K+ J/ {7 A% W# M    {
' n+ j. M, \4 R' p! n      //' s1 y( n# }6 k5 V- P
      // 成功则直接退出删除键盘过滤设备4 k/ e" A! I9 H- N' f2 i; y
      //( G0 |% h" T& Q6 c6 i' t4 h! E2 d
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
3 e5 b2 [% M7 J      goto __End;
0 O9 a6 z( ~2 R- n1 J    }
! q% r9 S# m, l2 H  }- E- R% W; E2 N% l, n- L/ k3 x5 v
+ B" I7 P9 L/ Q& p+ ~
  //
+ b( X5 q! u! ^; l  S% E8 x, S  // 如果取消失败,则一直等待按键
- `" ?0 h# [- f( x  //* Q& i1 J' z! ^0 H" B/ ]
  while ( KeyExtension->IrpsInProgress > 0 )
: S  I8 Y- W8 g0 f. k2 S8 {" O  {9 K5 ]' {! [* I- m2 {+ a
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );! g, u% Y2 r) k3 q$ D( h& g( {* ?
  }
5 s% R9 d8 {" p3 X2 [7 {* C; j  A8 I# a; @
  __End:- Q+ s- y9 `) _( E2 G; v) |4 n" C9 o
  IoDeleteDevice( KeyFilterDevice );
1 p3 S9 ]) O& V% C& T8 X3 m+ O1 Z- c& z3 W7 }
  return ;
/ ^  O" ~: I" H; F} 0 P4 k5 V9 J( S7 P' a" Z: _7 @7 o
7 Z7 j' i  a; x$ f! H
/////////////////////////////////////////////////////////////////
& W" e3 F- J, L, f( B// 函数类型 : 自定义工具函数$ @9 g/ a# h( ?6 T4 h
// 函数模块 : 键盘过滤模块
/ ?9 t& G9 b# \$ ?! B8 W6 d2 y  F/////////////////////////////////////////////////////////////////
( F; D: V+ T* S" F// 功能 : 取消 IRP 操作
1 c. }" S5 G" g3 b* x0 ?2 u// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
8 `0 x0 [$ I7 i2 o8 I//        使用此方法来取消 IRP
& {3 k' j2 s. h( }/////////////////////////////////////////////////////////////////& O; N3 ]" D2 u* G5 k3 }
// 作者 : sinister* ~( m. J: o% _: t" X) }
// 发布版本 : 1.00.00. b9 s  ~5 A* @% w; i  q; L
// 发布日期 : 2007.02.20# O- J- C$ v: ^# G) ]
/////////////////////////////////////////////////////////////////
$ y, V6 Z& E" ~8 Z// 重   大   修   改   历   史6 D0 s' n; T  v4 O1 \5 s
/////////////////////////////////////////////////////////////////
: x, x9 g6 x/ S4 d- m, N" y! M// 修改者 :
5 s/ V" [" r% ?- z5 R// 修改日期 :
* t: h4 X; P6 e0 m# {) ]5 s// 修改内容 : ( R8 h& l+ U: I" x2 \
/////////////////////////////////////////////////////////////////
5 `4 o5 S6 g4 Q9 b7 v. Q1 ]  C  p/ {, y
BOOLEAN
  H0 C& h8 X( ICancelKeyboardIrp( IN PIRP Irp )* b- K8 u* ?. Z& z
{
0 w$ D+ ^+ Y( ]' ~$ f  if ( Irp == NULL )
, G  m" s0 x. X# k  {# T" w, j1 [. _
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
+ t2 H. L' z7 c5 `& W+ u. p& b9 \0 O    return FALSE;$ \- {7 Q5 d; Y& A$ n
  }
5 K4 F; w2 i- i& @5 A0 [& C) D( U  K- a" W# @
4 B9 `8 ]$ C5 Z. J
  //1 g: j% }9 G5 H) v- s& h8 l
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
- }# O' K( N6 L/ u  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
, ]+ M/ ?& U5 e' X: Y  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占  l6 _' O! P) v: b6 r. R
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD7 P( [- g: K; f5 \, r& W$ [  H
  //2 K8 z: P1 y# U; Z/ K, _
* _- c0 n% r$ b
  //
1 y: g( l, v) e% D  // 如果正在取消或没有取消例程则直接返回 FALSE) h8 i. [4 s( z% x
  //5 P6 _  H) O5 u! C
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )9 h) b4 U8 R7 P& P, @, p* `
  {
5 I9 X8 a; o" H4 w( E& c, q    DbgPrint( "Can't Cancel the irp\n" );
, C# t/ [, [) C    return FALSE;- V# ^0 i3 \. U7 K. _9 k" @! \/ y
  }! E  ?, B  W9 m7 F. v) l

$ K7 g3 w9 h  |* s4 Y8 U1 S  G  if ( FALSE == IoCancelIrp( Irp ) )
5 X6 Z6 H( |4 v) S/ S4 G) t( p% P  {" f! ]' k$ o$ V* l& M: s( _+ B
    DbgPrint( "IoCancelIrp() to failed\n" );
' U4 Z7 Q2 i+ d    return FALSE;
1 }/ O9 G8 Q& R. Q1 Y  }* T* p" t/ b: R2 F- y
/ J* C4 H5 Y2 l. w+ s
  //
. D. t$ m, i, a$ A  }, r0 K7 ?2 W  // 取消后重设此例程为空
* L! Y, V1 O4 ^( z2 I  //# t7 l8 b# |$ K# \3 v- M* p
  IoSetCancelRoutine( Irp, NULL );* c8 J6 X5 g9 X: e9 x4 I, [0 ?! e

' o( r; i0 W) j3 U) Q  return TRUE;
9 |/ Y0 f  {: J}
- R4 i8 o' k( B7 K" C  A* `$ p' x. |* K7 [5 |0 d. Z
/////////////////////////////////////////////////////////////////
8 A; G& U5 p3 F, i// 函数类型 : 自定义工具函数7 u$ W% g; Y( G0 |, }1 ~6 [- c
// 函数模块 : 设备栈信息模块) _7 h4 d$ L% y2 I# y/ z
/////////////////////////////////////////////////////////////////
5 [! F" w7 Y6 L9 l- `// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘9 A* ?1 z: W  {& ^3 Z2 ~
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)) d6 z$ K( m4 A9 x. J
// 注意 : ) s: m. S* D  a
/////////////////////////////////////////////////////////////////
5 X9 }1 q8 {% M% H, e) J// 作者 : sinister7 s$ X8 Y3 P" o6 S9 `
// 发布版本 : 1.00.00: Z5 I* p. d/ u2 w+ k
// 发布日期 : 2005.06.02/ b5 U6 _% Z# Q& \: \/ x/ _4 j
/////////////////////////////////////////////////////////////////
+ j* {5 g3 e" X: n; o% h- l// 重   大   修   改   历   史) l* s4 p; K6 J  {
/////////////////////////////////////////////////////////////////
3 u; A( Y) y9 I) j// 修改者 : sinister* s+ o( I* K$ f0 j, B* g4 w
// 修改日期 : 2007.2.12
0 ~% Q6 u- b) p// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
& ?2 s3 r: H! \/////////////////////////////////////////////////////////////////
3 P4 T2 o; D& _! ~' D3 n
, H4 M2 b) q7 j" f6 BBOOLEAN
3 R' H1 R5 t2 CGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )! R+ o8 b- ]! k8 i; i$ l
{
" M5 v# ~6 T# g5 {8 w  PDEVICE_OBJECT DeviceObject;( L7 r  m1 l2 L1 A! t
  BOOLEAN bFound = FALSE;
9 ?5 P5 D$ B) V
0 V& F" j  k  L; ~) h( M  if ( DevObj == NULL )
% g% @1 l2 }8 @0 i2 |' |# @  {
: x" v2 B9 x$ G$ b5 ~6 g1 O2 c& N    DbgPrint( "DevObj is NULL!\n" );
( t: a* n/ a/ a7 F+ e9 N9 t    return FALSE;
* q+ h, w6 D& g+ j  }
/ I( r6 [  r* e5 W  S$ o3 a  i% N
! _5 k" X* ~+ J/ q- j1 b  DeviceObject = DevObj->AttachedDevice;3 ~! D3 P4 X6 P' d% U4 ?- _
+ i% l' i; B8 U7 f4 u( f
  while ( DeviceObject )
: c# y  h6 \+ h9 U/ E* g1 v$ Q, I  {
% T: O4 g" k+ B, i9 l    //2 Q8 n' ?3 [$ n# R
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
3 t: j% X0 t/ m: K. y    // 有一次足够了。这算是经验之谈
' Z0 A6 t7 v3 k/ f    //
; f7 o3 \3 W+ o$ E5 y- v7 K    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )% Y/ F7 j5 M' v! f. d& Q( N3 e' G
    {
; R5 @$ V1 d) z      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
  b* e( J+ L1 q                DeviceObject->DriverObject->DriverName.Buffer,1 g1 o# c9 Q! p4 G/ D. d
                DeviceObject->DriverObject,  h2 O3 m* |7 _! F
                DeviceObject );: g0 i7 l3 L% t* X( x" k2 C# N
. {1 V) {- q6 T2 F
      //
% K5 d9 R4 y- J7 {      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
7 ]( A+ t% g) X6 Z: }      //1 d, |7 w$ S/ c  I/ C& `' F* a
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer," j* U: P! ~" p# P; ^6 T
                      KDBDEVICENAME,
; t" @1 G& f5 C                      wcslen( KDBDEVICENAME ) ) == 0 )& }/ ?; S, K3 V8 C
      {
9 u$ o9 N0 ~1 v: J$ o" U# A        DbgPrint( "Found kbdhid Device\n" );: z: y+ N0 _' b3 ?$ V- u2 x; }
        bFound = TRUE;& E( o; ~5 }3 \, f2 i/ E4 H
        break;% X& t- I, t* [) r, k) ]  ^* O
      }0 i1 S1 S* s& Z  @" R8 S
    }9 c) ~1 z& |0 J, r* F  W5 o! A) Q

7 e4 P& P; p" W, L% U4 z5 {    DeviceObject = DeviceObject->AttachedDevice;
; F, x' u* R% j8 F  }9 \3 q8 \! P) @2 r& Q2 j: O  \
9 j. {, D9 f% E3 Y4 L* T
  return bFound;
& @* W- p# u' G0 S}; g* m! l% e: ]- a7 `

6 Q0 Z1 {& i+ l+ B5 a% d4 S* U* F+ d/////////////////////////////////////////////////////////////////# ^9 r" u  ^9 d# h$ k( b! h, _
// 函数类型 : 自定义工具函数3 A3 _( E/ b8 A$ q# v
// 函数模块 : 设备栈信息模块8 e. W* c2 A" i: ?; b0 f
/////////////////////////////////////////////////////////////////# w0 t2 {& w& h3 c! j: ?0 p! l
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
& u4 K$ x9 T( |- `// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改6 }+ r5 ^. E) |7 a* w
/////////////////////////////////////////////////////////////////
  V" T) |/ U* G* E0 E// 作者 : sinister9 ^. c* G4 _6 a5 X; O* e2 i: M
// 发布版本 : 1.00.00
9 J- F: M9 v9 O3 J// 发布日期 : 2006.05.02
7 B& n) A5 z1 W% p' j/////////////////////////////////////////////////////////////////% B' H  q' K1 t% ^" O2 J( D1 c
// 重   大   修   改   历   史; Y4 `2 P- s5 [: l; Z( N
/////////////////////////////////////////////////////////////////
3 l* X0 k- w' \' N- J7 x0 y* F// 修改者 : sinister3 K9 j9 p  q5 I: M
// 修改日期 : 2007.2.12
9 k  l2 ^5 h+ s& U% c/ t// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用2 o: R* Y! G7 i) {$ p
/////////////////////////////////////////////////////////////////
3 [. C9 ~* t& ]; d; J, L8 U
0 }& ], V: a# t# C+ GVOID
( c; f1 J) A4 RGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
' E0 h- I% B" z( }, u, b% Z' r* I{/ R  {+ B( \0 {4 ~# ~
  POBJECT_HEADER ObjectHeader;
6 ?4 T# e; Q$ e: }0 \' T$ V  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
: H) d4 _8 S+ q0 [' c% {/ B
2 d& F; g6 H3 n, P$ F9 u1 b  if ( DevObj == NULL )
; W7 K- M. C5 E" Z! q( Q$ i  {
5 N- B# d: Y* T# w& t" j7 o  `    DbgPrint( "DevObj is NULL!\n" );! B# F' U) y3 _4 @" f  \' ?
    return;( p0 r8 v' {( |* b
  }: n/ S) C; \! A: S1 v) F2 ^& p* s6 K

5 m% d9 W+ O8 g9 p: O5 j  //* E/ \" n7 {5 B4 i2 ?
  // 得到对象头
, a7 B: |& K- E, g/ {, i# A* w5 w6 A  //9 x& e) H5 L$ N& t" h4 j
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );) M+ X: B; @, t1 @" n5 V

9 ]! C$ M; ?( C1 F: P( L  if ( ObjectHeader )$ ]' A( e4 y  f" C
  {& ?% }8 f8 _. S  D5 C9 I% a
    //: _! B# H0 B) [2 a3 K5 i. L0 M
    // 查询设备名称并打印, _( Q# p. h8 X1 J  f% h! Y' H% Y
    //; Q" q) b& S+ L  v' t0 n& V
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );. R: c8 M$ c1 E

( q9 ~' y( s$ k( s: U2 l    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
6 E2 E5 O+ D0 h3 R    {
( K8 Y2 H+ p! n& Q) G* u8 z. n      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
7 A# r' g# I4 s- K5 i                ObjectNameInfo->Name.Buffer,  b& g: W5 k; ~4 k/ v( {* @: M" A
                DevObj );" ~* j9 p4 c. Q# Q) J/ |2 o

2 B: X- F  J4 S% s  V3 I  P      //
) _. c$ s+ Y. [' a' f0 I2 v      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示% `  ]9 p+ k0 D% j! W5 G
      // 用,没有实际的功能用途
8 s7 d4 B2 j7 J6 k% h/ f      //  p. V' g8 Z9 k) [) z" N7 ^
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
6 @3 x* J7 d$ `
! O* j) H% S! z      wcsncpy( szUsbDeviceName," W$ W. h- A/ U' I0 g) D! Y
               ObjectNameInfo->Name.Buffer,- V) u: B- n/ [* ]7 B! O
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );, N% I6 ?% N# T1 r( H9 t
    }
! ~8 ?$ J( l- e9 `9 P' U# E& i# J9 u. C/ s7 \: Z
    //8 U( m( j  [6 \: Q
    // 对于没有名称的设备,则打印 NULL9 F, W: U, E1 N. v1 F
    //
5 r/ ^: L9 K  r* w. d) @    else if ( DevObj->DriverObject )* W: Q  H& z- v; f
    {* j2 K5 b5 E1 E4 ^: G! B! R
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",  y% u  C7 H4 f/ @1 q1 }- M- E
                DevObj->DriverObject->DriverName.Buffer,# e" c. `6 X5 @" a1 x( q! Z9 `: J
                L"NULL",- x7 D+ f; D! [! B. _# D* U6 k
                DevObj->DriverObject,0 z+ R% v0 _( X9 u2 A
                DevObj );
) o3 N5 h6 Z4 w: ^. O4 M6 e1 Q8 c' X+ ~    }
+ f) f5 E1 m& \2 R, r  }
! o2 |& A+ u6 w1 w/ j}
9 G  Y9 I$ V& A) g! @) ~
7 E3 e. @* F3 B/////////////////////////////////////////////////////////////////# v+ T: m% h4 S) s3 ?% y
// 函数类型 : 自定义工具函数4 L' V: ?2 W8 [# A. ]6 u
// 函数模块 : 键盘过滤模块
8 V$ U8 o; R+ T; r! r4 I+ l/////////////////////////////////////////////////////////////////9 H& ]" [" I4 o2 o/ |1 M
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
8 K, k. g5 k) |5 Z9 Q7 w" Q' f+ f8 Z//        对象,过滤出 USB 键盘设备,将其设备对象返回
. j/ x. x! o0 j; q# O! M// 注意 : # [: N- W$ ]$ Z0 u
/////////////////////////////////////////////////////////////////
/ Y# t8 u8 C+ U4 H4 j5 K2 @) Y* F// 作者 : sinister
4 d" F* ?* A, L+ ^( n// 发布版本 : 1.00.00
0 T5 G: a5 L! ?// 发布日期 : 2007.02.13
+ g% C/ z% L" l( x. q, Z; r/////////////////////////////////////////////////////////////////) B3 G* C# i; o$ R; l
// 重   大   修   改   历   史  O2 p0 V2 n" R8 e0 U$ O( e
/////////////////////////////////////////////////////////////////% `4 d) n% ~; q8 m
// 修改者 :
4 r- X& G% ]# |' S/ s// 修改日期 :
0 m2 a8 e# A6 U' F# ?( Y// 修改内容 :
- C# L3 u  d; J) V' ]% S/////////////////////////////////////////////////////////////////) O' c, m# @$ h+ G* x4 P

8 C- O2 @$ V, YNTSTATUS
% \9 D. \5 T5 F/ i/ UGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )0 J/ `3 p- S& h! u5 g% ]
{) n' C/ P4 r$ _# c3 G/ W! `0 H
  UNICODE_STRING DriverName;
3 y& Z- r0 I: Q  PDRIVER_OBJECT DriverObject = NULL;
) C- C' K0 @4 I  u8 @: v8 O2 u  PDEVICE_OBJECT DeviceObject = NULL;- e# a1 ?: ~# C. l
  BOOLEAN bFound = FALSE;
/ I$ Y- Q6 r% z. }
) B7 E, [/ S* D  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
5 \: K: l/ Y$ p1 C1 v& a
0 D/ J2 T. _5 W( r% S  ObReferenceObjectByName( &DriverName,
" n1 b/ W1 l% z- N2 W% l! I& ]$ v                           OBJ_CASE_INSENSITIVE,
1 z1 Y+ D7 r( |& J* l                           NULL,& L; K1 L3 c. I  Z3 m# s9 B0 m
                           0,
5 ]/ s& q2 q  Z8 _                           ( POBJECT_TYPE ) IoDriverObjectType,
$ Y; c4 f' k* N3 ?9 q7 m) p                           KernelMode,
$ D7 W) f+ @$ a9 Z: Y                           NULL,
. e  l1 {+ L  x& D8 P' [* |  T                           &DriverObject );3 J  P% `/ u3 z# e3 \

; N& _5 T; A5 _" H- V/ p  if ( DriverObject == NULL )
% I% k  O' X) F4 {  {2 q  U. @3 X6 W0 d5 u- C
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
6 v. e: N" L% A, l+ t/ o    return STATUS_UNSUCCESSFUL;% L' Q5 g8 J2 P
  }3 N- S! K  c+ r  ~4 i# _. T
9 D1 r* C1 w2 _) E1 ]
  DeviceObject = DriverObject->DeviceObject;
9 }- _% W$ b' ?: U
1 n2 ^" e5 g* W) d% ~8 @  while ( DeviceObject )
4 ~1 Z& T: Y3 y% S, E* C: ~0 |  {: [; z( w' \2 @; f- J
    GetDeviceObjectInfo( DeviceObject );
. q! {! C/ L9 w% a! V' g. O: [9 X& d+ f. J5 h
    if ( DeviceObject->AttachedDevice )
" j" ^" d+ }& _* R$ x5 Z6 l) t( Z; u8 g! w    {2 f# l  Y5 h# }! o8 a
      //
3 ]0 t. \- w% \6 G2 C5 ~7 I      // 查找 USB 键盘设备
9 E- G$ C9 _2 q9 \# O( ~0 g      //! ?7 a! ^$ @- {
      if ( GetAttachedDeviceInfo( DeviceObject ) ); k4 T3 s8 B( H1 r
      {
, @4 ?* [% U  E1 c: i        bFound = TRUE;+ d4 D0 j, v$ w8 R* V+ E+ X) V
        goto __End;
6 B* t1 A" o# c5 P7 `4 H      }# J& ]4 E' T6 E) |1 I7 p8 T: @" I
    }
, W2 @  y- S+ D' B+ K9 [
3 m4 N+ Q3 F: N1 @% c! @, k    DeviceObject = DeviceObject->NextDevice;
6 Z9 l* K; e: u1 F2 N  }  z! x! x- ?, S: [  u- D% F! L3 A
' }1 x& m7 {2 G/ w# ]) H: t
  __End:
3 t! ]% ]' s; o8 b' j7 D' E* |1 e& [4 F" }1 G8 d
  if ( bFound )$ j& @1 K# K" Q  H2 l
  {
% b  w4 b+ Q; K$ {% y+ y/ \% D    //
) {/ B2 y+ h8 v* w1 B: y4 ~    // 找到则返回 USB 键盘设备对象
' e+ w2 b# h+ H( E" m    //% U, @) y! h- b1 n+ e
    *UsbDeviceObject = DeviceObject;
$ T: E. s- r0 w: y  @; b  }8 H/ L: j! w9 ?9 Z  M" C4 Q) x  o
  else
" j$ H3 M8 ~% `/ K  e* {1 {  {8 K! M) N2 ]2 `& j$ H6 N0 Q" D
    *UsbDeviceObject = NULL;
3 ~$ u, q/ s- U5 ]  }
  ~. c. E( Q3 Q! |  u" g( L6 W+ [! B
  return STATUS_SUCCESS;+ l& l/ ]0 Y7 o4 R2 x3 b
}
: y0 [8 `  i, y& @0 e
8 }- H1 f9 V# H7 w6 x) ?9 p/////////////////////////////////////////////////////////////////
* v' V# |! c3 A// 函数类型 : 自定义工具函数
4 {+ {1 s6 O& ~0 Y$ D8 R4 J// 函数模块 : 键盘过滤模块* u( R" h8 N8 d$ j
////////////////////////////////////////////////////////////////7 ^4 u+ V  b$ o9 H0 J% _( z+ |1 W* m5 N
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
6 X" c7 B1 j9 u0 p//        信息,返回附加后的驱动对象: H9 h8 V4 ~$ H/ m
// 注意 : 此函数仅挂接 USB 键盘设备
( ?% l/ F  i6 y) w2 u/////////////////////////////////////////////////////////////////, ?) ?& c) Q9 a: z5 G& r7 w* P
// 作者 : sinister9 B6 i2 X+ f5 f2 \
// 发布版本 : 1.00.00
. `/ ]" F* J7 @( S  l0 R// 发布日期 : 2005.12.27) e- B! K$ t8 }& H
/////////////////////////////////////////////////////////////////
+ c- F( ~% k( i) D// 重   大   修   改   历   史0 n2 L9 T  ~& |% w% D' ^, A
////////////////////////////////////////////////////////////////- U& O. w) }) z
// 修改者 :
+ ]- _, U' _, F# H// 修改日期 :
; e5 K% K' R. O% S; M  x// 修改内容 :
' y4 d( Y- {% i. Y) Y$ D' T/////////////////////////////////////////////////////////////////7 A5 J: g' M0 k2 N. N2 [# X

8 x" m( k' L$ h/ {7 K$ oNTSTATUS: E% a' d& f+ B, z
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
' l# \9 N* c( l3 i8 M                         IN PDRIVER_OBJECT  DriverObject )7 d% F1 v: P8 i; d
{# x8 ^9 U/ O2 ]  h# |
  PDEVICE_OBJECT DeviceObject;
. i3 o, Y, M4 b. g) e% ]  PDEVICE_OBJECT TargetDevice; 2 Z3 y0 U4 k* r- S3 l# H8 o6 D
  PDEVICE_EXTENSION DevExt;6 M* N% v; A4 L- t" O6 K
  NTSTATUS ntStatus;
* h9 K4 o/ m. k9 K# R  X& p! Z7 o( ?# _/ K3 |/ X
  //+ a6 ?) S& i0 \/ d+ N& m6 ~$ L; O) v
  // 创建过滤设备对象
( d3 P: U6 m0 e* |  //
0 l' r4 Q4 @' r5 F  ntStatus = IoCreateDevice( DriverObject,: ?9 P) p8 E, z: H# M8 K
                             sizeof( DEVICE_EXTENSION ),
1 o; J& X3 _; g, C/ q                             NULL,
1 e. T; S2 U7 P% T0 R0 V! L0 ^0 W# S, @- z                             FILE_DEVICE_UNKNOWN,: K% f3 w8 {9 J2 a3 T+ n
                             0,7 U: Z! v( E3 a2 s  _9 h" R
                             FALSE,; G- g, I! ^3 Q$ f# K2 u: {2 c: u
                             &DeviceObject );
% e+ [! C- }; w: U+ B% U, |. `( |! p, d0 i' q! w% ?- D  H& j
  if ( !NT_SUCCESS( ntStatus ) )
; a! P, n8 z  n+ N4 L& S! b, z1 F! ^: f  {9 ]! p; u* B6 o
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
1 B6 ?' f! U4 e8 A" M  ~& n    return ntStatus;
4 q1 N7 I0 L6 h9 f9 T  }
0 c: ?6 q( b: t! d5 v
4 d2 j! j; Y3 B; W  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;, D. j& p4 G. m' g
3 R/ p. `5 l0 ^" X0 D3 E
  //
; ^4 G9 \% l9 k  a  // 初始化自旋锁
" p; J: `1 |( ]( E: v1 z  //$ Q( |1 \4 m6 s; a* P4 [/ l; ]
  KeInitializeSpinLock( &DevExt->SpinLock );7 e( m# i9 Y0 v: X5 I9 L- k

1 c9 I9 w7 g3 f  //; |; i7 o8 K; `7 y
  // 初始化 IRP 计数器* o7 @+ m0 \6 ]( X
  //
/ w  k  U# h7 Z  DevExt->IrpsInProgress = 0;  O3 s8 M# j$ \5 P7 ^6 c  g
. i9 \/ m5 \9 o" k4 k2 T. D
  //2 U5 F. b; ^9 G2 [
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
4 G3 I5 B" g2 P  //% c9 ~& h& j% \9 I: l$ l3 d

5 L+ F  Y. {$ G" d# Z3 {  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
3 `; A( t8 }0 a2 V* U1 w  if ( !TargetDevice ); y* a, \: ~, p/ [' E9 N
  {9 u3 l& d7 V. a8 t
    IoDeleteDevice( DeviceObject );
1 u* F1 s6 ?; ?7 X& ~, G    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );* Y9 \# T* \$ F6 g4 `! X" y
    return STATUS_INSUFFICIENT_RESOURCES;' L! e1 E# I& ?8 B" b
  } / c% F, O# a; Y: t

9 F) g# m- h9 G. P  //  Y" c. u3 s- q% Z
  // 保存过滤设备信息. e/ L% t2 y, ?5 ?2 \& e9 ]
  //, C' W& z- ]: z8 _9 u
  DevExt->DeviceObject = DeviceObject;
0 ?5 u1 P) m: z, R. X; {; G+ L3 }  DevExt->TargetDevice = TargetDevice;; s9 s  e3 s" C; R

  L% ]0 ~: u, n! o+ j) O2 [  //( z. z/ i2 P) c6 C  N
  // 设置过滤设备相关信息与标志/ S5 ~) `2 d% b
  //
* R: C# J8 Y* I; N- d  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
+ V# f4 G- l2 f5 m7 @0 [+ e  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
( A) \8 A' F7 t$ ~. s( u6 M8 Y, y- _( j' S# ]) O, t# H
; \- E: t4 O/ M. B
  return STATUS_SUCCESS;( m+ h# o4 ~  ?0 I
}
, I; G2 Z. z8 u: F
1 \+ @, D- \; J2 j# Q/////////////////////////////////////////////////////////////////0 F9 d6 v& |/ S0 `
// 函数类型 : 自定义工具函数
  J( Z) X, J8 t: O  t! {5 I% b// 函数模块 : 键盘过滤模块) R' X. G; S4 N
////////////////////////////////////////////////////////////////
2 Q' Q: S9 Q/ T3 U' I// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关) r+ a" k& t# F& j& o
//        信息,返回附加后的驱动对象+ B- G# o) N1 F8 [/ C# r% }0 c
// 注意 : 此函数仅挂接 PS/2 键盘设备# U9 k- a8 }) e2 w7 i( A+ e
/////////////////////////////////////////////////////////////////
# u: v9 i" s% L3 v2 S# q( l5 C// 作者 : sinister
' ]4 a9 f( s' ]9 \5 U// 发布版本 : 1.00.00
- v' t; s8 X3 M1 y( t2 ^. E4 q" O. ?// 发布日期 : 2005.12.27
  v( ?4 V7 `+ y9 C8 L* R% N/////////////////////////////////////////////////////////////////
) _0 U8 Y5 ~0 q! W. Q9 G, B. l" U- V// 重   大   修   改   历   史
. b1 U/ \& Y5 ~, f////////////////////////////////////////////////////////////////4 [) C( N5 i1 {8 l* @  D/ j6 k
// 修改者 :. T; Y+ N1 W5 Q9 [0 u
// 修改日期 :
1 Z2 B/ }0 r  k% J' ?1 G// 修改内容 :! b' F8 z* J1 f. M( n
/////////////////////////////////////////////////////////////////
; P4 t. }8 J4 f, r
& H) k( ^# t8 y/ |$ GNTSTATUS  f6 [3 g: J$ l6 w2 b
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
5 j( M. J' {8 Q4 m7 y                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
/ ], x7 t" N5 e. T                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
3 G& _, a1 L, k1 j1 {$ }  J/ S9 n+ G0 T{
0 @7 V  o! O4 N6 c( q+ v  PDEVICE_OBJECT DeviceObject; - l" B6 l% V: _8 Y9 i9 b
  PDEVICE_OBJECT FilterDeviceObject;
( `$ Y' S+ f5 A  PDEVICE_OBJECT TargetDevice; ; J, |2 }% l( \& ?
  PFILE_OBJECT FileObject; : |8 w: b' u0 e
  PDEVICE_EXTENSION DevExt;
7 f% k: B) ~: o; c' q% ^, z4 x# l2 u2 r3 U! q4 D" e" g2 O9 Y
  NTSTATUS ntStatus;
8 H2 @/ M! t) s( {$ n" X  w, U7 n) I! v$ ]  G9 N3 f5 q+ Y
  //
" f2 q1 p1 d. o" N- W  // 根据设备名称找到需要附加的设备对象4 d3 ]; n1 |4 i8 ^
  //2 X# Y9 I4 x7 L4 b
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
+ I3 e$ x# W. W; E                                       FILE_ALL_ACCESS,: f4 J6 M9 h; b" s& v
                                       &FileObject,
( ?& N- V* \" r1 U                                       &DeviceObject );
& N, `9 [  V1 Q# h; `. D/ u. n( `6 J; L! I1 ]8 g6 s, T$ C: \4 K
  if ( !NT_SUCCESS( ntStatus ) ). H7 W0 b3 G  Z9 l
  {0 A5 U% O* x" ~# x9 T3 X( k9 O1 e
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );7 L4 M8 ]" H  K' ~& M  p
    return ntStatus;' c/ M9 t% ?) I) x5 i/ u
  }
# z8 `! C8 m. D. b6 x/ p$ w5 o6 l  [4 B- R( e# u: N+ p1 I
  //. U# A4 U6 x# Z/ ]0 ?! E0 o
  // 创建过滤设备对象
0 l$ E  y) E+ v% m; x  //
) K9 O+ k1 \5 R0 Y  ntStatus = IoCreateDevice( DriverObject,
4 {' f$ X: G4 ?/ Z4 T                             sizeof( DEVICE_EXTENSION ),5 Q% A; d) ~  _, G
                             NULL,
* z- s! A/ z. k- k$ p                             FILE_DEVICE_KEYBOARD,
9 p  D( [9 W& T& Y- N' ]3 a                             0,
$ l& m# R. ^8 {  j% A! T: d                             FALSE,8 ]# A9 W8 n. d6 _! @, l& f
                             &FilterDeviceObject );
' s) N3 n. l' Y6 x$ B( Y6 l* @2 ]& A* U- T0 t  u* ~
  if ( !NT_SUCCESS( ntStatus ) )
+ }3 [$ d- K4 b/ O1 Y* ~  {
) Q1 D( m$ K7 w) d- D9 K    ObDereferenceObject( FileObject );
" O6 z$ p: \  w    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );  \3 W; D& C. B" M# Y" P1 M' O
    return ntStatus;
; p5 S( I, Q. `; a, k& g  }
7 o8 u; p* D- B- {
% V& {: k+ \9 X- f  //
3 n- w0 C+ p1 V+ J4 v8 o/ _* H  // 得到设备扩展结构,以便下面保存过滤设备信息/ F! ^6 y9 s( {5 F
  //7 o$ A' K( e1 v* Z
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;- K4 C( D3 a, ~
' m1 K: G% S) P4 ^0 B

3 O0 h" Y9 b/ t" S. }9 m' |  //5 j9 H8 R) B% u7 N  e
  // 初始化自旋锁; o9 ^% ?) ?. z  M5 G8 W
  //3 l4 N1 T! Q; G+ t
  KeInitializeSpinLock( &DevExt->SpinLock );
  k. j1 D/ _. j7 \- Y
, z8 j! N( |( f  //* {. M0 R5 J. P$ l9 o- X
  // 初始化 IRP 计数器1 l8 e/ ~9 |  ~/ V9 C9 o
  //
$ i5 d6 B! }3 S' Y1 G; F' v  DevExt->IrpsInProgress = 0;4 L) z0 Z6 ?+ Y! n; L1 k9 O5 w4 F+ q# Z

% K* z; L; ^( h1 I# u0 D1 m& z" \  //  s0 l% A2 Q& O3 S; n' F
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
- [( ^; x+ n. o  g) p+ K  //
4 ?3 W3 k' [( P  V. z+ @  ?  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
" e; ], q5 T  @* M( z- C                                              DeviceObject );
/ l9 E9 y8 v1 k! Y1 ^  if ( !TargetDevice )
* U* [# ^& n/ H, C  {
2 y" P) H# g1 |" ^; K# D    ObDereferenceObject( FileObject );
& o# ~8 G8 T5 _2 `9 w    IoDeleteDevice( FilterDeviceObject );
9 c4 d! f% n. g7 ~5 O9 z. q    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );. J+ P, D# U( c1 R3 m4 J7 [( t
    return STATUS_INSUFFICIENT_RESOURCES;7 @7 U9 c/ V, g6 ?$ _
  }
. N8 W1 k6 L5 M7 b" d* |" G
- P" n6 s+ {+ F# W( O+ o  //3 M& b$ O; O. T9 S  N
  // 保存过滤设备信息
' }7 v4 @4 P6 B, I  //
$ Y- s" d- u* S& O2 ?! L  \  DevExt->DeviceObject = FilterDeviceObject; 8 S' R9 U! Q7 Z( L- {
  DevExt->TargetDevice = TargetDevice; 3 S* T3 V% f4 V! h" k( {, q
  DevExt->pFilterFileObject = FileObject;
( U& u4 s8 Z- R3 H6 K
4 J$ F* M8 C1 \5 i7 B, _  //
1 h7 ~4 x. R+ H5 h3 Y8 g' x  // 设置过滤设备相关信息与标志* V6 b! G8 J% ?2 q7 n
  //
% G/ z9 |; K9 L2 T; c  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; $ l$ y+ q& J1 t0 E2 A
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
: u) ], H, D9 F1 U, K1 y( j/ b  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;. E2 `5 p: X* C3 ^( V
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |$ Z3 L4 x- T/ c7 ], B- K
                                                         DO_BUFFERED_IO ) );
/ k! v& G( P! K; |  z' a9 P
( t2 u5 p! [) M' H8 ?  //
# k! H/ W+ m' N  // 返回附加后的驱动对象
) z8 L6 e! L0 _  e, p5 l9 w% c" F  //
4 O8 K$ @3 @8 ~  *FilterDriverObject = TargetDevice->DriverObject;
/ @, |5 N3 G, k  N2 h
# s: @6 q4 l2 j" p3 a3 L7 X  ObDereferenceObject( FileObject ); 8 b, ~' p5 r, U; Y4 C2 P/ A& Z7 Z

' Y  D+ G! \, ?  return STATUS_SUCCESS;
+ S  g) ]  Q; Z0 ?/ G}
4 n$ R0 y$ l- Z0 p
; F! f5 r" t& ^: x$ t/////////////////////////////////////////////////////////////////
. D% L: v( s, Y& y5 }* S// 函数类型 : 自定义工具函数# K$ j2 s3 Q  P: F  g; {
// 函数模块 : 键盘过滤模块
" j% d: m% c, j+ ^9 G- }////////////////////////////////////////////////////////////////) |3 R( r) ?1 d# p% \( L
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发. N6 G3 D  G, Z. ^9 s) @; Q+ ]7 V
//        这个 IRP 的完成: k4 t9 T# M! o9 F% @- G
// 注意 : 0 |8 W; W. x" S* N* s9 w
/////////////////////////////////////////////////////////////////
% S1 q. F4 C% W2 ~1 z7 Y// 作者 : sinister
9 u* ~' V$ {- d- K4 z2 f8 n+ H// 发布版本 : 1.00.00+ U. r: M2 b' l, D
// 发布日期 : 2007.2.156 {0 |4 a; c- x& X. y7 O, N" p
/////////////////////////////////////////////////////////////////
6 b* Z) [$ c( K) X  b# u// 重   大   修   改   历   史
1 w& `1 m4 R4 R3 i2 [" x# T& u; v2 f////////////////////////////////////////////////////////////////
' |6 U9 N5 F3 o8 W( E// 修改者 :0 e) \/ Q  [1 v/ M, C
// 修改日期 :
$ I2 L0 @( `" ]  Y// 修改内容 :
2 }, z. K! q5 _4 M- o" K/////////////////////////////////////////////////////////////////
+ ^) U7 {, ?% F# B7 ]
6 |1 i! y( a' j, YNTSTATUS3 p. _, B1 j( B' i- Q/ J
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
1 W+ @! ^  z  o! L& n{) y1 c' m2 ^$ I( W5 {
  NTSTATUS status;
/ R# V" r/ a4 W  M. l5 l' |8 |: k  KIRQL IrqLevel;
, T. N! c1 o6 q" J+ n* R; O8 Y. w! p( o: ?/ {
  PDEVICE_OBJECT pDeviceObject;
* N7 w! s8 g) A+ U' @  A  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
  b4 E0 D2 `/ W) x                                   DeviceObject->DeviceExtension;   P, T* m. E! Q! X' V9 g7 J4 b
$ R# y) Z3 |& M1 R' D3 J+ ~2 Y: h
3 s- \: v4 S. v+ `- A
  IoCopyCurrentIrpStackLocationToNext( Irp );6 r  ~# O; i/ \$ V/ s$ e
9 d, G. m. K6 L5 O3 G6 P
  //0 f. _1 [! f' b/ c- C. |8 {% [3 w( Y& r
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁7 @2 G+ |* T2 T+ Z" `+ O
  //
2 ?* n( G+ i( g! F- }  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );* Q* c# K$ g; b  O7 I. ?7 D
  InterlockedIncrement( &KeyExtension->IrpsInProgress );" M2 y6 x* o( X* {$ a2 \
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
$ u0 M$ k# S& j$ {6 I0 J2 j$ x/ j# ]* y  ]
  IoSetCompletionRoutine( Irp,4 N: @1 i/ @# }5 d# k* z  U0 R
                          KeyReadCompletion,( W7 ^# T( [( J: H' W
                          DeviceObject,
2 Q8 H# L+ Q$ h, u. T' D# C                          TRUE,2 ~; k0 G$ R$ A: L2 U% E
                          TRUE,' N! Z$ p$ f1 v  ^% \: n
                          TRUE );
5 h2 k0 y' r, F# S! B  q, ~; o2 V+ E/ ^- `* W5 u1 `4 J* K
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
* J) E4 o3 i' h7 v} 9 A4 Q# u' t# ]3 z( l  x9 O

! x- r1 Q' _9 r5 R  n' ^/////////////////////////////////////////////////////////////////
0 M. Z1 Y" g( _) [5 U: Z6 n" n// 函数类型 :系统回调函数; ^3 n& O% g5 X) u" x, l- B
// 函数模块 : 键盘过滤模块4 R- B3 ^+ m, ]7 |6 ^+ L
////////////////////////////////////////////////////////////////6 b# m! C, m$ C
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
2 N% E9 w% U6 C" u( M: e$ Q// 注意 :
: L5 a9 h7 k" L* L0 y; P/////////////////////////////////////////////////////////////////
4 r; d; Z' V. H8 Q/ l// 作者 : sinister& y! O  [0 y, }3 j  B
// 发布版本 : 1.00.003 S0 C  `$ |+ A/ c$ O
// 发布日期 : 2007.2.129 F+ O$ Q0 Z+ j. W: \1 M* ]  f
/////////////////////////////////////////////////////////////////" O6 m# _1 [2 ^! Q( j
// 重   大   修   改   历   史% U# f( Y6 U5 D
////////////////////////////////////////////////////////////////
9 a0 K7 K: q& s3 T* g' v/ T// 修改者 :
* p: K8 r+ Z6 m& N! |2 L2 p// 修改日期 :
+ d& z9 r, p/ o$ O  j+ |, |// 修改内容 :
1 N0 j. H( a2 ~0 c/////////////////////////////////////////////////////////////////
' Z: p1 W  X4 b3 Q( H
6 ]$ Q" k( ?7 S* @( Q# hNTSTATUS$ K% a. t5 H7 o5 S( z  D5 B, }
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
' w; F, U% h; f; v$ d3 @. f5 p                   IN PIRP Irp,
6 z1 X- \6 u, f' t2 [* {6 n: ?* Q. C                   IN PVOID Context )6 l6 b- o5 l% \) c. a. C! {
{4 e7 W; {# ^8 E: Y
  PIO_STACK_LOCATION IrpSp;( Z# K  e1 z/ J; _
  PKEYBOARD_INPUT_DATA KeyData;
: a  j, s2 j5 a/ ?  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )# B% ~% y) k; c9 U6 M% E; a5 e
                                   DeviceObject->DeviceExtension; 4 }! O; d  M" y1 A
  int numKeys, i;, ^3 k; a1 Z9 [; c& d) z% x
  KIRQL IrqLevel;/ \" l9 K$ R0 b. f# n- e% ^( Z

! v6 b! ^; j7 [! f5 X) m8 h  IrpSp = IoGetCurrentIrpStackLocation( Irp );# j- b5 b+ W+ H9 _& j& Y, y: ?

8 L5 e; ?% G: a2 q! h  j- N# C) D9 j3 T, K8 v( Y" B- `1 [
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )4 D$ ]& q5 H. d7 I/ T6 T
  {
1 ]: `2 @4 A% s    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );4 j% J% j. D1 H
    goto __RoutineEnd;. j, E- o# E$ z: [' K
  }$ n7 _, j# M# y7 V6 b6 u0 z

! Z" i( o7 I+ X8 F8 r3 w  //
2 s3 F5 E' `4 m  z6 w: d  // 系统在 SystemBuffer 中保存按键信息! b" e; g+ u" c
  //
& Q: h$ f5 L# t. N1 v8 a  KeyData = Irp->AssociatedIrp.SystemBuffer;
' l" r  f1 G  x" G6 S5 C  if ( KeyData == NULL )
& Q; C! q% \: t/ l& g) t/ i+ F( e  {8 u. l- u# Z3 d/ y3 H6 ]" h
    DbgPrint( "KeyData is NULL\n" );
! ~" F5 W+ @- ^% @    goto __RoutineEnd;
# o4 S# J/ ?; P4 S  }1 H4 J# k0 u+ y) _) i
; x: B5 p: ^3 \/ ~& ~$ u
  //
7 L8 j9 d9 j' A+ x  // 得到按键数+ _& Y6 g" G( L; [# X  I# W- }2 s& |8 r
  //
; J( y8 y3 q6 w+ }  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );* ^; ~5 {! \! I
  if ( numKeys < 0 )/ [' g- c+ u5 l; v% a8 Q
  {
! b2 f1 U2 u. J' N6 s    DbgPrint( "numKeys less zero\n" );
$ h/ W; k+ f' x3 d& K7 d  E6 s& m    goto __RoutineEnd;; Q; ^5 n2 c; q3 f0 `' W
  }. C  U: U3 Y2 z
' R" Y. h5 c/ h# q0 y2 H( w' T
  //
3 |" l4 ~5 H' j: K0 q$ n  // 使用 0 无效扫描码替换,屏蔽所有按键
+ E  a) F- J4 t( |8 ~+ h& z) E$ ]  //" D- Q- H! ~9 D7 _6 R9 Q+ f
  for ( i = 0; i < numKeys; i++ )
/ a1 r0 |8 E  G& o$ b2 |  {
; C9 Y5 K/ y7 M! o9 ]( F. o    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );& B' s: r! ~: J: w0 |7 U( @
    KeyData[i].MakeCode = 0x00;: l) y7 w) R; N8 [3 s
  }4 N. h/ L4 t3 U( g

, Y7 v7 g) L) o& s$ M5 x" J; a& {( ~
  __RoutineEnd :
1 q3 t9 I0 V) b" x
) u0 ]% o1 A# {) y3 Y  if ( Irp->PendingReturned )
% h( E. _' d5 o$ m* u+ P& M3 B  {& }, u- R# S0 K1 A5 z9 L
    IoMarkIrpPending( Irp );
" A+ ]$ m- L) a/ z: z  } 5 S& m, G1 N, M0 K0 o6 V

2 [% z( G1 e' I  //5 u4 d: z1 }6 Y+ E; J5 p
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
$ }4 E* d; j& q" D8 y8 V  //: T' Q  V$ H* t
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
) i7 O' U  D( Y6 l. H+ F" n  InterlockedDecrement( &KeyExtension->IrpsInProgress );+ l# C- p: `' ?5 U* |$ v+ O
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
0 _  K" W6 T$ w: P- f' R  L; s' G9 b0 f% f# x, e2 Y
  return Irp->IoStatus.Status ;/ x. M6 \. M4 Q. |* a& i
}
/ s/ u: Y: z( ^9 K, D
2 n" a- G5 Q9 R3 I& l( R2 F8 b! E/ V4 ?, p
/*****************************************************************7 S9 ^2 ~, ^# c
文件名        : WssLockKey.h
- E" N% t) p$ |, G" H. [ 描述          : 键盘过滤驱动
: C* L; g6 l% z6 y 作者          : sinister
/ A" b& B* b5 G0 a 最后修改日期  : 2007-02-26* Y8 J- _8 e; s: r$ K
*****************************************************************/
! k: S' A* y1 _% b/ S- q$ x/ G
) l1 s) ]% a8 x! @* Y" ~#ifndef __WSS_LOCKKEY_H_5 b# r" \  }* W+ t/ ?
#define __WSS_LOCKKEY_H_
7 U, n0 r5 d0 N4 `! g: q' e
  C$ G$ v* P) ?' E- f#include "ntddk.h"+ D4 \; X* J  W4 D. }
#include "ntddkbd.h"
0 O! q! m. v4 ~  b#include "string.h"
* E9 N+ H9 }, ]) e; P4 D! ^& Q3 r# I#include % Z5 ?, }/ @- p- b2 X( n

) W! V- F) F/ k' w# S/ L% @1 S9 m, }#define MAXLEN 256
+ a, P( w- i% E) Y- w+ N
) B1 F4 P) l' \7 `( Q; l& L#define KDBDEVICENAME L"\\Driver\\kbdhid"
  ]0 ^8 R$ y2 B4 H( o2 Y, H* Y8 e4 N* `#define USBKEYBOARDNAME L"\\Driver\\hidusb" 8 Y7 i$ @* Z" L# [/ c! c1 ]
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
! n" u( j9 U. D# p( s% ^1 m) ?1 I
typedef struct _OBJECT_CREATE_INFORMATION, {6 i, p3 P/ X
{  D% T# M" ~" `  r3 |8 M4 |' c! H
    ULONG Attributes;  ^5 K  G( K% y/ {6 |) _4 o7 O
    HANDLE RootDirectory;
! ]0 j4 p0 c# z    PVOID ParseContext;
2 z! A5 t) A- u* k+ g8 Q/ D    KPROCESSOR_MODE ProbeMode;
" V4 i6 @8 x9 r    ULONG PagedPoolCharge;
* b" E5 A3 @: v8 H    ULONG NonPagedPoolCharge;
8 c7 @  G" J7 B& E8 ^+ R    ULONG SecurityDescriptorCharge;; b; U8 k. O8 @- `; m. P
    PSECURITY_DESCRIPTOR SecurityDescriptor;+ {. T* J( D% M6 A3 s* P7 w
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
& p$ P9 Z5 c9 g+ \6 q    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
, R8 w$ F/ }' D5 J& `: o0 d} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
4 \( b* P% y5 }$ P, Y% |. `2 I. {+ t0 g8 m: D. e# U$ p5 |
typedef struct _OBJECT_HEADER; i. B5 v- ~0 H* {! U' M
{, o7 o& n. `! O" f
    LONG PointerCount;3 A8 _/ \/ d, `1 |
    union* ]8 b" r/ h' }  D2 Y+ m0 Z- m
    {
: }4 ?% o: U9 U. b- x: h% s        LONG HandleCount;
1 v7 p( j$ {( v! \# S        PSINGLE_LIST_ENTRY SEntry;
8 X5 V4 Y8 E# l0 b5 p    };3 [3 G! n4 B: h) g9 N
    POBJECT_TYPE Type;1 q* Y6 R0 o5 p4 ~; ~# b6 l
    UCHAR NameInfoOffset;9 C! L. T. o# g5 u+ g
    UCHAR HandleInfoOffset;
0 S# J0 ~9 X0 r6 d- W* D    UCHAR QuotaInfoOffset;* H. O7 b8 O* m6 ]! `: U
    UCHAR Flags;
; t* L& r1 {5 q8 \2 V( W    union
$ q) G8 t9 M8 j5 @+ c& E5 h    {
& X2 ?" o; }8 W3 C4 L        POBJECT_CREATE_INFORMATION ObjectCreateInfo;" g. }) D9 P: ^- `" }$ @
        PVOID QuotaBlockCharged;
% E* N. q! K5 n& f$ \    };9 X. g0 ?9 j" W( r

0 o2 l$ J! c9 m1 ^$ z8 X    PSECURITY_DESCRIPTOR SecurityDescriptor;! ~. Z) ]- O/ {# s
    QUAD Body;
1 W9 S% h% M0 S) [; g' B} OBJECT_HEADER, * POBJECT_HEADER;
$ o) x0 [1 W* ~% ]4 d4 z1 c1 y$ Q
- \7 ?+ u# d! e  P9 w7 o) ~#define NUMBER_HASH_BUCKETS 37
3 F; v5 _) A) J0 X% M
+ X0 q5 |" B# }% T# X3 htypedef struct _OBJECT_DIRECTORY
- \2 @1 T& T9 X: L{8 O  i8 ?1 B+ q! P! y; u  b
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];; D- E4 a: M/ A1 r0 b; ^; B5 H
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;5 p4 n; i; M7 x
    BOOLEAN LookupFound;
4 ?+ I8 M9 J3 m* ?, V$ `) ^) f    USHORT SymbolicLinkUsageCount;  V" m( ^6 z3 p: }: i0 T1 c
    struct _DEVICE_MAP* DeviceMap;
3 g5 U4 O6 I- e$ _) C" V} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;) ]3 v& }' c8 |( u% e) b

1 }( T6 h: M) P. N. ]) D4 ]" ktypedef struct _OBJECT_HEADER_NAME_INFO; z* E2 Z! \8 W# B3 v' J. B
{8 r; t8 x3 y6 T: P' b; _( e
    POBJECT_DIRECTORY Directory;: r8 X# y* ?9 \0 B* V% L
    UNICODE_STRING Name;  ^! b) U) H3 P" d' \+ K" d) k, _
    ULONG Reserved;
: w# V) N, @; j0 o  J0 N#if DBG
: ^2 e& @5 F4 w( K# S5 e5 b    ULONG Reserved2 ;7 V9 M; W' y; p$ B/ a
    LONG DbgDereferenceCount ;
% B6 s: M4 ~8 J  D- W#endif
: L1 ]( ?1 v2 G! Q- ~: I} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;# C3 ?  K- {7 V) X' O

* N. V. A6 `  ?  z9 q( ?#define OBJECT_TO_OBJECT_HEADER( o ) \
. L$ B5 M1 T; K1 V! A6 }- ~    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )$ ?5 e. K6 U9 w! ]8 Y
8 R" X) ]' C) w2 S) ?5 i
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
% o: C% T  r( I  a    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))2 U4 q& F+ @5 t; Q. I: F: M9 ?
2 \+ v& p) r8 P6 p
typedef struct _DEVICE_EXTENSION
" G% f6 z4 v' I9 W8 H{; S( |. y2 |' l
    PDEVICE_OBJECT DeviceObject;
; q3 ]3 x$ F; w( O    PDEVICE_OBJECT TargetDevice;' v/ M$ o6 _" }. p9 W
    PFILE_OBJECT pFilterFileObject;
/ A: }8 B3 A! R' x& n    ULONG DeviceExtensionFlags;
7 N* C) R% @- n    LONG IrpsInProgress;# |% \( }! J+ Z( `" p
    KSPIN_LOCK SpinLock;
% H1 B2 i4 F2 q  ^) [- w5 h}DEVICE_EXTENSION, * PDEVICE_EXTENSION;) z# s9 c6 x% a0 t: Y* C7 l
+ L/ k+ Q7 H0 {) R9 R0 E

- ?) G0 m! t) b" KVOID 0 l, j2 w, D6 S7 F1 N
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
* J" B% m5 t3 M$ y3 R/ _8 ], i1 l1 g6 ^/ d  C. ?
BOOLEAN3 S# U+ i2 a1 i# j5 D8 T
CancelKeyboardIrp( IN PIRP Irp );9 ~/ X, @/ H; G! J8 V
2 _9 k; _( g  B" s1 ~; \: q3 ?% J8 }8 M
extern POBJECT_TYPE* IoDriverObjectType;
0 z; w/ L" g; b- U' [% c6 t7 E4 Z& x( ?- f1 ?+ m
NTSYSAPI
, X' E  t- |1 _$ u8 `2 K: pNTSTATUS
6 p& [3 H* p/ T, G& ]NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,- Q( T) j9 |# `6 j
                               IN ULONG Attributes,
) g  \# K3 l2 x* X                               IN PACCESS_STATE AccessState OPTIONAL,% U( Z3 @% @! D0 k8 o7 o, E
                               IN ACCESS_MASK DesiredAccess OPTIONAL,
" t. ~3 x* U$ I  L6 x2 B3 ?1 y                               IN POBJECT_TYPE ObjectType,
) L; \' _$ r, O7 T( j" C. g                               IN KPROCESSOR_MODE AccessMode,
1 N' K+ Y# W9 b8 [0 w# S. ]2 W                               IN OUT PVOID ParseContext OPTIONAL,
$ U8 @' i# e7 y7 C6 `4 v0 U: V0 q5 z  H                               OUT PVOID* Object );
! c& M2 _  D5 x% U8 _0 y6 z4 k( V$ `, B: l: E4 _" d( \$ x
NTSTATUS & g3 q! B8 V, y$ m1 s
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );- W8 W4 q. l  I$ ~

- g7 N1 v; r: |7 a( ~: pBOOLEAN # G/ q4 q6 t5 I5 F" f9 I
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
. c% k% x9 a* k; s* @8 T/ G
7 x  ]- ^: _2 \+ aVOID 8 s( v5 v  ?, a8 T1 c! [: b, C
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
) G/ `! L) J; K1 u1 l  B3 R" q6 n, ?
NTSTATUS
0 [. U; P" G& X/ k6 |- ~1 rAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
- a& F/ e: ^8 ]                                  IN PDRIVER_OBJECT  DriverObject );
, [- k3 V4 f' k9 L7 @) W% I5 Y# J) R- O* }9 h
NTSTATUS
+ p! b. X9 @/ H( u: T, ?: ?AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
6 }3 B' C/ q, L( @4 |  K8 a, f2 a                                  IN PDRIVER_OBJECT  DriverObject,
7 q( f9 b  C9 S% Q- l                                  OUT PDRIVER_OBJECT* FilterDriverObject );
, q* Z( ~0 O6 e- Y+ {1 O* E* u* W, @$ \+ V( ]" H6 ?+ t1 l
NTSTATUS . X7 i$ M( C7 X. S2 W# V
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
1 ^9 P/ Z+ _) H4 d6 `6 \                            IN PIRP Irp,( w! g2 `2 z6 ~2 k( J& [
                            IN PVOID Context );
8 V/ H6 }9 J9 ]- g" }- V! |NTSTATUS ! |6 W  O% u7 U
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
2 X' h7 B5 s1 |3 y2 Q
8 B# c9 h! z& |2 q1 e" wWCHAR szUsbDeviceName[MAXLEN];
" V0 f* }+ i" }. ~* P( C+ ?- p
3 \0 k! R( C" O  b: L+ v#endif
! B  s4 E  p! w, o  i! x, b
1 Z: L  q2 e$ c2 X7 ~0 r. S" m2 I! g
9 i, Q8 R/ }' S9 f5 p1 W8 V2 z ) `6 e% J0 ?& p6 S
* E/ J1 w! j" [  |% B8 |

( q: `) g8 @* V& f- Z, d9 XWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。! s0 D! P2 p) n
WSS 主页:[url]http://www.whitecell.org/[/url] ; V/ Q" N% Q/ N. |9 ^7 Y
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-4-5 00:23 , Processed in 0.068691 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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