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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
* f3 F( V' r7 u7 G; ^' [. NEmail:   [email]sinister@whitecell.org[/email]2 u' I5 X( f1 M$ J. Y
Homepage:[url]http://www.whitecell.org[/url]
4 {0 Q3 S. E, Y+ X  i5 O& dDate:    2007-02-26; e) o% X% L# E7 O6 I. O( W

% g$ U. y' j- y' b* W' E& h- w- F' v( I& ^. j7 Z
/*******************************************************************
) u/ R  C( V* l
8 k( m8 v& \% N: l, s# u+ y# @这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
2 T9 g% \/ N/ |7 P2 V写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
7 l0 P( {) v* Y: x* f$ E$ b功能要求如下:
" R  y& X( z/ j) z+ B; v: L8 R& U0 L
1、强制锁定键盘/鼠标。& I. \) e* Q8 r6 `# N
2、可动态加/解锁. E$ }$ u2 l% ~+ M- }  H
3、兼容所有 NT 系列的操作系统。9 F8 _  j- V8 G1 j# C& g

& w3 J4 q$ o& Y0 O就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
/ K- g6 v) A' v4 t现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
! P) X/ H* i1 z  ~1 ]! p何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在0 ~+ s* z; |0 r7 Y/ [- P% A  w: ~
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是  e- k8 ]9 T9 ]4 u% {
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面6 l6 _( D# x) T
就来看一下我想到的几种实现方法:
& s7 T7 g+ s3 d8 q, V0 s6 s5 T8 B+ c) i0 W$ F
1、全局键盘/鼠标钩子1 z; @3 j5 g% u
2、BlockInput() API
  ?7 M$ W5 t; F' D/ V! i( j* G3、使用 setupapi 进行控制
% V+ W$ }! j9 _. [4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
8 G& j( p5 d+ _3 L8 ^/ F5、拦截 win23k!RawInputThread() 函数
: _0 N: a- R0 m" W- q( a6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
7 S) Q. n- Z6 a; X- E& G- @1 n7、拦截 kdbclass 驱动的 driver dispatch routine
, q6 V! g% j, t+ Y8、实现一个 PS/2 与 USB 键盘过滤驱动
% J+ w* C8 x9 M& u
$ @* \9 _, I0 C8 n3 k+ e) D) l: }
% D$ v' L3 I2 z- `9 l我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑# p, {) @( K4 X1 d
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( Z6 i/ M! H( q6 e: i
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
% |# l& c: H4 T9 S5 S" g兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
2 n9 I* g) C( E2 d素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性" h4 `4 D$ }& S+ T5 v3 I
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
# W( O: ~& R1 g2 x9 p) c载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我7 a, V( G7 }2 {* J5 u
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来  j0 [% D; I' O8 Q0 ?4 I$ X
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
4 X+ \9 x' o$ Q% f. ]果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有& W% E) q( Z# F. o
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
# R& M2 S$ A" Q" m/ ]IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
" w& y" ]8 I" p: z0 q1 i2 U8 {$ R; AUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
. h# a1 X  e) f. P盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方% O+ h4 p# [4 H6 y
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。+ ^: F- e+ i0 R, C4 P

2 _, R$ Q1 R3 w
8 e  F% C! d0 r2 F/ x$ y我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
( |" x7 H1 o+ F3 B+ ^7 p滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
6 x- H6 B: q5 c/ L行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
; m. L1 O3 K8 A& L' ~& Y8 Y( H5 M只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
/ u! e+ T7 @( n2 ~& E来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
( e& z0 j  o  J4 dKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
! a5 s' }' R- i& t8 P* m. s键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用; U7 f- }" o5 t- j9 O& E; K
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,' y% G3 n( x% a( I- A! J  v
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
1 u7 M, F" F6 L  s4 K$ w就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
! P; D3 ^9 M! t- @6 R  _而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使7 u3 s6 C4 G* F5 S, W, q, u
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通" W! b, w7 _; t- t$ o
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
" Y+ _8 v  g- j, G% @屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
' m' H3 `  s7 J2 Z" l9 X6 x- x过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb! q' x' W: w8 r+ }* `% ~
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
1 K2 T: @/ Z# O: P- O- C) p的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
" f# V$ r4 F; t; x+ t味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。- z; _8 B( b' N( W  Y
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们, L% i" O  i* B0 f$ _2 L
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
0 U1 K3 q1 G' y- `, e' k的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
5 s7 o; n( H6 T9 U$ v的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
# K- ~% E' l& i( a敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
) H: n& T8 d8 L/ K' G5 R根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程7 f2 O6 W& V' d) e
见下面代码。5 P  q, u  ~% G7 D) y

: o$ n3 o" ~8 g( [" B+ u这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
# D6 I6 X0 l7 o里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
; p: E/ n7 A. D3 F5 @盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20033 f2 v. R% h+ S0 k- y2 q2 j  \
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有% }/ B. Q4 A6 v( G1 V& V% t
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可" G4 P* L9 o! d2 h
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个' b. j# O* e) S3 {0 r0 p
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按! X4 N' O! e, k7 ^  C5 s+ T
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。' G% o( P- \6 ^8 j2 c$ o: C
9 s6 l0 E+ u+ |
7 A" @" G& S  H/ _- `$ o. S! R3 [8 `7 k
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
  U5 m- L8 h; J* j+ J* E# G0 }$ {' C的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是7 b5 V0 U9 C: Q$ W, c( I# b
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣  C3 D8 [- ~; X+ i
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我( }; ~+ z: z- ^. u0 R" x
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
* f% e: ?( L" \2 q7 m  H2 M4 @5 b们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
# v" O4 I" z. @$ M. F8 U) {3 R->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
4 ^8 a* Q* p# \8 K, M  J如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager+ n' X4 A4 q! ?
进行操作了。这个问题有待大家来完善了。! e/ {# \) @/ a- p6 U3 |

' Q! r1 L" u; I" ?
/ q5 e$ j, X3 O* I0 ~: d; p5 M要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出3 \% k6 `. x8 q$ k. ?7 u; a
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的* e- ?7 f5 x( s* U' _% O6 P
分析做个记录而已。我更愿意把它看做是一段注释。
5 o3 e  R4 j8 V! r  m' x; [% x% x% A" Q% \' {+ R$ [9 ?
最后在此代码中要5 d; Q& g. Z. L( Q& l1 S( C

0 R, j, c6 b! p- |感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
. `8 \0 I: {6 C, k
' B* {* B. e6 c# c" H感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
' c8 K, g8 N5 {& z0 F$ }- ^: M, _  A3 h; F
感谢:齐佳佳,过节请我吃好吃的。
! R9 L/ [6 ], }% M8 g8 }9 w7 W8 v
$ A$ w* l5 H5 l. T& F0 `
******************************************************************/9 @3 I" v2 ]0 A  g+ `# M

7 E: U0 F4 m3 f3 T+ ]$ N/ g' |* c6 L2 i5 F3 g$ Z; I7 Z% G  O& S9 U
/*****************************************************************
4 s. k6 |8 M0 h4 @9 C+ | 文件名        : WssLockKey.c
5 Z! W/ F) Z1 F0 w. i9 m3 A 描述          : 键盘过滤驱动! V, W& I2 a/ J1 s; O5 b, f1 m. r
作者          : sinister
* d: H8 \- ^3 H: E 最后修改日期  : 2007-02-26
: @! e3 Y; K2 l*****************************************************************/
- ?* ]. V2 o" `( Z1 f' j. y. w' Q/ I' |
  `/ B6 e- `! [% Y, Y* F
#include "WssLockKey.h"
. }' l, {/ P3 y! h. H: I! O/ |( i9 L8 F, }
NTSTATUS
( }7 M/ g' ]4 L, ^5 sDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
% P5 S  `1 R- V& Q+ L             IN PUNICODE_STRING RegistryPath )
1 |% Z) \# X: y' c" T3 j% w* w" h" y3 a{; |5 x7 v3 j/ w5 ]5 k
  UNICODE_STRING KeyDeviceName; ! P& H4 P; V) u! ?- W* G
  PDRIVER_OBJECT KeyDriver;
! |+ H8 k$ F  j% V0 t* @1 ^8 J4 u  PDEVICE_OBJECT UsbDeviceObject;
: B$ D; V" c5 c& m4 T* u$ b* B( S% q  NTSTATUS ntStatus;
6 Y. Y3 r3 q3 H) G/ i  ULONG i; 9 b- I# k6 z$ [6 [) D* m/ g) I  y$ Z
! |( g. [! N8 J+ Y4 n
  //
1 P/ O" U. w, [2 J3 d( o- M% {* D  // 保存设备名,调试使用
- e* ^3 a, k1 v5 e" f$ |  //& [# {+ D1 Q1 {
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
' |! u6 [+ W) p5 x6 C/ |% ]4 W  {6 M% q7 q/ `! e0 Y2 i6 d
    0
- r$ m, z4 G# T+ x  };
( H6 \; C& \( h2 z3 L9 t
5 U4 b4 I) l6 v+ n1 a8 d# K# K) A. z  KeyDriverObject->DriverUnload = KeyDriverUnload; 6 D* s( ^- M8 a! V* v* }
7 k0 ]$ F# i/ g5 {
  //9 Z; Z% |; L+ w1 g0 l4 x6 ~# F
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
$ t6 ?, }, i3 q* l5 m# E# L' x8 d  //! Z, r/ O5 ~# z- e4 R& P
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
( ~3 t5 z7 S$ T  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其# X: r; c; R' V" G4 o6 }: E
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到. s) B/ ]+ {5 P9 N+ p
  // USB 键盘设备来进行挂接
* H& N" l9 n* W( o6 s  //
( o2 N3 X" U$ V  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
4 _3 t, L: F8 M7 S. T7 p) o, [  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )7 K, a& e( U. j* B' W# `  n( I8 }- O
  {
3 t, J/ a- l7 U0 q, r    //' N8 W) h& }/ W& ?$ P& Z
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
5 _3 P8 |" s$ E# N    // 所以这里打印为空& _9 H5 G+ o  m" r0 ^
    //1 @- T8 I# i- f: U0 K& W
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
+ u; ?- o! A- X    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );9 ?1 f& r- I9 S  R0 t+ L3 ^; `
1 S6 O' ^0 @0 G' j" r4 b3 Z
    //0 ~( O& c+ ]7 x! t& N  O* ]
    // 挂接 USB 键盘设备8 V1 _$ k" h# O8 Y8 ^
    //  ~: {: d" `) X
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
/ c( X! y! b& g* L/ Q5 d& j% B2 Y    if ( !NT_SUCCESS( ntStatus ) )
& Y# a3 n6 g7 ~' F4 r. n    {
" m$ e" C  y, @/ Y, D, i      DbgPrint( "Attach USB Keyboard Device to failed!\n" );! o/ ]) f8 o# t7 n
      return STATUS_INSUFFICIENT_RESOURCES;
6 b, U4 q5 e- P* W# ]/ w    }* D, K8 s9 w5 |; w2 E
  }
9 `, W( t9 s5 e9 w# x  else4 ^, ]& ^  _+ _) V* Q4 R
  {
$ i% i# S7 g5 L/ B    //
* T1 t) l' C; {    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
, Q7 b( \- k) e8 y    //
4 n# T; U, p6 B: o; @/ _  h    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 6 ^6 \6 m. }! _: [% J6 _% [: i2 d

  o# W+ s2 R) [" p0 v/ k6 Z! [2 w    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
( I/ |% u1 N9 f- t/ n7 ^# R6 \. Q                                        KeyDriverObject,2 k: N) k. U9 a& M0 q- ~, E1 j
                                        &KeyDriver );9 G) ~; G: |+ K! p  C/ t7 T
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )1 N. y1 n; j. {( E! P6 e" c- j
    {& o1 u7 U1 d1 Q9 s3 M
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
# F" e! W+ {; Y) ?8 t      return STATUS_INSUFFICIENT_RESOURCES;' ]3 x1 R- D  b, |3 k
    }
- Z0 N; O/ M+ H: p# J; Z/ z; s  }- D& A5 g/ }: T* N  k
. ?# Z+ F( X1 o" ]5 H& Z, P
  //
( j+ T, F  z" S( O3 Y  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
# a3 J, Y! A1 e$ i* x  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
- Z" r( s3 ?5 t% M% T  //
! d! J. [3 @, G6 c% h  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; - r, }! x& J" G& B- [' T

9 r5 g; P" l8 o7 B  return STATUS_SUCCESS;
9 _, Z9 v& i7 E$ T# T} / F- t7 y; K" B9 t

9 X) j9 J6 {; V& f/////////////////////////////////////////////////////////////////' p  K! [& L7 X6 k- L
// 函数类型 : 系统函数
4 |+ o& f( f/ x5 B8 J0 \7 Q// 函数模块 : 键盘过滤模块4 W; e$ y: C! I  _0 p
////////////////////////////////////////////////////////////////+ p( N: }' d) q. t; }
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,2 X( D; [8 j, ]: t9 t
//        卸载键盘过滤驱动
  j% f/ V7 V$ R& o. K! R4 g// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
" `/ l2 n$ K7 h//        则需要等待用户按键,以后有待完善
  V. X+ \6 H$ Y1 B: K! N/////////////////////////////////////////////////////////////////
' Z$ R2 s- I' X7 F( O- u5 s// 作者 : sinister
( b+ v4 P. W# O7 O0 G// 发布版本 : 1.00.001 ?+ l7 w! s+ V, ~1 P
// 发布日期 : 2005.12.274 l( J* W' ~, x
/////////////////////////////////////////////////////////////////$ \/ ]4 o' V* G7 I
// 重   大   修   改   历   史1 o7 K4 K- U6 F
////////////////////////////////////////////////////////////////' j, ~% a7 ?6 v. V; l
// 修改者 :
; x& n- \2 i& r6 t; {6 l- `// 修改日期 :% D& G  N# z! O( b% Q# z
// 修改内容 :2 Q; H. H$ C# c9 @" t' ?1 \& a/ O
/////////////////////////////////////////////////////////////////. ?" ^$ `6 ~' g4 Q# h7 k; O& N6 `+ [& L

$ a! O3 z  s$ T' @' ?, rVOID
7 b- {; a( H6 n9 H  s7 g6 zKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
& m+ V2 Y5 ]! p$ m: T{
: z. s. {" T. g8 q) b  PDEVICE_OBJECT KeyFilterDevice ;      
4 t  P& f8 k+ f) u# j4 o2 T  PDEVICE_OBJECT KeyDevice ;: B; P" f  I, C0 P' b' E& y+ U
  PDEVICE_EXTENSION KeyExtension; 6 G3 ^3 W& W( f
  PIRP Irp;
1 [/ }$ z+ J- `( p( j) |! C0 ^  NTSTATUS ntStatus;; ?9 F$ |2 `/ O! C7 {. Y$ d

0 _6 u+ Q  T" h+ [, M4 C  KeyFilterDevice = KeyDriver->DeviceObject;
* n  u! V( R+ v5 d# J" g  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
; x! M- m0 c6 w6 o$ `6 @3 y  KeyDevice = KeyExtension->TargetDevice;
" p1 F! }- f& u! W7 W
! I; `  ?. V. C9 y1 V8 U  IoDetachDevice( KeyDevice );
7 E5 ^8 w4 }( b8 k: b; i6 Y, q' p, ?% m# ?& {: O1 {& s
  //
( f% y" k! V0 ]; `& D8 `% O; h6 H) B. v  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP& s2 n* g: s& F0 B
  //
, J% y9 \9 L  B  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )# a) \4 z, P/ t( i
  {
/ }! g* L/ J0 L# q/ G9 j$ y    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )7 L1 ~9 ?9 q$ x# L, z, ^/ B: K
    {
  C4 A6 u4 V1 q# ~/ a! D+ a      //
* ?! Q* X8 u/ D/ D3 I; ^      // 成功则直接退出删除键盘过滤设备
2 A( P! Q4 N* V- H- m1 m      //
, ~2 T; o1 t! X1 N* [; \' a8 n+ [      DbgPrint( "CancelKeyboardIrp() is ok\n" );
$ m$ E- [: Q8 z0 B$ n: V% i: z      goto __End;
) P8 q8 b& |2 V. ^% G    }
$ ?' P9 d6 U7 ]2 g  }
& z' s% S# g) n/ c- K2 V& Q8 q! g7 c  W
  //
; z) D$ W/ T6 P( \+ a! |  // 如果取消失败,则一直等待按键
8 O* v6 C% j7 E6 G  u: q  //& I; `3 U& [/ O/ {6 O
  while ( KeyExtension->IrpsInProgress > 0 )" W1 P# a: U& K5 O$ e4 {% T
  {" }7 I  l8 l+ M* b  \
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
" G% g0 U: z, M7 [  }0 t0 d9 V/ u8 G5 Y3 P

1 O; r) w' |1 T$ @0 ?" k! \  __End:' v1 a, L% u, }# ?8 Q+ d
  IoDeleteDevice( KeyFilterDevice );
2 Y" @  Z& x) o" I' a* C- Z$ L% Y" D: N( {
  return ;
& \' j1 }  m, g" h}
2 l! L; C. G5 E4 S8 R' A9 P
. y' Z% f( a6 y, a/////////////////////////////////////////////////////////////////0 O6 P, i+ N4 ]" N+ i5 y
// 函数类型 : 自定义工具函数
, w) D# \3 u4 ~+ A4 A3 l" C// 函数模块 : 键盘过滤模块! i2 U2 f: V2 O5 g- d2 s
////////////////////////////////////////////////////////////////// V' @! r4 {8 e$ j, x7 I( f9 f1 L
// 功能 : 取消 IRP 操作/ \& h$ l" ?$ `; ?. @' C+ o+ T" F
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能/ \0 j8 z0 s, F2 H; F
//        使用此方法来取消 IRP7 L# V0 o7 `# P) E
/////////////////////////////////////////////////////////////////
) G# w1 V) [. {// 作者 : sinister
/ z1 s/ R- u! W" |// 发布版本 : 1.00.00! ?3 [% |) G  T5 J
// 发布日期 : 2007.02.20
; i% n  P7 ^' w  S  v, h/////////////////////////////////////////////////////////////////
( a# I3 d( ^# {3 a/ F// 重   大   修   改   历   史3 k5 I) s1 X/ u  j' z$ n
/////////////////////////////////////////////////////////////////
! P) v: [$ Y: F+ b& k// 修改者 : 4 L4 t9 c" r7 f* |$ @- B( }
// 修改日期 :
' d. ~: Y3 J' G9 @// 修改内容 : $ A2 A$ X- ^- O
/////////////////////////////////////////////////////////////////
/ O5 {! i: w5 a7 }9 f0 j9 T7 ]  n) p1 O/ O+ {( i
BOOLEAN# A$ I& B2 G; ~9 M, Y% ]( S
CancelKeyboardIrp( IN PIRP Irp )
8 F" k* d' \4 P) j{0 i& _4 z/ f) a
  if ( Irp == NULL )
& c! @5 ]0 b& U; a  {
6 D4 m1 W' h) ^! _. X5 u    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
7 b% c* M4 _) u7 Z0 b    return FALSE;. d2 R) o. S( y, z7 @5 d9 h# E' `
  }0 [% u: T, Y& R( _- `. V  x

$ U8 n' N( A9 R+ h) w6 X4 ?; N6 k2 d9 A2 V( ]( h
  //( ]- V: ?$ D: @& S! R
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,% X6 C+ m7 J3 {+ m( j
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
  L3 C& O" ~3 J7 k( ]4 _  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占3 ]9 ]6 Q; f  L: O( G% ~$ h8 Q4 T+ G
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD. S% |% ?. g, `! l8 {" E3 m
  //6 s. c/ I3 I3 p5 |& O* ~% l
  l9 D; }( |8 Q$ A& F8 p2 o; b
  //5 m! L8 @& F- o8 M8 D7 t0 D
  // 如果正在取消或没有取消例程则直接返回 FALSE6 Q- u; P) o) C4 l
  //. z* r- V. n7 D; a4 M! F: q
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
1 B, Y' H0 k" `% m* M$ `  {
/ K* r; C+ ~. a" o6 x  t; J# |3 H    DbgPrint( "Can't Cancel the irp\n" );
+ e/ K  M$ p  G9 O* H; A, {    return FALSE;: n3 z' `! D0 B* Z4 h, m) c
  }
$ y4 x% Z0 M, b( k* s% D  Z: t/ C7 O, X0 W( ~+ M' j4 _( B
  if ( FALSE == IoCancelIrp( Irp ) )
0 o) q3 ^* ~. g/ H  |6 E" c2 B8 ^  {" O, }/ R+ o7 Y0 X$ U& s2 }& w
    DbgPrint( "IoCancelIrp() to failed\n" );
8 F. N, G$ E# z* S% I1 R$ z    return FALSE;
/ w/ }3 o3 k& j9 `' ~% N1 Q  }
4 W0 J4 }% z( T6 }! v. p$ a
# Y  T$ ?7 Y$ @* C* T2 K  //
5 t7 p% ]; Q  f9 W4 d  // 取消后重设此例程为空
8 M0 W% k' R6 ?5 Y  //& _7 V% [; q8 ]5 d- o
  IoSetCancelRoutine( Irp, NULL );: P- x  R' ]/ P1 f: |8 B5 q

( F' I( {/ h+ i5 u4 ^  {  return TRUE;
' b8 _- M# v9 g}  B2 s; z7 l: _" H0 B
% _% L4 Y. J. n
/////////////////////////////////////////////////////////////////
# G: a* B+ {8 F9 X// 函数类型 : 自定义工具函数
  R( C- X) s  z( `& U; v// 函数模块 : 设备栈信息模块
! m* y! ^6 q% i! v7 z/////////////////////////////////////////////////////////////////
' c0 W0 W2 y$ v// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
! R7 g# H6 P2 ]8 M, b//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)# g- H- N% M7 @* O( {8 U* t
// 注意 : + V$ h" s) }. D) D2 j! x% g
/////////////////////////////////////////////////////////////////
; e9 f9 e  b  d2 b; i// 作者 : sinister
4 o3 s/ r# k2 ?" a5 m// 发布版本 : 1.00.00" F1 M7 d" J4 X
// 发布日期 : 2005.06.023 ^) h5 s6 p5 ?: k" q
/////////////////////////////////////////////////////////////////
1 {! ]4 y" @8 O// 重   大   修   改   历   史- p) X4 }. M9 n0 U9 y, t
/////////////////////////////////////////////////////////////////* U6 p$ h! h1 Z, d% e1 P
// 修改者 : sinister
! U1 r& D4 F! N/ M) a! T// 修改日期 : 2007.2.12# p" P  Y# m3 o& }. B& D  V0 j
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改) b" H: b- w) L: m
/////////////////////////////////////////////////////////////////
* \1 L- G  t' m. v4 f
4 O% l9 }2 d) z! q) k, F& Q- i6 sBOOLEAN
- D, W+ r/ ~9 G6 p" fGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )7 T& G$ j4 K/ ^) C0 u, h" L7 N/ f( [
{2 Z& O+ a2 E2 n0 O) p/ x' D
  PDEVICE_OBJECT DeviceObject;2 |+ Z- R4 W2 w* d" E0 k0 t
  BOOLEAN bFound = FALSE;8 s  T) E8 E, c& t2 b9 |0 G

3 K) w# ^0 k# ]& \) Z  if ( DevObj == NULL )
3 E' H1 U$ Q. t" Y  {
$ E* G/ V: t- H9 H% W    DbgPrint( "DevObj is NULL!\n" );/ S- A  S/ l) n4 k" ^* A9 h- Z& c, u! X
    return FALSE;6 u; N' b# d5 E# Z; D* q' O6 }5 x, y
  }
; ]; j7 E9 O& T) ^$ y# q: G1 g; V1 I( n0 a& D) a% s8 [. j
  DeviceObject = DevObj->AttachedDevice;
0 d- d; Z% e: |* D
2 X+ `! M9 h* X( e% ~  while ( DeviceObject )
0 v% L( X( Q3 q- _" l  {" Z+ |1 C3 P2 ~7 k8 q4 V
    //
4 z% ]6 c7 A2 W    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
) T6 f5 a  O9 E    // 有一次足够了。这算是经验之谈
, d* D1 U7 l% L" h  J& E    //* H! Z/ k" V3 l* O
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
, M% I- V5 `. g  R- a    {
8 U1 [1 q; z8 {% l- P9 K      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",  s/ ?$ o9 L- L0 D5 G5 z! O
                DeviceObject->DriverObject->DriverName.Buffer,
( S) e3 J6 e- T/ [% X                DeviceObject->DriverObject,! o$ g! i+ G$ o% g, |
                DeviceObject );
6 A' r2 X2 `: F' g7 w( t1 l' w, j$ t
      //" n8 l0 b6 ^  T& C# _5 v  I
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
5 U! `+ m" _/ W  q4 {, t      //  e( `9 d' ~( r9 S
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,, A' m) K; n2 f8 X
                      KDBDEVICENAME,- A+ h- X* t# B$ z6 H: P! f
                      wcslen( KDBDEVICENAME ) ) == 0 )
/ l2 K& I9 b' g  i6 ?      {, j% g% y$ G1 b2 `+ D/ s. A
        DbgPrint( "Found kbdhid Device\n" );
- P+ S5 V0 F  q& [        bFound = TRUE;
$ _' q( @3 ]. e* ^        break;! ~  U3 k, U! b2 U5 k
      }8 x6 b6 a5 E) Z* V
    }
7 F1 ~% E: t' {$ a0 ~
$ ~3 H- b: o# \! ]. E% `3 |$ B    DeviceObject = DeviceObject->AttachedDevice;' P: ?3 C; d1 d3 `
  }
/ ?- _  `" S5 I! a  D4 s  {! ?9 p6 e% L9 |1 T0 T
  return bFound;
8 s7 {4 i$ B& d8 a; g5 @& D}) [* ?( n' I: K9 E" i; W
4 t( q. Z4 d% N5 a8 I; P
/////////////////////////////////////////////////////////////////7 X% K: C. v- M9 E& X) j
// 函数类型 : 自定义工具函数" X- `" d4 G0 S! Q* f: t0 q
// 函数模块 : 设备栈信息模块) S$ U9 \" _) Q$ f
/////////////////////////////////////////////////////////////////' r: H8 h. F8 `7 `1 a
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址+ d2 E, E6 Y/ t/ u) \
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
! t( r9 `( F) `0 |: U. B+ Q) |/////////////////////////////////////////////////////////////////
! s4 X( x2 @4 ~5 ?2 A* }% C" s// 作者 : sinister
& p! U8 m7 C% w5 \* W// 发布版本 : 1.00.00
" ?& a. c8 l5 U* M// 发布日期 : 2006.05.02  n) i: S! ?) B$ Y4 H( a- f
/////////////////////////////////////////////////////////////////
4 E$ S1 a/ Q; o, ~% s// 重   大   修   改   历   史
- h+ U  L7 w; N  ]2 L////////////////////////////////////////////////////////////////// P' ]/ D) p! p
// 修改者 : sinister
$ S, W1 v4 P6 R( U// 修改日期 : 2007.2.12* ~3 ~' ?  y0 O; i6 |1 v
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
# [7 r' s) w: }* e0 p2 \; x+ y/////////////////////////////////////////////////////////////////; c1 v( G5 Y4 W. X4 z, n

# @9 {& @! }" t8 g( Q# dVOID( }+ p+ ~, {$ M/ [% k8 \0 @
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
  N- q2 a* r6 N/ V9 N2 `  y& h2 g{/ r; n/ k1 b/ P
  POBJECT_HEADER ObjectHeader;
- ^1 I7 n; G$ x( m5 M" t  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
8 }6 ?9 k) b$ ]7 J, ]+ ~+ ?7 K3 F# Z, I; Q& N% B1 _
  if ( DevObj == NULL )" q0 ]' U7 c* K
  {9 w1 ^( Y2 ]+ A/ |/ a
    DbgPrint( "DevObj is NULL!\n" );, I$ s# `) F& Z& D) ?( N
    return;
- ~5 [. l8 o$ U8 ^( r4 I$ d& w% y/ ^  }
# Y5 Y! U6 Y; K  b0 o2 J7 J1 `; V. m9 d6 F9 t  @
  //$ h- B) S8 G1 e
  // 得到对象头6 F5 e( y2 w+ x% L/ U
  //
' _( ?0 _9 [7 {4 X  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
' R) X7 h* T1 V" R; z3 s+ m3 S9 q
1 k; I" B) p; q$ L  if ( ObjectHeader )
1 r2 p5 u0 f0 o! \  {0 V# P2 }/ v2 O3 D" J0 r
    //2 d. e. ^$ W4 i4 ?( H( P  ?7 C% h
    // 查询设备名称并打印
4 k& R. d- Y5 H9 U# W- X$ E    //
4 d' F4 F0 e4 P! i7 W6 L/ J    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );; r6 p8 y# [3 d) x; e" A# j, }4 x
# H$ h4 I& F( z! X" ?+ y
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
/ L0 p7 v+ [3 e9 I3 d    {
9 I9 \9 S, h, i% w* L& |( J      DbgPrint( "Device Name:%S - Device Address:0x%x\n",# H. ^4 x; ?8 H' B7 R$ ~
                ObjectNameInfo->Name.Buffer,/ |2 T0 i  W7 |6 U$ |' x" C( a
                DevObj );/ l  ?9 i3 T$ m! W$ J7 B0 g

7 H* p' F9 B* e# M8 t1 t5 G& n2 Y      //
) j8 K1 L# I7 k  G* M. H      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
6 A* e& _% ?2 K1 y; H" M* H      // 用,没有实际的功能用途& G1 m8 w% i9 F- B/ K; _
      //4 Z% V& Z: m3 ^  U3 M, H% {# B! R
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
) c& m% E. p) \4 H5 I9 J3 l# R* g; S4 T% }! a
      wcsncpy( szUsbDeviceName,+ v. M# d" Y% A' r2 n
               ObjectNameInfo->Name.Buffer,
& ~9 W2 `% H3 H& i7 t+ F/ Q3 n* }               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
7 Y% w  k6 m4 v4 [- u" A; K    }
$ r8 J0 `3 k! o6 I8 y. ~% g: t; Q; P! S5 d0 ?& X$ B
    //; j8 r. _1 K( W8 L' w
    // 对于没有名称的设备,则打印 NULL
5 d6 e. `! @  y    //
0 F; r& W- z3 d2 o) T    else if ( DevObj->DriverObject )  |! Y: R% ^5 J- v1 f4 Z% P5 X$ E
    {. t4 t+ b0 k! V
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
) @5 W- s. x( ~/ g( z: k. K                DevObj->DriverObject->DriverName.Buffer,- O+ l- B$ {' ~7 x" o! D/ V
                L"NULL",* ?! `  {$ ?! i
                DevObj->DriverObject,
2 C9 }4 ?. G( k3 P/ q                DevObj );
4 `9 p' l( [9 c+ Z2 ^0 ^    }
& V( x3 `; t% ]" \, T! ^" X# U  }
" i# F' k0 `0 E& c}  r* m5 A9 X8 s, S1 J
( J2 r" |9 |' G# _
/////////////////////////////////////////////////////////////////& n1 n2 o0 {& n# X5 x; f
// 函数类型 : 自定义工具函数, N/ P( g. r% ?
// 函数模块 : 键盘过滤模块5 d8 ~: R1 F) |! i- I
/////////////////////////////////////////////////////////////////
6 v! v1 Z$ F$ r9 I// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
. J" T! [( U# W! J0 `4 [//        对象,过滤出 USB 键盘设备,将其设备对象返回) ]* P& r* T* _6 J1 P+ g6 _
// 注意 :
* U$ w/ C/ C: f/////////////////////////////////////////////////////////////////$ v7 @+ n3 `6 ~9 Z# N# |: q
// 作者 : sinister3 N) }6 N4 k& W
// 发布版本 : 1.00.00- D9 W7 L, B' {7 j0 ^* [3 Z& a
// 发布日期 : 2007.02.13" }( ^- G* c2 _- ^: [
/////////////////////////////////////////////////////////////////
' j8 B$ }* G8 J% m% \// 重   大   修   改   历   史
: {* X* S  j% E- }5 n/////////////////////////////////////////////////////////////////3 Y5 Y* p' f2 v9 Y' F, Y% L
// 修改者 :
( y. R0 v+ w/ q# g) C// 修改日期 : 9 X0 t* n, X8 d! h- [! U
// 修改内容 :
; q' d; I* h3 q! s' l: ]  p/////////////////////////////////////////////////////////////////
& N# @8 a% t9 I4 m6 f) A+ W* a/ i3 g% e
NTSTATUS
  A9 E7 r5 m8 H& VGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
( P3 p5 _& ?9 Z$ L/ h! p{' Q2 ^$ E! E3 }% L8 o
  UNICODE_STRING DriverName;
% U! H( y$ l. l$ T3 O. n) {6 }  PDRIVER_OBJECT DriverObject = NULL;; s: \6 s7 ?& e' c; w
  PDEVICE_OBJECT DeviceObject = NULL;# e9 Y) Z1 B& q4 N( E( K
  BOOLEAN bFound = FALSE;
& c. C' w1 l1 y. B( t/ Q) A: A3 [) F2 Y/ ?
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
/ [- m, ^8 _+ K! B" X! g/ p0 t8 w+ S# [4 c
  ObReferenceObjectByName( &DriverName,+ A( @! |: E' Q6 @5 q; [
                           OBJ_CASE_INSENSITIVE,
& M# {+ K6 d: O! d                           NULL,' \: B5 g3 l6 L6 M) u8 K
                           0,
! i) w  G4 y6 S. d0 M                           ( POBJECT_TYPE ) IoDriverObjectType,
- @) N9 o( M9 j$ I9 o* n8 J                           KernelMode,
. G2 o& c  J7 e0 k8 L                           NULL,  ?8 x: k$ _; S" c, i; A9 x3 k
                           &DriverObject );5 B% b( E4 }3 N+ W
- y9 p  y$ c$ o9 k
  if ( DriverObject == NULL )
# y& n. J* X- l7 p9 [3 @, Z  {! s# O: N  @; q2 x+ j9 ~2 _
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
0 M7 n, h% _+ ~    return STATUS_UNSUCCESSFUL;
, R: [2 Y6 U8 |0 ]9 x$ X; P  }
( \: H/ D$ F7 m, w, A8 f/ l2 P0 ~7 ]  t: P$ M; b! N4 S
  DeviceObject = DriverObject->DeviceObject;
% q! f2 Q/ f0 g" }( u* J; M: ~1 V! A* G2 T/ h, j
  while ( DeviceObject )& H1 \$ ]8 U. Q+ i
  {" S) w/ B+ f: T6 T
    GetDeviceObjectInfo( DeviceObject );
. c. @, b) Q+ S+ y- m! [  B$ R6 ~' t9 u' K2 ]* j8 j: m
    if ( DeviceObject->AttachedDevice )
& M. ?1 M( C# t; U    {
, s3 V, p3 t* S' O6 O      //
! N+ T6 ~5 v, }; I- f( _8 }2 H      // 查找 USB 键盘设备" [1 r, p. u/ K4 L) r- @
      //
! P$ l/ }! S( ^      if ( GetAttachedDeviceInfo( DeviceObject ) )( {) o! H/ X8 W
      {$ F) j4 O  ]( E5 l
        bFound = TRUE;: _$ K& g! Q( u5 s" E% x
        goto __End;& b! H% b4 C2 }! F5 W: s
      }) b, w0 t% V( }& }( X
    }
8 y0 ?' o5 j3 E7 k9 K9 L
7 D' _  z" S/ P( X    DeviceObject = DeviceObject->NextDevice;
% l5 b' p+ H5 X0 [  }
9 l. a' T2 E' W# u1 G, Y: b0 o! G9 ?$ R6 U( z5 ]5 x2 I
  __End:
) X' a* N4 W- {, R: w/ i
  _+ [# z1 R( E5 O' a5 S6 t  O) a  if ( bFound )
4 S- c- J2 G6 m' A4 H9 v  {* R% t7 _  k8 H: \, a! }+ l' T- N
    //9 y9 \- z: x' `7 _5 e
    // 找到则返回 USB 键盘设备对象: j3 y' T& O4 Z1 [
    //
5 W% n+ }3 f- e. m8 D    *UsbDeviceObject = DeviceObject;% K4 m/ `( D4 Q% X( s2 h
  }5 `; v  E; t# L+ Z1 [; K1 J
  else0 P  K! P( Z+ `7 {: ~, }$ y
  {5 l3 l6 s" c/ c! Z2 }
    *UsbDeviceObject = NULL;
: I2 S' i$ a4 e  }- |( n: D2 \% u: n# Z6 r" r

; `7 I9 O9 D+ R' x, ?  return STATUS_SUCCESS;' |2 P, B+ Q4 N$ N
}
, H( i, k& @( v* o/ d/ W
1 x6 C( V$ O# J, Y4 [; W) V/////////////////////////////////////////////////////////////////  d1 c" f) [3 L- S& ^& v
// 函数类型 : 自定义工具函数
% z. Q0 d9 M  m, s// 函数模块 : 键盘过滤模块- z, k& W1 R* _; T. l3 W! a: {5 i
////////////////////////////////////////////////////////////////
; t8 O7 u" I- ~! }" F* ?: l: F// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关; e8 B- K$ Z0 W7 M
//        信息,返回附加后的驱动对象1 |& _; S4 X2 l1 Y
// 注意 : 此函数仅挂接 USB 键盘设备9 l5 m  i  d8 c; ]9 B( e
/////////////////////////////////////////////////////////////////
5 ]: Y* ~& F- d" ^9 \// 作者 : sinister
, j1 ?9 a2 Q" p0 Z// 发布版本 : 1.00.007 b: X9 a+ Y) p/ W+ z# V9 H8 o) `* l
// 发布日期 : 2005.12.27
2 L4 |8 F0 u3 e, G* }0 v/////////////////////////////////////////////////////////////////1 u- s/ g) h  [, q$ P# n
// 重   大   修   改   历   史2 b  ]: W8 J3 m9 u6 X
////////////////////////////////////////////////////////////////
" d+ M* N! I6 u$ t" b% x+ W// 修改者 :
7 l: t0 g( w9 \. R8 A// 修改日期 :/ r! J! }7 R5 q$ b9 @: g+ W
// 修改内容 :: C% o8 i- [! k* J5 X/ [3 W
/////////////////////////////////////////////////////////////////9 X# h# {+ y6 a7 k
( Z% w* j- l( u- o- T4 `! i
NTSTATUS
2 u# C! |) ~. d2 dAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
8 k1 ]! I. t% X0 D$ \. ?                         IN PDRIVER_OBJECT  DriverObject )
4 `0 k  I# ^0 b! H( I$ J* @* ]6 @{
8 C6 d8 e$ q- V# z  PDEVICE_OBJECT DeviceObject;
! ?8 q" B% H; s& \' k  PDEVICE_OBJECT TargetDevice;
, M  q- `5 O& U7 ?  PDEVICE_EXTENSION DevExt;
' P) r: H! j, V1 k6 J/ `  NTSTATUS ntStatus;
' e8 _$ o) s' K0 a' g- S, A, s! Y2 ~. X2 C2 }( f! Z# c# a0 B
  //
3 f  }% Y! G+ W2 F" T; ]  // 创建过滤设备对象
& c' i1 l' s1 I* x; @* T6 ^& X2 K  //, J& |  n  W3 ^4 K% B3 v" O
  ntStatus = IoCreateDevice( DriverObject,
( P4 z$ w3 i+ R, a, {  T& ~                             sizeof( DEVICE_EXTENSION ),
& o) k; }( c( C9 u8 N/ @                             NULL,- E( m1 x; n) Q1 ^+ z" i
                             FILE_DEVICE_UNKNOWN,
# d, b' Z% u; B& g% Q8 {+ j7 E2 ~; e                             0,2 {; G, g8 S% N. G6 k
                             FALSE,
4 K/ m; ?. g! Y, F6 U                             &DeviceObject ); , s, n; G2 z" O/ \5 r& U! t* o
) ~4 Z) Q" t6 d2 f. w. E' x0 p
  if ( !NT_SUCCESS( ntStatus ) )
1 I; @; ]: {( h$ H! w2 v  {! p& M' c  [7 l4 B6 q6 e
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );/ |" ]/ N( I# U
    return ntStatus;" p; d" \- Z: H: X, e+ Z3 s
  }
% s' ^' z2 _) A& i6 J& E% g0 p+ Q
% F! E2 l! }$ D- v9 q  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
/ O* y1 h- O5 x, A+ z0 B3 u  v; I# j8 Q9 h$ {7 _" @) l' A: ?! f
  //
3 c& B' s7 f  [6 N! p) A  // 初始化自旋锁
. e7 R2 _0 p  j, w8 k) [# j  //% ]* P, d' j5 I
  KeInitializeSpinLock( &DevExt->SpinLock );7 k) `5 z) p$ I& J" ?, M

9 q& W- J8 h. l4 o$ W6 z- S  //8 O( X! |2 J: s) h: ~
  // 初始化 IRP 计数器
; P3 n) |/ k* m4 I, b5 V+ H  //6 `  u1 X2 P5 X! G" c# o
  DevExt->IrpsInProgress = 0;8 H# W- |7 t6 ~# J/ v8 ?
- u" x1 ?7 P& c
  //; f% w7 L' f3 s( G
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象1 U% |6 V  t! @, N# f
  //
7 O7 H5 G$ c( W, A4 S% [
, n  j7 Z- V) ^4 u& Q  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
9 }  R8 F1 ~5 O$ G  B  if ( !TargetDevice )5 x1 N$ z" [5 H: V# K
  {
) m% I# H) t( o- I! }2 N  g, k. X: U0 p: h    IoDeleteDevice( DeviceObject );
9 G/ S; ?( i+ h& s9 K# ?    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
. n9 z* K1 Z3 O1 p3 B0 T+ o    return STATUS_INSUFFICIENT_RESOURCES;; k+ X& b, O% d8 w
  } 9 g: `% n8 j/ H" r, E

. U7 R0 N7 J, J- {4 W& y  //! e0 |9 z" \3 p
  // 保存过滤设备信息$ N3 B: F& T4 }; s2 i' ?) G; s7 c) o
  //
" U: M3 b$ O. U/ v, R& u  DevExt->DeviceObject = DeviceObject;
. i; y# `+ ?/ C$ o0 \9 S0 T) t/ d  DevExt->TargetDevice = TargetDevice;* C  S$ F& F9 P

1 y  A! B: M$ B  //
3 K% M" ~9 O( t3 l2 j) n  // 设置过滤设备相关信息与标志
/ }7 |0 z* z1 N/ x5 v6 Q0 C6 F  //
" l1 X- O5 z0 w0 c3 E  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
* |" ?1 F! Y/ s" d7 }  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;* ^0 F- ?% w/ {
1 i' U: u, @( u1 |: ]
9 r+ }2 B, f& J. g' Y
  return STATUS_SUCCESS;4 \0 h; F: y) p+ M7 p6 z" q# ]  p  q
}
% M% Q& [2 ?4 c1 a
1 J/ m" |4 d6 c/////////////////////////////////////////////////////////////////. c4 x& m. Y* s  L
// 函数类型 : 自定义工具函数0 L# |5 B0 p9 P. U3 Q+ q( p
// 函数模块 : 键盘过滤模块8 v4 U; x; g. S* |% Z) y" z% v- l# F' q
////////////////////////////////////////////////////////////////5 [  A/ F- o% v0 g, |9 M
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
  z' j8 f/ m8 D7 }//        信息,返回附加后的驱动对象  R+ P$ v6 L; k; y
// 注意 : 此函数仅挂接 PS/2 键盘设备
5 L& f# m3 C' e( s/ s. i/////////////////////////////////////////////////////////////////
: @& s2 J: Y4 [' y0 w3 c// 作者 : sinister
# k' o  `' Q  ], G4 S! G- j0 E8 Z// 发布版本 : 1.00.00) X; T& W' P( I/ O+ {6 d
// 发布日期 : 2005.12.27+ C# [7 x% T, w! |' O
/////////////////////////////////////////////////////////////////
, F  D" S2 V) L$ r( g, d0 F// 重   大   修   改   历   史
6 v' q; ?. N  L1 N* d' w////////////////////////////////////////////////////////////////
, Q7 Z3 K' b7 r// 修改者 :
$ q% P  ^# d% Z) F0 k2 @// 修改日期 :' t- a* F% m% w3 F  Q5 Q/ k( S; x
// 修改内容 :
$ n' q8 y& u; C9 v/////////////////////////////////////////////////////////////////
6 P/ t' M( C: M( a( Q% e/ T6 l. [/ \. I
NTSTATUS
6 r  V3 h6 a) S) @AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名$ I' C) n3 }4 }6 P. Z1 c+ m
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象5 Y9 ?* J# k( N) J7 V& |
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
2 R/ i7 F$ b0 r, T7 u. L: O{
0 I) k7 v  a! Z  PDEVICE_OBJECT DeviceObject; ' S2 ?- t7 m8 ], r  }- o. X
  PDEVICE_OBJECT FilterDeviceObject;0 c; t- y: U" x- q5 w* X4 Z
  PDEVICE_OBJECT TargetDevice;
) u, W$ J  _) B  PFILE_OBJECT FileObject;
( i' M) ]; N9 d8 a( N. ~" \% U$ G  PDEVICE_EXTENSION DevExt;  e) Z8 T3 d+ _8 Z' O: d$ @7 |
. v. B7 |3 H6 T1 W& a) \
  NTSTATUS ntStatus;
% ^$ e3 ^6 h# o, E! R6 `% x6 E7 D8 {8 H
  //
: i; T: x( G) s! \( r( D  // 根据设备名称找到需要附加的设备对象9 J; @, @2 B% m! K. X
  //
5 u& c8 ^& a" A' L0 h+ i  ntStatus = IoGetDeviceObjectPointer( DeviceName,
& b* [6 ]4 f' U* f9 E' c- i                                       FILE_ALL_ACCESS,1 ^$ [4 p3 c. Z3 A( y- z1 Z0 g4 u
                                       &FileObject,7 ?* ?! I* @* E7 a$ w) v9 `! D
                                       &DeviceObject );
  d$ N1 q; N$ D9 T- m/ c
1 i: [8 B/ ^# |5 j9 a  if ( !NT_SUCCESS( ntStatus ) )) B0 D, Y0 r$ c% p0 u1 F
  {
7 B3 j  h% z: O1 l" _- ]& U    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
- U% D2 z% c0 _3 @  v, u: N6 }    return ntStatus;
4 ~0 ?$ I" \: m$ I( F  }
7 [# P) X: R5 u! O. J- \% _: b
6 ~5 W' O: |# D# S5 S  //' W' k: N5 A$ z; [0 I% _
  // 创建过滤设备对象
+ v+ i$ f! K! g  //
  Q& s5 {, c; n/ _( B: ?& ^& a  ntStatus = IoCreateDevice( DriverObject,
( J8 N7 \6 t/ h3 v                             sizeof( DEVICE_EXTENSION ),! T6 t9 c* K; |3 d& s! e% e
                             NULL,
/ L* D) }# @7 f. x- j  L$ j! z4 g, x                             FILE_DEVICE_KEYBOARD,
/ O$ {. p$ Z7 O* ]9 R: p: U                             0,
% {1 v# L: A# H, G; o5 R+ c: P0 n                             FALSE,
1 F- o7 o% }5 ?% N9 i* j: k                             &FilterDeviceObject );
2 Q& ]$ L9 X6 T( a, P: n* B. q
( o7 [0 R. g3 D- r% B$ \8 B% h  if ( !NT_SUCCESS( ntStatus ) )
  H& Q9 f, i. ?  {, q' Z0 _- E: I1 a
    ObDereferenceObject( FileObject ); 7 e: K, a) Q; J  ]" r( C" H
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
7 h! q% O0 ?/ c! [( V' B2 T7 U! f    return ntStatus;
4 c; F5 |3 T' M. D  } . c9 d% J" K) _% ~, U  Z/ y

) P0 a1 q  }/ U4 g+ S- M) I* u  //, A1 y" h, @7 f
  // 得到设备扩展结构,以便下面保存过滤设备信息; N" O8 Y' A. y' L8 j
  //
# U6 l5 Y2 w  O( I% J  z' o  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;8 x4 k1 D& Q9 W: o, m

+ ~6 |/ s8 ^( f- k2 K7 {5 T/ G* l7 I$ D, n4 V5 L% w+ L
  //, _: ~! ~2 \3 x+ P
  // 初始化自旋锁
) g, J. L& M  ^; m- r  //
9 a9 N7 n+ w7 V  KeInitializeSpinLock( &DevExt->SpinLock );% e- R* ~5 _; B" w+ v" i& r5 M

, j! ^* I  u" \; P  //% q# ~- i" K0 W
  // 初始化 IRP 计数器- B& k% \$ n- F+ F, d. z
  //
" K3 ~5 [* C, ^# |1 ]  DevExt->IrpsInProgress = 0;
7 I% g5 n8 m% c2 ^1 A6 b" ]% b% F% \, J
  //
( m/ h/ j6 n$ x& {  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象5 U+ y7 b# Q( L' c8 w
  //
( t; B# c/ M# m0 _, O$ H- j  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,- D6 K# Z) I2 {  a) `: f) r
                                              DeviceObject );
3 n0 l  P6 a- @* |  if ( !TargetDevice )
) \/ q" k* }( s9 ~; ~0 r: X, f  {0 g* j. ]1 d7 p8 [  D2 P4 _
    ObDereferenceObject( FileObject );
- I( c+ f; C9 C8 v3 q1 W, d. p    IoDeleteDevice( FilterDeviceObject ); % @5 w' r/ Y, W, ]( J- @, c
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
3 V# N# t6 q( Y8 N4 i    return STATUS_INSUFFICIENT_RESOURCES;# y: N; k* k! E! N* X
  }
7 h: {4 k$ L' }! a1 ^) C2 d/ V! s. P) K
  //
" B# X9 I: m& M; c. p  // 保存过滤设备信息, d- I) Q" @2 ~3 }/ B5 I
  //
, ?1 H& N, f1 {- r4 ^  DevExt->DeviceObject = FilterDeviceObject;
3 R# ?- u/ m2 N+ G2 C2 q  DevExt->TargetDevice = TargetDevice;
- g" q- f, J2 j' w* [# O+ ]3 X: _  DevExt->pFilterFileObject = FileObject;' {+ n: ?, |& y! x
4 |4 k9 O0 E! f/ L( P2 t
  //
4 N( h! \2 ~0 Q5 L/ P4 p  // 设置过滤设备相关信息与标志
: Y/ ~% o- |4 y. N0 D; |  //
& Z, F4 a3 `( m6 r/ F4 H" p  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
4 Y2 y; P) }$ {7 n" u  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
$ f7 u' B" W9 b% g5 M* D( U# j  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2 t8 y1 a5 ~4 \* ~8 K& W6 J  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |% c9 v6 W, ?% i0 A$ k" E
                                                         DO_BUFFERED_IO ) ); ; D5 V" _3 s/ L( J0 S) \" Q; o
0 A" g, A5 g0 x2 C- v8 t
  //
6 j- s3 _4 A0 o: J/ y5 h  // 返回附加后的驱动对象5 R8 ^" M1 b1 _/ M
  //
+ c: d5 Y- Y* ]. q" ~5 R) m2 n9 ^  *FilterDriverObject = TargetDevice->DriverObject;
+ P( n' M3 w" `
( O- ?7 d" E: u3 o  ObDereferenceObject( FileObject );
6 A" h; g9 y! ~0 t4 a) I
3 j5 l/ T, K# S0 ~( L  return STATUS_SUCCESS;
: o" _+ T) }% U! _3 d}
8 Q. o. Q; V2 O. P- H( K- y& t7 {& H+ ?8 z! J
/////////////////////////////////////////////////////////////////
& T" f- {8 d* ^  w, q9 S8 _// 函数类型 : 自定义工具函数3 V: E! g0 F8 E: j
// 函数模块 : 键盘过滤模块! T/ l  B: V5 I  F" h( p
////////////////////////////////////////////////////////////////
1 j8 L% ^8 g' K9 p5 J$ I* m// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发$ K3 D: F( _; F, m
//        这个 IRP 的完成' V6 B+ _3 D$ c1 {, ?/ C
// 注意 : 0 \, P+ Y9 y2 p3 K6 c
/////////////////////////////////////////////////////////////////
; r9 g5 r' s! R) b! m/ e// 作者 : sinister5 N1 O+ q! B# [5 _& F4 {* _
// 发布版本 : 1.00.005 t4 s# l5 B9 ^1 a
// 发布日期 : 2007.2.152 G0 Q% b2 a- j
/////////////////////////////////////////////////////////////////6 W- j  [" w% X1 H( Z
// 重   大   修   改   历   史
( ]$ J* H% v* G( }////////////////////////////////////////////////////////////////
5 `. V4 j7 u- ]& `+ h// 修改者 :
/ A6 u+ u0 R( B// 修改日期 :
% m& _( x% y8 ?+ R// 修改内容 :
" d3 E6 {& x# ^& X- {9 t/////////////////////////////////////////////////////////////////
8 }% J/ W: Y; d( P' Y
' Y: s- i) O/ O; |; |. gNTSTATUS- v' T( P3 R6 E3 S% M" q# J& l
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
6 e3 P8 M1 c* V* d# X3 H2 w{6 [5 |+ E$ Z1 u) Q& M
  NTSTATUS status; + E9 C: x1 P" g/ F1 B
  KIRQL IrqLevel;
; t% W5 h7 P, ?+ I# n9 D$ h5 A7 a* ~( _' L$ o0 m" h
  PDEVICE_OBJECT pDeviceObject;
: R2 _6 _) {: r: L7 E, L/ l: f  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
& q+ k, p/ R8 y( V) y3 n2 K                                   DeviceObject->DeviceExtension;
/ {) o* s3 I# `3 @7 c) g  a- T' k, G) w5 o! D+ G- K

$ ]- F* N' e3 O0 j; {  IoCopyCurrentIrpStackLocationToNext( Irp );
2 m: d, x$ |7 o8 [  ]9 x
" v! E, c, i# Q- Q% ]$ L/ k# {- |1 S  //
: ]* l4 u( d( A6 {( ^  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
' W1 M6 G9 L. y' Y* G. j: f  //
$ p+ T. ^$ h4 S8 I# m0 Z  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );2 ]2 a2 M' ?: Q/ F
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
; I# ^1 Q! M; d+ {/ Y  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
% T6 {" j- U0 M. _2 \
: `2 Y) D0 L4 E% X+ O. g+ F2 ~5 e  IoSetCompletionRoutine( Irp,5 p7 m0 S3 \6 G* G2 x& N6 _
                          KeyReadCompletion,
$ D6 Y) t2 b  _9 o9 _9 W0 p                          DeviceObject,
! g# R! N+ C. X" B                          TRUE,
0 ]- r5 B6 m7 _. u5 u4 R0 L; Y                          TRUE,
4 Q1 s6 ~  Q; y. `1 D' s/ ?                          TRUE ); ) n/ v$ [- ]2 _+ p  f
, w1 q/ H( ]1 W# r; Y  j. Q
  return IoCallDriver( KeyExtension->TargetDevice, Irp );
' s: O3 M1 g9 q6 x% w) i}
- H1 ]5 ^/ f! e6 V5 o
0 C( b1 c( V6 S. O) a6 m/////////////////////////////////////////////////////////////////
' }; [, f) V; D8 ~5 j// 函数类型 :系统回调函数' _& O1 q" n* B4 j( e
// 函数模块 : 键盘过滤模块
" n" P  J2 S3 C: \8 ]6 A////////////////////////////////////////////////////////////////4 M8 d8 i8 S# I8 ~! t' |0 w" |; V
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的  F5 [7 O5 T  F0 m4 A# r( H3 K
// 注意 : % q' z; W2 `5 c9 ?" W6 D* T
/////////////////////////////////////////////////////////////////
0 _5 ?6 h3 Q/ T0 I3 v// 作者 : sinister; |9 k! E0 x2 I+ }" d
// 发布版本 : 1.00.00/ w0 _! ~9 X! M- W/ o6 P
// 发布日期 : 2007.2.12! i7 D' J1 d5 |  L# q9 U' \
/////////////////////////////////////////////////////////////////* E& Z* ]; l! }2 O) x3 n" o0 H
// 重   大   修   改   历   史; d! v# P4 p2 s9 {7 E) n
////////////////////////////////////////////////////////////////1 s- k- d7 s$ `* j* t/ m
// 修改者 :
5 w3 A3 U0 L! P% X3 F( s// 修改日期 :
, y3 C4 D' B/ z) q8 @// 修改内容 :
: v! K" b$ \. G! j  B/////////////////////////////////////////////////////////////////
6 l- q. [" w8 f  R- d! [# @1 k, I
8 D7 V. ^+ f' e' FNTSTATUS
  ^  A/ Y: x  p9 LKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
! R1 b. E* x: q. ^                   IN PIRP Irp,3 s' J5 c. g! }7 ~: E2 c
                   IN PVOID Context )( X' p% h5 M6 ^! L4 m1 z
{) a7 C* H5 P' u, A) F- |
  PIO_STACK_LOCATION IrpSp;( j2 u4 J3 u0 }
  PKEYBOARD_INPUT_DATA KeyData;
4 w& x/ h# v& r0 z0 ^  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )6 h0 {1 s* i# X* e0 p9 M# ~" v
                                   DeviceObject->DeviceExtension;
2 j+ S1 J, d3 v  l6 z  int numKeys, i;1 x" l1 ^  h- O) V+ f0 a
  KIRQL IrqLevel;
' a. u6 [0 ^2 D3 S' I* l* g$ r  m( T
  IrpSp = IoGetCurrentIrpStackLocation( Irp );. H; }6 t0 T: m3 \6 s( t) }
$ r0 m0 T% U. s! j/ v* d1 B% l

, |- G; j( L# M6 r; k- F- ?! b+ W  if ( Irp->IoStatus.Status != STATUS_SUCCESS )4 N, g6 U! \" x
  {
' [$ l* D# o' z$ @9 C3 ]6 I3 ~    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
  J* n! r  _* `2 Q  r& f8 z    goto __RoutineEnd;1 n1 u& p7 l. a9 O0 v, v3 ^
  }' O# }! S" a0 C0 A
$ [  O+ V; w6 R# s4 D
  //
* y8 Y; J" W' n2 \  // 系统在 SystemBuffer 中保存按键信息
1 ~. a' E# C$ \6 J. e, c$ {. S  //
8 P8 \0 X, a* t9 Y7 s' U  KeyData = Irp->AssociatedIrp.SystemBuffer;
2 W$ S  U/ q6 Y1 F  if ( KeyData == NULL )
" H+ n3 w  r2 ]: g- J  {5 V+ t3 L/ k" e. F( i
    DbgPrint( "KeyData is NULL\n" );
4 J4 x1 ]5 w* s! }/ h5 K% c    goto __RoutineEnd;/ T4 n, {, {7 r( i4 Z6 R
  }
1 }. R: U; g( u; u9 T' j! s1 s, L5 s2 w: {
  //
* i# `. Q1 |1 v0 l& [  // 得到按键数7 f6 v4 J+ W9 t8 `' @5 M4 ^
  //9 ~( c3 M$ F9 O3 F
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );5 E- a4 V' y5 h* }- p5 z' k7 Q  m
  if ( numKeys < 0 )
! `1 R3 e) G% x# h1 r$ `. T1 X  {$ t6 ?) y+ X" t
    DbgPrint( "numKeys less zero\n" );+ d% g, R  e5 V
    goto __RoutineEnd;
0 {% H+ X6 s1 h' ]/ q% f* s  }4 ]( a% s) l8 a; ?& a) A1 M- W
. B! x6 J0 v8 ]- p) V
  //
' z. Q  `8 |; q$ B% n* w% t0 o  // 使用 0 无效扫描码替换,屏蔽所有按键
  L: K8 O6 b+ @) S5 o! h  //
( Q2 Z0 D! _/ u9 F  for ( i = 0; i < numKeys; i++ )' ^) D! \' g- n, B' Q, D
  {- K0 T% C' E4 U# o- w. s4 m
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
1 K2 ~* j$ y: p+ F. r. x    KeyData[i].MakeCode = 0x00;
1 F8 j) B) I! G+ s4 z# X/ a- q' k  }; M' m* X/ {1 O$ L% z

) h( M  B. w3 L0 l) w4 @& |3 V% H
1 G, D) n. s8 Q2 x" u! B8 T- L$ r  __RoutineEnd : 9 Z& D# V6 z. H! K9 d. G3 Q1 `6 {# l

4 b2 `/ J: t6 `5 T  if ( Irp->PendingReturned )
1 u1 b4 s, }7 [. _  {" _* M8 M. h) a1 e3 G" S
    IoMarkIrpPending( Irp );
* p; c- j! {: v; B# P  } ! N& q5 `6 d0 \, R1 T. G- j

( K# e$ V, E% x  //
; d  b" V& ]2 |  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
6 A: w7 R1 Z# N. [2 E! _7 U  //. x  a0 _  _  H9 f) {# d6 x' ]
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );+ w$ O5 H8 q& h' a0 r+ I9 A
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
- Y6 ~. G; ]0 P( |0 X& h+ p  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );  t5 P" g8 J+ U+ `% u

& R9 j9 W$ N7 h/ o" D8 W  return Irp->IoStatus.Status ;
+ a# Z% o8 T! w# Y: x}
6 T& Q# {. w" {. O
) o& @1 w9 ~) H8 J) _6 c
+ B! r2 x5 y7 E- k2 b, b# d/*****************************************************************
/ h' y- Q% @' ~0 ^  S' T 文件名        : WssLockKey.h0 @! g8 v: L% Y$ u4 j
描述          : 键盘过滤驱动
5 T; f: v( d+ G$ l' P8 b 作者          : sinister
5 f+ C5 l1 v7 n 最后修改日期  : 2007-02-26. i' J8 l9 B8 K" Q
*****************************************************************/
% X0 [% j4 k. Q) ^) e7 ]- R& |, ]  e1 o* V
#ifndef __WSS_LOCKKEY_H_
& ?( A* z! M2 g7 X+ z( V, X#define __WSS_LOCKKEY_H_
+ Y$ U8 f0 N* y: O# p7 z9 m& A1 O- E& \& l2 y- ?! ^0 n' z
#include "ntddk.h"+ ]+ j5 f" M# X, [' B
#include "ntddkbd.h"4 E1 V; e1 M, n) i% w* s; s
#include "string.h"
3 F% G) C& r4 A9 {4 V! l#include 3 }# Z! |3 C0 H9 S
+ u* ?, L5 z, K* R$ @0 T/ C
#define MAXLEN 2564 B3 L* Z& c9 X3 [
7 a# L+ p% |) J
#define KDBDEVICENAME L"\\Driver\\kbdhid"
6 g/ z7 w6 f6 s- N& C4 i, a#define USBKEYBOARDNAME L"\\Driver\\hidusb" 2 ^! S0 X% s1 e+ [  e- }
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
+ a* @3 o" y# h3 u# U; q& p! T( j, L" p6 a( U1 f( n
typedef struct _OBJECT_CREATE_INFORMATION% y* w2 t- g% U: m+ o' \) a
{3 a: {' u4 a8 l/ C  x; C# F
    ULONG Attributes;
5 X6 k5 M# ^/ N+ d7 C9 I    HANDLE RootDirectory;
, o- J& q, ~. m7 p0 e! u    PVOID ParseContext;/ s  }; G- S1 e6 J9 p% ~
    KPROCESSOR_MODE ProbeMode;6 _$ @; a6 X4 ?8 t4 g
    ULONG PagedPoolCharge;  n; V9 y4 U* L! L& O
    ULONG NonPagedPoolCharge;; s. f2 }$ z# w9 y
    ULONG SecurityDescriptorCharge;( Q5 t9 C7 b0 E! a% H" V
    PSECURITY_DESCRIPTOR SecurityDescriptor;; ]! \4 d9 C7 k8 E) D- m9 ?7 U, n
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;6 a& g7 e- O* o6 R
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  n4 R9 q" y/ y. _( t$ u} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
, X( b+ m8 S! e
6 [$ n* e9 x0 [typedef struct _OBJECT_HEADER  B7 v! p$ R6 _& ?/ `  Q" {8 s$ u
{
: B3 Z! d  d. M+ ~8 Y    LONG PointerCount;  ?! u0 ]  \; ~2 e# F
    union
& a2 S$ u% v# _    {
4 v6 }; C2 W$ X4 t7 b/ A6 Q        LONG HandleCount;
; b( ?* Y: k0 e4 U3 b9 a        PSINGLE_LIST_ENTRY SEntry;5 z8 `( I2 _7 K) Q  M) T7 S
    };4 @8 |* z2 R" J+ ?2 s/ k# M; ~$ I; X
    POBJECT_TYPE Type;
2 T$ e' X. c) `+ [( L! ?    UCHAR NameInfoOffset;
. N8 z1 }6 a" n/ h    UCHAR HandleInfoOffset;3 M' L, [" U& ^7 t4 N( a
    UCHAR QuotaInfoOffset;
& p& Q. c% u; h/ U8 ]3 ?, F, v    UCHAR Flags;
' D! e" _2 o7 d! V/ s  I    union
' Y& {# l( c9 T2 G# H. ^    {
1 v" L, h9 ~$ v/ K0 S        POBJECT_CREATE_INFORMATION ObjectCreateInfo;: [7 m) m. w2 S6 b' ^
        PVOID QuotaBlockCharged;0 _& [. H3 W3 U! q% m
    };$ M0 c  D- H! p0 R. l. X
5 I/ T1 S6 e* f2 Q8 P
    PSECURITY_DESCRIPTOR SecurityDescriptor;
7 R8 T) w  V/ J; \+ I7 }3 J    QUAD Body;
. F% M8 `. r* H/ _5 k% Q} OBJECT_HEADER, * POBJECT_HEADER;* K8 b0 a5 ~5 y* Y8 b% ]. w
9 {. K# @9 z1 o; x! q6 Q2 A& d% `! \0 \
#define NUMBER_HASH_BUCKETS 37
) B2 }; f, E( l4 U6 L, X; k0 s, ^
typedef struct _OBJECT_DIRECTORY
1 T" W5 s. {, k! I6 y{
. E! ]- d8 W: s3 x. r* l% G' z2 g    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
0 Z& z: G7 L* b7 k# G    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
: i% R( Q1 f, ~: q$ F/ X+ u  [: S    BOOLEAN LookupFound;; Y( A4 v0 J4 e! W3 Z
    USHORT SymbolicLinkUsageCount;5 \9 O) t4 e" p5 P8 K! v$ V9 J0 q
    struct _DEVICE_MAP* DeviceMap;
/ X8 S/ S# ^- n' d  h} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;& U8 i8 l# [% _3 S7 k- a* X+ _! ]1 b

- n2 I: {6 \; `" i: U, Otypedef struct _OBJECT_HEADER_NAME_INFO
0 q" L: I4 p' X* q{
) G) d6 M9 Z5 S2 r    POBJECT_DIRECTORY Directory;
. q6 k5 V' k6 E    UNICODE_STRING Name;
4 n% h/ Z' T3 q6 H& @! U    ULONG Reserved;
" \5 K! |1 I. ?! w2 N: n, @#if DBG3 |1 l8 t8 y+ C) F( D/ o
    ULONG Reserved2 ;
+ _9 z7 P8 S; P" Q/ c4 X    LONG DbgDereferenceCount ;7 \% e7 R) @4 V' _- `
#endif
# }. p  m: }& t* L" h2 F} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
; a* @3 O4 j% d8 k0 x2 H2 @% _( l1 b! X9 E4 V* u3 I/ w  A% }
#define OBJECT_TO_OBJECT_HEADER( o ) \
1 A5 B, ?$ J) J7 H    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
! M4 z. y# U2 Y( r) D8 {, s6 W+ [9 v  M- t/ D6 P: P/ }
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \1 b, ?7 z5 U! g% `
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
. [& O, \0 X' q7 M/ A5 i5 a$ m7 W# }, I) e  ^' }
typedef struct _DEVICE_EXTENSION. w6 W5 l6 K4 ^" p+ n7 s4 M
{
5 L& [) _) g+ p! n- k5 \    PDEVICE_OBJECT DeviceObject;
5 t+ i) Q6 o1 s1 n    PDEVICE_OBJECT TargetDevice;$ y: S7 U5 w. I7 g
    PFILE_OBJECT pFilterFileObject;
: z; ?9 A8 k; u. K5 a' u" c    ULONG DeviceExtensionFlags;& a5 T  P% Y0 o7 j; x# d! K9 A
    LONG IrpsInProgress;
/ k, R+ K' i' [% L    KSPIN_LOCK SpinLock;: E5 Z; b; y6 u5 s8 y
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;! t/ {' W- x* P* e$ c8 L
, ]7 _( d( [$ j+ B3 T% m

) M+ A* B) X' L0 P4 K9 MVOID   F  H6 @$ f1 l% i- m( H- W
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
+ }5 s1 d0 k7 U: x2 p4 a# b# H8 |; O6 n+ p
BOOLEAN8 p8 \( k" v% X, o. A/ M" i
CancelKeyboardIrp( IN PIRP Irp );
5 x; A2 W4 }! A7 h+ o! K- V
8 C. ]' {1 P0 W9 `extern POBJECT_TYPE* IoDriverObjectType;7 y, X4 d  y: t

. o8 |: L- g. d( B  b3 MNTSYSAPI9 @+ o1 c$ x2 v7 s  C
NTSTATUS
2 A% u( C7 F/ |$ s$ a, \NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
3 x% u0 ~8 l4 @" }                               IN ULONG Attributes,2 C' ^4 J! Q. f! E# ?3 o
                               IN PACCESS_STATE AccessState OPTIONAL,0 F6 _) D' J: W7 f9 N
                               IN ACCESS_MASK DesiredAccess OPTIONAL,
+ @/ g# z! D3 |9 M                               IN POBJECT_TYPE ObjectType,+ }/ T# t! h- m  v% B: ^
                               IN KPROCESSOR_MODE AccessMode,
  f* r4 j4 T9 Q6 k8 x' ?- }; U& h% D                               IN OUT PVOID ParseContext OPTIONAL,/ V$ ?1 K. ~. w3 W3 M$ Z
                               OUT PVOID* Object );
1 c* e% q- O1 L+ D( |7 ?( F' j, s0 M0 a/ C, ?1 N7 K
NTSTATUS
2 ~  N' R7 h- S7 uGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
! K/ W5 m3 b; P: D0 i/ y
& n. o. ?+ S* z. SBOOLEAN 9 c4 h) n, j, i" s6 s6 d
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );% p& w4 w* I/ E

4 L$ {0 ^# S9 vVOID
/ R& @$ N# {" d7 C3 {, I) x, vGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );0 S; j+ l  T  M  m$ w

: X9 K% l+ I# \/ M' rNTSTATUS # w& Y! \4 I" m
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,4 q8 j. `; ?8 ~8 K/ E$ O# T% r( W
                                  IN PDRIVER_OBJECT  DriverObject );
* j+ A% w8 h& Z+ I" |5 S
8 _/ w9 e7 A8 [, D+ l3 i4 jNTSTATUS 2 D4 g8 ]5 N9 g; o* C$ a
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
8 c0 U/ i7 D9 F6 g                                  IN PDRIVER_OBJECT  DriverObject,
# B) K( B2 l" p6 U                                  OUT PDRIVER_OBJECT* FilterDriverObject );
) Y, f" B2 n" `% h5 J+ V) k5 y3 R9 p, M  @# ~+ u+ G
NTSTATUS / h% n7 b8 G( i: s& A# F8 s- ?
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
! v" C6 \! V  q9 d1 y. N                            IN PIRP Irp,
/ \$ v. @) |; Z7 U                            IN PVOID Context );; c) z& [- Y6 j& O
NTSTATUS
' L# [- A* V" GKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );& N. {6 w# n% x2 d
# J4 n% r+ Q  a* X; H
WCHAR szUsbDeviceName[MAXLEN];
4 \9 [: d  H, e/ G  ?: F( F# s: t; g8 w7 }$ C/ C) Z- X+ T' S+ S
#endif
& z) R4 F6 s4 K0 D7 v8 P% U4 H+ }$ o9 ~) a

7 I0 [. o6 Y+ h6 e% U/ O + b. l  `& W. m+ K+ \4 k7 b
# M: y, N4 j+ `5 D6 T. s# {
, c: W, N+ y0 ?% a8 \6 _8 S3 ]
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
8 {0 c  d3 \  j+ u6 dWSS 主页:[url]http://www.whitecell.org/[/url]
1 M- F. d2 Z0 Q3 k( P0 L) M; z  VWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-10-18 08:04 , Processed in 0.053773 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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