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