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