[PATCH] mmdveapi: Support older version of the AudioClientProperties structure

Andrew Eikum aeikum at codeweavers.com
Fri Nov 20 08:58:28 CST 2020


Warframe when using a win10 prefix uses an xaudio2_9redist.dll which
uses the older AudioClientProperties structure (missing the Options
member).

Based on a patch by Alistair Leslie-Hughes.

Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/mmdevapi/tests/render.c      | 12 +++++++++++-
 dlls/winealsa.drv/mmdevdrv.c      | 22 +++++++++++++++-------
 dlls/wineandroid.drv/mmdevdrv.c   | 22 +++++++++++++++-------
 dlls/winecoreaudio.drv/mmdevdrv.c | 22 +++++++++++++++-------
 dlls/wineoss.drv/mmdevdrv.c       | 22 +++++++++++++++-------
 dlls/winepulse.drv/mmdevdrv.c     | 22 +++++++++++++++-------
 include/audioclient.idl           |  8 ++++++++
 7 files changed, 94 insertions(+), 36 deletions(-)

diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c
index a0aa1b18936..495c1c6f496 100644
--- a/dlls/mmdevapi/tests/render.c
+++ b/dlls/mmdevapi/tests/render.c
@@ -276,6 +276,7 @@ static void test_audioclient(void)
         hr = IAudioClient2_SetClientProperties(ac2, NULL);
         ok(hr == E_POINTER, "SetClientProperties with NULL props gave wrong error: %08x\n", hr);
 
+        /* invalid cbSize */
         client_props.cbSize = 0;
         client_props.bIsOffload = FALSE;
         client_props.eCategory = AudioCategory_BackgroundCapableMedia;
@@ -284,7 +285,8 @@ static void test_audioclient(void)
         hr = IAudioClient2_SetClientProperties(ac2, &client_props);
         ok(hr == E_INVALIDARG, "SetClientProperties with invalid cbSize gave wrong error: %08x\n", hr);
 
-        client_props.cbSize = sizeof(client_props);
+        /* offload consistency */
+        client_props.cbSize = sizeof(client_props) - sizeof(client_props.Options);
         client_props.bIsOffload = TRUE;
 
         hr = IAudioClient2_SetClientProperties(ac2, &client_props);
@@ -293,10 +295,18 @@ static void test_audioclient(void)
         else
             ok(hr == S_OK, "SetClientProperties(offload) failed: %08x\n", hr);
 
+        /* disable offload */
         client_props.bIsOffload = FALSE;
         hr = IAudioClient2_SetClientProperties(ac2, &client_props);
         ok(hr == S_OK, "SetClientProperties failed: %08x\n", hr);
 
+        /* Options field added in Win 8.1 */
+        client_props.cbSize = sizeof(client_props);
+        hr = IAudioClient2_SetClientProperties(ac2, &client_props);
+        ok(hr == S_OK ||
+                broken(hr == E_INVALIDARG) /* <= win8 */,
+                "SetClientProperties failed: %08x\n", hr);
+
         IAudioClient2_Release(ac2);
     }
     else
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index 0c255a66f7d..318350471db 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -2676,21 +2676,29 @@ static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
         const AudioClientProperties *prop)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
 
     TRACE("(%p)->(%p)\n", This, prop);
 
-    if(!prop)
+    if(!legacy_prop)
         return E_POINTER;
 
-    if(prop->cbSize != sizeof(*prop))
+    if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory,
+                prop->Options);
+    }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory);
+    }else{
+        WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
         return E_INVALIDARG;
+    }
 
-    TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-            prop->bIsOffload,
-            prop->eCategory,
-            prop->Options);
 
-    if(prop->bIsOffload)
+    if(legacy_prop->bIsOffload)
         return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
 
     return S_OK;
diff --git a/dlls/wineandroid.drv/mmdevdrv.c b/dlls/wineandroid.drv/mmdevdrv.c
index 7d543ec4f61..d9b7cde2c80 100644
--- a/dlls/wineandroid.drv/mmdevdrv.c
+++ b/dlls/wineandroid.drv/mmdevdrv.c
@@ -1635,21 +1635,29 @@ static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
         const AudioClientProperties *prop)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
 
     TRACE("(%p)->(%p)\n", This, prop);
 
-    if(!prop)
+    if(!legacy_prop)
         return E_POINTER;
 
-    if(prop->cbSize != sizeof(*prop))
+    if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory,
+                prop->Options);
+    }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory);
+    }else{
+        WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
         return E_INVALIDARG;
+    }
 
-    TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-            prop->bIsOffload,
-            prop->eCategory,
-            prop->Options);
 
-    if(prop->bIsOffload)
+    if(legacy_prop->bIsOffload)
         return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
 
     return S_OK;
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 846e0ae3b1e..b002189e199 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -2243,21 +2243,29 @@ static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
         const AudioClientProperties *prop)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
 
     TRACE("(%p)->(%p)\n", This, prop);
 
-    if(!prop)
+    if(!legacy_prop)
         return E_POINTER;
 
-    if(prop->cbSize != sizeof(*prop))
+    if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory,
+                prop->Options);
+    }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory);
+    }else{
+        WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
         return E_INVALIDARG;
+    }
 
-    TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-            prop->bIsOffload,
-            prop->eCategory,
-            prop->Options);
 
-    if(prop->bIsOffload)
+    if(legacy_prop->bIsOffload)
         return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
 
     return S_OK;
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
index fd0784eb323..db2c6b23914 100644
--- a/dlls/wineoss.drv/mmdevdrv.c
+++ b/dlls/wineoss.drv/mmdevdrv.c
@@ -1800,21 +1800,29 @@ static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
         const AudioClientProperties *prop)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
 
     TRACE("(%p)->(%p)\n", This, prop);
 
-    if(!prop)
+    if(!legacy_prop)
         return E_POINTER;
 
-    if(prop->cbSize != sizeof(*prop))
+    if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory,
+                prop->Options);
+    }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory);
+    }else{
+        WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
         return E_INVALIDARG;
+    }
 
-    TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-            prop->bIsOffload,
-            prop->eCategory,
-            prop->Options);
 
-    if(prop->bIsOffload)
+    if(legacy_prop->bIsOffload)
         return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
 
     return S_OK;
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
index cef8a2d4d5b..417067f0bf8 100644
--- a/dlls/winepulse.drv/mmdevdrv.c
+++ b/dlls/winepulse.drv/mmdevdrv.c
@@ -2248,21 +2248,29 @@ static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
         const AudioClientProperties *prop)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
 
     TRACE("(%p)->(%p)\n", This, prop);
 
-    if(!prop)
+    if(!legacy_prop)
         return E_POINTER;
 
-    if(prop->cbSize != sizeof(*prop))
+    if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory,
+                prop->Options);
+    }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
+        TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
+                legacy_prop->bIsOffload,
+                legacy_prop->eCategory);
+    }else{
+        WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
         return E_INVALIDARG;
+    }
 
-    TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-            prop->bIsOffload,
-            prop->eCategory,
-            prop->Options);
 
-    if(prop->bIsOffload)
+    if(legacy_prop->bIsOffload)
         return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
 
     return S_OK;
diff --git a/include/audioclient.idl b/include/audioclient.idl
index 132e78a602b..cd13be5d575 100644
--- a/include/audioclient.idl
+++ b/include/audioclient.idl
@@ -126,6 +126,14 @@ typedef struct _AudioClientProperties
     AUDCLNT_STREAMOPTIONS Options;
 } AudioClientProperties;
 
+typedef struct _Win8AudioClientProperties
+{
+    UINT32 cbSize;
+    BOOL bIsOffload;
+    AUDIO_STREAM_CATEGORY eCategory;
+    /* Options field added in Win 8.1 */
+} Win8AudioClientProperties;
+
 [
     local,
     pointer_default(unique),
-- 
2.29.2




More information about the wine-devel mailing list