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