Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Driver tingkat yang lebih tinggi memiliki serangkaian rutinitas standar yang berbeda dari driver perangkat tingkat terendah, dengan subset rutinitas standar yang tumpang tindih yang umum untuk kedua jenis driver.
Set rutinitas untuk driver tingkat menengah dan tertinggi juga bervariasi sesuai dengan kriteria berikut:
Sifat perangkat fisik yang mendasar
Apakah driver perangkat yang mendasar mengatur objek perangkat untuk I/O langsung atau buffer
Desain driver tingkat lebih tinggi individu
Gambar berikut menggambarkan jalur yang mungkin diambil IRP melalui rutinitas standar driver cermin perantara yang berlapis di suatu tempat di atas driver perangkat tingkat terendah yang dijelaskan di bagian sebelumnya.
Driver yang diperlihatkan dalam gambar berikut memiliki karakteristik berikut:
Driver dilapisi lebih dari satu perangkat fisik dan mungkin lebih dari satu driver perangkat.
Driver terkadang mengalokasikan IRP tambahan untuk driver tingkat bawah, tergantung pada operasi yang diminta dalam IRP input.
Driver memiliki setidaknya satu driver sistem file yang berlapis di atasnya, dan driver sistem file tersebut mungkin berlapis di atas driver perantara lainnya pada tingkat yang lebih tinggi dari yang satu ini.
Seperti yang ditunjukkan oleh gambar, manajer I/O membuat IRP dan mengirimkannya ke rutinitas pengiriman driver untuk kode fungsi utama yang diberikan. Dengan asumsi kode fungsi IRP_MJ_WRITE, rutinitas pengiriman adalah DDDispatchWrite. Lokasi tumpukan I/O driver perantara ditampilkan di tengah, dengan jumlah lokasi tumpukan I/O yang tidak terbatas untuk driver tingkat yang lebih tinggi dan lebih rendah ditampilkan berbayang.
Mengalokasikan RUNPS
Tujuan driver cermin adalah untuk mengirim permintaan tulis ke beberapa perangkat fisik, dan untuk mengirim permintaan baca secara bergantian ke driver perangkat ini. Untuk permintaan tulis, driver membuat runtime integrasi duplikat untuk setiap perangkat tempat data akan ditulis, dengan asumsi parameter dalam IRP input valid.
Gambar sebelumnya menunjukkan panggilan ke IoAllocateIrp tetapi driver tingkat yang lebih tinggi dapat memanggil rutinitas dukungan lain untuk mengalokasikan RUN untuk driver tingkat bawah. Lihat Membuat RUNPS untuk Driver Lower-Level.
Ketika rutinitas pengiriman memanggil IoAllocateIrp, ia menentukan jumlah lokasi tumpukan I/O yang diperlukan untuk IRP. Driver harus menentukan lokasi tumpukan untuk setiap driver yang lebih rendah dalam rantai, mendapatkan nilai yang sesuai dari objek perangkat setiap driver tepat di bawah driver cermin. Secara opsional, driver dapat menambahkan satu ke nilai ini ketika memanggil IoAllocateIrp untuk mendapatkan lokasi tumpukannya sendiri untuk setiap IRP yang dialokasikannya, seperti yang dilakukan driver pada gambar sebelumnya.
Pengiriman driver perantara ini rutin memanggil IoGetCurrentIrpStackLocation (tidak ditampilkan) dengan IRP asli, untuk memeriksa parameter.
Ini memanggil IoSetNextIrpStackLocation karena mengalokasikan lokasi tumpukannya sendiri di setiap IRP dan IoGetCurrentIrpStackLocation yang baru dibuat untuk membuat konteks untuk dirinya sendiri yang digunakannya nanti dalam rutinitas IoCompletion .
Selanjutnya, ini memanggil IoGetNextIrpStackLocation dengan setiap IRP yang baru dibuat sehingga dapat mengatur lokasi tumpukan I/O driver tingkat bawah berikutnya di IRP yang dialokasikannya. Pengiriman driver cermin secara rutin menyalin kode fungsi dan parameter IRP (penunjuk ke buffer transfer, panjang byte yang akan ditransfer untuk IRP_MJ_WRITE) ke lokasi tumpukan I/O untuk driver yang lebih rendah berikutnya. Driver ini, pada gilirannya, akan mengatur lokasi tumpukan I/O untuk driver tepat di bawahnya, jika ada.
Memanggil IoSetCompletionRoutine dan IoCallDriver
Rutinitas pengiriman pada gambar sebelumnya memanggil IoSetCompletionRoutine untuk setiap IRP yang dialokasikan. Karena driver pada angka sebelumnya harus membuang RUNPS yang dialokasikannya, driver ini mengatur rutinitas IoCompletion-nya untuk dipanggil ketika driver yang lebih rendah menyelesaikan runtime integrasinya, apakah operasi I/O berhasil diselesaikan, gagal, atau dibatalkan.
Karena driver pada gambar sebelumnya mencerminkan secara paralel, driver ini meneruskan kedua RUN yang dialokasikan ke driver tingkat bawah berikutnya dengan memanggil IoCallDriver dua kali, sekali untuk setiap objek perangkat target yang mewakili partisi cermin.
Memproses IRP dalam Rutinitas IoCompletion Driver
Ketika salah satu set driver tingkat bawah menyelesaikan operasi yang diminta, manajer I/O memanggil rutinitas IoCompletion driver cermin perantara. Driver cermin mempertahankan hitungan di lokasi tumpukan I/O sendiri untuk IRP asli, untuk melacak ketika driver yang lebih rendah telah menyelesaikan semua runtime integrasi duplikat.
Dengan asumsi bahwa blok status I/O menunjukkan bahwa satu set driver yang lebih rendah telah menyelesaikan IRP duplikat yang ditunjukkan pada gambar sebelumnya, rutinitas IoCompletion driver cermin mengurangi jumlahnya tetapi tidak dapat menyelesaikan IRP asli sampai mengurangi hitungan menjadi nol. Jika jumlah yang dikurangi belum nol, rutinitas IoCompletion memanggil IoFreeIrp dengan IRP yang dikembalikan pertama (DupIRP1 pada gambar sebelumnya) yang dialokasikan driver dan mengembalikan STATUS_MORE_PROCESSING_REQUIRED.
Ketika rutinitas IoCompletion driver cermin dipanggil lagi dengan DupIRP2 yang ditunjukkan pada gambar sebelumnya, IoCompletion rutin mengurangi hitungan dalam IRP asli dan menentukan bahwa kedua set driver tingkat bawah telah melakukan operasi yang diminta.
Dengan asumsi blok status I/O di DupIRP2 juga diatur dengan STATUS_SUCCESS, IoCompletion rutin menyalin blok status I/O dari DupIRP2 ke IRP asli dan membebaskan DupIRP2. Ini memanggil IoCompleteRequest dengan IRP asli dan mengembalikan STATUS_MORE_PROCESSING_REQUIRED. Mengembalikan status ini mencegah manajer I/O mencoba pemrosesan penyelesaian lebih lanjut pada DupIRP2; karena IRP tidak terkait dengan utas, pemrosesan penyelesaiannya harus berakhir dengan driver yang membuatnya.
Jika salah satu set driver tingkat bawah tidak berhasil menyelesaikan runtime integrasi driver cermin, rutinitas IoCompletion driver cermin harus mencatat kesalahan dan mencoba pemulihan data cermin yang sesuai. Untuk informasi selengkapnya, lihat Kesalahan Pengelogan.