USB Device Naming with index

Hi again,

An other issue, I have with a WDM USB driver is to rename the device properly.

Several identical device can be connected on the same computer, and it is need to properly identify them for the user.

In the previous version, the driver were renamed by a UserMode library and incremented for each new device. This is not working anymore under Vista/Seven environment due to access right required. To avoid this, I have moved the renaming routine in the CoInstaller. At new device installation, it lists all the devices matching the interface and use the new name available. The name is build using the friendlyname concatenated with an index.

This work find on first installation, but when I update the driver, the CoInstaller is called, but is not able to get the friendlyname property. I receive an ERROR_INVALID_DATA error.

It there an issue with my logic? It there a better to properly name devices?

Thanks for your help
regards

After additional analysis, it seems that the FriendlyName value is removed from the hardware key (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx\6&1ab5e341&0&4) but is still present in the Driver key.

Initially, I believe that the Hardware key was build using the Driver key as base. Is it right?

>build using the friendlyname concatenated with an index.

Throw all of this outdated obsolete junk away, and use the PnP devinterfaces, which are the main way of getting the device name since year 2000 if not even earlier.

Do you understand that your \.\MyDev%d names are not persistent, and will change if the devices are plugged to the PC in different order?

The %d index is NOT bound to the physical device piece in any meaningful way, and you will require either the user to do wild guessing, or to blink the LED on the device piece (having the “Identify” path in the UI).

Devinterfaces are free from this. The devinterface instance is persistent and is bound either to the device piece (if it has USB serial number), or to the device kind+USB port (if there is no serial).

Yes, devinterfaces will require some remake of the user mode app too, but this is necessary.

The following paths should be remade in the app:

  • get a list of all present devices
    based on SetupDi calls
    returns a set of (UIName, InternalName) tuples
  • open one of the devices based on its InternalName (this is just CreateFile).

If you need to have the open by UIName function, than you can do some trivial std::map or such.

You can also use SetupDiOpenDeviceInterfaceRegKey to allow the UI to set the user-defined friendly name for the device, like “Yellow SanDisk” or such.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

This name is the device model name, not device instance name.

wrote in message news:xxxxx@ntdev…
> After additional analysis, it seems that the FriendlyName value is removed from the hardware key (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx\6&1ab5e341&0&4) but is still present in the Driver key.
>
> Initially, I believe that the Hardware key was build using the Driver key as base. Is it right?
>
>
>

>>build using the friendlyname concatenated with an index.

Throw all of this outdated obsolete junk away, and use the PnP
devinterfaces, which are the main way of getting the device name since year
2000 if not even earlier.
Do you understand that your \.\MyDev%d names are not persistent, and
will change if the devices are plugged to the PC in different order?
The %d index is NOT bound to the physical device piece in any meaningful
way, and you will require either the user to do wild guessing, or to blink
the LED on the device piece (having the “Identify” path in the UI).
Devinterfaces are free from this. The devinterface instance is persistent
and is bound either to the device piece (if it has USB serial number), or
to the device kind+USB port (if there is no serial).
Yes, devinterfaces will require some remake of the user mode app too, but
this is necessary.
The following paths should be remade in the app:

  • get a list of all present devices
    based on SetupDi calls
    returns a set of (UIName, InternalName) tuples
  • open one of the devices based on its InternalName (this is just
    CreateFile).
    If you need to have the open by UIName function, than you can do some
    trivial std::map or such.
    You can also use SetupDiOpenDeviceInterfaceRegKey to allow the UI to set
    the user-defined friendly name for the device, like “Yellow SanDisk” or
    such.

Thanks for your feedback.

I’m not sure I have properly describe the current implementation and I
think i’m already using PnP devinterfaces but not sure so here are the
exact way it is implemented currently:

  • Use SetupDixxx from CoInstaller to get device name format from a value
    located in the .INF file
  • Loop through all devices (connected or not) that matches the interface
    with
    SetupDiGetClassDevs/SetupDiEnumDeviceInfo/SetupDiGetDeviceRegistryProperty
    to ensure no device with the same name has been registered
  • Set the device FriendlyName with SetupDiSetDeviceRegistryProperty
    As the loop is done on all devices, the device name won’t change, but if
    the device is plugged on an other port, it will have a new name (the device
    has no serial number).

About application, there are using a dedicated library to access the
devices and the library is using call to SetupDiGetClassDevs(on interface)
and other SetupDixxx to list the devices and get their Friendlyname.

The goal of device renaming is only to have a friendly name for the user in
Device Manager and in User App, but it is not used to open the device.

If I’m not using “PnP devinterfaces”, is there a place where I can found
some example?

> After additional analysis, it seems that the FriendlyName value is
removed from the hardware key
(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx\6&1ab5e341&0&4)
but is still present in the Driver key.
This name is the device model name, not device instance name.

You mean this name (6&1ab5e341&0&4 ?) is the model name? So where are
located instance key? In the interface reg
(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses{7e313291-9559-453c-8539-341e4424d7e5}##?#USB#VID_xxxx&PID_xxxx#6&1ab5e341&0&4#{7e313291-9559-453c-8539-341e4424d7e5})?

Sorry for my newbie questions, but there are a lot of terms for the same
thing and want to be sure I properly get them.

Regards

On 13-Nov-2014 14:45, Maxim S. Shatskih wrote:

> build using the friendlyname concatenated with an index.

Throw all of this outdated obsolete junk away, and use the PnP devinterfaces, which are the main way of getting the device name since year 2000 if not even earlier.

Do you understand that your \.\MyDev%d names are not persistent, and will change if the devices are plugged to the PC in different order?

Maxim,
The OP didn’t mention that he uses “\.\MyDev%d” device names.
All he needs is “friendly names” to identify the instances in UI (and
dev. manager). It’s not clear how devinterfaces can help with this.

you will require either the user to do wild guessing, or to blink the LED on the device piece (having the “Identify” path in the UI).
If you need to have the open by UIName function, than you can do some trivial std::map or such.

You can also use SetupDiOpenDeviceInterfaceRegKey to allow the UI to set the user-defined friendly name for the device, like “Yellow SanDisk” or such.

Agreed. This leaves a lot of space for creativity…
Unless the devices do not have LEDs or push buttons, user can identify
them by plugging one-by-one (like Realtek audio software asks what is
that you’ve just plugged in).

– pa

> dev. manager). It’s not clear how devinterfaces can help with this.

It is the best help for the UI, since SetupAPI provides you with (logically) (UIName, RealName) tuples.

And yes, lots of camera-related software can display video cameras this way.

> You can also use SetupDiOpenDeviceInterfaceRegKey to allow the UI to set the user-defined
friendly name for the device, like “Yellow SanDisk” or such.
>

Agreed. This leaves a lot of space for creativity…

And even more creativity if you would like to support Vista+ unified device properties.

Then you will be able to put the device with the fancy vector icon for it to the Control Panel/Devices, where the printers are.

Unless the devices do not have LEDs or push buttons, user can identify
them by plugging one-by-one

This is what is going on with %d-based naming.

It is not an issue for disks, since disks have drive letters (persisent, dependent only on disk’s MBR signature and not connection) and volume labels.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

And what about IoSetDevicePropertyData with DEVPKEY_Device_FriendlyName property key ?

Take a look at that page.

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/8a74f6bc-82bf-4b79-8ffd-1d62c3d98ef5/using-iosetdevicepropertydata-to-change-device-descriptionfriendly-name?forum=wdk

My issue is not when I set the friendlyname, but when I try to read the
value of other installed device to avoid duplicating names.

I think I figure out the issue. Here is my understanding, thanks to tell me
if its possible or not at all:

On first installation, no driver are registered on the interface so when my
CoInstaller requests all the devices related to the interface it gets
nothing, so no conflict.
For further device installation, it get the already installed device and
increment the device name accordingly. Until there everything is fine.

On driver update, as the driver itself is not updated, it is not unloaded
and the device is still registered to the interface. However the device
registry key is cleaned before calling the CoInstaller.
When the CoInstaller is called, I’m requesting the devices related to the
interface and get all other installed devices including the current one
(the one updated which has a cleaned device registry). Result: I get an
error when I request the friendlyname value.

So I think I will just skip the current installed device to avoid this
issue.

Regards

>call to SetupDiGetClassDevs(on interface) and other SetupDixxx to list the devices

According to your descr, you’re already fine, and everything is already done. :slight_smile:

and get their Friendlyname.

The friendly name is just the device interface name :slight_smile: it is usually rather friendly :slight_smile: though it is not exactly what you want.

It is like “This Kind of the Device #1” or “This Kind of the Device #2”.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

You can have some registry value out of SYSTEM where the bitmask of all busy friendly name indices is stored.

The coinstaller will look at this mask, query/set the bit in it, and assign the friendly name using this index.

This is how the serial driver package assigns COM%d names.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

On 13-Nov-2014 23:07, Maxim S. Shatskih wrote:

You can have some registry value out of SYSTEM where the bitmask of all busy friendly name indices is stored.

Bitmask is not enough, he needs a map of instance path -> number (or
name). The serial “arbiter” (or how they call it) is too dumb.

  • pa