The duality of IoRegisterPlugPlayNotification and when you should call it

IoRegisterPlugPlayNotification() is a pretty scary looking function at first glance. The documentation is not that simple either. So what does this function do and why do you want to use it? IoRegisterPlugPlayNotification() does 2 things (OK 3, but the 3rd is a corner case), it tells you about:

  1. Arrival and departure of instances of device interfaces
  2. The graceful or sudden removal of a device stack which you opened a handle against
  3. A change in the hardware profile on the machine

Arrival and departure of device interfaces is important because there is no driver load ordering guarantees by the PnP manager, so your driver may load before or after the driver you want to open has been loaded. This is a change from versions previous of NT previous to Windows 2000 .0 where could specify such dependencies . Since there are no ordering guarantees, the OS provides a way for you to be notified when the driver you are interested comes online. To register for these notifications, you specify EventCategoryDeviceInterfaceChange as the EventCategory. Typically you would specify PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES as the EventCategoryFlags so that you are also notified of instances which came online before your driver has loaded. Note that this notification system only works for device interfaces, it does not work for the older style symbolic links created by calling IoCreateSymbolicLink(), which is good motivation (for me at least) to move to the new device interfaces.

The toastmon sample in the DDK demonstrates how to use this functionality of the API. KMDF does not wrap this functionality of the API.

Once you have opened a file handle against a pnp stack, being notified of the graceful or sudden removal of the device is important. Why? Well, a device cannot be gracefully removed if there are any open handles when the query remove is enacted. One consequence of not closing the handle to the device is that the device will never be disableable by the user. On the flip side, if the user unplugs the hardware from the machine, the device is put into the surprise removed pnp state. The only way it can transition to the removed state is if all open handles are closed, so by keeping your handle open you prevent the stack from being removed and the driver image from possibly unloading (which makes servicing the driver image impossible without a reboot). In both cases, you should behave nicely in the system and close the handle at the appropriate time. To register for these notifications, you specify EventCategoryTargetDeviceChange as the EventCategory.

The toastmon, kbdclass, and mouclass examples in the DDK all demonstrate how to register for notifications on an open handle. KMDF does wrap this functionality of the API in the WDFIOTARGET handle. When opening a WDFIOTARGET, you can override this functionality by providing the appropriate callbacks in WDF_IO_TARGET_OPEN_PARAMS.

So what about the 3rd category where you are notified about profile changes? I have seen very few drivers need to know this, the ones that do are primarily motherboard specific drivers (such as ACPI.sys). One driver which is not a motherboard specific driver which listens for this notification is i8042prt.sys, the PS/2 mouse and keyboard driver. Why does it listen for hardware profile changes? To reset the mouse when you dock/undock your laptop ;). It needs to do this because the driver does not know about the PS/2 pass through port in your dock and that the new mouse needs to be initialized (or it has disappeared). The BIOS does know about the existence of the pass through port and resetting the mouse makes everyone happy and functional again.