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