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