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