IRP Praproses dan Pascaproses

[Hanya berlaku untuk KMDF]

Jika driver Anda harus mencegat paket permintaan I/O (IRP) sebelum atau setelah kerangka kerja menangani IRP, driver dapat memanggil fungsi panggilan balik peristiwa WdfDeviceInitAssignWdmIrpPreprocessCallback untuk mendaftarkan fungsi panggilan balik peristiwa EvtDeviceWdmIrpPreprocess untuk kode fungsi I/O utama dan, opsional, untuk kode fungsi I/O kecil tertentu yang terkait dengan kode utama. Selanjutnya, kerangka kerja memanggil fungsi panggilan balik EvtDeviceWdmIrpPreprocess driver setiap kali driver menerima IRP yang berisi kode fungsi utama dan minor tertentu.

Fungsi panggilan balik EvtDeviceWdmIrpPreprocess dapat melakukan apa pun yang diperlukan untuk melakukan pra-proses IRP, dan kemudian harus memanggil WdfDeviceWdmDispatchPreprocessedIrp untuk mengembalikan IRP ke kerangka kerja kecuali driver menangani IRP yang tidak didukung kerangka kerja.

Setelah driver memanggil WdfDeviceWdmDispatchPreprocessedIrp, kerangka kerja memproses IRP dengan cara yang sama seperti jika driver tidak menyediakan fungsi panggilan balik EvtDeviceWdmIrpPreprocess . Jika kode fungsi I/O IRP adalah kode yang diteruskan kerangka kerja ke driver, driver akan menerima IRP lagi sebagai objek permintaan.

Jika driver perlu memposting IRP setelah driver tingkat bawah menyelesaikan IRP, fungsi panggilan balik EvtDeviceWdmIrpPreprocess driver dapat memanggil IoSetCompletionRoutine untuk mengatur rutinitas IoCompletion sebelum memanggil WdfDeviceWdmDispatchPreprocessedIrp.

Setelah driver Anda memanggil WdfDeviceInitAssignWdmIrpPreprocessCallback, kerangka kerja menyebabkan manajer I/O menambahkan lokasi tumpukan I/O tambahan ke semua RUN SEHINGGA fungsi panggilan balik EvtDeviceWdmIrpPreprocess dapat mengatur rutinitas IoCompletion . Fungsi panggilan balik harus memperbarui penunjuk lokasi tumpukan I/O IRP sebelum memanggil WdfDeviceWdmDispatchPreprocessedIrp.

Memanggil WdfDeviceWdmDispatchPreprocessedIrp

Karena manajer I/O menambahkan lokasi tumpukan I/O tambahan ke IRP, fungsi panggilan balik EvtDeviceWdmIrpPreprocess harus memanggil IoSkipCurrentIrpStackLocation atau IoCopyCurrentIrpStackLocationToNext (untuk menyiapkan lokasi tumpukan I/O berikutnya di IRP) sebelum memanggil WdfDeviceWdmDispatchPreprocessedIrp.

Jika driver Anda melakukan praproses IRP, tetapi tidak pascaproses IRP, driver tidak perlu mengatur rutinitas IoCompletion untuk IRP dan dapat memanggil IoSkipCurrentIrpStackLocation, seperti yang ditunjukkan contoh kode berikut.

NTSTATUS
  EvtDeviceMyIrpPreprocess(
    IN WDFDEVICE Device,
    IN OUT PIRP Irp
    )
{
//
// Perform IRP preprocessing operations here.
//
...
//
// Deliver the IRP back to the framework. 
//
IoSkipCurrentIrpStackLocation(Irp);
return WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
}

Jika driver Anda pascaproses IRP, driver harus memanggil IoCopyCurrentIrpStackLocationToNext, lalu harus memanggil IoSetCompletionRoutine untuk mengatur rutinitas IoCompletion untuk IRP, seperti yang ditunjukkan contoh kode berikut.

NTSTATUS
  EvtDeviceMyIrpPreprocess(
    IN WDFDEVICE Device,
    IN OUT PIRP Irp
    )
{
//
// Perform IRP preprocessing operations here, if needed.
//
...
//
// Set a completion routine and deliver the IRP back to
// the framework. 
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(
                       Irp,
                       MyIrpCompletionRoutine,
                       NULL,
                       TRUE,
                       TRUE,
                       TRUE
                      );
return WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
}

Driver Anda tidak boleh memanggil IoCopyCurrentIrpStackLocationToNext (dan karena itu tidak boleh mengatur rutinitas IoCompletion ) jika objek perangkat menangani fungsi panggilan balik EvtDeviceWdmIrpPreprocess driver mewakili objek perangkat fisik (PDO), dan jika kode fungsi utama IRP IRP_MJ_PNP atau IRP_MJ_POWER. Jika tidak, Pemverifikasi Driver akan melaporkan kesalahan.

Untuk informasi selengkapnya tentang kapan harus memanggil IoCopyCurrentIrpStackLocationToNext, IoSkipCurrentIrpStackLocation, dan IoSetCompletionRoutine, lihat Meneruskan RUNPS ke bawah Tumpukan Driver.