[PATCH 1/1] ddraw/tests: Add some QueryInterface() tests for surfaces.

Henri Verbeet hverbeet at codeweavers.com
Tue Apr 3 04:14:10 CDT 2012


This supersedes patch 85071.

Try2: Skip the tests if D3D is not supported, on 64-bit ddraw in particular.
---
 dlls/ddraw/tests/ddraw1.c   |  137 +++++++++++++++++++++++++++++++++++++++++
 dlls/ddraw/tests/ddraw2.c   |  137 +++++++++++++++++++++++++++++++++++++++++
 dlls/ddraw/tests/ddraw4.c   |  140 ++++++++++++++++++++++++++++++++++++++++++
 dlls/ddraw/tests/ddraw7.c   |  142 +++++++++++++++++++++++++++++++++++++++++++
 dlls/ddraw/tests/dsurface.c |  118 -----------------------------------
 5 files changed, 556 insertions(+), 118 deletions(-)

diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index aa1950d..8797797 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -1323,6 +1323,142 @@ static void test_ck_rgba(void)
     DestroyWindow(window);
 }
 
+struct qi_test
+{
+    REFIID iid;
+    REFIID refcount_iid;
+    HRESULT hr;
+};
+
+static void test_qi(const char *test_name, IUnknown *base_iface,
+        REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
+{
+    ULONG refcount, expected_refcount;
+    IUnknown *iface1, *iface2;
+    HRESULT hr;
+    UINT i, j;
+
+    for (i = 0; i < entry_count; ++i)
+    {
+        hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
+        ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
+        if (SUCCEEDED(hr))
+        {
+            for (j = 0; j < entry_count; ++j)
+            {
+                hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
+                ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
+                if (SUCCEEDED(hr))
+                {
+                    expected_refcount = 0;
+                    if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    refcount = IUnknown_Release(iface2);
+                    ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
+                            refcount, test_name, i, j, expected_refcount);
+                }
+            }
+
+            expected_refcount = 0;
+            if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
+                ++expected_refcount;
+            refcount = IUnknown_Release(iface1);
+            ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
+                    refcount, test_name, i, expected_refcount);
+        }
+    }
+}
+
+static void test_surface_qi(void)
+{
+    static const struct qi_test tests[] =
+    {
+        {&IID_IDirect3DTexture2,        &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirect3DTexture,         &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirectDrawGammaControl,  &IID_IDirectDrawGammaControl,   S_OK         },
+        {&IID_IDirectDrawColorControl,  NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawSurface7,      &IID_IDirectDrawSurface7,       S_OK         },
+        {&IID_IDirectDrawSurface4,      &IID_IDirectDrawSurface4,       S_OK         },
+        {&IID_IDirectDrawSurface3,      &IID_IDirectDrawSurface3,       S_OK         },
+        {&IID_IDirectDrawSurface2,      &IID_IDirectDrawSurface2,       S_OK         },
+        {&IID_IDirectDrawSurface,       &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirect3DDevice7,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice3,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice2,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice,          NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D7,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D3,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D2,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D,                NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw7,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw4,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw3,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw2,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw,              NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DLight,           NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial,        NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial2,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial3,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DExecuteBuffer,   NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport,        NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport2,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport3,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DVertexBuffer,    NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DVertexBuffer7,   NULL,                           E_INVALIDARG },
+        {&IID_IDirectDrawPalette,       NULL,                           E_INVALIDARG },
+        {&IID_IDirectDrawClipper,       NULL,                           E_INVALIDARG },
+        {&IID_IUnknown,                 &IID_IDirectDrawSurface,        S_OK         },
+    };
+
+    IDirectDrawSurface *surface;
+    DDSURFACEDESC surface_desc;
+    IDirect3DDevice *device;
+    IDirectDraw *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
+    {
+        win_skip("DirectDrawCreateEx not available, skipping test.\n");
+        return;
+    }
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    if (!(ddraw = create_ddraw()))
+    {
+        skip("Failed to create a ddraw object, skipping test.\n");
+        return;
+    }
+    /* Try to create a D3D device to see if the ddraw implementation supports
+     * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
+     * doesn't support e.g. the IDirect3DTexture interfaces. */
+    if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create D3D device, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+    IDirect3DDevice_Release(device);
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+    surface_desc.dwWidth = 512;
+    surface_desc.dwHeight = 512;
+    hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+    test_qi("surface_qi", (IUnknown *)surface, &IID_IDirectDrawSurface, tests, sizeof(tests) / sizeof(*tests));
+
+    IDirectDrawSurface_Release(surface);
+    IDirectDraw_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw1)
 {
     test_coop_level_create_device_window();
@@ -1333,4 +1469,5 @@ START_TEST(ddraw1)
     test_viewport_interfaces();
     test_zenable();
     test_ck_rgba();
+    test_surface_qi();
 }
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index d58a455..cc9d723 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -1533,6 +1533,142 @@ static void test_ck_rgba(void)
     DestroyWindow(window);
 }
 
+struct qi_test
+{
+    REFIID iid;
+    REFIID refcount_iid;
+    HRESULT hr;
+};
+
+static void test_qi(const char *test_name, IUnknown *base_iface,
+        REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
+{
+    ULONG refcount, expected_refcount;
+    IUnknown *iface1, *iface2;
+    HRESULT hr;
+    UINT i, j;
+
+    for (i = 0; i < entry_count; ++i)
+    {
+        hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
+        ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
+        if (SUCCEEDED(hr))
+        {
+            for (j = 0; j < entry_count; ++j)
+            {
+                hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
+                ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
+                if (SUCCEEDED(hr))
+                {
+                    expected_refcount = 0;
+                    if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    refcount = IUnknown_Release(iface2);
+                    ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
+                            refcount, test_name, i, j, expected_refcount);
+                }
+            }
+
+            expected_refcount = 0;
+            if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
+                ++expected_refcount;
+            refcount = IUnknown_Release(iface1);
+            ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
+                    refcount, test_name, i, expected_refcount);
+        }
+    }
+}
+
+static void test_surface_qi(void)
+{
+    static const struct qi_test tests[] =
+    {
+        {&IID_IDirect3DTexture2,        &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirect3DTexture,         &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirectDrawGammaControl,  &IID_IDirectDrawGammaControl,   S_OK         },
+        {&IID_IDirectDrawColorControl,  NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawSurface7,      &IID_IDirectDrawSurface7,       S_OK         },
+        {&IID_IDirectDrawSurface4,      &IID_IDirectDrawSurface4,       S_OK         },
+        {&IID_IDirectDrawSurface3,      &IID_IDirectDrawSurface3,       S_OK         },
+        {&IID_IDirectDrawSurface2,      &IID_IDirectDrawSurface2,       S_OK         },
+        {&IID_IDirectDrawSurface,       &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirect3DDevice7,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice3,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice2,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice,          NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D7,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D3,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D2,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D,                NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw7,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw4,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw3,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw2,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw,              NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DLight,           NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial,        NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial2,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial3,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DExecuteBuffer,   NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport,        NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport2,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport3,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DVertexBuffer,    NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DVertexBuffer7,   NULL,                           E_INVALIDARG },
+        {&IID_IDirectDrawPalette,       NULL,                           E_INVALIDARG },
+        {&IID_IDirectDrawClipper,       NULL,                           E_INVALIDARG },
+        {&IID_IUnknown,                 &IID_IDirectDrawSurface,        S_OK         },
+    };
+
+    IDirectDrawSurface *surface;
+    DDSURFACEDESC surface_desc;
+    IDirect3DDevice2 *device;
+    IDirectDraw2 *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
+    {
+        win_skip("DirectDrawCreateEx not available, skipping test.\n");
+        return;
+    }
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    if (!(ddraw = create_ddraw()))
+    {
+        skip("Failed to create a ddraw object, skipping test.\n");
+        return;
+    }
+    /* Try to create a D3D device to see if the ddraw implementation supports
+     * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
+     * doesn't support e.g. the IDirect3DTexture interfaces. */
+    if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create D3D device, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+    IDirect3DDevice_Release(device);
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+    surface_desc.dwWidth = 512;
+    surface_desc.dwHeight = 512;
+    hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+    test_qi("surface_qi", (IUnknown *)surface, &IID_IDirectDrawSurface, tests, sizeof(tests) / sizeof(*tests));
+
+    IDirectDrawSurface_Release(surface);
+    IDirectDraw2_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw2)
 {
     test_coop_level_create_device_window();
@@ -1545,4 +1681,5 @@ START_TEST(ddraw2)
     test_viewport_interfaces();
     test_zenable();
     test_ck_rgba();
+    test_surface_qi();
 }
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index a2bcaf9..ccad4da 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -1616,6 +1616,145 @@ static void test_ck_rgba(void)
     DestroyWindow(window);
 }
 
+struct qi_test
+{
+    REFIID iid;
+    REFIID refcount_iid;
+    HRESULT hr;
+};
+
+static void test_qi(const char *test_name, IUnknown *base_iface,
+        REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
+{
+    ULONG refcount, expected_refcount;
+    IUnknown *iface1, *iface2;
+    HRESULT hr;
+    UINT i, j;
+
+    for (i = 0; i < entry_count; ++i)
+    {
+        hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
+        ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
+        if (SUCCEEDED(hr))
+        {
+            for (j = 0; j < entry_count; ++j)
+            {
+                hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
+                ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
+                if (SUCCEEDED(hr))
+                {
+                    expected_refcount = 0;
+                    if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    refcount = IUnknown_Release(iface2);
+                    ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
+                            refcount, test_name, i, j, expected_refcount);
+                }
+            }
+
+            expected_refcount = 0;
+            if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
+                ++expected_refcount;
+            refcount = IUnknown_Release(iface1);
+            ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
+                    refcount, test_name, i, expected_refcount);
+        }
+    }
+}
+
+static void test_surface_qi(void)
+{
+    static const struct qi_test tests[] =
+    {
+        {&IID_IDirect3DTexture2,        &IID_IDirectDrawSurface4,       S_OK         },
+        {&IID_IDirect3DTexture,         &IID_IDirectDrawSurface4,       S_OK         },
+        {&IID_IDirectDrawGammaControl,  &IID_IDirectDrawGammaControl,   S_OK         },
+        {&IID_IDirectDrawColorControl,  NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawSurface7,      &IID_IDirectDrawSurface7,       S_OK         },
+        {&IID_IDirectDrawSurface4,      &IID_IDirectDrawSurface4,       S_OK         },
+        {&IID_IDirectDrawSurface3,      &IID_IDirectDrawSurface3,       S_OK         },
+        {&IID_IDirectDrawSurface2,      &IID_IDirectDrawSurface2,       S_OK         },
+        {&IID_IDirectDrawSurface,       &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirect3DDevice7,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice3,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice2,         NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DDevice,          NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D7,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D3,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D2,               NULL,                           E_INVALIDARG },
+        {&IID_IDirect3D,                NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw7,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw4,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw3,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw2,             NULL,                           E_INVALIDARG },
+        {&IID_IDirectDraw,              NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DLight,           NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial,        NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial2,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DMaterial3,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DExecuteBuffer,   NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport,        NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport2,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DViewport3,       NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DVertexBuffer,    NULL,                           E_INVALIDARG },
+        {&IID_IDirect3DVertexBuffer7,   NULL,                           E_INVALIDARG },
+        {&IID_IDirectDrawPalette,       NULL,                           E_INVALIDARG },
+        {&IID_IDirectDrawClipper,       NULL,                           E_INVALIDARG },
+        {&IID_IUnknown,                 &IID_IDirectDrawSurface,        S_OK         },
+    };
+
+    IDirectDrawSurface4 *surface;
+    DDSURFACEDESC2 surface_desc;
+    IDirect3DDevice3 *device;
+    IDirectDraw4 *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
+    {
+        win_skip("DirectDrawCreateEx not available, skipping test.\n");
+        return;
+    }
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    /* Try to create a D3D device to see if the ddraw implementation supports
+     * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
+     * doesn't support e.g. the IDirect3DTexture interfaces. */
+    if (!(device = create_device(window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create D3D device, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+    IDirect3DDevice_Release(device);
+    if (!(ddraw = create_ddraw()))
+    {
+        skip("Failed to create a ddraw object, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+    hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+    surface_desc.dwWidth = 512;
+    surface_desc.dwHeight = 512;
+    hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+    test_qi("surface_qi", (IUnknown *)surface, &IID_IDirectDrawSurface4, tests, sizeof(tests) / sizeof(*tests));
+
+    IDirectDrawSurface4_Release(surface);
+    IDirectDraw4_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw4)
 {
     test_process_vertices();
@@ -1629,4 +1768,5 @@ START_TEST(ddraw4)
     test_viewport_interfaces();
     test_zenable();
     test_ck_rgba();
+    test_surface_qi();
 }
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index f1dbea1..77210c9 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -16,6 +16,7 @@
  * 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 "wine/test.h"
 #include <limits.h>
@@ -1434,6 +1435,146 @@ static void test_ck_rgba(void)
     DestroyWindow(window);
 }
 
+struct qi_test
+{
+    REFIID iid;
+    REFIID refcount_iid;
+    HRESULT hr;
+};
+
+static void test_qi(const char *test_name, IUnknown *base_iface,
+        REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
+{
+    ULONG refcount, expected_refcount;
+    IUnknown *iface1, *iface2;
+    HRESULT hr;
+    UINT i, j;
+
+    for (i = 0; i < entry_count; ++i)
+    {
+        hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
+        ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
+        if (SUCCEEDED(hr))
+        {
+            for (j = 0; j < entry_count; ++j)
+            {
+                hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
+                ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
+                if (SUCCEEDED(hr))
+                {
+                    expected_refcount = 0;
+                    if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
+                        ++expected_refcount;
+                    refcount = IUnknown_Release(iface2);
+                    ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
+                            refcount, test_name, i, j, expected_refcount);
+                }
+            }
+
+            expected_refcount = 0;
+            if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
+                ++expected_refcount;
+            refcount = IUnknown_Release(iface1);
+            ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
+                    refcount, test_name, i, expected_refcount);
+        }
+    }
+}
+
+static void test_surface_qi(void)
+{
+    static const struct qi_test tests[] =
+    {
+        {&IID_IDirect3DTexture2,        NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DTexture,         NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawGammaControl,  &IID_IDirectDrawGammaControl,   S_OK         },
+        {&IID_IDirectDrawColorControl,  NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawSurface7,      &IID_IDirectDrawSurface7,       S_OK         },
+        {&IID_IDirectDrawSurface4,      &IID_IDirectDrawSurface4,       S_OK         },
+        {&IID_IDirectDrawSurface3,      &IID_IDirectDrawSurface3,       S_OK         },
+        {&IID_IDirectDrawSurface2,      &IID_IDirectDrawSurface2,       S_OK         },
+        {&IID_IDirectDrawSurface,       &IID_IDirectDrawSurface,        S_OK         },
+        {&IID_IDirect3DDevice7,         NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DDevice3,         NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DDevice2,         NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DDevice,          NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DRampDevice,      NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DRGBDevice,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DHALDevice,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DMMXDevice,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DRefDevice,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DTnLHalDevice,    NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DNullDevice,      NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3D7,               NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3D3,               NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3D2,               NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3D,                NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDraw7,             NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDraw4,             NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDraw3,             NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDraw2,             NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDraw,              NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DLight,           NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DMaterial,        NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DMaterial2,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DMaterial3,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DExecuteBuffer,   NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DViewport,        NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DViewport2,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DViewport3,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DVertexBuffer,    NULL,                           E_NOINTERFACE},
+        {&IID_IDirect3DVertexBuffer7,   NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawPalette,       NULL,                           E_NOINTERFACE},
+        {&IID_IDirectDrawClipper,       NULL,                           E_NOINTERFACE},
+        {&IID_IUnknown,                 &IID_IDirectDrawSurface,        S_OK         },
+    };
+
+    IDirectDrawSurface7 *surface;
+    DDSURFACEDESC2 surface_desc;
+    IDirect3DDevice7 *device;
+    IDirectDraw7 *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    /* Try to create a D3D device to see if the ddraw implementation supports
+     * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
+     * doesn't support e.g. the IDirect3DTexture interfaces. */
+    if (!(device = create_device(window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create D3D device, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+    IDirect3DDevice_Release(device);
+    if (!(ddraw = create_ddraw()))
+    {
+        skip("Failed to create a ddraw object, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+    hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+    surface_desc.dwWidth = 512;
+    surface_desc.dwHeight = 512;
+    hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+    test_qi("surface_qi", (IUnknown *)surface, &IID_IDirectDrawSurface7, tests, sizeof(tests) / sizeof(*tests));
+
+    IDirectDrawSurface7_Release(surface);
+    IDirectDraw7_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw7)
 {
     HMODULE module = GetModuleHandleA("ddraw.dll");
@@ -1454,4 +1595,5 @@ START_TEST(ddraw7)
     test_texture_load_ckey();
     test_zenable();
     test_ck_rgba();
+    test_surface_qi();
 }
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index 2937258..93efba8 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -1047,123 +1047,6 @@ static ULONG getRefcount(IUnknown *iface)
     return IUnknown_Release(iface);
 }
 
-static void IFaceRefCount(void)
-{
-    LPDIRECTDRAWSURFACE surf;
-    DDSURFACEDESC surface;
-    HRESULT ret;
-    IDirectDrawSurface2 *surf2;
-    IDirectDrawSurface2 *surf2a;
-    IDirectDrawSurface3 *surf3;
-    IDirectDrawSurface4 *surf4;
-    IDirectDrawSurface7 *surf7a;
-    IDirectDrawSurface7 *surf7b;
-    IDirect3DTexture* tex;
-    IDirect3DTexture2* tex2;
-    IDirectDrawGammaControl* gamma;
-    ULONG ref;
-
-    /* Create a surface */
-    ZeroMemory(&surface, sizeof(surface));
-    surface.dwSize = sizeof(surface);
-    surface.dwFlags = DDSD_CAPS;
-    surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-    ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
-
-    if (ret != DD_OK)
-    {
-        ok(FALSE, "Could not create surface, skipping test\n");
-        return;
-    }
-
-    ref = getRefcount((IUnknown *) surf);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
-
-    IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
-    ref = getRefcount((IUnknown *) surf);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
-    ref = getRefcount((IUnknown *) surf2);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
-
-    IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
-    ref = getRefcount((IUnknown *) surf2);
-    ok(ref == 2, "Refcount is %u, expected 2\n", ref);   /* Surf2's refcount should be 2 now, but surf should be 1 */
-    ref = getRefcount((IUnknown *) surf);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-    IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface3, (void **) &surf3);
-    ref = getRefcount((IUnknown *) surf3);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-    IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
-    ref = getRefcount((IUnknown *) surf4);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-    IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
-    ref = getRefcount((IUnknown *) surf7a);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-    IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
-    ref = getRefcount((IUnknown *) surf7b);
-    ok(ref == 2, "Refcount is %u, expected 2\n", ref);
-
-    /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
-    ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
-    if (SUCCEEDED(ret))
-    {
-        ref = getRefcount((IUnknown *) tex);
-        ok(ref == 2, "Refcount is %u, expected 2\n", ref);
-        ref = getRefcount((IUnknown *) surf);
-        ok(ref == 2, "Refcount is %u, expected 2\n", ref);
-
-        IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
-        ref = getRefcount((IUnknown *) tex);
-        ok(ref == 3, "Refcount is %u, expected 3\n", ref);
-        ref = getRefcount((IUnknown *) tex2);
-        ok(ref == 3, "Refcount is %u, expected 3\n", ref);
-        ref = getRefcount((IUnknown *) surf);
-        ok(ref == 3, "Refcount is %u, expected 3\n", ref);
-
-        IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
-        ref = getRefcount((IUnknown *) gamma);
-        ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-        ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
-        ok(ref == 2, "Refcount is %u, expected 2\n", ref);
-        ref = getRefcount((IUnknown *) surf);
-        ok(ref == 2, "Refcount is %u, expected 2\n", ref);
-
-        ref = IDirect3DTexture_Release(tex); /* Release the texture */
-        ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-        ref = getRefcount((IUnknown *) surf);
-        ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-        ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
-        ok(ref == 0, "Refcount is %u, expected 0\n", ref);
-    }
-
-    ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-    ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
-    ok(ref == 0, "Refcount is %u, expected 0\n", ref);
-
-    ref = IDirectDrawSurface3_Release(surf3);
-    ok(ref == 0, "Refcount is %u, expected 0\n", ref);
-
-    ref = IDirectDrawSurface4_Release(surf4);
-    ok(ref == 0, "Refcount is %u, expected 0\n", ref);
-
-    ref = IDirectDrawSurface7_Release(surf7a);
-    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
-
-    ref = IDirectDrawSurface7_Release(surf7b);
-    ok(ref == 0, "Refcount is %u, expected 0\n", ref);
-
-    ref = IDirectDrawSurface_Release(surf);
-    ok(ref == 0, "Refcount is %u, expected 0\n", ref);
-}
-
 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
 struct enumstruct
 {
@@ -5002,7 +4885,6 @@ START_TEST(dsurface)
     GetDDInterface_2();
     GetDDInterface_4();
     GetDDInterface_7();
-    IFaceRefCount();
     EnumTest();
     AttachmentTest();
     AttachmentTest7();
-- 
1.7.3.4




More information about the wine-patches mailing list