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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
+ \2 }/ k4 P& @) t# WEmail:   [email]sinister@whitecell.org[/email]
: T' g4 ~: p% ]8 f6 yHomepage:[url]http://www.whitecell.org[/url]
' z" j, B; n' M2 `+ x. jDate:    2007-02-26
8 e0 y% Q& V  y! G; s+ {: S
; M4 O; l! W0 _
* l- H3 B4 s( H! y( f/*******************************************************************
( s" o+ @. _1 C) w# ~( O
. [& n8 O4 T9 L2 }/ u2 c3 p这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
) u! p  k' W1 h2 X4 Y写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的9 u0 }* a  |1 _( V# R$ \. r
功能要求如下:6 @0 b# j. M3 F: y- Y1 H

) [9 ?8 q, Q% @* ~: e2 s( Y1、强制锁定键盘/鼠标。8 z9 R) @0 H5 Q8 u( Z
2、可动态加/解锁6 i4 S% D0 N2 h5 H% E( B
3、兼容所有 NT 系列的操作系统。
9 C% p- R8 ^$ Z
$ [: J' U0 Y- P5 R( O6 M6 j% I9 _就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
: W" Y8 q$ m6 t: n% E' Q2 G- U现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
; ]& C$ }. D" N# b; N5 ?何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在# ~) g6 V+ c5 @/ k
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
8 o/ E; {1 K3 ^9 J怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面/ w8 l# `: a7 Z) I1 y5 Y/ c! w, X
就来看一下我想到的几种实现方法:
/ {# i" H" K2 b" g+ R! W  t5 ?8 V+ I. }5 O' w8 D
1、全局键盘/鼠标钩子
/ U( M0 l: _( N) C2、BlockInput() API" B0 _4 H1 @% s0 Q
3、使用 setupapi 进行控制, u0 S" I+ _8 m) X- X
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
+ J( G2 D" f- j9 P2 S, C5、拦截 win23k!RawInputThread() 函数
& F; x9 |0 i1 K6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动" m; W7 H* {0 t& ]- H
7、拦截 kdbclass 驱动的 driver dispatch routine
* m/ t$ O9 z0 b) r" C8、实现一个 PS/2 与 USB 键盘过滤驱动
, y1 N; `, M3 e; c
2 j9 R4 u( l, r' X5 H& U
/ V/ u2 K: @* r5 a; s) h( O. ~6 {我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑# S& y+ W) Q  z5 n8 r& x
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
6 `: ~" A% o5 a  U: S7 q2 v案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在7 F! [& q2 \0 t( d& Z2 f2 }& A
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
6 b; d2 g. S8 S9 \( L素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
  h# d# U& c/ L( B4 M问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
) q5 ~/ Y4 V: [6 c载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我* O# i6 I2 S7 [. S, ]7 T
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
0 G( v9 O' u- E# }. ^也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如% `2 [+ R0 S& C5 d5 q4 ~" C# r
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有+ V* V+ n4 ^- R( E. H: ]- W
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
. P7 z1 ^+ ?( i- b: C* u" vIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
. C* q) h9 C- b2 tUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
- C$ s6 D2 Y  C2 F7 [盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
8 o% c7 B! f/ K' Q& N案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
3 I$ {7 M7 f, A2 |
( |) @$ L1 ~8 v$ x- M
9 L! d' A! [! ~* [0 f% x) ^9 s; v, p我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
5 ]  z7 N5 H( ?1 n# _9 l$ _6 m滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
- W4 W+ ^2 i, S! p行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
# O+ O- S0 {; ^9 C7 j6 b" p+ P& X只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
" g) H+ e3 c8 ^1 s' w来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从/ k. c: A1 e" h3 |  ?- z' i% {, n
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB3 s; E7 b% ~5 k5 z& J* Z) m! Z. y
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用0 M8 Z8 o" B0 X, E
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,$ j, ?, @% N9 Q/ M! B; I
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题! Q7 N7 G5 @7 I
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的0 w; D* J4 K( p, n3 R
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
# r( N* B1 J) q  z4 S, F用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通& `7 i! b* d! s6 @
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
+ d& A- z& ]( f8 v/ Q屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
9 a7 R( m8 C( y: b过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
5 V3 e+ p. g6 k! h! D9 t5 V8 g上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
, R" Q3 R% l5 }4 P2 Q的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意7 B% r6 u* n% M: q0 u
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
. M* g6 w. ^) p2 G3 F经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
: Z2 r; a) K+ p来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利  k- ~% e, f4 @% Z, l4 q, d
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo* ~2 G/ M$ [8 `6 g# o# X
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
8 G7 l" B) c+ ?# ^敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
& z" j9 q0 w# T, _8 N. m& C6 j/ J根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程/ x5 r- M1 L1 Q* [$ s2 q) t1 R
见下面代码。
# l. q& s. u5 I& f; z* c
$ i+ s5 N# C: r- }# W这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
. u+ L- j: |1 f* V里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键  h* F1 N" \/ X) M" P" X
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003  y$ k9 v6 L" N1 X  y0 e
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
9 A: V! u9 r( [7 k4 f完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可  U: F& b4 x: E7 ]$ x5 v/ U& r
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
. c# M: T5 H+ V  w7 T' c锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按$ B" B8 n0 I: M% K5 v8 Y! d
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
5 |" z( O" Y/ j: h8 ~6 [. K0 A' T; h$ @$ x/ G

5 c1 k( n! E+ h1 Y完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
. Z2 h. F; \& X) P4 @. J的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
. n$ U! V( Y0 X& t+ o: x/ e可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
! x. Z& k( v! ?9 T2 s) w9 P的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
/ F: K" M# H2 E* G# X们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
8 u* e  c4 F5 [' Z, Z8 O+ c/ X们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
- Q4 o# c" h) a  A% z->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。" ]5 `% L) g+ l, ^( n- K
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager: u+ a# z( X' [
进行操作了。这个问题有待大家来完善了。/ T% V# b) b7 X# h$ P' F
3 `$ ]* Z* W8 A$ ?0 J# O% V

. F* L  `' S# X. P6 h* O6 i4 B要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
8 U' m& `4 i0 y8 [# _来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的: y% B7 A- _% B
分析做个记录而已。我更愿意把它看做是一段注释。2 h  K4 m7 ?! o! v6 ~7 U" q9 v+ f
) U& B  j9 D  i9 \; e2 c9 g
最后在此代码中要
3 y" ~8 v8 g6 R  B  z/ Q( b8 N
6 W5 o' m: F8 D2 E& }1 O* w4 A6 P感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。6 p3 h' X3 ]' _* r$ K
% Y1 g6 F! U: F. W
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
4 k, B/ z$ i0 I  E, R  A8 S) ]. O$ R) I2 Y) u* w4 m
感谢:齐佳佳,过节请我吃好吃的。
/ C. h1 ^- f, N0 }0 X: k2 ?
& R4 I: v5 k0 ]
+ N* Q$ }( u+ i2 w3 Q******************************************************************/
3 ^1 ^* @# I: i* f: x. }# c
! G, A1 Q4 v0 {( F/ a
; T, b  _9 v% d  G/*****************************************************************! o; w( G  J" F! l' ]8 K
文件名        : WssLockKey.c# x6 m" S1 @1 a% g! U4 L
描述          : 键盘过滤驱动/ F) \6 z) s3 G: k! f9 X
作者          : sinister
* f5 u5 j2 p& a7 K# r6 x# l& I" b 最后修改日期  : 2007-02-26
" H/ z' }  t# S*****************************************************************/
, a: W% t+ X; v9 z/ y4 f  [8 H* |: b! J4 s3 B" u

" `9 y* W# u/ \, [2 Q/ b" o7 {7 a1 F' z#include "WssLockKey.h"
+ y( w- G) d1 h* f! f7 \6 f7 M0 [- `; Z- w' D$ v0 Z
NTSTATUS/ \+ {; S( q; Y" K8 Q# n
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
' B" c; t& t, t             IN PUNICODE_STRING RegistryPath )* y/ i% J' h5 k9 @1 f" Y
{
7 r  m- r5 P, P  }  UNICODE_STRING KeyDeviceName;
, f  l- D9 v2 d0 g( J  PDRIVER_OBJECT KeyDriver; ! y% e( e0 f; _7 o6 ?, x4 g5 P
  PDEVICE_OBJECT UsbDeviceObject;1 a4 d4 q, ?& g
  NTSTATUS ntStatus; - V1 a9 q0 `& ]& D8 r) o3 W0 }- c
  ULONG i;
2 c- \$ V3 J; F  q% \
" Q. C( u3 H5 o+ o1 p0 z& \7 ~  //: C6 [! f2 c: P* C( t5 Q
  // 保存设备名,调试使用
; ~- C1 z. T2 S& e  //# k7 _6 A9 Y; c: {& X
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
: z) k* p( I5 r; Z1 I8 ]# V1 o  {8 B. S- Q. k6 e, b5 ]$ r$ F3 d) `0 v
    01 `! G# F' e* U- d1 B* ^
  };. C; ]! o% [6 L
) _# H2 G! B% k1 A
  KeyDriverObject->DriverUnload = KeyDriverUnload; 2 K' Y$ G+ \0 `
' |# q; I1 f( e/ m; U* e$ z# p
  //4 \0 T) T* q- q! s7 K: c! w
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
$ T/ k! P3 V3 ~! K$ ~  //
' N3 }! i' ]  ?% C7 I5 X  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
8 A$ N, J+ U0 J  {0 {" _4 r; ^  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
: O& l; d/ \( r" b2 `1 c/ h  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到9 ^/ y1 S8 ~# o# Z) t
  // USB 键盘设备来进行挂接
4 J8 Z/ U2 O: i/ _, }2 {  //0 D8 G7 V6 \& o! O4 p7 t" I
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
0 g. \" t8 R$ o: c' p. M  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL ); h7 G( `, e3 x: [
  {
* T* e$ N1 D4 Q" f) ~! e8 G    //
" p" H% v$ O( ?( @2 n    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名2 s% i" U& ], k5 W$ E3 o, ?
    // 所以这里打印为空
+ ~5 ~* N/ J# p6 A! |0 V- X3 I    //
  Y5 C# w; D$ F/ R: q& H8 q9 Q& t    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
# J  O9 Q/ e2 |  i* G    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
3 U0 I, ~" ^+ U# Y9 z2 T/ x# \  G) P" I4 @$ m9 f! g
    //0 n; |6 G& y1 e2 c
    // 挂接 USB 键盘设备: t: w" Y1 ^: X
    //
( ?& ~5 O) G+ z: ~! b    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
4 @2 a; H" {1 F& r, s    if ( !NT_SUCCESS( ntStatus ) ); h8 A  @* A% ^
    {; F5 ?) E' L8 z# n1 i
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );9 _' K7 {# |6 ]
      return STATUS_INSUFFICIENT_RESOURCES;7 d# g5 h; V+ s: m" j  [' h
    }
9 ^' u, C5 G9 @4 A& ?& z  }% \0 {9 i& n9 W: D3 N3 }" ^
  else
' s" [. F! @) g  {2 j( ~& H- H: u+ U: W0 \
    //' W& y  F$ A* p8 t$ E1 d1 \
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
# {$ }! c- E' G7 I6 v    // # F" P. z2 `6 O) m  I& j9 O
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
8 S3 I& i- U* z5 D. @& |1 _  V- A' s. V1 ~" X; w
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
0 |( i  Y. q7 z- q' m( W5 {                                        KeyDriverObject,
9 I3 U! w3 J' z7 k. g, J" n                                        &KeyDriver );
" H# D  Z. O8 a    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL ). w; @6 k; a: i! W4 Z" X3 H
    {
0 @  s. m) M& _' I      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
- m& g9 d  C4 _* z) C0 a      return STATUS_INSUFFICIENT_RESOURCES;4 y( a$ D, z7 Y
    }
7 \7 N/ U' \( `4 z- V- x  }
. p% L* p) F2 g9 M5 p9 C/ N" D1 D
! g& ]! l( F/ Q  //1 C6 T' y7 r/ T! g+ C) T. N1 y
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止- b* S% h; i7 J' O. s  T6 P
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
, P9 O/ S' s  \$ ~8 b1 x- o7 s+ _  //7 f3 k3 n7 s1 S
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 8 d5 r+ {3 Q; b% x4 x
6 k: W) [, ?, u+ w& `1 Q
  return STATUS_SUCCESS;* F# H) S. l% v7 i" |# \" n/ Z8 l
}
3 ^* P# N7 G1 }/ h0 m( \
" d( g4 w; V! \6 y/////////////////////////////////////////////////////////////////
  a* }3 U: d7 l% V2 U3 ]) D// 函数类型 : 系统函数+ g1 c1 ~( G& c, D# I# @4 v9 P8 f
// 函数模块 : 键盘过滤模块  [  y  L! n8 I- [' U9 I4 k% {
////////////////////////////////////////////////////////////////# i- R2 V- r9 }
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
% E% Z: x; Q% d- c0 b7 `* S! h/ E5 f//        卸载键盘过滤驱动
4 l8 j. E' M! h2 k. i# v// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上& L* ^, G2 z% n6 g
//        则需要等待用户按键,以后有待完善2 M6 w8 @% d' w0 H8 i- p: S2 O" m0 |
/////////////////////////////////////////////////////////////////6 j8 F- _, b. G" V" R1 u9 O) U
// 作者 : sinister4 S5 Q( R& f4 h% T
// 发布版本 : 1.00.007 Y6 n* |  F/ h
// 发布日期 : 2005.12.27
- [8 |* j* ~8 l) w/////////////////////////////////////////////////////////////////8 a( N: u8 y0 B& g5 v
// 重   大   修   改   历   史2 Q6 b" e/ f( V% U
////////////////////////////////////////////////////////////////; x, j, F" x" P4 |
// 修改者 :
& U1 E  }! L9 _4 F  _// 修改日期 :) s* U/ I1 H7 U. g" c7 @
// 修改内容 :% ]+ t: m/ i- ~8 ^% @% x2 H
////////////////////////////////////////////////////////////////// \" U( Q) E9 C* r1 d

- B6 k* W! F4 L" \* b8 ?VOID
! k1 D, n+ y- ^: eKeyDriverUnload( PDRIVER_OBJECT KeyDriver )4 `+ m% B7 m) k- i7 S0 v
{/ }" K$ @- {9 \% f! ^& D
  PDEVICE_OBJECT KeyFilterDevice ;      
0 I- B9 P1 l$ T; `  PDEVICE_OBJECT KeyDevice ;
0 G" X' U0 I  m, Q  ?) q" P  PDEVICE_EXTENSION KeyExtension; * s9 ?: M9 I2 d1 Y8 T
  PIRP Irp;
( o9 H( d: G# @' f, r0 U" S$ Q  NTSTATUS ntStatus;
# V% q! h  e' n, b& _% S2 N6 H9 C) l1 a! T5 Y2 ?; t( a* n
  KeyFilterDevice = KeyDriver->DeviceObject; ; X/ }& B2 J0 g6 Z: J
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; ' ?( c$ x' K6 o
  KeyDevice = KeyExtension->TargetDevice;
: ~* c% F+ U, s6 j: D& ~# ]
+ Z6 S3 S1 |8 ~) R  IoDetachDevice( KeyDevice ); 4 r2 l5 r$ ^% |' R. M% J
# h/ w) B/ c( e, H: w) m3 N
  //
& p" T: M7 }/ \2 `  ^  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP6 C; s* x# k' y! H
  //$ _. y/ ?' s5 L. {2 K
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )* s, ~' I/ z4 j7 D# J2 G4 l
  {
6 U" Y& c- X: {" }    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
  v3 K0 N+ I6 {    {  j' y: U8 U' K8 l% M
      //* C9 w3 G: v8 ]4 H1 G
      // 成功则直接退出删除键盘过滤设备
. R6 e! s  L( O0 u5 C2 b$ V0 O      //
7 k" D9 h7 M( E% N      DbgPrint( "CancelKeyboardIrp() is ok\n" );! v) L5 _- }- Q# L% m
      goto __End;
0 Q' k, Q5 J" g8 x+ y    }
% N7 ~- r5 V! y) d  }" e5 P# Q. k) y0 X& b. H  j$ T

+ i8 Y" m, z) m- n  //
# u4 a; u" \: V. u  // 如果取消失败,则一直等待按键2 a( ?. N; @2 @* z# N4 R
  //. i5 \. k# J' Q% T7 F
  while ( KeyExtension->IrpsInProgress > 0 )
! q% L1 Z4 h6 r* X  {  i+ L; h# k, ^# `3 F1 ^& A
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );- f1 x- u1 A0 c) s6 ^
  }/ G- O* V4 Z/ f! L9 ~: J6 H
3 Z* Q9 Y+ w& s  \
  __End:
* i4 s! `" Y: r- q5 Y& `  IoDeleteDevice( KeyFilterDevice ); . t5 \* v" S" t
  m( H9 C% }) ]. Z( j5 u
  return ;
' K& N6 X& d3 A" b" y7 l} & o6 J* g+ P: P  n5 h" b  h
9 I; C$ ^6 P6 i$ y
/////////////////////////////////////////////////////////////////
8 h: r) Q+ A1 Z2 \7 s2 \1 n1 x# j// 函数类型 : 自定义工具函数/ o3 W; S4 W$ E
// 函数模块 : 键盘过滤模块( n) s. \# n* {) Z. K) i8 q( H
/////////////////////////////////////////////////////////////////2 R' |5 l/ b  a/ N* b
// 功能 : 取消 IRP 操作0 M, U3 j$ g4 \) v
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能! O+ X6 @+ H( L( M) C0 G* q2 R
//        使用此方法来取消 IRP
  I9 K" Z' r" G6 w9 Y3 B$ L/////////////////////////////////////////////////////////////////- M& J$ T0 \  d3 m  D! s2 M
// 作者 : sinister
3 K- u/ X9 C/ q+ ?; j3 E1 C// 发布版本 : 1.00.00& N! U- B: d9 M
// 发布日期 : 2007.02.20
" {! S7 W% l9 ]. q/////////////////////////////////////////////////////////////////) X7 ^6 l" _6 V4 f' C9 |; a
// 重   大   修   改   历   史
, R( j' M  j2 t, W4 F! Q/////////////////////////////////////////////////////////////////
, t8 t( r; V+ f2 j0 f// 修改者 :
8 p( W- [6 |3 A# |6 I" r( C// 修改日期 : 4 D; W6 a) |0 f! K2 r
// 修改内容 : # ^$ H0 W" W% R( N$ k! |
/////////////////////////////////////////////////////////////////, v; o* Q3 u( U* Q

; p& `5 e& D' J, @# m: B  gBOOLEAN. Y) d, N! M% e' T6 C! g6 W& w# v9 |" B+ q
CancelKeyboardIrp( IN PIRP Irp )9 C/ c' }' H/ N$ @( T
{6 w9 n% j3 p' d$ Q+ [
  if ( Irp == NULL )
2 K1 P' k* g" Y' a" W6 h  {4 w7 h+ \& |( d' O& q' h1 |
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );# E0 B, @- o0 \! A
    return FALSE;
3 H. h6 u, ?! N- I  H  }
1 c/ Q+ h( b/ f+ \/ y2 W9 T! d6 H8 e! ~$ q4 i2 h+ z# P" L
! I9 D& d1 P  x$ k! y% y% Z
  //
% ]7 `2 p2 F) \% J- f* d% p  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,, W) I9 y' _- W- }/ w0 b
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。& k/ i5 q, e; Y' u$ W$ r9 t) S6 ]
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
$ L1 n9 V. X% B. V  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD- }& o( G+ b2 @. t8 G
  //
1 z' {: G5 D$ B5 M/ ?
( r0 {3 l* p3 T. o  //. j% d# c; L5 N4 e# i# C9 X
  // 如果正在取消或没有取消例程则直接返回 FALSE& G: F( r! L4 Q# V- h" C) [/ H6 ]
  //
# W; z3 q: j; w0 ?  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
; N$ l+ z! T( z  {/ o( m4 [, {, M9 `; P
    DbgPrint( "Can't Cancel the irp\n" );% E0 l# o1 w+ m( h& K2 Y
    return FALSE;. [+ k, b* P, {
  }
8 M# Z5 f  Z+ h( V( d  ?4 c
. z* D1 r9 h5 k, r, p9 @  T  if ( FALSE == IoCancelIrp( Irp ) )
% [: I/ P: z5 R( Y6 u  {
* L5 o, j, a8 I+ j- r$ C    DbgPrint( "IoCancelIrp() to failed\n" );
+ z$ N0 n3 K- ~5 h6 ^! d3 j    return FALSE;$ X; E- q9 h; D2 Z
  }
# L# `: v, Y' x3 p# t1 z2 l
* f- \! s# i' f  U( ?  p  F: s  K  //
3 I2 V/ _/ |9 Y/ _2 H  // 取消后重设此例程为空
: f$ T7 ~% J7 N# T  //
& H0 B% o- z( P  IoSetCancelRoutine( Irp, NULL );9 |0 S! C" P# }7 y4 l! d1 k
9 U; C- A- Z1 G& f% O; l' O
  return TRUE;
$ y" @- o% S9 V& m}
( P/ M' e# d6 B1 e% A2 J& V
7 }! r9 ]  q% a/////////////////////////////////////////////////////////////////
! \8 O  p5 l# D% K7 t. @// 函数类型 : 自定义工具函数
. f9 O# v; f/ C. f+ V4 `// 函数模块 : 设备栈信息模块
7 ?3 e8 S7 `* I: f* K7 F9 e  q& c% ?/////////////////////////////////////////////////////////////////
/ T! W% |* {1 x4 U1 f& g, M// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
5 V% _/ }* v" X- f" _//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver). ^" o/ B' O; K, z) t9 n0 s# w1 Q
// 注意 :
1 N6 ]" p" f9 w! `# P9 n, q/////////////////////////////////////////////////////////////////
. Y1 s9 l& Y0 a5 |5 {# X; D( e// 作者 : sinister
1 h, j) |: H0 ?1 \) F0 G" W; O# S// 发布版本 : 1.00.005 `9 W( k3 b4 B9 ^7 H
// 发布日期 : 2005.06.02
' c- U/ a3 ?1 g8 j/////////////////////////////////////////////////////////////////
8 s0 [  K( r1 d2 D" h4 ^// 重   大   修   改   历   史- G8 g; V$ X& w% ~3 H
/////////////////////////////////////////////////////////////////4 y% b& ^$ `& e3 A3 I
// 修改者 : sinister
' v' h3 |# I" g8 ^, B6 r// 修改日期 : 2007.2.12' Z+ ]& J) f. M6 w6 m9 E3 ]& z
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改$ [& p& D# C( C8 U+ b
/////////////////////////////////////////////////////////////////  C  x# u' N0 ~

" M- q7 c' n! r: NBOOLEAN
$ h& Z# ^2 a# a# x8 D$ q. h6 mGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
! h0 I; E3 D: [$ J# J4 ^* ?{& o/ c) @1 }6 ~
  PDEVICE_OBJECT DeviceObject;8 t- X: j& C1 L/ b
  BOOLEAN bFound = FALSE;
( U9 g4 }% M3 R# W4 Z8 h
# \' Y. a* R# V+ ?4 i! e6 N  if ( DevObj == NULL )
2 c. e5 p% J+ w# k% F  {! F. D/ u6 ?* M+ W5 C4 f
    DbgPrint( "DevObj is NULL!\n" );3 l9 W* `% D; \" N, _2 c0 c7 J2 i" c
    return FALSE;
6 y2 b7 U! x& [. _) f  }
# ~: q% k" y8 l5 G, }) ?( P& y; l& C
  DeviceObject = DevObj->AttachedDevice;6 o: s( u( H$ s
) @$ U% y* p- z/ `) ^5 W1 `+ x1 j. S
  while ( DeviceObject )6 u5 p4 \# h. m' G* Y* H1 ?6 K
  {
; t9 T' b7 V% K9 `9 x    //
5 h4 w! ?& m  Z, M/ [    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但0 A3 ?$ r. `- M
    // 有一次足够了。这算是经验之谈! V3 {+ E) m$ H0 L  b9 I
    //
; J& m9 f0 Z6 t1 y  B    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )/ G, }$ R6 s& ^- _. j- X
    {9 t, m! I1 ]. A
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",! t$ J& ?3 V# T4 u+ V6 e: P
                DeviceObject->DriverObject->DriverName.Buffer,( e0 t& L( l$ `" c
                DeviceObject->DriverObject,1 m; ~8 f, R1 K" X- O9 E9 _- l
                DeviceObject );. W: Q* W5 i! ~

4 J" m. L# }- T# c' F) A0 a  U0 d      //
; E! Z" @: X: G& }& j+ \/ H      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
- A8 q) u* h% X0 N( s4 Z      //) j" i* E' r4 b- c/ y: C0 X4 |& B8 R
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,* D3 S9 D0 L* j" j) v
                      KDBDEVICENAME,
& r* R# N. \1 W7 r                      wcslen( KDBDEVICENAME ) ) == 0 )( D! n5 s' p, q# a8 E( t
      {6 S: \% |1 C1 H7 n
        DbgPrint( "Found kbdhid Device\n" );4 g, q" \$ Z3 P- T, ?+ ~
        bFound = TRUE;
8 t2 }, t8 o$ f        break;
- a6 z% b" n* R+ O7 S2 e0 q      }
; V+ s) q2 }. w! i    }; Q. R& f: C% K& O

, J' H% T" _+ S( j3 X! g  o, L/ b    DeviceObject = DeviceObject->AttachedDevice;! h! G' C4 F6 ~2 x) |
  }
9 G8 v% }8 f7 k# h2 |* ?1 B& u. g8 r) T: @& c! E6 v$ }
  return bFound;
% s9 F! k9 d- @, ^0 f) a8 }  B}
+ i3 ^2 i4 |# D: F% c6 K* m! b+ p. X2 ^( p+ A$ ~. U
/////////////////////////////////////////////////////////////////$ |3 _& H! N; T" e9 k  z
// 函数类型 : 自定义工具函数8 y; o- k& \) h3 M& {
// 函数模块 : 设备栈信息模块& i# z4 i! @( J0 q, L( t. N5 d& ^
/////////////////////////////////////////////////////////////////
3 G  d; R/ q# o// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
4 s, L% R" C& B- b- |// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改1 W4 u$ m; t8 H. u& W
/////////////////////////////////////////////////////////////////- J( f8 Z9 m9 c" s5 r% }# M
// 作者 : sinister  a% r3 T' V% R4 W! s4 `6 F  F
// 发布版本 : 1.00.00$ s3 W6 d$ r6 s, v6 y# i/ X% u
// 发布日期 : 2006.05.027 d( h  G3 ?, y7 u5 k
/////////////////////////////////////////////////////////////////
# ~2 o) r. y6 K# l// 重   大   修   改   历   史
+ N8 R4 b: Z0 m' g' ~6 a- B+ |4 }/////////////////////////////////////////////////////////////////7 K. E9 N: d8 M$ q
// 修改者 : sinister
3 z+ r/ B+ o$ o9 S5 l// 修改日期 : 2007.2.12% L! s& o; l" y2 }$ r' i" \
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
- f9 y" b- S/ w  b0 E- z+ b/////////////////////////////////////////////////////////////////5 d; k  E6 h4 N, T6 F2 l
) d5 c, F5 v: N8 |: W
VOID
& L( J. }2 p- s  ^GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )2 f- w" ]- ?$ o% }: F
{
; P+ l0 ?6 h/ b# V; p  POBJECT_HEADER ObjectHeader;2 c- O; c0 w  a) z- y8 `& ^
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
" k! l& t9 p* z: u+ Y8 Q, n# m% {  F. f: `  U; S) {
  if ( DevObj == NULL )
: p& Y7 ?( l5 _; Y9 Z  {9 j  u; D! J" e" t* q
    DbgPrint( "DevObj is NULL!\n" );" v0 A" y3 p- ?( c: j
    return;
9 i/ T( {6 U  h6 H; m+ n  }, P7 [1 b6 `0 L
4 C" T2 l1 E; f) d
  //# j1 [& m# b# h" ?/ O" f6 T# `' d
  // 得到对象头
! z  |0 K2 r$ Q/ l  @% T8 Q3 T  //
( P+ d2 o1 u5 R6 G$ Q  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
) p2 n; ^1 _  ?* c8 x! N6 y9 C2 V* d' R+ f- S/ D
  if ( ObjectHeader )
, i) z  D% j" o' R# G, B# L- A8 N3 D  {
, @& G  c% l8 N, A0 U. \3 E    //
: {- s1 d& r/ F% a    // 查询设备名称并打印/ q. M% Q3 H( _9 w+ _2 c% g
    //' @! K6 |  u$ N1 N) W
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
% O( T; m  ?, v" X$ G8 _5 T+ Q0 W& d+ V& Z& D
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )$ u2 s9 f& Z7 g/ _9 Q! C
    {
9 u8 e8 i. z% F% y4 w* @' L      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
. T( Z8 t( |; b5 ^3 R" {                ObjectNameInfo->Name.Buffer,% Z, c2 t" W9 n- o5 s  u
                DevObj );+ y# _& O3 P% d2 h- x

7 [* g$ D5 x: K9 G      //
' A- _' T8 U2 j4 S+ H; v      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示# D$ \$ `) W; T4 ^9 Q" J1 j1 h
      // 用,没有实际的功能用途+ `; ~" q( Y; c7 o2 k
      //
- D6 y- Z/ ~* I; w6 O+ S      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );+ D( p* i- U- z$ z3 t) `0 A
/ p4 h- @. D; L/ a- T
      wcsncpy( szUsbDeviceName,
/ q4 k0 ?: T$ g3 S  v, J* `               ObjectNameInfo->Name.Buffer,4 z  R- v& X- ^
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
  r4 u' b( A- F" S- o# A0 ~  d    }/ c4 }& C0 U5 `
) g9 ]" k* o0 M$ G/ h! Z
    //5 k/ W' d4 S; N% p  C2 I1 z
    // 对于没有名称的设备,则打印 NULL
& y. u! {. b" n    //" Z, M% ?- K$ [  [: O
    else if ( DevObj->DriverObject )
2 I* t( h! n' ~1 N! f/ Q    {
9 h1 b+ b2 h9 e/ ~$ n: h, N/ p      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",! t3 k& q. N8 e
                DevObj->DriverObject->DriverName.Buffer,
" s3 d' `* p' {+ @) {                L"NULL",
8 e; D, Q& i, w7 O                DevObj->DriverObject," B" v  p% X+ e0 t
                DevObj );
, Z4 k8 ?# |; W7 I! i# v! B    }
2 ^6 u1 I" C/ g+ D2 k/ M; ^3 F  }9 u2 p: o$ h) o
}
) ]5 z  J! A  _% ?6 m/ H: d4 G
% o0 A- T* e6 v- w/////////////////////////////////////////////////////////////////
4 ^$ J% Q9 R8 E; G/ F' r// 函数类型 : 自定义工具函数  c1 m4 ]9 O) q/ ]4 c' p1 D
// 函数模块 : 键盘过滤模块
# k$ @' h1 F$ l7 p: u# E6 o/////////////////////////////////////////////////////////////////
" U+ T  s+ E6 A6 `! X& v// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备" j) t9 |: V, p
//        对象,过滤出 USB 键盘设备,将其设备对象返回8 P1 h- J3 ~  Z3 q; ^  D) G
// 注意 :
1 V. E5 i" K3 b4 d8 u& P: _0 y' R/////////////////////////////////////////////////////////////////
5 e/ |' `$ p- ~1 u' C2 A// 作者 : sinister
$ F6 C9 @# b( x) b$ ^" i; n4 }; ?// 发布版本 : 1.00.00
3 n( b2 {, r7 }( F1 }1 A! L* R// 发布日期 : 2007.02.13
6 w+ d" y% b+ A. q$ X/////////////////////////////////////////////////////////////////
- u6 h- C4 E, U; g/ u: k! h, ~7 r// 重   大   修   改   历   史( g, f3 y( t6 [2 d" b6 q
/////////////////////////////////////////////////////////////////8 l8 I5 o) r  E$ H. U: c
// 修改者 :
/ T2 w- y, {7 ?# V4 a  b0 j// 修改日期 :   C, O  j( b. T
// 修改内容 : 8 q( C9 H, ]# w, e
/////////////////////////////////////////////////////////////////1 M! v( @  @) N/ F! n
) `2 ^  w7 t$ f: A9 D
NTSTATUS  K6 J; r- q* ]9 T5 i
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
# X0 ~1 v8 l0 i! {% U- w{
" w  m+ w! E: T0 Z* i3 |  UNICODE_STRING DriverName;" F7 w8 F# z" ~: A
  PDRIVER_OBJECT DriverObject = NULL;2 t- s" w- j" B/ X
  PDEVICE_OBJECT DeviceObject = NULL;& o" C1 y& h1 `/ ^9 Y; Q
  BOOLEAN bFound = FALSE;$ b. K- Q$ n) O7 v
  O" J4 Q" e" t* ~
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );$ @( r+ q  R4 d/ r

9 ~' o. i& c, h5 s+ v' s  ObReferenceObjectByName( &DriverName,  {* D- ^9 e/ w/ p
                           OBJ_CASE_INSENSITIVE,
4 B) Q) F4 @% G8 @9 ~                           NULL,6 C, J/ x( Z$ @# t: e8 n5 T0 y
                           0,  C1 g) E: H6 C& M7 S& J3 O
                           ( POBJECT_TYPE ) IoDriverObjectType,0 _4 l, v* B0 ^) E+ Y
                           KernelMode,
7 C) F) U/ I. h! L                           NULL,
! \1 q: r) \' W6 h& {9 _                           &DriverObject );
- Y9 \  O& S+ m- q" ?" U  n& N  |8 ]% y/ X* e
  if ( DriverObject == NULL )% ?) Y4 ]) D" J% J* A7 |
  {
% y) _* E# M5 @$ S) G' z- C0 A    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
; _( I  ?7 Z; n! e    return STATUS_UNSUCCESSFUL;
/ g  E" e4 K( g' A" k' i/ e  }
$ e4 w; I! O; O0 |5 D) D+ h9 G) X" h. u! i# n1 J7 O" R; ]1 A
  DeviceObject = DriverObject->DeviceObject;9 w- w, f  Z5 G+ I0 c' ?5 Q

  R: F, W; Z: U1 S( i  while ( DeviceObject )
1 Z& G0 S9 Z+ e- T  {
) G" a# c# j2 W. K/ A4 g6 ]2 M    GetDeviceObjectInfo( DeviceObject );
* k8 t: w: j+ z6 _3 ?' f  {, Z5 g8 i+ x2 p/ A8 q; J  M' i
    if ( DeviceObject->AttachedDevice )* l/ k( }% Q* q9 T  }" O+ r; j/ Z
    {
  d, w/ `9 C( y$ o      //
) W- ~( l) s$ _- S8 y9 v      // 查找 USB 键盘设备
+ I* b* P, m0 B/ v2 R( e, b2 r      //6 D' R5 n# F4 [' D
      if ( GetAttachedDeviceInfo( DeviceObject ) )+ ]7 Q- M2 {+ c/ f3 B; k5 A- @3 S
      {' \- `% j' {( X) G- G1 S! L
        bFound = TRUE;
" o7 i) J+ G+ m% Z4 a+ O/ G1 {) G        goto __End;$ g; r4 x+ K, Z% t8 c: e. S$ Y
      }+ _( k/ p& `; @; o* o  I( V  {
    }0 ]" b2 G- [) s1 [: k

: W# z8 h3 _: y$ x    DeviceObject = DeviceObject->NextDevice;% B/ G. Z5 g4 f& q# b
  }1 W; b( o4 T( ~2 K5 X& ?* I8 @2 D. X

7 l' S* b! k9 X2 [5 ~1 e8 ^  ]  __End:5 q/ W8 z# G( ^6 a6 y
/ r9 y$ i9 ~  M! D, ~! _
  if ( bFound )" ^1 ]& ~& j8 P! w
  {
3 `$ S! }- y& I8 P* G" p    //
& ~, t5 i1 E, |* u: z    // 找到则返回 USB 键盘设备对象
8 L( F3 `  H5 d$ j9 c    /// u* Y7 d  F) U
    *UsbDeviceObject = DeviceObject;
1 e" U- _9 A8 ]9 d) n% V: r6 q  }! [' }2 {; I, H! s
  else/ b9 x, ?( |" B( }( c
  {) {8 T0 A7 C% T9 }5 c# l
    *UsbDeviceObject = NULL;
) w. r8 P2 |3 ~  O% w: z- {  }3 B' M5 P* e; O, s4 h; [

7 |1 U9 D9 C' m  return STATUS_SUCCESS;
4 V" G8 e$ D  k}
1 a' d" w% m. T' w# q. U$ T- S
( k+ a# B. ?9 O+ {9 L/////////////////////////////////////////////////////////////////# r. n5 ]: D! |* E
// 函数类型 : 自定义工具函数
) l; B  v! v, A1 l$ ^' b// 函数模块 : 键盘过滤模块' j: J8 {" P5 x/ M( W
////////////////////////////////////////////////////////////////( u1 C  f2 j# |8 U
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
8 V- L7 X$ Z4 n. k3 J3 k& M//        信息,返回附加后的驱动对象" k: T7 ?3 w, z# `1 V: V1 H& B
// 注意 : 此函数仅挂接 USB 键盘设备
2 ?# _/ j$ Y! |7 C0 n( E8 B/////////////////////////////////////////////////////////////////
' Y# K2 K3 C7 M2 O( L// 作者 : sinister
2 W) s( H3 P" V, s- C7 F1 a7 f4 t// 发布版本 : 1.00.00
7 p  K7 E, [5 ?% I8 S// 发布日期 : 2005.12.27
! P4 d. b  ~/ `, E4 j" l! ~9 z2 w! ^/////////////////////////////////////////////////////////////////
) j; `" r' Z; z' C// 重   大   修   改   历   史
/ k0 ^0 S1 m3 y/ ]" ]) E////////////////////////////////////////////////////////////////6 D1 z7 H2 d: t2 r
// 修改者 :2 b1 O% p1 n/ x; C0 t* X- U  _
// 修改日期 :$ x8 I; @$ D3 i+ t
// 修改内容 :: q7 \- P" {9 C# H* i
/////////////////////////////////////////////////////////////////
* n) h8 S8 \5 Q, t5 F! o. G
" t2 I& v% \3 I- B. nNTSTATUS- d. Z/ d# `, {1 ?+ L
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
0 p' [5 i. y4 u- K$ I3 P                         IN PDRIVER_OBJECT  DriverObject )
  }9 |3 K" q7 D# u3 K9 }{
. q4 Y1 f, ?, b, H/ |) U  PDEVICE_OBJECT DeviceObject;
& o0 M# d2 b+ r3 k& ?6 `! I* O  PDEVICE_OBJECT TargetDevice; & U! i! W; I. Q" e
  PDEVICE_EXTENSION DevExt;7 Q5 o7 h0 m# S( r  C% |
  NTSTATUS ntStatus;* ^# m2 n/ h9 a5 {
7 K5 U; `4 |! b* `4 o  |
  //
* q5 B4 ^) ^' e* q1 v' \  // 创建过滤设备对象: @* l3 E0 e4 A* Z1 A% ~/ R
  //) Q8 L$ g" s1 I2 c! |
  ntStatus = IoCreateDevice( DriverObject,
0 g2 t1 q# M9 Y5 y                             sizeof( DEVICE_EXTENSION ),- @* B% y7 v  ?2 Z! U; U, {
                             NULL,; G+ {: o0 j; b( s
                             FILE_DEVICE_UNKNOWN,
) ^+ L/ Y% f6 N2 w                             0,, F, P; q' ]0 N
                             FALSE,
) J- q7 ]' r3 ]                             &DeviceObject ); 8 n  ?5 d; |8 J8 e' {

- g8 K* G/ r% ]) Z, d  if ( !NT_SUCCESS( ntStatus ) )
3 Q# ]* V- Z% e( `9 G* ^  {9 y/ V% A) C# ^6 K" o
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );+ {# e# E) o5 i4 r
    return ntStatus;
9 E2 ^( U5 f5 x/ w6 j  }
+ z/ m/ O! b8 @, V6 K: T' F7 @! `& Y, i  G' k. j) Q' l
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
0 @; `7 g+ H: R  ?
5 V0 C* i3 e; g+ L4 P& G7 K" G  //
1 z& r7 T6 a/ R/ M, I( Y( R0 p/ f  // 初始化自旋锁1 R% s+ R5 ^; L1 ]" |+ ?
  //
1 g! _/ g( q" z  KeInitializeSpinLock( &DevExt->SpinLock );
3 A2 T5 I. K  M, u" S2 S- V
& R. X3 G& o0 ]) g  //) D3 Q8 B. `0 z4 T" G. X8 l: |
  // 初始化 IRP 计数器2 E: G) j" A+ E7 @' ]. Z2 `
  //. ?! L( j% ?$ Q- o6 T4 n. d2 t- g, I
  DevExt->IrpsInProgress = 0;  R' E' Y' b* K/ m* k+ v& s) ]

$ ]3 x; D2 R( a3 F  //
8 V* y$ `# I! J, T' L" F  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
/ ?+ w( c! n2 C$ E  //
  @6 P4 a# B/ r. Q; V3 y! B  ^
' e1 n4 o  q( l: ~6 a  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
" R- o3 D# m2 \! q  if ( !TargetDevice )1 F" A9 Y+ u( s) z: U* _
  {# f$ Y! x0 A. n5 m1 B* U
    IoDeleteDevice( DeviceObject ); ! y: k" n$ S# X" q+ }8 x- d
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
4 f! f5 Z4 S$ Z% `3 c9 }* c# m    return STATUS_INSUFFICIENT_RESOURCES;+ l0 R1 T/ [! O3 u* @( I( D
  }
0 D: N( `1 U. P' |$ H( @7 O; X# Q8 r
" G4 e. t# x& Z; I. h3 {( G6 u  //
) k/ O2 _) c7 x  // 保存过滤设备信息
& l+ E: }( K4 I% L% ~- [  //" y4 L( T6 I0 j2 Q6 T! E$ z$ E8 x2 z& `
  DevExt->DeviceObject = DeviceObject; ) _4 Z# r0 E; f4 ?. U% a
  DevExt->TargetDevice = TargetDevice;/ |' K% k+ K8 O, J0 O# ~

# `% T! w+ N$ u  //
8 S$ t. b6 ^2 J/ ~: u: `  // 设置过滤设备相关信息与标志
) x! W0 J+ a! x: n3 O  //, z; m$ _: z& y# n
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );, v2 S: H4 C* m8 G( `$ Y8 i6 S0 X+ R
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
5 {" b% t$ _4 e* |" j+ _, ?& o  v% {( E' ^7 g

/ R% n6 E- \+ m* }% y  return STATUS_SUCCESS;5 Q  _. U& f$ ?9 y
}
- Z5 ~* v' }7 C1 f9 O
+ Q0 z) }& p7 Y. C% T2 P6 ?0 O/////////////////////////////////////////////////////////////////
% [, l# y. y4 J// 函数类型 : 自定义工具函数
4 X+ f* b; `0 l6 y4 G// 函数模块 : 键盘过滤模块! l0 \3 \7 u( J% N7 H& p/ g
////////////////////////////////////////////////////////////////
8 a7 `2 N, F4 k% p; ]. U) ?2 M8 b* j// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关" A9 r7 Z2 W0 c. Y
//        信息,返回附加后的驱动对象
# b4 ^: i5 G! l+ x! |// 注意 : 此函数仅挂接 PS/2 键盘设备8 H: o7 v! F( ?& a' l
/////////////////////////////////////////////////////////////////
2 t$ F7 Z- Y. S! {$ j+ |// 作者 : sinister
+ Y; x& U1 ]6 z6 v. I) i// 发布版本 : 1.00.00. Z3 ~3 h6 Y1 w8 [8 m
// 发布日期 : 2005.12.27
# J! ?4 W! U" o9 X/////////////////////////////////////////////////////////////////
# O8 H) T3 \; g$ b% f( l' C4 Q$ x// 重   大   修   改   历   史
) [" n  v/ ^8 }* D////////////////////////////////////////////////////////////////
/ M% y- q+ X' E- R! w// 修改者 :
% \+ p4 p1 L. w4 e* X. R// 修改日期 :# H5 t4 M3 W. k  C/ W% f  I
// 修改内容 :
5 F  N- j# G" o9 R+ M/////////////////////////////////////////////////////////////////$ E6 d6 u3 l+ Q+ B( H) P! [% F
! G$ F# W& e: O0 ~) f) o( S
NTSTATUS5 J: |, m& R( \+ ?$ q1 v
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
, |8 h$ ?* r0 h2 S% M) m                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象1 r% N% v  x& e4 }0 f+ z0 @
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象8 C$ l1 i6 g/ ?8 e  z" o) S' G
{2 p! [5 a; |! V6 B. x
  PDEVICE_OBJECT DeviceObject;
* T' s, D+ q/ ~! O  PDEVICE_OBJECT FilterDeviceObject;3 A! v/ I2 N  b2 P' u+ X
  PDEVICE_OBJECT TargetDevice; ) _( l. q; @) y$ r
  PFILE_OBJECT FileObject; 6 ~3 H/ B# I2 A8 ]* h
  PDEVICE_EXTENSION DevExt;
# ^' h* \$ o# i3 {! @" q8 `; \: W2 f, L) n; D
  NTSTATUS ntStatus;
  j6 ^4 J) D1 }, T! Z% x7 n
  c. j- ]8 v( g! u2 q3 Y  //1 i* V5 K, [& K8 A: e5 d2 z
  // 根据设备名称找到需要附加的设备对象
; C" k; x! D, Q) O" p* R  //# }* F& m) W1 s. E6 P9 b9 @- U
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
# A: s% ]  w* v0 Z: i3 p, l8 x! }                                       FILE_ALL_ACCESS,
" p! f: y) _/ y2 D                                       &FileObject,
! z) i9 n, X9 E) v9 ^                                       &DeviceObject );
- N, h' m5 S. z- j! n+ c8 A# q8 r- a" U
  if ( !NT_SUCCESS( ntStatus ) )3 |) m( ?2 i3 {: }2 U, X: `( U' T
  {/ L( }( N9 w' u  o! n* \! n" S# o
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
0 V: Y  D; z$ t! K# `    return ntStatus;
; y0 w- p0 |3 B  }
4 Q. t0 A2 W$ w' e* c! C$ I8 V" ]% a3 {9 ^3 E8 t
  //
# E! J2 Y) y, V/ A  // 创建过滤设备对象
5 @/ r+ z9 K4 ~1 o+ e  //
6 _+ _% G2 @0 J8 k  ntStatus = IoCreateDevice( DriverObject,5 J" e- Z0 ~5 y! W! j& _: t
                             sizeof( DEVICE_EXTENSION ),$ z$ S0 k  a* W& @8 V
                             NULL,
* _  ]  e$ v: a3 `5 D                             FILE_DEVICE_KEYBOARD,
' C) L( m0 Q1 g$ e. a% G                             0,3 j/ ^  r1 M4 h$ A; v5 F* X
                             FALSE,
; ?/ m" C+ v% ~+ _  y* H% m" h                             &FilterDeviceObject ); ; y! p/ F2 G' ?6 K- U' j0 M

# O. K$ B* @; e1 x9 k  if ( !NT_SUCCESS( ntStatus ) )
, G1 Z9 V3 G, E0 o4 s  {: P9 V* B7 C$ ^
    ObDereferenceObject( FileObject );
( C' W# _. T' [0 B, C    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );. j6 S! n: m* a* A8 i
    return ntStatus;' q$ f! f8 I- M. B( w
  } " l' k/ ^/ g+ [8 h

$ u( C& d8 u; r0 @  //
6 Z) \$ a3 L& \  // 得到设备扩展结构,以便下面保存过滤设备信息
2 P( A; _. l3 y/ C  //' ?# m6 |4 N5 U8 c0 a$ d8 g# [* ?- q3 Z
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
) L9 B. g, |( j$ |$ D9 t5 V8 j. A+ P4 K

5 ^- E0 W. |! Z8 ?  //- \/ i! `& x/ Z4 O
  // 初始化自旋锁7 a8 p, B" O7 ?- B
  //
/ H+ g) i1 ]8 C* W8 A9 H  KeInitializeSpinLock( &DevExt->SpinLock );0 D$ D% V( ^3 T& u  _; ~: i
0 \: b- n- L  ]9 b+ F2 {7 h2 f/ p
  //' K: N; r+ y1 o! t" B2 q$ P
  // 初始化 IRP 计数器- A: R" ^  U& G$ {+ O( E3 W
  //; U5 E5 _' E+ ~8 u" N3 H: e* ?
  DevExt->IrpsInProgress = 0;
5 h; ^. n* F. ?: Y6 C' T
+ n8 o& i1 Y$ H  ^& t- e( F8 P. q  //
8 l8 U8 h6 K, C4 h$ `9 q8 W1 D7 I, r! G  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象8 a& H) N0 [1 B5 O9 o
  /// o  Q  B6 z' z5 B5 a9 o! I
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
5 e4 F) `: S) e: P! R- U: H+ e                                              DeviceObject );
. K4 p% F2 p. t1 f# x" ?8 n  if ( !TargetDevice )
# `- ]0 b; o/ X# Y: A  {$ \& k3 [- y$ _5 H) o3 ?5 T- D0 p
    ObDereferenceObject( FileObject ); * c  x, b% V7 t1 G- {
    IoDeleteDevice( FilterDeviceObject ); 3 Z$ _( @0 D8 t- G) K( Z( z* }
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
! N9 f" R/ d  b& o" z    return STATUS_INSUFFICIENT_RESOURCES;0 i" D, Z1 t7 B0 ?
  } 6 h# k, y5 w% ^

, n- k5 {' \1 I$ H  //
9 M" N" l, u9 C- C! w& z, _  // 保存过滤设备信息
- x# s0 {/ \) x: \1 l  //* P6 `2 Y% P% `/ N" ~+ N
  DevExt->DeviceObject = FilterDeviceObject; 6 v- N5 d8 q$ Q( h3 }4 J+ w
  DevExt->TargetDevice = TargetDevice;
8 q& [: c( d5 g: }. E  DevExt->pFilterFileObject = FileObject;+ Z9 X4 l  z8 |5 u

2 t1 ?3 B( d) t( \4 T+ d+ T  //, U' N1 `7 ?$ Q$ E. N3 E
  // 设置过滤设备相关信息与标志! P7 f" q2 D& b- l
  //
: @' @, p/ S( V  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
. C1 E+ n/ @& K  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
4 [1 f0 N# E8 q7 C  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;: M- X  @3 L2 Z: b- S
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |& a! n. |3 p% s+ ]1 ^6 g6 R
                                                         DO_BUFFERED_IO ) );
9 d# @5 N4 T- |& h3 O) k% [0 d: l: V8 n# g0 U
  //. ~) O8 M2 R0 D  ^9 R
  // 返回附加后的驱动对象
; q' `! r: N: k( Z8 ?% V  //. z4 ^% `5 j# D. w# _7 G0 W- h4 L6 ?! `4 c
  *FilterDriverObject = TargetDevice->DriverObject;2 j& @4 }  x! ~. P/ K3 v. b7 J
6 p- x* v2 v" f% L4 H& H" @$ M
  ObDereferenceObject( FileObject );
0 D2 V; I2 ~- l
3 L$ M4 S( x* `! ?. t9 S  return STATUS_SUCCESS;, J! y- G% U8 O- B
}6 X% N7 E) ^! Q  M

- F% y1 s. ]; w5 Z5 q: z! Z/////////////////////////////////////////////////////////////////
" E, p- T/ U9 w, M9 U0 a// 函数类型 : 自定义工具函数
) _. X+ p! n0 H# R% J  |// 函数模块 : 键盘过滤模块
) _4 T& p. F1 b1 @////////////////////////////////////////////////////////////////
6 x/ N1 v7 B0 S- ]) ?1 a5 W// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发0 n, B5 y2 R, {! r
//        这个 IRP 的完成) E7 |3 e7 y* V+ O
// 注意 :
" ~% [( y+ _' f  ?: P' B+ e2 F/////////////////////////////////////////////////////////////////4 l: O1 x  ]. p+ f3 v8 p5 H9 R
// 作者 : sinister% I" d- L2 W+ ]% I  L# G) K
// 发布版本 : 1.00.00! N, z0 G2 J0 H, ]8 a
// 发布日期 : 2007.2.15
. X8 T( c" N7 t" Z2 X) e/////////////////////////////////////////////////////////////////
4 Y' J8 J, ^5 h& D0 {8 ^// 重   大   修   改   历   史. h4 h- e  k  O. e
////////////////////////////////////////////////////////////////
7 D) d$ x" a3 ]// 修改者 :
% N0 x* U' Y/ w1 S" E; R// 修改日期 :
  q2 L! ]7 D2 X3 V// 修改内容 :$ |& u+ m9 h% N3 j8 p
/////////////////////////////////////////////////////////////////9 t7 d. L2 o; O6 m+ G+ p
1 O- l" n& F* _- ^  `; w
NTSTATUS" ^; Y6 t5 g* ?5 Y
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); T8 H8 h4 H' X  b( O% z' h+ k
{
7 S6 p1 W" X! d7 N  }. f1 k  NTSTATUS status; ! Z; E$ U- S& T0 T  H8 j7 x; i9 G
  KIRQL IrqLevel;
: T5 c# F( O7 T: w/ u7 i+ u
& k* ^  O3 Y+ N  PDEVICE_OBJECT pDeviceObject;9 s6 \8 `! L8 l9 q) d6 d4 ]
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
1 }6 O3 K# C: k: d; ^5 Z6 H                                   DeviceObject->DeviceExtension; 5 z, ~! G& V$ Y8 S+ S

* d1 |( b- k) A' {% J. A1 T5 O1 p1 ~7 _
  IoCopyCurrentIrpStackLocationToNext( Irp );
3 [% N# W! ^& A0 ~- \
" d& j0 j4 j3 e9 c- i/ S4 _  //
$ ~0 D# m: M  I; w% P) z# }  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁+ }3 u% R* G* ?7 W$ X% g6 L  Z
  //1 Y% G9 v* C. O' Z% X2 a+ c* O$ w
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
  g4 @. ~2 R. @1 J- t  \  InterlockedIncrement( &KeyExtension->IrpsInProgress );, a% C8 I( Y  u$ f; Z9 l2 x
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
9 ?( t2 u9 ^& J! _# H
3 h" w2 S; C2 K6 c4 @  IoSetCompletionRoutine( Irp,
  p  U7 X: V0 |0 z* ?, U8 \                          KeyReadCompletion,
4 e; K0 `2 }. c8 c$ I                          DeviceObject,
1 O9 l* H( r3 W7 g* X+ L                          TRUE,
: \: _+ y: X0 }4 T# N1 P, y4 b: g                          TRUE,
5 e2 @; O. v' S+ v  J4 j  r                          TRUE ); - X1 {$ u$ m) y% j; }
9 X; q, ?1 i( x+ W# X
  return IoCallDriver( KeyExtension->TargetDevice, Irp );& U; t+ M, a+ ?6 I" g* u
} + N  ~$ E( R3 f  g

9 ?+ a. K( i% Y) I! V) @; ?* k2 b/////////////////////////////////////////////////////////////////
$ w# ?: s# K2 M3 j// 函数类型 :系统回调函数
6 e, N0 a# T. r1 H- U// 函数模块 : 键盘过滤模块) Y; z; n  i$ f& }9 {  F  u
////////////////////////////////////////////////////////////////
2 i+ m8 A4 S0 s  h6 V3 o// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
9 y' i+ B: W; N5 ]; p0 c// 注意 :
" q0 U* p2 h/ z: Y1 c* w/////////////////////////////////////////////////////////////////8 l# ~1 |+ j7 k; I0 P" N! E7 p
// 作者 : sinister' h8 x/ F+ {; N) q! S
// 发布版本 : 1.00.00! ?" t. x* `% p' K; v) w0 Y
// 发布日期 : 2007.2.12/ q( a9 x4 }9 [; p6 \
/////////////////////////////////////////////////////////////////
1 s" _1 `) ^6 j$ ?// 重   大   修   改   历   史
: |& i+ \( x' R! R3 u, q////////////////////////////////////////////////////////////////( z: u* W( N$ f  I3 F$ i
// 修改者 :2 e- a1 F' e" Y' k7 S
// 修改日期 :$ A; ^* F3 b8 Z) u: y- N% B6 ?
// 修改内容 :( D3 d3 O* S0 f% ^( M
/////////////////////////////////////////////////////////////////1 S. a; W5 g$ o0 [  v

/ N* M0 V+ ~" ]4 N. R3 L2 h6 Q! QNTSTATUS
' S% [" j0 Z' P& u- O4 oKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,& h3 m& ?' s% E* H9 N
                   IN PIRP Irp,% A+ I6 B0 X  h1 h. |+ n
                   IN PVOID Context )+ d( Y) B- A9 J  ?) w+ j
{+ y! i% e9 s4 z9 S8 |
  PIO_STACK_LOCATION IrpSp;# w5 `$ i: c  Z: T/ \+ f+ f
  PKEYBOARD_INPUT_DATA KeyData;* ^3 F- _6 _% U; p
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
" T& v8 {3 ]$ }5 b: o( ^4 W8 }                                   DeviceObject->DeviceExtension; / C+ a" n6 ~' a( H$ i4 a. c/ t4 n
  int numKeys, i;
5 D1 X% m- ^/ i) C$ P  KIRQL IrqLevel;
" b$ w$ x$ l3 }7 ]! @* d) ^& H/ Z5 x6 F; Z' n, q0 ^! y" K
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
; r. ]9 j" i8 s& ~
7 _6 S1 K1 ^5 |/ t* D5 N1 Q5 g3 M$ f5 J' b* B
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
7 M" U9 U( _9 [3 C2 _9 H  {" b" n& x) Q! K6 i# {7 w9 H; y
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );0 y8 V/ F( @& E) z
    goto __RoutineEnd;
, k7 l1 P% u% j8 {' n% q$ v* e5 n  }8 v, I! D' _8 Z' m5 ]& T
2 t( Z! K( \% u2 l7 Q) {5 N
  //3 W# v/ @3 W  `; a- [3 [7 U1 }0 I
  // 系统在 SystemBuffer 中保存按键信息
( {, z0 `7 e& V  //
. i2 z; `  V7 U# H$ k2 C  KeyData = Irp->AssociatedIrp.SystemBuffer;
( U5 |4 F/ b2 t# L; _8 Y1 L  if ( KeyData == NULL )
+ }, p* A* n& t% ?  {( K% e+ Z, R2 S% w- m' B% |! [
    DbgPrint( "KeyData is NULL\n" );
+ B: ~6 _* e, X: s9 G    goto __RoutineEnd;
3 J# C# P" K9 h3 U  }# {3 n, j8 d0 B( }
) F& b, \. |: l3 l# r0 ?& r
  //
$ C0 n: b4 H1 E- ^) X* J  // 得到按键数
; `+ E6 b* C) x1 N7 f+ o5 _  //( j- h' q1 y3 L+ I9 Z
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
. N6 N: j) m* }& b9 b# P2 q1 v  e  if ( numKeys < 0 )9 y$ W) G& t3 ?% r4 g
  {$ R  I" V, o7 H) G. L
    DbgPrint( "numKeys less zero\n" );. U: ]1 e7 a  {6 k5 B: n% b
    goto __RoutineEnd;7 A/ M4 {3 z) C- {+ \3 ]6 C
  }
" L6 x4 q- B- \- L9 e; |( ~
# G6 r$ x( A, I+ _3 N  //
" X/ c+ S9 e1 t  // 使用 0 无效扫描码替换,屏蔽所有按键% V! p( q' V. B0 v, y
  //, A$ L* z% t2 H# t- T% }
  for ( i = 0; i < numKeys; i++ )
5 V' k7 L/ W: j4 M8 T  {
6 h) n. }% z0 U. @/ }) A- s. h& M    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );4 A7 c0 `. w1 T7 M* m, E
    KeyData[i].MakeCode = 0x00;: Y+ R# V3 }2 e2 T  G5 a! s- H, g4 \3 s
  }
% B1 U' a3 Z' \  \% n8 I5 S, l4 O: V) \" }# P2 v. S" h
! A. d! p" P6 R% a- s
  __RoutineEnd :
$ R0 R; }2 d% J. g! s/ d# N! q2 e+ j# _% h. b5 d( e5 y5 P
  if ( Irp->PendingReturned )$ i5 w" |1 C4 y7 _
  {
6 L  w. G8 W3 s: ?9 v) z    IoMarkIrpPending( Irp );
6 c% I, h, t) l2 ~1 E  } 3 e6 a, X9 q! ~$ ]" y

9 T+ n  a# |/ o' ?4 [0 z  //
5 Z8 ^! U+ S1 D% V. ]  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁  B) N. W0 ?/ P: h2 ^9 S4 D" K% B+ [
  //5 p7 _4 c) A8 L7 M, K
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );2 r; y2 E" L' K$ R8 E
  InterlockedDecrement( &KeyExtension->IrpsInProgress );) R4 A+ x5 w3 q+ L. T& d
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
' a, u3 v. G; M* w. y8 P4 z- _! w
  return Irp->IoStatus.Status ;
. X& j" \& V' |) P; a}
0 a' n! I3 Q" D: U% N8 Y: z8 B: D2 A( J" ?$ \  i6 e4 ~* S! @

9 i1 [9 b5 N0 M# _7 K1 D% x/*****************************************************************2 ]( M4 e7 V4 K$ i, _% G
文件名        : WssLockKey.h! r* W! s8 w' l
描述          : 键盘过滤驱动; k, C2 T% x$ u$ s& X4 ~( ?0 a
作者          : sinister
( |: d; T5 g# J  B! X& y" I: X- M 最后修改日期  : 2007-02-26
9 |& |' ?' a# |*****************************************************************/: ~, ^; B$ }, q$ O9 m: ~
' d% u2 R, i) l  S2 f
#ifndef __WSS_LOCKKEY_H_0 f. E3 q( e9 T  h3 `  k
#define __WSS_LOCKKEY_H_
5 i, N6 b, h$ A2 q5 p2 h+ A- i
2 K- ^* G9 x* k) p#include "ntddk.h"
! r1 @4 I( l! G3 H# c; D#include "ntddkbd.h"/ R. Z  }1 D. R$ [+ k+ s
#include "string.h"
' e4 n8 I% s  w% Q6 u#include
/ z0 x8 S( ?. D* w* L, h/ l
7 M) T& [! w7 m#define MAXLEN 256! ]" Q2 e" d% Y4 r3 ?( H

  W  H" g+ L, V! F) C& k. f: n#define KDBDEVICENAME L"\\Driver\\kbdhid"+ L" V' m& e- u8 s& g8 J
#define USBKEYBOARDNAME L"\\Driver\\hidusb" & k% K& [" @4 ?8 J' O
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
0 B  z! o8 u9 f8 v! l0 E( R/ W9 T! E% w
typedef struct _OBJECT_CREATE_INFORMATION
* _) k2 ^. F4 L* u4 g! }{' e( n) A7 A7 y  W2 ~  }
    ULONG Attributes;3 ?5 e  R. T" x/ Z9 W
    HANDLE RootDirectory;
% I  @& P0 h9 C: j    PVOID ParseContext;7 Y. s* A7 a6 P& a: b
    KPROCESSOR_MODE ProbeMode;
  Z7 w( B6 r' a' C8 \. K5 p4 b    ULONG PagedPoolCharge;
4 H: [" \- N. y4 [    ULONG NonPagedPoolCharge;
' [/ D* t- T! X: v, W    ULONG SecurityDescriptorCharge;
6 g2 `$ v8 `: b% e2 j1 w    PSECURITY_DESCRIPTOR SecurityDescriptor;1 L7 S+ y8 P3 n
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;3 X+ y+ p. [8 z4 Z
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
$ O7 k' O6 P; S% |9 {, O# ^& e' _} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
6 d: S9 R: h7 U3 d) I" w
' i4 M: S! O3 ltypedef struct _OBJECT_HEADER
* o' g) h8 B; Y' n8 ^, U{
4 y8 `" m6 U0 E/ x8 i  ~& j    LONG PointerCount;0 y0 Q2 W- l. A% p) K# L
    union
# m6 ^# q9 j. s" }: Y    {) E0 |4 P: `  y' X/ s6 Q9 g5 Y$ U
        LONG HandleCount;
7 L9 ^9 e3 m5 Y7 P4 \! s        PSINGLE_LIST_ENTRY SEntry;
& {+ @! X$ Y5 u. M% k    };
0 Q1 B: Z6 ]1 p$ F0 q+ \0 v    POBJECT_TYPE Type;, v$ t9 p4 _! m
    UCHAR NameInfoOffset;: z& P  G- K7 p0 D) ^3 b* f
    UCHAR HandleInfoOffset;4 R" J& U* @# Y$ b
    UCHAR QuotaInfoOffset;3 d- y5 Y  Q8 L9 v/ Q
    UCHAR Flags;' A" B" N3 l. K. O( ?
    union6 M; }" \; C: E1 `: ^
    {1 V: b2 T) v/ Q6 [+ m
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
" m+ B$ X3 H" Y% q' r: |' j        PVOID QuotaBlockCharged;
; [+ f5 t# M& p& }    };
0 k4 T% M* b3 i# X
2 y, O# {  E) W% }  \. v9 {    PSECURITY_DESCRIPTOR SecurityDescriptor;- V: w8 g0 U  ~2 G9 r- s
    QUAD Body;3 e; p# E$ Q6 ]7 K3 o
} OBJECT_HEADER, * POBJECT_HEADER;+ M4 N3 O( R' O3 R- l6 d! T

+ H/ V' m( P# J: u" W8 _#define NUMBER_HASH_BUCKETS 371 d/ n5 g( V3 p
0 \: F6 [. Q5 t, G+ z& h
typedef struct _OBJECT_DIRECTORY! \9 z! y* s% f3 v: K8 H
{
8 i& k+ y4 d. L3 J3 X; z/ v    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
2 Q2 [7 |5 g1 V+ `" ]& Q    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
1 [9 v* o/ {7 ?" F, f+ I    BOOLEAN LookupFound;& `5 t: a/ @5 @' x0 W
    USHORT SymbolicLinkUsageCount;
  y' n0 Q: D+ F8 T: K5 T    struct _DEVICE_MAP* DeviceMap;
' F8 F. H# f, x) }. @7 z" }$ N} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
* l% m( x8 p7 M/ O. n4 l/ T! |" ]/ t6 w4 s9 A; Z0 [
typedef struct _OBJECT_HEADER_NAME_INFO3 s# e8 C# Q! Q( X& L; M+ O
{
* d# s) k& ^8 g% p' @: L    POBJECT_DIRECTORY Directory;
! M) H9 J' p5 j6 F    UNICODE_STRING Name;
% w( u' Y2 Z# {- @# K( p1 V6 O    ULONG Reserved;
- t$ O8 V+ t4 k. m$ Q#if DBG* x  ~; o  v1 W9 h# e
    ULONG Reserved2 ;
, P0 I& v  O, r7 ~' A$ H4 U0 j. ~( c1 y    LONG DbgDereferenceCount ;! Q* J9 ^2 y2 y" ~2 g& q
#endif/ \3 B0 T7 ?5 p( ]
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
7 L! z. ]+ d5 B) p8 K+ Q) [# c% t3 K8 j7 ]6 c
#define OBJECT_TO_OBJECT_HEADER( o ) \
' R' c) y! `, N# H2 N    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )% {" [+ W+ ^" i4 ^2 A; b6 l; d
4 j, c6 q7 k3 a* l7 J" Y* @/ E
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \' D" N+ D. |! V
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
. J: c% d( Q4 S5 I# l
9 y9 X2 q1 h3 i5 ~+ X: Wtypedef struct _DEVICE_EXTENSION. C. k/ a2 F' O; W2 W/ A) ~
{
, o; E3 k; p" J! ^6 p. p2 \    PDEVICE_OBJECT DeviceObject;1 \' p* R9 Q  B4 _- l
    PDEVICE_OBJECT TargetDevice;
" X4 i0 ^5 H. x    PFILE_OBJECT pFilterFileObject;
8 E) _. p- w  G; C( ?    ULONG DeviceExtensionFlags;
) G' m' o+ v* C" h$ o    LONG IrpsInProgress;
8 _0 n# K3 d9 M0 I' ?    KSPIN_LOCK SpinLock;
" z5 U, i( e% A- a& J}DEVICE_EXTENSION, * PDEVICE_EXTENSION;2 D+ p% r2 c  f6 p

: z; [3 M! c3 \8 h! T
$ u% ~" D, E+ D8 O4 c) h  VVOID
! p8 l1 k& ^& n- C" }& tKeyDriverUnload( PDRIVER_OBJECT KeyDriver );6 w# V! a4 W8 m+ e) e* A

3 r# h4 K' V4 p8 b8 oBOOLEAN
2 U3 d) H7 Z9 JCancelKeyboardIrp( IN PIRP Irp );
! s4 a, }4 X$ X9 H2 t
( r6 J0 V+ X# }: xextern POBJECT_TYPE* IoDriverObjectType;
# ]$ S3 n9 p8 C( [" g% K$ j
% X, g" g7 |1 j9 o1 wNTSYSAPI
3 P2 R$ M" h4 v* Z. h, yNTSTATUS0 o& ~. T( ?4 M9 U# S. L
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
" \; i8 s6 b# K( J7 G                               IN ULONG Attributes,
3 o8 Q5 a: j5 H$ N( p5 _  I& D                               IN PACCESS_STATE AccessState OPTIONAL,5 u" _/ q4 D: g% v4 G7 E
                               IN ACCESS_MASK DesiredAccess OPTIONAL,6 m7 q  C7 M2 E9 B: x7 P, Y
                               IN POBJECT_TYPE ObjectType,5 G  u" ~9 d2 D: n+ a8 S" P
                               IN KPROCESSOR_MODE AccessMode,+ B' z+ v. V8 b4 e9 p
                               IN OUT PVOID ParseContext OPTIONAL,
( u' l/ l. y$ f: L9 r% q                               OUT PVOID* Object );( O( Z# f* m/ D. F+ a) N! i4 o
( |) H: ~5 `& m! B8 D' t0 ]
NTSTATUS 8 W6 R% ~! }$ d: g" b
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
2 ]& J1 j* R+ K$ f: W: F! z2 z0 d+ w5 d" F$ q! v4 A6 R
BOOLEAN
/ c- o- R- U8 E1 ^GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );0 h: U8 K0 B& l; z
; B. h' H1 M2 b) k1 j' [" {8 f
VOID
8 r& g# Q, w; o1 U- L% RGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
. O, V' T3 I9 C7 J
$ x8 N1 ]8 k: t/ s( u7 lNTSTATUS   S& X# G* r% T0 M& F1 P  q
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
6 H* j) Z0 R' X1 \. \5 n                                  IN PDRIVER_OBJECT  DriverObject );- V3 s$ D/ x7 L/ L" v* G6 K1 M/ H0 X

1 o+ f3 N( `- j) GNTSTATUS 8 v* Y) }1 n6 g6 A7 G
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,8 _# S4 Z9 E9 }5 r! X: h+ f
                                  IN PDRIVER_OBJECT  DriverObject,! o# U$ t3 r4 Q- U: B8 x( a: N
                                  OUT PDRIVER_OBJECT* FilterDriverObject );) C4 L  `6 I# l- z

3 x/ Y4 M+ C. U) `4 f, A9 T( D# d! {NTSTATUS
* I6 I( m+ h/ h- D1 u3 [KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,( ^/ `# I3 C" |8 C
                            IN PIRP Irp,
, P4 S/ W! O- i                            IN PVOID Context );
# W4 {+ }1 j# g" V2 j1 _; W5 nNTSTATUS
7 E2 e/ p3 Q; E: C$ g5 Z" MKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
& t, G7 y8 ~- ~% w; C8 i& I4 r9 l5 `7 w  W+ W: C7 g2 o2 D
WCHAR szUsbDeviceName[MAXLEN];& E+ P% V! ]: \1 P# d2 e- z( l
/ g5 i5 w  Q# u0 M' c" t
#endif6 {7 U0 \/ l6 h
% q9 M" t1 a( |5 S) S) [% v& b% }
( S4 w# u9 u; p3 O' W
) W- W  G4 r) S: [
3 f/ M& B  N2 t6 y7 Q' A

' I% M4 J. T$ L' m! L; \WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
8 m2 J9 E+ s3 `& e, e: A3 gWSS 主页:[url]http://www.whitecell.org/[/url] # B2 H9 k; n! l  J
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-10-20 10:20 , Processed in 0.112254 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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