卸载标注驱动程序

若要卸载标注驱动程序,操作系统会调用标注驱动程序的 unload 函数。 有关如何指定标注驱动程序的 unload 函数的详细信息,请参阅 指定 Unload 函数

标注驱动程序的 unload 函数保证在从系统内存中卸载标注驱动程序之前,将从筛选器引擎中注销标注驱动程序的标注。 标注驱动程序调用 FwpsCalloutUnregisterById0 函数或 FwpsCalloutUnregisterByKey0 函数从筛选器引擎取消注册标注。 标注驱动程序在成功从筛选器引擎取消注册其所有标注之前,不得从其 unload 函数返回。

在标注驱动程序从筛选器引擎取消注册其所有标注后,它必须删除它最初注册其标注之前创建的设备对象。 基于 Windows 驱动程序模型 (WDM 的标注驱动程序) 调用 IoDeleteDevice 函数以删除设备对象。 基于 Windows 驱动程序框架的标注驱动程序 (WDF) 调用 WdfObjectDelete 函数以删除框架设备对象。

标注驱动程序还必须销毁它之前通过调用 FwpsInjectionHandleDestroy0 函数创建的任何数据包注入句柄,然后才能从其 unload 函数返回。

例如:

// Device object
PDEVICE_OBJECT deviceObject;

// Variable for the run-time callout identifier
UINT32 CalloutId;

// Injection handle
HANDLE injectionHandle;

// Unload function
VOID
 Unload(
    IN PDRIVER_OBJECT DriverObject
    )
{
  NTSTATUS status;

  // Unregister the callout
 status =
 FwpsCalloutUnregisterById0(
 CalloutId
      );

  // Check result
 if (status == STATUS_DEVICE_BUSY)
  {
    // For each data flow that is being processed by the
    // callout that has an associated context, clean up
    // the context and then call FwpsFlowRemoveContext0
    // to remove the context from the data flow.
    ...

    // Finish unregistering the callout
 status =
 FwpsCalloutUnregisterById0(
 CalloutId
        );
  }

  // Check status
 if (status != STATUS_SUCCESS)
  {
    // Handle error
    ...
  }

  // Delete the device object
 IoDeleteDevice(
 deviceObject
    );

  // Destroy the injection handle
 status =
 FwpsInjectionHandleDestroy0(
 injectionHandle
      );

  // Check status
 if (status != STATUS_SUCCESS)
  {
    // Handle error
    ...
  }
}

前面的示例假定基于 WDM 的标注驱动程序。 对于基于 WDF 的标注驱动程序,唯一的区别是传递给标注驱动程序的 unload 函数的参数,以及标注驱动程序如何删除框架设备对象。

WDFDEVICE wdfDevice;

VOID
 Unload(
    IN WDFDRIVER Driver;
    )
{

  ...

  // Delete the framework device object
 WdfObjectDelete(
 wdfDevice
    );

  ...
}