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