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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister" ]$ g" S; ]7 L  n
Email:   [email]sinister@whitecell.org[/email]# O& \/ Q) _  F1 H& `( m' q) O" C
Homepage:[url]http://www.whitecell.org[/url] 9 U3 z. @1 ~% w
Date:    2007-02-26
% W* V: _( i9 f: b' A% X  F  Q
# F% X9 F8 c) \4 i0 h& b
+ D# Z  J% B. [5 ?6 t* w/*******************************************************************: Z# s3 R) I: a' U9 _; Q
/ S7 t# w) e  o$ b7 D, Z6 K
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx5 ?5 M$ [7 |% o. V. `6 \
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
! m& r1 E3 B4 G* j& I功能要求如下:+ G% K# K8 K* s' O2 Z- z% s

1 w7 Z* K3 d, @6 |& u! q1、强制锁定键盘/鼠标。! ^- Z' d8 t; E7 g9 J" b  t
2、可动态加/解锁
; e" J5 g- ?+ l7 N. j+ t3、兼容所有 NT 系列的操作系统。. e8 i/ Y0 a0 O0 D3 m
% P4 _9 t9 |$ H' R: Y
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
) a) O& H5 ]+ u! Y& c; D% P现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如& u0 U, s  b  z& W& p) L9 q* v
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
$ ?; M. C  P, U# I% S/ V上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是7 z+ F- q9 S5 O. c! W
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
+ Z. g: N* T! w5 c. D# R/ \1 E就来看一下我想到的几种实现方法:9 s% E8 d3 Y3 f' w
* Y# P: l* _: _( K+ U( o. X
1、全局键盘/鼠标钩子7 h5 ]$ X; z# I/ i" D5 [
2、BlockInput() API5 Z! W  p  d* C
3、使用 setupapi 进行控制
5 N7 B  y! X: n: ?% K4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
# @; w, ~7 a# w; L5、拦截 win23k!RawInputThread() 函数
# J3 @( c8 y: [: C% j7 x; y6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
) W* K& J- [: m4 f# S7、拦截 kdbclass 驱动的 driver dispatch routine  h# l4 o# m1 b
8、实现一个 PS/2 与 USB 键盘过滤驱动/ ]  u& {$ c  v+ e  W+ F/ b
  V9 C; [- X* g6 [, k5 [$ S2 U

4 P# q7 t# m5 U( ~我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑% O* Q4 ^2 y2 J6 t
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
% G" D5 ]5 n* R5 k) l案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在3 y& l. b; Y- i  P0 c  T$ H
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因9 z2 V1 `4 n& u& C8 y4 d5 j& v& P
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
: K1 x" O: k& m( E, z! e' x问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
8 r/ a; U. ~- n! N" G" g载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
/ M8 p6 X% J* g9 H的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来$ @' v+ A9 T; k8 E  M5 c, S
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如9 h2 [/ d1 c) R6 h
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有3 S) m$ X/ q9 x2 Z  H7 g
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
- ~' n* y+ ]9 YIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 5 w1 Q  q, }$ i/ r; B- w# d* a" n
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
( L) X  E- g; [. w+ n盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方  g* c: g( e* F5 G4 w. |
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。/ Q' e, J6 o, _) h$ z4 W2 _

, ?" D! m! T. }' n! K; q
$ n' ^5 ?! D( |: g1 e我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过+ B$ Q9 f- E9 ^2 C  l5 U
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
/ v/ _. }3 k0 b1 W; V$ J行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是5 e8 \' y- g  l( z: T+ j' F0 {1 z
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越6 J# o6 @3 V! r# s
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
4 z4 H' k: v4 E' a+ nKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
5 J& @. S8 R' k/ C( u2 `7 B键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用- [- l( D2 `' _* X, u$ B4 o5 Q
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,! _1 N; V% ^% K9 w# _1 F' e; x
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
6 Z+ f: F" K+ Y+ z. F& W- _就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的+ c/ [& u; n; t. }$ J: O+ t
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使. v& _& w. U% z! X  [* T
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通1 ~3 r) H/ G6 ]1 J2 I3 e* B
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来' k, f7 Y9 r5 ^3 `! R) g2 u- O
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通# \7 N) f2 s: m! X5 c( C$ w
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
: q' ?$ t4 D' h% [7 U上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
7 L) [- @; \0 V4 x8 l3 ?的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
) Q8 m0 ~, G# [; c# x& R味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。$ ]4 U5 y1 M- r. ~' R3 h
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
" V! h9 @* H# S1 @" C5 w. |来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
# x  M6 D$ |( H3 V$ z的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo2 @* O! l% c/ R) V* h% r& p% F7 H
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
6 p3 h0 [: ~% b& c; p敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,- Y, U" D8 x/ k. M9 w2 i5 c
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程9 U9 C4 J* C' L! C' w
见下面代码。
, K  N# H+ Z- l6 z3 f, \% P4 V0 S2 w  E
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程9 U- W$ o+ e1 q& m. M; n8 [
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
# y0 S8 l! n' q: S6 {盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003* _/ S! U% b* o: ?/ @% R  n
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有" U0 a7 ~+ x# [7 A+ E8 G! _; J
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
" [% ~  V& s+ b/ V继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个: V" q8 ?! R$ l" Y, |1 N/ o$ @7 t
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
$ p$ R- ^# q  ?0 R1 E3 K! A键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。0 B- Z9 S' h" h/ N7 A4 i2 H

! W# x, x9 B4 K% d# Y+ L' s  I
! t& S/ ^( f% h3 R' _完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
+ Q: f. b4 {. k7 D% \: H% O+ f4 ?的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
6 @+ A3 D2 u! q可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
$ y- ~; F. J+ m3 V) i+ ]的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我' u6 M0 Z1 v% P0 @. Y5 G
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
, n, l# ]2 F$ E* S" b$ v3 }们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
" M+ _! x  n$ d->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
* s3 e0 n  b1 g+ A- W9 ]; S& P如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
! ^9 K! V' P) l) ^/ O' O进行操作了。这个问题有待大家来完善了。# ]( R$ ?% f; A. _0 p, U: e1 k

  @& T: A( g: Y5 g+ J3 Z
# |9 ?" g. w8 t. d/ ?要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
5 R4 X; A& N8 @5 E来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
6 t  p" @1 L' y! r& V) Z分析做个记录而已。我更愿意把它看做是一段注释。
- l( G( W; I; l( I
/ w0 t' k' v3 T最后在此代码中要: b0 r8 |- x1 g0 Y

' Q* [; i  N  I& r; B( F" M3 y感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。3 ]% L0 E/ \) w, Y9 B9 [

* T$ G0 m% W; f7 Z感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
( ^  ~( L& W: k  G
5 v$ i0 r. O' @7 R感谢:齐佳佳,过节请我吃好吃的。) V! n* N& o4 {6 `! r; x7 T: G
% b3 W7 K3 w' c6 d
1 n* @% _" r1 j
******************************************************************/
  q8 s" O8 Q9 E* S3 E: L$ |; U5 b3 m
. z  S& F0 x1 _9 t0 B" Z
4 P: e1 P$ \+ ]9 n# {/*****************************************************************
) b" @7 L  t9 G5 r( D( @ 文件名        : WssLockKey.c
% L0 S/ i8 e6 m5 p 描述          : 键盘过滤驱动
4 @* L  o( y) ^) |  ? 作者          : sinister
  v" E4 J4 O& R* K5 }9 p; {4 Y) } 最后修改日期  : 2007-02-26" n, o- Q. M4 F4 c  F2 ?1 X
*****************************************************************/
* p1 U# i9 k. q  U$ M" r
8 z. g# B# L) b3 V) r. c& S; n  t& K/ E: C; y
#include "WssLockKey.h"4 Y. q: L4 O, X# {* F% t

1 y  H2 B) Q. e$ ~- JNTSTATUS1 O: Y- D/ L6 v7 W/ N8 g! ]
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
# @6 W) G% [. F3 G! v* u/ ?/ V             IN PUNICODE_STRING RegistryPath )
2 l# g( @8 \- H9 Y+ P{
7 b  x! l9 x6 ]6 x; \. }  UNICODE_STRING KeyDeviceName; ; ?1 K2 b- h3 _+ |
  PDRIVER_OBJECT KeyDriver;
, W7 m1 t; u- D, d( q  PDEVICE_OBJECT UsbDeviceObject;
) N2 Q$ t$ y. v2 W7 @  NTSTATUS ntStatus;
# [  A& |: v& r! u! l- Z  ULONG i;
( d: l+ P9 _7 [8 V& }- T! E4 z+ F
( m( c, I1 s. P# Q/ z5 e' q4 f  //
4 X/ @/ g. o4 b  // 保存设备名,调试使用& a4 W/ d# I" E: Z8 b& e5 ?) q8 b
  //0 y7 F( |1 W0 k  ?/ o, I
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
: [, A! V. i- J9 P* i6 t  D. d3 w  {
; F' v# H+ _( D* ^    0
" ?, C$ q$ ]0 d5 A3 f6 [9 t* B! B$ K  };* b5 ^0 |8 _* p  ~2 y  j, p

# e) g* x8 P4 X) J1 D# b  KeyDriverObject->DriverUnload = KeyDriverUnload; & F1 V8 y- B! n4 \: l. f7 C8 X
+ ?# X7 z6 x$ G4 K) u1 [
  //
4 t+ R3 O; J* ^# b5 g  c- \! b, X  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
& t* B/ E9 C/ R6 F6 \  o6 w, D$ `  //  Y3 @7 k" N. V/ F0 t  R7 t
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法$ x, z6 `. i0 l1 D* a% S, o8 g# z7 L; w
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其0 x9 M& c) @) M0 i
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
$ N6 p. Z3 J0 Z4 o  // USB 键盘设备来进行挂接$ R1 D/ P' e9 J) n3 v
  //- i; N* G1 K3 I! \& g7 Z( w4 S% T; I. }
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
9 @6 V# o$ L, ^3 H! b5 J- [0 y  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
' U2 j3 Q6 }2 K' k( ?- r% y: c  {
2 b; U' _% [9 a# N0 q    //. F1 @  b/ O; R) N$ E& I) Z
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名/ D( q+ p% a) l
    // 所以这里打印为空+ \0 p5 c  u* |
    //
0 O+ M: I* N( N( A! E    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD2 o5 O0 ^, C7 H: |7 ^7 T6 Z
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );- R+ m8 p8 E* e7 D& H( b( H5 T* N

+ w& A' m  _3 M' z9 I! \    //
8 Z) j5 m! ~1 ]2 i0 T    // 挂接 USB 键盘设备
# z6 L: j: l& B3 G1 P) Q) c0 z, L    //" I: L+ a$ m0 K) U+ _
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
; h7 P; w7 [# e4 {# O    if ( !NT_SUCCESS( ntStatus ) )
5 _; l% @/ |% ~  S    {
- p5 u2 a( s# }5 o! q$ r. h      DbgPrint( "Attach USB Keyboard Device to failed!\n" );- x- B: O4 Y% u
      return STATUS_INSUFFICIENT_RESOURCES;: w3 k. P  i. j5 N$ Y+ s
    }8 j$ v) J$ ?" b! }7 c
  }
# s* k8 h' Y1 o( b4 }0 e9 J  else
+ c* e& S6 B  ]- T) v9 b  {0 U( p8 [  q# I5 K$ i1 @
    //
  C+ H2 r1 b8 n" k    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备7 g( E2 G% w6 N& K
    // / W) n5 C# M! R3 J1 Z5 d
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
8 W9 a# W& m+ e: }4 m9 U6 ?& b  O6 B+ Q$ J8 B$ V0 |3 W  l5 d# j1 @
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,5 i/ h- e* T6 @6 z/ p% Z* a
                                        KeyDriverObject,
  W2 j4 I1 R9 C' n                                        &KeyDriver );6 U- l+ H0 W% u$ s
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
  b; N; c+ r: k' v5 ~    {
7 C/ s+ u! k  {6 B7 X3 J" X2 _- V      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
/ M( e. }% x8 k" `      return STATUS_INSUFFICIENT_RESOURCES;; P" p# E+ D/ g# k, H
    }) g: U; D6 G, Q7 g
  }+ T: N! {( e8 ~/ a

2 S+ R# q; a5 w5 {  //
# ?8 ~* J5 ^3 g' Z3 |  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止  M7 q* K( k, L: c/ S" c
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程( W" u( J1 w4 _! h" _9 ]
  //! U: v+ N, P7 B" U0 z4 \
  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; 0 o# L: I, x9 `. B

$ [: \, _! E1 J; [- J1 w  return STATUS_SUCCESS;& `% ~( x( J7 i- X* C% n
}
1 H5 A, j  }  B8 U+ v% J* m) i
' i7 E+ B$ o0 d, n' ^  Y; ~/////////////////////////////////////////////////////////////////1 W0 N% I2 V$ L$ `6 q1 u
// 函数类型 : 系统函数
; R9 W' P2 b+ S& G' ^* i// 函数模块 : 键盘过滤模块
% Q6 x1 u+ i7 m) ^# K/ c# j5 z) f////////////////////////////////////////////////////////////////  h( j: G9 J% A+ Z9 A2 Y) O$ w
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,2 t0 ~+ l, \7 P& t4 ^
//        卸载键盘过滤驱动
$ R6 K' ]$ y2 e/ W// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上: M) `- M/ M! B# U1 b3 {
//        则需要等待用户按键,以后有待完善
! J: U2 O7 r; i3 m/////////////////////////////////////////////////////////////////
) {& U3 w* s/ q: S// 作者 : sinister1 a( }5 S6 p' D$ Q- G* ^
// 发布版本 : 1.00.00% t* ^( P( H+ s7 t# k+ L
// 发布日期 : 2005.12.27
) G4 ]+ g1 \5 I9 \+ f/////////////////////////////////////////////////////////////////2 _+ K5 [6 T& B( Q
// 重   大   修   改   历   史, T9 e4 ~, ~9 ?7 M
////////////////////////////////////////////////////////////////$ w9 Z7 N6 H( ?: }. \7 e8 T, {
// 修改者 :# o/ F% j+ {9 w6 S) i
// 修改日期 :5 w- u* U8 `; u, o
// 修改内容 :: V+ r/ d' q3 J; ]. E* @5 u' Q
/////////////////////////////////////////////////////////////////8 Q5 a. U  R* F7 m4 `, D6 ]
0 _4 k/ b* G. r- N% O6 W
VOID
8 X$ P1 u0 p0 }8 I9 r8 [. rKeyDriverUnload( PDRIVER_OBJECT KeyDriver )4 f: G7 p$ M1 U6 J
{
4 N( r! i$ P( i0 [/ U$ O  PDEVICE_OBJECT KeyFilterDevice ;      
6 e- d0 j2 r+ ?; c, ^' p" e  PDEVICE_OBJECT KeyDevice ;
' k6 D: s/ E' r6 E. @- P5 B9 O  PDEVICE_EXTENSION KeyExtension; 0 H1 n. D1 ?& t4 _( t' X4 D3 y
  PIRP Irp;8 V4 ]0 w8 E! N
  NTSTATUS ntStatus;
1 Y9 N5 N" Q! F2 [6 N/ k
9 ]9 l$ u$ c0 H& F' N7 d  KeyFilterDevice = KeyDriver->DeviceObject; 5 H* |( l1 e- u# ^
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;   l6 W& A# U, U! B, Z4 q
  KeyDevice = KeyExtension->TargetDevice; ) {2 P" ?; k+ Z: D8 t' [

' b. b2 ~5 d* g  IoDetachDevice( KeyDevice );
4 V( G$ A! A- }/ S$ ?) }) T/ n8 H
# ]5 g5 n9 w7 N4 f1 t9 c7 d  //
2 J; J# v( b4 P  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
! Y8 s$ L- F- i: X4 _; h  //- u/ ~/ n$ Z. A2 C4 j7 W& m
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
- b4 `* {/ l9 a( X5 o) B  {
2 l9 H9 n; v7 x, k7 {3 Y8 {, i    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
9 c; X- j" e/ G5 ?/ \& v    {
5 {- G! r9 j1 D      //
2 G7 r0 O: Q2 G; O/ P      // 成功则直接退出删除键盘过滤设备
4 u* |+ T8 W0 `) [3 S      //0 O+ b$ g" }, k7 |9 L
      DbgPrint( "CancelKeyboardIrp() is ok\n" );5 ~2 n! e( r& \; b3 e: o
      goto __End;- a5 `& W$ O, ], {! X8 @
    }
0 m! o$ W& ^% f) t. {  }
, A$ ?# i  ?2 ~7 `: S* c
/ r9 s5 y2 A1 \* \2 k  //) O- o( V* n% E  l
  // 如果取消失败,则一直等待按键
' @* R" t; K6 c  //" @* _4 A. c: M! m
  while ( KeyExtension->IrpsInProgress > 0 )
6 h3 L, ^* {+ E  {( [, I7 Q9 j7 Z$ w% Y( ]
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );/ z$ `( S2 m- L. Y
  }! W; z- N* O. @
* o( \- o7 |) T' G% H5 b
  __End:
$ [% K% C. V& L1 {  IoDeleteDevice( KeyFilterDevice ); # Z& O% }8 ], C' a! B; H) e

# S% v, o: g  H) K  return ;
# T. i7 h+ J9 Y- y9 E' o0 h}
; K+ V3 Z( ], R* a, p  o2 F7 @: i6 ^/ `* k
/////////////////////////////////////////////////////////////////
' F6 X8 H, j+ k# ?% D// 函数类型 : 自定义工具函数1 o# w4 A- \# f! V
// 函数模块 : 键盘过滤模块
9 c8 G( v- p7 L/////////////////////////////////////////////////////////////////  e# U! @  J5 U, N
// 功能 : 取消 IRP 操作
# Y) z0 u1 M8 d, B' d; g2 M6 W// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能6 d& O5 i8 k; J) p/ X6 C" U$ ~" ]
//        使用此方法来取消 IRP
5 ~/ V0 k/ Q! r////////////////////////////////////////////////////////////////// ^3 B* m- @# k/ {  o% G
// 作者 : sinister
1 g2 ?* ]8 }/ R7 v. Z// 发布版本 : 1.00.00
$ D9 r. q( `) Z$ I- L8 _$ x: q// 发布日期 : 2007.02.20
- B) @% x0 n% U! m% Y" V/////////////////////////////////////////////////////////////////
2 p. o3 H  I  l, A( ]+ W// 重   大   修   改   历   史
( h+ L: O0 C) i/////////////////////////////////////////////////////////////////, j& `0 W' n$ \. L' W0 y2 q
// 修改者 :   f8 q2 D3 X/ ?/ [' f+ y: H
// 修改日期 : % W4 ]" t. e) l! l  L
// 修改内容 :
( B7 V3 ^" p' o/////////////////////////////////////////////////////////////////7 F' r7 c% T" g# p7 k* [* f
" d$ _$ J1 c0 J1 F* ~2 h& c; y5 w4 N
BOOLEAN: w" B( N3 K% \" h
CancelKeyboardIrp( IN PIRP Irp )
0 O+ n3 u  D! L+ o5 {' _, n; W{9 b/ Z8 [# A& X  s, W2 }
  if ( Irp == NULL )$ {6 o0 T: S* A2 J, H8 @( `& }) N
  {
. W, g% a( |3 @0 u: s  G    DbgPrint( "CancelKeyboardIrp: Irp error\n" );+ I9 f0 v$ ~8 z; q
    return FALSE;
. Y2 ?  k3 i# H8 {2 K3 |  }0 r) p' H4 C/ x% {1 C

$ g0 z8 B+ P& ?( R3 F
4 k% U9 Y) m1 A  //
- B2 g* I3 G: Q/ k8 Q) [$ T' a0 m  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,  x2 Z7 t$ w: _0 }3 l4 L3 u
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
% x; o) M5 B0 o  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
8 n* O9 }8 `; q7 R" A2 N  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD1 |2 d9 ]2 A$ I; Z- B& T9 x, f! ~
  //' _# m7 _) S# e9 s1 L$ ?6 S) x

. }4 M7 \7 c* K7 N  //
8 H  H4 j6 S! G6 _! M4 U4 F& _  // 如果正在取消或没有取消例程则直接返回 FALSE: M" G: Q$ s) b) U3 v0 @5 E' z
  //
$ ~: u3 E4 q$ ?: R/ b  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
9 s" l/ y9 X4 B8 j- E$ B. P7 h  {
  ?. i0 m% ]5 X* u* ]( ^) k8 D    DbgPrint( "Can't Cancel the irp\n" );6 I) ^8 G# C8 v5 i$ }
    return FALSE;5 y9 L: P9 B6 O* e. g
  }
$ m' T0 }6 D( [  x9 b
0 y* y, {- }- x6 k0 ^6 K# A  if ( FALSE == IoCancelIrp( Irp ) ); h4 M  r: ]$ }
  {
) s  e% D. [- G) U. ?$ @4 B4 C    DbgPrint( "IoCancelIrp() to failed\n" );. G# u; r! X, u+ D9 [. B
    return FALSE;
* S# O2 f1 G6 e9 P8 i5 q% u- @4 y  }
8 t# E# Q3 t- Z+ }8 e9 v% d' v$ ?6 M( V
  //
1 B& S5 E2 \- N* g  // 取消后重设此例程为空
3 C, S- [) q; z  //: j, |, @' {0 M1 l, s; w1 X! @" w
  IoSetCancelRoutine( Irp, NULL );
1 v: C" w' h9 m" v& V* m0 L3 |9 d
3 y/ b- k  f9 {5 c# L! v  y& e  return TRUE;* L: L3 i1 _5 o) ~! U9 A
}% v4 [: }4 w& {" U8 w- ^  O

) T9 B  j* }. j  V# T% m' _/////////////////////////////////////////////////////////////////
# @5 h  i% Z7 p, c2 |3 v: z// 函数类型 : 自定义工具函数1 H4 [7 I. ~, p/ ^
// 函数模块 : 设备栈信息模块
: X' q" N/ J6 A" B/////////////////////////////////////////////////////////////////& Y" s7 n/ E( G0 {3 p
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘9 c) h) }" Z: }( V. _) Z
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
, j9 k& @0 f$ L2 o; i! u* ]// 注意 :
9 u- f, d$ P% L: A/////////////////////////////////////////////////////////////////
, @& \( V7 g9 [. j2 v1 l, I// 作者 : sinister
/ [& S% A1 r( Z& z+ k// 发布版本 : 1.00.00
8 L: v6 x6 T) ~! ?4 G; S// 发布日期 : 2005.06.02: I& H8 p. f$ O. H, J/ S0 x
/////////////////////////////////////////////////////////////////( b6 A+ i& M3 C& o& A, j
// 重   大   修   改   历   史
4 B; v0 b* E& d# Z( Z) ~////////////////////////////////////////////////////////////////// G. l& c$ b) a% h
// 修改者 : sinister
9 {0 |8 H" ^: d// 修改日期 : 2007.2.12* n- [: B  P* g& R
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
) K7 x( f$ a% m' a  }  |3 d/////////////////////////////////////////////////////////////////- a" Q- V! I) u2 }( d$ @' H& k  r
6 M; ~6 C- ]" i$ G6 D
BOOLEAN
: E, v% Q, T: v- g) y: [# c6 YGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
8 g  u# S0 |; K6 J{4 Q. [8 ~7 ]7 z# h& n
  PDEVICE_OBJECT DeviceObject;
2 g: B- G' U- Z) ~; R0 k  BOOLEAN bFound = FALSE;, H) q4 Y9 D* D) C7 Z. A% w8 _
7 `+ s) i4 f  P+ R( B! T) ~
  if ( DevObj == NULL )% {! R" \8 v- k; p
  {# r5 v8 F* I3 |' F5 ?; w+ _
    DbgPrint( "DevObj is NULL!\n" );
$ P3 _, [# L4 E2 [$ z) _' [" I8 p    return FALSE;4 k3 [  F( a, [4 A
  }
% h! E! V9 Q1 s2 j+ b4 P% ~2 @' x8 y( y
  DeviceObject = DevObj->AttachedDevice;
. O5 m( O# ?2 g/ }* F/ z; m- n4 D" t& N
  while ( DeviceObject )
) L" B' C+ q: y7 f; C  {! f7 z/ [6 [! p9 {9 |8 x2 Y
    //- C! [$ l+ P* N# V8 ~* e
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但% F6 _! @/ }6 a
    // 有一次足够了。这算是经验之谈
6 I, v5 }- n( C    //" z* q7 R$ e" C. f4 b
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
/ A2 u. ~/ [# h- m& J    {6 `/ @' u" b4 R) }! X% V
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
: E( o, ^6 k) b: j* X5 u                DeviceObject->DriverObject->DriverName.Buffer,: ?" d: v3 _6 E8 {5 c
                DeviceObject->DriverObject,! p: ]; n- l2 E) i4 F
                DeviceObject );7 _* n8 x8 d& f$ J( ?
1 a: R1 H8 K& N3 O; \3 B1 z, p
      //* A& c! u/ z5 Y. A$ _3 G) M
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
5 z8 j. _( w  b# H      //
! @0 j6 W5 b/ _. A, o6 j* [      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
2 d) r5 n* j( Z) A3 L9 D( C6 W                      KDBDEVICENAME,
: D* Y1 A  g0 l& v8 r                      wcslen( KDBDEVICENAME ) ) == 0 )* ]. y* t4 Q3 V- \) J
      {
0 k/ g$ w% @4 b" ?        DbgPrint( "Found kbdhid Device\n" );
; p( y$ K/ ^; P' R( `* B        bFound = TRUE;9 L6 B+ t6 t  d. |' D/ r
        break;
5 s7 s7 ~- Z. A$ H' B/ j      }+ K, I$ O/ t$ F' R, x
    }# w  {9 ?7 c1 U' C3 W

& X4 U/ u- h) B+ s    DeviceObject = DeviceObject->AttachedDevice;
: f  {/ ^0 Q/ e, B& U  }  R; f0 v. n9 A6 M  s2 y( z# ^
( r/ E! r5 b) U9 q
  return bFound;
, ~* s% o& ]3 \! O: a( b}: j' U- R1 p5 B; d% W1 i8 h
# {4 }' p0 ?) O4 p% e. c; [
/////////////////////////////////////////////////////////////////7 U. ~8 |, w$ I; I" r
// 函数类型 : 自定义工具函数- @# G2 r" z4 }
// 函数模块 : 设备栈信息模块* |5 A$ k7 D$ k- \8 p( L, T; Q
/////////////////////////////////////////////////////////////////
: z2 o* E8 C; |6 v$ B* W4 }// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
" o. S! n( p8 ^* a/ V/ k" I1 o// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改( a# o# d" f& e: a5 y  X  V
/////////////////////////////////////////////////////////////////
) m" {2 u1 x/ v! w// 作者 : sinister
5 m5 F3 I7 N& x- K% ?// 发布版本 : 1.00.00
& Y4 t0 @2 U. B! f0 O1 ]// 发布日期 : 2006.05.02
0 i* j2 T& P+ T* J. W5 [1 ]/////////////////////////////////////////////////////////////////
% V# W" L- ^" m. E2 x// 重   大   修   改   历   史) s; i/ a) j0 ]3 N# m/ E5 p( p. b
/////////////////////////////////////////////////////////////////, V& f( O5 ~& `- c
// 修改者 : sinister& J/ n- n, e& [6 X
// 修改日期 : 2007.2.12
: A! B8 H, O5 _: I: W- I// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
$ i8 D8 K$ o6 `( q) h/////////////////////////////////////////////////////////////////
* J6 R$ s, `5 e6 ]6 [1 F. {' [( ?5 t
VOID
2 O2 U7 w3 P' t% Z% m/ YGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
/ n2 y9 a4 H5 B{0 a, v' R5 X* b; r9 c, K9 V
  POBJECT_HEADER ObjectHeader;
; w1 q" O# H! s" D  POBJECT_HEADER_NAME_INFO ObjectNameInfo;   S* `  K* Y* z% Q% r6 Z, y0 E6 l
( }( f; e* V0 M4 m) r" X. g# c" Y, [1 k
  if ( DevObj == NULL )3 ]  z* n1 A2 H6 w
  {/ c- A9 ^: {, x) q5 I; w4 ?
    DbgPrint( "DevObj is NULL!\n" );; |+ ]6 G3 t0 D! c. R
    return;
" P7 t/ z4 j# ]* e& {) P% }8 e  }
7 Q; D# t( ~. Z" e7 z# T$ Q$ f  P6 I0 t" Q& m& i2 \6 a: Q$ Q2 Y. f* v
  //, a5 E7 Q4 ]) W2 T' e
  // 得到对象头
1 o/ q' z" N) m- b+ z+ q# a  //) b2 h+ C" X8 E) d
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
" {. `, l4 F. @: a/ o
" G& Q6 G. q2 h. o  if ( ObjectHeader )
; G1 {8 W3 D* V" U) p& A, Q  {
2 r) {& S9 V  z" p    //8 u5 @. R3 U, B) N2 H
    // 查询设备名称并打印
0 ~) L1 _+ T, h+ a1 A% Z    //+ v/ @8 C) `8 H, J. v- z
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
. O# m5 Z7 }) k0 D: V
4 d) s: [  {* q, }! G% k    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
+ |/ S( ^. Y/ t    {
+ ~( D4 X- ^) t1 p' w( P      DbgPrint( "Device Name:%S - Device Address:0x%x\n",/ F# C( q4 J, `
                ObjectNameInfo->Name.Buffer,4 x+ T: C2 Z9 z& e" _
                DevObj );+ `3 r% L( A1 |9 H
% y3 k  i0 I  U
      //
, @1 d5 ^6 O  {1 J$ R. [      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
( V" L$ P1 j; [( k      // 用,没有实际的功能用途
3 w( y* a' d1 M. `, }      //
: f: {1 N9 L' _" i7 B4 z5 i7 m. _      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
/ N/ |! n) `2 d. t' ]/ C' P5 k- @
+ g; t3 k: O6 p( r      wcsncpy( szUsbDeviceName,
8 Y. y% ^* G3 a' {               ObjectNameInfo->Name.Buffer,
( l, V: V" J) Y               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
& ?; _* b4 A$ ?. Q    }
1 J/ u% [2 ?7 \. y- F, _* J- j/ V$ ]4 d/ B% x6 [
    //: c4 H" U2 ~3 N8 `
    // 对于没有名称的设备,则打印 NULL
. Z- f% G. m* ~0 Z" y9 Z# j    /// @" z4 @0 S8 z; l& R, k
    else if ( DevObj->DriverObject )
! F7 [& D2 s, h- S2 s5 t& ?3 \    {. u( W6 ~) ?+ }3 T. W7 d
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
( z! b( T! W, S# }0 K                DevObj->DriverObject->DriverName.Buffer,& K; D+ p& c! _: v  u! G7 a! Z* X7 Z
                L"NULL",8 C0 O' h# t* s) |2 ^
                DevObj->DriverObject,
( q% H$ B0 ?# C" K4 i$ ]/ ]* U" y                DevObj );
) W& c* H' k( q5 c! S2 |, T( ^    }
: j0 o4 ~% {7 `4 k1 b  }
8 G/ }& C2 N8 [1 _}- L  ^& V+ c6 U8 q

; c. @9 K; e+ _& G  d) p  q/////////////////////////////////////////////////////////////////
9 `+ G1 ]3 \: J7 [, u// 函数类型 : 自定义工具函数
7 P( V1 a" {) x// 函数模块 : 键盘过滤模块% ]+ r2 _+ S5 H# A  m
/////////////////////////////////////////////////////////////////
% T  m' b7 Q; d0 x+ k: {( M+ w// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
$ U4 E, n* D$ U% ~//        对象,过滤出 USB 键盘设备,将其设备对象返回
* k4 i6 `6 S( N// 注意 : + K6 @2 S) p% `4 R" P: [
/////////////////////////////////////////////////////////////////
0 x* G' ~8 b* {5 l. P( a// 作者 : sinister( [5 Y5 B/ v# @3 [. a* `  @
// 发布版本 : 1.00.00
/ \/ L7 C4 Q) M2 Z// 发布日期 : 2007.02.13
% T# j- J+ S" S+ W4 h/////////////////////////////////////////////////////////////////. K# Z6 M0 ?4 @  g1 r* e
// 重   大   修   改   历   史
) o! W- S- Z- g9 v9 \1 b6 {/////////////////////////////////////////////////////////////////
3 X" {2 b) ?5 r) T// 修改者 : 2 Z  h$ a$ h1 F& E7 ~
// 修改日期 : ' J/ Z" ?/ u' p" s3 l
// 修改内容 :
+ x7 w4 q8 H$ W+ z/////////////////////////////////////////////////////////////////
( X: y% i. {+ N! _4 B: O2 t4 n" n" g9 C& R1 H; K+ H
NTSTATUS
" W# j! R% g7 g( b1 XGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )$ N3 F4 g% T9 N/ D( B3 b7 v
{" ]' }4 {; o# W$ J
  UNICODE_STRING DriverName;9 @  |/ F- X0 c) b0 c1 B
  PDRIVER_OBJECT DriverObject = NULL;
2 S: }9 W! N$ e6 `: S' |) `. p  PDEVICE_OBJECT DeviceObject = NULL;
3 k4 e$ [5 e: X; o% G* A  @7 G9 P5 s# T  BOOLEAN bFound = FALSE;' g4 Q; x$ J4 b2 V

3 L, K; a7 ]4 n% ^* G, C  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );. [* X$ n7 R+ |5 L

* ^' g" T( Z* X" x  ObReferenceObjectByName( &DriverName,
! p( D- l* ?. ]: M                           OBJ_CASE_INSENSITIVE,) H. s+ }6 r3 P0 R7 O% i+ F  h
                           NULL,5 _8 {% ~, r3 b, K
                           0,/ c. N4 z2 s5 T
                           ( POBJECT_TYPE ) IoDriverObjectType,8 F+ T# W& s9 k
                           KernelMode,
$ h* C# c  J- Z  ~                           NULL,& O# Z( _9 ^+ W
                           &DriverObject );; j  ~3 x1 |, X* c2 e+ Z# A' t

2 d# r, G, C% s" h# E  if ( DriverObject == NULL )7 t9 l2 U5 K6 ]- j5 w9 g
  {
( u7 ?0 |) e$ Y" I    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
6 T9 m5 W) Q8 v/ s    return STATUS_UNSUCCESSFUL;
( ?; `1 M$ U0 o" }, G  }3 g- I/ h0 D8 k% O4 o0 E# M
3 x  _" K) k0 q. E, y; R) I$ ~! B
  DeviceObject = DriverObject->DeviceObject;
8 x/ y7 e, l$ n4 X; I! W
8 ^; ~' X" y6 G& Y  while ( DeviceObject )* F6 u7 o, A& g5 O1 O$ p
  {
' n1 j: a. k3 a/ h" |    GetDeviceObjectInfo( DeviceObject );
$ u* |8 g9 O: J4 d& d3 B/ Q" x* B* _4 @, d+ {) l
    if ( DeviceObject->AttachedDevice )# `1 J7 O) v8 [1 k) H
    {
4 {! X( a3 |: w: R/ }* a      //
* q- c6 \! M9 O( d: f8 d+ T      // 查找 USB 键盘设备& [  D- ]7 ~# u( k9 |1 w# {4 P* O
      //+ Z( J2 v. A; N. y; r
      if ( GetAttachedDeviceInfo( DeviceObject ) )
' Z+ R  j, X( T8 I. P% I      {! a0 D0 ~3 L4 E
        bFound = TRUE;
: I# L8 g% f3 D* v" z: {) Z        goto __End;
( B1 v5 {" V" t2 o! |9 o+ |, O6 O      }
8 D& z6 ?% ]1 U3 ?! @    }2 e+ D1 O+ q% v$ l
5 L& [# l( L, h% v: `* X& v
    DeviceObject = DeviceObject->NextDevice;$ {+ p, R4 L# b9 }+ j# r6 L
  }/ @& [# i9 G8 e# q

" @$ D( q3 x1 ]  __End:( [; R  H2 ]- h+ [
8 ^5 G: B, T; U  v) M4 A- I
  if ( bFound )3 a. z+ y. P+ P+ l5 Z; U4 f
  {3 ~7 L3 T8 J/ G8 s
    //1 N" \- B% v* y/ ~/ b% J" V
    // 找到则返回 USB 键盘设备对象
  c$ z6 @* n% s    //
1 O- c/ I! m8 H    *UsbDeviceObject = DeviceObject;
0 Y- M, g4 ^$ r/ N  ~) v  s  }2 p! r7 b- Z$ E; H# _* J: u4 b8 T
  else" d  c" Z1 E, ?3 }
  {/ I! K& E8 e0 K2 E  S" C3 n
    *UsbDeviceObject = NULL;
6 ?/ R% a4 W/ Q1 e+ _! C1 s  }7 P& e7 f( h3 B8 @* Z" |

" }3 |) @2 O  V4 q, N5 j  return STATUS_SUCCESS;9 u2 r/ B& R+ C# `1 a6 [
}' u7 m% V  h6 S% l

; D; i. y4 X+ D1 t) H5 p2 y# s/////////////////////////////////////////////////////////////////4 ?% v" L  U5 `, y: N  A9 g
// 函数类型 : 自定义工具函数
- J, n8 z/ `3 {0 `// 函数模块 : 键盘过滤模块
8 k" S2 V) `: u- U/ g4 j& z////////////////////////////////////////////////////////////////6 G. y  P" Q$ @! s- o: v
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关& H4 F4 @. f$ `; r0 V
//        信息,返回附加后的驱动对象
. E9 |" u' n" Y& Y" t6 T# r8 a# @. e' H// 注意 : 此函数仅挂接 USB 键盘设备
$ x1 d( @; W0 ?8 H+ w* l- E* J9 M/////////////////////////////////////////////////////////////////
, k" n2 G" Z: Z1 z, A// 作者 : sinister' j7 a! }2 U0 n/ r" o" U# n
// 发布版本 : 1.00.00
! r; I: I; |: V5 B// 发布日期 : 2005.12.27
: Q( ~; B, ?6 y. ~. h/////////////////////////////////////////////////////////////////! X5 k4 d% E% z8 a" P, \! I
// 重   大   修   改   历   史
5 B) D* u5 p: ^////////////////////////////////////////////////////////////////' _$ {4 k7 J( L3 ]" l
// 修改者 :
% J# V( ^8 ^  a/ o4 y3 b0 }. y// 修改日期 :' f! `6 w9 n4 l7 `
// 修改内容 :
9 `" G) A/ K, H/////////////////////////////////////////////////////////////////5 @7 w5 |$ G$ B% w1 s/ J5 M" s

& {% v6 c/ r% }, YNTSTATUS
% Y9 t/ J* b1 u+ o- f7 {AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
7 ^9 k9 ~; I/ ?                         IN PDRIVER_OBJECT  DriverObject )
2 Y  Y- O9 N: t; F! A; P{, e5 X5 o& E! L
  PDEVICE_OBJECT DeviceObject;
( }: Z4 T9 _) G% B6 T  PDEVICE_OBJECT TargetDevice; , @% S, Z/ \0 I' ]0 K: T' Z
  PDEVICE_EXTENSION DevExt;0 ^7 H9 T4 w1 [" U& y5 o
  NTSTATUS ntStatus;- d1 l1 V- N1 c7 q
/ I8 P! Z2 ~6 ?( W6 C1 R3 h' X
  //; K8 E! N& k2 q2 v& I3 u
  // 创建过滤设备对象% ]/ Y4 C, L6 K2 i2 ?
  //, A+ d( |" L8 g8 ?0 B. o' p) w, P* b4 p1 w
  ntStatus = IoCreateDevice( DriverObject,7 I) [; j! J, y" |! ]0 T
                             sizeof( DEVICE_EXTENSION ),3 c1 Y) r1 j& l+ M
                             NULL,
4 p- C( L' G7 D2 g5 |3 \                             FILE_DEVICE_UNKNOWN,
7 |0 @9 C# W0 n7 j2 m, ~: g1 Z                             0,( D  y3 B, A0 l, k
                             FALSE,
/ S( N% M; u# C7 X6 K' J1 n$ o2 c                             &DeviceObject );
& ]9 A+ _# q' F, p. u- k! B/ ^: Q
( T* `9 M) |: A; ~( k+ F- S9 F  if ( !NT_SUCCESS( ntStatus ) )
. ~  D) o3 o1 F% V5 I0 V* r# ~  {, k, @( M- f' K6 x1 T
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
0 H! G; Z0 m- [. R& p! E    return ntStatus;
5 Z0 |( O( G* w  }
2 m6 K* A1 |( }) v! D
. q  v! Y# `  \5 G+ M0 e- s  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
. K# q7 r/ i# w  Q$ E$ R, e
, _5 W( G+ g0 c' |1 I  //3 y# N& ^( C% U
  // 初始化自旋锁
8 k# \% R. ^) d  //
% U$ W( f  V3 Y7 f  KeInitializeSpinLock( &DevExt->SpinLock );
; |# V: `8 N, `1 \* I- t3 ~
& J) ?4 X) e  E  //
1 s2 f, T3 z9 T  // 初始化 IRP 计数器" y& }- N4 m( S3 o3 h% V" |
  //) |' S0 w; e) @* x& F( {$ j6 o
  DevExt->IrpsInProgress = 0;2 K# C; l' Z. @5 s; J9 y0 A- e
) i# F, g7 B% Z% V
  //! E+ k  x- \: ~# y
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
3 P9 G2 y0 r" Q1 p( M0 i$ g! q  //. I0 H7 b( I$ Q

/ `' V# }1 x' S# o5 Y" {  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 3 z" C+ w" H' z" s- \5 S
  if ( !TargetDevice )
" S, T& b# m; ?& v2 Z  |$ |  {
4 k6 f) ~9 k% I" t0 z" {+ _+ |    IoDeleteDevice( DeviceObject );
6 @8 V+ z* W3 }/ z1 q( b9 C$ }; Q    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );1 T  }* }8 i9 k
    return STATUS_INSUFFICIENT_RESOURCES;6 v6 d. q" ?5 h4 _/ M8 @5 R& V. i
  } % t- o- `1 W) H. V5 G9 t" _
$ g9 x: l, a0 p% p, L
  //
1 n* D3 H) V9 M( _) K4 b  // 保存过滤设备信息* U7 Y# i8 @; i$ R
  //
# B8 X/ s5 \* C0 a4 n) V! q  `! d  DevExt->DeviceObject = DeviceObject; & X5 `, I* C* F6 q+ I+ Y' Z: d
  DevExt->TargetDevice = TargetDevice;, T, K( R% {' \1 o# O

" y5 l  |1 B7 o- ^' X5 s% F" e  //2 _+ N/ z/ u: N  K2 [
  // 设置过滤设备相关信息与标志- \( o  ]  N$ q! J; ~+ r/ f
  //3 r3 ]  y8 {1 {1 k+ t6 ~
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
: i' z: [& a3 t8 Q5 _. h! q, Y  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
7 m+ B" n, W5 `' Z- z
3 L; O! u4 y+ m' m; M* U3 }$ j& B+ C; ?1 f: o: O
  return STATUS_SUCCESS;% y3 {8 U9 s0 M; T& Q
}: p/ H8 ^' D  k/ A, r8 a+ \

6 r, D9 b8 }5 Q8 k0 U. Y/////////////////////////////////////////////////////////////////
% X; K- c( S2 V- a, f- g5 [$ w/ C' ?// 函数类型 : 自定义工具函数
! L* A/ z4 c9 l) S3 e# X% U// 函数模块 : 键盘过滤模块0 g1 r/ R; b. k' ]3 Z! g: l
////////////////////////////////////////////////////////////////, G6 s6 D+ @' M8 m! E0 X2 w# F1 D
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
* k% V& b- o5 z//        信息,返回附加后的驱动对象% g6 I) }3 y& i1 ^
// 注意 : 此函数仅挂接 PS/2 键盘设备
2 Y3 m7 |& [7 n9 n+ J/////////////////////////////////////////////////////////////////- S1 W' a5 z' K9 i4 I
// 作者 : sinister
8 n3 @) N: x1 D// 发布版本 : 1.00.00$ P. y) `% J7 f( I, X, _  s
// 发布日期 : 2005.12.275 t- B2 {3 ]5 `
/////////////////////////////////////////////////////////////////
5 ^9 }( V( P, I+ T// 重   大   修   改   历   史3 B8 }: [1 l( J$ S; U
////////////////////////////////////////////////////////////////
3 V( z; j! x5 H. d/ ~// 修改者 :
$ C$ x- ]1 f/ ]! z7 c! M// 修改日期 :
- q2 u8 c  ]. v$ L1 y. k  O9 z. F// 修改内容 :" x; C3 I  v8 k% {  ~/ n/ x+ Y9 d3 c* K
/////////////////////////////////////////////////////////////////( n; j0 @2 n) G8 d9 T& T, |
7 W0 Q3 D' Z' S1 q' S1 |5 Z& h
NTSTATUS
! M0 q9 E8 F$ j! d4 u" x  H4 {7 vAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名* B7 h  h' I: C* p7 K7 o0 q
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
, c- X5 r! k# p: o0 F9 S& e                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象1 m" A0 e  F$ u; n. l4 N
{4 j- n, S% x4 e; [# a& s, K
  PDEVICE_OBJECT DeviceObject;
2 U" b& |2 a9 R0 E; h  PDEVICE_OBJECT FilterDeviceObject;5 |! b$ E, F! V/ R* q( {8 X
  PDEVICE_OBJECT TargetDevice; 8 A2 n/ z1 W3 B' I. Q4 T
  PFILE_OBJECT FileObject;
: n! O9 A7 F" m0 Q  PDEVICE_EXTENSION DevExt;- G- S) `. [$ T, Q0 o
0 {# w3 H3 q  m5 p2 W
  NTSTATUS ntStatus;
; e; T5 I& c7 _4 N) p2 x4 k
6 x& m/ b; v' T5 V' F: U* x# Q  //$ s" V6 s5 k. O5 O6 B# U) {
  // 根据设备名称找到需要附加的设备对象4 @. y# n1 e, }
  //
3 G& T+ N! k; G7 a$ a* Z" \: K. q8 ]  ntStatus = IoGetDeviceObjectPointer( DeviceName,) o7 s9 C4 |; I' _4 M
                                       FILE_ALL_ACCESS,6 q2 C1 h9 o, ~8 \# j% Q0 E4 |
                                       &FileObject,  B& d; X7 |. d" g2 w7 ~4 T
                                       &DeviceObject );
) V0 U) \, ~; D9 ?7 c8 [
2 `( I8 h' F/ V! Q, I3 G7 p  if ( !NT_SUCCESS( ntStatus ) )/ N4 q: I  z4 i% b
  {) y. L7 x( ^) W+ o% W
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );& W$ C$ L) {2 Q: e
    return ntStatus;! `0 B5 q" s$ a# M
  }
2 j3 Q( Q/ \- G3 ?! M
6 y: ^4 M7 c4 X4 j7 p/ n+ d+ o  //
. r2 O: d$ c2 t; r  // 创建过滤设备对象
8 \5 ~1 t( j( p" G7 E5 n  G  //  \1 ~/ y8 D1 u3 c; Z( C' f
  ntStatus = IoCreateDevice( DriverObject,
9 U8 |8 h5 c% J7 U                             sizeof( DEVICE_EXTENSION ),
% y2 M! L5 h. ]/ h- f' L4 o' b( Q                             NULL,
7 T, R' Q1 j6 N# `: O                             FILE_DEVICE_KEYBOARD,6 ]$ F. A7 |6 O
                             0,) s  G. ?; }9 Q6 Y
                             FALSE,, M6 ~' T# s; c4 h
                             &FilterDeviceObject );
7 H" |) K! c  j$ @9 F" y2 \+ {4 N  Q1 k8 m
  if ( !NT_SUCCESS( ntStatus ) )
7 |/ }. D; z9 f3 \9 T- D  {
, I4 K) B0 T  K9 ]. ^    ObDereferenceObject( FileObject );
0 M( I1 Z0 A1 m$ c    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
: X& v' Z; |' N. L4 A9 n    return ntStatus;7 [+ c: o- c) R0 s
  }
+ S/ ^; k% @' V. ?, M# o( d/ h! ]
& w+ R% }" x$ }8 f4 K1 N9 h5 K6 G  //
, B$ M4 S6 R0 z4 N* Y: S  // 得到设备扩展结构,以便下面保存过滤设备信息
! H2 B$ j* N2 j- u# d1 \  //+ F" H7 n( f: q* O6 X* \: {& p
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
& T# `/ M& m5 b# y; }) u% q$ o* B
1 \; @! S! C( A: r; X7 H4 U
& j! L' y0 C/ y2 S/ o( Z  /// ~: k4 ^" Y# a: k
  // 初始化自旋锁" A# L" B. a' v; Z  Y
  //
5 Y3 ?2 @% C- t6 n4 D  KeInitializeSpinLock( &DevExt->SpinLock );1 u) ]* W% C1 }4 q
. Q0 V& r2 \1 }) b, K7 r
  //2 j, ]# v9 |) m* l
  // 初始化 IRP 计数器4 ?0 D# Y& t+ p6 d: r6 }
  //1 t# ?( C6 ]( n  s
  DevExt->IrpsInProgress = 0;
  J4 p  `6 F) U% G
* J5 s) C2 x$ y1 I6 \; O  //
/ ?+ S$ Y4 d: U" t) x- Y  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象! A* P$ R8 w8 M" ?- x
  //# {$ F6 k# O% b! T( k- m
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
. v( R2 q! Y; ]& S/ _                                              DeviceObject ); ( g5 Y) B9 e$ S( a& l
  if ( !TargetDevice )  n# y: |4 Y* \( z) b( o+ u
  {
5 u! {4 b6 T% _" s1 P# h/ I% ]    ObDereferenceObject( FileObject ); 2 o" n! n5 h  \! P7 \
    IoDeleteDevice( FilterDeviceObject );
( l) `+ I1 l. J% q    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
( ]  D6 X$ v. f# l1 g    return STATUS_INSUFFICIENT_RESOURCES;
' o5 c- y+ H2 n  t9 @  A  } 0 Q1 ?0 [* t/ ~' ~% z* W7 r( u
) C6 D: k4 I, u" G
  /// t9 q1 q! \) ^1 A, @
  // 保存过滤设备信息
" A6 B9 F% C/ z/ b2 d  //0 i3 e" f3 [+ T
  DevExt->DeviceObject = FilterDeviceObject;
8 |! Q) k8 \5 n2 Q& @6 x- B' X& g  DevExt->TargetDevice = TargetDevice;
/ E: w+ j& H! N( v+ r  DevExt->pFilterFileObject = FileObject;
& V; A1 Z& Q/ U2 Q: W; \5 V6 n
, S( t& D' G' i! t4 G  //7 v. M. v# J* Q$ C  P7 O$ j- X9 }) J
  // 设置过滤设备相关信息与标志3 l6 c( j8 O* O
  //) I  r: u# u$ V9 q# l: [8 X" k
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 5 a% \7 R. b# l0 c3 v  |! K
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 3 J, f$ U- p$ k2 L
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;# U! g6 s/ h2 w) D1 D
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |$ o( ~, S* F( B! \8 {" O
                                                         DO_BUFFERED_IO ) );   ]7 e( v% E- c1 r/ N

4 w9 r1 @5 D2 S4 @: D  //
* j! U' {/ i7 U8 F+ I  // 返回附加后的驱动对象5 ^3 ]2 ]0 P4 h9 E. z
  //
) P3 D# N1 c7 [+ z! I6 R  *FilterDriverObject = TargetDevice->DriverObject;' F) _$ n, y/ A
3 X; E) B8 |0 d4 I4 ?
  ObDereferenceObject( FileObject ); 7 k* u) K4 f! I, n3 t9 d! G

  f6 [: D8 ^# h* g: r8 }  v5 q6 M  return STATUS_SUCCESS;
3 d* u6 H8 G$ m}
% m) t- v* l3 |. F% A) t8 B( U* C% }7 `3 G1 `$ e! x& l. k
/////////////////////////////////////////////////////////////////& y- G0 J: ]; u* s4 X  d
// 函数类型 : 自定义工具函数9 y  d& g- C" k; w& K+ K
// 函数模块 : 键盘过滤模块
+ Y: R! d, J4 o* G: F* q////////////////////////////////////////////////////////////////) g% \1 Q: U: i. W- Z0 L
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
5 y6 K1 h- l( e9 V& G8 B# l0 b7 j4 _//        这个 IRP 的完成& h3 B  x! y" h% f0 W
// 注意 : " ~' H* ?- l! k2 |; y
/////////////////////////////////////////////////////////////////5 `: P, \9 j7 P; U
// 作者 : sinister' M3 K8 I3 p# H* |- z) g, J- N
// 发布版本 : 1.00.002 E' d# M* Y, e9 c3 k7 D
// 发布日期 : 2007.2.15
" U8 T! x" r5 Q2 A: k0 T7 v: t, b+ y/////////////////////////////////////////////////////////////////; l+ W) x; C1 W# u) H" W
// 重   大   修   改   历   史3 f  ^# m; L' V4 B8 v8 b
////////////////////////////////////////////////////////////////, Q& J7 T8 C" ]  i9 e
// 修改者 :8 p4 [) i3 u& a! d0 n* o$ v6 a
// 修改日期 :5 |1 \. v/ }4 E3 M7 s
// 修改内容 :" s  X% M' z! b& j6 \
/////////////////////////////////////////////////////////////////
6 f+ f2 V/ H5 g0 h0 H( f; V; E
3 R0 B; J; k7 FNTSTATUS
. Y% p- t" Q9 E# Q# B6 q9 ?KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )  A; j9 P8 C: u. s
{
+ ~  ^6 Y: l: e& V5 M  NTSTATUS status; " |3 o' c7 z9 i6 H& o6 ]- P
  KIRQL IrqLevel;
) P, d' N9 W2 a" W! H' b+ |$ [1 F1 a, l- S# W: C
  PDEVICE_OBJECT pDeviceObject;
0 ~" A5 ^9 }/ \  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
6 F$ I* S" m; G# z2 Z( D                                   DeviceObject->DeviceExtension; 7 m0 {$ u/ \) E! ]+ b' T

' G9 t$ F! J1 L1 @, A! `+ ?* \" y+ Y( x
  IoCopyCurrentIrpStackLocationToNext( Irp );
. p/ L: X/ W6 [3 y3 J
8 ~, f' g, p9 G6 k# b" O# X  //, u# w; l9 @( ?  O9 w
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁; m. I* |7 g* f+ ~- {. A8 z
  //
8 `: J. @7 p0 |  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
- n8 q+ P9 s/ n. ]) t1 X  R  V  InterlockedIncrement( &KeyExtension->IrpsInProgress );
+ n3 A: I; g* d  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
. T- |! D* ^6 h# q7 |; }' e1 X. p! [: M6 P5 s. i3 `2 W
  IoSetCompletionRoutine( Irp,
' w/ `3 `6 a( B# _" w                          KeyReadCompletion,0 f/ k  K$ I! u2 I6 |
                          DeviceObject,
7 h% d! {8 Z2 o2 v$ U, H6 ], k3 z                          TRUE,
8 \2 k* [0 {! V4 c9 ]6 v" Z8 |* x                          TRUE,
( j1 D7 D: K3 t4 C                          TRUE );
* v4 L! J  [# f3 J% P
8 j) P0 q2 C8 _: c  ~) ]4 Y  return IoCallDriver( KeyExtension->TargetDevice, Irp );5 \0 k+ ?4 `# g/ Y! P0 }2 Z' v# x
} 9 y5 d0 S' P/ \+ H6 |
, n& b4 Q5 C3 \0 [5 @0 H
/////////////////////////////////////////////////////////////////
0 M1 T6 X$ ~8 i2 Z3 J: y// 函数类型 :系统回调函数# Z0 z2 {/ t# C% X- Q
// 函数模块 : 键盘过滤模块/ [' p+ ~* S" K$ _" T
////////////////////////////////////////////////////////////////$ d9 W: c7 Z6 ~; [! A, O
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
1 }0 ~$ n5 g1 U: w& l// 注意 :
" w+ l, L* v2 k9 z% A  [0 T/////////////////////////////////////////////////////////////////9 T" o' x  C  y$ F) ]) ?! g' N& }
// 作者 : sinister
- C7 {  u. I3 ?9 k% v' t- f: ]// 发布版本 : 1.00.00
( S% k3 Y- C) w5 i' p) F! K// 发布日期 : 2007.2.127 d2 u! I5 x- N  F9 @  z
/////////////////////////////////////////////////////////////////' W! o2 q0 M/ w: ?# Y- h/ m5 R
// 重   大   修   改   历   史$ M" D1 Q; p- z9 n0 G
////////////////////////////////////////////////////////////////
: _: V2 ~( c& T// 修改者 :7 q$ O* e7 S) {4 [( ]+ u
// 修改日期 :0 P9 A0 N5 V1 v# |6 M# l/ n* x
// 修改内容 :
& _# h3 D1 F2 o9 m/ w$ G/////////////////////////////////////////////////////////////////
# H0 j. O/ p' |4 z7 g5 a: v6 \
$ @4 j4 R. d/ J2 W4 H& `' aNTSTATUS* L: a7 w" d0 Y
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
, K) _) D+ @/ R                   IN PIRP Irp,
, [! W" m& ]% y0 j. ?% e                   IN PVOID Context )* v: w* V& l$ ~
{
  B% r) M  O: I) V& g9 m2 ~0 f  PIO_STACK_LOCATION IrpSp;
. ?2 R" ~- m# ?( z8 f) ~/ V' |% v  PKEYBOARD_INPUT_DATA KeyData;
- h% ^3 j7 \) |# Q8 N* ]  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
6 S/ \3 r) n! p1 U* j  O3 E+ O! X/ o                                   DeviceObject->DeviceExtension;
# A, y- u' b1 h: m' I, A2 a  int numKeys, i;
& t5 D6 Q! ?: e  KIRQL IrqLevel;
- p* D3 R1 i$ y% }# O8 F# {9 ], X$ O3 J& p$ f, b  j/ h( N: D+ H
  IrpSp = IoGetCurrentIrpStackLocation( Irp );. V6 m" k2 J2 \. R$ y  A7 ]" Y4 n

0 n8 d' O" U6 k6 A; T
7 [3 Q/ Y" k5 d6 z6 `) U  if ( Irp->IoStatus.Status != STATUS_SUCCESS )0 A: g1 x( z5 E4 _, h
  {
. m+ ]% E7 A$ o9 E2 U8 x& ]    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );# `& T+ v3 t9 o( P* ]! q
    goto __RoutineEnd;
. d! m9 H4 e0 U1 E  }) g3 [8 M6 g' {1 I: G
' f" v+ C, r0 Q1 z
  //
" q& N0 J) j* Y& {  // 系统在 SystemBuffer 中保存按键信息
; u: V1 T6 B+ \. L- ]  //
! t2 v/ P  G& x8 b% o2 e  KeyData = Irp->AssociatedIrp.SystemBuffer;
  T. J2 d2 e$ H/ i  if ( KeyData == NULL )0 D/ g" S7 e$ n/ S1 e
  {
# r+ y/ O* q% F/ n. `( H% @9 G    DbgPrint( "KeyData is NULL\n" );
8 W2 w# H8 Y; I% J    goto __RoutineEnd;
. ?) z2 w& L8 d  n; g+ |6 \  }
/ T( B3 I+ H" m7 s8 W- z# e0 G: r& k
$ a+ g2 ]6 ]  V, _- I0 @6 Y  //. J2 h3 F5 D# U' d! Y/ U0 y
  // 得到按键数( [, _  D% Y% w( {5 I; F
  //
" B  P5 f; M6 b  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );: \4 S* R1 l$ t0 a" w, {
  if ( numKeys < 0 )
0 G  Y) X4 ], n  {
% ?1 }7 K& v& U+ U8 T5 `: v    DbgPrint( "numKeys less zero\n" );
" W  t7 M) P5 y5 {    goto __RoutineEnd;
  [6 ^( j$ S' V9 ^: z/ [+ n( W  }1 z9 k3 J7 w2 t8 s" j$ d, D; r
! G; h& w7 G0 c
  //
# U( u2 h7 X0 J7 B# n  [' ]% M  // 使用 0 无效扫描码替换,屏蔽所有按键
3 J  l; c- W+ `  //
. ?) z( T) W% }7 C  for ( i = 0; i < numKeys; i++ )
0 _" b& h' c  j5 O+ U: T  {
6 G" S+ n8 c" ?% ~, s: i    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
: o: v) K! o5 }% o: e, X    KeyData[i].MakeCode = 0x00;
: Y! A1 P5 ]$ q3 l1 y  }
4 T3 K, a) c9 [* n& p1 p  r* ^6 A0 @( f
8 B8 T/ f9 P; u/ ^3 P
  __RoutineEnd : ' B) s! Z/ {# \$ E  f- {
4 t3 h0 P/ G" ~! {, i
  if ( Irp->PendingReturned )5 O6 E8 y, T9 ^' k
  {
& K! U8 |3 v. n9 U" C- @1 C    IoMarkIrpPending( Irp );
% k& z% ~5 e  u) E6 q  }
* R/ j. X: h& e0 O5 h8 n
2 y' O5 ~$ ^( x1 j9 x) ^7 h  //
% Q2 R/ i+ t; p; |( \$ X5 i- Z/ n  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
1 a, F% _( y" N5 L. u1 j+ c  //( ^5 I, f4 c1 D, t* a
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
0 ^2 x% q" N( i  InterlockedDecrement( &KeyExtension->IrpsInProgress );4 T4 |  Z$ }# T, E  i
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
- J$ N/ e4 ^  R( Z3 B3 H
: w' z1 U. G+ h# N  return Irp->IoStatus.Status ;7 W, x" j5 B* C* @6 K" y$ @3 S
}
( d. L- M% f2 b, z4 n+ `' z5 ^) Q0 b# h/ F' L. Y7 G4 e) \- \" [5 g

9 q/ q; Z+ Y' G  n/*****************************************************************3 e  E; K1 J# D2 \1 W6 o
文件名        : WssLockKey.h
: X* X* G: X# l 描述          : 键盘过滤驱动
* k( C- s6 @# K, F5 Q 作者          : sinister. D/ n+ \- @+ ^5 g/ ~3 p
最后修改日期  : 2007-02-26
/ i! [. ]' f9 Z' f*****************************************************************/3 U; E* j- i7 r

7 U/ {8 Q: P/ a! X7 g#ifndef __WSS_LOCKKEY_H_2 N4 i( E' @5 J
#define __WSS_LOCKKEY_H_
+ U- q- w  A3 o8 g1 u( d8 X; L$ N2 d3 D, a! ^( A! ^3 n$ H9 B
#include "ntddk.h"0 B& M3 d5 G1 U" L, r+ A2 A- h! a* L
#include "ntddkbd.h"
, f, X9 J: j3 N4 m# M0 s3 v#include "string.h"
/ L3 ^2 G9 _0 ?4 l" D4 q#include + N6 m0 s9 f* i2 p

/ }- I# a3 z* c( Z#define MAXLEN 256
0 {4 I/ l# a5 [4 m& e' f
& r: j- i+ G3 P: Q3 C#define KDBDEVICENAME L"\\Driver\\kbdhid"
% i1 k4 `& |' o#define USBKEYBOARDNAME L"\\Driver\\hidusb" 1 h6 }4 ~9 y; i' ~. u7 \. g
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
- h5 ?; g) L5 V+ s- O8 @: `. ^; Z% u  N- r: B# e  |1 N4 b6 _
typedef struct _OBJECT_CREATE_INFORMATION
: j; @- o1 ~3 e; v, Y1 C" b2 U1 q{
! Y: c/ v( R2 m2 U    ULONG Attributes;! F5 s0 ^6 ~, ?( {; C) @8 s/ ~5 p
    HANDLE RootDirectory;* e' C( {2 C. i. e. C
    PVOID ParseContext;
" B! S; S8 C9 A) t. S    KPROCESSOR_MODE ProbeMode;; K3 Y( k9 }2 H; P* z: \6 e: V
    ULONG PagedPoolCharge;" @3 m+ ~3 O( W; {
    ULONG NonPagedPoolCharge;
+ l9 ?3 ~8 T1 n- o% ^    ULONG SecurityDescriptorCharge;# H! P0 B( @: m# Y
    PSECURITY_DESCRIPTOR SecurityDescriptor;
+ h3 e! S; I/ f% w4 t  c' j    PSECURITY_QUALITY_OF_SERVICE SecurityQos;$ V, V9 X4 H/ i
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;$ B8 L  n# W- _/ N6 i6 p! V$ D7 O
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;, N5 p! r2 ]- s/ i3 @: _/ U9 C2 R) q
5 q8 y* {* r) s4 W$ L' h
typedef struct _OBJECT_HEADER8 N1 d' M4 }# R9 }) r2 L
{
/ L& L+ ?" S( K, c1 m; l* s    LONG PointerCount;
0 A0 e# V( e) m; }) \4 u8 V    union
3 r, i- N: c3 M% _; e: D    {  g" r" }5 S; v& d5 @0 f; Y
        LONG HandleCount;
6 {8 e8 w+ p7 I3 |+ C        PSINGLE_LIST_ENTRY SEntry;
! i+ O! k0 [+ O    };5 A& v0 l, }2 E6 @/ G; q! L
    POBJECT_TYPE Type;
, k9 E* p" i, ?. `! g# I3 s    UCHAR NameInfoOffset;
  ], {  ^# e+ l% i8 [; }# c+ V& ]    UCHAR HandleInfoOffset;
* M7 g. S+ r9 N  V' x    UCHAR QuotaInfoOffset;
, v' F: \* @0 K4 l    UCHAR Flags;
  U: W) T3 _" C8 V7 V  _5 u/ k    union& e6 J/ k- b3 Z4 F( T4 S
    {! M' X, W, }! M# }
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;  P8 W( W1 S% e( e6 n% N' ]" B
        PVOID QuotaBlockCharged;
  L+ @/ H7 z1 A    };
( r7 `3 H$ p6 E, d, ^1 \: b% g
! F+ p% v4 }* Z$ D7 U5 M8 W6 `+ H" h    PSECURITY_DESCRIPTOR SecurityDescriptor;% E" @$ }6 c* R  x: \3 k4 `( O
    QUAD Body;
/ Z2 S: p" J6 [9 v6 c1 A6 T} OBJECT_HEADER, * POBJECT_HEADER;
) y2 G0 p3 y, a& \' S; p# V7 M3 f5 {+ Y4 J, V0 t1 Z
#define NUMBER_HASH_BUCKETS 37
8 k7 W6 g' w  v' s+ G  _
! F6 M: s- s' M6 @" [typedef struct _OBJECT_DIRECTORY! }; _" I; V9 w  P' Q+ B$ C9 H2 U
{9 O: R. U2 B# p5 e' a# e* D
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
, e, F4 E0 G! ]/ f" T! z3 R    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;" S' e# J/ F& T3 h
    BOOLEAN LookupFound;; o/ `0 B4 Z: u7 H" k7 t- V- u
    USHORT SymbolicLinkUsageCount;
! ~# G+ n6 L& e- |6 H* X2 E    struct _DEVICE_MAP* DeviceMap;
& y( f# u. d  d3 ]: \3 q2 M} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
4 l# R6 f% ]& o4 O1 q1 Q( X% d0 C  z( u0 z8 F- U- h- _. Y3 j  v
typedef struct _OBJECT_HEADER_NAME_INFO9 S1 _! o4 ~0 d% w& N4 U2 T/ V
{
' `6 C" i9 W" H8 }    POBJECT_DIRECTORY Directory;
9 d! r, I' D7 N& Y    UNICODE_STRING Name;
# M6 Y' C  ]2 \; e' \9 Y% X  x    ULONG Reserved;3 W0 j! B: N" d; a$ t! Q3 b+ @/ A
#if DBG; b9 e" g( u& ?( W, T4 R/ z
    ULONG Reserved2 ;
$ t0 @$ T! }) }  M) P. `. E    LONG DbgDereferenceCount ;! O4 }# O# t+ Z& }
#endif' u- h7 Y$ @( L  x0 B  j
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
4 m. A" B: X% T2 w) k0 n( D, r1 |; t, Y+ t) ?4 b0 c& ?
#define OBJECT_TO_OBJECT_HEADER( o ) \
/ X- ]) }* @' x4 h    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
' e! H0 L7 A  T% d  |
3 [5 n% d/ K, Z9 x5 }#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \# T: X" q% L; X5 r7 `
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))/ y9 x( h; a# R8 @5 G* ]3 O" R

) \1 c0 C% z; [( ~9 o) H+ g: }typedef struct _DEVICE_EXTENSION2 o) C& b6 _% v
{
$ b' ?3 Q+ l4 ?    PDEVICE_OBJECT DeviceObject;
6 i+ V+ r3 O5 `    PDEVICE_OBJECT TargetDevice;8 G7 ]  E* N6 z& G7 {
    PFILE_OBJECT pFilterFileObject;& k/ B) `- a8 K7 |4 N8 g
    ULONG DeviceExtensionFlags;
% N3 h, m1 b5 q: n- Z    LONG IrpsInProgress;
: {7 v( C+ N0 d4 M- J    KSPIN_LOCK SpinLock;
( u+ G8 E; z4 v6 O* c6 Z9 a}DEVICE_EXTENSION, * PDEVICE_EXTENSION;, _* i; X7 Y# u3 Y: ?

4 S0 d; F6 H8 ]2 k. T$ }- X
6 m+ ^4 ?. F. N+ p  f' aVOID
. a" [) a) x# T. WKeyDriverUnload( PDRIVER_OBJECT KeyDriver );! O  x) s' t$ u
% N8 Y! y' x. K! w3 n) v- J
BOOLEAN
5 n1 D5 A5 ^& I" h) vCancelKeyboardIrp( IN PIRP Irp );
9 e3 F- y, u, e7 Q7 K4 E. ?8 @/ V4 l- Y
extern POBJECT_TYPE* IoDriverObjectType;" {( J+ Y6 k: \# ]& L3 [
7 m# [5 \6 _# w# K8 F. a
NTSYSAPI1 {, c4 ?) f- @
NTSTATUS
" K5 l- a" R# R4 u) oNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
# v& Y, \4 b) d3 b. r                               IN ULONG Attributes,
. K, U# M/ F/ q: C$ t9 q- J/ [                               IN PACCESS_STATE AccessState OPTIONAL,
8 P9 j4 z( m2 l7 q$ O0 O7 I                               IN ACCESS_MASK DesiredAccess OPTIONAL,0 z; Z9 k% N  |" E; @% o
                               IN POBJECT_TYPE ObjectType,
" o6 u. D! b& `7 u- l; X                               IN KPROCESSOR_MODE AccessMode,! }9 b. |0 C0 x0 W5 G% b4 R! }
                               IN OUT PVOID ParseContext OPTIONAL,
& `+ g, A+ Z+ T6 ]; J4 D- c                               OUT PVOID* Object );
9 X" }$ n+ ?. O- N4 b+ `( d# {1 D. ?) W, k- }6 [
NTSTATUS 5 f8 s- s% Z$ [8 e. ~
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
; Z' s, Y4 c8 ?7 W* l: H! R
! J3 z0 \: U  oBOOLEAN
2 |% D8 S; X" g% a( iGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
/ x* u& h% g, v$ w% }. c: g, O
3 v7 p2 T; ^8 I3 q; Y0 h" MVOID
# G; K" u3 }6 a% `' C, nGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );# d. q" l& o7 D3 t6 b+ C; M
* ~# i, w) m4 a' H  z# y+ r
NTSTATUS 7 ?1 O' ~! L% x! [9 s" Z) y
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
5 d+ s: ?8 [8 C0 a- r                                  IN PDRIVER_OBJECT  DriverObject );0 H2 J$ L# k  L. ]4 N1 m
  |7 p5 j/ r7 p4 h/ r7 Q* |
NTSTATUS
% y! w3 w1 Q9 ]* IAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
, `8 z. }( \) @7 j+ U                                  IN PDRIVER_OBJECT  DriverObject,, M" L: R$ J+ p; w$ A  C) A; B, ]+ D
                                  OUT PDRIVER_OBJECT* FilterDriverObject );
8 y% ?3 Q, q0 h( y1 @: P2 i- G
5 N, [. h# E) F% _NTSTATUS
9 e) F& x# _) k4 F& W2 }KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,0 b5 z3 F  A% T: X6 T3 K
                            IN PIRP Irp,- H8 U: C" o) n9 f, p/ K
                            IN PVOID Context );
5 @$ x8 y4 j7 D" |$ j/ `NTSTATUS
# l! m; F* M. G4 H% i" y+ gKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );' U; h) I7 ^, {" v( N

; ?7 |* [% u/ nWCHAR szUsbDeviceName[MAXLEN];
, G, [2 W6 e# F, {& Y
/ v. O! K* U4 G8 k9 B' U) q#endif
7 K% W1 h) p9 E' B9 {1 t( v( t' ]
) F: P& {* U5 b
7 O) N  F- g' I$ v- H# h( M- Q
7 G; p/ T  h0 p
* r& r5 J6 {3 l) V. \6 _( m9 e- i- g, t6 Z+ Y9 A8 V+ Q4 L4 ~
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。9 O( j; o" u; x) M
WSS 主页:[url]http://www.whitecell.org/[/url]
! i0 O+ g! i$ m- fWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-5-13 20:50 , Processed in 0.041541 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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