quartz/tests: Fix test failures on Win95 by using A-functions.
[wine] / dlls / quartz / main.c
1 /*              DirectShow Base Functions (QUARTZ.DLL)
2  *
3  * Copyright 2002 Lionel Ulmer
4  *
5  * This file contains the (internal) driver registration functions,
6  * driver enumeration APIs and DirectDraw creation functions.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "wine/debug.h"
25
26 #include "quartz_private.h"
27 #include "wine/unicode.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
30
31 static DWORD dll_ref = 0;
32
33 /* For the moment, do nothing here. */
34 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
35 {
36     switch(fdwReason) {
37         case DLL_PROCESS_ATTACH:
38             DisableThreadLibraryCalls(hInstDLL);
39             break;
40         case DLL_PROCESS_DETACH:
41             break;
42     }
43     return TRUE;
44 }
45
46 /******************************************************************************
47  * DirectShow ClassFactory
48  */
49 typedef struct {
50     IClassFactory ITF_IClassFactory;
51
52     LONG ref;
53     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
54 } IClassFactoryImpl;
55
56 struct object_creation_info
57 {
58     const CLSID *clsid;
59     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
60 };
61
62 static const struct object_creation_info object_creation[] =
63 {
64     { &CLSID_SeekingPassThru, SeekingPassThru_create },
65     { &CLSID_FilterGraph, FilterGraph_create },
66     { &CLSID_FilterGraphNoThread, FilterGraphNoThread_create },
67     { &CLSID_FilterMapper, FilterMapper_create },
68     { &CLSID_FilterMapper2, FilterMapper2_create },
69     { &CLSID_AsyncReader, AsyncReader_create },
70     { &CLSID_MemoryAllocator, StdMemAllocator_create },
71     { &CLSID_AviSplitter, AVISplitter_create },
72     { &CLSID_MPEG1Splitter, MPEGSplitter_create },
73     { &CLSID_VideoRenderer, VideoRenderer_create },
74     { &CLSID_NullRenderer, NullRenderer_create },
75     { &CLSID_VideoRendererDefault, VideoRendererDefault_create },
76     { &CLSID_DSoundRender, DSoundRender_create },
77     { &CLSID_AudioRender, DSoundRender_create },
78     { &CLSID_AVIDec, AVIDec_create },
79     { &CLSID_SystemClock, QUARTZ_CreateSystemClock },
80     { &CLSID_ACMWrapper, ACMWrapper_create },
81     { &CLSID_WAVEParser, WAVEParser_create }
82 };
83
84 static HRESULT WINAPI
85 DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
86 {
87     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
88
89     if (IsEqualGUID(riid, &IID_IUnknown)
90         || IsEqualGUID(riid, &IID_IClassFactory))
91     {
92         IClassFactory_AddRef(iface);
93         *ppobj = This;
94         return S_OK;
95     }
96
97     *ppobj = NULL;
98     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
99     return E_NOINTERFACE;
100 }
101
102 static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
103 {
104     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
105     return InterlockedIncrement(&This->ref);
106 }
107
108 static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
109 {
110     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
111
112     ULONG ref = InterlockedDecrement(&This->ref);
113
114     if (ref == 0)
115         CoTaskMemFree(This);
116
117     return ref;
118 }
119
120
121 static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
122                                           REFIID riid, LPVOID *ppobj)
123 {
124     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
125     HRESULT hres;
126     LPUNKNOWN punk;
127     
128     TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
129
130     *ppobj = NULL;
131     hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
132     if (SUCCEEDED(hres)) {
133         hres = IUnknown_QueryInterface(punk, riid, ppobj);
134         IUnknown_Release(punk);
135     }
136     return hres;
137 }
138
139 static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
140 {
141     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
142     FIXME("(%p)->(%d),stub!\n",This,dolock);
143     return S_OK;
144 }
145
146 static const IClassFactoryVtbl DSCF_Vtbl =
147 {
148     DSCF_QueryInterface,
149     DSCF_AddRef,
150     DSCF_Release,
151     DSCF_CreateInstance,
152     DSCF_LockServer
153 };
154
155 /*******************************************************************************
156  * DllGetClassObject [QUARTZ.@]
157  * Retrieves class object from a DLL object
158  *
159  * NOTES
160  *    Docs say returns STDAPI
161  *
162  * PARAMS
163  *    rclsid [I] CLSID for the class object
164  *    riid   [I] Reference to identifier of interface for class object
165  *    ppv    [O] Address of variable to receive interface pointer for riid
166  *
167  * RETURNS
168  *    Success: S_OK
169  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
170  *             E_UNEXPECTED
171  */
172 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
173 {
174     unsigned int i;
175     IClassFactoryImpl *factory;
176     
177     TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
178     
179     if ( !IsEqualGUID( &IID_IClassFactory, riid )
180          && ! IsEqualGUID( &IID_IUnknown, riid) )
181         return E_NOINTERFACE;
182
183     for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
184     {
185         if (IsEqualGUID(object_creation[i].clsid, rclsid))
186             break;
187     }
188
189     if (i == sizeof(object_creation)/sizeof(object_creation[0]))
190     {
191         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
192         return CLASS_E_CLASSNOTAVAILABLE;
193     }
194
195     factory = CoTaskMemAlloc(sizeof(*factory));
196     if (factory == NULL) return E_OUTOFMEMORY;
197
198     factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
199     factory->ref = 1;
200
201     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
202
203     *ppv = &(factory->ITF_IClassFactory);
204     return S_OK;
205 }
206
207 /***********************************************************************
208  *              DllCanUnloadNow (QUARTZ.@)
209  */
210 HRESULT WINAPI DllCanUnloadNow(void)
211 {
212     return dll_ref != 0 ? S_FALSE : S_OK;
213 }
214
215
216 #define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
217     { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } , #name },
218
219 static const struct {
220         const GUID      riid;
221         const char      *name;
222 } InterfaceDesc[] =
223 {
224 #include "uuids.h"
225     { { 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0} }, NULL }
226 };
227
228 /***********************************************************************
229  *              qzdebugstr_guid (internal)
230  *
231  * Gives a text version of DirectShow GUIDs
232  */
233 const char * qzdebugstr_guid( const GUID * id )
234 {
235     int i;
236     char * name = NULL;
237
238     for (i=0;InterfaceDesc[i].name && !name;i++) {
239         if (IsEqualGUID(&InterfaceDesc[i].riid, id)) return InterfaceDesc[i].name;
240     }
241     return debugstr_guid(id);
242 }
243
244 LONG WINAPI AmpFactorToDB(LONG ampfactor)
245 {
246     FIXME("(%d) Stub!\n", ampfactor);
247     return 0;
248 }
249
250 LONG WINAPI DBToAmpFactor(LONG db)
251 {
252     FIXME("(%d) Stub!\n", db);
253     /* Avoid divide by zero (probably during range computation) in Windows Media Player 6.4 */
254     if (db < -1000)
255         return 0;
256     return 100;
257 }
258
259 /***********************************************************************
260  *              AMGetErrorTextA (QUARTZ.@)
261  */
262 DWORD WINAPI AMGetErrorTextA(HRESULT hr, LPSTR buffer, DWORD maxlen)
263 {
264     unsigned int len;
265     static const char format[] = "Error: 0x%x";
266     char error[MAX_ERROR_TEXT_LEN];
267
268     FIXME("(%x,%p,%d) stub\n", hr, buffer, maxlen);
269
270     if (!buffer) return 0;
271     wsprintfA(error, format, hr);
272     if ((len = strlen(error)) >= maxlen) return 0;
273     lstrcpyA(buffer, error);
274     return len;
275 }
276
277 /***********************************************************************
278  *              AMGetErrorTextW (QUARTZ.@)
279  */
280 DWORD WINAPI AMGetErrorTextW(HRESULT hr, LPWSTR buffer, DWORD maxlen)
281 {
282     unsigned int len;
283     static const WCHAR format[] = {'E','r','r','o','r',':',' ','0','x','%','l','x',0};
284     WCHAR error[MAX_ERROR_TEXT_LEN];
285
286     FIXME("(%x,%p,%d) stub\n", hr, buffer, maxlen);
287
288     if (!buffer) return 0;
289     wsprintfW(error, format, hr);
290     if ((len = strlenW(error)) >= maxlen) return 0;
291     lstrcpyW(buffer, error);
292     return len;
293 }