Compartir a través de


Descargar un controlador de llamada

Para descargar un controlador de llamada, el sistema operativo llama a la función de descarga del controlador de llamada. Para obtener más información sobre cómo especificar una función de descarga del controlador de llamada, vea Especificar una función unload.

Una función de descarga del controlador de llamada garantiza que las llamadas del controlador de llamada no se registran desde el motor de filtro antes de que el controlador de llamada se descargue de la memoria del sistema. Un controlador de llamada llama a la función FwpsCalloutUnregisterById0 o a la función FwpsCalloutUnregisterByKey0 para anular el registro de una llamada del motor de filtros. Un controlador de llamada no debe volver de su función de descarga hasta que haya anulado correctamente el registro de todas sus llamadas del motor de filtro.

Una vez que un controlador de llamada ha anulado el registro de todas sus llamadas del motor de filtros, debe eliminar el objeto de dispositivo que creó antes de registrar originalmente sus llamadas. Un controlador de llamada basado en el modelo de controlador de Windows (WDM) llama a la función IoDeleteDevice para eliminar el objeto de dispositivo. Un controlador de llamada basado en windows Driver Frameworks (WDF) llama a la función WdfObjectDelete para eliminar el objeto de dispositivo del marco.

Un controlador de llamada también debe destruir cualquier identificador de inyección de paquetes que haya creado anteriormente llamando a la función FwpsInjectionHandleDestroy0 antes de que vuelva de su función de descarga.

Por ejemplo:

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

En el ejemplo anterior se supone que hay un controlador de llamada basado en WDM. En el caso de un controlador de llamada basado en WDF, la única diferencia es el parámetro que se pasa a la función de descarga del controlador de llamada y cómo el controlador de llamada elimina el objeto de dispositivo de marco.

WDFDEVICE wdfDevice;

VOID
 Unload(
    IN WDFDRIVER Driver;
    )
{

  ...

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

  ...
}