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