Menggunakan Versi Lengkap Spesifikasi dari IoConnectInterruptEx

Seorang pengendali dapat menggunakan versi CONNECT_FULLY_SPECIFIED dari IoConnectInterruptEx untuk mendaftarkan rutinitas InterruptService untuk gangguan tertentu. Pengemudi dapat menggunakan versi CONNECT_FULLY_SPECIFIED mulai dari Windows Vista. Dengan menautkan ke pustaka Iointex.lib, driver dapat menggunakan versi CONNECT_FULLY_SPECIFIED di Windows 2000, Windows XP, dan Windows Server 2003. Untuk informasi selengkapnya, lihat Menggunakan IoConnectInterruptEx Sebelum Windows Vista.

Driver menentukan nilai CONNECT_FULLY_SPECIFIED untuk Parameter-Version> dan menggunakan anggota Parameters-FullySpecified> untuk menentukan parameter lain dari operasi:

  • Parameters-FullySpecified.PhysicalDeviceObject> menentukan PDO untuk perangkat tempat layanan ISR.

  • Parameters-FullySpecified.ServiceRoutine> menunjuk ke rutinitas InterruptService, sementara Parameters-FullySpecified>.ServiceContext menentukan nilai yang diteruskan sistem sebagai parameter ServiceContext ke InterruptService. Driver dapat menggunakan ini untuk meneruskan informasi konteks. Untuk informasi selengkapnya tentang meneruskan informasi konteks, lihat Menyediakan Informasi Konteks ISR.

  • Driver menyediakan pointer ke variabel PKINTERRUPT dalam Parameters-FullySpecified.InterruptObject>. Rutinitas IoConnectInterruptEx mengatur variabel ini untuk menunjuk ke objek interupsi untuk interupsi, yang dapat digunakan saat menghapus ISR.

  • Driver dapat secara opsional menentukan kunci putar di Parameters-FullySpecified.SpinLock> untuk digunakan sistem saat menyinkronkan dengan ISR. Sebagian besar driver hanya dapat menentukan NULL untuk memungkinkan sistem mengalokasikan kunci putar atas nama driver. Untuk informasi selengkapnya tentang menyinkronkan dengan ISR, lihat Menyinkronkan Akses ke Data Perangkat.

Driver harus menentukan properti kunci dari interupsi pada anggota lainnya dari Parameters->FullySpecified. Sistem menyediakan informasi yang diperlukan dalam array struktur CM_PARTIAL_RESOURCE_DESCRIPTOR ketika mengirim IRP IRP_MN_START_DEVICE ke driver.

Sistem menyediakan untuk setiap interupsi struktur CM_PARTIAL_RESOURCE_DESCRIPTOR dengan anggota Type yang bernilai CmResourceTypeInterrupt. Untuk interupsi yang disinyalir pesan, bit CM_RESOURCE_INTERRUPT_MESSAGE anggota Bendera diatur; jika tidak, itu dibersihkan.

Anggota u.InterruptCM_PARTIAL_RESOURCE_DESCRIPTOR berisi deskripsi interupsi berbasis baris, sementara anggota u.MessageInterrupt.Translated berisi deskripsi interupsi terkendali pesan. Tabel berikut menunjukkan lokasi dalam struktur CM_PARTIAL_RESOURCE_DESCRIPTOR untuk menemukan informasi yang diperlukan guna mengatur anggota dari Parameters->FullySpecified untuk kedua tipe interrupt. Untuk informasi selengkapnya, lihat contoh kode yang mengikuti tabel.

Anggota Interupsi berbasis garis Interupsi yang dipicu oleh pesan

ShareVector

ShareDisposition

ShareDisposition

Vektor

u.Interrupt.Vector

u.MessageInterrupt.Translated.Vector

Irql

u.Interrupt.Level

u.MessageInterrupt.Translated.Level

InterruptMode

Bendera &CM_RESOURCE_INTERRUPT_LATCHED

Bendera &CM_RESOURCE_INTERRUPT_LATCHED

ProcessorEnableMask

u.Interrupt.Affinity

u.MessageInterrupt.Translated.Affinity

Driver hanya akan menerima CM_PARTIAL_RESOURCE_DESCRIPTOR struktur untuk interrupt yang dipicu pesan pada Windows Vista dan versi Windows yang lebih baru.

Contoh kode berikut menunjukkan cara mendaftarkan rutinitas InterruptService menggunakan 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)) {
    ...
}