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