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