ddraw: Creating surfaces with old interfaces doesn't addref.
[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 static 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     IDirectDraw2 *DDraw2;
53     IDirectDraw  *DDraw1;
54     IDirectDrawPalette *palette;
55     IDirectDrawSurface7 *surface;
56     IDirectDrawSurface *surface1;
57     IDirectDrawSurface4 *surface4;
58     PALETTEENTRY Table[256];
59     DDSURFACEDESC2 ddsd;
60
61     hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
62     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
63     if(!DDraw7)
64     {
65         trace("Couldn't create DDraw interface, skipping tests\n");
66         return;
67     }
68
69     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
70     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
71     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
72     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
73     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
74     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
75
76     ref = getRefcount( (IUnknown *) DDraw7);
77     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
78
79     /* Fails without a cooplevel */
80     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
81     ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreatePalette returned %08x\n", hr);
82
83     /* This check is before the cooplevel check */
84     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, (void *) 0xdeadbeef);
85     ok(hr == CLASS_E_NOAGGREGATION, "CreatePalette returned %08x\n", hr);
86
87     hr = IDirectDraw7_SetCooperativeLevel(DDraw7, 0, DDSCL_NORMAL);
88     ok(hr == DD_OK, "SetCooperativeLevel failed with %08x\n", hr);
89
90     memset(&ddsd, 0, sizeof(ddsd));
91     ddsd.dwSize = sizeof(ddsd);
92     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
93     ddsd.dwWidth = 64;
94     ddsd.dwHeight = 64;
95     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
96     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
97     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
98     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
99
100     hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd, &surface, NULL);
101     ok(hr == DD_OK, "CreateSurface failed with %08x\n", hr);
102
103     /* DDraw refcount increased by 1 */
104     ref = getRefcount( (IUnknown *) DDraw7);
105     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
106
107     /* Surface refcount starts with 1 */
108     ref = getRefcount( (IUnknown *) surface);
109     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
110
111     hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
112     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
113
114     /* DDraw refcount increased by 1 */
115     ref = getRefcount( (IUnknown *) DDraw7);
116     ok(ref == 3, "Got refcount %ld, expected 3\n", ref);
117
118     /* Palette starts with 1 */
119     ref = getRefcount( (IUnknown *) palette);
120     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
121
122     /* Test attaching a palette to a surface */
123     hr = IDirectDrawSurface7_SetPalette(surface, palette);
124     ok(hr == DD_OK, "IDirectDrawSurface_SetPalette failed with %08x\n", hr);
125
126     /* Palette refcount increased, surface stays the same */
127     ref = getRefcount( (IUnknown *) palette);
128     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
129     ref = getRefcount( (IUnknown *) surface);
130     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
131
132     IDirectDrawSurface7_Release(surface);
133     /* Increased before - decrease now */
134     ref = getRefcount( (IUnknown *) DDraw7);
135     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
136
137     /* Releasing the surface detaches the palette */
138     ref = getRefcount( (IUnknown *) palette);
139     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
140
141     IDirectDrawPalette_Release(palette);
142
143     /* Increased before - decrease now */
144     ref = getRefcount( (IUnknown *) DDraw7);
145     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
146
147     /* Not all interfaces are AddRefed when a palette is created */
148     hr = IDirectDraw4_CreatePalette(DDraw4, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
149     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
150     ref = getRefcount( (IUnknown *) DDraw4);
151     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
152     IDirectDrawPalette_Release(palette);
153
154     /* No addref here */
155     hr = IDirectDraw2_CreatePalette(DDraw2, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
156     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
157     ref = getRefcount( (IUnknown *) DDraw2);
158     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
159     IDirectDrawPalette_Release(palette);
160
161     /* No addref here */
162     hr = IDirectDraw_CreatePalette(DDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
163     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
164     ref = getRefcount( (IUnknown *) DDraw1);
165     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
166     IDirectDrawPalette_Release(palette);
167
168     /* Simmilar for surfaces */
169     hr = IDirectDraw4_CreateSurface(DDraw4, &ddsd, &surface4, NULL);
170     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
171     ref = getRefcount( (IUnknown *) DDraw4);
172     ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
173     IDirectDrawSurface4_Release(surface4);
174
175     ddsd.dwSize = sizeof(DDSURFACEDESC);
176     hr = IDirectDraw2_CreateSurface(DDraw2, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
177     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
178     ref = getRefcount( (IUnknown *) DDraw2);
179     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
180     IDirectDrawSurface_Release(surface1);
181
182     hr = IDirectDraw_CreateSurface(DDraw1, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
183     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
184     ref = getRefcount( (IUnknown *) DDraw1);
185     ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
186     IDirectDrawSurface_Release(surface1);
187
188     IDirectDraw7_Release(DDraw7);
189     IDirectDraw4_Release(DDraw4);
190     IDirectDraw2_Release(DDraw2);
191     IDirectDraw_Release(DDraw1);
192 }
193
194 static void test_iface_refcnt(void)
195 {
196     HRESULT hr;
197     IDirectDraw  *DDraw1;
198     IDirectDraw2 *DDraw2;
199     IDirectDraw4 *DDraw4;
200     IDirectDraw7 *DDraw7;
201     IDirect3D7   *D3D7;
202     IDirect3D3   *D3D3;
203     IDirect3D2   *D3D2;
204     IDirect3D    *D3D1;
205     long ref;
206
207     hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
208     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
209     if(!DDraw7)
210     {
211         trace("Couldn't create DDraw interface, skipping tests\n");
212         return;
213     }
214
215     ref = getRefcount( (IUnknown *) DDraw7);
216     ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref);
217
218     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
219     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
220     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
221     ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08x\n", hr);
222     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
223     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
224
225     /* All interfaces now have refcount 1! */
226     ref = getRefcount( (IUnknown *) DDraw7);
227     ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
228     ref = getRefcount( (IUnknown *) DDraw7);
229     ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
230     ref = getRefcount( (IUnknown *) DDraw4);
231     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
232     ref = getRefcount( (IUnknown *) DDraw2);
233     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
234     ref = getRefcount( (IUnknown *) DDraw1);
235     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
236
237     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7);
238     ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
239
240     /* Apparently IDirectDrawX and IDirect3DX are linked together */
241     ref = getRefcount( (IUnknown *) D3D7);
242     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
243     ref = getRefcount( (IUnknown *) DDraw7);
244     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
245
246     IDirectDraw7_AddRef(DDraw7);
247     ref = getRefcount( (IUnknown *) D3D7);
248     ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref);
249     ref = getRefcount( (IUnknown *) DDraw7);
250     ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref);
251
252     IDirect3D7_Release(D3D7);
253     ref = getRefcount( (IUnknown *) D3D7);
254     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
255     ref = getRefcount( (IUnknown *) DDraw7);
256     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
257
258     /* Can't get older d3d interfaces. WHY????? */
259     hr = IDirectDraw7_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
260     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
261     if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
262
263     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
264     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
265     if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
266
267     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2);
268     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
269     if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
270
271     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
272     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
273     if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
274
275     hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1);
276     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
277     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
278
279     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
280     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
281     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
282
283     hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1);
284     todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08x\n", hr);
285     if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
286
287     /* Try an AddRef, it only affects the AddRefed interface */
288     IDirectDraw4_AddRef(DDraw4);
289     ref = getRefcount( (IUnknown *) DDraw7);
290     ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */
291     ref = getRefcount( (IUnknown *) DDraw4);
292     ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */
293     ref = getRefcount( (IUnknown *) DDraw2);
294     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
295     ref = getRefcount( (IUnknown *) DDraw1);
296     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
297     ref = getRefcount( (IUnknown *) D3D7);
298     ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */
299     IDirectDraw4_Release(DDraw4);
300
301     /* Make sure that they are one object, not different ones */
302     hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
303     ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08x\n", hr);
304     /* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */
305     hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW);
306     ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08x\n", hr);
307
308     /* All done, release all interfaces */
309     IDirectDraw7_Release(DDraw7);
310     IDirectDraw4_Release(DDraw4);
311     IDirectDraw2_Release(DDraw2);
312     IDirectDraw_Release(DDraw1);
313     IDirect3D7_Release(D3D7);
314 }
315
316 static void test_d3d_ifaces(void)
317 {
318     IDirectDraw *DDraw1;
319     IDirectDraw2 *DDraw2;
320     IDirectDraw4 *DDraw4;
321     IDirect3D *D3D1;
322     IDirect3D2 *D3D2;
323     IDirect3D3 *D3D3;
324     IDirect3D7 *D3D7;
325     HRESULT hr;
326     long ref;
327
328     hr = DirectDrawCreate(NULL, &DDraw1, NULL);
329     ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
330     if(!DDraw1)
331     {
332         trace("DirectDrawCreate failed with %08x\n", hr);
333         return;
334     }
335
336     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2);
337     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
338     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4);
339     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
340
341     ref = getRefcount( (IUnknown *) DDraw4);
342     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
343     ref = getRefcount( (IUnknown *) DDraw2);
344     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
345     ref = getRefcount( (IUnknown *) DDraw1);
346     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
347
348     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
349     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
350     ref = getRefcount( (IUnknown *) DDraw4);
351     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
352     ref = getRefcount( (IUnknown *) DDraw2);
353     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
354     ref = getRefcount( (IUnknown *) DDraw1);
355     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
356     IDirect3D_Release(D3D1);
357
358     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
359     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
360     ref = getRefcount( (IUnknown *) DDraw4);
361     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
362     ref = getRefcount( (IUnknown *) DDraw2);
363     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
364     ref = getRefcount( (IUnknown *) DDraw1);
365     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
366     IDirect3D2_Release(D3D2);
367
368     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
369     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
370     ref = getRefcount( (IUnknown *) DDraw4);
371     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
372     ref = getRefcount( (IUnknown *) DDraw2);
373     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
374     ref = getRefcount( (IUnknown *) DDraw1);
375     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
376     IDirect3D3_Release(D3D3);
377
378     /* Try to AddRef the D3D3 interface that has been released already */
379     IDirect3D3_AddRef(D3D3);
380     ref = getRefcount( (IUnknown *) DDraw1);
381     ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
382     ref = getRefcount( (IUnknown *) D3D3);
383     ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref);
384     /* The newer interfaces remain untouched */
385     ref = getRefcount( (IUnknown *) DDraw4);
386     ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
387     ref = getRefcount( (IUnknown *) DDraw2);
388     ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
389     IDirect3D3_Release(D3D3);
390     ref = getRefcount( (IUnknown *) DDraw1);
391     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
392     ref = getRefcount( (IUnknown *) DDraw1);
393     ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
394
395     /* It is possible to query any IDirect3D interfaces from any IDirectDraw interface,
396      * Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces)
397      */
398     hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1);
399     ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
400     IDirect3D_Release(D3D1);
401     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1);
402     ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
403     IDirect3D_Release(D3D1);
404
405     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2);
406     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
407     IDirect3D_Release(D3D2);
408     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2);
409     ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
410     IDirect3D_Release(D3D2);
411
412     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3);
413     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
414     IDirect3D_Release(D3D3);
415     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3);
416     ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
417     IDirect3D_Release(D3D3);
418
419     /* This does NOT work */
420     hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7);
421     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
422     if(D3D7) IDirect3D_Release(D3D7);
423     hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7);
424     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
425     if(D3D7) IDirect3D_Release(D3D7);
426     hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7);
427     todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
428     if(D3D7) IDirect3D_Release(D3D7);
429
430     /* Release the interfaces */
431     IDirectDraw4_Release(DDraw4);
432     IDirectDraw2_Release(DDraw2);
433     IDirectDraw_Release(DDraw1);
434 }
435
436 START_TEST(refcount)
437 {
438     init_function_pointers();
439     if(!pDirectDrawCreateEx)
440     {
441         trace("function DirectDrawCreateEx not available, skipping tests\n");
442         return;
443     }
444     test_ddraw_objects();
445     test_iface_refcnt();
446     test_d3d_ifaces();
447 }