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