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