Made access to the wnd struct thread-safe.

diff --git a/controls/button.c b/controls/button.c
index fe2f98f..6c59172 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -79,6 +79,7 @@
                               WPARAM wParam, LPARAM lParam )
 {
     RECT rect;
+    LRESULT retvalue;
     POINT pt = { LOWORD(lParam), HIWORD(lParam) };
     WND *wndPtr = WIN_FindWndPtr(hWnd);
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
@@ -87,6 +88,7 @@
     switch (uMsg)
     {
     case WM_GETDLGCODE:
+        WIN_ReleaseWndPtr(wndPtr);
         switch(style)
         {
         case BS_PUSHBUTTON:      return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON;
@@ -109,12 +111,18 @@
             checkBoxWidth  = bmp.bmWidth / 4;
             checkBoxHeight = bmp.bmHeight / 3;
         }
-        if (style < 0L || style >= MAX_BTN_TYPE) return -1; /* abort */
+        if (style < 0L || style >= MAX_BTN_TYPE)
+        {
+            WIN_ReleaseWndPtr(wndPtr);
+            return -1; /* abort */
+        }
         infoPtr->state = BUTTON_UNCHECKED;
         infoPtr->hFont = 0;
+        WIN_ReleaseWndPtr(wndPtr);
         return 0;
 
     case WM_ERASEBKGND:
+        WIN_ReleaseWndPtr(wndPtr);
         return 1;
 
     case WM_PAINT:
@@ -171,6 +179,7 @@
         break;
 
     case WM_NCHITTEST:
+        WIN_ReleaseWndPtr(wndPtr);
         if(style == BS_GROUPBOX) return HTTRANSPARENT;
         return DefWindowProcA( hWnd, uMsg, wParam, lParam );
 
@@ -178,6 +187,7 @@
         DEFWND_SetText( wndPtr, (LPCSTR)lParam );
 	if( wndPtr->dwStyle & WS_VISIBLE )
             PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+        WIN_ReleaseWndPtr(wndPtr);
         return 0;
 
     case WM_SETFONT:
@@ -187,7 +197,9 @@
         break;
 
     case WM_GETFONT:
-        return infoPtr->hFont;
+        retvalue = infoPtr->hFont;
+        WIN_ReleaseWndPtr(wndPtr);
+        return retvalue;
 
     case WM_SETFOCUS:
         infoPtr->state |= BUTTON_HASFOCUS;
@@ -219,7 +231,9 @@
 
     case BM_GETCHECK16:
     case BM_GETCHECK:
-        return infoPtr->state & 3;
+        retvalue = infoPtr->state & 3;
+        WIN_ReleaseWndPtr(wndPtr);
+        return retvalue;
 
     case BM_SETCHECK16:
     case BM_SETCHECK:
@@ -242,7 +256,9 @@
 
     case BM_GETSTATE16:
     case BM_GETSTATE:
-        return infoPtr->state;
+        retvalue = infoPtr->state;
+        WIN_ReleaseWndPtr(wndPtr);
+        return retvalue;
 
     case BM_SETSTATE16:
     case BM_SETSTATE:
@@ -260,8 +276,10 @@
         break;
 
     default:
+        WIN_ReleaseWndPtr(wndPtr);
         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return 0;
 }
 
@@ -522,11 +540,14 @@
     start = sibling = GetNextDlgGroupItem( parent, wndPtr->hwndSelf, TRUE );
     do
     {
+        WND *tmpWnd;
         if (!sibling) break;
+        tmpWnd = WIN_FindWndPtr(sibling);
         if ((wndPtr->hwndSelf != sibling) &&
-            ((WIN_FindWndPtr(sibling)->dwStyle & 0x0f) == BS_AUTORADIOBUTTON))
+            ((tmpWnd->dwStyle & 0x0f) == BS_AUTORADIOBUTTON))
             SendMessageA( sibling, BM_SETCHECK, BUTTON_UNCHECKED, 0 );
         sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
+        WIN_ReleaseWndPtr(tmpWnd);
     } while (sibling != start);
 }
 
diff --git a/controls/combo.c b/controls/combo.c
index 47fa929..1778402 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -1286,6 +1286,7 @@
 LRESULT WINAPI ComboWndProc( HWND hwnd, UINT message,
                              WPARAM wParam, LPARAM lParam )
 {
+    LRESULT retvalue;
     WND*	pWnd = WIN_FindWndPtr(hwnd);
    
     if( pWnd )
@@ -1302,58 +1303,59 @@
 	/* System messages */
 
      	case WM_NCCREATE: 
-		return COMBO_NCCreate(pWnd, lParam);
-
+                retvalue = COMBO_NCCreate(pWnd, lParam);
+                goto END;
      	case WM_NCDESTROY: 
 		COMBO_NCDestroy(lphc);
 		break;
 
      	case WM_CREATE: 
-		return COMBO_Create(lphc, pWnd, lParam);
+                retvalue = COMBO_Create(lphc, pWnd, lParam);
+                goto END;
 
      	case WM_PAINT:
 		/* wParam may contain a valid HDC! */
-		return COMBO_Paint(lphc, wParam);
-
+		retvalue = COMBO_Paint(lphc, wParam);
+                goto END;
 	case WM_ERASEBKGND:
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
      	case WM_GETDLGCODE: 
-		return (LRESULT)(DLGC_WANTARROWS | DLGC_WANTCHARS);
-
+		retvalue = (LRESULT)(DLGC_WANTARROWS | DLGC_WANTCHARS);
+                goto END;
 	case WM_SIZE:
 	        if( lphc->hWndLBox && 
 		  !(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_SETFONT:
 		COMBO_Font( lphc, (HFONT16)wParam, (BOOL)lParam );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_GETFONT:
-		return (LRESULT)lphc->hFont;
-
+		retvalue = (LRESULT)lphc->hFont;
+                goto END;
 	case WM_SETFOCUS:
 		if( lphc->wState & CBF_EDIT )
 		    SetFocus( lphc->hWndEdit );
 		else
 		    COMBO_SetFocus( lphc );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_KILLFOCUS:
 #define hwndFocus ((HWND16)wParam)
 		if( !hwndFocus ||
 		    (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox ))
 		    COMBO_KillFocus( lphc );
 #undef hwndFocus
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_COMMAND:
-		return COMBO_Command( lphc, wParam, (HWND)lParam );
-
+		retvalue = COMBO_Command( lphc, wParam, (HWND)lParam );
+                goto END;
 	case WM_GETTEXT:
-		return COMBO_GetText( lphc, (UINT)wParam, (LPSTR)lParam );
-
+		retvalue = COMBO_GetText( lphc, (UINT)wParam, (LPSTR)lParam );
+                goto END;
 	case WM_SETTEXT:
 	case WM_GETTEXTLENGTH:
 	case WM_CLEAR:
@@ -1361,21 +1363,24 @@
         case WM_PASTE:
 	case WM_COPY:
 		if( lphc->wState & CBF_EDIT )
-		    return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
-		return CB_ERR;
-
+                {
+                    retvalue = SendMessageA( lphc->hWndEdit, message, wParam, lParam );
+                    goto END;
+                }
+		retvalue = CB_ERR;
+                goto END;
 	case WM_DRAWITEM:
 	case WM_DELETEITEM:
 	case WM_COMPAREITEM:
 	case WM_MEASUREITEM:
-		return COMBO_ItemOp( lphc, message, wParam, lParam );
-
+		retvalue = COMBO_ItemOp( lphc, message, wParam, lParam );
+                goto END;
 	case WM_ENABLE:
 		if( lphc->wState & CBF_EDIT )
 		    EnableWindow( lphc->hWndEdit, (BOOL)wParam ); 
 		EnableWindow( lphc->hWndLBox, (BOOL)wParam );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_SETREDRAW:
 		if( wParam )
 		    lphc->wState &= ~CBF_NOREDRAW;
@@ -1385,8 +1390,8 @@
 		if( lphc->wState & CBF_EDIT )
 		    SendMessageA( lphc->hWndEdit, message, wParam, lParam );
 		SendMessageA( lphc->hWndLBox, message, wParam, lParam );
-		return 0;
-		
+		retvalue = 0;
+		goto END;
 	case WM_SYSKEYDOWN:
 		if( KEYDATA_ALT & HIWORD(lParam) )
 		    if( wParam == VK_UP || wParam == VK_DOWN )
@@ -1396,106 +1401,113 @@
 	case WM_CHAR:
 	case WM_KEYDOWN:
 		if( lphc->wState & CBF_EDIT )
-		    return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
+		    retvalue = SendMessageA( lphc->hWndEdit, message, wParam, lParam );
 		else
-		    return SendMessageA( lphc->hWndLBox, message, wParam, lParam );
+		    retvalue = SendMessageA( lphc->hWndLBox, message, wParam, lParam );
 
 	case WM_LBUTTONDOWN: 
 		if( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self->hwndSelf );
 		if( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_LBUTTONUP:
 		COMBO_LButtonUp( lphc, lParam );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case WM_MOUSEMOVE: 
 		if( lphc->wState & CBF_CAPTURE ) 
 		    COMBO_MouseMove( lphc, wParam, lParam );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	/* Combo messages */
 
 	case CB_ADDSTRING16:
 		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 	case CB_ADDSTRING:
-		return SendMessageA( lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
+                goto END;
 	case CB_INSERTSTRING16:
 		wParam = (INT)(INT16)wParam;
 		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 	case CB_INSERTSTRING:
-		return SendMessageA( lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
+                goto END;
 	case CB_DELETESTRING16:
 	case CB_DELETESTRING:
-		return SendMessageA( lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
+                goto END;
 	case CB_SELECTSTRING16:
 		wParam = (INT)(INT16)wParam;
 		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 	case CB_SELECTSTRING:
-		return COMBO_SelectString( lphc, (INT)wParam, (LPSTR)lParam );
-
+		retvalue = COMBO_SelectString( lphc, (INT)wParam, (LPSTR)lParam );
+                goto END;
 	case CB_FINDSTRING16:
 		wParam = (INT)(INT16)wParam;
 		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 	case CB_FINDSTRING:
-		return SendMessageA( lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
+                goto END;
 	case CB_FINDSTRINGEXACT16:
 		wParam = (INT)(INT16)wParam;
 		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 	case CB_FINDSTRINGEXACT:
-		return SendMessageA( lphc->hWndLBox, LB_FINDSTRINGEXACT, 
+		retvalue = SendMessageA( lphc->hWndLBox, LB_FINDSTRINGEXACT, 
 						       wParam, lParam );
+                goto END;
 	case CB_SETITEMHEIGHT16:
 		wParam = (INT)(INT16)wParam;	/* signed integer */
 	case CB_SETITEMHEIGHT:
-		return COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
-
+		retvalue = COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
+                goto END;
 	case CB_GETITEMHEIGHT16:
 		wParam = (INT)(INT16)wParam;
 	case CB_GETITEMHEIGHT:
 		if( (INT)wParam >= 0 )	/* listbox item */
-		    return SendMessageA( lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
-		return (lphc->RectEdit.bottom - lphc->RectEdit.top);
-
+                {
+                    retvalue = SendMessageA( lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
+                    goto END;
+                }
+                retvalue = (lphc->RectEdit.bottom - lphc->RectEdit.top);
+                goto END;
 	case CB_RESETCONTENT16: 
 	case CB_RESETCONTENT:
 		SendMessageA( lphc->hWndLBox, LB_RESETCONTENT, 0, 0 );
 		CBPaintText( lphc, 0 );
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case CB_INITSTORAGE:
-		return SendMessageA( lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
+                goto END;
 	case CB_GETHORIZONTALEXTENT:
-		return SendMessageA( lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
+                goto END;
 	case CB_SETHORIZONTALEXTENT:
-		return SendMessageA( lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
+                goto END;
 	case CB_GETTOPINDEX:
-		return SendMessageA( lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
+                goto END;
 	case CB_GETLOCALE:
-		return SendMessageA( lphc->hWndLBox, LB_GETLOCALE, 0, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETLOCALE, 0, 0);
+                goto END;
 	case CB_SETLOCALE:
-		return SendMessageA( lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
+                goto END;
 	case CB_GETDROPPEDWIDTH:
 		if( lphc->droppedWidth )
-		    return lphc->droppedWidth;
-		return lphc->RectCombo.right - lphc->RectCombo.left - 
+                {
+                    retvalue = lphc->droppedWidth;
+                    goto END;
+                }
+		retvalue = lphc->RectCombo.right - lphc->RectCombo.left - 
 		           (lphc->wState & CBF_EDIT) ? CBitOffset : 0;
-
+                goto END;
 	case CB_SETDROPPEDWIDTH:
 		if( (CB_GETTYPE(lphc) != CBS_SIMPLE) &&
 		    (INT)wParam < 32768 ) lphc->droppedWidth = (INT)wParam;
-		return CB_ERR;
-
+		retvalue = CB_ERR;
+                goto END;
 	case CB_GETDROPPEDCONTROLRECT16:
 		lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 		if( lParam ) 
@@ -1504,22 +1516,23 @@
 		    CBGetDroppedControlRect( lphc, &r );
 		    CONV_RECT32TO16( &r, (LPRECT16)lParam );
 		}
-		return CB_OKAY;
-
+		retvalue = CB_OKAY;
+                goto END;
 	case CB_GETDROPPEDCONTROLRECT:
 		if( lParam ) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
-		return CB_OKAY;
-
+		retvalue = CB_OKAY;
+                goto END;
 	case CB_GETDROPPEDSTATE16:
 	case CB_GETDROPPEDSTATE:
-		return (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;
-
+		retvalue = (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;
+                goto END;
 	case CB_DIR16: 
                 lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
                 /* fall through */
 	case CB_DIR:
-		return COMBO_Directory( lphc, (UINT)wParam, 
+		retvalue = COMBO_Directory( lphc, (UINT)wParam, 
 				       (LPSTR)lParam, (message == CB_DIR));
+                goto END;
 	case CB_SHOWDROPDOWN16:
 	case CB_SHOWDROPDOWN:
 		if( CB_GETTYPE(lphc) != CBS_SIMPLE )
@@ -1533,16 +1546,16 @@
 			if( lphc->wState & CBF_DROPPED ) 
 		            CBRollUp( lphc, FALSE, TRUE );
 		}
-		return TRUE;
-
+		retvalue = TRUE;
+                goto END;
 	case CB_GETCOUNT16: 
 	case CB_GETCOUNT:
-		return SendMessageA( lphc->hWndLBox, LB_GETCOUNT, 0, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETCOUNT, 0, 0);
+                goto END;
 	case CB_GETCURSEL16: 
 	case CB_GETCURSEL:
-		return SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+                goto END;
 	case CB_SETCURSEL16:
 		wParam = (INT)(INT16)wParam;
 	case CB_SETCURSEL:
@@ -1554,29 +1567,29 @@
 		    CBPaintText( lphc, 0 );
 		    lphc->wState &= ~CBF_SELCHANGE;
 		}
-	        return lParam;
-
+	        retvalue = lParam;
+                goto END;
 	case CB_GETLBTEXT16: 
 		wParam = (INT)(INT16)wParam;
 		lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
 	case CB_GETLBTEXT:
-		return SendMessageA( lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
+                goto END;
 	case CB_GETLBTEXTLEN16: 
 		wParam = (INT)(INT16)wParam;
 	case CB_GETLBTEXTLEN:
-		return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
+                goto END;
 	case CB_GETITEMDATA16:
 		wParam = (INT)(INT16)wParam;
 	case CB_GETITEMDATA:
-		return SendMessageA( lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
+                goto END;
 	case CB_SETITEMDATA16:
 		wParam = (INT)(INT16)wParam;
 	case CB_SETITEMDATA:
-		return SendMessageA( lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
-
+		retvalue = SendMessageA( lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
+                goto END;
 	case CB_GETEDITSEL16: 
 		wParam = lParam = 0;   /* just in case */
 	case CB_GETEDITSEL:
@@ -1584,37 +1597,48 @@
 		{
 		    INT	a, b;
 
-		    return SendMessageA( lphc->hWndEdit, EM_GETSEL,
+		    retvalue = SendMessageA( lphc->hWndEdit, EM_GETSEL,
 					   (wParam) ? wParam : (WPARAM)&a,
 					   (lParam) ? lParam : (LPARAM)&b );
+                    goto END;
 		}
-		return CB_ERR;
-
+		retvalue = CB_ERR;
+                goto END;
 	case CB_SETEDITSEL16: 
 	case CB_SETEDITSEL:
 		if( lphc->wState & CBF_EDIT ) 
-		    return SendMessageA( lphc->hWndEdit, EM_SETSEL, 
+                {
+                    retvalue = SendMessageA( lphc->hWndEdit, EM_SETSEL,
 			  (INT)(INT16)LOWORD(lParam), (INT)(INT16)HIWORD(lParam) );
-		return CB_ERR;
-
+                    goto END;
+                }
+		retvalue = CB_ERR;
+                goto END;
 	case CB_SETEXTENDEDUI16:
 	case CB_SETEXTENDEDUI:
-		if( CB_GETTYPE(lphc) == CBS_SIMPLE ) return CB_ERR;
-
+                if( CB_GETTYPE(lphc) == CBS_SIMPLE )
+                {
+                    retvalue = CB_ERR;
+                    goto END;
+                }
 		if( wParam )
 		    lphc->wState |= CBF_EUI;
 		else lphc->wState &= ~CBF_EUI;
-		return CB_OKAY;
-
+		retvalue = CB_OKAY;
+                goto END;
 	case CB_GETEXTENDEDUI16:
 	case CB_GETEXTENDEDUI:
-		return (lphc->wState & CBF_EUI) ? TRUE : FALSE;
-
+		retvalue = (lphc->wState & CBF_EUI) ? TRUE : FALSE;
+                goto END;
 	case (WM_USER + 0x1B):
 	        WARN(combo, "[%04x]: undocumented msg!\n", hwnd );
     }
-    return DefWindowProcA(hwnd, message, wParam, lParam);
+    retvalue = DefWindowProcA(hwnd, message, wParam, lParam);
+    goto END;
   }
-  return CB_ERR;
+    retvalue = CB_ERR;
+END:
+    WIN_ReleaseWndPtr(pWnd);
+    return retvalue;
 }
 
diff --git a/controls/desktop.c b/controls/desktop.c
index 96f5a34..f2573f8 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -24,8 +24,12 @@
  */
 int DESKTOP_GetScreenWidth()
 {
+    int retvalue;
   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
-  return MONITOR_GetWidth(pDesktop->pPrimaryMonitor);
+    retvalue = MONITOR_GetWidth(pDesktop->pPrimaryMonitor);
+    WIN_ReleaseDesktop();
+    return retvalue;
+    
 }
 
 /***********************************************************************
@@ -35,8 +39,12 @@
  */
 int DESKTOP_GetScreenHeight()
 {
+    int retvalue;
   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
-  return MONITOR_GetHeight(pDesktop->pPrimaryMonitor);
+    retvalue = MONITOR_GetHeight(pDesktop->pPrimaryMonitor);
+    WIN_ReleaseDesktop();
+    return retvalue;
+    
 }
 
 /***********************************************************************
@@ -46,8 +54,12 @@
  */
 int DESKTOP_GetScreenDepth()
 {
+    int retvalue;
   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
-  return MONITOR_GetDepth(pDesktop->pPrimaryMonitor);
+    retvalue = MONITOR_GetDepth(pDesktop->pPrimaryMonitor);
+    WIN_ReleaseDesktop();
+    return retvalue;
+
 }
 
 /***********************************************************************
@@ -119,6 +131,8 @@
     if (Wnd->hrgnUpdate > 1) DeleteObject( Wnd->hrgnUpdate );
     Wnd->hrgnUpdate = 0;
 
+    WIN_ReleaseWndPtr(Wnd);
+    
     GetClientRect( hwnd, &rect );    
 
     /* Paint desktop pattern (only if wall paper does not cover everything) */
@@ -173,6 +187,7 @@
 LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message,
                                WPARAM wParam, LPARAM lParam )
 {
+    LRESULT retvalue;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
 
@@ -187,23 +202,36 @@
 	desktopPtr->hbitmapWallPaper = 0;
 	SetDeskPattern();
 	SetDeskWallPaper( (LPSTR)-1 );
-	return 1;
+        retvalue = 1;
+        goto END;
 	
     case WM_ERASEBKGND:
 	if (X11DRV_WND_GetXRootWindow(wndPtr) == 
 	    DefaultRootWindow(display))
-	  return 1;
-	return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, desktopPtr );
+        {
+            retvalue = 1;
+            goto END;
+        }
+        retvalue = DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, desktopPtr );
+        goto END;
 
     case WM_SYSCOMMAND:
-	if ((wParam & 0xfff0) != SC_CLOSE) return 0;
+        if ((wParam & 0xfff0) != SC_CLOSE)
+        {
+            retvalue = 0;
+            goto END;
+        }
 	ExitWindows16( 0, 0 ); 
 
     case WM_SETCURSOR:
-        return (LRESULT)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
+        retvalue = (LRESULT)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
+        goto END;
     }
     
-    return 0;
+    retvalue = 0;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 /***********************************************************************
@@ -212,11 +240,14 @@
  */
 BOOL WINAPI PaintDesktop(HDC hdc)
 {
+    BOOL retvalue;
     HWND hwnd = GetDesktopWindow();
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
+    retvalue = DESKTOP_DoEraseBkgnd( hwnd, hdc, desktopPtr );
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 
-    return DESKTOP_DoEraseBkgnd( hwnd, hdc, desktopPtr );
 }
 
 /***********************************************************************
@@ -270,6 +301,7 @@
 	desktopPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
 	desktopPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
     }
+    WIN_ReleaseDesktop();
     return TRUE;
 }
 
@@ -301,6 +333,7 @@
 	DeleteObject( hbitmap );
     }
     else desktopPtr->hbrushPattern = CreateSolidBrush( GetSysColor(COLOR_BACKGROUND) );
+    WIN_ReleaseDesktop();
     return TRUE;
 }
 
diff --git a/controls/edit.c b/controls/edit.c
index 125ed0f..0971dda 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -310,15 +310,21 @@
 	case WM_DESTROY:
 		DPRINTF_EDIT_MSG32("WM_DESTROY");
 		EDIT_WM_Destroy(wnd, es);
-		return 0;
+                result = 0;
+                goto END;
 
 	case WM_NCCREATE:
 		DPRINTF_EDIT_MSG32("WM_NCCREATE");
-		return EDIT_WM_NCCreate(wnd, (LPCREATESTRUCTA)lParam);
+                result = EDIT_WM_NCCreate(wnd, (LPCREATESTRUCTA)lParam);
+                goto END;
 	}
 
 	if (!es)
-		return DefWindowProcA(hwnd, msg, wParam, lParam);
+        {
+            result = DefWindowProcA(hwnd, msg, wParam, lParam);
+            goto END;
+        }
+
 
 	EDIT_LockBuffer(wnd, es);
 	switch (msg) {
@@ -633,7 +639,7 @@
 			wnd->dwStyle &= ~ES_READONLY;
 			es->style &= ~ES_READONLY;
 		}
-		return 1;
+                result = 1;
  		break;
 
 	case EM_SETWORDBREAKPROC16:
@@ -856,7 +862,10 @@
 		break;
 	}
 	EDIT_UnlockBuffer(wnd, es, FALSE);
+    END:
+        WIN_ReleaseWndPtr(wnd);
 	return result;
+        
 }
 
 
diff --git a/controls/icontitle.c b/controls/icontitle.c
index 38d5b78..82dd726 100644
--- a/controls/icontitle.c
+++ b/controls/icontitle.c
@@ -54,6 +54,7 @@
 	wndPtr->owner = wnd;	/* MDI depends on this */
 	wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER);
 	if( wnd->dwStyle & WS_DISABLED ) wndPtr->dwStyle |= WS_DISABLED;
+        WIN_ReleaseWndPtr(wndPtr);
 	return hWnd;
     }
     return 0;
@@ -187,24 +188,25 @@
 LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg,
                                  WPARAM wParam, LPARAM lParam )
 {
+    LRESULT retvalue;
     WND *wnd = WIN_FindWndPtr( hWnd );
 
     switch( msg )
     {
 	case WM_NCHITTEST:
-	     return HTCAPTION;
-
+	     retvalue = HTCAPTION;
+             goto END;
 	case WM_NCMOUSEMOVE:
 	case WM_NCLBUTTONDBLCLK:
-	     return SendMessageA( wnd->owner->hwndSelf, msg, wParam, lParam );	
-
+	     retvalue = SendMessageA( wnd->owner->hwndSelf, msg, wParam, lParam );	
+             goto END;
 	case WM_ACTIVATE:
 	     if( wParam ) SetActiveWindow( wnd->owner->hwndSelf );
 	     /* fall through */
 
 	case WM_CLOSE:
-	     return 0;
-
+	     retvalue = 0;
+             goto END;
 	case WM_SHOWWINDOW:
 	     if( wnd && wParam )
 	     {
@@ -220,25 +222,30 @@
 				     titleRect.right, titleRect.bottom, 
 				     SWP_NOACTIVATE | SWP_NOZORDER );
 	     }
-	     return 0;
-
+	     retvalue = 0;
+             goto END;
 	case WM_ERASEBKGND:
 	     if( wnd )
 	     {
-		 WND* iconWnd = wnd->owner;
+		 WND* iconWnd = WIN_LockWndPtr(wnd->owner);
 
 		 if( iconWnd->dwStyle & WS_CHILD )
 		     lParam = SendMessageA( iconWnd->hwndSelf, WM_ISACTIVEICON, 0, 0 );
 		 else
 		     lParam = (iconWnd->hwndSelf == GetActiveWindow16());
 
+                 WIN_ReleaseWndPtr(iconWnd);
 		 if( ICONTITLE_Paint( wnd, (HDC)wParam, (BOOL)lParam ) )
 		     ValidateRect( hWnd, NULL );
-	         return 1;
+                 retvalue = 1;
+                 goto END;
 	     }
     }
 
-    return DefWindowProcA( hWnd, msg, wParam, lParam );
+    retvalue = DefWindowProcA( hWnd, msg, wParam, lParam );
+END:
+    WIN_ReleaseWndPtr(wnd);
+    return retvalue;
 }
 
 
diff --git a/controls/listbox.c b/controls/listbox.c
index 1c17bef..a298ff9 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -2120,19 +2120,26 @@
     LRESULT ret;
     LB_DESCR *descr;
     WND *wnd = WIN_FindWndPtr( hwnd );
+    LRESULT retvalue;
 
     if (!wnd) return 0;
     if (!(descr = *(LB_DESCR **)wnd->wExtra))
     {
         if (msg == WM_CREATE)
         {
-            if (!LISTBOX_Create( wnd, NULL )) return -1;
+            if (!LISTBOX_Create( wnd, NULL ))
+            {
+                retvalue = -1;
+                goto END;
+            }
             TRACE(listbox, "creating wnd=%04x descr=%p\n",
 			 hwnd, *(LB_DESCR **)wnd->wExtra );
-            return 0;
+            retvalue = 0;
+            goto END;
         }
         /* Ignore all other messages before we get a WM_CREATE */
-        return DefWindowProcA( hwnd, msg, wParam, lParam );
+        retvalue = DefWindowProcA( hwnd, msg, wParam, lParam );
+        goto END;
     }
 
     TRACE(listbox, "[%04x]: msg %s wp %08x lp %08lx\n",
@@ -2142,104 +2149,133 @@
     case LB_RESETCONTENT16:
     case LB_RESETCONTENT:
         LISTBOX_ResetContent( wnd, descr );
-        return 0;
+        retvalue = 0;
+        goto END;
 
     case LB_ADDSTRING16:
         if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
         /* fall through */
     case LB_ADDSTRING:
         wParam = LISTBOX_FindStringPos( wnd, descr, (LPCSTR)lParam, FALSE );
-        return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );
+        retvalue = LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );
+        goto END;
 
     case LB_INSERTSTRING16:
         if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
         wParam = (INT)(INT16)wParam;
         /* fall through */
     case LB_INSERTSTRING:
-        return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );
+        retvalue = LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );
+        goto END;
 
     case LB_ADDFILE16:
         if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
         /* fall through */
     case LB_ADDFILE:
         wParam = LISTBOX_FindFileStrPos( wnd, descr, (LPCSTR)lParam );
-        return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );
+        retvalue = LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );
+        goto END;
 
     case LB_DELETESTRING16:
     case LB_DELETESTRING:
-        return LISTBOX_RemoveItem( wnd, descr, wParam );
+        retvalue = LISTBOX_RemoveItem( wnd, descr, wParam );
+        goto END;
 
     case LB_GETITEMDATA16:
     case LB_GETITEMDATA:
         if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
-            return LB_ERR;
-        return descr->items[wParam].data;
+        {
+            retvalue = LB_ERR;
+            goto END;
+        }
+        retvalue = descr->items[wParam].data;
+        goto END;
 
     case LB_SETITEMDATA16:
     case LB_SETITEMDATA:
         if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
-            return LB_ERR;
+        {
+            retvalue = LB_ERR;
+            goto END;
+        }
         descr->items[wParam].data = (DWORD)lParam;
-        return LB_OKAY;
+        retvalue = LB_OKAY;
+        goto END;
 
     case LB_GETCOUNT16:
     case LB_GETCOUNT:
-        return descr->nb_items;
+        retvalue = descr->nb_items;
+        goto END;
 
     case LB_GETTEXT16:
         lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
         /* fall through */
     case LB_GETTEXT:
-        return LISTBOX_GetText( wnd, descr, wParam, (LPSTR)lParam );
+        retvalue = LISTBOX_GetText( wnd, descr, wParam, (LPSTR)lParam );
+        goto END;
 
     case LB_GETTEXTLEN16:
         /* fall through */
     case LB_GETTEXTLEN:
-        if (wParam >= descr->nb_items) return LB_ERR;
-        return (HAS_STRINGS(descr) ? strlen(descr->items[wParam].str)
+        if (wParam >= descr->nb_items)
+        {
+            retvalue = LB_ERR;
+            goto END;
+        }
+        retvalue = (HAS_STRINGS(descr) ? strlen(descr->items[wParam].str)
                                    : sizeof(DWORD));
+        goto END;
 
     case LB_GETCURSEL16:
     case LB_GETCURSEL:
-        return descr->selected_item;
+        retvalue = descr->selected_item;
+        goto END;
 
     case LB_GETTOPINDEX16:
     case LB_GETTOPINDEX:
-        return descr->top_item;
+        retvalue = descr->top_item;
+        goto END;
 
     case LB_GETITEMHEIGHT16:
     case LB_GETITEMHEIGHT:
-        return LISTBOX_GetItemHeight( wnd, descr, wParam );
+        retvalue = LISTBOX_GetItemHeight( wnd, descr, wParam );
+        goto END;
 
     case LB_SETITEMHEIGHT16:
         lParam = LOWORD(lParam);
         /* fall through */
     case LB_SETITEMHEIGHT:
-        return LISTBOX_SetItemHeight( wnd, descr, wParam, lParam );
+        retvalue = LISTBOX_SetItemHeight( wnd, descr, wParam, lParam );
+        goto END;
 
     case LB_ITEMFROMPOINT:
         {
             POINT pt = { LOWORD(lParam), HIWORD(lParam) };
             RECT rect = { 0, 0, descr->width, descr->height };
-            return MAKELONG( LISTBOX_GetItemFromPoint(wnd, descr, pt.x, pt.y),
+            retvalue = MAKELONG( LISTBOX_GetItemFromPoint(wnd, descr, pt.x, pt.y),
                              PtInRect( &rect, pt ) );
+            goto END;
         }
 
     case LB_SETCARETINDEX16:
     case LB_SETCARETINDEX:
-        return LISTBOX_SetCaretIndex( wnd, descr, wParam, !lParam );
+        retvalue = LISTBOX_SetCaretIndex( wnd, descr, wParam, !lParam );
+        goto END;
 
     case LB_GETCARETINDEX16:
     case LB_GETCARETINDEX:
-        return descr->focus_item;
+        retvalue = descr->focus_item;
+        goto END;
 
     case LB_SETTOPINDEX16:
     case LB_SETTOPINDEX:
-        return LISTBOX_SetTopItem( wnd, descr, wParam, TRUE );
+        retvalue = LISTBOX_SetTopItem( wnd, descr, wParam, TRUE );
+        goto END;
 
     case LB_SETCOLUMNWIDTH16:
     case LB_SETCOLUMNWIDTH:
-        return LISTBOX_SetColumnWidth( wnd, descr, wParam );
+        retvalue = LISTBOX_SetColumnWidth( wnd, descr, wParam );
+        goto END;
 
     case LB_GETITEMRECT16:
         {
@@ -2247,24 +2283,28 @@
             ret = LISTBOX_GetItemRect( wnd, descr, (INT16)wParam, &rect );
             CONV_RECT32TO16( &rect, (RECT16 *)PTR_SEG_TO_LIN(lParam) );
         }
-        return ret;
+        retvalue = ret;
+        goto END;
 
     case LB_GETITEMRECT:
-        return LISTBOX_GetItemRect( wnd, descr, wParam, (RECT *)lParam );
+        retvalue = LISTBOX_GetItemRect( wnd, descr, wParam, (RECT *)lParam );
+        goto END;
 
     case LB_FINDSTRING16:
         wParam = (INT)(INT16)wParam;
         if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
         /* fall through */
     case LB_FINDSTRING:
-        return LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, FALSE );
+        retvalue = LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, FALSE );
+        goto END;
 
     case LB_FINDSTRINGEXACT16:
         wParam = (INT)(INT16)wParam;
         if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
         /* fall through */
     case LB_FINDSTRINGEXACT:
-        return LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, TRUE );
+        retvalue = LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, TRUE );
+        goto END;
 
     case LB_SELECTSTRING16:
         wParam = (INT)(INT16)wParam;
@@ -2274,9 +2314,14 @@
         {
             INT index = LISTBOX_FindString( wnd, descr, wParam,
                                               (LPCSTR)lParam, FALSE );
-            if (index == LB_ERR) return LB_ERR;
+            if (index == LB_ERR)
+            {
+                retvalue = LB_ERR;
+                goto END;
+            }
             LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
-            return index;
+            retvalue = index;
+            goto END;
         }
 
     case LB_GETSEL16:
@@ -2284,128 +2329,171 @@
         /* fall through */
     case LB_GETSEL:
         if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
-            return LB_ERR;
-        return descr->items[wParam].selected;
+        {
+            retvalue = LB_ERR;
+            goto END;
+        }
+        retvalue = descr->items[wParam].selected;
+        goto END;
 
     case LB_SETSEL16:
         lParam = (INT)(INT16)lParam;
         /* fall through */
     case LB_SETSEL:
-        return LISTBOX_SetSelection( wnd, descr, lParam, wParam, FALSE );
+        retvalue = LISTBOX_SetSelection( wnd, descr, lParam, wParam, FALSE );
+        goto END;
 
     case LB_SETCURSEL16:
         wParam = (INT)(INT16)wParam;
         /* fall through */
     case LB_SETCURSEL:
         LISTBOX_SetCaretIndex( wnd, descr, wParam, TRUE );  
-        return LISTBOX_SetSelection( wnd, descr, wParam, TRUE, FALSE );
+        retvalue = LISTBOX_SetSelection( wnd, descr, wParam, TRUE, FALSE );
+        goto END;
 
     case LB_GETSELCOUNT16:
     case LB_GETSELCOUNT:
-        return LISTBOX_GetSelCount( wnd, descr );
+        retvalue = LISTBOX_GetSelCount( wnd, descr );
+        goto END;
 
     case LB_GETSELITEMS16:
-        return LISTBOX_GetSelItems16( wnd, descr, wParam,
+        retvalue = LISTBOX_GetSelItems16( wnd, descr, wParam,
                                       (LPINT16)PTR_SEG_TO_LIN(lParam) );
+        goto END;
 
     case LB_GETSELITEMS:
-        return LISTBOX_GetSelItems( wnd, descr, wParam, (LPINT)lParam );
+        retvalue = LISTBOX_GetSelItems( wnd, descr, wParam, (LPINT)lParam );
+        goto END;
 
     case LB_SELITEMRANGE16:
     case LB_SELITEMRANGE:
         if (LOWORD(lParam) <= HIWORD(lParam))
-            return LISTBOX_SelectItemRange( wnd, descr, LOWORD(lParam),
+        {
+            retvalue = LISTBOX_SelectItemRange( wnd, descr, LOWORD(lParam),
                                             HIWORD(lParam), wParam );
+        }
         else
-            return LISTBOX_SelectItemRange( wnd, descr, HIWORD(lParam),
+        {
+            retvalue = LISTBOX_SelectItemRange( wnd, descr, HIWORD(lParam),
                                             LOWORD(lParam), wParam );
+        }
+        goto END;
 
     case LB_SELITEMRANGEEX16:
     case LB_SELITEMRANGEEX:
         if ((INT)lParam >= (INT)wParam)
-            return LISTBOX_SelectItemRange( wnd, descr, wParam, lParam, TRUE );
+            retvalue = LISTBOX_SelectItemRange( wnd, descr, wParam, lParam, TRUE );
         else
-            return LISTBOX_SelectItemRange( wnd, descr, lParam, wParam, FALSE);
+            retvalue = LISTBOX_SelectItemRange( wnd, descr, lParam, wParam, FALSE);
+        goto END;
 
     case LB_GETHORIZONTALEXTENT16:
     case LB_GETHORIZONTALEXTENT:
-        return descr->horz_extent;
+        retvalue = descr->horz_extent;
+        goto END;
 
     case LB_SETHORIZONTALEXTENT16:
     case LB_SETHORIZONTALEXTENT:
-        return LISTBOX_SetHorizontalExtent( wnd, descr, wParam );
+        retvalue = LISTBOX_SetHorizontalExtent( wnd, descr, wParam );
+        goto END;
 
     case LB_GETANCHORINDEX16:
     case LB_GETANCHORINDEX:
-        return descr->anchor_item;
+        retvalue = descr->anchor_item;
+        goto END;
 
     case LB_SETANCHORINDEX16:
         wParam = (INT)(INT16)wParam;
         /* fall through */
     case LB_SETANCHORINDEX:
         if (((INT)wParam < -1) || ((INT)wParam >= descr->nb_items))
-            return LB_ERR;
+        {
+            retvalue = LB_ERR;
+            goto END;
+        }
         descr->anchor_item = (INT)wParam;
-        return LB_OKAY;
+        retvalue = LB_OKAY;
+        goto END;
 
     case LB_DIR16:
-        return LISTBOX_Directory( wnd, descr, wParam,
+        retvalue = LISTBOX_Directory( wnd, descr, wParam,
                                   (LPCSTR)PTR_SEG_TO_LIN(lParam), FALSE );
+        goto END;
 
     case LB_DIR:
-        return LISTBOX_Directory( wnd, descr, wParam, (LPCSTR)lParam, TRUE );
+        retvalue = LISTBOX_Directory( wnd, descr, wParam, (LPCSTR)lParam, TRUE );
+        goto END;
 
     case LB_GETLOCALE:
-        return descr->locale;
+        retvalue = descr->locale;
+        goto END;
 
     case LB_SETLOCALE:
         descr->locale = (LCID)wParam;  /* FIXME: should check for valid lcid */
-        return LB_OKAY;
+        retvalue = LB_OKAY;
+        goto END;
 
     case LB_INITSTORAGE:
-        return LISTBOX_InitStorage( wnd, descr, wParam, (DWORD)lParam );
+        retvalue = LISTBOX_InitStorage( wnd, descr, wParam, (DWORD)lParam );
+        goto END;
 
     case LB_SETCOUNT:
-        return LISTBOX_SetCount( wnd, descr, (INT)wParam );
+        retvalue = LISTBOX_SetCount( wnd, descr, (INT)wParam );
+        goto END;
 
     case LB_SETTABSTOPS16:
-        return LISTBOX_SetTabStops( wnd, descr, (INT)(INT16)wParam,
+        retvalue = LISTBOX_SetTabStops( wnd, descr, (INT)(INT16)wParam,
                                     (LPINT)PTR_SEG_TO_LIN(lParam), TRUE );
+        goto END;
 
     case LB_SETTABSTOPS:
-        return LISTBOX_SetTabStops( wnd, descr, wParam,
+        retvalue = LISTBOX_SetTabStops( wnd, descr, wParam,
                                     (LPINT)lParam, FALSE );
+        goto END;
 
     case LB_CARETON16:
     case LB_CARETON:
-        if (descr->caret_on) return LB_OKAY;
+        if (descr->caret_on)
+        {
+            retvalue = LB_OKAY;
+            goto END;
+        }
         descr->caret_on = TRUE;
         if ((descr->focus_item != -1) && (GetFocus() == wnd->hwndSelf))
             LISTBOX_RepaintItem( wnd, descr, descr->focus_item, ODA_FOCUS );
-        return LB_OKAY;
+        retvalue = LB_OKAY;
+        goto END;
 
     case LB_CARETOFF16:
     case LB_CARETOFF:
-        if (!descr->caret_on) return LB_OKAY;
+        if (!descr->caret_on)
+        {
+            retvalue = LB_OKAY;
+            goto END;
+        }
         descr->caret_on = FALSE;
         if ((descr->focus_item != -1) && (GetFocus() == wnd->hwndSelf))
             LISTBOX_RepaintItem( wnd, descr, descr->focus_item, ODA_FOCUS );
-        return LB_OKAY;
+        retvalue = LB_OKAY;
+        goto END;
 
     case WM_DESTROY:
-        return LISTBOX_Destroy( wnd, descr );
+        retvalue = LISTBOX_Destroy( wnd, descr );
+        goto END;
 
     case WM_ENABLE:
         InvalidateRect( hwnd, NULL, TRUE );
-        return 0;
+        retvalue = 0;
+        goto END;
 
     case WM_SETREDRAW:
         LISTBOX_SetRedraw( wnd, descr, wParam != 0 );
-        return 0;
+        retvalue = 0;
+        goto END;
 
     case WM_GETDLGCODE:
-        return DLGC_WANTARROWS | DLGC_WANTCHARS;
-
+        retvalue =DLGC_WANTARROWS | DLGC_WANTCHARS;
+        goto END;
     case WM_PAINT:
         {
             PAINTSTRUCT ps;
@@ -2414,67 +2502,67 @@
             ret = LISTBOX_Paint( wnd, descr, hdc );
             if( !wParam ) EndPaint( hwnd, &ps );
         }
-        return ret;
-
+        retvalue =ret;
+        goto END;
     case WM_SIZE:
         LISTBOX_UpdateSize( wnd, descr );
-        return 0;
-
+        retvalue =0;
+        goto END;
     case WM_GETFONT:
-        return descr->font;
-
+        retvalue =descr->font;
+        goto END;
     case WM_SETFONT:
         LISTBOX_SetFont( wnd, descr, (HFONT)wParam );
         if (lParam) InvalidateRect( wnd->hwndSelf, 0, TRUE );
-        return 0;
-
+        retvalue =0;
+        goto END;
     case WM_SETFOCUS:
         descr->caret_on = TRUE;
         if (descr->focus_item != -1)
             LISTBOX_RepaintItem( wnd, descr, descr->focus_item, ODA_FOCUS );
         SEND_NOTIFICATION( wnd, descr, LBN_SETFOCUS );
-        return 0;
-
+        retvalue =0;
+        goto END;
     case WM_KILLFOCUS:
         if ((descr->focus_item != -1) && descr->caret_on)
             LISTBOX_RepaintItem( wnd, descr, descr->focus_item, ODA_FOCUS );
         SEND_NOTIFICATION( wnd, descr, LBN_KILLFOCUS );
-        return 0;
-
+        retvalue =0;
+        goto END;
     case WM_HSCROLL:
-        return LISTBOX_HandleHScroll( wnd, descr, wParam, lParam );
-
+        retvalue =LISTBOX_HandleHScroll( wnd, descr, wParam, lParam );
+        goto END;
     case WM_VSCROLL:
-        return LISTBOX_HandleVScroll( wnd, descr, wParam, lParam );
-
+        retvalue =LISTBOX_HandleVScroll( wnd, descr, wParam, lParam );
+        goto END;
     case WM_LBUTTONDOWN:
-        return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
+        retvalue =LISTBOX_HandleLButtonDown( wnd, descr, wParam,
                                           (INT16)LOWORD(lParam),
                                           (INT16)HIWORD(lParam) );
-
+        goto END;
     case WM_LBUTTONDBLCLK:
         if (descr->style & LBS_NOTIFY)
             SEND_NOTIFICATION( wnd, descr, LBN_DBLCLK );
-        return 0;
-
+        retvalue =0;
+        goto END;
     case WM_MOUSEMOVE:
         if (GetCapture() == hwnd)
             LISTBOX_HandleMouseMove( wnd, descr, (INT16)LOWORD(lParam),
                                      (INT16)HIWORD(lParam) );
-        return 0;
-
+        retvalue =0;
+        goto END;
     case WM_LBUTTONUP:
-        return LISTBOX_HandleLButtonUp( wnd, descr );
-
+        retvalue =LISTBOX_HandleLButtonUp( wnd, descr );
+        goto END;
     case WM_KEYDOWN:
-        return LISTBOX_HandleKeyDown( wnd, descr, wParam );
-
+        retvalue =LISTBOX_HandleKeyDown( wnd, descr, wParam );
+        goto END;
     case WM_CHAR:
-        return LISTBOX_HandleChar( wnd, descr, wParam );
-
+        retvalue =LISTBOX_HandleChar( wnd, descr, wParam );
+        goto END;
     case WM_SYSTIMER:
-        return LISTBOX_HandleSystemTimer( wnd, descr );
-
+        retvalue =LISTBOX_HandleSystemTimer( wnd, descr );
+        goto END;
     case WM_ERASEBKGND:
         if (IS_OWNERDRAW(descr))
         {
@@ -2483,11 +2571,14 @@
                                               wParam, (LPARAM)wnd->hwndSelf );
             if (hbrush) FillRect( (HDC)wParam, &rect, hbrush );
         }
-        return 1;
-
+        retvalue =1;
+        goto END;
     case WM_DROPFILES:
         if( !descr->lphc ) 
-	    return SendMessageA( descr->owner, msg, wParam, lParam );
+        {
+            retvalue =SendMessageA( descr->owner, msg, wParam, lParam );
+            goto END;
+        }
 	break;
 
     case WM_DROPOBJECT:
@@ -2499,22 +2590,27 @@
             LPDRAGINFO dragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN( (SEGPTR)lParam );
             dragInfo->l = LISTBOX_GetItemFromPoint( wnd, descr, dragInfo->pt.x,
                                                 dragInfo->pt.y );
-            return SendMessageA( descr->owner, msg, wParam, lParam );
+            retvalue =SendMessageA( descr->owner, msg, wParam, lParam );
+            goto END;
         }
 	break;
 
     case WM_NCCREATE:
 	if (TWEAK_WineLook > WIN31_LOOK)
 	    wnd->dwExStyle |= WS_EX_CLIENTEDGE;
-        return DefWindowProcA( hwnd, msg, wParam, lParam );
-
+        retvalue =DefWindowProcA( hwnd, msg, wParam, lParam );
+        goto END;
     default:
         if ((msg >= WM_USER) && (msg < 0xc000))
             WARN(listbox, "[%04x]: unknown msg %04x wp %08x lp %08lx\n",
 			 hwnd, msg, wParam, lParam );
-        return DefWindowProcA( hwnd, msg, wParam, lParam );
+        retvalue =DefWindowProcA( hwnd, msg, wParam, lParam );
+        goto END;
     }
-    return 0;
+    retvalue =0;
+END:
+    WIN_ReleaseWndPtr(wnd);
+    return retvalue;
 }
 
 /***********************************************************************
@@ -2533,8 +2629,10 @@
 
 	    RedrawWindow( lphc->self->hwndSelf, NULL, 0, 
 			    RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
+            WIN_ReleaseWndPtr(wnd);
 	    return lRet;
 	}
+        WIN_ReleaseWndPtr(wnd);
     }
     return CB_ERR;
 }
@@ -2571,20 +2669,20 @@
 
 		     lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
 #undef  lpcs
-		     return LISTBOX_Create( wnd, lphc );
-
+		     lRet =LISTBOX_Create( wnd, lphc );
+                     goto END;
 		case WM_LBUTTONDOWN:
-		     return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
+		     lRet =LISTBOX_HandleLButtonDown( wnd, descr, wParam,
                              (INT16)LOWORD(lParam), (INT16)HIWORD(lParam));
-
+                     goto END;
 		/* avoid activation at all costs */
 
 		case WM_MOUSEACTIVATE:
-		     return MA_NOACTIVATE;
-
+		     lRet =MA_NOACTIVATE;
+                     goto END;
                 case WM_NCACTIVATE:
-                     return FALSE;
-
+                     lRet =FALSE;
+                     goto END;
 		case WM_KEYDOWN:
 		     if( CB_GETTYPE(lphc) != CBS_SIMPLE )
 		     {
@@ -2596,30 +2694,34 @@
 			       && (wParam == VK_DOWN || wParam == VK_UP)) )
 			 {
 			     COMBO_FlipListbox( lphc, FALSE );
-			     return 0;
+                             lRet =0;
+                             goto END;
 			 }
 		     }
-		     return LISTBOX_HandleKeyDown( wnd, descr, wParam );
+		     lRet =LISTBOX_HandleKeyDown( wnd, descr, wParam );
+                     goto END;
 
 		case LB_SETCURSEL16:
 		case LB_SETCURSEL:
 		     lRet = ListBoxWndProc( hwnd, msg, wParam, lParam );
-		     return (lRet == LB_ERR) ? lRet : descr->selected_item; 
-
+		     lRet =(lRet == LB_ERR) ? lRet : descr->selected_item; 
+                     goto END;
 		case WM_NCDESTROY:
 		     if( CB_GETTYPE(lphc) != CBS_SIMPLE )
 			 lphc->hWndLBox = 0;
 		     /* fall through */
 
 	        default:
-		     return ListBoxWndProc( hwnd, msg, wParam, lParam );
+                    lRet =ListBoxWndProc( hwnd, msg, wParam, lParam );
+                    goto END;
 	    }
         }
         lRet = DefWindowProcA( hwnd, msg, wParam, lParam );
 
         TRACE(combo,"\t default on msg [%04x]\n", (UINT16)msg );
     }
-
+END:
+    WIN_ReleaseWndPtr(wnd);
     return lRet;
 }
 
diff --git a/controls/menu.c b/controls/menu.c
index afe3223..3ba4f66 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -272,6 +272,37 @@
     return hMenu;
 }
 
+/***********************************************************************
+ *           MENU_GetTopPopupWnd()
+ *
+ * Return the locked pointer pTopPopupWnd.
+ */
+WND *MENU_GetTopPopupWnd()
+{
+    return WIN_LockWndPtr(pTopPopupWnd);
+}
+/***********************************************************************
+ *           MENU_ReleaseTopPopupWnd()
+ *
+ * Realease the locked pointer pTopPopupWnd.
+ */
+void MENU_ReleaseTopPopupWnd()
+{
+    WIN_ReleaseWndPtr(pTopPopupWnd);
+}
+/***********************************************************************
+ *           MENU_DestroyTopPopupWnd()
+ *
+ * Destroy the locked pointer pTopPopupWnd.
+ */
+void MENU_DestroyTopPopupWnd()
+{
+    WND *tmpWnd = pTopPopupWnd;
+    pTopPopupWnd = NULL;
+    WIN_ReleaseWndPtr(tmpWnd);
+}
+
+
 
 /**********************************************************************
  *           MENU_GetSysMenu
@@ -536,6 +567,7 @@
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return NULL;
     pt.x -= wndPtr->rectWindow.left;
     pt.y -= wndPtr->rectWindow.top;
+    WIN_ReleaseWndPtr(wndPtr);
     item = menu->items;
     for (i = 0; i < menu->nItems; i++, item++)
     {
@@ -565,6 +597,7 @@
     {
 	WND* w = WIN_FindWndPtr(hwndOwner);
 	hmenu = GetSubMenu(w->hSysMenu, 0);
+        WIN_ReleaseWndPtr(w);
     }
 
     if (hmenu)
@@ -1212,16 +1245,24 @@
                          BOOL suppress_draw)
 {
     LPPOPUPMENU lppop;
-    UINT i;
+    UINT i,retvalue;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     
     lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( (HMENU16)wndPtr->wIDmenu );
-    if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU;
+    if (lppop == NULL || lprect == NULL)
+    {
+        retvalue = SYSMETRICS_CYMENU;
+        goto END;
+    }
     TRACE(menu,"(%04x, %p, %p); !\n", 
 		 hDC, lprect, lppop);
     if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd);
     lprect->bottom = lprect->top + lppop->Height;
-    if (suppress_draw) return lppop->Height;
+    if (suppress_draw)
+    {
+        retvalue = lppop->Height;
+        goto END;
+    }
     
     FillRect(hDC, lprect, GetSysColorBrush(COLOR_MENU) );
 
@@ -1236,13 +1277,20 @@
 	LineTo( hDC, lprect->right, lprect->bottom );
     }
 
-    if (lppop->nItems == 0) return SYSMETRICS_CYMENU;
+    if (lppop->nItems == 0)
+    {
+        retvalue = SYSMETRICS_CYMENU;
+        goto END;
+    }
     for (i = 0; i < lppop->nItems; i++)
     {
 	MENU_DrawMenuItem( hwnd, hDC, &lppop->items[i], lppop->Height, TRUE,
 			   ODA_DRAWENTIRE );
     }
-    return lppop->Height;
+    retvalue = lppop->Height;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 } 
 
 
@@ -1251,34 +1299,37 @@
  */
 BOOL MENU_PatchResidentPopup( HQUEUE16 checkQueue, WND* checkWnd )
 {
-    if( pTopPopupWnd )
+    WND *pTPWnd = MENU_GetTopPopupWnd();
+    
+    if( pTPWnd )
     {
 	HTASK16 hTask = 0;
 
 	TRACE(menu,"patching resident popup: %04x %04x [%04x %04x]\n", 
-		checkQueue, checkWnd ? checkWnd->hwndSelf : 0, pTopPopupWnd->hmemTaskQ, 
-		pTopPopupWnd->owner ? pTopPopupWnd->owner->hwndSelf : 0);
+		checkQueue, checkWnd ? checkWnd->hwndSelf : 0, pTPWnd->hmemTaskQ,
+		pTPWnd->owner ? pTPWnd->owner->hwndSelf : 0);
 
 	switch( checkQueue )
 	{
 	    case 0: /* checkWnd is the new popup owner */
 		 if( checkWnd )
 		 {
-		     pTopPopupWnd->owner = checkWnd;
-		     if( pTopPopupWnd->hmemTaskQ != checkWnd->hmemTaskQ )
+		     pTPWnd->owner = checkWnd;
+		     if( pTPWnd->hmemTaskQ != checkWnd->hmemTaskQ )
 			 hTask = QUEUE_GetQueueTask( checkWnd->hmemTaskQ );
 		 }
 		 break;
 
 	    case 0xFFFF: /* checkWnd is destroyed */
-		 if( pTopPopupWnd->owner == checkWnd )
-		     pTopPopupWnd->owner = NULL;
+		 if( pTPWnd->owner == checkWnd )
+                     pTPWnd->owner = NULL;
+                 MENU_ReleaseTopPopupWnd();
 		 return TRUE; 
 
 	    default: /* checkQueue is exiting */
-		 if( pTopPopupWnd->hmemTaskQ == checkQueue )
+		 if( pTPWnd->hmemTaskQ == checkQueue )
 		 {
-		     hTask = QUEUE_GetQueueTask( pTopPopupWnd->hmemTaskQ );
+		     hTask = QUEUE_GetQueueTask( pTPWnd->hmemTaskQ );
 		     hTask = TASK_GetNextTask( hTask );
 		 }
 		 break;
@@ -1289,13 +1340,15 @@
 	    TDB* task = (TDB*)GlobalLock16( hTask );
 	    if( task )
 	    {
-		pTopPopupWnd->hInstance = task->hInstance;
-		pTopPopupWnd->hmemTaskQ = task->hQueue;
+		pTPWnd->hInstance = task->hInstance;
+                pTPWnd->hmemTaskQ = task->hQueue;
+                MENU_ReleaseTopPopupWnd();
 		return TRUE;
 	    } 
 	    else WARN(menu,"failed to patch resident popup.\n");
 	} 
     }
+    MENU_ReleaseTopPopupWnd();
     return FALSE;
 }
 
@@ -1358,8 +1411,13 @@
 					  WS_POPUP, x, y, width, height,
 					  hwndOwner, 0, wndOwner->hInstance,
 					  (LPVOID)hmenu ));
-	    if (!pTopPopupWnd) return FALSE;
+            if (!pTopPopupWnd)
+            {
+                WIN_ReleaseWndPtr(wndOwner);
+                return FALSE;
+            }
 	    menu->hWnd = pTopPopupWnd->hwndSelf;
+            MENU_ReleaseTopPopupWnd();
 	} 
 	else
 	    if( uSubPWndLevel )
@@ -1370,19 +1428,25 @@
 					  WS_POPUP, x, y, width, height,
 					  menu->hWnd, 0, wndOwner->hInstance,
 					  (LPVOID)hmenu );
-		if( !menu->hWnd ) return FALSE;
+                if( !menu->hWnd )
+                {
+                    WIN_ReleaseWndPtr(wndOwner);
+                    return FALSE;
+                }
 	    }
 	    else /* top level popup menu window already exists */
 	    {
-		menu->hWnd = pTopPopupWnd->hwndSelf;
+                WND *pTPWnd = MENU_GetTopPopupWnd();
+		menu->hWnd = pTPWnd->hwndSelf;
 
 		MENU_PatchResidentPopup( 0, wndOwner );
-		SendMessage16( pTopPopupWnd->hwndSelf, MM_SETMENUHANDLE, (WPARAM16)hmenu, 0L);	
+		SendMessage16( pTPWnd->hwndSelf, MM_SETMENUHANDLE, (WPARAM16)hmenu, 0L);
 
 		/* adjust its size */
 
 	        SetWindowPos( menu->hWnd, 0, x, y, width, height,
 				SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW);
+                MENU_ReleaseTopPopupWnd();
 	    }
 
 	uSubPWndLevel++;	/* menu level counter */
@@ -1392,6 +1456,7 @@
 	SetWindowPos( menu->hWnd, HWND_TOP, 0, 0, 0, 0,
 			SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
 	UpdateWindow( menu->hWnd );
+        WIN_ReleaseWndPtr(wndOwner);
 	return TRUE;
     }
     return FALSE;
@@ -1785,7 +1850,7 @@
 	MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE );
 	MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect );
 
-	if (submenu->hWnd == pTopPopupWnd->hwndSelf ) 
+	if (submenu->hWnd == MENU_GetTopPopupWnd()->hwndSelf )
 	{
 	    ShowWindow( submenu->hWnd, SW_HIDE );
 	    uSubPWndLevel = 0;
@@ -1795,6 +1860,7 @@
 	    DestroyWindow( submenu->hWnd );
 	    submenu->hWnd = 0;
 	}
+        MENU_ReleaseTopPopupWnd();
     }
 }
 
@@ -1817,11 +1883,19 @@
     if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return hmenu;
 
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd )) ||
-         (menu->FocusedItem == NO_SELECTED_ITEM)) return hmenu;
+        (menu->FocusedItem == NO_SELECTED_ITEM))
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return hmenu;
+    }
 
     item = &menu->items[menu->FocusedItem];
     if (!(item->fType & MF_POPUP) ||
-         (item->fState & (MF_GRAYED | MF_DISABLED))) return hmenu;
+        (item->fState & (MF_GRAYED | MF_DISABLED)))
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return hmenu;
+    }
 
     /* message must be send before using item,
        because nearly everything may by changed by the application ! */
@@ -1877,6 +1951,7 @@
 		    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
         MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
+    WIN_ReleaseWndPtr(wndPtr);
     return item->hSubMenu;
 }
 
@@ -1908,6 +1983,7 @@
 
 	    ht = ( ht == HTSYSMENU ) ? (UINT)(wndPtr->hSysMenu)
 		 : ( ht == HTMENU ) ? (UINT)(wndPtr->wIDmenu) : 0;
+            WIN_ReleaseWndPtr(wndPtr);
 	}
    }
    return (HMENU)ht;
@@ -2135,7 +2211,10 @@
 		/* switch to the menu bar */
 
 		if( wndPtr->dwStyle & WS_CHILD || !wndPtr->wIDmenu ) 
+                {
+                    WIN_ReleaseWndPtr(wndPtr);
 		    return FALSE;
+                }
 
 	        hNewMenu = wndPtr->wIDmenu;
 	        if( vk == VK_LEFT )
@@ -2149,7 +2228,12 @@
 		/* switch to the system menu */
 	        hNewMenu = wndPtr->hSysMenu; 
 	    }
-	    else return FALSE;
+            else
+            {
+                WIN_ReleaseWndPtr(wndPtr);
+                return FALSE;
+	}
+            WIN_ReleaseWndPtr(wndPtr);
 	}
 	else    /* application returned a new menu to switch to */
 	{
@@ -2171,8 +2255,10 @@
 		     * try to track hNewMenu as a popup? */
 
 		    TRACE(menu," -- got confused.\n");
+                    WIN_ReleaseWndPtr(wndPtr);
 		    return FALSE;
 		}
+                WIN_ReleaseWndPtr(wndPtr);
 	    }
 	    else return FALSE;
 	}
@@ -2702,6 +2788,7 @@
                                  LPARAM lParam )
 {    
     WND* wndPtr = WIN_FindWndPtr(hwnd);
+    LRESULT retvalue;
 
     switch(message)
     {
@@ -2709,11 +2796,13 @@
 	{
 	    CREATESTRUCTA *cs = (CREATESTRUCTA*)lParam;
 	    SetWindowLongA( hwnd, 0, (LONG)cs->lpCreateParams );
-	    return 0;
+            retvalue = 0;
+            goto END;
 	}
 
     case WM_MOUSEACTIVATE:  /* We don't want to be activated */
-	return MA_NOACTIVATE;
+        retvalue = MA_NOACTIVATE;
+        goto END;
 
     case WM_PAINT:
 	{
@@ -2722,27 +2811,30 @@
 	    MENU_DrawPopupMenu( hwnd, ps.hdc,
                                 (HMENU)GetWindowLongA( hwnd, 0 ) );
 	    EndPaint( hwnd, &ps );
-	    return 0;
+            retvalue = 0;
+            goto END;
 	}
     case WM_ERASEBKGND:
-	return 1;
+        retvalue = 1;
+        goto END;
 
     case WM_DESTROY:
 
 	/* zero out global pointer in case resident popup window
 	 * was somehow destroyed. */
 
-	if( pTopPopupWnd )
+	if(MENU_GetTopPopupWnd() )
 	{
 	    if( hwnd == pTopPopupWnd->hwndSelf )
 	    {
 		ERR(menu, "resident popup destroyed!\n");
 
-		pTopPopupWnd = NULL;
+                MENU_DestroyTopPopupWnd();
 		uSubPWndLevel = 0;
 	    }
 	    else
 		uSubPWndLevel--;
+            MENU_ReleaseTopPopupWnd();
 	}
 	break;
 
@@ -2764,12 +2856,17 @@
 
     case MM_GETMENUHANDLE:
 
-	return *(HMENU*)wndPtr->wExtra;
+        retvalue = *(HMENU*)wndPtr->wExtra;
+        goto END;
 
     default:
-	return DefWindowProcA( hwnd, message, wParam, lParam );
+        retvalue = DefWindowProcA( hwnd, message, wParam, lParam );
+        goto END;
     }
-    return 0;
+    retvalue = 0;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -2785,18 +2882,24 @@
     RECT rectBar;
     WND *wndPtr;
     LPPOPUPMENU lppop;
+    UINT retvalue;
 
     TRACE(menu, "HWND 0x%x, width %d, "
 		  "at (%d, %d).\n", hwnd, menubarWidth, orgX, orgY );
     
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
     if (!(lppop = (LPPOPUPMENU)USER_HEAP_LIN_ADDR((HMENU16)wndPtr->wIDmenu)))
+    {
+        WIN_ReleaseWndPtr(wndPtr);
       return 0;
+    }
     hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
     SetRect(&rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU);
     MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
     ReleaseDC( hwnd, hdc );
-    return lppop->Height;
+    retvalue = lppop->Height;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -3430,18 +3533,21 @@
     if (hMenu && hMenu != MENU_DefSysPopup)
     {
 	LPPOPUPMENU lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
+        WND *pTPWnd = MENU_GetTopPopupWnd();
 
-	if( pTopPopupWnd && (hMenu == *(HMENU*)pTopPopupWnd->wExtra) )
-	  *(UINT*)pTopPopupWnd->wExtra = 0;
+	if( pTPWnd && (hMenu == *(HMENU*)pTPWnd->wExtra) )
+	  *(UINT*)pTPWnd->wExtra = 0;
 
 	if (IS_A_MENU( lppop ))
 	{
 	    lppop->wMagic = 0;  /* Mark it as destroyed */
 
 	    if ((lppop->wFlags & MF_POPUP) && lppop->hWnd &&
-	        (!pTopPopupWnd || (lppop->hWnd != pTopPopupWnd->hwndSelf)))
+	        (!pTPWnd || (lppop->hWnd != pTPWnd->hwndSelf)))
 	        DestroyWindow( lppop->hWnd );
 
+            MENU_ReleaseTopPopupWnd();
+            
 	    if (lppop->items)	/* recursively destroy submenus */
 	    {
 	        int i;
@@ -3499,7 +3605,12 @@
 	    wndPtr->hSysMenu = MENU_GetSysMenu( hWnd, (HMENU)(-1) );
 
 	if( wndPtr->hSysMenu )
-	    return GetSubMenu16(wndPtr->hSysMenu, 0);
+        {
+            HMENU retvalue = GetSubMenu16(wndPtr->hSysMenu, 0);
+            WIN_ReleaseWndPtr(wndPtr);
+            return retvalue;
+        }
+        WIN_ReleaseWndPtr(wndPtr);
     }
     return 0;
 }
@@ -3525,6 +3636,7 @@
     {
 	if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
 	wndPtr->hSysMenu = MENU_GetSysMenu( hwnd, hMenu );
+        WIN_ReleaseWndPtr(wndPtr);
 	return TRUE;
     }
     return FALSE;
@@ -3536,10 +3648,17 @@
  */
 HMENU16 WINAPI GetMenu16( HWND16 hWnd ) 
 {
+    HMENU16 retvalue;
     WND * wndPtr = WIN_FindWndPtr(hWnd);
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD)) 
-	return (HMENU16)wndPtr->wIDmenu;
-    return 0;
+    {
+        retvalue = (HMENU16)wndPtr->wIDmenu;
+        goto END;
+}
+    retvalue = 0;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -3548,10 +3667,17 @@
  */
 HMENU WINAPI GetMenu( HWND hWnd ) 
 { 
+    HMENU retvalue;
     WND * wndPtr = WIN_FindWndPtr(hWnd);
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD)) 
-	return (HMENU)wndPtr->wIDmenu;
-    return 0;
+    {
+        retvalue = (HMENU)wndPtr->wIDmenu;
+        goto END;
+    }
+    retvalue = 0;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -3582,7 +3708,11 @@
 	{
 	    LPPOPUPMENU lpmenu;
 
-            if (!(lpmenu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
+            if (!(lpmenu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu)))
+            {
+                WIN_ReleaseWndPtr(wndPtr);
+                return FALSE;
+            }
             lpmenu->hWnd = hWnd;
             lpmenu->wFlags &= ~MF_POPUP;  /* Can't be a popup */
             lpmenu->Height = 0;  /* Make sure we recalculate the size */
@@ -3590,8 +3720,10 @@
 	if (IsWindowVisible(hWnd))
             SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
                         SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+        WIN_ReleaseWndPtr(wndPtr);
 	return TRUE;
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return FALSE;
 }
 
@@ -3639,13 +3771,19 @@
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && wndPtr->wIDmenu)
     {
         lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR((HMENU16)wndPtr->wIDmenu);
-        if (lppop == NULL) return FALSE;
+        if (lppop == NULL)
+        {
+            WIN_ReleaseWndPtr(wndPtr);
+            return FALSE;
+        }
 
         lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
         SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
                         SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+        WIN_ReleaseWndPtr(wndPtr);
         return TRUE;
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return FALSE;
 }
 
diff --git a/controls/scroll.c b/controls/scroll.c
index b157d62..d5705cd 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -146,8 +146,11 @@
  */
 static SCROLLBAR_INFO *SCROLL_GetScrollInfo( HWND hwnd, INT nBar )
 {
+   SCROLLBAR_INFO *retvalue;
    WND *wndPtr = WIN_FindWndPtr( hwnd );
-   return SCROLL_GetPtrScrollInfo( wndPtr, nBar );
+   retvalue = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
+   WIN_ReleaseWndPtr(wndPtr);
+   return retvalue;
 }
 
 
@@ -204,6 +207,7 @@
 	break;
 
     default:
+        WIN_ReleaseWndPtr(wndPtr);
         return FALSE;
     }
 
@@ -248,6 +252,7 @@
 		 + pixels * (info->CurVal-info->MinVal) / (max - info->MinVal);
         }
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return vertical;
 }
 
@@ -560,8 +565,8 @@
 
     if (!wndPtr || !infoPtr ||
         ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
-        ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) return;
-    if (!WIN_IsWindowDrawable( wndPtr, FALSE )) return;
+        ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) goto END;
+    if (!WIN_IsWindowDrawable( wndPtr, FALSE )) goto END;
 
     vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
                                         &arrowSize, &thumbSize, &thumbPos );
@@ -581,6 +586,8 @@
     if( interior )
 	SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
                          thumbPos, infoPtr->flags, vertical, FALSE, FALSE );
+END:
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -621,11 +628,13 @@
     case VK_UP:    msg = SB_LINEUP; break;
     case VK_DOWN:  msg = SB_LINEDOWN; break;
     default:
+        WIN_ReleaseWndPtr(wndPtr);
         return;
     }
     SendMessageA( GetParent(hwnd),
                     (wndPtr->dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
                     msg, hwnd );
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -1383,6 +1392,7 @@
 			     BOOL fShowH, BOOL fShowV )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
+    BOOL retvalue = FALSE;
 
     if (!wndPtr) return FALSE;
     TRACE(scroll, "hwnd=%04x bar=%d horz=%d, vert=%d\n",
@@ -1392,7 +1402,8 @@
     {
     case SB_CTL:
         ShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE );
-        return TRUE;
+        retvalue = TRUE;
+        goto END;
 
     case SB_BOTH:
     case SB_HORZ:
@@ -1423,17 +1434,22 @@
         break;
 
     default:
-        return FALSE;  /* Nothing to do! */
+        retvalue = FALSE;  /* Nothing to do! */
+        goto END;
     }
 
     if( fShowH || fShowV ) /* frame has been changed, let the window redraw itself */
     {
 	SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
                     | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
-        return TRUE;
+        retvalue = TRUE;
+        goto END;
     }
 
-    return FALSE; /* no frame changes */
+    retvalue = FALSE; /* no frame changes */
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
diff --git a/controls/static.c b/controls/static.c
index c7c21d0..c7846e7 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -182,12 +182,14 @@
 
         if (style == SS_ICON)
         {
-            if (cs->lpszName) {
+            if (cs->lpszName)
+            {
 	    	if (!HIWORD(cs->lpszName) || cs->lpszName[0])
 		    STATIC_SetIcon( wndPtr,
                                 STATIC_LoadIcon( wndPtr, cs->lpszName ));
 	    }
-            return 1;
+            lResult = 1;
+            goto END;
         }
 	if (style == SS_BITMAP)
 	{
@@ -196,15 +198,18 @@
                                 STATIC_LoadBitmap( wndPtr, cs->lpszName ));
 	    WARN(static, "style SS_BITMAP, dwStyle is 0x%08lx\n",
 			wndPtr->dwStyle);
-            return 1;
+            lResult = 1;
+            goto END;
 	}
-	if (!HIWORD(cs->lpszName) && (cs->lpszName)) {
+        if (!HIWORD(cs->lpszName) && (cs->lpszName))
+        {
 		FIXME(static,"windowName is 0x%04x, not doing DefWindowProc\n",
-		    LOWORD(cs->lpszName)
-		);
-		return 1;
+		    LOWORD(cs->lpszName));
+                lResult = 1;
+                goto END;
 	}
-        return DefWindowProcA( hWnd, uMsg, wParam, lParam );
+        lResult = DefWindowProcA( hWnd, uMsg, wParam, lParam );
+        goto END;
     }
     case WM_CREATE:
         if (style < 0L || style > SS_TYPEMASK)
@@ -268,8 +273,16 @@
         break;
 
     case WM_SETFONT:
-        if (style == SS_ICON) return 0;
-        if (style == SS_BITMAP) return 0;
+        if (style == SS_ICON)
+        {
+            lResult = 0;
+            goto END;
+        }
+        if (style == SS_BITMAP)
+        {
+            lResult = 0;
+            goto END;
+        }
         infoPtr->hFont = (HFONT16)wParam;
         if (LOWORD(lParam))
         {
@@ -279,18 +292,22 @@
         break;
 
     case WM_GETFONT:
-        return infoPtr->hFont;
+        lResult = infoPtr->hFont;
+        goto END;
 
     case WM_NCHITTEST:
-        return HTTRANSPARENT;
+        lResult = HTTRANSPARENT;
+        goto END;
 
     case WM_GETDLGCODE:
-        return DLGC_STATIC;
+        lResult = DLGC_STATIC;
+        goto END;
 
     case STM_GETIMAGE:
     case STM_GETICON16:
     case STM_GETICON:
-        return infoPtr->hIcon;
+        lResult = infoPtr->hIcon;
+        goto END;
 
     case STM_SETIMAGE:
     	/* FIXME: handle wParam */
@@ -311,6 +328,8 @@
         break;
     }
     
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return lResult;
 }
 
diff --git a/dlls/comctl32/updown.c b/dlls/comctl32/updown.c
index c147fb0..ea7885e 100644
--- a/dlls/comctl32/updown.c
+++ b/dlls/comctl32/updown.c
@@ -682,8 +682,12 @@
 	break;
       /*If we released the mouse and our buddy is an edit */
       /* we must select all text in it.                   */
-      if(WIDGETS_IsControl(WIN_FindWndPtr(infoPtr->Buddy), BIC32_EDIT))
-	SendMessageA(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
+      {
+          WND *tmpWnd = WIN_FindWndPtr(infoPtr->Buddy);
+          if(WIDGETS_IsControl(tmpWnd, BIC32_EDIT))
+              SendMessageA(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
+          WIN_ReleaseWndPtr(tmpWnd);
+      }
       break;
       
     case WM_LBUTTONDOWN:
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 531019d..b3328fd 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -2671,7 +2671,11 @@
 	/* This will be overwritten in the case of Full Screen mode.
 	   Windowed games could work with that :-) */
 	if (hwnd)
-	this->d.drawable  = X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd));
+        {
+            WND *tmpWnd = WIN_FindWndPtr(hwnd);
+            this->d.drawable  = X11DRV_WND_GetXWindow(tmpWnd);
+            WIN_ReleaseWndPtr(tmpWnd);
+        }
 
 	return DD_OK;
 }
@@ -2985,6 +2989,7 @@
 	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
 ) {
 	char	buf[200];
+        WND *tmpWnd;
 
 	TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
 		      this, width, height, depth);
@@ -3062,11 +3067,17 @@
 
 	_common_IDirectDraw_SetDisplayMode(this);
 
+        tmpWnd = WIN_FindWndPtr(this->d.window);
 	this->d.paintable = 1;
-        this->d.drawable  = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;  
+        this->d.drawable  = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
         /* We don't have a context for this window. Host off the desktop */
+
         if( !this->d.drawable )
+        {
            this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
+            WIN_ReleaseDesktop();
+        }
+        WIN_ReleaseWndPtr(tmpWnd);
 	return DD_OK;
 }
 
@@ -4068,11 +4079,15 @@
 
         if( !ret )
         {
+          WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
           /* We didn't handle the message - give it to the application */
-	  if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
-          	ret = CallWindowProcA( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
+          if (ddraw && ddraw->d.mainWindow && tmpWnd)
+          {
+          	ret = CallWindowProcA(tmpWnd->winproc,
                	                   ddraw->d.mainWindow, msg, wParam, lParam );
 	  }
+          WIN_ReleaseWndPtr(tmpWnd);
+
         }
         
       } else {
@@ -4223,10 +4238,14 @@
                           sizeof( LPDIRECTDRAW ); /*  ddrawXlibThisOffset */
 
         /* We can be a child of the desktop since we're really important */
+        /*
+         This code is not useful since hInstance is forced to 0 afterward
         pParentWindow   = WIN_GetDesktop();
 	wc.hInstance	= pParentWindow ? pParentWindow->hwndSelf : 0;
+        */
         wc.hInstance    = 0; 
 
+        
 	wc.hIcon	= 0;
 	wc.hCursor	= (HCURSOR)IDC_ARROWA;
 	wc.hbrBackground= NULL_BRUSH;
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 3f695b4..f91079f 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -273,6 +273,8 @@
     EBP_reg(&context) = OFFSETOF(thdb->cur_stack)
                         + (WORD)&((STACK16FRAME*)0)->bp;
 
+    WIN_ReleaseWndPtr(wndPtr);
+    
     if (lParam)
     {
 	/* Some programs (eg. the "Undocumented Windows" examples, JWP) only
diff --git a/include/win.h b/include/win.h
index f81eeed..2c8ab51 100644
--- a/include/win.h
+++ b/include/win.h
@@ -139,8 +139,11 @@
 extern int    WIN_SuspendWndsLock();
 extern void   WIN_RestoreWndsLock(int ipreviousLock);
 extern WND*   WIN_FindWndPtr( HWND hwnd );
+extern WND*   WIN_LockWndPtr(WND *wndPtr);
 extern void   WIN_ReleaseWndPtr(WND *wndPtr);
+extern void   WIN_UpdateWndPtr(WND **oldPtr,WND *newPtr);
 extern WND*   WIN_GetDesktop(void);
+extern void   WIN_ReleaseDesktop(void);
 extern void   WIN_DumpWindow( HWND hwnd );
 extern void   WIN_WalkWindows( HWND hwnd, int indent );
 extern BOOL WIN_UnlinkWindow( HWND hwnd );
@@ -153,6 +156,7 @@
 extern BOOL WIN_IsWindowDrawable(WND*, BOOL );
 extern HINSTANCE WIN_GetWindowInstance( HWND hwnd );
 extern WND**  WIN_BuildWinArray( WND *wndPtr, UINT bwa, UINT* pnum );
+extern void   WIN_ReleaseWinArray(WND **wndArray);
 
 extern HWND CARET_GetHwnd(void);
 extern void CARET_GetRect(LPRECT lprc);  /* windows/caret.c */
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
index 9081039..54f9314 100644
--- a/ipc/dde_proc.c
+++ b/ipc/dde_proc.c
@@ -462,7 +462,7 @@
   /* iterate through all the windows */
   for (wndPtr = WIN_FindWndPtr(GetTopWindow(GetDesktopWindow()));
        wndPtr != NULL;
-       wndPtr = wndPtr->next)
+       WIN_UpdateWndPtr(&wndPtr,wndPtr->next))
   {
      if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION) {
 	if (was_sent)
diff --git a/misc/spy.c b/misc/spy.c
index 7acac97..41804d2 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -653,6 +653,8 @@
 	if( *src ) for( n = 0; n < 3; n++ ) *(p++)='.';
 	*(p++) = postfix;
 	*(p++) = '\0';
+        WIN_ReleaseWndPtr(pWnd);
+
     }
     else lstrcpyA( wnd_buffer, "\"NULL\"" );
     return wnd_buffer;
diff --git a/windows/class.c b/windows/class.c
index ed39c79..31689e3 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -728,7 +728,11 @@
     if (offset >= 0)
     {
         if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
-            return GET_WORD(((char *)wndPtr->class->wExtra) + offset);
+        {
+            WORD retvalue = GET_WORD(((char *)wndPtr->class->wExtra) + offset);
+            WIN_ReleaseWndPtr(wndPtr);
+            return retvalue;
+        }
     }
     else switch(offset)
     {
@@ -741,9 +745,11 @@
         case GCW_CBWNDEXTRA:
         case GCW_CBCLSEXTRA:
         case GCW_HMODULE:
+            WIN_ReleaseWndPtr(wndPtr);
             return (WORD)GetClassLongA( hwnd, offset );
     }
 
+    WIN_ReleaseWndPtr(wndPtr);
     WARN(class, "Invalid offset %d\n", offset);
     return 0;
 }
@@ -763,7 +769,9 @@
     {
     case GCL_WNDPROC:
         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-        return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
+        ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
+        WIN_ReleaseWndPtr(wndPtr);
+        return ret;
     case GCL_MENUNAME:
         ret = GetClassLongA( hwnd, offset );
         return (LONG)SEGPTR_GET( (void *)ret );
@@ -779,6 +787,7 @@
 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
 {
     WND * wndPtr;
+    LONG retvalue;
     
     TRACE(class,"%x %x\n",hwnd, offset);
     
@@ -786,27 +795,41 @@
     if (offset >= 0)
     {
         if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
-            return GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
+        {
+            retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
+            goto END;
+        }
     }
+        
     switch(offset)
     {
-        case GCL_STYLE:      return (LONG)wndPtr->class->style;
-        case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
-        case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
-        case GCL_HMODULE:    return (LONG)wndPtr->class->hInstance;
+        case GCL_STYLE:      retvalue = (LONG)wndPtr->class->style;
+                             goto END;
+        case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
+                             goto END;
+        case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
+                             goto END;
+        case GCL_HMODULE:    retvalue = (LONG)wndPtr->class->hInstance;
+                             goto END;
         case GCL_WNDPROC:
-            return (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
+            retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
+            goto END;
         case GCL_MENUNAME:
-            return (LONG)CLASS_GetMenuNameA( wndPtr->class );
+            retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
+            goto END;
         case GCW_ATOM:
         case GCL_HBRBACKGROUND:
         case GCL_HCURSOR:
         case GCL_HICON:
         case GCL_HICONSM:
-            return GetClassWord( hwnd, offset );
+            retvalue = GetClassWord( hwnd, offset );
+            goto END;
     }
     WARN(class, "Invalid offset %d\n", offset);
-    return 0;
+    retvalue = 0;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -816,6 +839,7 @@
 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
 {
     WND * wndPtr;
+    LONG retvalue;
 
     TRACE(class,"%x %x\n",hwnd, offset);
 
@@ -823,10 +847,14 @@
     {
     case GCL_WNDPROC:
         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-        return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
+        retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
+        WIN_ReleaseWndPtr(wndPtr);
+        return retvalue;
     case GCL_MENUNAME:
         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-        return (LONG)CLASS_GetMenuNameW( wndPtr->class );
+        retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
+        WIN_ReleaseWndPtr(wndPtr);
+        return retvalue;
     default:
         return GetClassLongA( hwnd, offset );
     }
@@ -861,6 +889,7 @@
         else
         {
             WARN( class, "Invalid offset %d\n", offset );
+            WIN_ReleaseWndPtr(wndPtr);
             return 0;
         }
     }
@@ -870,6 +899,7 @@
         case GCW_CBWNDEXTRA:
         case GCW_CBCLSEXTRA:
         case GCW_HMODULE:
+            WIN_ReleaseWndPtr(wndPtr);
             return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
         case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
         case GCW_HCURSOR:       ptr = &wndPtr->class->hCursor; break;
@@ -878,6 +908,7 @@
         case GCW_ATOM:          ptr = &wndPtr->class->atomName; break;
         default:
             WARN( class, "Invalid offset %d\n", offset);
+            WIN_ReleaseWndPtr(wndPtr);
             return 0;
     }
     retval = GET_WORD(ptr);
@@ -892,6 +923,7 @@
         CLASS_SetClassNameA( wndPtr->class, NULL );
         FIXME(class,"GCW_ATOM changed for a class.  Not updating className, so GetClassInfoEx may not return correct className!\n");
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return retval;
 }
 
@@ -913,6 +945,7 @@
         retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
         WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
                          WIN_PROC_16, WIN_PROC_CLASS );
+        WIN_ReleaseWndPtr(wndPtr);
         return retval;
     case GCL_MENUNAME:
         return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
@@ -941,35 +974,41 @@
         else
         {
             WARN( class, "Invalid offset %d\n", offset );
-            return 0;
+            retval = 0;
+            goto END;
         }
     }
     else switch(offset)
     {
         case GCL_MENUNAME:
             CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
-            return 0;  /* Old value is now meaningless anyway */
+            retval = 0;  /* Old value is now meaningless anyway */
+            goto END;
         case GCL_WNDPROC:
             retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
                                             WIN_PROC_32A );
             WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
                              WIN_PROC_32A, WIN_PROC_CLASS );
-            return retval;
+            goto END;
         case GCL_HBRBACKGROUND:
         case GCL_HCURSOR:
         case GCL_HICON:
         case GCL_HICONSM:
-            return SetClassWord( hwnd, offset, (WORD)newval );
+            retval = SetClassWord( hwnd, offset, (WORD)newval );
+            goto END;
         case GCL_STYLE:      ptr = &wndPtr->class->style; break;
         case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
         case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
         case GCL_HMODULE:    ptr = &wndPtr->class->hInstance; break;
         default:
             WARN( class, "Invalid offset %d\n", offset );
-            return 0;
+            retval = 0;
+            goto END;
     }
     retval = GET_DWORD(ptr);
     PUT_DWORD( ptr, newval );
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return retval;
 }
 
@@ -991,10 +1030,12 @@
         retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
         WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
                          WIN_PROC_32W, WIN_PROC_CLASS );
+        WIN_ReleaseWndPtr(wndPtr);
         return retval;
     case GCL_MENUNAME:
         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
         CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
+        WIN_ReleaseWndPtr(wndPtr);
         return 0;  /* Old value is now meaningless anyway */
     default:
         return SetClassLongA( hwnd, offset, newval );
@@ -1008,8 +1049,11 @@
 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
 {
     WND *wndPtr;
+    INT16 retvalue;
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
-    return GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
+    retvalue = GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1023,6 +1067,7 @@
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
     ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
 
+    WIN_ReleaseWndPtr(wndPtr);
     TRACE(class,"%x %s %x\n",hwnd, buffer, count);
     return ret;
 }
@@ -1037,7 +1082,7 @@
 
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
     ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
-
+    WIN_ReleaseWndPtr(wndPtr);
     TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
     
     return ret;
diff --git a/windows/dce.c b/windows/dce.c
index 58e3f02..a2e9175 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -91,6 +91,8 @@
 	
 	    if( wnd->dwStyle & WS_CLIPCHILDREN ) dce->DCXflags |= DCX_CLIPCHILDREN;
 	    if( wnd->dwStyle & WS_CLIPSIBLINGS ) dce->DCXflags |= DCX_CLIPSIBLINGS;
+
+            WIN_ReleaseWndPtr(wnd);
 	}
 	SetHookFlags16(dce->hDC,DCHF_INVALIDATEVISRGN);
     }
@@ -248,14 +250,18 @@
 
 		if( wndCurrent && wndCurrent != WIN_GetDesktop() )
 		{
-		    WND* wnd = wndCurrent;
+		    WND* wnd = NULL;
 		    INT xoffset = 0, yoffset = 0;
 
-		    if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) ) continue;
+                    if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) )
+                    {
+                        WIN_ReleaseWndPtr(wndCurrent);
+                        continue;
+                    }
 
 		    /* check if DCE window is within the z-order scope */
 
-		    for( wnd = wndCurrent; wnd; wnd = wnd->parent )
+		    for( wnd = WIN_LockWndPtr(wndCurrent); wnd; WIN_UpdateWndPtr(&wnd,wnd->parent))
 		    {
 			if( wnd == wndScope )
 		 	{
@@ -298,6 +304,8 @@
 			yoffset += wnd->rectClient.top;
 		    }
 		}
+                WIN_ReleaseWndPtr(wndCurrent);
+                WIN_ReleaseDesktop();
 	    }
 	} /* dce list */
     }
@@ -338,10 +346,13 @@
 
 	while (wndPtr->dwStyle & WS_CHILD)
 	{
-	    wndPtr = wndPtr->parent;
+	    wndPtr = WIN_LockWndPtr(wndPtr->parent);
 
 	    if ( (wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
+            {
+                WIN_ReleaseWndPtr(wndPtr);
 		goto fail;
+            }
 
 	    xoffset += wndPtr->rectClient.left;
 	    yoffset += wndPtr->rectClient.top;
@@ -354,12 +365,17 @@
 		(lprect->right <= wndPtr->rectClient.left) ||
 		(lprect->top >= wndPtr->rectClient.bottom) ||
 		(lprect->bottom <= wndPtr->rectClient.top) )
+            {
+                WIN_ReleaseWndPtr(wndPtr);
 		goto fail;
+            }
 
 	    lprect->left = MAX( lprect->left, wndPtr->rectClient.left );
 	    lprect->right = MIN( lprect->right, wndPtr->rectClient.right );
 	    lprect->top = MAX( lprect->top, wndPtr->rectClient.top );
 	    lprect->bottom = MIN( lprect->bottom, wndPtr->rectClient.bottom );
+
+            WIN_ReleaseWndPtr(wndPtr);
 	}
 	OffsetRect( lprect, -xoffset, -yoffset );
 	return TRUE;
@@ -386,9 +402,13 @@
     if( pWndStart->pDriver->pIsSelfClipping( pWndStart ) )
         return TRUE; /* The driver itself will do the clipping */
 
-    for (; pWndStart != pWndEnd; pWndStart = pWndStart->next)
+    for (; pWndStart != pWndEnd; pWndStart = WIN_LockWndPtr(pWndStart->next))
     {
-	if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
+        if( !(pWndStart->dwStyle & WS_VISIBLE) )
+        {
+            WIN_ReleaseWndPtr(pWndStart);
+            continue;
+        }
 	    
 	rect.left = pWndStart->rectWindow.left + x;
 	rect.top = pWndStart->rectWindow.top + y;
@@ -397,8 +417,12 @@
 
 	if( IntersectRect( &rect, &rect, lpRect ))
 	    if(!REGION_UnionRectWithRgn( hrgnClip, &rect ))
+            {
+                WIN_ReleaseWndPtr(pWndStart);
 		break;
     }
+        WIN_ReleaseWndPtr(pWndStart);
+    }
     return (pWndStart == pWndEnd);
 }
 
@@ -500,7 +524,7 @@
 
 		while (wndPtr->dwStyle & WS_CHILD)
 		{
-		    wndPtr = wndPtr->parent;
+		    WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
 		    xoffset -= wndPtr->rectClient.left;
 		    yoffset -= wndPtr->rectClient.top;
 		    if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
@@ -526,6 +550,8 @@
     }
     else
 	hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
+    WIN_ReleaseWndPtr(wndPtr);
+    WIN_ReleaseWndPtr(childWnd);
     return hrgnVis;
 }
 
@@ -565,6 +591,7 @@
 	  wnd = WIN_FindWndPtr(dce->hwndCurrent);
 	  pt.x += wnd->rectClient.left - wnd->rectWindow.left;
 	  pt.y += wnd->rectClient.top - wnd->rectWindow.top;
+          WIN_ReleaseWndPtr(wnd);
       }
   }
   else return ERROR;
@@ -719,14 +746,22 @@
 	    }
 	}
     }
-    if (!dce) return 0;
+    if (!dce)
+    {
+        hdc = 0;
+        goto END;
+    }
 
     dce->hwndCurrent = hwnd;
     dce->hClipRgn = 0;
     dce->DCXflags = dcxFlags | (flags & DCX_WINDOWPAINT) | DCX_DCEBUSY;
     hdc = dce->hDC;
     
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )))
+    {
+        hdc = 0;
+        goto END;
+    }
     bUpdateVisRgn = bUpdateVisRgn || (dc->w.flags & DC_DIRTY);
 
     /* recompute visible region */
@@ -738,7 +773,7 @@
 
 	if (flags & DCX_PARENTCLIP)
         {
-            WND *parentPtr = wndPtr->parent;
+            WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
 
 	    if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
 	    {
@@ -759,6 +794,7 @@
 	    }
 	    else
 		hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
+            WIN_ReleaseWndPtr(parentPtr);
         }
         else 
 	    if ((hwnd == GetDesktopWindow()) &&
@@ -801,6 +837,8 @@
 
     TRACE(dc, "(%04x,%04x,0x%lx): returning %04x\n", 
 	       hwnd, hrgnClip, flags, hdc);
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return hdc;
 }
 
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 5ad889e..95052cb 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -215,6 +215,7 @@
                             SendMessageA( wnd->parent->hwndSelf, 
                                             CB_SHOWDROPDOWN, FALSE, 0 );
                     }
+                    WIN_ReleaseWndPtr(wnd);
                 }
             }
 	    return DefWindowProcA( hwnd, msg, wParam, lParam );
@@ -287,6 +288,7 @@
             case WM_ENTERMENULOOP:
             case WM_LBUTTONDOWN:
             case WM_NCLBUTTONDOWN:
+                WIN_ReleaseWndPtr(wndPtr);
                 return DEFDLG_Proc( (HWND)hwnd, msg, 
                                     (WPARAM)wParam, lParam, dlgInfo );
             case WM_INITDIALOG:
@@ -296,9 +298,11 @@
                 break;
 
             default:
+                WIN_ReleaseWndPtr(wndPtr);
                 return DefWindowProc16( hwnd, msg, wParam, lParam );
         }
     }   
+    WIN_ReleaseWndPtr(wndPtr);
     return DEFDLG_Epilog(dlgInfo, msg, result);
 }
 
@@ -344,6 +348,7 @@
             case WM_ENTERMENULOOP:
             case WM_LBUTTONDOWN:
             case WM_NCLBUTTONDOWN:
+                 WIN_ReleaseWndPtr(wndPtr);
                  return DEFDLG_Proc( (HWND)hwnd, msg,
                                      (WPARAM)wParam, lParam, dlgInfo );
             case WM_INITDIALOG:
@@ -353,9 +358,11 @@
                  break;
 
             default:
+                 WIN_ReleaseWndPtr(wndPtr);
                  return DefWindowProcA( hwnd, msg, wParam, lParam );
         }
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return DEFDLG_Epilog(dlgInfo, msg, result);
 }
 
@@ -401,6 +408,7 @@
             case WM_ENTERMENULOOP:
             case WM_LBUTTONDOWN:
             case WM_NCLBUTTONDOWN:
+                 WIN_ReleaseWndPtr(wndPtr);
                  return DEFDLG_Proc( (HWND)hwnd, msg,
                                      (WPARAM)wParam, lParam, dlgInfo );
             case WM_INITDIALOG:
@@ -410,8 +418,10 @@
                  break;
 
             default:
+                 WIN_ReleaseWndPtr(wndPtr);
                  return DefWindowProcW( hwnd, msg, wParam, lParam );
         }
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return DEFDLG_Epilog(dlgInfo, msg, result);
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 96c91f0..3bd9e15 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -306,6 +306,7 @@
 		wndPtr = WIN_FindWndPtr( hWnd );
 		if( wndPtr && !(wndPtr->class->style & CS_NOCLOSE) )
 		    PostMessage16( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+                WIN_ReleaseWndPtr(wndPtr);
 	    }
 	} 
 	else if( wParam == VK_F10 )
@@ -358,6 +359,7 @@
     case WM_CANCELMODE:
 	if (wndPtr->parent == WIN_GetDesktop()) EndMenu();
 	if (GetCapture() == wndPtr->hwndSelf) ReleaseCapture();
+        WIN_ReleaseDesktop();
 	break;
 
     case WM_VKEYTOITEM:
@@ -458,6 +460,7 @@
         break;
     }
 
+    WIN_ReleaseWndPtr(wndPtr);
     SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result );
     return result;
 }
@@ -520,6 +523,7 @@
         break;
     }
 
+    WIN_ReleaseWndPtr(wndPtr);
     SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result );
     return result;
 }
@@ -553,6 +557,7 @@
                 LPSTR str = HEAP_strdupWtoA(GetProcessHeap(), 0, cs->lpszName);
                 DEFWND_SetText( wndPtr, str );
                 HeapFree( GetProcessHeap(), 0, str );
+                WIN_ReleaseWndPtr(wndPtr);
             }
 	    result = 1;
 	}
diff --git a/windows/dialog.c b/windows/dialog.c
index 8c0195e..f391d51 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -707,9 +707,10 @@
 	   ShowWindow( hwnd, SW_SHOWNORMAL );	/* SW_SHOW doesn't always work */
 	   UpdateWindow( hwnd );
 	}
+        WIN_ReleaseWndPtr(wndPtr);
 	return hwnd;
     }
-
+    WIN_ReleaseWndPtr(wndPtr);
     if( IsWindow(hwnd) ) DestroyWindow( hwnd );
     return 0;
 }
@@ -874,6 +875,7 @@
         EnableWindow( owner, TRUE );
     }
     retval = dlgInfo->idResult; 
+    WIN_ReleaseWndPtr(wndPtr);
     DestroyWindow( hwnd );
     return retval;
 }
@@ -1005,6 +1007,7 @@
         dlgInfo->idResult = retval;
         dlgInfo->flags |= DF_END;
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
@@ -1086,6 +1089,7 @@
 	    {
 		hwndNext = 0;
 	    }
+            WIN_ReleaseWndPtr(wndPtr);
 	    if (!hwndNext)
 	    {
 	        hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
@@ -1294,8 +1298,13 @@
 INT16 WINAPI GetDlgCtrlID16( HWND16 hwnd )
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    if (wndPtr) return wndPtr->wIDmenu;
-    else return 0;
+    INT16 retvalue;
+    
+    if (!wndPtr) return 0;
+
+    retvalue = wndPtr->wIDmenu;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
  
 
@@ -1304,9 +1313,12 @@
  */
 INT WINAPI GetDlgCtrlID( HWND hwnd )
 {
+    INT retvalue;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    if (wndPtr) return wndPtr->wIDmenu;
-    else return 0;
+    if (!wndPtr) return 0;
+    retvalue = wndPtr->wIDmenu;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
  
 
@@ -1318,8 +1330,13 @@
     WND *pWnd;
 
     if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
-    for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
-        if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf;
+    for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
+        if (pWnd->wIDmenu == (UINT16)id)
+        {
+            HWND16 retvalue = pWnd->hwndSelf;
+            WIN_ReleaseWndPtr(pWnd);
+            return retvalue;
+        }
     return 0;
 }
 
@@ -1332,8 +1349,13 @@
     WND *pWnd;
 
     if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
-    for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
-        if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf;
+    for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
+        if (pWnd->wIDmenu == (UINT16)id)
+        {
+            HWND retvalue = pWnd->hwndSelf;
+            WIN_ReleaseWndPtr(pWnd);
+            return retvalue;
+        }
     return 0;
 }
 
@@ -1570,8 +1592,12 @@
     WND *pWnd = WIN_FindWndPtr( hwndDlg );
     if (!pWnd) return FALSE;
 
-    for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
-        if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break;
+    for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
+        if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID))
+        {
+            WIN_ReleaseWndPtr(pWnd);
+            break;
+        }
     if (!pWnd) return FALSE;
 
     if (pWnd->wIDmenu == lastID)
@@ -1580,8 +1606,12 @@
     {
 	SendMessageA( pWnd->hwndSelf, BM_SETCHECK,
                         (pWnd->wIDmenu == checkID), 0 );
-        if (pWnd->wIDmenu == lastID) break;
-	pWnd = pWnd->next;
+        if (pWnd->wIDmenu == lastID)
+        {
+                WIN_ReleaseWndPtr(pWnd);
+                break;
+        }
+	WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
     return TRUE;
 }
@@ -1609,6 +1639,7 @@
     rect->right  = (rect->right * dlgInfo->xBaseUnit) / 4;
     rect->top    = (rect->top * dlgInfo->yBaseUnit) / 8;
     rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -1625,6 +1656,7 @@
     rect->right  = (rect->right * dlgInfo->xBaseUnit) / 4;
     rect->top    = (rect->top * dlgInfo->yBaseUnit) / 8;
     rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
@@ -1645,33 +1677,51 @@
 HWND WINAPI GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl,
                                      BOOL fPrevious )
 {
-    WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
+    WND *pWnd = NULL,
+        *pWndLast = NULL,
+        *pWndCtrl = NULL,
+        *pWndDlg = NULL;
+    HWND retvalue;
 
     if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
     if (hwndCtrl)
     {
-        if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
+        if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl )))
+    {
+            retvalue = 0;
+            goto END;
+        }
         /* Make sure hwndCtrl is a top-level child */
         while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
-            pWndCtrl = pWndCtrl->parent;
-        if (pWndCtrl->parent != pWndDlg) return 0;
+            WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->parent);
+        if (pWndCtrl->parent != pWndDlg)
+        {
+            retvalue = 0;
+            goto END;
+        }
     }
     else
     {
         /* No ctrl specified -> start from the beginning */
-        if (!(pWndCtrl = pWndDlg->child)) return 0;
-        if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
+        if (!(pWndCtrl = WIN_LockWndPtr(pWndDlg->child)))
+        {
+            retvalue = 0;
+            goto END;
+        }
+        if (fPrevious)
+            while (pWndCtrl->next) WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->next);
     }
 
-    pWndLast = pWndCtrl;
-    pWnd = pWndCtrl->next;
+    pWndLast = WIN_LockWndPtr(pWndCtrl);
+    pWnd = WIN_LockWndPtr(pWndCtrl->next);
+
     while (1)
     {
         if (!pWnd || (pWnd->dwStyle & WS_GROUP))
         {
             /* Wrap-around to the beginning of the group */
-            WND *pWndStart = pWndDlg->child;
-            for (pWnd = pWndStart; pWnd; pWnd = pWnd->next)
+            WND *pWndStart = WIN_LockWndPtr(pWndDlg->child);
+            for (WIN_UpdateWndPtr(&pWnd,pWndStart); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
             {
                 if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd;
                 if (pWnd == pWndCtrl) break;
@@ -1681,12 +1731,20 @@
         if (pWnd == pWndCtrl) break;
 	if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED))
 	{
-            pWndLast = pWnd;
+            WIN_UpdateWndPtr(&pWndLast,pWnd);
 	    if (!fPrevious) break;
 	}
-        pWnd = pWnd->next;
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
-    return pWndLast->hwndSelf;
+    retvalue = pWndLast->hwndSelf;
+
+    WIN_ReleaseWndPtr(pWndLast);
+    WIN_ReleaseWndPtr(pWnd);
+END:
+    WIN_ReleaseWndPtr(pWndCtrl);
+    WIN_ReleaseWndPtr(pWndDlg);
+
+    return retvalue;
 }
 
 
@@ -1706,39 +1764,61 @@
 HWND WINAPI GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl,
                                    BOOL fPrevious )
 {
-    WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
+    WND *pWnd = NULL,
+        *pWndLast = NULL,
+        *pWndCtrl = NULL,
+        *pWndDlg = NULL;
+    HWND retvalue;
 
     if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
     if (hwndCtrl)
     {
-        if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
+        if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl )))
+    {
+            retvalue = 0;
+            goto END;
+        }
         /* Make sure hwndCtrl is a top-level child */
         while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
-            pWndCtrl = pWndCtrl->parent;
-        if (pWndCtrl->parent != pWndDlg) return 0;
+            WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->parent);
+        if (pWndCtrl->parent != pWndDlg)
+        {
+            retvalue = 0;
+            goto END;
+    }
     }
     else
     {
         /* No ctrl specified -> start from the beginning */
-        if (!(pWndCtrl = pWndDlg->child)) return 0;
-        if (!fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
+        if (!(pWndCtrl = WIN_LockWndPtr(pWndDlg->child))) return 0;
+        if (!fPrevious)
+            while (pWndCtrl->next) WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->next);
     }
 
-    pWndLast = pWndCtrl;
-    pWnd = pWndCtrl->next;
+    pWndLast = WIN_LockWndPtr(pWndCtrl);
+    pWnd = WIN_LockWndPtr(pWndCtrl->next);
     while (1)
     {
-        if (!pWnd) pWnd = pWndDlg->child;
+        if (!pWnd) pWnd = WIN_LockWndPtr(pWndDlg->child);
         if (pWnd == pWndCtrl) break;
 	if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE) &&
             !(pWnd->dwStyle & WS_DISABLED))
 	{
-            pWndLast = pWnd;
+            WIN_UpdateWndPtr(&pWndLast,pWnd);
 	    if (!fPrevious) break;
 	}
-        pWnd = pWnd->next;
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
-    return pWndLast->hwndSelf;
+    retvalue = pWndLast->hwndSelf;
+    
+    WIN_ReleaseWndPtr(pWndLast);
+    WIN_ReleaseWndPtr(pWnd);
+END:
+    WIN_ReleaseWndPtr(pWndCtrl);
+    WIN_ReleaseWndPtr(pWndDlg);
+
+    return retvalue;
+
 }
 
 
diff --git a/windows/dinput.c b/windows/dinput.c
index 60242a1..6418bdf 100644
--- a/windows/dinput.c
+++ b/windows/dinput.c
@@ -892,6 +892,7 @@
 
     /* This stores the current mouse handler.
        FIXME : need to be fixed for native USER use */
+      WND *tempWnd = 0;
     This->prev_handler = mouse_event;
     
     /* Store (in a global variable) the current lock */
diff --git a/windows/focus.c b/windows/focus.c
index 69d68a1..2901e36 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -34,13 +34,17 @@
 #endif
 
     if( !pFocusTo || hFocusTo != PERQDATA_GetFocusWnd( pMsgQ->pQData ) )
+    {
+        WIN_ReleaseWndPtr(pFocusTo);
 	return;
+    }
 
     /* According to API docs, the WM_SETFOCUS message is sent AFTER the window
        has received the keyboard focus. */
 
     pFocusTo->pDriver->pSetFocus(pFocusTo);
 
+    WIN_ReleaseWndPtr(pFocusTo);
 #if 0
     SendMessageA( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
 #else
@@ -154,6 +158,7 @@
     if ( pCurMsgQ )
         QUEUE_Unlock( pCurMsgQ );
 
+    WIN_ReleaseWndPtr(wndPtr);
     return bRet ? hWndFocus : 0;
 }
 
diff --git a/windows/input.c b/windows/input.c
index 1014ca3..7d85979 100644
--- a/windows/input.c
+++ b/windows/input.c
@@ -335,6 +335,7 @@
         WND* wndPtr = WIN_FindWndPtr( capturePrev );
         if( wndPtr && (wndPtr->flags & WIN_ISWIN32) )
             SendMessageA( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
+            WIN_ReleaseWndPtr(wndPtr);
     }
 }
 
@@ -345,6 +346,7 @@
     if ( pCurMsgQ )
         QUEUE_Unlock( pCurMsgQ );
     
+    WIN_ReleaseWndPtr(wndPtr);
     return capturePrev;
 }
 
@@ -598,6 +600,8 @@
 	    iStat = (hMenu) ? GetMenuState(hMenu,
 					    cmd, MF_BYCOMMAND) : -1 ;
 
+            WIN_ReleaseWndPtr(wndPtr);
+            
             if (iSysStat!=-1)
             {
               if (iSysStat & (MF_DISABLED|MF_GRAYED))
diff --git a/windows/mdi.c b/windows/mdi.c
index 0473ba7..5be8bc3 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -76,7 +76,11 @@
 				 wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
     BOOL	    bRet	    = 0;
 
-    if( !clientInfo->hWindowMenu ) return 0;
+    if( !clientInfo->hWindowMenu )
+    {
+        bRet =  FALSE;
+        goto END;
+    }
 
     if (wndPtr->text) lstrcpynA(buffer + n, wndPtr->text, sizeof(buffer) - n );
 
@@ -84,6 +88,8 @@
     bRet = ModifyMenuA(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
                       MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu, buffer );
     CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return bRet;
 }
 
@@ -96,9 +102,14 @@
     MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
     WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
     UINT	 index      = 0,id,n;
+    BOOL         retvalue;
 
     if( !clientInfo->nActiveChildren ||
-	!clientInfo->hWindowMenu ) return 0;
+        !clientInfo->hWindowMenu )
+    {
+        retvalue = FALSE;
+        goto END;
+    }
 
     id = wndPtr->wIDmenu;
     DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
@@ -127,7 +138,10 @@
 	ModifyMenuA(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
                       index - 1 , buffer ); 
     }
-    return 1;
+    retvalue = TRUE;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 /**********************************************************************
@@ -146,9 +160,9 @@
 
     if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0;
 
-    for ( pWnd = wndPtr->next; ; pWnd = pWnd->next )
+    for ( pWnd = WIN_LockWndPtr(wndPtr->next); ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
     {
-        if (!pWnd ) pWnd = wndPtr->parent->child;
+        if (!pWnd ) WIN_UpdateWndPtr(&pWnd,wndPtr->parent->child);
 
         if ( pWnd == wndPtr ) break; /* went full circle */
 
@@ -158,6 +172,8 @@
 	    if ( bNext ) break;
         }
     }
+    WIN_ReleaseWndPtr(wndPtr);
+    WIN_ReleaseWndPtr(pWnd);
     return pWndLast ? pWndLast->hwndSelf : 0;
 }
 
@@ -243,8 +259,10 @@
         SetMenu(hwndFrame, hmenuFrame);
         if( ci->hwndChildMaximized )
             MDI_AugmentFrameMenu(ci, w->parent, ci->hwndChildMaximized );
+        WIN_ReleaseWndPtr(w);
         return oldFrameMenu;
     }
+    WIN_ReleaseWndPtr(w);
     return 0;
 }
 
@@ -385,6 +403,7 @@
                 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );
 
 	}
+        WIN_ReleaseWndPtr(wnd);
         TRACE(mdi, "created child - %04x\n",hwnd);
     }
     else
@@ -420,8 +439,11 @@
     lpMinMax->ptMaxPosition.x = rect.left;
     lpMinMax->ptMaxPosition.y = rect.top; 
 
+    WIN_ReleaseWndPtr(childWnd);
+    
     TRACE(mdi,"max rect (%i,%i - %i, %i)\n", 
                         rect.left,rect.top,rect.right,rect.bottom);
+    
 }
 
 /**********************************************************************
@@ -444,7 +466,7 @@
 
     TRACE(mdi, "from %04x, to %04x\n",childHwnd,hwndTo);
 
-    if ( !hwndTo ) return; /* no window to switch to */
+    if ( !hwndTo ) goto END; /* no window to switch to */
 
     hwndPrev = ci->hwndActiveChild;
 
@@ -467,6 +489,8 @@
 	if( bOptimize )
 	    ShowWindow( clientHwnd, SW_SHOW );
     }
+END:
+    WIN_ReleaseWndPtr(w);
 }
 
 	    
@@ -499,6 +523,7 @@
 	    }
 	    MDI_MenuDeleteItem(w_parent, child);
 	}
+        WIN_ReleaseWndPtr(childPtr);
 	
         ci->nActiveChildren--;
 
@@ -527,11 +552,22 @@
     WND                 *wndPtr = WIN_FindWndPtr( hWndChild );
     WND			*wndPrev = WIN_FindWndPtr( prevActiveWnd );
     BOOL		 isActiveFrameWnd = 0;	 
+    LONG               retvalue;
 
-    if( hWndChild == prevActiveWnd ) return 0L;
+    if( hWndChild == prevActiveWnd )
+    {
+        retvalue = 0L;
+        goto END;
+    }
 
     if( wndPtr )
-        if( wndPtr->dwStyle & WS_DISABLED ) return 0L;
+    {
+        if( wndPtr->dwStyle & WS_DISABLED )
+        {
+            retvalue = 0L;
+            goto END;
+        }
+    }
 
     TRACE(mdi,"%04x\n", hWndChild);
 
@@ -570,7 +606,8 @@
     {
 	if( isActiveFrameWnd )
 	    SetFocus( clientInfo->self );
-	return 0;
+        retvalue = 0;
+        goto END;
     }
 	
     /* check menu item */
@@ -592,7 +629,10 @@
     }
     SendMessageA( hWndChild, WM_MDIACTIVATE, (WPARAM)prevActiveWnd,
                     (LPARAM)hWndChild );
-    return 1;
+    retvalue = 1;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    WIN_ReleaseWndPtr(wndPrev);
 }
 
 /* -------------------- MDI client window functions ------------------- */
@@ -766,7 +806,12 @@
 
     TRACE(mdi,"frame %p,child %04x\n",frame,hChild);
 
-    if( !frame->wIDmenu || !child->hSysMenu ) return 0; 
+    if( !frame->wIDmenu || !child->hSysMenu )
+    {
+        WIN_ReleaseWndPtr(child);
+        return 0;
+    }
+    WIN_ReleaseWndPtr(child);
 
     /* create a copy of sysmenu popup and insert it into frame menu bar */
 
@@ -856,6 +901,7 @@
 
     if (!clientWnd)
            return;
+    WIN_ReleaseWndPtr(clientWnd);
 
     if (!ci)
            return;
@@ -897,6 +943,7 @@
 		    strcat( lpBuffer, "]" );
 		}
 	    }
+            WIN_ReleaseWndPtr(childWnd);
 	}
 	else
 	{
@@ -929,8 +976,9 @@
     MDICLIENTINFO       *ci;
     RECT		 rect;
     WND                 *w 	  = WIN_FindWndPtr(hwnd);
-    WND			*frameWnd = w->parent;
+    WND			*frameWnd = WIN_LockWndPtr(w->parent);
     INT nItems;
+    LRESULT            retvalue;
     
     ci = (MDICLIENTINFO *) w->wExtra;
     
@@ -982,7 +1030,8 @@
 	TRACE(mdi,"Client created - hwnd = %04x, idFirst = %u\n",
 			   hwnd, ci->idFirstChild );
 
-	return 0;
+        retvalue = 0;
+        goto END;
       
       case WM_DESTROY:
 	if( ci->hwndChildMaximized ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf);
@@ -993,38 +1042,46 @@
 	    while( ci->nActiveChildren-- )
 	        DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--);
 	}
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_MDIACTIVATE:
         if( ci->hwndActiveChild != (HWND)wParam )
 	    SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_MDICASCADE:
-	return MDICascade(w, ci);
+        retvalue = MDICascade(w, ci);
+        goto END;
 
       case WM_MDICREATE:
-        if (lParam) return MDICreateChild( w, ci, hwnd,
+        if (lParam) retvalue = MDICreateChild( w, ci, hwnd,
                                            (MDICREATESTRUCTA*)lParam );
-	return 0;
+        else retvalue = 0;
+        goto END;
 
       case WM_MDIDESTROY:
-	return MDIDestroyChild( w, ci, hwnd, (HWND)wParam, TRUE );
+	retvalue = MDIDestroyChild( w, ci, hwnd, (HWND)wParam, TRUE );
+        goto END;
 
       case WM_MDIGETACTIVE:
           if (lParam) *(BOOL *)lParam = (ci->hwndChildMaximized > 0);
-          return ci->hwndActiveChild;
+          retvalue = ci->hwndActiveChild;
+          goto END;
 
       case WM_MDIICONARRANGE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
         ArrangeIconicWindows(hwnd);
 	ci->sbRecalc = SB_BOTH+1;
 	SendMessageA(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
-	return 0;
+        retvalue = 0;
+        goto END;
 	
       case WM_MDIMAXIMIZE:
 	ShowWindow( (HWND)wParam, SW_MAXIMIZE );
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_MDINEXT: /* lParam != 0 means previous window */
 	MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)? FALSE : TRUE );
@@ -1032,27 +1089,31 @@
 	
       case WM_MDIRESTORE:
         SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_MDISETMENU:
-          return MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
-	
+          retvalue = MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
+	  goto END;
       case WM_MDIREFRESHMENU:
-          return MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
+          retvalue = MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
+          goto END;
 
       case WM_MDITILE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
 	ShowScrollBar(hwnd,SB_BOTH,FALSE);
 	MDITile(w, ci, wParam);
         ci->mdiFlags &= ~MDIF_NEEDUPDATE;
-        return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_VSCROLL:
       case WM_HSCROLL:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
         ScrollChildren(hwnd, message, wParam, lParam);
 	ci->mdiFlags &= ~MDIF_NEEDUPDATE;
-        return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_SETFOCUS:
 	if( ci->hwndActiveChild )
@@ -1061,7 +1122,8 @@
 	   if( !(w->dwStyle & WS_MINIMIZE) )
 	       SetFocus( ci->hwndActiveChild );
 	} 
-	return 0;
+        retvalue = 0;
+        goto END;
 	
       case WM_NCACTIVATE:
         if( ci->hwndActiveChild )
@@ -1079,7 +1141,8 @@
             if( child && child != hwnd && child != ci->hwndActiveChild )
                 SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
         }
-        return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_SIZE:
         if( IsWindow(ci->hwndChildMaximized) )
@@ -1090,6 +1153,7 @@
 	    AdjustWindowRectEx(&rect, child->dwStyle, 0, child->dwExStyle);
 	    MoveWindow(ci->hwndChildMaximized, rect.left, rect.top,
 			 rect.right - rect.left, rect.bottom - rect.top, 1);
+            WIN_ReleaseWndPtr(child);
 	}
 	else
 	    MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
@@ -1103,10 +1167,15 @@
 	    ci->sbRecalc = 0;
 	    ci->mdiFlags &= ~MDIF_NEEDUPDATE;
 	}
-	return 0;
+        retvalue = 0;
+        goto END;
     }
     
-    return DefWindowProcA( hwnd, message, wParam, lParam );
+    retvalue = DefWindowProcA( hwnd, message, wParam, lParam );
+END:
+    WIN_ReleaseWndPtr(w);
+    WIN_ReleaseWndPtr(frameWnd);
+    return retvalue;
 }
 
 
@@ -1136,6 +1205,7 @@
 	    ci     = (MDICLIENTINFO*)wndPtr->wExtra;
 
 	    /* check for possible syscommands for maximized MDI child */
+            WIN_ReleaseWndPtr(wndPtr);
 
 	    if( ci && (
 	    	wParam <  ci->idFirstChild || 
@@ -1159,8 +1229,10 @@
 	      }
 	    else
 	      {
-	    	childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient),
-                                          wParam );
+                wndPtr = WIN_FindWndPtr(hwndMDIClient);
+                childHwnd = MDI_GetChildByID(wndPtr,wParam );
+                WIN_ReleaseWndPtr(wndPtr);
+
  	    	if( childHwnd )
 	            SendMessage16(hwndMDIClient, WM_MDIACTIVATE,
                                   (WPARAM16)childHwnd , 0L);
@@ -1172,9 +1244,11 @@
 	    break;
 
 	  case WM_SETTEXT:
-	    MDI_UpdateFrameText(WIN_FindWndPtr(hwnd), hwndMDIClient, 
+            wndPtr = WIN_FindWndPtr(hwnd);
+            MDI_UpdateFrameText(wndPtr, hwndMDIClient,
 				      MDI_REPAINTFRAME, 
 			             (LPCSTR)PTR_SEG_TO_LIN(lParam));
+            WIN_ReleaseWndPtr(wndPtr);
 	    return 0;
 	
 	  case WM_SETFOCUS:
@@ -1202,11 +1276,16 @@
 		    (wParam == VK_RIGHT &&
 		     GetSubMenu16(wndPtr->parent->hSysMenu, 0) == LOWORD(lParam)) )
 		{
+                    LRESULT retvalue;
+                    WIN_ReleaseWndPtr(wndPtr);
 		    wndPtr = WIN_FindWndPtr(ci->hwndActiveChild);
-		    return MAKELONG( GetSubMenu16(wndPtr->hSysMenu, 0), 
+		    retvalue = MAKELONG( GetSubMenu16(wndPtr->hSysMenu, 0),
 						  ci->hwndActiveChild);
+                    WIN_ReleaseWndPtr(wndPtr);
+                    return retvalue;
 		}
 	    }
+            WIN_ReleaseWndPtr(wndPtr);
 	    break;
 	}
     }
@@ -1302,7 +1381,8 @@
                                   WPARAM16 wParam, LPARAM lParam )
 {
     MDICLIENTINFO       *ci;
-    WND                 *clientWnd;
+    WND                 *clientWnd,*tmpWnd = 0;
+    LRESULT             retvalue;
 
     clientWnd  = WIN_FindWndPtr(GetParent16(hwnd));
     ci         = (MDICLIENTINFO *) clientWnd->wExtra;
@@ -1315,11 +1395,13 @@
 	if( ci->hwndChildMaximized == hwnd )
 	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
 				 MDI_REPAINTFRAME, NULL );
-        return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_CLOSE:
 	SendMessage16(ci->self,WM_MDIDESTROY,(WPARAM16)hwnd,0L);
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_SETFOCUS:
 	if( ci->hwndActiveChild != hwnd )
@@ -1328,7 +1410,8 @@
 
       case WM_CHILDACTIVATE:
 	MDI_ChildActivate(clientWnd, hwnd);
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_NCPAINT:
 	TRACE(mdi,"WM_NCPAINT for %04x, active %04x\n",
@@ -1339,30 +1422,44 @@
 	switch( wParam )
 	{
 		case SC_MOVE:
-		     if( ci->hwndChildMaximized == hwnd) return 0;
+                     if( ci->hwndChildMaximized == hwnd)
+                     {
+                         retvalue = 0;
+                         goto END;
+                     }
 		     break;
 	        case SC_RESTORE:
 	        case SC_MINIMIZE:
-		     WIN_FindWndPtr(hwnd)->dwStyle |= WS_SYSMENU;
+                     tmpWnd = WIN_FindWndPtr(hwnd);
+                     tmpWnd->dwStyle |= WS_SYSMENU;
+                     WIN_ReleaseWndPtr(tmpWnd);
 		     break;
 		case SC_MAXIMIZE:
 		     if( ci->hwndChildMaximized == hwnd) 
-			 return SendMessage16( clientWnd->parent->hwndSelf,
+                     {
+		          retvalue = SendMessage16( clientWnd->parent->hwndSelf,
                                              message, wParam, lParam);
-		     WIN_FindWndPtr(hwnd)->dwStyle &= ~WS_SYSMENU;
+                          goto END;
+                     }
+                     tmpWnd = WIN_FindWndPtr(hwnd);
+                     tmpWnd->dwStyle &= ~WS_SYSMENU;
+                     WIN_ReleaseWndPtr(tmpWnd);
 		     break;
 		case SC_NEXTWINDOW:
 		     SendMessage16( ci->self, WM_MDINEXT, 0, 0);
-		     return 0;
+                     retvalue = 0;
+                     goto END;
 		case SC_PREVWINDOW:
 		     SendMessage16( ci->self, WM_MDINEXT, 0, 1);
-		     return 0;
+                     retvalue = 0;
+                     goto END;
 	}
 	break;
 	
       case WM_GETMINMAXINFO:
 	MDI_ChildGetMinMaxInfo(clientWnd, hwnd, (MINMAXINFO16*) PTR_SEG_TO_LIN(lParam));
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_SETVISIBLE:
          if( ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
@@ -1424,16 +1521,23 @@
 	/* MDI children don't have menu bars */
 	PostMessage16( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, 
                        (WPARAM16)SC_KEYMENU, (LPARAM)wParam);
-	return 0x00010000L;
+        retvalue = 0x00010000L;
+        goto END;
 
       case WM_NEXTMENU:
 
 	if( wParam == VK_LEFT )		/* switch to frame system menu */
-	  return MAKELONG( GetSubMenu16(clientWnd->parent->hSysMenu, 0), 
+        {
+            retvalue = MAKELONG( GetSubMenu16(clientWnd->parent->hSysMenu, 0),
 			   clientWnd->parent->hwndSelf );
+            goto END;
+        }
 	if( wParam == VK_RIGHT )	/* to frame menu bar */
-	  return MAKELONG( clientWnd->parent->wIDmenu,
+        {
+            retvalue = MAKELONG( clientWnd->parent->wIDmenu,
 			   clientWnd->parent->hwndSelf );
+            goto END;
+        }
 
 	break;	
 
@@ -1442,11 +1546,14 @@
 	   {
 	   	SendMessage16(hwnd,WM_SYSCOMMAND,
 			(WPARAM16)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
-		return 0;
+                retvalue = 0;
+                goto END;
 	   }
     }
 	
-    return DefWindowProc16(hwnd, message, wParam, lParam);
+    retvalue = DefWindowProc16(hwnd, message, wParam, lParam);
+END:
+    WIN_ReleaseWndPtr(clientWnd);
 }
 
 
@@ -1457,10 +1564,13 @@
                                    WPARAM wParam, LPARAM lParam )
 {
     MDICLIENTINFO       *ci;
-    WND                 *clientWnd;
+    WND                 *clientWnd,*tmpWnd;
+    LRESULT             retvalue;
 
-    clientWnd  = WIN_FindWndPtr(WIN_FindWndPtr(hwnd)->parent->hwndSelf);
+    tmpWnd     = WIN_FindWndPtr(hwnd);
+    clientWnd  = WIN_FindWndPtr(tmpWnd->parent->hwndSelf);
     ci         = (MDICLIENTINFO *) clientWnd->wExtra;
+    WIN_ReleaseWndPtr(tmpWnd);
 
     switch (message)
     {
@@ -1470,7 +1580,8 @@
 	if( ci->hwndChildMaximized == hwnd )
 	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
 				 MDI_REPAINTFRAME, NULL );
-        return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_GETMINMAXINFO:
         {
@@ -1479,14 +1590,16 @@
             MDI_ChildGetMinMaxInfo( clientWnd, hwnd, &mmi );
             STRUCT32_MINMAXINFO16to32( &mmi, (MINMAXINFO *)lParam );
         }
-	return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_MENUCHAR:
 
 	/* MDI children don't have menu bars */
 	PostMessage16( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, 
                        (WPARAM16)SC_KEYMENU, (LPARAM)LOWORD(wParam) );
-	return 0x00010000L;
+        retvalue = 0x00010000L;
+        goto END;
 
       case WM_CLOSE:
       case WM_SETFOCUS:
@@ -1496,17 +1609,22 @@
       case WM_SETVISIBLE:
       case WM_SIZE:
       case WM_NEXTMENU:
-          return DefMDIChildProc16( hwnd, message, (WPARAM16)wParam, lParam );
+          retvalue = DefMDIChildProc16( hwnd, message, (WPARAM16)wParam, lParam );
+          goto END;
 
       case WM_SYSCHAR:
       	   if (wParam == '-')
 	   {
 	   	SendMessageA(hwnd,WM_SYSCOMMAND,
 			(WPARAM)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
-		return 0;
+                retvalue = 0;
+                goto END;
 	   }
     }
-    return DefWindowProcA(hwnd, message, wParam, lParam);
+    retvalue = DefWindowProcA(hwnd, message, wParam, lParam);
+END:
+    WIN_ReleaseWndPtr(clientWnd);
+    return retvalue;
 }
 
 
@@ -1518,6 +1636,7 @@
 {
     MDICLIENTINFO       *ci;
     WND                 *clientWnd;
+    LRESULT             retvalue;
 
     clientWnd  = WIN_FindWndPtr(GetParent16(hwnd));
     ci         = (MDICLIENTINFO *) clientWnd->wExtra;
@@ -1530,7 +1649,8 @@
 	if( ci->hwndChildMaximized == hwnd )
 	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
 				 MDI_REPAINTFRAME, NULL );
-        return 0;
+        retvalue = 0;
+        goto END;
 
       case WM_GETMINMAXINFO:
       case WM_MENUCHAR:
@@ -1542,17 +1662,23 @@
       case WM_SETVISIBLE:
       case WM_SIZE:
       case WM_NEXTMENU:
-          return DefMDIChildProcA( hwnd, message, (WPARAM16)wParam, lParam );
+          retvalue = DefMDIChildProcA( hwnd, message, (WPARAM16)wParam, lParam );
+          goto END;
 
       case WM_SYSCHAR:
       	   if (wParam == '-')
 	   {
 	   	SendMessageW(hwnd,WM_SYSCOMMAND,
 			(WPARAM)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
-		return 0;
+                retvalue = 0;
+                goto END;
 	   }
     }
-    return DefWindowProcW(hwnd, message, wParam, lParam);
+    retvalue = DefWindowProcW(hwnd, message, wParam, lParam);
+END:
+    WIN_ReleaseWndPtr(clientWnd);
+    return retvalue;
+    
 }
 
 
@@ -1601,6 +1727,7 @@
     MDICLIENTINFO* pCi;
     MDICREATESTRUCTA cs;
     WND *pWnd=WIN_FindWndPtr(hWndParent);
+    HWND retvalue;
 
     TRACE(mdi, "(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld)\n",
           debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
@@ -1622,7 +1749,9 @@
 
     pCi=(MDICLIENTINFO *)pWnd->wExtra;
     
-    return MDICreateChild(pWnd,pCi,hWndParent,&cs);
+    retvalue = MDICreateChild(pWnd,pCi,hWndParent,&cs);
+    WIN_ReleaseWndPtr(pWnd);
+    return retvalue;
 }
 
 /***************************************
@@ -1701,11 +1830,13 @@
 	WND*		wnd;
 
 	ci = (MDICLIENTINFO*) clientWnd->wExtra;
+        WIN_ReleaseWndPtr(clientWnd);
 	wnd = WIN_FindWndPtr(ci->hwndActiveChild);
 	if( wnd && !(wnd->dwStyle & WS_DISABLED) )
 	{
 	    WPARAM16	wParam = 0;
 
+            WIN_ReleaseWndPtr(wnd);
 	    /* translate if the Ctrl key is down and Alt not. */
   
 	    if( (GetKeyState(VK_CONTROL) & 0x8000) && 
@@ -1731,7 +1862,9 @@
 	        return 1;
 	    }
 	}
+        WIN_ReleaseWndPtr(wnd);
     }
+    WIN_ReleaseWndPtr(clientWnd);
     return 0; /* failure */
 }
 
@@ -1750,15 +1883,17 @@
     GetClientRect( hwnd, &clientRect );
     SetRectEmpty( &childRect );
 
-    for ( pWnd = pWnd->child; pWnd; pWnd = pWnd->next )
+    for ( WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
     {
 	  if( pWnd->dwStyle & WS_MAXIMIZE )
 	  {
 	      ShowScrollBar(hwnd, SB_BOTH, FALSE);
+              WIN_ReleaseWndPtr(pWnd);
 	      return;
 	  }
 	  UnionRect( &childRect, &pWnd->rectWindow, &childRect );
     } 
+    WIN_ReleaseWndPtr(pWnd);
     UnionRect( &childRect, &clientRect, &childRect );
 
     hmin = childRect.left; hmax = childRect.right - clientRect.right;
@@ -1780,6 +1915,7 @@
 			SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos,
 						  hmin, hmax, hpos);
     }    
+    WIN_ReleaseWndPtr(Wnd);
 }
 
 
@@ -1818,8 +1954,13 @@
 	length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
 	shift = SYSMETRICS_CXVSCROLL;
     }
-    else return;
+    else
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return;
+    }
 
+    WIN_ReleaseWndPtr(wndPtr);
     switch( wParam )
     {
 	case SB_LINEUP:	
diff --git a/windows/nonclient.c b/windows/nonclient.c
index e188b3d..30c9a84 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -349,6 +349,7 @@
 
 	    DrawIconEx (hdc, pt.x, pt.y, hAppIcon, sysMetrics[SM_CXSMICON],
 			  sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
+            WIN_ReleaseWndPtr(wndPtr);
 	}
 
 	rc.left += (rc.bottom - rc.top);
@@ -554,7 +555,7 @@
     rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
+    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
 
     /* Remove frame from rectangle */
     if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
@@ -570,7 +571,8 @@
 	if (wndPtr->dwStyle & WS_BORDER)
 	    InflateRect( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
     }
-
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return;
 }
 
@@ -592,7 +594,7 @@
     rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
+    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
 
     /* Remove frame from rectangle */
     if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
@@ -614,7 +616,8 @@
 	if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
 	    InflateRect (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
     }
-
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return;
 }
 
@@ -907,15 +910,18 @@
 LONG
 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
 {
+    LONG retvalue;
     WND *wndPtr = WIN_FindWndPtr (hwnd);
 
     if (!wndPtr)
 	return HTERROR;
 
     if (TWEAK_WineLook == WIN31_LOOK)
-        return NC_DoNCHitTest (wndPtr, pt);
+        retvalue = NC_DoNCHitTest (wndPtr, pt);
     else
-	return NC_DoNCHitTest95 (wndPtr, pt);
+        retvalue = NC_DoNCHitTest95 (wndPtr, pt);
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -940,6 +946,7 @@
       SelectObject( hdcMem, hbitmap );
       DeleteDC( hdcMem );
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -964,6 +971,8 @@
 		SRCCOPY );
       DeleteDC( hdcMem );
     }
+    WIN_ReleaseWndPtr(wndPtr);
+
 }
 
 
@@ -987,6 +996,7 @@
 		SRCCOPY );
       DeleteDC( hdcMem );
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -1030,8 +1040,10 @@
 			  sysMetrics[SM_CYSMICON],
 			  0, 0, DI_NORMAL);
 
+        WIN_ReleaseWndPtr(wndPtr);
 	return (hIcon != 0);
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return FALSE;
 }
 
@@ -1075,6 +1087,7 @@
 	SelectObject (hdcMem, hOldBmp);
 	DeleteDC (hdcMem);
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 /******************************************************************************
@@ -1125,6 +1138,7 @@
 	SelectObject (hdcMem, hOldBmp);
 	DeleteDC( hdcMem );
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 /******************************************************************************
@@ -1178,6 +1192,7 @@
        SelectObject (hdcMem, hOldBmp);
 	DeleteDC( hdcMem );
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 /***********************************************************************
@@ -1357,12 +1372,19 @@
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     char buffer[256];
 
-    if (wndPtr->flags & WIN_MANAGED) return;
+    if (wndPtr->flags & WIN_MANAGED)
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return;
+    }
 
     if (!hbitmapClose)
     {
 	if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
+        {
+            WIN_ReleaseWndPtr(wndPtr);
 	    return;
+        }
 	hbitmapCloseD    = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
 	hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
 	hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
@@ -1382,7 +1404,7 @@
 	r.right--;
 	SelectObject( hdc, hbrushOld );
     }
-
+    WIN_ReleaseWndPtr(wndPtr);
     MoveTo16( hdc, r.left, r.bottom );
     LineTo( hdc, r.right, r.bottom );
 
@@ -1455,7 +1477,12 @@
     char    buffer[256];
     HPEN  hPrevPen;
 
-    if (wndPtr->flags & WIN_MANAGED) return;
+    if (wndPtr->flags & WIN_MANAGED)
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return;
+    }
+    WIN_ReleaseWndPtr(wndPtr);
 
     hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
     MoveToEx( hdc, r.left, r.bottom - 1, NULL );
@@ -1755,6 +1782,7 @@
 	else
 	    NC_DoNCPaint95( wndPtr, clip, FALSE );
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return 0;
 }
 
@@ -1810,13 +1838,17 @@
     case HTCLIENT:
 	{
 	    WND *wndPtr;
+            BOOL retvalue;
+            
 	    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
 	    if (wndPtr->class->hCursor)
 	    {
 		SetCursor16( wndPtr->class->hCursor );
-		return TRUE;
+		retvalue = TRUE;
 	    }
-	    else return FALSE;
+            else retvalue = FALSE;
+            WIN_ReleaseWndPtr(wndPtr);
+            return retvalue;
 	}
 
     case HTLEFT:
@@ -1981,18 +2013,18 @@
     capturePoint = pt = *(POINT16*)&dwPoint;
 
     if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
-        (wndPtr->flags & WIN_MANAGED)) return;
+        (wndPtr->flags & WIN_MANAGED)) goto END;
 
     if ((wParam & 0xfff0) == SC_MOVE)
     {
-	if (!(wndPtr->dwStyle & WS_CAPTION)) return;
+	if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
 	if (!hittest) 
 	     hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
-	if (!hittest) return;
+	if (!hittest) goto END;
     }
     else  /* SC_SIZE */
     {
-	if (!thickframe) return;
+	if (!thickframe) goto END;
 	if ( hittest && hittest != HTSYSMENU ) hittest += 2;
 	else
 	{
@@ -2001,7 +2033,7 @@
 	    if (!hittest)
 	    {
 		ReleaseCapture();
-		return;
+		goto END;
 	    }
 	}
     }
@@ -2193,6 +2225,9 @@
 	    }
 	    else WINPOS_ShowIconTitle( wndPtr, TRUE );
 	}
+
+END:
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -2295,16 +2330,16 @@
 
     if ((wParam & 0xfff0) == SC_HSCROLL)
     {
-	if ((wParam & 0x0f) != HTHSCROLL) return;
+	if ((wParam & 0x0f) != HTHSCROLL) goto END;
 	scrollbar = SB_HORZ;
     }
     else  /* SC_VSCROLL */
     {
-	if ((wParam & 0x0f) != HTVSCROLL) return;
+	if ((wParam & 0x0f) != HTVSCROLL) goto END;
 	scrollbar = SB_VERT;
     }
 
-    if (!(msg = SEGPTR_NEW(MSG16))) return;
+    if (!(msg = SEGPTR_NEW(MSG16))) goto END;
     pt.x -= wndPtr->rectWindow.left;
     pt.y -= wndPtr->rectWindow.top;
     SetCapture( hwnd );
@@ -2336,6 +2371,8 @@
         }
     } while (msg->message != WM_LBUTTONUP);
     SEGPTR_FREE(msg);
+END:
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 /***********************************************************************
@@ -2532,5 +2569,6 @@
  	FIXME (nonclient, "unimplemented!\n");
         break;
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return 0;
 }
diff --git a/windows/painting.c b/windows/painting.c
index 9af95e2..520457b 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -35,8 +35,10 @@
     if(wnd == WIN_GetDesktop()) 
     {
         wnd->flags &= ~WIN_NEEDS_NCPAINT;
+        WIN_ReleaseDesktop();
         return;
     }
+    WIN_ReleaseDesktop();
 
     if( wnd->hrgnUpdate > 1 )
     {
@@ -136,6 +138,7 @@
     if (!lps->hdc)
     {
         WARN(win, "GetDCEx() failed in BeginPaint(), hwnd=%04x\n", hwnd);
+        WIN_ReleaseWndPtr(wndPtr);
         return 0;
     }
 
@@ -153,6 +156,7 @@
     }
     else lps->fErase = TRUE;
 
+    WIN_ReleaseWndPtr(wndPtr);
     return lps->hdc;
 }
 
@@ -248,17 +252,23 @@
 HBRUSH16 WINAPI GetControlBrush16( HWND16 hwnd, HDC16 hdc, UINT16 ctlType )
 {
     WND* wndPtr = WIN_FindWndPtr( hwnd );
+    HBRUSH16 retvalue;
 
     if((ctlType <= CTLCOLOR_MAX) && wndPtr )
     {
 	WND* parent;
-	if( wndPtr->dwStyle & WS_POPUP ) parent = wndPtr->owner;
-	else parent = wndPtr->parent;
+	if( wndPtr->dwStyle & WS_POPUP ) parent = WIN_LockWndPtr(wndPtr->owner);
+	else parent = WIN_LockWndPtr(wndPtr->parent);
 	if( !parent ) parent = wndPtr;
-	return (HBRUSH16)PAINT_GetControlBrush( parent->hwndSelf, hwnd, hdc, ctlType );
+	retvalue = (HBRUSH16)PAINT_GetControlBrush( parent->hwndSelf, hwnd, hdc, ctlType );
+        WIN_ReleaseWndPtr(parent);
+        goto END;
     }
-    return (HBRUSH16)0;
-}
+    retvalue = (HBRUSH16)0;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
+    }
 
 
 /***********************************************************************
@@ -290,7 +300,10 @@
     if (!hwnd) hwnd = GetDesktopWindow();
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
     if (!WIN_IsWindowDrawable( wndPtr, !(flags & RDW_FRAME) ) )
+    {
+        WIN_ReleaseWndPtr(wndPtr);
         return TRUE;  /* No redraw needed */
+    }
 
     bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
     if (rectUpdate)
@@ -440,13 +453,18 @@
     {
         if ( hrgnUpdate || rectUpdate )
 	{
-	   if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return TRUE;
+            if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 )))
+	{
+                WIN_ReleaseWndPtr(wndPtr);
+                return TRUE;
+            }
 	   if( !hrgnUpdate )
            {
 	        control |= (RDW_C_DELETEHRGN | RDW_C_USEHRGN);
  	        if( !(hrgnUpdate = CreateRectRgnIndirect( rectUpdate )) )
                 {
                     DeleteObject( hrgn );
+                    WIN_ReleaseWndPtr(wndPtr);
                     return TRUE;
                 }
            }
@@ -454,7 +472,7 @@
 	   {
 		for (ppWnd = list; *ppWnd; ppWnd++)
 		{
-		    wndPtr = *ppWnd;
+		    WIN_UpdateWndPtr(&wndPtr,*ppWnd);
 		    if (!IsWindow(wndPtr->hwndSelf)) continue;
 		    if (wndPtr->dwStyle & WS_VISIBLE)
 		    {
@@ -470,7 +488,7 @@
 			}
 		    }
 		}
-		HeapFree( SystemHeap, 0, list );
+                WIN_ReleaseWinArray(list);
 	   }
 	   DeleteObject( hrgn );
 	   if (control & RDW_C_DELETEHRGN) DeleteObject( hrgnUpdate );
@@ -481,15 +499,16 @@
 	    {
 		for (ppWnd = list; *ppWnd; ppWnd++)
 		{
-		    wndPtr = *ppWnd;
+		    WIN_UpdateWndPtr(&wndPtr,*ppWnd);
 		    if (IsWindow( wndPtr->hwndSelf ))
 			PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
 		}
-	        HeapFree( SystemHeap, 0, list );
+                WIN_ReleaseWinArray(list);
 	    }
 	}
 
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
@@ -632,6 +651,7 @@
  */
 BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
 {
+    BOOL retvalue;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return FALSE;
 
@@ -640,7 +660,11 @@
 	if (wndPtr->hrgnUpdate > 1)
 	{
 	    HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
-	    if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE;
+            if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR)
+            {
+                retvalue = FALSE;
+                goto END;
+            }
 	    GetRgnBox( hrgn, rect );
 	    DeleteObject( hrgn );
 	    if (wndPtr->class->style & CS_OWNDC)
@@ -653,7 +677,10 @@
 	}
 	else SetRectEmpty( rect );
     }
-    return (wndPtr->hrgnUpdate > 1);
+    retvalue = (wndPtr->hrgnUpdate > 1);
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -678,10 +705,13 @@
     if (wndPtr->hrgnUpdate <= 1)
     {
         SetRectRgn( hrgn, 0, 0, 0, 0 );
-        return NULLREGION;
+        retval = NULLREGION;
+        goto END;
     }
     retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
     if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return retval;
 }
 
@@ -719,8 +749,10 @@
 
 	ret = DCE_ExcludeRgn( hdc, wndPtr, hrgn );
 	DeleteObject( hrgn );
+        WIN_ReleaseWndPtr(wndPtr);
 	return ret;
     } 
+    WIN_ReleaseWndPtr(wndPtr);
     return GetClipBox( hdc, &rect );
 }
 
diff --git a/windows/property.c b/windows/property.c
index a7f7d93..b93dd6f 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -35,9 +35,9 @@
         {
             if (HIWORD(prop->string))
             {
-                if (!lstrcmpiA( prop->string, str )) return prop;
+                if (!lstrcmpiA( prop->string, str )) goto END;
             }
-            else if (LOWORD(prop->string) == atom) return prop;
+            else if (LOWORD(prop->string) == atom) goto END;
         }
     }
     else  /* atom */
@@ -47,12 +47,15 @@
         {
             if (HIWORD(prop->string))
             {
-                if (GlobalFindAtomA( prop->string ) == atom) return prop;
+                if (GlobalFindAtomA( prop->string ) == atom) goto END;
             }
-            else if (LOWORD(prop->string) == atom) return prop;
+            else if (LOWORD(prop->string) == atom) goto END;
         }
     }
-    return NULL;
+    prop = NULL;
+END:
+    WIN_ReleaseWndPtr(pWnd);
+    return prop;
 }
 
 
@@ -126,14 +129,21 @@
         /* We need to create it */
         WND *pWnd = WIN_FindWndPtr( hwnd );
         if (!pWnd) return FALSE;
-        if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) ))) return FALSE;
+        if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) )))
+        {
+            WIN_ReleaseWndPtr(pWnd);
+            return FALSE;
+        }
         if (!(prop->string = SEGPTR_STRDUP(str)))
         {
             HeapFree( SystemHeap, 0, prop );
+            WIN_ReleaseWndPtr(pWnd);
             return FALSE;
+
         }
         prop->next  = pWnd->pProp;
         pWnd->pProp = prop;
+        WIN_ReleaseWndPtr(pWnd);
     }
     prop->handle = handle;
     return TRUE;
@@ -207,6 +217,7 @@
             else if (LOWORD((*pprop)->string) == atom) break;
         }
     }
+    WIN_ReleaseWndPtr(pWnd);
     if (!*pprop) return 0;
     prop   = *pprop;
     handle = prop->handle;
@@ -275,6 +286,7 @@
         ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
         if (!ret) break;
     }
+    WIN_ReleaseWndPtr(pWnd);
     return ret;
 }
 
@@ -320,6 +332,7 @@
         ret = func( hwnd, prop->string, prop->handle, lParam );
         if (!ret) break;
     }
+    WIN_ReleaseWndPtr(pWnd);
     return ret;
 }
 
@@ -355,5 +368,6 @@
                         prop->handle, lParam );
         if (!ret) break;
     }
+    WIN_ReleaseWndPtr(pWnd);
     return ret;
 }
diff --git a/windows/queue.c b/windows/queue.c
index 63e756d..5ed0024 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -924,6 +924,7 @@
                                        smsg->lParam );
 
         queue->GetMessageExtraInfoVal = extraInfo;  /* Restore extra info */
+        WIN_ReleaseWndPtr(wndPtr);
 	TRACE(sendmsg,"result =  %08x\n", (unsigned)result );
     }
     else WARN(sendmsg, "\trcm: bad hWnd\n");
@@ -1090,13 +1091,17 @@
 	 if( (wndPtr = WIN_FindWndPtr( hwnd )) ) 
            {
                hQueue = wndPtr->hmemTaskQ;
+               WIN_ReleaseWndPtr(wndPtr);
            }
     }
 
     if( (hwnd = GetSysModalWindow16()) )
     {
       if( (wndPtr = WIN_FindWndPtr( hwnd )) )
+        {
             hQueue = wndPtr->hmemTaskQ;
+            WIN_ReleaseWndPtr(wndPtr);
+        }
     }
 
     if (hQueue)
@@ -1309,10 +1314,13 @@
  */
 HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
 {
+    HTASK16 retvalue;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
     if (!wndPtr) return 0;
-    return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
+    retvalue = QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 /***********************************************************************
@@ -1321,12 +1329,14 @@
 DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
 {
     HTASK16 htask;
+    DWORD retvalue;
     TDB	*tdb;
 
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
     if (!wndPtr) return 0;
     htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
+    WIN_ReleaseWndPtr(wndPtr);
     tdb = (TDB*)GlobalLock16(htask);
     if (!tdb || !tdb->thdb) return 0;
     if (process) *process = (DWORD)tdb->thdb->process->server_pid;
diff --git a/windows/scroll.c b/windows/scroll.c
index c54b49d..bba77af 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -236,7 +236,11 @@
     RECT rc, cliprc;
     WND*   wnd = WIN_FindWndPtr( hwnd );
 
-    if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE )) return ERROR;
+    if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE ))
+    {
+        retVal = ERROR;
+        goto END;
+    }
 
     GetClientRect(hwnd, &rc);
     if (rect) IntersectRect(&rc, &rc, rect);
@@ -307,7 +311,7 @@
 	{
 	    RECT	r;
 	    WND* 	w;
-	    for( w = wnd->child; w; w = w->next )
+	    for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next))
 	    {
 		 CONV_RECT16TO32( &w->rectWindow, &r );
 	         if( IntersectRect(&r, &r, &rc) )
@@ -332,5 +336,7 @@
 	DeleteObject( hrgnClip );
         DeleteObject( hrgnTemp );
     }
+END:
+    WIN_ReleaseWndPtr(wnd);
     return retVal;
 }
diff --git a/windows/win.c b/windows/win.c
index 475b5e1..fc68040 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -63,9 +63,9 @@
  */
 void WIN_LockWnds()
 {
+/*
     EnterCriticalSection(&WIN_CritSection);
-    ilockCounter++;
-    TRACE(win,"All windows hinstances have been locked (lock #%i)\n",ilockCounter);
+*/
 }
 
 /***********************************************************************
@@ -74,19 +74,10 @@
  *  Unlocks access to all WND structures
  */
 void WIN_UnlockWnds()
-{
-
-    TRACE(win,"Lock #%i been unlocked\n",ilockCounter+1);
-    ilockCounter--;
-    if(ilockCounter == 0)
     {
+/*
         LeaveCriticalSection(&WIN_CritSection);
-        TRACE(win,"All windows hinstances have been unlocked\n");
-    }
-    else if(ilockCounter < 0)
-    {
-        ERR(win,"Negative lock reference ==> missing call to  WIN_Lock!\n");
-    }
+*/
 }
 /***********************************************************************
  *           WIN_SuspendWndsLock
@@ -96,12 +87,12 @@
  */
 int WIN_SuspendWndsLock()
 {
-    int isuspendedLocks = ilockCounter;
-    ilockCounter = 0;
+/*
+    int isuspendedLocks = WIN_CritSection.RecursionCount;
+    WIN_CritSection.RecursionCount = 0;
     LeaveCriticalSection(&WIN_CritSection);
-    TRACE(win,"All windows hinstances locks have been suspended\n");
     return isuspendedLocks;
-
+*/
 }
 
 /***********************************************************************
@@ -109,10 +100,12 @@
  *
  *  Restore the suspended locks on WND structures
  */
-void WIN_Unlock(int ipreviousLocks)
+void WIN_RestoreWndslock(int ipreviousLocks)
 {
+/*
     EnterCriticalSection(&WIN_CritSection);
-    ilockCounter = ipreviousLocks;
+    WIN_CritSection.RecursionCount = ipreviousLocks;
+*/
 }
 /***********************************************************************
  *           WIN_FindWndPtr
@@ -126,8 +119,8 @@
     if (!hwnd || HIWORD(hwnd)) goto error2;
     ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
     /* Lock all WND structures for thread safeness
-     WIN_LockWnds();
-     and increment destruction monitoring value
+    WIN_LockWnds(ptr);
+    and increment destruction monitoring
      ptr->irefCount++;
      */
     if (ptr->dwMagic != WND_MAGIC) goto error;
@@ -140,7 +133,7 @@
     return ptr;
  error:
     /* Unlock all WND structures for thread safeness
-     WIN_UnlockWnds();
+    WIN_UnlockWnds(ptr);
      and decrement destruction monitoring value
      ptr->irefCount--;
      */
@@ -151,6 +144,25 @@
 }
 
 /***********************************************************************
+ *           WIN_LockWndPtr
+ *
+ * Use in case the wnd ptr is not initialized with WIN_FindWndPtr
+ * but by initWndPtr;
+ * Returns the locked initialisation pointer
+ */
+WND *WIN_LockWndPtr(WND *initWndPtr)
+{
+
+    if(!initWndPtr) return 0;
+    /*
+    WIN_LockWnds();
+    initWndPtr->irefCount++;
+    */
+    return initWndPtr;
+
+}
+        
+/***********************************************************************
  *           WIN_ReleaseWndPtr
  *
  * Release the pointer to the WND structure.
@@ -158,6 +170,7 @@
 void WIN_ReleaseWndPtr(WND *wndPtr)
 {
 
+    if(!wndPtr) return;
     /*Decrement destruction monitoring value
      wndPtr->irefCount--;
      Check if it's time to release the memory
@@ -167,10 +180,23 @@
      }
      unlock all WND structures for thread safeness
      WIN_UnlockWnds();
-
      */    
 }
 
+/***********************************************************************
+ *           WIN_ReleaseWndPtr
+ *
+ * Updates the value of oldPtr to newPtr.
+ */
+void WIN_UpdateWndPtr(WND **oldPtr, WND *newPtr)
+{
+    WND *tmpWnd = NULL;
+    
+    tmpWnd = WIN_LockWndPtr(newPtr);
+    WIN_ReleaseWndPtr(*oldPtr);
+    *oldPtr = tmpWnd;
+
+}
 
 /***********************************************************************
  *           WIN_DumpWindow
@@ -216,6 +242,7 @@
         DUMP( "\n" );
     }
     DUMP( "\n" );
+    WIN_ReleaseWndPtr(ptr);
 }
 
 
@@ -229,7 +256,8 @@
     WND *ptr;
     char className[80];
 
-    ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
+    ptr = hwnd ? WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
+
     if (!ptr)
     {
         WARN( win, "Invalid window handle %04x\n", hwnd );
@@ -253,8 +281,10 @@
                  ptr->text?ptr->text:"<null>");
         
         if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
-        ptr = ptr->next;
+        WIN_UpdateWndPtr(&ptr,ptr->next);
+        
     }
+
 }
 
 /***********************************************************************
@@ -266,10 +296,16 @@
 {    
     WND *wndPtr, **ppWnd;
 
-    if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+    else if(!wndPtr->parent)
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return FALSE;
+    }
     ppWnd = &wndPtr->parent->child;
     while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
     *ppWnd = wndPtr->next;
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
@@ -285,8 +321,12 @@
 {    
     WND *wndPtr, **ppWnd;
 
-    if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
-
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+    else if(!wndPtr->parent)
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return FALSE;
+    }
     if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
     {
         ppWnd = &wndPtr->parent->child;  /* Point to first sibling hwnd */
@@ -296,11 +336,17 @@
     else  /* Normal case */
     {
 	WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
-	if (!afterPtr) return FALSE;
+            if (!afterPtr)
+            {
+                WIN_ReleaseWndPtr(wndPtr);
+                return FALSE;
+            }
         ppWnd = &afterPtr->next;
+        WIN_ReleaseWndPtr(afterPtr);
     }
     wndPtr->next = *ppWnd;
     *ppWnd = wndPtr;
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
@@ -313,32 +359,35 @@
 HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE16 hQueue )
 {
     HWND hwndRet;
-    WND *pWnd = pWndDesktop;
+    WND *pWnd;
 
     /* Note: the desktop window never gets WM_PAINT messages 
      * The real reason why is because Windows DesktopWndProc
      * does ValidateRgn inside WM_ERASEBKGND handler.
      */
 
-    pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
+    pWnd = hwnd ? WIN_FindWndPtr(hwnd) : WIN_LockWndPtr(pWndDesktop->child);
 
-    for ( ; pWnd ; pWnd = pWnd->next )
+    for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
     {
         if (!(pWnd->dwStyle & WS_VISIBLE))
         {
             TRACE(win, "skipping window %04x\n",
                          pWnd->hwndSelf );
-            continue;
         }
-        if ((pWnd->hmemTaskQ == hQueue) &&
+        else if ((pWnd->hmemTaskQ == hQueue) &&
             (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
         
-        if (pWnd->child )
+        else if (pWnd->child )
             if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
-                return hwndRet;
+                goto end;
     }
     
-    if (!pWnd) return 0;
+    if(!pWnd)
+    {
+        hwndRet = 0;
+        goto end;
+    }
     
     hwndRet = pWnd->hwndSelf;
 
@@ -346,10 +395,12 @@
     while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
                     !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
     {
-        pWnd = pWnd->next;
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
     if (pWnd) hwndRet = pWnd->hwndSelf;
     TRACE(win,"found %04x\n",hwndRet);
+  end:
+    WIN_ReleaseWndPtr(pWnd);
     return hwndRet;
 }
 
@@ -358,6 +409,7 @@
  *           WIN_DestroyWindow
  *
  * Destroy storage associated to a window. "Internals" p.358
+ * returns a locked wndPtr->next
  */
 static WND* WIN_DestroyWindow( WND* wndPtr )
 {
@@ -372,9 +424,12 @@
 #endif  /* CONFIG_IPC */
 	
     /* free child windows */
-
+    WIN_LockWndPtr(wndPtr->child);
     while ((pWnd = wndPtr->child))
+    {
         wndPtr->child = WIN_DestroyWindow( pWnd );
+        WIN_ReleaseWndPtr(pWnd);
+    }
 
     SendMessageA( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
 
@@ -431,7 +486,8 @@
     wndPtr->hwndSelf = 0;
     wndPtr->class->cWindows--;
     wndPtr->class = NULL;
-    pWnd = wndPtr->next;
+
+    WIN_UpdateWndPtr(&pWnd,wndPtr->next);
 
     wndPtr->pDriver->pFinalize(wndPtr);
     USER_HEAP_FREE( hwnd );
@@ -450,7 +506,7 @@
 
     if (hNew)  /* Set a new queue */
     {
-        for (wnd = wnd->child; (wnd); wnd = wnd->next)
+        for (wnd = WIN_LockWndPtr(wnd->child); (wnd);WIN_UpdateWndPtr(&wnd,wnd->next))
         {
             if (wnd->hmemTaskQ == hQueue)
             {
@@ -458,14 +514,17 @@
                 ret = TRUE;
             }
             if (wnd->child)
+            {
                 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
         }
     }
+    }
     else  /* Queue is being destroyed */
     {
         while (wnd->child)
         {
-            WND *tmp = wnd->child;
+            WND *tmp = WIN_LockWndPtr(wnd->child);
+            WND *tmp2;
             ret = FALSE;
             while (tmp)
             {
@@ -475,11 +534,16 @@
                     ret = TRUE;
                     break;
                 }
-                if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
+                tmp2 = WIN_LockWndPtr(tmp->child);
+                if (tmp2 && WIN_ResetQueueWindows(tmp2,hQueue,0))
                     ret = TRUE;
                 else
-                    tmp = tmp->next;
+                {
+                    WIN_UpdateWndPtr(&tmp,tmp->next);
+                }
+                WIN_ReleaseWndPtr(tmp2);
             }
+            WIN_ReleaseWndPtr(tmp);
             if (!ret) break;
         }
     }
@@ -550,12 +614,18 @@
     pWndDesktop->hSysMenu          = 0;
     pWndDesktop->userdata          = 0;
     pWndDesktop->winproc = (WNDPROC16)class->winproc;
+    pWndDesktop->irefCount         = 0;
 
     /* FIXME: How do we know if it should be Unicode or not */
     if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
       return FALSE;
     
     SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 );
+
+    /* Initialisation of the critical section for thread safeness
+     InitializeCriticalSection(&WIN_CritSection);
+     MakeCriticalSectionGlobal(&WIN_CritSection);
+     */
     pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
     return TRUE;
 }
@@ -571,6 +641,7 @@
 {
     CLASS *classPtr;
     WND *wndPtr;
+    HWND retvalue;
     HWND16 hwnd, hwndLinkAfter;
     POINT maxSize, maxPos, minTrack, maxTrack;
     LRESULT (CALLBACK *localSend32)(HWND, UINT, WPARAM, LPARAM);
@@ -649,7 +720,7 @@
 
     /* Fill the window structure */
 
-    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
+    wndPtr = WIN_LockWndPtr((WND *) USER_HEAP_LIN_ADDR( hwnd ));
     wndPtr->next  = NULL;
     wndPtr->child = NULL;
 
@@ -657,6 +728,7 @@
     {
         wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
         wndPtr->owner  = NULL;
+        WIN_ReleaseWndPtr(wndPtr->parent);
     }
     else
     {
@@ -664,7 +736,10 @@
         if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
             wndPtr->owner = NULL;
         else
+        {
             wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
+            WIN_ReleaseWndPtr(wndPtr->owner);
+    }
     }
 
     wndPtr->pDriver = wndPtr->parent->pDriver;
@@ -712,7 +787,8 @@
 	    TRACE(win, "CBT-hook returned 0\n");
 	    wndPtr->pDriver->pFinalize(wndPtr);
 	    USER_HEAP_FREE( hwnd );
-	    return 0;
+            retvalue =  0;
+            goto end;
 	}
     }
 
@@ -764,7 +840,10 @@
     wndPtr->rectClient        = wndPtr->rectWindow;
 
     if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
-       return FALSE;
+    {
+        retvalue = FALSE;
+        goto end;
+    }
 
     /* Set the window menu */
 
@@ -853,7 +932,11 @@
 
 		SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
 				MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
-		if( !IsWindow(hwnd) ) return 0;
+                if( !IsWindow(hwnd) )
+                {
+                    retvalue = 0;
+                    goto end;
+	    }
 	    }
 
             if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
@@ -864,7 +947,8 @@
                 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
 
             TRACE(win, "created window %04x\n", hwnd);
-            return hwnd;
+            retvalue = hwnd;
+            goto end;
         }
         WIN_UnlinkWindow( hwnd );
     }
@@ -873,7 +957,10 @@
 
     WARN(win, "aborted by WM_xxCREATE!\n");
     WIN_DestroyWindow( wndPtr );
-    return 0;
+    retvalue = 0;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1048,11 +1135,11 @@
 
     if( IsWindow(pWnd->hwndSelf) )
     {
-	WND* pChild = pWnd->child;
+	WND* pChild = WIN_LockWndPtr(pWnd->child);
 	while( pChild )
 	{
 	    WIN_SendDestroyMsg( pChild );
-	    pChild = pChild->next;
+            WIN_UpdateWndPtr(&pChild,pChild->next);
 	}
 	WIN_CheckFocus(pWnd);
     }
@@ -1076,18 +1163,26 @@
 BOOL WINAPI DestroyWindow( HWND hwnd )
 {
     WND * wndPtr;
+    BOOL retvalue;
 
     TRACE(win, "(%04x)\n", hwnd);
     
       /* Initialization */
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
-    if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
+    if (wndPtr == pWndDesktop)
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return FALSE; /* Can't destroy desktop */
+    }
 
       /* Call hooks */
 
     if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
-        return FALSE;
+    {
+        retvalue = FALSE;
+        goto end;
+    }
 
     if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
     {
@@ -1101,7 +1196,11 @@
 	    /* Notify the parent window only */
 	    SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
 			    MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
-	    if( !IsWindow(hwnd) ) return TRUE;
+            if( !IsWindow(hwnd) )
+            {
+                retvalue = TRUE;
+                goto end;
+            }
 	}
 
     CLIPBOARD_GetDriver()->pResetOwner( wndPtr, FALSE ); /* before the window is unmapped */
@@ -1113,7 +1212,11 @@
         SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
 		        SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
 		        ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
-	if (!IsWindow(hwnd)) return TRUE;
+        if (!IsWindow(hwnd))
+        {
+            retvalue = TRUE;
+            goto end;
+        }
     }
 
       /* Recursively destroy owned windows */
@@ -1125,7 +1228,7 @@
 
       for (;;)
       {
-        WND *siblingPtr = wndPtr->parent->child;  /* First sibling */
+        WND *siblingPtr = WIN_LockWndPtr(wndPtr->parent->child);  /* First sibling */
         while (siblingPtr)
         {
             if (siblingPtr->owner == wndPtr)
@@ -1135,7 +1238,7 @@
                else 
                    siblingPtr->owner = NULL;
 	    }
-            siblingPtr = siblingPtr->next;
+            WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
         }
         if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
         else break;
@@ -1152,7 +1255,11 @@
       /* Send destroy messages */
 
     WIN_SendDestroyMsg( wndPtr );
-    if (!IsWindow(hwnd)) return TRUE;
+    if (!IsWindow(hwnd))
+    {
+        retvalue = TRUE;
+        goto end;
+    }
 
       /* Unlink now so we won't bother with the children later on */
 
@@ -1161,7 +1268,10 @@
       /* Destroy the window storage */
 
     WIN_DestroyWindow( wndPtr );
-    return TRUE;
+    retvalue = TRUE;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1180,9 +1290,19 @@
 BOOL WINAPI CloseWindow( HWND hwnd )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
+    BOOL retvalue;
+    
+    if (!wndPtr || (wndPtr->dwStyle & WS_CHILD))
+    {
+        retvalue = FALSE;
+        goto end;
+    }
     ShowWindow( hwnd, SW_MINIMIZE );
-    return TRUE;
+    retvalue = TRUE;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
+
 }
 
  
@@ -1215,6 +1335,7 @@
                               LPCSTR title )
 {
     WND *pWnd;
+    HWND retvalue;
     CLASS *pClass = NULL;
 
     if (child)
@@ -1222,17 +1343,33 @@
         if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
         if (parent)
         {
-            if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
+            if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
+            {
+                retvalue = 0;
+                goto end;
+            }
         }
-        else if (pWnd->parent != pWndDesktop) return 0;
-        pWnd = pWnd->next;
+        else if (pWnd->parent != pWndDesktop)
+        {
+            retvalue = 0;
+            goto end;
+        }
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
     else
     {
-        if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
-        pWnd = pWnd->child;
+        if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
+        {
+            retvalue = 0;
+            goto end;
+        }
+        WIN_UpdateWndPtr(&pWnd,pWnd->child);
     }
-    if (!pWnd) return 0;
+    if (!pWnd)
+    {
+        retvalue = 0;
+        goto end;
+    }
 
     /* For a child window, all siblings will have the same hInstance, */
     /* so we can look for the class once and for all. */
@@ -1240,11 +1377,14 @@
     if (className && (pWnd->dwStyle & WS_CHILD))
     {
         if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
-            return 0;
+        {
+            retvalue = 0;
+            goto end;
+        }
     }
 
 
-    for ( ; pWnd; pWnd = pWnd->next)
+    while (pWnd)
     {
         if (className && !(pWnd->dwStyle & WS_CHILD))
         {
@@ -1257,10 +1397,22 @@
 
         /* Now check the title */
 
-        if (!title) return pWnd->hwndSelf;
-        if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
+        if (!title)
+        {
+            retvalue = pWnd->hwndSelf;
+            goto end;
     }
-    return 0;
+        if (pWnd->text && !strcmp( pWnd->text, title ))
+        {
+            retvalue = pWnd->hwndSelf;
+            goto end;
+}
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
+    }
+    retvalue = 0;
+end:
+    WIN_ReleaseWndPtr(pWnd);
+    return retvalue;
 }
 
 
@@ -1367,10 +1519,19 @@
 
 /**********************************************************************
  *           WIN_GetDesktop
+ * returns a locked pointer
  */
 WND *WIN_GetDesktop(void)
 {
-    return pWndDesktop;
+    return WIN_LockWndPtr(pWndDesktop);
+}
+/**********************************************************************
+ *           WIN_ReleaseDesktop
+ * unlock the desktop pointer
+ */
+void WIN_ReleaseDesktop(void)
+{
+    WIN_ReleaseWndPtr(pWndDesktop);
 }
 
 
@@ -1419,6 +1580,7 @@
 BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
 {
     WND *wndPtr;
+    BOOL retvalue;
 
     TRACE(win,"EnableWindow32: ( %x, %d )\n", hwnd, enable);
    
@@ -1428,7 +1590,8 @@
 	  /* Enable window */
 	wndPtr->dwStyle &= ~WS_DISABLED;
 	SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
-	return TRUE;
+        retvalue = TRUE;
+        goto end;
     }
     else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
     {
@@ -1443,9 +1606,13 @@
 	    ReleaseCapture();  /* A disabled window can't capture the mouse */
         }
 	SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
-	return FALSE;
+        retvalue = FALSE;
+        goto end;
     }
-    return ((wndPtr->dwStyle & WS_DISABLED) != 0);
+    retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1464,9 +1631,13 @@
 BOOL WINAPI IsWindowEnabled(HWND hWnd)
 {
     WND * wndPtr; 
+    BOOL retvalue;
 
     if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
-    return !(wndPtr->dwStyle & WS_DISABLED);
+    retvalue = !(wndPtr->dwStyle & WS_DISABLED);
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
+
 }
 
 
@@ -1476,9 +1647,12 @@
 BOOL WINAPI IsWindowUnicode( HWND hwnd )
 {
     WND * wndPtr; 
+    BOOL retvalue;
 
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
-    return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
+    retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1496,6 +1670,7 @@
  */
 WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
 {
+    WORD retvalue;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     if (offset >= 0)
@@ -1503,9 +1678,11 @@
         if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
         {
             WARN( win, "Invalid offset %d\n", offset );
-            return 0;
+            retvalue = 0;
+            goto end;
         }
-        return *(WORD *)(((char *)wndPtr->wExtra) + offset);
+        retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
+        goto end;
     }
     switch(offset)
     {
@@ -1513,18 +1690,25 @@
     	if (HIWORD(wndPtr->wIDmenu))
     		WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
                     wndPtr->wIDmenu);
-    	return (WORD)wndPtr->wIDmenu;
+        retvalue = (WORD)wndPtr->wIDmenu;
+        goto end;
     case GWW_HWNDPARENT: 
-    	return GetParent( hwnd );
+    	retvalue =  GetParent(hwnd);
+        goto end;
     case GWW_HINSTANCE:  
     	if (HIWORD(wndPtr->hInstance))
     		WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
                     wndPtr->hInstance);
-   	return (WORD)wndPtr->hInstance;
+        retvalue = (WORD)wndPtr->hInstance;
+        goto end;
     default:
         WARN( win, "Invalid offset %d\n", offset );
-        return 0;
+        retvalue = 0;
+        goto end;
     }
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1533,9 +1717,12 @@
  */
 HINSTANCE WIN_GetWindowInstance( HWND hwnd )
 {
+    
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return (HINSTANCE)0;
+    WIN_ReleaseWndPtr(wndPtr);
     return wndPtr->hInstance;
+    
 }
 
 
@@ -1561,7 +1748,8 @@
         if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
         {
             WARN( win, "Invalid offset %d\n", offset );
-            return 0;
+            retval = 0;
+            goto end;
         }
         ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
     }
@@ -1569,13 +1757,17 @@
     {
 	case GWW_ID:        ptr = (WORD *)&wndPtr->wIDmenu; break;
 	case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
-	case GWW_HWNDPARENT: return SetParent( hwnd, newval );
+        case GWW_HWNDPARENT: retval = SetParent( hwnd, newval );
+                             goto end;
 	default:
             WARN( win, "Invalid offset %d\n", offset );
-            return 0;
+            retval = 0;
+            goto end;
     }
     retval = *ptr;
     *ptr = newval;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
     return retval;
 }
 
@@ -1587,7 +1779,7 @@
  */
 static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
 {
-    LONG retval;
+    LONG retvalue;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     if (offset >= 0)
@@ -1595,28 +1787,42 @@
         if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
         {
             WARN( win, "Invalid offset %d\n", offset );
-            return 0;
+            retvalue = 0;
+            goto end;
         }
-        retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
+        retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
         /* Special case for dialog window procedure */
         if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
-            return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
-        return retval;
+        {
+            retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
+            goto end;
+    }
+        goto end;
     }
     switch(offset)
     {
-        case GWL_USERDATA:   return wndPtr->userdata;
-        case GWL_STYLE:      return wndPtr->dwStyle;
-        case GWL_EXSTYLE:    return wndPtr->dwExStyle;
-        case GWL_ID:         return (LONG)wndPtr->wIDmenu;
-        case GWL_WNDPROC:    return (LONG)WINPROC_GetProc( wndPtr->winproc,
+        case GWL_USERDATA:   retvalue = wndPtr->userdata;
+                             goto end;
+        case GWL_STYLE:      retvalue = wndPtr->dwStyle;
+                             goto end;
+        case GWL_EXSTYLE:    retvalue = wndPtr->dwExStyle;
+                             goto end;
+        case GWL_ID:         retvalue = (LONG)wndPtr->wIDmenu;
+                             goto end;
+        case GWL_WNDPROC:    retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
                                                            type );
-        case GWL_HWNDPARENT: return GetParent(hwnd);
-        case GWL_HINSTANCE:  return wndPtr->hInstance;
+                             goto end;
+        case GWL_HWNDPARENT: retvalue = GetParent(hwnd);
+                             goto end;
+        case GWL_HINSTANCE:  retvalue = wndPtr->hInstance;
+                             goto end;
         default:
             WARN( win, "Unknown offset %d\n", offset );
     }
-    return 0;
+    retvalue = 0;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1656,7 +1862,8 @@
             /* Is this the right error? */
             SetLastError( ERROR_OUTOFMEMORY );
 
-            return 0;
+            retval = 0;
+            goto end;
         }
         ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
         /* Special case for dialog window procedure */
@@ -1665,7 +1872,7 @@
             retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
             WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval, 
                              type, WIN_PROC_WINDOW );
-            return retval;
+            goto end;
         }
     }
     else switch(offset)
@@ -1674,12 +1881,13 @@
 		ptr = (DWORD*)&wndPtr->wIDmenu;
 		break;
 	case GWL_HINSTANCE:
-		return SetWindowWord( hwnd, offset, newval );
+                retval = SetWindowWord( hwnd, offset, newval );
+                goto end;
 	case GWL_WNDPROC:
 					retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
 		WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval, 
 						type, WIN_PROC_WINDOW );
-		return retval;
+		goto end;;
 	case GWL_STYLE:
 	       	style.styleOld = wndPtr->dwStyle;
 		newval &= ~(WS_VISIBLE | WS_CHILD);	/* Some bits can't be changed this way */
@@ -1690,7 +1898,8 @@
 		wndPtr->dwStyle = style.styleNew;
 		if (wndPtr->flags & WIN_ISWIN32)
 			SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
-		return style.styleOld;
+                retval = style.styleOld;
+                goto end;
 		    
         case GWL_USERDATA: 
 		ptr = &wndPtr->userdata; 
@@ -1703,7 +1912,8 @@
 		wndPtr->dwExStyle = newval;
 		if (wndPtr->flags & WIN_ISWIN32)
 			SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
-		return style.styleOld;
+                retval = style.styleOld;
+                goto end;
 
 	default:
             WARN( win, "Invalid offset %d\n", offset );
@@ -1711,10 +1921,13 @@
             /* Don't think this is right error but it should do */
             SetLastError( ERROR_OUTOFMEMORY );
 
-            return 0;
+            retval = 0;
+            goto end;
     }
     retval = *ptr;
     *ptr = newval;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
     return retval;
 }
 
@@ -1962,8 +2175,14 @@
  */
 BOOL WINAPI IsWindow( HWND hwnd )
 {
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
+    WND * wndPtr;
+    BOOL retvalue;
+    
+    if(!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+    retvalue = (wndPtr->dwMagic == WND_MAGIC);
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
+    
 }
 
 
@@ -1981,20 +2200,35 @@
  */
 HWND WINAPI GetParent( HWND hwnd )
 {
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
-    if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
-    wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
-    return wndPtr ? wndPtr->hwndSelf : 0;
+    WND *wndPtr;
+    HWND retvalue;
+    
+    if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+    if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return 0;
+    }
+    WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
+    retvalue = wndPtr ? wndPtr->hwndSelf : 0;
+
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
+    
 }
 
 /*****************************************************************
  *         WIN_GetTopParent
  *
  * Get the top-level parent for a child window.
+ * returns a locked pointer
  */
 WND* WIN_GetTopParentPtr( WND* pWnd )
 {
-    while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
+    while( pWnd && (pWnd->dwStyle & WS_CHILD))
+    {
+        WIN_UpdateWndPtr(&pWnd,pWnd->parent);
+    }
     return pWnd;
 }
 
@@ -2005,8 +2239,14 @@
  */
 HWND WIN_GetTopParent( HWND hwnd )
 {
-    WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
-    return wndPtr ? wndPtr->hwndSelf : 0;
+    HWND retvalue;
+    WND *tmpPtr = WIN_FindWndPtr(hwnd);
+    WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
+    
+    retvalue = wndPtr ? wndPtr->hwndSelf : 0;
+    WIN_ReleaseWndPtr(tmpPtr);
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -2024,18 +2264,26 @@
  */
 HWND WINAPI SetParent( HWND hwndChild, HWND hwndNewParent )
 {
-  WND *wndPtr = WIN_FindWndPtr( hwndChild );
-  DWORD dwStyle = (wndPtr)?(wndPtr->dwStyle):0;
-  WND *pWndNewParent = 
-    (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
+  WND *wndPtr;
+  DWORD dwStyle;
+  WND *pWndNewParent;
   WND *pWndOldParent;
+  HWND retvalue;
+
+
+  if(!(wndPtr = WIN_FindWndPtr(hwndChild))) return 0;
+
+  dwStyle = wndPtr->dwStyle;
+
+  pWndNewParent = hwndNewParent ? WIN_FindWndPtr(hwndNewParent)
+                                : WIN_LockWndPtr(pWndDesktop);
 
   /* Windows hides the window first, then shows it again
    * including the WM_SHOWWINDOW messages and all */
   if (dwStyle & WS_VISIBLE)
       ShowWindow( hwndChild, SW_HIDE );
 
-  pWndOldParent = (wndPtr)?(*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent):NULL;
+  pWndOldParent = WIN_LockWndPtr((*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent));
 
   /* SetParent32 additionally needs to make hwndChild the topmost window
      in the x-order and send the expected WM_WINDOWPOSCHANGING and
@@ -2046,7 +2294,14 @@
   /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
    * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
 
-  return pWndOldParent?pWndOldParent->hwndSelf:0;
+  retvalue = pWndOldParent?pWndOldParent->hwndSelf:0;
+
+  WIN_ReleaseWndPtr(pWndOldParent);
+  WIN_ReleaseWndPtr(pWndNewParent);
+  WIN_ReleaseWndPtr(wndPtr);
+
+  return retvalue;
+  
 }
 
 /*******************************************************************
@@ -2066,9 +2321,14 @@
     WND * wndPtr = WIN_FindWndPtr( child );
     while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
     {
-        wndPtr = wndPtr->parent;
-	if (wndPtr->hwndSelf == parent) return TRUE;
+        WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
+        if (wndPtr->hwndSelf == parent)
+    {
+            WIN_ReleaseWndPtr(wndPtr);
+            return TRUE;
+        }
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return FALSE;
 }
 
@@ -2087,13 +2347,21 @@
  */
 BOOL WINAPI IsWindowVisible( HWND hwnd )
 {
+    BOOL retval;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
     {
-        if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
-        wndPtr = wndPtr->parent;
+        if (!(wndPtr->dwStyle & WS_VISIBLE))
+    {
+            WIN_ReleaseWndPtr(wndPtr);
+            return FALSE;
+        }
+        WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
     }
-    return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
+    retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
+    WIN_ReleaseWndPtr(wndPtr);
+    return retval;
+    
 }
 
 
@@ -2130,9 +2398,15 @@
  */
 HWND WINAPI GetTopWindow( HWND hwnd )
 {
+    HWND retval;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
-    else return 0;
+    if (wndPtr && wndPtr->child)
+    {
+        retval = wndPtr->child->hwndSelf;
+    }
+    else retval = 0;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retval;
 }
 
 
@@ -2150,41 +2424,71 @@
  */
 HWND WINAPI GetWindow( HWND hwnd, WORD rel )
 {
+    HWND retval;
+    
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     switch(rel)
     {
     case GW_HWNDFIRST:
-        if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
-	else return 0;
+        if (wndPtr->parent) retval = wndPtr->parent->child->hwndSelf;
+        else retval = 0;
+        goto end;
 	
     case GW_HWNDLAST:
-	if (!wndPtr->parent) return 0;  /* Desktop window */
-	while (wndPtr->next) wndPtr = wndPtr->next;
-        return wndPtr->hwndSelf;
-	
-    case GW_HWNDNEXT:
-        if (!wndPtr->next) return 0;
-	return wndPtr->next->hwndSelf;
-	
-    case GW_HWNDPREV:
-        if (!wndPtr->parent) return 0;  /* Desktop window */
-        wndPtr = wndPtr->parent->child;  /* First sibling */
-        if (wndPtr->hwndSelf == hwnd) return 0;  /* First in list */
+        if (!wndPtr->parent)
+        {
+            retval = 0;  /* Desktop window */
+            goto end;
+        }
         while (wndPtr->next)
         {
-            if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
-            wndPtr = wndPtr->next;
+            WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
         }
-        return 0;
+        retval = wndPtr->hwndSelf;
+        goto end;
+	
+    case GW_HWNDNEXT:
+        if (!wndPtr->next) retval = 0;
+        else retval = wndPtr->next->hwndSelf;
+        goto end;
+	
+    case GW_HWNDPREV:
+        if (!wndPtr->parent)
+        {
+            retval = 0;  /* Desktop window */
+            goto end;
+        }
+        WIN_UpdateWndPtr(&wndPtr,wndPtr->parent->child); /* First sibling */
+        if (wndPtr->hwndSelf == hwnd)
+        {
+            retval = 0;  /* First in list */
+            goto end;
+        }
+        while (wndPtr->next)
+        {
+            if (wndPtr->next->hwndSelf == hwnd)
+        {
+                retval = wndPtr->hwndSelf;
+                goto end;
+        }
+            WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
+        }
+        retval = 0;
+        goto end;
 	
     case GW_OWNER:
-	return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
+        retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
+        goto end;
 
     case GW_CHILD:
-	return wndPtr->child ? wndPtr->child->hwndSelf : 0;
+        retval = wndPtr->child ? wndPtr->child->hwndSelf : 0;
+        goto end;
     }
-    return 0;
+    retval = 0;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retval;
 }
 
 
@@ -2211,13 +2515,14 @@
  */
 BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
 {
-    WND *pWnd = pWndDesktop->child;
+    WND *pWnd;
+    pWnd = WIN_LockWndPtr(pWndDesktop->child);
     while (pWnd)
     {
         if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
             (pWnd->dwStyle & WS_POPUP))
             ShowWindow( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
-        pWnd = pWnd->next;
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
     return TRUE;
 }
@@ -2237,9 +2542,12 @@
 HWND WINAPI GetLastActivePopup( HWND hwnd )
 {
     WND *wndPtr;
+    HWND retval;
     wndPtr = WIN_FindWndPtr(hwnd);
-    if (wndPtr == NULL) return hwnd;
-    return wndPtr->hwndLastActive;
+    if (!wndPtr) return hwnd;
+    retval = wndPtr->hwndLastActive;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retval;
 }
 
 
@@ -2252,9 +2560,11 @@
  */
 WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
 {
+    /* Future : this function will lock all windows associated with this array */
+    
     WND **list, **ppWnd;
     WND *pWnd;
-    UINT count, skipOwned, skipHidden;
+    UINT count = 0, skipOwned, skipHidden;
     DWORD skipFlags;
 
     skipHidden = bwaFlags & BWA_SKIPHIDDEN;
@@ -2264,11 +2574,19 @@
 
     /* First count the windows */
 
-    if (!wndPtr) wndPtr = pWndDesktop;
-    for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) 
+    if (!wndPtr)
+        wndPtr = WIN_GetDesktop();
+
+    pWnd = WIN_LockWndPtr(wndPtr->child);
+    while (pWnd)
     {
 	if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
-	if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
+        if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
+        {
+            count++;
+            WIN_UpdateWndPtr(&pWnd,pWnd->next);
+    }
+
     }
 
     if( count )
@@ -2277,15 +2595,16 @@
 
 	if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
 	{
-	    for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
+	    for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
 	    {
-		if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
-		if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
+		if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
+		else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
 		{
 		   *ppWnd++ = pWnd;
 		    count++;
 		}
 	    }
+            WIN_ReleaseWndPtr(pWnd);
 	   *ppWnd = NULL;
 	}
 	else count = 0;
@@ -2294,7 +2613,15 @@
     if( pTotal ) *pTotal = count;
     return list;
 }
+/*******************************************************************
+ *           WIN_ReleaseWinArray
+ */
+void WIN_ReleaseWinArray(WND **wndArray)
+{
+    /* Future : this function will also unlock all windows associated with wndArray */
+     HeapFree( SystemHeap, 0, wndArray );
 
+}
 
 /*******************************************************************
  *           EnumWindows16   (USER.54)
@@ -2307,7 +2634,11 @@
     /* unpleasant side-effects, for instance if the callback  */
     /* function changes the Z-order of the windows.           */
 
-    if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
+    if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
+    {
+        WIN_ReleaseDesktop();
+        return FALSE;
+    }
 
     /* Now call the callback function for every window */
 
@@ -2317,7 +2648,8 @@
         if (!IsWindow((*ppWnd)->hwndSelf)) continue;
         if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
     }
-    HeapFree( SystemHeap, 0, list );
+    WIN_ReleaseWinArray(list);
+    WIN_ReleaseDesktop();
     return TRUE;
 }
 
@@ -2342,7 +2674,11 @@
     /* This function is the same as EnumWindows(),    */
     /* except for an added check on the window's task. */
 
-    if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
+    if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
+    {
+        WIN_ReleaseDesktop();
+        return FALSE;
+    }
 
     /* Now call the callback function for every window */
 
@@ -2353,7 +2689,8 @@
         if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
         if (!func( (*ppWnd)->hwndSelf, lParam )) break;
     }
-    HeapFree( SystemHeap, 0, list );
+    WIN_ReleaseWinArray(list);
+    WIN_ReleaseDesktop();
     return TRUE;
 }
 
@@ -2390,7 +2727,7 @@
         if (childList)
         {
             if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
-            HeapFree( SystemHeap, 0, childList );
+            WIN_ReleaseWinArray(childList);
         }
         if (!ret) return FALSE;
     }
@@ -2407,9 +2744,14 @@
     WND **list, *pParent;
 
     if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
-    if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
+    if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
+    {
+        WIN_ReleaseWndPtr(pParent);
+        return FALSE;
+    }
     WIN_EnumChildWindows( list, func, lParam );
-    HeapFree( SystemHeap, 0, list );
+    WIN_ReleaseWinArray(list);
+    WIN_ReleaseWndPtr(pParent);
     return TRUE;
 }
 
@@ -2439,10 +2781,22 @@
  */
 BOOL WINAPI AnyPopup(void)
 {
-    WND *wndPtr;
-    for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
-        if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
-    return FALSE;
+    WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
+    BOOL retvalue;
+    
+    while (wndPtr)
+    {
+        if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
+        {
+            retvalue = TRUE;
+            goto end;
+}
+        WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
+    }
+    retvalue = FALSE;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -2484,6 +2838,7 @@
 					  RDW_UPDATENOW | RDW_FRAME, 0 );
             wndPtr->flags &= ~WIN_NCACTIVATED;
         }
+        WIN_ReleaseWndPtr(wndPtr);
         return TRUE;
     }
     else
@@ -2493,6 +2848,7 @@
         else wparam = (hWnd == GetActiveWindow());
 
         SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
+        WIN_ReleaseWndPtr(wndPtr);
         return wparam;
     }
 }
@@ -2524,9 +2880,12 @@
  */
 DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
 {
+    DWORD retval;
     WND *wnd = WIN_FindWndPtr( hwnd );
     if (!wnd) return 0;
-    return wnd->helpContext;
+    retval = wnd->helpContext;
+    WIN_ReleaseWndPtr(wnd);
+    return retval;
 }
 
 
@@ -2538,6 +2897,7 @@
     WND *wnd = WIN_FindWndPtr( hwnd );
     if (!wnd) return FALSE;
     wnd->helpContext = id;
+    WIN_ReleaseWndPtr(wnd);
     return TRUE;
 }
 
@@ -2556,7 +2916,11 @@
  WND 	       *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
  RECT		tempRect;
 
- if( !ptrQueryWnd || !ptrDragInfo ) return 0;
+ if( !ptrQueryWnd || !ptrDragInfo )
+ {
+     WIN_ReleaseWndPtr(ptrQueryWnd);
+     return 0;
+ }
 
  CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
 
@@ -2564,7 +2928,10 @@
 
  if( !PtInRect(&tempRect,pt) ||
      (ptrQueryWnd->dwStyle & WS_DISABLED) )
+ {
+     WIN_ReleaseWndPtr(ptrQueryWnd);
 	return 0;
+ }
 
  if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) ) 
    {
@@ -2577,12 +2944,14 @@
 	{
 	 wParam = 0;
          
-	 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
+         for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
+         {
              if( ptrWnd->dwStyle & WS_VISIBLE )
 	     {
                  GetWindowRect( ptrWnd->hwndSelf, &tempRect );
                  if (PtInRect( &tempRect, pt )) break;
 	     }
+         }
 
 	 if(ptrWnd)
          {
@@ -2591,9 +2960,15 @@
 			ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
             if( !(ptrWnd->dwStyle & WS_DISABLED) )
 	        bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
+
+            WIN_ReleaseWndPtr(ptrWnd);
          }
 
-	 if(bResult) return bResult;
+         if(bResult)
+         {
+             WIN_ReleaseWndPtr(ptrQueryWnd);
+             return bResult;
+         }
 	}
      else wParam = 1;
    }
@@ -2610,6 +2985,7 @@
  if( !bResult ) 
      CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
 
+ WIN_ReleaseWndPtr(ptrQueryWnd);
  return bResult;
 }
 
@@ -2681,13 +3057,18 @@
     lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
     spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
 
-    if( !lpDragInfo || !spDragInfo ) return 0L;
+    if( !lpDragInfo || !spDragInfo )
+    {
+        WIN_ReleaseWndPtr(wndPtr);
+        return 0L;
+    }
 
     hBummer = LoadCursor16(0, IDC_BUMMER16);
 
     if( !hBummer || !wndPtr )
     {
         GlobalFree16(hDragInfo);
+        WIN_ReleaseWndPtr(wndPtr);
         return 0L;
     }
 
@@ -2696,6 +3077,7 @@
 	if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
 	{
 	    GlobalFree16(hDragInfo);
+            WIN_ReleaseWndPtr(wndPtr);
 	    return 0L;
 	}
 
@@ -2772,6 +3154,7 @@
     else
         msg.lParam = 0;
     GlobalFree16(hDragInfo);
+    WIN_ReleaseWndPtr(wndPtr);
 
     return (DWORD)(msg.lParam);
 }
diff --git a/windows/winpos.c b/windows/winpos.c
index 62a6e74..dbe7ec1 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -134,7 +134,7 @@
         for (x = rectParent.left; x <= rectParent.right-xspacing; x += xspacing)
         {
               /* Check if another icon already occupies this spot */
-            WND *childPtr = wndPtr->parent->child;
+            WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
             while (childPtr)
             {
                 if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
@@ -145,8 +145,9 @@
                         (childPtr->rectWindow.bottom > y - yspacing))
                         break;  /* There's a window in there */
                 }
-                childPtr = childPtr->next;
+                WIN_UpdateWndPtr(&childPtr,childPtr->next);
             }
+            WIN_ReleaseWndPtr(childPtr);
             if (!childPtr) /* No window was found, so it's OK for us */
             {
 		pt.x = x + (xspacing - SYSMETRICS_CXICON) / 2;
@@ -167,7 +168,7 @@
     return ArrangeIconicWindows(parent);
 }
 /***********************************************************************
- *           ArrangeIconicWindows32   (USER32.7)
+ *           ArrangeIconicWindows   (USER32.7)
  */
 UINT WINAPI ArrangeIconicWindows( HWND parent )
 {
@@ -186,12 +187,17 @@
     {
         if( IsIconic( hwndChild ) )
         {
-	    WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), FALSE );
+            WND *wndPtr = WIN_FindWndPtr(hwndChild);
+            
+            WINPOS_ShowIconTitle( wndPtr, FALSE );
+               
             SetWindowPos( hwndChild, 0, x + (xspacing - SYSMETRICS_CXICON) / 2,
                             y - yspacing - SYSMETRICS_CYICON/2, 0, 0,
                             SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
 	    if( IsWindow(hwndChild) )
-	        WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), TRUE );
+                WINPOS_ShowIconTitle(wndPtr , TRUE );
+            WIN_ReleaseWndPtr(wndPtr);
+
             if (x <= rectParent.right - xspacing) x += xspacing;
             else
             {
@@ -215,7 +221,7 @@
 
 
 /***********************************************************************
- *             SwitchToThisWindow32   (USER32.539)
+ *             SwitchToThisWindow   (USER32.539)
  */
 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
 {
@@ -234,11 +240,12 @@
     CONV_RECT32TO16( &wndPtr->rectWindow, rect );
     if (wndPtr->dwStyle & WS_CHILD)
 	MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 );
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
 /***********************************************************************
- *           GetWindowRect32   (USER32.308)
+ *           GetWindowRect   (USER32.308)
  */
 BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect ) 
 {
@@ -248,12 +255,13 @@
     *rect = wndPtr->rectWindow;
     if (wndPtr->dwStyle & WS_CHILD)
 	MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
 
 /***********************************************************************
- *           GetWindowRgn32 
+ *           GetWindowRgn 
  */
 BOOL WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
 
@@ -262,7 +270,7 @@
   WND * wndPtr = WIN_FindWndPtr( hwnd ); 
   if (!wndPtr) return (ERROR);
 
-  FIXME (win, "GetWindowRgn32: doesn't really do regions\n"); 
+  FIXME (win, "GetWindowRgn: doesn't really do regions\n"); 
   
   memset (&rect, 0, sizeof(rect));
 
@@ -272,17 +280,18 @@
 
   SetRectRgn ( hrgn, rect.left, rect.top, rect.right, rect.bottom );
 
+  WIN_ReleaseWndPtr(wndPtr);
   return (SIMPLEREGION);
 }
 
 /***********************************************************************
- *           SetWindowRgn32 
+ *           SetWindowRgn 
  */
 INT WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn,BOOL bRedraw)
 
 {
 
-  FIXME (win, "SetWindowRgn32: stub\n"); 
+  FIXME (win, "SetWindowRgn: stub\n"); 
   return TRUE;
 }
 
@@ -311,11 +320,12 @@
 	rect->right  = wndPtr->rectClient.right - wndPtr->rectClient.left;
 	rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
 /***********************************************************************
- *           GetClientRect32   (USER32.220)
+ *           GetClientRect   (USER.220)
  */
 BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect ) 
 {
@@ -325,6 +335,8 @@
     if (!wndPtr) return FALSE;
     rect->right  = wndPtr->rectClient.right - wndPtr->rectClient.left;
     rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+
+    WIN_ReleaseWndPtr(wndPtr);
     return TRUE;
 }
 
@@ -339,7 +351,7 @@
 
 
 /*******************************************************************
- *         ClientToScreen32   (USER32.52)
+ *         ClientToScreen   (USER32.52)
  */
 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
 {
@@ -358,7 +370,7 @@
 
 
 /*******************************************************************
- *         ScreenToClient32   (USER32.447)
+ *         ScreenToClient   (USER32.447)
  */
 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
 {
@@ -376,10 +388,12 @@
 {
     WND *wndPtr;
     INT16 hittest = HTERROR;
+    INT16 retvalue;
     POINT16 xy = pt;
 
    *ppWnd = NULL;
-    wndPtr = wndScope->child;
+    wndPtr = WIN_LockWndPtr(wndScope->child);
+   
     if( wndScope->flags & WIN_MANAGED )
     {
 	/* this prevents mouse clicks from going "through" scrollbars in managed mode */
@@ -408,8 +422,16 @@
                 *ppWnd = wndPtr;  /* Got a suitable window */
 
                 /* If window is minimized or disabled, return at once */
-                if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
-                if (wndPtr->dwStyle & WS_DISABLED) return HTERROR;
+                if (wndPtr->dwStyle & WS_MINIMIZE)
+                {
+                    retvalue = HTCAPTION;
+                    goto end;
+                }
+                if (wndPtr->dwStyle & WS_DISABLED)
+                {
+                    retvalue = HTERROR;
+                    goto end;
+                }
 
                 /* If point is not in client area, ignore the children */
                 if ((xy.x < wndPtr->rectClient.left) ||
@@ -419,9 +441,12 @@
 
                 xy.x -= wndPtr->rectClient.left;
                 xy.y -= wndPtr->rectClient.top;
-                wndPtr = wndPtr->child;
+                WIN_UpdateWndPtr(&wndPtr,wndPtr->child);
             }
-            else wndPtr = wndPtr->next;
+            else
+            {
+                WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
+            }
         }
 
 hittest:
@@ -433,9 +458,17 @@
 	{
             hittest = (INT16)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST, 
 						 0, MAKELONG( pt.x, pt.y ) );
-	    if (hittest != HTTRANSPARENT) return hittest;  /* Found the window */
+            if (hittest != HTTRANSPARENT)
+            {
+                retvalue = hittest;  /* Found the window */
+                goto end;
 	}
-	else return HTCLIENT;
+	}
+        else
+        {
+            retvalue = HTCLIENT;
+            goto end;
+	}
 
         /* If no children found in last search, make point relative to parent */
         if (!wndPtr)
@@ -445,9 +478,13 @@
         }
 
         /* Restart the search from the next sibling */
-        wndPtr = (*ppWnd)->next;
+        WIN_UpdateWndPtr(&wndPtr,(*ppWnd)->next);
         *ppWnd = (*ppWnd)->parent;
     }
+
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -458,12 +495,13 @@
 {
     WND *pWnd;
     WINPOS_WindowFromPoint( WIN_GetDesktop(), pt, &pWnd );
+    WIN_ReleaseDesktop();
     return pWnd->hwndSelf;
 }
 
 
 /*******************************************************************
- *         WindowFromPoint32   (USER32.582)
+ *         WindowFromPoint   (USER32.582)
  */
 HWND WINAPI WindowFromPoint( POINT pt )
 {
@@ -471,6 +509,7 @@
     POINT16 pt16;
     CONV_POINT32TO16( &pt, &pt16 );
     WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16, &pWnd );
+    WIN_ReleaseDesktop();
     return (HWND)pWnd->hwndSelf;
 }
 
@@ -487,7 +526,7 @@
 
 
 /*******************************************************************
- *         ChildWindowFromPoint32   (USER32.49)
+ *         ChildWindowFromPoint   (USER32.49)
  */
 HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
 {
@@ -495,6 +534,7 @@
 
     WND* wnd = WIN_FindWndPtr(hwndParent);
     RECT rect;
+    HWND retvalue;
 
     if( !wnd ) return 0;
 
@@ -503,15 +543,25 @@
     rect.right = wnd->rectClient.right - wnd->rectClient.left;
     rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
 
-    if (!PtInRect( &rect, pt )) return 0;
-
-    wnd = wnd->child;
+    if (!PtInRect( &rect, pt ))
+    {
+        retvalue = 0;
+        goto end;
+    }
+    WIN_UpdateWndPtr(&wnd,wnd->child);
     while ( wnd )
     {
-        if (PtInRect( &wnd->rectWindow, pt )) return wnd->hwndSelf;
-        wnd = wnd->next;
+        if (PtInRect( &wnd->rectWindow, pt ))
+        {
+            retvalue = wnd->hwndSelf;
+            goto end;
+        }
+        WIN_UpdateWndPtr(&wnd,wnd->next);
     }
-    return hwndParent;
+    retvalue = hwndParent;
+end:
+    WIN_ReleaseWndPtr(wnd);
+    return retvalue;
 }
 
 /*******************************************************************
@@ -535,6 +585,7 @@
 
     WND* wnd = WIN_FindWndPtr(hwndParent);
     RECT rect;
+    HWND retvalue;
 
     if( !wnd ) return 0;
 
@@ -543,26 +594,35 @@
     rect.right = wnd->rectClient.right - wnd->rectClient.left;
     rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
 
-    if (!PtInRect( &rect, pt )) return 0;
+    if (!PtInRect( &rect, pt ))
+    {
+        retvalue = 0;
+        goto end;
+    }
+    WIN_UpdateWndPtr(&wnd,wnd->child);
 
-    wnd = wnd->child;
     while ( wnd )
     {
         if (PtInRect( &wnd->rectWindow, pt )) {
 		if ( (uFlags & CWP_SKIPINVISIBLE) && 
-				!(wnd->dwStyle & WS_VISIBLE) )
-		        wnd = wnd->next;
+				!(wnd->dwStyle & WS_VISIBLE) );
 		else if ( (uFlags & CWP_SKIPDISABLED) && 
-				(wnd->dwStyle & WS_DISABLED) )
-		        wnd = wnd->next;
+				(wnd->dwStyle & WS_DISABLED) );
 		else if ( (uFlags & CWP_SKIPTRANSPARENT) && 
-				(wnd->dwExStyle & WS_EX_TRANSPARENT) )
-		        wnd = wnd->next;
+				(wnd->dwExStyle & WS_EX_TRANSPARENT) );
 		else
-			return wnd->hwndSelf;
+                {
+                    retvalue = wnd->hwndSelf;
+                    goto end;
+	        }
+                WIN_UpdateWndPtr(&wnd,wnd->next);
+                
 	}
     }
-    return hwndParent;
+    retvalue = hwndParent;
+end:
+    WIN_ReleaseWndPtr(wnd);
+    return retvalue;
 }
 
 
@@ -575,7 +635,7 @@
 static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
                                  POINT *offset )
 {
-    WND * wndPtr;
+    WND * wndPtr = 0;
 
     offset->x = offset->y = 0;
     if (hwndFrom == hwndTo ) return;
@@ -592,7 +652,7 @@
         {
             offset->x += wndPtr->rectClient.left;
             offset->y += wndPtr->rectClient.top;
-            wndPtr = wndPtr->parent;
+            WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
         }
     }
 
@@ -608,9 +668,10 @@
         {
             offset->x -= wndPtr->rectClient.left;
             offset->y -= wndPtr->rectClient.top;
-            wndPtr = wndPtr->parent;
+            WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
         }    
     }
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 
@@ -633,7 +694,7 @@
 
 
 /*******************************************************************
- *         MapWindowPoints32   (USER32.386)
+ *         MapWindowPoints   (USER32.386)
  */
 INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo,
                                LPPOINT lppt, UINT count )
@@ -661,13 +722,16 @@
 
 
 /***********************************************************************
- *           IsIconic32   (USER32.345)
+ *           IsIconic   (USER32.345)
  */
 BOOL WINAPI IsIconic(HWND hWnd)
 {
+    BOOL retvalue;
     WND * wndPtr = WIN_FindWndPtr(hWnd);
     if (wndPtr == NULL) return FALSE;
-    return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
+    retvalue = (wndPtr->dwStyle & WS_MINIMIZE) != 0;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
  
  
@@ -681,13 +745,16 @@
 
 
 /***********************************************************************
- *           IsZoomed   (USER32.352)
+ *           IsZoomed   (USER.352)
  */
 BOOL WINAPI IsZoomed(HWND hWnd)
 {
+    BOOL retvalue;
     WND * wndPtr = WIN_FindWndPtr(hWnd);
     if (wndPtr == NULL) return FALSE;
-    return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
+    retvalue = (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -743,7 +810,7 @@
 
 
 /*******************************************************************
- *         SetActiveWindow32    (USER32.463)
+ *         SetActiveWindow    (USER32.463)
  */
 HWND WINAPI SetActiveWindow( HWND hwnd )
 {
@@ -751,7 +818,11 @@
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
 
-    if ( !WINPOS_CanActivate(wndPtr) ) return 0;
+    if ( !WINPOS_CanActivate(wndPtr) )
+    {
+        prev = 0;
+        goto end;
+    }
 
     /* Get the messageQ for the current thread */
     if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
@@ -771,6 +842,7 @@
     /* Make sure that the window is associated with the calling threads
      * message queue. It must share the same perQ data.
      */
+    
     if ( pCurMsgQ->pQData != pMsgQ->pQData )
         goto CLEANUP;
     
@@ -786,6 +858,8 @@
     if ( pCurMsgQ )
         QUEUE_Unlock( pCurMsgQ );
     
+end:
+    WIN_ReleaseWndPtr(wndPtr);
     return prev;
 }
 
@@ -809,7 +883,7 @@
 
 
 /*******************************************************************
- *         GetForegroundWindow32    (USER32.241)
+ *         GetForegroundWindow    (USER32.241)
  */
 HWND WINAPI GetForegroundWindow(void)
 {
@@ -818,7 +892,7 @@
 
 
 /*******************************************************************
- *         SetForegroundWindow32    (USER32.482)
+ *         SetForegroundWindow    (USER32.482)
  */
 BOOL WINAPI SetForegroundWindow( HWND hwnd )
 {
@@ -836,7 +910,7 @@
 }
 
 /*******************************************************************
- *         SetShellWindow32    (USER32.504)
+ *         SetShellWindow    (USER32.504)
  */
 HWND WINAPI SetShellWindow(HWND hwndshell)
 {   WARN(win, "(hWnd=%08x) semi stub\n",hwndshell );
@@ -847,7 +921,7 @@
 
 
 /*******************************************************************
- *         GetShellWindow32    (USER32.287)
+ *         GetShellWindow    (USER32.287)
  */
 HWND WINAPI GetShellWindow(void)
 {   WARN(win, "(hWnd=%x) semi stub\n",hGlobalShellWindow );
@@ -866,7 +940,7 @@
 
 
 /***********************************************************************
- *           BringWindowToTop32   (USER32.11)
+ *           BringWindowToTop   (USER32.11)
  */
 BOOL WINAPI BringWindowToTop( HWND hwnd )
 {
@@ -885,7 +959,7 @@
 
 
 /***********************************************************************
- *           MoveWindow32   (USER32.399)
+ *           MoveWindow   (USER32.399)
  */
 BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
                             BOOL repaint )
@@ -972,6 +1046,7 @@
 		SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
 			        SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
 	    }
+            WIN_ReleaseWndPtr(pWnd);
 	}
 	else ShowWindow( hWnd, SW_HIDE );
     }
@@ -1144,14 +1219,14 @@
 }
 
 /***********************************************************************
- *           ShowWindowAsync32   (USER32.535)
+ *           ShowWindowAsync   (USER32.535)
  *
  * doesn't wait; returns immediately.
  * used by threads to toggle windows in other (possibly hanging) threads
  */
 BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
 {
-    /* FIXME: does ShowWindow32() return immediately ? */
+    /* FIXME: does ShowWindow() return immediately ? */
     return ShowWindow(hwnd, cmd);
 }
 
@@ -1166,7 +1241,7 @@
 
 
 /***********************************************************************
- *           ShowWindow32   (USER32.534)
+ *           ShowWindow   (USER32.534)
  */
 BOOL WINAPI ShowWindow( HWND hwnd, INT cmd ) 
 {    
@@ -1184,7 +1259,7 @@
     switch(cmd)
     {
         case SW_HIDE:
-            if (!wasVisible) return FALSE;
+            if (!wasVisible) goto END;;
 	    swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
 		        SWP_NOACTIVATE | SWP_NOZORDER;
             if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus()))
@@ -1240,14 +1315,14 @@
     if (showFlag != wasVisible)
     {
         SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
-        if (!IsWindow( hwnd )) return wasVisible;
+        if (!IsWindow( hwnd )) goto END;
     }
 
     if ((wndPtr->dwStyle & WS_CHILD) &&
         !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
         (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
     {
-        /* Don't call SetWindowPos32() on invisible child windows */
+        /* Don't call SetWindowPos() on invisible child windows */
         if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
         else wndPtr->dwStyle |= WS_VISIBLE;
     }
@@ -1257,7 +1332,7 @@
         if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
         SetWindowPos( hwnd, HWND_TOP, 
 			newPos.left, newPos.top, newPos.right, newPos.bottom, swp );
-        if (!IsWindow( hwnd )) return wasVisible;
+        if (!IsWindow( hwnd )) goto END;
 	else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
     }
 
@@ -1276,6 +1351,8 @@
 		   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
     }
 
+END:
+    WIN_ReleaseWndPtr(wndPtr);
     return wasVisible;
 }
 
@@ -1298,7 +1375,7 @@
 
 
 /***********************************************************************
- *           GetInternalWindowPos32   (USER32.245)
+ *           GetInternalWindowPos   (USER32.245)
  */
 UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
                                       LPPOINT ptIcon )
@@ -1319,9 +1396,11 @@
 BOOL16 WINAPI GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
 {
     WND *pWnd = WIN_FindWndPtr( hwnd );
-    if( pWnd )
-    {
-	LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
+    LPINTERNALPOS lpPos;
+    
+    if(!pWnd ) return FALSE;
+
+    lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
 			     *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
 	wndpl->length  = sizeof(*wndpl);
 	if( pWnd->dwStyle & WS_MINIMIZE )
@@ -1336,14 +1415,14 @@
 	wndpl->ptMinPosition = lpPos->ptIconPos;
 	wndpl->ptMaxPosition = lpPos->ptMaxPos;
 	wndpl->rcNormalPosition = lpPos->rectNormal;
+
+    WIN_ReleaseWndPtr(pWnd);
 	return TRUE;
     }
-    return FALSE;
-}
 
 
 /***********************************************************************
- *           GetWindowPlacement32   (USER32.307)
+ *           GetWindowPlacement   (USER32.307)
  *
  * Win95:
  * Fails if wndpl->length of Win95 (!) apps is invalid.
@@ -1412,6 +1491,7 @@
 	    /* SDK: ...valid only the next time... */
 	    if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
 	}
+        WIN_ReleaseWndPtr(pWnd);
 	return TRUE;
     }
     return FALSE;
@@ -1428,7 +1508,7 @@
 }
 
 /***********************************************************************
- *           SetWindowPlacement32   (USER32.519)
+ *           SetWindowPlacement   (USER32.519)
  *
  * Win95:
  * Fails if wndpl->length of Win95 (!) apps is invalid.
@@ -1482,7 +1562,7 @@
 
 
 /***********************************************************************
- *           SetInternalWindowPos32   (USER32.483)
+ *           SetInternalWindowPos   (USER32.483)
  */
 void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
                                     LPRECT rect, LPPOINT pt )
@@ -1521,7 +1601,7 @@
 BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
 {
     CBTACTIVATESTRUCT16* cbtStruct;
-    WND*     wndPtr, *wndTemp;
+    WND*     wndPtr=0, *wndTemp;
     HQUEUE16 hOldActiveQueue, hNewActiveQueue;
     MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
     WORD     wIconized = 0;
@@ -1539,7 +1619,7 @@
     /* paranoid checks */
     if( hWnd == GetDesktopWindow() || hWnd == hwndActive ) goto CLEANUP;
 
-/*  if (wndPtr && (GetFastQueue() != wndPtr->hmemTaskQ))
+/*  if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
  *	return 0;
  */
     wndPtr = WIN_FindWndPtr(hWnd);
@@ -1549,7 +1629,7 @@
 	wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
     else
 	TRACE(win,"no current active window.\n");
-
+    WIN_ReleaseWndPtr(wndTemp);
     /* call CBT hook chain */
     if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
     {
@@ -1584,7 +1664,7 @@
                         MAKEWPARAM( WA_INACTIVE, wIconized ),
                         (LPARAM)hWnd );
 #else
-	/* FIXME: must be SendMessage16() because 32A doesn't do
+	/* FIXME: must be SendMessage16() because A doesn't do
 	 * intertask at this time */
 	SendMessage16( hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
 				MAKELPARAM( (HWND16)hWnd, wIconized ) );
@@ -1593,9 +1673,6 @@
         /* check if something happened during message processing
          * (global active queue may have changed)
          */
-	if (hActiveQueue==0)
-	  goto CLEANUP;
-
         pTempActiveQueue = QUEUE_Lock( hActiveQueue );
         hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
         QUEUE_Unlock( pTempActiveQueue );
@@ -1623,8 +1700,12 @@
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
     {
 	/* check Z-order and bring hWnd to the top */
-	for (wndTemp = WIN_GetDesktop()->child; wndTemp; wndTemp = wndTemp->next)
+	for (wndTemp = WIN_LockWndPtr(WIN_GetDesktop()->child); wndTemp; WIN_UpdateWndPtr(&wndTemp,wndTemp->next))
+        {
 	    if (wndTemp->dwStyle & WS_VISIBLE) break;
+        }
+        WIN_ReleaseDesktop();
+        WIN_ReleaseWndPtr(wndTemp);
 
 	if( wndTemp != wndPtr )
 	    SetWindowPos(hWnd, HWND_TOP, 0,0,0,0, 
@@ -1639,9 +1720,9 @@
     if (hOldActiveQueue != hNewActiveQueue)
     {
         WND **list, **ppWnd;
+        WND *pDesktop = WIN_GetDesktop();
 
-        if ( (hNewActiveQueue!=0) && 
-	     (list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
+        if ((list = WIN_BuildWinArray( pDesktop, 0, NULL )))
         {
             for (ppWnd = list; *ppWnd; ppWnd++)
             {
@@ -1651,13 +1732,12 @@
                    SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
                                    0, QUEUE_GetQueueTask(hNewActiveQueue) );
             }
-            HeapFree( SystemHeap, 0, list );
+            WIN_ReleaseWinArray(list);
         }
 
 	hActiveQueue = hNewActiveQueue;
 
-        if ( (hOldActiveQueue!=0) &&
-	     (list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
+        if ((list = WIN_BuildWinArray(pDesktop, 0, NULL )))
         {
             for (ppWnd = list; *ppWnd; ppWnd++)
             {
@@ -1667,8 +1747,9 @@
                    SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
                                   1, QUEUE_GetQueueTask( hOldActiveQueue ) );
             }
-            HeapFree( SystemHeap, 0, list );
+            WIN_ReleaseWinArray(list);
         }
+        WIN_ReleaseDesktop();
         
 	if (!IsWindow(hWnd)) goto CLEANUP;
     }
@@ -1676,8 +1757,11 @@
     if (hWnd)
     {
         /* walk up to the first unowned window */
-        wndTemp = wndPtr;
-        while (wndTemp->owner) wndTemp = wndTemp->owner;
+        wndTemp = WIN_LockWndPtr(wndPtr);
+        while (wndTemp->owner)
+        {
+            WIN_UpdateWndPtr(&wndTemp,wndTemp->owner);
+        }
         /* and set last active owned popup */
         wndTemp->hwndLastActive = hWnd;
 
@@ -1719,6 +1803,7 @@
         QUEUE_Unlock( pOldActiveQueue );
     if ( pNewActiveQueue )
         QUEUE_Unlock( pNewActiveQueue );
+    WIN_ReleaseWndPtr(wndPtr);
     return bRet ? (hWnd == hwndActive) : 0;
 }
 
@@ -1761,17 +1846,24 @@
       while( !WINPOS_CanActivate(pWndTo) ) 
       {
 	 /* by now owned windows should've been taken care of */
-
-	  pWndTo = pWndPtr->next;
-	  pWndPtr = pWndTo;
+          WIN_ReleaseWndPtr(pWndTo);
+          pWndTo = WIN_LockWndPtr(pWndPtr->next);
+          WIN_ReleaseWndPtr(pWndPtr);
+	  pWndPtr = WIN_LockWndPtr(pWndTo);
 	  if( !pWndTo ) break;
       }
+      WIN_ReleaseWndPtr(pWndPtr);
   }
 
   bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
 
   /* switch desktop queue to current active */
-  if( pWndTo ) WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
+  if( pWndTo )
+  {
+      WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
+      WIN_ReleaseWndPtr(pWndTo);
+      WIN_ReleaseDesktop();
+  }
 
   hwndPrevActive = 0;
   return bRet;  
@@ -1784,8 +1876,12 @@
 BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
 {
     WND *wndPtr = WIN_FindWndPtr(hWnd);
+    WND *wndTemp;
+    BOOL retvalue;
     HWND hwndActive = 0;
 
+    if( !wndPtr ) return FALSE;
+
     /* Get current active window from the active queue */
     if ( hActiveQueue )
     {
@@ -1797,33 +1893,56 @@
         }
     }
 
-    if (!hWnd) return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
+    if (!hWnd)
+    {
+        retvalue = WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
+        goto end;
+    }
 
-    if( !wndPtr ) return FALSE;
 
     /* child windows get WM_CHILDACTIVATE message */
     if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
-	return SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
+    {
+        retvalue = SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
+        goto end;
+    }
 
         /* owned popups imply owner activation - not sure */
     if ((wndPtr->dwStyle & WS_POPUP) && wndPtr->owner &&
         (wndPtr->owner->dwStyle & WS_VISIBLE ) &&
         !(wndPtr->owner->dwStyle & WS_DISABLED ))
     {
-        if (!(wndPtr = wndPtr->owner)) return FALSE;
+        WIN_UpdateWndPtr(&wndPtr,wndPtr->owner);
+        if (!wndPtr)
+    {
+            retvalue = FALSE;
+            goto end;
+        }
 	hWnd = wndPtr->hwndSelf;
     }
 
-    if( hWnd == hwndActive ) return FALSE;
+    if( hWnd == hwndActive )
+    {
+        retvalue = FALSE;
+        goto end;
+    }
 
     if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
-	return FALSE;
+    {
+        retvalue = FALSE;
+        goto end;
+    }
 
     /* switch desktop queue to current active */
-    if( wndPtr->parent == WIN_GetDesktop())
-        WIN_GetDesktop()->hmemTaskQ = wndPtr->hmemTaskQ;
+    wndTemp = WIN_GetDesktop();
+    if( wndPtr->parent == wndTemp)
+        wndTemp->hmemTaskQ = wndPtr->hmemTaskQ;
+    WIN_ReleaseDesktop();
 
-    return TRUE;
+    retvalue = TRUE;
+end:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 
@@ -1888,7 +2007,7 @@
 
 
 /***********************************************************************
- *           WINPOS_HandleWindowPosChanging32
+ *           WINPOS_HandleWindowPosChanging
  *
  * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
  */
@@ -1931,27 +2050,35 @@
     }
     else if (hwndAfter == HWND_BOTTOM)
     {
-        if (!wndPtr->next) return;  /* Already at the bottom */
+        if (!wndPtr->next) goto END;  /* Already at the bottom */
         movingUp = FALSE;
     }
     else
     {
-        if (!(pWndAfter = WIN_FindWndPtr( hwndAfter ))) return;
-        if (wndPtr->next == pWndAfter) return;  /* Already placed right */
+        if (!(pWndAfter = WIN_FindWndPtr( hwndAfter ))) goto END;
+        if (wndPtr->next == pWndAfter)
+    {
+            WIN_ReleaseWndPtr(pWndAfter);
+            goto END;  /* Already placed right */
+        }
 
           /* Determine which window we encounter first in Z-order */
-        pWndCur = wndPtr->parent->child;
+        pWndCur = WIN_LockWndPtr(wndPtr->parent->child);
         while ((pWndCur != wndPtr) && (pWndCur != pWndAfter))
-            pWndCur = pWndCur->next;
+        {
+            WIN_UpdateWndPtr(&pWndCur,pWndCur->next);
+        }
         movingUp = (pWndCur == pWndAfter);
+        WIN_ReleaseWndPtr(pWndCur);
+        WIN_ReleaseWndPtr(pWndAfter);
     }
 
     if (movingUp)
     {
-        WND *pWndPrevAfter = wndPtr->next;
+        WND *pWndPrevAfter = WIN_LockWndPtr(wndPtr->next);
         WIN_UnlinkWindow( hwnd );
         WIN_LinkWindow( hwnd, hwndAfter );
-        pWndCur = wndPtr->next;
+        pWndCur = WIN_LockWndPtr(wndPtr->next);
         while (pWndCur != pWndPrevAfter)
         {
             RECT rect = { pWndCur->rectWindow.left,
@@ -1962,12 +2089,13 @@
                           -wndPtr->rectClient.top );
             PAINT_RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
                               RDW_FRAME | RDW_ERASE, 0 );
-            pWndCur = pWndCur->next;
+            WIN_UpdateWndPtr(&pWndCur,pWndCur->next);
         }
+        WIN_ReleaseWndPtr(pWndPrevAfter);
     }
     else  /* Moving down */
     {
-        pWndCur = wndPtr->next;
+        pWndCur = WIN_LockWndPtr(wndPtr->next);
         WIN_UnlinkWindow( hwnd );
         WIN_LinkWindow( hwnd, hwndAfter );
         while (pWndCur != wndPtr)
@@ -1980,9 +2108,11 @@
                           -pWndCur->rectClient.top );
             PAINT_RedrawWindow( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
                               RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
-            pWndCur = pWndCur->next;
+            WIN_UpdateWndPtr(&pWndCur,pWndCur->next);
         }
     }
+END:
+    WIN_ReleaseWndPtr(wndPtr);
 }
 
 /***********************************************************************
@@ -1993,7 +2123,8 @@
  */
 HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter,WND* wndPtr,WORD flags)
 {
- WND* 	w = WIN_GetDesktop()->child;
+ WND*   pDesktop = WIN_GetDesktop();
+ WND* 	w = WIN_LockWndPtr(pDesktop->child);
 
   if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner )
   {
@@ -2007,15 +2138,17 @@
 	{
           if (w != wndPtr) hwndLocalPrev = w->hwndSelf;
 	  if( hwndLocalPrev == hwndInsertAfter ) break;
-	  w = w->next;
+          WIN_UpdateWndPtr(&w,w->next);
 	}
 	hwndInsertAfter = hwndLocalPrev;
      }
 
   }
-  else if( wndPtr->dwStyle & WS_CHILD ) return hwndInsertAfter;
+  else if( wndPtr->dwStyle & WS_CHILD )
+      goto END;
 
-  w = WIN_GetDesktop()->child;
+  WIN_UpdateWndPtr(&w,pDesktop->child);
+
   while( w )
   {
     if( w == wndPtr ) break;
@@ -2026,9 +2159,12 @@
                      SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
       hwndInsertAfter = w->hwndSelf;
     }
-    w = w->next;
+    WIN_UpdateWndPtr(&w,w->next);
   }
 
+END:
+  WIN_ReleaseWndPtr(w);
+  WIN_ReleaseDesktop();
   return hwndInsertAfter;
 }
 
@@ -2174,7 +2310,7 @@
 }
 
 /***********************************************************************
- *           SetWindowPos   (USER.232)
+ *           SetWindowPos   (USER.2)
  */
 BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
                               INT16 x, INT16 y, INT16 cx, INT16 cy, WORD flags)
@@ -2189,13 +2325,13 @@
                               INT x, INT y, INT cx, INT cy, WORD flags)
 {
     WINDOWPOS winpos;
-    WND *	wndPtr;
+    WND *	wndPtr,*wndTemp;
     RECT 	newWindowRect, newClientRect, oldWindowRect;
     HRGN	visRgn = 0;
     HWND	tempInsertAfter= 0;
     int 	result = 0;
     UINT 	uFlags = 0;
-    BOOL      resync = FALSE;
+    BOOL      resync = FALSE,retvalue;
     HWND      hwndActive = 0;
 
     /* Get current active window from the active queue */
@@ -2264,9 +2400,15 @@
 	 WND* wnd = WIN_FindWndPtr(hwndInsertAfter);
 
 	 if( wnd ) {
-	   if( wnd->parent != wndPtr->parent ) return FALSE;
+             if( wnd->parent != wndPtr->parent )
+             {
+                 retvalue = FALSE;
+                 WIN_ReleaseWndPtr(wnd);
+                 goto END;
+             }
 	   if( wnd->next == wndPtr ) flags |= SWP_NOZORDER;
 	 }
+         WIN_ReleaseWndPtr(wnd);
        }
     else if (!X11DRV_WND_GetXWindow(wndPtr))
     {
@@ -2323,8 +2465,12 @@
 	/* reorder owned popups if hwnd is top-level window 
          */
 	if( wndPtr->parent == WIN_GetDesktop() )
+        {
 	    hwndInsertAfter = WINPOS_ReorderOwnedPopups( hwndInsertAfter,
 							 wndPtr, winpos.flags );
+        }
+        WIN_ReleaseDesktop();
+        
         if (X11DRV_WND_GetXWindow(wndPtr))
 
         {
@@ -2507,6 +2653,7 @@
 		    WND *pFocus = WIN_FindWndPtr( focus );
 		    if (pFocus)
 			pFocus->pDriver->pSetFocus(pFocus);
+                    WIN_ReleaseWndPtr(pFocus);
 		    break;
 		}
 		curr = GetParent(curr);
@@ -2563,10 +2710,14 @@
     if (!GetCapture() && ((wndPtr->dwStyle & WS_VISIBLE) || (flags & SWP_HIDEWINDOW)))
         EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
 
+    wndTemp = WIN_GetDesktop();
     if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
         PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
-    else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
+    else if( wndPtr->parent == wndTemp && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
+    {
 	PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
+    }
+    WIN_ReleaseDesktop();
 
       /* And last, send the WM_WINDOWPOSCHANGED message */
 
@@ -2580,7 +2731,10 @@
         if (resync) EVENT_Synchronize ();
     }
 
-    return TRUE;
+    retvalue = TRUE;
+END:
+    WIN_ReleaseWndPtr(wndPtr);
+    return retvalue;
 }
 
 					
@@ -2594,7 +2748,7 @@
 
 
 /***********************************************************************
- *           BeginDeferWindowPos32   (USER32.9)
+ *           BeginDeferWindowPos   (USER32.9)
  */
 HDWP WINAPI BeginDeferWindowPos( INT count )
 {
@@ -2627,7 +2781,7 @@
 
 
 /***********************************************************************
- *           DeferWindowPos32   (USER32.128)
+ *           DeferWindowPos   (USER32.128)
  */
 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
                                 INT x, INT y, INT cx, INT cy,
@@ -2635,8 +2789,8 @@
 {
     DWP *pDWP;
     int i;
-    HDWP newhdwp = hdwp;
-    /* HWND32 parent; */
+    HDWP newhdwp = hdwp,retvalue;
+    /* HWND parent; */
     WND *pWnd;
 
     pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
@@ -2659,7 +2813,8 @@
     else if (parent != pDWP->hwndParent)
     {
         USER_HEAP_FREE( hdwp );
-        return 0;
+        retvalue = 0;
+        goto END;
     }
 #endif
 
@@ -2688,14 +2843,19 @@
                                                SWP_NOOWNERZORDER);
             pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
                                               SWP_FRAMECHANGED);
-            return hdwp;
+            retvalue = hdwp;
+            goto END;
         }
     }
     if (pDWP->actualCount >= pDWP->suggestedCount)
     {
         newhdwp = USER_HEAP_REALLOC( hdwp,
                       sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
-        if (!newhdwp) return 0;
+        if (!newhdwp)
+        {
+            retvalue = 0;
+            goto END;
+        }
         pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
         pDWP->suggestedCount++;
     }
@@ -2707,7 +2867,10 @@
     pDWP->winPos[pDWP->actualCount].cy = cy;
     pDWP->winPos[pDWP->actualCount].flags = flags;
     pDWP->actualCount++;
-    return newhdwp;
+    retvalue = newhdwp;
+END:
+    WIN_ReleaseWndPtr(pWnd);
+    return retvalue;
 }
 
 
@@ -2721,7 +2884,7 @@
 
 
 /***********************************************************************
- *           EndDeferWindowPos32   (USER32.173)
+ *           EndDeferWindowPos   (USER32.173)
  */
 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
 {
diff --git a/windows/winproc.c b/windows/winproc.c
index d26886c..2541d22 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -391,9 +391,13 @@
  * Return TRUE if the lparam is a string
  */
 BOOL WINPROC_TestCBForStr ( HWND hwnd )
-{	WND * wnd = WIN_FindWndPtr(hwnd); 
-	return ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
+{
+    BOOL retvalue;
+    WND * wnd = WIN_FindWndPtr(hwnd);
+    retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
 	      (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
+    WIN_ReleaseWndPtr(wnd);
+    return retvalue;
 }
 /**********************************************************************
  *	     WINPROC_TestLBForStr
@@ -401,9 +405,14 @@
  * Return TRUE if the lparam is a string
  */
 BOOL WINPROC_TestLBForStr ( HWND hwnd )
-{	WND * wnd = WIN_FindWndPtr(hwnd); 
-	return ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || 
+{
+    BOOL retvalue;
+    WND * wnd = WIN_FindWndPtr(hwnd); 
+    retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
 	    (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
+    WIN_ReleaseWndPtr(wnd);
+    return retvalue;
+
 }
 /**********************************************************************
  *	     WINPROC_MapMsg32ATo32W
@@ -1681,8 +1690,10 @@
         *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
         return 0;
     case WM_MDIACTIVATE:
-	if( WIDGETS_IsControl(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
 	{
+            WND *tempWnd = WIN_FindWndPtr(hwnd);
+            if( WIDGETS_IsControl(tempWnd, BIC32_MDICLIENT) )
+            {
 	    *pwparam16 = (HWND)wParam32;
 	    *plparam = 0;
 	}
@@ -1692,6 +1703,8 @@
 	    *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
 				   (HWND16)LOWORD(wParam32) );
 	}
+            WIN_ReleaseWndPtr(tempWnd);
+        }
         return 0;
     case WM_NCCALCSIZE:
         {
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 884bd67..9e7d136 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -208,9 +208,8 @@
     if( !selectionAcquired && 
 	(wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
     {
-	owner = X11DRV_WND_FindXWindow( 
-	    WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup() ) 
-	);
+        WND *tmpWnd = WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup() );
+	owner = X11DRV_WND_FindXWindow(tmpWnd );
 
 	TSXSetSelectionOwner(display,XA_PRIMARY, owner, CurrentTime);
 	if( TSXGetSelectionOwner(display,XA_PRIMARY) == owner )
@@ -221,6 +220,7 @@
 	    TRACE(clipboard,"Grabbed X selection, owner=(%08x)\n", 
 						(unsigned) owner);
 	}
+        WIN_ReleaseWndPtr(tmpWnd);
     }
 }
 
@@ -230,6 +230,7 @@
 BOOL X11DRV_CLIPBOARD_RequestSelection()
 {
     HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
+    WND *tmpWnd = WIN_FindWndPtr(hWnd);
 
     if( selectionAcquired )
       return TRUE;
@@ -244,8 +245,10 @@
 
     TSXConvertSelection(display, XA_PRIMARY, XA_STRING,
 			TSXInternAtom(display, "PRIMARY_TEXT", False),
-			X11DRV_WND_FindXWindow( WIN_FindWndPtr( hWnd ) ),
+			X11DRV_WND_FindXWindow(tmpWnd ),
 			CurrentTime);
+    
+    WIN_ReleaseWndPtr(tmpWnd);
 
   /* wait until SelectionNotify is processed 
    *
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 46d9607..3e38071 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -1205,6 +1205,8 @@
       if( p_data ) TSXFree(p_data);  
       
     } /* WS_EX_ACCEPTFILES */
+
+  WIN_ReleaseWndPtr(pDropWnd);
 }
 
 /**********************************************************************
@@ -1349,6 +1351,7 @@
 			 (WPARAM16)hDrop.h16, 0L );
 	}
       }
+      WIN_ReleaseWndPtr(pDropWnd);
     }
     if( p_data ) TSXFree(p_data);  
   }
@@ -1413,9 +1416,11 @@
 void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
 {
   HWND hwndFocus = GetFocus();
+  WND *tmpWnd = WIN_FindWndPtr(hwndFocus);
   
   if (hwndFocus && IsChild( hWnd, hwndFocus ))
-    X11DRV_WND_SetFocus( WIN_FindWndPtr( hwndFocus ) );
+      X11DRV_WND_SetFocus(tmpWnd );
+  WIN_ReleaseWndPtr(tmpWnd);
   
   return;
 }
diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c
index 66c55eb..7eb8f7f 100644
--- a/windows/x11drv/mouse.c
+++ b/windows/x11drv/mouse.c
@@ -154,12 +154,15 @@
         HWND hwnd = GetWindow( GetDesktopWindow(), GW_CHILD );
         while(hwnd)
         {
-            Window win = X11DRV_WND_FindXWindow( WIN_FindWndPtr( hwnd ) );
+            WND *tmpWnd = WIN_FindWndPtr(hwnd);
+            Window win = X11DRV_WND_FindXWindow(tmpWnd );
             if (win && win!=DefaultRootWindow(display))
                 XDefineCursor( display, win, cursor );
             hwnd = GetWindow( hwnd, GW_HWNDNEXT );
+            WIN_ReleaseWndPtr(tmpWnd);
         }
     }
+    WIN_ReleaseDesktop();
     return TRUE;
 }
 
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index a1d9d0d..a6485bd 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -234,8 +234,10 @@
       
       if (cs->hwndParent)  /* Get window owner */
 	{
-	  Window win = X11DRV_WND_FindXWindow( WIN_FindWndPtr( cs->hwndParent ) );
+          WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
+	  Window win = X11DRV_WND_FindXWindow( tmpWnd );
 	  if (win) TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), win );
+          WIN_ReleaseWndPtr(tmpWnd);
 	}
       X11DRV_WND_RegisterWindow( wndPtr );
     }
@@ -264,7 +266,9 @@
  */
 WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
 {
-    if( wndPtr && pWndParent && (wndPtr != WIN_GetDesktop()) )
+    WND *pDesktop = WIN_GetDesktop();
+    
+    if( wndPtr && pWndParent && (wndPtr != pDesktop) )
     {
 	WND* pWndPrev = wndPtr->parent;
 
@@ -284,7 +288,7 @@
             /* Create an X counterpart for reparented top-level windows
 	     * when not in the desktop mode. */
 
-            if( pWndParent == WIN_GetDesktop () )
+            if( pWndParent == pDesktop )
             {
                 wndPtr->dwStyle &= ~WS_CHILD;
                 wndPtr->wIDmenu = 0;
@@ -325,8 +329,10 @@
             }
 	    WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
 	}
+        WIN_ReleaseDesktop();
 	return pWndPrev;
     } /* failure */
+    WIN_ReleaseDesktop();
     return 0;
 }
 
@@ -339,7 +345,7 @@
 void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
 {
   XWindowChanges winChanges;
-  WND *wndPrev;
+  WND *wndPrev,*pDesktop = WIN_GetDesktop();
   
   if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->flags & WIN_MANAGED) )
     return;
@@ -354,11 +360,12 @@
       if (X11DRV_WND_GetXWindow(wndPtr)) 
 	TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(wndPtr), 0,
 				CWStackMode, &winChanges );
-      wndPrev = WIN_GetDesktop()->child;
+      wndPrev = pDesktop->child;
       if (wndPrev == wndPtr) break;
       while (wndPrev && (wndPrev->next != wndPtr)) wndPrev = wndPrev->next;
       wndPtr = wndPrev;
     }
+  WIN_ReleaseDesktop();
 }
 
 /***********************************************************************
@@ -460,6 +467,8 @@
 	      
 	      TSXRestackWindows(display, stack, 2); 
 	      changeMask &= ~CWStackMode;
+              
+              WIN_ReleaseWndPtr(insertPtr);
 	    }
 	}
       if (changeMask)
@@ -472,6 +481,7 @@
     {
       if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
     }
+  WIN_ReleaseWndPtr(winposPtr);
 }
 
 /*****************************************************************