共用方式為


使用 CONNECT_MESSAGE_BASED 版本的 IoConnectInterruptEx

針對 Windows Vista 和之後的作業系統,驅動程式可以使用 CONNECT_MESSAGE_BASED 版的 IoConnectInterruptEx 來註冊與驅動程式訊息訊號中斷相對應的 ISR。 驅動程式將Parameters->Version 欄位指定為 CONNECT_MESSAGE_BASED 值,並使用 Parameters->MessageBased 的成員來指定作業的其他參數。

  • Parameters-MessageBased.PhysicalDeviceObject> 指定 ISR 所服務裝置的 PDO。 系統會使用裝置對象來自動識別裝置的訊息訊號中斷。

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

  • 驅動程式也可以在 Parameters->MessageBased.FallBackServiceRoutine 中指定後援 InterruptMessageService 例程。 如果裝置有以線路為基礎的中斷,但沒有訊息信號中斷,系統會改為註冊 InterruptMessageService 例程來服務以線路為基礎的中斷。 在此情況下,系統會將 Parameters-MessageBased.ServiceContext> 當做 ServiceContext 參數傳遞至 InterruptServiceIoConnectInterruptEx 會在註冊後援例程時,將Parameters->Version更新為CONNECT_LINE_BASED。

  • Parameters->MessageBased.ConnectionContext 指向一個變數,該變數將接收一個指向 IO_INTERRUPT_MESSAGE_INFO 結構(適用於 InterruptMessageService)或 KINTERRUPT 結構(適用於 InterruptService)的指標。 驅動程式可以使用收到的指標來移除ISR。 如需詳細資訊,請參閱 移除ISR

  • 驅動程式可以選擇性地在Parameters-MessageBased.SpinLock>中指定自旋鎖,讓系統在與ISR同步時使用。 大部分的驅動程式都可以指定 NULL,讓系統為驅動程式配置自旋鎖。 如需有關與 ISR 同步的詳細資訊,請參閱 同步處理裝置資料的存取

下列程式代碼範例示範如何使用 CONNECT_MESSAGE_BASED 註冊 InterruptMessageService 例程。

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