2 * Some unit tests for ddraw reference counting
4 * Copyright (C) 2006 Stefan Dösinger
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.
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.
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
22 #include "wine/test.h"
27 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
29 static void init_function_pointers(void)
31 HMODULE hmod = GetModuleHandleA("ddraw.dll");
32 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
35 static ULONG getRefcount(IUnknown *iface)
37 IUnknown_AddRef(iface);
38 return IUnknown_Release(iface);
41 static void test_ddraw_objects(void)
49 IDirectDrawPalette *palette;
50 IDirectDrawSurface7 *surface = NULL, *stencil;
51 IDirectDrawSurface *surface1, *stencil1;
52 IDirectDrawSurface4 *surface4;
53 PALETTEENTRY Table[256];
54 DDSURFACEDESC2 ddsd, ddsd_stencil;
56 hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
57 ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
60 trace("Couldn't create DDraw interface, skipping tests\n");
64 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
65 ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
66 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
67 ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
68 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
69 ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
71 ref = getRefcount( (IUnknown *) DDraw7);
72 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
74 /* Fails without a cooplevel */
75 hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
76 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreatePalette returned %08x\n", hr);
78 /* This check is before the cooplevel check */
79 hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, (void *) 0xdeadbeef);
80 ok(hr == CLASS_E_NOAGGREGATION, "CreatePalette returned %08x\n", hr);
82 hr = IDirectDraw7_SetCooperativeLevel(DDraw7, 0, DDSCL_NORMAL);
83 ok(hr == DD_OK, "SetCooperativeLevel failed with %08x\n", hr);
85 memset(&ddsd, 0, sizeof(ddsd));
86 ddsd.dwSize = sizeof(ddsd);
87 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
90 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
91 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
92 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
93 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
95 memset(&ddsd_stencil, 0, sizeof(ddsd_stencil));
96 ddsd_stencil.dwSize = sizeof(ddsd_stencil);
97 ddsd_stencil.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
98 ddsd_stencil.dwWidth = ddsd.dwWidth;
99 ddsd_stencil.dwHeight = ddsd.dwHeight;
100 ddsd_stencil.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
101 U4(ddsd_stencil).ddpfPixelFormat.dwSize = sizeof(U4(ddsd_stencil).ddpfPixelFormat);
102 U4(ddsd_stencil).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
103 U1(U4(ddsd_stencil).ddpfPixelFormat).dwZBufferBitDepth = 16;
104 U3(U4(ddsd_stencil).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
106 hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd, &surface, NULL);
109 win_skip("Could not create surface : %08x\n", hr);
110 IDirectDraw7_Release(DDraw7);
113 ok(hr == DD_OK, "CreateSurface failed with %08x\n", hr);
115 /* DDraw refcount increased by 1 */
116 ref = getRefcount( (IUnknown *) DDraw7);
117 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
119 /* Surface refcount starts with 1 */
120 ref = getRefcount( (IUnknown *) surface);
121 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
123 hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
124 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
126 /* DDraw refcount increased by 1 */
127 ref = getRefcount( (IUnknown *) DDraw7);
128 ok(ref == 3, "Got refcount %d, expected 3\n", ref);
130 /* Palette starts with 1 */
131 ref = getRefcount( (IUnknown *) palette);
132 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
134 /* Test attaching a palette to a surface */
135 hr = IDirectDrawSurface7_SetPalette(surface, palette);
136 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette failed with %08x\n", hr);
138 /* Palette refcount increased, surface stays the same */
139 ref = getRefcount( (IUnknown *) palette);
140 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
141 ref = getRefcount( (IUnknown *) surface);
142 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
144 IDirectDrawSurface7_Release(surface);
145 /* Increased before - decrease now */
146 ref = getRefcount( (IUnknown *) DDraw7);
147 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
149 /* Releasing the surface detaches the palette */
150 ref = getRefcount( (IUnknown *) palette);
151 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
153 IDirectDrawPalette_Release(palette);
155 /* Increased before - decrease now */
156 ref = getRefcount( (IUnknown *) DDraw7);
157 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
159 /* Not all interfaces are AddRefed when a palette is created */
160 hr = IDirectDraw4_CreatePalette(DDraw4, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
161 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
162 ref = getRefcount( (IUnknown *) DDraw4);
163 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
164 IDirectDrawPalette_Release(palette);
167 hr = IDirectDraw2_CreatePalette(DDraw2, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
168 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
169 ref = getRefcount( (IUnknown *) DDraw2);
170 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
171 IDirectDrawPalette_Release(palette);
174 hr = IDirectDraw_CreatePalette(DDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
175 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
176 ref = getRefcount( (IUnknown *) DDraw1);
177 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
178 IDirectDrawPalette_Release(palette);
180 /* Similar for surfaces */
181 hr = IDirectDraw4_CreateSurface(DDraw4, &ddsd, &surface4, NULL);
182 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
183 ref = getRefcount( (IUnknown *) DDraw4);
184 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
185 IDirectDrawSurface4_Release(surface4);
187 ddsd.dwSize = sizeof(DDSURFACEDESC);
188 hr = IDirectDraw2_CreateSurface(DDraw2, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
189 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
190 ref = getRefcount( (IUnknown *) DDraw2);
191 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
192 IDirectDrawSurface_Release(surface1);
194 hr = IDirectDraw_CreateSurface(DDraw1, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
195 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
196 ref = getRefcount( (IUnknown *) DDraw1);
197 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
198 IDirectDrawSurface_Release(surface1);
200 /* AddAttachedSurface with IDirectDrawSurface7 */
201 ddsd.dwSize = sizeof(DDSURFACEDESC2);
202 ddsd.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
203 hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd, &surface, NULL);
204 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
207 ddsd_stencil.dwSize = sizeof(DDSURFACEDESC2);
208 hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd_stencil, &stencil, NULL);
209 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
212 /* AddAttachedSurface with DeleteAttachedSurface */
213 hr = IDirectDrawSurface7_AddAttachedSurface(surface, stencil);
214 ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
217 ref = getRefcount( (IUnknown *) stencil);
218 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
219 hr = IDirectDrawSurface7_DeleteAttachedSurface(surface, 0, stencil);
220 ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
221 ref = getRefcount( (IUnknown *) stencil);
222 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
225 /* Releasing a surface should detach any attached surfaces */
226 hr = IDirectDrawSurface7_AddAttachedSurface(surface, stencil);
227 ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
228 ref = getRefcount( (IUnknown *) stencil);
229 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
230 ref = IDirectDrawSurface7_Release(surface);
231 ok(!ref, "Got refcount %d, expected 0\n", ref);
232 ref = getRefcount( (IUnknown *) stencil);
233 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
234 ref = IDirectDrawSurface7_Release(stencil);
235 ok(!ref, "Got refcount %d, expected 0\n", ref);
238 IDirectDrawSurface7_Release(surface);
241 /* AddAttachedSurface with IDirectDrawSurface */
242 ddsd.dwSize = sizeof(DDSURFACEDESC);
243 hr = IDirectDraw_CreateSurface(DDraw1, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
244 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
247 ddsd_stencil.dwSize = sizeof(DDSURFACEDESC);
248 hr = IDirectDraw_CreateSurface(DDraw1, (DDSURFACEDESC *) &ddsd_stencil, &stencil1, NULL);
249 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
252 /* AddAttachedSurface with DeleteAttachedSurface */
253 hr = IDirectDrawSurface_AddAttachedSurface(surface1, stencil1);
254 ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
257 ref = getRefcount( (IUnknown *) stencil1);
258 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
259 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, stencil1);
260 ok(hr == DD_OK, "DeleteAttachedSurface returned %08x\n", hr);
261 ref = getRefcount( (IUnknown *) stencil1);
262 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
265 /* Releasing a surface should detach any attached surfaces */
266 hr = IDirectDrawSurface_AddAttachedSurface(surface1, stencil1);
267 ok(hr == DD_OK, "AddAttachedSurface returned %08x\n", hr);
268 ref = getRefcount( (IUnknown *) stencil1);
269 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
270 ref = IDirectDrawSurface_Release(surface1);
271 ok(!ref, "Got refcount %d, expected 0\n", ref);
272 ref = getRefcount( (IUnknown *) stencil1);
273 todo_wine ok(ref == 1, "Got refcount %d, expected 1\n", ref);
274 ref = IDirectDrawSurface_Release(stencil1);
275 todo_wine ok(!ref, "Got refcount %d, expected 0\n", ref);
278 IDirectDrawSurface_Release(surface1);
281 IDirectDraw7_Release(DDraw7);
282 IDirectDraw4_Release(DDraw4);
283 IDirectDraw2_Release(DDraw2);
284 IDirectDraw_Release(DDraw1);
287 static void test_iface_refcnt(void)
291 IDirectDraw2 *DDraw2;
292 IDirectDraw4 *DDraw4;
293 IDirectDraw7 *DDraw7;
300 hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
301 ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
304 trace("Couldn't create DDraw interface, skipping tests\n");
308 ref = getRefcount( (IUnknown *) DDraw7);
309 ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref);
311 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
312 ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
313 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
314 ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08x\n", hr);
315 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
316 ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
318 /* All interfaces now have refcount 1! */
319 ref = getRefcount( (IUnknown *) DDraw7);
320 ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
321 ref = getRefcount( (IUnknown *) DDraw7);
322 ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
323 ref = getRefcount( (IUnknown *) DDraw4);
324 ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
325 ref = getRefcount( (IUnknown *) DDraw2);
326 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
327 ref = getRefcount( (IUnknown *) DDraw1);
328 ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
330 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7);
331 ok(hr == DD_OK || hr == E_NOINTERFACE, /* win64 */
332 "IDirectDraw7_QueryInterface returned %08x\n", hr);
335 IDirectDraw7_Release(DDraw7);
336 IDirectDraw4_Release(DDraw4);
337 IDirectDraw2_Release(DDraw2);
338 IDirectDraw_Release(DDraw1);
339 skip( "no IDirect3D7 support\n" );
343 /* Apparently IDirectDrawX and IDirect3DX are linked together */
344 ref = getRefcount( (IUnknown *) D3D7);
345 ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
346 ref = getRefcount( (IUnknown *) DDraw7);
347 ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
349 IDirectDraw7_AddRef(DDraw7);
350 ref = getRefcount( (IUnknown *) D3D7);
351 ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref);
352 ref = getRefcount( (IUnknown *) DDraw7);
353 ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref);
355 IDirect3D7_Release(D3D7);
356 ref = getRefcount( (IUnknown *) D3D7);
357 ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
358 ref = getRefcount( (IUnknown *) DDraw7);
359 ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
361 /* Can't get older d3d interfaces. WHY????? */
362 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D3, (void **) &D3D3);
363 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
364 if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
366 hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
367 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
368 if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
370 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2);
371 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
372 if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
374 hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
375 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
376 if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
378 hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1);
379 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
380 if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
382 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
383 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
384 if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
386 hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1);
387 todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08x\n", hr);
388 if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
390 /* Try an AddRef, it only affects the AddRefed interface */
391 IDirectDraw4_AddRef(DDraw4);
392 ref = getRefcount( (IUnknown *) DDraw7);
393 ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */
394 ref = getRefcount( (IUnknown *) DDraw4);
395 ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */
396 ref = getRefcount( (IUnknown *) DDraw2);
397 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
398 ref = getRefcount( (IUnknown *) DDraw1);
399 ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
400 ref = getRefcount( (IUnknown *) D3D7);
401 ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */
402 IDirectDraw4_Release(DDraw4);
404 /* Make sure that they are one object, not different ones */
405 hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
406 ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08x\n", hr);
407 /* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */
408 hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW);
409 ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08x\n", hr);
411 /* All done, release all interfaces */
412 IDirectDraw7_Release(DDraw7);
413 IDirectDraw4_Release(DDraw4);
414 IDirectDraw2_Release(DDraw2);
415 IDirectDraw_Release(DDraw1);
416 IDirect3D7_Release(D3D7);
419 static void test_d3d_ifaces(void)
422 IDirectDraw2 *DDraw2;
423 IDirectDraw4 *DDraw4;
431 hr = DirectDrawCreate(NULL, &DDraw1, NULL);
432 ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
435 trace("DirectDrawCreate failed with %08x\n", hr);
439 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2);
440 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
441 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4);
442 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
444 ref = getRefcount( (IUnknown *) DDraw4);
445 ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
446 ref = getRefcount( (IUnknown *) DDraw2);
447 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
448 ref = getRefcount( (IUnknown *) DDraw1);
449 ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
451 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
452 if (hr == E_NOINTERFACE) /* win64 */
454 IDirectDraw4_Release(DDraw4);
455 IDirectDraw2_Release(DDraw2);
456 IDirectDraw_Release(DDraw1);
457 skip( "no IDirect3D support\n" );
460 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
461 ref = getRefcount( (IUnknown *) DDraw4);
462 ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
463 ref = getRefcount( (IUnknown *) DDraw2);
464 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
465 ref = getRefcount( (IUnknown *) DDraw1);
466 ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
467 IDirect3D_Release(D3D1);
469 hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
470 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
471 ref = getRefcount( (IUnknown *) DDraw4);
472 ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
473 ref = getRefcount( (IUnknown *) DDraw2);
474 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
475 ref = getRefcount( (IUnknown *) DDraw1);
476 ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
477 IDirect3D2_Release(D3D2);
479 hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
480 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
481 ref = getRefcount( (IUnknown *) DDraw4);
482 ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
483 ref = getRefcount( (IUnknown *) DDraw2);
484 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
485 ref = getRefcount( (IUnknown *) DDraw1);
486 ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
487 IDirect3D3_Release(D3D3);
489 /* Try to AddRef the D3D3 interface that has been released already */
490 IDirect3D3_AddRef(D3D3);
491 ref = getRefcount( (IUnknown *) DDraw1);
492 ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
493 ref = getRefcount( (IUnknown *) D3D3);
494 ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref);
495 /* The newer interfaces remain untouched */
496 ref = getRefcount( (IUnknown *) DDraw4);
497 ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
498 ref = getRefcount( (IUnknown *) DDraw2);
499 ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
500 IDirect3D3_Release(D3D3);
501 ref = getRefcount( (IUnknown *) DDraw1);
502 ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
503 ref = getRefcount( (IUnknown *) DDraw1);
504 ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
506 /* It is possible to query any IDirect3D interfaces from any IDirectDraw interface,
507 * Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces)
509 hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1);
510 ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
511 IDirect3D_Release(D3D1);
512 hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1);
513 ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
514 IDirect3D_Release(D3D1);
516 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2);
517 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
518 IDirect3D_Release(D3D2);
519 hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2);
520 ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
521 IDirect3D_Release(D3D2);
523 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3);
524 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
525 IDirect3D_Release(D3D3);
526 hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3);
527 ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
528 IDirect3D_Release(D3D3);
530 /* This does NOT work */
531 hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7);
532 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
533 if(D3D7) IDirect3D_Release(D3D7);
534 hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7);
535 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
536 if(D3D7) IDirect3D_Release(D3D7);
537 hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7);
538 todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
539 if(D3D7) IDirect3D_Release(D3D7);
541 /* Release the interfaces */
542 IDirectDraw4_Release(DDraw4);
543 IDirectDraw2_Release(DDraw2);
544 IDirectDraw_Release(DDraw1);
549 init_function_pointers();
550 if(!pDirectDrawCreateEx)
552 win_skip("function DirectDrawCreateEx not available\n");
555 test_ddraw_objects();