コールアウト ドライバーのアンロード

コールアウト ドライバーをアンロードするには、オペレーティング システムは、コールアウト ドライバーのアンロード関数を呼び出します。 コールアウト ドライバーのアンロード関数を指定する方法の詳細については、アンロード関数の指定をご覧ください。

コールアウト ドライバーのアンロード関数は、コールアウト ドライバーがシステム メモリからアンロードされる前に、コールアウト ドライバーのコールアウトがフィルター エンジンから登録解除されることを保証します。 コールアウト ドライバーは、FwpsCalloutUnregisterById0 関数または FwpsCalloutUnregisterByKey0 のいずれかを呼び出して、フィルター エンジンからコールアウトを登録解除します。 コールアウト ドライバーは、アンロード関数から戻る前に、すべてのコールアウトをフィルター エンジンから正常に登録解除する必要があります。

コールアウト ドライバーは、すべてのコールアウトをフィルター エンジンから登録解除した後、最初にコールアウトを登録する前に作成したデバイス オブジェクトを削除する必要があります。 Windows ドライバー モデル (WDM) に基づくコールアウト ドライバーは、IoDeleteDevice 関数を呼び出してデバイス オブジェクトを削除します。 Windows ドライバー フレームワーク(WDF) に基づくコールアウト ドライバーは、WdfObjectDelete 関数を呼び出してフレームワーク デバイス オブジェクトを削除します。

コールアウトドライバーは、アンロード関数から戻る前に FwpsInjectionHandleDestroy0 関数を呼び出して、以前に作成したパケットインジェクションハンドルも破棄する必要があります。

次に例を示します。

// 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 ベースのコールアウト ドライバーの唯一の違いは、コールアウト ドライバーのアンロード関数に渡されるパラメーターと、コールアウト ドライバーがフレームワーク デバイス オブジェクトを削除する方法です。

WDFDEVICE wdfDevice;

VOID
 Unload(
    IN WDFDRIVER Driver;
    )
{

  ...

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

  ...
}