Menangani Permintaan IRP_MN_SURPRISE_REMOVAL

Manajer PnP Windows 2000 dan yang lebih baru mengirimkan IRP ini untuk memberi tahu driver bahwa perangkat tidak lagi tersedia untuk operasi I/O dan mungkin telah dihapus secara tiba-tiba dari mesin ("penghapusan mendadak").

Manajer PnP mengirimkan permintaan IRP_MN_SURPRISE_REMOVAL karena alasan berikut:

  • Jika bus memiliki pemberitahuan hot-plug, bus akan memberi tahu driver bus induk perangkat bahwa perangkat telah menghilang. Pengemudi bus memanggil IoInvalidateDeviceRelations. Sebagai tanggapan, manajer PnP meminta pengemudi bus untuk anak-anaknya (IRP_MN_QUERY_DEVICE_RELATIONS untuk BusRelations). Manajer PnP menentukan bahwa perangkat tidak ada dalam daftar anak baru dan memulai operasi penghapusan kejutan untuk perangkat.

  • Bus dijumlahkan karena alasan lain dan perangkat yang dihapus kejutan tidak termasuk dalam daftar anak-anak. Manajer PnP memulai operasi penghapusan mendadak.

  • Driver fungsi untuk perangkat menentukan bahwa perangkat tidak lagi ada (karena, misalnya, permintaannya berulang kali kehabisan waktu). Bus mungkin dapat dijumlahkan tetapi tidak memiliki pemberitahuan hot-plug. Dalam hal ini, driver fungsi memanggil IoInvalidateDeviceState. Sebagai respons, manajer PnP mengirimkan permintaan IRP_MN_QUERY_PNP_DEVICE_STATE ke tumpukan perangkat. Driver fungsi mengatur bendera PNP_DEVICE_FAILED di bitmask PNP_DEVICE_STATE yang menunjukkan bahwa perangkat telah gagal.

  • Tumpukan driver berhasil menyelesaikan permintaan IRP_MN_STOP_DEVICE tetapi kemudian gagal permintaan IRP_MN_START_DEVICE berikutnya. Dalam kasus seperti itu, perangkat mungkin masih terhubung.

Semua driver PnP harus menangani IRP ini dan harus mengatur Irp-IoStatus.Status> ke STATUS_SUCCESS. Driver untuk perangkat PnP harus siap menangani IRP_MN_SURPRISE_REMOVAL kapan saja setelah rutinitas AddDevice driver dipanggil. Penanganan IRP yang tepat memungkinkan driver dan manajer PnP untuk:

  1. Nonaktifkan perangkat, jika masih tersambung.

    Jika tumpukan driver berhasil menyelesaikan permintaan IRP_MN_STOP_DEVICE tetapi karena alasan tertentu, gagal permintaan IRP_MN_START_DEVICE berikutnya, perangkat harus dinonaktifkan.

  2. Merilis sumber daya perangkat keras yang ditetapkan ke perangkat dan membuatnya tersedia untuk perangkat lain.

    Segera setelah perangkat tidak lagi tersedia, sumber daya perangkat kerasnya harus dikosongkan. Manajer PnP kemudian dapat menetapkan ulang sumber daya ke perangkat lain, termasuk perangkat yang sama, yang mungkin dicolokkan kembali oleh pengguna ke komputer.

  3. Meminimalkan risiko kehilangan data dan gangguan sistem.

    Perangkat yang mendukung hot-plugging dan drivernya harus dirancang untuk menangani penghapusan kejutan. Pengguna berharap dapat menghapus perangkat yang mendukung hot-plugging kapan saja.

Manajer PnP mengirimkan IRP_MN_SURPRISE_REMOVAL di IRQL = PASSIVE_LEVEL dalam konteks utas sistem.

Manajer PnP mengirimkan IRP ini ke driver sebelum memberi tahu aplikasi mode pengguna dan komponen mode kernel lainnya. Setelah IRP selesai, manajer PnP mengirimkan pemberitahuan EventCategoryTargetDeviceChange dengan GUID_TARGET_DEVICE_REMOVE_COMPLETE ke komponen mode kernel yang terdaftar untuk pemberitahuan tersebut pada perangkat.

IRP IRP_MN_SURPRISE_REMOVAL ditangani terlebih dahulu oleh driver teratas di tumpukan perangkat dan kemudian oleh setiap driver yang lebih rendah berikutnya.

Menanggapi IRP_MN_SURPRISE_REMOVAL, driver harus melakukan hal berikut, dalam urutan yang tercantum:

  1. Tentukan apakah perangkat telah dihapus.

    Pengandar harus selalu berusaha menentukan apakah perangkat masih tersambung. Jika ya, driver harus mencoba menghentikan perangkat dan menonaktifkannya.

  2. Rilis sumber daya perangkat keras perangkat (gangguan, port I/O, register memori, dan saluran DMA).

  3. Dalam sopir bus induk, matikan slot bus jika pengemudi mampu melakukannya. Hubungi PoSetPowerState untuk memberi tahu manajer daya. Untuk informasi tambahan, lihat Manajemen Daya.

  4. Mencegah operasi I/O baru pada perangkat.

    Driver harus memproses permintaan IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_POWER, dan IRP_MJ_PNP berikutnya, tetapi driver harus mencegah operasi I/O baru. Driver harus gagal pada IRP berikutnya yang akan ditangani driver jika perangkat ada, selain IRP tutup, bersihkan, dan PnP.

    Driver dapat mengatur sedikit di ekstensi perangkat untuk menunjukkan bahwa perangkat telah dihapus secara mendadak. Rutinitas pengiriman driver harus memeriksa bit ini.

  5. Gagalkan permintaan I/O yang terutang pada perangkat.

  6. Terus berikan IRP apa pun yang tidak ditangani driver untuk perangkat.

  7. Nonaktifkan antarmuka perangkat dengan IoSetDeviceInterfaceState.

  8. Bersihkan alokasi, memori, peristiwa, atau sumber daya sistem khusus perangkat apa pun.

    Driver dapat menunda pembersihan tersebut sampai menerima permintaan IRP_MN_REMOVE_DEVICE berikutnya, tetapi jika komponen warisan memiliki handel terbuka yang tidak dapat ditutup, penghapusan IRP tidak akan pernah dikirim.

  9. Biarkan objek perangkat terpasang ke tumpukan perangkat.

    Jangan lepaskan dan hapus objek perangkat hingga permintaan IRP_MN_REMOVE_DEVICE berikutnya.

  10. 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 bawah berikutnya dengan IoCallDriver.

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

    • Jangan selesaikan IRP.

    Dalam sopir bus (yang menangani IRP ini untuk PDO anak):

    • Atur Irp-IoStatus.Status> ke STATUS_SUCCESS.

    • Selesaikan IRP (IoCompleteRequest) dengan IO_NO_INCREMENT.

    • Kembali dari rutinitas DispatchPnP .

Setelah IRP ini berhasil dan semua handel terbuka ke perangkat ditutup, manajer PnP mengirimkan permintaan IRP_MN_REMOVE_DEVICE ke tumpukan perangkat. Sebagai respons terhadap hapus IRP, driver melepaskan objek perangkat mereka dari tumpukan dan menghapusnya. Jika komponen warisan memiliki handel yang terbuka untuk perangkat dan membiarkan handel terbuka meskipun terjadi kegagalan I/O, manajer PnP tidak pernah mengirim hapus IRP.

Semua driver harus menangani IRP ini dan harus dicatat bahwa perangkat telah dihapus secara fisik dari komputer. Namun, beberapa driver tidak akan menyebabkan hasil yang buruk jika mereka tidak menangani IRP. Misalnya, perangkat yang tidak menggunakan sumber daya perangkat keras sistem dan berada di bus berbasis protokol, seperti USB atau 1394, tidak dapat mengikat sumber daya perangkat keras karena tidak menggunakannya. Tidak ada risiko driver mencoba mengakses perangkat setelah dihapus karena fungsi dan driver filter mengakses perangkat hanya melalui driver bus induk. Karena bus mendukung pemberitahuan penghapusan, driver bus induk diberi tahu ketika perangkat menghilang dan driver bus gagal semua upaya berikutnya untuk mengakses perangkat.

Pada Windows 98/Me, manajer PnP tidak mengirim IRP ini. Jika pengguna menghapus perangkat tanpa terlebih dahulu menggunakan antarmuka pengguna yang sesuai, manajer PnP hanya mengirim permintaan IRP_MN_REMOVE_DEVICE ke driver untuk perangkat. Semua driver WDM harus menangani IRP_MN_SURPRISE_REMOVAL dan IRP_MN_REMOVE_DEVICE. Kode untuk IRP_MN_REMOVE_DEVICE harus memeriksa apakah driver menerima IRP penghapusan kejutan sebelumnya dan harus menangani kedua kasus.

Menggunakan GUID_REENUMERATE_SELF_INTERFACE_STANDARD

Antarmuka GUID_REENUMERATE_SELF_INTERFACE_STANDARD memungkinkan driver untuk meminta agar perangkatnya dihidung ulang.

Untuk menggunakan antarmuka ini, kirim IRP_MN_QUERY_INTERFACE IRP ke driver bus Anda dengan InterfaceType = GUID_REENUMERATE_SELF_INTERFACE_STANDARD. Sopir bus memasok pointer ke struktur REENUMERATE_SELF_INTERFACE_STANDARD yang berisi pointer ke rutinitas antarmuka individu. ReenumerateSelf rutin meminta agar pengemudi bus menghitung ulang perangkat anak.

Tentang PNP_DEVICE_STATE

Jenis PNP_DEVICE_STATE adalah bitmask yang menjelaskan status PnP perangkat. Driver mengembalikan nilai jenis ini sebagai respons terhadap permintaan IRP_MN_QUERY_PNP_DEVICE_STATE .

typedef ULONG PNP_DEVICE_STATE, *PPNP_DEVICE_STATE;

Bit bendera dalam nilai PNP_DEVICE_STATE didefinisikan sebagai berikut.

Bit bendera Deskripsi
PNP_DEVICE_DISABLED

Perangkat hadir secara fisik tetapi dinonaktifkan dalam perangkat keras.

PNP_DEVICE_DONT_DISPLAY_IN_UI

Jangan tampilkan perangkat di antarmuka pengguna. Atur untuk perangkat yang hadir secara fisik tetapi tidak dapat digunakan dalam konfigurasi saat ini, seperti port game pada laptop yang tidak dapat digunakan saat laptop dilepas. (Lihat juga bendera NoDisplayInUI di struktur DEVICE_CAPABILITIES .)

PNP_DEVICE_FAILED

Perangkat ada tetapi tidak berfungsi dengan baik.

Ketika bendera ini dan PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED diatur, perangkat harus dihentikan sebelum manajer PnP menetapkan sumber daya perangkat keras baru (penyeimbangan ulang nonstop tidak didukung untuk perangkat).

PNP_DEVICE_NOT_DISABLEABLE

Perangkat diperlukan ketika komputer dimulai. Perangkat seperti itu tidak boleh dinonaktifkan.

Driver mengatur bit ini untuk perangkat yang diperlukan untuk operasi sistem yang tepat. Misalnya, jika driver menerima pemberitahuan bahwa perangkat berada di jalur halaman (IRP_MN_DEVICE_USAGE_NOTIFICATION untuk DeviceUsageTypePaging), driver memanggil IoInvalidateDeviceState dan mengatur bendera ini dalam permintaan IRP_MN_QUERY_PNP_DEVICE_STATE yang dihasilkan.

Jika bit ini diatur untuk perangkat, manajer PnP menyebarluaskan pengaturan ini ke perangkat induk perangkat, perangkat induk induknya, dan sebagainya.

Jika bit ini diatur untuk perangkat yang dijumlahkan akar, perangkat tidak dapat dinonaktifkan atau dihapus instalannya.

PNP_DEVICE_REMOVED

Perangkat telah dihapus secara fisik.

PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED

Persyaratan sumber daya untuk perangkat telah berubah.

Biasanya, driver bus menetapkan bendera ini ketika telah menentukan bahwa ia harus memperluas persyaratan sumber dayanya untuk menghitung perangkat anak baru.

PNP_DEVICE_DISCONNECTED

Pengandar perangkat dimuat, tetapi pengandar ini telah mendeteksi bahwa perangkat tidak lagi tersambung ke komputer. Biasanya, bendera ini digunakan untuk driver fungsi yang berkomunikasi dengan perangkat nirkabel. Misalnya, bendera diatur saat perangkat bergerak di luar rentang, dan dibersihkan setelah perangkat bergerak kembali ke rentang dan terhubung kembali.

Pengemudi bus biasanya tidak mengatur bendera ini. Driver bus seharusnya berhenti menghitung perangkat anak jika perangkat tidak lagi tersambung. Bendera ini hanya digunakan jika driver fungsi mengelola koneksi.

Satu-satunya tujuan bendera ini adalah untuk memberi tahu klien apakah perangkat terhubung. Mengatur bendera tidak memengaruhi apakah driver dimuat.

Manajer PnP meminta PNP_DEVICE_STATE perangkat tepat setelah memulai perangkat dengan mengirim permintaan IRP_MN_QUERY_PNP_DEVICE_STATE ke tumpukan perangkat. Menanggapi IRP ini, driver untuk perangkat mengatur bendera yang sesuai di PNP_DEVICE_STATE.

Jika salah satu karakteristik status berubah setelah kueri awal, driver memberi tahu manajer PnP dengan memanggil IoInvalidateDeviceState. Menanggapi panggilan ke IoInvalidateDeviceState, manajer PnP meminta PNP_DEVICE_STATE perangkat lagi.

Jika perangkat ditandai PNP_DEVICE_NOT_DISABLEABLE, debugger menampilkan bendera pengguna DNUF_NOT_DISABLEABLE untuk devnode. Debugger juga menampilkan nilai DisableableDepends yang menghitung jumlah alasan perangkat tidak dapat dinonaktifkan. Nilai ini adalah jumlah X+Y, di mana X adalah satu jika perangkat tidak dapat dinonaktifkan dan Y adalah jumlah perangkat anak perangkat yang tidak dapat dinonaktifkan.