[PATCH] ddrawex: Don't leak surfaces.

Stefan Dösinger stefan at codeweavers.com
Thu Sep 4 06:18:16 CDT 2014


dds_get_outer AddRefs the inner surface when it creates the wrapper
surface. The wrapper releases only one reference when it is destroyed,
leaking one of the two. AddRefing in dds_get_outer makes sense because
this is also used by e.g. GetAttachedSurface, where it creates a new
wrapper for surfaces ddrawex didn't know about yet.

Whether native ddrawex.dll properly handles GetAttachedSurfaces and
friends is an open question. We already know it doesn't properly handle
IDirectDraw4::GetSurfaceFromDC, even though the equivalent ddraw3 method
works.
---
 dlls/ddrawex/ddraw.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/dlls/ddrawex/ddraw.c b/dlls/ddrawex/ddraw.c
index af23c89..b32f726 100644
--- a/dlls/ddrawex/ddraw.c
+++ b/dlls/ddrawex/ddraw.c
@@ -338,6 +338,7 @@ static HRESULT WINAPI ddrawex4_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2
     HRESULT hr;
     const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
     BOOL permanent_dc;
+    IDirectDrawSurface4 *inner_surface;
 
     TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
             iface, desc, surface, outer_unknown);
@@ -362,8 +363,17 @@ static HRESULT WINAPI ddrawex4_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2
         permanent_dc = FALSE;
     }
 
-    hr = IDirectDraw4_CreateSurface(ddrawex->parent, desc, surface, outer_unknown);
-    *surface = dds_get_outer(*surface);
+    hr = IDirectDraw4_CreateSurface(ddrawex->parent, desc, &inner_surface, outer_unknown);
+    if (FAILED(hr))
+    {
+        *surface = NULL;
+        return hr;
+    }
+
+    *surface = dds_get_outer(inner_surface);
+    /* The wrapper created by dds_get_outer holds a reference to its inner surface. */
+    IDirectDrawSurface4_Release(inner_surface);
+
     if (permanent_dc)
         prepare_permanent_dc(*surface);
 
-- 
1.8.5.5




More information about the wine-patches mailing list