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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
, k2 u$ k9 S  `' |) L1 }Email:   [email]sinister@whitecell.org[/email]6 a  p; S2 x* ]
Homepage:[url]http://www.whitecell.org[/url] ; ?. A- n3 F6 R! z! L7 |) Y
Date:    2007-02-264 k. N* |0 T- Z' V3 x! X, Q
8 ]1 P; B3 t+ {3 ^6 Y. ]# P: m
0 A% G# }+ D7 u9 ?3 I8 ~, E( B
/*******************************************************************
- }* P, ^% V3 k  V  `* C  O: W6 h6 q% f/ L
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx4 B$ d2 Y& I/ U1 B# E
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
1 f4 d# Q5 Y7 R" g功能要求如下:! r/ V0 Q/ Q8 [# y

( I, O* d% T9 b1 d1、强制锁定键盘/鼠标。) e( O4 N) v) q# @9 d
2、可动态加/解锁
$ t6 o! H7 z! `3 M3、兼容所有 NT 系列的操作系统。
. p$ }$ p& b6 h0 U' ^
+ B( C5 L; W8 @; ]! C) r9 [8 x0 O就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
3 d# _' C8 i$ |* K/ {  Z5 c现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如( t9 \! ]7 K) o" C1 s: W5 q
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在7 f9 q3 F3 I  T
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是% {3 h+ ^  f, t4 A  F4 }4 Q5 ~
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
( z6 v) a0 g5 u* e: @就来看一下我想到的几种实现方法:( Y- e, _$ p8 ?, c. s7 z/ z" m
& F) a' n' `) c+ E$ o. \1 F/ u- S
1、全局键盘/鼠标钩子& i) F# R: `1 H5 \: Q$ j' F! H
2、BlockInput() API- g# O7 w' C* A" s  y2 w2 i
3、使用 setupapi 进行控制* H% e4 @  O0 o7 j  d
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL" [4 [4 \9 h3 l) @8 j
5、拦截 win23k!RawInputThread() 函数
6 }7 G# F1 c4 q( w- U' |6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
  r$ _- A* \; p7、拦截 kdbclass 驱动的 driver dispatch routine
3 \, B1 T8 j2 b# j9 U8、实现一个 PS/2 与 USB 键盘过滤驱动
* v1 x% F3 X* t6 P! c8 t* K5 S" n, Z, M+ ?
$ Q' O6 k: [9 H0 F3 O% n
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑+ z% D# U& K3 k  E/ _
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( X1 o% r& d3 T- g6 w
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
3 r) G) R5 o- A兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因; `% W2 V0 u$ ?" z, c! e' I+ }
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
) X/ c8 ^6 Q4 x: x问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
# V# Z) `1 ?, N3 N" {5 t载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我. E. `1 Q0 i3 _3 D- F
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来8 W. l; L: |% w1 A. [( O$ O
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
' a% c& ~5 S* c& B; c8 j果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有  R4 [: g" J. l: h- w; i4 F- W
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截* j# O2 X( A. J* b
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
5 Q$ O7 o, |+ {2 GUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键; D) C" \; n+ b+ a# [7 M; l2 D$ H
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
! W. `1 m" k4 s2 C9 z% ~7 }( n案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
* y+ B' U7 a( r- e* b4 g' k% B2 Y- _* T, N2 R" n

3 Z" d0 I8 x# `5 m我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
. ~, D2 o% k3 ], j: m! Z滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进7 f0 R% j8 X6 @1 g
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是3 g% @. ~' H0 @* t8 d  n
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越; Y+ b3 ?; ^9 l: H% L) I
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从- l5 ]6 `1 Z! T$ y: y1 M) ]  L
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
. A# c5 _' Y! b0 z1 x; t" L& @0 N键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
) e2 [( T+ i8 _IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败," s1 |! X+ c9 ?2 Q, [! ^# N
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
0 A7 @$ Z, J0 |( m1 e就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的: P; ^. [. p' S. ^$ v6 N
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使3 n0 G2 q! X( z
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
! k. V' N2 }6 }" b9 }0 o8 W! V4 w过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
0 E" O. m2 j: ?* i' t" s# n" z屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
( X3 n6 K* o9 Z% d过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb/ h; u# }1 C& ^+ V# D: U1 v
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
& O. G+ }2 N9 p) }- w/ r# o4 h- q的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意! [% s4 e  z3 I/ y) L
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
1 o( s# ]( N: ~3 u6 V经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
6 a0 K9 T# i- e来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利7 W6 F/ j8 a7 @' b. z6 [6 ~* Z+ s) h
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo7 N! p+ I% g- t* b* e
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致! Y( v/ Y! L& n2 r! t# {1 d( X
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,! o- i, r1 v) ?  W. `% s
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程/ A; d1 _2 `9 l  d- v% Q
见下面代码。
* u" C0 W2 z. y+ p. W& K; \7 ~9 h% q; n; R0 [
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程! n( {5 x* P9 x! V- D+ v5 j  H8 W
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键$ E% A* D; p: M9 e; x8 o" F0 [
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
+ y, l1 w! E( J, x4 |3 I/ e6 i上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有9 U" Z% \( }- G" U% A2 a0 n
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
- e- q, s) x9 E7 i继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个' M! D7 f* D- V  g" A! i! ~1 j, ]9 J( v
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
: `2 G- D- A/ g8 M键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
* o* O2 ?1 e* X
1 R' i% P+ m; o; p5 l/ S1 v1 b. L4 t3 Z8 C. E
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
9 J4 U" z: m( Z3 H  {8 T: i的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是' J) X! }$ D- D3 \
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
, ?: v1 e7 K5 b9 _) X: M的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
  w. {) a4 [. u) |/ I$ H% ?5 G们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我0 r/ A5 f& u! R
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension& O0 \! ^; h3 F
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。/ |1 N# q  H! k! H1 {) k  D% d/ a# I
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager, e0 y5 D( g6 `% C+ U# l4 L
进行操作了。这个问题有待大家来完善了。$ o3 X1 @' H, \* m& F9 k5 V/ ?( i9 I

, Q/ _, y/ l" s* q
+ t% u1 I: L9 M6 Y* @要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
1 ^- q6 ~' B8 R/ Y来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的$ N: N" A& ?8 z
分析做个记录而已。我更愿意把它看做是一段注释。8 N7 [, Q" D" R- w8 X' y

6 V, y  N( H* \: N, u5 U8 |最后在此代码中要
; N. S+ T& h$ @7 E  J' p7 y& ]3 M. F+ k2 c& ^% v* a
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。$ }; q  |( K0 B/ N

9 }+ y9 J; b3 O; l6 {( y感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
& N5 B8 Y/ G: s6 j* J5 f( S$ T& C# X) a5 ~) z
感谢:齐佳佳,过节请我吃好吃的。
* c( @0 P0 V. J5 m) t' r; ]. ?5 r) E4 H/ x+ u3 _

; Z! t; P! w* w- E******************************************************************/
' i) K& x1 E' H# I- f  i# [# C' f  ^3 e
' F1 p. ~2 l! `5 Y, o) {% a
/*****************************************************************
0 f! ?- j$ ?1 M( a3 u$ D# H) N 文件名        : WssLockKey.c
: R5 s/ l8 E- \2 K* Y 描述          : 键盘过滤驱动5 G  A8 K# {8 q+ R5 i: @
作者          : sinister- y% H% ?% V# u( H! t" J& q
最后修改日期  : 2007-02-26* x- f. x4 H4 U7 L
*****************************************************************/6 i9 W- d/ p7 s+ s& w5 K, U: F3 W
* U7 s( ^9 |; W
2 W  B( S. q2 b5 c3 ?2 c
#include "WssLockKey.h"
, ^6 a* d$ U- y2 _. n1 G4 |& T: Z+ [6 A! |  T' w. f
NTSTATUS/ v+ U( p$ D1 _% z8 s6 _( l! ?- f/ G
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
6 C$ y! y, O6 Q             IN PUNICODE_STRING RegistryPath )
4 n  _+ |( N  L& [7 R5 g{4 E/ K7 x/ A: K+ r
  UNICODE_STRING KeyDeviceName; $ x; X+ F$ z5 B: t' d
  PDRIVER_OBJECT KeyDriver; 1 `/ w# a' h/ l9 K2 c' Q
  PDEVICE_OBJECT UsbDeviceObject;- G2 j, d2 T. w
  NTSTATUS ntStatus;
( R: m& }1 `* _% C( [  ULONG i; 5 F8 Z! d3 u, P, u

7 N0 R; G4 l/ v# J5 ]4 z, t) P! c7 U  //
( |9 W1 P, Y2 N4 t5 r# H8 S  // 保存设备名,调试使用
0 U: x, I, G9 ~7 E# @# B  //
# `3 y! _5 n$ }& A. P' ]  d  WCHAR szDeviceName[MAXLEN + MAXLEN] =
5 q' R) D) E6 Z9 P9 T* d8 B  {
2 w+ }4 s8 B9 X5 }$ a    0' Y+ W8 B4 k; N1 ?
  };
3 K6 r% y0 Q' M+ M3 J3 d& e1 V% _/ G# v1 y( V( H. T4 F
  KeyDriverObject->DriverUnload = KeyDriverUnload; 3 a1 Y3 T/ J$ \* z$ W6 P9 V

" |' l: ]6 ^% j( i6 N8 _  //" C' K9 Y7 s0 g) ^: E
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘, F# D6 @& n& u" A& S
  //
- }2 a$ b1 x' z* M' ^  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
) z. ?3 D( `* A, F0 y- a; U  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其; u/ ^+ ^, J& A, _
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到9 t6 G( o! |7 i! s" E, C
  // USB 键盘设备来进行挂接4 @2 A( k$ X6 F" h9 T
  //
/ M# C2 _  U0 R$ L( g& ~+ g0 V  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );9 ?6 [5 P* z/ |* A
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
& B: l$ Q0 ^+ I  {
/ ^8 }! D2 V- Z' E/ ]    //
+ O1 |# ~; Z' ^2 l' M    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
# w1 ?' k# m5 ^. ?# u  j+ A    // 所以这里打印为空) c' c% Z- ^' l: z' A( y( U( V
    //2 f1 A: k# ]. w2 ]
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD; H! Q1 L  a# c8 |
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );" N2 j+ w# Q0 x' ~

& x2 a: W! w$ K1 `    //7 j( x6 l" c/ j1 i# y
    // 挂接 USB 键盘设备) y7 _, ?! {7 G% c  k  R7 \0 x
    //7 g. N: @: K  C; c" [
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
$ R" r! _# j) v  a/ ?    if ( !NT_SUCCESS( ntStatus ) )) t& n) I- Z% x# h& N" Z
    {
. X- k- Z) p- {! @& c$ H" D      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
3 W* X4 u6 y. P0 Z      return STATUS_INSUFFICIENT_RESOURCES;( X1 a8 o! p  Y( J4 a0 x
    }
* W1 r; Q( ?3 R$ Y1 T% e6 L5 J  }
" u9 f$ h1 @5 z5 w7 R! h7 J  else5 X4 B  R1 X2 D1 `- A
  {
7 X1 k$ D9 g: @: S* {* l/ x    //
/ x7 _1 {$ O6 T7 ~, _- ]% F2 w& j' d    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
# P2 ?6 s: a$ ]6 J7 j    // # ?) Z  b0 x" F6 Q0 M+ o
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
. g8 L: l8 a4 J. y; O3 Y! m. f% ^( ?; \( @2 J* e- S) G
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,3 p+ T. m+ {2 g: N
                                        KeyDriverObject,3 T% m/ H2 a9 `6 Z" m% q2 g
                                        &KeyDriver );
& y5 W- w: I9 t7 X3 t    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )7 ~# b& \; G: e, S" d3 ~
    {
9 |/ [7 g, C  U, }      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );2 ~# T  d8 U1 A: w
      return STATUS_INSUFFICIENT_RESOURCES;
$ E( t8 c3 Z' B/ e    }
+ i; Q9 c; l. H  }
* [. q6 U  ?4 r9 W# f1 j( j- E; Y6 j& T& ^+ p/ E" W
  //
. Q4 A2 {5 z3 |& _8 k  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
0 B2 [! l5 }" R/ x% p' b; s' C2 S  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
+ p( w/ r% G- J# i+ v3 R, m7 h  //9 J! v6 J6 ~5 A
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
! c" s+ i7 r( V9 J, ^
' t% d  }# i: F/ v% Q  return STATUS_SUCCESS;6 ~' c0 G, P# {+ [
} : v9 N% k; p" ~# T; i6 Z/ o

, P' d4 }  J+ x% L* [/ B7 n) b# {/////////////////////////////////////////////////////////////////
9 T' ^5 }* t7 |6 {3 m& l: G2 e// 函数类型 : 系统函数
! h. Q: x/ ]( ]+ N: c// 函数模块 : 键盘过滤模块4 \+ j% h+ g0 N# a6 g9 d+ ?
////////////////////////////////////////////////////////////////
  {' X; J( C1 O5 w// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,- V; y; M) ~4 t
//        卸载键盘过滤驱动$ x8 t7 D( B' n& p- D
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
5 P$ l+ ~; V3 h' R# y; q//        则需要等待用户按键,以后有待完善; f8 `# ~: P/ N* z
/////////////////////////////////////////////////////////////////
; p" P2 R0 h4 t% k3 I) I+ W5 V// 作者 : sinister
0 m2 o7 q$ R, E# |+ E  u, X// 发布版本 : 1.00.00; d1 V, [; {: Z7 O# L! R9 g" c
// 发布日期 : 2005.12.27
2 y4 _# x$ }4 f/////////////////////////////////////////////////////////////////
* Z9 x+ |4 E! v* q5 c7 V# m// 重   大   修   改   历   史
2 H7 c# U/ i: F0 \////////////////////////////////////////////////////////////////
0 ~# E8 R4 ]$ n; g// 修改者 :  `. w5 x& y& F4 }/ B
// 修改日期 :2 B. F' X) X; t2 i
// 修改内容 :
: k, Z% h+ l9 H6 }4 T8 F( A" @4 [/////////////////////////////////////////////////////////////////  i. w3 p) j: S* X

9 T( X( a2 M3 C2 a( s8 y0 jVOID$ l* `3 t1 G) G$ y" x# n
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
2 H) L- ?$ {0 ]8 r$ Z( M{3 H8 L! o& m& |, R- T
  PDEVICE_OBJECT KeyFilterDevice ;      
9 Z# y* j( C6 {2 @- x- k  PDEVICE_OBJECT KeyDevice ;
; C9 h+ E3 r; u/ W( w- v! W  PDEVICE_EXTENSION KeyExtension;
- ], d! m* U' {  PIRP Irp;) b- J, n+ t3 U1 n/ x! {
  NTSTATUS ntStatus;
+ S5 l9 G4 A4 F8 }( K1 J# ~/ ]
1 T0 u$ q; d" \  KeyFilterDevice = KeyDriver->DeviceObject; " _3 Q+ t9 I% e0 B
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
" S8 o. h! g; q, D8 C% o  KeyDevice = KeyExtension->TargetDevice; * r* B5 B8 N0 m9 s
' f4 F9 j/ O- R! L
  IoDetachDevice( KeyDevice );
! q# v/ O5 X& ^( t9 J# D8 [( j6 j
  //
; q$ \* p# A$ B! w5 j  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP5 E/ u0 \5 x5 t+ j* [! c
  //
4 ^, `3 \3 }) I2 E2 j9 q$ J. \3 [4 {" C  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )! q, c5 U2 f' R
  {0 O( E) V2 z  l# \: X4 I6 D4 b: M" R
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) ), K/ q  _  m) f- M) e' l
    {
  J* {2 D2 E! j1 [: r* M4 l1 x6 s% V      //8 J* J) ~* b- }) l4 S# b4 N1 F
      // 成功则直接退出删除键盘过滤设备2 U2 [% B# B8 n
      //
- q, K6 E5 \% j9 W5 M4 B( y; q" k      DbgPrint( "CancelKeyboardIrp() is ok\n" );) q* u0 ^6 y4 f4 u& b
      goto __End;
7 {# n$ v) X6 J4 ~    }) A1 e  G% o" P6 e: W- _! }; P
  }
  e0 V. F% x# Q  n7 v" _0 i
2 [1 `$ E2 s1 @5 z- w+ d& }  //
4 J5 n- I% U" C' O' n7 P  // 如果取消失败,则一直等待按键
* a: n3 P$ g& V4 P  //) g3 X2 |3 v4 b4 R
  while ( KeyExtension->IrpsInProgress > 0 )' T& E9 J- Y, C6 Q- t
  {
5 A; \$ l2 t/ e    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
9 l. w2 ?4 v* E9 S2 N1 O" T  }
1 e' G7 o# G. r; s0 I* V+ V# F$ ]7 r; |# f
  __End:/ }; H% @5 X4 x0 P
  IoDeleteDevice( KeyFilterDevice );
/ K% E  [, d) G" @( ?( V1 Q$ ?5 R2 P, ]% ~7 I/ Y2 @. a) W1 {
  return ;
- B% A' f9 N: S& f. j$ z}
- U- h* t! Y0 |5 ?  ?" }# b0 ~. Z" n4 [, K6 T# M5 s; f
/////////////////////////////////////////////////////////////////
& n5 M/ v) S. k7 Y( T. h// 函数类型 : 自定义工具函数7 C6 [2 w9 b* k) H! l
// 函数模块 : 键盘过滤模块" Z" @; }+ v- b& |  l
/////////////////////////////////////////////////////////////////) O! t' s& Y9 c# U% ~1 o; ~) t8 M
// 功能 : 取消 IRP 操作" |( N! f/ _* r1 Z
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
2 H/ l0 y* e: k. p3 j//        使用此方法来取消 IRP" M6 `2 K% O& f& b; o
/////////////////////////////////////////////////////////////////. z* |$ j0 S# A6 d8 V
// 作者 : sinister* A' c$ f8 h9 z- n7 K$ r& B
// 发布版本 : 1.00.00+ Y  \: a# K* O! d6 ~. g! D5 J
// 发布日期 : 2007.02.20
7 R0 J# x2 s: i6 f/////////////////////////////////////////////////////////////////
# I  H( K, ^, W8 T" }! D' F// 重   大   修   改   历   史2 S( s2 k' T! H7 C
/////////////////////////////////////////////////////////////////* F. Z% ?( k$ h2 P: {$ `2 B
// 修改者 :
! T2 J" [9 d5 B' E1 s3 M// 修改日期 :
! s" T; i& C+ ]// 修改内容 : : M1 \% s: B8 w2 l  U* Q
/////////////////////////////////////////////////////////////////) E' m! c# W/ m# [' t! }

  r7 `2 T5 f2 ]3 x3 `- n& y" FBOOLEAN: F. o5 W: }3 \0 J! c& ]
CancelKeyboardIrp( IN PIRP Irp )
% G1 I0 X( `1 G{9 u' r4 k+ h& S3 J; N, \" b
  if ( Irp == NULL )
3 _$ @; Z7 l+ _, M, W) `& r  {
7 }* Z  S+ t. M; d" i9 U    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
- P1 w2 l- M7 g# j, I( @! ~    return FALSE;0 N% d" L/ @( M) D
  }7 p* s3 W8 }& A4 j* _

" o" ?; O; W) f  ]. l2 p2 [: d
9 t4 w) v1 i  J9 u( R! M2 ?: N  //
% U% `$ ?9 x  X" `0 ^, T  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,2 w, g$ c! s2 D) P; D# W
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。- }3 W( F0 e! Z& m% w
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
2 @* `8 \+ M2 M# u/ e4 C# [  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
, a" f$ T) Q0 f  //* S# C- o" p; e' `, b

$ z' ~0 a9 L, c) y/ Y+ T  /// ~) M$ v0 ~; u+ _# g4 g/ \
  // 如果正在取消或没有取消例程则直接返回 FALSE# P5 k' X. U) _! }! c; ^+ |
  //
- U/ @1 b& ?( j; U  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
7 b& i1 k: d  d8 u3 U- @4 i8 b  {
( W% l2 U: x& ^% {    DbgPrint( "Can't Cancel the irp\n" );
7 ?8 i% G! y8 M0 O7 m  C: s7 m  V& P    return FALSE;
4 P0 M  A( _* w  }9 n: z5 e( x# o% K  b" O5 N9 `

) v+ Z# r+ c7 d$ M2 R; s  if ( FALSE == IoCancelIrp( Irp ) )! z) @# Y  U% [0 G# K+ o) I
  {
  {5 H! g! e2 v1 A. [! L; @# i    DbgPrint( "IoCancelIrp() to failed\n" );
3 _8 g+ l  ^4 A$ [' ]3 P    return FALSE;
0 v- q1 q$ @6 x+ b% |' j+ A* c' O3 y  }
+ i% `, d- e  k! [7 M- {# i' V' P$ Z" }& t# I' I+ v; ?) M, M
  //
4 ^7 V4 f$ u3 a" e5 J/ h0 u  // 取消后重设此例程为空& d9 J; `$ u, s9 H/ D: ?0 H
  //& u$ ^5 X* [7 K
  IoSetCancelRoutine( Irp, NULL );
0 L$ b" G4 }) t5 b+ q
+ R( F8 s4 d9 I! Y  return TRUE;
; z! f- ]4 J  l1 c}$ N6 u- V$ k' z# j
9 h" j; q) g* D, E7 T! X7 ^
/////////////////////////////////////////////////////////////////
+ u' X) }1 C) U: P2 I2 J// 函数类型 : 自定义工具函数( @$ L+ N- `4 \) j5 W
// 函数模块 : 设备栈信息模块) a! d! N8 u1 D- E. R- L1 S* _  X2 T* T
/////////////////////////////////////////////////////////////////: d/ U/ o# e: I
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘7 ~1 Z  O5 |+ g6 H
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)( \. a5 @% ]4 d2 [  M
// 注意 :
8 ^, @3 p- H' m# P2 X) @/////////////////////////////////////////////////////////////////% I# S' l( L! |6 |' a
// 作者 : sinister
8 `5 a* K2 J# b# p% z9 r// 发布版本 : 1.00.00, C, E6 Q8 q! U2 t9 Z, Z9 A# u% \  O
// 发布日期 : 2005.06.02
7 `+ z) t. u9 B) ?& B9 x* _1 i: }/////////////////////////////////////////////////////////////////3 R; D8 y  @2 T- s+ i
// 重   大   修   改   历   史
% O$ j- Y% {: f# H) p. n5 L* J/////////////////////////////////////////////////////////////////
# B- k- A& u5 Y) w// 修改者 : sinister1 |; e9 g* r& ?) R& Y$ P
// 修改日期 : 2007.2.12) y- r. ]; h! {0 A7 E
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
" F. l: {& y& D3 ^2 l/////////////////////////////////////////////////////////////////
( H: I3 ^$ m# g* i$ Y0 \# n/ U
* s7 n& J0 F6 G) i, L( xBOOLEAN' ]2 x( P5 m* k
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )7 h& M- A( o& H* O+ Z. B
{
9 o' o! U  O, w' N! A" \  PDEVICE_OBJECT DeviceObject;) |3 p7 [( P5 y# H0 M8 d+ g
  BOOLEAN bFound = FALSE;7 K5 \2 U+ B; @: J: B
. i: a7 o4 v- ^7 x1 N
  if ( DevObj == NULL )
- P6 |. k2 m; L0 {  {/ h9 }- y" x: N" i) F5 y' N
    DbgPrint( "DevObj is NULL!\n" );
5 J: G! y+ i6 D, e0 ]    return FALSE;- l8 _. d% @' P& N
  }5 E" O" m/ h, b8 J

* G( x4 s6 J  _+ Y  DeviceObject = DevObj->AttachedDevice;: j4 A1 c8 k& P* z  c/ J2 g

* Q. @; ^2 Y3 K: [8 _6 ?- K4 ^% E  while ( DeviceObject )9 _# q% ^" Y# @3 ?" Z
  {' I3 i: X3 Q5 g  G$ o( C  u( l+ ?" B0 f
    //8 X3 F' p8 G! O( `
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
; l7 s+ h$ g% s  \; z4 n# I. `. R    // 有一次足够了。这算是经验之谈. Q) N& B; c( \3 S- z: G, v8 z7 ]
    //
5 j; j/ r3 Y5 L+ V/ i7 a" z$ e    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) ). S8 u" C' a1 N  a
    {
7 b! A6 I/ x' y- t# x      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
- r7 N9 F0 W' v0 b                DeviceObject->DriverObject->DriverName.Buffer,
9 @2 m# L/ Q4 ], p. u  u" H5 L; O' u                DeviceObject->DriverObject,. D' m+ A% V: W5 @! d3 {) U. o
                DeviceObject );8 e7 k8 y4 B* Q) R( ^

- Q& `3 ?# ?4 K% X4 S5 W; p      //4 t3 h1 ^7 B$ a* n5 U
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了- D8 P% m3 y( g, W" N. w
      //
7 e9 \% ]6 P1 S- c1 c+ X      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,) z6 ~8 {/ ^: l3 x+ P% Y
                      KDBDEVICENAME,
8 g7 Q/ v1 F( i& n) v3 l" I. c                      wcslen( KDBDEVICENAME ) ) == 0 )
& ~7 p6 F* d0 \2 F2 V      {
8 u9 E7 \& H2 T. U) W: i        DbgPrint( "Found kbdhid Device\n" );& l. l5 I) E: `' _' t
        bFound = TRUE;" e/ i4 A+ I* O+ i# t6 s# r
        break;6 m  O3 q! Z. ?) N
      }
+ y2 {, H: _9 d    }! b% b; b4 e: ~% p( o

$ h; Y6 a& X9 b/ s3 v* r# ~    DeviceObject = DeviceObject->AttachedDevice;: j: j) e, B" J9 c' I9 D. L* M8 K
  }* t9 ]% _0 B4 d4 ]5 m5 w

# F" b% o# H; H& W' d  return bFound;: g' J; l/ k: g/ o3 ]! R3 t
}! j/ b4 N; i/ h
: _2 s9 h/ T0 t. A7 v: ]! y
/////////////////////////////////////////////////////////////////
& z& t6 p/ M. ^! S' I# p// 函数类型 : 自定义工具函数: S) ^/ h6 ]" |" r# Y3 d& D
// 函数模块 : 设备栈信息模块) J8 s2 B* e$ [3 e$ {* D
/////////////////////////////////////////////////////////////////
: q% N/ l  ~4 W8 b1 N' W// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址  l4 L5 i3 F  g9 {
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改6 F& L0 d7 a* J
/////////////////////////////////////////////////////////////////
1 b/ |+ V( n* x! C// 作者 : sinister
- }( @- R. a% W( E5 k, q' z/ u// 发布版本 : 1.00.00
& U+ P: b8 y* h// 发布日期 : 2006.05.02
: q' m2 T) V/ e! T+ C# I/ t/////////////////////////////////////////////////////////////////6 j8 b) a" @8 E* }
// 重   大   修   改   历   史4 G3 _9 H* |5 A% e% ^
/////////////////////////////////////////////////////////////////
! [9 X7 T4 a) v  L- v// 修改者 : sinister
8 K4 N! n; a) C// 修改日期 : 2007.2.12
1 Q% _' s# k) ^5 J5 n3 v, p// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用- ~  C) D6 Q& Z7 I# Z1 N* E8 `4 }
////////////////////////////////////////////////////////////////// T9 C2 |! @. H; B6 Q
( y. c8 Y8 H5 f/ K4 @) G8 C% H0 w
VOID
7 e: u6 t# |9 B; A; y% HGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
$ r: R1 j) l: {6 w* y. S) o{
- b4 ?7 Y9 U- K( x+ H  POBJECT_HEADER ObjectHeader;
6 m2 m  F  a- j+ S9 ]7 m5 b  POBJECT_HEADER_NAME_INFO ObjectNameInfo; 8 Q* C, O# u& k; ~8 S
) E' B2 y/ b  N' a" U( h9 Z
  if ( DevObj == NULL )
# f0 s2 b; X# O2 f4 I+ h! I: g  {; B$ g" C- Z) W; n
    DbgPrint( "DevObj is NULL!\n" );* g1 x- G" \  n& o
    return;* S7 E9 v7 _  g7 O+ [
  }
& S6 }  v' D4 r# s' Z% ?: ^7 n! }2 l, J& ?
  //7 k& q. n9 I: Q( E0 R
  // 得到对象头" L0 U% N6 c9 T9 e4 a2 p
  //3 l7 k# a4 N) R* W6 a1 v
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
$ P+ N+ L, U; w7 [7 I
& O: c) l* i5 R3 g8 P! R# |  if ( ObjectHeader )
, |8 h9 k5 U5 E$ }2 v  {
& }( }, N6 G* T" V* l! Y    //
& C" g& {0 ?6 s    // 查询设备名称并打印
% \" l: e3 m# U+ D# F% R( {) Y( ~    //& ^! U' Q4 U6 @- [
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
$ m2 \6 ~6 @( J# D* }/ U( @. i
2 w. G3 z; w: Z1 a    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
4 M/ J' E* Q0 I6 J$ R2 ^    {
9 z; R6 y) P, \, m8 {  F      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
" y; z+ Q& t( a, R                ObjectNameInfo->Name.Buffer,
+ [! n+ y( Y( P                DevObj );
: b  j2 S: R) \7 w6 A/ @+ L# x
; K( `% G* Q  E# |' E2 _      //
# d! o5 E1 x, z# c% U( O      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示$ i" T/ e9 R# ]/ B
      // 用,没有实际的功能用途
: U) V) B( d+ |7 U6 v4 S, S      //
: i) M* i' j+ _  ]  h: m      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );0 v. F6 I5 W( U

  ]( R5 Q# f% v- h      wcsncpy( szUsbDeviceName,
* o, m4 N5 w' M& v+ E4 X               ObjectNameInfo->Name.Buffer,; H( ~0 U3 F: l- t% @
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );1 |1 \0 w- Y) U: E. m
    }$ g. W& O4 X& |9 {* H+ r

; @6 l: s) U0 R* C0 K    //
0 M! G+ \* K" W+ o. G4 Q9 J    // 对于没有名称的设备,则打印 NULL; L3 e: [" g3 w6 a; M, b# t* D
    //
8 N( |, R2 }: `    else if ( DevObj->DriverObject )" G7 q/ [  |. W4 o. @9 y* M
    {
( G7 g. \6 T+ }" s  N! b' D- L8 @. x# X      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
+ Z: |# y$ g: o$ y- ?8 A                DevObj->DriverObject->DriverName.Buffer,
. x& K6 r% `- T3 P* e                L"NULL",. A& {  R% H/ q+ r' D( |
                DevObj->DriverObject,
, E; S' k4 w3 [$ e" @+ F9 T                DevObj );
0 i6 C8 B1 v: V+ F    }( }6 w3 s5 i) m: k* {7 B& \! c) o
  }
0 d4 z+ W+ h; x5 d  u! E% l}' D5 d5 I# e3 [
# r/ [( b  d& j" q! {: Y
/////////////////////////////////////////////////////////////////3 N% f3 E: D9 d) L$ t
// 函数类型 : 自定义工具函数7 K3 v  o* T8 o" T
// 函数模块 : 键盘过滤模块
( n% L9 N: V3 N! W7 u, r/////////////////////////////////////////////////////////////////  A: A9 E0 w, d7 Q
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
( P2 X! `4 l. h3 p//        对象,过滤出 USB 键盘设备,将其设备对象返回9 H$ p7 z; T# e# N3 k. W' l$ x
// 注意 :
% }4 s: O& B* h. O5 ~/////////////////////////////////////////////////////////////////
! {  P( H5 B6 b6 R1 {// 作者 : sinister! z4 [0 |9 i7 w
// 发布版本 : 1.00.00. {3 a; h& |% L/ v6 Q( }2 c
// 发布日期 : 2007.02.13
0 N% _1 G1 a- M& f% _/////////////////////////////////////////////////////////////////
! s- K4 @. w9 m# R1 x, S2 j. D// 重   大   修   改   历   史
( O" x! ?& T6 D8 g: c/////////////////////////////////////////////////////////////////+ [* g0 A+ M; b
// 修改者 : ! @1 O& O  ~; w& v9 M$ u
// 修改日期 : * V, ?) c  Y) P
// 修改内容 :
; Z& G8 Z) I. J/////////////////////////////////////////////////////////////////
& {+ h8 Z5 \; y# n0 W% }' `$ }; R& r, l2 F' E* e$ N. W) [$ z7 z$ e
NTSTATUS# F0 A% c! K! H
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
9 w* [" Z6 A* X! y{. J) w- M: F( k- o7 l7 W3 o* x
  UNICODE_STRING DriverName;
1 I8 W& b; i1 K- _7 |5 k  PDRIVER_OBJECT DriverObject = NULL;
! ^& L+ k* _" j; o  PDEVICE_OBJECT DeviceObject = NULL;
2 I# |4 V# U3 y! O  BOOLEAN bFound = FALSE;! S/ N. f) F1 Q- y4 _, t

, `$ e* Z0 r8 j" R  x  v: D  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );& Q. \1 S: d/ T: Y& }

2 H# C1 ^& ]0 \2 \- s  ObReferenceObjectByName( &DriverName,5 a  z0 ^6 d+ C5 W% g
                           OBJ_CASE_INSENSITIVE,# a6 J1 v9 m, w* X9 }  O0 c
                           NULL," q7 y' G6 o7 s' p0 e  ]& D4 J
                           0,; q3 z* `1 j" L- c2 F/ C  A
                           ( POBJECT_TYPE ) IoDriverObjectType,# U8 ~2 Z- I4 ]! d- m" k$ m
                           KernelMode,
3 ~( V( {! O( `                           NULL,
( ?* h3 s6 R: l                           &DriverObject );# ^; S( s7 q! ?0 B( ^+ G& c4 s
- m* q0 |  T' c# c+ o$ x0 ?
  if ( DriverObject == NULL )
8 W7 R+ n4 z5 q" }& z; w6 V+ V  {, T% e9 `+ x8 L5 x9 o8 Y1 o! F7 b* M
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
4 T( g+ P1 l1 G% X0 I( X    return STATUS_UNSUCCESSFUL;
) h' T- v+ m  G" Z: D4 `5 s. ~  }  Y! X3 A8 V' [( L. g6 P3 A8 t
; _! e: A6 f7 a: F
  DeviceObject = DriverObject->DeviceObject;  h+ q2 P+ _% r
8 O4 M6 Z8 l4 w2 M6 i7 H5 A
  while ( DeviceObject )
9 F! K6 C6 J/ y. W- O4 \: v  {
8 t! \. t! X2 u, I' {$ t, i, w    GetDeviceObjectInfo( DeviceObject );
0 t* m2 A2 x+ e! M7 R+ G
) H  \# }% W( a  j0 l    if ( DeviceObject->AttachedDevice )
# v9 V2 ?: F! E& _+ X; H    {% X. u" \- B3 A0 \+ \9 B. n* ^
      //' U9 x* E0 y" {/ ?+ {3 V- p0 K
      // 查找 USB 键盘设备* W  ~% v% w6 J' s% C9 ?) j* v
      //& C( `- J3 F: {3 m) k* C1 T4 Y6 ]- D
      if ( GetAttachedDeviceInfo( DeviceObject ) )- ]8 n* e+ a) [6 x, m1 Q* d& p& x
      {9 V/ D4 [  F, l5 d
        bFound = TRUE;
( `( E3 Q& A) M0 y5 A* p. O2 X& ?        goto __End;
% G+ x8 G. m6 {      }. Q( S; C' x, v  g
    }
  {( A, i2 N' h5 f7 E/ T% H5 B
) Y/ m! s3 Q- I0 {% H) V    DeviceObject = DeviceObject->NextDevice;
% q: r: A+ C' j& q% y. n" X3 ~3 e  }
( M% o# r8 k# N7 G6 g  N! q. ?: G" g/ j- x5 ~2 E
  __End:
4 a" }* [; y( |2 _0 ~$ B2 ^% e. v, e9 o; o+ y2 l
  if ( bFound )+ v- q9 Z0 V, C, b) ]. \
  {
9 o& f5 V( p6 {/ V% W4 M    //
  m! W: D( x) |& a) D1 j+ Z: t    // 找到则返回 USB 键盘设备对象
8 p5 r  Z6 l4 [    //
2 N- P- n9 y+ e" O& u2 f    *UsbDeviceObject = DeviceObject;8 [6 d* E" |/ y$ B9 J1 S
  }2 N4 Y" q& F8 z( h- z
  else
2 q+ d# Q2 |3 e. L  {
- @+ F" \' I. `% [; c- j    *UsbDeviceObject = NULL;( r% y8 L; R  c% `. i) t: {* N' ?
  }9 ?+ N9 k& ~, s/ c* X0 `
! R* _6 j) \' h7 n" ^
  return STATUS_SUCCESS;
; W4 m- G4 h6 D8 @: T/ m, I}) p' a* {- ?: B; B; f, a' u
2 r( ]8 n  |9 d# N. F$ ?( E
/////////////////////////////////////////////////////////////////- E9 o1 z4 c7 l- g+ {4 n- b
// 函数类型 : 自定义工具函数
0 h1 K, [. ?! H/ E// 函数模块 : 键盘过滤模块. B/ u# P! c. D% n% k7 ]; }
////////////////////////////////////////////////////////////////1 a3 U6 c7 m  `
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关( O- }3 p3 ]4 u4 w7 S
//        信息,返回附加后的驱动对象
% T5 y1 |2 k/ P3 b// 注意 : 此函数仅挂接 USB 键盘设备7 ?1 Q" A% G/ z( b% P
/////////////////////////////////////////////////////////////////
, X% f. t: _5 \// 作者 : sinister
4 y' G) K' J6 Q' u2 [1 Q// 发布版本 : 1.00.00* Y2 {. l8 @* R
// 发布日期 : 2005.12.27
* X& S0 `9 N& ?, E0 ]0 `4 f! ]/////////////////////////////////////////////////////////////////
" k' }3 q( ~4 H6 {6 F% I8 d; t$ h// 重   大   修   改   历   史
0 e" p' J$ T4 G2 r////////////////////////////////////////////////////////////////
3 N2 b% s5 M' G) D& n8 i( W// 修改者 :
, V4 k' N2 p8 m8 e- B+ y( F* J: W// 修改日期 :: B( E3 j) X4 R
// 修改内容 :, Q- B8 R+ S+ p/ I7 ^
////////////////////////////////////////////////////////////////// i7 F$ ]7 M- r) y8 q

* h1 ?% o7 z4 _+ ~3 A* PNTSTATUS( [/ H5 ?: X7 b2 S$ N
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,* {9 P) Q% V' B
                         IN PDRIVER_OBJECT  DriverObject )
0 k* G. h; c& a/ m$ k% M2 L& ^{3 ]; ?0 D- s& f9 R; v; E1 \
  PDEVICE_OBJECT DeviceObject; 6 w1 f2 }" X+ J& i8 \
  PDEVICE_OBJECT TargetDevice;
, G6 [- T# q! G6 c; Q  PDEVICE_EXTENSION DevExt;) d7 K0 m! j6 n1 {
  NTSTATUS ntStatus;" r! ?" C, T# P. S* [- c9 N

; N8 W( Q% Z" H% _+ x  //# \6 F/ Q1 A! ^: T, G# i+ `
  // 创建过滤设备对象
# c) }6 G8 G; H2 C! J  //9 |6 L% Y8 n! ]0 }4 [0 a1 a
  ntStatus = IoCreateDevice( DriverObject,5 |+ v$ m" s" {0 @- m- o. W
                             sizeof( DEVICE_EXTENSION ),1 k  C1 l: B& K) m. T# |
                             NULL,1 b( I: G8 Q1 W) H& E0 K
                             FILE_DEVICE_UNKNOWN,2 n0 x! c. W/ ~- |$ L  g7 }
                             0,& `8 f- I1 _/ k& k, g
                             FALSE,
( Y' o2 U" c9 V1 M$ P/ `( c                             &DeviceObject ); 4 V$ y* B4 b; u1 C; `  P
& R  Q/ C/ Z$ G) S  L2 {8 \/ P7 `
  if ( !NT_SUCCESS( ntStatus ) )
' G# R1 K) ?9 I8 y+ C% F1 w+ q: `  {
8 _; `/ C4 V( P9 r0 N    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );. v6 P4 G2 ?7 C" ^* V
    return ntStatus;
; ]$ h3 q0 l% N& W$ H; i  }
9 d! N2 G8 u" N1 ^" t# K: A* Y! ~. n( p% N" w* r: o
  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
0 _0 P; B; i+ T& l6 h- x
3 F8 T' e, [6 e9 P7 X3 @( f& q  /// f3 T: x4 d6 D; Z
  // 初始化自旋锁  _9 ~7 K- |+ ^4 @$ V$ l
  //
- b3 M# a9 R$ g0 Y: D  KeInitializeSpinLock( &DevExt->SpinLock );
+ \9 ]* i; Y' i9 j
2 k1 d* V+ c1 x0 n  //
+ q' |5 O" \, O# Q+ J/ g  // 初始化 IRP 计数器
+ x0 v$ k8 X) Z1 J. l  //0 R2 w: @' ~) z. M
  DevExt->IrpsInProgress = 0;) ~/ G( D) i- g0 e$ o7 C$ S

7 X5 ^( b; W1 z* |- Y6 y  //
$ _" I: N- G  @; H  \6 E+ @/ y  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象- L, B3 q* q2 r0 k/ Y4 Y) K/ ?- [# ~
  //
& m$ k. O) [! a  j' g7 a/ @6 S
0 ~3 e( q) p, ?# x& T1 P  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
& o& F  Y/ q3 h& w& Y9 Y8 H  if ( !TargetDevice )5 e" b* J2 P3 T7 h) W& y
  {0 a: b% \, n* J0 e6 I6 S! @/ d
    IoDeleteDevice( DeviceObject );
, Z' |# _4 B+ m! l5 s/ Z% B" l0 c    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
7 r5 K$ @* z2 Y7 `1 D4 P    return STATUS_INSUFFICIENT_RESOURCES;# }% M6 V# F: c% V1 A/ a: J) }
  }
+ {: |. B, d4 W2 j/ J+ m; d2 e. A% k5 s- l- {4 v
  //) Q, x9 n# u, r7 w$ m
  // 保存过滤设备信息6 Y& T/ M: }7 A5 |
  //
3 a. a- p3 u1 Q" |  DevExt->DeviceObject = DeviceObject;
* r: q, t+ h" {9 J9 X! n  DevExt->TargetDevice = TargetDevice;
0 ^% x" E3 }+ P4 n3 Y& {3 _' L/ A/ E% Z& Y% |" m& Z
  //
4 Z  n9 m/ L' H, _. F2 j7 p. H/ j  // 设置过滤设备相关信息与标志- H: y! O" M$ S4 ^
  //
6 j/ E# n7 ~. i, D1 Y0 ]7 A  \  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
# [) D' {  i, F; {6 G  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
3 R$ b" K3 Q! \; }$ r3 S* H; \& l4 b$ Z
* C* C/ }& I  O/ r7 M: d
  return STATUS_SUCCESS;
! k  G$ M9 R! R0 F& W/ |}7 D0 ~7 m( ?/ l) z5 F# J$ w8 k5 u* }8 e
; g. V( I9 y, K0 s
/////////////////////////////////////////////////////////////////
: W5 `6 w6 @: V- z  S+ g/ m; [0 ^3 Z4 X// 函数类型 : 自定义工具函数
# d' V& n# _2 _4 D& n// 函数模块 : 键盘过滤模块5 x# ^" L$ r! p% M
///////////////////////////////////////////////////////////////// q9 ]5 J- R+ s
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关( O5 H$ Q( s) t6 {4 ]# m! ^
//        信息,返回附加后的驱动对象' m* R! H3 W- D) k7 P
// 注意 : 此函数仅挂接 PS/2 键盘设备$ y0 a, D7 H9 n2 O
/////////////////////////////////////////////////////////////////
3 f# r4 E- d* R0 H// 作者 : sinister
- r% z( V2 P7 O* J// 发布版本 : 1.00.00) V1 B5 }  Q% d! o9 O& ?2 [/ J
// 发布日期 : 2005.12.27
4 l% f4 H9 G7 N$ i( m# m/////////////////////////////////////////////////////////////////
  R" O5 t. T  @" J+ D% I# D# r// 重   大   修   改   历   史
% X; A* C; [$ A! U* O* l  x////////////////////////////////////////////////////////////////
% B3 h# q6 s- Z// 修改者 :
/ Z6 C8 r. V, \& \+ s5 W. N3 o/ i6 u. f// 修改日期 :) H7 S& S$ t: m& z$ ~% n  [- D
// 修改内容 :* ?1 o: y4 l. ~8 h) o6 U. R$ f
/////////////////////////////////////////////////////////////////+ W/ A# ]+ ^8 j4 a. S/ f

% {* \, [/ b5 I( L+ _( n, {NTSTATUS. ?" q/ G' M# o9 c% f6 z7 c
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名6 y9 S! W1 W  }* P7 j0 g* k; [
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象& u, a. E* \5 C) t" m1 h: k
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
" ^0 c3 j2 o4 q{; ^' W8 \/ A* t& x; i+ C+ D, ?+ g3 v
  PDEVICE_OBJECT DeviceObject; * F3 e7 B. [. @7 H$ v
  PDEVICE_OBJECT FilterDeviceObject;
. l  R* k" ?9 R+ H  i# I  PDEVICE_OBJECT TargetDevice; 3 I% l; \$ W! r: ]! U$ ~
  PFILE_OBJECT FileObject; ( p6 _- F  n4 |
  PDEVICE_EXTENSION DevExt;
4 v" p4 G1 T1 q) q+ j& ^- V) J- T+ `' H* u; Q, m+ p
  NTSTATUS ntStatus;
  w9 W1 n  ]$ P# m. J) U* s0 {2 _$ G/ y8 F/ _
  //6 G0 Y1 ~8 Q: Z: {$ o* Q# B8 R: G
  // 根据设备名称找到需要附加的设备对象# [6 a9 M6 _9 o8 T9 U; M7 P
  //
$ o, A2 ~% A; b3 f6 l9 o. @  ntStatus = IoGetDeviceObjectPointer( DeviceName,- z% n. @. @6 Z8 U1 g
                                       FILE_ALL_ACCESS,
1 _, H- `  _. u  {/ \                                       &FileObject,
" F2 q+ J, f! s8 {) G& d: R- W                                       &DeviceObject ); 4 `1 z7 \! o3 {2 W9 M& J0 S, ]( |

# p' m( h. G) h* V. Y5 K  if ( !NT_SUCCESS( ntStatus ) )
% P' m7 Q! @0 {4 H1 [- d# K  {
3 ]' z( A! S1 T/ d. B# d7 _! o    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
- p4 V2 g; }! ?7 ^/ w/ T    return ntStatus;: l6 n; V- q3 N
  }
- X& D2 ~- e. a; y8 I- H3 g7 Z" O$ `  A$ E+ C! A2 ]) M& c2 V- l
  //
! V* O2 g; h( t; @" C7 Z. ^5 f  // 创建过滤设备对象
. [+ z) u/ |" ~7 a  a% p5 T  //
9 z1 ~. G! \4 H. x3 P% g3 C  ntStatus = IoCreateDevice( DriverObject,9 I# ?3 n* g' R' ?. m
                             sizeof( DEVICE_EXTENSION ),. \8 H" D) L0 ?
                             NULL,
1 h: r) s' m$ L: d                             FILE_DEVICE_KEYBOARD,
" L8 G- f8 G! @                             0,7 @5 F2 @, [7 I, p
                             FALSE,! c* g  f8 i5 |3 x- M4 J8 J
                             &FilterDeviceObject );
1 j; ]5 D, g" a8 o4 [
- R7 a- O( [+ j& s  if ( !NT_SUCCESS( ntStatus ) )
* j' ^' V3 e' m. f  {
' Y7 @- C) r+ K$ H/ l    ObDereferenceObject( FileObject ); . f+ q- |9 N- }8 l* K$ a
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
$ ?# J- t0 f9 t2 {    return ntStatus;4 M0 k* W& [9 n$ U- w4 @8 `% [$ M
  }
1 S) ^4 f; b" I* }" C# x; y5 `8 \9 |) T4 }
  //
3 A5 F3 w2 V, I4 R+ l  // 得到设备扩展结构,以便下面保存过滤设备信息
! [1 A, u  J& }5 }4 G- T( @+ N# D  //
" P' m7 c; W$ W; ~! Q  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
: B8 D8 F" z0 l" Z: [# z8 J) @, T  P( G4 h1 J& Y

; q' k0 c2 w! |9 R4 ~7 s( w# T7 T  //: s, r! z$ m- N6 ?8 I
  // 初始化自旋锁
& ^, @4 H$ i; T& I1 y' K# I  //
" r- H+ N6 Q1 F7 R  KeInitializeSpinLock( &DevExt->SpinLock );
/ V0 a/ P9 ]9 o5 a- \+ m9 C) C
$ @/ Y4 ?$ Z0 n5 e1 E: A  //
9 ?9 f9 Z- S' ~+ ^) g/ V  // 初始化 IRP 计数器9 |# d9 b; j% _( f  K
  //
, c# B0 [, e7 }& G1 ^7 f/ y8 D$ [  DevExt->IrpsInProgress = 0;9 x" j5 h- z* ~  ^+ i
( a9 _8 }" d  ], \/ n
  //4 y- R* Q' F3 ^  r& c
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
; V) |/ N+ x- [& g: Y* w  //
+ V8 i$ M9 x6 S3 h$ Z/ J& C  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,0 y( M% u# V. T% h2 R( `" @# o
                                              DeviceObject );
2 a6 X5 {; }2 o7 u* K0 Q% N  if ( !TargetDevice )! n1 S9 Z4 n! B3 v9 l4 \
  {0 A' b6 K- K/ P! O! G' d# m# g
    ObDereferenceObject( FileObject );
, {5 o" z3 Y8 y# \  {: B/ F0 x    IoDeleteDevice( FilterDeviceObject );
# e2 W/ @, O) ^6 Y& X    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );8 |3 e( k$ C$ ]! ^/ H# f- M
    return STATUS_INSUFFICIENT_RESOURCES;
8 J; f1 I8 p. |  }
" q7 _* B1 ?0 P1 e4 M' l' ]
8 H) J- V2 Y* Q: G5 o' U  //1 @* u. M4 C- `1 b' O) k- e! S
  // 保存过滤设备信息9 i1 F) L. t1 a3 Z
  //- j( x  ^" j4 d5 s, l) p
  DevExt->DeviceObject = FilterDeviceObject; 2 W$ T9 f& ^/ n
  DevExt->TargetDevice = TargetDevice;
: s+ r( l% y/ b  J* U% [+ f  DevExt->pFilterFileObject = FileObject;
! w& A- {0 r, L# l9 t  D2 {% i4 A3 @/ L7 w: l) c
  //" F9 u0 {4 q9 E5 b, c; f/ R
  // 设置过滤设备相关信息与标志; {7 d- e  |0 Q& a$ {( }
  //
1 Q% v3 `+ M; A8 V! P, F  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 8 c9 J2 o! g( D1 U2 H4 p2 \/ a2 h
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; / S" m$ o' V0 [2 n- R
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;0 E6 I0 j# O2 y- a/ Q# {( C% k  f
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |/ @8 H) u( s) \5 f4 b6 l0 I
                                                         DO_BUFFERED_IO ) ); 2 Q1 ^2 `$ U5 z0 j

9 c2 M2 e* e. j' S  //5 ?- ?2 y: V2 }1 D. L. ?6 n: W* A
  // 返回附加后的驱动对象
- Z$ z* M. W* O! H: \& k8 g  //
( ]- ^' X, F, L7 _  *FilterDriverObject = TargetDevice->DriverObject;
! A; P  W/ s, M! A* s$ p/ |0 I& J
  ObDereferenceObject( FileObject );
- U/ c3 O" _: @+ K( w$ S6 C
( C; }5 g8 Y" m  return STATUS_SUCCESS;
2 b9 P; b" L8 q6 I/ g2 k}
$ M$ o& M6 L( r+ W
* B$ h% f9 i" ?6 n# B/////////////////////////////////////////////////////////////////
$ t9 K5 `$ z2 T. r5 N) c* B, r// 函数类型 : 自定义工具函数
: u. \9 i! Q+ u. l6 ^  A% o# x// 函数模块 : 键盘过滤模块- X. g2 a2 u$ i) J0 W: r' Y
////////////////////////////////////////////////////////////////
# c! B% f: U  P* P/ D// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
% E5 y: p' z& }' O9 p2 T//        这个 IRP 的完成
+ M0 F3 G3 g9 x. a% t// 注意 : 3 M2 R0 y, H: ]: q
/////////////////////////////////////////////////////////////////
% l) m# ~- E5 E: y- W9 T// 作者 : sinister6 {, S( W; Y$ Z' ~
// 发布版本 : 1.00.00' s" s# {9 `+ e7 W/ |
// 发布日期 : 2007.2.15& p  n/ h/ V2 D
/////////////////////////////////////////////////////////////////; h6 i5 i( _/ w& a7 s' W9 w
// 重   大   修   改   历   史' d; T6 U$ l4 ^  e
////////////////////////////////////////////////////////////////$ P3 |# X5 @! A
// 修改者 :
$ k' u2 U5 c. X! ^# [// 修改日期 :
5 m6 E0 n4 l4 e) x# [, h# h4 O// 修改内容 :! A8 H! e# S, x: K( U
/////////////////////////////////////////////////////////////////9 e$ U7 B0 f) X2 v7 J2 W! a

9 L5 J2 R0 F1 e1 [NTSTATUS
* G0 m1 C% |- {, a/ n% gKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
$ _( ]9 f; ]1 l/ {, ?' i- ]/ c/ P{% [/ W8 k5 P& U. p: t& A- e4 u( q
  NTSTATUS status;   R" I) M7 F; `" N1 u4 _
  KIRQL IrqLevel;
! }5 E# W+ s& {. ?8 u$ ]
, p1 ^) t8 G2 O! Q2 r) C  q$ n. I) C  PDEVICE_OBJECT pDeviceObject;5 A+ r! n/ X( y  q
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
9 i6 `' M2 k& J; W+ t& ~                                   DeviceObject->DeviceExtension; 6 ?3 ]5 H  |  q* F( y# N; y/ z
2 A, b" t! ^' e# |: U

- P2 F- f2 H$ m% N+ S! w  IoCopyCurrentIrpStackLocationToNext( Irp );
, }4 T) l& I) \1 G/ f8 q7 Z+ T6 b( l4 g' [/ ]5 X' O2 j
  //4 w, C; [: p0 W2 }* o9 _
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
  B6 Z$ |$ r/ z* z1 E/ N- u* {/ ^  //
% R5 i& ?# \1 b7 y  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );! H, i7 e  |5 k" I3 t
  InterlockedIncrement( &KeyExtension->IrpsInProgress );, e8 @& X8 |( H: [4 X# h
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
% i, m# f9 c8 Q6 s* p
9 O; B$ q# c' [  IoSetCompletionRoutine( Irp,
3 }1 v% s1 J! |/ y9 T/ k9 L                          KeyReadCompletion,3 y8 c4 A6 f1 h% m' w+ x* U
                          DeviceObject,- ]. s0 z* F* }8 ~9 F" Z
                          TRUE,+ j" C+ y" G2 z) U" V9 |
                          TRUE,
! z. r- Z0 l2 b, u6 h7 e4 \$ \5 X                          TRUE ); $ ^& d8 Y" u! a3 M0 y% a& F$ Q

% m" E* {; P' K. s; j1 i9 U  return IoCallDriver( KeyExtension->TargetDevice, Irp );! l; @* ?/ a9 Y" a2 k" y1 M
}   n; b5 m& s2 _

$ o# i! h$ J; l+ |4 R0 j/////////////////////////////////////////////////////////////////
5 h, o0 {. I- ~6 A, n$ {) d// 函数类型 :系统回调函数6 O- V- B4 w  I) k. E0 i
// 函数模块 : 键盘过滤模块
5 t/ o5 a7 @$ W( B" D! y////////////////////////////////////////////////////////////////
, C! B  }: l9 F# Z+ \  |9 Z// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的% W( n+ j% `3 Y' d
// 注意 : 3 E2 r: K7 `# j7 c+ I' }6 y7 [
/////////////////////////////////////////////////////////////////
$ _: O1 U. P" ]7 Q; A8 }// 作者 : sinister' B: h4 x6 M4 M: |- ~$ N3 Y8 t8 J
// 发布版本 : 1.00.00! F  I8 t. ?. ^! J( l4 Y
// 发布日期 : 2007.2.12
: T3 |; h. \4 A( Z/////////////////////////////////////////////////////////////////
4 F0 Y, v, U' O( P" H% P' P2 v" d// 重   大   修   改   历   史) R( u$ D, l( R2 _, w2 p! |8 j
////////////////////////////////////////////////////////////////
  n- S7 \) m& w" f% ?// 修改者 :
; O8 ~1 w' \! l% i, R) X// 修改日期 :
7 v9 P% ]  _$ P// 修改内容 :" c0 n& w2 a$ F% @! p" W, d& `
/////////////////////////////////////////////////////////////////
8 `- q* a- c1 w0 V& p( l, i7 U( J# w
NTSTATUS
2 i! y! m2 f2 n/ }+ u( Y% LKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,  z/ N+ z6 z! [3 ~* r' a
                   IN PIRP Irp,) Q! m2 h+ y' H) Z; A& p2 S( r
                   IN PVOID Context )6 q' k  N* c) ^8 [. c8 e7 A. n( |4 b
{6 p( G: q4 ^3 ]" h2 e
  PIO_STACK_LOCATION IrpSp;# E9 W4 h) x9 c- A0 D6 e
  PKEYBOARD_INPUT_DATA KeyData;6 ]- [% D- C3 c. G' p
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
$ |* T' @1 \, H                                   DeviceObject->DeviceExtension;
& z4 n; I. e, E% q! c7 {9 f4 K* l' g$ b  int numKeys, i;
/ C9 j) B% o, R' j  KIRQL IrqLevel;0 H$ E# y' A0 B
9 M3 p' ]4 i/ a) C% Q7 m) A
  IrpSp = IoGetCurrentIrpStackLocation( Irp );
! j) ?9 H' }  \( N: I
7 L6 Z) [2 {4 b0 ~( F( Y$ z2 x, Q
4 J1 L- w, T: b, [8 m- M  if ( Irp->IoStatus.Status != STATUS_SUCCESS )4 A, Y8 o7 C) s% L( N: c
  {
0 I* ^1 z( S! j% i% B    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
  n! h: W7 b& l( A* K4 i    goto __RoutineEnd;
5 a1 }6 r6 B- l2 R  }
+ p7 m. M0 \+ u) e0 I4 f% A/ L" R
$ l: L# k' t( a$ h  //
: H' U; {0 x3 i  // 系统在 SystemBuffer 中保存按键信息
) d/ n7 |9 X+ Z* U9 ~0 |  //
6 W! u" `7 ^4 l" n  KeyData = Irp->AssociatedIrp.SystemBuffer;/ i* F2 b9 e. z) `4 r- ~4 R" T
  if ( KeyData == NULL )
2 ~# j5 |  H( e# A  {
# r. N) D1 a0 R$ v7 Y2 M    DbgPrint( "KeyData is NULL\n" );7 ?; n# p) A0 w! w+ G: f
    goto __RoutineEnd;
( n( l- K* d5 I( I  }
$ p/ n& o/ H" j$ [- l$ ?7 m1 T+ V4 _1 E& Y6 t" Z9 }
  //% t$ L6 p3 ^0 f* }, k# N9 Y
  // 得到按键数
; f3 M' t) N7 ], @3 `2 @! l  //9 O7 R  q% K+ ?. h9 D# U& q
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
( T) {" Q# s2 e# Q. F  if ( numKeys < 0 )$ l, W& C  x; A
  {
3 s" j! f6 F9 K/ c0 |! S. V    DbgPrint( "numKeys less zero\n" );
$ ^1 M: B0 x- z3 Y  q    goto __RoutineEnd;
9 N5 c' z2 w7 W, T0 \0 K7 x( E  }( V' u( I$ R+ s2 `) s% g# F
% ]( e& w; Y) m, ]
  //
, e, _: I! q4 L  Y( H, W1 W  // 使用 0 无效扫描码替换,屏蔽所有按键
1 U/ B; i+ O/ H1 f7 K  //
7 W7 [1 R: e/ t! T' w) J  for ( i = 0; i < numKeys; i++ )6 l( H9 f) R' T. m" A
  {
8 @+ s+ F$ d6 j3 N& Q; i    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
# t: R- w& x  C; N$ b7 W  H2 e    KeyData[i].MakeCode = 0x00;
) S/ E) y2 G; a% |9 M1 ]  }
+ U/ ~& q' x' \2 C' f3 x) m3 K
: e0 ?6 _2 l& H3 z+ u2 j7 u- f4 o+ g0 T3 c+ v' i9 J1 W
  __RoutineEnd : 1 r5 m- R7 x4 z$ C7 h( z3 C" t; _4 C
. f) U" `: C8 s/ ?0 J% p
  if ( Irp->PendingReturned )
, R1 [! {9 p" k& u; t  \  {& m$ l4 O2 z" i! R) v5 b
    IoMarkIrpPending( Irp );) O5 k5 o2 ]# w% @; H
  }
, h# w1 a2 i# w1 N( n8 P& Z! r
- t$ l2 ]$ V! V- d9 }& j5 ?  //: q1 t6 _8 ~8 h( ^! i
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁0 @: G4 R3 C  V6 A9 w+ e
  //+ B: o9 V* c0 }0 e; P: I
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
1 `+ X' p8 v( T/ x6 m  InterlockedDecrement( &KeyExtension->IrpsInProgress );( F' @* v! U1 e7 A! P
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );& }- \+ ], n# g$ L
% N& f% \! W! o5 C% j# x% B
  return Irp->IoStatus.Status ;* ^% y! @$ E) c* v: ^2 i
} 6 E+ n( ~* c: u: u

5 C1 W+ ?( n% b' R& X" b  R) [$ U3 w9 `3 x# m
/*****************************************************************4 }1 _5 \: t, \
文件名        : WssLockKey.h: F8 F% w. d2 J& S+ I
描述          : 键盘过滤驱动' @+ ~. n: }5 x2 j# V
作者          : sinister
" N0 [  g' ^" P! t' c3 I' F% X& R1 A 最后修改日期  : 2007-02-26
6 N6 h$ e# b5 l8 |/ q7 a% ^8 B6 o- c*****************************************************************/; Y: d; |2 [6 W: E1 {: C

* V2 u" J+ w. \8 B0 U+ d6 G8 v#ifndef __WSS_LOCKKEY_H_
8 c- f# W4 Q5 V. o# j; w#define __WSS_LOCKKEY_H_* K  ?2 ~( `  I9 A: e- P- i

" s! G# _+ F7 e#include "ntddk.h": C6 K4 U' t0 N" q6 C
#include "ntddkbd.h"$ i; ?, Y1 h! S! L8 O- k
#include "string.h"& H# ~' ?8 |: q  y2 ~% O
#include
: u: k" r0 P2 z% q, H5 w6 T( {$ ~( a+ J. N8 U: B
#define MAXLEN 256( z& W! ?1 I- I0 m, U" i

: E2 h9 E0 t& R& n0 ]#define KDBDEVICENAME L"\\Driver\\kbdhid"$ @4 k" H0 K- d8 S- _# C( z
#define USBKEYBOARDNAME L"\\Driver\\hidusb" 3 O  K% I2 I7 z$ `* L; B2 R7 T
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
  d! m. ?8 _  Y7 g# z. @% A5 x7 u& T8 `0 C/ k% W
typedef struct _OBJECT_CREATE_INFORMATION
, x2 \/ H6 G. m8 u5 L5 @, u, k{
( e& R  ]& L7 O; p( G) O3 b: z) k1 v    ULONG Attributes;9 u1 D3 C$ r0 a; I9 r( A/ t: Q
    HANDLE RootDirectory;1 O# G* y  @3 ]2 @, x
    PVOID ParseContext;& h, ]8 r) Q5 j7 m: r! r3 [
    KPROCESSOR_MODE ProbeMode;( x3 t" k& ~( }9 \9 D9 b; f! |
    ULONG PagedPoolCharge;
$ c/ {$ e! `) X- l    ULONG NonPagedPoolCharge;( s; \2 G, E1 l& Q$ ?2 d$ k
    ULONG SecurityDescriptorCharge;
7 r1 b# b; \# j9 |; _    PSECURITY_DESCRIPTOR SecurityDescriptor;" o3 {- {6 g7 O/ E( P
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;+ G0 @* l( s; I2 |, k  W3 h
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;- |' C/ T- N% v; Q& P
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
: S9 ~; d$ W) i. T0 ~3 K' J
% ?0 D( W' {4 C$ I! E4 ~typedef struct _OBJECT_HEADER/ {& y+ ?6 f3 j3 M
{
# ]6 U/ h' M7 r" S* c    LONG PointerCount;
8 ^2 a# [7 F8 Y  N    union
! c4 g3 w6 m; Y& ^    {% v4 @: ~% R5 ^2 O
        LONG HandleCount;
0 J* b0 b$ A: {) n# P* Y$ V' {        PSINGLE_LIST_ENTRY SEntry;
" h7 g( S0 n, s2 @- _* u) \3 o    };
/ g* F3 h% T" R    POBJECT_TYPE Type;
- e( `3 x! l% b* y; k    UCHAR NameInfoOffset;
/ e, B. W9 o# D* p$ P    UCHAR HandleInfoOffset;6 M$ {" y1 [. J6 x! P1 P2 _6 X
    UCHAR QuotaInfoOffset;1 _4 f% p% t' `, U) h8 ~: f' |
    UCHAR Flags;
$ n2 r+ ^! J: n    union$ `7 f) u& W0 K/ r
    {/ C& E- e. _1 {
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
3 T+ G* q7 l( p& ~3 G        PVOID QuotaBlockCharged;0 |2 K! W' ~* s/ k9 L
    };
8 M' O* {/ e0 ]( p7 c2 f( ~8 D/ m, \! r5 A- p
    PSECURITY_DESCRIPTOR SecurityDescriptor;
) J6 D' A* \- j- j" ?    QUAD Body;
: s% U' O) E  C( L6 t} OBJECT_HEADER, * POBJECT_HEADER;
2 ^1 d2 t' F/ y2 `! H& W3 V) X- i/ s# f! G  x  \
#define NUMBER_HASH_BUCKETS 375 X$ k" {( c# E

6 {# u$ E+ ~9 J% Etypedef struct _OBJECT_DIRECTORY
( m$ B4 S/ h$ d# e{
( _" x5 h1 _% q    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
$ }4 f# H6 [7 n5 ?    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
5 \# @" D# \1 A2 j' \" w' s    BOOLEAN LookupFound;/ N, p5 u  B7 S! B
    USHORT SymbolicLinkUsageCount;" b; m! x8 D1 B* K/ g  A9 P# u& M
    struct _DEVICE_MAP* DeviceMap;' J2 e1 W4 }- s' U; q- H
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;- _: f. l3 g' _. ?$ C; ~- n

& z, S3 F  W7 `2 W2 g% R- s+ o6 h3 T0 Ytypedef struct _OBJECT_HEADER_NAME_INFO
" A- f0 c  k1 L7 U{
2 H5 d# R& q# z2 O8 [0 ^- b    POBJECT_DIRECTORY Directory;
& B% u9 s2 `$ D2 n2 l' }% m    UNICODE_STRING Name;  r# y% Z1 I4 m0 ^
    ULONG Reserved;
5 I7 Z  ?9 x  R2 R#if DBG
0 D+ u3 T$ l8 s& ^7 p5 H; S3 {1 l    ULONG Reserved2 ;
# u" I. e" J$ D4 R6 U  @- K/ y2 J    LONG DbgDereferenceCount ;7 X# Z$ ?- ^! Z. [6 d6 o
#endif
) Y6 C, {  q/ d: n6 \, {2 J, K} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;1 I2 L  K( E1 d. g  B
) Z, D- d; Z) P, T& t9 C) m
#define OBJECT_TO_OBJECT_HEADER( o ) \
/ w! e! r2 e* ]8 f    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
! y, U0 _4 M# y5 Q  p' N4 o5 p: D# ^
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \4 e* b( n$ g) M* G/ @; |' I
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))( b& ~7 U( c  ?6 t& I) l: M

0 i! v5 Q, ^- j) b, I% Qtypedef struct _DEVICE_EXTENSION$ R! z5 r. Z4 B; F. F, b
{
1 X+ E. j" l$ Q    PDEVICE_OBJECT DeviceObject;
0 w( P' _# z4 i5 a* @    PDEVICE_OBJECT TargetDevice;
2 ]  U4 N* H  ]! G! M2 d! g    PFILE_OBJECT pFilterFileObject;3 P& Y8 C& K; t3 S, `8 O
    ULONG DeviceExtensionFlags;0 ~, t/ M* X) l" p4 C; y
    LONG IrpsInProgress;
, ]. v2 I0 d( ]8 d3 v( r4 R    KSPIN_LOCK SpinLock;
/ \) o0 G1 K! j, W" ^}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
" c' D& _7 s0 Q; K6 Q% |# J( R' c/ b+ }9 m+ o" n8 P# P
7 i6 q" R- K1 @) ]; v% h0 B2 Z8 b" g
VOID $ L+ ~" g( d# i
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
( M( _6 k9 q/ ?( P2 `/ C, S$ ]: n& r4 U$ [& F8 C: t" I
BOOLEAN
4 k) M, y& A! t7 v( q: OCancelKeyboardIrp( IN PIRP Irp );4 E- O( F* W- j# S
; s% z( C8 z) S2 e$ d3 |/ t
extern POBJECT_TYPE* IoDriverObjectType;
! @8 Q7 \' I+ ^9 x! e4 \8 g; ^4 X9 w6 e) Z/ \
NTSYSAPI
6 N! P, _8 Z7 o! y$ `NTSTATUS: E1 i8 {% o6 l
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
) C' g  @6 t5 H" ~, `                               IN ULONG Attributes,
/ ~, @2 c6 V1 d4 F1 c                               IN PACCESS_STATE AccessState OPTIONAL,
0 @. g# X2 r& ^" k; ]: O3 k                               IN ACCESS_MASK DesiredAccess OPTIONAL,
8 y) G* m& @' t* t! Y" h1 r, p2 r                               IN POBJECT_TYPE ObjectType,
  h$ k0 y4 C3 N1 ?: H                               IN KPROCESSOR_MODE AccessMode,  m, D2 R# `+ l. H) l; `
                               IN OUT PVOID ParseContext OPTIONAL,7 t# p2 w7 }% O8 o& O8 g8 m0 A7 x0 n: @
                               OUT PVOID* Object );1 F8 M5 P; X+ Z6 b

; u; u% N2 {8 CNTSTATUS & Q5 ]. |- o, G3 U2 L6 F
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
( `5 j% h4 V0 s5 i5 M: F$ {  I& @) o; I' i
BOOLEAN
, R/ {( |4 J8 Q0 s& ]' `GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
5 p, H( f$ ]' U5 o3 F
8 g; ?: e/ c! zVOID
' D- i3 ^$ y' t- C7 O. tGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );+ Y) t, M5 r4 L5 s) \- V
# f4 y/ z" H& f, t. t! {% x6 q
NTSTATUS
: i8 B, M2 v; `AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
: D3 i0 W' f: P$ s. G8 A! f                                  IN PDRIVER_OBJECT  DriverObject );
6 b& p2 g" ]1 F
: X, T0 H) t( D1 ENTSTATUS
) {) m3 ]. Y+ q/ E: F$ [" zAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,1 T, {; T2 E$ I) I6 {/ M8 F: ?2 s4 G
                                  IN PDRIVER_OBJECT  DriverObject,; |% G( ~! y( Q( q
                                  OUT PDRIVER_OBJECT* FilterDriverObject );0 \  S6 |6 n3 ]* w% Z1 ?8 }' i4 @
' k) e# G+ a4 b
NTSTATUS % N" x& i9 D( E$ h+ U
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
6 v3 Z  G  E" R& X' {3 ~  r- k                            IN PIRP Irp,
; d; o# r5 w: F, O* d9 ^                            IN PVOID Context );
0 k+ r7 h2 x( Z# sNTSTATUS 4 l4 q# m3 B+ t, K( K
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
/ H/ W5 g7 u. x4 d* ~8 s% U  }$ `7 I, n$ s  z% D
WCHAR szUsbDeviceName[MAXLEN];
  L) B2 x/ k/ F  g$ F; R; a
. p* H! R2 L! f, ?! c9 ^#endif
% {/ T3 K# R8 Y% d" ], j
& u0 Y9 s6 k* m& [! v: s0 J4 ?' K2 \  O$ |+ S' [4 i2 _5 l8 e

8 h+ a9 o) o9 l; a5 C6 m
9 u1 e) B2 X+ W1 r  l9 L4 @2 k, A
; V5 M6 H( C$ |4 j! z' UWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。# Y" r0 t0 K2 J. T
WSS 主页:[url]http://www.whitecell.org/[/url]
' T0 N# y* T  g  Q, f; TWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-1-18 20:59 , Processed in 0.061826 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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