Menggunakan I/O Buffered maupun Direct
Jika driver tidak menggunakan I/O buffer atau langsung, maka manajer I/O meneruskan alamat virtual ruang pengguna asli dalam RUN yang dikirimnya ke driver. Untuk mengakses buffer ini dengan aman, driver harus dijalankan dalam konteks utas panggilan. Oleh karena itu, biasanya, hanya driver tingkat tertinggi, seperti FSD, yang dapat menggunakan metode ini untuk mengakses buffer.
Driver tingkat menengah atau terendah tidak selalu dapat memenuhi kondisi ini. Misalnya, jika utas yang meminta menunggu penyelesaian permintaan I/O atau jika driver tingkat yang lebih tinggi berlapis di atas driver tingkat menengah atau terendah, maka rutinitas driver tingkat bawah tidak mungkin dipanggil dalam konteks utas yang meminta.
Manajer I/O menentukan bahwa operasi I/O tidak menggunakan I/O buffer atau langsung sebagai berikut:
Untuk permintaan IRP_MJ_READ dan IRP_MJ_WRITE , baik DO_BUFFERED_IO maupun DO_DIRECT_IO tidak diatur dalam anggota Bendera struktur DEVICE_OBJECT . Untuk informasi selengkapnya, lihat Menginisialisasi Objek Perangkat.
Untuk permintaan IRP_MJ_DEVICE_CONTROL dan IRP_MJ_INTERNAL_DEVICE_CONTROL , nilai kode IOCTL berisi METHOD_NEITHER sebagai nilai TransferType dalam nilai IOCTL. Untuk informasi selengkapnya, lihat Menentukan Kode Kontrol I/O.
Ketika driver menerima IRP yang menentukan operasi I/O menggunakan I/O buffer atau langsung, ia harus melakukan hal berikut:
Periksa validitas rentang alamat buffer pengguna dan periksa apakah akses baca atau tulis yang sesuai diizinkan, menggunakan rutinitas dukungan ProbeForRead dan ProbeForWrite . Driver harus menyertakan aksesnya ke rentang alamat buffer dalam handler pengecualian yang disediakan driver, sehingga utas pengguna tidak dapat mengubah hak akses untuk buffer saat driver mengakses memori. Jika pemeriksaan memunculkan pengecualian, driver harus mengembalikan kesalahan. Driver harus memanggil rutinitas ini dalam konteks utas yang membuat permintaan I/O; oleh karena itu, hanya driver tingkat yang lebih tinggi yang dapat melakukan tugas ini.
Kelola buffer dan operasi memori dengan salah satu cara berikut:
- Lakukan operasi buffering ganda sendiri, seperti yang dilakukan manajer I/O untuk driver yang menggunakan I/O buffer. Untuk informasi selengkapnya, lihat Menggunakan I/O Buffered.
- Buat MDL sendiri dan kunci buffer dengan memanggil rutinitas dukungan manajer memori, seperti yang dilakukan manajer I/O untuk driver yang menggunakan I/O langsung. Untuk informasi selengkapnya, lihat Menggunakan I/O Langsung.
- Lakukan semua operasi yang diperlukan pada buffer pengguna secara langsung dalam konteks utas panggilan. Driver harus membungkus aksesnya ke buffer dalam handler pengecualian yang disediakan driver, jika utas pengguna mengubah hak akses untuk buffer atau data dalam buffer saat driver mengakses memori. Untuk informasi selengkapnya, lihat Menangani Pengecualian.
Akibatnya, driver harus memilih berdasarkan per-IRP apakah akan melakukan I/O buffer, I/O langsung, atau I/O dalam konteks utas panggilan, dan harus menangani pengecualian apa pun yang mungkin terjadi dalam konteks utas mode pengguna. Driver harus mengelola akses buffer penggunanya sendiri, operasi buffering ganda, dan pemetaan memori, seperlunya, alih-alih membiarkan manajer I/O menangani operasi ini untuk driver.