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