共用方式為


使用 CONNECT_FULLY_SPECIFIED 版 IoConnectInterruptEx

驅動程式可以使用 IoConnectInterruptEx 的 CONNECT_FULLY_SPECIFIED 版本來註冊特定中斷的 InterruptService 常式。 驅動程式可以使用從 Windows Vista 開始的CONNECT_FULLY_SPECIFIED版本。 藉由連結至 Iointex.lib 程式庫,驅動程式可以使用 Windows 2000、Windows XP 和 Windows Server 2003 中的CONNECT_FULLY_SPECIFIED版本。 如需詳細資訊,請參閱 在 Windows Vista 之前使用 IoConnectInterruptEx

驅動程式會指定Parameters-Version > CONNECT_FULLY_SPECIFIED 的值,並使用Parameters-FullySpecified >的成員來指定作業的其他參數:

  • Parameters-FullySpecified.PhysicalDeviceObject >會指定 ISR 服務裝置的 PDO。

  • Parameters-FullySpecified.ServiceRoutine> 會指向InterruptService常式,而Parameters-FullySpecified >ServiceCoNtext會指定系統傳遞為ServiceCoNtext參數給InterruptService的值。 驅動程式可以使用這個來傳遞內容資訊。 如需傳遞內容資訊的詳細資訊,請參閱 提供 ISR 內容資訊

  • 驅動程式會在Parameters-FullySpecified.InterruptObject >中提供 PKINTERRUPT 變數的指標。 IoConnectInterruptEx常式會將這個變數設定為指向中斷的中斷物件,這可在移除 ISR時使用。

  • 驅動程式可以選擇性地在Parameters-FullySpecified.SpinLock >中指定微調鎖定,讓系統在與 ISR 同步處理時使用。 大部分驅動程式只能指定 Null ,讓系統代表驅動程式配置微調鎖定。 如需與 ISR 同步處理的詳細資訊,請參閱 同步處理裝置資料的存取

驅動程式必須在Parameters-FullySpecified >的其他成員中指定中斷的索引鍵屬性。 當系統將IRP_MN_START_DEVICE IRP傳送至驅動程式時,系統會在CM_PARTIAL_RESOURCE_DESCRIPTOR結構的陣列中提供必要的資訊。

系統會為每個中斷一 個CM_PARTIAL_RESOURCE_DESCRIPTOR 結構,且 Type 成員等於 CmResourceTypeInterrupt。 針對訊息訊號中斷,會設定 Flags 成員CM_RESOURCE_INTERRUPT_MESSAGE位;否則會清除它。

CM_PARTIAL_RESOURCE_DESCRIPTORu.Interrupt成員包含行型中斷的描述,而u.MessageInterrupt.Translated成員則包含訊息訊號中斷的描述。 下表指出在CM_PARTIAL_RESOURCE_DESCRIPTOR結構中,尋找針對這兩種中斷類型設定Parameters-FullySpecified > 成員所需的資訊。 如需詳細資訊,請參閱資料表後面的程式碼範例。

成員 線條型中斷 訊息訊號中斷

ShareVector

ShareDisposition

ShareDisposition

向量

u.Interrupt.Vector

u.MessageInterrupt.Translated.Vector

Irql

u.Interrupt.Level

u.MessageInterrupt.Translated.Level

InterruptMode

旗標 & CM_RESOURCE_INTERRUPT_LATCHED

旗標 & CM_RESOURCE_INTERRUPT_LATCHED

ProcessorEnableMask

u.Interrupt.Affinity

u.MessageInterrupt.Translated.Affinity

驅動程式只會在 Windows Vista 和更新版本的 Windows 上接收訊息訊號中斷 的CM_PARTIAL_RESOURCE_DESCRIPTOR 結構。

下列程式碼範例示範如何使用 CONNECT_FULLY_SPECIFIED註冊 InterruptService 常式。

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)) {
    ...
}