[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