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