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