找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 15080|回复: 0

[转载]支持 PS/2 与 USB 的键盘过滤驱动(可卸载) -- by sinister

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
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]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2024-12-23 22:04 , Processed in 0.059595 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表