When you initially create a PDO, it takes a few steps for PnP to recognize it. I wrote this problem of determining when a PDO becomes a PDO last year. At the end of the post I mentioned that KMDF handles all of this state management for you underneath the covers. This works for 99% of the client drivers out there who just register a device interface and then let KMDF manage the state and do not care about the interface string.
Unfortunately, this platform issue does bleed out to the driver writer in one DDI, WdfDeviceRetrieveDeviceInterfaceString (which, fortunately, is not a very commonly called DDI). This DDI returns the string generated by the call to IoRegisterDeviceInterface, but since this string cannot be generated (and subsequently returned to the client driver) until the created WDFDEVICE PDO is a PnP recognized PDO, this function returns error. (Currently the returned error is STATUS_INVALID_DEVICE_STATE, but that can change so do not rely on a particular error value, use !NT_SUCCESS instead.) To solve this timing problem, the client driver must query for the interface string at a later time.
I recommend querying for the string in EvtDeviceSelfManagedIoInit. It has two benefits over registering a WDM preprocess routine and querying for the string in IRP_MJ_PNP/IRP_MN_QUERY_RESOURCE_REQUIREMENTS.
- You don’t have to register a WDM preprocess routine and deal with the underlying WDM structures and not leveraging the state tracking that KMDF provides.
- EvtDeviceSelfManagedIoInit is called only on the first time a PDO is started, any subsequent PnP starts will not invoke this callback. This is not true for the WDM preprocess routine, it can be invoked multiple times. Since the preprocess routine can be invoked multipel times, you must now not only track the state of the PDO as reported to PnP, but also the registered state of the interface and the returned interface string.