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