ReactOS  0.4.14-dev-583-g2a1ba2c
main.c
Go to the documentation of this file.
1 /*
2  * Copyright 2009 Maarten Lankhorst
3  * Copyright 2011 Andrew Eikum for CodeWeavers
4  *
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.
9  *
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.
14  *
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
18  */
19 
20 #include <stdarg.h>
21 
22 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 
27 #include "ole2.h"
28 #include "olectl.h"
29 #include "rpcproxy.h"
30 #include "propsys.h"
31 #include "propkeydef.h"
32 #include "mmdeviceapi.h"
33 #include "mmsystem.h"
34 #include "dsound.h"
35 #include "audioclient.h"
36 #include "endpointvolume.h"
37 #include "audiopolicy.h"
38 #include "devpkey.h"
39 #include "winreg.h"
40 
41 #include "mmdevapi.h"
42 #include "wine/debug.h"
43 
45 
47 
49 
50 const WCHAR drv_keyW[] = {'S','o','f','t','w','a','r','e','\\',
51  'W','i','n','e','\\','D','r','i','v','e','r','s',0};
52 
53 static const char *get_priority_string(int prio)
54 {
55  switch(prio){
57  return "Unavailable";
58  case Priority_Low:
59  return "Low";
60  case Priority_Neutral:
61  return "Neutral";
62  case Priority_Preferred:
63  return "Preferred";
64  }
65  return "Invalid";
66 }
67 
69 {
70  WCHAR driver_module[264];
71  static const WCHAR wineW[] = {'w','i','n','e',0};
72  static const WCHAR dotdrvW[] = {'.','d','r','v',0};
73 
74  lstrcpyW(driver_module, wineW);
75  lstrcatW(driver_module, name);
76  lstrcatW(driver_module, dotdrvW);
77 
78  TRACE("Attempting to load %s\n", wine_dbgstr_w(driver_module));
79 
80  driver->module = LoadLibraryW(driver_module);
81  if(!driver->module){
82  TRACE("Unable to load %s: %u\n", wine_dbgstr_w(driver_module),
83  GetLastError());
84  return FALSE;
85  }
86 
87 #define LDFC(n) do { driver->p##n = (void*)GetProcAddress(driver->module, #n);\
88  if(!driver->p##n) { FreeLibrary(driver->module); return FALSE; } } while(0)
89  LDFC(GetPriority);
90  LDFC(GetEndpointIDs);
91  LDFC(GetAudioEndpoint);
92  LDFC(GetAudioSessionManager);
93 #undef LDFC
94 
95  /* optional - do not fail if not found */
96  driver->pGetPropValue = (void*)GetProcAddress(driver->module, "GetPropValue");
97 
98  driver->priority = driver->pGetPriority();
99  lstrcpyW(driver->module_name, driver_module);
100 
101  TRACE("Successfully loaded %s with priority %s\n",
102  wine_dbgstr_w(driver_module), get_priority_string(driver->priority));
103 
104  return TRUE;
105 }
106 
107 static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context)
108 {
109  static const WCHAR drv_value[] = {'A','u','d','i','o',0};
110 
111  static WCHAR default_list[] = {'p','u','l','s','e',',','a','l','s','a',',','o','s','s',',',
112  'c','o','r','e','a','u','d','i','o',',','a','n','d','r','o','i','d',0};
113 
115  HKEY key;
116  WCHAR reg_list[256], *p, *next, *driver_list = default_list;
117 
119  DWORD size = sizeof(reg_list);
120 
121  if(RegQueryValueExW(key, drv_value, 0, NULL, (BYTE*)reg_list,
122  &size) == ERROR_SUCCESS){
123  if(reg_list[0] == '\0'){
124  TRACE("User explicitly chose no driver\n");
125  RegCloseKey(key);
126  return TRUE;
127  }
128 
129  driver_list = reg_list;
130  }
131 
132  RegCloseKey(key);
133  }
134 
135  TRACE("Loading driver list %s\n", wine_dbgstr_w(driver_list));
136  for(next = p = driver_list; next; p = next + 1){
137  next = wcschr(p, ',');
138  if(next)
139  *next = '\0';
140 
141  driver.priority = Priority_Unavailable;
142  if(load_driver(p, &driver)){
143  if(driver.priority == Priority_Unavailable)
144  FreeLibrary(driver.module);
145  else if(!drvs.module || driver.priority > drvs.priority){
146  TRACE("Selecting driver %s with priority %s\n",
148  if(drvs.module)
150  drvs = driver;
151  }else
152  FreeLibrary(driver.module);
153  }else
154  TRACE("Failed to load driver %s\n", wine_dbgstr_w(p));
155 
156  if(next)
157  *next = ',';
158  }
159 
160  return drvs.module != 0;
161 }
162 
164 {
165  TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
166 
167  switch (fdwReason)
168  {
169  case DLL_PROCESS_ATTACH:
170  instance = hinstDLL;
171  DisableThreadLibraryCalls(hinstDLL);
172  break;
173  case DLL_PROCESS_DETACH:
174  if(lpvReserved)
175  break;
176  MMDevEnum_Free();
177  break;
178  }
179 
180  return TRUE;
181 }
182 
184 {
185  return S_FALSE;
186 }
187 
189 
190 typedef struct {
191  IClassFactory IClassFactory_iface;
192  REFCLSID rclsid;
193  FnCreateInstance pfnCreateInstance;
195 
197 {
198  return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
199 }
200 
201 static HRESULT WINAPI
203 {
205  TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
206  if (ppobj == NULL)
207  return E_POINTER;
208  if (IsEqualIID(riid, &IID_IUnknown) ||
210  {
211  *ppobj = iface;
212  IClassFactory_AddRef(iface);
213  return S_OK;
214  }
215  *ppobj = NULL;
216  return E_NOINTERFACE;
217 }
218 
219 static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
220 {
221  return 2;
222 }
223 
224 static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
225 {
226  /* static class, won't be freed */
227  return 1;
228 }
229 
231  LPCLASSFACTORY iface,
232  LPUNKNOWN pOuter,
233  REFIID riid,
234  LPVOID *ppobj)
235 {
237  TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
238 
239  if (pOuter)
240  return CLASS_E_NOAGGREGATION;
241 
242  if (ppobj == NULL) {
243  WARN("invalid parameter\n");
244  return E_POINTER;
245  }
246  *ppobj = NULL;
247  return This->pfnCreateInstance(riid, ppobj);
248 }
249 
250 static HRESULT WINAPI MMCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
251 {
253  FIXME("(%p, %d) stub!\n", This, dolock);
254  return S_OK;
255 }
256 
257 static const IClassFactoryVtbl MMCF_Vtbl = {
259  MMCF_AddRef,
260  MMCF_Release,
263 };
264 
266  { { &MMCF_Vtbl }, &CLSID_MMDeviceEnumerator, (FnCreateInstance)MMDevEnum_Create }
267 };
268 
270 {
271  static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
272  unsigned int i = 0;
273  TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
274 
275  if(!InitOnceExecuteOnce(&init_once, init_driver, NULL, NULL)) {
276  ERR("Driver initialization failed\n");
277  return E_FAIL;
278  }
279 
280  if (ppv == NULL) {
281  WARN("invalid parameter\n");
282  return E_INVALIDARG;
283  }
284 
285  *ppv = NULL;
286 
289  WARN("no interface for %s\n", debugstr_guid(riid));
290  return E_NOINTERFACE;
291  }
292 
293  for (i = 0; i < ARRAY_SIZE(MMDEVAPI_CF); ++i)
294  {
295  if (IsEqualGUID(rclsid, MMDEVAPI_CF[i].rclsid)) {
296  IClassFactory_AddRef(&MMDEVAPI_CF[i].IClassFactory_iface);
297  *ppv = &MMDEVAPI_CF[i];
298  return S_OK;
299  }
300  }
301 
302  WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
305 }
306 
307 /***********************************************************************
308  * DllRegisterServer (MMDEVAPI.@)
309  */
311 {
313 }
314 
315 /***********************************************************************
316  * DllUnregisterServer (MMDEVAPI.@)
317  */
319 {
321 }
void MMDevEnum_Free(void)
Definition: devenum.c:902
#define HRESULT
Definition: msvc.h:7
static const IClassFactoryVtbl MMCF_Vtbl
Definition: main.c:257
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
static IClassFactoryImpl * impl_from_IClassFactory(IClassFactory *iface)
Definition: main.c:196
HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
Definition: devenum.c:881
static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
Definition: main.c:224
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT __wine_register_resources(HMODULE module) DECLSPEC_HIDDEN
Definition: register.c:98
WINE_DEFAULT_DEBUG_CHANNEL(wmic)
Definition: http.c:7098
REFIID riid
Definition: precomp.h:44
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
#define REFCLSID
Definition: guiddef.h:117
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define WARN(fmt,...)
Definition: debug.h:111
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:593
REFIID LPVOID * ppv
Definition: atlbase.h:39
static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context)
Definition: main.c:107
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
#define E_FAIL
Definition: ddrawi.h:102
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:2663
static IN DWORD IN LPVOID lpvReserved
struct tagIClassFactoryImpl IClassFactoryImpl
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
HRESULT WINAPI DllRegisterServer(void)
Definition: main.c:212
static WCHAR wineW[]
Definition: localmon.c:128
unsigned int BOOL
Definition: ntddk_ex.h:94
static LPUNKNOWN
Definition: ndr_ole.c:49
HRESULT WINAPI DllUnregisterServer(void)
Definition: main.c:220
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
#define FIXME(fmt,...)
Definition: debug.h:110
#define LDFC(n)
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
#define LoadLibraryW(x)
Definition: compat.h:412
smooth NULL
Definition: ftsmooth.c:416
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
int priority
Definition: mmdevapi.h:36
#define DLL_PROCESS_DETACH
Definition: compat.h:119
BOOL NTAPI InitOnceExecuteOnce(INIT_ONCE *once, PINIT_ONCE_FN func, void *param, void **context)
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:413
GLsizeiptr size
Definition: glext.h:5919
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
GLfloat param
Definition: glext.h:5796
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI MMCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
Definition: main.c:202
HRESULT __wine_unregister_resources(HMODULE module) DECLSPEC_HIDDEN
Definition: register.c:110
HKEY key
Definition: reg.c:42
const GUID riid
Definition: main.c:223
unsigned char BYTE
Definition: mem.h:68
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
const WCHAR drv_keyW[]
Definition: main.c:50
#define ERR(fmt,...)
Definition: debug.h:109
struct @1623::@1624 driver
#define S_OK
Definition: intsafe.h:59
static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
Definition: main.c:219
static unsigned __int64 next
Definition: rand_nt.c:6
#define lstrcpyW
Definition: compat.h:414
static HRESULT WINAPI MMCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
Definition: main.c:230
#define ARRAY_SIZE(a)
Definition: main.h:24
DriverFuncs drvs
Definition: main.c:48
HRESULT WINAPI DllCanUnloadNow(void)
Definition: main.c:204
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
static const char * get_priority_string(int prio)
Definition: main.c:53
static HINSTANCE instance
Definition: main.c:46
Definition: name.c:38
unsigned int ULONG
Definition: retypes.h:1
HRESULT(* FnCreateInstance)(REFIID riid, LPVOID *ppobj)
Definition: main.c:188
#define GetProcAddress(x, y)
Definition: compat.h:418
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
GLfloat GLfloat p
Definition: glext.h:8902
#define E_POINTER
Definition: winerror.h:2365
const GUID IID_IClassFactory
static BOOL load_driver(const WCHAR *name, DriverFuncs *driver)
Definition: main.c:68
HMODULE module
Definition: mmdevapi.h:34
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static IClassFactoryImpl MMDEVAPI_CF[]
Definition: main.c:265
Definition: path.c:41
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
Definition: main.c:166
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Definition: main.c:26
static HRESULT WINAPI MMCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
Definition: main.c:250