Henri Verbeet : ddraw: Avoid destroying ddraw objects from DllMain().

Alexandre Julliard julliard at winehq.org
Wed Mar 1 16:45:10 CST 2017


Module: wine
Branch: master
Commit: 1a14a6efd574922b46ed410623e3bfd0c03918f7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1a14a6efd574922b46ed410623e3bfd0c03918f7

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed Mar  1 07:14:53 2017 +0100

ddraw: Avoid destroying ddraw objects from DllMain().

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>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);
+                }
             }
         }
 




More information about the wine-cvs mailing list