ObDereferenceObjectWithTag 宏 (wdm.h)

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

语法

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

参数

[in] a

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

[in] t

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

返回值

备注

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

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

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

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

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

  1. 调用 ObDereferenceObjectWithTag
  2. 获取对象的句柄。 如有必要,请调用相应的 ZwOpenXxx 或 ZwCreateXxx 例程以获取对象句柄。
  3. 使用步骤 2 中获取的句柄调用 ZwMakeTemporaryObject
  4. 使用步骤 2 中获取的句柄调用 ZwClose
如果当前线程立即删除对象可能会导致死锁,请不要调用 ObDereferenceObjectWithTag 来取消引用该对象。 请改为调用 ObDereferenceObjectDeferDeleteWithTag 例程来取消引用对象。

例如,如果 ObDereferenceObjectWithTag 用于取消引用 内核事务管理器 (KTM) 对象,则当驱动程序堆栈上的较高级别驱动程序持有锁时,可能会发生此类死锁。

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

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

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

要求

   
最低受支持的客户端 在 Windows 7 及更高版本的 Windows 操作系统中可用。
目标平台 桌面
Header 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