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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister, ]2 b% E. l8 G) `
Email:   [email]sinister@whitecell.org[/email]7 ~: i% r) ?! L. B; U
Homepage:[url]http://www.whitecell.org[/url] ) @  H( l; A) S6 L7 {9 B
Date:    2007-02-26. m8 d0 O7 f  M  Y( }

0 z4 T& [" A$ \& j
, [0 x; g( f& D2 k2 T+ T/*******************************************************************
( d* X9 q/ E, P' t! \( b5 a+ p, ~& A* ]
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
( c6 _" n: @  D0 t; C' L8 U9 t5 p写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
* A  p' m( e) [8 e6 V4 i9 f功能要求如下:3 x( {7 v1 f+ q( @; J; U/ j$ {
, u# H. ]0 C. G) ~
1、强制锁定键盘/鼠标。3 o4 D3 h* A) Q
2、可动态加/解锁
& X: H3 }  {8 `- }3、兼容所有 NT 系列的操作系统。2 O* U8 {0 Z& M6 R% }

3 ]' K2 E6 o% p) f就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
% i5 K% i# }8 H+ i现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
% H# A" p7 y; V  b! \; A何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在' `% S5 n% h, I( t
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是1 H% d/ J% q* B8 p; k* l2 f
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面. a, E! H& L5 F$ M8 k
就来看一下我想到的几种实现方法:) l4 `" C" U/ q8 `. P* e
3 g% b# ~- d0 d6 W3 K$ J( O2 y
1、全局键盘/鼠标钩子
0 ?: r6 n! e1 k2 l  u2、BlockInput() API) A2 K# g- a6 y& k/ ]
3、使用 setupapi 进行控制
0 [/ B4 e% k! m* [9 g2 f6 a4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
! @9 f- H% w' |6 q# M& h5、拦截 win23k!RawInputThread() 函数6 p$ V. L2 g0 d
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动3 B& n9 a; `) d# F+ u
7、拦截 kdbclass 驱动的 driver dispatch routine( a3 m# u# G2 y& u" ?
8、实现一个 PS/2 与 USB 键盘过滤驱动( I& {. x8 c7 ^6 n. A+ ^, E' W2 b

+ }- ~; m4 x  U; J7 p
; p* ?, o7 w3 [% g我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑4 k& _' [' l$ C8 c' ]# S
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方4 q/ f$ Y- I7 A8 U1 y) X
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
" O. c/ Z. h4 c, u兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因2 E: m+ Q1 U1 d6 n
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性5 T: R" s! c  |. X' I2 a5 \
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸+ ^  o" X. m7 ^# j4 O2 y
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我; o0 K4 v8 p2 ?2 ]1 S
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来' h. z- _7 Q# F9 b
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
  \* C( j* d& ?! B" u+ A果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
( D( P% K$ o) G1 r; {: C* T3 e障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截5 l" e+ ?# x# M5 I2 {
IRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 - V& I1 D$ C, s( r+ G  V
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键* R: S! p9 t# ]
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方5 |  m2 B$ \% _6 C% \$ m/ P, T
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
( j9 c, P( Y* i( h+ U6 @, a3 F
* p- D! y" m# C/ n
5 y0 ]/ B% Q" p/ k6 ~# A我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过: a6 _2 x: d1 S) s2 o0 @/ n% h
滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
/ z( ]' h/ b* z6 R  `8 b5 u行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是4 M' t% u/ O9 X! P: P  q% O
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
5 C5 [* f* h8 ]! |来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从; ?+ R' U9 y2 d5 c
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB& y: O+ u1 Y0 f5 q2 q$ u
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用4 }. F& F5 C8 u: h- O" c9 E
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,1 j1 C* z4 X1 s! U/ Q4 e$ e6 c. l
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
+ [8 t8 a8 l. J6 q就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的
6 b, z& n/ z, v而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
# y% H, G8 k( O5 K# X; Q( \' a% C用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
( p4 `* i7 V; K) ~: \过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
+ ]# A+ |* d' [1 s& M- A' C屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通  N- U5 y# e* A# I2 {  s8 M
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb0 @9 u: z) W, ~1 o
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
6 }( X% K' C4 J; p% T; |的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
* x- d  N2 d9 h3 X# E' a$ f4 q+ @味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
+ {. X# y' P6 k  Q4 _* b经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们4 w$ X& g9 X0 B- q/ w8 \: x
来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利' @' h; H3 @; I2 @7 h9 S
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo- X: V7 F! O" K# O" k8 p6 l
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致2 X  n: T: T0 r+ M
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
0 R3 Q7 O4 i" B$ N  _/ h: t根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
3 R. q4 r. D1 s  d' c( \见下面代码。" ~) d( O- E* M8 w: Q; @7 F
& y7 e+ h- m' n0 B( ^
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
6 H; k; _4 u3 P9 u' t里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键. b- q9 j: a4 ^7 ?9 }0 o  ?
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
8 S5 i+ E3 A/ Z0 r; z上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有( ^# n; ]. U4 |) x3 q# C3 s& |
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可( L( e2 q/ R) q6 D/ |
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
9 ^; d2 _( J) k锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按3 h% G2 e/ W' N, F1 R+ r
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
1 W" u1 l; q) D/ y2 b& X! a: V! H8 f" R# v8 e  E  V+ p- K" [

1 h. r; x6 n4 h0 [0 A. _完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用( Y# @. A3 o( _
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是
! _. _! L6 G2 w2 s! \可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣
9 ^2 ?. d6 `' O8 _& C, M的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
3 K# t. s! z/ D  [9 B  R: h8 K们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
: {2 X6 M1 l1 |# j0 A% ~) t们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension. @/ R0 ~% q4 ]! }4 O. ]. m) \
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
' x) `0 j7 k( c" x; B如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager) O- ?$ A* q2 I& D8 ]( B+ W) k* E# {
进行操作了。这个问题有待大家来完善了。. V1 t( W# g2 i- Z/ ]

4 k* q7 G5 c" y
3 C( e/ M  t! c2 r, n要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
( ?+ }6 \. N' E! r4 H- I' V来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
5 q5 S: \5 N6 }# Q+ q分析做个记录而已。我更愿意把它看做是一段注释。
6 }+ K5 @& \% c* m, `; ~8 t" L7 a$ E2 C3 X  u, t
最后在此代码中要2 r2 T0 a9 f5 A/ @
+ |( R' z" T+ ]8 I0 X! t- y
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。/ F, @+ {: Y& [$ T% m

% O: {3 @, E* s9 Z. [感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。& E. R* U6 G5 b/ {3 @: Q) f# j
4 `: \- I6 E# A9 X. x2 r: Z! n
感谢:齐佳佳,过节请我吃好吃的。; z) }" g$ g6 ~4 m
4 Z9 E  o& W0 p
& d& f, u+ ^& T8 S' n9 m
******************************************************************/
& ^6 U  P0 _. V, |4 ?1 O- B- d% J/ E9 |$ ?

0 O( N9 [5 D9 N2 z$ @/*****************************************************************
' j+ F' U4 F# H; }* r; z 文件名        : WssLockKey.c& o! S! _# o7 l: f2 f6 O
描述          : 键盘过滤驱动: F3 f/ f5 \/ x9 Z4 j' g9 J
作者          : sinister
; B8 v: K2 f/ x7 z  v 最后修改日期  : 2007-02-26
# v3 F1 G$ i* J+ T1 D& O*****************************************************************/# k, c6 y- j, L* m

. m* {. b, q5 x# b
" g+ a$ U" n0 U- m5 q' ?# Z! `( e#include "WssLockKey.h"
2 R0 b. m( K3 E3 M1 \2 T& V! s5 A7 t
NTSTATUS9 ]1 `$ o7 j0 z8 W" F2 Y
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
) o2 x8 R& g: ~" u" {# n0 Q             IN PUNICODE_STRING RegistryPath )4 [) A7 ?: W: \. @' W
{* ?' B3 c. a( s, z
  UNICODE_STRING KeyDeviceName;
; o6 a' L+ \0 k; j$ C  PDRIVER_OBJECT KeyDriver;
: G4 S" d7 o7 ^  PDEVICE_OBJECT UsbDeviceObject;
6 g1 I/ \6 y/ [) H& `  NTSTATUS ntStatus;
/ @+ M: L4 a" @  F  ?! |  ULONG i;
' v" R- v% G# ~; K
: M$ A; S; T1 w6 b4 p" N  //
. D& y$ K; S: k0 p- D% c7 q  // 保存设备名,调试使用  o7 G9 C3 ^! L. U+ R# _
  //
' K. w/ e9 v- Q0 U9 k  WCHAR szDeviceName[MAXLEN + MAXLEN] =: {% j  N6 y% G6 R3 f  U
  {1 ~0 o5 V' o1 @' L7 B" N2 m; O
    0
+ J9 G  U# _/ h* L  };; K1 |: B* t* l1 D, ^! f
4 L4 n7 ^/ W1 h6 h# G; d
  KeyDriverObject->DriverUnload = KeyDriverUnload; 8 `3 r" X  w$ w/ L7 h

- M1 S( @: y' C: w  //
; S8 X! n1 }/ z" u7 \$ u  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
% E+ z5 I. @, ]  //
. A' X; x& {+ X+ ]% Q  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
. y" O) }/ Y$ \: X# e6 ~8 ~% Y/ z5 u  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
+ |, H, V! M$ Q  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
# E/ F! }1 x$ R1 r2 `& t  // USB 键盘设备来进行挂接4 I% d1 ]* b# W3 v: n  K: C- I
  //9 {1 Z% L3 y6 h5 x
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
' p) R. Y* E) [' W; |4 M  v! {  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )8 |' |" F+ e* l9 v
  {; j7 y$ h: R, v1 I3 Q" T2 K
    //
+ m& _4 G' l- J" S; |    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
! x* m5 Z, t9 e; F. V3 x    // 所以这里打印为空
3 ?. ?9 T5 t  g  Z2 r    //
) ]/ X! h, }6 Q) [6 o+ X' i4 S: Q    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD9 S/ V4 Z1 l& r  V; Q0 P3 e
    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );' V/ l$ d9 A  B( [
  O7 \% K; F' |% o7 u
    //
* }8 U2 s3 Y6 _* p    // 挂接 USB 键盘设备
# M; C, s; c4 T* _    //8 e6 f  U3 R& O# W$ B# j0 d
    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
/ o4 J! F. z7 h    if ( !NT_SUCCESS( ntStatus ) )
2 s2 u- ]8 R" z% ?" V6 X9 ^5 t    {% y, @0 i& G) U
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );1 U, S  ~/ V% ?9 [# c
      return STATUS_INSUFFICIENT_RESOURCES;& p9 m+ i% r; J9 v
    }2 e- ^' [3 p8 }* v/ y
  }# X( O+ ^0 Q! n# [5 t
  else
  Z2 j' \& I' H' m) Y! G7 J3 f  {
+ P! r$ _( `# S: n9 c    //; c0 J) P+ p* ]% j  z/ t* E; f
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备- _5 ?" b& @4 M) N' L* \6 a* H
    // , o2 R+ L% k& m2 j; F
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
" O; N' Y/ f3 W( |# @" x2 B' q4 [# o) |& P# f3 u4 E
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
/ N: S8 u# |/ i5 F, b5 d                                        KeyDriverObject,, k/ K, V1 ~7 v; l5 ^- C" @2 H# @
                                        &KeyDriver );) W* e9 w# w8 h9 W9 W
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
: |6 f' `0 i, Q; Z2 F    {2 p  ]; ~* }$ x* e# n+ `
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );
9 q! U5 O4 a7 g3 ], X7 N. n      return STATUS_INSUFFICIENT_RESOURCES;, m  n- M" y$ U8 L( U
    }
' b: H+ \/ x) _( Q; D6 T* }  }  H; e( `7 Z! H6 O& O
% X) v! J; t% r. N
  //
, R5 n9 U$ j+ A! b5 [, P0 E2 @  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
2 C+ e4 i. e( _/ D) A  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
: R, f6 U0 i/ n3 q0 q1 K7 e1 P  //
/ h4 e9 e: {7 l* n" i0 t0 J+ r  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
8 h2 d1 Q. `. d; _7 w" d0 R* l* G3 k- G; n6 b# u
  return STATUS_SUCCESS;
3 k7 y0 |2 Q1 L' G$ K} / y' e* H1 E5 i% \( i

: }& ~7 V! C  ]) Q/////////////////////////////////////////////////////////////////+ H6 l# ]2 G5 P+ a4 U8 S/ i
// 函数类型 : 系统函数
$ E% b, I8 ~, s) n// 函数模块 : 键盘过滤模块! }) ~2 E5 x6 Z* C) l2 `
////////////////////////////////////////////////////////////////
* j8 X- v! T% X4 x- x4 h// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,. O) J3 H+ [0 }9 @3 X' {
//        卸载键盘过滤驱动
- k% ]# I6 p6 n( ~3 k// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上4 R( F% g5 q- W9 @0 u
//        则需要等待用户按键,以后有待完善
5 }, `6 Q8 @) s6 a) K* {8 o1 {/////////////////////////////////////////////////////////////////7 `4 a, J' V9 E5 Q$ h
// 作者 : sinister9 k3 z8 @; S$ y* p% t* @$ L
// 发布版本 : 1.00.00
* n  S0 `6 w! d, L9 T// 发布日期 : 2005.12.27
  n1 {+ G9 Q; B6 t* n7 `/////////////////////////////////////////////////////////////////0 g' p+ Y- F" G1 X
// 重   大   修   改   历   史
5 U$ L& @2 M; Y" @////////////////////////////////////////////////////////////////5 ^. ?9 C1 p, G+ @2 e
// 修改者 :# J4 p4 |$ @  _" E
// 修改日期 :
+ E, z$ I; o) o- f8 e" \// 修改内容 :
/ D) j% K5 G* J2 d5 N$ x) r7 @/////////////////////////////////////////////////////////////////
! R4 K- f- F' F7 J5 o5 S/ i# d; B! b
VOID
9 n8 n  p/ l* B. |' g% EKeyDriverUnload( PDRIVER_OBJECT KeyDriver )" X. s7 Q% T, S4 N4 O. P( B4 T
{
" W% i# \; k) n; N/ U/ }  PDEVICE_OBJECT KeyFilterDevice ;      
# r) G+ }9 u0 G  PDEVICE_OBJECT KeyDevice ;5 t9 i9 y# |, h+ o, \, A8 z
  PDEVICE_EXTENSION KeyExtension; ( @* t' r2 y, U- ~* d8 y4 |
  PIRP Irp;# d+ ]3 Z$ A$ Q5 y2 y% S) ]
  NTSTATUS ntStatus;3 }: h  m# s. E5 i0 J
( K* T4 D* _8 v+ o8 D
  KeyFilterDevice = KeyDriver->DeviceObject; 8 R$ |. x( X8 ~
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
$ h; c, l; d, }- r; E( _7 N* T  KeyDevice = KeyExtension->TargetDevice;
. c$ u1 Q1 J7 R$ J1 R7 n8 W" ], b  W& T
  IoDetachDevice( KeyDevice ); * S, x- a7 K: X1 D/ X  Z

0 a$ U. I! O: A8 U# ?) ~  //# N# S' e2 g: T5 s" X$ t4 T
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
9 z4 ^8 F" G7 u, l, t" s  _) ^- U  //
6 {# q* ?- ?+ v+ L8 S; f# ]  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )" n* N' @% k; H' z! n
  {
9 C8 I+ J$ P* e# e4 O2 {    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )) b, U. y3 Y3 c* R4 `4 A$ V
    {
, g) t- D: @1 }* E. N7 S' D" @      //0 W! j! ^: N& k; R- Y0 z
      // 成功则直接退出删除键盘过滤设备& U, v9 p3 Q# j9 q* {  o" C
      //, G/ x7 ]/ K. Y, {( n* w; V( {* y7 D
      DbgPrint( "CancelKeyboardIrp() is ok\n" );. j( ~5 e2 k% p5 f0 g4 h: D
      goto __End;; l' G, F1 ]. Y# a+ U* u
    }/ I% a4 {0 K/ G8 z8 G. m
  }4 t9 i7 @1 @: U1 {
* V7 T1 q5 g/ K3 T; O& D( k
  //
9 I+ ?. m% k2 v  // 如果取消失败,则一直等待按键) f, `# Q/ n: \* h9 g
  //
5 {8 a4 P* N+ @7 T. @) x9 N  while ( KeyExtension->IrpsInProgress > 0 )
( L- W1 D, n: a  c7 L+ s  {
/ K+ D+ g" a2 P. p    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );) V( g0 N/ h  b
  }
0 O8 c8 u( e7 N: N! L; p$ D
! Q3 S& Q. @# _+ u9 D! t5 n  __End:, N! }( E0 X( j6 z: n2 ^8 w
  IoDeleteDevice( KeyFilterDevice );
) x; n# m0 z" |! ]7 }5 Z# W% ]) _8 P
- z) B* Z9 l6 g2 o  return ;# z' c; z7 F! v' b
}   K9 f: G# b" ?6 s" n
2 ^) @  b8 h% k4 V% e7 i
/////////////////////////////////////////////////////////////////
" r6 K" L$ e! P2 |* Y  ~- ?7 _& t// 函数类型 : 自定义工具函数
2 H- X* H8 @! \5 Z// 函数模块 : 键盘过滤模块
8 r9 L+ h9 c5 L% f* g$ m) N" [/////////////////////////////////////////////////////////////////- `. u4 b+ x. V0 W" C3 ^# z+ O- @
// 功能 : 取消 IRP 操作! j0 s& y, x, S9 P/ S
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
+ }: R- ^' d+ b7 e' z# o4 a//        使用此方法来取消 IRP
$ U/ E5 c& S) Y% \0 D" B, V/////////////////////////////////////////////////////////////////
3 j+ [! Z/ }0 H9 m1 J// 作者 : sinister1 {8 {' P' T. A
// 发布版本 : 1.00.00
9 i( p1 v& i. Q! u9 @7 p( i, X// 发布日期 : 2007.02.20: z! a6 g$ S& ]  d6 X
/////////////////////////////////////////////////////////////////
" v7 X' B5 D6 l5 p// 重   大   修   改   历   史
( |4 G( x! U; @3 e/////////////////////////////////////////////////////////////////) ?4 E2 [# @0 ^3 k& o
// 修改者 :
2 g* l& S" Z% B& k// 修改日期 :
: D- o; @: l; _2 x% j/ _; L0 _6 R// 修改内容 :
$ [9 m0 q+ s8 S) c* A/////////////////////////////////////////////////////////////////
7 B4 O3 _3 z" P0 V1 Y" U* L# ]# n% S. X/ ~
BOOLEAN6 l9 \, _/ M. u5 a1 ?  Y1 T
CancelKeyboardIrp( IN PIRP Irp )
, ^8 B5 i& ~$ e; _{
& f& V* ]4 q) J& w% s3 `! q! ?3 Y4 O  if ( Irp == NULL )" L& r; X6 z  g( H- S  a
  {
% t; c  e' a9 S" b: `3 y    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
" X- X% G, J' N! K0 z    return FALSE;1 f  J" I- J% l2 k: s
  }
6 g# j5 \0 R9 r' L0 e
% R' O- ?' d) p" G% i; F; B7 U6 i, J* _  T' K$ A8 I/ _. p
  //
, u8 |3 u: {# @8 w  v  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
1 k3 ]1 A' O( _  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。7 {! o8 H' Y7 t# }4 d2 _
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占; X- l$ i# N" a0 M2 a) Y
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD( c& Y. W8 p  j7 p0 D8 V
  //
" Q' h# N& J( E0 S
6 X& l5 g  X' Z; L  //
" y) ?5 }) R* b& `  // 如果正在取消或没有取消例程则直接返回 FALSE; V9 M- m! B. m6 d$ a+ ]
  //7 V0 {6 d$ \( C' E" D0 O
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )+ r( K, L: _9 \0 _0 @! m
  {
! |  ]3 I; [# r+ V9 _0 k, }    DbgPrint( "Can't Cancel the irp\n" );* {* a; \' X5 n4 `3 `! m0 Y, j4 u
    return FALSE;# s# `! s* ]6 Y2 h
  }1 h( D& Z0 f$ O% u
: R9 s- `/ s" H6 C8 x
  if ( FALSE == IoCancelIrp( Irp ) )
' a* q! j+ r+ N* T$ E  {0 e0 ^; E; E6 g* ~% ?4 i
    DbgPrint( "IoCancelIrp() to failed\n" );
1 q' G! P) }5 I$ |% C    return FALSE;2 k# Y0 q# z6 N9 J) f
  }2 b. ]- B( ^6 o( c# R

) w+ u- P: \% Y' E7 h  //
7 [* ~2 `7 G8 g) h7 c! S) T5 M4 N  // 取消后重设此例程为空
4 h7 \8 f- U6 M* R. i  //" T* Z+ j+ f' @/ C0 J$ x
  IoSetCancelRoutine( Irp, NULL );
4 h& ~9 |8 }) C3 M9 D
! M; U& |& A4 Y2 \  return TRUE;# ]# p% L' V. h6 ]5 a8 A, w
}
: z. U1 v1 C; u+ [
, m! o$ L# D" Y0 K' x% N7 X/////////////////////////////////////////////////////////////////" j5 z1 H( I8 ?/ O
// 函数类型 : 自定义工具函数
+ `+ c) G! t4 `5 F8 a% B9 [// 函数模块 : 设备栈信息模块
8 o: ?- o3 Z' x, M/////////////////////////////////////////////////////////////////* D- p/ B# w& a, o9 p
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘% i+ f  ]  ^( g) G
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
7 a8 {/ A! Z( X" `$ a$ X// 注意 :
1 P( X. \! f+ J/ ~( U( g/////////////////////////////////////////////////////////////////
1 K$ \$ c# Q* T. U// 作者 : sinister9 R; u! k" r5 p+ A
// 发布版本 : 1.00.00# |* }- _& ?' ]
// 发布日期 : 2005.06.024 P* ?- |5 u: }5 e3 X
/////////////////////////////////////////////////////////////////2 F. Z$ T3 x. m7 C) t. f9 D
// 重   大   修   改   历   史! r& y% z  x3 Z: b3 o+ E0 `2 B; A8 r: W; V
/////////////////////////////////////////////////////////////////
& B; L: E, f. J! x// 修改者 : sinister
2 ?( J3 z  e- Q: s* O// 修改日期 : 2007.2.12
5 W6 Q$ [3 m, V' K! s* U// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改0 h; T2 G" M# U- {- d# R
/////////////////////////////////////////////////////////////////
( f7 E: w* }3 K' l. |) Z1 g- \+ s: o
BOOLEAN( T+ m8 K/ f+ ^7 `
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )* I. E$ o4 V" ?' c& E# V
{) Y" y& z" |: _( @$ f' o
  PDEVICE_OBJECT DeviceObject;
+ H6 f. j0 G7 R! m; g  BOOLEAN bFound = FALSE;# c% {* g' @! i

* n" W6 g! u! C$ O  if ( DevObj == NULL )0 j# P9 m2 A9 z/ ~: X" M: N) ?
  {! e" l0 Z1 a& M0 i' G* i
    DbgPrint( "DevObj is NULL!\n" );
2 G! n: E( u* ]5 R3 V: v. x    return FALSE;5 ?7 G! ?+ g" y5 u
  }
2 m: f5 K- P1 ]& ~: ]
, {) Y. ~: w: I  DeviceObject = DevObj->AttachedDevice;  F% _' r% k9 W/ C3 x

5 g% F4 v: S7 a* v9 B  while ( DeviceObject )
' n* ^2 j$ u, n8 I! v, ]. O  {; l1 f  ]8 z3 Q
    //
: \0 D! r$ h) ~    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
2 U- l# S) y+ }* n3 m    // 有一次足够了。这算是经验之谈
$ x( B/ l! }7 M/ e1 h    //0 a8 S2 F: M1 z# h8 P% m  S5 x6 Y
    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )  O+ r5 j' k2 I* r6 I2 C
    {" }, ^  J" ^- L2 K
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
' ]# y9 f$ u+ j                DeviceObject->DriverObject->DriverName.Buffer,
% |' [0 o7 B  c* d9 k( s, y2 l                DeviceObject->DriverObject,
6 A1 j0 R0 I" _# t& R                DeviceObject );
4 n. ]$ z, m$ O: u3 D( p; o; i7 c
      //
; d* z: c2 R5 r* V; n' }* P      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
& h3 T5 o5 @3 o# }* c* l      //2 g0 U8 S0 {6 z. [) ?
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,$ [, H7 Y, O  W$ C; Q4 P$ q3 x3 Y
                      KDBDEVICENAME,
1 Y0 T3 {/ z) Q" ?6 {                      wcslen( KDBDEVICENAME ) ) == 0 )
/ E/ h  g( [% Z4 _      {" {. c) c, l5 q/ H3 M/ L* r
        DbgPrint( "Found kbdhid Device\n" );2 K% |: t  w: ]: r
        bFound = TRUE;
" E& O. o0 T% F" c/ Z( |1 j2 d        break;
) s$ T  W  b" K. O9 n( o& J7 R6 r      }
* [2 G2 W3 W$ o4 X) f  a    }& T: u# C4 T3 {

+ ?, b# e1 ?) B6 [    DeviceObject = DeviceObject->AttachedDevice;
" u, H' t+ ]0 J: y( e6 j  }) r% I5 L7 p/ S& \6 f

6 i: P& m( i8 R1 M  J8 E( K$ }4 c  return bFound;. l8 r; K7 }8 w4 e/ `/ D3 A' Z
}
" }: B! c/ U  j6 r% f! u1 \! {2 E2 V
/////////////////////////////////////////////////////////////////& X4 }! r* q2 }$ z
// 函数类型 : 自定义工具函数/ \4 I" z- ]( Q) f( N
// 函数模块 : 设备栈信息模块9 f/ H8 `2 X, k
/////////////////////////////////////////////////////////////////% M6 E( d" t. d0 G0 E. P$ f' I0 ^
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
, q6 ], B  G" ^6 R// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
0 A( [" N* q' f. f$ ~* [/////////////////////////////////////////////////////////////////
3 P- O* G+ Z5 Z// 作者 : sinister
2 ?. C* p! ~+ F3 N// 发布版本 : 1.00.00
& ^) z; J/ R" k/ X# |* y' C// 发布日期 : 2006.05.02
. ?2 g  E; [2 Q1 T+ r6 |: Z/////////////////////////////////////////////////////////////////- k! p, z- \! R
// 重   大   修   改   历   史
* D( U  S' o6 r' h  D& o/////////////////////////////////////////////////////////////////8 }: n+ a  ]0 r5 m
// 修改者 : sinister1 O' h. s1 n$ u2 X% X
// 修改日期 : 2007.2.12
  a$ F7 v# ?: G& z" s1 X) y// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用; W0 x1 D8 R; D5 a! W0 P
/////////////////////////////////////////////////////////////////) P# k  _0 w* ]! i( {' g

  z3 [/ r, ^, JVOID
2 b3 O3 z" v8 qGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
, C8 v; m6 f5 l) s( `& ]{: _5 A" _  a. L1 }
  POBJECT_HEADER ObjectHeader;% G8 K/ e' A. p
  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
2 X2 q' f( I! t$ B$ g" x' Q# D" a( Q2 K5 d% Y5 n7 k
  if ( DevObj == NULL )0 C6 y( F" Y3 |( f) m/ o) ~  {. b
  {
  _1 `9 y" o! u! p    DbgPrint( "DevObj is NULL!\n" );; T6 ?; _" ?- {* K
    return;/ X3 f+ i+ E: {3 a- ~" _$ O7 m
  }
1 U  S( }7 j, g: d' J% j. L# `$ n" w/ t8 F6 J! K. k% s" I  \) q
  //
6 i, [+ [  \$ {% I  // 得到对象头
# z/ U; P1 F* P# J% A% f  //0 E7 Q% d5 H: R; K' v
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );: t7 z  \; F8 R
9 w% a5 i7 g1 ^$ z1 I, a: d
  if ( ObjectHeader )
2 ^% L' M2 l0 \  {  {- [; u. ?. L& c0 n
    //
( n$ E; [8 y4 P    // 查询设备名称并打印
8 B. n, s9 [! I5 b    //6 L9 D" M/ Y9 L5 h& u: {
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
& u# J( c8 V  x% d2 s, V  o. |5 t
0 x% S8 f, ~8 X2 q5 X    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
, C# G: K( W" R1 b1 n7 {    {
6 q' W  @, W; L      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
0 _3 {: b2 C8 B7 v( p+ j                ObjectNameInfo->Name.Buffer,& }' o4 H$ t6 h+ x+ X" g# E
                DevObj );" T+ d, |7 Y! O% u) o) g3 c
% e$ H* Z) p& \1 |! r/ E8 _
      //
  k* F$ }: l& o" z* r: _# d4 N      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
( W& A- b. h' ?2 B& N) C: h& D      // 用,没有实际的功能用途
* d$ j. N0 I  e0 ]9 Q      //' o: t% P# w0 z: n8 n( i9 Z
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
6 T; y+ t- B; G: U7 j* l  `- S6 t7 ~/ O7 {& F+ G
      wcsncpy( szUsbDeviceName,
' L. B. K7 X1 a. G* U               ObjectNameInfo->Name.Buffer,
2 z# S3 n- V% \" t, q& y* x9 i               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
# Y0 _# v' ?! o- Y& g: v    }
8 g; s  u' }7 z8 P" h5 {* ?. A" a' e8 h; p2 s( `* k. _: ~# x
    //
1 f, y2 ~1 C* M- G% Q. }    // 对于没有名称的设备,则打印 NULL) b  d- B$ S" Q3 o% s
    //5 X9 O4 _' S0 u6 J3 Q7 e
    else if ( DevObj->DriverObject )
2 _' J2 N! W; [+ l" F+ Y9 t! Q    {0 O! C+ a7 B0 k' v3 h' _
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n"," m% l3 M, Y2 x- |% L% r: U7 y
                DevObj->DriverObject->DriverName.Buffer,1 {% T8 S# w0 j8 U& H! @$ V0 a
                L"NULL",
) _7 ?4 h/ X2 B8 d                DevObj->DriverObject,' X& k# S/ {! {8 L6 q3 U* d! N5 c
                DevObj );
0 ]+ u4 C/ k. U7 `, @, ?    }
  Q! r% T2 z  z* R4 Q( m  }) o! {$ S" u5 [2 z
}7 A& s6 R; Q! c

1 p& L9 V; e6 w5 Y" s/////////////////////////////////////////////////////////////////7 z2 ]# n  R1 ~0 Q8 J
// 函数类型 : 自定义工具函数
& c3 d. ~' ?# b  d9 Z// 函数模块 : 键盘过滤模块# l9 ~+ e4 P( P- x# J' i( _
/////////////////////////////////////////////////////////////////
5 y) W; K7 z: ?// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备% e- u! L: J! B) _6 n
//        对象,过滤出 USB 键盘设备,将其设备对象返回1 \% S4 ^: i+ h4 |6 B2 ^  q$ @- q3 ^
// 注意 :
! Q. I2 f1 t. X$ B4 L; n' W' F/////////////////////////////////////////////////////////////////
' d) u8 y/ c& b7 u. F- h// 作者 : sinister: P' `3 y8 p; p3 @1 @
// 发布版本 : 1.00.002 m9 I" I+ B+ b% Q
// 发布日期 : 2007.02.13
& H) V0 b& e" [: W9 S/////////////////////////////////////////////////////////////////
$ J1 C! e4 M( ?9 o1 @// 重   大   修   改   历   史! b0 |7 }, p" [) ~! Q1 b
/////////////////////////////////////////////////////////////////
  ?) i/ J  l8 h( Y) K- \// 修改者 :
+ V" r" \# b% J% T6 Y// 修改日期 : / F* }. A7 M; R6 ^7 z" s- z
// 修改内容 :
7 R+ Y- Q. F7 Z! m1 t////////////////////////////////////////////////////////////////// ^; i4 N/ x9 M7 ?6 x

. q6 G) f( s& I  a8 pNTSTATUS- u' a6 V# i: c& b6 W
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
6 k  D. s  m4 ?* z0 x2 S& r{" c9 Q6 ?) X( g- x
  UNICODE_STRING DriverName;0 V1 B$ r% \9 W$ s2 B; G
  PDRIVER_OBJECT DriverObject = NULL;; }4 _8 r. ]- q- [; N" U
  PDEVICE_OBJECT DeviceObject = NULL;
( z, _5 o: D- }" |  BOOLEAN bFound = FALSE;+ \% U# H8 Z# @
! j8 }) P! `6 J* z5 l) Z0 O
  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );; j" j; z9 y) Y$ L  r* B) @

  q; j: C& T7 u; g; M8 s. }* H  ObReferenceObjectByName( &DriverName,! y! ]! Z' D4 f6 g* d5 e# z9 i
                           OBJ_CASE_INSENSITIVE,
! n! y7 H" G, }1 Q( x; y+ c, W% L                           NULL,
* x1 R  `* P- L( A                           0,- A# c4 Y; ~4 }) T8 |* j7 B8 B1 Z
                           ( POBJECT_TYPE ) IoDriverObjectType,) O6 _0 ?- L, v; j
                           KernelMode,
( b: W& l, g( `1 {1 r) u                           NULL,' @8 G: _: z( w) }* J" ]  Q
                           &DriverObject );2 z2 O) B/ ^, _- H

3 l. F% u$ M) H% w# S8 h" T2 y6 p  if ( DriverObject == NULL )# A" t3 }. x- M+ y* k% r
  {
7 {4 H+ N1 {, n3 D' r1 l+ K    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
3 d" J" K3 H- d3 n    return STATUS_UNSUCCESSFUL;- k6 W$ O: q. e5 ?) Y/ U- }/ b$ k2 [
  }
+ E8 m2 q, h- u
: C0 T0 l# B, ^4 Q) S" S, V( Q  DeviceObject = DriverObject->DeviceObject;5 O- k9 b# C( `$ I& P' s% M

3 N! d9 b- Y0 H1 \" q. F  while ( DeviceObject )6 G$ `" }4 A8 ^
  {/ Z9 v! S: S: |' K. C! N
    GetDeviceObjectInfo( DeviceObject );5 f" a! q, l& l

( a; e: D' X/ l+ b    if ( DeviceObject->AttachedDevice )$ ]% q4 s! E/ ?* w3 Z* U
    {* w. f( |& n! a3 T: W% ], Y. z
      //8 a& G) N6 p+ e% N# h/ M9 r- i. r
      // 查找 USB 键盘设备' o3 k) Q& b! M/ d) O8 [; d
      //4 y# {$ P) X, q5 u4 V* V
      if ( GetAttachedDeviceInfo( DeviceObject ) )8 I; |9 j, ~5 Q9 L0 m6 [
      {
$ k% {; _" X( w+ s( p$ D        bFound = TRUE;
% U; ^: D: i( z# i        goto __End;$ P* Z- l) v2 e* T4 @. Y7 w9 u
      }
0 s6 a; Z2 Z5 [4 w% |    }
/ v; q# c* U$ T3 }, P$ J6 r8 z: _# @$ }) ]2 I' e, n
    DeviceObject = DeviceObject->NextDevice;
( H9 x) h+ U- {  F$ l1 [: k4 L3 E  }! W% d5 |3 _# d  r- h+ }1 D
, F, W4 g7 [5 ^+ k) T  {  ]
  __End:4 B) I4 e1 p# |4 D5 r
/ W$ ^* Q- u4 k
  if ( bFound )
5 X* W: f5 S2 x7 U* }  {  t/ a  o3 D" v+ D3 A
    //
1 E+ Z: E3 T! u8 Q; F    // 找到则返回 USB 键盘设备对象; D& w7 d5 e% i, C$ ]
    //; p  \0 _& E6 m4 ~/ Q% j. r8 m
    *UsbDeviceObject = DeviceObject;$ G0 i0 s& f1 Y5 R) ]0 t; t
  }; U( @/ ~4 y$ z$ A- C$ ]1 q
  else) H( t) @% i6 p0 u- t7 T/ \, l( w
  {
5 Q/ J) l; G+ u' U    *UsbDeviceObject = NULL;" @1 H- C! I' f5 `
  }! f' J. z- [. e8 c1 I. e" ?
- W* N. A% p9 n3 F9 T) @! ^' B
  return STATUS_SUCCESS;& k" O9 d" F  V& ~( j. V3 c) \
}. r3 Q0 p- _6 y

2 t4 x1 [% C* A0 q/////////////////////////////////////////////////////////////////+ Q8 d. n/ w6 c  d& P
// 函数类型 : 自定义工具函数$ B2 U$ v. }' t: ]7 [9 `
// 函数模块 : 键盘过滤模块
, w+ W; L" j; V' c+ Z////////////////////////////////////////////////////////////////
2 t3 \- C4 [) f- n0 c9 s! K  t// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
+ V: f$ f+ W8 t+ p: d//        信息,返回附加后的驱动对象
6 ]% M! A1 U0 Z; e* A6 T4 V1 t% j6 ~// 注意 : 此函数仅挂接 USB 键盘设备" p' x4 R: j! F4 _; Q8 k$ F0 w
/////////////////////////////////////////////////////////////////1 X- d/ s( p2 K. @
// 作者 : sinister
: J( |1 u  p1 Z  y! N// 发布版本 : 1.00.00
$ d6 @- x  x5 n' u1 {) e$ W// 发布日期 : 2005.12.27
% l' h8 J8 F1 v& G% a1 f/////////////////////////////////////////////////////////////////
2 \5 O% _: R% i; J# k% G// 重   大   修   改   历   史8 Y" w/ ]0 m0 |1 `1 c, d# i
////////////////////////////////////////////////////////////////
; B7 s0 q! r" a// 修改者 :
; I0 ~+ M; C  E// 修改日期 :3 h) a% [& }" W- j
// 修改内容 :3 H, H3 o' D5 J$ \( z1 X: x! y
/////////////////////////////////////////////////////////////////3 E+ s$ ~' M4 ]: d1 O
( r$ R0 T' I8 L' T" q: _8 S: }4 E& z
NTSTATUS$ `5 k3 s  d% x" _
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,9 t% h; S! `+ k( G6 o2 w
                         IN PDRIVER_OBJECT  DriverObject )2 }+ ~: E' H/ [
{
; \; I+ I  P' Z  PDEVICE_OBJECT DeviceObject; ! }/ z0 t2 Q3 ^
  PDEVICE_OBJECT TargetDevice;
$ b- F: K8 p6 t" ]9 k+ G) P, _  PDEVICE_EXTENSION DevExt;
/ |: |7 G, O4 v6 u  NTSTATUS ntStatus;% f/ ?$ N7 R( ~
- |% ^. t( ~+ W) I' p4 _# g, i
  //2 p" U$ R/ F8 ?8 \( ^/ d' t
  // 创建过滤设备对象  a  K/ t: u/ ~5 H
  //. O  V0 U( y$ |9 U0 z
  ntStatus = IoCreateDevice( DriverObject,
. `: X. s: m9 h$ x% [                             sizeof( DEVICE_EXTENSION ),
2 Q8 H3 Z; O# u' @1 w0 q                             NULL,, R. O, ~, |9 E' y  j: ~1 `9 g
                             FILE_DEVICE_UNKNOWN,) [  X0 K8 u$ z* Q/ z$ e
                             0,
8 {+ p- m' K, _" ~) g1 p                             FALSE,
9 N/ p* T$ q9 Q* Q- |+ u                             &DeviceObject );
9 V4 Q1 ^8 ~, n$ p1 l  y! m
* y% N0 v& D( b. t  if ( !NT_SUCCESS( ntStatus ) )
. q* ?2 j# k2 F8 y6 f  {
* i. w  B. A1 v    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );" f/ h' _, O% a! Q
    return ntStatus;$ b! k2 X" u/ I: z" D9 C
  } % X' m  a5 k: j& X3 b

- G- H, S+ s, A2 O. a$ X  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;& i1 T& U5 v* e7 k
- L% K$ {4 i4 r; T& I
  //; }, Y5 U2 B; n+ c6 n$ S
  // 初始化自旋锁
; b9 ^. o% C% r0 Z! r  //
: w, e7 ?+ z' x- l' x0 e  KeInitializeSpinLock( &DevExt->SpinLock );
+ {& u, ^& R: n" k1 U. T
: V" \6 O- _% I; V  //
5 v3 u! Y. x. {/ ?  // 初始化 IRP 计数器, Q% w+ V/ p$ j5 P1 A& U, q
  //' J( V. E$ K7 w% t/ b' j
  DevExt->IrpsInProgress = 0;0 K2 b7 p( I/ c3 N  I1 Y/ w1 V0 D
8 @# `& i" E2 G' g5 e9 U" [
  //
1 _5 @4 \9 @4 x2 o/ @1 L6 n  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
0 `  _# j* g! G; l9 r! n7 d; T5 s  //
+ [  o4 I8 `# q  F4 x. @5 G. J" ~4 _! G
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 8 A! D! Q2 U; b2 z& H$ Q, |
  if ( !TargetDevice )! ?8 w, n6 d! j" F8 p$ a0 L
  {3 I, x# |9 h) D
    IoDeleteDevice( DeviceObject );
0 n1 q( w6 B' L: D3 t3 z2 j    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
. H5 M  E+ T9 z& @$ ?  z    return STATUS_INSUFFICIENT_RESOURCES;
2 f; `! ~+ m& H- ^: w  } ) r( r' o* X# i6 Z# ^

' O; M) A: T8 Y  [& z. s* a& c& g9 m& Q9 L  //+ C( s. ]" r; m+ Y: o3 ^2 d
  // 保存过滤设备信息$ ^6 B1 a7 O" l! |) ]' A1 O
  //1 B4 c4 ~( Y) x# N, r: ~* S
  DevExt->DeviceObject = DeviceObject; ( o: ~! q; i7 _
  DevExt->TargetDevice = TargetDevice;
* U3 o' G8 b2 {9 n! h3 J+ n. Q* S3 s7 k! [/ L+ v1 e! z  B% \4 ]
  //, W/ H) h8 J# A: F
  // 设置过滤设备相关信息与标志6 ~2 W( Y2 [" U; ]" e
  //7 k. c# t- ]9 Z8 I; E6 I; B
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
! C( J) t2 P' h+ I5 J. T( S# x! a  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;2 K& r- D7 v0 Z9 k
6 V5 x; T, a0 I+ U
1 z( ^( Y5 G; w6 c
  return STATUS_SUCCESS;6 ?; c- d3 x! r3 o  q6 W
}
8 X$ B- T7 c3 q/ J
5 y/ g8 U; o* U, H; P6 {% Z/////////////////////////////////////////////////////////////////* c1 F, e" B. r" @! u
// 函数类型 : 自定义工具函数. T. h3 b# p, t& i% }, X$ T
// 函数模块 : 键盘过滤模块* ^, H. @5 X1 W
////////////////////////////////////////////////////////////////
) A* t. {! J7 e# Z* ?- N// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关- D1 x. X( l5 \4 o5 E
//        信息,返回附加后的驱动对象
2 X. B- A5 x# D// 注意 : 此函数仅挂接 PS/2 键盘设备" x# N6 n, N0 J4 k
/////////////////////////////////////////////////////////////////  t/ h9 S& h0 X+ w- E  V
// 作者 : sinister
" k& `  w- v3 P. B2 ]9 q// 发布版本 : 1.00.00( [  N% R5 `( m% g  n# w
// 发布日期 : 2005.12.27' C1 R/ j: v) U2 `
/////////////////////////////////////////////////////////////////
/ O* l4 [( N) t; Z// 重   大   修   改   历   史' s/ v# N4 X( g& I
////////////////////////////////////////////////////////////////
* x1 w0 ]! x1 B- j( [) G: A8 e// 修改者 :* H# x6 m4 Q2 C
// 修改日期 :
4 i# v" }7 F9 s! T6 c// 修改内容 :$ y% I! @3 z$ |- A% [( F- A9 n
/////////////////////////////////////////////////////////////////
7 Y( u2 h, P0 l5 v3 R, ~
  _; @/ n; B" k9 Q6 m+ zNTSTATUS: ]0 W) y# @$ `* b+ Q7 ]
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名! Y4 u' K* J% P: S+ [' _+ q
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
' Q, I" F) ^; c+ t. o2 W                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
6 o! Z: d, W* V1 }( ?3 R{
8 N0 u" D: B" Q* p5 l4 c; D! A  PDEVICE_OBJECT DeviceObject; 3 Z9 e7 r/ v6 l* G
  PDEVICE_OBJECT FilterDeviceObject;) o0 ^$ M' `1 ^0 a' f
  PDEVICE_OBJECT TargetDevice; # F9 c# S/ b" @4 w. b9 [" g
  PFILE_OBJECT FileObject; + Z) [% ~- b4 ]' Z6 C
  PDEVICE_EXTENSION DevExt;3 z4 C% U5 g/ E$ p* b
4 k/ D* B; K# f% {# p2 f2 M
  NTSTATUS ntStatus;
3 C8 l" p! H+ F4 s5 \; Z$ Y  O
7 j! P: G) g, @, a  //
* K) s* ^4 h* |: ~6 z: U  // 根据设备名称找到需要附加的设备对象
! R; }$ J8 q+ x$ ^) |  y+ s  //
# s$ f4 s) P- e) q  O  ntStatus = IoGetDeviceObjectPointer( DeviceName,6 Z# b' A' k; G9 |/ O
                                       FILE_ALL_ACCESS,- O3 {0 m3 [, C9 F2 S1 o! ~
                                       &FileObject,
" u, d8 Y7 h, v( {& q6 D                                       &DeviceObject );
3 l% L) G2 o, W( N2 Q* ?7 ]0 ^0 P0 _3 u4 E
  if ( !NT_SUCCESS( ntStatus ) )
& W1 ~  ?& H7 G) f# l  {
# R6 s/ g! g9 c    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
( ]. t' p% W. H- O& `! J0 j    return ntStatus;
  T1 g6 d; M2 P- ?0 N- l  } # H1 @1 a7 @$ _% k
: y# C7 D7 ?8 m$ v
  //
4 ^/ s1 A5 @" r# c5 j  ^0 `. |+ Y  // 创建过滤设备对象
' J# A1 N% }$ I0 {2 P6 X  //: r. f4 h3 p: M4 _
  ntStatus = IoCreateDevice( DriverObject,
- D( w# `. G! O* A- b  D                             sizeof( DEVICE_EXTENSION ),6 L: R9 F4 a$ E4 z0 w
                             NULL,1 \8 d5 O2 u+ s" j1 @9 N) I
                             FILE_DEVICE_KEYBOARD,7 Y+ L& }& s: P+ v6 T
                             0,/ U: b0 _6 _- t  E5 |5 l6 X6 T6 X0 A! z
                             FALSE,4 R6 S3 n& x4 Y6 a$ L- V0 B3 _
                             &FilterDeviceObject ); 8 h# D3 z0 @; D
2 t% l  y  G, ]! q! b6 Z& f# l( u
  if ( !NT_SUCCESS( ntStatus ) )3 y1 K# n8 Q, a
  {
3 K; n- e# M% ^& ~7 |, D4 c/ H: Q    ObDereferenceObject( FileObject );
5 n- u' O1 \* C; C1 k) s( B$ K0 F8 U% V    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );# r" f* X& }( P1 v: D) }
    return ntStatus;+ d; {/ {4 Q' @' f; i8 H
  }
# d, P4 C* U8 @/ Y. f7 E# o# `! i& d+ l1 o+ }5 e! u; r
  //
1 \- a9 ?4 d" k& k: k. t) l  // 得到设备扩展结构,以便下面保存过滤设备信息$ K$ ?' O3 G0 S
  //' \! f$ d. x, I4 I1 T5 ?9 X
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;) _9 D/ ]  y) q# K, ^. |

8 n1 Q8 d' ?+ z3 e% O8 n' r+ s! a# q) J! G( Z3 P
  //
2 Y" T( J$ U$ A- g  // 初始化自旋锁
6 q3 {/ @, {. V" h! ^- ?  //4 L' F( W% A- E% c
  KeInitializeSpinLock( &DevExt->SpinLock );
* t! G! p1 @( V+ G
3 Z' e" m, S/ w7 S3 w, O' y6 d9 n/ p  //
' Z' b6 R2 `% z* Y9 T1 _; R5 I  // 初始化 IRP 计数器* `2 R% T. {# j' W3 \) Q
  //) l1 }0 G( @: n6 q, A
  DevExt->IrpsInProgress = 0;
' d: q# B$ R% c+ ~" k; Z* E2 j% l. @) r7 Y4 u' i* U
  //* ~, W2 r2 i3 J2 l, L
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象7 o* t1 ?3 U$ s4 j7 V# s: W
  //
+ p( s" Q/ n" w6 [, l$ e  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
; U% ]# G  r% l% Q" F                                              DeviceObject ); . Y! Y( d( |" o) Y
  if ( !TargetDevice )
3 e+ x( {- V- x# t! o% p  {& _. W2 I9 ?0 C0 ?8 `
    ObDereferenceObject( FileObject ); 6 }8 `& P+ Q: {0 n5 n: S
    IoDeleteDevice( FilterDeviceObject );
1 W7 Y5 |7 x& V" f) _4 l8 c% w    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );  r0 M- V/ y, t- K$ z
    return STATUS_INSUFFICIENT_RESOURCES;; A. q2 x( k8 \0 c: {- {) v- O- b
  }   R, C: ]3 y( O# M, e

' o9 c; F# s/ {% l! O! y9 ?  //1 P( z# J/ h! p5 V8 c" M$ X
  // 保存过滤设备信息6 k5 }% O) x; {& \* J, X
  //+ ]: e9 d$ u$ J. i% y$ I
  DevExt->DeviceObject = FilterDeviceObject; 3 O. O2 \( p2 l3 b% _0 e  ?
  DevExt->TargetDevice = TargetDevice; $ A5 V) G  h) ]. H
  DevExt->pFilterFileObject = FileObject;9 i8 ^( P6 @9 @4 `9 k& |: M! q! i
1 x, O  K! n4 |. t
  //
) j: |3 B+ b7 O2 V& w  // 设置过滤设备相关信息与标志( w# I+ h# ]2 k- ^- z/ Z
  //
; q/ s& |# {; P  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
8 k0 `2 T2 l/ y. I) m. N  FilterDeviceObject->Characteristics = TargetDevice->Characteristics; & `/ `% @) d  B2 E' |: B! _' B
  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
$ ~+ y3 @( u: {0 Q5 c5 b4 S: o% X7 L  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |, _1 z( W; B1 F1 Z# K# y- J
                                                         DO_BUFFERED_IO ) );
2 j; M( D( H( f0 l: B0 }
$ h' }  h' T* Q& R( i1 @; P  //
+ _2 `7 `- U" G& E7 ~+ K8 u  // 返回附加后的驱动对象5 U# N4 _- _  J
  //
4 B" E6 @/ t1 l) }  *FilterDriverObject = TargetDevice->DriverObject;
( E* b6 s$ x% z
8 Q* t( T$ v5 g( \5 E+ y/ b+ l  ObDereferenceObject( FileObject );
" J: \, l* Q  A+ J8 _* |. {+ F9 i3 `! b* p$ W, ]
  return STATUS_SUCCESS;
$ H+ A0 A5 k0 {7 W4 r: O& k8 K}
! b+ i) r) W) y, n( m: g) x# z- z. e& D& s1 `
/////////////////////////////////////////////////////////////////
7 [- u# B8 t6 g4 Z, n1 `; n// 函数类型 : 自定义工具函数
1 e# W7 o+ H0 X: G8 G& z  R// 函数模块 : 键盘过滤模块1 f7 E; l& G! f3 L" {+ c" u
////////////////////////////////////////////////////////////////  ]* ^( ?- r( ?" j* ?
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发9 ]( v  u0 ~! t1 ~
//        这个 IRP 的完成
' L$ ]& k9 `6 `: W/ U// 注意 :
2 N' V' V1 U, k! {) m/////////////////////////////////////////////////////////////////
. e& h# P2 F& |( Z- s// 作者 : sinister! r5 W+ [- M8 E: R. q2 R
// 发布版本 : 1.00.00; L/ R3 o& }# D9 S
// 发布日期 : 2007.2.15
9 U1 p! T: ~+ ]$ y" R2 }. U- j/////////////////////////////////////////////////////////////////- G, `- ?  R8 M  O8 A! E, a
// 重   大   修   改   历   史
$ ?# L6 i2 o6 I) K  M0 S- w- ]////////////////////////////////////////////////////////////////2 V6 p. B- k6 r& x
// 修改者 :
: H; `/ n' S! X( j$ [9 m; G; V9 r// 修改日期 :& I' ]. \; _1 r) v6 s
// 修改内容 :9 Z) k" \- T. G9 a0 I, i! {
/////////////////////////////////////////////////////////////////
+ c( x9 G0 ]6 e4 l; I4 W  S6 o' `. a# z6 W' n* H
NTSTATUS) E0 @4 c$ X$ m* t! D8 o
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )% m1 X* ~9 i- m8 @- M5 w
{
0 D8 o" `2 _6 b" f  NTSTATUS status;
& w" h1 V1 J  `( M% z; c& T0 J: u  KIRQL IrqLevel;+ m, I. R' k# H; w

( K, P' Q: S8 `  PDEVICE_OBJECT pDeviceObject;
5 f/ m- r- G; R; K/ g* \  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )- y* x- L3 t; X% U* T3 G
                                   DeviceObject->DeviceExtension; 3 r4 x; H$ |" V2 f0 @$ m- a
- A1 O: h5 S) c/ Q( L% T6 z

* w( N$ {/ c' O$ z  IoCopyCurrentIrpStackLocationToNext( Irp );5 @: U+ o  Q8 ?+ Z$ a, k
. Z, R" o: Z$ n7 F# E
  /// u5 `9 h8 ~# [) M& R7 ]4 G
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
  t6 R! m: k. _- U/ [! o  //
5 d7 u2 R( u) R' n3 ^+ e  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );2 r4 N6 J$ R6 e- o0 G% {
  InterlockedIncrement( &KeyExtension->IrpsInProgress );
5 I8 O  U' U0 Z+ [% G" ]( z  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );9 s4 X, `2 q. v
6 H- e( A3 c. ?5 J3 [
  IoSetCompletionRoutine( Irp,5 i- q, i' k! ~8 P+ |+ p$ D
                          KeyReadCompletion,
- P  p5 J+ L% d                          DeviceObject,
0 Z5 O) }1 l* X3 @                          TRUE,
5 w4 R) k' ^* V! N$ g                          TRUE,
7 f) o1 G7 ~7 H* ~$ G                          TRUE );
1 B4 w# ~( j% ^6 R; P0 `! a/ h3 _0 e  D) x$ r& ~# P1 ~
  return IoCallDriver( KeyExtension->TargetDevice, Irp );4 {6 k1 c9 A0 G9 `- V
}
, t; n- K6 d6 B% V: r; m" t: w- S: Q: |# Y
/////////////////////////////////////////////////////////////////$ f5 ?4 A6 N' Z; e2 @& F
// 函数类型 :系统回调函数
$ n2 H' R/ ]7 ^2 a- o; r// 函数模块 : 键盘过滤模块
4 v7 ^& h* h; h8 a0 {5 y) Y////////////////////////////////////////////////////////////////" C) e9 T, Q5 M) a
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的  \) Z9 O( u% L) R4 D
// 注意 : ) q/ X$ y4 z4 G: n2 O
/////////////////////////////////////////////////////////////////
, D# ]! M/ p- ^2 I  h// 作者 : sinister" S" ~: A# u' y2 D# C
// 发布版本 : 1.00.009 l+ x+ C  V$ K! `' e* E
// 发布日期 : 2007.2.12$ I& ?) i$ p( j: @
/////////////////////////////////////////////////////////////////
. j) o- d, x& m: p# b// 重   大   修   改   历   史( k# ~: ]5 L  e( t
////////////////////////////////////////////////////////////////) x" s/ m# T+ m6 s7 p! [
// 修改者 :
) _9 k' ~7 P9 j- M$ \// 修改日期 :9 ^" [% @1 y# @* J3 u0 a
// 修改内容 :( n' }, o: `( L* s, i% z* q
/////////////////////////////////////////////////////////////////0 U! J! O% k# Q6 L8 b6 m3 i1 J
/ \; X6 J% E/ G" E9 d, |
NTSTATUS0 Q* H' Y0 p+ F, i' c5 s5 e4 s
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
7 V1 l; l1 V2 ^& G                   IN PIRP Irp,
, y$ a- S% ^1 \( ?                   IN PVOID Context )
, S6 z, w! G9 q{/ u2 h% j# i4 j, W+ g* N( {
  PIO_STACK_LOCATION IrpSp;
6 b% I' t1 a- s4 u* ^0 Y2 w  PKEYBOARD_INPUT_DATA KeyData;6 X! \) M; U( Z  I
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
# o" k7 L+ N3 q  c* T4 V# \                                   DeviceObject->DeviceExtension; 0 ~- Y+ r/ t; X  d
  int numKeys, i;
: X4 N# `1 }7 O) C6 t  KIRQL IrqLevel;0 y- A5 Y4 u, _5 S: p9 T

2 v4 X" S: v+ }2 }  IrpSp = IoGetCurrentIrpStackLocation( Irp );
3 c! W  T/ E0 v- H9 H
5 n4 a: l! [( @2 a, H8 H; J8 e) f+ L% `/ U" O! e8 ?
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
, c/ [/ g; e0 [% j2 `$ K7 Y9 m  {
3 w8 G  [. Z( l    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
7 _# c1 f0 ~: b) \: H) g+ q. W    goto __RoutineEnd;
, y0 Q7 X8 V' `% z$ l  }5 z& i" g: r4 s9 p' {0 q: {3 \
4 t& ^6 k" `, u2 m. W, C( g
  //
" l7 v* w  A2 z2 k" O  // 系统在 SystemBuffer 中保存按键信息$ o) V2 O/ B% Q3 Q
  //
  A/ I$ u) U1 j- I# b  KeyData = Irp->AssociatedIrp.SystemBuffer;
( \% {: _+ M$ B" D  if ( KeyData == NULL )# W* j2 F4 j( t! h, y7 ~/ E
  {* J: c, J  g8 V
    DbgPrint( "KeyData is NULL\n" );
4 X/ F' g+ p$ O9 z    goto __RoutineEnd;
& _. p  J- a8 b) q( N7 J  }9 {4 z  v0 X/ |# p) ?
* m9 I7 t( K* n5 d) f$ G
  //
) Y  _* K: D$ Q  // 得到按键数! L5 p; O' u- @, k* a2 e  n
  //
" }6 s4 [( {* X: ~) Q  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
( A  c+ ^: H4 _0 t' m  if ( numKeys < 0 )2 G$ \* K2 W! B5 K  {% q3 k0 k
  {
% \8 d( K  `; ?( Y    DbgPrint( "numKeys less zero\n" );
' D0 h1 g5 j' E/ C2 F    goto __RoutineEnd;
5 v- L- O2 W$ B. R- L( g2 a  ^& {  }
( f, P8 u: r% Z6 b% v% Y9 ?: k9 v. D0 a0 T/ W# {
  //7 U. q4 r9 C3 Z
  // 使用 0 无效扫描码替换,屏蔽所有按键
+ Z. s! I; v6 K2 m: O* v1 l6 a  //4 C: T0 n+ x6 L% |* K
  for ( i = 0; i < numKeys; i++ )8 ~+ {* g- t& N+ n% Y0 O
  {
3 X1 z2 P+ z) l2 f. C3 f1 R1 p    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
3 U6 C3 e* c: f# l  [0 a    KeyData[i].MakeCode = 0x00;0 e. d3 s, a) K# C* G2 w
  }
! R9 p% n  n7 F7 ~) S) U; A: O* B/ @! `% k: y6 V
0 C& j* K% D% h4 W( \6 V! J: [  j
  __RoutineEnd : 5 X4 \, T* F5 R. H& S
# T9 T. Z6 f) q* |8 U4 V4 P2 M
  if ( Irp->PendingReturned )0 F+ g# a$ D8 f# j3 y
  {% _# Y- _( b& g  C$ M
    IoMarkIrpPending( Irp );# o, M1 S. B$ E% }$ z
  } ' `3 h; ~! r  r0 N; v* P

! {7 S; f$ z6 T  v" |  /// \5 h' M1 m8 h  ~4 l
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁
+ i; d3 G3 p' l( O- p- }6 l& }  //
9 J' B  ]0 Q4 h4 W5 l  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );6 O9 Y6 T% Y, a% M1 w+ `9 I' e& c
  InterlockedDecrement( &KeyExtension->IrpsInProgress );/ N+ l; U% H2 f+ Y5 x7 k
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
. v6 P  Z* m* j8 x" g5 i, m+ @1 g
" _6 p+ C9 f; b6 m6 S. G& V! j  return Irp->IoStatus.Status ;3 N: T. f/ |* i& e7 H1 `  G
} 5 T. b1 p- i1 c# u5 W, X" f# V* z

8 R3 i: e: ~3 a6 F+ K+ y" l1 b3 x! A4 g' Y8 v' X7 `2 V) q
/*****************************************************************
- u; u  [2 t+ \/ K& Z! c3 \* y 文件名        : WssLockKey.h
0 g! V9 L  X  U! e; _- t6 w+ \ 描述          : 键盘过滤驱动) j: P! I  l3 C( m& ~
作者          : sinister
( x9 {: R% A3 x 最后修改日期  : 2007-02-265 q, A' p+ d, h) `! f
*****************************************************************/
0 }0 t, K2 U1 ]' \' h' M) n! f, P
#ifndef __WSS_LOCKKEY_H_* d/ P4 i: l4 N& Y4 E% x. |
#define __WSS_LOCKKEY_H_5 ?# {# {  G3 S
* I6 f* G  d0 b/ W6 S$ ?  K7 U- J
#include "ntddk.h"# Q1 {5 _$ G' O4 e, e& K, p
#include "ntddkbd.h"/ P5 z6 y5 A0 T- x8 Y) l9 [) q
#include "string.h"* `- S; }& C/ K1 ^) y9 g8 r
#include 5 _0 S9 z- t0 D% {7 [, Z. g$ r

7 t# U" T$ n& K& G$ P#define MAXLEN 256
( f" w/ ~' g; D1 c+ K0 w) I! K
. M3 a+ D0 B/ p8 u6 L: g; \# x#define KDBDEVICENAME L"\\Driver\\kbdhid"* J( x; ~# t" x8 D8 s
#define USBKEYBOARDNAME L"\\Driver\\hidusb" # `" q, ~  d/ x: U* c
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0") Q+ J/ D/ k6 |5 s

( D( X/ |0 @0 J0 I% Y8 K) z4 ctypedef struct _OBJECT_CREATE_INFORMATION+ v: I" [- y1 L; j
{
# E* O& l9 R; V7 i1 ]9 R2 [6 K    ULONG Attributes;
+ V, c# b' B* ^8 [* }    HANDLE RootDirectory;
) p+ j$ L" w& s/ l9 `$ G    PVOID ParseContext;/ H# ]# ^5 ]8 R- [4 A3 \  E: I
    KPROCESSOR_MODE ProbeMode;
9 Z6 {: h3 e+ k    ULONG PagedPoolCharge;
% N5 {) W9 E2 u: x    ULONG NonPagedPoolCharge;6 H( i/ O- w- C1 \$ m3 s
    ULONG SecurityDescriptorCharge;% ~, R! _$ M% V0 }6 C9 k
    PSECURITY_DESCRIPTOR SecurityDescriptor;& [" c. \4 F3 M' l* d' {0 y3 r
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
& ~2 D; o! l; X0 p  C% F    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;8 C, _! E: N# T# B: p9 Y6 t
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
/ Z. O: w4 R6 l4 v2 y& m. x
& q9 X0 W5 F' xtypedef struct _OBJECT_HEADER
  }. P2 A7 F" e4 h{
* ?; ^) k6 @" o  Q$ g    LONG PointerCount;
+ w- H2 Q9 l5 k. m$ U  u    union2 O) F( m2 @# B' g
    {& N# H* u' A" l  f. t+ `) C$ p4 A
        LONG HandleCount;; w! S3 ~! a2 l% o
        PSINGLE_LIST_ENTRY SEntry;
& t' H: ^; X- R$ @! `    };
( p! R( S* [+ l  d/ d* Q# j    POBJECT_TYPE Type;6 _1 q$ [1 P7 `) l) v# X4 S0 a( z
    UCHAR NameInfoOffset;+ J6 |! S8 J/ r2 _) B$ T. L7 i
    UCHAR HandleInfoOffset;
. T: R$ Q$ @/ M) z& T    UCHAR QuotaInfoOffset;& H9 p* f" b  w1 v, r! Q9 B1 j7 L3 A
    UCHAR Flags;
% m+ I5 Q* |2 [3 u& R    union4 e3 O8 C; ]) Z* R/ ?  Q+ {' M
    {3 E# J1 r! ]! h, u
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
" _5 [9 D* A4 J8 f. y3 u- s6 e        PVOID QuotaBlockCharged;6 l  R% N1 N% k4 ^
    };
* i: l" B3 s$ _$ Q! X! W% o" Y& g- J* ]1 Y. ^4 |
    PSECURITY_DESCRIPTOR SecurityDescriptor;: `+ g3 ?: z& J
    QUAD Body;
# P& Q8 y5 {3 \} OBJECT_HEADER, * POBJECT_HEADER;& K$ g4 W4 k2 h( Z4 `
1 n. }) L2 n; B! @/ w
#define NUMBER_HASH_BUCKETS 37
/ z5 v! F% c+ L/ t2 P# ?. T' X$ }* W  m8 }, D+ O1 D: P, H+ S
typedef struct _OBJECT_DIRECTORY- C+ O) X0 o! d7 }" D& ~
{8 `& h7 T2 U0 k6 g6 ?
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];+ |" a9 J* K$ E7 d2 L
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
2 C/ t! ]3 i0 {0 f    BOOLEAN LookupFound;
  W! G$ ]% S: A7 K! l2 N8 Z4 E: J    USHORT SymbolicLinkUsageCount;8 Y! `; U) |, c! [" F0 Y$ t
    struct _DEVICE_MAP* DeviceMap;+ V+ h& l6 i/ t9 K7 ?6 u7 I
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
7 M9 v3 @6 J/ w* J2 O3 q1 |2 b7 P  P3 k1 n8 C; H
typedef struct _OBJECT_HEADER_NAME_INFO& O% c5 @6 e' P, v- L: _
{
: t# `3 s% S9 I! f: V& j    POBJECT_DIRECTORY Directory;. q. @/ C' ^7 G7 a3 ^( |# S
    UNICODE_STRING Name;
' T+ w2 c+ P' o- k$ ?    ULONG Reserved;
. j3 \9 [! e  X#if DBG
) t" P3 r* I* H% v& s    ULONG Reserved2 ;
* M! H$ b0 N. |, J+ b2 E! U    LONG DbgDereferenceCount ;3 a, j" r/ h: x7 b9 `" w
#endif
( F+ J& d; k9 F. n( H( p2 @: n} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
: Y/ Z7 I0 @0 ]& p- ?: c6 H4 Q. J* o/ t& S; ^
#define OBJECT_TO_OBJECT_HEADER( o ) \5 U3 n# k- s' M; W, u: A  M
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )* l9 L$ `) W& v5 y' B
# F3 N+ h2 ]# w, H& c( w! E" u
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \+ X3 ~1 i: F' y- Z+ s' x# o
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))7 c' `6 ~+ r- T# b" h, ]! l5 o: A" d

( j  g: M1 }/ o' F' R* Itypedef struct _DEVICE_EXTENSION
/ _* U/ K: v% B  M{0 o  b& [; g$ |6 I5 `( D7 V/ E
    PDEVICE_OBJECT DeviceObject;
+ _- A. p( d9 K8 }1 Q0 R    PDEVICE_OBJECT TargetDevice;
+ n8 k. r( m! Q" B    PFILE_OBJECT pFilterFileObject;
3 F" B' C( F1 t3 [( B" j1 W4 U    ULONG DeviceExtensionFlags;
9 a1 g+ `. \1 U  K; y! U    LONG IrpsInProgress;" ~9 |* I" |' R# G) R  g5 a1 e2 Y
    KSPIN_LOCK SpinLock;7 R- Z  _6 k- {' S, B$ J
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
# u3 g7 P. h8 y0 L( Y) M0 `, j3 N& @, ^2 T

3 g3 F) V& c1 x9 D6 F4 N5 G$ mVOID
% ^3 S' o; X. `+ _KeyDriverUnload( PDRIVER_OBJECT KeyDriver );# P0 t+ q( G& q4 @7 `9 h, V
; u6 g/ {% U+ J+ E% Q! j
BOOLEAN
8 z. H. e6 m. e9 zCancelKeyboardIrp( IN PIRP Irp );/ Y) }. S# y% {# [! Q) w

" b- P0 j' X$ B% fextern POBJECT_TYPE* IoDriverObjectType;
/ x7 z3 V4 A7 O; V! c+ w; L) ?
) O5 [, A3 ~# p4 wNTSYSAPI
! X; y4 `1 ^: P( C' S: r. uNTSTATUS& _) S( k  u/ n0 C8 ~0 E
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
, y, x3 O; b" _, k  n% e                               IN ULONG Attributes,
& I7 n5 F9 M9 ?9 k5 X                               IN PACCESS_STATE AccessState OPTIONAL,
: C3 ?: C5 S, S+ g- `9 j                               IN ACCESS_MASK DesiredAccess OPTIONAL,9 _* |( O$ f2 C- @! O
                               IN POBJECT_TYPE ObjectType,
* J6 {+ O" w; k9 H. C                               IN KPROCESSOR_MODE AccessMode,- w6 G" h5 O: R8 y: m
                               IN OUT PVOID ParseContext OPTIONAL,
" N" w" K4 ?7 ^! `1 J; P                               OUT PVOID* Object );
' T2 y, V( v$ p3 D; k6 Y  I+ z% Q& S& C4 M! A3 Z% ]; D
NTSTATUS 2 `% t* A+ g: q# i
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );+ c; p/ w6 }. H9 f

- ^# S0 z/ f; n. n4 wBOOLEAN * P2 g7 A4 p8 p4 y" P
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );- U) t6 J( F* z- t1 g
, d1 ^5 n  ?6 }/ R" |. C
VOID
2 \7 H3 h5 I( t7 ZGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );( |$ n+ B) h+ [& F; e; s

, a) h, B; v$ s8 TNTSTATUS 0 N6 @# M: L8 T' W+ q7 K
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
/ k% Q5 \  a, U; L: t+ V# x% H& |                                  IN PDRIVER_OBJECT  DriverObject );
7 E$ A4 }( T8 y# J6 i4 I9 u# r" z/ y0 v1 F; X/ J$ w; Z5 ~- d5 A: F
NTSTATUS
; c: o0 a6 K* q, Z) {AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
: g! x+ y: r2 B) R% g+ ?                                  IN PDRIVER_OBJECT  DriverObject,
) }# i$ c' e# y; {" A5 k8 k                                  OUT PDRIVER_OBJECT* FilterDriverObject );1 u1 Q9 z: g& ?& z2 ^
7 ~5 L3 J+ P# L7 O
NTSTATUS
7 J& d* M7 Y7 f7 v2 OKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
3 D# l( ~6 c0 [& J% }                            IN PIRP Irp,
2 S, |, r, \% x$ R. h5 X4 Y1 [                            IN PVOID Context );. ^* `$ X% N- p  T5 ?/ q5 |
NTSTATUS
. P6 j  Z6 q9 n% X! l) yKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
# n, Y' k2 E8 B0 W$ y' P! P7 V, L& @* x4 L8 q  h
WCHAR szUsbDeviceName[MAXLEN];
( I# C; V4 ^, P0 @8 ~# B. j  Q
- I$ ^6 Q6 G% U5 ?#endif
* R) X* T& ^" Y" b. q% V+ V4 [
" k. O  c  L2 h' b- U* T
! q" j$ }  }6 G1 P" U
# W; h. ~* |! O, q* u( \0 [2 ?, T

! r4 l& x$ y& n! z# n9 n) r/ ]WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。" N* M( T2 P4 L; H( I
WSS 主页:[url]http://www.whitecell.org/[/url]
3 E& Y! y4 z6 n$ i& U& hWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-2-1 04:09 , Processed in 0.060136 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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