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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
! D% z% \+ ?) L( LEmail:   [email]sinister@whitecell.org[/email]. D* g; X/ Z2 d; K
Homepage:[url]http://www.whitecell.org[/url] , v, T3 X& M( T3 N* B
Date:    2007-02-262 D# [; W: y1 d8 X# O
. ?1 _5 X+ S% g' Q

3 a' c2 s+ s( J# E9 W/*******************************************************************/ I$ v& m1 A7 h- N5 @5 M5 }

3 O9 E3 p8 f" _  [( l这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
$ u% p' d2 S! j8 O' c写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
: i3 n9 s* W) q" n/ L1 e- a功能要求如下:
7 B: l) P9 f! @) [+ j" k2 D' c- s$ u( l. ^, m3 g8 V, m
1、强制锁定键盘/鼠标。  C+ z1 A' X! a5 N7 V
2、可动态加/解锁+ Z6 z# X( K+ v. P) m& v* I- ?, F9 W$ N
3、兼容所有 NT 系列的操作系统。5 y* W) W7 z4 V6 N
2 Y1 b" N- O5 A
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
3 f4 Z2 B/ s3 W* e2 Y' _现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
1 b2 P. Q( |' K, a% f8 L+ P何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
& F" {& F" W2 ]+ f, s1 V上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是- p6 m- M* x3 `& B% d. m
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
6 \& y# S# r7 ~, B3 ?就来看一下我想到的几种实现方法:
, u% N1 s8 L6 e/ _4 Q8 c! Z# C) a9 y8 [; S" m
1、全局键盘/鼠标钩子
- f5 Y) V5 G: j  {9 Z( ]2、BlockInput() API5 X! Y# T3 i5 q* z
3、使用 setupapi 进行控制. y8 |' \; [8 G1 {
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL8 z1 y8 k1 e! z! h9 c3 L# @
5、拦截 win23k!RawInputThread() 函数( o. M' t: @+ c; ]  p& Z  S* Y
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
# e. \% T& ~7 F* m+ b' G7、拦截 kdbclass 驱动的 driver dispatch routine
+ @; v) d& \# ~+ w: E6 Z5 |8、实现一个 PS/2 与 USB 键盘过滤驱动3 F/ t) z- u# ]# }, W# {1 P+ m! f

/ Q2 {/ B+ _( |8 L9 k5 U8 f
& D/ j- Q8 D% K; b3 g我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
, R9 [( _+ E+ d4 q; f! o之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
1 x5 D- Y) V  g. U4 J案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
, m, M1 H* j) c" B兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
: }$ M6 |) M, r- r( N  e6 \素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
) }; ~; b" w& f* v7 x1 U. ~8 _- |% |问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸4 ]: f4 j9 `" n( b
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
& D1 D' l, V5 l' l! M的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
3 `, B3 f5 a' l0 H! X2 Y- @9 P. k9 d也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
5 |1 W0 h! x1 j$ d, N果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
. _& d& D$ @6 D+ h4 e0 X/ I  l2 n障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
4 ]5 k2 x+ t) U& K1 J# x) nIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 $ e% r) z5 U) A& @6 n
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键+ R; T; U! j9 W1 A5 P1 W
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
" m( Q6 @' z2 W# o/ j+ |- g) ^案的全部功能且不存在它所带来的问题,否则就没有什么意义了。: {2 S$ @2 @, @& Z" Z
4 S( \% F7 o- E1 g

" r! s. |% |; v4 l9 ^我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
8 ?' h' x+ W$ U3 Y滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进  v" z2 p' L1 q# j8 c- Q
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是5 b; u  {+ c5 q1 F1 v
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
0 b$ P6 ?- C+ K: q* |* I来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
+ ^5 i" A/ b; O0 V% ]KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
' n  W% j8 E: e& P- w% K键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
5 E2 U" A6 {) z! i* jIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败," y. C( B' Y: q7 \+ r
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
. B- l' u, A( @# M: y* @, t就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
- W5 H# I  D# [7 p7 E而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
; I, K5 ]& a( {用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通# n: Z# m; ]6 z- W
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
: X4 B1 l: ~. c* g5 S1 f  `屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
( J5 Y. G& d& f3 O- p) B  Q" J. x, n过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb$ D3 u' s1 m6 z
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
6 j) X& `! o- Y8 i# @8 u2 B- z的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
( T& c# @$ s+ G) q: W味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
2 ?9 {, C1 a. M' g: t4 U& {- K经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
( F, E, {2 G# t1 F. w3 _- B来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
% x1 c& i1 G3 @' M. X的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
/ V2 G% s! h- p5 M7 ]: ~  U) A的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致  ^4 ], [  a; o; @
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,6 c! M' C2 t7 r9 f- s! ?3 j% X/ \
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
# M+ T2 L5 @0 A见下面代码。. H+ _5 ~; i* p: o

  @7 T( W! f# u/ a- o4 L这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程( G1 x1 t8 p- W3 _, B4 E2 y
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键0 Z5 G9 @+ E2 v/ T& L. s' k6 K5 R! l
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003& ^+ h+ C' S1 R  [/ F' q& U1 m. _
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有! o( g/ X% c" E( e
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可7 _: g- U" N& f+ A5 o
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个0 U, k$ i0 k  g6 V0 h  `3 k
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按4 L( G& Y4 e7 \  |$ J8 w
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
7 P' |% v! ^- I2 O, \& B
1 X% z- X( m0 P& s' k
3 k% `8 ]1 a# J) l8 l$ j完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用) m$ N* Z7 g( v, w
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
* H: w. q. P; ]可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
) w" m$ k: P- H2 E9 X3 L的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我4 v" b0 d2 a6 ~8 F; t" s
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
% W9 l  N- W( x$ u: k们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
! C0 [7 E- p/ t/ v3 Z4 Y+ s( Q# P->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
" D+ z5 X  F) b* `3 p6 d! j2 o如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
% ~( P/ R, i/ S. [9 _进行操作了。这个问题有待大家来完善了。$ U: a3 B) O) s( |5 w1 e! y

2 Y! [7 P6 g0 K. ]: J- M8 I. W
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出% e, D5 d: n) Y; b! {
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的5 l+ m3 R) O# C+ g. v
分析做个记录而已。我更愿意把它看做是一段注释。
: K* C  s1 j1 g. t' |1 F7 v/ k* M# R8 E+ p7 b3 B
最后在此代码中要% c! j7 C. q& G" x4 I# ?% o
- ]! z. S% [8 _) Q' l
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
/ i( z/ k6 |  b" S" w/ v% q, W- @* q. I
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
) V+ k  u# I$ _/ m, e, n3 s4 \+ F$ G2 _. i  e. K
感谢:齐佳佳,过节请我吃好吃的。
+ B# F! h% H* o3 G2 w8 S8 m
# G1 _" w5 ^* Y0 A" X  j. p+ Z. l2 W2 E" t  A) ~
******************************************************************/! R) p2 s( `8 H3 m( n8 ]

8 O( p! r4 n- z% N! g/ T) c. w
5 V6 C# i: `4 B7 F* {# }) o7 k/*****************************************************************, |: w: i- N* W7 V; M0 g- [
文件名        : WssLockKey.c
8 u# t7 ~+ g' Y4 ~ 描述          : 键盘过滤驱动3 }$ a5 q/ E+ Y( a
作者          : sinister$ Y4 b, `& ]: F" J* D/ L( e
最后修改日期  : 2007-02-268 |3 J, q' K* H" h
*****************************************************************/+ R$ L' W; S# |' c3 n6 r
; {* n& X4 l  r# J/ r# q+ a

# }+ E+ p% S$ L& a( \#include "WssLockKey.h"
% }$ t7 i/ y: W% K3 w2 x3 l- H9 _6 a7 |  o* c
NTSTATUS1 G- e8 V% \/ `6 \; P
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,' a7 J1 l5 A! l
             IN PUNICODE_STRING RegistryPath )
- ~! c- o; d0 k! u& {{$ `9 ?. }' @$ S+ ^4 D* W% f
  UNICODE_STRING KeyDeviceName;
6 _* G3 t: q" t. O; E  PDRIVER_OBJECT KeyDriver; 6 h; B6 G7 \0 z4 Y
  PDEVICE_OBJECT UsbDeviceObject;
) L. _* A% C/ M( d7 F6 F  NTSTATUS ntStatus; : Q: o/ J% H% K. O
  ULONG i; $ X# r" c' r5 t) z

0 ?: ^0 M8 Y4 |1 H- v/ s  //
1 m7 q9 a! n, \$ i  // 保存设备名,调试使用
. K* \& d/ i1 o5 K$ v& @  //5 a# H0 Y. `/ R) D3 ]' s# l
  WCHAR szDeviceName[MAXLEN + MAXLEN] =4 T+ n$ v- y: o7 k6 Z4 e4 Z
  {# s  [. ^% l1 g; N
    0
, Q3 o2 z! _7 U' d1 m3 E$ U  };9 f2 G6 s2 F8 X6 q% w+ T& }

7 v$ f% u# m; |2 _  p) K7 b2 A0 [  KeyDriverObject->DriverUnload = KeyDriverUnload;
5 u% A) A. p5 z7 l; Q7 a9 ?4 l( @
  //
, O8 i$ ^. g  G2 B0 P' Q/ o  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘1 e/ M  n: M& O& K% Z
  //% w+ d. g( i2 g
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法0 H  L( Y; w5 ^* [- q. x% d
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
, z2 u& n% F+ j' P8 ~& N- U  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
& z; p7 r( u  \' n  // USB 键盘设备来进行挂接; ^$ f& v9 }6 K) M% x2 {# w
  //% w" j0 C; c5 A: i/ J2 s
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
. l9 R4 B2 W& h( R8 s& A) D; u* Y7 P; A  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )$ p2 x6 e" B9 O! |; K) c1 c& }
  {
* E1 x' a2 v  {    //, M% L& V" x0 f3 z  s5 k& L$ a
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名, s5 r- d, {  M/ i& ~, t( S7 Z% [
    // 所以这里打印为空4 j: ?+ n; s# ]) D* Y
    //* ~9 Y( D+ D3 z
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
) Z! c) n; j5 X' ^  `, c    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
% W: f/ K$ c  p( Y. f, ]
3 N- B# l; Z7 t3 V2 Y    //' y0 F5 Y! j/ ?8 `( m; T
    // 挂接 USB 键盘设备' M0 I% n1 a  y2 o" m4 _* `& u# G, ]
    //. I2 N7 o3 x/ H8 R0 {8 _
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
& Q, M( F' @) y! Y( G    if ( !NT_SUCCESS( ntStatus ) ): y8 q, G  I" O/ K' x+ G. H- O
    {
9 o+ {1 x  ?( G6 U      DbgPrint( "Attach USB Keyboard Device to failed!\n" );. o  X6 P+ r  X0 A
      return STATUS_INSUFFICIENT_RESOURCES;& p% r% [( n8 a, W
    }- ]8 G0 Y& b' O# {( V
  }* z& C, X8 [& {$ ^( F+ `
  else+ B5 m% k: b+ s
  {
6 h0 I/ _( K: u8 r( }' r( \5 P1 Z    //# s* t" {+ {- i% f( H7 m
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备2 K+ U, \- W" M' n% Q" x
    //
! B: N& |" P5 t. _( A7 I' ?    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 9 A! I" c) B) E$ s
, W$ @: \3 i. ?: X. E. s: H
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
( I1 \2 Z. [! X( l  U- F/ e                                        KeyDriverObject,
* C. R  s6 f' w5 i+ A/ `8 T' h                                        &KeyDriver );* L! D. K; R+ f/ r; f, b7 n
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
0 k+ F* A% N8 y% x  p    {1 s$ F( q9 k4 b* x3 r5 A
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
) e3 s4 J% S; i  A1 |4 L      return STATUS_INSUFFICIENT_RESOURCES;
) d, A' z2 m( \) ?2 R0 R. ?    }
" z* s+ p7 {$ c7 F  A" b' J  p  }
# A7 D& `/ {* c! j( R
# o0 t) A% i7 y  //9 B9 k* |3 A6 x/ A4 s1 X
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止; A8 y9 l& r7 ~3 ~( {( N
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程6 v3 D: z2 K; X$ U3 e0 z( o8 o3 e
  //: F0 s1 o5 v! t7 y; A: D  Z
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; : l& t) j: k8 E1 `# n
, W: g. l: ]7 E
  return STATUS_SUCCESS;
; C+ V; b% f5 H4 q8 Q3 M! t} 1 j3 L( Q* `5 p' G
! s3 o; y6 |/ J
/////////////////////////////////////////////////////////////////5 a5 S) B1 S* c) V6 m6 _
// 函数类型 : 系统函数
' c1 `6 }1 Q+ l// 函数模块 : 键盘过滤模块
3 ^4 B1 g! m4 Z: `////////////////////////////////////////////////////////////////; ^  B% P1 e( |# i" q$ A
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
& E6 V; G, B+ z//        卸载键盘过滤驱动, c4 m" F9 D+ w
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上  D9 e; ?( C: n/ i3 ~
//        则需要等待用户按键,以后有待完善$ |7 \6 F" n3 l; v! c" N, C
/////////////////////////////////////////////////////////////////* O2 l  j) o% L( ]& f( |  J5 T
// 作者 : sinister+ g3 ~' t# ^7 {9 h! Q
// 发布版本 : 1.00.001 a7 \* I$ O4 j3 A" P8 _: c
// 发布日期 : 2005.12.27
) c! \9 r; `# H9 R) i2 _/////////////////////////////////////////////////////////////////4 F( J7 }6 Z' a4 t
// 重   大   修   改   历   史
" x0 q, A7 c& m1 m; O////////////////////////////////////////////////////////////////
3 k  ]1 Q- q2 d6 Q) \( k/ ]) S// 修改者 :
% x: S) |* e) }3 b7 g. I0 Z// 修改日期 :
; ]" S, b  u: {// 修改内容 :
) F( X6 B/ f! P  U( i. h5 H3 S/////////////////////////////////////////////////////////////////  K, T7 T: @3 C% y/ t7 m  E4 x6 m
$ M' D  c$ w- r7 {! J" x6 z
VOID1 `( V- V8 I# ]$ Z' i0 l+ W4 c
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
/ L+ s) k# A' f9 X8 u$ m, v{
8 W# H# ^0 n+ J0 @" W, V' M1 ?  PDEVICE_OBJECT KeyFilterDevice ;      
' ^" T+ u8 G$ ~  PDEVICE_OBJECT KeyDevice ;
6 Y  b7 ?; b8 d" d/ p  PDEVICE_EXTENSION KeyExtension; 4 x% O6 q" K" K) ?" z) z  J. I% q
  PIRP Irp;
) _4 B0 z1 A6 y( e" o8 @% [7 p  NTSTATUS ntStatus;0 P) o) N. H( b6 f- M- A
. s* `5 h; W# o
  KeyFilterDevice = KeyDriver->DeviceObject;
0 Z1 e7 b$ H3 M! ]; k  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
) k: ^+ K; U( `& V1 k  KeyDevice = KeyExtension->TargetDevice; 5 t; u% j$ M# M% s4 @
+ _- x! l2 m* q& V8 X
  IoDetachDevice( KeyDevice ); ' ~, x1 T! `" R$ ~& ]" x

, |+ T% o6 ^( j8 y6 }  //
9 _6 k/ b) ^* ?' A6 O1 e* [  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
9 I; j% ~: H+ [+ i* R9 b  //
. Y: Z: z5 u& g& f# X, g  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )1 _( G1 c6 \* O( t( W8 K& n
  {
0 f: [. l6 E0 [1 l/ s8 s2 ~6 _    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
' z5 I! e/ ?9 _- ^. T    {; a7 ^% I9 H3 }' ~) r0 t  j/ ^& s
      //
; C+ d( m/ t% Z) Z      // 成功则直接退出删除键盘过滤设备; }# q* Z# V# u$ W9 n) F
      //: Z. _: V- H' X4 X0 @% I
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
# B4 b0 [: G- |/ s. z3 X# g      goto __End;) g; b' R- A$ W4 E- x3 g8 c
    }
" V! s; M, T  r' K: k, F% `2 a' B  }3 |; r1 {2 ~6 [! |( {

+ N) @& G3 `3 F5 K( K  //
% H5 w+ ^+ K8 x, `  y4 O: F2 ]  // 如果取消失败,则一直等待按键
3 O% b- k4 B8 R6 u- z1 `  //$ m. ^! [9 O: P6 y0 y( o) o. P
  while ( KeyExtension->IrpsInProgress > 0 )
0 E: a0 b) i% a7 Q7 @  {1 _! A& Z7 E3 {% v- N9 d2 v
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
/ |6 d3 b) V% |! m2 r9 r  }; V2 T; N5 i& H0 x! U

. x* N* e* K7 n# ^# {  __End:
  E7 Y. h2 V/ T, j/ a3 ]  IoDeleteDevice( KeyFilterDevice );
1 f/ p1 \1 x3 M. _1 e- g% h' O/ v: g" V, e' L
  return ;& ]9 a6 B# X! a1 Q8 c9 }8 ?1 R
}
  Z# D! S8 q, ^1 Z
& K9 e, E% b; Q6 q# H7 W3 H/////////////////////////////////////////////////////////////////7 x! T( n1 T1 H
// 函数类型 : 自定义工具函数( P+ g( J5 m9 X9 p: O0 F/ h5 A) ]
// 函数模块 : 键盘过滤模块
' k' g3 [2 V; k; Y/////////////////////////////////////////////////////////////////
/ c6 Y% R1 X- C1 `7 g% _9 Q1 T// 功能 : 取消 IRP 操作8 G9 P5 ]$ V$ j4 B6 r1 O% ^
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能) D% P: M0 K1 V% L% A, v% J
//        使用此方法来取消 IRP
( y" l7 J& l/ V9 I/ M/ T3 T% y5 D/////////////////////////////////////////////////////////////////9 i' M3 h  W8 ~+ U- ?6 F
// 作者 : sinister
: W5 T7 a# |; b% G" m// 发布版本 : 1.00.00, g) s, y: @3 w3 J, v
// 发布日期 : 2007.02.20
6 i, w( }6 ]& m# X5 K* K9 Q/////////////////////////////////////////////////////////////////
& @* ?2 Z& e  A4 E2 l4 @3 i// 重   大   修   改   历   史0 }1 ?, p) q+ N/ {  ~7 Y5 }
/////////////////////////////////////////////////////////////////
) X  A/ r) o+ b9 u// 修改者 : 7 V+ n% N9 t; P6 D! t
// 修改日期 :
, g8 Q, X$ T- q! N; ^/ J1 ~// 修改内容 : , e. B# F9 D; [- ~+ T: V6 V
/////////////////////////////////////////////////////////////////
( o9 R+ h  j* n, r% n
; y1 o8 \6 |$ }+ N" B8 e) rBOOLEAN5 L) g8 i4 ~/ t6 f/ I7 I& u
CancelKeyboardIrp( IN PIRP Irp )
. k, b8 D/ Q5 P" ]- ~{
. L* O# `& O1 K  if ( Irp == NULL )& G1 Q3 f: k' P8 j
  {
& A; A3 Y& }; z! f' {    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
9 p. i$ R- N" A    return FALSE;2 m4 P+ f$ a& `* e3 M6 D. r
  }
. k0 y& b2 x/ j
8 U* N0 @5 t7 b+ h3 V$ y5 X( a" t; u( o8 p  A. R: {
  //0 ?! J4 U% X7 F$ [
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
$ j! U  P" M* c3 n+ u. h  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。/ L4 `9 \2 }5 `6 e# C1 t/ }
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
3 V; x1 ]: J: q4 y( W1 u  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD2 Q& a0 s/ c8 t6 k/ m
  //
0 h6 c5 X% F( H7 }! z  t$ v! l. q+ X: R6 i; i
  //1 R6 i6 y. H2 Z
  // 如果正在取消或没有取消例程则直接返回 FALSE
6 c# g+ H0 M  j. |% E- f. _  //8 V6 r' L4 y9 u+ h: G7 W
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
* M# V. \2 c. h" m* U; R- h+ i  {& j% [7 d0 a0 X
    DbgPrint( "Can't Cancel the irp\n" );- @) J" @) i+ o* N* c, _6 i* C3 o( j
    return FALSE;
1 a- m$ `) K& V3 e! x8 P  [  }
6 E( g  M2 w! g+ X4 J5 P( b  p; I  i4 ]+ v; R
  if ( FALSE == IoCancelIrp( Irp ) )$ Q; r* W( l! \+ n* q
  {( s, |. p5 {  L& u1 |$ a# u
    DbgPrint( "IoCancelIrp() to failed\n" );
* D. C4 P6 s8 l  l. F" v, }! e    return FALSE;7 z, a* k+ l' W* |& x5 q, O
  }6 n+ v: N3 m8 W8 A8 ~  \

* B: ?  ]5 n8 k& f; T7 F& R  //
4 ?# E" J) }- [$ D  // 取消后重设此例程为空
8 a& d, \7 i1 r* K5 z9 S* _. O  //( j3 e* m. n4 L
  IoSetCancelRoutine( Irp, NULL );
0 {" j% i" L! z( d. _! k. w% t" Q. Z+ M; K  m& {( }3 q
  return TRUE;  l; {/ I) T0 x* ?( q
}" Z0 R, l  U0 k5 L# I9 q4 a* U
" a9 E9 K4 E( N% f4 R8 g0 T' b
/////////////////////////////////////////////////////////////////
/ ?) |0 V' k! U, ~// 函数类型 : 自定义工具函数% ~; h4 J5 k) [: w/ P' N* ]
// 函数模块 : 设备栈信息模块7 j5 ^! O  M+ p% _: {$ S" ~8 [
/////////////////////////////////////////////////////////////////
/ t. ^/ n! ~* B; H# B% U. Z* l// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘, G+ I( p5 n3 ]& N2 T3 e  i2 h
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
5 |, b! K$ x6 d9 Q7 }$ d' [* X// 注意 : ' {2 g0 Y2 S2 O- v% G. C9 w  a6 D
/////////////////////////////////////////////////////////////////
1 V) d+ h. r  i. @// 作者 : sinister. L+ k- }* F. @! X
// 发布版本 : 1.00.006 M* I3 `# N6 ^& U+ b3 D
// 发布日期 : 2005.06.02
# g! L) x2 [2 _0 G% o* k/////////////////////////////////////////////////////////////////9 k  ^% t& e# F/ i4 K; j, T4 y5 e, O3 j
// 重   大   修   改   历   史0 n0 Y# h: l% y: t/ n
/////////////////////////////////////////////////////////////////$ a2 c7 t" x7 ~
// 修改者 : sinister
! @' H' j. h7 k5 L) @5 M// 修改日期 : 2007.2.12
3 z9 h& T. h) p! z// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
! k, T" @' B* G8 [( X6 f. f% z; @' q/////////////////////////////////////////////////////////////////! \% ~; V0 l; Z  Q4 G
, u$ ^; c$ h) g; x  a6 }
BOOLEAN
. }4 h+ k( n' }$ b. C0 ~GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )/ _& w9 E, F2 D* H+ X2 h9 B' O
{
( [) _/ t9 O! R$ H$ B  PDEVICE_OBJECT DeviceObject;* ]9 U% [& D. I# a
  BOOLEAN bFound = FALSE;5 X' L& O' l, f4 N
$ [; {$ k) C( V6 k
  if ( DevObj == NULL )
3 U7 ]% i6 l% z% [2 A  {9 V% @4 [0 @: u4 M' a
    DbgPrint( "DevObj is NULL!\n" );
( P) w( l) k% o# E% ^    return FALSE;7 b7 D( E7 c( U- \) y
  }3 E" v- P2 R+ j0 \" z% V( c
8 h) B  `: s+ o7 ?7 _6 Z2 e3 I5 ~4 R
  DeviceObject = DevObj->AttachedDevice;5 v+ N+ u  E) p/ w- z
3 t- V; W. ]5 C8 e$ D
  while ( DeviceObject )
" Y! x0 F1 Q7 v# L6 r  {
  j" I# u. y" F8 q- ~    //$ T1 D; i# H7 j
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但- Y: ^9 c+ D: ~3 ?
    // 有一次足够了。这算是经验之谈
% @: @" `; T4 Z. X+ ^' s" ]    //4 d; P' x2 {1 p* `$ V. b$ B, S
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) ): y* g+ _/ N! T. a# L
    {! ?! v3 C7 u0 y2 j4 e- c' X
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",5 d5 a7 A8 _- b/ U' {
                DeviceObject->DriverObject->DriverName.Buffer,
  _; X* ~) u9 S. B$ A                DeviceObject->DriverObject,
, Q0 u5 x$ S, V1 q5 U- G* d3 `* M                DeviceObject );4 L- b1 b' F; L; ]  \
. l1 b- a# n# W5 H
      //& L% S9 O$ Q+ g# L& D
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了! p& q2 F4 o. h
      //
+ A: h1 D9 z4 ^      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,9 W0 h0 }! N  }
                      KDBDEVICENAME,/ K. b1 S* h, W
                      wcslen( KDBDEVICENAME ) ) == 0 )
& r2 x/ @# ]% L( v/ V" L9 }  H      {+ T4 r9 X0 B8 \! ^$ G2 F  E
        DbgPrint( "Found kbdhid Device\n" );1 _! g6 y/ W+ n- P4 |1 h5 X
        bFound = TRUE;
+ Z9 A8 j6 J* D( x5 V        break;
/ o2 c7 t2 w" C6 m      }
5 q2 k- ?' u# G    }7 \' h, y% V! h' o
5 I1 i( x! e4 A) y
    DeviceObject = DeviceObject->AttachedDevice;1 b* ^! N9 A) W
  }
1 a0 d  d8 s8 }5 ]( d, P
* j9 A$ ~5 ?# \3 ^5 N  return bFound;$ v. u) B* I; c% Z% i& ?- Z
}& T' c, }( T& ?

) g9 m) V, x& x  p" c. z/////////////////////////////////////////////////////////////////3 n% J# d1 Z' f
// 函数类型 : 自定义工具函数  f  M$ d. o" z& `' ?0 s- y! @
// 函数模块 : 设备栈信息模块/ t7 z( O5 T- i1 R
/////////////////////////////////////////////////////////////////
4 k3 O' f8 d" [# J* R8 G// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
5 P* \  ]2 S1 v1 A2 `, W// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改  i- s% g# G6 Q
/////////////////////////////////////////////////////////////////. d% F4 A, Z; H# Y4 z2 h0 e
// 作者 : sinister
5 B: Y3 \+ }6 V1 D( K6 O% r  H// 发布版本 : 1.00.00
; z9 }1 e  _/ }# l, l8 F// 发布日期 : 2006.05.02
( }9 C" M& v! S3 v) @: z9 }' D/////////////////////////////////////////////////////////////////
" Y% i8 v( V3 \# f& ?( C( U# q// 重   大   修   改   历   史; E5 K0 J  F3 t/ T4 q. h
/////////////////////////////////////////////////////////////////9 k6 R) y% F/ i* r  ]- T
// 修改者 : sinister
$ @: U% I! t. o8 h- _, E// 修改日期 : 2007.2.12
/ Y5 S& b1 E$ H5 D( T2 l: Y// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
9 D( @; P  g8 Z, c. B3 a/////////////////////////////////////////////////////////////////
- s3 `/ D* m2 r3 |1 M7 ~$ L* a, q1 A7 v; L; w9 ?  S4 M, B
VOID1 j0 R# _% [9 q/ y$ U
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
, J# ~  i4 x, R0 _3 q& g{
! l7 r+ \1 Y8 J& W# e1 T. Y- c  POBJECT_HEADER ObjectHeader;) q8 T$ {1 }5 n2 K* _9 ^
  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 3 w; a4 r) y1 R* e1 B% L
+ f1 b0 s) I8 ]! I/ |" N
  if ( DevObj == NULL )
1 Z& f1 N* M# I4 A$ U  {3 ~* [0 R9 w7 X$ p" J" p
    DbgPrint( "DevObj is NULL!\n" );! Q2 Q3 ]% s1 w* C; U% E
    return;& w: ]: t; F! D/ t7 S# J! h5 V8 G
  }
- u6 [+ z2 p$ o& q9 M0 H) M% e
. d9 M, [( d* B7 W  //; z; A$ t  u( t9 i
  // 得到对象头
& R8 e% N8 X8 z4 j% R' ~  //
- j6 m  J! ~+ S4 F! X  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );5 K, w% J% U! M. x  `. `* P

4 n! D1 m- _2 t- [  if ( ObjectHeader )
' v0 V2 r+ e- G# }. b- T  {
3 _" ^" v: n# D% _, B& G  g    //
) K& f- _  ]$ E8 U: T7 l    // 查询设备名称并打印
8 d. E& Y! Q  M. H    //
2 h' C' j9 j- n4 q8 z  E1 U6 E    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );7 t/ `! I  Q/ R: J- {6 a% K, o
9 J, C+ A- p" v9 J' H5 f' l- |
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )2 Q: L6 z0 D" J" G5 ^
    {
4 Q% M5 X$ M/ ]9 U- }3 B# s      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
; K( m( w! H& M4 B                ObjectNameInfo->Name.Buffer,
- f" H6 u# G. B5 \4 Y- q                DevObj );( \2 \& I7 H, n

1 j, g5 K! a$ q' y9 s+ r7 s      //
, u& J) w" b7 |      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
* e) [/ m3 D9 b" c! u* M) B- ?      // 用,没有实际的功能用途/ h+ x# u: a- U' o
      //
0 R* c4 V: u9 ?; ?" r/ z$ i      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );$ w5 h4 Z% \6 q; j1 w

! W' `9 w! R" C8 u, L, Z# l: L      wcsncpy( szUsbDeviceName,3 N. A, j- `" j5 k6 X& a, I% m( [( P
               ObjectNameInfo->Name.Buffer,
. l; I5 `( q( ~               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );  r: [' ?7 Z$ E, `. ~. Z- v& j
    }
: @- H( A7 Z' e3 p+ ^# n0 {! P7 @5 l0 a8 e3 g- |
    //; Q2 i1 c/ t& c. c4 H0 W: X, u" F6 \
    // 对于没有名称的设备,则打印 NULL+ M8 f6 A5 p7 J/ R1 ^# m" v9 e
    //
5 Y9 {0 R# X5 O8 ~& `1 k    else if ( DevObj->DriverObject )
' ?/ h  ~! ~/ v9 X6 K1 x    {2 U: o5 n2 D" Z: v" k( B9 e/ }5 D
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",6 K5 u: j4 a  e4 j9 f1 e
                DevObj->DriverObject->DriverName.Buffer,  J5 i5 e/ z: `8 e- q& ~: \$ m
                L"NULL",& l/ g# [/ c4 O( Z
                DevObj->DriverObject,( T/ t+ _# I; _
                DevObj );
$ E3 H) e. F3 k6 E0 k8 K/ a    }2 @2 X/ x1 V$ r: ?, h$ ]' {+ @
  }
) Q! g( {/ b1 U}4 k( z- }* H; o$ I
4 m% y, F) {, t% T! W6 D& U
/////////////////////////////////////////////////////////////////& r4 h, u: F3 C6 o# Q3 P" F# u
// 函数类型 : 自定义工具函数& N2 i  W; o, j) }0 ^$ g
// 函数模块 : 键盘过滤模块+ \& S) y% S% i5 t; ]. T0 O
/////////////////////////////////////////////////////////////////
; {7 e' S2 k; Z, i: \  v( ?// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
/ m9 S/ Z: i# S# F5 Y7 Z//        对象,过滤出 USB 键盘设备,将其设备对象返回8 b( j7 Q2 c  W1 y# w
// 注意 : & N! r# b) s1 |& b: k" }5 V
/////////////////////////////////////////////////////////////////6 V) c/ l+ s# H4 T5 S7 f
// 作者 : sinister
% ?) r. m9 ^/ a/ m2 C* m4 l/ u  g( ]) S  f// 发布版本 : 1.00.009 l; ?) k3 |) o5 Q& W" s: }
// 发布日期 : 2007.02.131 Z: P, I( o  z. ^- y  {
/////////////////////////////////////////////////////////////////
$ U2 D8 `4 ~, ?) c# q// 重   大   修   改   历   史1 e& A8 z- G/ h' U( x( J4 t
/////////////////////////////////////////////////////////////////
# K) l: w' a5 o! R/ |4 q// 修改者 : + o; c* O  l( j* Q
// 修改日期 : & j9 \- S) ]5 A) U; _/ o8 @" P7 N8 ]
// 修改内容 : ' C5 y; L9 G' y7 u0 O
/////////////////////////////////////////////////////////////////% d0 t% P; r% r
; A: m& I2 L& {3 I9 m5 l
NTSTATUS+ G* l: l, d7 r( q3 `3 r# U: P
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )& n# g( V# s  [
{  \7 Y6 X: H6 |* K7 c  v) h
  UNICODE_STRING DriverName;5 B$ |, o* ~/ C
  PDRIVER_OBJECT DriverObject = NULL;
: Y8 ^, ?; u8 o6 u- a  PDEVICE_OBJECT DeviceObject = NULL;
1 W. o  i+ m1 `' R  BOOLEAN bFound = FALSE;
* j# c, P; L) r& R& U+ c- p: c
$ U8 y, X( C. S: o( g2 x* [  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
+ T% ]% o: e! o0 c9 f5 I$ q. I; T8 R3 d/ k; ~1 V) L
  ObReferenceObjectByName( &DriverName,6 R; \4 R+ y/ Z2 P, `# N) ^
                           OBJ_CASE_INSENSITIVE,
" _% v0 Z6 j9 W9 j                           NULL,, ~9 E8 Q* q8 x* s3 j+ ^8 Q! \7 L
                           0,
( `2 t, c8 A1 a+ c& a                           ( POBJECT_TYPE ) IoDriverObjectType,7 K( e. v9 u: |0 _  H
                           KernelMode,2 V" v6 r8 _+ |( V0 Q$ c
                           NULL,1 |: S3 O+ _9 ^5 e2 Z! Q
                           &DriverObject );+ D8 ^- h9 W# y- `

- G" D9 Y9 a# C( d; F) v  if ( DriverObject == NULL )
2 l2 G3 N5 V6 |( M2 x* G  {7 i: Y. o! k% k) H) ^6 v" i4 H
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
0 N: _& O4 N6 ]7 Y/ d5 f    return STATUS_UNSUCCESSFUL;
6 \7 h! U, l# _- g5 G8 D  }
5 G8 |5 Z% j' q+ E  G6 Q# l! C9 o2 ?5 [/ g
  DeviceObject = DriverObject->DeviceObject;
) V- {5 I" f% U* ]: `1 U$ x7 W$ C) \/ p
  while ( DeviceObject )+ t+ f5 N( o/ S8 q& l
  {( P7 X$ r6 D/ Y1 ~; n' ^6 t
    GetDeviceObjectInfo( DeviceObject );
2 ^, J# z! C" F5 Z# Y8 D) N3 t) ]' O+ k
    if ( DeviceObject->AttachedDevice )- e* d# v+ s: t4 d
    {5 P2 c& `; J6 C) r6 I1 @/ w; v
      //
! X! G4 [) t: M, T4 M- n* l! U7 A      // 查找 USB 键盘设备
% i) z& D" C7 `4 J1 P! }. v      //! t& m" o* Z4 R% I
      if ( GetAttachedDeviceInfo( DeviceObject ) ). P" K' v$ A6 y% b
      {2 Z, x6 c6 A5 a/ a% ?
        bFound = TRUE;# o& D4 W9 _3 E! y: S' h: j
        goto __End;
8 ^1 G1 `" S) k4 v8 h! t! Z% _8 t      }
2 }% n, @, T7 a    }: X1 w9 @. X: q1 E) @
# ?  c" |* S* T& q3 G
    DeviceObject = DeviceObject->NextDevice;
3 e$ J" ]; L* R& H1 i1 q: |  }
6 F  V$ Y8 w7 \' ]+ k# g. Q% y. I7 X: r/ e
  __End:- A6 _" O( |  |# R- c7 D# M2 R: J

* h) C% g+ }- ?6 X' S* g  if ( bFound )
4 c0 U  _: ~. J8 C  {
0 q' K8 o, |% B& X    //
; I4 A* [& ~; V9 t2 E    // 找到则返回 USB 键盘设备对象7 _" a4 b3 |6 [' L
    //8 ?' E0 }6 B( M* N4 T; X
    *UsbDeviceObject = DeviceObject;
9 y% |/ S- D: A7 q  }
' {# T% [) T+ @- F  S% p  else
/ P* j% g7 h: f* `2 H/ h3 T  {+ }/ f1 v1 J' @9 N9 [7 W6 X
    *UsbDeviceObject = NULL;8 ?/ {9 \+ J/ s. @/ e! n
  }" ^8 m4 d# h# A( C

/ o  l- Q8 t' j: Y9 S  return STATUS_SUCCESS;
" X4 O, _5 W0 X* v' A9 l$ A% R}
5 R7 c3 P3 c. D% A
2 Z* h4 ]2 D( t% z/////////////////////////////////////////////////////////////////6 o0 w% y' K+ n& [" s1 A4 [+ y& g, H
// 函数类型 : 自定义工具函数
# D8 q5 h' p' Q. I+ A* f// 函数模块 : 键盘过滤模块
7 r( w6 m  ?7 B4 t////////////////////////////////////////////////////////////////1 `5 u9 b1 C  Z$ }, n+ u3 n
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关; ?8 P" t) L' S7 L; b
//        信息,返回附加后的驱动对象7 K; f9 d$ u4 c4 _
// 注意 : 此函数仅挂接 USB 键盘设备
" C) x8 L9 w4 \2 a9 ~  Z/////////////////////////////////////////////////////////////////
3 \4 }, |/ g- I. X  ^' C! q// 作者 : sinister3 G7 k. S; d  d7 b" l# @+ N; Q3 m
// 发布版本 : 1.00.00; w) L- N% y' V, f
// 发布日期 : 2005.12.27' }0 S1 M6 _0 \# ]& i5 E
/////////////////////////////////////////////////////////////////" L! }& q4 w! A
// 重   大   修   改   历   史
  W0 `+ ?0 b4 g+ d////////////////////////////////////////////////////////////////8 t% h2 C( `0 R/ Z8 T" ^
// 修改者 :
; o; J+ I- N" m& z4 z// 修改日期 :
% V. A0 a. Y! Y// 修改内容 :
" C' z2 F. r' Z" S* {. h  a/////////////////////////////////////////////////////////////////- I- N2 F" w! {! w  F* [5 v
6 s9 _6 |% @. d+ ^  B. i6 `
NTSTATUS' d5 d8 m' J$ p. V
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
( @+ H4 V6 S$ e( S) n                         IN PDRIVER_OBJECT  DriverObject )
, ?) D% d9 Z, F& f7 i$ i{
5 w) Z' h5 x% P- z  PDEVICE_OBJECT DeviceObject; $ B7 a% ~8 x4 d- X: [2 v5 N; C  G
  PDEVICE_OBJECT TargetDevice; 4 C# X+ y- k+ Y4 g6 ^3 [" `
  PDEVICE_EXTENSION DevExt;8 E: o& u4 u% {: Y9 i
  NTSTATUS ntStatus;3 Q8 k; Q3 ?5 m& e7 N
) U1 e5 Z4 l$ k& U7 z5 f) S
  //
0 p: ^  s" v4 {' S4 _4 I& A8 l  // 创建过滤设备对象
6 b' M0 m5 \! R' o! y* V; d. Q9 y! r  //
9 Y, i5 E& G/ k  ntStatus = IoCreateDevice( DriverObject,
, O# L. {9 f/ h  c                             sizeof( DEVICE_EXTENSION ),) E% H7 L$ @5 G. L0 K5 F
                             NULL,
" S; ]! Y( D8 R/ C2 i1 D& }                             FILE_DEVICE_UNKNOWN,
$ G  _7 f. C  l; S! f, m                             0,
4 ?/ b9 N* q- d& |  `4 Z( E                             FALSE,
$ _  v% z6 ?" t" Z                             &DeviceObject ); ! ?$ ~" c! n3 A+ n) a+ k
5 P) b/ W) g- ]6 ^) a& x
  if ( !NT_SUCCESS( ntStatus ) )
( y+ K9 d; x: Y  X  {
4 d, _! A: i& N' U( }3 j; [    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );; f0 c! x  Y* s+ C( G2 G1 a
    return ntStatus;4 L, X6 z0 W* H1 \% P
  }
# [) u; x5 T" b/ e, z3 h
, J$ {2 M( {6 d5 ]* l2 @  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;$ K' b- Z( D1 L4 M: e% i

. E1 Y0 `0 s, V* U- Z$ d  //8 @1 n1 k  `( e$ v. X# v
  // 初始化自旋锁" f/ i0 `- Z2 n, B7 X" _, j
  //- Z& n4 Y* n3 n4 F& ]
  KeInitializeSpinLock( &DevExt->SpinLock );
/ E  n, @. B5 |7 k) `, G5 |. v
, v% o* _, t4 q2 S2 v* I  //
9 i5 e" O; S0 D3 p; ~; H+ X/ M  // 初始化 IRP 计数器
0 ~0 l! ~0 T; ]* {: A  //
. A. Z# k. |/ d/ W! q, W% P1 I  DevExt->IrpsInProgress = 0;
; |. ]7 w7 ^% w! L$ r7 |) D- E' `0 g2 V4 l, [' z6 l
  //+ g, F9 Y, `3 ^" J8 [0 ^
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
; k+ V4 F) q7 o8 F9 s# B  //5 c( ~" B" R; d

& h, h' E% M; _6 [3 @  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
. w8 ?; J( l& ]5 a  if ( !TargetDevice )
- u+ y- M& {  E" J8 m& Q  {* @% _. Z0 _9 s+ `7 L
    IoDeleteDevice( DeviceObject ); . {; z6 p* }7 n6 o: o3 [
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );2 f4 `$ l+ |8 P5 G
    return STATUS_INSUFFICIENT_RESOURCES;
$ b0 o! I4 [5 ?6 b9 {  } ! `  @$ l2 F1 b. m& q$ R
! ?9 H0 i# `5 {7 T. n8 W: _
  //5 P/ `) z7 V- j
  // 保存过滤设备信息
( F9 [# T- |( N) U6 b0 ?9 _  //
/ x6 F( h; a7 F6 y  DevExt->DeviceObject = DeviceObject; 6 J. }" z9 Z$ D0 A) p0 b( W# C9 l8 z
  DevExt->TargetDevice = TargetDevice;
2 |9 x8 k/ C# e9 n0 @* \% T- M# b. V( d- i* `
  //$ x2 f0 k' N7 J# `* m$ `. _9 i
  // 设置过滤设备相关信息与标志- Q% l+ ]+ I8 t8 C$ w! n4 L: Y
  //, e- h- B! t9 r$ C
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );2 y7 E7 [% S+ m5 |( ?* N
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
& D1 V' j7 e: M+ }- l8 L. _- {$ k1 i7 O; \7 O. l$ B7 Q; d; C

8 R2 F' b/ ]9 |) o3 Y  return STATUS_SUCCESS;
/ \4 a2 z* u5 j; g3 P$ R}
. U" K  @. r1 o% j0 C% H+ f! d: Q- y$ }# S
/////////////////////////////////////////////////////////////////  X$ E7 a( x' u, c; K) o7 K0 t
// 函数类型 : 自定义工具函数
* s8 ?- Z# q: H/ \// 函数模块 : 键盘过滤模块  g. U% q5 v* `3 O
////////////////////////////////////////////////////////////////' f2 n+ W8 M) u) A
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
% }- j+ L4 r# C//        信息,返回附加后的驱动对象! r1 s" Q: r0 S: f4 y. |
// 注意 : 此函数仅挂接 PS/2 键盘设备, b: _' y  k* H% N
/////////////////////////////////////////////////////////////////
* L: ^1 q2 w9 v% @0 u# f6 a// 作者 : sinister
/ i7 R( Z. j6 E3 z, I; M' ^5 z// 发布版本 : 1.00.00- t5 U: C# G4 y
// 发布日期 : 2005.12.27
  w. C6 Z6 O" b/////////////////////////////////////////////////////////////////4 q3 D6 f0 q# m- s* s& W
// 重   大   修   改   历   史
9 A! j3 {6 y. E$ O" m////////////////////////////////////////////////////////////////
( L  X" I0 [) T6 q: O// 修改者 :  W7 i! W" h) F/ q$ e: u
// 修改日期 :
8 j# g# H& h& a: V- g) _// 修改内容 :
3 D; z% w' y7 H/////////////////////////////////////////////////////////////////
4 P- A% C) R7 a+ U& ]: ~' d+ l7 F2 Q) C: c5 N# f% l
NTSTATUS0 l( ^1 g: @2 m1 d: B+ E* L
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
  I1 U- ^! t) P* L4 I* n7 A$ r                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象; p- E1 ], s, s6 ^& n
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象+ g9 M+ m( W$ V6 }
{# v/ k( V& r% o+ W. c2 O; I
  PDEVICE_OBJECT DeviceObject; : q. |' c. g) _
  PDEVICE_OBJECT FilterDeviceObject;
/ |5 {5 Q6 j% D8 D8 P! G  PDEVICE_OBJECT TargetDevice;
. j/ L: J: [1 ~9 T2 Q) ^  PFILE_OBJECT FileObject; * C( f/ g5 @9 k% y( \2 _
  PDEVICE_EXTENSION DevExt;
$ `( r7 s, m: R; Z6 i( ^. g3 p5 _# \
  NTSTATUS ntStatus; 6 A: s: K& g5 V$ g% |
$ s& B5 O' e& i% T3 f
  //
9 |/ a/ {, M. m" v  // 根据设备名称找到需要附加的设备对象
: @2 y- V. l$ G  //
6 R* a: Z1 P3 ^5 F! A5 }  ntStatus = IoGetDeviceObjectPointer( DeviceName,: L$ M2 ?) g4 ]2 k: P
                                       FILE_ALL_ACCESS,; [3 Y7 L% a! g5 F9 g4 {4 o
                                       &FileObject,. p! V& c- k! q* Q
                                       &DeviceObject ); , i  a1 }4 f* L9 \% d2 \

3 w9 A0 D/ w0 F/ s% M( h  if ( !NT_SUCCESS( ntStatus ) )
) @) S4 a1 h  _9 @& z  {
+ k7 y* M1 l! L    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );  u9 K$ |& e2 q" K- ?5 P4 x! O
    return ntStatus;
2 p) h8 \, A' F& L2 {; \' Z- k  }
% A) x9 C4 B& `5 @8 K6 H0 U( K: X8 S& x
  //
7 ]9 L" e- x: }+ M  // 创建过滤设备对象3 R) L2 ~  V6 O( g" r- N
  //
: B. ?3 r9 ~) s4 ^  ntStatus = IoCreateDevice( DriverObject,0 e. ^5 |' e) |+ T% c
                             sizeof( DEVICE_EXTENSION ),
: g3 M% t" B7 G/ R                             NULL,
, w! o/ H5 Y% [- j4 I  R                             FILE_DEVICE_KEYBOARD,) f  S# L$ Z  O6 D' {% D/ b" o. l- _
                             0,
& W! r) a* B0 D* f) K% l                             FALSE,
  ^) _1 |# N" W5 d7 m. F: K# ^4 f                             &FilterDeviceObject );   `& X5 T4 N, ~, z4 z; Z

% u& ^5 R+ l" j8 w% `  if ( !NT_SUCCESS( ntStatus ) )
. Z  q* M  T( k) m* Q3 u# w$ _$ _  {2 j; j2 F4 ~! j  f$ }
    ObDereferenceObject( FileObject );
- N* R3 u8 s9 q5 i1 b/ v% \8 p% D    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
$ Y  K$ n  C9 g$ n9 C* B- J2 n. t    return ntStatus;4 z. V6 X# N, T
  } 7 G- K5 ]. g" D3 ~! u7 N% R
+ i# J3 Z/ M3 s0 D1 r) t1 \
  /// Y' C" b2 S5 k7 q/ Q
  // 得到设备扩展结构,以便下面保存过滤设备信息
* Z/ q3 L# k3 o  //
8 F2 }5 F8 b! P$ n, S4 q3 `. Z- [  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;7 \+ l( u* z# i$ t* [3 D1 |) B
/ _3 H1 q* {  P; D% O6 H

1 X# a: ?1 C, u$ e  E1 X  ?& L, h  //
8 a6 `& P1 V: q+ p9 A: n7 o  Z7 f/ u  // 初始化自旋锁/ N/ G' w! H) r1 E
  //* U7 Z" u* b9 S' W) u6 j* O8 n5 ^
  KeInitializeSpinLock( &DevExt->SpinLock );; |* T, ?* `  Z1 d- i& [2 J" g

: c9 G4 d$ t  S: T% ]3 X7 ?# n# a  //
- F  i" X6 W( J! U# {% `  // 初始化 IRP 计数器( m) |# c5 k$ A2 [
  //: Q+ D8 G; ?3 m* O( F& ?
  DevExt->IrpsInProgress = 0;! s" ?5 O  {/ M
' A, A9 E0 A5 A
  //
5 {0 m* o4 d* \1 o  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象, Q4 z3 y+ i1 G3 c  {) r% k  g
  //4 W9 V$ i* D( r8 w
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
% O; Q" Z( A$ l2 g7 ?4 ?                                              DeviceObject ); $ }) ?7 D! d4 b( N. \
  if ( !TargetDevice )% T. O! L2 a$ t
  {! A% P( c, A$ _7 `1 P1 @& }$ q
    ObDereferenceObject( FileObject ); # H- u% K2 E# \; s
    IoDeleteDevice( FilterDeviceObject ); 1 v) k/ t) u6 t# T& G" G
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
/ h: {& }/ C% f    return STATUS_INSUFFICIENT_RESOURCES;" A4 k; T1 c8 h5 s
  } / I$ i9 Z5 s# z! C$ x

) A* a& M8 U9 t5 {5 n& a5 Z  //
4 b( |7 R4 m7 L0 X: Q  // 保存过滤设备信息/ c' ~3 @$ [/ o3 |: x: R. o2 t
  //
/ j4 k) g( g3 k  DevExt->DeviceObject = FilterDeviceObject; 1 L1 `7 c' ], C* N- ?- S  _
  DevExt->TargetDevice = TargetDevice;
; a* z' v& L- y! m( w& h. B) o  DevExt->pFilterFileObject = FileObject;
0 _& l0 U$ E  z2 |; u: ]% |4 i/ J: Y; s+ r
  /// a* H& K2 m8 l
  // 设置过滤设备相关信息与标志
% I2 \7 U7 a- v  P% T9 g$ A  //& h$ i, _" d* S0 L+ D8 D
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
' S) i' Q" {- ]4 X  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; ) M# {" ]$ s) `
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
$ \3 z1 v: h* G/ k$ T8 M  j  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
$ U0 W, e$ j. U3 n, c# n                                                         DO_BUFFERED_IO ) ); 9 G( w3 o$ c: y+ R# Z% Y& G

% v- k5 K- l2 h  i8 q0 S6 B  //9 }5 K0 T* b9 T' S9 ]  v7 {
  // 返回附加后的驱动对象
( W# U0 w7 Q  l! U* l( y4 j1 F' H: F  //$ D6 M# T3 p( E/ q
  *FilterDriverObject = TargetDevice->DriverObject;( K2 I: y7 ?3 h/ R/ X' w) U2 _

/ v# m7 x& R9 n  ObDereferenceObject( FileObject );
) S% H( o* j& H" w" Q
  W; e3 u" |* J: U4 R+ p- p# ?  return STATUS_SUCCESS;. `* w6 H3 t# w/ Y
}. U& ^2 n7 J" [8 f7 {! y3 O( t
5 N' N- @0 D% o8 `) n; x
/////////////////////////////////////////////////////////////////) r9 S+ x) h! ^) x
// 函数类型 : 自定义工具函数
, M3 C+ _/ r7 s, W// 函数模块 : 键盘过滤模块
# ^5 I/ z, F. u) H////////////////////////////////////////////////////////////////
6 _! j! L4 u4 s3 n7 J& X( C// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发/ c% N3 w9 v& S8 b5 d
//        这个 IRP 的完成
5 I) q3 y, y5 B- ?+ v3 ^// 注意 : 0 _7 c. U, W$ L, \9 t2 R+ K- z9 k
/////////////////////////////////////////////////////////////////
! _) N5 Q; Z7 }7 {9 u// 作者 : sinister4 D0 U) Y( ]8 p
// 发布版本 : 1.00.00) T: Q& |' }9 p! c. h8 M$ ?
// 发布日期 : 2007.2.150 ?2 M# g1 Y# |2 d
/////////////////////////////////////////////////////////////////  X- R( \4 ?7 u, l/ d2 L$ o
// 重   大   修   改   历   史
3 r6 d: `: m: D( H- E" n" @////////////////////////////////////////////////////////////////
7 {/ ^' P- t" ?  H3 J// 修改者 :4 q% r6 M3 o# u7 e7 ]
// 修改日期 :: j  v; w8 o) i" U$ r
// 修改内容 :
: ~( A# u- ?: w9 g8 o/////////////////////////////////////////////////////////////////* ^- n6 k# Y. t9 u  p6 k
* t7 \6 D9 m9 P
NTSTATUS1 z6 s' v0 N' L8 ?' e6 [1 [3 d
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
% h) P4 g) J4 H8 Q! h6 B) F% i{
$ v9 u: ~7 X# r  NTSTATUS status;
# Y7 q0 {: ]  Q' L& m7 K, d  KIRQL IrqLevel;  b+ m' d9 [" B4 e  N0 K
2 P) V3 P6 [8 \) @
  PDEVICE_OBJECT pDeviceObject;
- s. c6 M0 X: ?  S* o  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
( c( o) {5 h% Z7 a" E5 \                                   DeviceObject->DeviceExtension; ; o, d" G+ ?& O, a

# E1 T* \8 ]$ E* }9 C7 U4 `6 f/ U' i$ g. U
  IoCopyCurrentIrpStackLocationToNext( Irp );5 P6 Y( Y2 I/ x2 P# i$ h" C8 f* E

2 s" u3 P+ m7 z8 ]" h% W5 S  //
% K/ n) z5 G: q# x  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
( a- Y% T' ~: p0 M2 w. M  //
3 v; Q5 F' U+ q1 R  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );2 e: G( D) r7 H5 q  i: U
  InterlockedIncrement( &KeyExtension->IrpsInProgress );3 N, S. _! t6 ?) P; M( T) O/ H0 K
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );2 W- z3 P3 u! R/ i

3 |# R: u5 l4 b% {  IoSetCompletionRoutine( Irp,2 i4 `4 F/ m- Y7 v
                          KeyReadCompletion,% Z. o& ?1 r5 w# ]% C
                          DeviceObject,2 @7 J8 a, W. d/ s% H( D7 L' J0 I
                          TRUE,& T+ A. B/ V/ K5 m# r
                          TRUE,
0 v/ m2 r8 R2 W                          TRUE );
0 v1 e% e! F& K' M  R  v% S! R' ]3 z* o1 s" }6 X
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
7 U9 h( `( f% N}
1 q" m& n2 k3 e3 e2 _( n  w+ ?& `  s* {- `
/////////////////////////////////////////////////////////////////
  G* ]3 I# W* j) N// 函数类型 :系统回调函数
; ]  F4 `9 J# d: W; @$ L) O6 \// 函数模块 : 键盘过滤模块
" h  L! s* I, }7 N. `. }////////////////////////////////////////////////////////////////
. k, q1 B$ g5 D5 X// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
2 g5 G/ X5 ]# F- O7 f6 a// 注意 : 5 l( O+ x$ z+ o& z6 d2 \. [
/////////////////////////////////////////////////////////////////6 {% o% [9 l; A# i' K" O7 f
// 作者 : sinister
' p( X! A- Q4 G: U4 p  T// 发布版本 : 1.00.00
/ o$ b) `$ u( E& o# g( _0 U& h# @0 ?$ U// 发布日期 : 2007.2.127 d; m; [6 m% u4 |$ c2 U4 L
/////////////////////////////////////////////////////////////////
5 e6 N$ N5 ]  T' h3 p1 T1 G- r// 重   大   修   改   历   史& n! J1 p! h" T. X6 G
////////////////////////////////////////////////////////////////
8 u8 H0 F5 \' _// 修改者 :
6 o5 G1 o, q8 ?4 L// 修改日期 :
# t  j7 g2 s" c$ J: W2 X4 k// 修改内容 :" C& O, v) B, s* v8 v
/////////////////////////////////////////////////////////////////
- o8 X; T, A7 T
  G4 m8 y8 R5 ?- F* f6 W4 j& k& QNTSTATUS1 j% N1 \3 c$ }! M& A
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,, k. M$ o; u8 C7 [1 u9 h
                   IN PIRP Irp,
7 _5 G$ i. _) N0 B5 M4 U5 k$ }                   IN PVOID Context )
+ x( j- H- B& }8 X. ?/ R{
+ _6 _! t1 e" W$ t; m2 r  PIO_STACK_LOCATION IrpSp;
: u' P3 K( i2 p5 E  PKEYBOARD_INPUT_DATA KeyData;
7 ]1 f/ x" W$ f0 v" w  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
* s+ p! t) `6 g7 g' K: j2 {! u                                   DeviceObject->DeviceExtension;
% L7 o, |3 l- m( L; _1 e  int numKeys, i;8 j3 [+ v1 O: t1 E. N' \& G
  KIRQL IrqLevel;  M7 T/ B' g# b$ M
2 r! x: N8 t- w8 x
  IrpSp = IoGetCurrentIrpStackLocation( Irp );2 l2 f" D9 D; q; {' B
, n& I5 ~& r" w% r4 B! ^
. Z# }7 n; `! z: u
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
5 W9 p" @7 P' d  {
, T* K; S* n, W0 E) j9 h    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
6 }) b( }5 |4 c. d% `    goto __RoutineEnd;* S# ?7 e, _& W  x
  }
9 p! J" |; C+ g7 H  M# x+ v- ~' @7 W6 h. n% Z, i- M1 q  k
  //- j5 |. f# G# e5 ?1 V
  // 系统在 SystemBuffer 中保存按键信息  _& ^+ n' z8 @6 C9 q
  //
2 R  L9 D6 i$ |5 _& O  KeyData = Irp->AssociatedIrp.SystemBuffer;
2 |+ G3 w5 [# y) D5 H* \3 D- P  if ( KeyData == NULL )" S6 g+ s- E& ~) z2 N% K8 y
  {
5 ^6 t# _8 B6 j: @" }& c- f    DbgPrint( "KeyData is NULL\n" );
, i/ ?' i: F+ E- m    goto __RoutineEnd;
0 U4 p  v) E- i8 X1 V  }
! r+ F' H, u/ v. K/ s3 c1 g, w* h9 D- ~
  //
' c) E" \: ^) U9 f' O8 \- P& w  // 得到按键数
# l$ k+ b, w7 c  //7 b  R- D: x* D% {( Y7 z3 p
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );4 l5 B5 Z1 G4 e+ M5 a
  if ( numKeys < 0 )5 Y0 X6 S) U: ^" M$ k7 A* V2 @5 V
  {
; ^2 g5 w* C3 o    DbgPrint( "numKeys less zero\n" );: K4 l  T4 p; Y  S9 U
    goto __RoutineEnd;
' x2 M% C% c+ a' H* _" K  }9 M2 Q/ [! |3 ]& [4 ?

  O5 ^+ T9 R  u9 t" j( q) D& V  w. L  //# I( t; _8 e5 l- \+ o8 F
  // 使用 0 无效扫描码替换,屏蔽所有按键2 C9 M  {6 b* O' X8 a8 j! S) K! f
  //1 h( b! T; E1 A3 f5 x
  for ( i = 0; i < numKeys; i++ )
) S+ t4 A# ^% Z2 Y  {
7 O/ y8 J) `0 o3 X6 t4 P: s1 V, w    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );3 a5 Y% K" q$ m( _2 s6 N( I+ Q
    KeyData[i].MakeCode = 0x00;
. x/ G! ?, `. V& d& c! |  }
1 H) M3 j1 v/ y9 S; d
' z: O4 I# l# Z" `9 y3 \" i9 z, h! Q' F1 _  H8 e# @
  __RoutineEnd : 8 ^9 p9 r' F1 n3 B$ }

( @* n/ b6 a, M' R  if ( Irp->PendingReturned )# o: _  Q  e6 v
  {* P& Q+ e8 A% l$ W5 k  p
    IoMarkIrpPending( Irp );
+ j; l5 r0 M8 x. b  }
6 Z  Z) U; p! a/ J) A! ]1 g; r; _1 |% j7 W) o& {2 n
  //
- q- n1 f7 ^2 J- P& K$ O  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
9 ?$ a6 a  Q1 v; T4 B  q1 h2 _  //
  y: g# l0 V8 @- x0 F  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
7 P* |, `' z6 K& ?; E  C: P( D; p  InterlockedDecrement( &KeyExtension->IrpsInProgress );$ ^/ w( p  o" [% C6 z2 P
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );% y8 v( Y" l( h9 \

0 Y$ @3 F. C. k" j) B; H3 R  return Irp->IoStatus.Status ;# E0 y* o* B* V# |9 _6 |
} - |0 D' ^; Y; C0 C. G
/ f  B- s, g$ r" G
* N3 _" y3 J" ]/ O& q
/*****************************************************************
% t3 Z! Q' V, x% o) P4 t& [ 文件名        : WssLockKey.h
+ T' H* |4 n: a6 d( m6 d9 }& W 描述          : 键盘过滤驱动
2 o# J* |5 l4 `0 f' x7 B! N 作者          : sinister
+ O+ V5 g4 t, s4 [ 最后修改日期  : 2007-02-26
* l9 X0 c# {9 G*****************************************************************/% S4 h/ U" f# [6 d: o4 F( f

) r2 c* n" E# c+ W8 c& q+ I: Z#ifndef __WSS_LOCKKEY_H_
* T' L# m& l- t3 e" w9 A#define __WSS_LOCKKEY_H_
6 {5 ~4 w2 D+ m& G
5 g- E$ X, Q1 y) L3 I" P+ \#include "ntddk.h"& @: E1 R0 G) ^5 P0 y; f
#include "ntddkbd.h"7 _" [% T: N5 U$ w+ l
#include "string.h"" T; z9 |9 e  w2 n% l) H
#include
& |& F  J( e* u) Z! D
3 u+ M! e. K7 p1 A2 c#define MAXLEN 2561 i( x) B* \3 Y
$ E/ {- e1 q/ c
#define KDBDEVICENAME L"\\Driver\\kbdhid"% A& D! P2 c/ |
#define USBKEYBOARDNAME L"\\Driver\\hidusb" / }# {% i+ [8 Z" z% I
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"- [6 \5 B0 t) B3 A9 y- j4 _

8 [9 n5 L/ p2 q/ _' Ntypedef struct _OBJECT_CREATE_INFORMATION
; F; O( C( t3 m; M{; G) e. z5 J4 P+ A
    ULONG Attributes;
, V, \2 c: p4 q8 J2 m3 ^9 W! F) X    HANDLE RootDirectory;
* ?& K* `& t# M4 \    PVOID ParseContext;5 ~; b4 e: |* M
    KPROCESSOR_MODE ProbeMode;
6 E2 d* v+ ^$ I' n    ULONG PagedPoolCharge;
0 e) h& O7 T8 R6 W! Q3 y    ULONG NonPagedPoolCharge;
% H- y2 N9 V) |% R( E4 J8 q    ULONG SecurityDescriptorCharge;
% A( {, C9 u; z2 I8 ~9 y    PSECURITY_DESCRIPTOR SecurityDescriptor;: _& i- k8 _0 p! ~% g
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;" N/ ~' ?5 x2 a' r8 [7 v
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;, Z  l( e% J' I# }
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;! R. K7 x) P- y  T
+ T4 C: k) z; f1 J! R/ [
typedef struct _OBJECT_HEADER0 t! b0 `# V8 r5 k& M9 j
{
6 b! B- T4 p( }    LONG PointerCount;5 v( e: c; U! d( p
    union
: i' I* r3 C' @! K8 t( j6 o/ C- A" H' I    {
/ |& @3 L8 ]2 _; d: z, x! Q3 W. y# V        LONG HandleCount;
, ^& R" t; R4 ]8 X5 R% r1 f        PSINGLE_LIST_ENTRY SEntry;
. F( N* }: _/ r: A7 O    };" N( J; J" z7 R- ^  h% q. A- x* o4 B
    POBJECT_TYPE Type;0 O6 F9 y5 y' c& U4 _& L" i
    UCHAR NameInfoOffset;8 B0 r$ H1 @# N! s6 r4 \
    UCHAR HandleInfoOffset;% `: W# `+ _0 J" s" j% w; `9 c
    UCHAR QuotaInfoOffset;$ I* a3 e6 C# e% F
    UCHAR Flags;# x$ R3 I5 _) s+ [$ E2 Z# `7 f
    union
6 z3 C7 i' H9 a5 A8 @4 X    {
0 U: P* {+ H. G- N' ^        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
/ m; q7 q5 S9 l0 U        PVOID QuotaBlockCharged;; ~1 x: D! q% _5 U
    };8 R# V* `( u; \1 M( t" d! H, F# h

% C$ O0 W) Y1 s0 W* R    PSECURITY_DESCRIPTOR SecurityDescriptor;, ~( i9 u7 n+ B
    QUAD Body;
+ ^1 t- x- m% X2 e} OBJECT_HEADER, * POBJECT_HEADER;8 u' y9 ]4 e* I. c: n# _: m

/ \+ M2 k, Q  ]' i#define NUMBER_HASH_BUCKETS 37
) g  f5 g4 f( E( P
# ^) J: o2 E3 f0 x# e% ~typedef struct _OBJECT_DIRECTORY
5 Q% V0 Z8 Y1 c: U" _7 ]7 H1 L) Y- ]{3 @) A3 Q$ {8 ], ^1 }8 _/ j
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];: x9 |4 l7 n  j) r+ C7 t# K
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
/ v7 a; {2 [$ r- f1 n    BOOLEAN LookupFound;9 X2 @. D  k7 D0 k) a# O) M, p
    USHORT SymbolicLinkUsageCount;
! V( @1 Q2 Z( H3 [  m! L! t! M" l    struct _DEVICE_MAP* DeviceMap;
- a- g, j4 ^* ?$ }3 U} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
& G! v8 y5 T) B6 f8 M4 [: e! [
# S! U! w2 A) ytypedef struct _OBJECT_HEADER_NAME_INFO. G. V: n  P* |! C* J+ f$ c/ }! y
{
: W2 ~3 h+ Y) ?0 y& C    POBJECT_DIRECTORY Directory;5 g: H, L/ N3 h( x3 ?! ~
    UNICODE_STRING Name;# n  O* T, S# ]7 x5 w  M
    ULONG Reserved;
0 \. n9 j3 l, ?% v9 K* Q! i#if DBG
9 s/ D# w$ i8 D5 f    ULONG Reserved2 ;
- i! F6 f  I8 u' w, [% E    LONG DbgDereferenceCount ;0 h% w0 i' {7 S- j9 [
#endif
0 T! K) C: N: t& l} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;: @9 J6 S5 u: _: w. s3 ]
' \/ w: \( X4 Q7 ~: \+ \. a; T
#define OBJECT_TO_OBJECT_HEADER( o ) \9 _& r* I; T+ x# \5 i4 }
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
5 n8 X7 \8 b8 W5 O4 U
2 i$ P8 ^1 t3 c' `% ]9 l6 ]#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \5 B! Z0 A- c3 Y" i
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
# I0 [( ~3 K- U# @. f9 s+ C. Z7 @8 N) u+ u
typedef struct _DEVICE_EXTENSION! s, n" x: j1 K: m- T3 i
{
) o* `4 L( j2 k" \4 J    PDEVICE_OBJECT DeviceObject;
) u6 h1 O4 B# V' x    PDEVICE_OBJECT TargetDevice;
/ `5 W9 Y  @( {  I( q' ~    PFILE_OBJECT pFilterFileObject;
. ?& X. l( A" q+ E" U    ULONG DeviceExtensionFlags;
" ^4 A* R, g% T    LONG IrpsInProgress;+ R1 Z% X( D& j+ w/ i
    KSPIN_LOCK SpinLock;
6 `" l* H" i) w/ I) S4 p# z4 n& W9 M, Q}DEVICE_EXTENSION, * PDEVICE_EXTENSION;- {, t3 A( J3 W# K

3 b( F  ^  |6 h) Z6 f
$ \9 w" Q7 K# r/ |* o# gVOID
5 `( n9 c# N  oKeyDriverUnload( PDRIVER_OBJECT KeyDriver );$ Z9 m  {$ ~5 u, B* b1 Y0 n; b; i

# e' ]5 A( k, s* z# c6 W3 Q* J, |BOOLEAN
  v: o7 m9 s  r( vCancelKeyboardIrp( IN PIRP Irp );
% `' Y8 i, G1 P1 i8 \7 z8 S; l, e' T* P" k# `" J: [# W
extern POBJECT_TYPE* IoDriverObjectType;' E5 w3 _1 C8 G1 {1 ~- U" q. U# _

/ t' I' R2 ]# g* ~NTSYSAPI
- ^  r- f" r2 l9 S2 H( [3 Q% z/ ZNTSTATUS9 ]; v8 ~5 O4 D" T) r
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
2 Q$ C+ U0 \3 q1 r( G/ F                               IN ULONG Attributes,
6 j4 L6 X- ~5 \' s. a8 X                               IN PACCESS_STATE AccessState OPTIONAL,9 W% m" ]8 t! S' m) s
                               IN ACCESS_MASK DesiredAccess OPTIONAL,, c. o8 r0 ^5 {5 K& W' ^+ x  y5 O
                               IN POBJECT_TYPE ObjectType,
' X7 B2 S- H( F# u1 _- K* T# W% u) e                               IN KPROCESSOR_MODE AccessMode,3 S: x% h2 m& j- o3 l# B9 l: u6 q
                               IN OUT PVOID ParseContext OPTIONAL,
- H* c' ]8 l; }* f2 S( S; n                               OUT PVOID* Object );; P4 D' O% y! P, X4 ~; W7 Q

; Q; V& X1 R. w: RNTSTATUS
. s9 ~; H- n$ U( C4 ~+ CGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );; ]0 m  |( b! z) D4 j$ `" y

9 P# _8 c, [* z) j1 q. j( ?( vBOOLEAN * Y4 `0 Y+ h1 Q5 h
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
9 z0 R* V$ N* f1 ^4 h9 f. w. Z
( W0 Y% w( [% P6 V# R/ }+ D7 X1 uVOID
/ k# ^3 }- J  ^) |2 qGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
9 u; l% V& a( E( v% @) S! n0 e0 @7 v( l5 e
NTSTATUS
; {1 a) N1 |( ]AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,! B6 p: ^2 H  ^6 T$ `6 n
                                  IN PDRIVER_OBJECT  DriverObject );$ z" x' C! b) z0 `% h

+ @6 w3 g) O& i6 i6 @8 w( f- SNTSTATUS / E" B, b% a" t; s
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
" E( j9 S% b& S% l' \9 V                                  IN PDRIVER_OBJECT  DriverObject,
) L0 g: L  ]! Y. B+ ?1 s2 w                                  OUT PDRIVER_OBJECT* FilterDriverObject );) K5 U% g" Z4 q. o7 m7 M/ Q
, I+ b. k% x% e8 X8 M/ z% M
NTSTATUS 1 a, L: `  B9 f- Q
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,  \9 }. v& C2 @
                            IN PIRP Irp,
/ ~; h7 w1 q2 Z                            IN PVOID Context );/ v8 k7 J/ b; D5 J7 j" l  U
NTSTATUS + X, R. i9 U' L
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
" i; k9 V, _. N
+ E8 J! [- c* y, h  x# LWCHAR szUsbDeviceName[MAXLEN];
- E& v; b9 ^# @# A: G9 R6 h% z4 ^7 t
, J( _; s9 K8 v9 z9 W, O0 i#endif
. h# f9 z. p* M- p5 y; Q7 \
! w8 M# `  Z/ B: I2 d6 r! H  y& h% y6 q; J+ G; z( }" r+ X9 v
5 [7 c  a4 p/ N( W+ q
# _$ l/ }! J9 l: P; |! k2 Z$ _' ^% `
# i) m1 _# e; h. m( v  n
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
. t, D, w6 ^0 o' ^8 W- \$ t* u) uWSS 主页:[url]http://www.whitecell.org/[/url] ; }$ x7 |7 X  d$ c' L  ?+ k
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-6-13 06:35 , Processed in 0.047668 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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