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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister/ m  f) j2 e" z# T+ U
Email:   [email]sinister@whitecell.org[/email]
) `6 V! I- o6 ^7 j/ }) S+ A1 lHomepage:[url]http://www.whitecell.org[/url]
( q7 y$ l/ P9 [+ H) q! f# CDate:    2007-02-269 g% g: r  [4 o( ]. W% h

* E/ H7 o( t2 [8 q
9 H9 h( s' ~, S" A/*******************************************************************
- F) t' q; X4 P+ W$ t4 M
6 l/ n; ?( x8 b% o5 t; n这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
1 Z4 Q2 P2 q4 w( y写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的5 i& P6 l' Y/ F1 P* U+ B9 o' V+ h
功能要求如下:* i6 e- q8 ~: B7 R' g

' q1 [4 v% X: X+ ?3 m1、强制锁定键盘/鼠标。
3 r% a2 ^5 q* }2 f) E$ q& k1 r5 o2、可动态加/解锁
; D9 ]& w; n) S  @2 g3、兼容所有 NT 系列的操作系统。. P# z: f2 R+ ]

  A! S" [0 O/ p4 ~9 a就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实4 k+ [# A& M, e0 J; D6 q
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如+ G8 P7 s5 n0 M6 U. N  L
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
/ f$ R0 [4 Q+ ?; ^- G# {) m上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是) V" b2 h1 C* `+ ]# d0 O1 [, O
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面+ n/ t/ N) x3 I! o  F$ x" x- l
就来看一下我想到的几种实现方法:
5 E' `  A$ P- h& h9 |' W5 p  D! b/ \
+ _+ W7 L+ ^  R5 _1 ?1、全局键盘/鼠标钩子
) q( N3 F6 d: H( s2、BlockInput() API
  V$ V; R0 p9 s3、使用 setupapi 进行控制3 r/ ?7 B4 A3 m) H9 X: V) n! d0 Y
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL" Z1 x1 S& ]" u# }% W
5、拦截 win23k!RawInputThread() 函数
9 K+ e4 M6 U6 Y$ Q" c6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动3 T$ ]8 U- m0 e5 ~
7、拦截 kdbclass 驱动的 driver dispatch routine/ S6 i- o. M. b- e4 F6 R& p
8、实现一个 PS/2 与 USB 键盘过滤驱动
- F4 B7 y) U& E  m
$ S) e. y$ Z( \% V# z( U% M4 i1 N& V( E
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
* f4 R6 [4 b8 Q9 h% f之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方; E, s5 G: @0 P& d
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在+ R+ G8 |. H( j' {5 {
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因! p7 [: r8 {" x% m) t
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性  D5 h4 x+ b; a: Q
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸! ^, L$ E# X9 n0 E, E
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
/ r/ Y  u' w8 f/ T8 @' P% r的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来- @: e* s- l, E5 b( T
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
* ~+ V) w" s& ^果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
. Z0 S0 _. Q" |+ T障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
( \5 S3 D% u( |9 z" uIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
4 U; L7 e( p1 i: m  M2 n3 wUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键4 e: a) p8 D+ l0 y( F7 X1 F
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
8 Z% c, R& X/ Z案的全部功能且不存在它所带来的问题,否则就没有什么意义了。# G1 c: t* r) ?# |: {) a

5 W- ?9 A. D1 Q8 ]; x
' @9 `8 h! Z$ F我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
  Y. L- }" G' X& a# F滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进7 u' I* e1 `4 P. z& _$ Q! f
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
  `2 J8 Q, F7 X2 o3 l  f" J只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
7 C: P  G2 L; Z9 U& r+ |1 ^" ?3 }来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从- _- \( Z( I- F% `, P
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
  k2 S: T, N2 E' l2 w+ q键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
/ |0 W) {7 v% b7 |IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,- I1 r! Z4 H; g6 ^1 d0 l& a7 K
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
) l. Q# |! y$ D# V就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的) G+ v4 W* U4 Y' G0 I
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
+ g- T7 e5 P. o用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通: ?. Y3 q$ C4 h
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
  M1 A7 }4 w2 [( F; `; A屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通0 N/ {$ C2 R( l) C# f* _
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb# z  U4 O) `8 X* `( x$ L' k( }
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid ) u9 n. l$ Z0 _7 B! p
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意1 `. {, h3 V: \, |
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。: V1 y0 x3 H4 {; n( @& T1 _; d
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们& t2 _4 P5 A7 v7 Q& H$ ^
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利4 y4 r+ Q3 ]8 C2 |9 t2 H; F& z
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
) G* A: T/ d* E的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
5 {9 W, R: c0 A& B" X2 N; t敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,* `/ Q1 ~5 r4 t9 q9 g; t9 k
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程+ a2 g  X" Q6 L
见下面代码。
& H; o5 d. N. X; U2 R4 q/ C' A  w* B% `2 i( G
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程* A- B* Z5 {: D
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键* k3 [3 r7 Y5 o$ \5 Q
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
( }) t0 |1 x  j) W( q7 d上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有2 V* O9 G1 ?5 S# {$ l
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可: e! v1 O3 G9 I' U- y8 v
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个# z. t; u9 m- t2 T8 E" N- ]  _% Z0 U
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按1 F# Q) R8 H' x: R9 L* u: ~# Q
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。7 U) G; V: `9 M
5 [: c5 x' b. p* [5 \# P. ~

, D5 a' u8 {- H完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
! G9 R4 ?$ ?: ~# Q/ h4 p+ R的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是8 {2 E. G# w) D& i3 Z- `( ]/ K
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
  c% Y8 F' a5 s4 o的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我  x- S% d) x$ x& r+ o. _! ^3 V5 ^
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我; |+ F9 V2 ?7 [- {8 O
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
- w" g9 `, E3 q6 t2 @0 R$ H- L->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
6 d- b$ t5 \1 y) \# g; v9 H) u如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
3 ]; F% A- g+ C4 j9 I0 ^9 g进行操作了。这个问题有待大家来完善了。
1 V, L7 C/ e3 `- m& J
, q, w4 P9 G% t7 y) [% `
. l( m) A3 n+ G3 P! k8 Q要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出& z% M' G4 w' \9 x2 V( U7 t6 o) |
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的8 `! B. w7 r" y& ^
分析做个记录而已。我更愿意把它看做是一段注释。5 W9 K7 K/ f& z9 l
# _+ z- e& t6 ?+ a  m3 }0 k: h
最后在此代码中要+ P' S1 a$ w& U
' m5 D$ f' w2 x0 i, Q
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
8 J9 [" y+ D1 z9 ]% n* b% e6 y7 r) }! c* B+ F
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
0 T$ a( W+ O. y7 s: {9 q0 P; h& S8 l5 v; C" M
感谢:齐佳佳,过节请我吃好吃的。
5 S3 F8 Q( V$ ^+ j( k# y% H  h0 a7 W$ E$ n1 A* }

; D' c% y( J+ C7 Y& m, T******************************************************************/" ]2 q4 W! ]+ E' ?

) L# i8 B' H$ g4 i3 W0 t/ @9 ^& H9 Z4 r7 {% F) |# Z
/*****************************************************************; e* g9 Y5 `# k+ D5 o! Q
文件名        : WssLockKey.c( |% a  c/ `+ a% J- C" ?& h9 ^6 }
描述          : 键盘过滤驱动
6 G% o1 ]% m5 P3 G8 v. n" p 作者          : sinister
4 M7 M5 ?$ }' {9 b. q 最后修改日期  : 2007-02-261 x& M% I' M, K
*****************************************************************/
6 N1 P( j# N+ F, z4 \2 K+ ^/ U
" X6 l- G7 ?6 K5 @% `
$ l4 `6 c  b- S; b% ?7 r4 r#include "WssLockKey.h"
3 A2 {5 t. y5 M" k
( h" P1 Q0 W5 l3 J7 aNTSTATUS
( z: K; j6 R& N3 ]DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
9 V# N7 B2 e# k* S5 {             IN PUNICODE_STRING RegistryPath ); }; @6 q3 V/ G  ^
{
% e- h3 N: {+ E4 c- j- t8 _- }  UNICODE_STRING KeyDeviceName;
. S$ T: L% U  W& }) b) p( G  PDRIVER_OBJECT KeyDriver; 6 w  O& c& \  V5 o6 w
  PDEVICE_OBJECT UsbDeviceObject;
% G$ ~# B' r  i4 ^  NTSTATUS ntStatus;
6 g% _% `' C% @) t6 n8 @% e) d# v  ULONG i;
' ]& x2 U! `5 V% ~+ V  l7 U& F9 D2 E; |% i
  //3 q) o& m4 O4 c8 I- Z7 y5 ~
  // 保存设备名,调试使用
% P5 G# W# ^: O. i( e. i4 y5 ~! H! ]  //
& G$ P. q- {. u; B& n% {! ~8 P  WCHAR szDeviceName[MAXLEN + MAXLEN] =% n7 H% L( y9 x( \* g; Y% N6 {9 D3 U
  {$ u" N; J& e" e! N
    0% M; @/ }5 q2 ^. [" q8 f8 O
  };
! L0 S9 `- \0 X. Q/ }) K
2 u; z' {- B- Q) [! \" D* ~  KeyDriverObject->DriverUnload = KeyDriverUnload;
6 q: s8 e' [) F' `/ e( W! \% {8 P( R8 }/ G
  //
. ~- f3 O! c6 h: ^+ _  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘" a1 F/ n0 T* U( }: Q* d' ]8 L
  //
' h- g  C! A' M$ L! b  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
% O4 I5 o; L8 `6 j" `% c" l# k0 J  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
+ b2 H: ]8 f7 L; z1 `; w& i  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到. X7 ^) Z* m7 A, b3 B9 N4 k
  // USB 键盘设备来进行挂接/ e. Y& g: L$ X8 Y) c) @
  //& r+ W6 h, W2 I! m7 i, A$ v/ A0 h
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
% V" F; D' L6 t( Z; U+ Z& y  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
( E1 {, l4 X2 }  {( r. ?6 L2 v& Y/ g* d. Q
    //
$ w. C, {( E' o! Q9 i    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
! e6 H( K0 H- C7 F# y1 X3 F    // 所以这里打印为空, h2 G0 y, k) U) g( i) f: g7 G+ u" j5 _
    //6 p+ M1 G7 C4 L- }+ D7 V- W
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD4 K. z) p" a& [6 E& N$ C
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
6 _- m/ R. {6 q+ y: u+ {) J$ p+ k+ j- @" P, }. ?% A
    //
# Y" C) @3 [+ |$ y    // 挂接 USB 键盘设备
. B4 f- ~  c; ^( @: U5 I, ?    //
2 t0 g$ A- o7 P8 K2 Q    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
! Q/ [3 d) |2 ^% }    if ( !NT_SUCCESS( ntStatus ) ); s  U8 H* Y. A5 X+ n* J/ |
    {! L* ?0 `$ a6 f2 o) {( w
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );- c! T! i, f# X$ s- |$ y# N
      return STATUS_INSUFFICIENT_RESOURCES;
1 v5 E7 h( `- m! z# {    }
7 P4 N( u( ]& W0 ?; R( L. @  }
) X5 x) L. F% z4 c! i" i6 s/ J  else. p' J  F1 s) i6 t6 A0 t
  {5 i! h* y/ o2 `& {& `
    //* x# m  B/ H5 z- {% Q. y# v
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备+ x5 x/ U8 X. f" X1 Y2 o
    // 5 E, {# k; n. _" s  H, F; v( T
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
- Y' B1 Z0 w+ j% ^+ q6 V% g4 r' W3 ]( H+ z6 r
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,& d3 Q3 D2 a% e7 e+ g& U
                                        KeyDriverObject,2 s* J1 R2 ]9 D5 v* p' W, p' ]
                                        &KeyDriver );. ?( D+ H; i  v
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
2 n) P; \9 q6 f1 b! w: `    {
0 d4 j) p9 C, L# B* @      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
0 u% f$ h4 y% F! q      return STATUS_INSUFFICIENT_RESOURCES;
4 A) h- `  R8 B; `    }3 k; j8 i# K7 J, J6 o
  }& a% j; U' ?' y) [, x

; x' @# _6 s4 }! L9 o  //
5 @3 F; G2 S: X  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止, z% o8 r2 B5 n5 [* I0 M
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程- O' O$ [, `8 ~" r
  //
) f: K+ ^' v: w* z  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
! \/ N, s3 h+ w( j/ X) w/ y
8 H( b( n$ h9 C9 W, E  return STATUS_SUCCESS;
& {. t2 P9 Y( s/ F} ) {& f9 Z& ^6 n2 y
" z, a" K  a6 Y1 B) `
/////////////////////////////////////////////////////////////////
' M% Q0 p* D- M  p8 L// 函数类型 : 系统函数& u$ ]8 d4 p  Y; f+ [' W5 C( x. _6 E
// 函数模块 : 键盘过滤模块- S, D5 u" I6 E' K, C9 |
////////////////////////////////////////////////////////////////
& u2 e6 t4 U6 V1 X; u" @8 O// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
7 T& \% |6 ~' V. D//        卸载键盘过滤驱动5 v0 E( a# f7 H7 K' M
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上$ U+ e+ D  W2 ?
//        则需要等待用户按键,以后有待完善( C/ U3 |* D: F- D  i1 q
/////////////////////////////////////////////////////////////////' t1 A% m/ f9 S4 B+ `, b- U& j
// 作者 : sinister
7 ]! a+ S- [/ q% k2 Z// 发布版本 : 1.00.005 A# u  B9 c* V5 x: Y
// 发布日期 : 2005.12.271 Y) u7 y4 Y' d  B
/////////////////////////////////////////////////////////////////( e9 H- u" G- f( ]5 F
// 重   大   修   改   历   史, d- Q3 K+ L2 Y! h
////////////////////////////////////////////////////////////////, i- `) X8 h4 N& ~% f
// 修改者 :
1 Y7 Q1 s2 h/ U0 a' G. @6 ]// 修改日期 :* c* ^5 \! P% C/ n% `: B; v
// 修改内容 :
- U" O' \+ a8 ?& M0 h1 o3 Z- u2 K/////////////////////////////////////////////////////////////////
7 ?2 K' C, P# l; |2 y; U. Z+ e/ w/ J6 Y4 N& `2 s* [$ d% _
VOID5 p+ ^! h% N% M3 G
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )" Z  n  [  ~! v" p( D
{/ s) D2 X) ?1 F1 K6 w7 w6 m
  PDEVICE_OBJECT KeyFilterDevice ;      
( }+ Q7 L9 F0 Z( g/ e. I  PDEVICE_OBJECT KeyDevice ;0 c9 ?9 u, k, m0 x% w7 S2 ]7 s
  PDEVICE_EXTENSION KeyExtension;
# C6 Z/ j2 }; r+ K6 u  PIRP Irp;
( _* F% D/ Y4 h  NTSTATUS ntStatus;
9 m+ B' e) I3 }6 S0 ^/ o% P- A, J- w7 g' S' H1 x1 m9 H2 N: w6 J8 {
  KeyFilterDevice = KeyDriver->DeviceObject;
" m( H; o$ G3 a& s# f5 o. r7 o  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
, K# G; Y; V. g% Q5 q  KeyDevice = KeyExtension->TargetDevice;
- ~2 R2 r  k# r" ^, x
" {& R( M- {4 C  IoDetachDevice( KeyDevice );
- F6 `4 s+ e. ^
' `& o& b0 I: G# W  //
/ x& i* C, d" h- p( U' v  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
$ J% K2 \: Q- {- d" \& z) {. ^/ n' o  //0 K* B1 @) X# I/ }4 g
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
5 j; u6 _* B" h2 X/ [. W- e  {; N2 A- v% `9 H0 P" W- I9 a- M
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )3 T, C0 x& P5 E
    {
5 k) E- w( f2 J! e" C/ J; a% [! P      //0 B: Y) L$ R+ g
      // 成功则直接退出删除键盘过滤设备' B2 w! X; t/ @! W- j  [& M
      //
1 Y. J+ F* e9 O3 a3 e      DbgPrint( "CancelKeyboardIrp() is ok\n" );* D. ~7 R- N' {
      goto __End;
( M* E4 {5 C! i+ y6 V5 g8 l& A    }
2 V9 w* j# o! o3 m  }" h2 d2 a6 X! R

# l( t1 {  {+ n& u  //
' K1 h$ T1 u7 a$ b: j1 ?7 {' Y# i  // 如果取消失败,则一直等待按键
0 T' x. O2 {/ `1 I' c# h2 j  //
; [/ x" Y' y- O* u6 d$ Y  while ( KeyExtension->IrpsInProgress > 0 ); U3 ]. K/ W' P+ d
  {2 g. C! \, N, z( {1 Y
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
1 e# \5 ~. f' G  }% ~+ M. ]/ m3 x

( h' [5 v" [: d/ S, R4 g- P  __End:
4 u2 H# P4 g# P+ ]: Y: F- V  IoDeleteDevice( KeyFilterDevice );
! T$ c: ]4 `5 V! p1 R. W- l; A+ t* m$ e" W
  return ;$ n, Q+ l" y- n- |: [
} " V: O% p/ f0 ?! S7 K6 M

6 T$ u" f. _7 Q2 ]' }/////////////////////////////////////////////////////////////////
9 @8 E. T7 v: k9 W/ `// 函数类型 : 自定义工具函数
. s% r, u/ D0 u1 l& s$ f: }// 函数模块 : 键盘过滤模块9 C) K5 k0 S5 r1 O5 G8 M
/////////////////////////////////////////////////////////////////
7 [; N4 R+ Y$ R( {// 功能 : 取消 IRP 操作
4 u  U2 ~0 [6 B; i2 M3 I+ i* O7 r// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能. [- K$ L7 d9 [" V1 F. H
//        使用此方法来取消 IRP3 l- a6 i+ D8 r. g
/////////////////////////////////////////////////////////////////
( ~. v8 X$ f  r+ \: u// 作者 : sinister
! ?! @. v0 F* z1 h' l( `// 发布版本 : 1.00.00
+ _, ~2 q! M6 M// 发布日期 : 2007.02.20
! W( y9 C3 F5 T* s/////////////////////////////////////////////////////////////////
; E3 f( ]+ d- p// 重   大   修   改   历   史
  q& v9 G5 e9 _& v5 a7 }6 T/////////////////////////////////////////////////////////////////
, w9 ]3 F: f) `// 修改者 :
: i# X: E5 f; ?" j0 e5 f// 修改日期 :
4 p, F: i: \2 l0 R/ A8 M0 D0 o' S// 修改内容 : 5 T, E, \7 E' A( [
/////////////////////////////////////////////////////////////////
: p8 M3 X) p# C  d: w5 {" _# k* m4 a& E4 c$ Y
BOOLEAN. r' s0 x9 ~4 u+ [
CancelKeyboardIrp( IN PIRP Irp )
; K4 J. X- i; K. }' d{( U" M8 Q1 I* d! j2 |
  if ( Irp == NULL )
) C) B) V& ^# v2 c  {
$ ~# C: P' Z5 f+ I    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
5 {7 f: j* b3 p3 [6 A0 t0 q    return FALSE;
- L- x2 P3 X* N! p* ^, X  }" A& a) ]* q  Q. u' w7 Y6 v
% Q; o. W+ [( o8 k% [- G8 m
5 V+ j# m& }/ d# M! K! z, a
  //
" G0 _, g6 T1 a4 J  l  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,3 V6 ?, m5 T, E8 V
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。0 k' o; Q0 e6 ]5 D: K% S+ [% N
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占* ~3 L: v* r' y+ C$ L5 v
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD: I2 z5 I( X& f5 l
  //
* L: m3 g! g  {8 k5 K! ~' F. ~4 V' O+ `' l! h
  //- Q. n( W2 A) V/ M
  // 如果正在取消或没有取消例程则直接返回 FALSE" C7 k7 p2 [; ?
  //
3 _- p+ ~. q7 A2 J/ W' E$ w  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
) u1 X! o( g. X0 ]) M/ L  {% Z8 ?7 x0 }& F% d, B6 |
    DbgPrint( "Can't Cancel the irp\n" );; h/ `' C/ X4 g
    return FALSE;
' {8 K0 k3 c* H; T, P% H, }! \. V  }0 w  G. I  [" ]" c& h9 J
/ {$ O6 ]! s3 l) u
  if ( FALSE == IoCancelIrp( Irp ) )% L8 L/ C! Y) y. o! @4 M5 z2 H
  {
" ?3 T+ Q( Q# Q1 |    DbgPrint( "IoCancelIrp() to failed\n" );
1 Q0 _" i( D, g! @4 h    return FALSE;. B4 r  x* P/ ~5 e" r# E/ {2 ]
  }
0 y& P% f3 W+ p5 d2 Y, l* c) C" M4 a2 ?# I
  //
9 q3 v) d* d$ j6 n+ D# C5 [7 j  // 取消后重设此例程为空8 a0 {% I9 d& }# ]2 G) W# t5 a
  //
( e+ J+ q3 R/ t! C' g0 m6 h  IoSetCancelRoutine( Irp, NULL );5 K3 E1 c5 Y6 Q6 j

$ @9 s  Z& w$ j. X7 V% u4 [  return TRUE;" ]* t" o, E$ P* U% E. `
}1 Q6 ?) X0 M0 Z; E; A* W2 \2 {- Z
! @) Y+ K: f) e, v, b: r
/////////////////////////////////////////////////////////////////+ _3 U, V! F- L+ _  g
// 函数类型 : 自定义工具函数% J1 l6 Y: |7 W. p0 z# F! e
// 函数模块 : 设备栈信息模块3 t* j6 a7 u$ K5 q" \+ `, d
/////////////////////////////////////////////////////////////////
9 ^& F4 U, l0 F4 W// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
* j7 M) z2 p5 s" v//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
1 y, T$ d% C( z/ ]2 Y. ^// 注意 : , K  v! O* E# }
/////////////////////////////////////////////////////////////////
9 c! l. W) z7 Q8 K/ H// 作者 : sinister6 s3 a" ~  f5 W( l5 Q. C
// 发布版本 : 1.00.00
. L  o  H! o. E4 D. G" z// 发布日期 : 2005.06.02
- a/ N1 e1 P  O7 ^2 W% p/////////////////////////////////////////////////////////////////
5 V, g$ f9 M+ V  [// 重   大   修   改   历   史
8 o+ q7 T' F4 T# @5 ?7 q/////////////////////////////////////////////////////////////////7 @/ Q" R1 l; L5 f( s# a( e( N$ A
// 修改者 : sinister, J; g2 I$ f/ Y
// 修改日期 : 2007.2.12
+ M' U7 D2 G, v, {. m% w) c9 N$ r# E1 w; F// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
9 O4 Z8 W$ t6 {/////////////////////////////////////////////////////////////////
5 j( B- B, e( }& N5 H- E  ?6 D5 ]3 {+ I( [
BOOLEAN* K' B, b: ]) U& N% @
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
& U1 W8 T7 F  }! |. b1 O{. F1 G% Z1 T. e8 P' a, y1 C
  PDEVICE_OBJECT DeviceObject;
. M. Z# y  a9 j5 I% T  BOOLEAN bFound = FALSE;- M* m- _, _9 B* ^5 k7 a" c! L3 q

4 F3 X& A- |5 j0 n' J% v6 c  if ( DevObj == NULL )$ }4 J' E- S3 ^: |2 n+ T5 Y
  {
( e+ w- ?9 _6 ]  Z4 C    DbgPrint( "DevObj is NULL!\n" );7 C) S0 L$ I' i, c: n: R+ G
    return FALSE;
9 u* S) n: r& ~# ^( X* ?  }6 f+ l% W8 d2 O, R, g+ P8 B

6 B8 N1 H! U& ^  DeviceObject = DevObj->AttachedDevice;
5 y) d8 D6 Y4 A0 \; P; u6 o- l) i" b% i" h2 F1 H4 a# i0 D# z+ f4 s
  while ( DeviceObject )
& s7 G* `- h: Q% c: T' f2 J: w! I  {
) o! O9 p) R7 D- k1 n    //
: `" z1 i$ l. r  D: l3 F% i, V    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
" |0 v3 p, n& \; @1 s& O    // 有一次足够了。这算是经验之谈
2 K8 [9 }. d$ S    //
# E: q) N. @0 E; e, s; _/ I    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )' J/ K+ ^3 O' w, e8 O) k) K
    {
' P9 R6 N' ]5 o+ K$ {      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",6 l) E; |* L# f; T* h: I  R; A
                DeviceObject->DriverObject->DriverName.Buffer,% R5 D* ]0 @% E. e2 q) c
                DeviceObject->DriverObject,- W, w5 E2 ]0 H- {
                DeviceObject );
) R7 M4 K. D0 Z6 h( P
3 D" i5 P: Z: T* Y; ^      //% Q, O" t9 q6 `
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了: c; l- f4 z0 f; y; \: B9 A0 b. k$ I
      //" F7 u- m# e% y3 Z0 e
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
, e! a8 R8 A  i$ D# c; K9 W                      KDBDEVICENAME,4 d5 |9 d1 z& E: C7 M- S
                      wcslen( KDBDEVICENAME ) ) == 0 )
0 ^9 [) A. J6 ^" n# [      {# {! h' x0 K/ {8 z. H/ Y+ j, l( _
        DbgPrint( "Found kbdhid Device\n" );
9 ~/ ^0 N5 \- p6 D& C5 |  u4 N        bFound = TRUE;
  V- \% k+ C; d0 P- G/ C        break;! d" @! i8 j* k8 N' F/ d( Z
      }
! h) E: @- r/ J! ~8 F9 s    }7 z8 }5 |! Q( x+ K8 v

' c/ B4 R4 S" V0 Y. N2 ]2 M    DeviceObject = DeviceObject->AttachedDevice;& E/ ~0 d, L8 j* F1 g
  }
( A1 l8 V9 [2 }9 |( V, C  q, I! a  a' f$ l+ ?/ f3 _! D
  return bFound;! f' T' w' }" _  C
}
5 m- E" s0 X5 S! g, i& @5 W6 [1 b! ^- w; q& H# L& |
/////////////////////////////////////////////////////////////////
5 \2 T9 S; ?; p2 f' F2 p: A// 函数类型 : 自定义工具函数9 P+ s" S8 z8 J9 g' H( Q
// 函数模块 : 设备栈信息模块
: Q# o/ ~& F! M+ B/////////////////////////////////////////////////////////////////! q5 X8 O+ b0 X; ]  [( w3 U' C
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
, T5 V2 C) ]! q% u! u9 @- G( m// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
* Q% e7 B  v, l7 Z8 i5 U/////////////////////////////////////////////////////////////////
9 g) X; j7 B8 |$ K) P  C; N/ @// 作者 : sinister6 \1 k5 J5 t! H
// 发布版本 : 1.00.00* R5 O, w  F, ]: t
// 发布日期 : 2006.05.02
; s" l% k/ i3 i. y5 v5 q/////////////////////////////////////////////////////////////////
/ O. o/ Q$ k: S1 p. h  k' |// 重   大   修   改   历   史& z0 l* o% b$ |' A6 T0 X5 L9 I
/////////////////////////////////////////////////////////////////
7 K9 W3 s' G; {% d, \" z// 修改者 : sinister+ l6 L5 r" _5 d
// 修改日期 : 2007.2.12
- Q2 j: V  k( O8 \% U// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用% g6 U) ]+ Z. m1 v' D! f9 q2 h3 g
/////////////////////////////////////////////////////////////////+ R; R! T2 h+ j' l5 ?' M6 y4 Z

% i$ V6 M% ^" K, F( r; ^' k) S; }" IVOID* y( X- ?5 P/ B3 Y
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
- L4 S+ Z8 Q" N' Y( i{
5 A; g9 m: U/ v9 K5 ^  y, i  POBJECT_HEADER ObjectHeader;6 ?2 v: G1 I" w, |! B
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
* g1 P6 y1 w. ?( l9 s2 r) v4 ~3 J# y% ]* g$ s
  if ( DevObj == NULL )
; L" ^; m$ Z- ^" H/ I  {
" p: N4 Q- {  N6 U    DbgPrint( "DevObj is NULL!\n" );
" Z0 J0 H" V$ X2 L: m, d8 w    return;
/ @& p0 ^# V" G' J/ D% Q  }. S6 K; V: V+ ~& ~
$ Y' ]5 p7 A; C) U$ b. ]3 ]: i# M
  //+ b7 g3 {( X! @; l& y! ?  x: b- t
  // 得到对象头
/ q. \) ]- ~" l$ ~4 P9 `% H  //
+ W5 f9 I8 Z+ E5 U3 H7 H  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
* d1 L- |( t5 R  T& B0 N
3 i6 A8 E6 }) A( ~+ Z" Y  if ( ObjectHeader )
3 _/ n8 h! r4 z: g5 ~& V0 _  m  {
% _5 Y' g7 \1 c    //; P3 ^) O, k1 v) e" G& b7 Z
    // 查询设备名称并打印- e3 K8 l- S$ `9 j1 U0 R0 v, }$ y) c
    //4 H, n8 S3 l* v% ]
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );: v( c& [8 o) L

0 s5 s1 _9 I4 ~3 _    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )5 p$ N9 f+ x- N( c4 K# Z
    {
0 ~8 E( B; i# L- b. A  ^) @% d      DbgPrint( "Device Name:%S - Device Address:0x%x\n",# Y6 ]9 ?5 q9 e4 h* B( g; y
                ObjectNameInfo->Name.Buffer,/ Q1 Z) M' ?  S  h9 l
                DevObj );5 d! ?( {  x6 I- e& U

# X* p% L2 t6 X! U9 B2 s7 m      //
0 ~% o& r, k& f9 R6 t: V: O      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
4 M! Q4 J) Y, V4 X. @7 S, @      // 用,没有实际的功能用途* B* A( _" w! `
      //3 v+ ?2 r# z) z% k* C2 S
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );: P* i. ~5 K" p2 b, r8 r, M

7 T1 N2 Y5 ]! k/ I0 ^+ ?$ u      wcsncpy( szUsbDeviceName,% y2 Q: r9 j  H4 \. T( f  H
               ObjectNameInfo->Name.Buffer,3 a( W* O$ i7 @3 n/ P
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
3 u! B2 q* w9 `, C6 l& @* R6 C    }  x, @; t! J" G( i* g& X

" ^( t  P/ a1 P5 O" R    //) I# T% i  c5 T
    // 对于没有名称的设备,则打印 NULL% s8 @$ b5 I# R5 U4 l  G
    //
( z  `8 @; T6 r( U0 L* Q7 R    else if ( DevObj->DriverObject )
- H- G% e/ V/ P! J; c, H: u    {
. P; J  A  C+ I0 A( @      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",- N$ K; f  O5 [( t3 X6 \  ~
                DevObj->DriverObject->DriverName.Buffer,: A4 d. A2 H$ y6 O* J' P
                L"NULL",
* `7 l* c0 k6 A7 b7 G% S, o  C9 }                DevObj->DriverObject,
" |4 Q0 {" k4 i" \1 @                DevObj );
! L8 ~9 }8 O3 M# x2 r0 m+ e6 j    }
9 C8 E) b" c. {8 c9 b3 Z  }
! U* T# X+ @) a}
' l0 O: D+ [; C9 m1 p3 h& G
* ?" V/ U: d/ J0 E/////////////////////////////////////////////////////////////////
6 I1 b* Y$ o) D6 z' p// 函数类型 : 自定义工具函数, R; {/ w$ ~& |* Q+ y0 ]5 ~5 B- \
// 函数模块 : 键盘过滤模块. f0 v& f" i/ _, N. q
/////////////////////////////////////////////////////////////////$ Z' R0 @$ [6 {: X# x
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备, h4 M) C. u% v: d
//        对象,过滤出 USB 键盘设备,将其设备对象返回
* k% f4 Z9 O3 l9 A! c/ g3 p; @% K; V// 注意 :
: E8 D- n1 r; C, \/ d/////////////////////////////////////////////////////////////////
/ D- X5 {7 m3 J3 ?: z$ Q9 L// 作者 : sinister
  E) q9 m, U' g: z& K// 发布版本 : 1.00.006 R7 e. e8 G" L( u) _6 t
// 发布日期 : 2007.02.135 P! Z; M6 [6 D4 F0 a& g) |
/////////////////////////////////////////////////////////////////
" [; B9 N0 h4 ~$ l) `5 ]3 c8 ^// 重   大   修   改   历   史6 X( k7 o( z) A' H7 z# R; L; t
/////////////////////////////////////////////////////////////////
) c0 q* j0 `. K" s$ p: M// 修改者 : ) g" h% E7 D2 g6 r8 J/ R- W
// 修改日期 :
# S! d  u) A8 l8 v, l( m# n// 修改内容 :
% ^* q9 z8 J( v/////////////////////////////////////////////////////////////////  R9 L2 I; @* i( A$ d: Y1 w
" j$ H7 A% q2 E3 c! o* g
NTSTATUS
' v8 w% C% q7 ?/ X6 V9 lGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
3 [. \+ S+ r) F0 k# M' V{. N; U7 f6 ]" ?4 t  }8 z
  UNICODE_STRING DriverName;
9 S; X" g8 z9 [! K7 y% Z  PDRIVER_OBJECT DriverObject = NULL;2 _4 W% S% w8 J- b
  PDEVICE_OBJECT DeviceObject = NULL;
0 g9 r  b* `$ s$ D1 m0 r, f  BOOLEAN bFound = FALSE;
% ?! i9 w1 e& G& `6 E) ~8 v0 a" j3 T8 Y0 Z. u
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
; i* F# P. y& x/ s% W5 B
* p6 ]0 w) y# J* D7 s* l  ObReferenceObjectByName( &DriverName,. h) F6 j9 {. \( f; a, G) }
                           OBJ_CASE_INSENSITIVE,
# N6 R* f  p/ o0 n" a, }                           NULL,, V! {3 @. c. Y! Y8 H. K& I
                           0,  C; {! K% k+ X  ^, R% N
                           ( POBJECT_TYPE ) IoDriverObjectType,6 P' ^0 v0 w: v. r* e
                           KernelMode,+ [7 d9 r. k+ S; v2 B7 t
                           NULL,. b8 _$ @2 K5 o( Z
                           &DriverObject );% ]6 l- E2 X7 z, D7 B

* l0 b1 v6 [+ ~+ P+ m  if ( DriverObject == NULL )2 l7 y; ~6 y; x: T/ j) F
  {
, Q1 H4 }" {$ e: Y+ O9 A! N    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
9 J2 X+ @9 \" B6 V; {  ^    return STATUS_UNSUCCESSFUL;3 A, J; r1 U: L: E9 s# b
  }9 \' Z7 M9 Q6 R) k* k) ?
; ^' U1 |  ~( M  D8 g+ S" G
  DeviceObject = DriverObject->DeviceObject;
, m6 M! a& ]1 `9 d1 e9 |
2 A: C( q1 ?( }4 `. N  while ( DeviceObject )3 Z; J5 x- N& L* l- p. r
  {
, N1 v) Q+ x2 D& `8 x    GetDeviceObjectInfo( DeviceObject );9 w  ]9 W: Z1 V, k& {+ [

" n0 X. D; t7 m    if ( DeviceObject->AttachedDevice )% m' U* S+ P8 ^- b
    {! l; b" ~" w* @
      //
3 g% q4 s# H+ |  H1 ]% |; w+ Y) r      // 查找 USB 键盘设备
0 }0 {2 T: x, c, P, x) p+ v# G* S      //
1 C0 O" k" z& Z: ?/ @2 E6 k      if ( GetAttachedDeviceInfo( DeviceObject ) ), ~: D  z7 s4 n5 B
      {
" U( o( i& C' d- d7 x- _        bFound = TRUE;
" A2 H! b  k2 P. h6 k) a        goto __End;0 G7 c( v, J, X
      }  Q2 x9 v* R- G/ F& e7 B
    }2 Y4 b# p- S. R, D; P4 R

* j% p* ~; x5 M/ i! ^1 C    DeviceObject = DeviceObject->NextDevice;
+ p; b' x' o; v  }! w/ x' n, ?7 Q8 `# m5 L& I9 i; ^

4 C/ W0 }: _5 S" J* E  __End:% a" _  ^2 v& c6 F+ ^% k
+ R6 X  `2 q- P1 d' b
  if ( bFound ). v7 X6 d- ?2 V3 e
  {
2 }8 z5 R' c% C/ x3 Z  h7 U    //2 `, ?" |' g/ e. Y& [- S3 v
    // 找到则返回 USB 键盘设备对象
4 s% v, M0 J+ R& V    //# Q6 y, X) r: {9 A; [0 s$ M. _2 U
    *UsbDeviceObject = DeviceObject;& w( d3 w) R$ c! G1 \: Y- _$ T
  }) u( V) x3 S  x' b; ?* R3 {. {* {
  else
1 f9 z. i7 @0 ^. I( o; q3 K! R  {# ~8 C( d, ~( v7 s; C
    *UsbDeviceObject = NULL;
3 k3 b+ ~! C+ o4 d  R" i) U  }: v& B- s1 [; k2 d0 N5 a% u8 d

; @7 Y0 P8 K( c& `  return STATUS_SUCCESS;
7 i3 |3 k7 |) c: T}  v" u# @5 i5 u6 [* y: T8 J3 I$ ]

0 S  s4 O7 Z4 O; o9 z2 w  P/////////////////////////////////////////////////////////////////
3 ^$ U$ x  u" i( v// 函数类型 : 自定义工具函数1 F, y4 H$ S! N1 S1 Y. S4 _
// 函数模块 : 键盘过滤模块6 I) ?5 M) \* b; Q2 b
////////////////////////////////////////////////////////////////. n, b* U( r, P( q% p  s
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关* _% S* X* q; R
//        信息,返回附加后的驱动对象
  c1 E0 W& E! F7 q- b( m3 a# u// 注意 : 此函数仅挂接 USB 键盘设备
$ `: m: v$ P* {* K4 g& u: L' @/////////////////////////////////////////////////////////////////
4 R) Z# j5 v( [5 W; F3 d4 c' h- W9 z// 作者 : sinister
$ o' Z* f5 C6 Z! {; H  H// 发布版本 : 1.00.00" A1 Q, W' V, V
// 发布日期 : 2005.12.27: q; L$ e5 H- M  u2 J
/////////////////////////////////////////////////////////////////0 D) [, ^5 i' R5 M9 V
// 重   大   修   改   历   史
. Z' j, }" G8 A! S////////////////////////////////////////////////////////////////2 L4 A7 }, r; _0 v0 K+ g
// 修改者 :
, ^% G8 C8 o: y( r// 修改日期 :
) ]; C! H% y7 O- f// 修改内容 :7 x& e# s) X( H& }, y6 g# h: h
/////////////////////////////////////////////////////////////////6 Y% \1 T# K3 ^  B

6 j; K5 g4 r6 Q. D& \NTSTATUS
% E8 ]0 L& m4 m/ @AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
( I; y' T1 ^6 i- q6 x                         IN PDRIVER_OBJECT  DriverObject )& ?9 p/ |3 P$ V( l2 P' E
{
+ a3 {# o! N$ }5 g$ b7 W  PDEVICE_OBJECT DeviceObject; % j' a# a& ^8 C/ R4 k2 s' }
  PDEVICE_OBJECT TargetDevice; + d1 f" p0 l" N* ?: q
  PDEVICE_EXTENSION DevExt;
4 x, l/ E; z3 O% Z' g& U  NTSTATUS ntStatus;5 i& ?9 I* G8 `. c5 c" ~" X9 ?# j; o

7 _& d. r0 M% O) M8 y* l4 _$ `  //
2 V$ N& E" ~  o# P- C: p2 `6 |  // 创建过滤设备对象: |% t: a8 d$ _, a. U7 @5 d
  //% m4 P* @, h  H  ?# H
  ntStatus = IoCreateDevice( DriverObject,  k1 y$ ]5 D* F# t. q+ a- U
                             sizeof( DEVICE_EXTENSION ),
% S0 ~! Q. E6 S  }$ v9 U                             NULL,
" L. F6 Y/ s, C6 S! J! N- x                             FILE_DEVICE_UNKNOWN,3 l% N3 u9 C7 R5 ?
                             0,9 t; w' h5 C8 d9 S
                             FALSE,
" ?; p* ?# y! X                             &DeviceObject );
# r8 g5 C! ^! ^0 ^% C9 ]* I* W% A0 |
8 |1 P, w: A4 f, O; N: q  if ( !NT_SUCCESS( ntStatus ) )
) A9 o2 [% I5 P8 H  {
) a1 h" f8 d& J& i3 Y* d    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );; n2 y+ Y7 q1 I. J9 d" D7 j$ ?
    return ntStatus;- B3 s6 r  e1 C
  } 9 g; |' g% K7 X- Q; ]
% V' B; c- s% O0 U) N( o
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;7 t1 M2 j% Y0 Y  G/ E; N

5 }! A* }! t& f2 U  //
! d4 p9 S0 h. q; L7 ?" t. V  // 初始化自旋锁
" {/ l$ q1 s8 Q2 s& ^, p8 l' v  //
: K( @  |& |. t  KeInitializeSpinLock( &DevExt->SpinLock );- K/ S1 ^  M' H: ~0 ^+ `

, X% v8 z" O, |* H  //
7 F, Q" Q* o, C# X2 m$ q  // 初始化 IRP 计数器1 S$ c1 n) P, ]( Z0 A6 O
  //
  ~$ J( \' R" Y5 y  DevExt->IrpsInProgress = 0;
& A9 A0 s$ w( V! R/ u; F# L, [! M4 P1 I8 U5 B4 z
  //
0 p- _6 f- o2 i, V% t; S  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象( l$ }4 m. x6 K% q+ g# s
  /// H9 m! p8 m* O1 U' ]

$ j( I+ ]5 S6 [; e: g8 \  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); , l1 ~% Q; x! S* N/ {5 a
  if ( !TargetDevice )2 T+ R9 Y9 ~: {% O2 @& d2 C
  {* W& D- @* [7 D# @7 p4 W
    IoDeleteDevice( DeviceObject ); ( N; O& v/ t) P5 J2 K
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );3 S* j( G2 K( D4 w1 i/ s) }3 M+ B
    return STATUS_INSUFFICIENT_RESOURCES;8 M  K* p1 T. q% h
  } 3 ?" O; N3 L4 E& }( P2 z0 ^
/ n" ~0 O7 W0 C2 g' a( h
  //( K3 A0 O: P0 J! P4 p. b
  // 保存过滤设备信息( c  A! A4 e% A6 k* Q7 C3 L4 g
  //! e4 q: N  J* u' s/ Y/ I* Y
  DevExt->DeviceObject = DeviceObject; " h! q+ k1 ~3 r7 s
  DevExt->TargetDevice = TargetDevice;9 Q; u# r+ D  M$ t( ]8 j4 A- D2 |9 ~

9 f% p4 {/ U7 N$ J" ?! J1 K  //
+ [  k' o1 E* z& Z: C  // 设置过滤设备相关信息与标志
0 ]4 j' M3 \0 U/ w  //% l$ F# A- h! R% l9 {  s8 j
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
  v  f. R! n7 k" c5 i+ p: a  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
! s  t( e2 r4 t
! Q/ B# `3 y$ F! i5 c( A8 q9 \4 X' H4 d# q- x) r5 P
  return STATUS_SUCCESS;
$ e, q7 ~# q/ o}* r9 @. U" P2 J
: f8 U( y2 O/ u8 R
/////////////////////////////////////////////////////////////////" X; g6 e4 D- R* E8 J: }* w
// 函数类型 : 自定义工具函数
- C& G1 F8 f  j6 w// 函数模块 : 键盘过滤模块% y! m) G  C3 {" b, y
////////////////////////////////////////////////////////////////& V2 I, b; f2 `$ v3 w' R6 B
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
: R4 \& _9 M# d//        信息,返回附加后的驱动对象
* e1 j5 C* c+ o/ _8 n% x6 r. Y// 注意 : 此函数仅挂接 PS/2 键盘设备) T& Z- p7 G4 a5 v3 s7 k
/////////////////////////////////////////////////////////////////
8 A, [* ?& E8 {7 y2 E// 作者 : sinister0 J$ E  m# P: d, h
// 发布版本 : 1.00.00% M* N& w3 u$ [7 L/ W0 i- ^# G
// 发布日期 : 2005.12.27' u+ T$ I& y- J1 Y6 ^4 {
/////////////////////////////////////////////////////////////////4 |% f" z0 E* H
// 重   大   修   改   历   史
5 R& T5 V- a2 G% S3 y////////////////////////////////////////////////////////////////
5 B$ C" V9 P6 I6 n( w- S// 修改者 :
: F' l9 ^3 N; [9 }: N2 l// 修改日期 :) f7 v/ [) @& Y2 A" s- h8 y% ]# o, p
// 修改内容 :7 c8 K$ a6 A& x8 m
/////////////////////////////////////////////////////////////////
# ]) k- P" Z& Z% v# |+ h1 [+ u5 h4 A& ~4 v
NTSTATUS
& E' X' k( F2 a7 D; lAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名8 }0 [& w/ S2 G2 K# M; m: ~9 ~
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
  ^! U. k4 e6 ^& N                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
8 r+ N2 ^; ]3 H+ x& n# O{
& F2 T8 V1 y' @% q+ O" D7 X  PDEVICE_OBJECT DeviceObject; $ N' r/ K  Q- Z3 b3 F4 R7 K
  PDEVICE_OBJECT FilterDeviceObject;
; C- y( l1 _# `; L  PDEVICE_OBJECT TargetDevice; 0 f& r5 j' ~4 D1 ~
  PFILE_OBJECT FileObject; ; ?" q1 _) M( h  }: P6 b2 W+ T& E
  PDEVICE_EXTENSION DevExt;
7 p6 S  w( h9 w. }. m6 Z
) n7 w4 J5 o$ p& A' B  NTSTATUS ntStatus; 1 T3 ~& m% h; C/ p8 J

8 f2 m  S7 _  `  //
8 D* ~. g' E* X& ~) Z7 I. k  // 根据设备名称找到需要附加的设备对象) I% v0 P2 }' J  ?  s+ O2 u" Q- o: ^
  //6 y, R, j2 P2 h% u: q6 D9 R7 r
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
+ y6 b8 I4 n% Y( B8 ?                                       FILE_ALL_ACCESS,8 q, e, m: S  t$ ?  F! y
                                       &FileObject,5 n1 V$ R% Z+ u9 I* J4 m4 e
                                       &DeviceObject ); % W5 t: j7 F" o9 f( x( {* s7 C$ J; p
* h6 t6 @, }/ q0 j1 K5 C& Y0 K! H* W6 Y4 p
  if ( !NT_SUCCESS( ntStatus ) )
2 |% H. M; }* ?2 j$ `" w  {
* n# n% r4 R& H) ^1 k5 o    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
) W1 X7 O8 q/ Q' R. V    return ntStatus;
& U1 \5 u! @0 Z& D7 E  } , F' W0 [# v$ b: ~" F9 @# e

% b- L6 T, {- [! _" C/ y  //
% @& ~3 @" [; {4 }  `1 {* m  // 创建过滤设备对象
# t! K$ C2 H7 j; l  //( y! m* T, O1 g( R5 b& H, F0 n
  ntStatus = IoCreateDevice( DriverObject,
3 `- }. h* ^) ]6 x) r# h( q                             sizeof( DEVICE_EXTENSION ),8 c2 M' l9 h4 D$ Y
                             NULL,
6 X+ K% h( i/ n4 m+ }) y                             FILE_DEVICE_KEYBOARD,5 |; ]7 S- X3 M0 b7 s: }0 m# H
                             0,
! F0 h; j" n3 r9 m* w1 _                             FALSE,
0 _; F$ \" @5 Y! B4 w                             &FilterDeviceObject ); % t6 `( [2 y, S6 Q; p

/ F* X+ n3 z( T- j  if ( !NT_SUCCESS( ntStatus ) )
) x# ~) L6 v( q' y/ \3 ~  {, a& r* k; c+ @# I# s
    ObDereferenceObject( FileObject );
! w# X" N* e5 ?( d2 m) p0 w    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
$ l" F$ j1 l- Q" u% q! O9 S    return ntStatus;6 a4 F, [6 o4 C" x! y
  } 2 P. h$ r% t' T" a  F  G

0 ]% C& F: a/ }# ^  //! H4 M( d" x! K; i
  // 得到设备扩展结构,以便下面保存过滤设备信息+ v7 _7 A$ W7 [# S9 ]6 Q3 r
  //
  G+ q& G- |$ f0 W" e, T' D  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;) P( k. ^# h3 i5 L- t" e
% x/ O4 i1 N( [

. O" d- a* t3 @0 i; i" _  //8 z1 y& e) B' Z# B  R' J2 E/ f% L
  // 初始化自旋锁
  G: K, ^' q# _3 O6 q5 s  //
6 ?% W! c9 \4 s2 P3 d! c6 \' e  KeInitializeSpinLock( &DevExt->SpinLock );! [2 p! ~; {" V" _$ h, `# s

9 n1 @: V8 W  Q. o( o1 \  //
% {4 {7 W6 P/ _- `% _* l  // 初始化 IRP 计数器% f- h2 x6 R, T
  //
) \. q, ^4 z; [' p( ^  DevExt->IrpsInProgress = 0;
2 B# `3 e9 T, B- K9 {6 s
$ a, n1 V5 ~! M3 e  //
/ c* w2 R* Y! z/ O4 |8 e0 k  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象6 U. q2 }5 {3 `* l
  //7 c( ^; ]) }2 c6 d
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,& k( _- q# F2 R" B( ^* I% R3 B% `
                                              DeviceObject );
6 p( O# b) @3 Q# y  if ( !TargetDevice )
! ~; G! E0 v' L* {' m" b8 O  {! T0 {% p4 M& M' g
    ObDereferenceObject( FileObject ); ; V/ K! R5 C& M& g5 s6 I; P
    IoDeleteDevice( FilterDeviceObject ); 4 e, |/ y+ T' J- g& T$ ]1 k( h
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
  K6 _9 @5 L8 q+ l    return STATUS_INSUFFICIENT_RESOURCES;
8 N# @/ q& x6 t9 K+ }  } 2 ]/ f; ~1 O& V# r+ O1 b

# c# ?% s) k& S  //
, l  w. y" G4 m  // 保存过滤设备信息1 d) i$ b9 b% D5 M
  //; U' ?  n3 M4 n) x; z
  DevExt->DeviceObject = FilterDeviceObject; ( V; V2 y, d9 U6 R
  DevExt->TargetDevice = TargetDevice; 1 q: T' e( S$ R% y* H
  DevExt->pFilterFileObject = FileObject;/ v2 P- @: |, O) [1 U- |9 s8 ?0 w

: d* \+ y! N4 J6 D& F  //
5 d3 x, t& P4 I  // 设置过滤设备相关信息与标志
+ w: {! g% H* E8 G  //
; M+ X2 f6 Y0 D3 s! A  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 8 U  L: X6 v+ l; a2 l; l( p
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 9 g0 W2 q0 |: Z+ z' D! @
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;: E9 f' l) L& I- g. F$ x
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |' n7 f/ t2 [$ w* b
                                                         DO_BUFFERED_IO ) );
8 ]$ X& B8 l) i! u9 h5 F
- N5 r5 K+ R; A, W. g# Z  //2 j1 p, B9 j* O- ^
  // 返回附加后的驱动对象2 w) s# V- v" i0 s& Y3 |9 B6 ]
  //- @5 Q3 K, ?3 P8 a# P
  *FilterDriverObject = TargetDevice->DriverObject;
  }- X5 u# f9 y4 k5 K: J6 {# L( }4 y9 r' o: K' k/ {7 h- J
  ObDereferenceObject( FileObject ); ; f3 K* S' Y( n: {# c4 Z! ?- q
: E* \+ P% p2 q, p. G7 |
  return STATUS_SUCCESS;
8 O$ A2 ]! X6 L: g}: H/ T8 c" l2 |
+ \2 V4 {  z6 K1 y$ }' q
////////////////////////////////////////////////////////////////// _6 T& y6 u* e& V0 W4 J
// 函数类型 : 自定义工具函数
6 z. u$ S; c. J9 F4 c& e4 l// 函数模块 : 键盘过滤模块
: u6 j# j6 ?/ b" v7 p6 D1 d////////////////////////////////////////////////////////////////: _; o4 |: H* b
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发& T! P5 D6 r& @1 o9 z- Z7 }
//        这个 IRP 的完成8 [; c; ?4 n' I) y8 a
// 注意 : / g  D% F1 D# i3 E3 ~4 [& T8 c
/////////////////////////////////////////////////////////////////+ B3 o, @& v- I& t; U6 Q7 x
// 作者 : sinister
1 J- p. S$ p: n( c! G: a0 C// 发布版本 : 1.00.00, ^! h+ E! D# G- s" Z0 ]
// 发布日期 : 2007.2.152 u) Q4 }( K! b$ {, G' [$ Q1 d
/////////////////////////////////////////////////////////////////) d* P* n! X5 Q1 }/ z
// 重   大   修   改   历   史$ t3 [, H. q: i- `" t
////////////////////////////////////////////////////////////////6 {; E+ Z4 _) o) ^" O
// 修改者 :/ Q: z; x0 Z+ p& |; T, P. H
// 修改日期 :
, [+ X2 t5 E8 z4 k7 B8 L$ ]// 修改内容 :- `& W$ j9 |9 F8 @  X
/////////////////////////////////////////////////////////////////
4 z1 z: e/ x5 }+ U
$ Q/ j' A3 J" P& d& B3 `+ p8 tNTSTATUS
- k, J) ?. a0 lKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )* p9 A3 z- m! [
{
% x% b+ q- B$ B: U. a9 E( s' c  NTSTATUS status;   K" K& p# W1 P5 H; m5 G
  KIRQL IrqLevel;
1 J+ h' B# Z  c# t% T! @- r5 l0 ]3 u
  PDEVICE_OBJECT pDeviceObject;3 X% @6 v: q" Q0 M4 ]
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
) K' C4 G7 ], V9 G- H5 P, p                                   DeviceObject->DeviceExtension;
6 }1 m0 A0 e. J/ y; C7 L& @$ A/ `' m2 }; a

+ Y/ F' H% w: Y  I  IoCopyCurrentIrpStackLocationToNext( Irp );* {) ]7 _1 `# `- k& H3 P1 G
' X5 F- ?' r+ m
  //6 P: S' v. ~3 }5 O9 F: b% P
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁! q. h& K% v  ?
  //; ]- n$ _5 M" ]3 o9 c  g
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
: _* s, J4 h, E1 e$ v% H: z4 O  InterlockedIncrement( &KeyExtension->IrpsInProgress );( u0 N! ]: b  x0 m( {
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
8 t) f3 }: D# t9 E7 R9 J& ~$ H; [3 ^  B" c5 _, B
  IoSetCompletionRoutine( Irp,
6 a: \) w/ \, L" ]( A                          KeyReadCompletion,
8 l. Y! ]- A4 b  R' I  b# \                          DeviceObject,
8 Z% x  y4 O. F& `                          TRUE,
( U) {4 L6 c9 W# j# G' C! I                          TRUE,
/ N& e( [6 i+ y" h3 @. Q3 N3 R/ D/ z2 O2 q                          TRUE ); 6 Q& p7 u- h3 V9 Q- U' P. }

6 Z! ~7 ]! E0 C) _  return IoCallDriver( KeyExtension->TargetDevice, Irp );) S* L+ m5 \! C
}
8 h. D& {' Q! j! I! }8 }8 q
, c6 I; E% n! |5 F9 g' c/////////////////////////////////////////////////////////////////
. I4 i: F9 A( Y# K// 函数类型 :系统回调函数9 y8 {6 d; S  W- W2 C8 |
// 函数模块 : 键盘过滤模块
; W" f2 S$ F. `  U////////////////////////////////////////////////////////////////
5 D* f1 m( g% F- L$ w0 A// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的* d; x$ W  S9 V2 m5 |& P: o: s/ K
// 注意 :
. K& B4 B# B$ |: Z8 a, p6 u+ y/////////////////////////////////////////////////////////////////' z  B2 U; x2 m) O. a
// 作者 : sinister7 f$ r  T7 L) @7 S9 z( u
// 发布版本 : 1.00.005 [8 y2 h8 a- H
// 发布日期 : 2007.2.12
+ e6 E3 ^" l- m, n4 o) }/////////////////////////////////////////////////////////////////
* _3 {0 L( g4 T+ q2 ]// 重   大   修   改   历   史% z0 N" _2 n1 s; E1 L
////////////////////////////////////////////////////////////////7 P2 S, C0 m5 [3 o
// 修改者 :
. {: ^4 V; x. A" \// 修改日期 :2 n# D* E0 X" ^5 O
// 修改内容 :
' v$ |6 e, _/ }* e. H/////////////////////////////////////////////////////////////////$ ^1 R2 p& L. n5 R+ S

$ d! a4 ?: e$ F7 Y% JNTSTATUS
+ C4 e8 n" _0 E8 @KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
( S* i  Z  r/ k! y+ A                   IN PIRP Irp,
+ f' n5 y% q0 q0 v; O9 o( X$ `# ~* r                   IN PVOID Context )
) ]! m& b6 S: p; q{
( ^' x6 y/ V. ^: n2 Q, [- O; @  PIO_STACK_LOCATION IrpSp;
) a: q6 t+ g0 q  i4 f/ C6 a+ U  PKEYBOARD_INPUT_DATA KeyData;' x' Y. |9 ~$ p& _$ e
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )( \5 E! s. u# I6 _. i7 w( }
                                   DeviceObject->DeviceExtension; " t5 K1 A& I. d& `
  int numKeys, i;
2 a  O# ~9 q% X1 N/ l8 M$ ^  KIRQL IrqLevel;
1 a6 p/ \7 I! ?/ B$ f% k, C# b' |5 ~& Y7 Q6 n
  IrpSp = IoGetCurrentIrpStackLocation( Irp );9 Q& j: m3 S6 z, @* l% Y
- M6 J& u8 D6 G$ D0 H7 n/ l5 }( S3 h

- s. D5 E( k, e6 v  if ( Irp->IoStatus.Status != STATUS_SUCCESS )9 K: v; ^, v! x" }2 ?8 S  y5 Q' O1 s
  {
, j0 `! u8 i+ E) x9 Q. ], x. l    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );' z2 _' f2 S/ v
    goto __RoutineEnd;
. X1 L0 Y- i+ o" W5 H* d+ U  }
+ v8 {$ u: w! k' n; G- d3 K' l' T, t. V9 r9 @* q! J
  //  j, `: z/ b* S+ x+ F) G. h
  // 系统在 SystemBuffer 中保存按键信息; o4 w9 P/ i7 k
  //
% m( q# ^3 s" z& w  KeyData = Irp->AssociatedIrp.SystemBuffer;( {. R* y0 ]1 z7 Z
  if ( KeyData == NULL )- T; u/ a; }7 t# V2 `; S3 h
  {# ~% J1 U6 f5 r; R' t! z
    DbgPrint( "KeyData is NULL\n" );
+ T! ~  Z2 ~! k0 }' l    goto __RoutineEnd;2 Y& _( |* ~% i( E$ S
  }9 H$ U' C8 U3 I& u
& @: s: E. Z4 `) O' B1 O! T
  //
6 ^& S! t3 r) s2 E  // 得到按键数
$ F* B- X3 z/ m# @8 p  //* ~5 L+ n$ G. i+ D
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
- g  A- @  l6 f* e% w, W9 _  if ( numKeys < 0 )
1 ~" A7 L3 `" ^+ u0 O8 ]. P" n* ]5 F  {; W- N/ ~0 w# v: |& ]
    DbgPrint( "numKeys less zero\n" );! p3 h. b3 _2 ]" ^3 K& E
    goto __RoutineEnd;( ~- Q1 E- @' z! ]0 D7 t7 @
  }$ D$ ]  k/ f" d/ Z+ a3 }

3 `5 e/ t3 f# |: }  //5 ], r9 \% N* y) J" `5 \# M7 }
  // 使用 0 无效扫描码替换,屏蔽所有按键
7 G$ [3 F5 T/ u# i  //5 K: C; t  D2 ]& `3 T) Y
  for ( i = 0; i < numKeys; i++ )7 g- c: M9 b+ \7 m1 ~& \, T
  {
3 r1 G: h5 b$ w9 A  F4 B    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
: y3 z6 H5 U" R+ M3 D6 N/ |7 C    KeyData[i].MakeCode = 0x00;
8 r( o! l! p# t% N  }
- s2 i" H% D! x; _4 U+ i8 v* q
1 Q2 C  B; X) B
: X) U8 X+ `, I  __RoutineEnd :   B& o8 ^9 \9 T

% P/ |7 X4 Z& J6 G; W  if ( Irp->PendingReturned )$ X7 W, C& N3 M* g
  {
/ f# X$ o% K8 w    IoMarkIrpPending( Irp );
6 {  N' T$ O- B$ w) |- J  }
2 ~3 ^: f9 R+ q" j$ z  E) v6 ?! ?1 S9 k. t3 a* U
  //- _# W" _$ m. A
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
! E2 {7 I$ v! |0 [* O) L  //
+ w) y" E* n2 I4 I  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
9 o7 [! I! C& C- z  InterlockedDecrement( &KeyExtension->IrpsInProgress );
$ [: \" n* F6 P5 b# i  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );& y9 |) k' G: ]  a7 }9 [2 I* B+ d0 @

3 \! k- g* L( A  return Irp->IoStatus.Status ;
/ T) o7 U) z  d+ _* n}
3 n8 Z& E, k! L* w* W  `% k5 J3 ?+ w4 S" M, `
; n" J- g% N) @- A
/*****************************************************************
' a. P7 V3 X1 {+ J! j  O 文件名        : WssLockKey.h
/ s* J, X8 H' |6 {5 [, K% M& d 描述          : 键盘过滤驱动: R6 X" z  ?; b0 u' w7 j" [
作者          : sinister5 K) O/ e2 H* ~9 G( V3 C
最后修改日期  : 2007-02-26  M; n5 N& j. b5 n* g( v( t7 C) k
*****************************************************************/7 b, S; K0 @, d0 R
& g, }" g0 k! I2 G1 V/ [$ n  p
#ifndef __WSS_LOCKKEY_H_" j7 n& r8 K! o* j' V. q* @
#define __WSS_LOCKKEY_H_
( P6 ^, Z) V* ^, y" E* H" r# L  @+ }: F/ q6 o' Y, A5 }3 i8 b
#include "ntddk.h"* ]/ @0 N, Q1 j+ Z" _0 R: |
#include "ntddkbd.h"
, P8 j6 h3 o* g' D#include "string.h"
8 ^1 m: G1 ^8 _/ R#include $ a) P3 I& M& V+ x: u3 y5 z
8 X7 B# P" m% Y# V) m/ }
#define MAXLEN 256* {/ ]1 m  ?& |$ m
6 a& t& K5 u% c$ k% {6 S) }  M6 r  X* X
#define KDBDEVICENAME L"\\Driver\\kbdhid"# g  p9 m% O4 t. G: s
#define USBKEYBOARDNAME L"\\Driver\\hidusb" * W$ _" \9 X' \4 }
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"3 J9 `8 ~: V- o9 C" R- _( i

# H) _: o1 N* e6 u5 T  O' d* Jtypedef struct _OBJECT_CREATE_INFORMATION
, V3 Y$ q; A9 w0 ^' R{# Y) l# x+ n; ]. k7 {% Y
    ULONG Attributes;
% O' u7 T: ~7 R- {* z2 Z    HANDLE RootDirectory;
9 A) e- {8 T/ H, T    PVOID ParseContext;& N* c6 D* r! ?2 T9 c
    KPROCESSOR_MODE ProbeMode;
3 w' o6 z1 z8 I  l. \    ULONG PagedPoolCharge;
, ?, B: t0 w( v  D' \4 h% S    ULONG NonPagedPoolCharge;
3 s& e( M* m# ~: j( J6 S8 R' }* m4 z! D$ M    ULONG SecurityDescriptorCharge;
- P( t) \. P0 G( C1 R    PSECURITY_DESCRIPTOR SecurityDescriptor;$ a- Z% `" x+ @+ c+ k8 D
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;. L6 p& @7 O% r, q3 V
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;0 a7 m+ F; P1 V/ b3 H9 g
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;0 s. ]: q; V; ], P# _
6 F) c3 N$ @4 M! e; @  I% [  ]. [8 P
typedef struct _OBJECT_HEADER
) ~5 |4 q- J7 L: H+ n; [{: b8 w" n2 W6 j1 N
    LONG PointerCount;3 T4 R8 d8 u2 M- h
    union! P# I! ~. a7 I+ n
    {- Z8 [% n  Y! l6 m; J. _  z) w$ o
        LONG HandleCount;
0 j+ U6 F7 @. _1 t; Z( |        PSINGLE_LIST_ENTRY SEntry;! ^# E4 f- z( v6 }
    };
6 J6 n1 X6 V0 x0 B1 K    POBJECT_TYPE Type;' h/ C# i/ t  e+ R/ p3 M
    UCHAR NameInfoOffset;
6 V3 w8 I6 U. P5 g2 h" {# P" h    UCHAR HandleInfoOffset;
6 M" X! t, F6 g+ ?% r    UCHAR QuotaInfoOffset;
: _+ a: Q  ?/ q7 n6 A3 B& d; S2 P0 z    UCHAR Flags;
, f+ s! f) ?/ P    union" W0 o& Q2 k" ]; x. i* a
    {
7 k+ Z3 _) ?' `2 h3 o4 H$ M& d$ R        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
! A4 r" w" B$ u- j6 k# `7 S        PVOID QuotaBlockCharged;5 \0 D) A" Z6 u7 b0 F
    };2 c0 j0 k  M# Z. n8 u

% G8 Z5 [5 A$ `, y4 f    PSECURITY_DESCRIPTOR SecurityDescriptor;/ a7 ^' ^8 n5 f5 E; R/ s
    QUAD Body;
) I/ Q& U& y# M* a2 V% p% t* [0 X} OBJECT_HEADER, * POBJECT_HEADER;
7 R0 c! P6 h- ]! }: [* O8 ]  j
5 G5 d9 w4 q5 X9 m/ e5 v#define NUMBER_HASH_BUCKETS 37. \& t" }0 J' F" l8 F, b2 \) D

! Z0 o) ?2 c) h9 }# F- Ctypedef struct _OBJECT_DIRECTORY  V6 N7 q& n; Y! y
{4 N1 Q) R' B6 M/ P
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];/ w% N9 G9 u. ]  V& A
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;) r' G1 X! _  U# n- Q4 j! H
    BOOLEAN LookupFound;
$ k7 q; Y0 [5 t  y/ ^$ k* f/ L; D    USHORT SymbolicLinkUsageCount;' o0 |! S1 b" l! q8 H4 u% K
    struct _DEVICE_MAP* DeviceMap;. s! H7 r! V8 [5 i; L, q" G5 Y
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;! \8 V/ e. S- A" [/ m- S
6 F! {0 R2 }" v; _+ T& I) R7 e
typedef struct _OBJECT_HEADER_NAME_INFO
3 j' u) ]: |4 S- |( E8 b( t: h- {{
! y) Q3 ~( Y- Y( r+ j" y- q0 ?    POBJECT_DIRECTORY Directory;
% i2 ^. l8 y. E4 e9 q    UNICODE_STRING Name;
3 s' j- f( F7 V" ^    ULONG Reserved;, I; H; w6 e9 p; m: G" H7 g* p4 _
#if DBG
. P0 `5 D% @/ `6 t    ULONG Reserved2 ;) p; d( |9 o2 d' [3 B
    LONG DbgDereferenceCount ;. B8 J8 A; d# X5 |* a. u
#endif
2 D! Q* ]" s5 S" w! B7 R9 r} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
8 M8 a# r$ r0 \/ D6 C4 f- S
0 g$ l0 O0 i: B) [7 d$ P#define OBJECT_TO_OBJECT_HEADER( o ) \
/ N) q8 A4 z# I3 D/ \; n    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
# C% a8 O; d; P7 G$ i. {' C1 O+ O7 ]+ [8 H) @: _
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
, v6 o6 i1 z5 P    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))- u, v$ w+ I) Z

# X# L/ R. K2 ], H; A8 T: m- ?* Gtypedef struct _DEVICE_EXTENSION( d; _$ R; R" e$ q
{
# }* e# D  v* ^2 F' i0 C3 r    PDEVICE_OBJECT DeviceObject;: l3 m0 Y/ a4 k- G- D: ]
    PDEVICE_OBJECT TargetDevice;
0 E. m& A0 W9 S  \    PFILE_OBJECT pFilterFileObject;
5 x! g- ~/ w2 a# Z    ULONG DeviceExtensionFlags;+ v: p; o& G) z
    LONG IrpsInProgress;
4 L5 I. J) Y) p1 S  i    KSPIN_LOCK SpinLock;3 t: S5 v' y7 c$ f: |/ D1 N! ^& \
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
3 D4 N1 m9 O; E9 I9 E- q  d/ t3 Q) K- w- I
  a) x1 m! Y7 @, o) W  i
VOID   S, H3 [: Y3 n7 q5 u1 G- z0 g
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
* g3 R7 u  i6 ]; U; i8 r7 l) O, h, h) ~8 h, A
BOOLEAN( I& ~7 e6 b% |
CancelKeyboardIrp( IN PIRP Irp );
# w! r) ]# X% `$ H0 H+ l$ {: {4 O' O3 {/ W
extern POBJECT_TYPE* IoDriverObjectType;& @' _* I0 D0 O) P

( L/ u+ X% G) l8 X4 R* MNTSYSAPI/ h# U* w7 a( w2 e, N1 \
NTSTATUS
2 Z, C' Y9 O) DNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
% J- U( n7 D8 u( a! l5 q6 p                               IN ULONG Attributes,% ?9 \9 V' V4 D; q  O& m' l+ h3 }
                               IN PACCESS_STATE AccessState OPTIONAL,
" t; I! v5 M$ P. Q& f5 n7 Q4 v                               IN ACCESS_MASK DesiredAccess OPTIONAL,/ W3 ]" B+ t- Z. J
                               IN POBJECT_TYPE ObjectType,) e% F" `; P0 D- g' N
                               IN KPROCESSOR_MODE AccessMode,
: r: y6 f( Y/ ?. T4 S  Y                               IN OUT PVOID ParseContext OPTIONAL,
  W8 X+ p9 z5 O' H. I                               OUT PVOID* Object );
- }6 G6 ?. P2 S
# j, m) b: E4 f, c: W- wNTSTATUS 6 h  Q  H. D5 L0 U) J( U- U0 Y1 C2 p
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );/ m) Y" d* |* ^( d$ e; S
0 v+ H1 N. |1 h, O  Q( c
BOOLEAN " A) w" H, J2 b  [
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
9 m' P, {% s* Q! O
3 ]/ z* M" z  K! XVOID
, @6 V+ `, q6 F, O$ L. {5 o8 vGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );) n7 q, g8 z6 y* O+ k4 I  k0 k0 Y# V

; g2 I1 ~5 h# r3 C# nNTSTATUS + F# i7 `0 ]+ B# J; S- h. ~# Y
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject," _. d" H9 ]+ @7 P; @+ c2 b; X# `
                                  IN PDRIVER_OBJECT  DriverObject );& ]& S/ O/ W$ [) H  F7 @: v  ~- j% q! u! [

. o  V* S/ i1 L% {8 }$ HNTSTATUS
% j& @6 D6 L3 @- B* X2 UAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
" Q" ^! O/ ~+ ?( u2 L2 v" l                                  IN PDRIVER_OBJECT  DriverObject,
8 k4 O& v+ H. k% _. K" n; Q7 z# M- Q                                  OUT PDRIVER_OBJECT* FilterDriverObject );* L% S# Q/ D# G8 ^2 I

5 n" \3 M) U" P& CNTSTATUS
* D% B+ E; r3 c: T' Y( d6 {3 vKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
/ P9 P/ m4 G6 S% S: W) c0 P                            IN PIRP Irp,* ^  A0 W1 J: ?1 l
                            IN PVOID Context );1 n' y* x3 t8 J1 Z+ w+ t# g
NTSTATUS ) ?" `& ~$ l" R9 @4 z: p
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
' W; C1 v9 U6 ]! r3 N1 z1 v( ]4 D2 x2 c3 r0 @
WCHAR szUsbDeviceName[MAXLEN];
) v' j5 O, G* `* {  I4 \) `# P( O* D
) P4 E1 Y  j  _/ [#endif
9 B+ D5 w8 h5 v% Y! l6 O( o9 }( ?
- O3 `2 T/ R( X- V- O( B

# S6 k; ~! ?+ r3 z3 d3 y( r. e- I6 M* U6 M2 F) ~

  `( F+ V$ T+ M6 NWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
8 r. ^. G: |6 i$ sWSS 主页:[url]http://www.whitecell.org/[/url]
( U7 Z( D' N6 bWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-1-18 19:14 , Processed in 0.061067 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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