From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/Makefile.in | 1 + dlls/mmdevapi/audiosessionmanager.c | 186 ++++++++++++++++++++++++++++ dlls/mmdevapi/mmdevapi.h | 1 + 3 files changed, 188 insertions(+) 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..30af9711808 --- /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 "mmdevapi.h" + +#include <audiopolicy.h> +#include <mmdeviceapi.h> + +#include <wine/debug.h> +#include <wine/list.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/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index 7bf259ef61d..dd6b2a817d1 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -77,6 +77,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;