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