[PATCH] ddraw: Register / unregister the ddraw window class from DllMain().

Henri Verbeet hverbeet at codeweavers.com
Fri Jun 18 06:09:50 CDT 2010


This avoids failing in DDRAW_Create() if a previous IDirectDrawImpl object
with the same pointer value was imporperly cleaned up. The improper cleanup is
of course the larger problem, but I don't believe that can be fixed without
making more invasive changes to ddraw.
---
 dlls/ddraw/ddraw.c         |   30 +++++++++++++----------
 dlls/ddraw/ddraw_private.h |    7 +----
 dlls/ddraw/main.c          |   54 ++++++++++++++++++-------------------------
 3 files changed, 42 insertions(+), 49 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index a8dbafa..7d6558d 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -275,9 +275,6 @@ IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
         This->devicewindow = 0;
     }
 
-    /* Unregister the window class */
-    UnregisterClassA(This->classname, 0);
-
     EnterCriticalSection(&ddraw_cs);
     list_remove(&This->ddraw_list_entry);
     LeaveCriticalSection(&ddraw_cs);
@@ -504,11 +501,15 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
         /* Don't create a device window if a focus window is set */
         if( !(This->focuswindow) )
         {
-            HWND devicewindow = CreateWindowExA(0, This->classname, "DDraw device window",
-                                                WS_POPUP, 0, 0,
-                                                GetSystemMetrics(SM_CXSCREEN),
-                                                GetSystemMetrics(SM_CYSCREEN),
-                                                NULL, NULL, GetModuleHandleA(0), NULL);
+            HWND devicewindow = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "DDraw device window",
+                    WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+                    NULL, NULL, NULL, NULL);
+            if (!devicewindow)
+            {
+                ERR("Failed to create window, last error %#x.\n", GetLastError());
+                LeaveCriticalSection(&ddraw_cs);
+                return E_FAIL;
+            }
 
             ShowWindow(devicewindow, SW_SHOW);   /* Just to be sure */
             TRACE("(%p) Created a DDraw device window. HWND=%p\n", This, devicewindow);
@@ -2875,11 +2876,14 @@ IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This,
     /* If there's no window, create a hidden window. WineD3D needs it */
     if(window == 0 || window == GetDesktopWindow())
     {
-        window = CreateWindowExA(0, This->classname, "Hidden D3D Window",
-                                 WS_DISABLED, 0, 0,
-                                 GetSystemMetrics(SM_CXSCREEN),
-                                 GetSystemMetrics(SM_CYSCREEN),
-                                 NULL, NULL, GetModuleHandleA(0), NULL);
+        window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "Hidden D3D Window",
+                WS_DISABLED, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+                NULL, NULL, NULL, NULL);
+        if (!window)
+        {
+            ERR("Failed to create window, last error %#x.\n", GetLastError());
+            return E_FAIL;
+        }
 
         ShowWindow(window, SW_HIDE);   /* Just to be sure */
         WARN("(%p) No window for the Direct3DDevice, created a hidden window. HWND=%p\n", This, window);
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index d6f4a57..1cb3070 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -143,11 +143,6 @@ struct IDirectDrawImpl
     /* The surface type to request */
     WINED3DSURFTYPE         ImplType;
 
-
-    /* Our private window class */
-    char classname[32];
-    WNDCLASSA wnd_class;
-
     /* Helpers for surface creation */
     IDirectDrawSurfaceImpl *tex_root;
     BOOL                    depthstencil;
@@ -165,6 +160,8 @@ struct IDirectDrawImpl
     UINT                    numConvertedDecls, declArraySize;
 };
 
+#define DDRAW_WINDOW_CLASS_NAME "ddraw_wc"
+
 /* Declare the VTables. They can be found ddraw.c */
 extern const IDirectDraw7Vtbl IDirectDraw7_Vtbl DECLSPEC_HIDDEN;
 extern const IDirectDraw4Vtbl IDirectDraw4_Vtbl DECLSPEC_HIDDEN;
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 591f46c..45a156f 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -242,37 +242,6 @@ DDRAW_Create(const GUID *guid,
     This->wineD3DDevice = wineD3DDevice;
     TRACE("wineD3DDevice created at %p\n", This->wineD3DDevice);
 
-    /* Register the window class
-     *
-     * It is used to create a hidden window for D3D
-     * rendering, if the application didn't pass one.
-     * It can also be used for Creating a device window
-     * from SetCooperativeLevel
-     *
-     * The name: DDRAW_<address>. The classname is
-     * 32 bit long, so a 64 bit address will fit nicely
-     * (Will this be compiled for 64 bit anyway?)
-     *
-     */
-    sprintf(This->classname, "DDRAW_%p", This);
-
-    memset(&This->wnd_class, 0, sizeof(This->wnd_class));
-    This->wnd_class.style = CS_HREDRAW | CS_VREDRAW;
-    This->wnd_class.lpfnWndProc = DefWindowProcA;
-    This->wnd_class.cbClsExtra = 0;
-    This->wnd_class.cbWndExtra = 0;
-    This->wnd_class.hInstance = GetModuleHandleA(0);
-    This->wnd_class.hIcon = 0;
-    This->wnd_class.hCursor = 0;
-    This->wnd_class.hbrBackground = GetStockObject(BLACK_BRUSH);
-    This->wnd_class.lpszMenuName = NULL;
-    This->wnd_class.lpszClassName = This->classname;
-    if(!RegisterClassA(&This->wnd_class))
-    {
-        ERR("RegisterClassA failed!\n");
-        goto err_out;
-    }
-
     /* Get the amount of video memory */
     This->total_vidmem = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice);
 
@@ -817,8 +786,28 @@ DllMain(HINSTANCE hInstDLL,
         DWORD size = sizeof(buffer);
         HKEY hkey = 0;
         HKEY appkey = 0;
+        WNDCLASSA wc;
         DWORD len;
 
+        /* Register the window class. This is used to create a hidden window
+         * for D3D rendering, if the application didn't pass one. It can also
+         * be used for creating a device window from SetCooperativeLevel(). */
+        wc.style = CS_HREDRAW | CS_VREDRAW;
+        wc.lpfnWndProc = DefWindowProcA;
+        wc.cbClsExtra = 0;
+        wc.cbWndExtra = 0;
+        wc.hInstance = hInstDLL;
+        wc.hIcon = 0;
+        wc.hCursor = 0;
+        wc.hbrBackground = GetStockObject(BLACK_BRUSH);
+        wc.lpszMenuName = NULL;
+        wc.lpszClassName = DDRAW_WINDOW_CLASS_NAME;
+        if (!RegisterClassA(&wc))
+        {
+            ERR("Failed to register ddraw window class, last error %#x.\n", GetLastError());
+            return FALSE;
+        }
+
        /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
        if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
 
@@ -955,6 +944,9 @@ DllMain(HINSTANCE hInstDLL,
                 while(IDirectDraw7_Release((IDirectDraw7 *)ddraw));
             }
         }
+
+        /* Unregister the window class. */
+        UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, hInstDLL);
     }
 
     return TRUE;
-- 
1.6.4.4




More information about the wine-patches mailing list