netapi32: Convert the Unix library to the __wine_unix_call interface.
[wine.git] / dlls / windows.media.devices / main.c
blobc4b5b6478777d274bb8d5f73448dec226131402c
1 /*
2 * Copyright 2021 Andrew Eikum for CodeWeavers
3 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
22 #define COBJMACROS
23 #include "initguid.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winstring.h"
27 #include "wine/debug.h"
28 #include "wine/heap.h"
29 #include "objbase.h"
31 #include "activation.h"
32 #include "mmdeviceapi.h"
34 #define WIDL_using_Windows_Foundation
35 #define WIDL_using_Windows_Foundation_Collections
36 #include "windows.foundation.h"
37 #define WIDL_using_Windows_Media_Devices
38 #include "windows.media.devices.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
42 static const char *debugstr_hstring(HSTRING hstr)
44 const WCHAR *str;
45 UINT32 len;
46 if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)";
47 str = WindowsGetStringRawBuffer(hstr, &len);
48 return wine_dbgstr_wn(str, len);
51 static ERole AudioDeviceRole_to_ERole(AudioDeviceRole role)
53 switch(role){
54 case AudioDeviceRole_Communications:
55 return eCommunications;
56 default:
57 return eMultimedia;
61 struct windows_media_devices
63 IActivationFactory IActivationFactory_iface;
64 IMediaDeviceStatics IMediaDeviceStatics_iface;
65 LONG ref;
68 static inline struct windows_media_devices *impl_from_IActivationFactory(IActivationFactory *iface)
70 return CONTAINING_RECORD(iface, struct windows_media_devices, IActivationFactory_iface);
73 static inline struct windows_media_devices *impl_from_IMediaDeviceStatics(IMediaDeviceStatics *iface)
75 return CONTAINING_RECORD(iface, struct windows_media_devices, IMediaDeviceStatics_iface);
78 static HRESULT STDMETHODCALLTYPE windows_media_devices_QueryInterface(
79 IActivationFactory *iface, REFIID iid, void **out)
81 struct windows_media_devices *impl = impl_from_IActivationFactory(iface);
83 TRACE("iface %p, iid %s, out %p\n", iface, debugstr_guid(iid), out);
85 if (IsEqualGUID(iid, &IID_IUnknown) ||
86 IsEqualGUID(iid, &IID_IInspectable) ||
87 IsEqualGUID(iid, &IID_IAgileObject) ||
88 IsEqualGUID(iid, &IID_IActivationFactory))
90 IUnknown_AddRef(iface);
91 *out = iface;
92 return S_OK;
95 if (IsEqualGUID(iid, &IID_IMediaDeviceStatics))
97 IUnknown_AddRef(iface);
98 *out = &impl->IMediaDeviceStatics_iface;
99 return S_OK;
102 FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
103 *out = NULL;
104 return E_NOINTERFACE;
107 static ULONG STDMETHODCALLTYPE windows_media_devices_AddRef(
108 IActivationFactory *iface)
110 struct windows_media_devices *impl = impl_from_IActivationFactory(iface);
111 ULONG ref = InterlockedIncrement(&impl->ref);
112 TRACE("iface %p, ref %u.\n", iface, ref);
113 return ref;
116 static ULONG STDMETHODCALLTYPE windows_media_devices_Release(
117 IActivationFactory *iface)
119 struct windows_media_devices *impl = impl_from_IActivationFactory(iface);
120 ULONG ref = InterlockedDecrement(&impl->ref);
121 TRACE("iface %p, ref %u.\n", iface, ref);
122 return ref;
125 static HRESULT STDMETHODCALLTYPE windows_media_devices_GetIids(
126 IActivationFactory *iface, ULONG *iid_count, IID **iids)
128 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids);
129 return E_NOTIMPL;
132 static HRESULT STDMETHODCALLTYPE windows_media_devices_GetRuntimeClassName(
133 IActivationFactory *iface, HSTRING *class_name)
135 FIXME("iface %p, class_name %p stub!\n", iface, class_name);
136 return E_NOTIMPL;
139 static HRESULT STDMETHODCALLTYPE windows_media_devices_GetTrustLevel(
140 IActivationFactory *iface, TrustLevel *trust_level)
142 FIXME("iface %p, trust_level %p stub!\n", iface, trust_level);
143 return E_NOTIMPL;
146 static HRESULT STDMETHODCALLTYPE windows_media_devices_ActivateInstance(
147 IActivationFactory *iface, IInspectable **instance)
149 FIXME("iface %p, instance %p stub!\n", iface, instance);
150 return E_NOTIMPL;
153 static const struct IActivationFactoryVtbl activation_factory_vtbl =
155 windows_media_devices_QueryInterface,
156 windows_media_devices_AddRef,
157 windows_media_devices_Release,
158 /* IInspectable methods */
159 windows_media_devices_GetIids,
160 windows_media_devices_GetRuntimeClassName,
161 windows_media_devices_GetTrustLevel,
162 /* IActivationFactory methods */
163 windows_media_devices_ActivateInstance,
166 static HRESULT get_default_device_id(EDataFlow direction, AudioDeviceRole role, HSTRING *device_id_hstr)
168 HRESULT hr;
169 WCHAR *devid, *s;
170 IMMDevice *dev;
171 IMMDeviceEnumerator *devenum;
172 ERole mmdev_role = AudioDeviceRole_to_ERole(role);
174 static const WCHAR id_fmt_pre[] = L"\\\\?\\SWD#MMDEVAPI#";
175 static const WCHAR id_fmt_hash[] = L"#";
176 static const size_t GUID_STR_LEN = 38; /* == strlen("{00000000-0000-0000-0000-000000000000}") */
178 *device_id_hstr = NULL;
180 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
181 CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum);
182 if (FAILED(hr))
184 WARN("Failed to create MMDeviceEnumerator: %08x\n", hr);
185 return hr;
188 hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, direction, mmdev_role, &dev);
189 if (FAILED(hr))
191 WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
192 IMMDeviceEnumerator_Release(devenum);
193 return hr;
196 hr = IMMDevice_GetId(dev, &devid);
197 if (FAILED(hr))
199 WARN("GetId failed: %08x\n", hr);
200 IMMDevice_Release(dev);
201 IMMDeviceEnumerator_Release(devenum);
202 return hr;
205 s = heap_alloc((sizeof(id_fmt_pre) - sizeof(WCHAR)) +
206 (sizeof(id_fmt_hash) - sizeof(WCHAR)) +
207 (wcslen(devid) + GUID_STR_LEN + 1 /* nul */) * sizeof(WCHAR));
209 wcscpy(s, id_fmt_pre);
210 wcscat(s, devid);
211 wcscat(s, id_fmt_hash);
213 if(direction == eRender)
214 StringFromGUID2(&DEVINTERFACE_AUDIO_RENDER, s + wcslen(s), GUID_STR_LEN + 1);
215 else
216 StringFromGUID2(&DEVINTERFACE_AUDIO_CAPTURE, s + wcslen(s), GUID_STR_LEN + 1);
218 hr = WindowsCreateString(s, wcslen(s), device_id_hstr);
219 if (FAILED(hr))
220 WARN("WindowsCreateString failed: %08x\n", hr);
222 heap_free(s);
224 CoTaskMemFree(devid);
225 IMMDevice_Release(dev);
226 IMMDeviceEnumerator_Release(devenum);
228 return hr;
231 static HRESULT WINAPI media_device_statics_QueryInterface(IMediaDeviceStatics *iface,
232 REFIID riid, void **ppvObject)
234 struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
235 return windows_media_devices_QueryInterface(&This->IActivationFactory_iface, riid, ppvObject);
238 static ULONG WINAPI media_device_statics_AddRef(IMediaDeviceStatics *iface)
240 struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
241 return windows_media_devices_AddRef(&This->IActivationFactory_iface);
244 static ULONG WINAPI media_device_statics_Release(IMediaDeviceStatics *iface)
246 struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
247 return windows_media_devices_Release(&This->IActivationFactory_iface);
250 static HRESULT WINAPI media_device_statics_GetIids(IMediaDeviceStatics *iface,
251 ULONG *iidCount, IID **iids)
253 struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
254 return windows_media_devices_GetIids(&This->IActivationFactory_iface, iidCount, iids);
257 static HRESULT WINAPI media_device_statics_GetRuntimeClassName(IMediaDeviceStatics *iface,
258 HSTRING *className)
260 struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
261 return windows_media_devices_GetRuntimeClassName(&This->IActivationFactory_iface, className);
264 static HRESULT WINAPI media_device_statics_GetTrustLevel(IMediaDeviceStatics *iface,
265 TrustLevel *trustLevel)
267 struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
268 return windows_media_devices_GetTrustLevel(&This->IActivationFactory_iface, trustLevel);
271 static HRESULT WINAPI media_device_statics_GetAudioCaptureSelector(IMediaDeviceStatics *iface,
272 HSTRING *value)
274 FIXME("iface %p, value %p stub!\n", iface, value);
275 return E_NOTIMPL;
278 static HRESULT WINAPI media_device_statics_GetAudioRenderSelector(IMediaDeviceStatics *iface,
279 HSTRING *value)
281 FIXME("iface %p, value %p stub!\n", iface, value);
282 return E_NOTIMPL;
285 static HRESULT WINAPI media_device_statics_GetVideoCaptureSelector(IMediaDeviceStatics *iface,
286 HSTRING *value)
288 FIXME("iface %p, value %p stub!\n", iface, value);
289 return E_NOTIMPL;
292 static HRESULT WINAPI media_device_statics_GetDefaultAudioCaptureId(IMediaDeviceStatics *iface,
293 AudioDeviceRole role, HSTRING *value)
295 TRACE("iface %p, role 0x%x, value %p\n", iface, role, value);
296 return get_default_device_id(eCapture, role, value);
299 static HRESULT WINAPI media_device_statics_GetDefaultAudioRenderId(IMediaDeviceStatics *iface,
300 AudioDeviceRole role, HSTRING *value)
302 TRACE("iface %p, role 0x%x, value %p\n", iface, role, value);
303 return get_default_device_id(eRender, role, value);
306 static HRESULT WINAPI media_device_statics_add_DefaultAudioCaptureDeviceChanged(
307 IMediaDeviceStatics *iface,
308 ITypedEventHandler_IInspectable_DefaultAudioCaptureDeviceChangedEventArgs *handler,
309 EventRegistrationToken *token)
311 FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
312 if(!token)
313 return E_POINTER;
314 token->value = 1;
315 return S_OK;
318 static HRESULT WINAPI media_device_statics_remove_DefaultAudioCaptureDeviceChanged(
319 IMediaDeviceStatics *iface,
320 EventRegistrationToken token)
322 FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
323 return S_OK;
326 static HRESULT WINAPI media_device_statics_add_DefaultAudioRenderDeviceChanged(
327 IMediaDeviceStatics *iface,
328 ITypedEventHandler_IInspectable_DefaultAudioRenderDeviceChangedEventArgs *handler,
329 EventRegistrationToken *token)
331 FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
332 if(!token)
333 return E_POINTER;
334 token->value = 1;
335 return S_OK;
338 static HRESULT WINAPI media_device_statics_remove_DefaultAudioRenderDeviceChanged(
339 IMediaDeviceStatics *iface,
340 EventRegistrationToken token)
342 FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
343 return S_OK;
346 static IMediaDeviceStaticsVtbl media_device_statics_vtbl = {
347 media_device_statics_QueryInterface,
348 media_device_statics_AddRef,
349 media_device_statics_Release,
350 media_device_statics_GetIids,
351 media_device_statics_GetRuntimeClassName,
352 media_device_statics_GetTrustLevel,
353 media_device_statics_GetAudioCaptureSelector,
354 media_device_statics_GetAudioRenderSelector,
355 media_device_statics_GetVideoCaptureSelector,
356 media_device_statics_GetDefaultAudioCaptureId,
357 media_device_statics_GetDefaultAudioRenderId,
358 media_device_statics_add_DefaultAudioCaptureDeviceChanged,
359 media_device_statics_remove_DefaultAudioCaptureDeviceChanged,
360 media_device_statics_add_DefaultAudioRenderDeviceChanged,
361 media_device_statics_remove_DefaultAudioRenderDeviceChanged,
364 static struct windows_media_devices windows_media_devices =
366 {&activation_factory_vtbl},
367 {&media_device_statics_vtbl},
371 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out)
373 FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out);
374 return CLASS_E_CLASSNOTAVAILABLE;
377 HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory)
379 TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory);
380 *factory = &windows_media_devices.IActivationFactory_iface;
381 IUnknown_AddRef(*factory);
382 return S_OK;