propsys/tests: Added PropVariantToGUID tests.
[wine] / dlls / ddrawex / main.c
1 /*        DirectDrawEx
2  *
3  * Copyright 2006 Ulrich Czekalla
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
24 #include "wine/debug.h"
25
26 #define COBJMACROS
27
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "objbase.h"
31 #include "rpcproxy.h"
32
33 #include "ddraw.h"
34
35 #include "initguid.h"
36 #include "ddrawex_private.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);
39
40 static HINSTANCE instance;
41
42 /******************************************************************************
43  * DirectDraw ClassFactory implementation
44  ******************************************************************************/
45 typedef struct
46 {
47     IClassFactory IClassFactory_iface;
48     LONG ref;
49     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID *ppObj);
50 } IClassFactoryImpl;
51
52 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
53 {
54     return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
55 }
56
57 /*******************************************************************************
58  * IDirectDrawClassFactory::QueryInterface
59  *
60  *******************************************************************************/
61 static HRESULT WINAPI IDirectDrawClassFactoryImpl_QueryInterface(IClassFactory *iface, REFIID riid,
62         void **obj)
63 {
64     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
65
66     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj);
67
68     if (IsEqualGUID(riid, &IID_IUnknown)
69         || IsEqualGUID(riid, &IID_IClassFactory))
70     {
71         IClassFactory_AddRef(iface);
72         *obj = This;
73         return S_OK;
74     }
75
76     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),obj);
77     return E_NOINTERFACE;
78 }
79
80 /*******************************************************************************
81  * IDirectDrawClassFactory::AddRef
82  *
83  *******************************************************************************/
84 static ULONG WINAPI IDirectDrawClassFactoryImpl_AddRef(IClassFactory *iface)
85 {
86     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
87     ULONG ref = InterlockedIncrement(&This->ref);
88
89     TRACE("(%p)->() incrementing from %d.\n", This, ref - 1);
90
91     return ref;
92 }
93
94 /*******************************************************************************
95  * IDirectDrawClassFactory::Release
96  *
97  *******************************************************************************/
98 static ULONG WINAPI IDirectDrawClassFactoryImpl_Release(IClassFactory *iface)
99 {
100     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
101     ULONG ref = InterlockedDecrement(&This->ref);
102
103     TRACE("(%p)->() decrementing from %d.\n", This, ref+1);
104
105     if (ref == 0)
106         HeapFree(GetProcessHeap(), 0, This);
107
108     return ref;
109 }
110
111
112 /*******************************************************************************
113  * IDirectDrawClassFactory::CreateInstance
114  *
115  *******************************************************************************/
116 static HRESULT WINAPI IDirectDrawClassFactoryImpl_CreateInstance(IClassFactory *iface,
117         IUnknown *UnkOuter, REFIID riid, void **obj)
118 {
119     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
120
121     TRACE("(%p)->(%p,%s,%p)\n",This,UnkOuter,debugstr_guid(riid),obj);
122
123     return This->pfnCreateInstance(UnkOuter, riid, obj);
124 }
125
126 /*******************************************************************************
127  * IDirectDrawClassFactory::LockServer
128  *
129  *******************************************************************************/
130 static HRESULT WINAPI IDirectDrawClassFactoryImpl_LockServer(IClassFactory *iface,BOOL dolock)
131 {
132     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
133
134     FIXME("(%p)->(%d),stub!\n",This,dolock);
135
136     return S_OK;
137 }
138
139
140 /*******************************************************************************
141  * The class factory VTable
142  *******************************************************************************/
143 static const IClassFactoryVtbl IClassFactory_Vtbl =
144 {
145     IDirectDrawClassFactoryImpl_QueryInterface,
146     IDirectDrawClassFactoryImpl_AddRef,
147     IDirectDrawClassFactoryImpl_Release,
148     IDirectDrawClassFactoryImpl_CreateInstance,
149     IDirectDrawClassFactoryImpl_LockServer
150 };
151
152
153 /******************************************************************************
154  * DirectDrawFactory implementation
155  ******************************************************************************/
156 typedef struct
157 {
158     IDirectDrawFactory IDirectDrawFactory_iface;
159     LONG ref;
160 } IDirectDrawFactoryImpl;
161
162 static inline IDirectDrawFactoryImpl *impl_from_IDirectDrawFactory(IDirectDrawFactory *iface)
163 {
164     return CONTAINING_RECORD(iface, IDirectDrawFactoryImpl, IDirectDrawFactory_iface);
165 }
166
167 /*******************************************************************************
168  * IDirectDrawFactory::QueryInterface
169  *
170  *******************************************************************************/
171 static HRESULT WINAPI IDirectDrawFactoryImpl_QueryInterface(IDirectDrawFactory *iface, REFIID riid,
172         void **obj)
173 {
174     IDirectDrawFactoryImpl *This = impl_from_IDirectDrawFactory(iface);
175
176     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj);
177
178     if (IsEqualGUID(riid, &IID_IUnknown)
179         || IsEqualGUID(riid, &IID_IDirectDrawFactory))
180     {
181         IDirectDrawFactory_AddRef(iface);
182         *obj = This;
183         return S_OK;
184     }
185
186     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),obj);
187     return E_NOINTERFACE;
188 }
189
190 /*******************************************************************************
191  * IDirectDrawFactory::AddRef
192  *
193  *******************************************************************************/
194 static ULONG WINAPI IDirectDrawFactoryImpl_AddRef(IDirectDrawFactory *iface)
195 {
196     IDirectDrawFactoryImpl *This = impl_from_IDirectDrawFactory(iface);
197     ULONG ref = InterlockedIncrement(&This->ref);
198
199     TRACE("(%p)->() incrementing from %d.\n", This, ref - 1);
200
201     return ref;
202 }
203
204 /*******************************************************************************
205  * IDirectDrawFactory::Release
206  *
207  *******************************************************************************/
208 static ULONG WINAPI IDirectDrawFactoryImpl_Release(IDirectDrawFactory *iface)
209 {
210     IDirectDrawFactoryImpl *This = impl_from_IDirectDrawFactory(iface);
211     ULONG ref = InterlockedDecrement(&This->ref);
212
213     TRACE("(%p)->() decrementing from %d.\n", This, ref+1);
214
215     if (ref == 0)
216         HeapFree(GetProcessHeap(), 0, This);
217
218     return ref;
219 }
220
221 /*******************************************************************************
222  * IDirectDrawFactoryImpl_DirectDrawEnumerate
223  *******************************************************************************/
224 static HRESULT WINAPI
225 IDirectDrawFactoryImpl_DirectDrawEnumerate(IDirectDrawFactory* iface,
226                                            LPDDENUMCALLBACKW lpCallback,
227                                            LPVOID lpContext)
228 {
229     FIXME("Stub!\n");
230     return E_FAIL;
231 }
232
233
234 /*******************************************************************************
235  * Direct Draw Factory VTable
236  *******************************************************************************/
237 static const IDirectDrawFactoryVtbl IDirectDrawFactory_Vtbl =
238 {
239     IDirectDrawFactoryImpl_QueryInterface,
240     IDirectDrawFactoryImpl_AddRef,
241     IDirectDrawFactoryImpl_Release,
242     IDirectDrawFactoryImpl_CreateDirectDraw,
243     IDirectDrawFactoryImpl_DirectDrawEnumerate,
244 };
245
246 /***********************************************************************
247  * CreateDirectDrawFactory
248  *
249  ***********************************************************************/
250 static HRESULT
251 CreateDirectDrawFactory(IUnknown* UnkOuter, REFIID iid, void **obj)
252 {
253     HRESULT hr;
254     IDirectDrawFactoryImpl *This = NULL;
255
256     TRACE("(%p,%s,%p)\n", UnkOuter, debugstr_guid(iid), obj);
257
258     if (UnkOuter != NULL)
259         return CLASS_E_NOAGGREGATION;
260
261     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawFactoryImpl));
262
263     if(!This)
264     {
265         ERR("Out of memory when creating DirectDraw\n");
266         return E_OUTOFMEMORY;
267     }
268
269     This->IDirectDrawFactory_iface.lpVtbl = &IDirectDrawFactory_Vtbl;
270
271     hr = IDirectDrawFactory_QueryInterface(&This->IDirectDrawFactory_iface, iid,  obj);
272
273     if (FAILED(hr))
274         HeapFree(GetProcessHeap(), 0, This);
275
276     return hr;
277 }
278
279
280 /*******************************************************************************
281  * DllCanUnloadNow [DDRAWEX.@]  Determines whether the DLL is in use.
282  */
283 HRESULT WINAPI DllCanUnloadNow(void)
284 {
285     return S_FALSE;
286 }
287
288
289 /*******************************************************************************
290  * DllGetClassObject [DDRAWEX.@]
291  */
292 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
293 {
294     IClassFactoryImpl *factory;
295
296     TRACE("ddrawex (%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
297
298     if (!IsEqualGUID( &IID_IClassFactory, riid)
299         && !IsEqualGUID( &IID_IUnknown, riid))
300         return E_NOINTERFACE;
301
302     if (!IsEqualGUID(&CLSID_DirectDrawFactory, rclsid))
303     {
304         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
305         return CLASS_E_CLASSNOTAVAILABLE;
306     }
307
308     factory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*factory));
309     if (factory == NULL) return E_OUTOFMEMORY;
310
311     factory->IClassFactory_iface.lpVtbl = &IClassFactory_Vtbl;
312     factory->ref = 1;
313
314     factory->pfnCreateInstance = CreateDirectDrawFactory;
315
316     *ppv = factory;
317
318     return S_OK;
319 }
320
321
322 /***********************************************************************
323  * DllMain
324  */
325 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID lpv)
326 {
327     switch (reason)
328     {
329     case DLL_PROCESS_ATTACH:
330         instance = hInstDLL;
331         DisableThreadLibraryCalls( hInstDLL );
332         break;
333     }
334     return TRUE;
335 }
336
337 /***********************************************************************
338  *              DllRegisterServer (DDRAWEX.@)
339  */
340 HRESULT WINAPI DllRegisterServer(void)
341 {
342     return __wine_register_resources( instance );
343 }
344
345 /***********************************************************************
346  *              DllUnregisterServer (DDRAWEX.@)
347  */
348 HRESULT WINAPI DllUnregisterServer(void)
349 {
350     return __wine_unregister_resources( instance );
351 }