[7/10] DDraw: Test and fix IDirectDrawSurfaceX::GetDDInterface

Stefan Dösinger stefan at codeweavers.com
Fri Feb 16 12:09:19 CST 2007


-------------- next part --------------
From a447b27895beff4e0ac91cc4e6820b165891a363 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Tue, 13 Feb 2007 18:16:01 +0100
Subject: [PATCH] DDraw: Test and fix IDirectDrawSurfaceX::GetDDInterface

---
 dlls/ddraw/surface.c        |   10 +-
 dlls/ddraw/tests/dsurface.c |  284 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 290 insertions(+), 4 deletions(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index c41d08f..5eca9c2 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -1667,10 +1667,7 @@ IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7 *iface,
 {
     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
 
-    /* It is not quite correct to use the same lpVtable for the different
-     * IDirectDrawSurface versions because the GetDDInterface return different interfaces
-     */
-    FIXME("(%p)->(%p)\n",This,DD);
+    TRACE("(%p)->(%p)\n",This,DD);
 
     if(!DD)
         return DDERR_INVALIDPARAMS;
@@ -1685,8 +1682,13 @@ IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7 *iface,
         case 4:
             *((IDirectDraw4 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
             IDirectDraw4_AddRef(*(IDirectDraw4 **) DD);
+            break;
 
         case 2:
+            *((IDirectDraw2 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
+            IDirectDraw_AddRef( *(IDirectDraw2 **) DD);
+            break;
+
         case 1:
             *((IDirectDraw **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw);
             IDirectDraw_AddRef( *(IDirectDraw **) DD);
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index 5e7f649..2d5a625 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -19,10 +19,12 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
+#define COBJMACROS
 
 #include <assert.h>
 #include "wine/test.h"
 #include "ddraw.h"
+#include "unknwn.h"
 
 static LPDIRECTDRAW lpDD = NULL;
 
@@ -605,6 +607,284 @@ static void QueryInterface(void)
     IDirectDrawSurface_Release(dsurface);
 }
 
+/* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
+ * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
+ * partially in the refcount test
+ */
+
+static unsigned long getref(IUnknown *iface)
+{
+    IUnknown_AddRef(iface);
+    return IUnknown_Release(iface);
+}
+
+static void GetDDInterface_1(void)
+{
+    LPDIRECTDRAWSURFACE dsurface;
+    LPDIRECTDRAWSURFACE2 dsurface2;
+    DDSURFACEDESC surface;
+    HRESULT ret;
+    IDirectDraw2 *dd2;
+    IDirectDraw4 *dd4;
+    IDirectDraw7 *dd7;
+    unsigned long ref1, ref2, ref4, ref7;
+    void *dd;
+
+    /* Create a surface */
+    ZeroMemory(&surface, sizeof(surface));
+    surface.dwSize = sizeof(surface);
+    surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+    surface.dwHeight = 10;
+    surface.dwWidth = 10;
+    ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
+    if(ret != DD_OK)
+    {
+        ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
+        return;
+    }
+    ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
+    ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+
+    ref1 = getref((IUnknown *) lpDD);
+    ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
+    ref2 = getref((IUnknown *) dd2);
+    ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
+    ref4 = getref((IUnknown *) dd4);
+    ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
+    ref7 = getref((IUnknown *) dd7);
+    ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
+
+
+    ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
+    ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+    ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
+    ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
+    ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
+    ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
+
+    ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
+    IUnknown_Release((IUnknown *) dd);
+
+    /* try a NULL pointer */
+    ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
+    ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+
+    IDirectDraw_Release(dd2);
+    IDirectDraw_Release(dd4);
+    IDirectDraw_Release(dd7);
+    IDirectDrawSurface2_Release(dsurface2);
+    IDirectDrawSurface_Release(dsurface);
+}
+
+static void GetDDInterface_2(void)
+{
+    LPDIRECTDRAWSURFACE dsurface;
+    LPDIRECTDRAWSURFACE2 dsurface2;
+    DDSURFACEDESC surface;
+    HRESULT ret;
+    IDirectDraw2 *dd2;
+    IDirectDraw4 *dd4;
+    IDirectDraw7 *dd7;
+    unsigned long ref1, ref2, ref4, ref7;
+    void *dd;
+
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+
+    /* Create a surface */
+    ZeroMemory(&surface, sizeof(surface));
+    surface.dwSize = sizeof(surface);
+    surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+    surface.dwHeight = 10;
+    surface.dwWidth = 10;
+    ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
+    if(ret != DD_OK)
+    {
+        ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
+        return;
+    }
+    ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
+    ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
+
+    ref1 = getref((IUnknown *) lpDD);
+    ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
+    ref2 = getref((IUnknown *) dd2);
+    ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
+    ref4 = getref((IUnknown *) dd4);
+    ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
+    ref7 = getref((IUnknown *) dd7);
+    ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
+
+
+    ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
+    ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+    ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
+    ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
+    ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
+    ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
+
+    ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
+    IUnknown_Release((IUnknown *) dd);
+
+    IDirectDraw_Release(dd2);
+    IDirectDraw_Release(dd4);
+    IDirectDraw_Release(dd7);
+    IDirectDrawSurface2_Release(dsurface2);
+    IDirectDrawSurface_Release(dsurface);
+}
+
+static void GetDDInterface_4(void)
+{
+    LPDIRECTDRAWSURFACE2 dsurface2;
+    LPDIRECTDRAWSURFACE4 dsurface4;
+    DDSURFACEDESC2 surface;
+    HRESULT ret;
+    IDirectDraw2 *dd2;
+    IDirectDraw4 *dd4;
+    IDirectDraw7 *dd7;
+    unsigned long ref1, ref2, ref4, ref7;
+    void *dd;
+
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+
+    /* Create a surface */
+    ZeroMemory(&surface, sizeof(surface));
+    surface.dwSize = sizeof(surface);
+    surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+    surface.dwHeight = 10;
+    surface.dwWidth = 10;
+    ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
+    if(ret != DD_OK)
+    {
+        ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
+        return;
+    }
+    ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
+    ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
+
+    ref1 = getref((IUnknown *) lpDD);
+    ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
+    ref2 = getref((IUnknown *) dd2);
+    ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
+    ref4 = getref((IUnknown *) dd4);
+    ok(ref4 == 2, "IDirectDraw4 refcount is %ld\n", ref4);
+    ref7 = getref((IUnknown *) dd7);
+    ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
+
+    ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
+    ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+    ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
+    ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
+    ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
+    ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
+
+    ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
+    IUnknown_Release((IUnknown *) dd);
+
+    /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
+    ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
+    ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+    ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
+    ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
+    ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
+    ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
+
+    ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
+    IUnknown_Release((IUnknown *) dd);
+
+    IDirectDraw_Release(dd2);
+    IDirectDraw_Release(dd4);
+    IDirectDraw_Release(dd7);
+    IDirectDrawSurface4_Release(dsurface4);
+    IDirectDrawSurface2_Release(dsurface2);
+}
+
+static void GetDDInterface_7(void)
+{
+    LPDIRECTDRAWSURFACE4 dsurface4;
+    LPDIRECTDRAWSURFACE7 dsurface7;
+    DDSURFACEDESC2 surface;
+    HRESULT ret;
+    IDirectDraw2 *dd2;
+    IDirectDraw4 *dd4;
+    IDirectDraw7 *dd7;
+    unsigned long ref1, ref2, ref4, ref7;
+    void *dd;
+
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+    ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
+    ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
+
+    /* Create a surface */
+    ZeroMemory(&surface, sizeof(surface));
+    surface.dwSize = sizeof(surface);
+    surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+    surface.dwHeight = 10;
+    surface.dwWidth = 10;
+    ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
+    if(ret != DD_OK)
+    {
+        ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
+        return;
+    }
+    ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
+    ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
+
+    ref1 = getref((IUnknown *) lpDD);
+    ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
+    ref2 = getref((IUnknown *) dd2);
+    ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
+    ref4 = getref((IUnknown *) dd4);
+    ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
+    ref7 = getref((IUnknown *) dd7);
+    ok(ref7 == 2, "IDirectDraw7 refcount is %ld\n", ref7);
+
+    ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
+    ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+    ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
+    ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
+    ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
+    ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
+
+    ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
+    IUnknown_Release((IUnknown *) dd);
+
+    /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
+    ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
+    ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
+    ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
+    ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
+    ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
+    ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
+
+    ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
+    IUnknown_Release((IUnknown *) dd);
+
+    IDirectDraw_Release(dd2);
+    IDirectDraw_Release(dd4);
+    IDirectDraw_Release(dd7);
+    IDirectDrawSurface4_Release(dsurface4);
+    IDirectDrawSurface7_Release(dsurface7);
+}
+
 START_TEST(dsurface)
 {
     if (!CreateDirectDraw())
@@ -612,5 +892,9 @@ START_TEST(dsurface)
     MipMapCreationTest();
     SrcColorKey32BlitTest();
     QueryInterface();
+    GetDDInterface_1();
+    GetDDInterface_2();
+    GetDDInterface_4();
+    GetDDInterface_7();
     ReleaseDirectDraw();
 }
-- 
1.4.4.3



More information about the wine-patches mailing list