Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
En drivrutin kan använda den CONNECT_FULLY_SPECIFIED versionen av IoConnectInterruptEx för att registrera en InterruptService-rutin för ett specifikt avbrott. En drivrutin kan använda den CONNECT_FULLY_SPECIFIED versionen från och med Windows Vista. Genom att länka till biblioteket Iointex.lib kan drivrutinen använda den CONNECT_FULLY_SPECIFIED versionen i Windows 2000, Windows XP och Windows Server 2003. För mer information, se Före Windows Vista, använda IoConnectInterruptEx.
Drivrutinen anger värdet CONNECT_FULLY_SPECIFIED för Parameters->Version och använder medlemmarna i Parameters->FullySpecified för att ange de andra parametrarna för operationen.
Parametrar->FullySpecified.PhysicalDeviceObject specificerar PDO för den enhet som ISR hanterar.
Parameters-FullySpecified.ServiceRoutine> pekar på InterruptService-rutinen, medan Parameters-FullySpecified->ServiceContext specificerar det värde som systemet skickar som ServiceContext-parametern till InterruptService. Föraren kan använda detta för att skicka kontextinformation. Mer information om hur du skickar kontextinformation finns i Tillhandahålla ISR-kontextinformation.
Drivrutinen ger en pekare till en PKINTERRUPT-variabel i Parameters->FullySpecified.InterruptObject. IoConnectInterruptEx-rutinen anger att den här variabeln ska peka på avbrottsobjektet för avbrottet, som kan användas vid borttagning av ISR.
Drivrutiner kan också ange ett spinnlås i Parameters-FullySpecified.SpinLock> som systemet ska använda vid synkronisering med ISR. De flesta drivrutiner kan bara ange NULL för att göra det möjligt för systemet att allokera ett spinnlås åt drivrutinen. Mer information om hur du synkroniserar med en ISR finns i Synkronisera åtkomst till enhetsdata.
Drivrutinen måste specificera egenskaperna för avbrottet i andra medlemmar i Parameters->FullySpecified. Systemet tillhandahåller den nödvändiga informationen i CM_PARTIAL_RESOURCE_DESCRIPTOR-strukturerna när det skickar IRP_MN_START_DEVICE IRP till drivrutinen.
Systemet tillhandahåller för varje avbrott en CM_PARTIAL_RESOURCE_DESCRIPTOR struktur med typmedlem lika med CmResourceTypeInterrupt. För ett meddelandesignalerat avbrott anges CM_RESOURCE_INTERRUPT_MESSAGE-biten i flags-medlemmen. Annars rensas den.
U.Interrupt-medlemmen i CM_PARTIAL_RESOURCE_DESCRIPTOR innehåller beskrivningen av ett linjebaserat avbrott, medan medlemmen u.MessageInterrupt.Translated innehåller beskrivningen av ett meddelandesignalerat avbrott. Följande tabell anger var i CM_PARTIAL_RESOURCE_DESCRIPTOR-strukturen, för att hitta informationen som krävs för att ange medlemmar i Parameters->FullySpecified för båda typerna av avbrott. Mer information finns i kodexemplet som följer tabellen.
| Medlem | Linjebaserat avbrott | Meddelandesignalerat avbrott |
|---|---|---|
ShareVector |
ShareDisposition |
ShareDisposition |
Vektor |
u.Interrupt.Vector |
u.MessageInterrupt.Translated.Vector |
Irql |
u.Interrupt.Level |
u.MessageInterrupt.Translated.Level |
Avbrottsläge |
Flaggor och CM_RESOURCE_INTERRUPT_LATCHED |
Flaggor och CM_RESOURCE_INTERRUPT_LATCHED |
ProcessorEnableMask |
u.Interrupt.Affinity |
u.MessageInterrupt.Translated.Affinity |
En drivrutin får endast CM_PARTIAL_RESOURCE_DESCRIPTOR strukturer för meddelandesignalerade avbrott i Windows Vista och senare versioner av Windows.
Följande kodexempel visar hur du registrerar en InterruptService-rutin med hjälp av CONNECT_FULLY_SPECIFIED.
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( ¶ms, 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(¶ms);
if (!NT_SUCCESS(status)) {
...
}