Compartir a través de


Uso de la versión CONNECT_FULLY_SPECIFIED de IoConnectInterruptEx

Un controlador puede usar la versión CONNECT_FULLY_SPECIFIED de IoConnectInterruptEx para registrar una rutina InterruptService para una interrupción específica. Un controlador puede usar la versión de CONNECT_FULLY_SPECIFIED a partir de Windows Vista. Al vincular a la biblioteca Iointex.lib, el controlador puede usar la versión de CONNECT_FULLY_SPECIFIED en Windows 2000, Windows XP y Windows Server 2003. Para obtener más información, consulte Uso de IoConnectInterruptEx antes de Windows Vista.

El controlador especifica un valor de CONNECT_FULLY_SPECIFIED para Parameters-Version> y usa los miembros de Parameters-FullySpecified> para especificar los demás parámetros de la operación:

  • Parameters-FullySpecified.PhysicalDeviceObject> especifica el PDO para el dispositivo que los servicios ISR.

  • Parameters-FullySpecified.ServiceRoutine> apunta a la rutina InterruptService, mientras que Parameters-FullySpecified.> ServiceContext especifica el valor que el sistema pasa como el parámetro ServiceContext a InterruptService. El controlador puede usarlo para pasar información de contexto. Para obtener más información sobre cómo pasar información de contexto, vea Proporcionar información de contexto de ISR.

  • El controlador proporciona un puntero a una variable PKINTERRUPT en Parameters-FullySpecified.InterruptObject>. La rutina IoConnectInterruptEx establece esta variable para que apunte al objeto de interrupción de la interrupción, que se puede usar al quitar el ISR.

  • Opcionalmente, los controladores pueden especificar un bloqueo de número en Parameters-FullySpecified.SpinLock> para que el sistema lo use al sincronizar con el ISR. La mayoría de los controladores simplemente pueden especificar NULL para permitir que el sistema asigne un bloqueo de número en nombre del controlador. Para obtener más información sobre la sincronización con un ISR, consulte Sincronizar el acceso a los datos del dispositivo.

El controlador debe especificar las propiedades clave de la interrupción en otros miembros de Parameters-FullySpecified>. El sistema proporciona la información necesaria en la matriz de estructuras de CM_PARTIAL_RESOURCE_DESCRIPTOR cuando envía el IRP IRP_MN_START_DEVICE al controlador.

El sistema proporciona para cada interrupción una estructura de CM_PARTIAL_RESOURCE_DESCRIPTOR con el miembro Type igual a CmResourceTypeInterrupt. Para una interrupción señalada por mensaje, se establece el bit de CM_RESOURCE_INTERRUPT_MESSAGE del miembro Flags ; de lo contrario, se borra.

El miembro u.Interrupt de CM_PARTIAL_RESOURCE_DESCRIPTOR contiene la descripción de una interrupción basada en línea, mientras que el miembro u.MessageInterrupt.Translated contiene la descripción de una interrupción señalada por mensaje. En la tabla siguiente se indica dónde, en la estructura CM_PARTIAL_RESOURCE_DESCRIPTOR, para buscar la información necesaria para establecer los miembros de Parameters-FullySpecified> para ambos tipos de interrupción. Para obtener más información, vea el ejemplo de código que sigue a la tabla.

Miembro Interrupción basada en línea Interrupción señalada por mensaje

ShareVector

ShareDisposition

ShareDisposition

Vector

u.Interrupt.Vector

u.MessageInterrupt.Translated.Vector

Irql

u.Interrupt.Level

u.MessageInterrupt.Translated.Level

InterruptMode

Marcas & CM_RESOURCE_INTERRUPT_LATCHED

Marcas & CM_RESOURCE_INTERRUPT_LATCHED

ProcessorEnableMask

u.Interrupt.Affinity

u.MessageInterrupt.Translated.Affinity

Un controlador solo recibirá estructuras CM_PARTIAL_RESOURCE_DESCRIPTOR para interrupciones señaladas por mensajes en Windows Vista y versiones posteriores de Windows.

En el ejemplo de código siguiente se muestra cómo registrar una rutina InterruptService mediante 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( &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)) {
    ...
}