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