[PATCH 3/3] ddraw/tests: Test writing to vtbls.

Zebediah Figura z.figura12 at gmail.com
Sun Apr 26 22:58:29 CDT 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
This doesn't test the actual hooking that the games in question attempt, though
I suspect that such tests would be uninteresting, as I guess the games are only
trying to intercept their own calls.

 dlls/ddraw/tests/ddraw1.c | 94 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 0e1f4ce85c6..7625831fe0c 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -13410,6 +13410,99 @@ done:
     DestroyWindow(window);
 }
 
+static void test_write_vtbl(void)
+{
+    IDirectDrawSurface7Vtbl orig_surface7_vtbl, *surface7_vtbl;
+    IDirectDrawSurface4Vtbl orig_surface4_vtbl, *surface4_vtbl;
+    IDirectDrawSurface3Vtbl orig_surface3_vtbl, *surface3_vtbl;
+    IDirectDrawSurface2Vtbl orig_surface2_vtbl, *surface2_vtbl;
+    IDirectDrawSurfaceVtbl orig_surface1_vtbl, *surface1_vtbl;
+    IDirectDrawPaletteVtbl orig_palette_vtbl, *palette_vtbl;
+    IDirectDrawVtbl orig_ddraw_vtbl, *ddraw_vtbl;
+    PALETTEENTRY palette_entries[256];
+    IDirectDrawSurface7 *surface7;
+    IDirectDrawSurface4 *surface4;
+    IDirectDrawSurface3 *surface3;
+    IDirectDrawSurface2 *surface2;
+    IDirectDrawSurface *surface1;
+    IDirectDrawPalette *palette;
+    DDSURFACEDESC surface_desc;
+    IDirectDraw *ddraw;
+    ULONG refcount;
+    HWND window;
+    HRESULT hr;
+
+    window = create_window();
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+    hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface1, NULL);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface2, (void **)&surface2);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface3, (void **)&surface3);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface4, (void **)&surface4);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **)&surface7);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+    memset(palette_entries, 0, sizeof(palette_entries));
+    hr = IDirectDraw_CreatePalette(ddraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256,
+            palette_entries, &palette, NULL);
+    ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+    ddraw_vtbl = (IDirectDrawVtbl *)ddraw->lpVtbl;
+    surface1_vtbl = (IDirectDrawSurfaceVtbl *)surface1->lpVtbl;
+    surface2_vtbl = (IDirectDrawSurface2Vtbl *)surface2->lpVtbl;
+    surface3_vtbl = (IDirectDrawSurface3Vtbl *)surface3->lpVtbl;
+    surface4_vtbl = (IDirectDrawSurface4Vtbl *)surface4->lpVtbl;
+    surface7_vtbl = (IDirectDrawSurface7Vtbl *)surface7->lpVtbl;
+    palette_vtbl = (IDirectDrawPaletteVtbl *)palette->lpVtbl;
+    memcpy(&orig_ddraw_vtbl, ddraw_vtbl, sizeof(*ddraw_vtbl));
+    memcpy(&orig_surface1_vtbl, surface1_vtbl, sizeof(*surface1_vtbl));
+    memcpy(&orig_surface2_vtbl, surface2_vtbl, sizeof(*surface2_vtbl));
+    memcpy(&orig_surface3_vtbl, surface3_vtbl, sizeof(*surface3_vtbl));
+    memcpy(&orig_surface4_vtbl, surface4_vtbl, sizeof(*surface4_vtbl));
+    memcpy(&orig_surface7_vtbl, surface7_vtbl, sizeof(*surface7_vtbl));
+    memcpy(&orig_palette_vtbl, palette_vtbl, sizeof(*palette_vtbl));
+
+    memset(ddraw_vtbl, 0, sizeof(*ddraw_vtbl));
+    memset(surface1_vtbl, 0, sizeof(*surface1_vtbl));
+    memset(surface2_vtbl, 0, sizeof(*surface2_vtbl));
+    memset(surface3_vtbl, 0, sizeof(*surface3_vtbl));
+    memset(surface4_vtbl, 0, sizeof(*surface4_vtbl));
+    memset(surface7_vtbl, 0, sizeof(*surface7_vtbl));
+    memset(palette_vtbl, 0, sizeof(*palette_vtbl));
+
+    /* Prevent the compiler from optimizing these writes. */
+    __asm__ __volatile__( "" : : : "memory" );
+
+    memcpy(ddraw_vtbl, &orig_ddraw_vtbl, sizeof(*ddraw_vtbl));
+    memcpy(surface1_vtbl, &orig_surface1_vtbl, sizeof(*surface1_vtbl));
+    memcpy(surface2_vtbl, &orig_surface2_vtbl, sizeof(*surface2_vtbl));
+    memcpy(surface3_vtbl, &orig_surface3_vtbl, sizeof(*surface3_vtbl));
+    memcpy(surface4_vtbl, &orig_surface4_vtbl, sizeof(*surface4_vtbl));
+    memcpy(surface7_vtbl, &orig_surface7_vtbl, sizeof(*surface7_vtbl));
+    memcpy(palette_vtbl, &orig_palette_vtbl, sizeof(*palette_vtbl));
+
+    IDirectDrawPalette_Release(palette);
+    IDirectDrawSurface_Release(surface1);
+    IDirectDrawSurface2_Release(surface2);
+    IDirectDrawSurface3_Release(surface3);
+    IDirectDrawSurface4_Release(surface4);
+    IDirectDrawSurface7_Release(surface7);
+    refcount = IDirectDraw_Release(ddraw);
+    ok(!refcount, "%u references left.\n", refcount);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw1)
 {
     DDDEVICEIDENTIFIER identifier;
@@ -13523,4 +13616,5 @@ START_TEST(ddraw1)
     test_caps();
     test_d32_support();
     test_cursor_clipping();
+    test_write_vtbl();
 }
-- 
2.26.2




More information about the wine-devel mailing list