ddraw: Use QueryInterface rather than casting from the DDS3 vtbl (needed to fix ddraw surface refcounting)
Luke Benstead
kazade at gmail.com
Mon Jun 28 14:28:47 CDT 2010
Luke.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20100628/72f8ddbb/attachment.htm>
-------------- next part --------------
From 7cf888f3c918f2d96bf842be2f83679a69334334 Mon Sep 17 00:00:00 2001
From: Luke Benstead <kazade at gmail.com>
Date: Mon, 28 Jun 2010 19:23:30 +0100
Subject: ddraw: Use QueryInterface rather than casting from the DDS3 vtbl (needed to fix ddraw surface refcounting)
---
dlls/ddraw/ddraw_thunks.c | 119 ++++++++++++++++++++++++++++++++------------
1 files changed, 86 insertions(+), 33 deletions(-)
diff --git a/dlls/ddraw/ddraw_thunks.c b/dlls/ddraw/ddraw_thunks.c
index 28991d1..b3db778 100644
--- a/dlls/ddraw/ddraw_thunks.c
+++ b/dlls/ddraw/ddraw_thunks.c
@@ -354,7 +354,8 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
}
impl = (IDirectDrawSurfaceImpl *)pSurface7;
- *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
+ IDirectDrawSurface7_QueryInterface(pSurface7, &IID_IDirectDrawSurface, (void**) ppSurface);
+ IDirectDrawSurface7_Release(pSurface7);
set_surf_version(impl, 1);
IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This));
impl->ifaceToRelease = NULL;
@@ -380,7 +381,10 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
}
impl = (IDirectDrawSurfaceImpl *)pSurface7;
- *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
+
+ IDirectDrawSurface7_QueryInterface(pSurface7, &IID_IDirectDrawSurface2, (void**) ppSurface);
+ IDirectDrawSurface7_Release(pSurface7);
+
set_surf_version(impl, 2);
IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This));
impl->ifaceToRelease = NULL;
@@ -406,7 +410,10 @@ IDirectDraw3Impl_CreateSurface(LPDIRECTDRAW3 This, LPDDSURFACEDESC pSDesc,
}
impl = (IDirectDrawSurfaceImpl *)pSurface7;
- *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
+
+ IDirectDrawSurface7_QueryInterface(pSurface7, &IID_IDirectDrawSurface3, (void**) ppSurface);
+ IDirectDrawSurface7_Release(pSurface7);
+
set_surf_version(impl, 3);
IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw3(This));
IDirectDraw3_AddRef(This);
@@ -421,18 +428,28 @@ IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
IUnknown *pUnkOuter)
{
HRESULT hr;
+ LPDIRECTDRAWSURFACE7 pSurface7;
IDirectDrawSurfaceImpl *impl;
hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
- pSDesc, (LPDIRECTDRAWSURFACE7 *)ppSurface, pUnkOuter);
- impl = (IDirectDrawSurfaceImpl *)*ppSurface;
- if(SUCCEEDED(hr) && impl)
+ pSDesc, &pSurface7, pUnkOuter);
+
+ if (FAILED(hr))
{
- set_surf_version(impl, 4);
- IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw4(This));
- IDirectDraw4_AddRef(This);
- impl->ifaceToRelease = (IUnknown *) This;
+ *ppSurface = NULL;
+ return hr;
}
+
+ impl = (IDirectDrawSurfaceImpl *)pSurface7;
+
+ IDirectDrawSurface7_QueryInterface(pSurface7, &IID_IDirectDrawSurface4, (void**) ppSurface);
+ IDirectDrawSurface7_Release(pSurface7);
+
+ set_surf_version(impl, 4);
+ IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw4(This));
+ IDirectDraw4_AddRef(This);
+ impl->ifaceToRelease = (IUnknown *) This;
+
return hr;
}
@@ -446,9 +463,13 @@ IDirectDrawImpl_DuplicateSurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE pSrc,
hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw1(This),
pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
- /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
- * IDirectDrawSurface vtable layout at the beginning */
- *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
+ if(pDst7)
+ {
+ IDirectDrawSurface7_QueryInterface(pDst7, &IID_IDirectDrawSurface, (void**) ppDst);
+ IDirectDrawSurface7_Release(pDst7);
+ }
+ else
+ *ppDst = NULL;
return hr;
}
@@ -463,9 +484,13 @@ IDirectDraw2Impl_DuplicateSurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE pSrc,
hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw2(This),
pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
- /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
- * IDirectDrawSurface vtable layout at the beginning */
- *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
+ if(pDst7)
+ {
+ IDirectDrawSurface7_QueryInterface(pDst7, &IID_IDirectDrawSurface2, (void**) ppDst);
+ IDirectDrawSurface7_Release(pDst7);
+ }
+ else
+ *ppDst = NULL;
return hr;
}
@@ -480,10 +505,14 @@ IDirectDraw3Impl_DuplicateSurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE pSrc,
hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw3(This),
pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
- /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
- * IDirectDrawSurface vtable layout at the beginning */
- *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
-
+ if(pDst7)
+ {
+ IDirectDrawSurface7_QueryInterface(pDst7, &IID_IDirectDrawSurface3, (void**) ppDst);
+ IDirectDrawSurface7_Release(pDst7);
+ }
+ else
+ *ppDst = NULL;
+
return hr;
}
@@ -492,8 +521,20 @@ IDirectDraw4Impl_DuplicateSurface(LPDIRECTDRAW4 This,
LPDIRECTDRAWSURFACE4 pSrc,
LPDIRECTDRAWSURFACE4 *ppDst)
{
- return IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
- (LPDIRECTDRAWSURFACE7)pSrc, (LPDIRECTDRAWSURFACE7 *)ppDst);
+ LPDIRECTDRAWSURFACE7 pDst7;
+ HRESULT hr;
+ hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
+ (LPDIRECTDRAWSURFACE7)pSrc, (LPDIRECTDRAWSURFACE7 *)&pDst7);
+
+ if(pDst7)
+ {
+ IDirectDrawSurface7_QueryInterface(pDst7, &IID_IDirectDrawSurface4, (void**) ppDst);
+ IDirectDrawSurface7_Release(pDst7);
+ }
+ else
+ *ppDst = NULL;
+
+ return hr;
}
struct displaymodescallback_context
@@ -742,10 +783,14 @@ IDirectDrawImpl_GetGDISurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE *ppSurf)
hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(This), &pSurf7);
- /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
- * IDirectDrawSurface vtable layout at the beginning */
- *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
-
+ if(pSurf7)
+ {
+ IDirectDrawSurface7_QueryInterface(pSurf7, &IID_IDirectDrawSurface, (void**) ppSurf);
+ IDirectDrawSurface7_Release(pSurf7);
+ }
+ else
+ *ppSurf = NULL;
+
return hr;
}
@@ -757,9 +802,13 @@ IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE *ppSurf)
hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(This), &pSurf7);
- /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
- * IDirectDrawSurface vtable layout at the beginning */
- *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
+ if(pSurf7)
+ {
+ IDirectDrawSurface2_QueryInterface(pSurf7, &IID_IDirectDrawSurface2, (void**) ppSurf);
+ IDirectDrawSurface7_Release(pSurf7);
+ }
+ else
+ *ppSurf = NULL;
return hr;
}
@@ -772,10 +821,14 @@ IDirectDraw3Impl_GetGDISurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE *ppSurf)
hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(This), &pSurf7);
- /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
- * IDirectDrawSurface vtable layout at the beginning */
- *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
-
+ if(pSurf7)
+ {
+ IDirectDrawSurface3_QueryInterface(pSurf7, &IID_IDirectDrawSurface3, (void**) ppSurf);
+ IDirectDrawSurface7_Release(pSurf7);
+ }
+ else
+ *ppSurf = NULL;
+
return hr;
}
--
1.7.0.4
More information about the wine-patches
mailing list