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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
# e7 _& Q9 T3 W  YEmail:   [email]sinister@whitecell.org[/email]) ]. W) U( P$ B3 Q( S
Homepage:[url]http://www.whitecell.org[/url]
8 b8 O- W. c& ?: Q9 z8 zDate:    2007-02-267 M! b* M- f4 t7 R

* m0 _/ T. D) s. k# |
# j4 M9 \, O' j  w/*******************************************************************' {0 K- Y' F1 s8 y& d" j

( Y5 _* A! D; h3 J2 y+ a这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx. k0 g# I. ?3 b$ c4 P# W+ m
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的( {' ~6 I6 F: g+ k& C
功能要求如下:
; _/ J1 G9 p  }) |# x0 o+ c0 r# [5 g) R
1、强制锁定键盘/鼠标。
% G4 B5 l/ `: ~8 J3 w9 A. r& X2、可动态加/解锁5 U, W- `/ \. J' i0 I9 I
3、兼容所有 NT 系列的操作系统。$ M5 L' d8 v! t  r; X& W7 [
, d( X! s' _/ e9 C
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实0 f& }, m$ X1 B  @9 E1 e
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
& i0 m" s& L. m$ W1 f: p/ }, `  u何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在7 {2 H( ?2 |* A, B
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是- k3 N0 ^% {% l  i7 g
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面0 ^  [' j3 c$ z0 P5 ~
就来看一下我想到的几种实现方法:; N' S  E$ `" D( S# R% M
; V( Q& `2 J+ L3 ^9 g. H
1、全局键盘/鼠标钩子
& N+ k0 m( U3 e2 H+ M0 M2、BlockInput() API% P: |  R, n/ {# F6 o& r' L
3、使用 setupapi 进行控制" |5 {" M2 ?9 P6 v) e  x& V9 o
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL$ `! t" }" e1 f( m; C8 K$ ^: N
5、拦截 win23k!RawInputThread() 函数! g  ~# u0 ^! n" R
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
% _: Z* g9 i' t) N+ w7、拦截 kdbclass 驱动的 driver dispatch routine
, |. A/ S7 R/ R- @9 v8、实现一个 PS/2 与 USB 键盘过滤驱动% Q* M8 ]# G5 n! c4 N; ]5 @

  ?' D& _3 Z; ?' N! a
% z0 T& m- ^7 L" p+ x" ]2 q5 H我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
& c0 f* K: j/ P; k4 {, e之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( f3 Z3 x& ?% p4 e0 @' _
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在7 e: g& C3 O% i+ x
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因( j$ D  L7 N2 P# C) ?) D+ ~$ _. _
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性6 v8 ?/ {& W( r# C0 o- r3 k
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
8 w& \  G  v; ]$ B载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我- h# z1 \( d* J3 O: l  S6 P
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
3 L  \, C7 i! e6 U  J2 d, N也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如! z/ w( z# t. X. H& ^) B8 A9 w1 i
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
% n6 j2 b5 L7 m; x$ Y2 B: ^障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截- d$ m9 R6 ?, n
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 / |# W! y8 g# H/ T8 A- A/ d
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
: ^( W% }3 [  L5 w; Y8 w$ \" Q1 f盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方! g& w" A3 @& b7 t  c/ [
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。* u* C" ^6 T0 C* `& O: }
$ Y' d" [% c* |( F4 t

" l: [$ A- N) W5 L( U/ s/ G5 U我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过# g5 L& p$ v2 b1 j
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
, y& }  u, z1 s5 ]6 X/ L6 Q行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
0 q9 T1 t5 f/ T只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越1 U, m8 N' ]9 V0 p
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
& U& o' e" {  [  `" E0 eKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
2 G; K# Z6 ]3 W, }' D键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用; w- M! G( X" \
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,7 T" y* E& H# M" p) Q' F
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题/ {* ?$ Z4 _8 z, d8 c2 I: N
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
) m) w1 ]+ i* y' v1 }2 n; j而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
# J& C! j4 d6 T; Q- l1 e- n用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
2 ^  K: z: r& G7 l) K过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
6 F4 Y& o6 s0 s0 x& ?& R屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通9 `% d2 {5 u# T  z* @
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb* E1 E* C' \) ^' d: N
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid ( P( o" f7 ^9 w8 _- D( m2 K8 g
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意( n2 k) Z$ X3 V& C. s' H7 d
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
& m- A7 ~9 _$ n% ~经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们$ t  V% M. A1 h* {
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
8 {: ?, C; _9 N& P& n, B4 F的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo" _4 ]) }0 e$ h4 W* W3 ]
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
+ v$ A  a8 s& i2 G敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
8 b1 |+ [& c. p' P7 e根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程5 l2 Y4 K4 x7 G- `
见下面代码。* H$ w+ d5 |4 }) B. a
  j6 K, _& H# J' _- l# V
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
5 U1 L! w( Q  m+ Q* @5 T% E里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
! U/ k" ~& U0 F$ w& [1 W盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
2 U- R# [% T1 k* a& k3 ~% q2 V* |上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有9 V$ F. `! b. [" Z. k
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可& o& Z+ y- D9 M, I, R
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个' S6 c2 e9 Y0 c, l; q% y
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按1 Z8 W4 }6 Q. Q2 }
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
0 V. A) m0 R7 G7 `! R3 [( R" K1 X% O. a& D' n. u# o4 v

2 O1 c  d, i9 K( N# L' `* L完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用# f; U4 j: C. b. Z* i- D6 A
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是  r  t7 k, |1 c( B8 t* P
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣7 y% I6 g3 B" ]& R' R
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
2 W, k7 b/ b  K0 M. G  A4 {们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
" x3 Z- B' M; K# m: w9 c! O0 [们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
, q0 G/ z; f8 k5 v$ P% S->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
$ T4 {6 s) f3 a如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
* t+ \9 k8 \# y1 p进行操作了。这个问题有待大家来完善了。  J) Q+ r* w/ M: |' `7 ]" u

% k* O2 [, v# e5 L, l3 y! U. E+ T9 B, c  ?1 I7 O
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
; L( ^1 V9 c( w8 o2 x6 R2 c来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的7 n" m& n9 s4 }5 I3 r+ ~5 m
分析做个记录而已。我更愿意把它看做是一段注释。9 g' o: h3 h9 t" E) o2 \

3 t! X  \+ z1 ?5 i4 C- a最后在此代码中要; h4 S/ y) F1 [8 H- h2 D* C

9 O" i  c: I' x* f感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
8 ^( U; w! y. ~  D" N
% J  m7 w0 S$ \$ X/ X* |感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。+ o8 X3 S) B' ]: h$ A1 c

/ H- {: [4 H# H" B4 T% s6 ]# T感谢:齐佳佳,过节请我吃好吃的。
/ O$ P& z( C1 y* H9 M. f* E3 r  Q7 ?. `! v
! Z7 b  q8 P) |7 N( q
******************************************************************/  }* b2 n. `) C+ x

: N' |% g% r4 S: E6 I( h$ |# b  [5 e! r6 H& G3 M
/*****************************************************************
6 _8 B: \& y1 A5 a5 K% D. A 文件名        : WssLockKey.c
' Y! v" V) y2 S$ @! A( M" C8 x 描述          : 键盘过滤驱动
+ u6 |& P, X, Y' ?+ ?% F; s! _ 作者          : sinister, ?0 D: f7 \$ A& F: y( c
最后修改日期  : 2007-02-26
; q0 s) m+ x& s5 i: g2 c% _& j( X/ i5 M1 N*****************************************************************/
; k) [4 D7 n# Z5 A3 J  v2 D8 h- d! x4 U( P! {, u# D

$ I1 J7 Z* O. ]) ~7 U#include "WssLockKey.h"
0 L* {# p  L0 u2 C4 d. b3 V  a7 O
0 n6 `. \+ t1 W- nNTSTATUS
8 ^3 c7 o, g0 [$ x# z+ hDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,- d# v0 d: s# z- Z: l" k1 y
             IN PUNICODE_STRING RegistryPath )
( t" _! D9 H6 J5 I{3 \7 X( c' T8 i& p' d
  UNICODE_STRING KeyDeviceName;
8 J5 o* z. t3 Q" f# t5 a8 S5 P+ s  PDRIVER_OBJECT KeyDriver;
3 U* n6 X5 n& d( }# ]8 [  PDEVICE_OBJECT UsbDeviceObject;# c. t% J7 K5 \6 \- G8 Y
  NTSTATUS ntStatus; ' ]2 t8 `% A% h+ a$ \3 |
  ULONG i;
$ h* Z! r8 t3 k* E4 O! Y  e6 Q7 V1 P5 o
  //; z- m( R2 G5 }8 w( P% v
  // 保存设备名,调试使用8 V3 A+ \2 R! m+ j! Q  y! J
  //
6 I: n: d! B0 X% O/ b  WCHAR szDeviceName[MAXLEN + MAXLEN] =
9 A$ z: q8 [' q' K  m- i# b  {
% N- e0 m" D9 J" W+ u7 ^    0
5 _9 _1 i  x; `+ N9 E  };4 \1 s2 C9 s6 h

% E. ~; E) n, y  KeyDriverObject->DriverUnload = KeyDriverUnload;
7 D$ Z, i& W7 U" k8 x$ B
3 l: \: S1 s2 T7 O8 ?  //% v  u; v* L8 s
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘1 I+ a! A. ~' ?% e9 l# s
  //
  L  O3 Q& O" s6 h: L# t# X. G  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
+ V- Q2 k( {  X5 Z8 d0 o  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
* s+ w4 A, g7 [7 U" t' Z  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到( D3 h! [1 g  Y! K  m
  // USB 键盘设备来进行挂接+ o) @4 i9 x( V" g- Z2 D9 c% n
  //: {) M9 l' K( b8 b" Z
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
$ n  K: r$ q$ I* y  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
+ S$ [' _5 h& ~8 L+ |1 G  {
4 W6 z+ J" U6 |3 Q% \0 R    //! C6 i; o0 [) D7 ^4 `. u& `
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
: }" }1 W# i0 S. l2 K+ q3 M    // 所以这里打印为空
$ P1 z9 W1 v2 Y, k    //
% F0 N! z+ [+ w: p; c" h0 @    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
1 t' M. k, A* E    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );' c+ D) @/ j7 H

( F4 U+ r, f8 m% t6 T    //8 q  I* Z4 N1 S" `
    // 挂接 USB 键盘设备
0 t, K0 k4 ~9 x% {+ w- k: y' _    //
" ~% @1 J/ V% d5 |  u3 Y, x1 `    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
# m/ s5 Z% Z# P  }4 q) P+ v9 S3 k    if ( !NT_SUCCESS( ntStatus ) )
# m; T% O* P3 x$ `# r' i( o) \( M    {4 }# c% ]0 F& C9 X
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );) g7 p# K3 O0 c; j
      return STATUS_INSUFFICIENT_RESOURCES;5 V! Z( j4 l5 Z# x/ H( q# O
    }( K/ W. I& n$ P, X# r' m% l2 x
  }/ h2 n  `" @8 b* z
  else2 S* \6 [" f- \$ P
  {1 m. ~5 x4 {( Y- R
    //' |* Q' @# F' @7 I; p3 x3 i: `  J
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备% Y; m+ z1 v7 |% x+ o# P0 X
    // " W; f: c0 C2 N) P9 E  Y. g
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 6 m2 b1 U2 O( g7 `7 G

/ f2 ~: Q& q" L( M1 H$ s9 a2 D    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,2 V  z7 f8 j! C) _
                                        KeyDriverObject,
1 `3 _0 Y* ?: C+ V7 ~8 C0 b                                        &KeyDriver );: e. c% U7 s( S% z/ X& C7 C+ U0 \
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )( L% x" I5 G5 p, p0 i7 w4 c) w
    {+ Z$ {! ~/ T2 g$ X# l3 c
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
9 y. ^- V8 j7 \! U1 Y+ U" j      return STATUS_INSUFFICIENT_RESOURCES;
9 m! q/ y, M+ @' \2 R/ V0 e    }
% j" V/ {* l/ Z# j. S4 G% ~  }
2 W  T/ b) E9 N( ?. D; ~% f1 o6 j& Z
  //" u' B4 c6 A! N. s4 o
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
2 O1 x0 b( `4 r7 `' X# K- M1 O  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程1 y4 P( h0 [" s) ?( j
  //
$ U0 ?" `" F$ `/ F& \/ J  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 3 |- i- A4 y" C7 H9 p; H; K
+ P0 n( k! c; e' K3 j' B
  return STATUS_SUCCESS;
0 t' c, U1 b' E5 o/ z& U} 8 z/ K0 }7 D' H: M4 C& J. m  ?6 V7 O
$ L5 j1 C# o# ^/ ^% \+ |
/////////////////////////////////////////////////////////////////, H1 ^, i7 {; L  Q7 X
// 函数类型 : 系统函数5 ^+ |1 Y" S. c& Q8 m& A8 @9 P/ j
// 函数模块 : 键盘过滤模块
& v) S& h; I9 E2 g  I2 K////////////////////////////////////////////////////////////////5 X/ \3 |" e* u
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,/ r/ {7 h! r$ o% m/ \; m+ B5 q' a
//        卸载键盘过滤驱动  w; i4 {6 m% A
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
' A1 _9 i' |9 s/ Q- w$ K3 N//        则需要等待用户按键,以后有待完善
' r8 _9 A5 ~0 A& p+ h4 k/////////////////////////////////////////////////////////////////' X) b7 Z3 X. G9 m
// 作者 : sinister
4 X* d; \+ L$ y// 发布版本 : 1.00.00
& }  ?3 K% g" C% k3 g// 发布日期 : 2005.12.279 w  B1 s/ k% Z; H' _
/////////////////////////////////////////////////////////////////
# ]1 S4 b0 Y6 b4 v0 q2 `0 {6 V  g// 重   大   修   改   历   史
) I  m% Z# b' @, ^  }///////////////////////////////////////////////////////////////// s  K7 C$ U8 k8 O  x
// 修改者 :
, ^* C5 U& S% D0 W" r+ M" r/ W$ j# ?. n// 修改日期 :
, h4 E. e5 q) x" \) z5 i' p9 e// 修改内容 :: z  K: V0 @4 e4 \1 T; b
/////////////////////////////////////////////////////////////////
' Q5 n1 y; Y* ^& x. B5 f
% G' N4 R: J( G: X5 z$ |VOID1 S, y$ y* ~% ^4 q+ H* ]  ?8 V
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
6 v1 z( x5 E. W/ T6 R{
8 y  f2 R- J' e( x( N  PDEVICE_OBJECT KeyFilterDevice ;        q$ {0 i: l% e# e
  PDEVICE_OBJECT KeyDevice ;
. I% o  y5 X! ~3 n  PDEVICE_EXTENSION KeyExtension;
# h- i# q; z3 F) K  PIRP Irp;
$ L8 ~4 l8 _! C( N  U% Q: v  NTSTATUS ntStatus;
; I6 k- h( Q" v$ P2 Z
$ b. L) F6 n: W% b! n- R) F1 v  KeyFilterDevice = KeyDriver->DeviceObject;
9 @( z3 ^! V; k' a% o/ @& a  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; 3 Z% }$ T7 l  K+ ?: ^8 f
  KeyDevice = KeyExtension->TargetDevice; 4 n) X- a" S3 X  z. R; p; U/ ?

  F' y1 J- l0 f9 M+ o  IoDetachDevice( KeyDevice );
8 [; `5 @/ y( n
/ U) ?* m6 a' w! n* j8 x  //- d4 e% t8 s3 n: p8 o5 u
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP* Z/ |; _3 R8 w' G/ n7 C' z% \- t; ~
  //
" X2 b) v  p- ]8 h3 y+ }  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL ); B! u7 t: H7 R. B
  {5 [; }# Z( i. F6 j: P+ P
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
3 ]" Y, R/ ~; ?* |2 p    {& F$ K1 N3 K; V) n! q( R4 e
      /// t3 J# v% [8 |7 ]4 X
      // 成功则直接退出删除键盘过滤设备  d) D, |3 W) P- r
      //! e" u7 J+ [; P9 l
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
" z' b. w$ V" m, {  h1 Q" Z1 C, ~      goto __End;
/ b. F/ `8 m6 }  x$ T! L+ c    }
$ }! Q- o/ N4 O  @1 \$ e  }
% H! m' k0 B: p5 X: y  l- O* Z' W) X3 y* a8 m& i' P9 }& e
  //
7 k' h. l2 I* W' w  // 如果取消失败,则一直等待按键- H* n- b5 w: P& {- m5 g1 J- P
  //5 z. X2 W/ l! c" ~% ~. V3 t* [
  while ( KeyExtension->IrpsInProgress > 0 )
3 |" C, p! l: Q  {
5 J  G" R7 T2 h    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );3 z  g! K* s6 ]" D3 @  y- k2 f
  }
5 h- V9 F3 c) j8 p" Y$ _/ I# W' ]! S/ K" l
  __End:
3 I+ t. N7 n+ J' N, O; F. n6 v  IoDeleteDevice( KeyFilterDevice ); 3 V& A; V  q% z4 P

- y% B& z) c. {1 c' i9 A  return ;" }& T/ H0 f, S" M/ _
} ( H# d+ t" U" |! Y7 z- j; p
9 D" G& h9 A' t& ^. Q4 Q
/////////////////////////////////////////////////////////////////
3 ?. }) Y+ K' I/ T1 L- x// 函数类型 : 自定义工具函数
5 _$ z" o( s: Y  ~! J' g// 函数模块 : 键盘过滤模块
5 z6 p2 w4 M# d/////////////////////////////////////////////////////////////////
8 z# W7 @4 f# M& Q2 b3 I// 功能 : 取消 IRP 操作
  r8 f/ j* [: @# T! H// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
& s; B( q" E; Z- \+ }, L3 e//        使用此方法来取消 IRP
7 q2 |7 {9 n. R/////////////////////////////////////////////////////////////////
7 A- i' B  s& f  @% i1 ~: U) A// 作者 : sinister
0 q( L" d* h! l: L3 J" `3 y5 ]// 发布版本 : 1.00.006 \/ C  F. A( J* a9 p( G- L
// 发布日期 : 2007.02.20
' o$ B5 @* K! P! L5 g+ X* {6 W" c/////////////////////////////////////////////////////////////////
+ E' W! b* O3 }# y// 重   大   修   改   历   史  A& i% Z( G) C8 B' L
/////////////////////////////////////////////////////////////////% M5 D$ O; C& H
// 修改者 :
2 D( N8 P7 F  i  e+ D: x// 修改日期 : ) V% i# t& l* |/ g, g
// 修改内容 : ' S  y5 j, y1 A9 u1 u" {
/////////////////////////////////////////////////////////////////2 `$ u9 Q9 I+ Z( l/ y

, W$ X7 M7 p& z. R9 u# O6 |3 ]! wBOOLEAN% k+ v2 @! U5 d
CancelKeyboardIrp( IN PIRP Irp )& ]# K3 Z: c- H. u8 D
{
5 J) V/ L) ~$ h$ `- h* O  if ( Irp == NULL )
$ `' d& L8 S" \5 n* r5 P- n7 W( T; v  {& l/ L( T- o" A3 Y( w2 h
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );3 |5 q  ~" s8 P: F9 a7 ?0 n8 I
    return FALSE;4 Z0 l9 T- F) @% n3 w, A
  }* l3 S2 H+ H; v/ V. ~
% ^" Q' y6 O# A2 t( v

/ m) C! w, ~1 y* A  k  //  ~) U. m! a9 b2 s7 y) s
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
2 u* b; a. q. T0 y  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。( J0 m  L0 ?( f( t
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占/ U. T- p& m1 E& X5 E
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
- j5 K6 g' u2 P: w9 N8 n  //* i6 j0 q4 a' e* D/ ~7 |

9 w& f, y, M, O4 t: z  //# j% o  S9 ^0 |+ z+ V: E
  // 如果正在取消或没有取消例程则直接返回 FALSE
9 C8 {3 J& \: n  //
- Q) ~: G* c. z1 L  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
( T& u9 S7 m, U% a  {
& J% ^9 E" Z" `9 b    DbgPrint( "Can't Cancel the irp\n" );: V; X; y3 q) C5 Z- Z
    return FALSE;
" c2 N5 \* G; X# m, i  }) |7 b* e  P' G4 j4 V7 _8 Z, D
! w* A- E8 H+ i7 @6 x! |
  if ( FALSE == IoCancelIrp( Irp ) )
4 U, ~- a. N  X4 z  {; M( C! @; r: W4 i
    DbgPrint( "IoCancelIrp() to failed\n" );; n3 a; }2 q3 \
    return FALSE;
+ t5 U! d5 x5 _, t  }: R7 R$ t2 J- b
- u7 Q& s- V* g" ^) ?5 H- ]' ^8 S. ^0 a
  //* v* R0 m+ A. t
  // 取消后重设此例程为空6 o1 T: e; v5 q% _: E! o' M* B( {
  //
+ K# M7 n3 L' b. x' i3 H  IoSetCancelRoutine( Irp, NULL );
. x# c3 l( s4 p, L9 Q
: z5 N3 w8 z) Y+ |) _  return TRUE;, v3 r$ \2 C/ _+ @1 K
}
& k$ A' q! Y; _) s$ j3 T0 \
# }% B, y# y% l/////////////////////////////////////////////////////////////////
4 e# t( h8 l4 ~; x: _+ p// 函数类型 : 自定义工具函数
, f1 x6 n3 S' H0 O// 函数模块 : 设备栈信息模块
& [. b, `1 O% V, E  O5 @7 v, o1 T# l/////////////////////////////////////////////////////////////////
4 t1 |6 E0 Z1 M0 R: B// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
8 }0 g( K3 C" _" d/ U$ P, h) o//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver), a. a8 l- e5 P( i
// 注意 :
" E& |$ I$ R& a, k6 @- K- U/////////////////////////////////////////////////////////////////4 K* l; i9 y$ N- F% L
// 作者 : sinister# Q* m+ c( y) T5 Q  j& S  A
// 发布版本 : 1.00.00
8 l$ Z- e- Q! \% M; h// 发布日期 : 2005.06.02) c$ }# @1 |0 r) p  _
/////////////////////////////////////////////////////////////////
6 m' H( ^# n$ g6 H2 n+ c// 重   大   修   改   历   史
+ R* |. U+ {8 @/////////////////////////////////////////////////////////////////
* h" A9 s1 y( P% T& M, S// 修改者 : sinister
# g: _0 H7 y3 y) x1 x: e// 修改日期 : 2007.2.12( Q" x7 S2 H( u( F
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
$ o4 n) V0 N7 Q2 p  a" W% I1 U) Z  Z/////////////////////////////////////////////////////////////////, ]9 z" \: v  s9 |! Q6 I# D

/ e9 E7 `2 ]  cBOOLEAN
4 W) {/ [  v2 j$ G2 {0 w- EGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
7 c3 j( C) u4 U! {, M{  a' V, I) y* i! c
  PDEVICE_OBJECT DeviceObject;* b$ }4 @! p1 G
  BOOLEAN bFound = FALSE;
* o6 f9 q" X0 l3 I, _3 s6 R0 F/ i$ O8 P
  if ( DevObj == NULL )
' X' H9 q3 R# a' K  {
/ U  y: P2 Z5 B3 n    DbgPrint( "DevObj is NULL!\n" );" k" S( z/ `5 F2 P6 Y2 i
    return FALSE;
, j6 m: n/ @2 x; \3 e* ]9 Z) e- w  }: A' z9 J( I* V! a

" L+ k5 u# I) `  DeviceObject = DevObj->AttachedDevice;
# W, l% V+ }; i) R& @6 b
  b" V5 o# i- e  while ( DeviceObject )" Y0 t$ N1 V: X, _. X
  {9 _8 M0 Y( h, m0 g! k" h5 [) ?; T
    //
* q0 e6 C# G. O8 U    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
5 x, x3 u9 f4 W2 F5 y    // 有一次足够了。这算是经验之谈
7 w" ]7 g" A7 \5 t( q" ]    //  g) s: o) k6 X
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )0 N* w& Q; U$ U2 l) w* n
    {
; P  O% ~; t) S. P( J4 s5 c+ I+ d      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",$ M/ K  R0 ~+ h. i7 {
                DeviceObject->DriverObject->DriverName.Buffer,
* M1 {  y3 u9 d3 D' l' r% s                DeviceObject->DriverObject,' J. \- q) Z+ b  l, c
                DeviceObject );
) `- m: T0 d8 ]) H* O! a
& ?7 W. p7 ^0 R+ U' I' x      //
1 {7 b- r7 S# I. V9 C  i      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了: {1 N: h' w) {: D# G0 O
      //  v' ?0 j; V, k6 h& A
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
6 C4 C; C4 p) [  V: R1 d0 c                      KDBDEVICENAME,
& A  s' j% e6 \1 i/ A- I                      wcslen( KDBDEVICENAME ) ) == 0 )
8 Q# P+ Z( C( G) `' Y      {
- i, v5 V- R/ Q9 r9 H        DbgPrint( "Found kbdhid Device\n" );' d& g: l3 ?' F8 `* h
        bFound = TRUE;
+ |0 |" O  u9 F8 Z* u4 l0 z+ a        break;
/ d! u/ K, G- D      }
5 k& D6 V- S! ~    }
  d% l( K, e. l# l: G1 K6 R! g: H6 A, Q% S0 [# C5 A
    DeviceObject = DeviceObject->AttachedDevice;
8 t, s* }, i: @, l& \: [, q7 I  }
% |9 E1 ?! G7 n( q3 J/ {. {( m9 d7 c7 Q- z" O" t! @2 J
  return bFound;
7 w, k  {# e3 J5 \1 I}
  }' Q+ l" X* N( z2 k+ }/ y3 D# O: q( f& A, ?
/////////////////////////////////////////////////////////////////# U& h0 R. g2 ]. k+ K! `" a% \  a
// 函数类型 : 自定义工具函数: ~/ Y$ O9 g$ f' {8 g
// 函数模块 : 设备栈信息模块+ r; R3 k1 `0 Q; u
/////////////////////////////////////////////////////////////////0 x# L2 v  C! {) j
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
$ P2 l0 z& T+ v: T// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改* w$ g- @4 S5 r9 u
/////////////////////////////////////////////////////////////////
9 F- v* u9 f6 P5 L) X8 M// 作者 : sinister3 R" r) p$ d& O: W) K8 `
// 发布版本 : 1.00.00& Q" ~0 f4 E7 w) K7 I6 g
// 发布日期 : 2006.05.02% x2 Y9 M. k6 R2 s5 R6 c
/////////////////////////////////////////////////////////////////, R+ I. X3 `) {. B/ w- U, {7 \4 F
// 重   大   修   改   历   史+ _" f0 j6 w; p) q+ O/ W4 B
/////////////////////////////////////////////////////////////////
4 S. N( {# m" b* Q' B0 d// 修改者 : sinister
" F1 A; H3 m0 B6 h7 w// 修改日期 : 2007.2.12& x: S' V/ W; e. }% E/ Y( M
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用+ ^5 ^1 x" [" J) ]: D) N+ I* ^
////////////////////////////////////////////////////////////////// z( u" x) x1 v4 T

, r5 }6 `% F. g5 @* F  q  l& kVOID
. U, y- h1 ~1 zGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
: e% c# m( }( _$ b, G7 ~{
, ?6 Z4 `6 U) {9 u0 K4 X- u  POBJECT_HEADER ObjectHeader;3 C. x; I' ^1 i9 I- \; i) j
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+ K; C: t1 N/ l+ S; n2 K. M+ u% p2 _- H3 U3 S( V
  if ( DevObj == NULL )$ Y3 ~* B2 H  U1 H# n8 l) [
  {& C1 c) {$ j- D
    DbgPrint( "DevObj is NULL!\n" );  L: G, U2 C% @# x. S1 P
    return;: e, p! L0 R5 P8 R/ n
  }
5 C' X9 _* }$ u/ s
, M: u) k& P4 Z) ~! [% W  r  //
+ |( N/ j( R  C$ z) q5 m$ m  // 得到对象头& B/ `4 G: g0 v/ I& I4 ~- z
  //4 G; U: j' A! O3 v; i
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );' B  F9 w, m  G  Q& d

4 ~" w8 \& {$ t* |( y9 l! }  if ( ObjectHeader ). h) z# T+ T0 y* c* A. O/ y
  {
6 t9 ]2 Q2 C5 Y3 _% j    //, Z; Y/ l9 f0 H) N( W, l6 a( ]
    // 查询设备名称并打印3 q+ n; t% @8 @, y
    //2 u+ q: ?7 V2 _, \1 {
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );3 ]2 j6 t) ~' h4 v. P
. k; I8 J$ r+ R- O* D
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer ), S! Y' f+ p  ?1 i: d; z; Y
    {. a3 h* C& G; r% u2 R. }
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
# d3 j* w3 ^( A( a                ObjectNameInfo->Name.Buffer,1 j5 N2 r! J& i. A, Z9 e0 C' W! i
                DevObj );
5 t. n; M6 s  l9 o0 ], ]& K" Z6 ]/ ~0 c5 p5 q& H$ P# X+ ?
      //0 Z, D/ Q: o8 }% ?/ q  z
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示# R/ c  W: Z6 K9 s, j: P, ~# |
      // 用,没有实际的功能用途( e# z5 A6 H: T' P9 Z1 H
      /// H# W4 T% k4 j- @4 B! a
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
' k6 r5 m/ w3 h- S0 R7 k# M& x1 I- [! w
      wcsncpy( szUsbDeviceName,2 T/ E, H# I1 u3 |; j" N: g8 L3 u
               ObjectNameInfo->Name.Buffer,4 Z0 i% u# I0 a
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );: {) v/ s+ ]* g  M( `, J1 e' ]$ C
    }' e2 ]2 {# v) ]5 I0 {0 f0 h+ P

" Z% F  ~& x& _$ Z! F1 \# h) d    //
; v. F7 ~4 U) Y    // 对于没有名称的设备,则打印 NULL
5 h, J# Z2 R; R; N2 C% o" J    //
: H6 ], \9 g4 ^8 j, `; R    else if ( DevObj->DriverObject )
+ a1 C  t' u) A    {
. a! }) p5 X$ m( ^      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
, x/ j% y8 v( D# J$ ~* t" ?* w) r* v                DevObj->DriverObject->DriverName.Buffer,
* F1 j$ R4 ~% u( V0 l                L"NULL",: U; @* y$ v3 \. o/ h8 X! M
                DevObj->DriverObject,
& I6 J/ ]8 P1 a$ `                DevObj );
" _; n) z- j9 x9 |$ w/ l    }
6 H& [$ f+ u! N! E! ]) i  }
5 }  y- G9 G1 s. ~6 @}
2 I4 X, k9 y( N+ F! d/ Z9 f8 x! e# E- q7 _
/////////////////////////////////////////////////////////////////% c" p- Z- S2 p( @
// 函数类型 : 自定义工具函数
  o* ^: G" ^- {; @/ q) g2 Y4 `. G// 函数模块 : 键盘过滤模块1 K+ {  a6 B) E* |1 C1 w2 N
/////////////////////////////////////////////////////////////////$ [) b8 p5 E' k0 v5 }
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
. S, S7 a) i/ E# e! C. ]//        对象,过滤出 USB 键盘设备,将其设备对象返回/ q& F; V9 v2 T: ~7 V6 }9 x
// 注意 :
7 |' S: U( K2 Z* [+ S, Y/////////////////////////////////////////////////////////////////
- h% s: K4 _* l$ e// 作者 : sinister% A3 D: E( J, V0 L. i* |
// 发布版本 : 1.00.00! [$ @8 _: h+ T# R% Z
// 发布日期 : 2007.02.13; c8 F# Q2 F6 A) v- W
/////////////////////////////////////////////////////////////////
" h1 w& J( o; }; ~4 c4 J// 重   大   修   改   历   史. W; g9 I, C0 n& x/ |) _8 ]
/////////////////////////////////////////////////////////////////7 M; s* ^3 h% [/ x# [
// 修改者 : 9 _0 R; y3 b# o# o* m: Y% M' T! q* d
// 修改日期 :
% J5 E! a, }% H// 修改内容 : # y# n; y* B* J, n, h
/////////////////////////////////////////////////////////////////
. F; `3 S% F9 I3 Q% B: z- o% p$ t3 l3 r/ @# }/ D. W2 y
NTSTATUS
6 v& D! v. c; b2 l+ l6 \GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )2 S6 P3 [+ b- l
{
6 N9 b6 e6 H& E. r( o0 `  UNICODE_STRING DriverName;- A9 u: Q& E/ Y
  PDRIVER_OBJECT DriverObject = NULL;3 g; A' I. _3 i. v1 \3 ^: a  i
  PDEVICE_OBJECT DeviceObject = NULL;
( [% e' s! n; Y+ u* S  BOOLEAN bFound = FALSE;( [5 ^' [1 [8 X4 I
" q8 p! ~9 _" z$ C, S$ l
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
. d1 j/ y8 f# j8 ~+ p+ T* `; \
! Z" i( {1 i/ N- W  ObReferenceObjectByName( &DriverName,
  O9 T! Y$ F3 e' N0 f9 k: t                           OBJ_CASE_INSENSITIVE,
; q1 _9 Q7 i4 N                           NULL,7 w/ C/ P0 ~2 L% \3 {  Q
                           0,
% e; r# |7 s$ T# |4 W* f  N& g: j                           ( POBJECT_TYPE ) IoDriverObjectType,
# X. T: e" d' f, s$ _) u9 {4 r4 {                           KernelMode,
6 x3 G2 w* S5 ]                           NULL,4 S) q0 t9 `7 y+ z0 \' [: V8 K6 T
                           &DriverObject );
2 o" v& H8 i& u1 K8 b& @6 A1 r6 q* W9 t8 h  M7 N
  if ( DriverObject == NULL )) Z0 o: g0 [$ J+ s" f5 A
  {! {+ R/ m; Q8 {. v- }* m9 T$ \+ q
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );" D- f# p: m& B4 u0 f- ]. N4 R% m: e, Z
    return STATUS_UNSUCCESSFUL;6 h% a4 n  S& Y/ m8 h' O; V
  }8 v6 W  G) A9 ?3 ]+ `. ^

4 r. P, o8 N0 p8 h: p  DeviceObject = DriverObject->DeviceObject;2 J; w. V( M& W( [6 S% n- O$ m
+ }) D! q! p4 k8 s& X* k7 {
  while ( DeviceObject )& G! ~5 \! k+ a
  {
  g, }( f  Q( |/ L1 f5 p    GetDeviceObjectInfo( DeviceObject );0 d6 ]% z/ c6 i7 B+ |

9 I; M4 @, S8 N9 B    if ( DeviceObject->AttachedDevice )
0 [1 X5 Y& ~6 O- N9 a    {( ]/ L3 k: a- u7 i- i/ t/ p
      //
8 o6 R4 [# ~5 E# N6 {      // 查找 USB 键盘设备, \) T: l' r' `7 _5 C9 E
      //
" ~& o0 d  S. b& S6 O/ ?      if ( GetAttachedDeviceInfo( DeviceObject ) )
' M& k5 x8 l9 \: \- L$ M# B/ i      {
# Z9 G3 [2 B. A        bFound = TRUE;' |2 {' x' O, U% s0 a+ h
        goto __End;7 I8 J' a/ L4 j% |. F: h
      }
, f. E% L( U$ j+ j2 b8 E" i    }2 r9 g* }/ A/ ]6 w0 m4 ]

; H$ [, d( f4 j( h    DeviceObject = DeviceObject->NextDevice;- z& ^) M# r, c  u$ z8 j( ?
  }1 Y( e; v, e, ?* e" i+ I

: @' s9 O  j# A1 f  __End:) t, G; \4 e2 t( _' R7 J5 H# Q

  R* |+ A' |/ J6 w( M1 V3 `% G  if ( bFound )
' {1 R7 Y0 k* @2 u( g8 L  {
4 p3 N0 Y9 c5 w4 ?& `    //
' l. Z  B) P0 {+ o( D    // 找到则返回 USB 键盘设备对象
7 F. R, j8 v  R: }8 c    //
6 P4 g3 i5 y# |2 f# i4 _    *UsbDeviceObject = DeviceObject;& C" Y) x  {2 G6 c
  }
1 @* B3 ^; W4 ?, Y0 ^* l  N' W  else  o% q, b. I0 a7 U$ H
  {) _" [3 w$ B' f& }0 A
    *UsbDeviceObject = NULL;) y+ q! F) F$ @- `5 n
  }  i# X' z% z# g4 @" ?0 A0 L, q
! Q9 N% B' j8 P) J7 {6 l' W
  return STATUS_SUCCESS;
6 t( r1 @1 ?1 R0 h$ y& `1 i6 X) k}
9 r2 X' U' L: Y' L$ K
: [% |7 x$ w1 X  K( {1 I) y- y! z/////////////////////////////////////////////////////////////////) j. H% K6 r7 t
// 函数类型 : 自定义工具函数) u9 y2 A* e% Q4 g) S& Q
// 函数模块 : 键盘过滤模块
5 F% i8 J3 ^0 ?2 b////////////////////////////////////////////////////////////////+ w4 B" h* G1 G( z2 O& X1 E  R. w
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关- i6 f( W) \! j! g6 }! Z
//        信息,返回附加后的驱动对象" F( d0 x- u) n1 |  p
// 注意 : 此函数仅挂接 USB 键盘设备7 Z% B3 o9 k! Z. k2 @1 `. ^
/////////////////////////////////////////////////////////////////* o2 x  [$ A5 ?/ I
// 作者 : sinister
* z, M3 h! E- F9 Z" D: g7 U// 发布版本 : 1.00.00
+ h" B+ W8 g5 g+ o- f, z* g3 a$ `// 发布日期 : 2005.12.27
, a# t; J8 \  }' s& J% A: C/////////////////////////////////////////////////////////////////8 X3 c1 d0 t' C) B$ Z
// 重   大   修   改   历   史
2 [( X: f8 W9 F; t- }) k8 _, {////////////////////////////////////////////////////////////////( X# h4 D5 F: s
// 修改者 :
+ o/ V8 k9 r' I1 o// 修改日期 :5 i; v  h5 M& P8 b% ^  M! H+ F
// 修改内容 :5 N$ @8 y0 v$ B: O! E4 u' L
/////////////////////////////////////////////////////////////////  c$ Q; A5 v% I6 A2 }* P
* \0 k1 O" u( q; a
NTSTATUS' \  l; C+ R# l8 h8 L
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
1 W1 q3 U0 k4 e3 O                         IN PDRIVER_OBJECT  DriverObject )( n! w/ @/ {! W2 q" a- b, I7 S  ]* t
{& Q9 A# D( C2 y' a
  PDEVICE_OBJECT DeviceObject; ) S* N1 m, o6 `9 ~3 L1 M) S- m
  PDEVICE_OBJECT TargetDevice; + l2 v% H! Q) `0 G9 {6 \
  PDEVICE_EXTENSION DevExt;
( M0 a  H7 p# K; r! m# k  NTSTATUS ntStatus;
; Z( M0 [4 j; u, y( i/ p/ s2 _0 u1 ]7 u) x
  //
6 k" N. E6 T( R7 s7 s  // 创建过滤设备对象
* a' E6 i3 ^4 c6 r& G  //' ]2 {; z- u# f6 n# A( y
  ntStatus = IoCreateDevice( DriverObject,8 m- f8 T) j! _! g$ t2 ?# d
                             sizeof( DEVICE_EXTENSION ),
# g/ t& ?/ W7 N3 A  T1 y0 h                             NULL,
9 |! |6 ^$ c+ w                             FILE_DEVICE_UNKNOWN,' Q* j  D) q1 K6 L$ R# x5 t
                             0,
! _7 w( C8 U" g. ?! _                             FALSE,
0 N4 \* w: x8 ^. ], `  m                             &DeviceObject );
; a+ S+ v9 u& V+ V" s  P
9 h6 T8 \0 T$ f9 c0 M  if ( !NT_SUCCESS( ntStatus ) )
3 c2 b# a% e# h5 [/ B) g  {
0 ^# H9 l0 K4 r) u" h9 G    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );4 A6 b# i( t2 U$ ?
    return ntStatus;" ], ?; w1 g  i: e
  } & t: C6 r  L; w  A% o
3 y9 H7 w" j' b2 f
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
1 g+ S; y( B0 D  v* j' T; f8 V$ l0 E) P: r
  //
4 R# @+ d  u( `& [2 S  // 初始化自旋锁
+ v7 L8 A4 F. M  //
3 Q8 i& K) v* v4 @* w% [- c- @( b  KeInitializeSpinLock( &DevExt->SpinLock );
8 k. s- J$ t# Q8 d: E, g; a* [9 p1 ^6 R# b; `* z& ~  Y% `
  //
( @( ~% {& m1 I2 ^( R  n, [  // 初始化 IRP 计数器
7 I5 |/ C  _9 {# `, ^  //2 z' R2 x7 u: d0 }7 x' T1 @' |
  DevExt->IrpsInProgress = 0;6 R8 ]7 f8 i1 |, f5 T" P' d' [. d3 k
8 ^1 ?! {6 W$ B
  //2 A: I" A" U5 V/ O0 O, d. ?" T! X4 U
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象7 c$ T# Y; n% M
  //6 F3 ?# w2 G6 @9 ~* b
2 u% \" A$ u* r8 ~
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
2 U2 u" i/ w3 s/ c6 p7 D  if ( !TargetDevice )% N3 a- a( P( e1 ^
  {
" ^9 T; R3 `2 I6 C6 o% F3 ~    IoDeleteDevice( DeviceObject ); . z6 j1 I+ |( a/ p3 Z
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
( {  D6 ~( T  S; e* N/ m6 V    return STATUS_INSUFFICIENT_RESOURCES;
: f2 {9 Y: Z6 [1 ]# m/ n; u! o: H, v  } 3 k1 q4 R2 A0 N* P* H8 c

8 G0 P  J5 o6 F  //
' _6 J$ @9 v  ~3 s3 V  // 保存过滤设备信息: j  w2 {$ a% J; P7 F
  //4 ]4 M8 I* X  ^! c6 M; c: _' v
  DevExt->DeviceObject = DeviceObject;
3 y, W3 Z) W" t( x6 a. u, A  DevExt->TargetDevice = TargetDevice;; s7 }6 f, g; J7 D2 o- R. d$ J

( L8 c& v: w& q  //
: Q! s. O8 i& N, o2 Y7 c  // 设置过滤设备相关信息与标志0 Z( o, W" h' d! e( b/ G& n
  //
( A5 f& d6 q8 e  a4 ]  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );" z3 ~( J' [! X+ n9 q) G( t
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
7 z& b/ d& L4 X# c( l' o
) J1 z9 {' f- y/ k4 ^. A, X# X: U" e( R0 d5 R
  return STATUS_SUCCESS;5 Y1 ?+ C( a1 q9 ~7 m. ]
}" k7 m: h; [9 r# K) c9 k
4 [2 Q; }- o6 r$ ^. `
/////////////////////////////////////////////////////////////////
9 T7 x- ~. i7 c2 ]7 v: }// 函数类型 : 自定义工具函数" d) L2 P6 }8 b
// 函数模块 : 键盘过滤模块# s% q; Z2 c" l% r% _. O- j
////////////////////////////////////////////////////////////////
4 j7 G2 H9 ~5 L5 T& V// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关2 t& ^5 X) r1 G1 L
//        信息,返回附加后的驱动对象5 I. B5 P! A& H3 `
// 注意 : 此函数仅挂接 PS/2 键盘设备
1 \* I4 S) o1 c) p" s+ P& \/////////////////////////////////////////////////////////////////$ _6 l( z' e' P9 R3 R# P
// 作者 : sinister7 \' g( L7 |6 j7 ?9 `/ U% a
// 发布版本 : 1.00.00- e7 [4 b5 l& \% N2 z
// 发布日期 : 2005.12.278 y0 j0 @7 ~; K; g3 R8 o: f
/////////////////////////////////////////////////////////////////
2 z8 y9 j3 i; X: j$ ]. H! L3 \// 重   大   修   改   历   史% v& Q+ x7 F: ]* m8 Y
////////////////////////////////////////////////////////////////
6 j2 N+ {0 b7 w% n: E1 }7 s% G// 修改者 :
% r; t. v/ r, e9 H8 {* S- o// 修改日期 :
+ T$ V$ S3 L" |- S// 修改内容 :& w' m$ P: n7 M. s: a# @
/////////////////////////////////////////////////////////////////
* E$ D: b% |' F+ Q% v4 x% J
; \% g4 B, f6 s: T! A# PNTSTATUS& Z- D' G$ u5 Y' v+ e0 R( d
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
' W7 l( v: q% S# s( x, m                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
3 _* s+ a6 y2 l                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
. ~/ K" @1 r2 d& h+ f+ [' _# ^{
7 u; j; p. v/ k' l1 O  PDEVICE_OBJECT DeviceObject;
: M( r' \8 |1 N( L7 ?) i  PDEVICE_OBJECT FilterDeviceObject;
, `* E% z" F0 b- X, o! g  PDEVICE_OBJECT TargetDevice;
4 v' @" N5 P4 A  PFILE_OBJECT FileObject; 5 P% d( d/ j: u0 P
  PDEVICE_EXTENSION DevExt;
( G6 D0 k9 W  C/ E$ }9 z# o2 r  ^/ E1 e0 ]$ m! G4 |
  NTSTATUS ntStatus; # Y' [; E5 ^. A. e

3 N- D2 X, y  M( U8 o) N! ~- e  //) ]7 w& z+ Z& W
  // 根据设备名称找到需要附加的设备对象8 H. M8 L# K8 V! ~7 W
  //  ?2 n: ^$ N$ {3 @7 M$ }$ V  f/ Y
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
, `8 p( Z9 g+ m! m. o+ t9 s                                       FILE_ALL_ACCESS,9 v* W& j& L$ N% c' M
                                       &FileObject,
( t" U4 a# H$ d1 t8 F9 r% C( s6 Y                                       &DeviceObject );
  e7 i1 a3 a8 p: }& p* L9 X1 x' d5 w: w# o& g
  if ( !NT_SUCCESS( ntStatus ) )- m3 Y' s* z# @
  {/ B/ s/ h  U, T3 R0 i
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );) K3 x" V- g0 B, Q
    return ntStatus;. u; U6 M! D  V9 E
  }
% ^- O0 d5 Q4 T+ H6 O; h
$ U+ W6 |6 Y* Y( Q5 b" E! v  //$ l  u3 ]* j8 R( B
  // 创建过滤设备对象
! g: Y7 @8 [2 V! \+ e+ b  //$ h0 J; m4 q* _9 M' {. {8 D
  ntStatus = IoCreateDevice( DriverObject,* n4 k. q3 y) l* g
                             sizeof( DEVICE_EXTENSION ),
' f( ?$ o' d2 J" e                             NULL,: p: w, i' d' e/ h
                             FILE_DEVICE_KEYBOARD,% W8 S- m" o" Q, K
                             0,
0 L1 ~9 `" o' t4 A                             FALSE,
% z. X, B* W6 U; w$ t                             &FilterDeviceObject ); ! Y. Q6 c' z- F( A" d1 `1 X$ _
( N3 B' ^' n8 F4 o: X
  if ( !NT_SUCCESS( ntStatus ) )) z9 n- P7 g4 U7 R) l
  {
4 Q1 e4 d, r2 e' A    ObDereferenceObject( FileObject );
6 P/ Z4 C/ Y6 ?' x    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
1 {2 M( d+ s1 i3 a: V0 u8 ?    return ntStatus;: x% ^- a: x; [. X
  } 7 p- X* i5 E4 X3 ^$ V* p) @

" R8 W' {8 C; A: N  //# J. }7 q: ]1 Y* t: o
  // 得到设备扩展结构,以便下面保存过滤设备信息! C6 y. e" a% Q% q6 [/ j1 F
  //
+ d& \" i2 T. a+ j3 }# H  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;9 ^7 F0 t0 S) N/ \
4 J% L0 V1 _) W8 c1 U
) ?7 u; R' Y8 Z3 G
  //4 S" A$ ^, \5 U, X2 [: H
  // 初始化自旋锁
$ e1 _) H$ w6 \# m& p* D; K; i  //# I1 M+ ?6 G& ^! W) U
  KeInitializeSpinLock( &DevExt->SpinLock );$ ^; |5 Z! d* ], N% y2 E& ~

4 g  }+ C7 S8 l1 t" \  //
* U3 o9 r( }; S  W2 ?  // 初始化 IRP 计数器
4 v" F! O. n( G9 v7 o' C2 Y7 o, u( e8 R  //
! ]. I7 ?! g1 ]: o  DevExt->IrpsInProgress = 0;4 z( |: v- W0 o8 h! a

" c  u3 R  f9 {" `: x  //- [4 O8 i3 B, z
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象/ v. E  ^$ l0 z7 t* c# v. |/ d
  //# S! u- N7 E& F0 }9 i3 E
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,* d! i( P1 E% ^' ]2 D
                                              DeviceObject ); - T" b5 J( h9 n. ~4 L. z* t
  if ( !TargetDevice ). ]! R( y( f. n5 X
  {
. j" r; q7 q& V0 r; H' z$ R    ObDereferenceObject( FileObject );
# _1 z  A( W3 Q6 d    IoDeleteDevice( FilterDeviceObject ); 7 a9 z. _4 i# R, c
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );& j0 |' u0 ~/ H/ ~& R6 T
    return STATUS_INSUFFICIENT_RESOURCES;$ R1 Q, c5 e/ X9 ~
  } 3 L; i! `5 _/ t' t2 m
6 S7 E6 ]+ Y6 \: r: g9 L' B* J
  //
% z3 o; ^2 Z0 R% m: T  // 保存过滤设备信息
* y: S5 ?+ |" U' F1 G5 F- I  //; b! Y- C, I! v9 x5 P
  DevExt->DeviceObject = FilterDeviceObject; 3 {  b* {' [5 C9 g
  DevExt->TargetDevice = TargetDevice;
2 k/ K! _% E% K: b: v  DevExt->pFilterFileObject = FileObject;6 S- ^0 w+ s& }, b- q

/ e; U8 @% k* Q5 m# o* A1 \; _  /// b: c+ e* e# Q; j( ^6 F
  // 设置过滤设备相关信息与标志# ]0 V5 a: o- Y# U
  //
8 Q8 j0 C2 a9 x( e3 d/ |  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
3 D3 k! V5 D- Q  W4 p/ z7 }3 h2 J  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; * ]6 A3 R& O' O) w* M! H
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;! {; |3 C, c! a" n
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
: `* f- q4 K0 z/ u$ x                                                         DO_BUFFERED_IO ) ); 8 E9 n  W9 y& k6 S
% f, k' D( ~! V$ o9 O8 u9 a
  //
2 i- l0 L, g6 J: P( k" S8 e0 C  // 返回附加后的驱动对象/ U( }9 |; `/ T. m
  //
" u* X$ S: C' R; x+ m  *FilterDriverObject = TargetDevice->DriverObject;
& E4 B8 M/ r8 @" K4 J- p2 e1 m2 R
  ObDereferenceObject( FileObject );
2 f0 a0 E# n- z) k7 M9 o; h1 `4 w6 e5 U& X, O3 x
  return STATUS_SUCCESS;
- l3 @8 @% b' Z7 N5 k}# P: _8 l9 y9 V" Q3 v

/ o/ |% Q8 a* m. f0 Z; D' Q  [/////////////////////////////////////////////////////////////////. \: f0 q/ s) F
// 函数类型 : 自定义工具函数
) x  t; b2 Y6 {0 u! H4 X8 u// 函数模块 : 键盘过滤模块
2 Z6 I; l' S1 T  l4 S/ u* D////////////////////////////////////////////////////////////////& f. f( r6 j; R% j1 c' y
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
6 ~9 L+ J: ]0 H: A//        这个 IRP 的完成
8 m5 s* v( N1 c$ Y$ B// 注意 : 3 p% j  V9 C& w0 J( [8 b; M% h& M
/////////////////////////////////////////////////////////////////: H5 \! Z9 t* H3 U; R* h. ]
// 作者 : sinister
) ]: N7 O9 n! B% Y// 发布版本 : 1.00.00% ]& X, A" t$ t5 s
// 发布日期 : 2007.2.15
- ?8 ?; w/ p# v# M7 f3 ]////////////////////////////////////////////////////////////////// F' Z+ @$ e$ `; |! ~2 w. W( |
// 重   大   修   改   历   史7 ~  ^( n) Z& r2 }' p% L6 @/ _! D
////////////////////////////////////////////////////////////////
" R9 v0 I" F" o4 S% g; S& J// 修改者 :
* T: ^; S, V5 k) D5 e// 修改日期 :+ W9 ~; P0 ^" o/ i9 l
// 修改内容 :
, {' T- `" v+ E/////////////////////////////////////////////////////////////////, V- X; f$ s, V6 O8 I$ H& }, q  g

0 h  w$ N- v9 a  BNTSTATUS! {- L5 F* `- s" m
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
" C6 K$ i- c$ a$ R4 T3 x{
0 R& F: l3 h# r8 r0 {  NTSTATUS status;
2 ~$ m& l% L3 T1 O  KIRQL IrqLevel;
& B/ `2 A9 v* c$ B- y; s( E: s, j) W+ i3 p! u6 G
  PDEVICE_OBJECT pDeviceObject;
7 a' h( b* [8 [  v4 ]. `% {* e! R  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
! M- G% P2 q2 x$ h2 ?. n                                   DeviceObject->DeviceExtension;
2 D4 j* Q8 a- b  H+ g6 s5 ]' l
6 \# Y( M/ B* Y+ o" Y) T# B- V( x" s" A, c1 I; G: I4 {
  IoCopyCurrentIrpStackLocationToNext( Irp );' B7 @1 Z4 X4 V' h5 z; X/ ^+ r

; Q0 Z8 y: y6 t8 E  //, S' ]/ V* \5 M3 ?- K
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁: }: c- c+ p' Q! K3 n
  //9 @; o3 L* G- u8 Q
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );+ s8 }2 G7 Z& W6 x( p
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
& i' ]2 V2 g1 c8 S7 n8 E6 B- Q" Q  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
+ X! u+ f" ?4 F* q9 [5 Z% h! w
9 `! J) i+ f: h. Z1 U  IoSetCompletionRoutine( Irp,6 t" h6 E+ m# k. H* p- W
                          KeyReadCompletion,. g8 F5 ^' y, {7 L
                          DeviceObject,; G9 ?$ V- k- F# C2 y+ y4 K; T
                          TRUE,; z5 H, q- @& S8 b8 S& h6 P
                          TRUE,8 L2 X' i4 H! v" _: ]
                          TRUE );
0 x) v1 {9 s; z: J( t; \+ o: p7 \/ L9 E. Y4 `0 e
  return IoCallDriver( KeyExtension->TargetDevice, Irp );& r* P# D3 i- b' q" j
} . k% \* S4 y. c0 M5 t
& a. z( l# v/ V- a9 E9 A
/////////////////////////////////////////////////////////////////
1 q( |2 r) @8 ~& V/ a" Q+ w// 函数类型 :系统回调函数% }) G& _$ O! T1 \$ X9 j' ^
// 函数模块 : 键盘过滤模块# A5 Q; E9 a6 q6 @5 J6 @5 f8 q( a
////////////////////////////////////////////////////////////////8 g6 F) {& B2 }) u
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的9 s5 ^( {- r+ X
// 注意 : 6 I$ L$ M. T; H# Q* ?  d. ~
/////////////////////////////////////////////////////////////////3 P3 l0 j) Y$ ]% {( b
// 作者 : sinister
" _+ {+ t9 L9 ~// 发布版本 : 1.00.00# R8 Q, q  y4 E; h( g
// 发布日期 : 2007.2.12; [% ~! p+ D' |
/////////////////////////////////////////////////////////////////# I1 v0 r* L, k! ~% k: f" K
// 重   大   修   改   历   史
# S5 X* q$ C2 A5 d5 T9 H////////////////////////////////////////////////////////////////$ w1 ]+ W+ _5 u+ H7 f
// 修改者 :* f" }% \; i9 ]1 s& C
// 修改日期 :
4 N8 n4 O2 a) H: W- t// 修改内容 :
7 \/ a# U2 ^5 Y% p6 A/////////////////////////////////////////////////////////////////
5 T+ K! `, T, D) C
8 x' K, l' j. x  VNTSTATUS, K7 n' p" S) {; [2 M  K
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
9 @  W3 ~) u$ J% q. ~                   IN PIRP Irp,2 z1 G' ]9 d3 p* |6 k: ?
                   IN PVOID Context )
# t. Z! h( v; l* X6 E# w5 Q{
6 n  L6 ~' M- S' W6 \2 D9 e1 Q0 t1 J( X  PIO_STACK_LOCATION IrpSp;
. T' {& l2 s4 p2 p' d/ c  PKEYBOARD_INPUT_DATA KeyData;
, A8 K8 Z, N9 H  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )% U" ^7 o1 A4 [+ [/ s  `0 e2 A& ]
                                   DeviceObject->DeviceExtension; 1 ?" @- A/ ^) D
  int numKeys, i;
' a! |5 Z6 O9 H; e  KIRQL IrqLevel;
+ n2 i, G& b+ Z1 a. Q
1 y& T( d! w& T0 J. ~7 H! q9 j7 u9 S  IrpSp = IoGetCurrentIrpStackLocation( Irp );
5 p2 `0 y$ x# R7 I# _& R( M/ f9 W% @# u* H4 z' t
! r0 f9 W, }5 M9 P/ L* X4 |1 U" V1 a
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )  s+ C* K# v5 D* U
  {
' `; J% Y0 G% ^. u/ }    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );' e9 y( o$ V$ t5 m) n
    goto __RoutineEnd;5 D8 w' t, }% l& _' X
  }
. w* g$ q& ?4 l3 d( D) W: U" X2 ?# w- g6 V9 B- x: e! J
  //  X6 O& M: I$ D! v8 y& i
  // 系统在 SystemBuffer 中保存按键信息
* H) U: a0 w7 B& p) |5 z7 P  //* F7 o! H. Q( t5 `+ ?6 \+ o8 D* Q
  KeyData = Irp->AssociatedIrp.SystemBuffer;
9 ]6 G, h4 P$ J& c  if ( KeyData == NULL )1 B% f% L' P  j; t! `$ h! ^' n
  {
/ y. u) j- e; n; I' c/ {( d    DbgPrint( "KeyData is NULL\n" );
& U% f; R$ G" B; Y+ Y; c    goto __RoutineEnd;2 }$ A6 I' {4 X" [; u
  }
7 J- ]8 j  M# P
/ Q2 D! h5 Y; a, E  //
- W8 T5 H9 ]1 w+ a9 j3 {8 t  // 得到按键数
! @" Z% B; N5 H/ O  //
1 k9 B& y. s6 [" k  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );8 |& D8 P/ V2 K0 J( u/ x
  if ( numKeys < 0 )0 E+ K& n* f2 M  c1 Q
  {
! w8 C4 ?4 Z. [8 x, h2 X+ t/ l    DbgPrint( "numKeys less zero\n" );- ~& q, o2 s- I4 B) S: D4 G
    goto __RoutineEnd;5 z: o* \, z5 Z2 o6 X! k9 l
  }; L7 u& f* B0 W
: @( d- P. |, E# G% @! {  k
  //
9 x- G* G) Y4 z: Z) H  // 使用 0 无效扫描码替换,屏蔽所有按键, B0 E. O# o( q  ^; J1 q6 d: j9 S
  //
! _) `+ u2 \$ K# x1 y4 ]' N  for ( i = 0; i < numKeys; i++ )
% R, l/ h  m/ a  {
$ X& ^9 G0 u8 i  x    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
3 [% d# N/ s- d( A; D7 |; m    KeyData[i].MakeCode = 0x00;" x( n6 Z5 w4 s% _; u0 K. E5 ?# K8 I
  }. u( S- N6 A" G0 [

0 d* q5 b4 A. u; r
( f5 {4 h$ S* K  __RoutineEnd : 0 L/ ^* r, x# H/ n- \

: ]# Z1 y7 m& c) A- g7 ?  if ( Irp->PendingReturned )
* O- n: K& Q  O* Z( a: ?  {
  D, a& t) [9 h: d. ]3 M6 e6 ^    IoMarkIrpPending( Irp );
% b8 Z. F. _$ a; Y5 I' \  }
: W7 `. h- e" b( Q, [/ u4 q1 V! h8 C# _7 A/ g. Y
  //
- w) L# {$ ?, |" h& @$ h( w  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁; a) U! [5 @. l; z- X+ W
  //
+ x" {! q$ ~% X  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );/ X" C" F; r, \7 \( W/ U  u
  InterlockedDecrement( &KeyExtension->IrpsInProgress );* e: Y  v, ]  ]0 X
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
6 V5 T3 \" P: O
3 Y- m+ [! Y% U& Z  return Irp->IoStatus.Status ;
$ S; _& y) O1 y2 o0 L} 7 G# e" b4 K" W# j4 W

' S* P! o; K8 ?: x( D. V
+ {; g/ p* i% F) s# @/*****************************************************************
& l4 {3 b4 n) }6 F5 w8 C2 a: J 文件名        : WssLockKey.h8 L1 [8 t8 ?0 F% }& w
描述          : 键盘过滤驱动
- I* ^% s8 p+ G3 C, v; o! \ 作者          : sinister
+ n- \+ n. Y" f! F6 _" F 最后修改日期  : 2007-02-26
1 X4 n/ \3 ]" _) r8 ]2 ^9 ]# D*****************************************************************/* X6 m* X7 L  p- [: R% f
- X$ F% X- V4 C/ E
#ifndef __WSS_LOCKKEY_H_
6 D( F' x6 g' f+ v5 V- G  N- T#define __WSS_LOCKKEY_H_
( E; }1 Q+ k* E$ q) R) g  G7 f+ ^! q- R( I6 U1 o: Q
#include "ntddk.h"
- [; m  Z) P9 Q8 K/ _' x#include "ntddkbd.h"
0 n" G1 l- }! T& X7 A: `#include "string.h"% s; |% b/ X2 ?! u6 m9 o1 \
#include
( x  \3 _9 H5 X0 [) H8 s
: e9 V. i2 b! n# L5 a! y" ?/ Z#define MAXLEN 256
; m6 S1 U6 s4 R- x5 |* O
) I6 Y7 y* @2 G/ {& W7 k#define KDBDEVICENAME L"\\Driver\\kbdhid"
4 `6 t: ~" V3 b6 R' D* z" _#define USBKEYBOARDNAME L"\\Driver\\hidusb"
5 l3 K/ n6 f3 ]2 N! _#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"% f9 m- {6 e& f- P: T

. Y6 P& b, F( g3 D5 dtypedef struct _OBJECT_CREATE_INFORMATION
& g- v* A% L/ `4 g! ~; M{
- x1 E9 Z( o( w2 O; G% o    ULONG Attributes;$ M6 p' @5 H9 K
    HANDLE RootDirectory;
9 M& _0 I- h9 y5 k* o, g' \    PVOID ParseContext;
8 V0 J- I- f! b, N/ C7 B. k    KPROCESSOR_MODE ProbeMode;% K# p$ B( ~( [) G% \( o6 |
    ULONG PagedPoolCharge;
* u  W) t8 W2 f7 B) \* U# ]    ULONG NonPagedPoolCharge;6 l" T! A2 z; y1 k( J
    ULONG SecurityDescriptorCharge;
7 d/ }! I8 _1 \& ^. E2 Q    PSECURITY_DESCRIPTOR SecurityDescriptor;! u2 w0 m7 ~) p
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
% J  s# @' N% X& u6 u    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
# W( D+ |5 P7 z7 r. p} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;# z3 Y9 M: G6 }  ]; Q3 T6 U4 g
& @' J2 B& l6 ^1 H
typedef struct _OBJECT_HEADER* ?8 f7 d4 ]7 T. X3 i' _$ p& O- a! {
{) ]  J$ u9 ~4 z' }4 M( k7 b
    LONG PointerCount;
. z' H0 r9 A! @' _6 g3 k5 s" A. C    union
6 P" l/ w5 H% E  M! b    {7 o1 g2 m8 X6 A
        LONG HandleCount;+ r7 S+ T. e1 d% P% o
        PSINGLE_LIST_ENTRY SEntry;
5 G+ T7 n1 a. ]: v. y    };
5 x, J- O0 ]( A2 Z0 O/ Q* T* P    POBJECT_TYPE Type;
1 A; b8 K% I3 I1 M0 P* U% R, j    UCHAR NameInfoOffset;0 M4 O' x: _! r7 Z" S2 g
    UCHAR HandleInfoOffset;
2 S( v) B* W. m8 {    UCHAR QuotaInfoOffset;/ e+ E! j& x2 g; x2 g1 o8 s5 z
    UCHAR Flags;8 r; d, L& R7 b+ ^; T6 e$ m- g
    union5 t" X& b6 ^, Y6 F4 ?# w  F" x
    {
6 E* ~" T5 z1 q0 d+ b4 r0 p2 G4 i        POBJECT_CREATE_INFORMATION ObjectCreateInfo;. |+ I. h7 H* F" N+ H3 R* X! _4 f
        PVOID QuotaBlockCharged;
( b' s6 K$ @6 ?  V/ E    };0 h1 L0 A) b9 h. R

3 b. P6 s9 D& g) M( @    PSECURITY_DESCRIPTOR SecurityDescriptor;& Q9 Q1 U  ~% c
    QUAD Body;
8 \$ ~% p2 z, O} OBJECT_HEADER, * POBJECT_HEADER;9 g+ J* b* d% ]' i% N% s! ?2 n- }
1 l$ ?0 {" l! x2 \1 |/ ^
#define NUMBER_HASH_BUCKETS 37
3 a1 G# w% h( h7 e
1 U+ K) V$ U' o! Etypedef struct _OBJECT_DIRECTORY
2 `9 ~% P  A( b{
) F2 N* _: s4 Z    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];, m% b' \8 {' l# g5 I) M4 H8 i
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
# k6 i* Q% Z& s. X9 N+ S* y    BOOLEAN LookupFound;' ]4 m8 E7 e$ s* h! \
    USHORT SymbolicLinkUsageCount;, L+ @& h7 d, J' F- X7 r( M
    struct _DEVICE_MAP* DeviceMap;6 E3 K  d0 z! V+ ^
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
- [( U% t' `/ v. P
. I% q  d: A+ S) C2 f( V- b2 Xtypedef struct _OBJECT_HEADER_NAME_INFO* v6 s5 }9 r$ b1 l  i
{9 L! X( U" Z) E- y& x
    POBJECT_DIRECTORY Directory;
% |0 h9 o1 Z* j% X    UNICODE_STRING Name;
9 X. I/ n& T/ o+ ]; y" Q. X    ULONG Reserved;
, v- I% o2 R7 ^* \1 i% A: M/ {, Y2 M#if DBG9 |7 {# d) i; x. G6 v0 n# W
    ULONG Reserved2 ;
; m- x5 {% v( i$ G  Y    LONG DbgDereferenceCount ;; p2 ^) y! `9 V$ `
#endif8 T3 z3 Q0 T6 M; V# D6 q
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;& B! i. L. Z% w, I' M/ E) d

) s- i; O3 S* T+ K#define OBJECT_TO_OBJECT_HEADER( o ) \
' X2 d& }5 A0 @* c. C" W) a    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
3 X4 m! ^8 s& @- c5 J) V$ b) M! J5 u: F4 J7 Y+ g
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \  u' [1 w/ D' c
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))2 d. [, ?7 b9 \+ w" Z9 H9 j
/ t# w/ J9 I$ U8 T4 _0 b* \( h
typedef struct _DEVICE_EXTENSION
" o# w/ ^* m6 j( B7 N8 F{
: z' H% u1 g/ r% ^    PDEVICE_OBJECT DeviceObject;
* E3 l3 U& b2 D$ G7 l' G, w    PDEVICE_OBJECT TargetDevice;
: e, C! v# r, Q7 w    PFILE_OBJECT pFilterFileObject;: |! p5 }! u! ^7 z2 h1 d' {/ J
    ULONG DeviceExtensionFlags;! {2 g' u/ [$ {/ P0 _6 p
    LONG IrpsInProgress;9 V3 X7 n/ x4 _# i7 j
    KSPIN_LOCK SpinLock;
8 B8 `6 B4 M2 l! H- F) e! }  B}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
6 n( Q) v( m. e# n# b  b* ~( M8 _* f, g& x7 p  R
" m' `0 Y* X. L, `
VOID
" N/ {" f6 S, D# X4 lKeyDriverUnload( PDRIVER_OBJECT KeyDriver );
5 h$ g) {$ ~) L2 s5 Q7 Q& [
2 a2 K) _( C0 H  O2 v) O9 T, ZBOOLEAN( x; d' _6 L9 }# |- d5 E
CancelKeyboardIrp( IN PIRP Irp );
2 q/ ^' V/ ?, @5 e2 b! `
$ g# a& F# ~( T& {- t5 j4 i$ zextern POBJECT_TYPE* IoDriverObjectType;9 `7 S/ }9 J; Z2 @6 J2 c% L; s# R4 U

+ P$ M; i" \1 [+ q6 K9 R- F" JNTSYSAPI
$ l" H, z0 m8 W! QNTSTATUS: B4 j& k* H- }7 k9 e3 n
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
& L; d1 I3 V" V* ^6 k                               IN ULONG Attributes,/ X' r8 C2 Y1 Y0 j2 W7 |  |
                               IN PACCESS_STATE AccessState OPTIONAL,
* y2 F3 _. C+ L- W4 e                               IN ACCESS_MASK DesiredAccess OPTIONAL,
5 T, ]) W  a3 i. Y9 a% D4 k                               IN POBJECT_TYPE ObjectType,
+ T' H( j- a: H) M( a6 K                               IN KPROCESSOR_MODE AccessMode,
- M. d8 _' y( u0 }! W9 U/ g                               IN OUT PVOID ParseContext OPTIONAL,: F' q% Y0 W4 K
                               OUT PVOID* Object );4 {. W! V$ L( A% o8 h% M

! X9 Q$ \; l5 `+ B' F/ t5 DNTSTATUS : m  C" [# o  i" Q
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
- R* t9 m% ]* n; \$ f- B2 e4 L* J2 E& |$ T9 I+ Y
BOOLEAN
0 V  ?% i( s/ Z% |3 oGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
% r. T6 J+ a; G9 _& {( }& E" k; v6 k+ L* G7 H. D: J' B
VOID : v! v; m! |, z# M
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
# G4 r$ P+ q  B9 F2 r
& h0 R1 Q8 Y! ]+ E1 bNTSTATUS
! z0 _- A. }4 T+ x! ^0 VAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,* z) P3 W/ c4 n
                                  IN PDRIVER_OBJECT  DriverObject );
9 c) B6 `5 y' i5 S
. h3 j. c$ a, fNTSTATUS 6 Y) J. T+ I0 H2 q) S9 Q$ M
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
2 ?& }0 r+ L; s0 `                                  IN PDRIVER_OBJECT  DriverObject,
: m2 U! E$ j8 ~/ u                                  OUT PDRIVER_OBJECT* FilterDriverObject );. }$ |% {& ]' W' E

4 S  Q. ?+ y' |, E9 t7 VNTSTATUS
; g( Y# w& P3 F/ R/ L5 xKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
* @; [2 k% X. X- w% W4 w6 h/ Q                            IN PIRP Irp,
# ^) e4 z) E5 M  F& v" ~5 h                            IN PVOID Context );4 {5 c' A8 T6 |
NTSTATUS 4 E0 O: q1 E' ?0 z
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );: ]7 v/ ~5 P4 s& A9 c; {# p
; V: h' x9 v( Y2 {; S9 V+ \
WCHAR szUsbDeviceName[MAXLEN];
2 x( E9 C  z; D. D1 v& l4 g9 N
2 g* m; Z( j0 w( A' D* b#endif
3 i1 \( x6 g/ O6 O" H8 N; E; ]: u  _: M* w/ O
8 y% T1 p* Q" {2 j7 V6 D' E' A0 K

/ a3 S1 N1 c! ?
2 s0 h9 m% N" p& w
; ]0 f) U0 e6 `% eWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
* t& x# w* r1 K5 p8 z+ |" l/ aWSS 主页:[url]http://www.whitecell.org/[/url] ' X/ }2 \4 H7 o7 f# a; F% t
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-9-10 15:03 , Processed in 1.828127 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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