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`)
This is made specific to containerId rather than supporting VT_CLSID on every property because Wine currently stores VT_BLOBs directly in the registry value, which does not allow us to safely disambiguate between VT_CLSID and VT_BLOB values when reading from registry.
-- v3: mmdevapi: copy ContainerID from audio driver if available mmdevapi: decode ContainerId property to CLSID in MMDevice_GetPropValue
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..10bf76057ee 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.cbSize == 24 && 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; }
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 10bf76057ee..bf0fc4728d1 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);