[PATCH 2/5] ddraw: Avoid destroying ddraw objects from DllMain().

Henri Verbeet hverbeet at codeweavers.com
Wed Mar 1 00:14:53 CST 2017


It's not clear we're supposed to clean up after the application like this, and
it seems questionable whether it makes things better in general.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/ddraw/main.c | 114 +++++++-----------------------------------------------
 1 file changed, 14 insertions(+), 100 deletions(-)

diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 4caa923..863dc31 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -792,52 +792,6 @@ HRESULT WINAPI DllUnregisterServer(void)
     return __wine_unregister_resources( instance );
 }
 
-/*******************************************************************************
- * DestroyCallback
- *
- * Callback function for the EnumSurfaces call in DllMain.
- * Dumps some surface info and releases the surface
- *
- * Params:
- *  surf: The enumerated surface
- *  desc: its description
- *  context: Pointer to the ddraw impl
- *
- * Returns:
- *  DDENUMRET_OK;
- *******************************************************************************/
-static HRESULT WINAPI
-DestroyCallback(IDirectDrawSurface7 *surf,
-                DDSURFACEDESC2 *desc,
-                void *context)
-{
-    struct ddraw_surface *Impl = impl_from_IDirectDrawSurface7(surf);
-    ULONG ref7, ref4, ref3, ref2, ref1, gamma_count, iface_count;
-
-    ref7 = IDirectDrawSurface7_Release(surf);  /* For the EnumSurfaces */
-    ref4 = Impl->ref4;
-    ref3 = Impl->ref3;
-    ref2 = Impl->ref2;
-    ref1 = Impl->ref1;
-    gamma_count = Impl->gamma_count;
-
-    WARN("Surface %p has an reference counts of 7: %u 4: %u 3: %u 2: %u 1: %u gamma: %u\n",
-            Impl, ref7, ref4, ref3, ref2, ref1, gamma_count);
-
-    /* Skip surfaces which are attached somewhere or which are
-     * part of a complex compound. They will get released when destroying
-     * the root
-     */
-    if( (!Impl->is_complex_root) || (Impl->first_attached != Impl) )
-        return DDENUMRET_OK;
-
-    /* Destroy the surface */
-    iface_count = ddraw_surface_release_iface(Impl);
-    while (iface_count) iface_count = ddraw_surface_release_iface(Impl);
-
-    return DDENUMRET_OK;
-}
-
 /***********************************************************************
  * DllMain (DDRAW.0)
  *
@@ -923,66 +877,26 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
     }
 
     case DLL_PROCESS_DETACH:
-        if(!list_empty(&global_ddraw_list))
+        if (WARN_ON(ddraw))
         {
-            struct list *entry, *entry2;
-            WARN("There are still existing DirectDraw interfaces. Wine bug or buggy application?\n");
+            struct ddraw *ddraw;
 
-            /* We remove elements from this loop */
-            LIST_FOR_EACH_SAFE(entry, entry2, &global_ddraw_list)
+            LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry)
             {
-                struct ddraw *ddraw = LIST_ENTRY(entry, struct ddraw, ddraw_list_entry);
-                HRESULT hr;
-                DDSURFACEDESC2 desc;
-                int i;
-
-                WARN("DDraw %p has a refcount of %d\n", ddraw, ddraw->ref7 + ddraw->ref4 + ddraw->ref3 + ddraw->ref2 + ddraw->ref1);
-
-                /* Add references to each interface to avoid freeing them unexpectedly */
-                IDirectDraw_AddRef(&ddraw->IDirectDraw_iface);
-                IDirectDraw2_AddRef(&ddraw->IDirectDraw2_iface);
-                IDirectDraw4_AddRef(&ddraw->IDirectDraw4_iface);
-                IDirectDraw7_AddRef(&ddraw->IDirectDraw7_iface);
-
-                /* Does a D3D device exist? Destroy it
-                    * TODO: Destroy all Vertex buffers, Lights, Materials
-                    * and execute buffers too
-                    */
-                if(ddraw->d3ddevice)
-                {
-                    WARN("DDraw %p has d3ddevice %p attached\n", ddraw, ddraw->d3ddevice);
-                    while(IDirect3DDevice7_Release(&ddraw->d3ddevice->IDirect3DDevice7_iface));
-                }
+                struct ddraw_surface *surface;
 
-                /* Destroy the swapchain after any 3D device. The 3D device
-                 * cleanup code needs a swapchain. Specifically, it tries to
-                 * set the current render target to the front buffer. */
-                if (ddraw->wined3d_swapchain)
-                    ddraw_destroy_swapchain(ddraw);
-
-                /* Try to release the objects
-                    * Do an EnumSurfaces to find any hanging surfaces
-                    */
-                memset(&desc, 0, sizeof(desc));
-                desc.dwSize = sizeof(desc);
-                for(i = 0; i <= 1; i++)
-                {
-                    hr = IDirectDraw7_EnumSurfaces(&ddraw->IDirectDraw7_iface, DDENUMSURFACES_ALL,
-                            &desc, ddraw, DestroyCallback);
-                    if(hr != D3D_OK)
-                        ERR("(%p) EnumSurfaces failed, prepare for trouble\n", ddraw);
-                }
+                WARN("DirectDraw object %p has reference counts {%u, %u, %u, %u, %u}.\n",
+                        ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1);
 
-                if (!list_empty(&ddraw->surface_list))
-                    ERR("DDraw %p still has surfaces attached.\n", ddraw);
+                if (ddraw->d3ddevice)
+                    WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice);
 
-                /* Release all hanging references to destroy the objects. This
-                    * restores the screen mode too
-                    */
-                while(IDirectDraw_Release(&ddraw->IDirectDraw_iface));
-                while(IDirectDraw2_Release(&ddraw->IDirectDraw2_iface));
-                while(IDirectDraw4_Release(&ddraw->IDirectDraw4_iface));
-                while(IDirectDraw7_Release(&ddraw->IDirectDraw7_iface));
+                LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
+                {
+                    WARN("Surface %p has reference counts {%u, %u, %u, %u, %u, %u}.\n",
+                            surface, surface->ref7, surface->ref4, surface->ref3,
+                            surface->ref2, surface->ref1, surface->gamma_count);
+                }
             }
         }
 
-- 
2.1.4




More information about the wine-patches mailing list