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