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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
. j4 E2 h7 A7 _5 z. N, REmail:   [email]sinister@whitecell.org[/email]5 I8 v/ z8 F/ q" l" G
Homepage:[url]http://www.whitecell.org[/url] , ~, x4 }7 k+ V9 S' f- b# `* `6 F
Date:    2007-02-26. G# m4 X- |; z' T
- w5 Q  O6 N( d5 w3 }7 N
! y' [0 j: {& C% I3 b
/*******************************************************************
$ v  z8 X) d: A& T$ F4 T
6 q. a7 T, u" L9 Q: x9 a( {这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
( F  }( w( U, w- e$ k写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的9 d  ^0 P% _. [. I! p& H' \8 ?6 A
功能要求如下:
% h9 s' V5 l% O" h) Y/ g% D7 p1 p$ m
1、强制锁定键盘/鼠标。
# ~1 }% _" E1 P" M# R2 ~2、可动态加/解锁
3 {0 B4 ^! Y$ o- O. b1 A; E3、兼容所有 NT 系列的操作系统。
  H5 i+ y, Z* G: l
8 b2 Y, E( K, ?$ R' g  g+ E* Y就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
2 H  r) ?5 v/ |/ k4 u1 e: d4 y) d现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
1 q/ a; J& G& y$ W何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
' r- B- o1 k* x. {7 w2 J' s/ e上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
0 I% `+ g6 u/ {$ P6 x9 F怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
+ A3 v& i  L; v就来看一下我想到的几种实现方法:. s0 |2 A% ]+ f+ S+ _7 R" l, F
! X. C5 P4 J8 ?
1、全局键盘/鼠标钩子5 S8 ~( S' O9 [8 X5 n+ R
2、BlockInput() API
, B/ p5 P3 u" u' g/ a3、使用 setupapi 进行控制
% `2 X5 K; k' u) A" A( D4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
/ N& ~5 S( p$ a# g5、拦截 win23k!RawInputThread() 函数/ h$ u. U* J) B/ j3 o* `0 x
6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动# f! ^, m( w/ s6 W( S, q
7、拦截 kdbclass 驱动的 driver dispatch routine! l7 Z+ F1 Y' d4 M0 Z9 ~8 d( W
8、实现一个 PS/2 与 USB 键盘过滤驱动
& V( H8 ?; x3 l( l+ j" L0 q8 G  D8 e$ K9 V1 Y3 V4 i* l6 t+ v, j
( t& E0 a5 R; A
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑1 W, G' e3 [3 t; m/ c/ W4 E3 ^2 E
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
& W+ q$ z4 M0 z) U! \$ a0 i案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
2 N3 b) g8 B! A6 e6 _兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因
- l9 z1 R- w! J, A& d& c7 Y! y2 H+ a素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
" Z4 t' S2 b8 A1 L; z问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸: x/ d2 E1 a. h1 p. G  A
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我" V7 n( A: S& ^9 l( E% |" A- B
的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来. ]# t4 e* ?( P( q% n  u6 }
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
9 J# s- o8 z- V) E7 c# o& a! f; s果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
" A% T8 ?/ V- Q. Q" h% _障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
  z0 ?2 R; r: r0 FIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
2 W7 c8 W  S1 n4 b* c+ vUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键3 r& E" B( I' V
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方7 S$ c' W' Y  R/ F1 @
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
! I5 F- c9 `1 T) c* r& C& w# @1 G( @
/ K( [" D" H4 ^# _
* F2 J9 z: K# M+ t" U# L0 ^* y/ ?我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
$ l* s# m  L3 a# X4 ~滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
9 Y( O0 c  z9 I# h行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
5 V! m' n# I8 \; Y+ c8 j# W$ g只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越& ~0 q2 g% p; I2 R8 g/ P
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
  q/ x+ Z  k5 A. X; X. C# k3 r+ BKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB8 d1 a) Q2 U8 t9 z# G' b! u
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用! G; [+ y7 ^& e$ w) R& _# n
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
: }; i4 p# w$ g8 h: T( U+ J+ O# O我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题9 |* D4 Y& P% P# k, n
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的3 ]( y: o* N9 Y( K
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
- u0 o' j$ V1 v) `/ L& @) y# b0 \用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通2 V7 a- C  Z4 Y. n/ K
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
, y( H+ @% w1 M4 g# Y屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通6 ~+ ^, M  H# B- B* {) I- |2 X
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb8 d2 E7 u+ n! O7 }" b3 S
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
5 v+ d3 B. Q& z" W: R- c! A的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意5 p" {( H) S/ N/ t* v
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
" f, {8 O  G+ e% Q; t经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
. |2 J/ V' v) F6 @" m! g$ o+ @来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
  W0 w) @$ x/ q的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo. N/ y# e; C0 C. I7 [, d
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
: h+ T& M% J( A+ k/ n敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,& b5 |& C+ m  U" A- {: _" f' q' ]& W
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
: q2 l; ?% K# F9 M. ]& f见下面代码。
) o( ^% r. b' p- v! Y  m' F) G, ~  A6 T
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程
$ T7 {& s& c, @) u. q6 h7 c里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键# ?$ X2 W' p* t
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/20035 Y" o& X. q/ \( {, [" U3 z* N
上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有! p9 \  `! u/ E' k9 M2 E" s
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
, r' ]5 e4 Y1 ^继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个8 S3 a* C" F, r
锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按  y' \1 z5 v' @. m2 q3 ]
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。9 l" ?' g0 o2 T

/ j8 E$ ~- f3 s: G6 T; B6 S! G& c
完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用2 u. ]6 Q. ^* R; T$ ~3 a8 ~
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是$ [( B3 |7 M+ T' T5 d5 p1 x
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣) k7 w) [5 z+ c4 T2 }+ n; `9 C
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我
6 }- ^# g  g6 l7 J+ ^7 Z4 u们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
1 Q2 U/ @3 ^$ j" G% ~- _们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
( Y; T; x9 g  U# i: n2 S" g->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。
- o/ O$ ]  A' A6 P* |如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
- M# R, n% F6 i1 U8 e进行操作了。这个问题有待大家来完善了。- N9 |& c0 z* q6 s" a9 y4 J

( w2 \8 S  _: o1 y, C
! p6 M' o& B) K2 }7 W要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
+ q7 h3 y0 |6 l5 p. ]. D3 h6 j7 v5 D来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的6 {' _5 }/ i! @7 t9 M
分析做个记录而已。我更愿意把它看做是一段注释。
8 E8 `! B7 q: [& |% k. z+ ?2 @3 S. q! s
最后在此代码中要- w9 g7 `) H+ [+ z' d/ |9 R, p8 s

. E2 \; D9 B- p+ w9 g: Z9 }/ {7 X感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
. e0 d5 P7 _* V2 c  p
) }- S, ?; E: [" i5 V7 r& b感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。" r  R" {! y2 t
8 m5 w3 K( o: E% [3 n, e
感谢:齐佳佳,过节请我吃好吃的。5 V4 `/ a; a5 u+ s/ x! f

; R7 _, Y" @) g4 I
7 Y7 Q' S; n1 x7 l; o******************************************************************/- E$ u  t1 R$ t9 F5 Z, v, ^6 S
* S+ a3 n6 B, r4 B: L5 ~
/ r& v0 m: d9 ]* @" \
/*****************************************************************7 h: W( m: ]- P9 @
文件名        : WssLockKey.c* w1 A+ o9 ?( d4 p
描述          : 键盘过滤驱动
2 v" i! D' Y9 J1 Q8 A 作者          : sinister
' e( z+ @0 I) p9 W. [* p 最后修改日期  : 2007-02-26
, c; W. }: S: [8 a*****************************************************************/
' E2 f+ d: s/ O# r7 g/ z  Z; V* |
2 _* u) \- h2 z! o2 R) O% ^. Y2 C- o0 y& d7 R" Y) X. N
#include "WssLockKey.h"
2 P! `: d- E, q8 _2 \! b- w& }* {- i2 W/ @7 U  D+ l7 O7 u" d0 Y
NTSTATUS
5 L0 B3 y* d% X7 o* z, y" ^DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
  l( @! ^! I  R+ r* V             IN PUNICODE_STRING RegistryPath )" I: O1 E8 d6 @" j" m
{5 b- b5 A6 L/ W% [0 W4 g+ h
  UNICODE_STRING KeyDeviceName;
4 K5 c0 e: }% A3 d. m  PDRIVER_OBJECT KeyDriver; 9 X: }0 z; s' x  ?0 k7 J; ^. a
  PDEVICE_OBJECT UsbDeviceObject;
& t& r+ S4 K2 f" @  NTSTATUS ntStatus; 9 |6 q3 z6 [: W1 _
  ULONG i; # {+ n( c1 E! `7 k8 h
4 u0 t" I) [- ]
  //
% q+ P! o. d2 a/ D3 X+ T' e  // 保存设备名,调试使用- {! h) _; x9 b  w1 k* `2 H
  //* {& F- p* n0 m# k: o- V: g" K
  WCHAR szDeviceName[MAXLEN + MAXLEN] =1 Z% Y; k- U# u9 S$ h0 B/ E
  {
* f7 U/ C2 ]; P5 k    00 [3 i( h, m; M% T1 h  y
  };
2 U! I4 C6 `( d4 x) h  D) u6 F2 q* q( w# h5 b# E! e# ^) h: G
  KeyDriverObject->DriverUnload = KeyDriverUnload;
8 H% H, `0 C( O# c
0 G8 ]8 s- ~+ P% y) O  //2 f& ~3 y1 s  Y, {  {; Y, ^
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
, \, g. l- l0 c" B+ A) d; p! M  //
; H8 I) ?3 o  `1 N5 I) l. i* O  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
! S2 M$ K8 K+ x4 i  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
  i. U! {$ h, }7 k7 Y+ r: d4 R  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
0 {/ A6 ~5 s- H% B& x3 Y! U! [" m  // USB 键盘设备来进行挂接
* S. N$ a4 n8 f/ V1 t3 H  //
* N' f2 ~( A/ T- R2 @( Z( Q  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
5 m+ t$ L0 {( x% W8 ]  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL ); X3 n" E4 w6 r( g; h
  {
! `$ B4 l4 k) b    //
; I5 t/ M2 o) `* i7 T! \  ?    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名# O" l8 B! H- v3 A) x
    // 所以这里打印为空
: r) x$ M# {: l, G1 Z" b$ d    //
; L3 J# S8 d! \2 h2 q7 z2 w    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
6 ^# o& {" a! p0 f    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );& E* J$ d7 g( D

: a5 y6 Z& H3 m7 u& v. M; X    //9 O0 y1 N; H$ u6 k- l7 U
    // 挂接 USB 键盘设备
2 p: r/ L5 i" x: y    //
6 [! G5 r! _" K  Z1 c$ t: a1 V    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );; i4 A* f% f% R4 j! N! j2 F
    if ( !NT_SUCCESS( ntStatus ) )6 h5 |" b# L" i& _( X: B5 s! Y
    {
" B7 ^" p6 T) T; S5 ]      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
8 g2 Z, g- Q/ R& D; H+ _  d0 [3 X      return STATUS_INSUFFICIENT_RESOURCES;+ N2 @+ ^: y: Q4 B/ N8 j
    }4 m5 H* @' {3 \( x
  }7 {4 L, n2 f0 p4 K( {
  else
, {8 B% P/ }) z# ]  {
- T$ p& H" Q. M0 m+ t" L5 g1 V    //3 r. \2 w4 b& V4 Q. p7 c& h2 ?1 i
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
7 m5 y" e6 P5 ^- J+ U5 V; i    // 0 G8 o6 O2 X+ k( F4 p! u3 A2 ]
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); - b( c( d  t# A8 h1 A
0 z9 G: k3 I* j" |# z7 y
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,8 s) D- l+ [: Y
                                        KeyDriverObject,
  h/ V" q: e- ?/ X5 E" B1 K+ X                                        &KeyDriver );, q/ |4 Z. d) J2 q
    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )) Q$ @* ]0 H! M' C! g8 b5 Q
    {. K1 _4 W- o/ G; W* w
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );6 X3 j5 o. Q! n( Q
      return STATUS_INSUFFICIENT_RESOURCES;
% W0 z# V) q* w    }
; G  U; U$ D& _* `  }# r$ Y: E# K- `% X8 F" i$ f2 d, c

! j1 f+ T& \6 h0 _; ~* s  //  l; T5 Y$ X  H8 {
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止( V4 T4 |  x! A6 e0 e2 J
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
0 T6 E4 y  V% o( ^  //
7 n( s4 }; n9 `0 R7 a  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
9 O: g! y+ j+ `) K9 Q) s4 N7 D5 B6 i; V# i
  return STATUS_SUCCESS;
2 g; M; {" ^" f* z1 m5 z}
6 K% ^6 i& ^6 K* T
$ w  J* B  U: h/////////////////////////////////////////////////////////////////
8 r2 l- E# o1 Q  ^$ X1 Z// 函数类型 : 系统函数5 Q& a9 r+ c/ }' L  N8 E
// 函数模块 : 键盘过滤模块! Q. U6 p' p* Q, h4 t/ L
///////////////////////////////////////////////////////////////// V0 C- U2 q9 Q& t# o0 {
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
% g5 R, C. t& X: s2 c$ \+ v//        卸载键盘过滤驱动1 \& L  ]2 j, R
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上4 S0 m! Q& Z% r* a" S0 ^9 A
//        则需要等待用户按键,以后有待完善9 O3 Y% g6 |' q5 W1 A( h
/////////////////////////////////////////////////////////////////
: {& v6 L- q' @* H, E# w  _// 作者 : sinister# Y: f' s/ _1 D4 x+ D5 U
// 发布版本 : 1.00.00) k" g6 v# a7 O0 Z
// 发布日期 : 2005.12.27
5 o% J# i: Q2 q4 I" h////////////////////////////////////////////////////////////////// m/ [6 S: m6 T+ {! A+ I7 |1 v' ?
// 重   大   修   改   历   史& s2 s8 w" d0 E/ D, I" J7 @' S
////////////////////////////////////////////////////////////////! q$ R9 n1 p1 l) u8 J
// 修改者 :
, [" Q! ?! G9 J- j: h// 修改日期 :1 A, P/ S6 n7 m! Y
// 修改内容 :
" F9 A* l% }- O" h6 X) h: O/////////////////////////////////////////////////////////////////- I* C. w' E- D1 I

3 m# y/ Y  ^" Q" `9 NVOID
5 b; J$ M: ^# ]3 JKeyDriverUnload( PDRIVER_OBJECT KeyDriver )
# i1 c( S% W$ T% G! a) w{( W# `  Y$ d) E$ d* @" Q' \
  PDEVICE_OBJECT KeyFilterDevice ;      
+ B& f/ q! o0 z( f2 h" Z1 f# z9 x  PDEVICE_OBJECT KeyDevice ;/ E- B( k2 @5 a% y# g
  PDEVICE_EXTENSION KeyExtension; 0 S: m. d" v% M3 m/ f! Q& E
  PIRP Irp;. f2 F: X% K3 [4 q& c
  NTSTATUS ntStatus;
. P3 w3 ]" P3 T" ?$ y- p/ ?1 j8 j; {& e2 t* w6 y
  KeyFilterDevice = KeyDriver->DeviceObject;
+ a$ c+ S) v- m% q) @  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
/ k5 u! A/ y. k, c  KeyDevice = KeyExtension->TargetDevice;
3 y/ i  R0 O/ ?# ^7 B" P8 P6 N, Z& {: B; x& p/ u7 e
  IoDetachDevice( KeyDevice ); 6 e, [+ b8 Z& W
9 y+ n% ?2 \6 f, }! C: x
  //: G0 X. p7 F; z& k# z
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
7 g# `% L$ O) A0 {7 U  //( @) j5 }, T4 n# f
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )2 O5 K4 A$ P5 M
  {' K0 _- p# I. f" o
    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )
5 C# f. }/ L: E7 x$ v    {
" Q2 u" @5 d) Q1 M: J      //
$ Q6 a$ ~" Q7 U3 J  |% v      // 成功则直接退出删除键盘过滤设备# K% C6 x) H, b! A: f, L  N/ ~
      //  N2 Z( y5 |1 {. N% U$ t4 ~5 P
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
' K/ c6 o1 M$ s) H" Z" h: [      goto __End;" @2 I" @: M" [
    }% b9 g: a6 n- d$ V  z
  }2 Q. w( y. J' ]% U8 s' L

  U, L* S. i) f( o  //
/ S$ I% i& j/ T& {" ~7 y$ W! B  // 如果取消失败,则一直等待按键
, [- S% r" x( K. w& [2 X- P  //: R& M% Y2 L2 J: e/ O4 P. u
  while ( KeyExtension->IrpsInProgress > 0 )# _$ H+ o8 Z- X9 K1 e) A: w
  {! C, k$ ^$ D: |  c) a* m
    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
$ \  Y$ _( Z1 _8 T/ v! f' X' M  }
5 n+ E  V( e5 [' z- z1 z) c3 v) O
1 ~) M) d- D5 e% ^+ f0 h- F, D( [  __End:6 |3 C4 O+ {, K
  IoDeleteDevice( KeyFilterDevice );
$ B6 r* r! {8 ?9 h& m' x, A  X; \( X9 J' ~1 R
  return ;
3 g5 r& A6 P: V}
0 K% E( B6 O6 g6 \+ f
7 d1 A4 }& i! k" y; N- c+ ~6 a- w/ [3 m/////////////////////////////////////////////////////////////////# g) i( N9 B: o; q+ G9 S
// 函数类型 : 自定义工具函数
6 q$ B6 {7 C, n0 o' e// 函数模块 : 键盘过滤模块
, g) g) D! g% b* U" Q/////////////////////////////////////////////////////////////////
: F. R/ `6 y/ p- G// 功能 : 取消 IRP 操作& x: O( E9 c0 r# l( E8 l) i0 q
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
. Z7 W; g/ c2 A+ @) M+ H& l//        使用此方法来取消 IRP
2 h; j; w1 N  t2 O2 V- a/ v9 S/////////////////////////////////////////////////////////////////
* T' N8 d  `, e+ }, p% {// 作者 : sinister
* I+ [9 G. [" P& Z, v2 z// 发布版本 : 1.00.00
, }9 d2 ?2 q5 j# C$ ?+ r// 发布日期 : 2007.02.20
% B, [/ d3 c1 m0 S- M) l; C/////////////////////////////////////////////////////////////////9 n; A0 b& n& b0 w
// 重   大   修   改   历   史
! E7 h4 @& U; p& f7 M2 O8 v/////////////////////////////////////////////////////////////////1 F* Y$ m5 o7 c5 O$ h
// 修改者 : * D8 j3 A1 ^4 @
// 修改日期 :
4 K( d$ c5 [, \; }& n" n/ w// 修改内容 :
+ y% }/ e* F( m: g( n% C  N/////////////////////////////////////////////////////////////////
7 K; D1 U4 z) T. G  }' C9 V# S1 V% n- p$ {3 t3 _0 F- y3 M
BOOLEAN
. e3 V; V- c, p+ KCancelKeyboardIrp( IN PIRP Irp ); u7 ?( M/ ^/ U% n
{
; i- `/ e0 a, \' z! j  if ( Irp == NULL )- n0 [4 ^- l  o0 m& C$ r) U
  {
1 F2 g/ X6 z# N1 f" e) H, @    DbgPrint( "CancelKeyboardIrp: Irp error\n" );: d$ b' Z8 k$ P
    return FALSE;5 z) a# p% U& c' h- v% M3 B: U
  }& G7 \4 c2 D7 J% Y# b) H  Q- Y
" h  K0 X6 }. U& c( a/ J% d& Y
# P, s' _% c  }# r3 E8 V% _
  //
# [* Z/ q6 v' }" c5 h  `+ g/ L  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,. Y$ T8 Y- {/ Q+ ?
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。' |# P0 y0 g. {* ~( m! y$ }
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
5 W* D5 W* t( U; F- U  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
+ C! J3 @) ^. V7 M  //- i3 Y+ {7 P$ s& G, u0 t
! N# [, k2 m! r: }. T3 P; S9 F
  //
6 b5 {- V  l. L6 \. a* u$ c. j6 T  // 如果正在取消或没有取消例程则直接返回 FALSE; p4 b# L' W* ~9 s
  //
6 Y; {5 S6 w) h  if ( Irp->Cancel || Irp->CancelRoutine == NULL )! ^( _! T( I/ R! I" V
  {
0 c7 a: c% r* P1 _1 ~    DbgPrint( "Can't Cancel the irp\n" );
1 x- e  N: y! I) X) p: k2 J    return FALSE;. o, T' I9 \  w5 K8 t: X
  }( V4 V  z; ^0 M. ~! R; j: a$ ?$ ^

: N- i& c1 e. y( ~  if ( FALSE == IoCancelIrp( Irp ) )' J( W+ f6 C. o6 V( q+ P
  {' L0 B2 M" P7 {/ y! y8 l+ p- T! P
    DbgPrint( "IoCancelIrp() to failed\n" );1 t  n8 D( \: ?1 ^4 @
    return FALSE;* p/ C! c3 R" J4 D! h" K
  }
5 R. W( @- X+ Z- I5 r( c+ Z, f9 K; @; D$ ]( I7 v7 v7 @
  //+ p. b, K! K: I) D
  // 取消后重设此例程为空
2 ~5 P' O% p9 D2 a" {  //" Z6 A5 E4 n! E# T: C
  IoSetCancelRoutine( Irp, NULL );0 ?1 v0 {  U1 x$ d
. `& t9 L. Q# @9 ~  q1 W6 }. h
  return TRUE;& z" S+ o3 V  O- M( u7 M" r
}
0 u/ E5 g- L/ [5 U' l
0 T( W6 O$ v) w# o7 B/ \: N/////////////////////////////////////////////////////////////////
* k  b4 ^& Z9 M2 t* W// 函数类型 : 自定义工具函数+ J; o% C# f/ I( |( h& Q7 L
// 函数模块 : 设备栈信息模块
6 x2 _1 i3 K( X8 Q% L5 y; Z" e, ?/////////////////////////////////////////////////////////////////6 g" [$ X6 S; g- v# Z% ]
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
( f" t1 t7 n& e6 m5 d//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver), d: h2 U8 w& t( A3 i8 r
// 注意 : 1 W, _9 H- {+ S# A* k- U
/////////////////////////////////////////////////////////////////: {9 x' w% U# u; W
// 作者 : sinister0 ~) C2 J3 _, @8 _, G
// 发布版本 : 1.00.00
: Q# O  V& i  G( C2 }8 R; G2 S// 发布日期 : 2005.06.02! k8 O2 b+ \% U' ?( z
/////////////////////////////////////////////////////////////////; Y9 Z3 ?  m& B* C
// 重   大   修   改   历   史
$ `9 x$ ?0 w! b" \8 ?2 K/////////////////////////////////////////////////////////////////6 f  M7 a- z% ^" G1 c; N
// 修改者 : sinister
" Z# \: [! T" l// 修改日期 : 2007.2.12
0 C. x" N, U: S6 `// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改; G8 B- m) B( c5 q5 o3 C- c
/////////////////////////////////////////////////////////////////- A; Y0 Q! K* q, D. _
4 S' s5 h, S  [+ a$ a8 A
BOOLEAN+ k- o+ j1 `1 k" f: [# [+ @
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )' F4 y. U+ D8 B0 A" j3 G" W
{9 m6 x8 A' ?  b4 z% L! {7 c3 q
  PDEVICE_OBJECT DeviceObject;
  C0 B3 [4 C# k6 E1 p0 S$ j8 @0 v  BOOLEAN bFound = FALSE;
" x2 u4 e& {2 b: p1 h4 Q/ n( I) N4 p! i' I
  if ( DevObj == NULL )/ L" ~4 u% L7 B# {9 K, F, m# ?
  {
  J, ]% z. D6 q, u4 C3 S* P    DbgPrint( "DevObj is NULL!\n" );: E0 |  K* W! x9 Y6 e( w! L
    return FALSE;1 l4 G2 G. B% c" v# C: o" q
  }
5 n) P" U  w1 u+ W2 d  Q
0 y# J& Y* y  F" W' _% M  DeviceObject = DevObj->AttachedDevice;
, _9 T( G. K( B& b* U6 b
( n9 r( w0 o8 {+ @; s9 y2 J  while ( DeviceObject )( b$ g( l: f2 y- d6 r, k; T
  {
* D. ?5 [, I# s8 K' A  i1 ?    //
9 L5 m% ^* S0 |% u6 S. n- G( R    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但3 V; C0 a) Y4 ?1 q$ [$ L: M; J
    // 有一次足够了。这算是经验之谈
3 U# o& a% V5 ]    //
4 _' |: }; l/ _+ [% U+ L* a2 H    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )4 y! h& L' W) F& X. e$ f9 F
    {* S) K& F% _9 ?( U/ I, g( o# L
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
: k' n% ~9 |' g' `4 R) H                DeviceObject->DriverObject->DriverName.Buffer,! r7 {/ Q$ t7 A) K" `6 P0 ~2 Z* J
                DeviceObject->DriverObject,  e1 _) p! @) G% {/ o
                DeviceObject );# c0 H5 T& |2 f- a0 e

. E0 ~$ R2 n/ P" ^7 a, s      /// @6 J+ o1 J% x, g. X! I
      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
7 V, ^2 W# ^2 K1 I7 E. m      //# {' u% v1 [& Q+ S6 a) C
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
, q! k% G& ?' t* B                      KDBDEVICENAME,' D7 o9 ~7 |' d. W( |
                      wcslen( KDBDEVICENAME ) ) == 0 )5 K9 l' J( s/ U: o- p
      {9 h7 W, Y& T8 l* {  q- w. C$ N
        DbgPrint( "Found kbdhid Device\n" );! \) L6 ~4 p( h3 m
        bFound = TRUE;! T, j5 d8 Y6 |5 ~: e0 x' f: K3 L
        break;3 J, i8 p" |8 N5 K
      }4 ~5 g* z& {3 i7 W3 i6 H
    }0 K9 y) S. \6 v5 p# I0 J4 C
, r% t8 u# G$ b( |8 X, M) v
    DeviceObject = DeviceObject->AttachedDevice;
3 u0 g# I2 |: I# J  }
& e, U; R8 i& r8 `. K# G" A, j; u  X, B* i% D
  return bFound;, A( T3 L7 D9 c8 g
}
. g. a' W; n% S! X! ^' t7 v; J
$ X, _- U" H! n/////////////////////////////////////////////////////////////////
4 v, g% N7 r4 l// 函数类型 : 自定义工具函数
+ L9 h2 `0 E! B" P* a, Y$ C4 s9 N// 函数模块 : 设备栈信息模块
3 S% }! a" v5 f8 C, F* T/////////////////////////////////////////////////////////////////2 ]. ~+ F, i8 \# |
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址) ]( U- s, Z) ~: \: q
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改* H5 o2 \: ^" _) e; U  U
/////////////////////////////////////////////////////////////////
9 B4 ~0 {0 g2 `! d6 L% V) A// 作者 : sinister
+ l! ]) {9 E9 g: E9 \// 发布版本 : 1.00.00  k* ^8 d; {* B
// 发布日期 : 2006.05.02
1 b8 _2 T% e+ }9 D; p8 v/////////////////////////////////////////////////////////////////
; g& }+ S9 `, P- G6 B- @// 重   大   修   改   历   史
5 }( O! U2 W+ p/////////////////////////////////////////////////////////////////8 `! }1 w0 M+ L# l2 k' R
// 修改者 : sinister
% d* E7 ]( J- S, L// 修改日期 : 2007.2.12
1 P) ^  s9 K2 w2 n: j// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
1 s9 x" z% j+ h; v! p" m- Q/////////////////////////////////////////////////////////////////5 L7 `8 l$ |2 a$ f% _8 U3 @

0 ?* Z( D9 k1 F& _VOID
! u2 B% \9 @8 qGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
  U6 e5 B0 P: R0 Q1 K{$ D& t; k6 U) _0 s4 I# Z
  POBJECT_HEADER ObjectHeader;
2 o& L+ }1 [% f% W: S  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
( k% o' G  ^) s( V& K: _6 l* e1 }9 s' ?- {( I9 a: Z! N
  if ( DevObj == NULL )4 a0 K) d1 S6 t& O" o+ ?. u5 N- F
  {  B) o5 `' k) B$ c
    DbgPrint( "DevObj is NULL!\n" );. k- M" h: V# N
    return;
7 E& B3 H3 w& N& v  }$ A. H3 s7 L) W& V6 t& A
- `! y. v6 H$ h" T2 H
  /// h, u- O+ B7 I7 r& k. p' t4 S
  // 得到对象头: D6 k* L; O. k) F4 ^
  //4 a: ~& Z0 G" h, W7 |
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );. O7 N( y* A! J5 a/ B

/ c; Z# h& r% v  |3 l  if ( ObjectHeader )* |4 u6 a+ Y$ F- C8 a
  {
+ |/ v6 g) v5 ?! G" b! r. m. Q    //$ u! L0 y$ F# N, }
    // 查询设备名称并打印
3 E7 X* y' K  T6 _6 U( A8 ?    //3 o' ^, h6 d& Z; ~" \
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
& V% f( I% M6 m" A: Q9 h2 k
: ]6 G$ [2 n$ ~' o9 ?/ m+ `    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
5 R  q9 N0 X7 X$ Z    {& G; J6 {1 u5 h4 A
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
5 i  r2 A& Y" R% R; ^                ObjectNameInfo->Name.Buffer,& u% V! _" T* I
                DevObj );+ o2 e. F5 w: Z0 }5 _% G9 P
) o2 J( x- |! S1 z1 D6 c2 k
      //8 j8 D5 A: H: n
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
' c. r) W: U0 b( N" F) p0 K" @+ V2 \      // 用,没有实际的功能用途" j  n5 |) m1 r
      //( {  [& P9 N. v  d
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );. N3 K! J8 `% \$ u' L7 A" \, c

7 T7 s! C7 i. y0 W+ `$ A5 ]/ N4 h      wcsncpy( szUsbDeviceName,
9 X+ q. @  c* r+ Q, ?: h               ObjectNameInfo->Name.Buffer,
' T* h* g8 j+ Z. P               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
( W7 O4 u% ^& s' \2 |: z    }
3 E! h% i. ~0 ^1 _4 z
0 P' C) J3 V; a- e2 s4 L& d    //5 P' }2 o' \$ E4 A
    // 对于没有名称的设备,则打印 NULL3 j& t4 |0 |% G5 B# r) S7 Q# p4 Y
    //, [0 t" g$ T# X" e) w: v
    else if ( DevObj->DriverObject )
" C: R9 U0 ]5 e6 @/ P    {8 @1 J: |6 n8 o* V3 L  }& P
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",7 F9 c" c: U- e4 [5 y
                DevObj->DriverObject->DriverName.Buffer,
5 }$ |' Z* r1 {9 ]0 g                L"NULL",+ E1 V3 M6 O* N; ?) n
                DevObj->DriverObject,: J9 r  D6 x0 A. C& O
                DevObj );
! u( m  \( p/ _; s! Z    }
! {4 k; ]2 {) g" N# a; G  \; R  }. x# c9 f) a1 {' L6 V5 Y4 j+ p5 ]
}
# K7 J# k' u2 d6 d- B' [+ u- y) [5 q) n# X! @8 p* D& p& M
/////////////////////////////////////////////////////////////////
( x$ ^( q! a8 _% Y( n// 函数类型 : 自定义工具函数  H, ]& Z! N3 I5 O; i+ r, Q4 w0 J$ L
// 函数模块 : 键盘过滤模块& l; T! Y( K  q- Z0 w. O7 l! `
/////////////////////////////////////////////////////////////////" X+ [/ x. P' _# G1 I4 a6 Q% W
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
1 r2 K4 y; o, Q( t: }( U//        对象,过滤出 USB 键盘设备,将其设备对象返回
) w5 W5 e1 g+ s& q7 e' K// 注意 :
9 \; @1 k3 s7 I% o, w8 u/////////////////////////////////////////////////////////////////
1 g+ y0 X/ S) a1 ~// 作者 : sinister: r. {3 s0 @. ]& w5 w. l- {) F$ I6 Z
// 发布版本 : 1.00.00
, y( W5 {9 L3 E  m// 发布日期 : 2007.02.135 a/ O) e- l" r$ Y& ?3 {( E
/////////////////////////////////////////////////////////////////
. J+ `" c5 E0 L; M" \; J// 重   大   修   改   历   史& }3 N# q- R; o" A. }3 F( h; _
/////////////////////////////////////////////////////////////////
  D" j1 p* M2 p) f* F$ v// 修改者 : 1 s2 N. B2 ^3 h0 e  f7 Q5 y
// 修改日期 : & ]0 h  W1 m3 K
// 修改内容 :
+ d2 C- g/ D- c, M2 s/////////////////////////////////////////////////////////////////$ l7 `8 O, X& i
# k  @, {8 D0 J' [6 n: T: m
NTSTATUS* A' T! e* R& M: u9 _
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
1 |4 p8 {+ Q  i7 R2 F9 e+ i{
+ o4 a9 c/ c: ?5 w3 c9 g. w& ?  UNICODE_STRING DriverName;
! h, ^, e! m) h. _  PDRIVER_OBJECT DriverObject = NULL;
5 v9 p* g6 y  ]4 F) @  PDEVICE_OBJECT DeviceObject = NULL;
# S# |) n! ?7 h  BOOLEAN bFound = FALSE;% C2 [2 E3 ^0 D1 p& A5 [+ {

1 Q$ V7 `, S( O  v9 p0 P  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
# N, c( I# m+ s9 p5 K; [/ H. E: m- n
  ObReferenceObjectByName( &DriverName,- E1 U: {: Q1 A2 F: a  ?" B
                           OBJ_CASE_INSENSITIVE,- s. Y4 @& ]+ C$ u
                           NULL,
5 v: X7 p8 O' f0 u" G& k0 a                           0,
8 e9 `. s  q. \6 E6 `3 S) g                           ( POBJECT_TYPE ) IoDriverObjectType,% L7 K+ _( f$ R5 ~9 i" U
                           KernelMode,* ~$ q$ b; n5 G' V& d0 S1 G
                           NULL,3 y* j* W- g' [0 B" K7 i* Y
                           &DriverObject );
9 y2 C/ U( U6 r! R; Y8 D2 Q7 U2 v* h3 R) p
  if ( DriverObject == NULL )
1 B) D7 ^$ @% }# e, M  {2 w" v3 R  o9 D! D1 x9 X. ^& ]
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
+ y4 D* D: m7 H" n    return STATUS_UNSUCCESSFUL;1 I9 y% u' D% _- Y% \6 N
  }6 o- D" A, }7 x$ \" w. R! z

3 e1 c4 j  F* r6 ^$ D. z  DeviceObject = DriverObject->DeviceObject;
* p0 E" [1 g; V: C0 O. k# r, P
  while ( DeviceObject )
" F  h9 k/ t2 I3 e7 g) L; w. @3 W  ]  {7 l2 i4 H. E5 D; W4 ^
    GetDeviceObjectInfo( DeviceObject );
" x6 y4 K% z) O% n% C3 E, p; z" B7 P
    if ( DeviceObject->AttachedDevice )
$ o, ~- t" |3 S7 z2 `    {
: \- y+ [  V0 A# \      //* P7 c, h4 @, h' c
      // 查找 USB 键盘设备
, y: r3 I) M5 D0 W/ M/ v1 g! F4 [$ A      //" H  `. i1 u! y  k
      if ( GetAttachedDeviceInfo( DeviceObject ) )
4 H5 e# k; ]. p0 t% j      {
; Y3 r( F" i8 d6 t        bFound = TRUE;5 A# v6 I, y5 B/ ^6 q9 z, l
        goto __End;  U# n/ S# `- K* `% x9 M
      }
) H( a! e0 m# g    }, Z8 ~) c4 w% f- o

* r8 w( L; o4 O/ P( K# {9 J4 e0 r0 M    DeviceObject = DeviceObject->NextDevice;" O8 L( q. Q9 w: ?  }( r, v: i
  }
+ u9 ^- U$ E: _* y
2 p3 k, y, T; |" A4 g  __End:* A) E# W4 X1 s7 k% \7 n; }

" W4 z3 W2 ?2 p* \* N( Z  if ( bFound )
7 C" f9 @  @. z  {
+ Y8 s8 S! _3 y8 [    //! O" n8 q+ k) ?: }$ ?
    // 找到则返回 USB 键盘设备对象' G; z8 z' t- ?
    //. E8 s: y5 ^. ~- l+ a$ G# Y% q
    *UsbDeviceObject = DeviceObject;
7 `- w7 s% J8 Q  }
- R; j- E, A/ P* A& M5 Y9 S  else
: s0 p* `: l7 s7 v3 t) g6 _  m  {3 T+ ]7 M. z: G5 T2 X8 R2 `7 W
    *UsbDeviceObject = NULL;
. T2 M; Y# b: d4 Y( B! Q9 M  \  }# H1 ^6 [$ c8 x$ G6 ?" n

* |5 D6 X6 r9 X6 R/ V  return STATUS_SUCCESS;
- I3 V* v/ t" ?! ~8 H' J  E% O}
. W" n0 J& Y5 M4 t2 b3 T: q2 Z- T/ Q+ D+ t: [, a4 F
/////////////////////////////////////////////////////////////////
8 g4 k1 t9 P8 z1 j// 函数类型 : 自定义工具函数
6 H$ W* S$ [9 `8 W// 函数模块 : 键盘过滤模块
, `8 w. D9 U9 {" {, A0 j////////////////////////////////////////////////////////////////
- k+ [8 ?" u8 B( ?// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
$ o" L: z0 o6 V; R* I& y0 w" V//        信息,返回附加后的驱动对象
+ z# ~  {6 T) Y# \( b- d6 O// 注意 : 此函数仅挂接 USB 键盘设备0 ~3 ^! n4 b$ \5 `3 Q
/////////////////////////////////////////////////////////////////
7 Z2 D3 S" V+ Q// 作者 : sinister! M3 c: r, [, J4 k3 E
// 发布版本 : 1.00.004 z2 M  [1 H6 f! q; V+ {
// 发布日期 : 2005.12.27
! ?, V/ d5 k1 n. z/////////////////////////////////////////////////////////////////( [$ P+ O; A2 ?. X: x0 g) _, |* ?* K
// 重   大   修   改   历   史
, |2 M2 ^% }8 n% J2 }////////////////////////////////////////////////////////////////
( i- s- s$ W6 I; u// 修改者 :
9 X1 }  u& R1 ]$ U% M( @% ]// 修改日期 :
8 a) V  L# T$ a7 \5 n2 N// 修改内容 :
$ u3 Q9 s* h5 L4 l0 N7 b/////////////////////////////////////////////////////////////////
3 W% G( [3 S  ~5 B- P# z1 I- ^
$ j; L: J2 s3 m( `3 a1 T6 S7 v( kNTSTATUS  j/ N- s1 k" n" a# [( Y6 x
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,7 G/ W. N% _4 m9 e8 D
                         IN PDRIVER_OBJECT  DriverObject )
5 p& H" N9 f% c3 S7 O" O4 _{
! T1 @6 e0 P* U% v& b2 G  PDEVICE_OBJECT DeviceObject;
4 C, x, c% o+ ^* h. L% X: V  PDEVICE_OBJECT TargetDevice; ( k# }% n# Z$ e. j) n: N
  PDEVICE_EXTENSION DevExt;6 J5 T  F: P( r5 F6 U
  NTSTATUS ntStatus;
, \  p  M9 R9 O& a0 |) P) B9 @
& i+ G" j2 p0 Z  //
, J/ m5 {! l9 q  // 创建过滤设备对象
. u& a4 b, C. W2 N" s  //
% {  B9 c* s: l& s3 C  ntStatus = IoCreateDevice( DriverObject,
3 q% @0 X7 G7 C- S/ O, U* ^                             sizeof( DEVICE_EXTENSION ),1 }1 X: F# Q9 Y6 f8 l
                             NULL,0 a% V* w+ i/ g! ^
                             FILE_DEVICE_UNKNOWN,
, C' D. \) w" g; C8 E* Q& H5 [9 e                             0,- E( u0 S3 k4 P" d  d* K
                             FALSE,
9 R$ N+ \. P- Z; F" G                             &DeviceObject ); 5 C( x1 q. \8 `$ n+ ^5 z+ j  ]
+ q% q; Q0 i! {3 V* [4 F6 o. P1 Q. k
  if ( !NT_SUCCESS( ntStatus ) )2 l% p% w+ V0 O& {: T6 j# _. j
  {
' y% `) R4 H- N: D6 t% K* X  X    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );; }* }8 |' o8 _' e6 p/ L' r
    return ntStatus;2 P) V4 Y* V5 i+ {- @- O
  }
" g3 _1 G( T5 R
1 F3 D- G% O2 R  S% c) N  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
2 s  s/ f6 w5 B" x6 K1 R1 f3 C2 S$ V* H$ C; c
  //
0 }2 Z2 B- F9 u( Z  // 初始化自旋锁5 t, I- [' u6 v, l
  //3 \- ]+ k& ~) a, o
  KeInitializeSpinLock( &DevExt->SpinLock );% R7 [5 v. v) \9 r0 B, q

/ d# M  L, Y, L- Q% T& g0 @, r( F  //
- [3 W) f0 G1 y3 n% s  // 初始化 IRP 计数器
1 _2 [. o6 E7 R( ?  //, @; I; T9 B9 u: n9 s; V
  DevExt->IrpsInProgress = 0;
! ^1 B3 N" z1 R! W/ a7 @5 T
" x, m+ e. K7 s8 ~8 U  //
) k7 }6 V; N! P& a  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
: N9 H, |/ ^' g; c8 G. [. R  //- Z  i- h0 G; O  l
) H; V' @5 C) k+ }! b2 @) D
  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 3 r0 k- l) W. R3 ^$ c
  if ( !TargetDevice )
6 P& M" F, ^1 w) Z/ D3 f, I$ d  {
# s( v, y* W/ E6 n  [  k    IoDeleteDevice( DeviceObject );
* V$ @' k5 L" C7 X    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
$ Z5 b; v0 |8 T3 a- E# v    return STATUS_INSUFFICIENT_RESOURCES;
! }4 P$ Y& E/ r4 x  }
$ M9 h6 }$ W$ s  n: ]! S
/ W5 E* i% r5 E9 Z. ?  //
9 n9 L8 Q" O! U. P5 w, y" D0 k  // 保存过滤设备信息
, C& j- y. ?+ ^7 T; ]  //
3 p% S. i6 w2 t6 ?( {  DevExt->DeviceObject = DeviceObject;
# y( C% T8 z8 U+ z  s* z# M  DevExt->TargetDevice = TargetDevice;
0 T6 C9 ~: J. Q8 ~  v( v# d( q; W# R# Y/ z2 y, ^' m0 ~- h
  //0 G  D" W7 l5 e2 F% H( u
  // 设置过滤设备相关信息与标志+ }3 C+ \) |/ k4 Y( U
  //2 J5 u' r% k# p) `$ m6 q
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
9 i3 y1 x" v9 c; H  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
3 g. F9 U  ~8 u- G6 U
2 {3 K" R- W* S% J  c) ]" n  o
  [0 t% }0 D! K& W) C/ S$ g+ C  return STATUS_SUCCESS;$ A6 P6 r( g0 A3 d6 @
}
1 l8 N5 ?' k9 P9 H8 V0 Q4 A  j, t& a' ]1 W+ L: ]
/////////////////////////////////////////////////////////////////! e! {( M4 P7 k3 |$ a# W
// 函数类型 : 自定义工具函数+ O# F; f0 T, \
// 函数模块 : 键盘过滤模块
. |( X  p1 u8 ^: @5 z* ?$ B////////////////////////////////////////////////////////////////- q7 w5 ^9 J6 S4 x4 v  S
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
- h, v$ Q! Q6 j" _2 h//        信息,返回附加后的驱动对象
7 a, D3 F& u( W9 A// 注意 : 此函数仅挂接 PS/2 键盘设备
- _( F, P5 h* T/ [- r8 Q) d/////////////////////////////////////////////////////////////////
7 v0 }( C- n% z9 j// 作者 : sinister
0 f1 S% E+ }1 L' V0 h! L# f// 发布版本 : 1.00.00
5 ?, g$ a7 `' \- [, J5 @2 ]// 发布日期 : 2005.12.27% m1 A% D  l9 y+ f& X
/////////////////////////////////////////////////////////////////) u1 _. Y  C* u3 z( C8 b9 Q; V& L, J
// 重   大   修   改   历   史
, h2 r4 S# M+ H& _7 l0 X- @- d////////////////////////////////////////////////////////////////
7 ~( `; i- o  ^// 修改者 :
9 [% X% z* @/ X- I" B( E1 _4 y6 M// 修改日期 :
( `% e7 B  {! h: l+ V2 z4 r// 修改内容 :
. j) }# S; q$ U' D/////////////////////////////////////////////////////////////////3 r4 c, x$ r9 E. b
8 x7 J' m$ D- e6 f8 w; a- c! T
NTSTATUS# c2 i) n- ~% C( N0 J( v
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名' [+ H& s( V+ n, m# l: l
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象# T9 _5 ^5 c2 t( n" G/ {
                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象
% W4 s  V+ B* M: h8 y& N7 P( K; e{  {0 v7 y6 o( V* |! X& e
  PDEVICE_OBJECT DeviceObject;
5 I& ~, ~! w7 P0 ^+ k  PDEVICE_OBJECT FilterDeviceObject;
% b7 u& A! F2 V- H. l* ?* R' z  PDEVICE_OBJECT TargetDevice; 8 |: }; h9 ~. e+ H9 O9 D, S, a2 v% C
  PFILE_OBJECT FileObject;
# l8 t/ @) \) O  PDEVICE_EXTENSION DevExt;& C2 V2 G) G6 W1 T; [4 [

1 J- q) i4 D" m  NTSTATUS ntStatus; 1 h0 v% |% c+ S/ m3 Y) [! N% o5 J% b
7 n# V  l- `/ J) x+ I- u; h
  //9 Z8 t, M2 N" V8 B) @
  // 根据设备名称找到需要附加的设备对象# B% d4 m" Q6 s8 Z
  //
1 }5 P* r0 v; J  ntStatus = IoGetDeviceObjectPointer( DeviceName,
" z- x/ G5 F" @1 q% O$ }# V                                       FILE_ALL_ACCESS,+ _/ g! r' c  g5 f
                                       &FileObject,
3 N% m5 ~- a+ d, Y                                       &DeviceObject ); + j" N9 [) j, F% q9 U7 z

" ^2 e+ u! S( N9 d  if ( !NT_SUCCESS( ntStatus ) )6 W1 z# ?0 N6 J$ g; E4 S5 S
  {
5 ?/ c6 @7 R  G    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );
/ j( \; H* t9 z7 P    return ntStatus;
$ m! s9 u6 q, h- u  } ) s: P+ D" T. F2 V
+ s4 }& G0 U* ^* O6 p% S
  //
( N( ~7 I/ Y, q- p" I" G: S  // 创建过滤设备对象
9 w0 n( d# R9 f0 E0 q, t% k) B  //
- ?" p1 J; P* z# D' }  ntStatus = IoCreateDevice( DriverObject,
& s: X5 k4 [6 ^; e+ |                             sizeof( DEVICE_EXTENSION ),3 J0 ?2 ?1 w8 Q% ]# E
                             NULL,
% X5 Z. o8 _0 W                             FILE_DEVICE_KEYBOARD,
) @; V" Z3 f5 A9 q4 f3 Y                             0,2 d+ C4 A% g  g. Y3 H: \! A
                             FALSE,
4 U' g& w4 J1 ], [5 ]                             &FilterDeviceObject ); : H7 W% I; o. X% t7 N9 ?: [

# r' M+ _2 c0 f) o  q* }/ e  if ( !NT_SUCCESS( ntStatus ) )4 X0 S8 K$ k: [4 j
  {9 Y# D2 M- [* ]7 _9 ^9 H1 t
    ObDereferenceObject( FileObject ); - _- U7 g$ K" p  W
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
  R$ h1 V3 I0 I; b3 K    return ntStatus;
2 T6 s" c% k7 ]3 |7 ^7 ~  } / J' i+ A6 D7 E/ p; H" I
7 U+ D! F3 q5 f7 j2 J* f
  //
( K  k" v6 h  n' P, |- |  // 得到设备扩展结构,以便下面保存过滤设备信息
1 ^: U# j0 p# g2 X9 G  B+ y5 w# V  /// V6 [7 ^+ g+ ?- D* A
  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;1 m" N, l; u# z! o9 h/ G

8 }9 H6 D2 Z) J2 @2 X) V- a9 B
* l  Q7 u8 c: i0 S/ e% P  //
2 W6 |) T# }; ^# E, h- y  q  // 初始化自旋锁
; K; ~4 ^6 U2 e) u  //% i, ~( c' u- r$ P7 ~8 z* C
  KeInitializeSpinLock( &DevExt->SpinLock );
. T6 K/ c1 ]: Y4 m" X. c' v& d% Q4 \+ i
  //
* y* H6 I8 w! P  // 初始化 IRP 计数器, y3 h/ ]* v6 u. C* e
  //
5 {/ }. n) p4 C" H8 V  DevExt->IrpsInProgress = 0;' a! |- P: q& {) X# i0 x7 N

, \! i2 g6 u' V% \/ o3 O4 L  //
) o1 _$ k% c9 I7 t' K2 t5 y  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象- v* M. d' a2 E. {, j( H) y& P% d
  //+ \3 ~* a8 u: o4 E2 |
  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,* \. ?* c, n: u1 u/ u
                                              DeviceObject );
: N% |! u; y) i; N  if ( !TargetDevice )7 s+ J( d6 O$ h: S5 {2 s4 n
  {
$ j0 e' H+ E0 Q2 J5 t- K" t2 i    ObDereferenceObject( FileObject );
2 D# ^2 }4 V* H  {: U$ D, B    IoDeleteDevice( FilterDeviceObject );
8 n% [' T, ^$ H, g/ p) s$ X    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );4 k# b6 k) {- d& Y& l( N% t# M7 z
    return STATUS_INSUFFICIENT_RESOURCES;
- S7 I4 \4 u3 M9 z' h. i  }
6 B, c0 W  e: V( {2 {6 H9 u9 `7 E5 R
8 K3 x# P& V) ~. m  //
& [0 ~' ]* ~* w# P$ H8 @  // 保存过滤设备信息
$ r' J" y8 c6 @  //- j$ K8 s7 W: m3 |. K% }
  DevExt->DeviceObject = FilterDeviceObject;
/ P0 v, U, l/ x  DevExt->TargetDevice = TargetDevice;
" z5 {& K6 ?( @1 @1 W: ~  DevExt->pFilterFileObject = FileObject;* K/ ?' l* C0 G! t6 e7 R7 J+ ~' b4 ]

' V/ S# H: a! D/ |) k  //
8 t: ]% H1 b4 n- z5 [9 F$ B. p/ q  // 设置过滤设备相关信息与标志. ]7 A: o! U7 r7 D. e; O
  //( ]3 a$ `9 E' W( |) }. u. f
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType; ' A' p" T0 e, Y, I
  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
. n3 Z7 X- N8 ~3 j3 M& V  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;* C) A0 E* M# b# K* i+ }/ |
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
) l9 ^% q4 K- d6 u                                                         DO_BUFFERED_IO ) ); : c8 N2 ?2 W8 Y/ H" q

( F" G$ f) i7 a; F2 ]1 \$ P/ W2 C  //* a. `% Z' [) W$ d/ D3 M- \# Y
  // 返回附加后的驱动对象7 B$ }6 O- y! V5 o* h( k
  //+ Y( ^9 t* Z: z. z2 a5 Z: E
  *FilterDriverObject = TargetDevice->DriverObject;
1 n3 n2 g7 j7 J" \! D
. t0 N9 t0 ?! A' Q  ObDereferenceObject( FileObject ); 3 O, r8 |) @/ n8 s4 D+ E0 m

4 j5 h+ G- |; ^& }: P, f% K  return STATUS_SUCCESS;4 j! a! |7 U1 E6 w8 T$ [9 G
}9 R$ F$ w4 e$ Z7 M( y" [
  Q$ G% @& C; D- S: U6 |3 ~
/////////////////////////////////////////////////////////////////
1 x2 h1 Z( F8 d7 }3 [$ [1 h& E// 函数类型 : 自定义工具函数
0 E! ^  `  \! H$ s& e// 函数模块 : 键盘过滤模块
7 z' [1 I4 a1 {2 S2 g$ d; g* x, e# |& }////////////////////////////////////////////////////////////////
1 H2 d; F, u# f# r// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
0 O3 a0 s+ r0 L0 U//        这个 IRP 的完成
+ |* [# \9 h1 ^  h; f3 r8 k4 A5 X$ d// 注意 : 8 ^& h1 E* g; [2 a9 r- b
/////////////////////////////////////////////////////////////////
3 G3 x) {$ H( Q// 作者 : sinister
6 l# g6 l& u* j* q// 发布版本 : 1.00.00
* d' D4 Q) \/ G) ?% H5 q3 \8 v// 发布日期 : 2007.2.15
) h( I6 V, b4 T& q' f4 v/////////////////////////////////////////////////////////////////5 ]: W) ]" E) \. U* D/ w
// 重   大   修   改   历   史: t& t" c- h6 }6 X
////////////////////////////////////////////////////////////////
7 Z( a7 m) C3 d# E// 修改者 :
$ |% N8 T! t/ }4 d; i" f( E4 Y$ v) @// 修改日期 :/ r  }; J3 {! }/ Y2 @2 ]) a3 ]
// 修改内容 :
/ h* ?4 L# c- u! q7 F/////////////////////////////////////////////////////////////////
1 t; _8 z& Z1 {6 Y' r9 U7 l1 p( C) j4 n0 @: O8 Q1 G1 _
NTSTATUS4 D* X6 C0 k, y* o8 v7 Y
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
; n1 m: m% z9 Q+ g$ P' Q# G{  {8 ^# ^+ n4 X* ]8 o6 Q& j  {: g
  NTSTATUS status; 3 D& \* A2 J6 M) b) `8 H
  KIRQL IrqLevel;
% C3 _9 U# G# y
' H( d7 U+ e8 o1 J  PDEVICE_OBJECT pDeviceObject;5 P& e! i6 \7 E, r, E% C
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
/ W6 R% M2 K3 \* J- |                                   DeviceObject->DeviceExtension;
( \& j4 Q. x# p7 h2 L+ \- _7 v% N! o2 p, o! o" p7 m% v5 U% ^# F) |
' @4 d0 v7 c$ l8 @: F/ `9 t
  IoCopyCurrentIrpStackLocationToNext( Irp );
( F6 x0 \( [. T; D/ f* R
5 @1 a4 F/ H- o2 V* j  //5 o, Y: w- x% h( e% Q+ h
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁5 N) r% W" L" n, D: }
  //' o9 v# H: y0 f
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
$ A, Q5 `# h$ D. c; |  InterlockedIncrement( &KeyExtension->IrpsInProgress );
6 C' f3 r% `* L* j* C- X2 P' ]  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );# S- Z% a$ r8 c$ T, _/ a. d
) L; Q0 f9 X* j, e! c2 o/ E! X3 d
  IoSetCompletionRoutine( Irp,
6 ?4 G- I, W5 R2 m+ D                          KeyReadCompletion,9 s+ ~, B6 R1 {  m9 H3 c. x
                          DeviceObject,+ J/ G. j2 G6 B9 Z! d; k5 H
                          TRUE,3 I  R! C0 Q" h3 x5 V5 z: @
                          TRUE,- f: z: Y% J& t2 H" T
                          TRUE ); ( T' p' k6 c7 b8 v5 i+ \2 |

0 U6 b7 R3 l; ]  return IoCallDriver( KeyExtension->TargetDevice, Irp );- Q  S4 B/ S& U! ^1 d0 C: X7 `
} ; N) U- i- b4 d' ^1 M' q: ]
& R+ _, O0 B- j3 T
/////////////////////////////////////////////////////////////////
5 R7 B( Z1 l5 t% b9 c. t// 函数类型 :系统回调函数
/ h& ]5 A4 [, a/ c// 函数模块 : 键盘过滤模块. w+ ?+ l1 S7 b. V
////////////////////////////////////////////////////////////////+ h1 I7 r7 N3 ]* @
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
3 f- R! f5 D; A4 T- N& M// 注意 :
, m4 t  R- S* ^  r& V( n1 W  ~% k/////////////////////////////////////////////////////////////////; h; l: q) A. q  e
// 作者 : sinister+ v+ {7 i) f$ e7 q8 e
// 发布版本 : 1.00.00& s5 `6 y0 z* M0 R) V. W
// 发布日期 : 2007.2.123 l0 C0 L( T- ^- u% P# \; V* e
/////////////////////////////////////////////////////////////////* {7 ?; u% V+ f+ n
// 重   大   修   改   历   史7 l  r! C# D6 W$ T- x% h* V' S7 m
////////////////////////////////////////////////////////////////
) J3 Y1 u: P& i+ m7 o7 u/ P// 修改者 :' j# r+ v0 ]9 w* r3 Q% M, g) i
// 修改日期 :
& h6 _5 w5 @+ K% {* V) C// 修改内容 :! U1 Z# g  Y! {6 X* D- b! r
/////////////////////////////////////////////////////////////////
# J' i) Y* l& ~& t8 b
- C) e& C' Y' `" b+ q+ m  A7 S! J- CNTSTATUS7 F) F& ]& I, O7 Q* ]
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
$ P, `6 f9 j: o) e' K                   IN PIRP Irp,+ P. F3 i9 F' R# a# I( w
                   IN PVOID Context )
5 H5 p1 |3 Y$ e& D( i{
) [4 y( D* U, m! @0 P3 H+ \  PIO_STACK_LOCATION IrpSp;
/ W* g# N9 X6 R  U( W) X" z! v  PKEYBOARD_INPUT_DATA KeyData;+ c( y3 m* Z* U& `$ k% A
  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
0 o  ]; u' \3 v' ~# `                                   DeviceObject->DeviceExtension;
/ \9 N6 s3 W& s5 m4 N0 c* _0 x  int numKeys, i;, x) }3 x% I; f7 C* l+ H
  KIRQL IrqLevel;( j$ U6 x: {9 `$ J& o: j: L3 i* f

' v9 ]- R6 C4 C+ J% K9 [  IrpSp = IoGetCurrentIrpStackLocation( Irp );5 N! S1 e1 b7 W: |( Q
& ~% N* `. b+ _
2 t- I; C5 U% y3 w& E
  if ( Irp->IoStatus.Status != STATUS_SUCCESS ). I' o" i$ ^5 r- y  z( J
  {
) M" z3 \' o. y( a/ K    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );0 u: J% A$ @8 f# L9 m5 A- l
    goto __RoutineEnd;  B/ s8 U& u) ?2 f
  }
4 o( G$ G- _4 Z0 B% L* ^0 o, O4 _% S  s# b, ]( o8 K
  //7 X: a7 t4 l$ a" q( D4 X' D
  // 系统在 SystemBuffer 中保存按键信息1 \- e, c; \& d& f* A7 C
  //9 }% N% {: }; b7 }- |2 q, X* v
  KeyData = Irp->AssociatedIrp.SystemBuffer;
  r2 ~$ J; v1 e8 j3 O+ R  B  I2 g  if ( KeyData == NULL )
! u9 r. O1 s' z' n/ H- f, s- g  {  v: k  R8 h: L# J
    DbgPrint( "KeyData is NULL\n" );5 h$ l) o9 W  }: R0 T; @
    goto __RoutineEnd;: O, E9 b7 f4 ^  T2 Z& K
  }
/ c! J% l$ v- d( }. R/ p, \( V% J: t& g7 K
  //
( _2 Y/ I* U8 c- k  // 得到按键数
  x8 x  t4 f& G4 ^6 {* J  //
, h  C# \" y. J$ J- a$ C  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );. r; f0 V8 {" o! a$ ?
  if ( numKeys < 0 )
$ `1 q! z4 X: S5 u  V2 t  {
! `, B: r; V/ f) G9 ?" @! O    DbgPrint( "numKeys less zero\n" );
' `- @( L  }; I/ Q; }: `/ Y    goto __RoutineEnd;% `' ~/ N6 J8 S/ j  ?; F. O4 Y( h# r
  }
, F: J7 `6 `# e3 i0 f$ ^) B5 |+ m5 ?& h
  //. l/ y1 {# }  T3 [+ K( m! `5 f$ T
  // 使用 0 无效扫描码替换,屏蔽所有按键2 i, f  `1 }9 r# U% H
  //
6 s# J3 b7 g# B  for ( i = 0; i < numKeys; i++ )
9 c/ y9 e2 |8 A/ H5 {8 V4 Y( M9 y; V  {
. E+ L/ b3 i% k# u4 _    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
6 |; \7 ~9 n* n! D    KeyData[i].MakeCode = 0x00;
3 N% Z- G9 E  F- j- q  }
* d* p5 j; M% f+ Z2 h: E% W1 @" Y) R8 C: q% U, F  Z  a; Q' T
1 `- q. P$ Q+ }3 K. C; K3 X, d
  __RoutineEnd : . Z* Z( D' n' X9 p) d8 M4 V. }0 S. n
* Y9 t( F' `0 w& }3 [( [
  if ( Irp->PendingReturned )9 O2 M: k, A) Z: F4 S* a) Z+ I
  {+ V6 `' e4 `& R9 ]: }
    IoMarkIrpPending( Irp );
( q; W' T- [, x- s+ S  }
9 A" Y$ r8 ?2 `, q* B9 ]; @& Y5 i& }9 o8 ~5 T9 M
  //9 O' {/ u+ T/ H& P" }/ l2 J" V
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁: f7 p3 w0 v: r; I" M
  //
8 J: ~4 u  b4 u: v  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );" ]' w3 Y6 e' a3 X
  InterlockedDecrement( &KeyExtension->IrpsInProgress );. o; D' z  M6 b3 Z4 A6 z( U5 B
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );- t, `5 h2 @, f
5 h/ z1 n( k+ q2 w' g
  return Irp->IoStatus.Status ;
9 }7 z6 e, u2 ?( D; a, d}
/ J# L+ W9 B: l1 q1 z  S
  j( q0 `7 V: O0 L7 L' C7 A' ]4 g, l+ o4 s
/*****************************************************************
5 u  v; f8 O6 i: F4 G! j/ M 文件名        : WssLockKey.h- t) X+ q8 y$ [0 w# {- l4 w+ R/ ?8 i
描述          : 键盘过滤驱动; w9 [# F2 x5 r& G
作者          : sinister
- X' Z" e: m. a2 Q# { 最后修改日期  : 2007-02-26, }3 ~" {& G. n8 v( X
*****************************************************************/
' f* x0 Q' y6 f! d9 c* I/ c
& S& T$ M( |0 c" d#ifndef __WSS_LOCKKEY_H_
2 R2 n! E: d/ h6 T: z#define __WSS_LOCKKEY_H_7 j) U, d- O1 t8 ]9 \; J

' Z) x4 G9 i# {& j0 z#include "ntddk.h"
; W; g% e+ o( I0 P0 W#include "ntddkbd.h"
9 n8 Q- V5 ]" ~. c7 i#include "string.h"  e/ w' f5 _) j3 X
#include
5 O- s" N  m' L
7 @1 {: [$ ~; C9 [2 u+ n, B' v$ @#define MAXLEN 256# t+ b: \% w% y1 Y8 V% Z3 H; \
) J  B& O# z0 T0 P3 ?
#define KDBDEVICENAME L"\\Driver\\kbdhid"
( u! _  P$ q$ {$ j- I9 _1 J) M( Z#define USBKEYBOARDNAME L"\\Driver\\hidusb" 8 C% R6 f" u+ [: K+ d$ W, L% k
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"- n+ O: g; _  o: w) V' x+ C% d" O, H2 J# U. j
" ?% ~1 c/ Z  A/ ?
typedef struct _OBJECT_CREATE_INFORMATION1 ]) z- W7 B, o& P/ N
{! K/ z1 B+ X* h5 Z* g
    ULONG Attributes;
/ U' G4 x' D0 a1 h0 `    HANDLE RootDirectory;  B% V5 i9 }6 W4 |) `: J
    PVOID ParseContext;
- Q6 ~" v/ |' {- X% K1 b# r$ q6 p    KPROCESSOR_MODE ProbeMode;1 p# x( q3 W; x( x0 Z7 C
    ULONG PagedPoolCharge;! E- n4 b9 z; g# |% u
    ULONG NonPagedPoolCharge;
$ H9 q5 W1 u) ]: m/ J    ULONG SecurityDescriptorCharge;. T9 n9 w$ I) k" J
    PSECURITY_DESCRIPTOR SecurityDescriptor;
1 i6 ^) c9 w- T- l    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
8 P0 r- J& q2 _; `    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;% T! w- P/ }" L
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
1 a" O3 @- d' \( Q3 a2 H% I& l( v  V. I" z
typedef struct _OBJECT_HEADER
3 m& z) ^3 l+ x# L{8 o8 Y; H, b; V. \/ j1 Z
    LONG PointerCount;0 T7 I% |5 m4 m# \' k+ `( {$ g
    union& h* ]5 z$ z' p8 z! C4 X1 t
    {6 V4 T9 T  A: f( [  F8 k- W
        LONG HandleCount;1 y, B; J: [+ n6 m9 `* \
        PSINGLE_LIST_ENTRY SEntry;5 e8 [  X9 C+ J
    };
9 d( A! g9 E1 H7 O2 Y$ E    POBJECT_TYPE Type;
7 Y" [* a4 S* |" g) a9 Z    UCHAR NameInfoOffset;4 R: T- h! I* Q; f4 F) q
    UCHAR HandleInfoOffset;
, h5 r0 G1 _& j2 r" t  r    UCHAR QuotaInfoOffset;
0 [( j9 q! }, u    UCHAR Flags;
# s6 S; j9 `, S    union( p0 q2 ~* [  |( k8 p
    {- M! v5 u: @4 [, P# C2 n7 Y7 h' o
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;; f6 h/ w, p# j5 _  J- y8 |' U
        PVOID QuotaBlockCharged;
1 S( a; M/ g: x" [. D! m. M0 ^    };- `5 R" o$ a, T/ X* z" M
5 G0 V9 F* s6 i0 h& @4 ~
    PSECURITY_DESCRIPTOR SecurityDescriptor;
" Y/ k5 T% q  X' [7 T; D+ q% i    QUAD Body;
. v' b- X% P2 R  z- r$ P  V- D' T8 u} OBJECT_HEADER, * POBJECT_HEADER;- a- p; N* {; ?
: N" u& _: j+ U9 E* u) e  V
#define NUMBER_HASH_BUCKETS 37
- V! m) ~# g) U1 f$ K2 s; e! p" R
- z. e, b# J0 G+ R* o) a- {typedef struct _OBJECT_DIRECTORY' o3 t# }+ x( l* \0 |9 o& u5 v' U
{! z+ n$ K' C- }; K  O1 H
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];/ Q- u; E8 A- W, [9 K
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;6 R4 O, Z6 P9 i/ z$ G0 n
    BOOLEAN LookupFound;
# b3 l& E! h; Q) l% [( Z    USHORT SymbolicLinkUsageCount;+ l3 f, f: b3 ~' @8 z% P6 j
    struct _DEVICE_MAP* DeviceMap;
" t" p- P/ z% \- t2 w# Q} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;, K" s* K0 c& E

( g+ [" j+ V, K6 I  n& ntypedef struct _OBJECT_HEADER_NAME_INFO
# h: B  k( x( S; D4 d) Y8 ~{+ H3 Y% {, y2 u; }! f0 ]0 ]' o
    POBJECT_DIRECTORY Directory;  V$ u7 H% ]! L& d2 g( }9 s) z
    UNICODE_STRING Name;
2 d$ A/ M" z- t! G- C" j0 D    ULONG Reserved;" b% q8 M) T7 d8 c
#if DBG) M! W9 ^( ^4 Q6 H9 p, d
    ULONG Reserved2 ;
7 i- o1 G4 h) q# U/ O+ {    LONG DbgDereferenceCount ;
& _9 B2 Z; M6 Y#endif1 X! I' k2 o% V+ N, {. X
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;2 g* T  O  S: H2 J: u/ ?; l

) W7 d. E1 S3 b8 \#define OBJECT_TO_OBJECT_HEADER( o ) \- p  K  B( G% m
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )" H4 A( b/ {: N1 d

% m3 T( z! y- B; H0 d#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
; N2 h2 I' x9 v    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
4 i, \$ F5 ]$ U) O
7 \% K+ Z" L% u% Ytypedef struct _DEVICE_EXTENSION1 s2 L6 `) u! [4 ]- A1 y
{
7 y. C; D* `6 @6 w    PDEVICE_OBJECT DeviceObject;
9 z: W. A3 J  ^. V    PDEVICE_OBJECT TargetDevice;7 j* j) K1 w& m( Z  Y) r7 @
    PFILE_OBJECT pFilterFileObject;
7 U/ z9 }3 W) ]- n  G* ]    ULONG DeviceExtensionFlags;
" |/ \  Y# K, v9 ~2 u# j7 g    LONG IrpsInProgress;) d: G1 }6 z' p; G: ]  |
    KSPIN_LOCK SpinLock;# s* \" B9 g: Y  E$ W0 f
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
8 J& i7 m. z8 C. _4 K$ N. B8 ^+ z' x. J5 P  y
$ o! B# K8 p( r7 R. S' A' N
VOID   r% b! ]2 A# ]2 P( E& p/ q
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );" o! _+ C; r0 F) a) i
9 w" `' G% s; i. H; R. N" S- v  G( V
BOOLEAN  L% d7 c& N" {
CancelKeyboardIrp( IN PIRP Irp );0 c/ r9 @6 j% `3 M1 P9 t- l1 F* U3 U
% n7 @- n8 X5 Y+ O7 G7 g% i
extern POBJECT_TYPE* IoDriverObjectType;5 b: r3 k3 E9 L. {& R8 }  R
: o1 k0 C+ u2 u, ^3 p  }
NTSYSAPI* T! Q; S" B& t0 |$ W/ H! w/ S, m
NTSTATUS0 }4 O% j* q8 E+ Z' W% w
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
- S% o3 O/ D6 S' z5 s( s                               IN ULONG Attributes,
- D5 ]. ^; H) d& r, E                               IN PACCESS_STATE AccessState OPTIONAL,
$ R$ l+ z. E5 S                               IN ACCESS_MASK DesiredAccess OPTIONAL,
0 Y: W" m( l+ L2 S0 O9 P- h; |                               IN POBJECT_TYPE ObjectType,
+ {, o  h- T+ v% X& }. v) M                               IN KPROCESSOR_MODE AccessMode,
9 u8 I; e2 A6 i. a, C) a' k5 e5 p                               IN OUT PVOID ParseContext OPTIONAL,
( `1 E  n8 |1 b1 a) G                               OUT PVOID* Object );
" e1 K: K# W8 o
$ z& N/ y( m( z* h7 d! l& [NTSTATUS ' w- f% o! F8 v1 L
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );( U+ k) Y9 e2 Y1 B/ \; D% ]# T7 r
; R3 O- X% j! [3 @0 O
BOOLEAN 6 {- C: k6 O$ ]7 ~. g: Z7 L) S/ d9 J
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
; |8 a5 x! ?4 @) e. F2 j8 Y
7 c, p% t$ ~3 T/ T$ o( SVOID
$ w  D$ O& m" q1 c2 hGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );
' t- [/ [+ k& a" @; f  V: p9 d" k8 C  k8 ?3 {, x! _6 S
NTSTATUS 7 m9 t' _) ^" {* u' E; s
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,$ K; I$ s% ?7 ]/ \! R4 S* c
                                  IN PDRIVER_OBJECT  DriverObject );
, K; _9 ^$ K# j% j8 R' n6 N+ m/ Z# z
NTSTATUS
& I- X- z9 f! z5 Q. G# R* D6 cAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,- }( |: @8 |- j9 U
                                  IN PDRIVER_OBJECT  DriverObject,5 [# N! u( J* b
                                  OUT PDRIVER_OBJECT* FilterDriverObject );8 D' f9 s5 y5 B9 |* T

/ |; S/ t# S: ONTSTATUS
, K5 e  T6 Y$ c: j4 c$ R" ]8 Q1 zKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,' l! `- f: `% M; P3 n. K
                            IN PIRP Irp,5 o: q5 C3 E4 ^$ p4 o. g/ z$ G
                            IN PVOID Context );
9 b! s! G5 y4 z$ N$ P- WNTSTATUS ) `1 U$ k2 J: _4 x7 E
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );0 ]. l* X- |: P" ~$ K4 E. S3 ?: |- K

3 @. Q1 I7 R2 Y! R5 WWCHAR szUsbDeviceName[MAXLEN];
: n- _( @! |3 ], s- U7 l* F' e: z; v- H! v# I  ~- F
#endif
/ A! j* T# i* m& F2 C# g. A, z- V( T* g+ q2 N
7 i8 `) y0 [' _0 S/ i7 h$ J

# u% S5 n3 Q8 R0 H" a, m% I5 V( B
/ h  W  ^7 P7 c& {, i
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
, s4 w" r. T! x$ y# H! OWSS 主页:[url]http://www.whitecell.org/[/url] 8 b6 Y7 ^) J9 I# S
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-8 07:05 , Processed in 1.044381 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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