プロバイダー モジュールのアンロード

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

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

次に例を示します。

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

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

  // Deregister the provider module from the NMR
  Status =
    NmrDeregisterProvider(
      ProviderHandle
      );

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

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

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

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

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