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

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

[复制链接]
发表于 2007-11-16 12:01:11 | 显示全部楼层 |阅读模式
Author:  sinister
! S7 o7 B! |5 T4 c5 `Email:   [email]sinister@whitecell.org[/email]
2 s0 c  f9 z8 R6 N; ]Homepage:[url]http://www.whitecell.org[/url]
% S# S) |4 c6 R, }Date:    2007-02-262 W' A9 m/ Q1 k

1 I, g: q' A2 N/ r1 T
7 {* m7 F: e; f6 q# T/*******************************************************************
( R5 ~1 a+ y+ R& I3 w! `/ _
$ J  U7 B9 u6 C7 h/ ^, @$ A/ U这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx9 l0 S* A) H4 n& k) g+ n
写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
- U$ z- `0 v3 ?8 Q) T7 r& h8 s. s功能要求如下:( I' B0 W9 m2 W8 Z* v. P# D* Q  m: n9 c
; l% x- m; B' w$ h
1、强制锁定键盘/鼠标。7 O7 U( J& C5 U4 c6 X( d2 e
2、可动态加/解锁
6 w, a2 j  O3 Q) x- {' c" r5 D3、兼容所有 NT 系列的操作系统。1 {7 Z8 c+ o3 J$ ^
0 y0 m2 D* k  f( k" w) J6 ]/ @
就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实2 m+ U3 Y+ r1 V
现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如
; I* i1 r9 f4 d; K4 Z0 h* m) C何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在2 t3 b& C) Z& j9 g7 q
上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是" P5 O: [1 u; c6 q3 \1 A# I* L
怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面4 w3 z* n5 y! N: F1 B% y+ L2 }
就来看一下我想到的几种实现方法:$ y1 h1 c, y; K4 R  ]

: q. e/ V* t3 ^& `- N1、全局键盘/鼠标钩子+ D. ?8 c8 q& s
2、BlockInput() API
6 q7 G& t; n7 F' H- C* r3、使用 setupapi 进行控制$ ~' S5 s9 C# m0 ~4 u
4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL
9 G9 a0 X2 r5 ~1 D7 ?; d5、拦截 win23k!RawInputThread() 函数
' G3 l+ \4 c0 p; n1 m7 K1 e6 c6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动
  {+ J% f" s' [2 \1 L& U7、拦截 kdbclass 驱动的 driver dispatch routine- c) U: A( D$ [
8、实现一个 PS/2 与 USB 键盘过滤驱动: ]7 ~# x9 x9 b& v

7 R: b+ |  o1 s; D- k5 O
0 H' n8 c" `% K$ S* X% _8 X% k我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
/ c3 D' t+ i  \! i0 t  j* j之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方7 E" e$ ]& s8 F, z' A% J
案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在# T4 c* ~4 i. ^  z1 L& t7 ^
兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因! C" r$ U7 s; p' B& M
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性9 `  }* ^9 i2 x
问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸
# R8 f( W) z: K  r) T载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
% L: q+ {4 c  Q! K8 v& U# }  V的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来
9 F" b  f" ?$ h. x" O& m2 Y也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
+ w+ U3 M. N, {  w果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有5 d9 z: |7 U7 e  t6 y
障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
7 f( }6 I7 e; S# KIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 # }2 D; F. \+ O9 m: q
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
( e+ A  J  C4 I7 w9 M盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方9 L2 e8 E) L4 t+ d; ]$ y
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
( v$ E* l8 D- o; ~; d$ z: W
) I: U2 Z/ E  l7 U) t4 V& G& ^1 _- V- J, g3 }
我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
/ n& d' p3 F6 ?9 ^/ H9 m- }滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进# u0 D7 ~/ `8 Q' M1 H
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
" A) p; N  s- a, ?# x只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越3 ~" |! V; G, F7 x9 N5 @; p) {
来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从
, f- I: c' x) A! U+ A0 u% i( sKeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB9 U5 [, }0 i" s6 A/ I% V" v
键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用& s, r9 c2 l4 |8 Y2 ~, S6 \/ G* V
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,
8 D8 a6 n7 g' f# T/ ~5 Y# B+ ~我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
8 Q: z# S5 X% l9 o就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的5 v( m& W9 [* x/ Q4 {! j* U6 T
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使7 E& a( V; a! ?% E
用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通' d& h& p2 I  M, o: m, t& p
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来( @! D" K: b/ i0 z' ~2 q: P
屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通. a/ u4 G% ?+ Q) {6 I4 H# n' W, C
过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
9 V% M1 ~7 Y! s) [, F; g2 S6 t1 }/ O上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid & }% \: L( p+ F$ R5 n9 ^
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意$ q* X7 c' O+ i& b, Y; `2 ~3 u
味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
4 M' ^* |1 _+ ^4 T. @经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
6 Q* s5 y3 K% H9 g8 c' z& O; t, X来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
' N( e' n( U& S1 W' }( O的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo* e, P% L- t: |5 Q
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
4 @9 [2 d/ {3 j  e. j敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,( W* B- U: N$ ?
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程
% s9 T6 j7 ~+ j+ x见下面代码。
# V6 H' S$ `# o4 ?7 |5 x% ]: g5 D) \- H
这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程# z8 }* ^& H+ ?# g7 |5 e
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键
9 J& S5 K" D0 K; S# B盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
7 A* f0 v/ W* x; u上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
! F1 ?9 J3 J2 r' }& Y2 w& H1 ?完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可
+ {5 Q5 t- }3 q+ P; Y继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
2 @& {9 j/ [' U3 j# L0 e" p5 m) h) u锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按8 l: c6 X( ]) j4 e' O
键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。8 B3 s* {& }; j- `

1 h7 N9 m! v' _! p: Q2 V8 }2 S" O9 P
/ l, k6 R" p6 a! Y6 k完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用
; R* W" {" r( @的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是' ?) _7 \# L- j6 |0 f7 ^
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣) i: x5 f- x, @4 d% D# j0 X; P! F" `
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我' F& W$ e% X& a$ Q
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
4 B7 m* R: f9 Z们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension% E4 v/ q$ `! p: @5 a% G
->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。. v" S4 ]5 \7 q0 ^: y  a# j# m
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
' ~; t6 f% K1 G. N进行操作了。这个问题有待大家来完善了。/ o+ b; E/ z- b, D* E, [

' w3 E$ U# j* X# L" I! \2 R# I; `
要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出7 e  K. A7 ]4 k' J# {1 s
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的
! X, B9 v, D4 t* P9 N8 x; |9 H. R分析做个记录而已。我更愿意把它看做是一段注释。
+ a1 e$ W4 G. a7 M5 R" l% C3 v3 V3 S4 y
最后在此代码中要
) J7 K0 A' T! M' H( w  g  F* M- D& ^5 O
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。
8 L4 I/ x2 S$ ~8 n' Q, q* ^
* H0 h& O& A# b% r7 @: L# c4 Z感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
3 |; W' e. x- M5 h- ]* f4 N8 f  z& q. ?* S  f+ j. b
感谢:齐佳佳,过节请我吃好吃的。; ~" G* q6 J; a
# q1 z( X. K- Z# j2 u

9 ]; M) O8 }' b2 x$ }5 E******************************************************************/0 b0 ~1 ]2 O) w8 \

7 ~& }1 i' R; ]5 v1 }5 [- ?7 R: ~' w/ z$ k5 `& |- }* k1 m. X  V
/*****************************************************************% o) O; ]- N; f
文件名        : WssLockKey.c
8 l" i( Z  P% l" h 描述          : 键盘过滤驱动9 L# b3 q9 g3 x5 L7 L2 T# H
作者          : sinister
+ T  N* X) W( z3 w+ h 最后修改日期  : 2007-02-26: f: j* k; U+ S% B% e
*****************************************************************/" C9 z$ |! J% |1 l5 A+ X

- O! M" R2 m5 X0 l: V1 @6 y  Q6 {3 s7 {& ?
#include "WssLockKey.h"
& U  Q3 C/ v7 r3 X, }9 x! }. C0 J9 ~% ]) I. J6 c" |
NTSTATUS
2 x! E" `$ M; y6 \  hDriverEntry( IN PDRIVER_OBJECT KeyDriverObject,& D) ], W% e2 w0 z& D1 F+ t* s
             IN PUNICODE_STRING RegistryPath )
( Q8 N5 ^0 a8 p{
( m2 D  S8 r0 K# i# T% R  h" f  t4 g  UNICODE_STRING KeyDeviceName;
$ \8 n4 O& A( L8 v  PDRIVER_OBJECT KeyDriver;
" T/ q: l/ V5 R7 d  PDEVICE_OBJECT UsbDeviceObject;6 k/ C' o( ^& ~( T" f
  NTSTATUS ntStatus; 8 n& N9 J( D7 |9 i% l. f
  ULONG i;
8 q4 [/ O1 g! E' A% p8 J! J* O& z. h% m- R1 j! [
  //
+ q7 C  [: F' [8 l  // 保存设备名,调试使用3 G% I( d% S9 m7 |  O  K, s: T
  //
, m2 z  ~6 w- ]" Q2 K+ x6 H8 \  WCHAR szDeviceName[MAXLEN + MAXLEN] =% o: j7 F4 r& w2 d" |
  {
1 U  n0 I. B( e    0$ ]0 v9 Y2 P6 ^
  };0 l) A9 ~9 x  o# x* @; ?9 Z

- W" S9 Y- F6 ]  KeyDriverObject->DriverUnload = KeyDriverUnload;
" Y9 ]9 P# }3 R- R0 t
) t8 K4 D+ I5 b+ P. i( V  //" x6 b& D  P2 H2 q# ]
  // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
  a5 K- c' v0 B2 m  //
; ~% x6 ?3 |8 }* w" F" H; M$ K8 b+ D  // 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
: u3 W1 ]3 \& [; Q& w% S2 z) T* T  // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其" ?0 b; R1 C* H& O* J
  // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到! m7 G) j1 l1 ?/ j
  // USB 键盘设备来进行挂接
* C  A% v( K& M  //
' {2 X( K: C$ z  ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );) d" f6 p7 j* ?) e8 ?; A( X" v
  if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )7 Z9 M4 i) V- B' U
  {7 w* ~7 W) ]8 x
    //
" W, H# W' q* h! \: e    // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名4 ]& u9 G/ Z3 ^4 p/ l
    // 所以这里打印为空
7 o# I1 i$ b! Z1 O- P    //1 L/ T1 j9 \. g0 e/ d
    RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
( [! X/ r1 A4 \  e' e    DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );8 T, Q+ Q6 z' \: H

% R" g) V: H: c9 z/ q; K7 a    //8 u* X( s& ]6 `3 ?+ |, x9 q2 Q4 \
    // 挂接 USB 键盘设备* r& z# b5 z" j( r! W  Y% E" s
    //
& q( r0 _7 E2 i, e    ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
6 r6 {9 S' Z/ q    if ( !NT_SUCCESS( ntStatus ) )0 x. w! b$ R7 Q  l% u0 d
    {
% O" N6 G1 b! {; n) U1 N) R% Y      DbgPrint( "Attach USB Keyboard Device to failed!\n" );! m* {: p' C" N9 A( d& f. d
      return STATUS_INSUFFICIENT_RESOURCES;
1 F$ d3 o$ i* A: s& ]+ J# o8 C    }: Z7 k5 z8 I+ d% f
  }; }  {9 P- ~/ a  f. b
  else
) H- u/ H  K. Q  {+ p) j- J0 j& W( [
    //4 K, w3 U# C- H+ M5 r
    // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备. I8 c" I- L: Q8 E8 r
    // ' g. U: Q( Q6 ]4 V& `5 o8 c$ q
    RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); * y& d/ q. s1 N. _
' h4 k3 P5 S) s: S. _/ v
    ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
; b( T7 `; [8 D  L$ R2 |                                        KeyDriverObject,' ~$ q9 Y4 l  F; m
                                        &KeyDriver );
) i+ p# Q% u- J    if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )* M/ q) b' w5 b: g: j) z+ W% f, D
    {' W& x; P, b5 V  a
      DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );# M: F3 J6 U( }/ u& m; h' N3 m
      return STATUS_INSUFFICIENT_RESOURCES;
; R0 A4 d; Q' n" u2 v+ ]    }9 Q5 z  W# P. z
  }9 N4 ]3 v0 s7 Q+ H

  b  a& P) n& {: l% K  //
2 v3 g, o4 ]# B! B& I. a" w4 |  // 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
0 v# w! o9 Y3 g" R& v8 ]2 d2 l6 Q; l  // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
" f0 n$ b  D" p8 ]  //
1 W* z# k8 I6 @, @, |' m: A. p7 d  KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
8 s5 @+ i$ N2 e- I8 l0 Q7 R* i$ E8 H2 x- ^
  return STATUS_SUCCESS;
: A4 r3 l! P' ^5 x. M3 ^}
0 X, n; i* ?! I3 A) x4 _, A
4 n1 ?" d3 C$ T5 u/////////////////////////////////////////////////////////////////7 _0 S* U8 N/ {( m
// 函数类型 : 系统函数
* W+ K5 p( n" Y& a! k# T" i// 函数模块 : 键盘过滤模块+ I5 ^# Y# V4 y! n/ ]" a5 E
////////////////////////////////////////////////////////////////
* t" S8 f, ~- Q) m7 a9 H// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,- j' u& N9 M' ]. q6 O
//        卸载键盘过滤驱动: l9 p" D1 G8 {
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
& }# v$ \6 k0 @//        则需要等待用户按键,以后有待完善
# k2 s, t1 Z* E0 v/////////////////////////////////////////////////////////////////9 m$ Z8 }6 c. s, p
// 作者 : sinister
6 e( U4 u( y+ S9 Q* }+ T// 发布版本 : 1.00.00
. F3 m) o6 u8 M, O; T$ ?# j' S// 发布日期 : 2005.12.27+ S4 v3 E- M' A0 ?8 Z
/////////////////////////////////////////////////////////////////
( W. R) o2 J, g/ o2 L; u// 重   大   修   改   历   史: m$ J' O0 R2 B0 a) D6 H1 z
////////////////////////////////////////////////////////////////, H1 N" q. s! L! N7 V
// 修改者 :
0 M$ p$ V/ P$ [// 修改日期 :
, q7 t# o2 k1 n- e// 修改内容 :
/ k) i* F% N- Y! k# J/////////////////////////////////////////////////////////////////' f" N. H1 z4 _0 ^* w
* F  R; v+ c7 ]4 I4 B
VOID8 D5 |6 f/ `% {  N% v
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
8 T- q! D) Z4 m{
2 r- F9 ]1 B$ Y+ l: L  PDEVICE_OBJECT KeyFilterDevice ;      
0 `! ]' l) s+ Q/ B, }! v  PDEVICE_OBJECT KeyDevice ;
" Z5 l9 g+ K! C7 X/ J  PDEVICE_EXTENSION KeyExtension; . R/ k. n4 z$ y' |3 R" G5 [# g  a
  PIRP Irp;: m1 U6 J0 Y' j
  NTSTATUS ntStatus;
1 ?  g3 f! H6 H0 Q4 V2 l  d5 B& H- ?+ K+ w
  KeyFilterDevice = KeyDriver->DeviceObject;
: \( w, ?; l, X/ j8 E; d, L  KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension; : t+ B  x+ F; _% h
  KeyDevice = KeyExtension->TargetDevice;
5 R0 u, g! r1 ]# N" y& l8 X8 O" ~& C- V
  IoDetachDevice( KeyDevice );
( r1 y5 ]2 i% k" l1 r+ o& y' R# W% E
  //
' ]4 L2 Z1 [2 q) [% {) \& o+ {( x  // 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP' ~1 i1 n$ R$ k! i: u. L
  //! v1 x5 z3 }. i6 Q
  if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL ). c+ e, ?! \: m- |% n, \: x
  {
+ T- L2 M+ [, f* z    if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )2 q: M6 P( P- L% E, x8 \3 H: O
    {/ G6 j1 [1 F: Z- K
      //
& h) e: Q; p* F! U8 R2 l: {      // 成功则直接退出删除键盘过滤设备
# N! M6 |# O% P! s      //( N/ k8 H+ c+ Q( e1 i7 J
      DbgPrint( "CancelKeyboardIrp() is ok\n" );
5 y" w+ z, J/ k7 m8 a2 M      goto __End;2 h$ h5 M' Q- u: F
    }0 g" R7 M; u0 P+ I, F* X& d
  }  a/ U+ o$ O0 G% b9 E0 P

8 |: @7 i; R  ^6 ?4 J7 \6 [1 I$ n  //
0 Q% m( r! z, C# e  // 如果取消失败,则一直等待按键
: h8 y7 s9 W: R/ u, G  //
, l" R3 b0 D- R" u1 ^; k6 \/ @1 X- Z( Y  while ( KeyExtension->IrpsInProgress > 0 )
' P' j& \, ]! ]* K6 B  {
- W' f4 T: V" r3 ~+ y    DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );
' O7 F; t1 e. z- ]4 r2 c7 F  }
. I' t6 t  ]. q' O& @, A! X3 N0 U+ _, ]: X6 F* A) |+ G
  __End:, N9 y: [7 t& n" G
  IoDeleteDevice( KeyFilterDevice ); 5 d9 {1 T, i( J8 \, r6 p

' X5 Q- B/ i3 `8 y  return ;
7 V1 t* }5 }3 d} 5 j% a# f0 u& X- |1 k- c) ?
0 G0 f8 Y4 R# i1 Y4 v2 K9 o
/////////////////////////////////////////////////////////////////
3 L" }6 \& e/ j3 ~  I# F8 D5 K// 函数类型 : 自定义工具函数
; B! f4 X4 G# \- q' N// 函数模块 : 键盘过滤模块
& U" c# I, P9 m. G% i2 W* h3 O/////////////////////////////////////////////////////////////////
2 q; N# L* y* W0 U/ A6 j// 功能 : 取消 IRP 操作
2 J% w, g$ h3 o' J6 P// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能2 J( b1 L6 A' r6 j
//        使用此方法来取消 IRP
3 Q" S  u- h: g. H/////////////////////////////////////////////////////////////////4 [" y0 ~6 w2 e. v. @0 }( ~
// 作者 : sinister
1 t  o: s8 a3 F" k// 发布版本 : 1.00.00& n! t# i0 z5 x3 t- ~! e% l
// 发布日期 : 2007.02.20) s% o8 K2 b# q5 L7 m
/////////////////////////////////////////////////////////////////
3 h( M; X; f1 P9 }' @  ?5 |// 重   大   修   改   历   史
9 Z+ f0 C4 ^+ t+ M+ P) i+ Y/////////////////////////////////////////////////////////////////+ J: n% k# r6 }( d# r
// 修改者 :
# @6 I7 R  d. [  R* e% K' `' Y$ Z. G// 修改日期 :
  N3 ?- J$ Z. u6 c  O// 修改内容 :
4 h9 G7 U3 s2 Y: ~( \8 P6 Y/////////////////////////////////////////////////////////////////
- }6 f8 q) Z% Y# S- V4 a; A6 S
2 X# B9 \, Q0 }8 j) p9 J) o) v) xBOOLEAN* j! B! R& i* X" B0 I& T
CancelKeyboardIrp( IN PIRP Irp )
, ~6 Q4 T, t( A* Q# N) E, y( \{/ e5 D4 o& C. b, l; X6 h' K2 C1 T
  if ( Irp == NULL )
  }( H6 g& g. B. \: Z  {
$ j4 e/ [. `( j# v* c' \    DbgPrint( "CancelKeyboardIrp: Irp error\n" );
* c) [# J/ @; I/ [$ i  f    return FALSE;
+ B! M1 T+ U& ~# O  }0 s5 b. f  @; Z; d0 ^
, ?' t% c& y  c! U; u1 `( B
5 G% h# G% m- P! t+ O- O2 m
  //. K" ?/ L, m+ @9 Z4 y8 f
  // 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,1 m, b0 d1 r6 X/ |" ?: _; Y2 S
  // 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
+ V: o1 t6 v0 T6 \4 I  // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占5 S; d' ?# B4 i4 O8 }2 N
  // 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD
3 m& t  }8 r( Y. m  //( K4 t( _5 ~$ B; I  a. B
+ u) r) v; c) y* w( n* h1 i2 l+ v, \
  //* G7 f7 I1 ^' [1 ]2 D  V2 h
  // 如果正在取消或没有取消例程则直接返回 FALSE
% ^1 M: q, K% \; ]0 C: o  //
" T& J- k* Y% h$ J2 i% V7 F  if ( Irp->Cancel || Irp->CancelRoutine == NULL )
5 p- h. U) @& \  {2 Q* C$ g0 x1 `6 i! B. o) J$ Y5 L8 H
    DbgPrint( "Can't Cancel the irp\n" );2 _, b% O3 j9 S2 G; m; V5 S7 _# v, m
    return FALSE;3 ~; |( s# O; _
  }  x! K( ^+ ]3 G" h5 W
0 ^% j- p$ R3 ~! [/ J; B# k- `- B
  if ( FALSE == IoCancelIrp( Irp ) )
6 k& e* ?1 A* B3 \8 H/ Q: q# I  {/ {1 h6 g8 t0 }) m
    DbgPrint( "IoCancelIrp() to failed\n" );" g- Y  l5 L0 _& B$ s
    return FALSE;' x3 P# {* ^/ Y& w) D
  }2 Z/ ~$ \$ \2 H" L5 |

9 p' v% N: ?! J! Z, p+ c  //
" Y% p5 ~( m- t- p' h* Z* t1 S  // 取消后重设此例程为空' V8 j* Z1 X( W, t
  //  ~9 T3 D5 f2 _& Z4 P% v. i# s
  IoSetCancelRoutine( Irp, NULL );0 _9 W2 r- m) s

  t% E- r+ i4 E4 |7 i  return TRUE;
: {. L2 ~) Y. _% [5 s! ]& \9 w}0 z. g# L* X. _! B; f) }! d* |

7 r9 P: m0 A, J" z& h4 X" V/////////////////////////////////////////////////////////////////
- @* {) l/ y4 \! |# A2 a' J+ v// 函数类型 : 自定义工具函数
9 c4 ?4 r( v% h, ^9 ~' y  s// 函数模块 : 设备栈信息模块
# _& V. j4 m2 W" B3 b: T/////////////////////////////////////////////////////////////////9 C" s+ d9 j2 U5 A! T
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘  }5 u: m0 K7 p' z, b4 S  M1 q* U3 {
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
( Z& U, C: V6 T2 A2 O4 }9 J// 注意 : % \# G# S! o7 X2 F
/////////////////////////////////////////////////////////////////# [7 U& \+ [1 A" F* h
// 作者 : sinister
. S" D# f! J6 ~- v7 E6 `// 发布版本 : 1.00.00
9 [$ ]  o  k& X: i% W// 发布日期 : 2005.06.02+ {/ M" G2 }  B7 J1 q
/////////////////////////////////////////////////////////////////9 V5 b3 g& x; Q/ \- }6 v) P
// 重   大   修   改   历   史
) e% B1 j' }9 b% S. _/////////////////////////////////////////////////////////////////9 t  s1 I% [, A1 W( _- k1 p/ M
// 修改者 : sinister5 N) p2 l0 P) W( ~0 G9 L- [
// 修改日期 : 2007.2.120 `6 X3 q- t, G% P
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改  d* {0 K1 h0 ]3 V" p8 l
/////////////////////////////////////////////////////////////////1 s. N* z& R* O' a
2 ?* R- U' v9 i
BOOLEAN
; U/ g. d7 T6 [  ~1 a2 p( ?! `GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
! m4 r) f- ?! |! i+ x{
  r2 m8 ]6 o5 R  PDEVICE_OBJECT DeviceObject;
9 {8 @0 X, d' H! V7 O  BOOLEAN bFound = FALSE;
  I2 `6 V& t" |8 @7 X) ?- M# y2 U
  if ( DevObj == NULL )
4 Z6 O9 Z0 P8 [5 m# H8 r% S: l5 ?  {+ _( P+ U3 B: V: g6 V6 C
    DbgPrint( "DevObj is NULL!\n" );; p9 }5 S4 x5 q1 x7 y5 H
    return FALSE;
) B! q/ S7 u2 r# H" A1 [6 u  }+ |# F3 ^3 T+ T6 w0 F. H, }2 S
6 n9 W2 J. U! g4 e4 U
  DeviceObject = DevObj->AttachedDevice;
6 a4 V9 i, t+ {) W- p! J. _" N6 ^: A, O# U/ D
  while ( DeviceObject ): I2 ~8 a0 I% S! y/ s/ L1 _
  {* ~; B5 P, X3 I) t; `/ r' c
    //
  r5 i, S8 x. f    // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但" n! ^! u; ^$ A+ y
    // 有一次足够了。这算是经验之谈
5 g7 m) j9 b0 P    //
/ s6 J/ V3 V3 @9 M" w: z& W2 R    if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )) M5 r5 X# R" M
    {2 l- {6 u6 l4 H* ]' }' H3 R& X
      DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
5 H8 @# b; K& p4 ^; c) \, u) @! @                DeviceObject->DriverObject->DriverName.Buffer,  N& c) p$ v& {5 e: B: g
                DeviceObject->DriverObject,
: {9 [4 M) n, B                DeviceObject );
6 J* ~$ d* }' m+ G9 W' W' Z% d; {  p5 g% F6 S6 y0 E9 C- c/ `' s
      //
# T, h* a2 {4 p* {+ h      // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
) \* s: R2 O/ t( p      //- S+ N0 M( H0 C; k" B) H
      if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,
0 k) d! X8 B6 l+ Y5 ^* j1 e                      KDBDEVICENAME,. b3 `8 _+ y. J& v: z
                      wcslen( KDBDEVICENAME ) ) == 0 )( Z; d$ t/ b: h" K( s4 Q8 @
      {
0 \1 J, z& J7 X- I0 L( }; n        DbgPrint( "Found kbdhid Device\n" );
9 _1 K' d( Y1 {" A$ |        bFound = TRUE;
" H1 R& n7 Y7 S0 L9 ^/ ^+ x        break;
! Q5 f5 l, K  W+ P$ r6 _      }! {, Y  v; m; v  ?
    }
. R$ _2 T3 X5 e* B7 c  C$ s% U* S& L& e4 P
    DeviceObject = DeviceObject->AttachedDevice;0 Q+ r- Q" o/ N
  }
# x' b5 {% x6 M: w' g2 x  J- Q3 k2 ^* |$ W1 I: ^# }
  return bFound;: @+ m  `2 H6 N2 W' M+ ?
}: |. o& f% A3 B. C6 W
: i0 o2 T$ C3 A/ V$ F1 \; }# C
/////////////////////////////////////////////////////////////////
9 ^% j+ M' |4 [// 函数类型 : 自定义工具函数( `9 ^8 i0 a- N, A8 H8 S8 R6 b
// 函数模块 : 设备栈信息模块
5 ~) z& w* f+ a9 y: Y8 [  ?/////////////////////////////////////////////////////////////////
/ l* o+ f7 I: P$ G/ D% o( d/ g// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
5 V8 @% f2 L- ?" \# [// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
! @) i" u, ?3 e$ l! O( J/////////////////////////////////////////////////////////////////% z7 X* V( |6 }" H
// 作者 : sinister9 w/ Z% e. r; Z/ [! k
// 发布版本 : 1.00.00
- K* F) I- Y7 `! x/ e// 发布日期 : 2006.05.02( ?; i) E' g: `! }- O
/////////////////////////////////////////////////////////////////$ J( Z$ Q  _) o' [$ J* E
// 重   大   修   改   历   史
& K4 \1 j+ M0 c% D9 g  f7 q/////////////////////////////////////////////////////////////////
. w, e1 J- S9 s  s/ {% t) R/ \// 修改者 : sinister" t5 l. f+ m) D% N% A
// 修改日期 : 2007.2.12
4 O+ ?7 f. G% Z// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用0 Y/ V0 h3 S% Q5 W1 r# o* D5 k
/////////////////////////////////////////////////////////////////
, a, W: U/ ~* o  B! J$ Z% i" x/ t5 D4 x! u
VOID3 p2 c8 P& F% I$ [4 O
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )1 M! S4 ]( O% P0 [
{% O. N, i# p* j; o/ C* l0 }
  POBJECT_HEADER ObjectHeader;
* g2 ^2 N$ d5 ~  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
- J- ^! B& |0 h" I; r# h+ S
" j8 j# J6 w' e( D9 z9 V  j" k6 }  if ( DevObj == NULL ), b7 E- w' C) t; P' n6 D
  {" ~7 `3 l; }8 b$ b9 f2 r8 o
    DbgPrint( "DevObj is NULL!\n" );0 S3 d7 s; l) A( c
    return;
# d! O- d8 f8 Y  S& K3 `1 G  }
' C7 q, O( s% B/ i/ L' m0 o% b8 ]+ H6 y. E2 ?* `
  //
+ V* C( g' m! ]6 k3 E% _  // 得到对象头  ~4 |; \; W5 ~( E, |8 t
  //
; F- ]/ f% J0 }0 c: M+ X% S' C8 I- F  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );* R5 N# X4 j  H$ w, _

' n% [, _5 S' u  if ( ObjectHeader )
( ^1 u) t7 J" h, v  {( y# S: w' T( k
    //
( O3 Z: W5 n+ F3 X- Z    // 查询设备名称并打印
- b( Z6 `, V5 R, L+ M. t    //
( S, d" u$ o/ x3 j: j% }    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
, V6 z" q9 Y, g% q5 U" ]9 \) p6 B3 z; h+ b% k
    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
. q0 g$ b  L+ |) ~0 w8 H. u    {
/ |7 l- `; C9 ]/ b5 x8 M: E, A  W      DbgPrint( "Device Name:%S - Device Address:0x%x\n",
0 E0 ?9 u* p; \                ObjectNameInfo->Name.Buffer,
& Z) T  N  \* u8 B! o                DevObj );
  C' t% S3 @6 e$ s( v0 k5 _0 A1 J3 n2 ?( h$ M* @) f! h/ y1 Y" K2 b
      //
" H  e; z/ u7 Y' n, i      // 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
  T( X3 [# V$ W, O1 a; l3 g      // 用,没有实际的功能用途
7 m8 _- a# `- ], Q# L! [6 Z* G9 X; `4 A      //, U/ Y- y. H" ]) B0 ?8 Z
      RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );7 L/ z5 i! a' A! u* \$ Z

1 n3 e+ b* f' @4 y      wcsncpy( szUsbDeviceName,
# q# I& j" H* i, Y# h. q; G2 K% _; w6 c               ObjectNameInfo->Name.Buffer,$ a1 l: F' q  d3 `" E7 A
               ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
( X! `' |( ~4 z0 q9 E7 e    }
8 K- e1 n& j" X* b/ `2 t, k* X
# K0 b" Q9 Q0 |3 O; e6 ^9 {    //
& A; l9 j; e* ]! N+ u4 V: l    // 对于没有名称的设备,则打印 NULL
8 i! @; h: H( ?& {( n8 N    //. H1 K8 V" N# L( W: k. p
    else if ( DevObj->DriverObject )
' ?  f6 ]  ]: b2 Z' v    {  V" G! e, `4 @! ]
      DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n"," L- ?2 [0 O9 j- F$ P3 w! b* }( k
                DevObj->DriverObject->DriverName.Buffer,5 c& w6 @% f: R: ]7 Q; ]5 ^# N: n, y
                L"NULL",5 ^! o9 W0 x! q
                DevObj->DriverObject," i/ n& f6 Y1 [# v
                DevObj );
$ ]4 T- s* \% r$ x. G) I) @    }2 @/ ~* d: P( Q1 Z5 d" p, e' G
  }: Y. M- C% a4 i
}
9 i/ L, b( J, }7 t
9 O/ q# \' g: ?5 h/ F" e/////////////////////////////////////////////////////////////////
) a  a' r/ f6 `; M8 l* e: S- c// 函数类型 : 自定义工具函数! g. _2 ]- H5 ]9 ~& e
// 函数模块 : 键盘过滤模块
+ M( ?+ d- ?% F. N2 N* J/////////////////////////////////////////////////////////////////
7 p) i9 h4 n8 Z) Y, J- L/ x( `' \// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
# m, [1 Z0 ~$ P/ o$ X0 q9 M6 K//        对象,过滤出 USB 键盘设备,将其设备对象返回( ~/ y7 [8 b: x& S7 l, N. ^9 Q$ C
// 注意 : - o3 W; m$ n. q0 b8 ^* N5 r* L
/////////////////////////////////////////////////////////////////" G( m$ C: V/ `2 o4 i
// 作者 : sinister! u( Q4 G" F' k' \
// 发布版本 : 1.00.00
7 |6 p5 v9 s. }1 X; p// 发布日期 : 2007.02.13% T6 E0 y/ k2 c8 u" s( F
/////////////////////////////////////////////////////////////////
; |  z4 t, o8 V8 W// 重   大   修   改   历   史
3 _! V9 W/ X' P# y( O8 j/////////////////////////////////////////////////////////////////
3 C- w7 n1 L0 m// 修改者 :
( U  V" {1 A3 U/ F; f8 l// 修改日期 : $ V* n# P0 i; R+ z7 w* _6 g3 G5 ~
// 修改内容 : 2 N0 g/ a, g& |0 E
/////////////////////////////////////////////////////////////////
' r3 s. u/ l. T+ t3 V" F4 g- d; q- {& G( ?' B! n
NTSTATUS
! a! S) j/ ~, z5 n7 FGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
7 G1 B8 S0 _5 j" o9 v{* Y5 A) _2 D& I7 K, r/ c5 e( u# ^
  UNICODE_STRING DriverName;3 n: ~1 b8 ^9 d$ v( G
  PDRIVER_OBJECT DriverObject = NULL;
, c+ H% w( S. @" x  N) u+ `  PDEVICE_OBJECT DeviceObject = NULL;, C9 d( E$ c4 X7 r6 K( Z
  BOOLEAN bFound = FALSE;6 H7 L6 r7 i% n5 @4 e! {& e" d# A5 v

* v1 Z# d. q3 N3 }$ j( ?+ g  RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
, w1 [! u6 ~) x0 e
) H( o$ ~4 |9 S: B# c: C/ t  ObReferenceObjectByName( &DriverName,
$ U. R  n- n2 z3 h                           OBJ_CASE_INSENSITIVE,
# E6 x/ T* d: i' {2 a3 [: O                           NULL,! ^; z, N3 j3 J/ E8 P
                           0,
. d9 x6 r8 [) t2 [0 o$ ^8 D5 a                           ( POBJECT_TYPE ) IoDriverObjectType,
& M/ M  X9 W9 a3 n7 Q& n                           KernelMode,
- p2 f: H+ ?; _) j0 a) [$ W                           NULL,* x: g$ i3 |0 w
                           &DriverObject );
! a/ v* H4 t5 G1 q$ o% S+ o
, ?# a" t: B: n: J6 @. [9 e  if ( DriverObject == NULL )
- }- t( J" f" [" x4 `! d  {7 c- [) Q, D6 J, R
    DbgPrint( "Not found USB Keyboard Device hidusb!\n" );
2 I4 i) U, m8 _( a    return STATUS_UNSUCCESSFUL;
7 I  R+ i( b5 }8 W" f  }
9 c' y, q+ |! `1 ^. T& r* I3 h8 k( I4 `4 ~2 Q0 }; o
  DeviceObject = DriverObject->DeviceObject;
2 ]" b( Q9 g9 E3 d* h/ i- J- m0 Y
  while ( DeviceObject )& \4 H; W7 D# U$ f) \7 |
  {
. k" \/ D" B+ A8 o& l9 @    GetDeviceObjectInfo( DeviceObject );
. a4 y, p: K4 y" Q- g5 ?& j7 G, U5 D+ s
    if ( DeviceObject->AttachedDevice )
7 a4 A/ j& k: U0 l* m' k    {
& O: |3 a2 `8 t7 b+ j      //: d2 W% R9 R" i5 H( r% D8 s/ Y
      // 查找 USB 键盘设备
& r' V3 G7 f' _. H1 k+ K      //
9 S3 J7 Y8 q' j' E5 ?/ l, H* N      if ( GetAttachedDeviceInfo( DeviceObject ) )! G! ~2 F9 @& ~" F/ x0 u
      {
! G3 R) H: _. k& l+ m5 A0 z        bFound = TRUE;
( F- {8 ]8 m9 X3 K7 h/ p        goto __End;4 ^+ S. M, U' M' l; g
      }+ n% Z& B" C1 c5 k
    }, Z& u" \  }2 G

1 w/ m% f! M8 X- p7 W0 }    DeviceObject = DeviceObject->NextDevice;
& ]+ [9 k7 w' _% a- H; R  }
% G: P( }" O4 p) S  j- s; f9 u( n5 _% m* P: Q, i
  __End:( G3 O( m% ?% S0 x/ q* C3 B* y
- |. X9 u  e) j, n; d
  if ( bFound )7 N/ E" i7 S6 b3 t3 f. W
  {
8 h$ g8 Q9 @2 X: d+ b) h! }    //
7 E/ n) \. f* \% v; }6 [6 k    // 找到则返回 USB 键盘设备对象7 ?. b2 Z- _/ ^( F
    //5 Q. e! K. y0 m) v& ~, W
    *UsbDeviceObject = DeviceObject;
! c3 S& X6 j% @! r) j& {* A$ j( n! I  }' q' j5 E* v0 \
  else& x. A7 [0 ^' s! l! @
  {2 y. Y  N& o! Z9 i( z* W
    *UsbDeviceObject = NULL;
, s+ l5 R5 b, {7 q$ V. h  }
0 r9 a6 w. y- F( h9 `
6 L0 m6 N: L  I! U9 |  return STATUS_SUCCESS;" A* S9 @9 ]$ R. S! I# {
}
2 F6 Q3 x5 u+ Y
' d! a1 f* |6 ^! D/ Q0 D/////////////////////////////////////////////////////////////////
+ ]1 U$ _; W' |  [3 ^/ N// 函数类型 : 自定义工具函数
6 O! Y/ D  _, Y! l; O& R$ Q// 函数模块 : 键盘过滤模块
& ~* N6 N7 V% p6 T! L////////////////////////////////////////////////////////////////
0 j: N, w# @/ `- x9 `0 l  Q7 j// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关, M4 G0 t3 c3 H- G6 S
//        信息,返回附加后的驱动对象6 u, j' `; z6 _( z2 x0 a
// 注意 : 此函数仅挂接 USB 键盘设备) c7 X* @: f& O" \' S& E
/////////////////////////////////////////////////////////////////2 p% I2 f8 X9 T. ^
// 作者 : sinister
7 a) d7 g  D4 L& D8 a) V* A* `// 发布版本 : 1.00.002 C0 z# {4 }8 T) ^7 g/ C% h
// 发布日期 : 2005.12.279 ?6 s+ C6 v2 |( a! D- \7 [) T
/////////////////////////////////////////////////////////////////: F* [. {7 D6 l
// 重   大   修   改   历   史
% |0 W) r- Q! D* E////////////////////////////////////////////////////////////////
$ j! h" F- R& W6 `' Y# e+ J9 ~// 修改者 :! Z6 A3 e4 Q9 Q% M/ s
// 修改日期 :" j8 [1 F6 Y& S& n: m; Z/ }
// 修改内容 :
7 s( W# t/ y2 i6 r9 O4 l5 E* p/////////////////////////////////////////////////////////////////, P4 z0 t$ y8 E+ G0 J8 o# V7 }

4 }5 a. Z# H; X3 g9 j* [: _NTSTATUS
) U: z5 a" p2 T. N- VAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,1 a1 ^$ Z6 M$ G# H7 _4 M8 v
                         IN PDRIVER_OBJECT  DriverObject )7 i& \5 }! _' h
{' J1 E+ h/ |  }+ U4 X
  PDEVICE_OBJECT DeviceObject; 7 K9 R- L; l/ s% z
  PDEVICE_OBJECT TargetDevice;
* A8 j# S. U) _0 T  PDEVICE_EXTENSION DevExt;$ ^4 v+ t8 M2 b/ d' N" p/ L1 D
  NTSTATUS ntStatus;
7 K; E, I4 c$ ?  @/ {% O1 S0 [6 |4 g! S) c. H7 S" k! V6 t( n9 v
  //% D$ p! i4 v7 K/ u2 D* [& Z
  // 创建过滤设备对象
. s5 o; m; _/ U- `  //) V' K+ B+ L  E  B5 E' \$ U$ O3 I
  ntStatus = IoCreateDevice( DriverObject,! [3 K6 C( _9 x4 b9 m
                             sizeof( DEVICE_EXTENSION ),
& ]5 I  H2 o" N6 \* D+ F3 I3 B% |                             NULL,
2 ~; A6 |( W9 u  X, }                             FILE_DEVICE_UNKNOWN,( P0 Z1 |, [: [) G4 X# x! V
                             0," ]$ Q6 a( i4 E1 e3 K, B& f2 ~, ~
                             FALSE,
6 |$ D' \- k8 K/ V% Q8 n, o                             &DeviceObject ); 9 f3 F( R# E$ q" W+ ~( b2 S

4 w: t& ]4 G' a4 c* E! a  if ( !NT_SUCCESS( ntStatus ) )
% q( C( v# i" {% {! Y  {2 w) J1 {, b0 ~5 `2 m. F
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
6 a% U( `* e6 V- U6 `8 x6 d    return ntStatus;
- m& z" v- g) j3 I- [  }
2 S  G3 p. z9 e8 m. H+ n, @
- i* G1 w& Z& O  DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;0 v: J+ m6 {( \

" J1 ?! x( k; \$ S  //
- |  }2 ?$ ]7 |- S  J+ A8 X  // 初始化自旋锁
9 Y  Q! V6 ]# R% k; R5 a  //
/ ~  f5 u0 F+ V+ Q, }7 j5 a. ?4 z  KeInitializeSpinLock( &DevExt->SpinLock );6 C. P/ ~2 c, v' s+ I  Q
3 x8 X3 r9 R& a
  //
4 {* I5 r) q* ?: `% h  // 初始化 IRP 计数器1 r9 @4 Q& @0 c( c& _
  //
0 x* k( I; t- E5 Z% A! P1 \  DevExt->IrpsInProgress = 0;+ J; s, }- {4 D1 N3 q7 ]; l; M

" T6 L2 r  r% y$ E* P  //# F9 p  Z4 g: _- o' w* r# l
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象  y+ n' w5 u8 n
  //
! H( I0 `8 ]( M' O5 d7 D
! N: M8 y9 |5 t' \2 {4 j  TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 4 X; @5 L, n1 g# U( A% B6 @
  if ( !TargetDevice )
+ P0 V1 e2 Z4 D/ A/ t9 m8 n  {8 {1 r( ^" d# y3 Y( _
    IoDeleteDevice( DeviceObject );
7 u# o- ]% W& k2 ~    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
' x2 b. T$ q' c$ |: f% H    return STATUS_INSUFFICIENT_RESOURCES;5 ?3 |% w  x$ e0 q0 t: f4 @# }
  }
# p- f' Q! P) R  h4 s
1 R4 ^- Y6 M8 k  //
5 b$ ~% h* M: f3 V* M  // 保存过滤设备信息
  a( l+ h/ A: E. S3 n0 |3 u  /// P6 {1 k0 E& e" g5 d
  DevExt->DeviceObject = DeviceObject;
3 s0 J. [  ^) G  DevExt->TargetDevice = TargetDevice;
* n+ R' y5 X' J% b( ?$ r7 T' n! Z+ C* J
  //* S: {9 ^$ v( R! B9 B
  // 设置过滤设备相关信息与标志/ ]$ O8 J: b8 |  K
  //( W; |$ e- L" ]6 _
  DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
# u8 C( {3 ]0 s6 d) D  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1 W0 O# @/ e' }& D$ r% e: Z5 C) l% p. N

7 `) N8 i+ J) o  return STATUS_SUCCESS;
. S  R0 D+ ?+ I. }1 v}! b1 _$ i- B' i, o
# U5 R, q2 r' C
/////////////////////////////////////////////////////////////////
( H7 E3 q* n- M3 J// 函数类型 : 自定义工具函数
& w/ @# N& L% I! \' t& z1 o) O// 函数模块 : 键盘过滤模块8 e0 y, T" t# ?  e
////////////////////////////////////////////////////////////////7 z. p  W5 L/ z0 h2 i' n
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
2 `' x9 J0 @! p9 |" M$ R//        信息,返回附加后的驱动对象0 g2 _; S6 z2 C0 G, D! r4 n1 K; E
// 注意 : 此函数仅挂接 PS/2 键盘设备
  c  l) R) {2 T/////////////////////////////////////////////////////////////////- n8 ?6 {! ]+ @' M+ n7 b( q
// 作者 : sinister9 J0 |1 S7 z. Q. S5 k9 q' W( Z  r
// 发布版本 : 1.00.00! I& j6 I; P- N+ t0 {7 S6 f
// 发布日期 : 2005.12.27
( @( b) f9 Q) n9 e4 [2 }0 ?$ I. V/////////////////////////////////////////////////////////////////+ c$ X! a7 ?( y% l
// 重   大   修   改   历   史
, {4 _( [6 S+ I: d0 x" W) s; b/ t////////////////////////////////////////////////////////////////
7 Z5 H0 X4 u* W: b// 修改者 :: i1 X3 k& }7 y  ~1 D
// 修改日期 :
# D& k. I% B$ g9 `4 j' m// 修改内容 :
+ E: X: \9 O# x% D/////////////////////////////////////////////////////////////////8 P2 d4 X6 P! v" S1 W( c
% u1 i7 r$ \4 N3 j
NTSTATUS- u6 [3 ]2 x: v$ J0 f
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名  j: g' C2 r2 r* a+ @7 _: G) }" S: N: ^
                         IN PDRIVER_OBJECT  DriverObject, // 过滤驱动也就是本驱动的驱动对象
: |0 n- C$ O2 d# b' l, R# t                         OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象% L( y: `* v3 J: _
{/ F" W# o/ e0 Q( a, _7 T( w+ e( P& T
  PDEVICE_OBJECT DeviceObject;
/ g' O; w0 C) e8 O  PDEVICE_OBJECT FilterDeviceObject;
0 \5 [& X8 Z% |$ ^8 S) k  R6 u  PDEVICE_OBJECT TargetDevice;
  r$ s( P: u: O# S1 J* t, Y  PFILE_OBJECT FileObject;
& L% d& A. |7 y/ P, P3 `: m; r& w  PDEVICE_EXTENSION DevExt;
' B/ |4 v! V" l( n! M- B- C, x8 A1 `, u" b- A
  NTSTATUS ntStatus; 3 k+ b+ \& C8 ~6 q' u5 K; H: I
, }  y9 |( X  v
  //
& |5 O8 O1 `& I3 t& `" q9 o% x  // 根据设备名称找到需要附加的设备对象+ d' i/ c, ]* b3 u
  //& |/ h" t5 A4 H# _: p9 c; S4 ]9 H
  ntStatus = IoGetDeviceObjectPointer( DeviceName,
9 n3 A# U( }6 }' {. A                                       FILE_ALL_ACCESS,
4 u; d( U5 V, S# }1 E                                       &FileObject,
9 g: `, O2 r& I* S9 m# |4 {2 U: E                                       &DeviceObject ); 8 l4 N# U: L$ u( S9 y. [
1 A" E! e2 W* Q' V
  if ( !NT_SUCCESS( ntStatus ) )
; I; t6 X6 ~; m$ \, C  {
' ?+ S; k% c! k' j% C    DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );/ x# e' j6 `0 ~7 m0 G
    return ntStatus;5 R4 K; r$ g! T9 A3 `7 a. J
  } 7 k9 U0 m/ \( `4 i' r4 G% e
" ?6 N5 D- N! M& u
  //: Q% m& t/ W# H0 i
  // 创建过滤设备对象
- D2 t# y1 M0 V) Q  //- ~' S5 r0 l! r$ h* h% H
  ntStatus = IoCreateDevice( DriverObject,& A% g5 G$ g2 q/ U( Y
                             sizeof( DEVICE_EXTENSION ),$ u) T0 g) \4 y$ y& n
                             NULL,
8 K; W; {% F: X  t                             FILE_DEVICE_KEYBOARD,
0 ?: N  I! E6 c% _                             0,
, F! ~* Z7 A6 R1 L/ [                             FALSE,
0 V( _: @6 R' j  w' g, [0 A                             &FilterDeviceObject );
* c3 A6 v' O0 n+ T* {3 f8 P4 R0 u
" n! X+ j2 D' P- u  if ( !NT_SUCCESS( ntStatus ) )1 k5 p; i. }* S4 K+ l! W/ h
  {. ]( u$ [, l% p8 }5 d1 ]% ?' h
    ObDereferenceObject( FileObject ); * `( \+ k% y& i1 K8 S
    DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
5 k2 V* {' T( w' ^    return ntStatus;( x5 F& Z1 S/ Y2 a2 w& _) r: i
  } : L4 V9 u; {. ]+ l2 k; ?, ]

1 c2 ~% x& l. A  //
7 U4 {* E& k" o; H. w  // 得到设备扩展结构,以便下面保存过滤设备信息
* w, ~" ?; |" ^* u1 w2 r( ~  //
  U3 o, R/ d7 R( k; g  DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;0 `7 O0 b5 i* L5 G8 A8 c
6 s) a( Z1 s9 Q- Q: {
0 o! v9 @4 S9 ~8 G6 [& y) w+ C6 }
  //0 v& \+ H# Y+ v8 a. D5 L! {
  // 初始化自旋锁
- h" E- W" g4 b' C& C% p8 O, r% h  //
6 E+ q! q8 u9 b/ n+ w  KeInitializeSpinLock( &DevExt->SpinLock );4 d0 _; M1 k& l& ~3 C0 m# P! i4 k
' M9 R: @5 N& e3 O
  //
3 i' G6 f; c( b( _6 x  // 初始化 IRP 计数器
* y! ?7 N& B- ~- U% j5 y& Z  //
% W+ b! L. J7 ?! j, s' r' d* F- Y& n! w% ^  DevExt->IrpsInProgress = 0;) Z) O5 p9 J6 d' k  ]
# Z, ]- A1 R1 M9 ^
  //9 f" R, e& R/ D5 W! |- k
  // 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象0 w4 u4 ], K. a8 d+ T. t
  //
6 R% d8 J2 }2 G  TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,' Q% T, W6 R" R; r# l5 x
                                              DeviceObject ); 6 V8 z1 Z7 |1 ~1 |
  if ( !TargetDevice ), i; ]1 P4 Z$ _
  {
" Q  m1 `) S. h( c/ s    ObDereferenceObject( FileObject ); 9 A/ B" l$ `4 A$ G9 d2 R
    IoDeleteDevice( FilterDeviceObject ); " @- x3 K1 W: x' o: y7 B- @
    DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
& M$ v* T- ^1 Z: c" M, m" _* f9 a* x; e    return STATUS_INSUFFICIENT_RESOURCES;
" W/ \/ C$ z5 U; ]- Z  }   |% c% a; ^  ^0 F4 R4 {

: D& I9 ^1 \9 E5 K4 F- B  //$ S! B- L8 d4 }  V; d1 q
  // 保存过滤设备信息" ], |8 ]! M3 p! n. J/ k1 c# P0 Y
  //& S" v9 E  c* }6 [- T
  DevExt->DeviceObject = FilterDeviceObject; ) Z; N2 V3 z) [. l  g
  DevExt->TargetDevice = TargetDevice; ; h) N* e; ^: X7 O# A
  DevExt->pFilterFileObject = FileObject;
/ q. ~$ t# v% @$ s6 _! ?
" U, }( R( _7 b( ]+ V; n  //4 {6 U2 D! P, |  m, n. ^6 I" h9 B# C
  // 设置过滤设备相关信息与标志1 Z) V8 G! w1 c  R0 ~; W4 b$ ^& V
  //1 B9 T( A- f+ n* _1 o1 b* g
  FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
3 o) p- l8 V6 y6 Q# ]! R  FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
2 U2 Z( A! n- w" L9 [  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1 ~# a+ n; y! A  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
3 B2 h% P3 x8 N+ c2 T' X                                                         DO_BUFFERED_IO ) );
" l7 h$ s. u7 O: G% y* G8 L$ {. I' g
  //
/ c0 d$ Z0 G$ i( T& w  // 返回附加后的驱动对象
' d6 E( p5 M. ?4 [  //
: o( X1 E' e+ b$ H; @* L/ y9 b  *FilterDriverObject = TargetDevice->DriverObject;$ N2 b7 Z+ H* G8 ]6 m# `' l

% Z% z3 j6 x8 W$ d  ObDereferenceObject( FileObject ); 3 M4 O5 Y! U: C$ K

+ {- a% j. I5 @! H8 D9 Y; |! H' p  return STATUS_SUCCESS;
8 a& M4 o5 _# l1 f1 {" c+ N}4 b! M+ u: p9 Y1 I1 T
' c" Y& u$ P9 X; F( l4 O/ ?
/////////////////////////////////////////////////////////////////, S+ B  C. s' Z+ {# G8 f3 Q
// 函数类型 : 自定义工具函数
# B0 V2 u+ a; R9 ]0 ]- C1 |: n. x// 函数模块 : 键盘过滤模块7 n6 v$ v- T: _0 z1 p4 B/ I/ f
////////////////////////////////////////////////////////////////
+ Z' D, x; h9 {* s0 ]5 i// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发  }7 k2 k7 O5 r0 c  w
//        这个 IRP 的完成
# u& c. C4 K. _8 s6 x: r* _// 注意 : & k" _6 o# ^2 }+ O* A
/////////////////////////////////////////////////////////////////
0 ]7 ^  t& w( n// 作者 : sinister/ F1 I& f) S3 Q7 K
// 发布版本 : 1.00.00/ q8 K# b4 m6 a% ^7 E) J5 A
// 发布日期 : 2007.2.15
8 A. W& X7 Z% n: n- k( F! W/////////////////////////////////////////////////////////////////( Q0 B7 n1 O' f7 c5 n) f5 Y
// 重   大   修   改   历   史. G7 b' U7 B. `1 _, D6 u& n& P
////////////////////////////////////////////////////////////////
1 ~6 N  H$ S& q' _// 修改者 :4 ]+ f6 o- o$ O0 ~1 \: @
// 修改日期 :( m0 x2 T, n) k7 `$ [' D  h* S
// 修改内容 :
: J* \: c+ D3 k0 X5 d' E/////////////////////////////////////////////////////////////////- b. H, L! P: n8 W! O8 X# N

, ]; C: Z4 d7 ^4 WNTSTATUS4 f) V! t6 e& |7 U
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )0 R" s: C& p6 P5 z( D
{
1 m0 v: N2 X% J' n; y  r" L  NTSTATUS status; / D5 r7 _3 i' C3 l* O6 ]% d$ U
  KIRQL IrqLevel;/ R8 p/ |5 x0 g' J

7 z, d+ x+ A  ?6 u5 Z6 b6 x- O5 x+ H  PDEVICE_OBJECT pDeviceObject;
. ^: C6 x7 q6 g5 T  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
. e7 p; b- O. C/ a- i9 o                                   DeviceObject->DeviceExtension;
( i, X9 t/ C8 A/ H" i+ v* \6 c
* v7 o+ q4 y0 c$ }/ P& b
! Y+ v& Y7 X( ^7 z/ K+ _: a: y; s% f  IoCopyCurrentIrpStackLocationToNext( Irp );( Y6 p' N9 |6 V, [' a# d& U6 P

: K- O( K! g0 ~( r/ F; P( g2 d  //
# g9 s7 i8 O, @' B6 f- ^  // 将 IRP 计数器加一,为支持 SMP 使用自旋锁
7 B, y7 V/ s7 H' |6 n9 A  //! [  h  _( a* L4 g- R
  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );' @- S0 q1 \( G& O0 Y  ?
  InterlockedIncrement( &KeyExtension->IrpsInProgress );! [5 n2 B0 T; S; f* X, s$ c, q
  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );& ?1 J/ J& m* W# e0 ]

1 h% N$ J  C- y/ z" `- n/ ^/ k7 x  IoSetCompletionRoutine( Irp,
! H) x* I; o6 G$ a7 M, m' S                          KeyReadCompletion,
$ o/ q4 p! c: m                          DeviceObject,$ ~9 X5 r- {$ H! r% @( Y) O9 @
                          TRUE,9 C4 A6 y% Q: C/ w/ ?$ g
                          TRUE,
, E- F+ A( e( @1 f! V- c                          TRUE );
6 w8 i) {' c" P! B& s0 F/ O+ v) x3 _5 X$ B$ U% o, s8 k) Z
  return IoCallDriver( KeyExtension->TargetDevice, Irp );  G' v  I. A$ o8 e* L
}
" w, f; h2 Y% K3 u+ X; y# U* N! ^) F. t
/////////////////////////////////////////////////////////////////# Y; n% D! E# ?& T
// 函数类型 :系统回调函数
- r- \; Y1 f" a// 函数模块 : 键盘过滤模块- t8 u) i) ]% l/ O9 D) k* y
////////////////////////////////////////////////////////////////, ]. \/ ^7 k6 r- z
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
/ Q; L5 d: W7 p' W+ X4 M6 Y// 注意 : 0 E1 `1 c/ }3 q0 x* U7 _
/////////////////////////////////////////////////////////////////1 [& M) u9 x, x1 j# R1 J
// 作者 : sinister9 I0 k* K1 S/ a1 R. Q
// 发布版本 : 1.00.00) v6 |7 @3 r; z3 P) e& G. x* N3 S9 x
// 发布日期 : 2007.2.12
( s5 d5 i7 d  z4 w7 A: d9 u/////////////////////////////////////////////////////////////////( V' ]; O7 k9 V3 s2 ?$ J* U2 N3 \
// 重   大   修   改   历   史+ \- D/ k! ?5 Q. ]9 Y
////////////////////////////////////////////////////////////////6 F& U( e6 W  [! S
// 修改者 :
; ]% g) [6 l1 M/ w0 {) |( `// 修改日期 :% d+ E: f& X. X5 N: J3 N/ o
// 修改内容 :" f( g4 D/ ]( R  t
/////////////////////////////////////////////////////////////////1 F, E3 G# _4 }$ p; \( D3 t6 C

2 ^4 v/ s7 y; q  ~4 vNTSTATUS* E. z, j  t2 `# a
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,; w7 x# m+ U$ K) U
                   IN PIRP Irp,
# v1 u6 w/ H4 j- ^6 \# S                   IN PVOID Context )
& U. p4 F$ c5 x2 C) T{
5 ]/ A& ~) c8 t( Q6 B( t  PIO_STACK_LOCATION IrpSp;2 r% s  a- F5 _/ K. J, J( l* |
  PKEYBOARD_INPUT_DATA KeyData;
/ C5 V' l) ^  p3 |" t1 Q% `  PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
7 a0 }& @9 }& m5 t4 Y                                   DeviceObject->DeviceExtension; / X" ?* }* [6 I8 d6 |
  int numKeys, i;( Y! F% P% `7 ^% f4 N
  KIRQL IrqLevel;
. I$ d3 q! {7 }. D" W
0 t8 q7 v' u& K5 G  IrpSp = IoGetCurrentIrpStackLocation( Irp );8 T2 \6 O% j  i/ F7 r2 x0 [
2 R) Q8 D# S% q

; S( u. i7 x2 H# H! g9 _. H2 P  if ( Irp->IoStatus.Status != STATUS_SUCCESS )& L+ E7 O2 p  ]2 A4 c0 F5 a
  {4 m& \" W- b7 Z' A# _% w
    DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );2 M1 u2 t4 J4 h- q8 @; H
    goto __RoutineEnd;
, q5 _0 Y" p% n6 Y+ E& i: R. @  }) e) Y- e2 [, ^: Z. X
; I% p8 Z4 {7 j  Z4 k) u9 t6 h
  //1 T; M0 o$ q$ v6 n, }
  // 系统在 SystemBuffer 中保存按键信息
1 [: a+ n9 u- z! g  //
2 X: ~9 K8 i* i) [5 i- p' ?$ F  KeyData = Irp->AssociatedIrp.SystemBuffer;* w3 U+ ~2 T1 C# k4 P
  if ( KeyData == NULL )( [  W! B7 m8 y' o/ z# N
  {  o; d- @; \9 x7 L
    DbgPrint( "KeyData is NULL\n" );
- k( E8 }& ~" j+ l, A+ _# n+ p+ Y    goto __RoutineEnd;' I  |: C+ L: _: ^  n: M0 w$ x
  }
* `, N$ S/ _; K) o9 U9 [) Z0 k0 t7 o, t& E* Y0 Q3 @6 u
  //. r" W$ b3 R" a0 S+ J3 m. y
  // 得到按键数& j" K1 z& d- N3 ]3 ~$ U
  //
2 W1 s8 q& @- n/ K  numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );; h# }5 S$ s' r
  if ( numKeys < 0 )
# u/ \. t0 M0 O% t  {  U& F! Q0 a4 d- @5 h8 W
    DbgPrint( "numKeys less zero\n" );0 R2 P% o7 X& `8 i5 }3 y7 q
    goto __RoutineEnd;
5 f& @* u3 k, G3 [% x* z4 J  }
/ d' P+ D6 c6 R! U6 N) A
5 t9 {& c- b1 g% q  T. z0 }2 H5 s; n  //
7 M+ |. q1 U% Z+ f  // 使用 0 无效扫描码替换,屏蔽所有按键5 R. u2 g# s, ]- H  N9 g
  //
. w4 @% y0 c% K$ \2 W3 b0 k  for ( i = 0; i < numKeys; i++ )
  a( n" y! C0 g, e5 L3 w/ F  {
  K/ W5 o: O, G2 b* p' _# K    DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );
' ^6 z6 l! x0 Q+ s' c$ s    KeyData[i].MakeCode = 0x00;# H! ^$ K% Z  h
  }
0 r6 c( [7 o/ K
4 [- V( }# |  p! z- E; x  P! K' b7 p- n* t
  __RoutineEnd :
% j( J4 ]* K; v1 k% e8 I1 x+ B' s$ s9 Z1 n
  if ( Irp->PendingReturned )6 K! U/ J/ ~4 H
  {
0 T, S% F! |9 K. _+ m3 N    IoMarkIrpPending( Irp );# o2 q' z7 V4 U0 V* [  J
  }
4 ^; Q8 D& `5 G! X2 W- }4 q# ^. J# E& ]4 O: y# l
  //0 L7 f, _9 d  p
  // 将 IRP 计数器减一,为支持 SMP 使用自旋锁, B- G  }8 w+ m, U
  //
. g6 |! z9 Q8 U$ ?  KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );$ O: I" o% _5 W) j4 n
  InterlockedDecrement( &KeyExtension->IrpsInProgress );
* \; e& ^" u9 U! U( P9 }  KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );; }9 [$ b- G1 l9 c+ {1 W
, H, h5 v3 F9 L- h3 Y& f/ O4 Z
  return Irp->IoStatus.Status ;
0 f' w# m: B+ S& K}
. J9 |2 I$ c  w- S
# X- j3 a% y8 E" u+ B, e: M" [( E) `) i( A, u6 i1 a
/*****************************************************************
& s" ?+ Z- R2 P5 Q# r 文件名        : WssLockKey.h5 T7 w* a/ n6 Q6 I
描述          : 键盘过滤驱动
+ y0 A" d6 G9 l/ d. _8 [8 C3 ] 作者          : sinister
; i; W  H) l" z/ e% |/ R4 S 最后修改日期  : 2007-02-26  t. F/ f1 L2 W: h
*****************************************************************/
: q; e- H$ d, `5 z" ~; ]5 Z2 F3 y6 O4 l
#ifndef __WSS_LOCKKEY_H_* R; L9 z- V/ C
#define __WSS_LOCKKEY_H_* j. z1 A9 T/ {. {

7 @6 n; d9 v! P% L#include "ntddk.h"
; D9 p: h6 j: [" Z#include "ntddkbd.h"
$ i' Q" e/ e2 x: x5 N6 \#include "string.h"
7 g) @6 r* Q1 J3 @4 q#include
$ e' u  r) ~: h& }" E# i9 n3 V5 Q" d% |) u
#define MAXLEN 256
& ~! v  R: W$ O& k2 m/ r; t8 O: N! @$ ?
#define KDBDEVICENAME L"\\Driver\\kbdhid"' |' f/ m* q3 h4 R* \# N
#define USBKEYBOARDNAME L"\\Driver\\hidusb"
" w! t% D6 w! A& O( n( X2 _#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0": {. U* m- n1 c) P0 o3 c
: U) D5 R" r- V: O2 ]" j1 M
typedef struct _OBJECT_CREATE_INFORMATION
. Q% j3 G# I' h1 V0 }{3 C% z4 {! C5 w' m
    ULONG Attributes;
! P+ T/ `, U- V% h, [    HANDLE RootDirectory;! Z9 y+ F+ [- {. ]/ \
    PVOID ParseContext;& ?$ m- i, p% @7 t  d
    KPROCESSOR_MODE ProbeMode;. o8 d7 {  U: {( S: U. g1 e
    ULONG PagedPoolCharge;: p% i9 ~. v' ~  ^" E
    ULONG NonPagedPoolCharge;- }) X! |6 k! ~4 e& c8 H& A/ Y
    ULONG SecurityDescriptorCharge;9 K6 d) C6 {5 m: P/ ~, |
    PSECURITY_DESCRIPTOR SecurityDescriptor;
) i2 O5 A6 q4 a, D+ }    PSECURITY_QUALITY_OF_SERVICE SecurityQos;3 j+ y4 b6 D7 `; _- K, s( E# L
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
1 i2 g9 \" e6 }% j& O: d} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
6 r( g( S0 }5 _6 m6 I. g
, p, G8 B, C% Ftypedef struct _OBJECT_HEADER, p2 i' V% k) ^; ^8 @
{' ?' ^* Q% o( e# `, z0 T
    LONG PointerCount;' d& c) i+ Y) S' Z% Y5 d/ h0 o' e
    union$ J7 }* k  c8 d" E2 o- y$ l$ y: Y
    {! n' h9 z8 y9 _2 x5 P; Y& Q1 H5 v
        LONG HandleCount;2 q& C3 X- z# d- U2 g
        PSINGLE_LIST_ENTRY SEntry;) X% y( ]& [8 @' u
    };
& w1 Z9 C, L" ]$ j    POBJECT_TYPE Type;$ b" ~+ V" [& [: t9 F- ~
    UCHAR NameInfoOffset;
5 v6 q* f( c- V2 s. \9 x    UCHAR HandleInfoOffset;
5 T" C% C% B9 [    UCHAR QuotaInfoOffset;! h' w, L; d1 r: ?
    UCHAR Flags;
# A. v+ f4 w: L: R$ S    union
' l' P5 A# U7 I/ _( a. `, l    {
8 ~/ l1 h( }9 a; @( B        POBJECT_CREATE_INFORMATION ObjectCreateInfo;' H3 r! V# m$ P6 C6 O' d9 I
        PVOID QuotaBlockCharged;
: S4 [6 U  U3 g) _    };
1 P2 X6 r+ r( P* X' w
! R! M; }) G; Q* r' D: P3 {- B6 g0 M    PSECURITY_DESCRIPTOR SecurityDescriptor;
2 P$ C8 i4 m* j9 J$ z: v3 m) a    QUAD Body;
" A8 x9 U7 C  H. Z" n. D  d} OBJECT_HEADER, * POBJECT_HEADER;) O8 G, A9 ?3 \" h# O2 F/ b( J, ?$ D' W
2 V7 `' A% K/ M1 ~5 z8 l
#define NUMBER_HASH_BUCKETS 37
: L# \2 H; g4 t+ Z0 ?: w# k7 C0 n4 E: L" h6 Q% d
typedef struct _OBJECT_DIRECTORY
  l4 @$ K% O+ }{5 N2 A6 t. D' N) E' O9 F( m
    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];6 D3 z8 F8 D" X  Y  n  _  n
    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
) z+ _1 ^6 U+ ?6 n  ]    BOOLEAN LookupFound;
- u# n3 X* j8 u    USHORT SymbolicLinkUsageCount;
2 R3 u7 X% Z0 Q7 d2 R; v5 E    struct _DEVICE_MAP* DeviceMap;
& u8 S, E" T) ]2 m} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;+ g% d1 {. }7 I) W& ]) u" z6 Z

5 N2 h$ z; b, t7 |# A% Ctypedef struct _OBJECT_HEADER_NAME_INFO
+ w9 z5 k) U% S) C4 Y{
& O4 S1 t, c7 B1 [6 t- |, x    POBJECT_DIRECTORY Directory;) P+ H9 U3 ]7 }  M0 d) Q2 s
    UNICODE_STRING Name;
! y; x8 _- Y: A, |    ULONG Reserved;
4 j7 d# e9 g& j- g1 O% g0 d#if DBG& h7 O$ Q; p7 q2 E
    ULONG Reserved2 ;, H6 G5 L. i8 U4 Z
    LONG DbgDereferenceCount ;* W% W: b, R/ E' a( ~8 k4 d
#endif+ y; n; S6 ?( B" e8 s
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;2 x, t3 c8 u% K$ u3 s

9 c, r% P, ]. Z) j#define OBJECT_TO_OBJECT_HEADER( o ) \8 \2 t1 W$ F5 e9 b$ r2 z4 c
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
1 G. b2 E0 n7 E" N3 e
; d+ R) n/ `7 l# H! V+ t* e4 c#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
& k. y& i) b2 u# E& X. C    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
' G* D4 @+ r: V$ T
9 `* }9 O2 J5 Stypedef struct _DEVICE_EXTENSION
7 @( z* |0 k: J; n) Y( W( T9 s{* e4 P( n. c+ `/ ?1 S( P) S$ m
    PDEVICE_OBJECT DeviceObject;6 \' |" w) z2 ?/ k
    PDEVICE_OBJECT TargetDevice;
- ]& \$ h0 {5 t/ K    PFILE_OBJECT pFilterFileObject;
0 _# g$ }- {4 @. f$ S% `! Q    ULONG DeviceExtensionFlags;
! Z7 O  x, F6 \6 P+ p* W" g    LONG IrpsInProgress;
; }0 Q2 K& `! G    KSPIN_LOCK SpinLock;
% ~( c6 _; \5 t/ R! L}DEVICE_EXTENSION, * PDEVICE_EXTENSION;# n0 }$ B- g  w: ^

5 U  p0 |# T* z, @8 j, `
$ D- @# [) u# N. ~$ t/ BVOID
% \7 n% B. g) A6 V) H4 nKeyDriverUnload( PDRIVER_OBJECT KeyDriver );, v8 F0 P* h; a
' Q$ q2 y& ~: v) V
BOOLEAN
0 E) e5 Z% J/ `% a" z7 E# BCancelKeyboardIrp( IN PIRP Irp );7 \* X5 m! I0 p, u

5 h* s' F. C2 m& U" [1 J' h, q, Gextern POBJECT_TYPE* IoDriverObjectType;
+ k: C: t  [  F, _+ @0 |
5 s1 w* T: E! PNTSYSAPI
$ n$ r' g! t7 a8 qNTSTATUS
/ y7 M5 Q' C' e8 C: Z; Y" x9 lNTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName,
7 }1 e% K- f& w- e' ~: G! |                               IN ULONG Attributes,! ^% h4 z3 I, R. \! c9 c& O! {
                               IN PACCESS_STATE AccessState OPTIONAL,
+ Z7 h5 z& R6 o; a7 v: i                               IN ACCESS_MASK DesiredAccess OPTIONAL,) u9 k) u( u1 u& k. s; L4 L
                               IN POBJECT_TYPE ObjectType,
$ `( D* ?# Y% V) e5 V6 J! }0 p8 ~                               IN KPROCESSOR_MODE AccessMode,
3 {! s) J) z; \. W/ Z& n                               IN OUT PVOID ParseContext OPTIONAL,
6 h: ^/ [: y0 U& o; R                               OUT PVOID* Object );* v6 ?: @% L. X1 c
; T7 ]" z, [' @8 p) }2 E! ]
NTSTATUS
& t7 H+ s7 s2 c) J7 M2 U8 LGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );; D- Z! ]1 P0 b& b1 R" P

: o/ D7 Y! \% p+ m6 ^" o3 F2 tBOOLEAN " F2 n: u1 ?# a5 h) \  T
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );# o, I$ v5 [. A: ^$ F, l

: s# T' M5 w! E0 F1 ^! k8 L+ `1 V: pVOID
, y2 ]  \. _( i* i4 g/ G, [$ p3 T6 EGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );- q+ u7 ~+ P' a, s! D( y

- a/ K$ s) a0 M7 k+ L8 wNTSTATUS
4 ~. Q! n2 \1 q8 ~" W" [6 NAttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject," @5 D" N0 f) A4 Y; I3 K& _2 Y
                                  IN PDRIVER_OBJECT  DriverObject );
+ r  x; c0 ^. K% e5 Y! Z! y% [: W9 Z: g
NTSTATUS 5 o  c, f7 F, x8 M
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,! Z' ~0 O9 k3 Z7 _" X/ P
                                  IN PDRIVER_OBJECT  DriverObject,5 T- x& H% x0 T1 f
                                  OUT PDRIVER_OBJECT* FilterDriverObject );
7 q  o) h: q; f7 J/ @1 b4 h, d! ~# t5 M" _. h5 o+ B2 T. C$ E2 K% q
NTSTATUS 5 D8 d/ S; w9 z3 ]
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,! L7 w' [. w+ T" t- D" F
                            IN PIRP Irp,- n* I, t- B5 u  x
                            IN PVOID Context );
" y* J8 L. {- V7 E& V6 TNTSTATUS 1 c9 O1 C4 \' U' O8 {
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
* F8 B; r3 O) H. W  C+ J; ]0 U) z5 @' V( x% K/ e
WCHAR szUsbDeviceName[MAXLEN];
9 b" j* y& b1 O9 D) o+ X/ U1 T  V- A8 a) ?
#endif, b: H6 X! Z& j

* }7 W( G& b7 _% i- R$ d" M+ J
7 K: Y0 k* I$ |3 ]: B . Q: q$ w0 {5 @, R# Q1 S
5 p# b2 E' R# z1 C9 N; K
6 k: U/ A# Y* X8 H* U
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。! w5 p) [+ a7 C4 i# c
WSS 主页:[url]http://www.whitecell.org/[/url] 7 @' H: Z; W/ ?
WSS 论坛:[url]http://www.whitecell.org/forums/[/url]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-13 20:44 , Processed in 0.494503 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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