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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister: ?- {- H$ W4 s1 M3 Q* b, ^8 d
Email:   [email]sinister@whitecell.org[/email]
9 c2 ]% t) r; G( U& mHomepage:[url]http://www.whitecell.org[/url]
1 U  x* m1 g9 d. ^6 y: ~Date:    2007-02-26, T7 ^3 C6 H4 R* T  [
& a# b. a' E+ @4 ?. l! a& `
) C) I0 c6 E' E3 _- G
/*******************************************************************
# E% Q" @8 u" g$ q
- U1 d9 R! d* T! r( V/ T6 w这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
$ m: Z  L) x  Y9 l写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的6 }" c8 n/ ~1 g# Y
功能要求如下:- ~* @0 E9 v4 z6 G

9 H: o* n8 [% b! V1、强制锁定键盘/鼠标。
$ {" O1 E! K. H) r6 r8 b2、可动态加/解锁
9 I) D& Y4 W4 A- w3、兼容所有 NT 系列的操作系统。
0 L7 B1 ?/ a- W% c
5 j! a* _5 [6 s0 T! J4 ]2 o2 j0 j就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实1 y" \. i7 o1 Z/ x* E
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
' {7 l9 ^# K- L何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
5 l2 I9 b0 x1 q; ]上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
4 w$ e& M/ h$ @$ F$ M3 ]怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面* }" o- ]( `. [" o1 t, a
就来看一下我想到的几种实现方法:
& v- F, e1 o' F9 B: G) O0 `% a. G0 `# E4 i* r6 t% J) o  ]2 ^
1、全局键盘/鼠标钩子% Z" I2 |1 v9 {& g/ I
2、BlockInput() API
, C0 O3 S; `5 O6 k& y  E1 k1 |4 K3、使用 setupapi 进行控制2 Z' w9 P$ E3 T8 {9 i' L- H# A
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
3 `9 b/ P! q$ d; I4 J4 w- }5、拦截 win23k!RawInputThread() 函数" C7 I0 T1 U9 i9 b: Y# c
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动" h$ u. d1 r5 J
7、拦截 kdbclass 驱动的 driver dispatch routine5 X; G' ?% _3 Q( [  A
8、实现一个 PS/2 与 USB 键盘过滤驱动; ^! Z4 |* {; P" n* Y* `

1 o% A6 I' p9 ]- b; x2 l7 A
& i; }, n9 A9 O我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑; c" H: T( I1 j3 n
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
) h1 l: J8 Z% N0 U. q1 d案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
2 w& t" A: D" l兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
& B) b/ p4 \' L- u2 ^1 K# F素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性' a$ F, ]; J, ]2 U& n: f7 N
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸, h  Y$ V/ b" p1 x4 O
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我; f6 p9 O- y: G. q/ ~2 L! u. |
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
8 N" u7 E; e; m& w  i1 L4 W  K也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
! K: c0 d( K" M果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有+ y) Y$ g. x% J# b6 F1 G
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
( k" Z* x8 h  X% P- y. L! O5 O& tIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 ' m% z1 o9 [+ s
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键* Z5 G! Q, X) i, g: R7 Z
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
1 A8 F7 U4 @) G, c1 j案的全部功能且不存在它所带来的问题,否则就没有什么意义了。7 v; ]/ n8 y) d5 }1 w6 D0 I
5 z, l2 h2 o% @' y  P) n# x9 }" ]3 i/ `
9 h/ \+ }* B: L# R
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
2 D; [2 Q1 E8 M0 {# I滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
/ P( n" M1 P! d6 S" b行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
+ V6 M+ R  v) u只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越. o% a) a* I6 {8 c2 w( d8 N/ D
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从. ~/ C% U+ G- F( Y0 x
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
* x8 |+ R, K2 V' ?键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
, k) s. R9 ]7 ]* A5 m% A8 a' JIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
- R: Z- d& O6 p* L% n, @我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
* J* X$ @8 D" N$ W1 r; E  J9 a就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
) Q: M2 I0 W* _! ~0 w' o( a" N6 M而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
% b" H" ~9 ^& b# V用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
4 U- Y/ C; @) v5 H% n& _8 |过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
/ r9 R0 Q( G3 Q屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
, n2 Z. R( |; t' E! I! S" d' F过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb+ ~2 _" _, U( Q' R7 `1 ?! N
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid & g: E' C* y$ _6 [, k: D
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意1 r! Z3 }# m7 T+ g3 [4 o, p' W! s! S1 y
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
  M9 N' `, M% g* ^1 n经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
- S8 r' |4 y/ h2 L. v* a7 e- T7 g来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利* |$ ?& |/ F  C) ~1 P
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
# a( W8 z. Z( R6 n的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致5 H9 q: {0 B$ ^" V9 M8 s
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,' o" ~; q6 @5 W, _
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程. O" H& H+ j! {0 N7 a% l3 C
见下面代码。
6 x5 G0 \* L% [( {7 V
/ O  L2 p9 k8 q5 T' B这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
5 t- C+ @$ ]/ ^' \; o' M, V! T3 \里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键7 c: B1 ~0 j( N1 Y" D
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003$ U1 O8 `8 Q: Q8 N
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
2 [" K8 x% k$ n% S% Z完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可! n4 u8 a9 R$ P1 V( C. H
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
. C- Y0 O2 M# e' P2 D锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
2 A  b7 m  K$ a( |1 p( r键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
( q6 d7 ?. f! a, L9 M% v  r' X( U) L/ l, e, C/ c
, f5 _+ X7 k! L' T% l) k4 K
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用2 t% J& ?  |$ i) z- J; y
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
. m) F5 k' w: a可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
/ y' X8 q8 T. G9 e. W5 B0 U: p- J& }! c的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我0 o6 z( P; ?. K+ ?- w$ @8 y5 x
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我/ k# a* e- @7 _1 V5 ~3 j
们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension- B: I9 N6 c+ K& F% c4 W+ A
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
9 `$ Z+ f( i; Y4 \4 b( w. B: ^: |如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager" v& |7 R, Q4 {7 j- E  J
进行操作了。这个问题有待大家来完善了。/ [6 B) B% x* B
2 O2 D( v  {# w3 h& \: b
& K9 P4 v8 q7 U8 I+ j
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
! n; M3 @5 [) g% A3 z7 f来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的( h. ]- R) z) z) o7 K5 b( s
分析做个记录而已。我更愿意把它看做是一段注释。/ B9 C$ e! y7 p7 R+ c4 Z0 J8 o
. h  K* o$ w1 Y0 U+ B
最后在此代码中要
; z) _( i- e) E
2 ~+ N3 W0 I* D" O感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
3 [9 r" Z% n( G4 s
" b) b) K6 e% z- |$ ~! N9 r% N感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
0 I/ X  |1 D- X" X% u1 M$ v3 X9 Q
$ V! d, h9 \/ N0 l感谢:齐佳佳,过节请我吃好吃的。
/ o3 K5 d" B6 ~3 x5 s
3 W3 W2 W8 [7 J8 x- U) o- X2 E4 B" W* ]$ K
******************************************************************/
9 X; V/ |5 @9 ]! \
  {8 a! |- S: }& v& B" A1 J7 E2 G
7 `. M8 A: k) ~6 r/*****************************************************************
0 Z1 M& F! W1 E$ J  r 文件名        : WssLockKey.c3 W0 C6 K" [) ~, W
描述          : 键盘过滤驱动
4 C- {  f8 G6 ?1 H0 r, e  V 作者          : sinister
. A# U* Q( j- _ 最后修改日期  : 2007-02-26
# A* V! ~% `( l! T, o/ S*****************************************************************/' |8 }# Y) _, J* y1 T
! I. {- V/ }- g

) @4 ?& d& y" U$ |6 J8 M- d& i#include "WssLockKey.h"3 f( R, R8 H1 t% }( X
* j) q6 K$ c" a- ?# Q
NTSTATUS
/ k9 V9 L8 w# \6 |% gDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,& ]; w0 y: I/ A+ }& z) X  S2 h
             IN PUNICODE_STRING RegistryPath )) X7 A2 L1 S, h2 o& X' T+ L& z
{9 M1 Y; L8 b6 S7 Z
  UNICODE_STRING KeyDeviceName;
4 R/ Z# E+ D9 W, V  PDRIVER_OBJECT KeyDriver;
0 \1 D0 o$ F4 b9 T0 q  PDEVICE_OBJECT UsbDeviceObject;5 `0 Q4 g3 `, a, e% l8 j: v8 D
  NTSTATUS ntStatus; $ R: X' f, V( K0 `5 X
  ULONG i; 4 Q- k+ X' b% F: D- n! ?

) P# l  x: Y( {* Z7 }  //4 Q2 H  b/ U- y
  // 保存设备名,调试使用/ g; `- ~/ k& }/ L( ?8 X& P4 R6 O
  //
. P' u3 l* f3 j* K2 ^/ S! P  WCHAR szDeviceName[MAXLEN + MAXLEN] =
, }! h$ d( ~% M/ L1 U  {3 t$ A3 w$ `- l  |
    0! j5 S( Z4 v9 ?& {6 h
  };
1 _! L& `% Q9 g! v0 b( h. G# I8 U4 P
  KeyDriverObject->DriverUnload = KeyDriverUnload; ) Y" D, _8 P' o" a3 P+ r% i8 l

5 U+ G1 H* d( A  //1 g4 S/ L4 }$ \: |7 J
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
3 a1 R; R1 J) d/ V  //- k- F! J: t( e7 b% i9 K
  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
$ q% v% {+ G8 E$ K, m, R  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其% D$ E& o% G! v; r
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
& G8 U8 L+ b" _+ K/ S1 M  // USB 键盘设备来进行挂接" v  l! F; E# d4 B
  //
; A2 m( ~4 b% E- t" u2 p0 L  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
1 @1 g5 @, b" `% S0 b' P( c. l  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )) H/ T  h3 t  A+ M9 ^# e
  {
% G( {* [$ ?' d7 |7 G    //( `) g4 P" Y$ `
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名. a  @/ [" ?8 L& A! W. d
    // 所以这里打印为空  {! t5 b) U; C. Y
    //
' B7 M( {0 }# t! l3 v( R    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD) k" x/ R9 u: F3 A' F( M, G5 \
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
% D; q3 `% n" }: b6 R/ W% q; d8 T4 ^% b3 m1 I/ Q6 O( Z  a" i
    //: Q0 s% J( X8 z9 a! o! c
    // 挂接 USB 键盘设备
. O- ^  F, U! W) h    //
- X7 }0 Q! E8 b* i. x& J    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );" e$ q4 h. Q4 Q  J  i
    if ( !NT_SUCCESS( ntStatus ) )
: Z- a0 P+ ^% f    {4 c/ Z# c1 \5 A  n
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );" P2 P' r9 W# Y' c% I1 I% W6 b  y
      return STATUS_INSUFFICIENT_RESOURCES;7 g% x: b2 ^& [
    }
% R! j/ D# m+ z+ n  }, R$ ?1 h5 r" I7 A! I  N# B! @/ Z
  else/ A: `) k. N, F: {4 L6 v6 S
  {
, p" K* J* X' V' b# v    //9 a% J5 o# Q2 e3 R
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
1 w% h0 ^0 X0 h7 Q, k. E    //
2 M: R4 g8 ^) c1 D2 B# Y6 I    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
% A. j; \$ P  G6 i) o2 E
; v5 T: ?. ?* o: m1 c    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
2 O7 ]! Q& u3 \" A* o$ M                                        KeyDriverObject,; X5 o2 T9 o, Y4 p" G0 ^; E
                                        &KeyDriver );
  I" k. p1 {- _, l" m* z" ]* ^    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
& |" Z/ \8 r$ B6 H% b" D$ F    {0 l& d* T: z% \1 b7 h; O' J% P
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );. ]3 _& f7 F' |
      return STATUS_INSUFFICIENT_RESOURCES;) Z. n3 v( W* q' L; W
    }+ J7 r: o) n1 h
  }$ P0 d! P7 n' p4 Z2 |6 W
8 P/ G  C; H4 r  a  n- A5 x, S
  //
' g( X1 o0 W) E4 |  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
5 T( g' ^( l: @$ M- G& |/ G  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程4 m( b5 [+ D% K0 u6 q
  //
7 v1 G. `! [" S  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
' P( n/ R" ~7 B  U0 N9 f4 ^5 {
# }' a7 I/ B% a4 i+ U" y* x  return STATUS_SUCCESS;. L  K3 V: v1 ^5 a$ P1 ^5 ^8 F7 U
} & q: [: j4 {9 i; n# E( V

9 p0 a' T! K+ S3 ]/////////////////////////////////////////////////////////////////
1 ^; |! e# z' B! W, J// 函数类型 : 系统函数2 V' \. x0 l( a( R' Z: H2 [/ A& i
// 函数模块 : 键盘过滤模块+ s4 g0 H5 Z. [
////////////////////////////////////////////////////////////////* t. c9 U. {9 I6 E: O
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
: R; S' V, g0 ?//        卸载键盘过滤驱动* o  u3 t& S& Z! x2 Q% @9 s4 |
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上& E! v- ]1 X2 ~! U# n9 S
//        则需要等待用户按键,以后有待完善$ V+ }$ a! b1 d* G6 y
/////////////////////////////////////////////////////////////////
# j4 D5 V. G) g// 作者 : sinister- J- w% P% x+ s5 j+ N8 o' V
// 发布版本 : 1.00.00
- x6 t7 ^' i+ a0 k  |' }. v// 发布日期 : 2005.12.27$ ?; t& W* u# h( o
/////////////////////////////////////////////////////////////////' S0 }2 H2 ]5 d% F* f
// 重   大   修   改   历   史$ t: }* g- L# f( b2 I: H
////////////////////////////////////////////////////////////////
' T  z$ A  v- [% r) h// 修改者 :
( Y6 j3 w: L! |// 修改日期 :
8 f( `: Y3 p4 a+ C// 修改内容 :' f& K. `' S3 `/ ]2 h; @2 l- P
/////////////////////////////////////////////////////////////////$ T6 {/ U) A. h

% o, @% M( F9 u9 a7 U* q: sVOID& }/ {& |/ u  S1 a( Y# P+ C
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )8 S7 P  r7 N- u# T! Z
{
2 `8 l6 M# G- k8 H. ]: v  PDEVICE_OBJECT KeyFilterDevice ;      
/ X! s3 b2 P6 w  u  PDEVICE_OBJECT KeyDevice ;  ]1 S6 n1 A* W) K6 ?
  PDEVICE_EXTENSION KeyExtension; $ i' Q$ h8 ~3 r: ]
  PIRP Irp;
$ P, c3 g; S7 d  NTSTATUS ntStatus;
4 {7 q2 C/ Y: S( Z% p% A9 M+ z0 f! R3 o' @) X$ I+ X
  KeyFilterDevice = KeyDriver->DeviceObject;
$ M- T3 H4 E+ ^% T6 N& ?  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; 4 [$ U1 {7 D3 W5 J
  KeyDevice = KeyExtension->TargetDevice; 0 U4 }; b4 L9 p) V" X6 v
1 i) S* [+ ~7 G9 @& z) A
  IoDetachDevice( KeyDevice );
. c3 n( ~% b2 I% Y9 v
. {1 f: J8 t2 p! \8 {. Z- q  //
: N9 v$ ?7 b3 k  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP+ Y6 m8 J3 L5 R3 f  i
  //
8 N3 f7 E# Y" N4 v  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
' f1 r4 [  u  \1 |3 g4 m  {
- ?# P% o6 W9 D4 |4 S* v% g    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )) b1 S. {( [/ [/ K. U. S
    {
, q3 Z$ x8 _3 j6 U3 U3 s5 S4 {      //
2 ?- N7 j! o' n5 Z; Q) t2 Q' U0 `      // 成功则直接退出删除键盘过滤设备
  u* e7 a. A$ d# r+ r- v- C      //: Z/ O7 `, S2 x' z4 n
      DbgPrint( "CancelKeyboardIrp() is ok\n" );, v) x5 H% n- B9 Z* _3 Q0 G# Y
      goto __End;
/ V3 I4 n$ I- g5 K! n$ X: z% B    }/ ?& T# N- E: z- J8 k, {0 E
  }( u, i6 a$ T' y" G7 ^
1 W5 s; H. f* B9 F
  //" {: P, d* y, H( y( u( v& T+ }  E( ^
  // 如果取消失败,则一直等待按键
- Z; f- Z- Y5 r  //1 B$ K1 e* @- g
  while ( KeyExtension->IrpsInProgress > 0 )
$ m& z7 X* r" F  \& _2 ]  {  y3 V% \3 w3 M# _7 X- ~' ~  w
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
% X5 J5 U- p3 A7 U+ r  }
# q# u7 _1 V9 b! p( b/ u, W5 S$ P. D# Y4 B8 g
  __End:
: g# A" d/ p2 h/ p' S2 k, ~  IoDeleteDevice( KeyFilterDevice ); % Q# E+ |8 u! U

% N; v; O, h: q% O% t  return ;* A) J6 |2 `- Y+ r/ Y+ f
} + K( M+ D  p; l
3 K2 A6 B+ q# a6 \  O
/////////////////////////////////////////////////////////////////5 X/ m6 V( y5 I: c. g$ h, B
// 函数类型 : 自定义工具函数
6 ]3 g% |' H5 s* \4 Y4 d// 函数模块 : 键盘过滤模块
2 W3 Z! q3 `! c$ j////////////////////////////////////////////////////////////////// _1 m  r$ e/ t2 O& r* [# z
// 功能 : 取消 IRP 操作- ?0 r9 K/ b; s! u. l8 D  x
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
; V( M9 T: A6 H: U1 b: F% @" N//        使用此方法来取消 IRP
4 D. G$ ^% C) c. y% c/////////////////////////////////////////////////////////////////1 @  o0 \$ [2 L0 F( o
// 作者 : sinister
/ g3 v: h& [3 j+ `% K// 发布版本 : 1.00.003 |4 |) v- C' s" C5 {
// 发布日期 : 2007.02.20
; C/ W- U3 K# u% y/////////////////////////////////////////////////////////////////
0 S  Y+ i6 s5 O- {# G4 d// 重   大   修   改   历   史
1 U1 O0 S$ E4 \( O2 e/ T/////////////////////////////////////////////////////////////////
% R& F! l9 }( ~// 修改者 : . ~" w  J0 A; k$ \
// 修改日期 :
" a: x0 y" R, Y- H  C. P1 J; u// 修改内容 :
$ B- ~5 ^& h2 L/////////////////////////////////////////////////////////////////
) y1 V* S- \4 q. k0 Q! _! r0 s: h- ~7 |0 x' C; z1 ~6 l
BOOLEAN
  R  g4 A2 G  \- sCancelKeyboardIrp( IN PIRP Irp )2 }$ L* @# w3 C9 d* o
{
. ^' R& @8 r0 U. }- z  if ( Irp == NULL )
" ?/ t9 Z3 ^& u" O, U: A5 ^  {( w( E: P, U4 d* g$ S- \- R8 ]
    DbgPrint( "CancelKeyboardIrp: Irp error\n" );; o6 c& M. P+ x0 [" x# z
    return FALSE;
8 G7 a" a7 }6 t5 j) V  }
. b3 b. `; V( Q- F& a7 K) v9 y- b' W4 A

7 a0 l$ f# \( ]* ]  //8 @% O4 |0 ^; y3 Q" d5 h- T5 A
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,# h/ b# e% E9 [6 g2 V& f
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
# _2 ]  Y& ?, r; y+ d  [  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
" A9 K2 k% c8 G1 x% t  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
0 W  k4 g7 K$ c' F  //
3 o6 N# j$ Q) F" I+ ?$ L
) t4 f4 z* P/ ]  n2 k' U1 {  //# _" }9 \$ Z' ^$ n- ~. f3 S" r
  // 如果正在取消或没有取消例程则直接返回 FALSE# G* M$ O+ M5 f8 ]* O. @4 `6 {9 c
  //
6 R2 P- O: L0 B- Q, p6 p  if ( Irp->Cancel || Irp->CancelRoutine == NULL )8 v( x) o8 o. H( R5 C
  {6 E5 }* m( g2 }
    DbgPrint( "Can't Cancel the irp\n" );# k- C2 N' P9 }
    return FALSE;; c6 L: O' Z& x; b3 z0 p0 V
  }4 A0 a- R" m" ^

" C. g# s' T) B: p  if ( FALSE == IoCancelIrp( Irp ) )
! _" }9 k9 S8 r  {+ M0 b) r/ d8 H/ R# E4 ?
    DbgPrint( "IoCancelIrp() to failed\n" );; e; @  r  G# }/ `) p* G9 R% f& q' l
    return FALSE;% p3 g: q; Z" D; }5 Q
  }' }+ ^( Z& E# S. E( @, W9 e  A

" _6 F3 }6 t, @$ Q! U* F. [* j. @! q' y  //) W8 C) h% @! c6 B3 f
  // 取消后重设此例程为空
3 R9 y- s( s( E4 H  s  //
9 w0 d; Y& J/ D3 N( a9 ~% S  IoSetCancelRoutine( Irp, NULL );( E; {2 w( J" M3 u4 X/ q

/ u. j) Q" J( V& {. @  return TRUE;
2 Z5 [) `- G! D) C7 A}" J3 n, h1 h$ X; Z  p! m8 Z
8 O: _$ i( M/ S
/////////////////////////////////////////////////////////////////
, i0 M6 V7 t9 x+ B+ S1 P// 函数类型 : 自定义工具函数
  t% A) k& N( _3 \// 函数模块 : 设备栈信息模块' ^& e% }$ X1 j8 h& `
/////////////////////////////////////////////////////////////////. b5 v! F+ f6 @. r5 ]3 x
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘4 O% N0 y: l& i  q: E0 }
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)3 y, y) D1 K5 n9 e" @
// 注意 :
  T' c8 j. Z% f5 l/////////////////////////////////////////////////////////////////
- F( i9 L0 ?: R4 }// 作者 : sinister  p+ \& ~( w% u# d  D  y
// 发布版本 : 1.00.00& T2 C3 r0 C/ ], a5 m8 C0 e
// 发布日期 : 2005.06.02' p6 ]$ \" e9 x! {) w( Q
/////////////////////////////////////////////////////////////////
7 i; U4 o; v& a  T/ i1 X// 重   大   修   改   历   史* U+ N$ Q# A  n5 S! a2 \  a" }* p
/////////////////////////////////////////////////////////////////% G: u8 S5 n# D7 W) g: {7 D0 M2 g
// 修改者 : sinister0 D$ P2 G8 U0 V/ L3 L
// 修改日期 : 2007.2.12
0 D' T7 b: [$ |3 Z! F( |1 ~7 L// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
1 u% `, |8 {9 V* B" x0 G5 V5 g/////////////////////////////////////////////////////////////////5 ~/ N/ Y2 T' i

5 L: n# F) C% g$ I1 ]7 [5 }BOOLEAN
& M4 V" o2 B% G7 r8 PGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )5 J+ X, d" R0 ]8 Q9 F
{. T$ _( P; ?, P( l$ C2 P
  PDEVICE_OBJECT DeviceObject;3 Q3 d( J9 [+ X- l
  BOOLEAN bFound = FALSE;0 ]6 l/ J1 i3 X

1 c" i2 ^# \$ C, i  ?2 h  if ( DevObj == NULL )
1 z& [/ B7 L; t5 B  {
& R1 l& `4 h( i% T    DbgPrint( "DevObj is NULL!\n" );6 e7 n1 [+ ?0 p7 a
    return FALSE;3 r" H. N" [$ ]+ @6 @% x- m
  }
, K2 ~( W1 B& Q4 n. t( d# L! J% c: R, i4 Q2 l- Y$ J
  DeviceObject = DevObj->AttachedDevice;
- U/ ]. i2 y% a- H+ G0 q
4 u1 b- O. w4 Q/ f  while ( DeviceObject )
: j0 B) v" Y& s4 k8 K9 f  {
, m- v- \( \4 s, P    //( W! A0 o) a5 O
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但' u) n% h1 [# d3 @% Q' B9 R
    // 有一次足够了。这算是经验之谈
5 V3 m$ ]% Y0 U9 e7 g& i  t    //
) p1 J( |( x) Y. R$ O9 P    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
$ p" V3 Z# v; s- }3 \    {/ B- O! q7 a# P+ F+ a
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
1 O( M% u/ P  x; D$ Y$ Q                DeviceObject->DriverObject->DriverName.Buffer,2 }5 w/ r% U) \7 I9 |/ S8 y  K
                DeviceObject->DriverObject,$ ~% d- q6 ^% V# B0 q) o3 F4 f/ t
                DeviceObject );' l; V) |6 G3 E+ s

4 U5 z! k/ E* W  p- A* Y  G      //
* J) n* i1 G/ q$ E3 Z      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
  y3 u4 K: M2 K3 F; y      //
  k- G, i/ y, \# [$ o      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
+ R8 G, ^$ J& d1 _/ `                      KDBDEVICENAME,
" N! i% S3 r( u/ K1 C1 _                      wcslen( KDBDEVICENAME ) ) == 0 )
( Z- h/ D0 x2 J/ K4 }& n      {
& [# [( W! Q( T1 A+ ^( {        DbgPrint( "Found kbdhid Device\n" );
3 w2 _  [2 S3 H. C! I# \2 v6 d        bFound = TRUE;
7 t6 }5 z3 G; x6 ]. u1 n" A8 d        break;- L1 W+ C+ M) h* p( T
      }  n: R: j# A1 [2 q  g- Y- |' P
    }
" l9 S( K. y* H- G; u
; \( A5 u0 j* a, R! E    DeviceObject = DeviceObject->AttachedDevice;( R$ G; `! D4 f" n, x
  }( I. [! E  ~& E; n1 O
. A# L" ]7 J; a
  return bFound;: }; \0 ]3 R$ i$ x5 q% t1 V
}4 [3 M5 M$ R0 _9 ~( v
! z" _: v: Q/ {
/////////////////////////////////////////////////////////////////
/ X0 w4 V( T, h3 I  E// 函数类型 : 自定义工具函数
  H1 h8 j; p( k  Y// 函数模块 : 设备栈信息模块/ M1 M$ E  E& F5 p) p4 r
/////////////////////////////////////////////////////////////////
3 a& f& ?* H& @8 w) S' }4 U// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
2 r& ]0 l! z9 H: e( _// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
  C9 J: Z6 I% d# |: }  T! ?/////////////////////////////////////////////////////////////////
  {- y5 Z# @& q1 N3 {: _// 作者 : sinister
3 ?6 T8 j: ~$ x( y// 发布版本 : 1.00.00
9 Y/ @' E+ N4 p; I// 发布日期 : 2006.05.02- @% w- A; @  i; L
/////////////////////////////////////////////////////////////////8 D; \. R+ _1 |/ w$ J* d
// 重   大   修   改   历   史
/ d* F2 V  ?! g3 h/////////////////////////////////////////////////////////////////
- B! W$ m' P2 p6 I5 Z// 修改者 : sinister. r+ N# M' L* s8 `: F1 h! k6 Y7 ?
// 修改日期 : 2007.2.123 Y5 x: S+ v, j) l6 f1 ~. |
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
* T' t; `; s; b6 [/////////////////////////////////////////////////////////////////0 k% s- }3 F  M/ l7 Y$ w

7 O7 _6 a4 l) u4 d! pVOID  W9 }4 C% X, J
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )3 z# l7 n' q3 P1 j- _
{$ u/ N( K. m: X
  POBJECT_HEADER ObjectHeader;
+ f6 q3 U! d9 N1 u8 O  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
  Q! s$ t$ m; p" A
8 q7 M7 Y8 W; l3 Z0 ]  if ( DevObj == NULL )3 g, P8 J8 H/ ?% \3 U% ]
  {0 O1 i: J, v1 ~  D( G4 c$ L+ {
    DbgPrint( "DevObj is NULL!\n" );& A# b9 V' q$ b; N  j
    return;9 [2 ?! E& V0 U
  }  R6 W. X% F2 {3 |! c

+ Q6 e4 P, B* o5 t" q" ]3 U  //
' Q1 ~# v7 s# k& W7 R  // 得到对象头+ k0 b" ~! Z6 |
  //6 Y3 e) p1 @# \+ m2 ^5 x
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );
( b! R: G; N3 L* J# s  H/ P; }% _
  if ( ObjectHeader )
6 [' |: v7 }/ I% N; t! j- z. m  {
$ B/ T0 J0 J( V    //
& V6 O" e) h4 [8 J$ y# w    // 查询设备名称并打印
  Z/ b1 K; X  Y& ]9 J    //' D- u" _' u% G$ D' \/ T. \
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );' M, c1 L2 m  i

( [/ o5 c) L4 M    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
3 ]% P7 u" `8 M) u    {
( \/ \. h& e" _+ K0 @3 ?; V      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
0 T) X: O: v. W* q                ObjectNameInfo->Name.Buffer,
  b$ J' R0 J/ ~" z                DevObj );* E- u( p( U0 Q3 W7 ~

8 B! A' u, p$ D7 L: {      //3 Y- K' ]; E' i3 [+ N
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示+ V; \0 V+ l4 j4 _0 ^
      // 用,没有实际的功能用途% V. R) Z; q0 t7 c# |6 t
      //
$ |! K6 n' H; B! R6 H      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );+ h& D7 h) ~* l; r

5 d5 u' z" E7 X6 g* ~5 x8 ?# p! h      wcsncpy( szUsbDeviceName,/ ^' ]3 p" ?4 j2 E7 y& Y8 y4 [  h
               ObjectNameInfo->Name.Buffer,
. \: f4 B  w( F! S7 \6 D! K  s               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
! \! }6 k7 }9 d$ ~5 C& V    }& R/ `' p: o, C; H, c
; B' z1 [" d, X6 v9 K+ o9 m
    //
3 G1 v( a9 V& B    // 对于没有名称的设备,则打印 NULL- r9 }+ y( F1 A* h( y8 y' n
    //% F6 t8 Q8 a% b. p" C( y6 H' X
    else if ( DevObj->DriverObject )
' f% P$ W8 [" w. @) q/ g    {. P: U6 T; r  e- D+ ^
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
: p. L& r9 I' T! v; ~                DevObj->DriverObject->DriverName.Buffer,7 K8 I4 h* Z  J" S
                L"NULL",: n) `+ B/ u1 O; H
                DevObj->DriverObject,# i6 O& F- {1 p: z; N2 d1 _
                DevObj );  o) s' s0 x. [, q: _( `7 t  `
    }
+ ?' l1 C+ j: ]) [6 A  }4 M' N( M- }! c; Y) R) Y% w4 ^, Q
}2 H; r6 p' w% {& E: f" q+ [

( V: Q2 `1 M# I9 g% ?/////////////////////////////////////////////////////////////////1 o) j4 d4 g! h, X
// 函数类型 : 自定义工具函数% K% p7 T, e, I6 g+ D. _
// 函数模块 : 键盘过滤模块4 r: h" d! S1 D7 [8 X
/////////////////////////////////////////////////////////////////  f2 c$ w4 K( x1 K2 ]
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
3 ?7 N6 r5 f6 B5 {//        对象,过滤出 USB 键盘设备,将其设备对象返回+ `& z: `8 P9 {+ u9 Y/ J
// 注意 : * o  j7 m7 n7 p+ k6 Z
/////////////////////////////////////////////////////////////////4 y2 Z* l; O4 e8 \; r& O6 ^
// 作者 : sinister) t$ d9 w7 G' b* g" t4 i- a
// 发布版本 : 1.00.00: u) y& s6 d" P  [* g/ _" r- m
// 发布日期 : 2007.02.13
0 X) G! E& z8 d/////////////////////////////////////////////////////////////////
0 {4 o: N2 G/ O$ }// 重   大   修   改   历   史) V. J+ f3 G* P; K
////////////////////////////////////////////////////////////////// K5 r+ F- o. w' ^1 K
// 修改者 :
, s; Q3 b( K8 Y  f// 修改日期 :
# r& F9 ]& C* e5 [' t# A* `* _// 修改内容 : ' Z4 |8 U9 m$ U5 J
/////////////////////////////////////////////////////////////////
% w8 I; |" I# O  U7 {: f4 d- e, p2 V# q6 m4 \* S" U
NTSTATUS
+ b! x) J- }8 f  ]/ WGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )1 Y4 g" m! e. t  [! O
{+ y8 n5 @$ a- \0 i# y
  UNICODE_STRING DriverName;
, u* u6 H; j) A0 f4 W2 P% V  PDRIVER_OBJECT DriverObject = NULL;) b+ Z4 `) T1 T- S6 F4 g3 m
  PDEVICE_OBJECT DeviceObject = NULL;
- e7 Y. q: h/ Z! t: g) A( y* x  BOOLEAN bFound = FALSE;. l9 f* V: i, S1 h8 e$ B

4 S6 I6 v7 v7 M0 L5 L+ o3 ^+ y  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );% h0 I% J9 e9 y1 V

# H# r3 F! K0 L6 J% I. B+ a  ObReferenceObjectByName( &DriverName,. G# k9 d1 H8 @& {
                           OBJ_CASE_INSENSITIVE,5 I- M! ?) n9 P' I9 ?6 Z
                           NULL,
* ?7 L& P& |- Q+ w1 V                           0,* k4 `: ]& f: V4 M
                           ( POBJECT_TYPE ) IoDriverObjectType," x. o9 C, S9 k* z  ^0 e  }
                           KernelMode,+ A% M' h0 R7 p" Y. P1 ~3 n
                           NULL,
. W6 L0 Z4 F# F& `                           &DriverObject );
% j+ v2 ~+ {$ P6 W2 O% R4 E' }3 i1 z) k) P) w3 X6 O% T0 u
  if ( DriverObject == NULL )- H+ @- Z3 B. ]. S- i
  {
) P/ W3 m$ E% a: ]& A* h    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );) I* x. V& u1 K' i0 _
    return STATUS_UNSUCCESSFUL;8 F: ]5 x. T( }7 U
  }" V' L+ _% P5 V# ]; r

  j4 d$ I, b; {. F  DeviceObject = DriverObject->DeviceObject;
$ C, h- P# y/ p0 L5 V* W. x
. ~. Y) u* N6 P- K  while ( DeviceObject )
/ S- ^$ b# n# K; M  {8 Y& w4 a1 q& ~2 Q1 V" n
    GetDeviceObjectInfo( DeviceObject );
) N3 }' w- L$ ^0 c! I
# o$ B8 x% H" ?/ I  q    if ( DeviceObject->AttachedDevice )
" ^- X' {$ ?* F+ T7 }    {
7 u! E% L! G7 c" t) k# E. C      //- \( B; q: [: j" g5 k8 M
      // 查找 USB 键盘设备4 S0 q( J$ E1 t- I, m- D. z
      //
' F$ g7 e8 t+ g6 r, \, m3 _      if ( GetAttachedDeviceInfo( DeviceObject ) )
. T% i8 T5 k9 n" o& o      {
3 C- k) `2 G8 ^" u        bFound = TRUE;
2 \* ]+ [5 H. S; |- i  |  z. i% d        goto __End;
, C( V" w6 s6 ~0 n; y! Q2 ~      }
$ z& R1 M9 ^* F/ u5 k: K5 z    }! C' i/ p  r& |$ [) \/ N: Z1 P9 ~

* i1 E; O5 ~  x3 o+ s    DeviceObject = DeviceObject->NextDevice;
6 p1 e; l8 m: Y- I  }
0 {& R4 z. U( \1 O% f2 u7 q# J* c
  __End:
3 J# x9 J  ~+ O8 f
8 ]8 ^( i/ d6 y0 u) N9 I9 o  if ( bFound ). V  Z( W! h, Z" [* u
  {4 `: E6 Y4 b6 O! B9 S2 Z8 i
    //8 j' e* b3 P, b2 M
    // 找到则返回 USB 键盘设备对象; q& Z( R& D# }" V" }
    //0 e1 w2 T5 b% D/ F7 q  b! K/ d
    *UsbDeviceObject = DeviceObject;
% h/ P2 \$ W: ], t& {% k1 c  }
; L4 i% O: D& ~% E6 O9 A  else
/ P" B6 N# C1 x# A  {
, w. e1 f9 D$ P* T    *UsbDeviceObject = NULL;
) w' v* ]6 m/ d% ?6 K. }( P" B7 U  }
6 O) o% p# q! P$ |. u5 `0 P' ]+ P! C; w- ^1 k% t/ O6 t
  return STATUS_SUCCESS;
8 g' d; B+ @5 T  |# ?}
% D9 [0 h( k6 W
$ y8 U6 ^# W) u% c8 q( u5 f/////////////////////////////////////////////////////////////////# L/ m! C2 P, t1 }, r
// 函数类型 : 自定义工具函数7 v! S" x6 Z: M/ E9 S& x
// 函数模块 : 键盘过滤模块
( \3 l$ }, ]* v  j# Z- n////////////////////////////////////////////////////////////////+ Q; E2 y  B' s
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关5 r" K! T, W* o5 Y( h% m+ ]
//        信息,返回附加后的驱动对象
, h& `6 m. d3 L# U5 z" m3 i// 注意 : 此函数仅挂接 USB 键盘设备
; O2 `  t5 D4 l/////////////////////////////////////////////////////////////////
/ a/ b$ m5 F, \2 ?( d4 Y9 q// 作者 : sinister
6 ^2 T& e, l: t/ o" e! N9 M// 发布版本 : 1.00.003 }$ o. W7 P# F- E- b' h
// 发布日期 : 2005.12.27  l' y4 h* c, n5 m% K
/////////////////////////////////////////////////////////////////  j, m/ u2 J  p8 I5 a8 ~# ?
// 重   大   修   改   历   史1 |5 f/ y3 s, p& T6 U  d0 h. e! r
////////////////////////////////////////////////////////////////
' L0 m8 o% O9 O( C& q% X& }// 修改者 :/ ~* L( l5 B8 B. s
// 修改日期 :
4 ^9 ?5 {4 {! x0 |- c// 修改内容 :
, f' K, i. p+ X# P/////////////////////////////////////////////////////////////////" K0 K/ i" O% k4 @$ w
% A  S- O  N! \2 u* ]' e1 I
NTSTATUS% I+ d( Z8 q7 T; z/ y
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
$ k. v2 v. j6 |# `  l                         IN PDRIVER_OBJECT  DriverObject ). r' G, ?1 y" ]; Y
{
1 A! V, \2 h- p: B3 a  PDEVICE_OBJECT DeviceObject;
7 t6 `) R9 U! V5 h  PDEVICE_OBJECT TargetDevice;
1 N$ r. H! R% e. m7 r  e  PDEVICE_EXTENSION DevExt;
# S) r7 Q# t% a4 R0 b  NTSTATUS ntStatus;: h& J% d2 t% l; D4 u

: w6 E* f0 a. }4 p; d* [8 U# m# ?  //! j  w* ^6 M3 d0 V7 r1 k1 X
  // 创建过滤设备对象
  b2 P9 Q8 E8 y( Z  //
+ z) G$ q) U# p" y  ntStatus = IoCreateDevice( DriverObject,
. C6 s3 d( ?# a6 E                             sizeof( DEVICE_EXTENSION ),/ x+ U5 a9 E; W* @' z3 }! a/ r" u! E% h, p
                             NULL,4 v2 c8 g. m5 D. r
                             FILE_DEVICE_UNKNOWN,
. G# L. [2 d9 |4 f: W# P                             0,
* E' M1 i' W  l- s0 E                             FALSE,) Z( [/ F( `0 i% m) `; T
                             &DeviceObject ); ( G: E7 Q* A; B5 q: z

2 U3 b% l  `9 t3 C  if ( !NT_SUCCESS( ntStatus ) )
' Q* e' K; I! h+ F6 d: }6 i  {
$ s3 `* l6 p. L( F. V1 Q. J0 l    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );4 s) S6 @. R0 T
    return ntStatus;' _% F: D3 b$ l
  }   ^9 J2 H% d3 n6 Y# L* {

1 @4 [0 a; b0 g5 C  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
7 m* G: g& o) d* j; n( m+ X4 U4 c  f
  //
% e, f! J1 G4 L+ S7 E- s& Y  // 初始化自旋锁6 ~; X8 F& T! G
  //
" ~6 p( |1 i! h  KeInitializeSpinLock( &DevExt->SpinLock );) F- A9 C2 S) v" m2 `# R8 `

# Q- @2 d' N8 @: R7 G+ c9 ~  //3 N- Y" e$ g6 \
  // 初始化 IRP 计数器
# \4 @( |* M; i$ p( ?) v/ y) H  //
; k8 D9 c: b$ @0 r8 j+ W$ ?  DevExt->IrpsInProgress = 0;
' w$ c! G4 A: T: G/ U# C7 ~; y$ |4 F4 d; K% ]- D
  //( ]: {% N- P( X! _8 e0 q: b" t
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
$ r2 y2 M# O/ t! }  //$ |* y2 [$ G1 ~7 x6 |/ _" M. \) X5 u
$ y; x+ s( n$ F: f/ y* Q. b0 n0 m
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
1 W/ M3 ]1 h% x) H& X2 W6 V  if ( !TargetDevice )
. I+ z& S; N, R/ B: I* ]  {3 h8 \* d4 p6 C3 e+ H) r
    IoDeleteDevice( DeviceObject ); 9 N7 L! Y5 b: p4 G' c0 }
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );/ [2 K% D3 s8 k$ j2 {
    return STATUS_INSUFFICIENT_RESOURCES;" M  h1 N, f* Z
  } / n4 m7 K, R1 h7 ?- [
; [/ @1 d) ]+ S: v( M5 d
  //
5 v5 F1 v/ t9 m+ b7 ~! @  // 保存过滤设备信息% [/ ^5 ?* e* N. u8 d1 W
  //, h' i! Y" `( H3 K* \* S8 k
  DevExt->DeviceObject = DeviceObject; ! I4 f2 v$ P1 i) g$ |
  DevExt->TargetDevice = TargetDevice;
( R2 T( X5 v9 z) X( A
) j5 J8 l6 g  M! c/ g  //
. q6 t. ~$ @4 f. `" _( T5 M# m  // 设置过滤设备相关信息与标志( q/ `- {+ l& s% G
  //
7 c0 e0 ^  `# [  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );& m' a$ _& ]/ H# d4 L
  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
3 F9 I/ ~8 `% R5 L8 [; K) Y
" {% P5 o9 `9 j+ n- u" g$ D1 N& V4 v% q0 F/ j
  return STATUS_SUCCESS;
4 I1 O# k) B, T; A! S}3 {- m9 A$ T- t" Y
3 \! V( r. @( v& F: Y6 U" [
/////////////////////////////////////////////////////////////////$ X6 ?7 d7 v2 v" i! B/ t
// 函数类型 : 自定义工具函数
& }7 L* c6 T$ M3 o2 p8 Z// 函数模块 : 键盘过滤模块
2 w& W$ Y' [. X) H& H' @5 h////////////////////////////////////////////////////////////////
9 w. T. Y) u7 m0 j0 C2 e. x// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
6 }  Q9 z% U6 k: @//        信息,返回附加后的驱动对象# m* J, g* b: b6 x
// 注意 : 此函数仅挂接 PS/2 键盘设备; |/ v- s; Q* d% V  Z3 w+ w: }
/////////////////////////////////////////////////////////////////- E4 o, ]( s5 C! J
// 作者 : sinister
/ Z5 h6 V9 E9 U) e# o// 发布版本 : 1.00.00
4 W/ [  Q: C7 H0 `// 发布日期 : 2005.12.27
; d; k- P! u0 {5 }- B/////////////////////////////////////////////////////////////////
# ~/ j  B; m8 A# X# b! e// 重   大   修   改   历   史$ G) u% n. R* j9 l7 ]- E
////////////////////////////////////////////////////////////////
: x, z+ m/ g' e' p8 P% K7 z3 J: E' Q// 修改者 :
# R* E# }% c4 N8 A7 C' C8 L// 修改日期 :
" i* a$ V: h$ r6 k% A8 G: a5 e// 修改内容 :( k. a1 \! `# A8 X$ J6 Y
/////////////////////////////////////////////////////////////////
" b9 I" V& x% H9 |/ c8 p9 a1 k# J1 ?* \
# ^- e) d. s" d* c, b# E0 o9 k  TNTSTATUS2 c$ }6 f$ l; x. |
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名# n4 b* l" l6 v' V) Y' I
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象- E9 }1 R! A; l3 W% U# O/ E  W
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
8 j# U5 v. k/ I/ u" O{
6 Y* B% \: A) s6 b; V/ D6 Q  PDEVICE_OBJECT DeviceObject;
! T7 `0 ^2 C, g5 J  PDEVICE_OBJECT FilterDeviceObject;6 f: X' L7 W% [+ _$ \2 c- P5 R
  PDEVICE_OBJECT TargetDevice;
5 S% n- ?& j* d7 X1 w3 \9 R' m  PFILE_OBJECT FileObject;
* z# [) p2 e0 y% F' K  PDEVICE_EXTENSION DevExt;! q5 h; w& t% w# U$ _1 V
& s, f8 \- N! F
  NTSTATUS ntStatus;
9 e1 J% q- R  ~. v
1 K# x7 j0 L* P' y9 w$ u: w  //% G7 ~6 M% ]5 a9 C
  // 根据设备名称找到需要附加的设备对象
- B9 v' i8 X# q  //1 [. ~/ N$ V) [8 q0 \0 u
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
6 f7 P/ m, S& p; i                                       FILE_ALL_ACCESS,1 d: |" j5 D. z# F5 G0 r# S3 o
                                       &FileObject,
, i- t. g/ R6 G+ h% p                                       &DeviceObject ); 1 s* n8 Y: l: n6 X" ~- ?+ g

$ z1 z+ \7 ?. t7 A  R+ t0 [  if ( !NT_SUCCESS( ntStatus ) ); i; p1 f! h6 c2 m, E2 @
  {
0 j3 z- d% n  a$ R. x4 \6 d$ ^    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );+ a8 A' G' J$ [7 w
    return ntStatus;
# K$ o7 V6 ~; m3 w  } + C- n+ g4 ~; l: p5 \: d% ?1 `) t
3 r; F" }) b  j. D9 E, a
  //
2 F8 t7 {5 F6 W) ^" W8 f  // 创建过滤设备对象
# H' [! n* _/ U4 o2 x  //- z: z8 D7 `7 u/ X
  ntStatus = IoCreateDevice( DriverObject,
2 i5 Y! p' U  J                             sizeof( DEVICE_EXTENSION ),5 T9 i" F/ K" |0 v5 e" M
                             NULL,
# X+ ?4 s0 X) G1 U6 h! ~4 Z                             FILE_DEVICE_KEYBOARD,; O+ w. _$ R( e  d4 F" [  ~
                             0,
3 z) z  V9 A7 R! s  `' R% v: q                             FALSE,
: m- x; p" m+ t                             &FilterDeviceObject );
1 h& N! x( U( D! k+ N2 \+ ?" H6 n; ]  Q
  if ( !NT_SUCCESS( ntStatus ) )& C8 s5 _! @5 j! m# G
  {
9 `! P" p. `7 P7 J  F) k    ObDereferenceObject( FileObject );
( j8 q) Y$ f6 \+ M; C9 h- D    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );2 j) z  z, O: `5 q5 I7 C9 Y* k
    return ntStatus;' n- ~1 U* `# W/ Q
  }
4 @+ U, W8 ]" |; U9 q) R1 B3 v9 ?3 _- b# Z& ?
  //4 @) z' M9 ]1 n' I
  // 得到设备扩展结构,以便下面保存过滤设备信息, f  @  i- g6 u; E8 |1 v
  //
9 l0 b" d# y5 ~7 ^9 C" B; r  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
4 f- y) H0 R. W& \% \5 m; S( S( w' b- K- _. E% ]" ?
, U3 B$ w2 I7 o
  //2 {) d7 C' t. m% N
  // 初始化自旋锁: Y: u  |; ]8 i" S
  //
2 v, I5 z6 A/ t7 L8 X  KeInitializeSpinLock( &DevExt->SpinLock );2 G' J0 C. ?4 c! O
9 \, p; Q4 b6 s/ U$ ?4 u' M, g
  //" N5 z  k1 [$ H: S3 }5 e$ x2 y
  // 初始化 IRP 计数器2 l! Z4 y7 ?9 V$ i# @( v
  //" d2 t& w. q) _) Y: X% b. H8 W
  DevExt->IrpsInProgress = 0;
# @& Z" l) A+ F9 q+ k5 }1 @0 p: {- ?( T! h2 P9 [2 X' S
  //
& W; j! X$ W- E# Y3 a" U, G7 e/ \; g  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
- @" D7 }0 U1 c; P' I3 t- T4 c  I  //; W: `# I) ~9 B( ?4 }( l
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,) n. t1 E* X- d3 S0 [& @* B
                                              DeviceObject ); - }/ H0 ?' |9 ]8 ~
  if ( !TargetDevice )
- Y% e; G1 H' }; N  P2 @  {
4 x' O+ ?. p1 h2 K9 p% X/ p! j    ObDereferenceObject( FileObject ); 8 k# d, \2 M7 c( f$ T
    IoDeleteDevice( FilterDeviceObject ); 7 k, n- i% R/ ^
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
; J/ ?2 |2 P$ m+ f    return STATUS_INSUFFICIENT_RESOURCES;
! v6 ?8 t$ \/ n% a  e  } $ F: s$ l' U: X  g5 t( q( j" r! t
( V: g( c2 D# ^; {; f3 Q6 f8 L: F8 m
  //
" \$ m9 C/ f2 `/ F0 o7 \! C  // 保存过滤设备信息
! }" M, R( g$ i) D" \  //
: ~5 W/ _# x; t* D/ _; `! ~  DevExt->DeviceObject = FilterDeviceObject;
2 }0 Y" K# \+ w7 J  DevExt->TargetDevice = TargetDevice;
; |# G( e; A! v2 \# J  DevExt->pFilterFileObject = FileObject;, O; E. [! G  Y/ V& ]6 ^
$ p5 S+ R' W$ i$ P/ a. [
  //
7 m- f$ [  L. J, |' F8 o1 |  // 设置过滤设备相关信息与标志* ]( |4 a* C7 n7 c, ?
  //. Z, d1 |1 t" o: Y5 M. B0 r
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
/ a: U" |! E9 n7 D, G  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
$ \* g( N% N7 @6 c( m- V- z$ O  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;+ I1 ~# X' i! Y( R: J9 e4 P
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |6 g1 q1 D, d- _, {6 J6 Z
                                                         DO_BUFFERED_IO ) );
$ f7 \4 y8 B! [- M
- n0 L  [* G) Q- j, k0 g2 Q  //
7 L, ^. G  h2 R  z: p9 ?  // 返回附加后的驱动对象/ q3 r- I/ J" _5 p3 |
  //: m0 Z9 u( X* @2 M8 J: e
  *FilterDriverObject = TargetDevice->DriverObject;# U  o/ w" R, p9 G  @

. X4 v- Z7 i9 d  J; r  ObDereferenceObject( FileObject ); ( T; n2 c, P8 C! ?9 p% x
$ s$ F( I7 S* @7 F0 U3 f6 _
  return STATUS_SUCCESS;
+ j. _5 r. U* O9 g+ v- R; }5 n}+ e" V$ k; Y  ~9 O* t8 L# Z

  E$ w- M5 E4 M8 D/ `5 C/////////////////////////////////////////////////////////////////, e5 n: }8 _& a( J0 p3 J
// 函数类型 : 自定义工具函数: D$ e$ d  t- \- x9 i# Y
// 函数模块 : 键盘过滤模块7 [6 b" g6 [8 }' h1 j4 _! k
////////////////////////////////////////////////////////////////' h3 C* ]! t# P, w) @! ^- L
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
7 T' s' e8 g! E; C//        这个 IRP 的完成( A0 J" ]1 k) K2 S' @/ \6 [" l
// 注意 :
5 ^2 N- p2 T" r) S/////////////////////////////////////////////////////////////////, z5 `0 A1 `* W0 f3 j5 f
// 作者 : sinister
$ G6 a  B7 k' I// 发布版本 : 1.00.00, [& K* w9 M7 e7 {
// 发布日期 : 2007.2.15( E4 E$ \" }% \; y% k3 ~; j3 t
/////////////////////////////////////////////////////////////////
! m+ f/ v4 K( f( [# @, q# R// 重   大   修   改   历   史7 z4 x0 s$ C9 l  t
////////////////////////////////////////////////////////////////' R" V$ V( v0 G0 A) c# @5 r+ _$ y
// 修改者 :
" q, O- t$ i5 J( ^! V6 K// 修改日期 :4 R) c  p, ], E. |4 S" {% ]' C0 `3 l
// 修改内容 :% R+ s8 C# C' ~6 c6 y5 Y* n( a
/////////////////////////////////////////////////////////////////0 C0 l/ g8 g7 p: e

& ]* b" [+ |5 J" R  TNTSTATUS/ N2 g' ], E: i' P
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
- K' x/ C$ x8 S0 U; j2 G# S! C! B{
2 d8 W; M/ V! }4 r' r  NTSTATUS status; * K' D/ l% c% j8 R# D4 C
  KIRQL IrqLevel;. }9 i5 }9 `+ v, x
. f  ^' k) H; s7 y8 f' ?4 C. c
  PDEVICE_OBJECT pDeviceObject;" E! p& p  Y$ |% R
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
! j- k1 p3 I# b' X                                   DeviceObject->DeviceExtension;
* R/ S; a' d# m2 K, j
7 ]. B4 `, w0 |. j) o1 o0 f% }3 H6 [, d! n4 N, q8 d# j, z
  IoCopyCurrentIrpStackLocationToNext( Irp );
* S: x: E4 i: D6 n) A
3 }6 B  u, J# ~' \7 k  //
+ A  j9 O  p4 ?% H3 z' n0 w. a/ i* a  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
, j4 `) k8 Y; u( f6 ]% P) K  //3 d3 _' H% X; z: H3 j; y5 w- g9 `' I
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
% X) _  g  D5 C  InterlockedIncrement( &KeyExtension->IrpsInProgress );
! v$ H! Y5 D0 g, Z* Z0 N  d- P& r  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );1 V5 Z' Z7 b5 c4 w& u1 b" y8 s

) f0 V! p" d0 {- z* ]  IoSetCompletionRoutine( Irp,7 z, A( n' t/ D' c
                          KeyReadCompletion,
" T7 v# T) N7 Q" W, s: r' N                          DeviceObject,
1 C8 @, |. T( c9 X  g$ J" l                          TRUE,  _- y  y. U7 H6 v+ D7 I! t* t) d4 R
                          TRUE,
" H( n8 c/ X3 X- \5 S' {( b4 H/ I                          TRUE ); ) D1 L% d- k7 S! ~: X+ Z  m4 {

* Q4 g4 B& s# D$ ~  return IoCallDriver( KeyExtension->TargetDevice, Irp );
& N' N' |5 ?( D3 E$ V- h2 q  B0 d} . G7 @0 P* K: w3 S

0 d3 b8 n* D2 q: G! e/////////////////////////////////////////////////////////////////
) }) T* W& Y0 g  a// 函数类型 :系统回调函数
5 i" v( G# v/ n5 T9 p// 函数模块 : 键盘过滤模块- T" q9 Z: Y$ v9 M1 E
////////////////////////////////////////////////////////////////1 k5 W$ N- C  _, T: u8 M
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
+ S9 Q; j/ ?. o2 K8 p, b8 ~) j% W// 注意 :
, X* C; b; M3 n' _" k+ J7 [8 {  }/////////////////////////////////////////////////////////////////, W3 Q( L; w% c* o: D  t9 p
// 作者 : sinister2 k/ [! W! M" q) Q' ~
// 发布版本 : 1.00.00) v0 N, b+ S3 o, a# {( _: A1 ]
// 发布日期 : 2007.2.12
* T/ b0 l  C  ^8 h; H- [5 J+ S$ B/////////////////////////////////////////////////////////////////( \9 O# g% c0 b( C! }, v& s: Z& k( l
// 重   大   修   改   历   史$ L* G" q6 I/ @' s
////////////////////////////////////////////////////////////////
& [+ M1 r; ~7 D! Y, q// 修改者 :
, _/ |; E4 |5 @, E0 r// 修改日期 :
4 i- M9 {  U7 C1 l8 F6 k& C// 修改内容 :
5 j3 B5 C% L- i" A/////////////////////////////////////////////////////////////////4 C( x1 l& B, m5 ~* [- R
4 {  \, z" j; U- J4 A
NTSTATUS( l- K+ C  s/ L! d6 m
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
* x1 U) [- r+ {/ ~( {: A4 X/ G                   IN PIRP Irp,7 ?1 H1 Z# B+ y( g9 z
                   IN PVOID Context ); [1 L9 @2 F( T7 ?; h3 f: e# Q0 n  W
{
2 ]# a! s1 v1 L, f8 u0 p% Y  PIO_STACK_LOCATION IrpSp;. ~# Z& ?( t+ B) ^
  PKEYBOARD_INPUT_DATA KeyData;
2 I. Z  d. r! d$ w- S( j5 K  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )! a# v: |# ^' j
                                   DeviceObject->DeviceExtension; * Y2 s* c$ ]2 S# G
  int numKeys, i;+ o, d, [+ r" Z. b# \' x
  KIRQL IrqLevel;
5 \2 ?( v. E; J+ y" r$ h8 o: J: X- v! H% f( j  h6 k
  IrpSp = IoGetCurrentIrpStackLocation( Irp );1 V% T- T: |4 Q. S  u
  Z$ ?& J9 b5 Y" I" G
2 ~/ W$ }" m0 l3 T7 r# [  _6 q
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
. Y* G" e; ~6 d7 E3 c, V  H* p  {( P; P. A( q! \! J: a5 C
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
" d& }1 }) ~$ n( g    goto __RoutineEnd;
, I6 F: W' K; m: x  }3 w. {9 D1 x/ Y+ u+ @' k1 i

+ P/ S6 I1 q/ L3 D  i* C  //
- S$ @" m& N- V  // 系统在 SystemBuffer 中保存按键信息
7 `5 G# c# e5 u& o  //' w" `" P9 I  ~3 u" N) \
  KeyData = Irp->AssociatedIrp.SystemBuffer;; i  X2 o" Y" }" ?, O3 G" ~( p
  if ( KeyData == NULL )8 `+ F% i; i# y# s, V% j
  {
, R2 U* q  Q1 z0 E! E; P    DbgPrint( "KeyData is NULL\n" );! W( a- m8 z& s( o! ^
    goto __RoutineEnd;
3 b$ v( L0 K3 k4 r1 r4 D7 _& h  }
4 N8 n1 Q1 w. b; B$ x; j' n, C3 v/ c6 H+ X% D4 a$ F% w0 X. D$ y! q7 U
  //
+ Z) \. d$ B: ^! r. F  // 得到按键数
! y  ^8 i  z0 O$ W  /// y0 m& i" r) S+ d
  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
( M5 G- v5 v* n  if ( numKeys < 0 )
7 u, G0 _- ^, m5 ]/ r( w  {5 z% s8 C. k& V) y) P' e2 B- z3 k0 S
    DbgPrint( "numKeys less zero\n" );; Q( v8 t  E3 }
    goto __RoutineEnd;
! W; s3 C; ]1 l+ Y( T9 g% W& x  }$ W/ }: n/ K( V: e' W; d) u5 Y

, c  t& F* s5 }! o- j  //; p# i. Q8 K, ?& |8 n1 b& s
  // 使用 0 无效扫描码替换,屏蔽所有按键
0 Y' }/ o6 X# E' ~4 V# b. w* d  //0 ?5 s) E! t  y; e
  for ( i = 0; i < numKeys; i++ )) ?/ @0 e* j9 W8 q# d
  {
! e6 L9 w$ D- O; |- U, D, E/ t' i    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );. y5 H8 A- [4 U/ u1 ]
    KeyData[i].MakeCode = 0x00;3 S5 x! Z1 {, D3 a8 c
  }3 M. T0 ?/ e; O

$ Z( v2 u- U/ d4 R
+ X$ v, u( X7 g9 ^4 k6 y  __RoutineEnd : , x% u9 j5 V% J; V- l3 U1 v# G

' r& b) S! k$ u* U  F) Q  if ( Irp->PendingReturned )
  N) ?$ O, S% y  {
2 V& `0 E6 B# F0 E8 @7 P2 u6 I3 \    IoMarkIrpPending( Irp );& }- s4 ?& b8 Y  i# `1 d  M5 |
  } ) O+ z% n, G+ K7 c1 l

3 a; l( T1 t& e# B  //1 ]0 \3 }8 g& o1 h9 }  Y
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁8 b( M- q/ u0 o5 j3 }
  //! v3 T* ^1 F! U+ {5 [5 m4 t/ E- x
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );$ s+ \8 N& m- x. k: _( D
  InterlockedDecrement( &KeyExtension->IrpsInProgress );  X4 b1 m! R1 M5 T$ Z2 R3 M( U# _- J
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
, R) _  ?' _) j. t+ Y; _7 L* V8 M7 `: L
  return Irp->IoStatus.Status ;! `3 V" r" A6 U9 j) l( d" T+ |
} 5 s7 o6 _% v: Y9 Y& @( e$ {1 Y

- S- L, T/ s$ P% `( n
6 i5 q: z. }% i& `+ u+ k" z/*****************************************************************! l- w6 G2 b$ p" F% ], a
文件名        : WssLockKey.h
& j/ ^2 h6 A6 n( X/ W9 S& Q# |5 }5 S% V 描述          : 键盘过滤驱动
% `# Q* o0 ?7 { 作者          : sinister2 A; E6 o! M" h8 j8 `
最后修改日期  : 2007-02-266 M3 M+ l7 W$ Y: q+ f" A+ _
*****************************************************************/  Q9 y+ x5 z# T5 e

" ?1 H4 h3 P( C" j( `; |( I#ifndef __WSS_LOCKKEY_H_. d* g; k. s6 l! A( q" v
#define __WSS_LOCKKEY_H_2 [: ?# p" w: k# y& [
) n' h0 H( t& w/ d' V9 U  m+ a
#include "ntddk.h"
; i0 {3 z) `  U#include "ntddkbd.h") E6 h" @; f  A( c8 Q" R- g0 ]0 B
#include "string.h"
8 f2 j) H3 e& p3 l- h#include
+ @+ v8 r/ c# j# p3 i9 e- B9 _( @
#define MAXLEN 256; i: R, e  W  G1 y! o

+ ?  @. U9 n6 v#define KDBDEVICENAME L"\\Driver\\kbdhid"; `) v9 @4 \3 |
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
( C4 [  \# ^$ |$ r' Q: m# y#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"5 B, d# s5 e# Q' a! i4 _

/ b8 K5 S+ A: f" ytypedef struct _OBJECT_CREATE_INFORMATION
, v* {7 C+ I( D8 x' W' d2 ^{
; v+ Y3 b7 }0 @0 h$ ^$ b    ULONG Attributes;
$ b. z+ o7 P0 f    HANDLE RootDirectory;8 O: C) V  ]3 V1 H2 H
    PVOID ParseContext;. Z. U, J$ A0 T2 [5 p7 f
    KPROCESSOR_MODE ProbeMode;
2 ~  m* z- x. c+ {# |4 _8 l    ULONG PagedPoolCharge;! l0 W# w- x; z4 i0 |; F
    ULONG NonPagedPoolCharge;
) N3 x7 U! }1 v4 h% D3 M3 H    ULONG SecurityDescriptorCharge;
9 O% _9 T- ^/ N& @' d4 _( |    PSECURITY_DESCRIPTOR SecurityDescriptor;
  y$ `" z; b) h6 [7 {  }- S    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
. V5 `+ ~  h/ o; [; T+ Q) Q. }; E    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;( t  q8 Z  [3 q3 @6 C6 |
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
- _4 C  n0 O3 r0 u( b: T* K1 q' b' U
typedef struct _OBJECT_HEADER% Z- a2 S8 e5 X' Y* a
{+ \6 R6 c2 M9 f; }1 Z6 \+ p
    LONG PointerCount;6 P& b( Z) Q6 F5 E8 s2 K- U9 V
    union
4 v; m: t6 f9 R5 N/ E    {* A# w/ P$ `1 @+ s
        LONG HandleCount;
0 D5 J" s' l8 J, \% n' M3 C' j  t        PSINGLE_LIST_ENTRY SEntry;3 d) G( W0 A/ U9 c/ `0 u8 r$ a2 `
    };  O2 t" x) ], x  M
    POBJECT_TYPE Type;
9 O) u/ A$ y+ r3 k& V6 D    UCHAR NameInfoOffset;2 D# k: L  c+ `% Q4 m
    UCHAR HandleInfoOffset;2 `3 B" X( L' X% G2 d6 G2 F) M
    UCHAR QuotaInfoOffset;4 J5 F, B! B6 J; _6 h' m6 L- T/ t
    UCHAR Flags;4 G( p" E- j2 _4 t
    union
, Y4 i2 H( A1 u% p3 {! r    {3 C) w* N! t0 q) z
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;+ U% A, Z  k8 y) E3 i
        PVOID QuotaBlockCharged;( D- k" d# l) d6 k# I# ^
    };
1 G6 {* `6 Z( _. @+ ^+ a' M7 v" z; k: u2 L0 X8 K) @* h6 p: m
    PSECURITY_DESCRIPTOR SecurityDescriptor;
( o0 N: X6 O6 X7 P! u- x% E7 G    QUAD Body;3 _1 v2 S/ t6 t$ T$ @* Y5 V. U
} OBJECT_HEADER, * POBJECT_HEADER;/ I" g5 Y  O8 b# w; n; }
6 ~  |0 f2 [, e8 }0 {. H
#define NUMBER_HASH_BUCKETS 37* Y, F7 R1 c! G: Q7 `- R$ `
+ h, O5 ^+ {$ i, c0 X8 F" @' Y
typedef struct _OBJECT_DIRECTORY: ~! m% r2 x% `5 w) o
{( V2 v  \; g' A2 y$ C
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
" {# o! b6 u& v5 z; ~8 b& F) V    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;/ H# o3 T( Z1 \0 p$ L& t: z/ j
    BOOLEAN LookupFound;
) s) E; n+ S7 Z: b    USHORT SymbolicLinkUsageCount;1 i' _7 ~* `( }% @) T) a$ _6 b
    struct _DEVICE_MAP* DeviceMap;
, s4 G' \/ b: t} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;1 c$ M' s6 `$ H6 r% X% M
3 P$ e& F2 a1 a; S$ R/ R7 G" _! h' f
typedef struct _OBJECT_HEADER_NAME_INFO
$ H% E5 U( y1 W{
5 B( t2 k- F6 O- h# [% d: y    POBJECT_DIRECTORY Directory;7 V- m4 N* a' M
    UNICODE_STRING Name;
& y+ _5 z0 P9 w    ULONG Reserved;! v. u) M! P- o' R6 ^3 c
#if DBG
6 @- H* p3 y; L, u6 x    ULONG Reserved2 ;
4 w3 @9 u" r$ I5 |. G( d. H2 b8 c    LONG DbgDereferenceCount ;
9 y7 R( c; c! z/ H7 S8 \#endif
7 o$ i# R: {2 G8 H+ I} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;* V# `/ B; f4 |9 X" t

- S; S: B# Z$ y+ v#define OBJECT_TO_OBJECT_HEADER( o ) \
" i8 u2 {: ?$ ]! ?7 w2 d    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
' \, g& y3 @$ a7 U* v& f
, V4 p9 U2 k8 z" O( x6 e#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
, P( k, ~7 L7 M% [9 ~    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))9 k# F7 b/ F* o) r

) R. j" G$ V( c9 Dtypedef struct _DEVICE_EXTENSION
( w6 d9 F4 c/ I  P{: D! I9 B' G1 H; m
    PDEVICE_OBJECT DeviceObject;5 R1 l( d- D& ?5 K
    PDEVICE_OBJECT TargetDevice;$ f3 s5 R1 N& T
    PFILE_OBJECT pFilterFileObject;+ P$ Q2 }- [) f
    ULONG DeviceExtensionFlags;
9 P' K# d$ ~/ {) S: V    LONG IrpsInProgress;( c/ _' P9 q$ M: a$ `5 l. w0 b
    KSPIN_LOCK SpinLock;2 P# _2 Q4 M" N3 N/ s3 y
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;4 S8 R( Q/ g8 p# n2 }1 s
' g2 B/ \  e/ t- w# e$ b( W- X4 v

' V  n/ t7 ]) }# @VOID ' c8 E6 O8 M" `& R  R0 X! w
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );3 c( n0 T1 a8 G6 n6 M; \
/ m+ |6 u: f4 i' Z' c
BOOLEAN" P/ L3 H6 [, E! X. |4 ^4 c
CancelKeyboardIrp( IN PIRP Irp );" e8 |. [% J6 B
3 P9 c9 _% B" b+ l( h, m
extern POBJECT_TYPE* IoDriverObjectType;
3 {+ p- m! h( L: e- P
0 t, A4 R0 @# C6 p  eNTSYSAPI! Q$ G5 Q# X4 i3 b& x
NTSTATUS
8 q2 n7 f2 S' W" J$ ?8 u1 }& uNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
1 U0 a8 B4 G0 g- y                               IN ULONG Attributes,
& F  R3 ?% K8 c" ?& N                               IN PACCESS_STATE AccessState OPTIONAL,4 z9 B8 j8 |. H; g" V
                               IN ACCESS_MASK DesiredAccess OPTIONAL,
7 W" F! O  n% _6 n) p3 ]" o# L                               IN POBJECT_TYPE ObjectType," [; o6 m- b& ?, z& D# X5 l
                               IN KPROCESSOR_MODE AccessMode,
% N) p) k' J( H' R9 c                               IN OUT PVOID ParseContext OPTIONAL,& @  f4 s6 R9 e+ V6 p8 d" e
                               OUT PVOID* Object );
6 r/ V& O& [  }. J. p
6 u3 F/ F# J% ~& t: k" |NTSTATUS
  }4 i1 V# G* bGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );, G" X7 k  \. S( I/ r
# a$ j. D1 }3 I' Z9 ^) G# z
BOOLEAN 1 P" ?7 U* l7 i+ `3 K# j, N
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );0 C# V3 P, c5 q* Y

7 F% m7 J) N$ xVOID 9 y4 u: x$ E) v# ]6 f
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );$ c9 g7 R- J5 v( W! ~
1 b( N- ]/ Q) T& |
NTSTATUS
* p  b9 v  P4 ?3 z) YAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
0 E9 Q1 P$ n+ d  k( r                                  IN PDRIVER_OBJECT  DriverObject );. Y* g& R; e0 I, _
% k3 c* ^# S3 Z) W$ D, t& ?
NTSTATUS
8 l2 [4 Q4 ^" x5 ^! \2 kAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,) w' T& h9 m; j
                                  IN PDRIVER_OBJECT  DriverObject,
7 l- m# _  X4 ^  L4 e7 D2 Q                                  OUT PDRIVER_OBJECT* FilterDriverObject );
* R7 C2 v! E6 [, H9 Q! N
) ~% g  {! s% B& n; oNTSTATUS ! S/ f% f# X* o
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
# f8 l* M( o( I7 c! d8 L                            IN PIRP Irp,' l; t" [( Q* ^7 u
                            IN PVOID Context );
$ T1 v- X4 e3 H' k8 xNTSTATUS . m7 z, f! j" \, O. ^/ R
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
. v% ^5 n' f7 s, ?( q# H! x" B% m5 C2 i/ b# Y% P
WCHAR szUsbDeviceName[MAXLEN];9 O, f2 H/ Y- d7 q* K7 L

& E: N( v! l2 n  D#endif
  y  o  n& o8 h/ C$ V) L% d, Q$ X8 J: b3 J7 ?0 v
9 ]; ~, y0 O1 C( y( e& z$ d

6 r' S' R( |  E1 B, J8 h6 l/ y: N) v+ h

' X( p5 k0 N$ a' u/ `9 b' t& R- R0 ]( a* kWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。/ p# j9 L6 p" |! s2 n6 S
WSS 主页:[url]http://www.whitecell.org/[/url] ' x9 F5 M. r& ]/ i' F. x
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-19 22:02 , Processed in 0.077244 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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