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