Dela via


Använda den CONNECT_MESSAGE_BASED-versionen av IoConnectInterruptEx

För Windows Vista och senare operativsystem kan en drivrutin använda den CONNECT_MESSAGE_BASED versionen av IoConnectInterruptEx för att registrera en ISR för drivrutins meddelandesignalerade avbrott. Drivrutinen anger värdet CONNECT_MESSAGE_BASED för Parameters->Version och använder medlemmarna i Parameters->MessageBased för att ange de andra parametrarna för åtgärden.

  • Parameters-MessageBased.PhysicalDeviceObject> anger PDO för enheten som hanteras av ISR-tjänsten. Systemet använder enhetsobjektet för att automatiskt identifiera enhetens meddelandesignalerade avbrott.

  • Parameters-MessageBased.MessageServiceRoutine> pekar på rutinen InterruptMessageService, medan Parameters-MessageBased.ServiceContext> anger det värde som systemet skickar som parametern ServiceContext till InterruptMessageService. 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 kan också ange en reservrutin för InterruptMessageService i Parameters->MessageBased.FallBackServiceRoutine. Om enheten har linjebaserade avbrott, men inga meddelandesignalerade avbrott, registrerar systemet i stället interruptMessageService-rutinen för att betjäna de linjebaserade avbrotten. I det här fallet skickar systemet Parameters->MessageBased.ServiceContext som parametern ServiceContext till InterruptService. IoConnectInterruptEx uppdaterar Parameters->Version till CONNECT_LINE_BASED om den har registrerat reserverutinen.

  • Parameters->MessageBased.ConnectionContext pekar på en variabel som tar emot en pekare till antingen en IO_INTERRUPT_MESSAGE_INFO-struktur (för InterruptMessageService) eller en KINTERRUPT-struktur (för InterruptService). Drivrutinen kan använda den mottagna pekaren för att ta bort ISR. Mer information finns i Ta bort en ISR.

  • Drivrutiner kan också ange ett spinnlås i Parameters-MessageBased.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.

Följande kodexempel visar hur du registrerar en InterruptMessageService-rutin med hjälp av 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.
    ...
}