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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister7 p8 }8 J, E3 z7 K6 r& x8 ?
Email:   [email]sinister@whitecell.org[/email]8 L+ ^. e% a0 p
Homepage:[url]http://www.whitecell.org[/url]
; U5 `& G- u' IDate:    2007-02-266 I0 s: N) f3 Y% |

; F8 e, c# z3 q+ v) K7 v5 e: X9 x1 u) U3 V: {0 D
/*******************************************************************
/ V  L* ~/ j* g% B* c# Q
# h% u( r- r& y3 t  [这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
& |; o  S5 x- l0 t  o" I: O0 t写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的7 Y, X3 f3 ?7 b
功能要求如下:& Q; j4 |# e& d7 [! J

# [& A. F" a2 o/ `1、强制锁定键盘/鼠标。
3 Q9 v1 ?9 G; E2、可动态加/解锁
6 R+ t3 @2 n$ D8 F3、兼容所有 NT 系列的操作系统。
4 S0 ~. @- W+ L3 E+ R& I/ o7 a2 F
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
% F* `+ r7 {2 x$ {# v% x现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
: G) Q5 r" g; Z1 j! q, B何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
! ]3 \# Q6 c1 E8 q( ~1 {9 U) z上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
( r9 W7 ^7 G9 |, z怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面
' X' d$ t$ `: |/ X1 t就来看一下我想到的几种实现方法:# C$ c- ?9 s; C- v. Y

+ ?/ y% k& P- D9 P6 S. P1 t3 G1、全局键盘/鼠标钩子# w* X: P. Y+ d" P* P( [5 j9 ?
2、BlockInput() API) o# D, @; f/ K; l
3、使用 setupapi 进行控制6 V1 T) S  |% t" z. X
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
4 ]( O. v6 |2 e2 c+ \* f, V5、拦截 win23k!RawInputThread() 函数
) s* f+ f- \- q! K, R6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
" ~0 I+ H) k1 c6 s$ r$ [4 j: T2 G! o7、拦截 kdbclass 驱动的 driver dispatch routine7 c7 W6 x8 C. C
8、实现一个 PS/2 与 USB 键盘过滤驱动/ A, g; n$ p1 t$ [

( H) z! K, e' C7 ~/ D3 Y
! H8 Z) U& b' p8 J2 P* I3 j  Y# |我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑0 u2 N: a; g5 l  V6 u
之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方( }4 \+ D# M! |1 V3 D, U
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在! e, J2 `$ |: S) r; X" f
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因, H* g. v+ X# s2 x, C5 m/ j; q% U
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
  f- g8 t9 R0 Y" c7 R问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸9 n* r: W, N! N9 t
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
) {. W. N/ ]4 f5 _' _的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
# a. l, X4 n. J- S也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如& b) `$ s6 n: Q7 ~! z
果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
% c% z! B5 ?  k; M" z$ b: u, g障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
8 ]0 J& Q/ Y; g, |( JIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于
% ?+ C5 r7 \2 n; b2 g- H% SUSB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键5 p; F6 Y. N( Z7 C/ _
盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方
! c+ s' G0 S& ~, J) h: @, A案的全部功能且不存在它所带来的问题,否则就没有什么意义了。" Y6 D3 h7 R# d
2 I$ x' ~6 T$ W9 v

2 g/ S7 G4 f( q3 N8 j我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
6 f6 y! ~$ f  Y5 M, o滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进
- B  ~) }. l% _0 Z4 h6 y1 ^行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是9 ^* o& C% q3 j! P3 H3 \6 q
只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
# a1 h5 c$ }  h来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从; P+ Y) r8 h) x6 L  l
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
/ k7 g6 f8 C7 P( g; t% P! a键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用
* d4 E% l0 G- r# M( W' R) lIoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
' q% V/ S$ D4 d$ g) T9 O我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题6 ~2 _6 @2 g  L; _) t+ a" c' ~
就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的  L  q! c  x9 Z$ O/ j1 w
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
" z4 l- X/ R$ N3 s1 N用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通
" Z$ A  D/ r# Z  c9 i+ w. Q过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来! u; V- D; O7 e" [: X+ R
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
# ~1 ~9 d+ {. W# a过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb& e7 V: |5 @5 y( G" v. K
上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid
$ j. ]6 i( |3 @  ]2 M的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意8 D( A- X+ g2 M* C9 ?8 p
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
7 l2 M! A7 ?2 I$ v经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
4 |: o7 Y& Z: z6 y' n! |! S来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利$ W  q! M7 U  q+ z5 r5 p% W  y
的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo6 c. U0 |/ s1 @2 M8 Q# @
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致$ m9 n8 s- ^& n) T! g0 {5 ~- u
敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,
- N- j/ _4 r! Q( p- D  U根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程# J: i. z7 z+ ?
见下面代码。
/ Z0 f' c$ j& \# N! Q8 {9 T& M  i+ h4 M+ Y% ?8 F5 D8 \! f4 z1 j
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程6 T8 v) [& ]5 K/ F
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键- j: ?, c' `  g2 O: S7 i/ i4 c
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
/ I$ I! x- `/ G; k! h  B上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有! h7 p# _. o$ v) Z
完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可7 E# O4 \+ L. f. Y, ?
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
4 V/ h# S5 j0 p- H5 c* h1 C锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
8 T7 q1 U0 H, v5 W! k$ U键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。
. ~. f  A& a( G% w9 G4 ~8 l
6 |8 Q+ |# m7 o7 g' }
, b/ h, d' x3 z3 p4 o  i% G. j3 m完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用: a) |1 B4 P5 ]. M' k8 ]( |
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是6 h, |1 t  ]% i' D5 a, X
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣4 c, _" V0 e, d4 {$ A. k
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我7 L  \  l/ |7 g, V8 o' J- X
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
- V1 B8 z6 R5 f+ C5 X们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
/ C4 g8 U$ H, P/ z5 T' x->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。' l5 K- k! F7 y3 L
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
8 y3 I* c8 q! @9 n& z8 p进行操作了。这个问题有待大家来完善了。8 R/ Y8 [; l# A, f1 J  K, \% a

6 ]# f* z& D% I( f$ Q, H
& Z+ O1 P& q2 z" I8 X, c要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出
& b2 o4 w# W: d" e1 `/ Q来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
) ^  x5 d. ]5 U  \# s9 F3 M. e分析做个记录而已。我更愿意把它看做是一段注释。
- N9 n: C9 R6 d, z8 w
7 J; i) U2 H, w/ ?8 d8 A# T$ g最后在此代码中要6 f- l: \! U( |$ e  u6 _- ]- G* C) T

  f2 z' K, W) o2 G感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
6 O1 V! i0 q9 Q3 v/ @
! M8 |9 T/ W# t, l7 @7 K感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
. ^" F3 t$ ~# p0 n% e% p" h$ z  A* n9 r( B4 l5 g- [
感谢:齐佳佳,过节请我吃好吃的。
2 U% X0 E2 A3 R* l
* ~! C" h# g5 a& X3 ~
; I8 c+ T3 O& k7 E# K& S8 X1 r******************************************************************/
! M$ F, m1 A8 x& T3 `
) |3 D$ g6 Q+ g, ~- |" A' M6 s* G! a2 d0 U( l0 o# L
/*****************************************************************
0 Z1 A& S" C, x0 j8 r1 `0 }& C4 @ 文件名        : WssLockKey.c
2 J( `& x1 l* I+ c/ T7 Z/ }" e 描述          : 键盘过滤驱动' `- X; P/ Y9 t6 f+ Q" }
作者          : sinister, ~# I3 y# c$ b4 x. |/ K$ U* y
最后修改日期  : 2007-02-26
9 [5 N  M$ H2 f7 @. A3 i' L" T3 j5 |# x% o*****************************************************************/+ C) a  o. M" e; l) W5 O5 Q

0 T5 I" L8 h6 i; e2 ~) ~$ I
6 R+ a  u5 r# R#include "WssLockKey.h"+ E* z( t9 F! [8 E% t! ~. T/ ]

1 l0 I5 c0 o5 ?2 iNTSTATUS
  Q- p6 q% |7 ~4 oDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
+ R/ `* U* S. M             IN PUNICODE_STRING RegistryPath )- \, q, V( Q& O4 `" G5 _" M
{4 n; Y. S) m* Y' |0 ?7 K1 {2 i7 B
  UNICODE_STRING KeyDeviceName;
5 J( B: Q& U0 S! i( w  PDRIVER_OBJECT KeyDriver; 8 b; y; h( w1 g1 N! K. h2 E# b7 r
  PDEVICE_OBJECT UsbDeviceObject;
3 c, F& ^0 q- x. W; a4 a  NTSTATUS ntStatus; . s+ e1 f: g0 u
  ULONG i;
6 u$ L* P; ~+ }- l( L: n
/ c2 P: W: X; }4 _  //4 n& F" E5 ]' u- i
  // 保存设备名,调试使用( R" H- Q4 W6 k2 D' \
  //9 d4 R: j+ p$ T1 l; I
  WCHAR szDeviceName[MAXLEN + MAXLEN] =
/ i$ b! D2 ?: ~. z  {
6 C( Q; q+ e$ X& p6 m, U& ]4 y5 p    05 |$ H: a, S$ \; v9 ~
  };
  j( c0 ?8 {$ T4 y+ Y1 ~! G1 W0 g1 v$ o/ R3 c
  KeyDriverObject->DriverUnload = KeyDriverUnload; , I/ }+ G6 N0 x$ z

( c2 N  M( k  E0 o+ q& O5 I  //
  n6 }* A1 }7 L: `6 M+ j) P& j  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘, W6 u0 h8 ~+ g* p+ d
  //
% q8 j( y; `% C2 ^: \. A  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法6 ?5 C5 M: u! R( |  [
  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其' B% B6 X) E4 F
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到( z4 ^' X5 N" w5 @2 m3 t* Z
  // USB 键盘设备来进行挂接
3 D$ P) `* E4 c  //  l0 \( z" s* H! m, }: q
  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );1 p* F5 R  u: O$ Z: Z
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )) y9 V1 ~+ j. l  M
  {
5 L2 J9 s( ?9 k4 A0 i    //* R* ]3 r! ^# ^, V/ V; `. W5 j: r+ R
    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名" j' H8 ^& O- U+ i( W* l9 ^
    // 所以这里打印为空
* \; K: c; h0 ~% N1 N    //$ a7 r, M1 |2 s% i6 o' q
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
! H0 n) {8 o4 {6 D% I  n    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );
9 `9 e4 m9 A8 M9 V
% L9 G: w8 n+ v- x8 I    //
  P* j7 R& j* S# s    // 挂接 USB 键盘设备& g4 \  \; X/ ?5 V
    //
% ^$ m* _$ i7 h1 W( H$ J    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
8 I; J6 E7 _$ c5 B    if ( !NT_SUCCESS( ntStatus ) )
% M6 z3 w- `! @7 j7 o7 x  K    {2 r  X- ]7 d+ i
      DbgPrint( "Attach USB Keyboard Device to failed!\n" );
7 O- R: e6 L1 Q; \& S9 E      return STATUS_INSUFFICIENT_RESOURCES;4 v' f3 D! L7 S) c* ~! p
    }
9 E' M5 x, L" |7 h; W  N; Y  }
9 v3 ?! U2 h( k0 g  else
% P1 E6 b1 k  [: P  {' \5 c1 p3 {+ N5 G, h/ X
    //
& ~! e/ a0 c( @3 |4 N  A2 v. e    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备# c2 l1 @3 {# e" y' X
    // $ K2 Q4 l+ b6 C( B& b4 u
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); ! X4 e1 O. X0 J
7 `& Q; D. A5 h7 e- A9 Y, B& C
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,( E( V" i' L% F3 ^" O$ O
                                        KeyDriverObject,+ y* s# R; ]8 J
                                        &KeyDriver );
# X5 @' ]; p$ e* R    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )2 Y0 c  S  o& c  y3 {
    {
" Y: v$ _! k( {# u. U/ H, m7 U      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );1 Q4 g2 m' y2 U9 c0 \* G$ ?
      return STATUS_INSUFFICIENT_RESOURCES;
! S3 K. H( x: A8 y9 R8 |/ u    }
: \4 ^# \9 S) G: A  }: c& e. Y% v2 p. K

3 i3 u3 E/ _( D3 J4 Z4 z  //  @' k8 C4 Z, n2 B+ D* Q
  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止: K( d* n6 ?* R- y, P  f8 v7 C
  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程# T/ l, x1 e, z8 h& s: L2 {! S
  //
0 a8 j/ {% e4 N3 i% g4 x  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
" t; y  v( ?- Q% m+ |+ [) m
3 p" V. w# t: W9 c  return STATUS_SUCCESS;
; q. {: _8 ~8 {$ P}
% i) b  }, O  A- E6 X
' \) |; H$ c2 R/ P. Z+ v  Z/////////////////////////////////////////////////////////////////7 i+ d8 c; \) \; [
// 函数类型 : 系统函数0 {! Q3 I) U8 U5 r( W4 t2 a' T
// 函数模块 : 键盘过滤模块7 R) D+ ~- D* v$ J6 @+ p( {9 ^& ~
////////////////////////////////////////////////////////////////* L) Q5 m, q* p3 K- R9 n9 q
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
( x+ T! E+ R( z' H: O8 h  n: K//        卸载键盘过滤驱动
, u5 S4 [2 K% {: n7 T7 e; M// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
  }. V( L( E3 [4 N/ W3 Q! a//        则需要等待用户按键,以后有待完善; p6 C. C; {6 k$ b
/////////////////////////////////////////////////////////////////
" e. ~+ e! Q/ G7 X6 N) V// 作者 : sinister/ R  b% c% K- L6 ]& |. R
// 发布版本 : 1.00.00! F( p' T" S0 O: L3 s
// 发布日期 : 2005.12.272 U- W' H! @& {/ I0 ?5 c, B
/////////////////////////////////////////////////////////////////
, Q$ ^" _) ~) X$ p// 重   大   修   改   历   史# v  I# C( h) |8 }! L
////////////////////////////////////////////////////////////////
3 I& c- M- C5 r6 r2 K$ V6 s// 修改者 :
( o. Z: [3 a# k6 ^! s; Y4 Z// 修改日期 :
! ~) L0 i& `; M, F// 修改内容 :
7 q* ?4 d% [* Z/////////////////////////////////////////////////////////////////
1 T8 n9 U  T$ t8 j* a: W
% w% a* U, v! }4 O* z$ WVOID
8 p: `7 y8 u  k" xKeyDriverUnload( PDRIVER_OBJECT KeyDriver )( M$ ^9 H+ f3 N/ d
{
4 p5 b8 R" o. h2 v2 N% v  PDEVICE_OBJECT KeyFilterDevice ;      : ~* l% _0 r0 m% ~, Q2 V  ^6 W; e+ }
  PDEVICE_OBJECT KeyDevice ;# \& o  I6 f2 A; H* `; q* E4 i
  PDEVICE_EXTENSION KeyExtension;
6 K$ t  _3 b4 |; u$ Z, Q  PIRP Irp;% q7 u" U2 h2 i* y4 `( e
  NTSTATUS ntStatus;
" ~5 _3 x5 q' u6 m+ ^) r9 v- f9 P! T4 B  z* w9 N
  KeyFilterDevice = KeyDriver->DeviceObject; 2 ^% b- V+ k+ q* B+ M( U% ~5 s( b
  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; + g/ d' d4 N' m8 i  U& Z  W
  KeyDevice = KeyExtension->TargetDevice;
# ^! F! Z$ \4 B$ w6 i! u
' M+ {& b- U0 P/ Q8 Z6 L3 J3 S  IoDetachDevice( KeyDevice );
9 A% g  J! W3 Z7 U
. Q/ I) w3 r8 d  O- x  //2 K* }6 `( c* Q- j  w4 A
  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
. P) O5 h1 o4 N0 n5 P* s# z. m  //
! b( f  u1 [! i  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL ), f, z2 p9 q2 L; ~# ~6 c" k
  {
4 s5 R; O% i: o% X& i2 V4 W- u( }    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )( y7 ~5 d6 Z; _# i
    {
. s2 y: @9 G3 \9 k; X      //5 d. l/ N7 U' W# R; Z2 U2 _8 W9 {
      // 成功则直接退出删除键盘过滤设备4 F/ V$ \9 R4 K$ B, H6 W' f
      //
% I7 }) N3 ^8 r7 p+ w      DbgPrint( "CancelKeyboardIrp() is ok\n" );( O5 ~4 z2 r4 t& s& Y; E% p) A
      goto __End;. D8 V: n# m. m" i
    }- F" U) o* v0 f4 M
  }( m: p! k- B6 g/ ]8 K5 e: p6 a6 R
6 V. x, H4 O$ X
  //
6 Z8 r* k/ K  w  // 如果取消失败,则一直等待按键7 b0 H# x+ w0 \$ ]4 i$ s
  //  ^; X/ E% U( ~
  while ( KeyExtension->IrpsInProgress > 0 )
% V) d& B/ |0 H# b  {
4 L! u, G0 o; G3 m  U    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );, X0 Y: n2 q0 Z9 m- S
  }
" E& ^* ~5 [8 ~+ w4 D4 x9 p0 z6 a4 F) U4 X* [
  __End:% T* u! S. T/ o- n7 a6 O
  IoDeleteDevice( KeyFilterDevice ); ; n3 }% {, |% o

# k5 Q' i3 C' G; t  return ;
$ P! ^! M* M- k" D}
$ q8 C6 z) z" n8 N5 C5 O) [4 ~. c6 d
/////////////////////////////////////////////////////////////////
9 q0 @, C( G" d% ~// 函数类型 : 自定义工具函数
6 z1 L0 l( o& e1 f+ ]! E// 函数模块 : 键盘过滤模块
% J* \$ A: v- D. K/////////////////////////////////////////////////////////////////% ]5 P: W3 y5 I
// 功能 : 取消 IRP 操作
- o- k/ }! l" x// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
; Q1 o) X, w2 f# F) W//        使用此方法来取消 IRP
- S# P+ I; t9 t/////////////////////////////////////////////////////////////////" L" z) t0 D4 w+ ~' q5 v% o
// 作者 : sinister
1 d% b' U+ W- X; D// 发布版本 : 1.00.00
  ^* r( G8 s6 K" m* c8 t// 发布日期 : 2007.02.20
9 W$ ~$ C0 X2 l% v0 X1 w, D/////////////////////////////////////////////////////////////////3 o5 F; s6 \: P7 u
// 重   大   修   改   历   史. t# a% U. `# V+ n
/////////////////////////////////////////////////////////////////
9 X) O: r6 \# b! m" B/ x// 修改者 :
7 w) b4 r: Q" T. D5 `// 修改日期 :
: s* }1 t2 V( H5 |: e  @// 修改内容 :
$ d4 j9 N6 Z+ a8 U////////////////////////////////////////////////////////////////// h3 b5 w/ v! [& T8 Z+ c
( T% t/ ~. @$ [4 x- J2 M
BOOLEAN
  Y* [3 V) m: y0 O' GCancelKeyboardIrp( IN PIRP Irp )
/ `5 n- p8 P3 h( T4 r  M; h- d{
7 h" [8 ~- @8 q7 W9 }$ P6 ?0 e4 G  if ( Irp == NULL )
5 o9 c7 T" d" D* _  {
: }3 I, b: N7 p' a    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
- B8 \0 `; |% G    return FALSE;' L8 E5 m, K3 q! _- _/ ]7 ^
  }9 L* t' \7 }) u0 A; M* R

, Q5 D! @" V, X" g' `( `) F/ ^
  //
6 |( z2 Y# R/ I  w3 ~& Z7 ~9 u! ~) |' {  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,
# }2 V1 r' H& Z  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。+ n7 Q0 a! S( s) B; |$ e7 E
  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占
+ h- ^% T. V$ J3 c  Y. I  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
; G( B0 M" q7 C/ z7 ?; i7 P  //& H+ b5 z& J4 s6 U1 u8 z

, u, }7 t/ k6 T) O" @/ i  //) G7 q: i8 U) T1 o4 q& |
  // 如果正在取消或没有取消例程则直接返回 FALSE
# y! N8 w$ X; v  \* o, g  //9 `5 S( E% }9 Q$ Y+ C8 s1 T
  if ( Irp->Cancel || Irp->CancelRoutine == NULL )+ S. g  x, e* F  r8 T" }4 w
  {. M3 E3 j: }( Y
    DbgPrint( "Can't Cancel the irp\n" );
+ T- G* r7 E4 d- j    return FALSE;
- _7 n3 D( T; t: R/ h1 F  }
4 C& W! U5 d  W' S
# N- F, |+ E6 A2 m  if ( FALSE == IoCancelIrp( Irp ) )) {( r6 r' n6 y+ ^& Q  R& Z: s
  {
) c9 b$ ]" R1 E1 u1 g1 i    DbgPrint( "IoCancelIrp() to failed\n" );
" B8 y6 t3 P1 I8 V" e& R/ Z% W1 Q    return FALSE;
. p! m$ `# z' o' Y. u  }
1 ]) y% ]/ P3 f3 u  ^, {8 l; L7 k( H; e/ r# _' \) U) {5 t# P' D
  //
( W+ r% c% m$ C* M  // 取消后重设此例程为空
, E0 B* R; Z( m  //9 s8 U2 d' I1 y2 g. i$ i
  IoSetCancelRoutine( Irp, NULL );8 V9 R9 g, ^* f. N) A

/ ]: _2 n. s  }# S% x) O* {1 J  return TRUE;
. X6 X% S2 R1 M( P8 K}2 Z- _' [: u- v2 R

/ a" c% G, g% v/ j1 p$ w/////////////////////////////////////////////////////////////////3 F- s9 |9 `/ M/ ?" o7 g% W
// 函数类型 : 自定义工具函数
$ D1 p1 Z, e  y+ Y  l+ ^# x9 z" p// 函数模块 : 设备栈信息模块# J2 l" ^4 u& y2 n0 l. [
/////////////////////////////////////////////////////////////////
* X9 B7 ]7 ~( g9 P// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
7 S' M  b) E9 z5 f//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
6 h0 B+ o) U$ _9 {0 w( Z// 注意 : 8 {$ k- p* `$ k! ^0 |0 L9 h3 j; R4 K
/////////////////////////////////////////////////////////////////" S5 o1 S( @2 }* m5 B. p
// 作者 : sinister; W5 h5 a" A( w! Q8 V. q6 t
// 发布版本 : 1.00.00+ Y6 W. c, Q  ?. m4 c! q
// 发布日期 : 2005.06.02
2 Z, X  g7 |0 T: p$ _/////////////////////////////////////////////////////////////////
$ h+ \- U1 j" \1 r( ~// 重   大   修   改   历   史! S3 T' _# y7 q8 V0 ]' r
/////////////////////////////////////////////////////////////////
' p& I; F; q7 B& m7 \// 修改者 : sinister- l8 Y  q$ {: F
// 修改日期 : 2007.2.12( H" v* t; d0 U2 h* k# m' I
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改, X$ M2 e4 [  W0 Z( e1 Y
/////////////////////////////////////////////////////////////////' |9 B+ L: d$ m( G/ z' l1 H
- a6 M0 r3 X! Y( @8 s4 P* @
BOOLEAN2 r! |5 E6 e, ^8 D" H3 k
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )% c1 u3 U0 N( F0 V3 b, _+ v
{  J# G% H' c" e: V  A
  PDEVICE_OBJECT DeviceObject;4 I4 P5 D0 C3 q9 q; Q
  BOOLEAN bFound = FALSE;# W, T4 g4 U* O: _2 ^
  y5 Z& I7 l6 N& O. {8 e7 g' J
  if ( DevObj == NULL )
; U+ j8 H5 e8 E6 l8 u  {
* D2 ]6 |* g! _7 P; p0 h    DbgPrint( "DevObj is NULL!\n" );/ i* @, g7 T( `, A7 B& O
    return FALSE;
: B6 T* a. i, ?! F1 `  }2 t+ q+ O0 e7 Y

' x' M' V6 |7 o' \* F6 g, i- T; a  DeviceObject = DevObj->AttachedDevice;
$ c. W2 W# V9 q4 r# U% I' i# m1 l- I7 p1 t' o8 f& [
  while ( DeviceObject )- w4 G& C) G8 H1 |- M& U
  {
: F: [5 j( E4 G# h# o7 d    //) u: j$ ?* Z4 T2 t1 S$ v
    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但2 R) {% F- J5 d1 w. y, I- `' H, ]
    // 有一次足够了。这算是经验之谈  M. m' J$ E* U0 x+ \
    //
! Z# Y! @0 g) ]    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
$ d/ D2 A5 T; k( a1 m. h$ L3 \    {
2 J$ J6 B6 [1 t4 [& _) d' ]      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
* Y3 t! [1 b; g+ w7 m; d                DeviceObject->DriverObject->DriverName.Buffer,
9 ]. J  n& \& [( c                DeviceObject->DriverObject,- [" d9 [7 ]1 G9 V( M
                DeviceObject );  R+ M5 c& F' ?) u) g

, V, k. c, C( A# {# X2 @! c      //
9 ~! i& M" U9 S4 k8 n; _  _3 |      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
6 s$ A3 K2 }# Q      //
$ g* N' B+ t2 t4 H% r+ e' I. ]      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,* O! ]9 W0 ]% `1 C- n2 L% b2 R) h
                      KDBDEVICENAME,
7 Y  b- D% J/ h. F                      wcslen( KDBDEVICENAME ) ) == 0 )1 ]- w' A6 U8 [! W
      {4 n: }. x# K+ s, w; b
        DbgPrint( "Found kbdhid Device\n" );7 ?0 |% D+ k! \/ C
        bFound = TRUE;% E4 p1 H5 f2 V6 A4 `9 A$ P' |
        break;
1 {' c3 y+ ]5 z6 K. J      }! q9 q" o/ v3 ]$ g/ [2 @0 e, u
    }6 f6 @4 `8 `# i) I( }7 v3 u

5 a7 s' F9 e: z5 y7 b. j    DeviceObject = DeviceObject->AttachedDevice;) N; D+ y' b! h" b- w
  }
& a! m) u: j3 |4 ^
" R% l! J# X+ s. z8 n) G$ R2 V  return bFound;" O& \% y' w% a% e3 w" h' X
}
& W7 J7 Q0 J& J6 U. w# z
% X* k' U+ G2 _# ?$ ?# h5 B/ @! Y/////////////////////////////////////////////////////////////////0 W7 z# m% q% |& _
// 函数类型 : 自定义工具函数' h3 ~- n% n; ~% o- u" k
// 函数模块 : 设备栈信息模块, Q' l$ Z% L4 S2 x
////////////////////////////////////////////////////////////////// Q* N( W8 J# M  G
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
5 x" ?1 w) V1 I4 y  ^/ I& }5 C// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
( L" I8 {* c4 E' A- T, Q/////////////////////////////////////////////////////////////////
2 G6 J9 C: B: {  a1 f5 j// 作者 : sinister( V" i) y6 ]) x! P2 w
// 发布版本 : 1.00.00
7 Y8 N, o5 f5 r3 \; a// 发布日期 : 2006.05.02
0 V' w1 o$ W7 ^, z& e; x/////////////////////////////////////////////////////////////////6 i! O" \1 B7 C$ j* C/ O
// 重   大   修   改   历   史
1 v; d- o/ ]8 m; L: }3 n0 i/////////////////////////////////////////////////////////////////
# b3 K" W7 U( F+ I& y8 }& Q// 修改者 : sinister3 v. ~; S2 L# g6 p1 y/ s
// 修改日期 : 2007.2.12
. j9 v8 h' P: v* L: l3 q( i// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
' D* z% N# Q1 D5 L) C/////////////////////////////////////////////////////////////////) u+ l" d* e* s7 c: E

" C5 a, }; w5 F1 n) ?7 K8 U% j- AVOID
: j/ l3 ]) W5 h( K7 i5 x; Q& GGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
- \' L7 O/ x% M{
' [6 B1 S% d' O( y: i' L  POBJECT_HEADER ObjectHeader;1 r# n2 R& M% u8 ~; j+ H; l
  POBJECT_HEADER_NAME_INFO ObjectNameInfo; ) d* l# w* ~: d0 f$ t6 S8 O8 J5 q

5 [9 G. ^' k( [8 m1 X2 a  if ( DevObj == NULL )
% v2 e+ _  @: z8 `3 I' ~, c  {  Y: c. w9 `. F5 ?; v% y
    DbgPrint( "DevObj is NULL!\n" );
$ O6 r- e) z3 D* b. ~1 b' a0 a    return;
! v) q8 ~0 A1 B* Q) Z0 |& a  t  }
4 y4 z: i* \7 z' Z5 H2 B
9 [! ?( L) _7 O5 y8 K* n; b  //( X* H, l" U/ @* u1 w7 c
  // 得到对象头
9 Y; n* B1 q, q+ [6 Y+ D0 n  //. u1 }) {; |" V$ R0 t; i$ O
  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );) Y; S" ~2 v- F% d- Q6 j

" c) d% c# t5 J" ^$ c9 [  if ( ObjectHeader )7 r* D2 q8 Y1 M3 ~+ K( d5 j
  {. [/ W# j. q2 l: O& y
    /// Z# U) ^7 X/ \) I8 \
    // 查询设备名称并打印. h, n# F. d8 w7 n
    //; j2 h$ N, m9 ]/ T% ~
    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );# ^$ l# D2 k2 M* p+ Q
: [1 E/ V$ e3 a  ^, _. W  X: l
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )) @+ M2 V' `( W' r
    {" \- c- [2 [: L1 Q/ Y# h
      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
& W! C% J. O: K9 i) ?                ObjectNameInfo->Name.Buffer,) n; c0 g/ M2 Y4 t
                DevObj );
: u$ }0 ]- \( q7 p) p, V5 X6 c/ b* F2 }% G* M5 k7 `
      //$ L! q1 j# n6 m, `% [" e; ?
      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示0 L+ g* y+ h8 w7 b7 F
      // 用,没有实际的功能用途* H' P+ S8 e/ s
      //
9 Y( {+ a/ q. ^, Z      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
) |' K1 E6 w9 j9 ]/ |: Y
- C+ j2 P" Z% D1 D      wcsncpy( szUsbDeviceName,
) V4 |  Z* q; K. |8 @( j7 y               ObjectNameInfo->Name.Buffer,
9 M/ F; Y. i" I8 Y, M% q: y& U               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );; Y$ a* R8 a2 {6 Z0 J5 G
    }0 W& F9 F- w$ o$ N9 B% h  |

3 }' W1 n" v9 ~% f/ B% {; }    //; U: N3 c* m; F1 X4 Q6 O. w5 x
    // 对于没有名称的设备,则打印 NULL9 K7 i; t% i) J- g9 z; _
    //
2 s  m8 g8 x# }: F    else if ( DevObj->DriverObject )6 A& k" l3 P8 y3 J
    {0 M* `! U8 y( d
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",; v$ H! Y' ~) O2 i: a7 a
                DevObj->DriverObject->DriverName.Buffer,* g, T3 s: c8 A/ _3 T6 ]
                L"NULL",8 k5 Y  W2 N! T2 ]- Z' Z1 m. i" v
                DevObj->DriverObject,% \. m% n; v9 r0 X
                DevObj );
& V/ f5 i, ]' `7 r+ Y/ k    }
: Q& g( B( e: D7 c$ l# I) I  }4 I: |. }- p5 }7 h' [# N( @
}
! i6 q& A, [$ Q* F+ r4 ]. D9 {% z: d. y" o7 ?& v2 a( p
/////////////////////////////////////////////////////////////////3 {5 F) h: e0 Y: \1 _$ k% o6 G2 \
// 函数类型 : 自定义工具函数
. B8 [5 M: V! `8 t* V- q2 P// 函数模块 : 键盘过滤模块( F2 t+ g6 ^8 o$ z! M# G( E" R
/////////////////////////////////////////////////////////////////& Y; t5 s' `( N+ w: }2 r
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
) S' _! J2 ]. H. q7 f4 J" M//        对象,过滤出 USB 键盘设备,将其设备对象返回3 H2 [0 E  |% o
// 注意 :
2 I3 a/ I  U6 W) z/////////////////////////////////////////////////////////////////- B& y- `; C6 p  T+ n# i0 `5 x! O' t
// 作者 : sinister
) @+ N$ V5 l9 F$ b  q, m4 C// 发布版本 : 1.00.00$ A3 S7 N2 ^7 {4 E* F& r+ H
// 发布日期 : 2007.02.13
* ~; j5 T& ?8 O/////////////////////////////////////////////////////////////////
. t! `* N8 W+ f  t( b. J$ }- j// 重   大   修   改   历   史
) ?4 x% S- X$ x4 @) S/////////////////////////////////////////////////////////////////
4 h" b' c" Q$ V/ o% {6 ~3 Q// 修改者 :
/ @6 h8 c1 q! ~- R// 修改日期 : & B& H) q( j9 C, e
// 修改内容 : ' v7 q- M8 z, z2 ~
/////////////////////////////////////////////////////////////////
0 i3 M& R% k5 K$ V9 P$ Z
) r8 Q8 d& {0 B+ D7 x9 t$ RNTSTATUS( \+ |3 }  N0 w* U) x, k
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject ). v: Z% B; |6 H+ P$ u* X6 b2 D
{
) ?5 {: J& o) ?+ Q2 @  UNICODE_STRING DriverName;
& O2 |) L$ H! _2 o( H% H  PDRIVER_OBJECT DriverObject = NULL;! X2 R' U* o9 B$ b) k
  PDEVICE_OBJECT DeviceObject = NULL;
1 A2 R! X$ @# f  BOOLEAN bFound = FALSE;
4 i; v  I* ?, d3 H6 z. T# g
) |3 ]  ]/ X7 P. Z  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
2 F7 a; ]. W* ?" d
8 `# l% U* S8 H3 N$ K* u  ObReferenceObjectByName( &DriverName,  t& j) L8 p* S, L$ b7 U$ A! T" U# k; W
                           OBJ_CASE_INSENSITIVE,
6 f% M* e6 i4 M% `% i0 r                           NULL,
# j* o7 K" J" v# U                           0,! T1 r# z0 D$ u* D( w0 h3 m
                           ( POBJECT_TYPE ) IoDriverObjectType,/ h4 H7 p& T( q5 w: W$ ^3 H+ f
                           KernelMode," |5 F; d* |9 t( }) m, i, Q% d
                           NULL,
, D  N8 D/ H) L# {/ ?; G3 Q0 Q                           &DriverObject );+ ?5 c" v: `. k& T7 Q
, s: V1 G; Z  u. V, s: F/ e! x
  if ( DriverObject == NULL )2 O9 |2 }; c/ L% m
  {9 _$ ^7 t- K( r# j4 W
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
4 q/ q7 U% i# J8 |    return STATUS_UNSUCCESSFUL;
/ d! H9 \4 w5 V2 P  }
# a. K/ |/ \% G6 T3 M& e) ]9 c& j" Q* O
  DeviceObject = DriverObject->DeviceObject;
- J. P6 h1 h' Y! r
4 \; R% P5 X* c4 A5 i/ c) @  while ( DeviceObject )
+ Q% [' t7 b& \4 `  {
2 N6 V! V( y! _; p  m! c5 Z    GetDeviceObjectInfo( DeviceObject );- R- v3 R' l# Q8 I' b2 O
6 u" S8 y  ?; A, R  F: a$ m
    if ( DeviceObject->AttachedDevice )9 V$ ?( `, B9 a0 T( G
    {
6 l8 G; n& s) I! L      //
/ W# S' E' E4 a4 r8 F+ ~      // 查找 USB 键盘设备6 K  ?3 x' b* X) k' }$ o6 @2 L+ D
      //+ l8 J  _3 H1 U" O) n
      if ( GetAttachedDeviceInfo( DeviceObject ) )
  @; l9 x" M2 ?. r- F) ]      {
4 Y1 d) [( y; l/ c) y        bFound = TRUE;$ j, W, U7 C  ^- `7 m% B' s  @
        goto __End;. k$ }+ i* L' ?3 k. [; P
      }
* R/ _( ?: y  y/ |+ m1 B) {    }
' ~! w% {1 s- J! e3 Q% f! e0 e8 M+ [: B
    DeviceObject = DeviceObject->NextDevice;
. c$ M; y! M5 J* e  }
+ Q6 A5 p; X  V: L. H/ U/ r' j" I  d& x: w/ i
  __End:
( o2 O3 z5 |3 C+ }9 ], {3 A+ b9 i# x" M$ ?3 d( N  y3 y
  if ( bFound )6 _8 H% D4 ^' s. `
  {: i1 g( K  @; ^' {6 v1 x- k
    //9 f4 F, w9 D! F: v! Z  e: F
    // 找到则返回 USB 键盘设备对象, f3 l% Q+ P0 m$ K3 `0 r
    //9 ]0 l, @! S. y* @# y  u2 \
    *UsbDeviceObject = DeviceObject;
) F8 f" {* Y# p9 y: T* ~8 p  C( a  }
5 \0 N  r( U3 M2 e( C" i, l  else
& Z5 W- b- c- Q  M4 z, z: {1 |  {8 Q6 Z% j2 a/ J6 r" T5 D
    *UsbDeviceObject = NULL;
/ J9 o4 x' Q% j" D. x  }
, N, P1 m6 X' Q: a3 O6 n7 I9 E- {1 ~% N7 N- k
  return STATUS_SUCCESS;
$ x8 P5 O. U' P! u+ y  i: a}
+ _6 o+ t0 _% \' y4 R% Y0 s
" m8 v+ j: p3 ^2 F( e/////////////////////////////////////////////////////////////////& L7 O. P0 i' k7 O' C) X. b/ g
// 函数类型 : 自定义工具函数
1 C. K9 J/ e% ^! I) k+ t// 函数模块 : 键盘过滤模块0 D. r' G0 j; Q. l
////////////////////////////////////////////////////////////////* {6 y4 _3 D/ }! V/ e5 M$ s! z
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
0 Z/ a* y% S, C( `7 c% b  P//        信息,返回附加后的驱动对象# @' V) g; y* e2 S- R
// 注意 : 此函数仅挂接 USB 键盘设备
* O9 F3 x& z3 w$ k: S/////////////////////////////////////////////////////////////////; K% ~& q. P: u  F: a
// 作者 : sinister
& R% b: ]2 K" p3 P4 y; B* f// 发布版本 : 1.00.00& a) m% U% r9 i4 J5 s) s" p/ L- k
// 发布日期 : 2005.12.275 u2 E4 ^2 L, @/ G" F' b5 z/ o% I: Q
/////////////////////////////////////////////////////////////////
( y" {: x% ]1 x5 }: E/ U" t// 重   大   修   改   历   史* {- r: N5 Z" P4 a$ Y2 Y3 N/ I, R3 }
////////////////////////////////////////////////////////////////
, N3 c, F/ t0 g- W; n6 B// 修改者 :
9 N9 W# e# q" C0 r5 P// 修改日期 :; b: ?* D* N3 g1 ?& n: m; A+ f( r3 r
// 修改内容 :
# Q; g) n& S5 I/////////////////////////////////////////////////////////////////
0 d5 p3 y/ {" Q+ g( b/ ?+ w# }9 b3 k; C7 X" B
NTSTATUS1 x9 M" B+ D7 x5 o$ H
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,, N2 s) C2 z. |7 c+ L1 f  v: u
                         IN PDRIVER_OBJECT  DriverObject )5 `3 `8 F+ L. T2 B/ d
{4 F; W4 ?! S0 w! n4 G
  PDEVICE_OBJECT DeviceObject; * G& d7 Z* |7 _% R7 W6 i
  PDEVICE_OBJECT TargetDevice; : f9 ^* u3 M+ [8 d
  PDEVICE_EXTENSION DevExt;
0 L7 ]' P8 u: a  NTSTATUS ntStatus;
' J# j( E! o7 f' U) u( o' S2 U0 q
' N$ f- q; B$ A, [9 d7 u$ ]  //' l9 M9 v2 v( r; `; b+ G- `) C
  // 创建过滤设备对象( R3 y2 R4 G% [; ^. n8 r1 h
  //
" F( n6 K& p: S  ntStatus = IoCreateDevice( DriverObject,
8 `2 k  Q7 L: V0 L1 [                             sizeof( DEVICE_EXTENSION ),, k& f- f5 `% i+ ?! S
                             NULL,
9 n; d. {& e/ y) ^7 A6 U                             FILE_DEVICE_UNKNOWN,+ F4 b9 q; @7 d1 T$ [6 I6 [+ n; l5 K
                             0,5 S1 [& t2 `' k- |
                             FALSE,& z* g% b1 `  u2 P* g. ]
                             &DeviceObject ); . Y0 R7 V( e. L. e9 y3 e" {: W

' {0 K! h- N1 K% X  if ( !NT_SUCCESS( ntStatus ) )
1 \! Y. S$ t3 j& }# P5 N4 l  {5 m% \" S" A5 d
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
% t8 k  F, z6 M9 C; P% @. z) a    return ntStatus;
* S# c6 O3 N$ p, ^  }
5 i( l  P3 K5 l' ]! t, e0 z% Z! ~
& _: y# g0 B+ n  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;) b/ g2 w' r( ~

0 \3 \1 S% y  Q4 e& R  //# p# P6 F  X6 t/ k$ c5 L
  // 初始化自旋锁
! J7 a  h/ `% C# L: R) s  //
4 d1 j4 ], |# {7 @% O  KeInitializeSpinLock( &DevExt->SpinLock );8 D$ D+ o4 Q  L; l

/ N# a+ S, a  ]/ }/ V; L  //
4 b8 W7 J' t' v/ \  // 初始化 IRP 计数器. \! A) N; E  d! ?0 q
  //. A: \: L% R4 G
  DevExt->IrpsInProgress = 0;
3 i5 o  b& F" D0 L9 ~$ G! R0 q
9 ~' B8 I8 m2 b. {! Q  F% B  //# a% L. k6 }! i  d9 x
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象3 [) V9 \+ ]' n0 [- Z( j
  //
* O6 B) s: A4 q
7 r7 v' z' a7 R  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject );
* t  m" d. w* p% F8 M  if ( !TargetDevice )- F# B0 G* |% ]- v2 J
  {
5 N6 S- y" N; P3 U3 Q    IoDeleteDevice( DeviceObject ); ' R2 C1 N0 B: Z: |4 X
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
. H  Z! @1 J6 R4 U4 N    return STATUS_INSUFFICIENT_RESOURCES;$ B" f' T( \8 c1 ~2 _; G$ `/ E
  }
7 |/ g5 h8 p* Z; R" p. n  r% O5 O3 Q" z" w% O
  //
/ i; g1 U& E% V6 \# I% V/ y  // 保存过滤设备信息& G( s; J4 X$ f$ I
  //
: L4 q* i8 b# @$ l. ]- N  DevExt->DeviceObject = DeviceObject; - I9 H; I# v' h0 H% M, b6 c( g
  DevExt->TargetDevice = TargetDevice;
6 E: l( _  f% \( g$ m, U0 t, W* w; Q& I  T- ~
  //
5 L: q  G1 x' ]! z3 ?2 C  // 设置过滤设备相关信息与标志1 B! i$ g, S/ o) B/ x
  //3 K% y7 X! `4 D. @* p: r; T% [
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
  ]$ v4 i1 b% h% @! f) d  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
0 U$ E  X+ Y  y( N) a4 p: ~. i8 j( m

# ~, a7 X2 j, ?1 B/ X2 o! N  return STATUS_SUCCESS;
( E8 z- z6 i3 O# N+ \- I+ C) H2 i}
0 s# l3 b) i7 {5 L2 y: ]& k
, y  F1 w+ B: c" n' F1 P5 ]/////////////////////////////////////////////////////////////////$ T) L' G# K# L8 v4 W7 ~* n+ |: W
// 函数类型 : 自定义工具函数
$ U% |; x8 S3 G; G% F; L9 \// 函数模块 : 键盘过滤模块
' X- k1 W) T! [6 _( k////////////////////////////////////////////////////////////////$ P  O; o- j; V1 I% }
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
6 U/ l" {9 c4 z) v' M//        信息,返回附加后的驱动对象" U) @  d3 u2 Q3 t: c
// 注意 : 此函数仅挂接 PS/2 键盘设备
: k4 W1 E6 D/ i6 V  ?/////////////////////////////////////////////////////////////////
# a7 f& `; P7 [& C: g/ R' I& V// 作者 : sinister
, @3 G5 n2 q: Q) Q# c// 发布版本 : 1.00.002 V; ]7 H6 g6 O; [( w- x. S5 j& a+ O' A
// 发布日期 : 2005.12.27: u1 d% P. _9 R; r  Z) J: T
/////////////////////////////////////////////////////////////////
& \0 e8 |2 F2 m7 ~$ w// 重   大   修   改   历   史9 ^+ w, f# l1 L
////////////////////////////////////////////////////////////////7 C8 k# ^0 ^% n* U
// 修改者 :4 T$ O9 h9 e7 {
// 修改日期 :! F# k* H5 ^. y) I* g3 _
// 修改内容 :* J0 t" d. e8 b. H6 |# V
/////////////////////////////////////////////////////////////////
7 T8 U; M9 _3 O& D$ m* o2 T3 o# M$ n. ^6 ]9 W% k
NTSTATUS1 B  s# W2 r0 b6 L) e: H  i7 ?) c
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名
$ [- \( T' q' y, u3 j$ S# t                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
6 s* P- u# z! P5 N& p) T5 y0 {                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象; x* D  E& l1 b" f+ D' S9 ]1 t, K
{
0 ?/ I; ^3 l% n  c  PDEVICE_OBJECT DeviceObject;
; K2 a9 w' [% m5 L! J  PDEVICE_OBJECT FilterDeviceObject;
( g  T4 E8 p6 O  PDEVICE_OBJECT TargetDevice; . [. N- {7 \( j, f# B
  PFILE_OBJECT FileObject; $ x- K3 g; ~1 m; u
  PDEVICE_EXTENSION DevExt;4 Z- G# x9 T6 @; J' v) w
: @; A% R6 b! A- ~6 C: u9 g  ]
  NTSTATUS ntStatus; + b% T% n+ l! U" `, @

* }* |  H/ R( g6 Z  i  //- V- \: h8 s; M  w
  // 根据设备名称找到需要附加的设备对象
' ?* }3 |3 h6 p1 W3 z  //
9 w  P$ T2 v3 [) a; g8 Z  ntStatus = IoGetDeviceObjectPointer( DeviceName,2 V* |5 q9 f- a. f" q6 }$ l
                                       FILE_ALL_ACCESS,
( n8 O+ [5 C. H$ D! Z                                       &FileObject,3 ]* u1 l  O, Y  R
                                       &DeviceObject ); 1 r1 R2 ~0 @. C9 N9 n

+ i; q0 S3 c2 o  if ( !NT_SUCCESS( ntStatus ) )0 T0 J2 z! i% A' a9 [
  {: c( f( {6 \3 W
    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );0 T) e* B6 ^) p9 i: n) C" k
    return ntStatus;
( m) Z9 s7 K' V* s  }
: t1 b- `7 \" f) y+ J& z8 B) F, R9 D) |8 x9 s0 r9 c0 e3 M
  //
5 f1 @0 n. Z  b" @9 y9 c% D  // 创建过滤设备对象- |/ V3 X9 E) @
  //( Q: A( f& Q7 y3 C1 m4 P3 M7 u) n8 ?1 x
  ntStatus = IoCreateDevice( DriverObject,( u: m' P% _# P6 h# A
                             sizeof( DEVICE_EXTENSION ),
& f% _  }, {7 j5 S" n8 D/ }                             NULL,2 P' Y0 E. J4 h; D
                             FILE_DEVICE_KEYBOARD,
$ I# o" a" ?* g5 c* x                             0,
; ~, v( |. U; k1 |; {% |                             FALSE,0 D1 I* ]  Z3 V" N# K% X7 a
                             &FilterDeviceObject ); & b" B1 E) \! G; _8 |
5 ]% U( S0 J  s  u1 ?/ W0 `  C9 S
  if ( !NT_SUCCESS( ntStatus ) )
6 w" P; ^: F5 R& e1 r/ |& ]* Q1 ^6 @  {
7 Z6 |1 b. n! h0 o    ObDereferenceObject( FileObject );
* ^; Z, N4 d  @* l# @: x% D    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );) {8 k: n% c" f  w  F
    return ntStatus;
! M: U0 R6 u* r( {& u2 J  Z0 \' `  } 7 |' Z, _8 S. o8 i

$ X/ O' R* o0 x# k- }8 @. y1 |  //
5 ^5 q) h; M. O5 ?7 M- ?2 I. a  // 得到设备扩展结构,以便下面保存过滤设备信息
' N  J; u1 M8 D9 @& X, q  //
! L3 f- _) @9 S2 {: |  {  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;
5 v/ r1 U# M4 E% A
3 B2 [& ^6 g% _+ c3 r0 Z; n7 z; A" C) e% B* `
  //
+ I5 {! w' m9 N! d  // 初始化自旋锁- R$ ~* K" u& H! w
  //! H. u1 i8 D0 e& z- `
  KeInitializeSpinLock( &DevExt->SpinLock );
1 A5 U1 A# o7 N7 x. h0 D6 y
+ `/ n. l5 i& ]% Z  //
2 A( r: D8 R& z) W7 N  q  // 初始化 IRP 计数器
: K4 G1 |8 U1 ?  //( K  I% I; O# e' c/ k
  DevExt->IrpsInProgress = 0;0 N' p  O1 m( m1 C5 J! g. ~6 N
" Y$ m( c: s" o1 m4 U
  //
+ Q8 q! T1 z: @  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象& M$ T1 T- X6 n5 ]& C- f
  //
+ o7 G1 v# W  }  K  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,; E9 V% g, K) f- l$ H9 [0 s
                                              DeviceObject ); 0 o& U. m. z8 `; F( X, c2 V& t8 R5 ~
  if ( !TargetDevice )
# w5 k$ g  T5 I. u% i# n4 O  {
$ p2 b5 {; |1 g- E: n* h    ObDereferenceObject( FileObject ); 4 n& C; g1 z% U9 v* I' q; T
    IoDeleteDevice( FilterDeviceObject );
4 ?: n. C/ c, o    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );1 e1 @: X0 Y. [: I5 a
    return STATUS_INSUFFICIENT_RESOURCES;
5 `; w/ _( F8 x; y4 H  }
- C0 R. y( l* z$ b, C7 `/ _& O- [6 D& z1 _6 E* G4 S* j4 c9 W
  //
8 a/ @/ [! |, r/ A- ~  // 保存过滤设备信息5 \5 t2 ~+ h4 u. \) i/ V
  //5 n9 G6 y/ @* p+ d
  DevExt->DeviceObject = FilterDeviceObject;
  ~* x0 i: R' s  k  DevExt->TargetDevice = TargetDevice;
6 s% ^: y& m) }; e7 i5 x; w. O  DevExt->pFilterFileObject = FileObject;
' V7 M) S1 m2 Q0 u4 H% p5 H* Z' M' d
  //
0 X3 x( q0 k, }3 J; E5 S' W  // 设置过滤设备相关信息与标志" m) J" F$ h0 |: B3 {& j
  //- N! ?# r  l8 j% |$ O
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
+ H0 m% k+ K2 |8 O  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
! U+ E2 m4 @, [8 T, J, ^' o  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;1 {4 M9 q9 u+ O3 Q
  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |" d4 h4 ]% z' f4 ?) Z+ }
                                                         DO_BUFFERED_IO ) ); ; X- a! o. e. e) e, H+ F  n$ \

% ?/ \: E8 |2 p) U# A7 k; a  //! H  n( l8 b- h* [5 \9 o
  // 返回附加后的驱动对象
* g; ^7 C0 z* b6 p* w7 C; U  //
* `1 b! m, ?* t# J  f' S! F& t  *FilterDriverObject = TargetDevice->DriverObject;; q3 m7 a, e7 q, e# m( B1 ?( l
8 Y) v  A% ?' h% Y
  ObDereferenceObject( FileObject );
( G% Z/ _5 S* a
' e* z3 [$ j+ N; b6 p( g. N  k  D  return STATUS_SUCCESS;4 X* ]8 m. C' C/ L& Z
}5 o4 W- Z+ m. A& Z+ a
: C6 Q2 S, H" D
/////////////////////////////////////////////////////////////////
; m. m" t$ b7 w3 b# P: e// 函数类型 : 自定义工具函数6 T5 B  W3 r& b5 a6 f& |  z
// 函数模块 : 键盘过滤模块
. h: T% Y6 b: u; d1 C////////////////////////////////////////////////////////////////
: j9 A: H$ G$ r// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
) o2 y& m0 s! E' d2 N, e6 D//        这个 IRP 的完成- j- S3 X* A% K4 a
// 注意 : ( l+ L1 g& ]1 M4 m7 @
/////////////////////////////////////////////////////////////////* N# I. ^) n0 T1 n" m
// 作者 : sinister4 V- S; }& C* i7 m: \8 A2 l. j3 o/ x
// 发布版本 : 1.00.003 L, @+ C3 t( \  P8 g/ t$ c3 i
// 发布日期 : 2007.2.15: _$ {5 ^/ N9 X5 {6 E
/////////////////////////////////////////////////////////////////
" z, b& M$ I0 @6 R1 j// 重   大   修   改   历   史
- l# J; H8 o4 F+ q% M8 A0 t) ~6 S////////////////////////////////////////////////////////////////
0 R& H' g0 l+ r. P/ Y+ n// 修改者 :( g! D2 F0 }6 y
// 修改日期 :
' H; ?2 r5 W4 [+ ^// 修改内容 :( g. t1 g4 u7 y; s' e- ~
/////////////////////////////////////////////////////////////////
7 L. N, p+ {0 u3 Z) q& m1 M
/ a" f( w" V1 G' |* YNTSTATUS
& p& u* }; C, ~+ x; X* DKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )  ]" K* \. M, @+ l1 Z2 _! [5 [  L" G( @
{
+ ~  b3 V+ Q6 ^, V/ _- a- u  NTSTATUS status; ( A' c4 g; }3 |/ ]. i
  KIRQL IrqLevel;& ^, b, X, j( w0 `
; |0 W8 c2 |* }3 s2 v; }
  PDEVICE_OBJECT pDeviceObject;
' c' S* ?, p* p/ X  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
( c- p, J. A# G" Z2 G                                   DeviceObject->DeviceExtension; 1 _* ^! [) l2 u" G6 V3 a- T
1 D& a' _( J. M! E  O
# S9 k7 S- o; D" m' U2 m9 P& ^
  IoCopyCurrentIrpStackLocationToNext( Irp );
* Q0 F6 o; f0 @$ ~: g) |* B0 k  C, h  P
  //$ P' P; a5 S5 @( _) f- q4 {
  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
- H: }5 j+ F5 k1 H# S) p; Q  //
8 m4 M7 Y; n3 ~! J  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );/ n/ e. m" x' W8 q# t, Z
  InterlockedIncrement( &KeyExtension->IrpsInProgress );5 v0 J9 q/ ~/ W* B; G, l9 R
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
) h1 d$ f* u4 S. X
" b" t  {8 S- ]: H* k6 W  IoSetCompletionRoutine( Irp,
) V) l2 s5 T0 k# ~' Y                          KeyReadCompletion,
/ ]$ Q9 K. M3 X5 ?/ @; W+ n                          DeviceObject,
  K/ `' A$ k  \0 b                          TRUE,
7 L4 R: ?+ e) t: W( l& J, T  ^                          TRUE,
+ J7 b+ o' \  l: ]6 j/ E: i  A                          TRUE ); 3 H: S3 n3 ^  v, O% b4 D: V- K

8 Z3 ?' E' f1 L$ r9 S8 l* y  return IoCallDriver( KeyExtension->TargetDevice, Irp );
0 A! ?% y# m' Y3 k} ! A$ q. }1 E1 R5 {1 u: I

; _7 ]) _0 h, @$ e' O# |- M2 g2 n+ t/////////////////////////////////////////////////////////////////. y# D9 l* M! }. v# C
// 函数类型 :系统回调函数. K. r8 L* c9 T9 f# ?, D6 H. E  h
// 函数模块 : 键盘过滤模块
/ i2 L" h8 }, v5 i# O////////////////////////////////////////////////////////////////5 }! i3 [& s+ f( p$ F4 r0 S
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
& p0 b8 @# K% _# M& @// 注意 :
2 Q9 R2 B! D# z/////////////////////////////////////////////////////////////////, U0 _" W4 {" I+ a: b  l
// 作者 : sinister6 T0 y! E- y& s! X' A8 M
// 发布版本 : 1.00.00
" M- y- T+ S  ?2 I. Z* x) X// 发布日期 : 2007.2.12
! n; h* f$ {6 ?7 n2 s4 m/////////////////////////////////////////////////////////////////; `! ?1 a& {( f7 L# m
// 重   大   修   改   历   史
3 ^: o- T# t* G; q4 m+ V- j' }////////////////////////////////////////////////////////////////
- t: u/ C7 }. }0 v+ K8 }7 U+ `// 修改者 :
+ z) h. D& {! w8 i6 H  n// 修改日期 :
- |! G: n9 v* R+ U) o1 t. j// 修改内容 :
  ]4 l, G4 K: {* S' I/////////////////////////////////////////////////////////////////( S, k- `6 |* b$ D

2 ^6 ^2 |5 n, a) a) }" ^& WNTSTATUS
0 A/ g9 |' [; w# t+ P3 k. I! nKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
7 Y8 h( j* ?+ D. g# l) F                   IN PIRP Irp,3 r# C$ D( C9 J$ G
                   IN PVOID Context )
% x+ B& j/ ?2 t9 Y. L$ U1 e$ s{
) p# E- u2 @5 ^& K: D  PIO_STACK_LOCATION IrpSp;- s* f# i% P* y! u
  PKEYBOARD_INPUT_DATA KeyData;
  Q& r$ R. `9 B9 W7 o4 Z  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )$ a: t% b: `" b& m) L6 X/ F
                                   DeviceObject->DeviceExtension;
( u* T0 e! C  I, o0 H1 ?- @5 t  int numKeys, i;5 q/ [5 S& h( G: {0 c8 r% V
  KIRQL IrqLevel;$ O: }* ^& k; K/ t2 h

) L  o- ~! Y/ U& H  IrpSp = IoGetCurrentIrpStackLocation( Irp );
$ Q0 U' `4 s; U$ ?, x8 h( l: U
. d/ ]: H8 r5 l; \+ ^  f$ g! h2 ]) y' j$ n- b
  if ( Irp->IoStatus.Status != STATUS_SUCCESS )
) y  Q, H( @  u- y" d  {5 M% [& k# v' N- b2 k. h9 N6 ~& z
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
3 _& `- j# `! m% _' M7 k2 L6 o    goto __RoutineEnd;
0 G5 _3 e9 [7 z8 A, X  }" O/ R* w2 s9 ~+ @9 {9 G

+ a( y( f( o9 \9 G  //  ]6 v2 q  G4 p2 C# ?' W1 R
  // 系统在 SystemBuffer 中保存按键信息3 g: _' T' L% d3 U+ |
  //
4 z0 k2 y, W2 G' j$ e  KeyData = Irp->AssociatedIrp.SystemBuffer;
$ D: m( C- K( U. i* s& r  if ( KeyData == NULL )
( }8 W! a9 y. D: g! f0 _  {
7 h8 O  N2 F. M" Z3 h# ?% j; N+ ]    DbgPrint( "KeyData is NULL\n" );/ `1 G* x3 M: g1 [. j
    goto __RoutineEnd;
% B! ^7 n1 Q% b5 r+ ]  }) n0 A" u7 z7 n2 ~# B* ?( G! K6 `

3 r* f+ P* @. d0 O" c6 r  //% l5 h2 j# \$ \5 T
  // 得到按键数( R! ~% M' b1 ^
  //
3 |3 q2 w2 m2 a; i  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
- P! a7 X  B3 B* e  if ( numKeys < 0 )
  d0 S6 A; \  u9 ~; f8 A1 a2 Z0 Q  {
+ M( o! y& E! O4 g( r4 p0 t6 q; v  x: N    DbgPrint( "numKeys less zero\n" );
3 k( q# l8 s4 J% U0 X6 f    goto __RoutineEnd;
2 I5 z8 n( c$ \) c( h1 f1 O6 @  }( @% d1 t& e; _1 g

* {0 T$ Q/ q3 n# w! u  //9 k/ T+ D; y) P3 I5 _/ O* ]
  // 使用 0 无效扫描码替换,屏蔽所有按键
$ {) d9 _' L& C% N8 ]  //
# l3 N& p9 p; h9 I# e  for ( i = 0; i < numKeys; i++ )+ S4 ^; K' b8 y1 {- Q% Q
  {$ O0 B* ?6 ?' f! D& H  k! I8 a
    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
) Z$ n0 ^, Z* R# l    KeyData[i].MakeCode = 0x00;  d" g, l; R  d3 S7 `+ ~9 _* T
  }2 k' {% F* e( t0 }+ @2 o
+ m7 b9 W& E6 k; I2 O+ m  B& W; y
+ R1 I$ ^' P& a( b7 t1 x; a
  __RoutineEnd :
# ~5 u/ n' L; L; v+ {9 w. p  L3 A) }% L0 l! K6 u1 u
  if ( Irp->PendingReturned ), l) ]  L2 [! ?0 d
  {
- v2 J2 J( j& n$ T# ^! t' T    IoMarkIrpPending( Irp );
- o. l5 i* [& [& z. S  } - D# O: d: s" ~; Q" i" d$ @) b
$ V( Z' N" A5 j) t7 U
  //( y. R+ d; H2 f6 g6 U5 G9 {
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁1 H4 P9 l% t! Y, ]
  //6 X9 D7 G( i3 p- t( B2 N+ e9 Y
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );$ \5 d$ ~' R- X% X5 [
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
, ], X! `. k  n- T. W7 `: g8 o: b  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );! i1 m0 H8 t/ o) T5 M. d) i  P
, {/ Q  v- [- L2 S" R/ S0 M
  return Irp->IoStatus.Status ;
8 ?% C- W3 m* @) ]7 D$ l8 Z}
5 X6 X8 P4 m: u) P* Q1 V$ S( [
& `5 O! x6 ^) F, K& |3 i' p: L" s
" T. j1 M8 H1 b4 v. s. ^' D; Y( O/*****************************************************************/ x8 ?, f" k$ q8 z2 r6 n& A$ ]
文件名        : WssLockKey.h
6 r) P" B. c9 E 描述          : 键盘过滤驱动# A. X; q! z% A) }. C$ ?0 @1 G8 a8 d2 `
作者          : sinister
. R/ X9 z, L! I1 |8 n, x' Q/ K 最后修改日期  : 2007-02-26
" `3 {- t& _# N4 W  F. A*****************************************************************/8 N% G' o6 [( K! B; \; m# I7 V
% A; W" Z  k6 P" c$ L! R
#ifndef __WSS_LOCKKEY_H_1 V/ ?3 k! h; `  [. o
#define __WSS_LOCKKEY_H_
' \9 Q. ^# B! m4 x
3 {  l) a0 K' I4 y0 v% n0 G+ C#include "ntddk.h"5 A. F6 {$ p# `5 P# R$ f
#include "ntddkbd.h"9 ?0 J6 X& L+ N
#include "string.h"
% n6 p5 U4 r0 b+ ~' N4 r5 I#include
- H7 i1 }% d; w9 C/ f6 T* s9 I; U8 G/ v
#define MAXLEN 256
0 E9 V  J6 z0 C4 }6 A* c5 E9 K$ \) s. b. \- r# g: Y9 v* \
#define KDBDEVICENAME L"\\Driver\\kbdhid"% G0 J+ }8 i7 P# B( w' g4 o# B' H1 S
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
! R% d6 a: h3 `  T! F. @- t1 ^#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"- r2 v8 X5 r" J4 r' E/ `- x$ x: B, N9 Y
7 w& L  |/ j) M/ R4 ]
typedef struct _OBJECT_CREATE_INFORMATION
7 ^, p7 i4 h7 U{
8 Z( D' a0 d- T" o& H- y0 y    ULONG Attributes;/ U$ {! _5 y: e! }+ y6 }
    HANDLE RootDirectory;
* l+ |; y) z0 o4 ~+ I% I7 ~: A    PVOID ParseContext;2 ~# y) q5 c) H+ {- D- a1 J$ M
    KPROCESSOR_MODE ProbeMode;5 H' W: s- s) w) E
    ULONG PagedPoolCharge;6 O1 y2 J7 L. Z
    ULONG NonPagedPoolCharge;
' x8 `1 f/ p2 L) y    ULONG SecurityDescriptorCharge;
) U% Y9 x5 d: m! P5 P    PSECURITY_DESCRIPTOR SecurityDescriptor;& J3 a2 t( X$ H- ]- C' x% Q, u7 K
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;3 j. C) A- d- W0 }9 K4 Y
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
! r  I/ s) ]6 S9 l5 M} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
& |- @" F1 [4 M" ~+ L# a& ^6 v$ x6 s9 T# Y9 v7 L: f4 B  H0 A
typedef struct _OBJECT_HEADER
' X* h! {5 G9 N- O+ B9 `$ f8 ?4 r{
1 ]7 s/ R, C( E" ], K    LONG PointerCount;" c: ]% D7 e8 M5 A
    union
7 }: g+ s4 z$ o2 |! e. q, |1 [    {, u. A3 M# }, k' T( v
        LONG HandleCount;1 _9 B/ J+ P% {0 V, `
        PSINGLE_LIST_ENTRY SEntry;9 R0 I3 P7 a" E" o
    };
: T% M( _1 u; x4 r2 G1 \    POBJECT_TYPE Type;
" f" j! W: B- w4 {  d5 W$ x    UCHAR NameInfoOffset;, e2 F0 }; I3 n9 m2 v! F
    UCHAR HandleInfoOffset;8 z$ W4 k3 D; _* ?% a
    UCHAR QuotaInfoOffset;2 Y/ a6 `+ t& P* r" w
    UCHAR Flags;
6 W7 Y2 F% h  r. p1 J- s! `    union
9 ~) }6 T4 J$ _0 s    {
$ [8 u/ r& b0 t" _* s1 B        POBJECT_CREATE_INFORMATION ObjectCreateInfo;7 \. Z4 K/ G! E* O7 t2 o' d
        PVOID QuotaBlockCharged;# W! _3 p; G; K( t$ I; i
    };
2 U* P- L8 ?7 x+ A) Q
7 F; `$ Z* f. j" q5 S# l    PSECURITY_DESCRIPTOR SecurityDescriptor;  w, n( F$ D" S: b. D. s
    QUAD Body;3 k7 V: N* J, w# r( F
} OBJECT_HEADER, * POBJECT_HEADER;7 p( w& G1 b6 p1 a. b3 t3 _$ {

( a7 q* C/ z" {+ C" f) F7 L#define NUMBER_HASH_BUCKETS 372 V9 M6 n5 e$ f+ l

: n* t4 i7 m5 ?/ {0 Y% itypedef struct _OBJECT_DIRECTORY
+ r$ l2 Y8 ~0 T0 G. x% d{8 n1 k& x! P8 F0 J
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];( m  b7 G- X5 \: B3 j; m
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;* H3 f2 Y$ T; C. s! _! Q
    BOOLEAN LookupFound;
$ j. U- e" z/ `1 q( R' W+ l4 i    USHORT SymbolicLinkUsageCount;
; k: _, i, j" P0 _% }. T    struct _DEVICE_MAP* DeviceMap;7 Y$ s" E8 T  p
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
+ j# F9 b, p2 \: x0 z+ l" y
7 s! X. P0 R* S5 r1 x- ttypedef struct _OBJECT_HEADER_NAME_INFO9 J# {3 h9 [! `' Y$ G9 _; @1 l
{
! q! }3 T* ?! ?7 j- t# t, k    POBJECT_DIRECTORY Directory;
2 h1 V: ?0 n6 Z% [# x5 C/ {    UNICODE_STRING Name;
" Y* R4 n, _  L+ H# p( y+ \5 m" |    ULONG Reserved;
" q$ |0 s4 l# t, _2 |#if DBG: P2 K' d5 V. O  r, q: I9 s6 I
    ULONG Reserved2 ;
% T  _& X  g, l" t  x    LONG DbgDereferenceCount ;1 K" c9 C: G& T- F0 }$ ?- c
#endif
9 I; y) R4 C7 x" G! S5 u0 V} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
. M5 `) X3 I0 E. h; y  e: T( t' Q1 D/ U/ K. D& Q4 @
#define OBJECT_TO_OBJECT_HEADER( o ) \
; M5 m- S6 G) V7 W. U    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
& \! k2 e5 Z/ u7 k8 R3 H* i+ y' p3 T8 q2 f
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
% A8 k! j* |5 S$ I    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset))): s5 a2 D2 f8 y% N3 i$ V  X
" D+ H% V% S+ b5 E" L
typedef struct _DEVICE_EXTENSION
. K6 a0 y* Z/ m  [8 g! {( D{
# y! D) p7 g6 `2 Z+ }    PDEVICE_OBJECT DeviceObject;
. K0 F+ \* P) E5 G, o    PDEVICE_OBJECT TargetDevice;
* x4 {+ n0 }$ N& H    PFILE_OBJECT pFilterFileObject;7 H  h& M# C3 T- C; o
    ULONG DeviceExtensionFlags;
  f' @( I& H+ C/ y    LONG IrpsInProgress;6 ^( M( R/ @$ ^
    KSPIN_LOCK SpinLock;
) \/ G7 ]9 _1 _& o( z! R}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
% b' A9 A9 L4 w# D1 S$ U" a0 ~+ M: E  x
8 e* ?% Z) {% [2 u' i( K
VOID
( ^* f* V! `8 z8 DKeyDriverUnload( PDRIVER_OBJECT KeyDriver );" x# ]9 W7 T! A- n
9 u4 |2 W0 @: Q0 |0 b
BOOLEAN
2 l: B8 q- a) YCancelKeyboardIrp( IN PIRP Irp );
6 Z7 Z; K6 v- i& F& P
) T' H  ~/ a0 n7 G$ a3 ]extern POBJECT_TYPE* IoDriverObjectType;
3 W- i8 s" N. S; z8 d
  h4 b0 U7 G' `5 GNTSYSAPI
/ b* ^# d( c7 Z% c; f% D8 CNTSTATUS
. q9 z+ ~+ Z& |3 \9 K6 ANTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,0 e( e9 q7 K: p% W- s
                               IN ULONG Attributes,: w3 ^, p6 ^1 S2 G! M1 k, u
                               IN PACCESS_STATE AccessState OPTIONAL,$ R1 m! G" J6 p; b
                               IN ACCESS_MASK DesiredAccess OPTIONAL,; X- o5 i. m) t9 d. y& n
                               IN POBJECT_TYPE ObjectType,
0 x' L; l4 u3 r6 J8 m                               IN KPROCESSOR_MODE AccessMode,. |: k/ t: t! v( y  p9 x
                               IN OUT PVOID ParseContext OPTIONAL,  A0 X' L" \2 _4 L4 T" f; L- w3 g
                               OUT PVOID* Object );6 k( r$ Q/ h* {7 O. q

! h5 C9 \; A6 e/ P" [. sNTSTATUS 1 p2 {7 y( U- K' [. s: m
GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
) w0 d0 _4 b; F  S; V  |
2 K5 _; K# z; U" d# h* C9 v* k; z5 NBOOLEAN
' D' b+ r% G* o& E, rGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );
6 \) n/ \9 A3 ~, J( T8 a- O
9 P4 s3 }& k& R( j" r& R  S& OVOID
2 N9 W' Y7 A# p. IGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );$ E1 u+ F! e& c' g# b2 v" {# y2 ^
/ S2 C8 ^* [# w3 _2 F* P" e
NTSTATUS
( r8 @# _  w# c7 A+ S, OAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
( D' z8 n4 ]0 L% ?; A                                  IN PDRIVER_OBJECT  DriverObject );& n6 L& m, d$ X; E- j7 I; s" R/ Y
$ z% @5 i' T' l5 G
NTSTATUS
3 A  A  _# h2 v" b# [* X5 pAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,
  k) ^* S1 F  e; H6 E7 T                                  IN PDRIVER_OBJECT  DriverObject,
3 H" G# j- t0 k' g                                  OUT PDRIVER_OBJECT* FilterDriverObject );
+ h' I6 i2 M# U6 {2 G; Y$ I! t, o
- F' p' O* h$ O" B. xNTSTATUS
8 Y- v% K) d7 i. T' XKeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
4 x+ a1 h/ R: B* w9 Z, i/ X                            IN PIRP Irp,0 x8 r8 ^) f- F/ E( U: f$ s
                            IN PVOID Context );
' i% U& w* z7 p) h% \3 U6 [. fNTSTATUS
. W8 }1 Z6 F$ q7 E0 D- |5 K2 LKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
; l6 H1 n) A$ Y2 ^$ m1 a7 }
& l( p+ n0 i1 k7 RWCHAR szUsbDeviceName[MAXLEN];
7 _% R& E' T9 b1 ]& ]! L
# d0 O. K5 S* e8 N#endif
5 G. t: P; |/ J1 n" g
, N( H+ {- b7 G6 H) z# ?) t* E1 T# Y# f9 ~/ B8 G: f' P
# J6 ^+ t0 b' e4 C

, k' d3 a$ s, C3 J
' A9 j% o1 G0 ]4 C5 _0 BWSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
' c/ A/ z) j3 h3 T$ iWSS 主页:[url]http://www.whitecell.org/[/url]
/ z9 a0 s6 D! g( xWSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-29 02:40 , Processed in 0.076634 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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