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