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