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