|
|
Author: sinister
: Y: Y7 A# n' [ {! e: ?! pEmail: [email]sinister@whitecell.org[/email]
" W" F& x2 c. s6 ]Homepage:[url]http://www.whitecell.org[/url]
2 d9 }0 H" \; V4 h: i3 `Date: 2007-02-26
9 [2 S: K$ E% V* ^) ~- |& Y( g! U9 w. d( e) t/ X9 h
# Z* z: [ `7 x) k/*******************************************************************
6 ]) L1 M: y, m: K ~: r" S/ n, {$ x
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
9 q$ h# N. ^* F; U9 U写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
; G( i! S/ L! R# L! P u4 Q功能要求如下:& Y- Z( ?( H [# d
4 R( o, Q( Z k1、强制锁定键盘/鼠标。
2 \. w6 Z) D/ u2、可动态加/解锁
4 ]7 Y' ?1 H" ~3 y: _- W8 w5 `3、兼容所有 NT 系列的操作系统。
U' B% F4 s+ F9 T( s# M& Y9 p2 \! O( z, h1 o7 ?5 ]6 C1 g5 B
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实8 @$ W, r% T& l4 Q+ n
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
1 t4 L# J% M! n& e _) y0 I' D何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
) u9 T4 U# e$ a" ^/ o上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是* _& e4 U9 q) K9 U: H+ p
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
4 S% k( c# u9 G, U4 Q- V* L就来看一下我想到的几种实现方法:& ^% A2 u+ T T% z
1 O- h; @' b) ~* ^& u2 v$ w1、全局键盘/鼠标钩子" `% ~4 D% h& k: `/ b
2、BlockInput() API
$ g- C8 d8 }8 T& n/ e3、使用 setupapi 进行控制. l6 r. G6 P0 e. c' {! \4 m" f
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
8 v' _* |7 i' T" k1 _0 Y5、拦截 win23k!RawInputThread() 函数; N' B, X$ W" ~3 Y
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
$ E1 t9 h8 Z% X' S" G; f7、拦截 kdbclass 驱动的 driver dispatch routine: r9 }$ ]$ b8 O. R5 Z% L) Y0 K
8、实现一个 PS/2 与 USB 键盘过滤驱动! A* U. `' R% R/ ]* M* S
6 w' q/ H4 _6 I% N. U5 ?
4 ?/ @# |2 ?6 j" F* ?% i我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
9 Z& _' K2 g) v( M9 C3 R& \6 w之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
& a: y! a% g" j" D8 A6 p& ~, e' r' I案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
5 z* S3 Q% k5 l4 s& `8 X; {兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因& ?) u/ L/ K2 p8 _
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性3 F& t3 l% a/ L4 r
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
/ c7 o& q3 W0 q9 f/ p ]( |载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我9 t8 q: ]% e+ _* y4 P
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来$ M% u$ C" L3 R* g
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如 c; U( @( v" W, |* d
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
" a" `% ~( f: X1 D. h* M* m障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截8 i5 A0 v- X3 \; E3 D' I+ X' |$ `3 u
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 * `$ A; q4 \5 L* C) a. o5 s
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键9 c& ]$ T4 q" z y" w* H+ Q
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方+ _. w4 L+ c& k% l& ^+ A
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
/ k2 c1 Y$ c2 O8 c b: z/ _' U. Q" \* h3 I
3 I2 M! v4 L+ K7 ^, s. Z我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
1 }: d% W O1 Q- A. c3 b滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进! I6 R4 D4 \/ p
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
. ^+ K9 _" \! d2 Z0 N& S只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越9 p6 |- l9 n( y+ I
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从9 {; x& g/ b Z; Q& f
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB2 ?7 M1 r1 ]- ], C) K
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用7 z2 q3 O$ R& L+ o7 b
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,* a/ y) Y6 m. t/ f# d* N1 ~0 }
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题- X% N( u. i4 ?3 f- S5 x% n
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的- w/ d/ F! }0 c( c" |6 [/ n
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
# P: G) }7 z8 [4 T5 r7 Q6 k$ p用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通9 U) z- g# w' J
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
# [! \6 h% Q7 s1 l' |( U3 K) R屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通5 L8 H" i+ }9 G) N+ }* r
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb2 Q/ J+ S8 E+ N/ i( [: z2 m1 W
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
2 a- Q$ S% }( | b o- Z& Z6 X的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
8 J. T3 S: ^3 X( `. i. x# @味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。: d8 g" X4 A8 I0 ^& s
经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
$ p1 \. u& y+ p/ _5 t: }来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
0 k! ^0 ~2 V. k的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo
6 H% [. o8 S. F, {的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致, p- R. \( T$ Q, H
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
5 }% l3 A& v; j9 E* w根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程; W) J0 Q0 q) G/ d
见下面代码。$ m5 }/ }5 u" }9 Y% {4 F
, F0 _) @7 v7 s9 p. L& k; A1 W
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程1 ~4 o7 F8 o/ J) |3 c2 K- e$ W
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
2 L& c+ G+ M) @盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20035 H3 Q) m+ o7 P0 i
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有( l3 z) M+ `( G7 A r9 [1 t
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
$ Z8 d8 U2 Z. N继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个, B/ z9 ~/ L* H! d; j0 ~2 Q
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按! s) A1 d. ]; U% y& z( K
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。8 e0 t; @% F0 Q3 V' l
. @0 i0 k& o8 S% @; O' ^. d
8 y5 S. G0 h0 c o完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用2 H1 _( t" d+ f% Y d2 @/ F. @) F
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
; ]: t) ^) F8 Y# A' O' E可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
, {+ v) g* ]& b1 b; ` O6 k0 X# U# M( Z的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
5 A9 M5 W; `3 M3 O% S们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
' P8 L+ |% T; ? c( B. w; z! _/ [1 f们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension5 L. A+ H- R0 N% U2 _- {+ ]
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
/ F! A& z+ U! w) U: V/ ~如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
y* Q, y0 v5 x" [* A/ q进行操作了。这个问题有待大家来完善了。/ |+ |6 {2 x$ d5 F7 t( p( I: I7 [
9 B4 |+ m7 J* W6 d& ~
+ s( v" }9 g4 }9 p* [" L: [要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出$ m* j: v2 [4 @* |1 Z8 _
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的; r3 x% m$ x3 j- R8 J
分析做个记录而已。我更愿意把它看做是一段注释。
1 [5 a- f+ G+ b
0 c* A3 R: h1 _; I/ g最后在此代码中要2 e, \6 Z Y* h ?5 K8 Z' j1 a
' F0 r; [) e2 n感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
" m& i' ~3 b& s: [7 ?9 `2 y! y
+ W8 h$ P0 s# c感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
2 U: A: O9 J8 }: a
& F6 p* A9 A: ~: s感谢:齐佳佳,过节请我吃好吃的。* A! Y0 U. @3 _! _
0 U0 [, y I9 I- }) F1 [) {
2 h; E+ x" R, k6 c" G, x! k- G******************************************************************/, y2 d' H; ~# N) y8 V- T8 u4 t
) j9 z6 ^+ n' h( j! ]& g) Z
5 f1 c# P4 s8 U% @- E/*****************************************************************
6 @( a$ ?4 _2 f' r8 t1 \2 q 文件名 : WssLockKey.c+ D6 D0 ]4 a. e, s1 i" H) }
描述 : 键盘过滤驱动& y6 w1 w7 w l8 L5 o1 C
作者 : sinister
# c6 \* _% K; x" C 最后修改日期 : 2007-02-26; }& d1 h# N, J; [6 s4 R. A
*****************************************************************/" W' Y4 W3 E6 L0 u& s
f& f+ k3 t, w& h% x, Q# w, R
) Z8 z: Y/ A9 `6 j* h) y/ z#include "WssLockKey.h"5 o& U* }! O6 y
2 Q8 R! m, h/ g& aNTSTATUS- `, B# Y. i, s3 d j+ J+ O9 z- U7 ]5 v
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
! Y' m- k: W6 x, Y2 b IN PUNICODE_STRING RegistryPath )) Z5 c( U* v5 Z* r$ h1 L) ^- [
{' k- i: l1 k$ K0 ^* t
UNICODE_STRING KeyDeviceName;
/ P* v7 W5 S# n# R0 {8 W PDRIVER_OBJECT KeyDriver; 7 n7 b: j% `2 ]8 V9 q
PDEVICE_OBJECT UsbDeviceObject;$ a8 p" z+ S6 y9 K
NTSTATUS ntStatus; - E2 V: D7 D5 @
ULONG i;
7 q' E! B* H% I- |/ \" q$ r" a* D7 l6 [; d) ?
//
! G9 ?8 J, U# C // 保存设备名,调试使用6 c) j# o% }! T; A( k
//
" g }3 @+ N% p4 o9 W% E WCHAR szDeviceName[MAXLEN + MAXLEN] =
8 x) g8 H0 {! }4 m; Z4 J8 h {& q$ B1 n" M6 p/ u" U; p+ J
0
+ X( d* g- ]) m% K };" a9 [5 Y+ \: L' G& l! A; @! C
( G+ ~# M; S7 `$ `2 e
KeyDriverObject->DriverUnload = KeyDriverUnload; . ^ O2 ^. \+ a* E8 b
) f9 t! C5 H7 a% d
//: E; P; V3 e% j7 y( r- D, ~: ^ y
// 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
9 H; m: L9 [ W4 i: h2 X //
1 ?* m; `: m: J+ x9 r4 B2 t- d, F // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法, a+ Q; b8 y+ s( @* O, m' {: t+ R
// 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其/ D. J% N. H( N+ T% @, `) U9 M) h2 U. N
// 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
4 I: M" X8 _& `; k! b // USB 键盘设备来进行挂接
0 l2 S" z4 r3 I. z+ H1 K //
- ~9 B2 w6 k& f9 r ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );$ ~2 T- n* m5 G3 `* W, U6 B4 L+ E3 ^
if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )1 G. ^0 }& d8 j3 [1 ]+ e1 |5 _
{9 Q2 H7 e4 l5 ?4 V1 n1 \7 L
//! F4 |! i0 \7 H* w1 I" H2 \# y
// 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
! p1 {) `+ `5 |$ y5 m // 所以这里打印为空* E+ i. t; }. \- f& z Z
//1 U# [6 `$ B! R
RtlInitUnicodeString( &KeyDeviceName, szDeviceName ); // USB KEYBOARD) }, t, b, O" H. q
DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );0 B9 n! m+ E/ O6 G5 Z' U9 v; U
( T }1 R4 ^9 q* J3 L+ d l! f# @0 y9 T
//
' O) j/ f! x9 U X6 g$ N# |$ M7 v( g6 Q // 挂接 USB 键盘设备
5 ]/ a! k* @/ R' z //8 e, U8 f0 X( Z" n8 ~; @1 u
ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );0 h* O' K/ _, z$ s6 @
if ( !NT_SUCCESS( ntStatus ) )
8 ]. b6 L" O$ C. @ { d5 h6 e) D4 U2 G. e% b
DbgPrint( "Attach USB Keyboard Device to failed!\n" );5 z; j; h' Z( J1 a
return STATUS_INSUFFICIENT_RESOURCES;4 X( x' i9 v: q! Y
}9 T! V' x, r- C. I
}
$ Z3 H1 n' q( i/ y8 | else
: e' \2 c: p; b7 n' B0 ? {
( Y6 m1 G# c8 I$ `$ q# P. [9 \( d //
/ f! ?6 p8 _' H3 h/ ]& s // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
& _9 w, G9 r4 Q8 K5 s1 G( V. n //
+ o% `4 Z, L$ a' Z' P RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
/ M. z, x% z1 }& ^& T4 V* \% o- Y x7 j
ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
4 Y" t1 C" q5 `- `4 h, u6 W KeyDriverObject,
u: q: C: C" V+ M' o6 _$ y &KeyDriver );% }* w3 M3 D2 G- W7 {
if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )2 x* Q5 B. f; ^8 c% ~
{
8 k) N* T# i# V" G1 Z8 [ DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
$ S( F5 O+ @% a# j8 s0 H) U) F return STATUS_INSUFFICIENT_RESOURCES;
' `8 Z8 O! U- D1 a/ Z A) d }
+ K2 D5 A, P; r" A }! Y+ u; E4 J4 w1 a2 H- H2 U
; e3 i e4 b: `$ X; G& B- N
//
' T, _: H& U1 n // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
7 ]' b- @5 t, }# H. L7 y% y // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
2 P8 c, X+ V9 Y1 f6 A //
7 H8 l# o5 `$ J4 N- f KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough; + n7 [* g+ z9 Q" B [: B
; |3 n- W* V) Q; Q return STATUS_SUCCESS;
0 Y7 K ]& K F}
9 g+ p9 P# R+ _! z7 ~
) @9 t5 C5 G! ~/////////////////////////////////////////////////////////////////
$ N' M9 I" U" h// 函数类型 : 系统函数
4 f$ H0 ^: u/ H) h// 函数模块 : 键盘过滤模块
$ v1 x: U5 J+ v" x////////////////////////////////////////////////////////////////8 {7 n7 r" l& V: ~
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,# c3 u3 d3 ]7 j \5 ?
// 卸载键盘过滤驱动
- V1 z/ a) |) {. e6 W0 t// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
' J% I; n, c! e// 则需要等待用户按键,以后有待完善) u5 V: X4 n, j( d% U3 L: u
/////////////////////////////////////////////////////////////////! M' d7 J/ m: Z4 h! Z/ I2 i
// 作者 : sinister
# ?: A3 W9 `& I/ v: o w' Z// 发布版本 : 1.00.00
6 v$ S6 \/ U; r5 [* ]- U, c: {// 发布日期 : 2005.12.27
+ B# \) e% g; F7 e2 d% V/////////////////////////////////////////////////////////////////
$ n2 z' p" G1 j8 U( [// 重 大 修 改 历 史% Z: t$ i: G, N6 b5 G U
////////////////////////////////////////////////////////////////
5 v9 [% o' k0 O E) w// 修改者 :3 p/ B l @& N4 `1 i7 H
// 修改日期 :+ i% `; R9 s6 n
// 修改内容 :1 t8 r$ f" e" U8 J% A$ b! F# W
////////////////////////////////////////////////////////////////// L" n4 |8 G! i8 E# M" `4 m
: V; O0 n0 t5 _ A" pVOID1 B0 z# v+ k- ]3 C) b
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
, \+ }' Z5 c' ?( _; E" h{
& c, g5 m3 u) `; H, c7 Y PDEVICE_OBJECT KeyFilterDevice ; ! _: r9 l! Y7 ?' J
PDEVICE_OBJECT KeyDevice ;, p0 |& H! y1 C6 W* w/ N( M8 Q7 |
PDEVICE_EXTENSION KeyExtension;
6 r+ O4 {5 K* A& o3 V+ d* J PIRP Irp;0 g) o2 _' M- g; f4 V
NTSTATUS ntStatus;
% _( P; x( A+ w' _) S/ U0 W& j2 S( y1 o; j3 B: ~7 \
KeyFilterDevice = KeyDriver->DeviceObject;
; [$ S+ \& ]: o KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; / T* X, o% h7 \+ S' Y
KeyDevice = KeyExtension->TargetDevice; ' i% S2 U( t7 H8 h s- ]7 J
+ ~9 F G2 J+ U; e% z9 P0 O& H' J IoDetachDevice( KeyDevice );
; z/ V+ e% O) ~" W" k% ?0 |% P" Y! V1 e) ` q A& d
//
( Q6 j- d d. `" s2 n, P; ?& p% { // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
. e+ ]2 N, W! d0 q //+ g# J5 v+ L' r2 R6 U9 Q. j
if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )5 B* p9 }, Y6 m) }
{) ?' Q, E/ Y1 k7 b& j5 G
if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) ): x& i1 L7 E' G0 a
{
+ N8 L, k7 d5 S9 h% k) Z //6 G& |" P' Q8 D# V& F, C5 K4 x
// 成功则直接退出删除键盘过滤设备
, H" I/ o* k( p0 d# `: X/ u" v3 ] //3 t1 j* X5 D# Q9 c5 K- m
DbgPrint( "CancelKeyboardIrp() is ok\n" ); ~/ i, W6 Y8 G- q
goto __End;: `8 W5 P4 a: u* q ], L
}: [) ?4 K6 e- w
}
' _7 H6 J7 I \) l9 n9 e1 X
8 l8 i5 V4 W6 a* h' k/ P //1 N. Q( k* A- R- P4 c
// 如果取消失败,则一直等待按键% t9 j1 |2 B8 ^% Y
//: f% ? E' K. j1 h% o* k
while ( KeyExtension->IrpsInProgress > 0 )4 {* g. a" N8 y6 Q0 w4 a/ D0 P G
{9 \/ D% ?* e/ o, ]
DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
( {3 p* P9 Z+ a* b1 D' F }5 @" H G& K) {
" j7 `8 p4 C5 D! `1 e1 m
__End:
/ o N5 ]; H y. M IoDeleteDevice( KeyFilterDevice );
* B6 A5 n# q/ w3 ?% x% U% y1 X( E9 \) O3 n$ ?; ~% J
return ;; L$ |% R2 k9 \6 E
}
( K8 Q2 ?- Z% H* C' t' e9 H+ H' H/ O7 P0 `8 H
/////////////////////////////////////////////////////////////////
: u# E1 D4 {# G; s// 函数类型 : 自定义工具函数8 n0 \' S2 \7 N. P* i1 x
// 函数模块 : 键盘过滤模块6 L/ i0 n9 \4 T- V
/////////////////////////////////////////////////////////////////
1 ~0 F' |5 L0 M! T, N- F// 功能 : 取消 IRP 操作
6 n% `. O4 q) W( ]- G5 W5 N4 N. v// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
4 M( m7 `6 T- T5 g ~+ @# {// 使用此方法来取消 IRP
, N9 i+ p, k, I4 L: o/ ?/////////////////////////////////////////////////////////////////
4 d0 F3 X8 K% G" w; r' {# y/ p// 作者 : sinister4 N+ R& \2 }3 o7 \5 u7 ^8 Q
// 发布版本 : 1.00.00; p) I \& }) ?3 Y) r% E# X
// 发布日期 : 2007.02.20
9 ~' ?3 ]. F) g3 o2 X2 N+ Z! V/////////////////////////////////////////////////////////////////5 r6 |" ~" [7 s% p
// 重 大 修 改 历 史) S! X3 ~, f) R" f2 q+ L r$ a
/////////////////////////////////////////////////////////////////7 k7 \% U: v) u! A# M# D/ \
// 修改者 :
7 F Q" ?2 B; j; B2 [// 修改日期 : * g% m1 O" d4 o/ S. C' T9 ?
// 修改内容 : ; s7 i7 E/ F6 E0 @3 @* R+ u
/////////////////////////////////////////////////////////////////
1 o# r$ R) j4 A( L$ N' a0 h( |6 @: D' n" H. y; e, O
BOOLEAN
6 X% d; }+ E: J4 J4 ?# JCancelKeyboardIrp( IN PIRP Irp )
/ p, I$ j& G0 K{0 y1 y3 S7 X0 a" I) `) j- O
if ( Irp == NULL )
+ J O1 L! Q8 v {
! {- O: _# v& h DbgPrint( "CancelKeyboardIrp: Irp error\n" );
" q5 r8 o9 K2 n; `; h return FALSE;
: z' G8 i r) R3 ~1 y6 ?2 m6 k }
+ g7 B' I) K8 h, `, A! M
1 |3 J) W1 _8 s h
6 u* [6 K _2 d& P //9 V# @" z3 [7 ?( } T6 c
// 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
$ p% h/ n T) C" u+ o // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。: r& X% D/ i1 I ]0 H
// 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占* M1 E0 q; E4 Z5 g
// 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD3 i. g7 z' h/ j; f; a. O& u# r& d
//+ g* T6 C, B) O# F% M8 g5 Z) @
* Z0 r+ D7 ~0 E2 v' W3 w7 q //
: P1 U1 G! f) S+ }8 C( {! b // 如果正在取消或没有取消例程则直接返回 FALSE0 N* Y* I+ C& H; C2 X3 ^. d. d
//
* ?! |/ m2 F$ Z) |' D7 B if ( Irp->Cancel || Irp->CancelRoutine == NULL )2 w+ [6 `% X0 d. C% e
{
+ A5 a/ R4 ~+ m4 h/ Q' c DbgPrint( "Can't Cancel the irp\n" );3 a1 O7 J8 p! W# J' {9 n5 t
return FALSE;0 ?0 ^# d* J8 y) j% m
}: R5 f% x: _1 N! p
" ^) Q8 x5 I$ R# R* O
if ( FALSE == IoCancelIrp( Irp ) ). m9 f$ p/ f- v% g
{3 y: t9 A& R, Y
DbgPrint( "IoCancelIrp() to failed\n" );
0 K8 B' z7 r$ K8 I! v0 M7 X' C return FALSE;7 ` D1 Q' ?+ X& W" p. z) |
}
7 V2 n3 b2 S' P
9 u& c: f0 w3 y //; Y* x+ g9 |4 L- X9 J; c
// 取消后重设此例程为空
" O: r0 |$ u9 w- E9 B- S //+ X g+ K+ R# k R$ c% Y! V
IoSetCancelRoutine( Irp, NULL );
0 U$ k* C# @0 c6 ?
* e9 |' l! t6 u* b return TRUE;! z; b8 Y" @9 m5 f9 `" X* [4 k
}# `2 h8 z3 _$ V' s
, |2 j* I" q( e/////////////////////////////////////////////////////////////////
. ^, N8 q8 N6 F7 L1 s6 F// 函数类型 : 自定义工具函数6 L: x6 m) {& F6 E3 e& x+ i
// 函数模块 : 设备栈信息模块
1 q/ ]6 C7 o8 N/////////////////////////////////////////////////////////////////0 q5 I; ?, R( Z( J: [- l5 r% @
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘7 l& u* j6 @0 N: w
// 设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)3 {& t! `$ f* X0 z
// 注意 : - i `# y9 q. P+ w+ X
/////////////////////////////////////////////////////////////////1 z: `( [0 B8 F4 x/ D6 v: c
// 作者 : sinister
, }% W' P4 W. G+ w// 发布版本 : 1.00.002 N# |0 W/ ~% d
// 发布日期 : 2005.06.02* I9 V6 D- Q* L6 k8 J! ?
/////////////////////////////////////////////////////////////////" i) @7 `1 n% x) G3 g
// 重 大 修 改 历 史
1 K% @( j8 ^ K6 |% i. T4 s/////////////////////////////////////////////////////////////////
" g4 V6 ?0 ~' a+ P4 K// 修改者 : sinister$ `6 e q+ K1 A( |
// 修改日期 : 2007.2.12
; g# c; O* q1 u4 |2 l5 \3 j// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改* p' H4 x6 u0 y. [1 k
/////////////////////////////////////////////////////////////////) N3 |: P% {* s/ H& w- d
; _8 k3 Z, U- b y8 @9 rBOOLEAN
T) r$ h: [: M4 sGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )8 Q3 q$ }! p9 R8 I K% ?
{# m+ a" n+ t. A/ S+ i
PDEVICE_OBJECT DeviceObject;
+ U6 x; b3 y+ M7 @5 u" p BOOLEAN bFound = FALSE;
8 N0 l! d, C5 ~
6 }4 h* c; {1 t# \ if ( DevObj == NULL )
5 h1 K' s. Q' A3 z% |9 m% A {
" R8 D$ ^4 N/ Q DbgPrint( "DevObj is NULL!\n" );8 L. q# q' [0 O
return FALSE;
$ q, I, H w$ c Z/ G1 j }
4 E, q3 n0 R: t! E- x" Y$ j4 i* [
7 b. y# t e# ] c DeviceObject = DevObj->AttachedDevice;
1 d" a) m6 Y' _. c% {
1 w( @, I2 l& T+ K: a X5 `* K: o while ( DeviceObject )7 I8 p% [* H% S# L; ?$ v
{& b( i% Z v2 D/ k n3 C1 Y; L
//1 Z$ C( n1 q9 R3 z- g$ v# P3 s3 O
// 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
" X/ I, _* \9 z; R) W) | // 有一次足够了。这算是经验之谈- e: u" @8 I- b [& z
//4 ]5 m5 ?+ h0 {
if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) ). K6 u6 Q7 l# R
{+ d+ i7 l5 u G! i2 [9 y/ r
DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",- N5 V# p: R5 u0 y9 G+ U
DeviceObject->DriverObject->DriverName.Buffer, s2 ]: v3 D. C& q/ F+ C! g
DeviceObject->DriverObject,4 ]% K( _; K9 h# H
DeviceObject );
4 J6 z6 n8 W5 b- y/ Q' _4 T( _5 t' i) Z! `
//6 C7 r y' P \# v
// 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了5 ~1 ^: u! b3 W4 I
//
; {( O% x/ Q3 q8 G. C. J. @( ^2 @ if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,3 n# P+ D) ^- S. `8 H% Y& A2 y
KDBDEVICENAME,( w5 e% T6 s, Y
wcslen( KDBDEVICENAME ) ) == 0 )
: m5 ~' b: @1 E' _ {" a4 @. a% R5 K/ n u0 X
DbgPrint( "Found kbdhid Device\n" );# q1 K0 i! e( f# }
bFound = TRUE;% P% k! \& ~: r& m) E+ ~
break;2 x# N+ }% o7 p7 w0 L. D/ C( L u
}- E; M. i. K% k. A8 `# f, u j
}
; Z: x5 l- N$ u8 o3 [1 b2 |- B
3 r7 |5 q: ?- l! F+ S( r% s DeviceObject = DeviceObject->AttachedDevice;" e5 o) C2 `" V5 B# O8 q
}6 e4 F, F2 F; I# v- e
8 J3 e. _. s! ^/ r4 x& [; Y
return bFound;; i. _7 l0 ~1 E) `( V# ^4 U
}5 J5 e- ~ W6 J9 F2 Z N4 |* U0 ?1 W
3 ^ R4 D1 |+ ]6 u
/////////////////////////////////////////////////////////////////0 ?; L G5 z- E, J) d! [& b% `4 u
// 函数类型 : 自定义工具函数: V9 F+ q% L& [7 B
// 函数模块 : 设备栈信息模块
, c* G4 V" f1 U0 i0 L2 C/////////////////////////////////////////////////////////////////7 }5 r% y8 |4 K
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
+ r3 `3 |" m6 o// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
. k; I6 J2 v" `+ V3 y9 f/////////////////////////////////////////////////////////////////7 z' \# \ _% D# R" z% P5 [8 a
// 作者 : sinister( i7 o6 d# o% \- }
// 发布版本 : 1.00.00
' H3 b0 A& @$ V7 x// 发布日期 : 2006.05.02! n. j' p7 {: s
/////////////////////////////////////////////////////////////////; r7 E8 {5 R* w) S
// 重 大 修 改 历 史
* |1 ]; M- e; p6 ]5 Z/////////////////////////////////////////////////////////////////
5 ^/ l; e# t% _4 q: n/ V// 修改者 : sinister
) k1 G; w) b( Q5 h; m0 x// 修改日期 : 2007.2.12
$ b( y# g' _0 q0 T/ h+ O// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
" {. z) Z( T4 E/ Y/////////////////////////////////////////////////////////////////
& R2 m- ^. V+ W( \* W" J
. l' J: `& g# O0 h! V- ]! Q( MVOID5 K( ~( u+ C$ I b
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )1 R7 ]8 ?4 S2 _# S, c
{
$ b$ Y$ f3 M% L) U$ l7 P2 ^ POBJECT_HEADER ObjectHeader;) B f! D( [ P0 p- U6 S: ?5 I
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
: i. O5 T+ J1 [' h5 F6 J9 F# e0 | Q: Q" X3 S
if ( DevObj == NULL )
7 X& p( g0 _' `, q6 g# D {
# `7 [0 h% G6 W b/ X+ P- i DbgPrint( "DevObj is NULL!\n" );
4 {. \% o5 ` h$ ^# P return;: ?( k9 Q. ?4 I
}, w: D9 i% [0 z; O
7 |4 Q/ Y7 w6 X //
( b; n8 ~1 A9 W- F: {( b3 G // 得到对象头
$ T2 M# R- d) Q- t, n //
3 C' G, J) I- M5 M0 i3 q/ _9 U g ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );* c$ Y# i) [% P5 W$ Q/ d* y
2 m) C1 z6 o' A. f
if ( ObjectHeader )* Y ^ h. g% l
{5 q; A. q0 Q4 f n1 \) }( Y7 Y
//- P n" }( T: `
// 查询设备名称并打印! @- y% L m- C# a
//
) w8 ]( s7 }# G6 h' K2 M1 D/ x ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );& X' G3 C( X$ Q7 H
( p2 b& I2 k a
if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer ); F6 w6 _! J3 W! o6 m0 u1 F
{
0 i) e h- c: \4 P: o! W$ _ DbgPrint( "Device Name:%S - Device Address:0x%x\n",
# B7 ^$ ~& E; I6 w' H- M0 B ObjectNameInfo->Name.Buffer,4 Q# g: l' M3 {. E
DevObj );; h9 B/ m$ v# X5 a1 V8 d* g. W9 o/ j
0 }% m& E2 e# e, Z2 P' P //- J9 d' Q0 K. n+ w
// 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示' u, y0 Y3 T0 a6 U5 D
// 用,没有实际的功能用途+ E, D- [- A. T9 r5 l1 Z, P. ?9 ~
//& B+ d; H$ d$ `! }4 S; s6 q
RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
) G( b* p; @8 b/ D7 x' N6 ?
2 K. o" k3 L! G wcsncpy( szUsbDeviceName,! s( w9 Q; A8 h
ObjectNameInfo->Name.Buffer,
0 Y/ t' T7 A: E( [! X, d$ C ObjectNameInfo->Name.Length / sizeof( WCHAR ) );: [1 T. w, S3 l
}/ F$ {3 ^- l: K7 l, U' }
7 P( H8 T7 X# W+ H7 Q/ k //$ g/ o" _" C1 V; s( |
// 对于没有名称的设备,则打印 NULL
, a2 c5 c: S. O. D3 e' |( g //
4 U- S, c, P4 a7 f- u. }# U' \ else if ( DevObj->DriverObject )
S. t x/ t( o6 W2 E6 w; B {6 G$ b, Z ^3 V9 W
DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
N" f4 h& l3 U% S/ r% P DevObj->DriverObject->DriverName.Buffer,
4 s5 ], @: V, ?6 ~; p/ H, E L"NULL",' P) ^+ H' f) s/ Q7 c; H' A
DevObj->DriverObject,: s/ h0 A% {& N" |5 |3 d* Z( D1 r
DevObj );
4 m+ i' i7 B! x) e$ M* n P* z }
0 _/ Y T$ o9 L% t }) M" A0 {% D9 C' \' o4 d
}* J% _6 w. [/ | j, t) E- ?7 ?
( `, Q) G. T& k/ d
/////////////////////////////////////////////////////////////////
/ [8 v& h) @ _// 函数类型 : 自定义工具函数
1 I% |4 G3 R Q( p0 s9 C// 函数模块 : 键盘过滤模块
' q7 S2 r2 P+ ~' I0 k0 v/////////////////////////////////////////////////////////////////
# W# O/ k) e( D) a// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备& x0 X1 R$ @2 Y4 h7 k6 n
// 对象,过滤出 USB 键盘设备,将其设备对象返回
# \! a: r3 \5 R* `- x* c, i# ?7 K// 注意 : ) D+ m: x @" e
/////////////////////////////////////////////////////////////////
9 |5 s& k$ [( C9 D5 G9 ` v* `// 作者 : sinister7 x- m; ^( y+ T2 l
// 发布版本 : 1.00.005 S# P+ U3 C7 [: j7 n
// 发布日期 : 2007.02.13
, J L- e9 c1 G+ ?/////////////////////////////////////////////////////////////////
/ C# I+ b8 U5 }! T# `2 Y7 {$ ~// 重 大 修 改 历 史8 P4 a3 n8 h- R; }
/////////////////////////////////////////////////////////////////3 c; ^4 c: E. X- A- {$ o7 s" g, ^
// 修改者 :
! ], U% ^/ d" m( p) h7 h) I9 ?// 修改日期 : % Z$ o8 E( M; N$ f, k( y
// 修改内容 : + E7 b m7 e, v( r8 Y7 h s& m
/////////////////////////////////////////////////////////////////- V4 E/ p1 L) U" m
5 l1 h6 k" ~0 [: y! X5 A- U6 e
NTSTATUS
. D; Y# [3 b% ~+ l/ ]( aGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
: X) ^! @8 ]' p6 k) d% N2 H{
: }) c4 t q, U) k" g5 j: c UNICODE_STRING DriverName;/ ]# r; |; d' i1 l
PDRIVER_OBJECT DriverObject = NULL;! _4 e! n# W: R1 r+ B0 ?
PDEVICE_OBJECT DeviceObject = NULL;
+ E; V. s" ~& G9 ?3 \7 O6 Q: h9 i BOOLEAN bFound = FALSE;* f& A; A9 c3 T' L- z! e, ~2 l
: k: h+ S# l# N$ m% A( n! l3 I RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );3 N' f3 |2 F5 A @
0 v5 N4 b2 o6 B, S" ~ t
ObReferenceObjectByName( &DriverName,
: v8 `4 B" _0 S8 R) A OBJ_CASE_INSENSITIVE,
7 Q: s& P$ R% U- d& w: a3 N% o NULL,0 K" p7 m/ \" F9 Y7 D! |4 F
0,
' Q5 \* x; H3 X# ]. f ( POBJECT_TYPE ) IoDriverObjectType,2 j: `% e d! n B
KernelMode,
/ N c' U# t9 l NULL,& W2 v$ t: m( t4 Q4 K+ O
&DriverObject );- H5 K) k. N- A( _2 X$ R2 O3 n
2 R4 h% C' S+ c1 X; R
if ( DriverObject == NULL )' q1 J4 ~ v' x
{
3 t8 s$ {" y0 y DbgPrint( "Not found USB Keyboard Device hidusb!\n" );) ^; m2 a1 c$ u. b) S5 H
return STATUS_UNSUCCESSFUL;
4 {# L+ T! g- W- k }) \, y+ W: K3 O
% J' ?2 V/ I% Q$ j9 ^
DeviceObject = DriverObject->DeviceObject;
# h! Y$ I8 s4 A9 R
( T5 y3 h3 i( @$ a7 | `+ s while ( DeviceObject )
4 |! L4 P9 i: D- ^4 J) O* x {" v# h+ W1 r! k4 ?2 f$ J; J
GetDeviceObjectInfo( DeviceObject );1 I3 a& t% V3 L. Q* [
3 U9 b+ z4 S# G; n! d& e if ( DeviceObject->AttachedDevice )
1 V2 K$ ]% s# a {
' F1 ?3 O, w) T! u% d8 H" J8 E" V //
* |9 {6 K2 l3 S& F/ U // 查找 USB 键盘设备+ V5 l$ P$ Z9 {4 m3 j; m8 r% A
// U2 a* @, C) o3 A
if ( GetAttachedDeviceInfo( DeviceObject ) )4 b: b8 q M0 O' }4 b% u i
{; s. ^" h! u$ f& c
bFound = TRUE;
; z4 Z( O0 x# `, i& p goto __End;
1 {! r! Z8 D5 M! s; y; |+ v }* @& O4 P% E& p8 x
} K" Y+ S* V4 E* k
0 y i" b4 u2 U0 |' |
DeviceObject = DeviceObject->NextDevice;
" H5 E9 b3 G+ V2 I7 F$ g5 u% w }5 ^6 v+ f# E+ o9 O1 n& O' Z! B6 F
$ F" W. Q9 [0 U# o1 @ __End:
: ?! L: F" `+ j: h' ]. e, |9 J' |6 m) U8 \: W: M( o% S' v! J" q
if ( bFound )+ Q+ p4 @; j( o' s
{
, b7 g, x2 A2 A& w D- W4 c //
7 _' p6 V" C7 g& h // 找到则返回 USB 键盘设备对象3 G0 G4 O. g9 A4 D4 c9 E
//
/ N! S) I+ K4 P' Q6 ]% G, ~$ K: t *UsbDeviceObject = DeviceObject;7 T! O. H! b% u% z' o# V" Y8 n
}5 N; G7 p% G) n2 P, S: a2 ?
else
- U' `) Y0 _& _; M {
. Q1 q4 g% G, U *UsbDeviceObject = NULL;
: L2 C+ q y) F. ~# a3 J }
& F* \9 t9 X2 T+ _5 _9 n: v7 Y+ x( {
return STATUS_SUCCESS;* b' Z0 l+ ?* o
}
9 s5 g& x5 @7 D C
6 o6 s; m! O! W* H/////////////////////////////////////////////////////////////////
* e# N$ Q. Y2 A& ?3 X0 x& _) F// 函数类型 : 自定义工具函数
, \/ l2 {6 V+ A$ q, V9 D// 函数模块 : 键盘过滤模块
5 {2 j C" o! [# p/ W////////////////////////////////////////////////////////////////
2 k1 N0 Y5 b9 q/ c: u1 L2 _6 G+ E5 F// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关) e1 X9 Z2 |: \5 V
// 信息,返回附加后的驱动对象9 k) D. T1 B4 p' a1 S# M
// 注意 : 此函数仅挂接 USB 键盘设备
/ t7 W' p. |) N! `7 I/////////////////////////////////////////////////////////////////. p! u4 f9 x* N+ z% c
// 作者 : sinister% C7 ~, d) J' [. }' a
// 发布版本 : 1.00.00
% `& Q* C' x& f8 {: m// 发布日期 : 2005.12.274 n2 x* Z: M- D& q# V4 W; x) X
/////////////////////////////////////////////////////////////////
/ l; S# r, w o# v// 重 大 修 改 历 史$ p8 M2 H/ W& H7 Z# M2 R
////////////////////////////////////////////////////////////////
) x* g9 r3 j+ I' Y// 修改者 :
) f8 |0 g; G7 {" f& z// 修改日期 :
) V. ~7 Z* D: q6 E* Z: p0 L// 修改内容 :8 C1 Y, t r4 o4 }' W
/////////////////////////////////////////////////////////////////' @1 l5 e; n6 Q9 s L; V
L, D( Q! X1 J! ^NTSTATUS
+ {8 F9 |" q; kAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
6 t5 B0 j" j4 P7 E: ^7 U4 ^% F IN PDRIVER_OBJECT DriverObject )! E9 X2 _# J# Y. Q/ ~) B5 |2 q
{+ i# j4 V) X# t3 u7 Y3 e' B
PDEVICE_OBJECT DeviceObject;
2 I- T; u3 o/ s& e/ @ PDEVICE_OBJECT TargetDevice; 0 F- O+ M5 L* M- J
PDEVICE_EXTENSION DevExt;/ ~( u! R. R) Q; L
NTSTATUS ntStatus;
4 Y: O5 F& K4 R% J6 }* A! v- u4 b9 O0 g' Q
//
7 A+ a8 j: Y. n7 ]( `$ f // 创建过滤设备对象( x: @( z$ d0 Z3 i0 Q
//. c% S( f4 _/ ~3 v7 Y- a! m
ntStatus = IoCreateDevice( DriverObject,
! X& y8 ^: \& ]" A. }1 V2 N sizeof( DEVICE_EXTENSION ),+ I- Z1 @/ v6 c) J( m
NULL,) g! k: [1 F' x, Q& ^& w2 q
FILE_DEVICE_UNKNOWN,. ~2 S/ D- y$ ~
0,) X; B9 v* s# Y9 R
FALSE,, p6 j( l( Z. v# l+ R1 }" Z% |5 }
&DeviceObject );
* u D) J0 W: b/ }# X, F7 Y
5 H# q7 _) W% F3 ~+ m. j F1 O& ~ if ( !NT_SUCCESS( ntStatus ) )0 O9 w- K8 h/ j2 v6 j3 Q
{- P& M4 T" a( J8 N5 N
DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
. n' S0 I. |- ~4 S return ntStatus;& h& C. Q+ [5 ]+ ~/ ^3 z
} # ]$ |4 b V6 A; {6 U* B2 {
5 q; O2 Y2 y5 V; @" _; x8 M* e" U1 x
DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
2 ]# J n1 X; J* y" O% w% I. S& j/ f0 i5 W
//
G: \' k5 X+ v& G2 K9 I5 W% D // 初始化自旋锁8 y+ U- Q2 K9 N6 |3 t
//! Z. a* I& c- R; {: S' G8 D
KeInitializeSpinLock( &DevExt->SpinLock );6 `' l" A0 N' j. o1 b- I% p' k% ?
2 l" X0 r# [0 V. E1 E( U //4 u5 _0 v. B3 _" f1 H4 l
// 初始化 IRP 计数器
" B( @& c5 I0 r) B/ q; j //
: \& H) a2 r0 U* l2 { DevExt->IrpsInProgress = 0;/ a0 }5 n$ q& u9 Y( f% i% W$ N
9 E# [) D6 O5 Z. b c% r7 z/ _7 ~6 U! H# [ //; o. I6 m* P5 X+ V% c X
// 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象. L3 _4 M9 e, _; H( v
//) U6 }; Y% u; u' \2 P
' w' o+ B) `+ l3 ?) B8 J. { TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
& W- G, J- y6 W2 U$ N if ( !TargetDevice )
" O! K) c8 j$ H {( v* a: T! W o
IoDeleteDevice( DeviceObject ); % ]/ f% V1 ~: d8 H# f/ @$ w
DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );* W9 V+ D3 @9 B! f' D; D
return STATUS_INSUFFICIENT_RESOURCES;
d! `! p, b" J* R& O, \ }
6 c0 i7 v8 P; m3 S3 X6 g
- |/ p& K6 s) o1 J( \0 [ //& v0 [" G( b9 F
// 保存过滤设备信息
& {' J4 l u, j! z" {$ a, ^ //$ E1 G5 a o# @3 I! ?
DevExt->DeviceObject = DeviceObject;
, J6 `9 F( {! Z( \0 u8 i2 i DevExt->TargetDevice = TargetDevice;: O$ g6 \0 H" k
, X8 T- X" W( J3 s# A$ C8 A
//
4 @$ I s d9 b X // 设置过滤设备相关信息与标志5 E( Q1 L! ~+ b& {$ i- q! C0 g
//
8 F2 W8 i+ d2 t$ F, r/ ~; v DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );4 `$ l: ?& \; v9 L& N
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
; c6 w2 ]8 e h0 D4 _0 G: z5 F" s+ y0 k9 }9 ?5 s
& W& U( ]& h; F( U. H+ k2 m) r
return STATUS_SUCCESS;2 J. O# o9 a# M/ T3 K
}$ Q& G$ ^" p7 L4 s9 U4 b! y" M
* ]2 G9 ~8 `4 u$ _/////////////////////////////////////////////////////////////////
2 ?# s( Y( g! ?2 {5 R" B// 函数类型 : 自定义工具函数
' Z( v+ m. P7 Y) y, z// 函数模块 : 键盘过滤模块* I m" K! ^% K
////////////////////////////////////////////////////////////////
+ v6 A+ V ~0 o4 A- Z// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
6 z) ]0 I8 L0 k& f: ^// 信息,返回附加后的驱动对象
1 d8 i2 N+ T. D// 注意 : 此函数仅挂接 PS/2 键盘设备
+ d I' q( o* C- }/////////////////////////////////////////////////////////////////
* }2 E. U% U& d7 s A// 作者 : sinister( _/ { Q% P7 L5 A% w4 T5 T: ~
// 发布版本 : 1.00.008 g7 d/ L5 ?5 J2 a& k3 t
// 发布日期 : 2005.12.27
7 X. T. j/ L1 _+ m$ N* _/ Q/////////////////////////////////////////////////////////////////
; m8 \0 f8 I$ X' x7 b( H// 重 大 修 改 历 史
; A; o, F# v7 J6 }8 A l0 F////////////////////////////////////////////////////////////////2 E, c! q! J) G
// 修改者 :$ |- Y" g/ p! D; O! y
// 修改日期 :1 ~6 @: P; h m+ H, \
// 修改内容 :
+ E( s9 s1 w! L& r3 l////////////////////////////////////////////////////////////////// l" n$ x1 L# Z$ u# w
5 R8 H6 G0 `' _; v! @, R" C S% GNTSTATUS( B* n$ Z' G9 V/ `8 V4 q
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
7 l* b& p; q4 E# [- c- ? IN PDRIVER_OBJECT DriverObject, // 过滤驱动也就是本驱动的驱动对象
' b1 c: N+ P# w OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
" {7 Z; z$ K! B$ w" c4 g# [{
/ s7 B5 E A# y PDEVICE_OBJECT DeviceObject; - h" k$ g& G3 J2 F, |5 F+ w& v% f
PDEVICE_OBJECT FilterDeviceObject;
7 c, Y7 U& \ \ PDEVICE_OBJECT TargetDevice; * I' Q4 w7 q3 ^4 K3 J
PFILE_OBJECT FileObject;
/ H& [% V% o* f. G PDEVICE_EXTENSION DevExt;
; M/ o; X' r# o) o o9 x" V3 @( _
+ I9 T/ O) [, h NTSTATUS ntStatus; 4 b: z+ I( T6 M' s# L
' K o4 F6 I$ M1 C; N- m
//
! S5 ]& T9 |& Z) S // 根据设备名称找到需要附加的设备对象
# o- T0 U4 G+ |/ l //, w$ Y$ g* u, k# @
ntStatus = IoGetDeviceObjectPointer( DeviceName,1 A. E9 C! i$ Q% Y
FILE_ALL_ACCESS,
% Z3 n9 k6 t8 u2 q& u( L &FileObject,
1 r# C, d% p" ` &DeviceObject ); ( n5 H3 i5 L- A( | \" g* L
1 X) J+ I! R3 N! e% F* l
if ( !NT_SUCCESS( ntStatus ) )
- o- p$ {! j! P4 K/ L {: e V& ]1 y3 I5 A: h H; V
DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );0 K( M0 ]6 `& q/ ?: E
return ntStatus;( P6 g! s" U$ {8 ^$ P# \
}
, \6 R4 Y& @5 B# M' n C# Q* q& \& O. g! l, L
//
" P& F, _! U) F$ y+ \8 F8 H // 创建过滤设备对象$ @$ g' m+ l* R* t' v
//# |3 i9 l6 z5 E
ntStatus = IoCreateDevice( DriverObject,' t; P% P' @8 j, ^
sizeof( DEVICE_EXTENSION ),9 H& e. ]5 C1 D8 b
NULL,
! h* a: L" c) U2 o1 N+ s FILE_DEVICE_KEYBOARD,/ b/ V( t* [* g8 h
0,
2 n0 r, v! Y) O* j FALSE,
; e" p. f* w' c &FilterDeviceObject ); . n/ D4 N1 v: i- _% {0 C' l7 ^
3 U3 E0 w1 ~& G' }8 y
if ( !NT_SUCCESS( ntStatus ) )% g3 j* n% h0 ~+ Y0 r( ^% ~
{
3 r) H0 K, b9 p0 Y5 o8 D4 D' ~ ObDereferenceObject( FileObject );
/ S l, w& F2 T; Q2 H" |; g DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );+ y5 q1 i* c! k6 d+ N. B
return ntStatus;
1 H0 }% C) p" t( N2 v o } % G2 Q3 _, q" y, A; M5 {. u' N
8 t1 k% F' }( G% w4 G- l
//: W8 @- a3 g! ~3 Y( {( }1 }1 f0 W
// 得到设备扩展结构,以便下面保存过滤设备信息) A7 A- ~' P: h* `' d
//
9 U* G& D3 x" Z+ q! i DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;+ X a) h7 ]) ] Q
5 E" s, T( w' K7 N
; m( x7 }- x2 B0 _4 W `) n) R
// M J+ i1 f$ ~- V
// 初始化自旋锁
! c8 T" d0 V- a' C //
! @5 h Y# H8 u KeInitializeSpinLock( &DevExt->SpinLock ); P2 C$ h6 s3 N; r( w- K; f i5 |
5 k9 u+ @3 j# p //+ K' z' Y. h4 f. v/ e
// 初始化 IRP 计数器2 ^9 w4 ? A" q, `3 o6 }; n
//, E. t' Z3 Y8 e- m! y5 H. z
DevExt->IrpsInProgress = 0;
$ E% H8 _! x4 X p1 o
3 a# h0 `/ [! R7 \% f' h" ]/ m //. h% w( d( k, `" h! A _$ f: H
// 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象6 K+ N/ b) i( d: B1 W
//) o: m/ E" C2 R G. J/ w2 V4 h5 [
TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,! i) l M! D1 R% x) C+ v8 \
DeviceObject ); 3 ]* ?' K/ ^3 u- d8 J9 L1 D4 Z
if ( !TargetDevice )3 t' ~2 [# C4 R- l7 L K3 ?/ t4 j
{( {% R: ~. O }) D8 M% ?8 C
ObDereferenceObject( FileObject );
) ~8 `& o5 x0 w1 S3 ?4 v! a IoDeleteDevice( FilterDeviceObject );
9 q; Y4 }3 s: O( ]* {1 C' q3 u DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );+ _% a% \& M! U0 `2 ~9 P7 c" o
return STATUS_INSUFFICIENT_RESOURCES;& w& `* V- f5 j+ Z% K; ~0 m
}
% Z, E8 j7 r2 k
! s. G) t9 i4 A //
7 f% W* {; P4 T7 j1 q // 保存过滤设备信息
% F s9 h* D$ q' l1 }$ z8 r) b- Q //
/ F5 ?5 h* p2 A DevExt->DeviceObject = FilterDeviceObject;
9 ?0 a: ?' `3 Y DevExt->TargetDevice = TargetDevice;
) V! B/ B" V: G5 U$ G% p DevExt->pFilterFileObject = FileObject;
) p p8 C$ A2 y x5 C5 S" d2 N
" q+ V9 b/ \' D# x //" Q' L6 ?, b+ v& C9 E/ Q% ?
// 设置过滤设备相关信息与标志3 J( M+ \! h2 n7 S' C/ F
//# l, \& W7 x! w, J# J& e$ O. ]
FilterDeviceObject->DeviceType = TargetDevice->DeviceType; . Z! o7 o/ @# I+ n# L% D
FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
0 B# p1 o( m2 Y4 [ FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
' ~3 Z% s6 h- j) H: I6 M4 Q FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |' b V w$ u9 u* F- d* a9 b: t
DO_BUFFERED_IO ) ); " t$ G k: w2 b1 J% q3 M
; K' b! P9 |; \7 |/ U n: J //, Y$ q) O: Y" y; I7 L O1 ^
// 返回附加后的驱动对象* R1 S" a5 r. f# V0 ~! Y
//
! P' y/ p$ ^6 h' F4 u *FilterDriverObject = TargetDevice->DriverObject;
8 g/ f9 A: D% S$ C- X$ Z3 Y2 l% `; d
ObDereferenceObject( FileObject ); / @; _/ y1 V. |6 Q Y% u& s
: U9 K7 l4 H+ a7 C P return STATUS_SUCCESS;
6 D+ Y( D" U$ L" k}
0 ]. ^5 l4 l: N& n7 j0 u O+ _/ D$ m) U( ~! J
/////////////////////////////////////////////////////////////////
* x5 X3 }+ U4 g9 | J2 Q# F+ P+ ?// 函数类型 : 自定义工具函数7 @' Z% i4 H2 i
// 函数模块 : 键盘过滤模块! F7 s, {" a: ~1 _, n8 U2 z, @
////////////////////////////////////////////////////////////////% P( z; j3 J- I$ U
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
5 Q* ]: X3 I$ s' h' m; ?// 这个 IRP 的完成
; U! K: d6 y; L$ K4 E2 M. b// 注意 :
) |3 {) v- U. a7 Y/////////////////////////////////////////////////////////////////$ Y( g, ^! H3 r
// 作者 : sinister
: L5 v8 ^# L6 v$ z7 G, K2 c// 发布版本 : 1.00.00$ j, M7 h, E+ u+ H/ }3 R
// 发布日期 : 2007.2.15
% |( T' e" ?4 A" t- `6 N4 A/////////////////////////////////////////////////////////////////
! ?; m& \3 ?+ R; W6 E// 重 大 修 改 历 史
% U+ w$ \8 A: L7 n, F1 I4 S////////////////////////////////////////////////////////////////
2 H% j( G R) @7 f9 R// 修改者 : ^0 [4 [/ A# S: K- D5 C
// 修改日期 : ?; V* Y% y2 w4 l
// 修改内容 :
0 @' k" B3 M4 Y: R: Y" B/ J$ E/////////////////////////////////////////////////////////////////6 O0 s+ R% d- Y( Q
+ L; y6 }) \9 d4 H0 x9 f
NTSTATUS" }* ^' l: M* T; H
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
* m; J# D4 M) q5 ~* k{
7 ]. N' n- {4 g1 ]' j0 y4 G NTSTATUS status; & Y; s1 f( E6 R( j7 g% H
KIRQL IrqLevel;0 U% N/ @1 ]: {
" N8 L4 I0 I2 s1 x, X/ E. S) f PDEVICE_OBJECT pDeviceObject;
+ a z1 P3 t( d! c) a, ^1 Q& K PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )1 Q. f# l. q) {$ F, _* W
DeviceObject->DeviceExtension;
" e/ x2 j! }9 u' Z/ p V
% |9 v- y4 ^6 N0 y/ R- j5 P; d! U# C4 Q4 i* U5 x9 Q) c% J
IoCopyCurrentIrpStackLocationToNext( Irp );* R1 v- N7 Y: n) @# C
* ^, N6 _+ n$ g2 t //
0 r- h6 e8 T3 C9 B // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
8 `4 D6 V( G+ _' w //. h( c4 q7 F$ f9 f' i' M
KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
/ @+ h+ \. {. u( j+ Q9 H+ N InterlockedIncrement( &KeyExtension->IrpsInProgress );
, \8 i: g3 S% ?- j* m! V: [/ E KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
" Z3 B+ {1 y% j7 v2 ^1 e6 e7 h, N4 @9 t+ b+ b
IoSetCompletionRoutine( Irp,$ V$ ?0 z- ]- F" Y
KeyReadCompletion,! Y* ?, F N6 r# G0 E+ z: ?2 F4 Z
DeviceObject,
! z- [/ M- u& M$ {" |3 Q TRUE,5 ?1 M! q) v5 k6 b
TRUE,
; ^4 N: w" h% G i8 X7 n TRUE );
" `) @: T$ `# n$ P0 W# |
- n. ]4 H8 ?; j- {% [+ ~7 ? return IoCallDriver( KeyExtension->TargetDevice, Irp );! I! F# a# j d1 \
} / B: H3 c( x `4 b; x' V
# t. i8 L: j8 Q3 P' q! F8 n; U/////////////////////////////////////////////////////////////////
+ R: p; t. K% z& ?* {// 函数类型 :系统回调函数& i& H5 ?+ [" ?1 _' X( T2 g; y
// 函数模块 : 键盘过滤模块( X2 d/ d5 U: X* A0 I
////////////////////////////////////////////////////////////////3 u+ |/ e! W# `9 N# {: d
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
) J) H' w4 q$ w0 h5 N5 `; t: `& J// 注意 :
8 L4 i( @( c& b: }% {1 a7 Z2 o/////////////////////////////////////////////////////////////////
% {1 {- K" _+ Q% j8 h3 H7 y0 ~// 作者 : sinister
+ D* z4 J. ?- a3 [// 发布版本 : 1.00.009 ~2 {: L+ s2 B' o% i% w' l/ @
// 发布日期 : 2007.2.128 h( ~6 d3 ?, O5 c0 Z) Q0 w9 [. U
/////////////////////////////////////////////////////////////////
5 u, ]; ?' e9 @0 Y- H// 重 大 修 改 历 史
^$ [( O$ Z% N8 k9 x: ^. W////////////////////////////////////////////////////////////////
" V: A! M# V3 u: n// 修改者 :
( Z- {6 o! [- B. R6 k, o, i+ `' M// 修改日期 :6 b5 X" f+ q# L- y
// 修改内容 :( d- t! q4 z5 C" h( P
/////////////////////////////////////////////////////////////////
- r/ h. z6 i! ?* S u0 e% Z7 H6 N/ }- i0 X. o2 S ~$ p" a* O) g3 u
NTSTATUS) \, i; @- V) `- Z+ v" @
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
7 l; T, M" g: n8 j IN PIRP Irp,
" O' p- s/ {* W IN PVOID Context )
$ A, H9 Y7 \- G+ m. w7 }2 v [) V{
% y/ e c( y) x% G* y, k: S PIO_STACK_LOCATION IrpSp;
- z" ^! M, l: |3 L& N PKEYBOARD_INPUT_DATA KeyData;
: z# C5 v5 k) O2 q/ [% W- s PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )8 @" S8 u6 n4 q# ^# v6 P5 Q: h# ^
DeviceObject->DeviceExtension; ) B9 {! Y7 g% z
int numKeys, i;8 H. J- G3 V2 m/ ?9 N' T7 B" r
KIRQL IrqLevel;
: E4 y" s5 q( F$ N) Y3 {& l- d( R! [
+ x8 [3 d K9 b; q* Y IrpSp = IoGetCurrentIrpStackLocation( Irp );
/ C: c4 |6 B/ m( J X: Q8 m4 {2 y% y# a
- `% ?8 M i% A! y% B
if ( Irp->IoStatus.Status != STATUS_SUCCESS )
2 {9 b7 |- w1 k, _$ r {$ I" W4 g0 P2 y) @, Z# F, ]1 K1 d% Z3 ?
DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );8 \" }6 D5 p! C* @- S
goto __RoutineEnd;2 ^- n o, C* P! K
}
' h4 i1 t! N! j- T
% B& d/ R3 U/ s g' U //
% W% a* b( I) b, n; M5 c // 系统在 SystemBuffer 中保存按键信息
; z1 h- k5 T$ y0 M //" l2 g* h" @1 B& V% }
KeyData = Irp->AssociatedIrp.SystemBuffer;
9 v/ ?$ s0 Q" i! y( h# P if ( KeyData == NULL )7 A# A3 g2 y- m, t% }
{9 i" @' J1 a% V+ }4 D: n
DbgPrint( "KeyData is NULL\n" );
7 E- {$ f0 _! ~) X9 { goto __RoutineEnd;2 `& f5 a& a4 ]6 L" ?
}
& y* q6 R4 t5 l, t6 r9 r4 K2 E
% B" {: c9 S1 n" m v1 M //( G# w' ~8 l( Y; K" u6 _+ C
// 得到按键数7 p" O2 @' |' I% t
//
: N: C9 _2 u# q, B# w: [- D numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
$ ~4 u. K$ D' e- @ `: U ] if ( numKeys < 0 )
Q, Q! }/ K4 A( W: _ {
# O- y2 I; q; N+ ^9 W' \& _9 N DbgPrint( "numKeys less zero\n" );% d3 I' z5 B8 A% x* J v2 Z: w2 \$ L
goto __RoutineEnd;. \- U0 _# t& B |, N
}5 T+ R! D6 u5 Z" |! g6 s
0 |; V; z; b2 P1 t+ m) d, h h //$ c8 ]- p! Y' R& R8 d
// 使用 0 无效扫描码替换,屏蔽所有按键: [+ x1 ?! N/ ?7 F4 y
//: R5 H5 O3 o7 R8 A) u7 h3 L! b
for ( i = 0; i < numKeys; i++ )
$ m* ~2 v. t' j+ l' W0 d9 C$ J2 t {
5 m& v q, T# Z! e2 e DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );* y" V7 G+ R8 v6 e0 ^
KeyData[i].MakeCode = 0x00;& g/ X4 l- A; F( d0 M5 ]
}
7 K( b' ~/ }3 ]: h7 b! n8 \
# O! k" r: Z+ V6 F- i- }0 h _2 ~
__RoutineEnd :
9 K0 ~3 |- }$ H# X6 y# q! Z* M; L/ r# e0 f8 V, }% M* H
if ( Irp->PendingReturned )& i: r6 B" |7 a0 v/ C' _, l/ W
{
3 i- n1 w% c! ?; l IoMarkIrpPending( Irp );; i$ @; }3 n7 |) I
} 6 P0 z$ J* X, G; E; g$ \ S( H5 n5 h
O) w. P% ?' L //
5 \* X7 z! P4 h // 将 IRP 计数器减一,为支持 SMP 使用自旋锁! ~0 S; j- F# f( {1 P8 [. p. V# n) }
//5 w% n m0 i$ W! H R
KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
* e8 E/ E$ ^) Y+ q9 ` InterlockedDecrement( &KeyExtension->IrpsInProgress );
9 o# U, G% W% j% X+ { KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
" T- O8 o4 b _, k7 P0 c M) t1 K7 B3 M) A
return Irp->IoStatus.Status ;4 A5 e0 m3 Z* | ]& A. a
}
5 T" {" d( ^: ]' ]& N, J: \- B% {) Y+ G% ~# U+ s! ~/ @
5 ]+ _- u( ]. ^% x: g
/*****************************************************************
& ~! T. [- E; M 文件名 : WssLockKey.h4 G7 U9 I7 K1 `$ r* J& r4 J; H
描述 : 键盘过滤驱动: D6 X/ Y6 N- g4 P
作者 : sinister% X4 L) s& k; s
最后修改日期 : 2007-02-26) e+ o% A2 |# x" y0 @9 t9 {
*****************************************************************/* a( F& W+ b; u0 D: O9 o
% ~' A8 M5 p9 m" \6 R
#ifndef __WSS_LOCKKEY_H_9 x( Z" M$ [+ h0 U, b) E- [ M
#define __WSS_LOCKKEY_H_
8 Z, A E9 w2 w& L( U* B) R) s/ [9 b4 e0 d4 \
#include "ntddk.h"% ]9 A, O2 F; z: b: s' n* x, k
#include "ntddkbd.h"
3 n' v5 Y7 u: O3 S. i8 j#include "string.h"7 A. @0 l) S3 G# w" S
#include
2 k' b: |! C9 r) j' q' o8 g; \
1 q# U* [0 I1 Y5 o% a, d0 ~: B#define MAXLEN 256% p D( f# J8 o. X6 O1 w
, a0 T2 Z7 m @; N#define KDBDEVICENAME L"\\Driver\\kbdhid"
/ W3 x9 b( \5 B( F5 a#define USBKEYBOARDNAME L"\\Driver\\hidusb" ! S/ H: O$ s+ G% u+ K& M
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"
* X1 K: q+ B* m& J3 K% R: K
, L# G1 ?; D5 O, d: w) qtypedef struct _OBJECT_CREATE_INFORMATION
7 K; r7 N8 o$ E# Z+ ^, A$ ]{5 ?+ J" ^5 U# v1 C8 ?8 [
ULONG Attributes;
- z1 {- S; J, T8 b3 {: D4 ?: h HANDLE RootDirectory;
5 A$ \2 p3 S/ j$ { PVOID ParseContext;* R+ L9 h3 n1 F$ \7 n# C( o$ `
KPROCESSOR_MODE ProbeMode;; B+ ^; ^. p; I4 B+ |+ A; ]
ULONG PagedPoolCharge;) `+ N+ q* Q' y. n
ULONG NonPagedPoolCharge;
. V$ k- P3 i0 }2 t ULONG SecurityDescriptorCharge;& Y" n4 Y3 X- r& F+ k* h% K
PSECURITY_DESCRIPTOR SecurityDescriptor;
, O* ]: x1 u+ [' }( \) d e+ P# u _ PSECURITY_QUALITY_OF_SERVICE SecurityQos;
4 {5 }! I$ p% u" C SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
) B9 L# _1 E' J} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
+ Y! ]5 T) N& M& Q. v0 j0 G: n; p" P- n, t( k7 g$ Z
typedef struct _OBJECT_HEADER
3 _1 M& C& a3 l: U" S{
( O9 U& i) V/ U: {6 ^, @- C LONG PointerCount;& h* }* U% A$ I4 E' b
union
' L$ E e9 n3 N j, K1 f* c/ r {
^ x1 F3 K* k) J0 N% c9 F4 I LONG HandleCount;& J8 j' ~. D# [
PSINGLE_LIST_ENTRY SEntry;& S1 n) R5 G6 [7 i7 G: E' O
};
, a8 ]$ M( l" d: U POBJECT_TYPE Type;
* v+ P- Q8 p2 K. x3 w9 u UCHAR NameInfoOffset;6 h' H: w4 u7 l* o8 [ x
UCHAR HandleInfoOffset;2 t8 F1 Q/ t" j% r; M
UCHAR QuotaInfoOffset;
5 e' ^9 K( g2 V9 |7 ~/ ]* O/ E UCHAR Flags;
. x# M L1 e7 [ union0 V$ i: O! J2 d1 f: h4 X: d$ }
{9 y0 Y3 f9 ^0 Z
POBJECT_CREATE_INFORMATION ObjectCreateInfo; H$ p$ t5 x3 n$ P
PVOID QuotaBlockCharged;% E4 S' j5 E( e- q& W/ m
};6 H x$ j2 H3 \
$ h% c' i+ I( w+ l! H
PSECURITY_DESCRIPTOR SecurityDescriptor;8 ^. X) Q' I& a8 C
QUAD Body;
% U" W! v6 N( E* a: s1 W} OBJECT_HEADER, * POBJECT_HEADER;1 A4 i, w% Z0 Y N
/ L: I1 ]; O/ d
#define NUMBER_HASH_BUCKETS 37
8 V3 Z7 b+ Y) w( @5 s% m- U R ]: [6 ]' G
typedef struct _OBJECT_DIRECTORY
" k, u3 V0 {6 w! E6 y/ O{8 K3 C \; X t* Y. g
struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
2 Z/ U4 c" W0 t7 ^: k struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
! {9 @( D V/ \; M9 r! P BOOLEAN LookupFound;! k+ f' d3 r9 {4 C
USHORT SymbolicLinkUsageCount;3 r# Y4 I( k1 D* I# i) {
struct _DEVICE_MAP* DeviceMap;; T5 b3 b5 @; ~
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
9 s2 h4 q# d7 v/ V M
: T3 E( L% u6 L7 ftypedef struct _OBJECT_HEADER_NAME_INFO4 ^+ V v/ e. b) S$ t3 U& I2 y
{
3 W% U2 m. B2 e5 h; ^2 A POBJECT_DIRECTORY Directory;5 I- x% E2 e: y
UNICODE_STRING Name;
" u! w1 a# U. |( V- C* w7 x ULONG Reserved;" g; A3 C% t; ]4 r$ y( y
#if DBG
, {* M9 a3 ^; f& J. u4 {# s, l ULONG Reserved2 ;
2 I* f! y% f9 G3 K) [8 ~3 y- H/ E LONG DbgDereferenceCount ;+ m3 I: L: L' B: c7 k$ V. f0 `
#endif
' K! q, ]3 F: Z$ m' Q} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
8 V% \& d5 `9 j; {5 `$ H! T1 i5 Q- F" K7 _/ B+ F x0 e' O" p
#define OBJECT_TO_OBJECT_HEADER( o ) \
* w4 @& ~; F! M& Z) D CONTAINING_RECORD( (o), OBJECT_HEADER, Body )$ j! p* h Y) k5 n7 y# O! `
7 F7 l4 J: }; d! r6 p#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
& D' B. O: n/ V6 V0 ? ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
3 a) o! b! \$ A3 g9 Y5 w4 R
* J$ D0 ]6 Z" e2 n0 Wtypedef struct _DEVICE_EXTENSION
% T9 R2 @; h8 W# y# a( X- a7 E{
& Y' A+ S( m, X' h PDEVICE_OBJECT DeviceObject;3 B! ~( R9 F" @6 M* l5 X
PDEVICE_OBJECT TargetDevice;
, Y) J6 `4 c- S PFILE_OBJECT pFilterFileObject;
, K' S$ A! Y7 x ULONG DeviceExtensionFlags;* o, ^, T$ a2 R; M, \, p* [3 o
LONG IrpsInProgress;9 o2 J }2 Y. r7 [
KSPIN_LOCK SpinLock;
! j! _# o: O! }}DEVICE_EXTENSION, * PDEVICE_EXTENSION;5 U! ~1 n: N* W% i) l) r& {
6 \7 W% @+ U3 H5 p5 l/ x6 u3 p' r- G/ p
VOID 6 n6 Q! _5 z8 C7 M1 U* x8 @
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
5 X+ R& ^4 G: `1 P7 H# o) a& S$ ^# L- g2 x
BOOLEAN( e$ H2 a/ ]5 t: N
CancelKeyboardIrp( IN PIRP Irp );- _+ N) C) q2 N; F
0 x% i4 J! c) q: a' ]
extern POBJECT_TYPE* IoDriverObjectType;
& k# k5 p: Y4 k! F- T {. n. n& e- v5 y4 [
NTSYSAPI) k2 q2 Z/ S! q2 k4 W3 Y7 r* \4 d. e
NTSTATUS/ m" \) i1 L' J
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
2 m' ]; \/ x% q, T. x3 _ IN ULONG Attributes,
[$ N3 r- `0 z IN PACCESS_STATE AccessState OPTIONAL,$ l: f: C5 @8 d. T" x3 z
IN ACCESS_MASK DesiredAccess OPTIONAL,
x4 F$ B# B7 `. E2 k$ { IN POBJECT_TYPE ObjectType,
& F9 z+ F7 E' U# L. @ IN KPROCESSOR_MODE AccessMode,
" J, V9 r/ q& S IN OUT PVOID ParseContext OPTIONAL,4 [) W' p3 l0 }- A! c/ B
OUT PVOID* Object );
' a8 k2 Q8 q% r3 Y, x0 k) Y( ], r% N$ B6 m8 ?
NTSTATUS # `) G9 |/ C+ L$ U- @1 P4 g1 w
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
9 r& o/ z9 Z; T" {$ `# U
/ ?% R' ~& `$ }9 y& R. R. A3 h" dBOOLEAN
F0 ?$ [: m- R1 J. l- W6 bGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
( L( Y6 A8 m4 H, K4 x
* g; o6 p5 b Y$ n" f' {VOID 7 b6 X9 o, O# d* `2 S
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
0 b" ^8 X G% ?" ~' r3 f) V: B
+ m% E7 a3 c8 F- lNTSTATUS ( o% N$ t4 [4 F1 Y8 q6 [* R1 E
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,$ P4 D: o; d# c, p9 s& d
IN PDRIVER_OBJECT DriverObject );
- l; ^+ L" S Z4 r% Z
, B) [3 x- X [, R: }3 oNTSTATUS 0 }& j. t# Q" j2 u
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,4 c) u0 R) O% o# \3 G# B
IN PDRIVER_OBJECT DriverObject,$ x. l: N# U! Y* h( V) @- ~" G
OUT PDRIVER_OBJECT* FilterDriverObject );
$ _9 G6 _( d1 ]- k1 `: \' _' m1 Z; S% w7 D: w, u2 {! [
NTSTATUS
- p0 ?( A1 j+ a) E: X! DKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,# p4 K" I# H) ^ d. j, T
IN PIRP Irp,/ p! F) ?$ }' G% F
IN PVOID Context );2 l; a/ H' ], G s
NTSTATUS
- k7 D/ f9 B% ~; z8 D& OKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );* S8 }% D0 }+ W, v
5 T' E) w) h# A1 L1 |& j/ i( l4 qWCHAR szUsbDeviceName[MAXLEN];
: b b/ x3 q: S( }/ i4 a8 l4 P7 D; V" l( R( @0 j+ @+ `7 P% @
#endif
8 s+ s3 J% a; Q0 @; ^" @! Y' d3 D+ K- B7 \! ]
2 R+ B7 S: M; M2 V0 o4 \. r, H- [ 9 b" |; @4 {$ P, y1 f5 S
% _, P2 a7 d% \
7 V% t k/ M8 I9 F' W: N" _WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。( {0 @. x3 ~, r4 P2 f
WSS 主页:[url]http://www.whitecell.org/[/url]
! @& I6 D( |0 O. Z: B$ J# U# aWSS 论坛:[url]http://www.whitecell.org/forums/[/url] |
|