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