When is my first chance to access PLUGPLAY_REGKEY_DEVICE?

Hi all,

in my virtual USB controller project, I’ve run into a problem related to the extended properties descriptor as it is used by modern WinUSB devices. The hard part where I am currently stuck, however, is just related to PnP and WDF, so I think that it doesn’t take a dedicated USB expert to help me here.

Anyway, when WinUSB.sys gets loaded for a device, in its AddDevice routine it looks for a “DeviceInterfaceGUID” value in the device hardware key (the “Device Parameters” branch in the registry) which it passes on to WdfDeviceCreateDeviceInterface(). WinUSB client applications then can use SetupDiGetClassDevs( DIGCF_DEVICEINTERFACE ) to locate their device.

Now my responsibility as the (virtual) USB hub driver is to make sure that this registry value exists before WinUSB goes looking for it. But when do I do that? Right after WdfDeviceCreate() is too soon: WdfDeviceOpenRegistryKey( PLUGPLAY_REGKEY_DEVICE ) will return STATUS_INVALID_DEVICE_STATE. (It seems that the “Device Parameters” branch is not even created until the PnP system has selected a suitable driver for the first time.) And the device’s EvtDevicePrepareHardware callback is too late: experiments tell me that it runs only after WinUSB’s AddDevice routine.

So to summarize my question: When is my first chance to write to the registry hardware key of a device that I, as a bus driver, have just created myself? And is there even a standard callback available that will run at the right moment?

Hmmm… I don’t think you’re supposed to write that Registry key yourself.

That key gets written as a result of calling IoRegisterDeviceInterface/WdfDeviceRegisterDeviceInterface, doesn’t it??

Peter

DeviceInterfaceGUID is a specific to WinUSB, but it does have a broadly applicable name that can lead you to believe it is used everywhere ;). IRP_MJ_PNP/IRP_MN_DEVICE_ENUMERATED tells the bus driver that the PDO it has reported previously is now a “real enough” PDO which as a devnode and can be passed as a PDO to APIs. Before this minor code was added, a bus driver had to infer when this state transition occurred. WDF does not appear to abstract this minor code with a callback, so you would need to add a preprocess callback for it when you create the PDO (WdfDeviceInitAssignWdmIrpPreprocessCallback)

Originally, it was the responsibility of the driver writer to place that value in the INF file. However, if the device supports the “Microsoft OS Descriptors”, then no INF is required, and the GUID is embedded in one of the extended descriptors. To be honest, I do not know which driver is responsible for transferring that info. If I had to guess, I’d guess it was the USB hub driver, since it’s going to create that devnode. Are you using the standard hub driver, or have you written your own?

DeviceInterfaceGUID is a specific to WinUSB, but it does have a broadly applicable name that can lead you to believe it is used everywhere

So, for the record (and the clarity of the OP), I stand corrected! “Never mind”…

Thank you Doron and Tim.

Peter

Peter: Most of what IoRegisterDeviceInterface/WdfDeviceRegisterDeviceInterface do seems to take place in HKLM\System\CurrentControlSet\Control\DeviceClasses. But don’t worry, I would never try to mess with that part of the registry directly.

Tim: The hub driver is my own, too.

Doron: IRP_MN_DEVICE_ENUMERATED seems to be exactly what I was looking for. Thanks!