Ekstensi Perangkat

Untuk sebagian besar driver tingkat menengah dan terendah, ekstensi perangkat adalah struktur data terpenting yang terkait dengan objek perangkat. Struktur internalnya ditentukan driver, dan biasanya digunakan untuk:

  • Pertahankan informasi status perangkat.

  • Menyediakan penyimpanan untuk objek yang ditentukan kernel atau sumber daya sistem lainnya, seperti kunci putar, yang digunakan oleh driver.

  • Pegang data apa pun yang harus dimiliki pengemudi dan di ruang sistem untuk melakukan operasi I/O-nya.

Karena sebagian besar driver bus, fungsi, dan filter (driver tingkat terendah dan menengah) dijalankan dalam konteks utas sewenang-wenang (bahwa dari utas apa pun yang terjadi saat ini), ekstensi perangkat adalah tempat utama setiap driver untuk mempertahankan status perangkat dan semua data khusus perangkat lainnya yang dibutuhkan driver. Misalnya, driver apa pun yang mengimplementasikan rutinitas CustomTimerDpc atau CustomDpc biasanya menyediakan penyimpanan untuk timer yang ditentukan kernel dan/atau objek DPC yang diperlukan dalam ekstensi perangkat.

Setiap driver yang memiliki ISR harus menyediakan penyimpanan untuk pointer ke sekumpulan objek interupsi yang ditentukan kernel, dan sebagian besar driver perangkat menyimpan pointer ini dalam ekstensi perangkat. Setiap driver menentukan ukuran ekstensi perangkat saat membuat objek perangkat, dan setiap driver menentukan konten dan struktur ekstensi perangkatnya sendiri.

Rutinitas IoCreateDevice dan IoCreateDeviceSecure manajer I/O mengalokasikan memori untuk objek perangkat dan ekstensi dari kumpulan memori yang tidak disebarkan.

Setiap rutinitas driver standar yang menerima IRP juga menerima pointer ke objek perangkat yang mewakili perangkat target untuk operasi I/O yang diminta. Rutinitas driver ini dapat mengakses ekstensi perangkat yang sesuai melalui pointer ini. Biasanya, penunjuk DeviceObject juga merupakan parameter input ke ISR driver tingkat terendah.

Gambar berikut menunjukkan sekumpulan data yang ditentukan driver yang representatif untuk ekstensi perangkat objek perangkat driver tingkat terendah. Driver tingkat yang lebih tinggi tidak akan menyediakan penyimpanan untuk pointer objek interupsi yang dikembalikan oleh IoConnectInterrupt dan diteruskan ke KeSynchronizeExecution dan IoDisconnectInterrupt. Namun, driver tingkat yang lebih tinggi akan menyediakan penyimpanan untuk timer dan objek DPC yang ditunjukkan pada gambar berikut jika driver memiliki rutinitas CustomTimerDpc . Driver tingkat yang lebih tinggi juga dapat menyediakan penyimpanan untuk kunci putaran eksekutif dan antrean kerja yang saling terkunci.

diagram yang mengilustrasikan contoh ekstensi perangkat untuk driver tingkat terendah.

Selain menyediakan penyimpanan untuk pointer objek interupsi, driver perangkat tingkat terendah harus menyediakan penyimpanan untuk kunci spin yang mengganggu jika ISR-nya menangani gangguan untuk dua perangkat atau lebih pada vektor yang berbeda atau jika memiliki lebih dari satu ISR. Untuk informasi selengkapnya tentang mendaftarkan ISR, lihat Mendaftarkan ISR.

Biasanya, driver menyimpan pointer ke objek perangkat mereka di ekstensi perangkat mereka, seperti yang ditunjukkan pada gambar. Driver mungkin juga menyimpan salinan daftar sumber daya untuk perangkat di ekstensi.

Driver tingkat yang lebih tinggi biasanya menyimpan pointer ke objek perangkat driver berikutnya yang lebih rendah dalam ekstensi perangkatnya. Driver tingkat yang lebih tinggi harus meneruskan penunjuk ke objek perangkat driver yang lebih rendah berikutnya ke IoCallDriver, setelah menyiapkan lokasi tumpukan I/O driver yang lebih rendah berikutnya di IRP, seperti yang dijelaskan dalam Menangani RUNPS.

Perhatikan juga bahwa setiap driver tingkat lebih tinggi yang mengalokasikan IRP untuk driver tingkat bawah harus menentukan berapa banyak lokasi tumpukan yang harus dimiliki IRP baru. Secara khusus, jika driver tingkat yang lebih tinggi memanggil IoMakeAssociatedIrp, IoAllocateIrp, atau IoInitializeIrp, driver harus mengakses objek perangkat target dari driver tingkat bawah berikutnya untuk membaca nilai StackSize-nya , untuk menyediakan StackSize yang benar sebagai argumen untuk rutinitas dukungan ini.

Meskipun driver tingkat yang lebih tinggi dapat membaca data dari objek perangkat driver tingkat bawah berikutnya melalui pointer yang dikembalikan oleh IoAttachDeviceToDeviceStack, driver tersebut harus mengikuti panduan implementasi ini:

  • Jangan pernah mencoba menulis data ke objek perangkat driver yang lebih rendah.

    Satu-satunya pengecualian untuk pedoman ini adalah sistem file, yang mengatur dan menghapus DO_VERIFY_VOLUME di Bendera objek perangkat driver media yang dapat dilepas tingkat bawah.

  • Jangan pernah mencoba mengakses ekstensi perangkat driver yang lebih rendah karena alasan berikut:

    • Tidak ada cara yang aman untuk menyinkronkan akses ke satu ekstensi perangkat antara dua driver.

    • Sepasang driver yang mengimplementasikan skema komunikasi backdoor tersebut tidak dapat ditingkatkan satu per satu, tidak dapat memasukkan driver perantara di antara mereka tanpa mengubah sumber driver yang ada, dan tidak dapat dikomputasi ulang dan dipindahkan dengan mudah dari satu platform Windows ke platform Windows berikutnya.

Untuk mempertahankan interoperabilitas mereka dengan driver tingkat bawah dari satu platform atau versi Windows ke driver tingkat yang lebih tinggi berikutnya harus menggunakan kembali IRP yang diberikan kepada mereka atau harus membuat RUN baru, dan mereka harus menggunakan IoCallDriver untuk mengomunikasikan permintaan ke driver tingkat bawah.