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