From: Harald Sitter sitter@kde.org
ContainerId on Windows is a bit special. It actually gets stored in the registry as a blob of data that starts with the variant type and ends with the GUID. The bits inbetween have no immediately obvious meaning and aren't used for the time being. --- dlls/mmdevapi/devenum.c | 43 ++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index b1993573dd9..078fd14e8a1 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -47,6 +47,13 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); static HKEY key_render; static HKEY key_capture;
+struct clsid_blob { + BYTE vt; + BYTE wReserved0[3]; // Unknown metadata, maybe flags? + DWORD wReserved1; // Possibly a version of some sort? + GUID puuid; +}; + typedef struct MMDevPropStoreImpl { IPropertyStore IPropertyStore_iface; @@ -196,15 +203,28 @@ static HRESULT MMDevice_GetPropValue(const GUID *devguid, DWORD flow, REFPROPERT RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_DWORD, NULL, (BYTE*)&pv->ulVal, &size); break; } - case REG_BINARY: - { - pv->vt = VT_BLOB; - pv->blob.cbSize = size; - pv->blob.pBlobData = CoTaskMemAlloc(size); - if (!pv->blob.pBlobData) - hr = E_OUTOFMEMORY; - else - RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_BINARY, NULL, (BYTE*)pv->blob.pBlobData, &size); + case REG_BINARY: { + if (IsEqualPropertyKey(*key, DEVPKEY_Device_ContainerId)) { + struct clsid_blob blob; + DWORD size = sizeof(blob); + + RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_BINARY, NULL, (BYTE *)&blob, &size); + + pv->vt = VT_CLSID; + pv->puuid = CoTaskMemAlloc(sizeof(GUID)); + if (!pv->puuid) + hr = E_OUTOFMEMORY; + else + *pv->puuid = blob.puuid; + } else { + pv->vt = VT_BLOB; + pv->blob.cbSize = size; + pv->blob.pBlobData = CoTaskMemAlloc(size); + if (!pv->blob.pBlobData) + hr = E_OUTOFMEMORY; + else + RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_BINARY, NULL, (BYTE *)pv->blob.pBlobData, &size); + } break; } default: @@ -249,6 +269,11 @@ 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: { + struct clsid_blob blob = {.vt = VT_CLSID, .wReserved0 = {0, 0, 0}, .wReserved1 = 0, .puuid = *pv->puuid}; + ret = RegSetValueExW(regkey, buffer, 0, REG_BINARY, (const BYTE *)&blob, sizeof(blob)); + break; + } default: ret = 0; FIXME("Unhandled type %u\n", pv->vt);