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