Suspend all windows locks before the control is passed to the
application.
Also fixed some bugs in dce.c
diff --git a/misc/callback.c b/misc/callback.c
index 69f605f..83da4a3 100644
--- a/misc/callback.c
+++ b/misc/callback.c
@@ -13,6 +13,7 @@
#include "user.h"
#include "queue.h"
#include "debug.h"
+#include "win.h"
/**********************************************************************
@@ -22,7 +23,15 @@
UINT16 msg, WPARAM16 wParam,
LPARAM lParam )
{
- return proc( hwnd, msg, wParam, lParam );
+ LRESULT retvalue;
+ int iWndsLocks;
+
+ /* To avoid any deadlocks, all the locks on the windows structures
+ must be suspended before the control is passed to the application */
+ iWndsLocks = WIN_SuspendWndsLock();
+ retvalue = proc( hwnd, msg, wParam, lParam );
+ WIN_RestoreWndsLock(iWndsLocks);
+ return retvalue;
}
diff --git a/windows/dce.c b/windows/dce.c
index 2f52572..646f613 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -227,7 +227,8 @@
*/
BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
{
- WND* wndScope = pWnd->parent;
+ WND* wndScope = WIN_LockWndPtr(pWnd->parent);
+ WND *pDesktop = WIN_GetDesktop();
BOOL bRet = FALSE;
if( wndScope )
@@ -260,10 +261,10 @@
continue;
}
- if( !Options.desktopGeometry && wndCurrent == WIN_GetDesktop() )
+ if( !Options.desktopGeometry && wndCurrent == pDesktop )
{
/* don't bother with fake desktop */
- WIN_ReleaseDesktop();
+ WIN_ReleaseWndPtr(wndCurrent);
continue;
}
@@ -306,6 +307,7 @@
bRet = TRUE;
}
}
+ WIN_ReleaseWndPtr(wnd);
break;
}
xoffset += wnd->rectClient.left;
@@ -315,7 +317,9 @@
WIN_ReleaseWndPtr(wndCurrent);
}
} /* dce list */
+ WIN_ReleaseWndPtr(wndScope);
}
+ WIN_ReleaseDesktop();
return bRet;
}
diff --git a/windows/win.c b/windows/win.c
index 67c21f0..58fcb8e 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -2766,9 +2766,19 @@
for (ppWnd = list; *ppWnd; ppWnd++)
{
+ LRESULT lpEnumFuncRetval;
+ int iWndsLocks = 0;
/* Make sure that the window still exists */
if (!IsWindow((*ppWnd)->hwndSelf)) continue;
- if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
+
+ /* To avoid any deadlocks, all the locks on the windows
+ structures must be suspended before the control
+ is passed to the application */
+ iWndsLocks = WIN_SuspendWndsLock();
+ lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
+ WIN_RestoreWndsLock(iWndsLocks);
+
+ if (!lpEnumFuncRetval) break;
}
WIN_ReleaseWinArray(list);
WIN_ReleaseDesktop();
@@ -2806,10 +2816,20 @@
for (ppWnd = list; *ppWnd; ppWnd++)
{
+ LRESULT funcRetval;
+ int iWndsLocks = 0;
/* Make sure that the window still exists */
if (!IsWindow((*ppWnd)->hwndSelf)) continue;
if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
- if (!func( (*ppWnd)->hwndSelf, lParam )) break;
+
+ /* To avoid any deadlocks, all the locks on the windows
+ structures must be suspended before the control
+ is passed to the application */
+ iWndsLocks = WIN_SuspendWndsLock();
+ funcRetval = func( (*ppWnd)->hwndSelf, lParam );
+ WIN_RestoreWndsLock(iWndsLocks);
+
+ if (!funcRetval) break;
}
WIN_ReleaseWinArray(list);
WIN_ReleaseDesktop();
@@ -2841,11 +2861,20 @@
for ( ; *ppWnd; ppWnd++)
{
+ int iWndsLocks = 0;
+
/* Make sure that the window still exists */
if (!IsWindow((*ppWnd)->hwndSelf)) continue;
/* Build children list first */
childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
+
+ /* To avoid any deadlocks, all the locks on the windows
+ structures must be suspended before the control
+ is passed to the application */
+ iWndsLocks = WIN_SuspendWndsLock();
ret = func( (*ppWnd)->hwndSelf, lParam );
+ WIN_RestoreWndsLock(iWndsLocks);
+
if (childList)
{
if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
diff --git a/windows/winproc.c b/windows/winproc.c
index 2541d22..601ecf2 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -118,9 +118,17 @@
static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
+ LRESULT retvalue;
+ int iWndsLocks;
+
TRACE(relay, "(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
- return proc( hwnd, msg, wParam, lParam );
+ /* To avoid any deadlocks, all the locks on the windows structures
+ must be suspended before the control is passed to the application */
+ iWndsLocks = WIN_SuspendWndsLock();
+ retvalue = proc( hwnd, msg, wParam, lParam );
+ WIN_RestoreWndsLock(iWndsLocks);
+ return retvalue;
}
@@ -2156,7 +2164,9 @@
if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
return 0;
+
result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
+
return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
}