クライアント モジュールのアンロード

クライアント モジュールをアンロードするには、オペレーティング システムはクライアント モジュールのアンロード関数を呼び出します。 初期化中にクライアント モジュールのアンロード関数を指定する方法の詳細については、クライアント モジュールの初期化と登録をご覧ください。

クライアント モジュールのアンロード関数は、クライアント モジュールがシステム メモリからアンロードされる前に、クライアント モジュールがネットワーク モジュール レジストラー (NMR) から登録解除されるようにします。 クライアント モジュールは、NmrDeregisterClient 関数を呼び出すことで NMR からの登録解除を開始します。NmrDeregisterClient 関数は通常、アンロード関数から呼び出します。 クライアント モジュールは、NMR から完全に登録解除されるまで、アンロード関数から戻ることはできません。 NmrDeregisterClient への呼び出しが STATUS_PENDING を返す場合、クライアント モジュールは、mrWaitForClientDeregisterComplete 関数を呼び出して登録解除が完了するのを待機してからアンロード関数から戻る必要があります。

次に例を示します。

// 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
    ...
  }
}

クライアント モジュールが複数のネットワーク プログラミング インターフェイス (NPIs)のクライアントとして登録されている場合は、それがサポートしているNPIごとに、NmrDeregisterClient を呼び出す必要があります。 ネットワーク モジュールがクライアント モジュールとプロバイダー モジュールの両方として登録されている場合 (つまり、1 つの NPI のクライアントであり、別の NPI のプロバイダーである場合)、NmrDeregisterClientNmrDeregisterProviderの両方を呼び出す必要があります。

ネットワーク モジュールは、すべての登録解除処理が完了するまで待機してから、アンロード関数から戻る必要があります。

クライアント モジュールは、アンロード関数内から NmrDeregisterClient を呼び出す必要はありません。 たとえば、クライアント モジュールが複雑なドライバーのサブコンポーネントである場合、クライアント モジュールの登録解除は、クライアント モジュールのサブコンポーネントが非アクティブ化される際に発生することがあります。 ただし、このような状況では、ドライバーは、クライアント モジュールが完全に NMR から登録解除されていることを、アンロード関数から戻る前に確認する必要があります。