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