Uso della versione CONNECT_FULLY_SPECIFIED di IoConnectInterruptEx
Un driver può usare la versione CONNECT_FULLY_SPECIFIED di IoConnectInterruptEx per registrare una routine InterruptService per un interruzione specifico. Un driver può usare la versione CONNECT_FULLY_SPECIFIED a partire da Windows Vista. Collegando la libreria Iointex.lib, il driver può usare la versione CONNECT_FULLY_SPECIFIED in Windows 2000, Windows XP e Windows Server 2003. Per altre informazioni, vedere Uso di IoConnectInterruptEx prima di Windows Vista.
Il driver specifica un valore di CONNECT_FULLY_SPECIFIED per Parameters-Version e usa i membri di Parameters-FullySpecified >> per specificare gli altri parametri dell'operazione:
Parameters-FullySpecified.PhysicalDeviceObject> specifica l'oggetto PDO per il dispositivo che i servizi ISR.
Parameters-FullySpecified.ServiceRoutine> punta alla routine InterruptService, mentre Parameters-FullySpecified.> ServiceContext specifica il valore passato dal sistema come parametro ServiceContext a InterruptService. 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 fornisce un puntatore a una variabile PKINTERRUPT in Parameters-FullySpecified.InterruptObject>. La routine IoConnectInterruptEx imposta questa variabile per puntare all'oggetto interrupt per l'interruzione, che può essere usato quando si rimuove l'ISR.
I driver possono facoltativamente specificare un blocco spin in Parameters-FullySpecified.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.
Il driver deve specificare le proprietà chiave dell'interruzione in altri membri di Parameters-FullySpecified>. Il sistema fornisce le informazioni necessarie nella matrice di strutture CM_PARTIAL_RESOURCE_DESCRIPTOR quando invia il IRP_MN_START_DEVICE IRP al driver.
Il sistema fornisce per ogni interruzione una struttura CM_PARTIAL_RESOURCE_DESCRIPTOR con membro Type uguale a CmResourceTypeInterrupt. Per un interruzione segnalato dal messaggio, viene impostato il CM_RESOURCE_INTERRUPT_MESSAGE bit del membro Flags ; in caso contrario, viene cancellata.
Il membro u.Interrupt di CM_PARTIAL_RESOURCE_DESCRIPTOR contiene la descrizione di un interruzione basato su riga, mentre il membro u.MessageInterrupt.Translated contiene la descrizione di un interruzione segnalato dal messaggio. La tabella seguente indica dove, nella struttura CM_PARTIAL_RESOURCE_DESCRIPTOR, per trovare le informazioni necessarie per impostare i membri di Parameters-FullySpecified> per entrambi i tipi di interruzione. Per altre informazioni, vedere l'esempio di codice che segue la tabella.
Membro | Interruzione basata su linea | Interruzione segnalata dal messaggio |
---|---|---|
ShareVector |
ShareDisposition |
ShareDisposition |
Vettore |
u.Interrupt.Vector |
u.MessageInterrupt.Translated.Vector |
Irql |
u.Interrupt.Level |
u.MessageInterrupt.Translated.Level |
InterruptMode |
Flag & CM_RESOURCE_INTERRUPT_LATCHED |
Flag & CM_RESOURCE_INTERRUPT_LATCHED |
ProcessorEnableMask |
u.Interrupt.Affinity |
u.MessageInterrupt.Translated.Affinity |
Un driver riceverà solo CM_PARTIAL_RESOURCE_DESCRIPTOR strutture per interruzioni segnalate da messaggi in Windows Vista e versioni successive di Windows.
Nell'esempio di codice seguente viene illustrato come registrare una routine InterruptService usando 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)) {
...
}