janitorial: Remove remaining NULL checks before free() (found by Smatch).
[wine] / dlls / ddraw / tests / refcount.c
1 /*
2  * Some unit tests for ddraw reference counting
3  *
4  * Copyright (C) 2006 Stefan Dösinger
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 #define COBJMACROS
21
22 #include <assert.h>
23 #include "wine/test.h"
24 #include "ddraw.h"
25 #include "d3d.h"
26 #include "unknwn.h"
27
28 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
29
30 static void init_function_pointers(void)
31 {
32     HMODULE hmod = GetModuleHandleA("ddraw.dll");
33
34     if(hmod)
35     {
36         pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
37     }
38 }
39
40 unsigned long getRefcount(IUnknown *iface)
41 {
42     IUnknown_AddRef(iface);
43     return IUnknown_Release(iface);
44 }
45
46 static void test_ddraw_objects(void)
47 {
48     HRESULT hr;
49     unsigned long ref;
50     IDirectDraw7 *DDraw7;
51     IDirectDraw4 *DDraw4;
52     IDirectDraw4 *DDraw2;
53     IDirectDraw4 *DDraw1;
54     IDirectDrawPalette *palette;
55     IDirectDrawSurface7 *surface;
56     PALETTEENTRY Table[256];
57     DDSURFACEDESC2 ddsd;
58
59     hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
60     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %lx\n", hr);
61     if(!DDraw7)
62     {
63         trace("Couldn't create DDraw interface, skipping tests\n");
64         return;
65     }
66
67     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
68     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
69     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
70     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
71     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
72     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
73
74     ref = getRefcount( (IUnknown *) DDraw7);
75     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
76
77     /* Fails without a cooplevel */
78     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
79     ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreatePalette returned %08lx\n", hr);
80
81     /* This check is before the cooplevel check */
82     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, (void *) 0xdeadbeef);
83     ok(hr == CLASS_E_NOAGGREGATION, "CreatePalette returned %08lx\n", hr);
84
85     hr = IDirectDraw7_SetCooperativeLevel(DDraw7, 0, DDSCL_NORMAL);
86     ok(hr == DD_OK, "SetCooperativeLevel failed with %08lx\n", hr);
87
88     memset(&ddsd, 0, sizeof(ddsd));
89     ddsd.dwSize = sizeof(ddsd);
90     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
91     ddsd.dwWidth = 64;
92     ddsd.dwHeight = 64;
93     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
94     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
95     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
96     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
97
98     hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd, &surface, NULL);
99     ok(hr == DD_OK, "CreateSurface failed with %08lx\n", hr);
100
101     /* DDraw refcount increased by 1 */
102     ref = getRefcount( (IUnknown *) DDraw7);
103     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
104
105     /* Surface refcount starts with 1 */
106     ref = getRefcount( (IUnknown *) surface);
107     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
108
109     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
110     ok(hr == DD_OK, "CreatePalette returned %08lx\n", hr);
111
112     /* DDraw refcount increased by 1 */
113     ref = getRefcount( (IUnknown *) DDraw7);
114     ok(ref == 3, "Got refcount %ld, expected 3\n", ref);
115
116     /* Palette starts with 1 */
117     ref = getRefcount( (IUnknown *) palette);
118     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
119
120     /* Test attaching a palette to a surface */
121     hr = IDirectDrawSurface7_SetPalette(surface, palette);
122     ok(hr == DD_OK, "IDirectDrawSurface_SetPalette failed with %08lx\n", hr);
123
124     /* Palette refcount increased, surface stays the same */
125     ref = getRefcount( (IUnknown *) palette);
126     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
127     ref = getRefcount( (IUnknown *) surface);
128     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
129
130     IDirectDrawSurface7_Release(surface);
131     /* Increased before - decrease now */
132     ref = getRefcount( (IUnknown *) DDraw7);
133     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
134
135     /* Releasing the surface detaches the palette */
136     ref = getRefcount( (IUnknown *) palette);
137     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
138
139     IDirectDrawPalette_Release(palette);
140
141     /* Increased before - decrease now */
142     ref = getRefcount( (IUnknown *) DDraw7);
143     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
144
145     /* Not all interfaces are AddRefed when a palette is created */
146     hr = IDirectDraw4_CreatePalette(DDraw4, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
147     ok(hr == DD_OK, "CreatePalette returned %08lx\n", hr);
148     ref = getRefcount( (IUnknown *) DDraw4);
149     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
150     IDirectDrawPalette_Release(palette);
151
152     /* No addref here */
153     hr = IDirectDraw2_CreatePalette(DDraw2, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
154     ok(hr == DD_OK, "CreatePalette returned %08lx\n", hr);
155     ref = getRefcount( (IUnknown *) DDraw2);
156     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
157     IDirectDrawPalette_Release(palette);
158
159     /* No addref here */
160     hr = IDirectDraw_CreatePalette(DDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
161     ok(hr == DD_OK, "CreatePalette returned %08lx\n", hr);
162     ref = getRefcount( (IUnknown *) DDraw1);
163     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
164     IDirectDrawPalette_Release(palette);
165
166     IDirectDraw7_Release(DDraw7);
167     IDirectDraw4_Release(DDraw4);
168     IDirectDraw2_Release(DDraw2);
169     IDirectDraw_Release(DDraw1);
170 }
171
172 static void test_iface_refcnt(void)
173 {
174     HRESULT hr;
175     IDirectDraw  *DDraw1;
176     IDirectDraw2 *DDraw2;
177     IDirectDraw4 *DDraw4;
178     IDirectDraw7 *DDraw7;
179     IDirect3D7   *D3D7;
180     IDirect3D3   *D3D3;
181     IDirect3D2   *D3D2;
182     IDirect3D    *D3D1;
183     long ref;
184
185     hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
186     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %lx\n", hr);
187     if(!DDraw7)
188     {
189         trace("Couldn't create DDraw interface, skipping tests\n");
190         return;
191     }
192
193     ref = getRefcount( (IUnknown *) DDraw7);
194     ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref);
195
196     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
197     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
198     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
199     ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08lx\n", hr);
200     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
201     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
202
203     /* All interfaces now have refcount 1! */
204     ref = getRefcount( (IUnknown *) DDraw7);
205     ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
206     ref = getRefcount( (IUnknown *) DDraw7);
207     ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
208     ref = getRefcount( (IUnknown *) DDraw4);
209     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
210     ref = getRefcount( (IUnknown *) DDraw2);
211     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
212     ref = getRefcount( (IUnknown *) DDraw1);
213     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
214
215     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7);
216     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
217
218     /* Apparently IDirectDrawX and IDirect3DX are linked together */
219     ref = getRefcount( (IUnknown *) D3D7);
220     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
221     ref = getRefcount( (IUnknown *) DDraw7);
222     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
223
224     IDirectDraw7_AddRef(DDraw7);
225     ref = getRefcount( (IUnknown *) D3D7);
226     ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref);
227     ref = getRefcount( (IUnknown *) DDraw7);
228     ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref);
229
230     IDirect3D7_Release(D3D7);
231     ref = getRefcount( (IUnknown *) D3D7);
232     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
233     ref = getRefcount( (IUnknown *) DDraw7);
234     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
235
236     /* Can't get older d3d interfaces. WHY????? */
237     hr = IDirectDraw7_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
238     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
239     if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
240
241     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
242     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
243     if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
244
245     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2);
246     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
247     if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
248
249     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
250     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
251     if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
252
253     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1);
254     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
255     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
256
257     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
258     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08lx\n", hr);
259     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
260
261     hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1);
262     todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08lx\n", hr);
263     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
264
265     /* Try an AddRef, it only affects the AddRefed interface */
266     IDirectDraw4_AddRef(DDraw4);
267     ref = getRefcount( (IUnknown *) DDraw7);
268     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */
269     ref = getRefcount( (IUnknown *) DDraw4);
270     ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */
271     ref = getRefcount( (IUnknown *) DDraw2);
272     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
273     ref = getRefcount( (IUnknown *) DDraw1);
274     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
275     ref = getRefcount( (IUnknown *) D3D7);
276     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */
277     IDirectDraw4_Release(DDraw4);
278
279     /* Make sure that they are one object, not different ones */
280     hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
281     ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08lx\n", hr);
282     /* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */
283     hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW);
284     ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08lx\n", hr);
285
286     /* All done, release all interfaces */
287     IDirectDraw7_Release(DDraw7);
288     IDirectDraw4_Release(DDraw4);
289     IDirectDraw2_Release(DDraw2);
290     IDirectDraw_Release(DDraw1);
291     IDirect3D7_Release(D3D7);
292 }
293
294 static void test_d3d_ifaces(void)
295 {
296     IDirectDraw *DDraw1;
297     IDirectDraw2 *DDraw2;
298     IDirectDraw4 *DDraw4;
299     IDirect3D *D3D1;
300     IDirect3D2 *D3D2;
301     IDirect3D3 *D3D3;
302     IDirect3D7 *D3D7;
303     HRESULT hr;
304     long ref;
305
306     hr = DirectDrawCreate(NULL, &DDraw1, NULL);
307     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %lx\n", hr);
308     if(!DDraw1)
309     {
310         trace("DirectDrawCreate failed with %08lx\n", hr);
311         return;
312     }
313
314     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2);
315     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
316     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4);
317     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
318
319     ref = getRefcount( (IUnknown *) DDraw4);
320     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
321     ref = getRefcount( (IUnknown *) DDraw2);
322     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
323     ref = getRefcount( (IUnknown *) DDraw1);
324     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
325
326     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
327     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
328     ref = getRefcount( (IUnknown *) DDraw4);
329     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
330     ref = getRefcount( (IUnknown *) DDraw2);
331     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
332     ref = getRefcount( (IUnknown *) DDraw1);
333     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
334     IDirect3D_Release(D3D1);
335
336     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
337     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
338     ref = getRefcount( (IUnknown *) DDraw4);
339     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
340     ref = getRefcount( (IUnknown *) DDraw2);
341     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
342     ref = getRefcount( (IUnknown *) DDraw1);
343     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
344     IDirect3D2_Release(D3D2);
345
346     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
347     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
348     ref = getRefcount( (IUnknown *) DDraw4);
349     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
350     ref = getRefcount( (IUnknown *) DDraw2);
351     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
352     ref = getRefcount( (IUnknown *) DDraw1);
353     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
354     IDirect3D3_Release(D3D3);
355
356     /* Try to AddRef the D3D3 interface that has been released already */
357     IDirect3D3_AddRef(D3D3);
358     ref = getRefcount( (IUnknown *) DDraw1);
359     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
360     ref = getRefcount( (IUnknown *) D3D3);
361     ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref);
362     /* The newer interfaces remain untouched */
363     ref = getRefcount( (IUnknown *) DDraw4);
364     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
365     ref = getRefcount( (IUnknown *) DDraw2);
366     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
367     IDirect3D3_Release(D3D3);
368     ref = getRefcount( (IUnknown *) DDraw1);
369     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
370     ref = getRefcount( (IUnknown *) DDraw1);
371     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
372
373     /* It is possible to query any IDirect3D interfaces from any IDirectDraw interface,
374      * Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces)
375      */
376     hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1);
377     ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
378     IDirect3D_Release(D3D1);
379     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1);
380     ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
381     IDirect3D_Release(D3D1);
382
383     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2);
384     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
385     IDirect3D_Release(D3D2);
386     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2);
387     ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
388     IDirect3D_Release(D3D2);
389
390     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3);
391     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
392     IDirect3D_Release(D3D3);
393     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3);
394     ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
395     IDirect3D_Release(D3D3);
396
397     /* This does NOT work */
398     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7);
399     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08lx\n", hr);
400     if(D3D7) IDirect3D_Release(D3D7);
401     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7);
402     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
403     if(D3D7) IDirect3D_Release(D3D7);
404     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7);
405     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
406     if(D3D7) IDirect3D_Release(D3D7);
407
408     /* Release the interfaces */
409     IDirectDraw4_Release(DDraw4);
410     IDirectDraw2_Release(DDraw2);
411     IDirectDraw_Release(DDraw1);
412 }
413
414 START_TEST(refcount)
415 {
416     init_function_pointers();
417     if(!pDirectDrawCreateEx)
418     {
419         trace("function DirectDrawCreateEx not available, skipping tests\n");
420         return;
421     }
422     test_ddraw_objects();
423     test_iface_refcnt();
424     test_d3d_ifaces();
425 }