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