From: Michael Müller michael@fds-team.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=39534 Signed-off-by: Michael Müller michael@fds-team.de Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ddraw/ddraw.c | 3 ++- dlls/ddraw/surface.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 7cfb56f45cc..b7e7e6514a8 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4661,7 +4661,8 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl = ddraw2_GetAvailableVidMem, };
-static const struct IDirectDrawVtbl ddraw1_vtbl = +/* Bad Mojo Redux expects this vtbl to be writable. */ +static struct IDirectDrawVtbl ddraw1_vtbl = { /* IUnknown */ ddraw1_QueryInterface, diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index c418bb7b2b3..44230838352 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5613,7 +5613,8 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = ddraw_surface2_PageUnlock, };
-static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = +/* Bad Mojo Redux expects this vtbl to be writable. */ +static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = { /* IUnknown */ ddraw_surface1_QueryInterface,
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46949 Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ddraw/palette.c | 3 ++- dlls/ddraw/surface.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/dlls/ddraw/palette.c b/dlls/ddraw/palette.c index 980c62b60b4..68fb3a53207 100644 --- a/dlls/ddraw/palette.c +++ b/dlls/ddraw/palette.c @@ -215,7 +215,8 @@ static HRESULT WINAPI ddraw_palette_GetEntries(IDirectDrawPalette *iface, return hr; }
-static const struct IDirectDrawPaletteVtbl ddraw_palette_vtbl = +/* Some windowed mode wrappers expect this vtbl to be writable. */ +static struct IDirectDrawPaletteVtbl ddraw_palette_vtbl = { /*** IUnknown ***/ ddraw_palette_QueryInterface, diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 44230838352..ba56fad9644 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5406,7 +5406,8 @@ static HRESULT WINAPI d3d_texture1_Load(IDirect3DTexture *iface, IDirect3DTextur * The VTable *****************************************************************************/
-static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = +/* Some windowed mode wrappers expect this vtbl to be writable. */ +static struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = { /* IUnknown */ ddraw_surface7_QueryInterface, @@ -5465,7 +5466,8 @@ static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = ddraw_surface7_GetLOD, };
-static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = +/* Some windowed mode wrappers expect this vtbl to be writable. */ +static struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = { /* IUnknown */ ddraw_surface4_QueryInterface, @@ -5519,7 +5521,8 @@ static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = ddraw_surface4_ChangeUniquenessValue, };
-static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = +/* Some windowed mode wrappers expect this vtbl to be writable. */ +static struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = { /* IUnknown */ ddraw_surface3_QueryInterface, @@ -5567,7 +5570,8 @@ static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = ddraw_surface3_SetSurfaceDesc, };
-static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = +/* Some windowed mode wrappers expect this vtbl to be writable. */ +static struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = { /* IUnknown */ ddraw_surface2_QueryInterface,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(); }