push 6e61d6ca5bcaf95ac09a664b4ba4f88238c927be
[wine/hacks.git] / dlls / mmdevapi / main.c
blob9a3d4d10835c3b09767b33dea1b562db52c0c317
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"
21 #include <stdarg.h>
23 #define CINTERFACE
24 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "wine/debug.h"
30 #include "initguid.h"
31 #include "ole2.h"
32 #include "mmdeviceapi.h"
33 #include "dshow.h"
34 #include "dsound.h"
35 #include "audioclient.h"
36 #include "endpointvolume.h"
37 #include "audiopolicy.h"
38 #include "devpkey.h"
40 #include "mmdevapi.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
44 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
46 TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
48 switch (fdwReason)
50 case DLL_PROCESS_ATTACH:
51 DisableThreadLibraryCalls(hinstDLL);
52 break;
53 case DLL_PROCESS_DETACH:
54 MMDevEnum_Free();
55 break;
58 return TRUE;
61 HRESULT WINAPI DllCanUnloadNow(void)
63 return S_FALSE;
66 typedef HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj);
68 typedef struct {
69 const IClassFactoryVtbl *lpVtbl;
70 REFCLSID rclsid;
71 FnCreateInstance pfnCreateInstance;
72 } IClassFactoryImpl;
74 static HRESULT WINAPI
75 MMCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
77 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
78 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
79 if (ppobj == NULL)
80 return E_POINTER;
81 if (IsEqualIID(riid, &IID_IUnknown) ||
82 IsEqualIID(riid, &IID_IClassFactory))
84 *ppobj = iface;
85 IUnknown_AddRef(iface);
86 return S_OK;
88 *ppobj = NULL;
89 return E_NOINTERFACE;
92 static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
94 return 2;
97 static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
99 /* static class, won't be freed */
100 return 1;
103 static HRESULT WINAPI MMCF_CreateInstance(
104 LPCLASSFACTORY iface,
105 LPUNKNOWN pOuter,
106 REFIID riid,
107 LPVOID *ppobj)
109 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
110 TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
112 if (pOuter)
113 return CLASS_E_NOAGGREGATION;
115 if (ppobj == NULL) {
116 WARN("invalid parameter\n");
117 return E_POINTER;
119 *ppobj = NULL;
120 return This->pfnCreateInstance(riid, ppobj);
123 static HRESULT WINAPI MMCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
125 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
126 FIXME("(%p, %d) stub!\n", This, dolock);
127 return S_OK;
130 static const IClassFactoryVtbl MMCF_Vtbl = {
131 MMCF_QueryInterface,
132 MMCF_AddRef,
133 MMCF_Release,
134 MMCF_CreateInstance,
135 MMCF_LockServer
138 static IClassFactoryImpl MMDEVAPI_CF[] = {
139 { &MMCF_Vtbl, &CLSID_MMDeviceEnumerator, (FnCreateInstance)MMDevEnum_Create }
142 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
144 int i = 0;
145 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
147 if (ppv == NULL) {
148 WARN("invalid parameter\n");
149 return E_INVALIDARG;
152 *ppv = NULL;
154 if (!IsEqualIID(riid, &IID_IClassFactory) &&
155 !IsEqualIID(riid, &IID_IUnknown)) {
156 WARN("no interface for %s\n", debugstr_guid(riid));
157 return E_NOINTERFACE;
160 for (i = 0; i < sizeof(MMDEVAPI_CF)/sizeof(MMDEVAPI_CF[0]); ++i)
162 if (IsEqualGUID(rclsid, MMDEVAPI_CF[i].rclsid)) {
163 IUnknown_AddRef((IClassFactory*) &MMDEVAPI_CF[i]);
164 *ppv = &MMDEVAPI_CF[i];
165 return S_OK;
167 i++;
170 WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
171 debugstr_guid(riid), ppv);
172 return CLASS_E_CLASSNOTAVAILABLE;