WdfDeviceRetrieveDeviceInterfaceString and PDOs

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. 

  1. 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. 
  2. 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.
Comments (1)

  1. matt.lewis@nextlabs.com says:

    It seems that the device instance ID would be available in the context of an FDO setup when a device arrives in the system.  To distinguish two identical devices on a system this is required, however, only the hardware ID appears available from the device (via WdfDeviceQueryProperty).

    WdfDeviceRetrieveDeviceInterfaceString seems like it supplies the device name in a form that would match the symbolic link in the PNP notification mechanism, however, I am not able to retrieve the interface string using EvtDeviceSelfManagedIoInit.  The name does not exist, STATUS_OBJECT_NAME_NOT_FOUND.  Am I barking up the wrong tree here?  Just looking to identify the uniqueness of the device, access to the serial number would be great.