Función IoSetCompletionRoutine (wdm.h)
La rutina IoSetCompletionRoutine registra una rutina de IoCompletion , a la que se llamará cuando el controlador de nivel inferior haya completado la operación solicitada para el IRP especificado.
Sintaxis
void IoSetCompletionRoutine(
[in] PIRP Irp,
[in, optional] PIO_COMPLETION_ROUTINE CompletionRoutine,
[in, optional] __drv_aliasesMem PVOID Context,
[in] BOOLEAN InvokeOnSuccess,
[in] BOOLEAN InvokeOnError,
[in] BOOLEAN InvokeOnCancel
);
Parámetros
[in] Irp
Puntero al IRP que está procesando el controlador.
[in, optional] CompletionRoutine
Especifica el punto de entrada de la rutina IoCompletion proporcionada por el controlador, al que se llama cuando el controlador siguiente inferior completa el paquete.
[in, optional] Context
Puntero a un contexto determinado por el controlador que se va a pasar a la rutina IoCompletion . La información de contexto debe almacenarse en memoria no paginada, ya que se llama a la rutina IoCompletion en IRQL <= DISPATCH_LEVEL.
[in] InvokeOnSuccess
Especifica si se llama a la rutina de finalización si el IRP se completa con un valor de estado correcto en la estructura de IO_STATUS_BLOCK del IRP, en función de los resultados de la macro de NT_SUCCESS (consulte Uso de valores NTSTATUS).
[in] InvokeOnError
Especifica si se llama a la rutina de finalización si el IRP se completa con un valor de estado no especificado en la estructura de IO_STATUS_BLOCK de IRP.
[in] InvokeOnCancel
Especifica si se llama a la rutina de finalización si un controlador o el kernel ha llamado a IoCancelIrp para cancelar el IRP.
Valor devuelto
None
Observaciones
Solo un controlador que pueda garantizar que no se descargará antes de que finalice su rutina de finalización puede usar IoSetCompletionRoutine. De lo contrario, el controlador debe usar IoSetCompletionRoutineEx, lo que impide que el controlador se descargue hasta que se ejecute su rutina de finalización.
Esta rutina establece la dirección de transferencia de la rutina IoCompletion en el IRP especificado. El controlador de nivel más bajo de una cadena de controladores superpuestas no puede llamar a esta rutina.
IoSetCompletionRoutine registra la rutina especificada que se va a llamar cuando el controlador de nivel inferior siguiente ha completado la operación solicitada de cualquiera o todas las maneras siguientes:
Con un valor de estado correcto
Con un valor de estado no válido
Al cancelar el IRP
Normalmente, el controlador de dispositivo subyacente establece el bloque de estado de E/S. Es leído pero no modificado por las rutinas de IoCompletion de los controladores de nivel superior.
Los controladores de nivel superior que asignan IRP con IoAllocateIrp o IoBuildAsynchronousFsdRequest deben llamar a esta rutina con todos los parámetros InvokeOnXxx establecidos en TRUE antes de pasar el IRP asignado por el controlador a IoCallDriver. Cuando se llama a la rutina IoCompletion con un IRP de este tipo, debe liberar el IRP asignado por el controlador y cualquier otro recurso que el controlador configuró para la solicitud, como mdLs con IoBuildPartialMdl. Este controlador debe devolver STATUS_MORE_PROCESSING_REQUIRED cuando llama a IoFreeIrp para evitar el procesamiento de finalización del administrador de E/S para el IRP asignado por el controlador.
Los controladores que no son PnP que podrían descargarse antes de que se ejecuten sus rutinas de IoCompletion deben usar IoSetCompletionRoutineEx en su lugar.