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