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