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