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