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?
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.
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.
> 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).
> 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.
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.