Uso della versione CONNECT_MESSAGE_BASED di IoConnectInterruptEx

Per i sistemi operativi Windows Vista e versioni successive, un driver può usare la versione CONNECT_MESSAGE_BASED di IoConnectInterruptEx per registrare un ISR per gli interruzioni segnalato dal driver. Il driver specifica un valore di CONNECT_MESSAGE_BASED per Parameters-Version e usa i membri diParameters-MessageBased>> per specificare gli altri parametri dell'operazione.

  • Parameters-MessageBased.PhysicalDeviceObject> specifica il PDO per il dispositivo che i servizi ISR. Il sistema usa l'oggetto dispositivo per identificare automaticamente gli interruzioni segnalate dal dispositivo.

  • Parameters-MessageBased.MessageServiceRoutine punta alla routine InterruptMessageService, mentre Parameters-MessageBased.ServiceContext>> specifica il valore passato dal sistema come parametro ServiceContext a InterruptMessageService. Il driver può usarlo per passare le informazioni di contesto. Per altre informazioni sul passaggio delle informazioni sul contesto, vedere Fornire informazioni sul contesto ISR.

  • Il driver può anche specificare una routine di fallback InterruptMessageService in Parameters-MessageBased.FallBackServiceRoutine>. Se il dispositivo ha interruzioni basate su riga, ma non viene interrotto alcun messaggio, il sistema registra invece la routine InterruptMessageService per il servizio degli interruzioni basati su riga. In questo caso, il sistema passa Parameters-MessageBased.ServiceContext> come parametro ServiceContext a InterruptService. IoConnectInterruptEx aggiorna Parameters-Version> in CONNECT_LINE_BASED se ha registrato la routine di fallback.

  • Parameters-MessageBased.ConnectionContext> punta a una variabile che riceve un puntatore a una struttura IO_INTERRUPT_MESSAGE_INFO (for InterruptMessageService) o a una struttura KINTERRUPT (per InterruptService). Il driver può usare il puntatore ricevuto per rimuovere l'ISR. Per altre informazioni, vedere Rimozione di un ISR.

  • I driver possono facoltativamente specificare un blocco spin in Parameters-MessageBased.SpinLock> per il sistema da usare durante la sincronizzazione con ISR. La maggior parte dei driver può solo specificare NULL per consentire al sistema di allocare un blocco spin per conto del driver. Per altre informazioni sulla sincronizzazione con un ISR, vedere Sincronizzazione dell'accesso ai dati del dispositivo.

Nell'esempio di codice seguente viene illustrato come registrare una routine 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.
    ...
}