ReactOS  0.4.13-dev-52-g0efcfec
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 "config.h"
21 #include "wine/port.h"
22 
23 #include <stdarg.h>
24 
25 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "wine/library.h"
30 
31 #include "ole2.h"
32 #include "olectl.h"
33 #include "rpcproxy.h"
34 #include "propsys.h"
35 #include "propkeydef.h"
36 #include "mmdeviceapi.h"
37 #include "mmsystem.h"
38 #include "dsound.h"
39 #include "audioclient.h"
40 #include "endpointvolume.h"
41 #include "audiopolicy.h"
42 #include "devpkey.h"
43 #include "winreg.h"
44 
45 #include "mmdevapi.h"
46 #include "wine/debug.h"
47 #include "wine/unicode.h"
48 
50 
52 
54 
55 const WCHAR drv_keyW[] = {'S','o','f','t','w','a','r','e','\\',
56  'W','i','n','e','\\','D','r','i','v','e','r','s',0};
57 
58 static const char *get_priority_string(int prio)
59 {
60  switch(prio){
62  return "Unavailable";
63  case Priority_Low:
64  return "Low";
65  case Priority_Neutral:
66  return "Neutral";
67  case Priority_Preferred:
68  return "Preferred";
69  }
70  return "Invalid";
71 }
72 
74 {
75  WCHAR driver_module[264];
76  static const WCHAR wineW[] = {'w','i','n','e',0};
77  static const WCHAR dotdrvW[] = {'.','d','r','v',0};
78 
79  lstrcpyW(driver_module, wineW);
80  lstrcatW(driver_module, name);
81  lstrcatW(driver_module, dotdrvW);
82 
83  TRACE("Attempting to load %s\n", wine_dbgstr_w(driver_module));
84 
85  driver->module = LoadLibraryW(driver_module);
86  if(!driver->module){
87  TRACE("Unable to load %s: %u\n", wine_dbgstr_w(driver_module),
88  GetLastError());
89  return FALSE;
90  }
91 
92 #define LDFC(n) do { driver->p##n = (void*)GetProcAddress(driver->module, #n);\
93  if(!driver->p##n) { FreeLibrary(driver->module); return FALSE; } } while(0)
94  LDFC(GetPriority);
95  LDFC(GetEndpointIDs);
96  LDFC(GetAudioEndpoint);
97  LDFC(GetAudioSessionManager);
98 #undef LDFC
99 
100  /* optional - do not fail if not found */
101  driver->pGetPropValue = (void*)GetProcAddress(driver->module, "GetPropValue");
102 
103  driver->priority = driver->pGetPriority();
104  lstrcpyW(driver->module_name, driver_module);
105 
106  TRACE("Successfully loaded %s with priority %s\n",
107  wine_dbgstr_w(driver_module), get_priority_string(driver->priority));
108 
109  return TRUE;
110 }
111 
112 static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context)
113 {
114  static const WCHAR drv_value[] = {'A','u','d','i','o',0};
115 
116  static WCHAR default_list[] = {'p','u','l','s','e',',','a','l','s','a',',','o','s','s',',',
117  'c','o','r','e','a','u','d','i','o',',','a','n','d','r','o','i','d',0};
118 
120  HKEY key;
121  WCHAR reg_list[256], *p, *next, *driver_list = default_list;
122 
124  DWORD size = sizeof(reg_list);
125 
126  if(RegQueryValueExW(key, drv_value, 0, NULL, (BYTE*)reg_list,
127  &size) == ERROR_SUCCESS){
128  if(reg_list[0] == '\0'){
129  TRACE("User explicitly chose no driver\n");
130  RegCloseKey(key);
131  return TRUE;
132  }
133 
134  driver_list = reg_list;
135  }
136 
137  RegCloseKey(key);
138  }
139 
140  TRACE("Loading driver list %s\n", wine_dbgstr_w(driver_list));
141  for(next = p = driver_list; next; p = next + 1){
142  next = strchrW(p, ',');
143  if(next)
144  *next = '\0';
145 
146  driver.priority = Priority_Unavailable;
147  if(load_driver(p, &driver)){
148  if(driver.priority == Priority_Unavailable)
149  FreeLibrary(driver.module);
150  else if(!drvs.module || driver.priority > drvs.priority){
151  TRACE("Selecting driver %s with priority %s\n",
153  if(drvs.module)
155  drvs = driver;
156  }else
157  FreeLibrary(driver.module);
158  }else
159  TRACE("Failed to load driver %s\n", wine_dbgstr_w(p));
160 
161  if(next)
162  *next = ',';
163  }
164 
165  return drvs.module != 0;
166 }
167 
169 {
170  TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
171 
172  switch (fdwReason)
173  {
174  case DLL_PROCESS_ATTACH:
175  instance = hinstDLL;
176  DisableThreadLibraryCalls(hinstDLL);
177  break;
178  case DLL_PROCESS_DETACH:
179  if(lpvReserved)
180  break;
181  MMDevEnum_Free();
182  break;
183  }
184 
185  return TRUE;
186 }
187 
189 {
190  return S_FALSE;
191 }
192 
194 
195 typedef struct {
196  IClassFactory IClassFactory_iface;
197  REFCLSID rclsid;
198  FnCreateInstance pfnCreateInstance;
200 
202 {
203  return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
204 }
205 
206 static HRESULT WINAPI
208 {
210  TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
211  if (ppobj == NULL)
212  return E_POINTER;
213  if (IsEqualIID(riid, &IID_IUnknown) ||
215  {
216  *ppobj = iface;
217  IClassFactory_AddRef(iface);
218  return S_OK;
219  }
220  *ppobj = NULL;
221  return E_NOINTERFACE;
222 }
223 
224 static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
225 {
226  return 2;
227 }
228 
229 static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
230 {
231  /* static class, won't be freed */
232  return 1;
233 }
234 
236  LPCLASSFACTORY iface,
237  LPUNKNOWN pOuter,
238  REFIID riid,
239  LPVOID *ppobj)
240 {
242  TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
243 
244  if (pOuter)
245  return CLASS_E_NOAGGREGATION;
246 
247  if (ppobj == NULL) {
248  WARN("invalid parameter\n");
249  return E_POINTER;
250  }
251  *ppobj = NULL;
252  return This->pfnCreateInstance(riid, ppobj);
253 }
254 
255 static HRESULT WINAPI MMCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
256 {
258  FIXME("(%p, %d) stub!\n", This, dolock);
259  return S_OK;
260 }
261 
262 static const IClassFactoryVtbl MMCF_Vtbl = {
264  MMCF_AddRef,
265  MMCF_Release,
268 };
269 
271  { { &MMCF_Vtbl }, &CLSID_MMDeviceEnumerator, (FnCreateInstance)MMDevEnum_Create }
272 };
273 
275 {
276  static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
277  unsigned int i = 0;
278  TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
279 
280  if(!InitOnceExecuteOnce(&init_once, init_driver, NULL, NULL)) {
281  ERR("Driver initialization failed\n");
282  return E_FAIL;
283  }
284 
285  if (ppv == NULL) {
286  WARN("invalid parameter\n");
287  return E_INVALIDARG;
288  }
289 
290  *ppv = NULL;
291 
294  WARN("no interface for %s\n", debugstr_guid(riid));
295  return E_NOINTERFACE;
296  }
297 
298  for (i = 0; i < ARRAY_SIZE(MMDEVAPI_CF); ++i)
299  {
300  if (IsEqualGUID(rclsid, MMDEVAPI_CF[i].rclsid)) {
301  IClassFactory_AddRef(&MMDEVAPI_CF[i].IClassFactory_iface);
302  *ppv = &MMDEVAPI_CF[i];
303  return S_OK;
304  }
305  }
306 
307  WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
310 }
311 
312 /***********************************************************************
313  * DllRegisterServer (MMDEVAPI.@)
314  */
316 {
318 }
319 
320 /***********************************************************************
321  * DllUnregisterServer (MMDEVAPI.@)
322  */
324 {
326 }
void MMDevEnum_Free(void)
Definition: devenum.c:905
#define HRESULT
Definition: msvc.h:9
static const IClassFactoryVtbl MMCF_Vtbl
Definition: main.c:262
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
static IClassFactoryImpl * impl_from_IClassFactory(IClassFactory *iface)
Definition: main.c:201
HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
Definition: devenum.c:884
static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
Definition: main.c:229
#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:6587
REFIID riid
Definition: precomp.h:44
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
#define REFCLSID
Definition: guiddef.h:112
#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
#define wine_dbgstr_w
Definition: kernel32.h:34
static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context)
Definition: main.c:112
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:116
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:3311
#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:404
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:40
#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:405
GLsizeiptr size
Definition: glext.h:5919
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
__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:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI MMCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
Definition: main.c:207
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:55
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
Definition: main.c:224
static unsigned __int64 next
Definition: rand_nt.c:6
#define lstrcpyW
Definition: compat.h:406
static HRESULT WINAPI MMCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
Definition: main.c:235
#define ARRAY_SIZE(a)
Definition: main.h:24
DriverFuncs drvs
Definition: main.c:53
HRESULT WINAPI DllCanUnloadNow(void)
Definition: main.c:204
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static const char * get_priority_string(int prio)
Definition: main.c:58
static HINSTANCE instance
Definition: main.c:51
Definition: name.c:36
unsigned int ULONG
Definition: retypes.h:1
HRESULT(* FnCreateInstance)(REFIID riid, LPVOID *ppobj)
Definition: main.c:193
#define GetProcAddress(x, y)
Definition: compat.h:410
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:73
HMODULE module
Definition: mmdevapi.h:38
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
struct @1596::@1597 driver
static IClassFactoryImpl MMDEVAPI_CF[]
Definition: main.c:270
Definition: path.c:42
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:255