winebus,mmdevapi: implement audio device container id
This is a bit convoluted because of the amount of pieces involved. I'll try to untangle things a bit.
The container id is meant to be globally unique and stable. We therefore need a suitable amount of stable entropy that we can feed into a hash function to get a stable and unique output.
This happens in winebus. The corner stone of hash inputs is the linux device topology (sysfs path) obtained via udev. Along with all other possible data we feed this into a hash function to obtain our container id.
A bunch of extra wine-specific keys needed to be added to carry the necessary metadata from the driver into the ntoskrnl (where it gets written to the property registry of the relevant device).
Separate from this we also ingest the linux device topology (sysfs path) in the winepulse driver.
In mmdevapi we then use winepulse's sysfs path to find the matching device in the setupapi and query its container id. We now have the same container id in both the device and the MMDevice, allowing applications (in particular Games) to find the MMDevice for a given device.
For practical reasons we always resolve the sysfs path to the root device as early as possible. Container ids are meant to be equal for sub devices inside a "container" anyway.
Merge request reports
Activity
requested review from @rbernon
added 1 commit
- 7636b934 - winebus,mmdevapi: implement audio device container id
Fwiw there was some previous attempts before (see !535 and !360) and as I understand it's mostly blocked by !359, which is necessary to store the mmdevapi property correctly. The issue is that we need to change the format of the properties in the registry and it would break existing prefix if not done properly.
Other than that, the changes would probably need to be split into finer grained changes. I'm also not sure we want to expose the sysfs path outside of the unix libraries. It's very specific to the linux backend, and even more to the udev backend. I would instead try to make both unix-side code generate a similar stable container id from whatever information they can get, and get that container id exposed instead.
Sounds reasonable. Assuming we want to hash a bunch of information from sysfs I think we'll want to share a hash function between bus_udev.c and pulse.c?
char *container_id_for_sysfs(char const *path)
or some such. If so, is there some prior art for implementing a library for sharing a function between two dlls' unix libs? Or is there an existing library I can add that function to?
added 1 commit
- 941ab1c2 - winebus,mmdevapi: implement audio device container id
I've adjusted the MR to hash sysfs information on both sides. I am not quite sure how to best get access to the sha implementation in crypt.c though. As far as I understand it's not part of the unix lib. I am also not sure putting the sysfs/containerid handling into ntdll is at all that pretty.
Input would be greatly appreciated.
Do we really need to use a cryptographic hash there? Could we instead extract the useful bits from the sysfs path, like USB port numbers and put them into some of the GUID data fields? We only need it to match the mmdevapi side when it is plugged in, I don't think we need to have anything stable across hotplugs or prefix restart.
Note that in any case there's things to resolve on the mmdevapi side before this can be useful like the property registry format in !359, and perhaps also how audio device hot-plugging works (if it does) or would work.
Could we instead extract the useful bits from the sysfs path, like USB port numbers and put them into some of the GUID data fields?
Probably. Question is what are the useful bits for any given subsystem though. My thinking is that by hashing the entire path we side step the issue of sysfs paths sometimes not being well defined and also get easier to reason code as we don't need to care how to deconstruct the path, nor how the GUID specifically is calculated. I am fine with doing it differently as well though.
Microsoft also documents the container id as globally unique, so we need some degree of smartness here IMHO.
I don't think we need to have anything stable across hotplugs or prefix restart.
From observing windows it seems the containerid is stable there, so conceivably an application could store the id persistently somewhere. Granted, bit of a stretch.
BTW !359 is implemented in devenum as clsid_blob (and read/write thereof) !7238 (diffs) I think
requested review from @huw
added 272 commits
-
941ab1c2...59720e7d - 270 commits from branch
wine:master
- 51054e1b - mmdevapi: correctly read and write containerid as clsid blob
- 9600a564 - containerid: helper to generate a containerid from a sysfs path
-
941ab1c2...59720e7d - 270 commits from branch