Bagikan melalui


Menulis Rutinitas Panggilan Balik Pra-operasi

Driver minifilter menggunakan satu atau beberapa rutinitas panggilan balik pra-operasi untuk memfilter operasi I/O. Rutinitas panggilan balik pra-operasi mirip dengan rutinitas pengiriman yang digunakan dalam model filter warisan.

Minifilter mendaftarkan rutinitas panggilan balik pra-operasi untuk jenis operasi I/O tertentu dengan menyimpan titik masuk rutinitas panggilan balik dalam anggota OperationRegistration dari struktur FLT_REGISTRATION . Minifilter meneruskan anggota ini ke FltMgr sebagai parameter ke FltRegisterFilter dalam rutinitas DriverEntry-nya .

Minifilter hanya menerima jenis operasi I/O yang telah mereka daftarkan rutinitas panggilan balik pra-operasi atau pasca-operasi. Minifilter dapat mendaftarkan rutinitas panggilan balik pra-operasi untuk jenis operasi I/O tertentu tanpa mendaftarkan rutinitas panggilan balik pasca-operasi, dan sebaliknya.

Setiap rutinitas panggilan balik pra-operasi didefinisikan sebagai berikut:

typedef FLT_PREOP_CALLBACK_STATUS 
(*PFLT_PRE_OPERATION_CALLBACK) ( 
    IN OUT PFLT_CALLBACK_DATA Data, 
    IN PCFLT_RELATED_OBJECTS FltObjects, 
    OUT PVOID *CompletionContext 
    ); 

Ketika FltMgr memanggil rutinitas panggilan balik pra-operasi minifilter untuk operasi I/O tertentu, minifilter untuk sementara mengontrol operasi I/O. Minifilter mempertahankan kontrol ini sampai:

  • Mengembalikan nilai status selain FLT_PREOP_PENDING dari rutinitas panggilan balik pra-operasinya.

  • Memanggil FltCompletePendedPreOperation dari rutinitas kerja yang telah memproses operasi yang sebelumnya tertunda dalam rutinitas panggilan balik pra-operasinya.

Tabel berikut mencantumkan beberapa skenario penggunaan yang mungkin dari rutinitas panggilan balik pra-operasi minifilter dan menyediakan detail implementasi dan nilai pengembalian untuk setiap skenario.

Skenario Penggunaan Implementasi Nilai yang Dikembalikan
Rutinitas tidak relevan untuk operasi dan tidak memerlukan status akhir operasi atau tidak memiliki panggilan balik pasca-operasi. Lewati operasi I/O dan beri tahu FltMgr untuk tidak memanggil panggilan balik pasca-operasi minifilter setelah selesai. FLT_PREOP_SUCCESS_NO_CALLBACK
Rutinitas memerlukan status akhir operasi. Lewati operasi dan beri tahu FltMgr untuk memanggil rutinitas panggilan balik pasca-operasi minifilter. FLT_PREOP_SUCCESS_WITH_CALLBACK
Minifilter harus menyelesaikan atau melanjutkan pemrosesan operasi ini di masa mendatang. Masukkan operasi ke dalam status tertunda. Gunakan FltCompletePendedPreOperation untuk menyelesaikan operasi nanti. Mungkin ada perlombaan yang dapat diterima antara rutinitas pra-operasi yang kembali FLT_PREOP_PENDING, dan FltCompletePendingOperation dipanggil. FltMgr menangani skenario ini tanpa input dari driver. FLT_PREOP_PENDING
Pemrosesan pasca-operasi harus terjadi dalam konteks utas yang sama dengan rutinitas pengiriman dipanggil. Kondisi ini memastikan IRQL yang konsisten dan mempertahankan status variabel lokal Anda. Sinkronkan operasi dengan pasca-operasi. FLT_PREOP_SYNCHRONIZE
Rutinitas panggilan balik pra-operasi perlu menyelesaikan operasi. Hentikan pemrosesan untuk operasi dan tetapkan nilai NTSTATUS akhir. FLT_PREOP_COMPLETE

Rutinitas panggilan balik IRQL dan pra-operasi

FltMgr tidak memiliki cara untuk mengetahui apa yang mungkin dilakukan minifilter dalam panggilan balik pra-operasinya (atau panggilan balik apa pun). Jadi FltMgr tidak memiliki cara untuk mengetahui apakah panggilan ke panggilan balik pra-operasi miniport dapat menyebabkan masalah. (Ada hal-hal yang dapat Anda lakukan dengan aman di IRQL yang ditingkatkan dan hal-hal yang tidak dapat Anda lakukan). Oleh karena itu, terserah minifilter untuk mewaspadai IRQL dan menanganinya dengan tepat. Minifilter dapat dengan aman dan murah memanggil KeGetCurrentIRQL untuk situasi di mana ia perlu mengetahui IRQL tempat itu dipanggil.

Informasi berikut tentang IRQL rutin panggilan balik pra-operasi minifilter berguna untuk diketahui:

  • Panggilan balik pra-operasi dapat dipanggil di IRQL = PASSIVE_LEVEL atau IRQL = APC_LEVEL. Sebagian besar panggilan balik pra-operasi dipanggil di IRQL = PASSIVE_LEVEL, dalam konteks utas yang berasal dari permintaan I/O. Hanya beberapa panggilan balik pra-operasi yang mungkin dipanggil di IRQL = APC_LEVEL.

  • Untuk operasi berbasis IRP, panggilan balik pra-operasi minifilter dapat dipanggil dalam konteks utas pekerja sistem jika filter atau driver minifilter yang lebih tinggi menunggu operasi untuk diproses oleh utas pekerja. Panggilan balik pra-operasi setara dengan rutinitas pengiriman filter warisan, jadi mengetahui IRQL dan konteks utas dari rutinitas pengiriman filter warisan mungkin berguna.

  • Objek konteks tidak dapat diambil dalam rutinitas pasca-operasi di APC_LEVEL IRQL > . Sebagai gantinya, dapatkan objek konteks selama rutinitas pra-operasi dan teruskan ke rutinitas pasca-operasi atau lakukan pemrosesan pasca-operasi di IRQL <= APC_LEVEL. Untuk informasi selengkapnya tentang konteks, lihat Mengelola Konteks.

Meneruskan Operasi I/O Ke Bawah Tumpukan Instans Minifilter

Menyelesaikan Operasi I/O dalam Rutinitas Panggilan Balik Praoperasi

Melarang Operasi I/O Cepat dalam Rutinitas Panggilan Balik Praoperasi

Menunggu Operasi I/O dalam Rutinitas Panggilan Balik Praoperasi