Commit 00eaf27d authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

ddraw: Validate that surfaces are on the same swap chain in ddraw_surface7_Flip().

parent 74e3f516
...@@ -1170,62 +1170,55 @@ static HRESULT WINAPI ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *dat ...@@ -1170,62 +1170,55 @@ static HRESULT WINAPI ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *dat
return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL); return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL);
} }
/***************************************************************************** static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *src, DWORD flags)
* IDirectDrawSurface7::Flip
*
* Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to
* IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces,
* the flip target is passed to WineD3D, even if the app didn't specify one
*
* Params:
* DestOverride: Specifies the surface that will become the new front
* buffer. If NULL, the current back buffer is used
* Flags: some DirectDraw flags, see include/ddraw.h
*
* Returns:
* DD_OK on success
* DDERR_NOTFLIPPABLE if no flip target could be found
* DDERR_INVALIDOBJECT if the surface isn't a front buffer
* For more details, see IWineD3DSurface::Flip
*
*****************************************************************************/
static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *DestOverride, DWORD Flags)
{ {
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
struct ddraw_surface *Override = unsafe_impl_from_IDirectDrawSurface7(DestOverride); struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src);
IDirectDrawSurface7 *Override7; DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, 0};
IDirectDrawSurface7 *current;
HRESULT hr; HRESULT hr;
TRACE("iface %p, dst %p, flags %#x.\n", iface, DestOverride, Flags); TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
if (DestOverride == iface || !(surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY))) if (src == iface || !(dst_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)))
return DDERR_NOTFLIPPABLE; return DDERR_NOTFLIPPABLE;
wined3d_mutex_lock(); wined3d_mutex_lock();
/* WineD3D doesn't keep track of attached surface, so find the target */ if (src_impl)
if(!Override)
{ {
DDSCAPS2 Caps; for (current = iface; current != src;)
{
memset(&Caps, 0, sizeof(Caps)); if (FAILED(hr = ddraw_surface7_GetAttachedSurface(current, &caps, &current)))
Caps.dwCaps |= DDSCAPS_BACKBUFFER; {
hr = ddraw_surface7_GetAttachedSurface(iface, &Caps, &Override7); WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
if(hr != DD_OK) wined3d_mutex_unlock();
return DDERR_NOTFLIPPABLE;
}
ddraw_surface7_Release(current);
if (current == iface)
{
WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
wined3d_mutex_unlock();
return DDERR_NOTFLIPPABLE;
}
}
}
else
{
if (FAILED(hr = ddraw_surface7_GetAttachedSurface(iface, &caps, &current)))
{ {
ERR("Can't find a flip target\n"); ERR("Can't find a flip target\n");
wined3d_mutex_unlock(); wined3d_mutex_unlock();
return DDERR_NOTFLIPPABLE; /* Unchecked */ return DDERR_NOTFLIPPABLE; /* Unchecked */
} }
Override = impl_from_IDirectDrawSurface7(Override7); src_impl = impl_from_IDirectDrawSurface7(current);
ddraw_surface7_Release(current);
/* For the GetAttachedSurface */
ddraw_surface7_Release(Override7);
} }
hr = wined3d_surface_flip(surface->wined3d_surface, Override->wined3d_surface, Flags); if (SUCCEEDED(hr = wined3d_surface_flip(dst_impl->wined3d_surface, src_impl->wined3d_surface, flags))
if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE); hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
......
...@@ -3618,7 +3618,7 @@ static void test_flip(void) ...@@ -3618,7 +3618,7 @@ static void test_flip(void)
hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface_Flip(primary, surface, DDFLIP_WAIT); hr = IDirectDrawSurface_Flip(primary, surface, DDFLIP_WAIT);
todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr); ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface_Release(surface); IDirectDrawSurface_Release(surface);
hr = IDirectDrawSurface_Flip(primary, primary, DDFLIP_WAIT); hr = IDirectDrawSurface_Flip(primary, primary, DDFLIP_WAIT);
......
...@@ -4299,7 +4299,7 @@ static void test_flip(void) ...@@ -4299,7 +4299,7 @@ static void test_flip(void)
hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface_Flip(primary, surface, DDFLIP_WAIT); hr = IDirectDrawSurface_Flip(primary, surface, DDFLIP_WAIT);
todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr); ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface_Release(surface); IDirectDrawSurface_Release(surface);
hr = IDirectDrawSurface_Flip(primary, primary, DDFLIP_WAIT); hr = IDirectDrawSurface_Flip(primary, primary, DDFLIP_WAIT);
......
...@@ -4903,7 +4903,7 @@ static void test_flip(void) ...@@ -4903,7 +4903,7 @@ static void test_flip(void)
hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_Flip(primary, surface, DDFLIP_WAIT); hr = IDirectDrawSurface4_Flip(primary, surface, DDFLIP_WAIT);
todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr); ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface4_Release(surface); IDirectDrawSurface4_Release(surface);
hr = IDirectDrawSurface4_Flip(primary, primary, DDFLIP_WAIT); hr = IDirectDrawSurface4_Flip(primary, primary, DDFLIP_WAIT);
......
...@@ -4790,7 +4790,7 @@ static void test_flip(void) ...@@ -4790,7 +4790,7 @@ static void test_flip(void)
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(primary, surface, DDFLIP_WAIT); hr = IDirectDrawSurface7_Flip(primary, surface, DDFLIP_WAIT);
todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr); ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface7_Release(surface); IDirectDrawSurface7_Release(surface);
hr = IDirectDrawSurface7_Flip(primary, primary, DDFLIP_WAIT); hr = IDirectDrawSurface7_Flip(primary, primary, DDFLIP_WAIT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment