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