卸载客户端模块

若要卸载客户端模块,操作系统会调用客户端模块的 Unload 函数。 有关如何在初始化期间指定客户端模块的 Unload 函数的详细信息,请参阅初始化和注册客户端模块。

客户端模块的 Unload 函数可确保在从系统内存中卸载客户端模块之前,从网络模块注册器 (NMR) 取消注册客户端模块。 客户端模块通过调用 NmrDeregisterClient 函数(它通常从其 Unload 函数调用)从 NMR 启动取消注册。 客户端模块在从 NMR 完全注销之前,不得从其 Unload 函数返回。 如果对 NmrDeregisterClient 的调用返回STATUS_PENDING,则客户端模块必须调用 NmrWaitForClientDeregisterComplete 函数,等待取消注册完成,然后才能从其 Unload 函数返回。

例如:

// Variable containing the handle for the registration
HANDLE ClientHandle;

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

  // Deregister the client module from the NMR
  Status =
    NmrDeregisterClient(
      ClientHandle
      );

  // Check if pending
  if (Status == STATUS_PENDING)
  {
    // Wait for the deregistration to be completed
    NmrWaitForClientDeregisterComplete(
      ClientHandle
      );
  }

  // An error occurred
  else
  {
    // Handle error
    ...
  }
}

如果客户端模块注册为多个 网络编程接口的客户端, (NPI) ,则必须为其支持的每个 NPI 调用 NmrDeregisterClient 。 如果网络模块同时注册为客户端模块和提供程序模块 (即,它是一个 NPI 的客户端和另一个 NPI) 的提供程序,则它必须同时调用 NmrDeregisterClientNmrDeregisterProvider

网络模块必须等待所有注销完成,然后才能从其 Unload 函数返回。

客户端模块不需要从其 Unload 函数中调用 NmrDeregisterClient。 例如,在客户端模块是复杂驱动程序的子组件的情况下,在停用客户端模块子组件时,可能会取消注册客户端模块。 但是,在这种情况下,驱动程序仍必须确保客户端模块已从 NMR 中完全注销,然后再从其 Unload 函数返回。