Some games with support for the haptic feedback and speaker features of the Sony DualSense controller select the controller's audio output by filtering on the ContainerId IMMDevice property to find one that matches the controller's HID's. This MR allows this information to be accessible from the IMMDevice's property store when the audio driver provides it (none for now, but I intend to add that feature to `winepulse.drv` and maybe `winealsa.drv`)
Windows also stores the property in that registry key, but serializes it as binary instead of storing the string representation. I did not find documentation on that serialization, and while it seems mostly straightforward, there are two bytes I could not understand the meaning of: `{4a412178-e895-11ec-a989-00dbdfb57d1c}` is stored as `48 00 2b b7 01 00 00 00 78 21 41 4a 95 e8 ec 11 a9 89 00 db df b5 7d 1c`. The `01 00 00 00` DWORD seems to always have that same value, and the `2b b7` parts are safe to ignore when reading, but I do not know what meaning they have.
If there are already parts of Wine dealing with such a serialization, I could not find them, but I would gladly use them. Using the proper encoding would also conflict with `VT_BLOB` handling, but I suspect Windows also encodes `VT_BLOB` properties in a similar way than it does for `VT_CLSID`. On that note, Windows' behavior for `PKEY_AudioEngine_DeviceFormat` is different from Wine's, storing it as `41 00 04 00 01 00 00 00 ff fe 04 … 38 9b 71`, while Wine stores the `ff fe … 71` payload directly.
-- v2: mmdevapi: copy ContainerID from audio driver if available mmdevapi: decode ContainerId property to CLSID in MMDevice_GetPropValue mmdevapi: support VT_CLSID for containerId property in MMDevice_SetPropValue
From: Claire Girka claire@sitedethib.com
CLSID is special-cased to this property because we can't safely differentiate an encoded VT_CLSID from an encoded VT_BLOB. --- dlls/mmdevapi/devenum.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index bfeb3f3ecd8..48f4c736217 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -225,6 +225,18 @@ static HRESULT MMDevice_SetPropValue(const GUID *devguid, DWORD flow, REFPROPERT ret = RegSetValueExW(regkey, buffer, 0, REG_SZ, (const BYTE*)pv->pwszVal, sizeof(WCHAR)*(1+lstrlenW(pv->pwszVal))); break; } + case VT_CLSID: + { + if (IsEqualPropertyKey(*key, DEVPKEY_Device_ContainerId)) { + BYTE value[24] = { VT_CLSID, 0, 0, 0, 1, 0, 0, 0 }; + memcpy(value + 8, pv->puuid, sizeof(GUID)); + + ret = RegSetValueExW(regkey, buffer, 0, REG_BINARY, (const BYTE*)value, 24); + break; + } + /* If it's not containerId, fall through the default unsupported case as we can't + ensure it will be decoded as CLSID. */ + } default: ret = 0; FIXME("Unhandled type %u\n", pv->vt);
From: Claire Girka claire@sitedethib.com
--- dlls/mmdevapi/devenum.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 48f4c736217..b288ed79880 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -189,6 +189,21 @@ static HRESULT MMDevice_GetPropValue(const GUID *devguid, DWORD flow, REFPROPERT break; } RegCloseKey(regkey); + + /* Special case ContainerID as CLSID */ + if(pv->vt == VT_BLOB && pv->blob.pBlobData && pv->blob.pBlobData[0] == VT_CLSID && IsEqualPropertyKey(*key, DEVPKEY_Device_ContainerId)) { + GUID *guid = CoTaskMemAlloc(sizeof(GUID)); + if (!guid) { + PropVariantClear(pv); + hr = E_OUTOFMEMORY; + } else { + memcpy(guid, pv->blob.pBlobData + 8, sizeof(GUID)); + CoTaskMemFree(pv->blob.pBlobData); + pv->vt = VT_CLSID; + pv->puuid = guid; + } + } + return hr; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118159
Your paranoid android.
=== debian11 (32 bit report) ===
mmdevapi: capture.c:205: Test failed: GCP 16571 past ReleaseBuffer(0) initially 16077
From: Claire Girka claire@sitedethib.com
Some games with support for the haptic feedback and speaker features of the Sony DualSense controller select the controller's audio output by filtering on the ContainerId IMMDevice property to find one that matches the controller's HID's. --- dlls/mmdevapi/devenum.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index b288ed79880..f317e587412 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -391,6 +391,8 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_FriendlyName, &pv); MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_DeviceDesc, &pv);
+ set_driver_prop_value(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_ContainerId); + pv.pwszVal = guidstr; MMDevice_SetPropValue(id, flow, &deviceinterface_key, &pv);