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@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),
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=82261
Your paranoid android.
=== w8adm (32 bit report) ===
mmdevapi: render.c:1106: Test failed: Position 6656 too far after playing 100ms
=== w864 (32 bit report) ===
mmdevapi: render.c:1332: Test failed: GetBuffer large (20671) at iteration 1 render.c:1332: Test failed: GetBuffer large (20671) at iteration 2 render.c:1332: Test failed: GetBuffer large (20671) at iteration 4 render.c:1332: Test failed: GetBuffer large (20671) at iteration 6
=== w1064v1507 (32 bit report) ===
mmdevapi: render.c:1332: Test failed: GetBuffer large (20671) at iteration 3 render.c:1106: Test failed: Position 6875 too far after playing 100ms
=== w1064 (32 bit report) ===
mmdevapi: render.c:1106: Test failed: Position 58888 too far after playing 100ms
=== w864 (64 bit report) ===
mmdevapi: render.c:1332: Test failed: GetBuffer large (20671) at iteration 2
=== w1064v1507 (64 bit report) ===
mmdevapi: render.c:1106: Test failed: Position 52344 too far after playing 100ms render.c:1332: Test failed: GetBuffer large (20671) at iteration 8 render.c:1106: Test failed: Position 6606 too far after playing 100ms
=== w1064v1809 (64 bit report) ===
mmdevapi: render.c:1106: Test failed: Position 53632 too far after playing 100ms
=== w1064 (64 bit report) ===
mmdevapi: render.c:1106: Test failed: Position 57040 too far after playing 100ms render.c:1106: Test failed: Position 6815 too far after playing 100ms
=== w1064_2qxl (64 bit report) ===
mmdevapi: render.c:1106: Test failed: Position 59152 too far after playing 100ms
=== w10pro64_ar (64 bit report) ===
mmdevapi: render.c:1372: Test failed: GetCurrentPadding returned 480, should be 0 render.c:1373: Test failed: Position 414720 at end vs. 52320 submitted frames
=== w10pro64_he (64 bit report) ===
mmdevapi: render.c:1372: Test failed: GetCurrentPadding returned 480, should be 0 render.c:1373: Test failed: Position 433920 at end vs. 54720 submitted frames
=== w10pro64_ja (64 bit report) ===
mmdevapi: render.c:1332: Test failed: GetBuffer large (22500) at iteration 4 render.c:1373: Test failed: Position 664320 at end vs. 85920 submitted frames render.c:1332: Test failed: GetBuffer large (22500) at iteration 8
=== w10pro64_zh_CN (64 bit report) ===
mmdevapi: render.c:1332: Test failed: GetBuffer large (22500) at iteration 8 render.c:1372: Test failed: GetCurrentPadding returned 3300, should be 0 render.c:1373: Test failed: Position 744960 at end vs. 96420 submitted frames