Freigeben über


Verwenden der CONNECT_FULLY_SPECIFIED Version von IoConnectInterruptEx

Ein Treiber kann die CONNECT_FULLY_SPECIFIED Version von IoConnectInterruptEx verwenden, um eine InterruptService-Routine für einen bestimmten Interrupt zu registrieren. Ein Treiber kann die CONNECT_FULLY_SPECIFIED Version ab Windows Vista verwenden. Durch verknüpfen mit der Iointex.lib-Bibliothek kann der Treiber die CONNECT_FULLY_SPECIFIED Version in Windows 2000, Windows XP und Windows Server 2003 verwenden. Weitere Informationen finden Sie unter Verwenden von IoConnectInterruptEx vor Windows Vista.

Der Treiber gibt den Wert CONNECT_FULLY_SPECIFIED für Parameters-Version> an und verwendet die Member von Parameters-FullySpecified>, um die anderen Parameter des Vorgangs anzugeben:

  • Parameters-FullySpecified.PhysicalDeviceObject> gibt die PDO für das Gerät an, das von der ISR bereitgestellt wird.

  • Parameters-FullySpecified.ServiceRoutine> verweist auf die InterruptService-Routine, während Parameters-FullySpecified>. ServiceContext gibt den Wert an, den das System als ServiceContext-Parameter an InterruptService ü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 stellt einen Zeiger auf eine PKINTERRUPT-Variable in Parameters-FullySpecified.InterruptObject> bereit. Die IoConnectInterruptEx-Routine legt diese Variable so fest, dass sie auf das Interruptobjekt für den Interrupt verweist, das beim Entfernen der ISR verwendet werden kann.

  • Treiber können optional eine Drehsperre in Parameters-FullySpecified.SpinLock> für das System angeben, das bei der Synchronisierung mit der ISR verwendet werden 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.

Der Treiber muss die Schlüsseleigenschaften des Interrupts in anderen Membern von Parameters-FullySpecified> angeben. Das System stellt die erforderlichen Informationen im Array der CM_PARTIAL_RESOURCE_DESCRIPTOR-Strukturen bereit, wenn es die IRP_MN_START_DEVICE IRP an den Treiber sendet.

Das System stellt für jeden Interrupt eine CM_PARTIAL_RESOURCE_DESCRIPTOR-Struktur bereit, deren Type-MembercmResourceTypeInterrupt entspricht. Bei einem Interrupt mit Nachrichtensignal wird das CM_RESOURCE_INTERRUPT_MESSAGE Bit des Flags-Elements festgelegt. Andernfalls wird es gelöscht.

Der u.Interrupt-Member von CM_PARTIAL_RESOURCE_DESCRIPTOR enthält die Beschreibung eines zeilenbasierten Interrupts, während das u.MessageInterrupt.Translated-Element die Beschreibung eines Nachrichtensignal-Interrupts enthält. Die folgende Tabelle gibt an, wo in der CM_PARTIAL_RESOURCE_DESCRIPTOR-Struktur die Informationen gefunden werden können, die zum Festlegen der Member von Parameters-FullySpecified> für beide Interrupttypen erforderlich sind. Weitere Informationen finden Sie im Codebeispiel, das auf die Tabelle folgt.

Member Zeilenbasierter Interrupt Interrupt mit Nachrichtensignalen

ShareVector

ShareDisposition

ShareDisposition

Vektor

u.Interrupt.Vector

u.MessageInterrupt.Translated.Vector

Irql

u.Interrupt.Level

u.MessageInterrupt.Translated.Level

InterruptMode

flags & CM_RESOURCE_INTERRUPT_LATCHED

flags & CM_RESOURCE_INTERRUPT_LATCHED

ProcessorEnableMask

u.Interrupt.Affinity

u.MessageInterrupt.Translated.Affinity

Ein Treiber empfängt nur CM_PARTIAL_RESOURCE_DESCRIPTOR Strukturen für unterbrechungsfreie Nachrichten unter Windows Vista und höheren Versionen von Windows.

Im folgenden Codebeispiel wird veranschaulicht, wie eine InterruptService-Routine mithilfe von CONNECT_FULLY_SPECIFIED registriert wird.

IO_CONNECT_INTERRUPT_PARAMETERS params;

// deviceExtension is a pointer to the driver's device extension. 
//     deviceExtension->IntObj is a PKINTERRUPT.
// deviceInterruptService is a pointer to the driver's InterruptService routine.
// IntResource is a CM_PARTIAL_RESOURCE_DESCRIPTOR structure of either type CmResourceTypeInterrupt or CmResourceTypeMessageInterrupt.
// 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_FULLY_SPECIFIED;
params.FullySpecified.PhysicalDeviceObject = PhysicalDeviceObject;
params.FullySpecified.InterruptObject = &devExt->IntObj;
params.FullySpecified.ServiceRoutine = deviceInterruptService;
params.FullySpecified.ServiceContext = ServiceContext;
params.FullySpecified.FloatingSave = FALSE;
params.FullySpecified.SpinLock = NULL;

if (IntResource->Flags & CM_RESOURCE_INTERRUPT_MESSAGE) {
    // The resource is for a message-signaled interrupt. Use the u.MessageInterrupt.Translated member of IntResource.
 
    params.FullySpecified.Vector = IntResource->u.MessageInterrupt.Translated.Vector;
    params.FullySpecified.Irql = (KIRQL)IntResource->u.MessageInterrupt.Translated.Level;
    params.FullySpecified.SynchronizeIrql = (KIRQL)IntResource->u.MessageInterrupt.Translated.Level;
    params.FullySpecified.ProcessorEnableMask = IntResource->u.MessageInterrupt.Translated.Affinity;
} else {
    // The resource is for a line-based interrupt. Use the u.Interrupt member of IntResource.
 
    params.FullySpecified.Vector = IntResource->u.Interrupt.Vector;
    params.FullySpecified.Irql = (KIRQL)IntResource->u.Interrupt.Level;
    params.FullySpecified.SynchronizeIrql = (KIRQL)IntResource->u.Interrupt.Level;
    params.FullySpecified.ProcessorEnableMask = IntResource->u.Interrupt.Affinity;
}

params.FullySpecified.InterruptMode = (IntResource->Flags & CM_RESOURCE_INTERRUPT_LATCHED ? Latched : LevelSensitive);
params.FullySpecified.ShareVector = (BOOLEAN)(IntResource->ShareDisposition == CmResourceShareShared);

status = IoConnectInterruptEx(&params);

if (!NT_SUCCESS(status)) {
    ...
}