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