From: Claire Girka claire@sitedethib.com
--- dlls/winepulse.drv/mmdevdrv.c | 5 ++++ dlls/winepulse.drv/pulse.c | 55 +++++++++++++++++++++++++++++++++++ dlls/winepulse.drv/unixlib.h | 1 + 3 files changed, 61 insertions(+)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 446354fb9a5..1ac9ee1e0a8 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -2681,6 +2681,11 @@ HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARI return E_OUTOFMEMORY; memcpy(out->pwszVal, params.wstr, size); break; + case VT_CLSID: + if (!(out->puuid = CoTaskMemAlloc(sizeof(GUID)))) + return E_OUTOFMEMORY; + memcpy(out->puuid, ¶ms.uuid, sizeof(GUID)); + break; case VT_UI4: out->ulVal = params.ulVal; break; diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 268d59a71ab..1be3ae38771 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -41,6 +41,8 @@
#include "wine/debug.h"
+#include "devpkey.h" + WINE_DEFAULT_DEBUG_CHANNEL(pulse);
struct pulse_stream @@ -2301,6 +2303,55 @@ static BOOL get_device_path(PhysDevice *dev, struct get_prop_value_params *param return TRUE; }
+static BOOL get_device_container(PhysDevice *dev, struct get_prop_value_params *params) +{ + char buffer[10]; + char *path, *p; + + if (dev->sysfs_path == NULL) + return FALSE; + + path = malloc(strlen(dev->sysfs_path) + strlen("/sys") + strlen("/removable") + 1); + strcpy(path, "/sys"); + strcat(path, dev->sysfs_path); + + while ((p = strrchr(path, '/'))) { + FILE *f; + + strcpy(p, "/removable"); + f = fopen(path, "r"); + *p = 0; + + if (f) { + if (fgets(buffer, 10, f)) { + if (strcmp(buffer, "fixed") != 0) { + /* It's a potentially removable device, so treat it as a container */ + fclose(f); + break; + } + } + fclose(f); + } + } + + if (p && (p - path) > 4) { + char *guid = (char*) ¶ms->uuid; + memset(¶ms->uuid, 0, sizeof(GUID)); + + for (int i = strlen(path); i > 4; i--) { + guid[i % 16] ^= path[i]; + } + + params->vt = VT_CLSID; + + free(path); + return TRUE; + } + + free(path); + return FALSE; +} + static NTSTATUS pulse_get_prop_value(void *args) { static const GUID PKEY_AudioEndpoint_GUID = { @@ -2321,6 +2372,10 @@ static NTSTATUS pulse_get_prop_value(void *args) if (!get_device_path(dev, params)) break; return STATUS_SUCCESS; + } else if (IsEqualPropertyKey(*params->prop, DEVPKEY_Device_ContainerId)) { + if (!get_device_container(dev, params)) + break; + return STATUS_SUCCESS; } else if (IsEqualGUID(¶ms->prop->fmtid, &PKEY_AudioEndpoint_GUID)) { switch (params->prop->pid) { case 0: /* FormFactor */ diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h index 1481a5db4b8..b13048369ef 100644 --- a/dlls/winepulse.drv/unixlib.h +++ b/dlls/winepulse.drv/unixlib.h @@ -227,6 +227,7 @@ struct get_prop_value_params union { WCHAR wstr[128]; + GUID uuid; ULONG ulVal; }; };