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