obDereferenceObjectWithTag 宏 (wdm.h)

ObDereferenceObjectWithTag 例程递减指定对象的引用计数,并将四字节标记值写入对象以支持对象引用跟踪

语法

void ObDereferenceObjectWithTag(
  [in]  a,
  [in]  t
);

参数

[in] a

指向 对象的指针。 调用方在创建 对象时获取此指针,或者在打开对象后从对 ObReferenceObjectByHandleWithTag 例程的先前调用中获取此指针。

[in] t

指定四字节的自定义标记值。 有关更多信息,请参见下面的“备注”部分。

返回值

备注

ObDereferenceObjectWithTag 返回保留供系统使用的值。 驱动程序必须将此值视为 VOID。

内核模式驱动程序调用此例程以将对象的引用计数递减 1。 如果对象是作为 临时 (创建的,则) 创建对象时未指定OBJ_PERMANENT标志,并且引用计数达到零,则对象管理器将删除该对象。

当对象的引用计数达到零时,内核模式组件可以删除该对象。 但是,驱动程序只能删除它创建的那些对象,并且驱动程序绝不应尝试删除它未创建的任何对象。

如果对象是使用指定的OBJ_PERMANENT对象属性标志创建的,则它是 永久性 的。 (有关对象属性的详细信息,请参阅 InitializeObjectAttributes.) 创建永久对象时,初始引用计数为 1,因此在驱动程序删除对对象的最后一个引用时不会删除该对象。

若要准备要删除的永久对象,驱动程序可以调用 ZwMakeTemporaryObject 例程以使该对象成为临时对象。 驱动程序应仅删除它创建的永久对象。 使用以下步骤删除永久对象:

  1. 调用 ObDereferenceObjectWithTag

  2. 获取 对象的句柄。 如有必要,请调用相应的 ZwOpenXxxZwCreateXxx 例程以获取对象句柄。

  3. 使用步骤 2 中获取的句柄调用 ZwMakeTemporaryObject

  4. 使用在步骤 2 中获取的句柄调用 ZwClose

如果当前线程立即删除对象可能会导致死锁,请不要调用 ObDereferenceObjectWithTag 来取消引用该对象。 相反,调用 ObDereferenceObjectDeferDeleteWithTag 例程来取消引用对象。

例如,如果使用 ObDereferenceObjectWithTag 取消引用 内核事务管理器 (KTM) 对象,则可能会出现此类死锁。

有关对象引用的详细信息,请参阅 对象的生命周期

ObDereferenceObject 例程类似于 ObDereferenceObjectWithTag,只不过它不允许调用方将自定义标记写入对象。 在 Windows 7 及更高版本的 Windows 中, ObDereferenceObject 始终将默认标记值 ('tlfD') 写入对象。 对 ObDereferenceObject 的调用与对指定 Tag = 'tlfD' 的 ObDereferenceObjectWithTag 的调用具有相同的效果。

若要在 Windows 调试工具中查看对象引用跟踪,请使用 !obtrace 内核模式调试器扩展。 在 Windows 7 中,如果启用了对象引用跟踪,则会增强 !obtrace 扩展以显示对象引用标记。 默认情况下,对象引用跟踪处于关闭状态。 使用 全局标志编辑器 (Gflags) 启用对象引用跟踪。 有关详细信息,请参阅 使用标记进行对象引用跟踪

要求

要求
最低受支持的客户端 在 Windows 7 及更高版本的 Windows 操作系统中可用。
目标平台 桌面
标头 wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h、Fltkernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL
DDI 符合性规则 HwStorPortProhibitedDDI (storport)

另请参阅

InitializeObjectAttributes

IoGetDeviceObjectPointer

ObDereferenceObject

ObDereferenceObjectDeferDeleteWithTag

ObReferenceObjectByHandleWithTag

ZwClose

ZwMakeTemporaryObject