Verwenden der CONNECT_MESSAGE_BASED Version von IoConnectInterruptEx

Unter Windows Vista und höheren Betriebssystemen kann ein Treiber die CONNECT_MESSAGE_BASED Version von IoConnectInterruptEx verwenden, um eine ISR für die nachrichtensignalierten Interrupts des Treibers zu registrieren. Der Treiber gibt den Wert CONNECT_MESSAGE_BASED für Parameters-Version> an und verwendet die Member von Parameters-MessageBased>, um die anderen Parameter des Vorgangs anzugeben.

  • Parameters-MessageBased.PhysicalDeviceObject> gibt die PDO für das Gerät an, das von der ISR bereitgestellt wird. Das System verwendet das Geräteobjekt, um automatisch die nachrichtensignalierten Interrupts des Geräts zu identifizieren.

  • Parameters-MessageBased.MessageServiceRoutine> verweist auf die InterruptMessageService-Routine, während Parameters-MessageBased.ServiceContext> den Wert angibt, den das System als ServiceContext-Parameter an InterruptMessageService übergibt. Der Treiber kann dies verwenden, um Kontextinformationen zu übergeben. Weitere Informationen zum Übergeben von Kontextinformationen finden Sie unter Bereitstellen von ISR-Kontextinformationen.

  • Der Treiber kann auch eine Fallbackroutine interruptMessageService-Routine in Parameters-MessageBased.FallBackServiceRoutine> angeben. Wenn das Gerät über leitungsbasierte Interrupts, aber keine nachrichtensignalierten Interrupts verfügt, registriert das System stattdessen die InterruptMessageService-Routine , um die leitungsbasierten Interrupts zu bedienen. In diesem Fall übergibt das System Parameters-MessageBased.ServiceContext> als ServiceContext-Parameter an InterruptService. IoConnectInterruptEx aktualisiert Parameters-Version> auf CONNECT_LINE_BASED, wenn die Fallbackroutine registriert wurde.

  • Parameters-MessageBased.ConnectionContext> verweist auf eine Variable, die einen Zeiger auf eine IO_INTERRUPT_MESSAGE_INFO-Struktur (für InterruptMessageService) oder eine KINTERRUPT-Struktur (für InterruptService) empfängt. Der Treiber kann den empfangenen Zeiger verwenden, um die ISR zu entfernen. Weitere Informationen finden Sie unter Entfernen einer ISR.

  • Treiber können optional eine Drehsperre in Parameters-MessageBased.SpinLock> angeben, die das System bei der Synchronisierung mit der ISR verwenden soll. Die meisten Treiber können einfach NULL angeben, damit das System eine Drehsperre im Namen des Treibers zuweisen kann. Weitere Informationen zum Synchronisieren mit einer ISR finden Sie unter Synchronisieren des Zugriffs auf Gerätedaten.

Im folgenden Codebeispiel wird veranschaulicht, wie eine InterruptMessageService-Routine mithilfe von CONNECT_MESSAGE_BASED registriert wird.

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