对象的生命周期

本主题介绍对象的“生命周期”,即对象管理器如何引用和跟踪对象。 本主题还介绍如何使对象成为临时或永久对象。

对象引用计数

对象管理器维护对对象的引用数的计数。 创建对象时,对象管理器会将对象的引用计数设置为 1。 该计数器降至零后,将释放对象。

驱动程序必须确保对象管理器为其操作的任何对象提供准确的引用计数。 过早释放的对象可能导致系统崩溃。 引用计数错误地高的对象将永远不会释放。

对象可以通过句柄或指针进行引用。 除了引用计数之外,对象管理器还维护对象打开的句柄数的计数。 打开句柄的每个例程都会使对象引用计数和对象句柄计数增加一个。 对此类例程的每次调用必须与 对 ZwClose 的相应调用匹配。 有关详细信息,请参阅 对象句柄

在内核模式下,对象可以通过指向 对象的指针进行引用。 返回指向对象的指针的例程(如 IoGetAttachedDeviceReference)将引用计数增加一个。 使用指针完成驱动程序后,它必须调用 ObDereferenceObject ,以将引用计数减少 1。

以下例程都会将对象的引用计数增加 1:

ExCreateCallback

IoGetAttachedDeviceReference

IoGetDeviceObjectPointer

IoWMIOpenBlock

ObReferenceObject

ObReferenceObjectByHandle

ObReferenceObjectByPointer

对上述任何例程进行的每个调用都必须与对 ObDereferenceObject 的相应调用匹配。

提供 ObReferenceObjectObReferenceObjectByPointer 例程,以便驱动程序可以将已知对象指针的引用计数增加 1。 ObReferenceObject 只是增加了引用计数。 ObReferenceObjectByPointer 在增加引用计数之前执行访问检查。

ObReferenceObjectByHandle 例程接收对象句柄并提供指向基础对象的指针。 它也会使引用计数增加 1。

临时和永久对象

大多数对象是 临时的;只要它们正在使用,它们就会存在,然后由对象管理器释放它们。 可以创建 永久对象。 如果对象是永久性的,则对象管理器本身保留对 对象的引用。 因此,其引用计数仍大于零,并且对象在不再使用时不会释放。

仅可按名称访问临时对象,前提是其句柄计数为非零。 句柄计数递减到零后,将从对象管理器的命名空间中删除对象的名称。 只要此类对象的引用计数仍大于零,这些对象仍可通过指针访问。 只要永久对象存在,就可以按名称访问它们。

通过在对象的 OBJECT_ATTRIBUTES 结构中 指定 OBJ_PERMANENT 属性,可以在创建对象时将其永久化。 有关详细信息,请参阅 InitializeObjectAttributes

若要使永久对象成为临时对象,请使用 ZwMakeTemporaryObject 例程。 此例程导致对象在不再使用后自动删除。 (如果对象没有打开的句柄,则会立即从对象管理器的命名空间中删除对象的名称。对象本身一直保留,直到引用计数降至零。)