IRIRP_MJ_CLOSE
发送时机
:
当
FO
的引用为
0
时
,
发送此
IRP.
通常是由于文件系统驱动或其它内核组件调用
ObDereferenceObject()
而引发的
.
ObDereferenceObject
CLOSE
通常在
CleanUp
之后发送
.
但并不是说在
CleanUp
之后马上就会收到
Close IRP,
可能在几分钟之后或几个小时之后
,
更爽的是可能在几天之后收到这个
Close IRP.
操作
:
文件系统驱动
若目标设备对象是文件系统控制设备对象
(CDO),
在
IRP
处理完成之后必须完成这个
IRP.
否则
,
文件系统驱动应该处理
CLOSE IRP.
操作
:
文件过滤驱动
若目标设备对象是过滤驱动的控制设备对象
(CDO),
过滤驱动应该结束与
CDO
有任何信息联系的操作
,
同时结束这个
IRP.
否则
,
在作相应的处理
,
如每个
FO
或
FILE
关联的
CONTEXT,
之后
过滤驱动应该把此
IRP
向下层驱动发送
.
IR IRP_MJ_CLEANUP
发 发送时机
:
当 一个文件对象的句柄引用为
0
时
,
发送此
IRP.
也 就是这个文件对象的所有句柄都关闭了
.
一 一般是上层调用
CloseHandle(),
或下层调用
ZwClose
()
关闭 文件对象的最后一个句柄引用时发送此
IRP.
(
the last out standing handle to a file object).
值 值得注意的是一个文件对象的句柄全关闭并不意味着这个 文件对象不再使用了
.
系 系统组件,如缓冲管理器
,VMM
都可能对这个文件对象还有 引用
.
这些在组件在
CLEANUP
发送之后还能对此文件对象 进行操作
.
即
:
总 引用数
=
句柄数
+
内核引用数
操操作
:
文件系统驱动
若目标文件对象是文件系统控制设备对象
(CDO),
那么文件系统驱动必须完成这个
IRP.
否则
,
文件系统驱动应该处理
CLEANUP IRP.
操作
:
文件过滤驱动
若目标对象是文件过滤驱动的控制设备对象,这个过滤驱动应该完成这个
IRP.
否则
,
在完成必要的处理之后将此
IRP
发送到下层驱动。
NE:值得注意的地方!
对于文件过滤驱动开发人员来说,应该注意一个特例
:
IoCreateStreamFileObject
会引发一个
IRP_MJ_CLEANUP,
发送到一个
Volume
的文件驱动
Stack
之中
.
因文件系统驱动经常创建文件流对象
,
但其不是用
IRP_MJ_CREATE,
一个副作用就是过滤驱动难以监测文件流对象的创建
!!
因此有一个心理准备
:
在
Close,CleanUp
中会收在
Create
中没出现过的
FO!!
哈哈
,
原因不是明摆吗?!
过滤驱动开发人员也应该注意的一点是
:
与
IoCreateStreamFileObject
不同
,
IoCreateStreamFileObjectLite
并不引发一个
IRP_MJ_CLEANUP IRP.
估计也不会发送
IRP_MJ_CRAETE,
太奇怪了
,
不太肯定
?
!
因为这此样
,
过滤难以监测到
Stream File Object
的创建
!!
因此有一个心理准备
:
在
Close,CleanUp
中会收在
Create
中没出现过的
FO!!
哈哈
,
原因不是明摆吗?!
1.
"Receipt of the IRP_MJ_CLEANUP request indicates that the handle
reference count . a file object has reached zero. (In other words,
all handles to the file object have been closed.) Often it is sent
when a user-mode application has called the Microsoft Win32
CloseHandle function (or when a kernel-mode driver has called ZwClose)
on the last outstanding handle to a file object. "
The DDK docs here are pretty clear that this is per FILE_OBJECT not
per process nor per DEVICE_OBJECT. .e DEVICE_OBJECT instance can have
many related FILE_OBJECT instances and each FILE_OBJECT instance can
have many related handles.
Ignoring filesystems, as I think you are not an FSD, each user mode
CreateFile is going to correspond to a new FILE_OBJECT associated with
your device driver's DEVICE_OBJECT. Your application gets a handle to
use that correlates to that FILE_OBJECT. Your application could
duplicate that particular handle, and then that FILE_OBJECT would have
more than .e handle associated with it. Do another CreateFile in your
application and you get a new handle associated with a different
FILE_OBJECT associated with the same DEVICE_OBJECT.
2.
IRP_MJ_CLEANUP is guaranteed to be sent in the context of the process that
created the handle. IRP_MJ_CLOSE can come in *any* context, including the
system context after the process has exitted.