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