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