msi: Directly pass the disk id to installfiles_cb.
[wine/hacks.git] / dlls / mmdevapi / main.c
blob18d8f80fd90754f0c87868edadedf510ba2ebc9a
1 /*
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
19 #include "config.h"
20 #include "wine/port.h"
22 #include <stdarg.h>
24 #ifdef HAVE_AL_AL_H
25 #include <AL/al.h>
26 #include <AL/alc.h>
27 #elif defined(HAVE_OPENAL_AL_H)
28 #include <OpenAL/al.h>
29 #include <OpenAL/alc.h>
30 #endif
32 #define CINTERFACE
33 #define COBJMACROS
34 #include "windef.h"
35 #include "winbase.h"
36 #include "wingdi.h"
37 #include "wine/library.h"
39 #include "ole2.h"
40 #include "olectl.h"
41 #include "initguid.h"
42 #include "mmdeviceapi.h"
43 #include "dshow.h"
44 #include "dsound.h"
45 #include "audioclient.h"
46 #include "endpointvolume.h"
47 #include "audiopolicy.h"
48 #include "devpkey.h"
50 #include "mmdevapi.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
55 #ifdef HAVE_OPENAL
57 int local_contexts;
59 static CRITICAL_SECTION_DEBUG openal_crst_debug =
61 0, 0, &openal_crst,
62 { &openal_crst_debug.ProcessLocksList,
63 &openal_crst_debug.ProcessLocksList },
64 0, 0, { (DWORD_PTR)(__FILE__ ": openal_crst_debug") }
66 CRITICAL_SECTION openal_crst = { &openal_crst_debug, -1, 0, 0, 0, 0 };
68 static void *openal_handle = RTLD_DEFAULT;
69 int openal_loaded;
70 #ifdef SONAME_LIBOPENAL
71 LPALCCREATECONTEXT palcCreateContext = NULL;
72 LPALCMAKECONTEXTCURRENT palcMakeContextCurrent = NULL;
73 LPALCPROCESSCONTEXT palcProcessContext = NULL;
74 LPALCSUSPENDCONTEXT palcSuspendContext = NULL;
75 LPALCDESTROYCONTEXT palcDestroyContext = NULL;
76 LPALCGETCURRENTCONTEXT palcGetCurrentContext = NULL;
77 LPALCGETCONTEXTSDEVICE palcGetContextsDevice = NULL;
78 LPALCOPENDEVICE palcOpenDevice = NULL;
79 LPALCCLOSEDEVICE palcCloseDevice = NULL;
80 LPALCGETERROR palcGetError = NULL;
81 LPALCISEXTENSIONPRESENT palcIsExtensionPresent = NULL;
82 LPALCGETPROCADDRESS palcGetProcAddress = NULL;
83 LPALCGETENUMVALUE palcGetEnumValue = NULL;
84 LPALCGETSTRING palcGetString = NULL;
85 LPALCGETINTEGERV palcGetIntegerv = NULL;
86 LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice = NULL;
87 LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice = NULL;
88 LPALCCAPTURESTART palcCaptureStart = NULL;
89 LPALCCAPTURESTOP palcCaptureStop = NULL;
90 LPALCCAPTURESAMPLES palcCaptureSamples = NULL;
91 LPALENABLE palEnable = NULL;
92 LPALDISABLE palDisable = NULL;
93 LPALISENABLED palIsEnabled = NULL;
94 LPALGETSTRING palGetString = NULL;
95 LPALGETBOOLEANV palGetBooleanv = NULL;
96 LPALGETINTEGERV palGetIntegerv = NULL;
97 LPALGETFLOATV palGetFloatv = NULL;
98 LPALGETDOUBLEV palGetDoublev = NULL;
99 LPALGETBOOLEAN palGetBoolean = NULL;
100 LPALGETINTEGER palGetInteger = NULL;
101 LPALGETFLOAT palGetFloat = NULL;
102 LPALGETDOUBLE palGetDouble = NULL;
103 LPALGETERROR palGetError = NULL;
104 LPALISEXTENSIONPRESENT palIsExtensionPresent = NULL;
105 LPALGETPROCADDRESS palGetProcAddress = NULL;
106 LPALGETENUMVALUE palGetEnumValue = NULL;
107 LPALLISTENERF palListenerf = NULL;
108 LPALLISTENER3F palListener3f = NULL;
109 LPALLISTENERFV palListenerfv = NULL;
110 LPALLISTENERI palListeneri = NULL;
111 LPALLISTENER3I palListener3i = NULL;
112 LPALLISTENERIV palListeneriv = NULL;
113 LPALGETLISTENERF palGetListenerf = NULL;
114 LPALGETLISTENER3F palGetListener3f = NULL;
115 LPALGETLISTENERFV palGetListenerfv = NULL;
116 LPALGETLISTENERI palGetListeneri = NULL;
117 LPALGETLISTENER3I palGetListener3i = NULL;
118 LPALGETLISTENERIV palGetListeneriv = NULL;
119 LPALGENSOURCES palGenSources = NULL;
120 LPALDELETESOURCES palDeleteSources = NULL;
121 LPALISSOURCE palIsSource = NULL;
122 LPALSOURCEF palSourcef = NULL;
123 LPALSOURCE3F palSource3f = NULL;
124 LPALSOURCEFV palSourcefv = NULL;
125 LPALSOURCEI palSourcei = NULL;
126 LPALSOURCE3I palSource3i = NULL;
127 LPALSOURCEIV palSourceiv = NULL;
128 LPALGETSOURCEF palGetSourcef = NULL;
129 LPALGETSOURCE3F palGetSource3f = NULL;
130 LPALGETSOURCEFV palGetSourcefv = NULL;
131 LPALGETSOURCEI palGetSourcei = NULL;
132 LPALGETSOURCE3I palGetSource3i = NULL;
133 LPALGETSOURCEIV palGetSourceiv = NULL;
134 LPALSOURCEPLAYV palSourcePlayv = NULL;
135 LPALSOURCESTOPV palSourceStopv = NULL;
136 LPALSOURCEREWINDV palSourceRewindv = NULL;
137 LPALSOURCEPAUSEV palSourcePausev = NULL;
138 LPALSOURCEPLAY palSourcePlay = NULL;
139 LPALSOURCESTOP palSourceStop = NULL;
140 LPALSOURCEREWIND palSourceRewind = NULL;
141 LPALSOURCEPAUSE palSourcePause = NULL;
142 LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers = NULL;
143 LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers = NULL;
144 LPALGENBUFFERS palGenBuffers = NULL;
145 LPALDELETEBUFFERS palDeleteBuffers = NULL;
146 LPALISBUFFER palIsBuffer = NULL;
147 LPALBUFFERF palBufferf = NULL;
148 LPALBUFFER3F palBuffer3f = NULL;
149 LPALBUFFERFV palBufferfv = NULL;
150 LPALBUFFERI palBufferi = NULL;
151 LPALBUFFER3I palBuffer3i = NULL;
152 LPALBUFFERIV palBufferiv = NULL;
153 LPALGETBUFFERF palGetBufferf = NULL;
154 LPALGETBUFFER3F palGetBuffer3f = NULL;
155 LPALGETBUFFERFV palGetBufferfv = NULL;
156 LPALGETBUFFERI palGetBufferi = NULL;
157 LPALGETBUFFER3I palGetBuffer3i = NULL;
158 LPALGETBUFFERIV palGetBufferiv = NULL;
159 LPALBUFFERDATA palBufferData = NULL;
160 LPALDOPPLERFACTOR palDopplerFactor = NULL;
161 LPALDOPPLERVELOCITY palDopplerVelocity = NULL;
162 LPALDISTANCEMODEL palDistanceModel = NULL;
163 LPALSPEEDOFSOUND palSpeedOfSound = NULL;
164 #endif
166 typeof(alcGetCurrentContext) *get_context;
167 typeof(alcMakeContextCurrent) *set_context;
169 static void load_libopenal(void)
171 DWORD failed = 0;
173 #ifdef SONAME_LIBOPENAL
174 char error[128];
175 openal_handle = wine_dlopen(SONAME_LIBOPENAL, RTLD_NOW, error, sizeof(error));
176 if (!openal_handle)
178 ERR("Couldn't load " SONAME_LIBOPENAL ": %s\n", error);
179 return;
182 #define LOAD_FUNCPTR(f) \
183 if((p##f = wine_dlsym(openal_handle, #f, NULL, 0)) == NULL) { \
184 ERR("Couldn't lookup %s in libopenal\n", #f); \
185 failed = 1; \
188 LOAD_FUNCPTR(alcCreateContext);
189 LOAD_FUNCPTR(alcMakeContextCurrent);
190 LOAD_FUNCPTR(alcProcessContext);
191 LOAD_FUNCPTR(alcSuspendContext);
192 LOAD_FUNCPTR(alcDestroyContext);
193 LOAD_FUNCPTR(alcGetCurrentContext);
194 LOAD_FUNCPTR(alcGetContextsDevice);
195 LOAD_FUNCPTR(alcOpenDevice);
196 LOAD_FUNCPTR(alcCloseDevice);
197 LOAD_FUNCPTR(alcGetError);
198 LOAD_FUNCPTR(alcIsExtensionPresent);
199 LOAD_FUNCPTR(alcGetProcAddress);
200 LOAD_FUNCPTR(alcGetEnumValue);
201 LOAD_FUNCPTR(alcGetString);
202 LOAD_FUNCPTR(alcGetIntegerv);
203 LOAD_FUNCPTR(alcCaptureOpenDevice);
204 LOAD_FUNCPTR(alcCaptureCloseDevice);
205 LOAD_FUNCPTR(alcCaptureStart);
206 LOAD_FUNCPTR(alcCaptureStop);
207 LOAD_FUNCPTR(alcCaptureSamples);
208 LOAD_FUNCPTR(alEnable);
209 LOAD_FUNCPTR(alDisable);
210 LOAD_FUNCPTR(alIsEnabled);
211 LOAD_FUNCPTR(alGetString);
212 LOAD_FUNCPTR(alGetBooleanv);
213 LOAD_FUNCPTR(alGetIntegerv);
214 LOAD_FUNCPTR(alGetFloatv);
215 LOAD_FUNCPTR(alGetDoublev);
216 LOAD_FUNCPTR(alGetBoolean);
217 LOAD_FUNCPTR(alGetInteger);
218 LOAD_FUNCPTR(alGetFloat);
219 LOAD_FUNCPTR(alGetDouble);
220 LOAD_FUNCPTR(alGetError);
221 LOAD_FUNCPTR(alIsExtensionPresent);
222 LOAD_FUNCPTR(alGetProcAddress);
223 LOAD_FUNCPTR(alGetEnumValue);
224 LOAD_FUNCPTR(alListenerf);
225 LOAD_FUNCPTR(alListener3f);
226 LOAD_FUNCPTR(alListenerfv);
227 LOAD_FUNCPTR(alListeneri);
228 LOAD_FUNCPTR(alListener3i);
229 LOAD_FUNCPTR(alListeneriv);
230 LOAD_FUNCPTR(alGetListenerf);
231 LOAD_FUNCPTR(alGetListener3f);
232 LOAD_FUNCPTR(alGetListenerfv);
233 LOAD_FUNCPTR(alGetListeneri);
234 LOAD_FUNCPTR(alGetListener3i);
235 LOAD_FUNCPTR(alGetListeneriv);
236 LOAD_FUNCPTR(alGenSources);
237 LOAD_FUNCPTR(alDeleteSources);
238 LOAD_FUNCPTR(alIsSource);
239 LOAD_FUNCPTR(alSourcef);
240 LOAD_FUNCPTR(alSource3f);
241 LOAD_FUNCPTR(alSourcefv);
242 LOAD_FUNCPTR(alSourcei);
243 LOAD_FUNCPTR(alSource3i);
244 LOAD_FUNCPTR(alSourceiv);
245 LOAD_FUNCPTR(alGetSourcef);
246 LOAD_FUNCPTR(alGetSource3f);
247 LOAD_FUNCPTR(alGetSourcefv);
248 LOAD_FUNCPTR(alGetSourcei);
249 LOAD_FUNCPTR(alGetSource3i);
250 LOAD_FUNCPTR(alGetSourceiv);
251 LOAD_FUNCPTR(alSourcePlayv);
252 LOAD_FUNCPTR(alSourceStopv);
253 LOAD_FUNCPTR(alSourceRewindv);
254 LOAD_FUNCPTR(alSourcePausev);
255 LOAD_FUNCPTR(alSourcePlay);
256 LOAD_FUNCPTR(alSourceStop);
257 LOAD_FUNCPTR(alSourceRewind);
258 LOAD_FUNCPTR(alSourcePause);
259 LOAD_FUNCPTR(alSourceQueueBuffers);
260 LOAD_FUNCPTR(alSourceUnqueueBuffers);
261 LOAD_FUNCPTR(alGenBuffers);
262 LOAD_FUNCPTR(alDeleteBuffers);
263 LOAD_FUNCPTR(alIsBuffer);
264 LOAD_FUNCPTR(alBufferf);
265 LOAD_FUNCPTR(alBuffer3f);
266 LOAD_FUNCPTR(alBufferfv);
267 LOAD_FUNCPTR(alBufferi);
268 LOAD_FUNCPTR(alBuffer3i);
269 LOAD_FUNCPTR(alBufferiv);
270 LOAD_FUNCPTR(alGetBufferf);
271 LOAD_FUNCPTR(alGetBuffer3f);
272 LOAD_FUNCPTR(alGetBufferfv);
273 LOAD_FUNCPTR(alGetBufferi);
274 LOAD_FUNCPTR(alGetBuffer3i);
275 LOAD_FUNCPTR(alGetBufferiv);
276 LOAD_FUNCPTR(alBufferData);
277 LOAD_FUNCPTR(alDopplerFactor);
278 LOAD_FUNCPTR(alDopplerVelocity);
279 LOAD_FUNCPTR(alDistanceModel);
280 LOAD_FUNCPTR(alSpeedOfSound);
281 #undef LOAD_FUNCPTR
282 #endif
284 if (failed)
286 WARN("Unloading openal\n");
287 if (openal_handle != RTLD_DEFAULT)
288 wine_dlclose(openal_handle, NULL, 0);
289 openal_handle = NULL;
290 openal_loaded = 0;
292 else
294 openal_loaded = 1;
295 local_contexts = palcIsExtensionPresent(NULL, "ALC_EXT_thread_local_context");
296 if (local_contexts)
298 set_context = palcGetProcAddress(NULL, "alcSetThreadContext");
299 get_context = palcGetProcAddress(NULL, "alcGetThreadContext");
300 if (!set_context || !get_context)
302 ERR("TLS advertised but functions not found, disabling thread local context\n");
303 local_contexts = 0;
306 if (!local_contexts)
308 set_context = palcMakeContextCurrent;
309 get_context = palcGetCurrentContext;
314 #endif /*HAVE_OPENAL*/
316 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
318 TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
320 switch (fdwReason)
322 case DLL_PROCESS_ATTACH:
323 DisableThreadLibraryCalls(hinstDLL);
324 #ifdef HAVE_OPENAL
325 load_libopenal();
326 #endif /*HAVE_OPENAL*/
327 break;
328 case DLL_PROCESS_DETACH:
329 MMDevEnum_Free();
330 break;
333 return TRUE;
336 HRESULT WINAPI DllCanUnloadNow(void)
338 return S_FALSE;
341 typedef HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj);
343 typedef struct {
344 const IClassFactoryVtbl *lpVtbl;
345 REFCLSID rclsid;
346 FnCreateInstance pfnCreateInstance;
347 } IClassFactoryImpl;
349 static HRESULT WINAPI
350 MMCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
352 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
353 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
354 if (ppobj == NULL)
355 return E_POINTER;
356 if (IsEqualIID(riid, &IID_IUnknown) ||
357 IsEqualIID(riid, &IID_IClassFactory))
359 *ppobj = iface;
360 IUnknown_AddRef(iface);
361 return S_OK;
363 *ppobj = NULL;
364 return E_NOINTERFACE;
367 static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
369 return 2;
372 static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
374 /* static class, won't be freed */
375 return 1;
378 static HRESULT WINAPI MMCF_CreateInstance(
379 LPCLASSFACTORY iface,
380 LPUNKNOWN pOuter,
381 REFIID riid,
382 LPVOID *ppobj)
384 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
385 TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
387 if (pOuter)
388 return CLASS_E_NOAGGREGATION;
390 if (ppobj == NULL) {
391 WARN("invalid parameter\n");
392 return E_POINTER;
394 *ppobj = NULL;
395 return This->pfnCreateInstance(riid, ppobj);
398 static HRESULT WINAPI MMCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
400 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
401 FIXME("(%p, %d) stub!\n", This, dolock);
402 return S_OK;
405 static const IClassFactoryVtbl MMCF_Vtbl = {
406 MMCF_QueryInterface,
407 MMCF_AddRef,
408 MMCF_Release,
409 MMCF_CreateInstance,
410 MMCF_LockServer
413 static IClassFactoryImpl MMDEVAPI_CF[] = {
414 { &MMCF_Vtbl, &CLSID_MMDeviceEnumerator, (FnCreateInstance)MMDevEnum_Create }
417 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
419 int i = 0;
420 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
422 if (ppv == NULL) {
423 WARN("invalid parameter\n");
424 return E_INVALIDARG;
427 *ppv = NULL;
429 if (!IsEqualIID(riid, &IID_IClassFactory) &&
430 !IsEqualIID(riid, &IID_IUnknown)) {
431 WARN("no interface for %s\n", debugstr_guid(riid));
432 return E_NOINTERFACE;
435 for (i = 0; i < sizeof(MMDEVAPI_CF)/sizeof(MMDEVAPI_CF[0]); ++i)
437 if (IsEqualGUID(rclsid, MMDEVAPI_CF[i].rclsid)) {
438 IUnknown_AddRef((IClassFactory*) &MMDEVAPI_CF[i]);
439 *ppv = &MMDEVAPI_CF[i];
440 return S_OK;
442 i++;
445 WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
446 debugstr_guid(riid), ppv);
447 return CLASS_E_CLASSNOTAVAILABLE;