From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/Makefile.in | 1 + dlls/mmdevapi/audiosessionmanager.c | 186 ++++++++++++++++++++++++++++ dlls/mmdevapi/devenum.c | 2 +- dlls/mmdevapi/main.c | 1 - dlls/mmdevapi/mmdevapi_private.h | 3 +- 5 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 dlls/mmdevapi/audiosessionmanager.c
diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in index b60372b812b..85a52d87184 100644 --- a/dlls/mmdevapi/Makefile.in +++ b/dlls/mmdevapi/Makefile.in @@ -2,6 +2,7 @@ MODULE = mmdevapi.dll IMPORTS = uuid ole32 oleaut32 user32 advapi32
C_SRCS = \ + audiosessionmanager.c \ audiovolume.c \ devenum.c \ main.c \ diff --git a/dlls/mmdevapi/audiosessionmanager.c b/dlls/mmdevapi/audiosessionmanager.c new file mode 100644 index 00000000000..039b1c264df --- /dev/null +++ b/dlls/mmdevapi/audiosessionmanager.c @@ -0,0 +1,186 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include <audiopolicy.h> +#include <mmdeviceapi.h> + +#include <wine/debug.h> +#include <wine/list.h> + +#include "mmdevapi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); + +static struct list g_sessions = LIST_INIT(g_sessions); + +static inline struct session_mgr *impl_from_IAudioSessionManager2(IAudioSessionManager2 *iface) +{ + return CONTAINING_RECORD(iface, struct session_mgr, IAudioSessionManager2_iface); +} + +static HRESULT WINAPI ASM_QueryInterface(IAudioSessionManager2 *iface, REFIID riid, void **ppv) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); + + if (!ppv) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAudioSessionManager) || + IsEqualIID(riid, &IID_IAudioSessionManager2)) + *ppv = &This->IAudioSessionManager2_iface; + else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*ppv); + + return S_OK; +} + +static ULONG WINAPI ASM_AddRef(IAudioSessionManager2 *iface) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) new ref %lu\n", This, ref); + return ref; +} + +static ULONG WINAPI ASM_Release(IAudioSessionManager2 *iface) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p) new ref %lu\n", This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI ASM_GetAudioSessionControl(IAudioSessionManager2 *iface, + const GUID *guid, DWORD flags, + IAudioSessionControl **out) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + AudioSessionWrapper *wrapper; + HRESULT hr; + + TRACE("(%p)->(%s, %lx, %p)\n", This, debugstr_guid(guid), flags, out); + + hr = drvs.pGetAudioSessionWrapper(guid, This->device, &wrapper); + if (FAILED(hr)) + return hr; + + *out = (IAudioSessionControl*)&wrapper->IAudioSessionControl2_iface; + + return S_OK; +} + +static HRESULT WINAPI ASM_GetSimpleAudioVolume(IAudioSessionManager2 *iface, + const GUID *guid, DWORD flags, + ISimpleAudioVolume **out) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + AudioSessionWrapper *wrapper; + HRESULT hr; + + TRACE("(%p)->(%s, %lx, %p)\n", This, debugstr_guid(guid), flags, out); + + hr = drvs.pGetAudioSessionWrapper(guid, This->device, &wrapper); + if (FAILED(hr)) + return hr; + + *out = &wrapper->ISimpleAudioVolume_iface; + + return S_OK; +} + +static HRESULT WINAPI ASM_GetSessionEnumerator(IAudioSessionManager2 *iface, + IAudioSessionEnumerator **out) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + FIXME("(%p)->(%p) - stub\n", This, out); + return E_NOTIMPL; +} + +static HRESULT WINAPI ASM_RegisterSessionNotification(IAudioSessionManager2 *iface, + IAudioSessionNotification *notification) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + FIXME("(%p)->(%p) - stub\n", This, notification); + return E_NOTIMPL; +} + +static HRESULT WINAPI ASM_UnregisterSessionNotification(IAudioSessionManager2 *iface, + IAudioSessionNotification *notification) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + FIXME("(%p)->(%p) - stub\n", This, notification); + return E_NOTIMPL; +} + +static HRESULT WINAPI ASM_RegisterDuckNotification(IAudioSessionManager2 *iface, + const WCHAR *session_id, + IAudioVolumeDuckNotification *notification) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + FIXME("(%p)->(%s, %p) - stub\n", This, debugstr_w(session_id), notification); + return E_NOTIMPL; +} + +static HRESULT WINAPI ASM_UnregisterDuckNotification(IAudioSessionManager2 *iface, + IAudioVolumeDuckNotification *notification) +{ + struct session_mgr *This = impl_from_IAudioSessionManager2(iface); + FIXME("(%p)->(%p) - stub\n", This, notification); + return E_NOTIMPL; +} + +static const IAudioSessionManager2Vtbl AudioSessionManager2_Vtbl = +{ + ASM_QueryInterface, + ASM_AddRef, + ASM_Release, + ASM_GetAudioSessionControl, + ASM_GetSimpleAudioVolume, + ASM_GetSessionEnumerator, + ASM_RegisterSessionNotification, + ASM_UnregisterSessionNotification, + ASM_RegisterDuckNotification, + ASM_UnregisterDuckNotification +}; + +HRESULT AudioSessionManager_Create(IMMDevice *device, IAudioSessionManager2 **ppv) +{ + struct session_mgr *This; + + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->IAudioSessionManager2_iface.lpVtbl = &AudioSessionManager2_Vtbl; + This->device = device; + This->ref = 1; + + *ppv = &This->IAudioSessionManager2_iface; + + return S_OK; +} diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 47456e3215c..2b7833edd08 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -600,7 +600,7 @@ static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD cls else if (IsEqualIID(riid, &IID_IAudioSessionManager) || IsEqualIID(riid, &IID_IAudioSessionManager2)) { - hr = drvs.pGetAudioSessionManager(iface, (IAudioSessionManager2**)ppv); + hr = AudioSessionManager_Create(iface, (IAudioSessionManager2**)ppv); } else if (IsEqualIID(riid, &IID_IBaseFilter)) { diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index 80c5e60880c..d3d4ec6a905 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -100,7 +100,6 @@ static BOOL load_driver(const WCHAR *name, DriverFuncs *driver) if(!driver->p##n) { goto fail; } } while(0) LDFC(GetEndpointIDs); LDFC(GetAudioEndpoint); - LDFC(GetAudioSessionManager); LDFC(GetAudioSessionWrapper); #undef LDFC
diff --git a/dlls/mmdevapi/mmdevapi_private.h b/dlls/mmdevapi/mmdevapi_private.h index a61375869ee..684d303eefb 100644 --- a/dlls/mmdevapi/mmdevapi_private.h +++ b/dlls/mmdevapi/mmdevapi_private.h @@ -49,8 +49,6 @@ typedef struct _DriverFuncs { GUID **guids, UINT *num, UINT *default_index); HRESULT (WINAPI *pGetAudioEndpoint)(void *key, IMMDevice *dev, IAudioClient **out); - HRESULT (WINAPI *pGetAudioSessionManager)(IMMDevice *device, - IAudioSessionManager2 **out); HRESULT (WINAPI *pGetAudioSessionWrapper)(const GUID *guid, IMMDevice *device, struct audio_session_wrapper **out); HRESULT (WINAPI *pGetPropValue)(GUID *guid, @@ -76,6 +74,7 @@ typedef struct MMDevice {
extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC_HIDDEN; extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv) DECLSPEC_HIDDEN; +extern HRESULT AudioSessionManager_Create(IMMDevice *device, IAudioSessionManager2 **ppv) DECLSPEC_HIDDEN; extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient **out) DECLSPEC_HIDDEN;
extern HRESULT load_devices_from_reg(void) DECLSPEC_HIDDEN;