Usando a versão CONNECT_MESSAGE_BASED de IoConnectInterruptEx

Para o Windows Vista e sistemas operacionais posteriores, um driver pode usar a versão CONNECT_MESSAGE_BASED de IoConnectInterruptEx para registrar um ISR para interrupções sinalizadas por mensagem do driver. O driver especifica um valor de CONNECT_MESSAGE_BASED para Parameters-Version> e usa os membros deParameters-MessageBased> para especificar os outros parâmetros da operação.

  • Parameters-MessageBased.PhysicalDeviceObject> especifica o PDO para o dispositivo que o ISR serviços. O sistema usa o objeto de dispositivo para identificar automaticamente as interrupções sinalizadas por mensagem do dispositivo.

  • Parameters-MessageBased.MessageServiceRoutine> aponta para a rotina InterruptMessageService, enquanto Parameters-MessageBased.ServiceContext > especifica o valor que o sistema passa como o parâmetro ServiceContext para InterruptMessageService. O driver pode usar isso para passar informações de contexto. Para obter mais informações sobre como passar informações de contexto, consulte Fornecendo informações de contexto do ISR.

  • O driver também pode especificar uma rotina InterruptMessageService de fallback em Parameters-MessageBased.FallBackServiceRoutine>. Se o dispositivo tiver interrupções baseadas em linha, mas nenhuma interrupção sinalizada por mensagem, o sistema registrará a rotina InterruptMessageService para atender às interrupções baseadas em linha. Nesse caso, o sistema passa Parameters-MessageBased.ServiceContext> como o parâmetro ServiceContext para InterruptService. IoConnectInterruptEx atualiza Parameters-Version> para CONNECT_LINE_BASED se registrou a rotina de fallback.

  • Parameters-MessageBased.ConnectionContext> aponta para uma variável que recebe um ponteiro para uma estrutura IO_INTERRUPT_MESSAGE_INFO (para InterruptMessageService) ou uma estrutura KINTERRUPT (para InterruptService). O driver pode usar o ponteiro recebido para remover o ISR. Para obter mais informações, consulte Removendo um ISR.

  • Opcionalmente, os drivers podem especificar um bloqueio de rotação em Parameters-MessageBased.SpinLock> para o sistema usar ao sincronizar com o ISR. A maioria dos drivers pode apenas especificar NULL para permitir que o sistema aloque um bloqueio de rotação em nome do driver. Para obter mais informações sobre como sincronizar com um ISR, consulte Sincronizando o acesso aos dados do dispositivo.

O exemplo de código a seguir demonstra como registrar uma rotina InterruptMessageService usando 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.
    ...
}