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