Bagikan melalui


Menangani Permintaan IRP_MN_QUERY_REMOVE_DEVICE

Manajer PnP mengirim IRP ini untuk memberi tahu driver bahwa perangkat akan dihapus dari mesin dan menanyakan apakah perangkat dapat dihapus tanpa mengganggu mesin. Ini juga mengirimkan IRP ini ketika pengguna meminta untuk memperbarui driver untuk perangkat.

Manajer PnP mengirimkan IRP ini di IRQL PASSIVE_LEVEL dalam konteks utas sistem.

Ini melakukan hal berikut sebelum mengirim IRP ini ke driver untuk perangkat:

  • Memberi tahu semua aplikasi mode pengguna yang terdaftar untuk pemberitahuan di perangkat (atau perangkat terkait).

    Ini termasuk aplikasi yang terdaftar untuk pemberitahuan pada perangkat, pada salah satu turunan perangkat (perangkat anak, turunan dari anak, dan sebagainya), atau pada salah satu hubungan penghapusan perangkat. Aplikasi mendaftar untuk pemberitahuan tersebut dengan memanggil RegisterDeviceNotification.

    Menanggapi pemberitahuan ini, aplikasi bersiap untuk penghapusan perangkat (menutup handel ke perangkat) atau gagal kueri.

  • Memberi tahu semua driver mode kernel yang terdaftar untuk pemberitahuan pada perangkat (atau perangkat terkait).

    Ini termasuk driver yang terdaftar untuk pemberitahuan pada perangkat, pada salah satu turunan perangkat, atau pada salah satu hubungan penghapusan perangkat. Driver mendaftar untuk pemberitahuan ini dengan memanggil IoRegisterPlugPlayNotification dengan kategori peristiwa EventCategoryTargetDeviceChange.

    Menanggapi pemberitahuan ini, driver bersiap untuk penghapusan perangkat (menutup handel ke perangkat) atau gagal kueri.

  • Mengirim IRP_MN_QUERY_REMOVE_DEVICE IRP ke driver untuk turunan perangkat.

  • (Sistem Windows 2000 dan yang lebih baru) Jika sistem file dipasang pada perangkat, manajer PnP mengirimkan permintaan penghapusan kueri ke sistem file dan filter sistem file apa pun. Jika ada handel terbuka ke perangkat, sistem file biasanya gagal dalam permintaan penghapusan kueri. Jika tidak, sistem file biasanya mengunci volume untuk mencegah pembuatan di masa mendatang berhasil. Jika sistem file yang dipasang tidak mendukung permintaan penghapusan kueri, manajer PnP gagal dalam permintaan penghapusan kueri untuk perangkat.

Jika semua langkah di atas berhasil, manajer PnP mengirimkan IRP_MN_QUERY_REMOVE_DEVICE ke driver untuk perangkat.

Permintaan IRP_MN_QUERY_REMOVE_DEVICE ditangani terlebih dahulu oleh driver atas di tumpukan perangkat dan kemudian oleh setiap driver yang lebih rendah berikutnya. Driver menangani penghapusan RUNPS dalam rutinitas DispatchPnP-nya .

Menanggapi IRP_MN_QUERY_REMOVE_DEVICE, driver harus melakukan hal berikut:

  1. Tentukan apakah perangkat dapat dihapus dari komputer tanpa mengganggu operasi.

    Driver harus gagal menghapus IRP kueri jika salah satu hal berikut ini benar:

    • Jika menghapus perangkat dapat mengakibatkan kehilangan data.

    • Jika komponen memiliki handel terbuka ke perangkat. (Ini adalah masalah pada Windows 98/Me saja. Windows 2000 dan versi yang lebih baru dari Windows melacak handel terbuka dan gagal kueri jika ada handel terbuka setelah IRP_MN_QUERY_REMOVE_DEVICE selesai.)

    • Jika driver telah diberi tahu (melalui IRP_MN_DEVICE_USAGE_NOTIFICATION IRP) bahwa perangkat berada di jalur untuk file paging, crash dump, atau hibernation.

    • Jika driver memiliki referensi antarmuka yang luar biasa terhadap perangkat. Artinya, driver menyediakan antarmuka sebagai respons terhadap permintaan IRP_MN_QUERY_INTERFACE dan antarmuka belum didereferensikan.

  2. Jika perangkat tidak dapat dihapus, gagalkan IRP penghapusan kueri.

    Atur Irp-IoStatus.Status> ke status kesalahan yang sesuai (biasanya STATUS_UNSUCCESSFUL), panggil IoCompleteRequest dengan IO_NO_INCREMENT, dan kembali dari rutinitas DispatchPnP driver. Jangan teruskan IRP ke driver bawah berikutnya.

  3. Jika driver sebelumnya mengirim permintaan IRP_MN_WAIT_WAKE untuk mengaktifkan perangkat untuk bangun, batalkan IRP wait-wake.

  4. Rekam status PnP perangkat sebelumnya.

    Driver harus merekam status PnP tempat perangkat berada saat driver menerima permintaan IRP_MN_QUERY_REMOVE_DEVICE karena driver harus mengembalikan perangkat ke status tersebut jika kueri dibatalkan (IRP_MN_CANCEL_REMOVE_DEVICE). Status sebelumnya biasanya "dimulai", yang merupakan status yang dimasukkan perangkat ketika driver berhasil menyelesaikan permintaan IRP_MN_START_DEVICE .

    Namun, status sebelumnya lainnya dimungkinkan. Misalnya, pengguna mungkin telah menonaktifkan perangkat melalui Manajer Perangkat. Atau, sebagai tanggapan atas permintaan IRP_MN_QUERY_CAPABILITIES , driver bus induk (atau driver filter pada driver bus) mungkin telah melaporkan bahwa perangkat keras perangkat dinonaktifkan. Dalam kedua kasus, driver untuk perangkat yang dinonaktifkan dapat menerima permintaan IRP_MN_QUERY_REMOVE_DEVICE sebelum menerima permintaan IRP_MN_START_DEVICE .

  5. Selesaikan IRP:

    Dalam fungsi atau driver filter:

    • Atur Irp-IoStatus.Status> ke STATUS_SUCCESS.

    • Siapkan lokasi tumpukan berikutnya dengan IoSkipCurrentIrpStackLocation dan teruskan IRP ke driver yang lebih rendah berikutnya dengan IoCallDriver.

    • Sebarkan status dari IoCallDriver sebagai status pengembalian dari rutinitas DispatchPnP .

    • Jangan selesaikan IRP.

    Dalam sopir bus:

    • Atur Irp-IoStatus.Status> ke STATUS_SUCCESS.

    • Selesaikan IRP (IoCompleteRequest) dengan IO_NO_INCREMENT.

    • Kembali dari rutinitas DispatchPnP .

Jika ada driver di tumpukan perangkat yang gagal IRP_MN_QUERY_REMOVE_DEVICE, manajer PnP mengirimkan IRP_MN_CANCEL_REMOVE_DEVICE ke tumpukan perangkat. Ini mencegah driver memerlukan rutinitas IoCompletion untuk IRP penghapusan kueri untuk mendeteksi apakah driver yang lebih rendah gagal IRP.

Setelah driver berhasil IRP_MN_QUERY_REMOVE_DEVICE dan menganggap perangkat berada dalam status hapus-tertunda, driver harus gagal setiap permintaan pembuatan berikutnya untuk perangkat. Driver memproses semua IRP lainnya seperti biasa, sampai driver menerima IRP_MN_CANCEL_REMOVE_DEVICE atau IRP_MN_REMOVE_DEVICE.