I have a USB Device with the following string present in the string descriptor table:
Index 0: Standard Language 0x0409 (English)
Index 1: Standard Manufacturer "xxx Corporation"
Index 2: Standard Product "xxx Board HID Device"
Index 3: Custom Sector "Bootloader" or "Application" (depending on current mode of operation).
I want to read the string at Index 3. For Windows, we have an API
HidD_GetIndexedString() which allows to get the string at any Index. What is the corresponding API in Linux? I see the driver is using usb_string to get the string in drivers but do we have any similar userspace API for usb in Linux?
Related
I have a setup with two regular displays and three projectors connected to a windows pc. In my win32 program I need to uniquely identify each monitor and store information for each such that I can retrieve the stored information even after computer restart.
The EnumDisplayDevices seems to return different device orders after restarting the computer. There is also GetPhysicalMonitorsFromHMONITOR which at least gives me the display's name. However, I need something like a serial number for my projectors, since they are the same model. How can I get such a unique identifier?
EDIT: This is the solution I came up with after reading the answer from user Anders (thanks!):
DISPLAY_DEVICEA dispDevice;
ZeroMemory(&dispDevice, sizeof(dispDevice));
dispDevice.cb = sizeof(dispDevice);
DWORD screenID;
while (EnumDisplayDevicesA(NULL, screenID, &dispDevice, 0))
{
// important: make copy of DeviceName
char name[sizeof(dispDevice.DeviceName)];
strcpy(name, dispDevice.DeviceName);
if (EnumDisplayDevicesA(name, 0, &dispDevice, EDD_GET_DEVICE_INTERFACE_NAME))
{
// at this point dispDevice.DeviceID contains a unique identifier for the monitor
}
++screenID;
}
EnumDisplayDevices with the EDD_GET_DEVICE_INTERFACE_NAME flag should give you a usable string. And if not, you can use this string with the SetupAPI to get the hardware id or driver key or whatever is unique enough for your purpose.
Set this flag to EDD_GET_DEVICE_INTERFACE_NAME (0x00000001) to retrieve the device interface name for GUID_DEVINTERFACE_MONITOR, which is registered by the operating system on a per monitor basis. The value is placed in the DeviceID member of the DISPLAY_DEVICE structure returned in lpDisplayDevice. The resulting device interface name can be used with SetupAPI functions and serves as a link between GDI monitor devices and SetupAPI monitor devices.
I have a setup with two regular displays and three projectors connected to a windows pc. In my win32 program I need to uniquely identify each monitor and store information for each such that I can retrieve the stored information even after computer restart.
The EnumDisplayDevices seems to return different device orders after restarting the computer. There is also GetPhysicalMonitorsFromHMONITOR which at least gives me the display's name. However, I need something like a serial number for my projectors, since they are the same model. How can I get such a unique identifier?
EDIT: This is the solution I came up with after reading the answer from user Anders (thanks!):
DISPLAY_DEVICEA dispDevice;
ZeroMemory(&dispDevice, sizeof(dispDevice));
dispDevice.cb = sizeof(dispDevice);
DWORD screenID;
while (EnumDisplayDevicesA(NULL, screenID, &dispDevice, 0))
{
// important: make copy of DeviceName
char name[sizeof(dispDevice.DeviceName)];
strcpy(name, dispDevice.DeviceName);
if (EnumDisplayDevicesA(name, 0, &dispDevice, EDD_GET_DEVICE_INTERFACE_NAME))
{
// at this point dispDevice.DeviceID contains a unique identifier for the monitor
}
++screenID;
}
EnumDisplayDevices with the EDD_GET_DEVICE_INTERFACE_NAME flag should give you a usable string. And if not, you can use this string with the SetupAPI to get the hardware id or driver key or whatever is unique enough for your purpose.
Set this flag to EDD_GET_DEVICE_INTERFACE_NAME (0x00000001) to retrieve the device interface name for GUID_DEVINTERFACE_MONITOR, which is registered by the operating system on a per monitor basis. The value is placed in the DeviceID member of the DISPLAY_DEVICE structure returned in lpDisplayDevice. The resulting device interface name can be used with SetupAPI functions and serves as a link between GDI monitor devices and SetupAPI monitor devices.
Is there a bash command, a program or a libusb function (although I did not find one) which indicates me what are the OUT or IN endpoints of a usb device ?
For example, bNumEndpoints of libusb_interface_descriptor (from libusb1.0 library) shows me my usb drive has 3 endpoints, but how can I know what is their idnumber ?
After you have claimed the device, run this (where $ represents the terminal entry point):
$ sudo lsusb -v -d 16c0:05df
Where 16c0:05df are your vendor and product ids separated by a colon. (If you don't know these, type lsusb and figure out which device is yours by unplugging and re-running lsusb)
If you get confused use the lsusb man page:
http://linux.die.net/man/8/lsusb
Then once your description comes up, find the line labeled bEndpointAddress and the hex code following will be the endpoint for that specific Report.
I finally found the answer in lubusb-1.0. In was actually not a function, but a struct field :
uint8_t libusb_endpoint_descriptor::bEndpointAddress
The address of the endpoint described by this descriptor.
Bits 0:3 are the endpoint number. Bits 4:6 are reserved. Bit 7
indicates direction, see libusb_endpoint_direction.
For each interface for the usb drive, I just had to write these lines to display the available endpoints :
cout<<"Number of endpoints: "<<(int)interdesc->bNumEndpoints<<endl;
for(int k=0; k<(int)interdesc->bNumEndpoints; k++) {
epdesc = &interdesc->endpoint[k];
cout<<"Descriptor Type: "<<(int)epdesc->bDescriptorType<<endl;
cout<<"EP Address: "<<(int)epdesc->bEndpointAddress<<endl;
}
Where epdesc is the libusb_endpoint_descriptor and interdesc is the libusb_interface_descriptor.
in windows if you go
DeviceManager -> Select Device(Like a a keyboard) -> Go to details -> List of properties:
Device description
Hardware Ids
Compatible Ids
Device class
Device class guid
Driver key
ConfigFlags
... etc
Where can I find what each of these properties mean?
From MSDN documentation, you will find description for Device Instance IDs, and link to other descriptions. This link briefly describes some of them, which are listed as following:
Device IDs
A device ID is a vendor-defined identification string that is the most
specific ID that Setup uses to match a device to an INF file. A device
has only one device ID. A device ID has the same format as a hardware
ID. If an enumerator reports a list of hardware IDs for a device, the
device ID should be the first hardware ID in the list.
The PnP Manager uses the device ID to create a subkey for a device
under the registry key for the device's enumerator.
To obtain a device ID, use an IRP_MN_QUERY_ID request and set the
Parameters.QueryId.IdType field to BusQueryDeviceID.
Hardware IDs
A hardware ID is a vendor-defined identification string that Setup
uses to match a device to an INF file. In most cases, a device has
associated with it a list of hardware IDs. (However, there are
exceptions – see Identifiers for 1394 Devices). The first hardware ID
in the list should be the device ID, and the remaining IDs should be
listed in order of decreasing suitability.
A hardware ID has one of the following generic formats:
<enumerator>\<enumerator-specific-device-ID> This is the most common
format for individual PnP devices reported to the PnP Manager by a
single enumerator. New enumerators should use this format or the
following format.
*<enumerator-specific-ID> The asterisk indicates that the device is supported by more than one enumerator, such as ISAPNP and the BIOS.
<device-class-specific-ID> An existing device class that has
established its own naming convention might use a custom format. For
information on their hardware ID formats, see the hardware
specification for such buses. New enumerators should not use this
format. The number of characters of a hardware ID, excluding a
NULL-terminator, must be less than MAX_LENGTH_LEN. This constraint
applies to the sum of the lengths of all the fields and any “\” field
separators in a hardware ID. In addition, when an instance ID is
concatenated to a hardware ID to create a device instance ID, the
lengths of the hardware ID and the instance ID are further constrained
by the maximum possible length of a device instance ID.
To obtain the list of hardware IDs for a device, call
IoGetDeviceProperty with the DeviceProperty parameter set to
DevicePropertyHardwareID. The list of hardware IDs that this routine
retrieves is a REG_MULTI_SZ value. The maximum number of characters in
a hardware list, including a NULL terminator after each hardware ID
and a final NULL terminator, is REGSTR_VAL_MAX_HCID_LEN. The maximum
possible number of IDs in a list of hardware IDs is MAX_HCID_COUNT.
Examples of Hardware IDs
In the following, the first example is a generic identifier for a PnP
device, and the second example is an identifier for a PCI device:
root*PNP0F08
PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02
Compatible IDs
A compatible ID is a vendor-defined identification string that Setup
uses to match a device to an INF file. A device can have associated
with it a list of compatible IDs. The compatible IDs should be listed
in order of decreasing suitability. If Setup cannot locate an INF file
that matches one of a device's hardware IDs, it uses compatible IDs to
locate an INF file. Compatible IDs have the same format as hardware
IDs; however, compatible IDs are typically more generic than hardware
IDs.
If a vendor ships an INF file that specifies a compatible ID for a
driver node, the vendor should ensure that their INF file can support
all the hardware that matches the compatible ID. Because a match with
a compatible ID is not as strong as a match to a hardware ID, the PnP
Manager prompts the user for confirmation before processing the INF
file.
To obtain a list of compatible IDs for a device, call
IoGetDeviceProperty with the DeviceProperty parameter set to
DevicePropertyCompatibleID. The list of compatible IDs that this
routine retrieves is a REG_MULTI_SZ value. The maximum number of
characters in a compatible ID list, including a NULL terminator after
each compatible ID and a final NULL terminator, is
REGSTR_VAL_MAX_HCID_LEN. The maximum possible number of IDs in a list
of compatible IDs is MAX_HCID_COUNT.
Instance IDs
An instance ID is a device identification string that distinguishes a
device from other devices of the same type on a machine. An instance
ID contains serial number information, if supported by the underlying
bus, or some kind of location information. The string cannot contain
any "\" characters; otherwise, the generic format of the string is
bus-specific.
The number of characters of an instance ID, excluding a
NULL-terminator, must be less than MAX_LENGTH_LEN. In addition, when
an instance ID is concatenated to a device ID to create a device
instance ID, the lengths of the device ID and the instance ID are
further constrained by the maximum possible length of a device
instance ID.
The UniqueID member of the DEVICE_CAPABILITIES structure for a device
indicates if a bus-supplied instance ID is unique across the system,
as follows:
If UniqueID is FALSE, the bus-supplied instance ID for a device is
unique only to the device's bus. The PnP Manager modifies the
bus-supplied instance ID, and combines it with the corresponding
device ID, to create a device instance ID that is unique in the
system. If UniqueID is TRUE, the device instance ID, formed from the
bus-supplied device ID and instance ID, uniquely identifies a device
in the system. An instance ID is persistent across system boots.
To obtain the bus-supplied instance ID for a device, use an
IRP_MN_QUERY_ID request and set the Parameters.QueryId.IdType member
to BusQueryInstanceID.
Device Instance IDs
A device instance ID is a system-supplied device identification string
that uniquely identifies a device in the system. The PnP Manager
assigns a device instance ID to each device node in a system's device
tree.
The format of this string consists of an instance ID concatenated to a
device ID, as follows:
\ The number of characters of a
device instance ID, excluding a NULL-terminator, must be less than
MAX_LENGTH_LEN. This constraint applies to the sum of the lengths of
all the fields and “\” field separator between the device ID and
instance-specific-ID fields. A device instance ID is persistent across
system boots.
The following is an example of an instance ID ("1&08") concatenated to
a device ID for a PCI device:
PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02\1&08
Most of it is exposed via the "Setup API". Some data may be driver-specific, in which case you'd have to ask the driver writer. The ones you've listed are all standard Microsoft properties. E.g. the "device class" describes what type of device it is, eg. mouse/keyboard/storage/videocard/audio/...
In my code NVRAM is implemented as character device and I want to give a condition to check whether it is character device or not. How to implement it programmatically? How can I do it through c++ code.
In terminal I gave command cat /proc/devices and it lists:
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/nvram
What does this number 5 in /dev/nvram denote?
The number denotes the device's major number, and the Character devices: heading in that listing tells you it's a character device.
If your character device is linked into the filesystem somewhere, like /dev/mydevice, you can also get information about it via the stat system call. The st_mode field of the struct stat structure can be tested with the S_ISCHR macro.