Vulkan: serializing physical devices - vulkan

Let's say I have more physical devices supporting Vulkan (dedicated + integrated GPU, or 2 dedicated, or other possibilities). The user can choose the device to use in the options screen. I need to be able to persist his choice on disk.
What field can I use to uniquely identify a physical device across different executions?
vendorID + deviceID is not enough: I could have 2 identical GPUs connected
deviceName is not enough for the same reason
deviceLUID is not guaranteed to be present, and may have the same problems as deviceUUID (below)
deviceUUID looks like the correct choice, but the spec says:
While VkPhysicalDeviceIDPropertiesKHR::deviceUUID is specified to remain consistent across driver versions and system reboots, it is not intended to be usable as a serializable persistent identifier for a device. It may change when a device is physically added to, removed from, or moved to a different connector in a system while that system is powered down.
So... what should I use?

deviceUUID is the best you're going to get.
Think it like this. If the deviceUUID matches a cached copy, then you are certain that it's the same device. And if the cached ID doesn't match any existing device, then either that hardware was removed or something radical happened. Either way, you need to pop up that dialog again to let the user decide what to do.

Related

Retrieve mount point of WPD device

I've worked with WPD API for a while now, and I seem to run in to problem after problem.
Once I fix one problem, something else pops up. But hey, that's life.
I've been trying to determine if a WPD device is a storage device or a phone or whatever.
Turns out, devices such as iPhone are not set to be recognized as a phone, but instead as a generic device in terms of WPD_DEVICE_TYPE.
But, it is presented to Windows as a storage device.
When connecting external harddrives, SD memory card readers and other more conventional storage devices, they are recognized by the WPD API as well, but ehy that also get a dedicated mount point in Windows.
If I connect an external harddrive, it will have one functional category object, and the value of that object will be the path of that drive, say E:.
Nice. Great!
So my question is: How can I somehow read if the WPD device has a mountpoint?
Sure the functional object indicates that it has one, but is it possible that there could be an indicational value which states that a mount point is available?
Check the device Ids, here's an example how they differ:
\\?\swd#wpdbusenum#_??_usbstor#disk&ven_usb&prod_flash_disk&rev_1100#aa04012700007404&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}#{6ac27878-a6fa-4155-ba85-f98f491d4f33
vs.
USBSTOR\DISK&VEN_USB&PROD_FLASH_DISK&REV_1100\AA04012700007404&0
The upper one is the Id gathered from PortableDeviceManagerClass (first step to create an PortableDevice object), the lower one I've just read from the Device Manager, but it should be easily retrievable with one of these solutions:
How do I get a Unique Identifier for a Device within Windows 10 Universal?
https://sourceforge.net/projects/sharpdevelop/files/SharpUSBLib/

Is there a POSIX way of determining if a file (serial port actually) is open-able without opening it?

We make a device that can appear as a USB serial port on a variety of POSIX-compliant systems. I'm supporting an API that allows callers to retrieve a list of all the currently available (i.e. not in use, have correct privileges, etc.) instances of our device available to them. The caller can also get a list where the in-use devices are also indicated.
The simple way to do this of course is just attempt to open/close each candidate serial port and take note of which ones are open-able. I would prefer not to do this as it is possible that multiple applications using this API (which would be a library / dylib in their app) could create race conditions where they both try to query the same serial port simultaneously which would cause one app to erroneously think the device was in use.
So what I need is a way of knowing the port is open-able without actually opening it. I have seen others use lock-file schemes where there is a special file created to indicate the port is in use - the assumption being that if the file is not present the port is available. My problem is that there may be other users of the port other than my library that do not abide by such as scheme, so I cannot rely on it.
Is there perhaps some low-level POSIX functionality that lets me query a file's status in this regard without actually attempting to open it?

WDM: Given device FDO/PDO determine if it's USB Root Hub

USBPcap attaches as Upper Filter for all Root Hubs. It does so by adding UpperFilters entry for {36FC9E60-C465-11CF-8056-444553540000} class. Then in AddDevice function I retrieve the PDO and get list of hardware IDs. Then the list is checked for USB\ROOT_HUB and USB\ROOT_HUB20 entries. If it's in the list, the device is considered Root Hub, otherwise not.
The source code for above function is available at github: https://github.com/desowin/usbpcap/blob/master/USBPcapDriver/USBPcapHelperFunctions.c#L725
This solution doesn't play nice with USB 3.0 Root Hubs. As there are many different drivers for USB 3.0 controllers floating around there is not standard USB\ROOT_HUB30 entry. Basically every driver has its own hardware ID. I would prefer to avoid making a list of hardware IDs for all root hubs out there.
I would like to know if there is any way to reliably determine whether device is root hub without relying solely on hardware ids.
I thought about checking if device has GUID_DEVINTERFACE_USB_HUB and its parent has GUID_DEVINTERFACE_USB_HOST_CONTROLLER, but I don't know how (and if) it can be done in kernel mode inside function called in AddDevice callback.
I solved this issue by generating list of non standard (by standard Hardware ID I mean USB\ROOT_HUB and USB\ROOT_HUB20) Hardware IDs in user-space application and storing it in registry. I enumerate all GUID_DEVINTERFACE_USB_HOST_CONTROLLER instances and assume that children are Root Hubs.
Driver checks if the Hardware ID is present in registry entry generated by user-space application. If it matches, it is considered a Root Hub.

Is an ASHWID guaranteed to uniquely identify a device?

We want to use a unique device identifier in a Windows 8 Metro app and the recommendation is an ASHWID, documented here:
http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx
I'm struggling to see how this can possibly be guaranteed unique. The format includes two bytes per hardware component, of which the most uniquely identifiable are MAC address and hard disk serial number. But just two bytes for those values really doesn't seem like enough.
If the bytes used are anything other than the least significant digits (the rightmost, as a human reads them) are taken, then two identical laptops adjacent on the production line would probably have the same ASHWIDs. The MACs and drive serials would likely be adjacent.
So, I guess the crux of my question really is how many devices have to be produced with the same CPU type and memory configuration before you're likely hit a duplicate. Seems like the same sort of problem as the Birthday Paradox, so I found a calculator for that and plugged in the numbers :)
With one MAC address and one hard disk with a two-byte identifier each, you have about 4 billion permutations. Once you've allocated just 6,000 of them, it's roughly 50/50 that you've got two the same.
(go to http://jeff.aaron.ca/cgi-bin/birthday and plug in "6563" and "4294967296" for the actual calculation).
So this really doesn't seem very unique at all. Am I right in being ultra-sceptical of this identifier, or am I missing something really significant?
No, the ASHWID is not guaranteed to uniquely identify a device. At work, I've seen dozens of daily collisions where one monthly is our tolerance.
Further, the ASHWID might frequently change for the same device -- since Windows 8 will often run on laptops that might add a docking station, USB thumb-drive, or a plug-in Bluetooth adapter. The best use of the ASHWID is for verifying that a user has only installed your app to a limited number of devices, and you do that by parsing the ASHWID and selectively comparing it to previously-seen ASHWIDs from that user.
As for a unique hardware identifier, I suggest an MD5 digest of a string containing multiple components, of which some components of the ASHWID can play a part.
You might randomly generate a large number (64+ bits) and store that (eg in the registry). And of course the user's login name/ID should be unique to that user, if you want something else to include in a hash. You also need to consider what you want to do if the user clones an OS install, or replaces the HD after a drive failure.
Back in the Windows Desktop world, I used the MachineGuid registry key and the serial number of the boot device, but I'm fighting to get access to that info in a Windows Store app. If you have access, MachineGuid is in HKLM\SOFTWARE\Microsoft\Cryptography, which MS guarantees to be unique. The serial number of the boot device ::GetVolumeInformationW(::SHGetFolderPathW(~),~) will be fairly unique but only 32 bits.
From the article:
The ASHWID provides a strong binding between the app/package and the
device by representing several individual hardware characteristics. In
order to protect user privacy, the ASHWID varies from app to app.
Unless the underlying hardware has changed, two calls from the same
app will result in identical ASHWIDs. However, the ASHWID changes if
the hardware profile of the device changes, such as when the user
unplugs a USB Bluetooth adapter. The back-end cloud service can verify
the ASHWID and compare it with previously reported values. Though the
ASHWID varies, it can be parsed to detect if the variance was simply
due to a minor change such as an addition of memory to the system. The
level of tolerance for variance is up to the implementation of the
back-end cloud service.
The ASHWID is made up of 9 components:
CPU ID of the processor
Size of the memory
Serial number of the disk device
Network adapter (NIC MAC address - first instance)
Audio adapter
Docking station
Bluetooth address
Mobile broadband device ID
BIOS
CPU ID is only unique to processor model, but NIC MAC Address should be very unique. Having said that, MAC addresses can be cloned and USB NICs can be moved from device to device. So, while I guess it's possible for two devices to have the same ASHWID, it's very unlikely. What's most challenging in using this ID is the fact that hardware can change. It's up to the service to decide which parts of the ASHWID they allow to change and which parts the do not (acceptable variance). The article itself provides guidance on that.

Reading values from a Power Meter via USB

Over the past two days, I am doing some reading on how to get data over USB from an external device which has no device driver installed. I have to read data from a WT500 Yokogawa Power Meter (basically I want to read just one of the parameter that the meter shows, just the power values) over USB. I am aware that a device driver for WT500 is available, but it has some dependencies and I do not want to install a software or change anything majorly in our node to cater to that.
I have found that libusb could be used to perform what I would want, and I have a C program that sniffs the USB device and returns some information. I have looked into usb-robot as well, which also uses libusb. The server node that I am probing has OpenSUSE Linux kernel 2.6.30. I have usbfs mounted.
Question:
I am expecting that using libusb, I would be able to get data dumps from the power meter whenever I request, via usb device. Can I request the meter something like - send 25k of data, and then upon parsing it, I get the parameter value that I am looking for? Considering that I have zero knowledge about the device, can I get some meaningful values out of it? An example code would help.
--
There are some standard messages like ?IDN with which a USBTMC device could be queried. However, specific queries need to be sent to a meter (the syntax should be there in the technical doc/manual/communication interface) if one needs to get whatever is showing up on screen.
I guess there are no easier ways of doing what I want - like just reading a file using something like fread ??
--
Yes, almost. If USBTMC module is installed (the default one in our kernel did not work, detailed explanation of installing and querying a device is here - http://code.google.com/p/scte/wiki/USBTMC), then one just needs to send some queries and read the response via cat or something from the specific files under /dev.
From the meter technical document, I see that the driver communication interface that is described is Windows specific, so I reckon I might need to do some reverse engineering.
--
Yes, but only a tiny bit or may be not at all.
Thank you.
EDIT: After a bit of googling I think I have the answers, I have added them next to the questions I asked.