Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56763
-- v3: mmdevapi: Implement IAudioSessionControl2 GetGroupingParam SetGroupingParam mmdevapi: Implement IAudioSessionControl2 GetIconPath / SetIconPath mmdevapi: Implement IAudioSessionControl2 GetDisplayName / SetDisplayName
From: Fabian Maurer dark.shadow4@web.de
--- dlls/mmdevapi/tests/render.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index a7da68ec3f1..4ec2b5e3f04 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -1453,6 +1453,7 @@ static void test_session(void) WAVEFORMATEX *pwfx; ULONG ref; HRESULT hr; + WCHAR *str;
hr = CoCreateGuid(&ses1_guid); ok(hr == S_OK, "CoCreateGuid failed: %08lx\n", hr); @@ -1575,6 +1576,40 @@ static void test_session(void) ok(hr == S_OK, "GetState failed: %08lx\n", hr); ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
+ /* Test GetDisplayName / SetDisplayName */ + + hr = IAudioSessionControl2_GetDisplayName(ses1_ctl2, NULL); + todo_wine + ok(hr == E_POINTER, "GetDisplayName failed: %08lx\n", hr); + + str = NULL; + hr = IAudioSessionControl2_GetDisplayName(ses1_ctl2, &str); + todo_wine + ok(hr == S_OK, "GetDisplayName failed: %08lx\n", hr); + todo_wine + ok(str && !wcscmp(str, L""), "Got %s\n", wine_dbgstr_w(str)); + if (str) + CoTaskMemFree(str); + + hr = IAudioSessionControl2_SetDisplayName(ses1_ctl2, NULL, NULL); + todo_wine + ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "SetDisplayName failed: %08lx\n", hr); + + hr = IAudioSessionControl2_SetDisplayName(ses1_ctl2, L"WineDisplayName", NULL); + todo_wine + ok(hr == S_OK, "SetDisplayName failed: %08lx\n", hr); + + str = NULL; + hr = IAudioSessionControl2_GetDisplayName(ses1_ctl2, &str); + todo_wine + ok(hr == S_OK, "GetDisplayName failed: %08lx\n", hr); + todo_wine + ok(str && !wcscmp(str, L"WineDisplayName"), "Got %s\n", wine_dbgstr_w(str)); + if (str) + CoTaskMemFree(str); + + /* Test capture */ + if(cap_ctl){ hr = IAudioSessionControl2_GetState(cap_ctl, &state); ok(hr == S_OK, "GetState failed: %08lx\n", hr);
From: Fabian Maurer dark.shadow4@web.de
--- dlls/mmdevapi/tests/render.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 4ec2b5e3f04..77028e9ef77 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -1608,6 +1608,38 @@ static void test_session(void) if (str) CoTaskMemFree(str);
+ /* Test GetIconPath / SetIconPath */ + + hr = IAudioSessionControl2_GetIconPath(ses1_ctl2, NULL); + todo_wine + ok(hr == E_POINTER, "GetIconPath failed: %08lx\n", hr); + + str = NULL; + hr = IAudioSessionControl2_GetIconPath(ses1_ctl2, &str); + todo_wine + ok(hr == S_OK, "GetIconPath failed: %08lx\n", hr); + todo_wine + ok(str && !wcscmp(str, L""), "Got %s\n", wine_dbgstr_w(str)); + if(str) + CoTaskMemFree(str); + + hr = IAudioSessionControl2_SetIconPath(ses1_ctl2, NULL, NULL); + todo_wine + ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "SetIconPath failed: %08lx\n", hr); + + hr = IAudioSessionControl2_SetIconPath(ses1_ctl2, L"WineIconPath", NULL); + todo_wine + ok(hr == S_OK, "SetIconPath failed: %08lx\n", hr); + + str = NULL; + hr = IAudioSessionControl2_GetIconPath(ses1_ctl2, &str); + todo_wine + ok(hr == S_OK, "GetIconPath failed: %08lx\n", hr); + todo_wine + ok(str && !wcscmp(str, L"WineIconPath"), "Got %s\n", wine_dbgstr_w(str)); + if (str) + CoTaskMemFree(str); + /* Test capture */
if(cap_ctl){
From: Fabian Maurer dark.shadow4@web.de
--- dlls/mmdevapi/tests/render.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 77028e9ef77..23ff0892dfe 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -1454,6 +1454,7 @@ static void test_session(void) ULONG ref; HRESULT hr; WCHAR *str; + GUID guid1 = GUID_NULL, guid2 = GUID_NULL;
hr = CoCreateGuid(&ses1_guid); ok(hr == S_OK, "CoCreateGuid failed: %08lx\n", hr); @@ -1640,6 +1641,35 @@ static void test_session(void) if (str) CoTaskMemFree(str);
+ /* Test GetGroupingParam / SetGroupingParam */ + + hr = IAudioSessionControl2_GetGroupingParam(ses1_ctl2, NULL); + todo_wine + ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "GetGroupingParam failed: %08lx\n", hr); + + hr = IAudioSessionControl2_GetGroupingParam(ses1_ctl2, &guid1); + todo_wine + ok(hr == S_OK, "GetGroupingParam failed: %08lx\n", hr); + todo_wine + ok(!IsEqualGUID(&guid1, &guid2), "Expected non null GUID\n"); /* MSDN is wrong here, it is not GUID_NULL */ + + hr = IAudioSessionControl2_SetGroupingParam(ses1_ctl2, NULL, NULL); + todo_wine + ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "SetGroupingParam failed: %08lx\n", hr); + + hr = CoCreateGuid(&guid2); + ok(hr == S_OK, "CoCreateGuid failed: %08lx\n", hr); + + hr = IAudioSessionControl2_SetGroupingParam(ses1_ctl2, &guid2, NULL); + todo_wine + ok(hr == S_OK, "SetGroupingParam failed: %08lx\n", hr); + + hr = IAudioSessionControl2_GetGroupingParam(ses1_ctl2, &guid1); + todo_wine + ok(hr == S_OK, "GetGroupingParam failed: %08lx\n", hr); + todo_wine + ok(IsEqualGUID(&guid1, &guid2), "Got %s\n", wine_dbgstr_guid(&guid1)); + /* Test capture */
if(cap_ctl){
From: Fabian Maurer dark.shadow4@web.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56763 --- dlls/mmdevapi/mmdevdrv.h | 2 ++ dlls/mmdevapi/session.c | 37 +++++++++++++++++++++++++++++++----- dlls/mmdevapi/tests/render.c | 7 ------- 3 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/dlls/mmdevapi/mmdevdrv.h b/dlls/mmdevapi/mmdevdrv.h index 1f4d65e4436..115c5e32fcc 100644 --- a/dlls/mmdevapi/mmdevdrv.h +++ b/dlls/mmdevapi/mmdevdrv.h @@ -30,6 +30,8 @@ typedef struct audio_session { float *channel_vols; BOOL mute;
+ WCHAR *display_name; + struct list entry; } AudioSession;
diff --git a/dlls/mmdevapi/session.c b/dlls/mmdevapi/session.c index 9a36adb5bf2..6f45ab120c0 100644 --- a/dlls/mmdevapi/session.c +++ b/dlls/mmdevapi/session.c @@ -37,6 +37,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); extern void sessions_lock(void); extern void sessions_unlock(void);
+static WCHAR *duplicate_wstr(const WCHAR *str) +{ + const WCHAR *source = str ? str : L""; + int len = (wcslen(source) + 1) * sizeof(WCHAR); + WCHAR *ret = CoTaskMemAlloc(len); + memcpy(ret, source, len); + return ret; +} + extern void set_stream_volumes(struct audio_client *This);
static struct list sessions = LIST_INIT(sessions); @@ -144,16 +153,34 @@ static HRESULT WINAPI control_GetState(IAudioSessionControl2 *iface, AudioSessio static HRESULT WINAPI control_GetDisplayName(IAudioSessionControl2 *iface, WCHAR **name) { struct audio_session_wrapper *This = impl_from_IAudioSessionControl2(iface); - FIXME("(%p)->(%p) - stub\n", This, name); - return E_NOTIMPL; + struct audio_session *session = This->session; + + TRACE("(%p)->(%p) - stub\n", This, name); + + if (!name) + return E_POINTER; + + *name = duplicate_wstr(session->display_name); + + return S_OK; }
static HRESULT WINAPI control_SetDisplayName(IAudioSessionControl2 *iface, const WCHAR *name, - const GUID *session) + const GUID *event_context) { struct audio_session_wrapper *This = impl_from_IAudioSessionControl2(iface); - FIXME("(%p)->(%p, %s) - stub\n", This, name, debugstr_guid(session)); - return E_NOTIMPL; + struct audio_session *session = This->session; + + TRACE("(%p)->(%p, %s) - stub\n", This, name, debugstr_guid(event_context)); + FIXME("Ignoring session_guid\n"); + + if (!name) + return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER); + + CoTaskMemFree(session->display_name); + session->display_name = duplicate_wstr(name); + + return S_OK; }
static HRESULT WINAPI control_GetIconPath(IAudioSessionControl2 *iface, WCHAR **path) diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 23ff0892dfe..6d76bff8b22 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -1580,31 +1580,24 @@ static void test_session(void) /* Test GetDisplayName / SetDisplayName */
hr = IAudioSessionControl2_GetDisplayName(ses1_ctl2, NULL); - todo_wine ok(hr == E_POINTER, "GetDisplayName failed: %08lx\n", hr);
str = NULL; hr = IAudioSessionControl2_GetDisplayName(ses1_ctl2, &str); - todo_wine ok(hr == S_OK, "GetDisplayName failed: %08lx\n", hr); - todo_wine ok(str && !wcscmp(str, L""), "Got %s\n", wine_dbgstr_w(str)); if (str) CoTaskMemFree(str);
hr = IAudioSessionControl2_SetDisplayName(ses1_ctl2, NULL, NULL); - todo_wine ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "SetDisplayName failed: %08lx\n", hr);
hr = IAudioSessionControl2_SetDisplayName(ses1_ctl2, L"WineDisplayName", NULL); - todo_wine ok(hr == S_OK, "SetDisplayName failed: %08lx\n", hr);
str = NULL; hr = IAudioSessionControl2_GetDisplayName(ses1_ctl2, &str); - todo_wine ok(hr == S_OK, "GetDisplayName failed: %08lx\n", hr); - todo_wine ok(str && !wcscmp(str, L"WineDisplayName"), "Got %s\n", wine_dbgstr_w(str)); if (str) CoTaskMemFree(str);
From: Fabian Maurer dark.shadow4@web.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56763 --- dlls/mmdevapi/mmdevdrv.h | 1 + dlls/mmdevapi/session.c | 28 +++++++++++++++++++++++----- dlls/mmdevapi/tests/render.c | 7 ------- 3 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/dlls/mmdevapi/mmdevdrv.h b/dlls/mmdevapi/mmdevdrv.h index 115c5e32fcc..d4060fa304f 100644 --- a/dlls/mmdevapi/mmdevdrv.h +++ b/dlls/mmdevapi/mmdevdrv.h @@ -31,6 +31,7 @@ typedef struct audio_session { BOOL mute;
WCHAR *display_name; + WCHAR *icon_path;
struct list entry; } AudioSession; diff --git a/dlls/mmdevapi/session.c b/dlls/mmdevapi/session.c index 6f45ab120c0..89d2544c293 100644 --- a/dlls/mmdevapi/session.c +++ b/dlls/mmdevapi/session.c @@ -186,16 +186,34 @@ static HRESULT WINAPI control_SetDisplayName(IAudioSessionControl2 *iface, const static HRESULT WINAPI control_GetIconPath(IAudioSessionControl2 *iface, WCHAR **path) { struct audio_session_wrapper *This = impl_from_IAudioSessionControl2(iface); - FIXME("(%p)->(%p) - stub\n", This, path); - return E_NOTIMPL; + struct audio_session *session = This->session; + + TRACE("(%p)->(%p) - stub\n", This, path); + + if (!path) + return E_POINTER; + + *path = duplicate_wstr(session->icon_path); + + return S_OK; }
static HRESULT WINAPI control_SetIconPath(IAudioSessionControl2 *iface, const WCHAR *path, - const GUID *session) + const GUID *event_context) { struct audio_session_wrapper *This = impl_from_IAudioSessionControl2(iface); - FIXME("(%p)->(%s, %s) - stub\n", This, debugstr_w(path), debugstr_guid(session)); - return E_NOTIMPL; + struct audio_session *session = This->session; + + TRACE("(%p)->(%s, %s) - stub\n", This, debugstr_w(path), debugstr_guid(event_context)); + FIXME("Ignoring session_guid\n"); + + if (!path) + return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER); + + CoTaskMemFree(session->icon_path); + session->icon_path = duplicate_wstr(path); + + return S_OK; }
static HRESULT WINAPI control_GetGroupingParam(IAudioSessionControl2 *iface, GUID *group) diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 6d76bff8b22..64bb2799705 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -1605,31 +1605,24 @@ static void test_session(void) /* Test GetIconPath / SetIconPath */
hr = IAudioSessionControl2_GetIconPath(ses1_ctl2, NULL); - todo_wine ok(hr == E_POINTER, "GetIconPath failed: %08lx\n", hr);
str = NULL; hr = IAudioSessionControl2_GetIconPath(ses1_ctl2, &str); - todo_wine ok(hr == S_OK, "GetIconPath failed: %08lx\n", hr); - todo_wine ok(str && !wcscmp(str, L""), "Got %s\n", wine_dbgstr_w(str)); if(str) CoTaskMemFree(str);
hr = IAudioSessionControl2_SetIconPath(ses1_ctl2, NULL, NULL); - todo_wine ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "SetIconPath failed: %08lx\n", hr);
hr = IAudioSessionControl2_SetIconPath(ses1_ctl2, L"WineIconPath", NULL); - todo_wine ok(hr == S_OK, "SetIconPath failed: %08lx\n", hr);
str = NULL; hr = IAudioSessionControl2_GetIconPath(ses1_ctl2, &str); - todo_wine ok(hr == S_OK, "GetIconPath failed: %08lx\n", hr); - todo_wine ok(str && !wcscmp(str, L"WineIconPath"), "Got %s\n", wine_dbgstr_w(str)); if (str) CoTaskMemFree(str);
From: Fabian Maurer dark.shadow4@web.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56763 --- dlls/mmdevapi/mmdevdrv.h | 1 + dlls/mmdevapi/session.c | 29 ++++++++++++++++++++++++----- dlls/mmdevapi/tests/render.c | 7 ------- 3 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/dlls/mmdevapi/mmdevdrv.h b/dlls/mmdevapi/mmdevdrv.h index d4060fa304f..42b01443ff0 100644 --- a/dlls/mmdevapi/mmdevdrv.h +++ b/dlls/mmdevapi/mmdevdrv.h @@ -32,6 +32,7 @@ typedef struct audio_session {
WCHAR *display_name; WCHAR *icon_path; + GUID grouping_param;
struct list entry; } AudioSession; diff --git a/dlls/mmdevapi/session.c b/dlls/mmdevapi/session.c index 89d2544c293..899221ec04c 100644 --- a/dlls/mmdevapi/session.c +++ b/dlls/mmdevapi/session.c @@ -219,16 +219,33 @@ static HRESULT WINAPI control_SetIconPath(IAudioSessionControl2 *iface, const WC static HRESULT WINAPI control_GetGroupingParam(IAudioSessionControl2 *iface, GUID *group) { struct audio_session_wrapper *This = impl_from_IAudioSessionControl2(iface); - FIXME("(%p)->(%p) - stub\n", This, group); - return E_NOTIMPL; + struct audio_session *session = This->session; + + TRACE("(%p)->(%p) - stub\n", This, group); + + if (!group) + return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER); + + *group = session->grouping_param; + + return S_OK; }
static HRESULT WINAPI control_SetGroupingParam(IAudioSessionControl2 *iface, const GUID *group, - const GUID *session) + const GUID *event_context) { struct audio_session_wrapper *This = impl_from_IAudioSessionControl2(iface); - FIXME("(%p)->(%s, %s) - stub\n", This, debugstr_guid(group), debugstr_guid(session)); - return E_NOTIMPL; + struct audio_session *session = This->session; + + TRACE("(%p)->(%s, %s) - stub\n", This, debugstr_guid(group), debugstr_guid(event_context)); + FIXME("Ignoring session_guid\n"); + + if (!group) + return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER); + + session->grouping_param = *group; + + return S_OK; }
static HRESULT WINAPI control_RegisterAudioSessionNotification(IAudioSessionControl2 *iface, @@ -631,6 +648,8 @@ static struct audio_session *session_create(const GUID *guid, IMMDevice *device,
ret->master_vol = 1.f;
+ CoCreateGuid(&ret->grouping_param); + return ret; }
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 64bb2799705..b8ef4b5a549 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -1630,30 +1630,23 @@ static void test_session(void) /* Test GetGroupingParam / SetGroupingParam */
hr = IAudioSessionControl2_GetGroupingParam(ses1_ctl2, NULL); - todo_wine ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "GetGroupingParam failed: %08lx\n", hr);
hr = IAudioSessionControl2_GetGroupingParam(ses1_ctl2, &guid1); - todo_wine ok(hr == S_OK, "GetGroupingParam failed: %08lx\n", hr); - todo_wine ok(!IsEqualGUID(&guid1, &guid2), "Expected non null GUID\n"); /* MSDN is wrong here, it is not GUID_NULL */
hr = IAudioSessionControl2_SetGroupingParam(ses1_ctl2, NULL, NULL); - todo_wine ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "SetGroupingParam failed: %08lx\n", hr);
hr = CoCreateGuid(&guid2); ok(hr == S_OK, "CoCreateGuid failed: %08lx\n", hr);
hr = IAudioSessionControl2_SetGroupingParam(ses1_ctl2, &guid2, NULL); - todo_wine ok(hr == S_OK, "SetGroupingParam failed: %08lx\n", hr);
hr = IAudioSessionControl2_GetGroupingParam(ses1_ctl2, &guid1); - todo_wine ok(hr == S_OK, "GetGroupingParam failed: %08lx\n", hr); - todo_wine ok(IsEqualGUID(&guid1, &guid2), "Got %s\n", wine_dbgstr_guid(&guid1));
/* Test capture */
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146059
Your paranoid android.
=== w8adm (32 bit report) ===
mmdevapi: render.c:1376: Test failed: GetBuffer large (20671) at iteration 5
=== w1064v1507 (32 bit report) ===
mmdevapi: render.c:1376: Test failed: GetBuffer large (20671) at iteration 3 render.c:1376: Test failed: GetBuffer large (20671) at iteration 4
=== w1064v1507 (64 bit report) ===
mmdevapi: render.c:1376: Test failed: GetBuffer large (20671) at iteration 2 render.c:1376: Test failed: GetBuffer large (20671) at iteration 3 render.c:1376: Test failed: GetBuffer large (20671) at iteration 5
On Tue Jun 4 15:06:23 2024 +0000, Fabian Maurer wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/5773/diffs?diff_id=116520&start_sha=34d317b6034670a787d9006887b45bbb6817d32f#93e6661c548f95d6c2ae8340ba18809196820745_42_42)
Alright
On Tue Jun 4 15:06:22 2024 +0000, Fabian Maurer wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/5773/diffs?diff_id=116520&start_sha=34d317b6034670a787d9006887b45bbb6817d32f#93e6661c548f95d6c2ae8340ba18809196820745_40_40)
Sorry, forgot
On Tue Jun 4 14:47:33 2024 +0000, Fabian Maurer wrote:
Is wcsdup compatible with CoTaskMemFree? I thought that you have to need to use CoTaskMemAlloc when you later want CoTaskMemFree (like MSDN says).
No. We'd use `wcsdup()` / `free()` in the setter and only use `CoTaskMemAlloc()` when we actually need to return something. So that means not using `duplicate_wstr()` in the setters and instead calling `free()` and `wcsdup()` directly.
On Wed Jun 5 07:56:05 2024 +0000, Huw Davies wrote:
No. We'd use `wcsdup()` / `free()` in the setter and only use `CoTaskMemAlloc()` when we actually need to return something. So that means not using `duplicate_wstr()` in the setters and instead calling `free()` and `wcsdup()` directly.
For some modules we have helpers like "HRESULT return_string();" that will allocate properly, handle null/empty strings, and set return code correctly. Might not be worth it if you need to return such value only once, but still the shorter method body is, less branching it has, the better.