Uso de la versión CONNECT_MESSAGE_BASED de IoConnectInterruptEx

Para Windows Vista y sistemas operativos posteriores, un controlador puede usar la versión CONNECT_MESSAGE_BASED de IoConnectInterruptEx para registrar un ISR para las interrupciones señaladas por mensajes del controlador. El controlador especifica un valor de CONNECT_MESSAGE_BASED para Parameters-Version> y usa los miembros deParameters-MessageBased> para especificar los demás parámetros de la operación.

  • Parameters-MessageBased.PhysicalDeviceObject> especifica el PDO para el dispositivo que los servicios ISR. El sistema usa el objeto de dispositivo para identificar automáticamente las interrupciones señaladas por mensajes del dispositivo.

  • Parameters-MessageBased.MessageServiceRoutine> apunta a la rutina InterruptMessageService, mientras que Parameters-MessageBased.ServiceContext> especifica el valor que el sistema pasa como el parámetro ServiceContext a InterruptMessageService. El controlador puede usarlo para pasar información de contexto. Para obtener más información sobre cómo pasar información de contexto, vea Proporcionar información de contexto de ISR.

  • El controlador también puede especificar una rutina InterruptMessageService de reserva en Parameters-MessageBased.FallBackServiceRoutine>. Si el dispositivo tiene interrupciones basadas en línea, pero no hay interrupciones señaladas por mensajes, el sistema registrará en su lugar la rutina InterruptMessageService para atender las interrupciones basadas en línea. En este caso, el sistema pasa Parameters-MessageBased.ServiceContext> como el parámetro ServiceContext a InterruptService. IoConnectInterruptEx actualiza Parameters-Version> para CONNECT_LINE_BASED si registró la rutina de reserva.

  • Parameters-MessageBased.ConnectionContext> apunta a una variable que recibe un puntero a una estructura IO_INTERRUPT_MESSAGE_INFO (para InterruptMessageService) o a una estructura KINTERRUPT (para InterruptService). El controlador puede usar el puntero recibido para quitar el ISR. Para obtener más información, consulte Eliminación de un ISR.

  • Opcionalmente, los controladores pueden especificar un bloqueo de número en Parameters-MessageBased.SpinLock> para que el sistema lo use al sincronizar con el ISR. La mayoría de los controladores simplemente pueden especificar NULL para permitir que el sistema asigne un bloqueo de número en nombre del controlador. Para obtener más información sobre la sincronización con un ISR, consulte Sincronizar el acceso a los datos del dispositivo.

En el ejemplo de código siguiente se muestra cómo registrar una rutina InterruptMessageService mediante CONNECT_MESSAGE_BASED.

IO_CONNECT_INTERRUPT_PARAMETERS params;

// deviceExtension is a pointer to the driver's device extension. 
//     deviceExtension->IntInfo is a PVOID.
//     deviceExtension->IntType is a ULONG.
// deviceInterruptService is a pointer to the driver's InterruptService routine.
// deviceInterruptMessageService is a pointer to the driver's InterruptMessageService routine.
// PhysicalDeviceObject is a pointer to the device's PDO. 
// ServiceContext is a pointer to driver-specified context for the ISR.

RtlZeroMemory( &params, sizeof(IO_CONNECT_INTERRUPT_PARAMETERS) );
params.Version = CONNECT_MESSAGE_BASED;
params.MessageBased.PhysicalDeviceObject = PhysicalDeviceObject;
params.MessageBased.MessageServiceRoutine = deviceInterruptMessageService;
params.MessageBased.ServiceContext = ServiceContext;
params.MessageBased.SpinLock = NULL;
params.MessageBased.SynchronizeIrql = 0;
params.MessageBased.FloatingSave = FALSE;
params.MessageBased.FallBackServiceRoutine = deviceInterruptService;

status = IoConnectInterruptEx(&params);

if (NT_SUCCESS(status)) {
    // We record the type of ISR registered.
    devExt->IsrType = params.Version;
} else {
    // Operation failed. Handle error.
    ...
}