Scaricamento di un driver callout

Per scaricare un driver callout, il sistema operativo chiama la funzione di scaricamento del driver del callout. Per altre informazioni su come specificare la funzione di scaricamento di un driver di callout, vedere Specifica di una funzione di scaricamento.

La funzione di scaricamento di un driver di callout garantisce che i callout del driver del callout vengano annullati dalla registrazione dal motore di filtro prima che il driver del callout venga scaricato dalla memoria di sistema. Un driver callout chiama la funzione FwpsCalloutUnregisterById0 o la funzione FwpsCalloutUnregisterByKey0 per annullare la registrazione di un callout dal motore di filtro. Un driver di callout non deve restituire dalla funzione di scaricamento finché non viene annullata la registrazione di tutti i callout dal motore di filtro.

Dopo che un driver di callout ha annullato la registrazione di tutti i relativi callout dal motore di filtro, deve eliminare l'oggetto dispositivo creato prima di registrare originariamente i relativi callout. Un driver di callout basato sul modello di driver Windows (WDM) chiama la funzione IoDeleteDevice per eliminare l'oggetto dispositivo. Un driver callout basato su Windows Driver Frameworks (WDF) chiama la funzione WdfObjectDelete per eliminare l'oggetto dispositivo framework.

Un driver di callout deve anche distruggere qualsiasi handle di inserimento di pacchetti creato in precedenza chiamando la funzione FwpsChangectionHandleDestroy0 prima che restituisca dalla funzione di scaricamento.

Ad esempio:

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

Nell'esempio precedente si presuppone un driver di callout basato su WDM. Per un driver di callout basato su WDF, l'unica differenza è il parametro passato alla funzione di scaricamento del driver del callout e il modo in cui il driver del callout elimina l'oggetto dispositivo framework.

WDFDEVICE wdfDevice;

VOID
 Unload(
    IN WDFDRIVER Driver;
    )
{

  ...

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

  ...
}