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