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