Utilisation de la version CONNECT_FULLY_SPECIFIED d’IoConnectInterruptEx
Un pilote peut utiliser la version CONNECT_FULLY_SPECIFIED d’IoConnectInterruptEx pour inscrire une routine InterruptService pour une interruption spécifique. Un pilote peut utiliser la version CONNECT_FULLY_SPECIFIED à partir de Windows Vista. En lisant la bibliothèque Iointex.lib, le pilote peut utiliser la version CONNECT_FULLY_SPECIFIED dans Windows 2000, Windows XP et Windows Server 2003. Pour plus d’informations, consultez Utilisation d’IoConnectInterruptEx avant Windows Vista.
Le pilote spécifie une valeur de CONNECT_FULLY_SPECIFIED pour Parameters-Version> et utilise les membres de Parameters-FullySpecified> pour spécifier les autres paramètres de l’opération :
Parameters-FullySpecified.PhysicalDeviceObject> spécifie le PDO pour l’appareil que l’ISR dessert.
Parameters-FullySpecified.ServiceRoutine> pointe vers la routine InterruptService, tandis que Parameters-FullySpecified>. ServiceContext spécifie la valeur que le système transmet comme paramètre ServiceContext à InterruptService. Le pilote peut l’utiliser pour transmettre des informations de contexte. Pour plus d’informations sur la transmission d’informations de contexte, consultez Fournir des informations de contexte ISR.
Le pilote fournit un pointeur vers une variable PKINTERRUPT dans Parameters-FullySpecified.InterruptObject>. La routine IoConnectInterruptEx définit cette variable pour pointer vers l’objet d’interruption pour l’interruption, qui peut être utilisé lors de la suppression de l’ISR.
Les pilotes peuvent éventuellement spécifier un verrou de rotation dans Parameters-FullySpecified.SpinLock> pour le système à utiliser lors de la synchronisation avec l’ISR. La plupart des pilotes peuvent simplement spécifier NULL pour permettre au système d’allouer un verrou de rotation pour le compte du pilote. Pour plus d’informations sur la synchronisation avec un ISR, consultez Synchronisation de l’accès aux données d’appareil.
Le pilote doit spécifier les propriétés clés de l’interruption dans les autres membres de Parameters-FullySpecified>. Le système fournit les informations nécessaires dans le tableau des structures de CM_PARTIAL_RESOURCE_DESCRIPTOR lorsqu’il envoie le IRP_MN_START_DEVICE IRP au pilote.
Le système fournit pour chaque interruption une structure CM_PARTIAL_RESOURCE_DESCRIPTOR dont le membre Type est égal à CmResourceTypeInterrupt. Pour une interruption signalée par un message, le bit CM_RESOURCE_INTERRUPT_MESSAGE du membre Flags est défini ; sinon, il est effacé.
Le membre u.Interrupt de CM_PARTIAL_RESOURCE_DESCRIPTOR contient la description d’une interruption basée sur des lignes, tandis que le membre u.MessageInterrupt.Translated contient la description d’une interruption signalée par un message. Le tableau suivant indique où, dans la structure CM_PARTIAL_RESOURCE_DESCRIPTOR, trouver les informations nécessaires pour définir les membres de Parameters-FullySpecified> pour les deux types d’interruption. Pour plus d’informations, consultez l’exemple de code qui suit le tableau.
Membre | Interruption basée sur les lignes | Interruption signalée par message |
---|---|---|
ShareVector |
ShareDisposition |
ShareDisposition |
Vecteur |
u.Interrupt.Vector |
u.MessageInterrupt.Translated.Vector |
Irql |
u.Interrupt.Level |
u.MessageInterrupt.Translated.Level |
InterruptMode |
Indicateurs & CM_RESOURCE_INTERRUPT_LATCHED |
Indicateurs & CM_RESOURCE_INTERRUPT_LATCHED |
ProcessorEnableMask |
u.Interrupt.Affinity |
u.MessageInterrupt.Translated.Affinity |
Un pilote reçoit uniquement CM_PARTIAL_RESOURCE_DESCRIPTOR structures pour les interruptions signalées par les messages sur Windows Vista et les versions ultérieures de Windows.
L’exemple de code suivant montre comment inscrire une routine InterruptService à l’aide de 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)) {
...
}