winex11.drv: Remove unneeded address-of operators from array names.
[wine] / dlls / qcap / qcap_main.c
1 /*
2  * Qcap implementation, dllentry points
3  *
4  * Copyright (C) 2003 Dominik Strasser
5  * Copyright (C) 2005 Rolf Kalbermatter
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 #include "config.h"
22
23 #include <assert.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26
27 #define COBJMACROS
28 #define NONAMELESSSTRUCT
29 #define NONAMELESSUNION
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "wingdi.h"
34 #include "winerror.h"
35 #include "objbase.h"
36 #include "uuids.h"
37 #include "strmif.h"
38
39 #include "dllsetup.h"
40 #include "qcap_main.h"
41
42 #include "wine/unicode.h"
43 #include "wine/debug.h"
44
45 WINE_DEFAULT_DEBUG_CHANNEL(qcap);
46
47 static LONG objects_ref = 0;
48 static LONG server_locks = 0;
49
50 static const WCHAR wAudioCaptFilter[] =
51 {'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
52 static const WCHAR wAVICompressor[] =
53 {'A','V','I',' ','C','o','m','p','r','e','s','s','o','r',0};
54 static const WCHAR wVFWCaptFilter[] =
55 {'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
56 static const WCHAR wVFWCaptFilterProp[] =
57 {'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',' ',
58  'P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
59 static const WCHAR wAVIMux[] =
60 {'A','V','I',' ','m','u','x',0};
61 static const WCHAR wAVIMuxPropPage[] =
62 {'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
63 static const WCHAR wAVIMuxPropPage1[] =
64 {'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e','1',0};
65 static const WCHAR wFileWriter[] =
66 {'F','i','l','e',' ','W','r','i','t','e','r',0};
67 static const WCHAR wCaptGraphBuilder[] =
68 {'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r',0};
69 static const WCHAR wCaptGraphBuilder2[] =
70 {'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r','2',0};
71 static const WCHAR wInfPinTeeFilter[] =
72 {'I','n','f','i','n','i','t','e',' ','P','i','n',' ','T','e','e',' ','F','i',
73  'l','t','e','r',0};
74 static const WCHAR wSmartTeeFilter[] =
75 {'S','m','a','r','t',' ','T','e','e',' ','F','i','l','t','e','r',0};
76 static const WCHAR wAudioInMixerProp[] =
77 {'A','u','d','i','o','I','n','p','u','t','M','i','x','e','r',' ','P','r','o',
78  'p','e','r','t','y',' ','P','a','g','e',0};
79  
80 static CFactoryTemplate const g_cTemplates[] = {
81 /*
82     {
83         wAudioCaptureFilter, 
84         &CLSID_AudioCaptureFilter,
85         QCAP_createAudioCaptureFilter,
86         NULL,
87         NULL
88     },{
89         wAVICompressor, 
90         &CLSID_AVICompressor, 
91         QCAP_createAVICompressor,
92         NULL,
93         NULL
94     },*/{
95         wVFWCaptFilter,
96         &CLSID_VfwCapture,
97         QCAP_createVFWCaptureFilter,
98         NULL,
99         NULL
100     },/*{
101         wVFWCaptFilterProp,
102         &CLSID_VFWCaptureFilterPropertyPage,
103         QCAP_createVFWCaptureFilterPropertyPage,
104         NULL,
105         NULL
106     },{
107         wAVIMux,
108         &CLSID_AVImux,
109         QCAP_createAVImux,
110         NULL,
111         NULL
112     },{
113         wAVIMuxPropPage,
114         &CLSID_AVImuxPropertyPage,
115         QCAP_createAVImuxPropertyPage,
116         NULL,
117         NULL
118     },{
119         wAVIMuxPropPage1,
120         &CLSID_AVImuxPropertyPage1,
121         QCAP_createAVImuxPropertyPage1,
122         NULL,
123         NULL
124     },{
125         wFileWriter,
126         &CLSID_FileWriter,
127         QCAP_createFileWriter,
128         NULL,
129         NULL
130     },*/{
131         wCaptGraphBuilder,
132         &CLSID_CaptureGraphBuilder,
133         QCAP_createCaptureGraphBuilder2,
134         NULL,
135         NULL
136     },{
137         wCaptGraphBuilder2,
138         &CLSID_CaptureGraphBuilder2,
139         QCAP_createCaptureGraphBuilder2,
140         NULL,
141         NULL
142     }/*,{
143         wInfPinTeeFilter, 
144         &CLSID_InfinitePinTeeFilter, 
145         QCAP_createInfinitePinTeeFilter,
146         NULL,
147         NULL
148     },{
149         wSmartTeeFilter,
150         &CLSID_SmartTeeFilter,
151         QCAP_createSmartTeeFilter,
152         NULL,
153         NULL
154     },{
155         wAudioInMixerProp,
156         &CLSID_AudioInputMixerPropertyPage,
157         QCAP_createAudioInputMixerPropertyPage,
158         NULL,
159         NULL
160     }*/
161 };
162
163 static int g_numTemplates = sizeof(g_cTemplates) / sizeof(g_cTemplates[0]);
164
165 /***********************************************************************
166  *    Dll EntryPoint (QCAP.@)
167  */
168 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
169 {
170     switch (fdwReason)
171     {
172         case DLL_PROCESS_ATTACH:
173             DisableThreadLibraryCalls(hInstDLL);
174             SetupInitializeServers(g_cTemplates, g_numTemplates, TRUE);
175             break;
176         case DLL_PROCESS_DETACH:
177             SetupInitializeServers(g_cTemplates, g_numTemplates, FALSE);
178             break;
179     }
180     return TRUE;
181 }
182
183 /***********************************************************************
184  *    DllRegisterServer (QCAP.@)
185  */
186 HRESULT WINAPI DllRegisterServer(void)
187 {
188     TRACE("()\n");
189
190     return SetupRegisterServers(g_cTemplates, g_numTemplates, TRUE);
191 }
192
193 /***********************************************************************
194  *    DllUnregisterServer (QCAP.@)
195  */
196 HRESULT WINAPI DllUnregisterServer(void)
197 {
198     TRACE("\n");
199
200     return SetupRegisterServers(g_cTemplates, g_numTemplates, FALSE);
201 }
202
203 /***********************************************************************
204  *    DllCanUnloadNow (QCAP.@)
205  */
206 HRESULT WINAPI DllCanUnloadNow(void)
207 {
208     TRACE("\n");
209
210     if (objects_ref == 0 && server_locks == 0)
211         return S_OK;
212     return S_FALSE;     
213 }
214
215 /******************************************************************************
216  * DLL ClassFactory
217  */
218 typedef struct {
219     IClassFactory ITF_IClassFactory;
220
221     LONG ref;
222     LPFNNewCOMObject pfnCreateInstance;
223 } IClassFactoryImpl;
224
225 static HRESULT WINAPI
226 DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
227 {
228     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
229
230     if (IsEqualGUID(riid, &IID_IUnknown) ||
231         IsEqualGUID(riid, &IID_IClassFactory))
232     {
233         IClassFactory_AddRef(iface);
234         *ppobj = This;
235         return S_OK;
236     }
237
238     WARN("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppobj);
239     return E_NOINTERFACE;
240 }
241
242 static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
243 {
244     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
245     return InterlockedIncrement(&This->ref);
246 }
247
248 static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
249 {
250     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
251
252     ULONG ref = InterlockedDecrement(&This->ref);
253
254     if (ref == 0)
255         HeapFree(GetProcessHeap(), 0, This);
256
257     return ref;
258 }
259
260 static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
261                                           REFIID riid, LPVOID *ppobj)
262 {
263     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
264     HRESULT hres = ERROR_SUCCESS;
265     LPUNKNOWN punk;
266
267     TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
268
269     if (!ppobj)
270         return E_POINTER;
271
272     /* Enforce the normal OLE rules regarding interfaces and delegation */
273     if (pOuter && !IsEqualGUID(riid, &IID_IUnknown))
274         return E_NOINTERFACE;
275
276     *ppobj = NULL;
277     punk = This->pfnCreateInstance(pOuter, &hres);
278     if (!punk)
279     {
280         /* No object created, update error if it isn't done already and return */
281         if (!FAILED(hres))
282             hres = E_OUTOFMEMORY;
283     return hres;
284     }
285
286     if (SUCCEEDED(hres))
287     {
288         hres = IUnknown_QueryInterface(punk, riid, ppobj);
289     }
290     /* Releasing the object. If everything was successful, QueryInterface
291        should have incremented the refcount once more, otherwise this will
292        purge the object. */
293     IUnknown_Release(punk);
294     return hres;
295 }
296
297 static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
298 {
299     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
300     TRACE("(%p)->(%d)\n",This, dolock);
301
302     if (dolock)
303         InterlockedIncrement(&server_locks);
304     else
305         InterlockedDecrement(&server_locks);
306     return S_OK;
307 }
308
309 static const IClassFactoryVtbl DSCF_Vtbl =
310 {
311     DSCF_QueryInterface,
312     DSCF_AddRef,
313     DSCF_Release,
314     DSCF_CreateInstance,
315     DSCF_LockServer
316 };
317
318 /***********************************************************************
319  *    DllGetClassObject (QCAP.@)
320  */
321 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
322 {
323     const CFactoryTemplate *pList = g_cTemplates;
324     IClassFactoryImpl *factory;
325     int i;
326
327     TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
328
329     if (!ppv)
330         return E_POINTER;
331
332     *ppv = NULL;
333
334     if (!IsEqualGUID(&IID_IClassFactory, riid) &&
335         !IsEqualGUID(&IID_IUnknown, riid))
336         return E_NOINTERFACE;
337
338     for (i = 0; i < g_numTemplates; i++, pList++)
339     {
340         if (IsEqualGUID(pList->m_ClsID, rclsid))
341             break;
342     }
343
344     if (i == g_numTemplates)
345     {
346         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
347         return CLASS_E_CLASSNOTAVAILABLE;
348     }
349
350     factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl));
351     if (!factory)
352         return E_OUTOFMEMORY;
353
354     factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
355     factory->ref = 1;
356
357     factory->pfnCreateInstance = pList->m_lpfnNew;
358
359     *ppv = &(factory->ITF_IClassFactory);
360     return S_OK;
361 }
362
363 DWORD ObjectRefCount(BOOL increment)
364 {
365     if (increment)
366         return InterlockedIncrement(&objects_ref);
367     return InterlockedDecrement(&objects_ref);
368 }