2 * Copyright 2009 Maarten Lankhorst
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
30 #include "mmdeviceapi.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
36 typedef struct MMDevEnumImpl
38 const IMMDeviceEnumeratorVtbl *lpVtbl;
42 static MMDevEnumImpl *MMDevEnumerator;
43 static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl;
45 typedef struct MMDevColImpl
47 const IMMDeviceCollectionVtbl *lpVtbl;
49 MMDevEnumImpl *parent;
53 static const IMMDeviceCollectionVtbl MMDevColVtbl;
55 static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, MMDevEnumImpl *parent, EDataFlow flow, DWORD state)
58 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
62 This->lpVtbl = &MMDevColVtbl;
64 This->parent = parent;
67 *ppv = (IMMDeviceCollection*)This;
71 static void MMDevCol_Destroy(MMDevColImpl *This)
73 HeapFree(GetProcessHeap(), 0, This);
76 static HRESULT WINAPI MMDevCol_QueryInterface(IMMDeviceCollection *iface, REFIID riid, void **ppv)
78 MMDevColImpl *This = (MMDevColImpl*)iface;
82 if (IsEqualIID(riid, &IID_IUnknown)
83 || IsEqualIID(riid, &IID_IMMDeviceCollection))
89 IUnknown_AddRef((IUnknown*)*ppv);
93 static ULONG WINAPI MMDevCol_AddRef(IMMDeviceCollection *iface)
95 MMDevColImpl *This = (MMDevColImpl*)iface;
96 LONG ref = InterlockedIncrement(&This->ref);
97 TRACE("Refcount now %i\n", ref);
101 static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface)
103 MMDevColImpl *This = (MMDevColImpl*)iface;
104 LONG ref = InterlockedDecrement(&This->ref);
105 TRACE("Refcount now %i\n", ref);
107 MMDevCol_Destroy(This);
111 static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs)
113 MMDevColImpl *This = (MMDevColImpl*)iface;
114 TRACE("(%p)->(%p)\n", This, numdevs);
121 static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT i, IMMDevice **dev)
123 MMDevColImpl *This = (MMDevColImpl*)iface;
124 TRACE("(%p)->(%u, %p)\n", This, i, dev);
131 static const IMMDeviceCollectionVtbl MMDevColVtbl =
133 MMDevCol_QueryInterface,
140 HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
142 MMDevEnumImpl *This = MMDevEnumerator;
146 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
149 return E_OUTOFMEMORY;
151 This->lpVtbl = &MMDevEnumVtbl;
152 MMDevEnumerator = This;
154 return IUnknown_QueryInterface((IUnknown*)This, riid, ppv);
157 void MMDevEnum_Free(void)
159 HeapFree(GetProcessHeap(), 0, MMDevEnumerator);
160 MMDevEnumerator = NULL;
163 static HRESULT WINAPI MMDevEnum_QueryInterface(IMMDeviceEnumerator *iface, REFIID riid, void **ppv)
165 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
169 if (IsEqualIID(riid, &IID_IUnknown)
170 || IsEqualIID(riid, &IID_IMMDeviceEnumerator))
175 return E_NOINTERFACE;
176 IUnknown_AddRef((IUnknown*)*ppv);
180 static ULONG WINAPI MMDevEnum_AddRef(IMMDeviceEnumerator *iface)
182 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
183 LONG ref = InterlockedIncrement(&This->ref);
184 TRACE("Refcount now %i\n", ref);
188 static ULONG WINAPI MMDevEnum_Release(IMMDeviceEnumerator *iface)
190 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
191 LONG ref = InterlockedDecrement(&This->ref);
194 TRACE("Refcount now %i\n", ref);
198 static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, EDataFlow flow, DWORD mask, IMMDeviceCollection **devices)
200 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
201 TRACE("(%p)->(%u,%u,%p)\n", This, flow, mask, devices);
205 if (flow >= EDataFlow_enum_count)
207 if (mask & ~DEVICE_STATEMASK_ALL)
209 return MMDevCol_Create(devices, This, flow, mask);
212 static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)
214 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
215 TRACE("(%p)->(%u,%u,%p)\n", This, flow, role, device);
220 static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device)
222 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
223 TRACE("(%p)->(%s,%p)\n", This, debugstr_w(name), device);
228 static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
230 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
231 TRACE("(%p)->(%p)\n", This, client);
236 static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
238 MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
239 TRACE("(%p)->(%p)\n", This, client);
244 static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl =
246 MMDevEnum_QueryInterface,
249 MMDevEnum_EnumAudioEndpoints,
250 MMDevEnum_GetDefaultAudioEndpoint,
252 MMDevEnum_RegisterEndpointNotificationCallback,
253 MMDevEnum_UnregisterEndpointNotificationCallback