发送时机:
当FO的引用为0时,发送此IRP.
通常是由于文件系统驱动或其它内核组件调用ObDereferenceObject()而引发的.
ObDereferenceObject
CLOSE通常在CleanUp之后发送.
但并不是说在CleanUp之后马上就会收到Close IRP,可能在几分钟之后或几个小时之后,更爽的是可能在几天之后收到这个Close IRP.
操作:文件系统驱动
若目标设备对象是文件系统控制设备对象(CDO),在IRP处理完成之后必须完成这个IRP.否则,文件系统驱动应该处理CLOSE IRP.
操作:文件过滤驱动
若目标设备对象是过滤驱动的控制设备对象(CDO),过滤驱动应该结束与CDO有任何信息联系的操作,同时结束这个IRP.
否则,在作相应的处理,如每个FO或FILE关联的CONTEXT,之后
过滤驱动应该把此IRP向下层驱动发送.
发 发送时机:
当 一个文件对象的句柄引用为0时,发送此IRP.
也 就是这个文件对象的所有句柄都关闭了.
一 一般是上层调用CloseHandle(),或下层调用ZwClose()关闭 文件对象的最后一个句柄引用时发送此IRP.
( the last out standing handle to a file object).
值 值得注意的是一个文件对象的句柄全关闭并不意味着这个 文件对象不再使用了.
系 系统组件,如缓冲管理器,VMM都可能对这个文件对象还有 引用.这些在组件在CLEANUP发送之后还能对此文件对象 进行操作.
即:
总 引用数 = 句柄数 + 内核引用数
操操作:文件系统驱动
若目标文件对象是文件系统控制设备对象(CDO),那么文件系统驱动必须完成这个IRP.
否则,文件系统驱动应该处理CLEANUP IRP.
操作:文件过滤驱动
若目标对象是文件过滤驱动的控制设备对象,这个过滤驱动应该完成这个IRP.
否则,在完成必要的处理之后将此IRP发送到下层驱动。
NE:值得注意的地方!
对于文件过滤驱动开发人员来说,应该注意一个特例:
一个副作用就是过滤驱动难以监测文件流对象的创建!!
因此有一个心理准备:
在Close,CleanUp中会收在Create中没出现过的FO!!
哈哈,原因不是明摆吗?!
过滤驱动开发人员也应该注意的一点是:
与IoCreateStreamFileObject不同,
并不引发一个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.