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