- Update KTHREAD and KUSER_SHARED_DATA to latest versions. This should make 2K3 drive...
[reactos.git] / reactos / subsys / win32k / ntuser / window.c
index e04c0cf..7afc46f 100644 (file)
 
 #include <w32k.h>
 
+#define NDEBUG
+#include <debug.h>
+
 static WndProcHandle *WndProcHandlesArray = 0;
 static WORD WndProcHandlesArraySize = 0;
 #define WPH_SIZE 0x40 /* the size to add to the WndProcHandle array each time */
 
 /* dialog resources appear to pass this in 16 bits, handle them properly */
-#define CW_USEDEFAULT16        (0x8000)
+#define CW_USEDEFAULT16 (0x8000)
 
 #define POINT_IN_RECT(p, r) (((r.bottom >= p.y) && (r.top <= p.y))&&((r.left <= p.x )&&( r.right >= p.x )))
 
@@ -72,20 +75,60 @@ CleanupWindowImpl(VOID)
 
 /* HELPER FUNCTIONS ***********************************************************/
 
+
+PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
+{
+   PWINDOW_OBJECT Window;
+   
+   if (!hWnd) return NULL;
+
+   Window = UserGetWindowObject(hWnd);
+   if (Window)
+   {
+      ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+
+      USER_BODY_TO_HEADER(Window)->RefCount++;
+   }
+   return Window;
+}
+
+/* temp hack */
+PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
+{
+   PWINDOW_OBJECT Window;
+   
+   if (!hWnd)
+   { 
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      return NULL;
+   }
+   
+   Window = (PWINDOW_OBJECT)UserGetObject(&gHandleTable, hWnd, otWindow);
+   if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
+   {
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      return NULL;
+   }
+
+   ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+   return Window;
+}
+
+
 /*
  * IntIsWindow
  *
  * The function determines whether the specified window handle identifies
- * an existing window. 
+ * an existing window.
  *
  * Parameters
- *    hWnd 
- *       Handle to the window to test. 
+ *    hWnd
+ *       Handle to the window to test.
  *
  * Return Value
  *    If the window handle identifies an existing window, the return value
  *    is TRUE. If the window handle does not identify an existing window,
- *    the return value is FALSE. 
+ *    the return value is FALSE.
  */
 
 BOOL FASTCALL
@@ -93,83 +136,49 @@ IntIsWindow(HWND hWnd)
 {
    PWINDOW_OBJECT Window;
 
-   if (!(Window = IntGetWindowObject(hWnd)))
+   if (!(Window = UserGetWindowObject(hWnd)))
       return FALSE;
-   
-   IntReleaseWindowObject(Window);
+
    return TRUE;
 }
 
-/*
- * IntGetProcessWindowObject
- *
- * Get window object from handle of specified process.
- */
 
+
+/* 
+  Caller must NOT dereference retval!
+  But if caller want the returned value to persist spanning a co_ call,
+  it must reference the value (because the owner is not garanteed to
+  exist just because the owned window exist)!
+*/
 PWINDOW_OBJECT FASTCALL
-IntGetProcessWindowObject(PW32THREAD Thread, HWND hWnd)
+IntGetParent(PWINDOW_OBJECT Wnd)
 {
-   PWINDOW_OBJECT WindowObject;
-   NTSTATUS Status;
-   
-   if(Thread->Desktop != NULL)
+   if (Wnd->Style & WS_POPUP)
    {
-     Status = ObmReferenceObjectByHandle(Thread->Desktop->WindowStation->HandleTable,
-                                         hWnd, otWindow, (PVOID*)&WindowObject);
-     if (NT_SUCCESS(Status))
-     {
-        return WindowObject;
-     }
+      return UserGetWindowObject(Wnd->hOwner);
    }
+   else if (Wnd->Style & WS_CHILD)
+   {
+      return Wnd->Parent;
+   }
+
    return NULL;
 }
 
 
-PWINDOW_OBJECT FASTCALL
-IntGetParent(PWINDOW_OBJECT Wnd)
-{
-  HWND hWnd;
-  
-  if (Wnd->Style & WS_POPUP)
-  {
-    IntLockRelatives(Wnd);
-    hWnd = Wnd->Owner;
-    IntUnLockRelatives(Wnd);
-    return IntGetWindowObject(hWnd);
-  }
-  else if (Wnd->Style & WS_CHILD) 
-  {
-    IntLockRelatives(Wnd);
-    hWnd = Wnd->Parent;
-    IntUnLockRelatives(Wnd);
-    return IntGetWindowObject(hWnd);
-  }
-
-  return NULL;
-}
-
+/* 
+  Caller must NOT dereference retval!
+  But if caller want the returned value to persist spanning a co_ call,
+  it must reference the value (because the owner is not garanteed to
+  exist just because the owned window exist)!
+*/
 PWINDOW_OBJECT FASTCALL
 IntGetOwner(PWINDOW_OBJECT Wnd)
 {
-  HWND hWnd;
-
-  IntLockRelatives(Wnd);
-  hWnd = Wnd->Owner;
-  IntUnLockRelatives(Wnd);
-
-  return IntGetWindowObject(hWnd);
+   return UserGetWindowObject(Wnd->hOwner);
 }
 
-PWINDOW_OBJECT FASTCALL
-IntGetParentObject(PWINDOW_OBJECT Wnd)
-{
-  HWND hParent;
-  
-  IntLockRelatives(Wnd);
-  hParent = Wnd->Parent;
-  IntUnLockRelatives(Wnd);
-  return IntGetWindowObject(hParent);
-}
+
 
 /*
  * IntWinListChildren
@@ -188,98 +197,96 @@ IntWinListChildren(PWINDOW_OBJECT Window)
    HWND *List;
    UINT Index, NumChildren = 0;
 
-   IntLockRelatives(Window);
-
    for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
       ++NumChildren;
-  
+
    List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
    if(!List)
    {
-     DPRINT1("Failed to allocate memory for children array\n");
-     IntUnLockRelatives(Window);
-     SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-     return NULL;
+      DPRINT1("Failed to allocate memory for children array\n");
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
    }
    for (Child = Window->FirstChild, Index = 0;
-        Child != NULL;
-        Child = Child->NextSibling, ++Index)
-      List[Index] = Child->Self;
+         Child != NULL;
+         Child = Child->NextSibling, ++Index)
+      List[Index] = Child->hSelf;
    List[Index] = NULL;
 
-   IntUnLockRelatives(Window);
-
    return List;
 }
 
 /***********************************************************************
  *           IntSendDestroyMsg
  */
-static void IntSendDestroyMsg(HWND Wnd)
+static void IntSendDestroyMsg(HWND hWnd)
 {
 
-  PWINDOW_OBJECT Window, Owner, Parent;
+   PWINDOW_OBJECT Window;
 #if 0 /* FIXME */
-  GUITHREADINFO info;
-
-  if (GetGUIThreadInfo(GetCurrentThreadId(), &info))
-    {
-      if (Wnd == info.hwndCaret)
-       {
-         DestroyCaret();
-       }
-    }
+
+   GUITHREADINFO info;
+
+   if (GetGUIThreadInfo(GetCurrentThreadId(), &info))
+   {
+      if (hWnd == info.hwndCaret)
+      {
+         DestroyCaret();
+      }
+   }
 #endif
 
-  Window = IntGetWindowObject(Wnd);
-  if (Window) {
-    Owner = IntGetOwner(Window);
-    if (!Owner) {
-      Parent = IntGetParent(Window);
-      if (!Parent) 
-        IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) Wnd);
-      else
-        IntReleaseWindowObject(Parent);
-    } else {
-      IntReleaseWindowObject(Owner);
-    }
+   Window = UserGetWindowObject(hWnd);
+   if (Window)
+   {
+//      USER_REFERENCE_ENTRY Ref;
+//      UserRefObjectCo(Window, &Ref);
+      
+      if (!IntGetOwner(Window) && !IntGetParent(Window))
+      {
+         co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd);
+      }
 
-    IntReleaseWindowObject(Window);
-  }
+//      UserDerefObjectCo(Window);
+   }
 
-  /* The window could already be destroyed here */
+   /* The window could already be destroyed here */
 
-  /*
-   * Send the WM_DESTROY to the window.
-   */
+   /*
+    * Send the WM_DESTROY to the window.
+    */
 
-  IntSendMessage(Wnd, WM_DESTROY, 0, 0);
+   co_IntSendMessage(hWnd, WM_DESTROY, 0, 0);
 
-  /*
-   * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
-   * make sure that the window still exists when we come back.
-   */
+   /*
+    * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
+    * make sure that the window still exists when we come back.
+    */
 #if 0 /* FIXME */
-  if (IsWindow(Wnd))
-    {
+
+   if (IsWindow(Wnd))
+   {
       HWND* pWndArray;
       int i;
 
-      if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
+      if (!(pWndArray = WIN_ListChildren( hwnd )))
+         return;
 
       /* start from the end (FIXME: is this needed?) */
-      for (i = 0; pWndArray[i]; i++) ;
+      for (i = 0; pWndArray[i]; i++)
+         ;
 
       while (--i >= 0)
-       {
-         if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
-       }
+      {
+         if (IsWindow( pWndArray[i] ))
+            WIN_SendDestroyMsg( pWndArray[i] );
+      }
       HeapFree(GetProcessHeap(), 0, pWndArray);
-    }
-  else
-    {
+   }
+   else
+   {
       DPRINT("destroyed itself while in WM_DESTROY!\n");
-    }
+   }
 #endif
 }
 
@@ -287,269 +294,270 @@ static void IntSendDestroyMsg(HWND Wnd)
  *           IntDestroyWindow
  *
  * Destroy storage associated to a window. "Internals" p.358
+ *
+ * This is the "functional" DestroyWindows function ei. all stuff
+ * done in CreateWindow is undone here and not in DestroyWindow:-P
+  
  */
-static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
-                                PW32PROCESS ProcessData,
-                                PW32THREAD ThreadData,
-                                BOOLEAN SendMessages)
+static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
+                                   PW32PROCESS ProcessData,
+                                   PW32THREAD ThreadData,
+                                   BOOLEAN SendMessages)
 {
-  HWND *Children;
-  HWND *ChildHandle;
-  PWINDOW_OBJECT Child;
-  PMENU_OBJECT Menu;
-  BOOLEAN BelongsToThreadData;
-  
-  ASSERT(Window);
-  
-  IntLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-  if(Window->Status & WINDOWSTATUS_DESTROYING)
-  {
-    IntUnLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-    DPRINT("Tried to call IntDestroyWindow() twice\n");
-    return 0;
-  }
-  Window->Status |= WINDOWSTATUS_DESTROYING;
-  Window->Flags &= ~WS_VISIBLE;
-  /* remove the window already at this point from the thread window list so we
-     don't get into trouble when destroying the thread windows while we're still
-     in IntDestroyWindow() */
-  RemoveEntryList(&Window->ThreadListEntry);
-  IntUnLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-  
-  BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
+   HWND *Children;
+   HWND *ChildHandle;
+   PWINDOW_OBJECT Child;
+   PMENU_OBJECT Menu;
+   BOOLEAN BelongsToThreadData;
 
-  IntDeRegisterShellHookWindow(Window->Self);
-  
-  if(SendMessages)
-  {
-    /* Send destroy messages */
-    IntSendDestroyMsg(Window->Self);
-  }
-
-  /* free child windows */
-  Children = IntWinListChildren(Window);
-  if (Children)
-    {
+   ASSERT(Window);
+
+   if(Window->Status & WINDOWSTATUS_DESTROYING)
+   {
+      DPRINT("Tried to call IntDestroyWindow() twice\n");
+      return 0;
+   }
+   Window->Status |= WINDOWSTATUS_DESTROYING;
+   Window->Style &= ~WS_VISIBLE;
+   /* remove the window already at this point from the thread window list so we
+      don't get into trouble when destroying the thread windows while we're still
+      in IntDestroyWindow() */
+   RemoveEntryList(&Window->ThreadListEntry);
+
+   BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
+
+   IntDeRegisterShellHookWindow(Window->hSelf);
+
+   if(SendMessages)
+   {
+      /* Send destroy messages */
+      IntSendDestroyMsg(Window->hSelf);
+   }
+
+   /* free child windows */
+   Children = IntWinListChildren(Window);
+   if (Children)
+   {
       for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
-        {
-          if ((Child = IntGetWindowObject(*ChildHandle)))
+      {
+         if ((Child = IntGetWindowObject(*ChildHandle)))
+         {
+            if(!IntWndBelongsToThread(Child, ThreadData))
             {
-              if(!IntWndBelongsToThread(Child, ThreadData))
-              {
-                /* send WM_DESTROY messages to windows not belonging to the same thread */
-                IntSendDestroyMsg(Child->Self);
-              }
-              else
-                IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
-              IntReleaseWindowObject(Child);
+               /* send WM_DESTROY messages to windows not belonging to the same thread */
+               IntSendDestroyMsg(Child->hSelf);
             }
-        }
+            else
+               co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
+            
+            UserDerefObject(Child);
+         }
+      }
       ExFreePool(Children);
-    }
-
-  if(SendMessages)
-  {
-    /*
-     * Clear the update region to make sure no WM_PAINT messages will be
-     * generated for this window while processing the WM_NCDESTROY.
-     */
-    IntRedrawWindow(Window, NULL, 0,
-                    RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
-                    RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
-    if(BelongsToThreadData)
-      IntSendMessage(Window->Self, WM_NCDESTROY, 0, 0);
-  }
-  MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->Self);
-  
-  /* flush the message queue */
-  MsqRemoveWindowMessagesFromQueue(Window);
-  
-  /* from now on no messages can be sent to this window anymore */
-  IntLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-  Window->Status |= WINDOWSTATUS_DESTROYED;
-  /* don't remove the WINDOWSTATUS_DESTROYING bit */
-  IntUnLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-
-  /* reset shell window handles */
-  if(ThreadData->Desktop)
-  {
-    if (Window->Self == ThreadData->Desktop->WindowStation->ShellWindow)
-      ThreadData->Desktop->WindowStation->ShellWindow = NULL;
-
-    if (Window->Self == ThreadData->Desktop->WindowStation->ShellListView)
-      ThreadData->Desktop->WindowStation->ShellListView = NULL;
-  }
-  
-  /* Unregister hot keys */
-  UnregisterWindowHotKeys (Window);
+   }
 
-  /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
+   if(SendMessages)
+   {
+      /*
+       * Clear the update region to make sure no WM_PAINT messages will be
+       * generated for this window while processing the WM_NCDESTROY.
+       */
+      co_UserRedrawWindow(Window, NULL, 0,
+                          RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
+                          RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
+      if(BelongsToThreadData)
+         co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0);
+   }
+   MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf);
+
+   /* flush the message queue */
+   MsqRemoveWindowMessagesFromQueue(Window);
+
+   /* from now on no messages can be sent to this window anymore */
+   Window->Status |= WINDOWSTATUS_DESTROYED;
+   /* don't remove the WINDOWSTATUS_DESTROYING bit */
+
+   /* reset shell window handles */
+   if(ThreadData->Desktop)
+   {
+      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellWindow)
+         ThreadData->Desktop->WindowStation->ShellWindow = NULL;
+
+      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellListView)
+         ThreadData->Desktop->WindowStation->ShellListView = NULL;
+   }
+
+   /* Unregister hot keys */
+   UnregisterWindowHotKeys (Window);
+
+   /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
 
 #if 0 /* FIXME */
-  WinPosCheckInternalPos(Window->Self);
-  if (Window->Self == GetCapture())
-    {
+
+   WinPosCheckInternalPos(Window->hSelf);
+   if (Window->hSelf == GetCapture())
+   {
       ReleaseCapture();
-    }
+   }
 
-  /* free resources associated with the window */
-  TIMER_RemoveWindowTimers(Window->Self);
+   /* free resources associated with the window */
+   TIMER_RemoveWindowTimers(Window->hSelf);
 #endif
-  
-  if (!(Window->Style & WS_CHILD) && Window->IDMenu
-      && (Menu = IntGetMenuObject((HMENU)Window->IDMenu)))
-    {
-       IntDestroyMenuObject(Menu, TRUE, TRUE);
-       Window->IDMenu = 0;
-       IntReleaseMenuObject(Menu);
-    }
-  
-  if(Window->SystemMenu
-     && (Menu = IntGetMenuObject(Window->SystemMenu)))
-  {
-    IntDestroyMenuObject(Menu, TRUE, TRUE);
-    Window->SystemMenu = (HMENU)0;
-    IntReleaseMenuObject(Menu);
-  }
-  
-  DceFreeWindowDCE(Window);    /* Always do this to catch orphaned DCs */
+
+   if (!(Window->Style & WS_CHILD) && Window->IDMenu
+         && (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
+   {
+      IntDestroyMenuObject(Menu, TRUE, TRUE);
+      Window->IDMenu = 0;
+   }
+
+   if(Window->SystemMenu
+         && (Menu = UserGetMenuObject(Window->SystemMenu)))
+   {
+      IntDestroyMenuObject(Menu, TRUE, TRUE);
+      Window->SystemMenu = (HMENU)0;
+   }
+
+   DceFreeWindowDCE(Window);    /* Always do this to catch orphaned DCs */
 #if 0 /* FIXME */
-  WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
-  CLASS_RemoveWindow(Window->Class);
+
+   WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
+   CLASS_RemoveWindow(Window->Class);
 #endif
-  
-  IntUnlinkWindow(Window);
-  
-  IntReferenceWindowObject(Window);
-  ObmCloseHandle(ThreadData->Desktop->WindowStation->HandleTable, Window->Self);
-  
-  IntDestroyScrollBars(Window);
-  
-  /* remove the window from the class object */
-  IntLockClassWindows(Window->Class);
-  RemoveEntryList(&Window->ClassListEntry);
-  IntUnLockClassWindows(Window->Class);
-  
-  /* dereference the class */
-  ClassDereferenceObject(Window->Class);
-  Window->Class = NULL;
-  
-  if(Window->WindowRegion)
-  {
-    NtGdiDeleteObject(Window->WindowRegion);
-  }
-  
-  RtlFreeUnicodeString(&Window->WindowName);
-  
-  IntReleaseWindowObject(Window);
 
-  return 0;
+   IntUnlinkWindow(Window);
+
+   UserRefObject(Window);
+   ObmDeleteObject(Window->hSelf, otWindow);
+
+   IntDestroyScrollBars(Window);
+
+   /* dereference the class */
+   ClassDerefObject(Window->Class);
+   Window->Class = NULL;
+
+   if(Window->WindowRegion)
+   {
+      NtGdiDeleteObject(Window->WindowRegion);
+   }
+
+   RtlFreeUnicodeString(&Window->WindowName);
+
+   UserDerefObject(Window);
+
+   return 0;
 }
 
 VOID FASTCALL
-IntGetWindowBorderMeasures(PWINDOW_OBJECT WindowObject, UINT *cx, UINT *cy)
+IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
 {
-  if(HAS_DLGFRAME(WindowObject->Style, WindowObject->ExStyle) && !(WindowObject->Style & WS_MINIMIZE))
-  {
-    *cx = NtUserGetSystemMetrics(SM_CXDLGFRAME);
-    *cy = NtUserGetSystemMetrics(SM_CYDLGFRAME);
-  }
-  else
-  {
-    if(HAS_THICKFRAME(WindowObject->Style, WindowObject->ExStyle)&& !(WindowObject->Style & WS_MINIMIZE))
-    {
-      *cx = NtUserGetSystemMetrics(SM_CXFRAME);
-      *cy = NtUserGetSystemMetrics(SM_CYFRAME);
-    }
-    else if(HAS_THINFRAME(WindowObject->Style, WindowObject->ExStyle))
-    {
-      *cx = NtUserGetSystemMetrics(SM_CXBORDER);
-      *cy = NtUserGetSystemMetrics(SM_CYBORDER);
-    }
-    else
-    {
-      *cx = *cy = 0;
-    }
-  }
+   if(HAS_DLGFRAME(Window->Style, Window->ExStyle) && !(Window->Style & WS_MINIMIZE))
+   {
+      *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
+      *cy = UserGetSystemMetrics(SM_CYDLGFRAME);
+   }
+   else
+   {
+      if(HAS_THICKFRAME(Window->Style, Window->ExStyle)&& !(Window->Style & WS_MINIMIZE))
+      {
+         *cx = UserGetSystemMetrics(SM_CXFRAME);
+         *cy = UserGetSystemMetrics(SM_CYFRAME);
+      }
+      else if(HAS_THINFRAME(Window->Style, Window->ExStyle))
+      {
+         *cx = UserGetSystemMetrics(SM_CXBORDER);
+         *cy = UserGetSystemMetrics(SM_CYBORDER);
+      }
+      else
+      {
+         *cx = *cy = 0;
+      }
+   }
 }
 
 BOOL FASTCALL
-IntGetWindowInfo(PWINDOW_OBJECT WindowObject, PWINDOWINFO pwi)
+IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
 {
-  pwi->cbSize = sizeof(WINDOWINFO);
-  pwi->rcWindow = WindowObject->WindowRect;
-  pwi->rcClient = WindowObject->ClientRect;
-  pwi->dwStyle = WindowObject->Style;
-  pwi->dwExStyle = WindowObject->ExStyle;
-  pwi->dwWindowStatus = (NtUserGetForegroundWindow() == WindowObject->Self); /* WS_ACTIVECAPTION */
-  IntGetWindowBorderMeasures(WindowObject, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
-  pwi->atomWindowType = (WindowObject->Class ? WindowObject->Class->Atom : 0);
-  pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
-  return TRUE;
+   pwi->cbSize = sizeof(WINDOWINFO);
+   pwi->rcWindow = Window->WindowRect;
+   pwi->rcClient = Window->ClientRect;
+   pwi->dwStyle = Window->Style;
+   pwi->dwExStyle = Window->ExStyle;
+   pwi->dwWindowStatus = (UserGetForegroundWindow() == Window->hSelf); /* WS_ACTIVECAPTION */
+   IntGetWindowBorderMeasures(Window, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
+   pwi->atomWindowType = (Window->Class ? Window->Class->Atom : 0);
+   pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
+   return TRUE;
 }
 
 static BOOL FASTCALL
 IntSetMenu(
-   PWINDOW_OBJECT WindowObject,
+   PWINDOW_OBJECT Window,
    HMENU Menu,
    BOOL *Changed)
 {
-  PMENU_OBJECT OldMenuObject, NewMenuObject = NULL;
+   PMENU_OBJECT OldMenu, NewMenu = NULL;
 
-  *Changed = (WindowObject->IDMenu != (UINT) Menu);
-  if (! *Changed)
-    {
+   if ((Window->Style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+   {
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      return FALSE;
+   }
+
+   *Changed = (Window->IDMenu != (UINT) Menu);
+   if (! *Changed)
+   {
       return TRUE;
-    }
-
-  if (0 != WindowObject->IDMenu)
-    {
-      OldMenuObject = IntGetMenuObject((HMENU) WindowObject->IDMenu);
-      ASSERT(NULL == OldMenuObject || OldMenuObject->MenuInfo.Wnd == WindowObject->Self);
-    }
-  else
-    {
-      OldMenuObject = NULL;
-    }
-
-  if (NULL != Menu)
-    {
-      NewMenuObject = IntGetMenuObject(Menu);
-      if (NULL == NewMenuObject)
-        {
-          if (NULL != OldMenuObject)
-            {
-              IntReleaseMenuObject(OldMenuObject);
-            }
-          SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-          return FALSE;
-        }
-      if (NULL != NewMenuObject->MenuInfo.Wnd)
-        {
-          /* Can't use the same menu for two windows */
-          if (NULL != OldMenuObject)
-            {
-              IntReleaseMenuObject(OldMenuObject);
-            }
-          SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-          return FALSE;
-        }
-    }
-
-  WindowObject->IDMenu = (UINT) Menu;
-  if (NULL != NewMenuObject)
-    {
-      NewMenuObject->MenuInfo.Wnd = WindowObject->Self;
-      IntReleaseMenuObject(NewMenuObject);
-    }
-  if (NULL != OldMenuObject)
-    {
-      OldMenuObject->MenuInfo.Wnd = NULL;
-      IntReleaseMenuObject(OldMenuObject);
-    }
-
-  return TRUE;
+   }
+
+   if (Window->IDMenu)
+   {
+      OldMenu = IntGetMenuObject((HMENU) Window->IDMenu);
+      ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Window->hSelf);
+   }
+   else
+   {
+      OldMenu = NULL;
+   }
+
+   if (NULL != Menu)
+   {
+      NewMenu = IntGetMenuObject(Menu);
+      if (NULL == NewMenu)
+      {
+         if (NULL != OldMenu)
+         {
+            IntReleaseMenuObject(OldMenu);
+         }
+         SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+         return FALSE;
+      }
+      if (NULL != NewMenu->MenuInfo.Wnd)
+      {
+         /* Can't use the same menu for two windows */
+         if (NULL != OldMenu)
+         {
+            IntReleaseMenuObject(OldMenu);
+         }
+         SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+         return FALSE;
+      }
+
+   }
+
+   Window->IDMenu = (UINT) Menu;
+   if (NULL != NewMenu)
+   {
+      NewMenu->MenuInfo.Wnd = Window->hSelf;
+      IntReleaseMenuObject(NewMenu);
+   }
+   if (NULL != OldMenu)
+   {
+      OldMenu->MenuInfo.Wnd = NULL;
+      IntReleaseMenuObject(OldMenu);
+   }
+
+   return TRUE;
 }
 
 
@@ -557,59 +565,41 @@ IntSetMenu(
 
 
 VOID FASTCALL
-DestroyThreadWindows(struct _ETHREAD *Thread)
+co_DestroyThreadWindows(struct _ETHREAD *Thread)
 {
-  PLIST_ENTRY Current;
-  PW32PROCESS Win32Process;
-  PW32THREAD Win32Thread;
-  PWINDOW_OBJECT *List, *pWnd;
-  ULONG Cnt = 0;
-
-  Win32Thread = Thread->Tcb.Win32Thread;
-  Win32Process = Thread->ThreadsProcess->Win32Process;
-  
-  IntLockThreadWindows(Win32Thread);
-  Current = Win32Thread->WindowListHead.Flink;
-  while (Current != &(Win32Thread->WindowListHead))
-  {
-    Cnt++;
-    Current = Current->Flink;
-  }
-  
-  if(Cnt > 0)
-  {
-    List = ExAllocatePool(PagedPool, (Cnt + 1) * sizeof(PWINDOW_OBJECT));
-    if(!List)
-    {
-      DPRINT("Not enough memory to allocate window handle list\n");
-      IntUnLockThreadWindows(Win32Thread);
-      return;
-    }
-    pWnd = List;
-    Current = Win32Thread->WindowListHead.Flink;
-    while (Current != &(Win32Thread->WindowListHead))
-    {
-      *pWnd = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
-      IntReferenceWindowObject(*pWnd);
-      pWnd++;
-      Current = Current->Flink;
-    }
-    IntUnLockThreadWindows(Win32Thread);
-    *pWnd = NULL;
-    
-    for(pWnd = List; *pWnd; pWnd++)
-    {
-      NtUserDestroyWindow((*pWnd)->Self);
-      IntReleaseWindowObject(*pWnd);
-    }
-    ExFreePool(List);
-    return;
-  }
-  
-  IntUnLockThreadWindows(Win32Thread);
+   PW32THREAD WThread;
+   PLIST_ENTRY Current;
+   PWINDOW_OBJECT Wnd;
+   USER_REFERENCE_ENTRY Ref;
+   WThread = (PW32THREAD)Thread->Tcb.Win32Thread;
+   
+   while (!IsListEmpty(&WThread->WindowListHead))
+   {
+      Current = WThread->WindowListHead.Flink;
+      Wnd = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+
+      DPRINT1("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
+
+      /* window removes itself from the list */
+      
+      /*
+      fixme: it is critical that the window removes itself! if now, we will loop
+      here forever...
+      */
+      
+      //ASSERT(co_UserDestroyWindow(Wnd));
+      
+      UserRefObjectCo(Wnd, &Ref);//faxme: temp hack??
+      if (!co_UserDestroyWindow(Wnd))
+      {
+         DPRINT1("Unable to destroy window 0x%x at thread cleanup... This is _VERY_ bad!\n", Wnd);
+      }
+      UserDerefObjectCo(Wnd);//faxme: temp hack??
+   }
 }
 
 
+
 /*!
  * Internal function.
  * Returns client window rectangle relative to the upper-left corner of client area.
@@ -617,14 +607,14 @@ DestroyThreadWindows(struct _ETHREAD *Thread)
  * \note Does not check the validity of the parameters
 */
 VOID FASTCALL
-IntGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
+IntGetClientRect(PWINDOW_OBJECT Window, PRECT Rect)
 {
-  ASSERT( WindowObject );
-  ASSERT( Rect );
+   ASSERT( Window );
+   ASSERT( Rect );
 
-  Rect->left = Rect->top = 0;
-  Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
-  Rect->bottom = WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
+   Rect->left = Rect->top = 0;
+   Rect->right = Window->ClientRect.right - Window->ClientRect.left;
+   Rect->bottom = Window->ClientRect.bottom - Window->ClientRect.top;
 }
 
 
@@ -632,430 +622,375 @@ IntGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
 HWND FASTCALL
 IntGetFocusWindow(VOID)
 {
-  PUSER_MESSAGE_QUEUE Queue;
-  PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
+   PUSER_MESSAGE_QUEUE Queue;
+   PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
 
-  if( !pdo )
-       return NULL;
+   if( !pdo )
+      return NULL;
 
-  Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
+   Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
 
-  if (Queue == NULL)
+   if (Queue == NULL)
       return(NULL);
-  else
+   else
       return(Queue->FocusWindow);
 }
 #endif
 
 PMENU_OBJECT FASTCALL
-IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
+IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
 {
-  PMENU_OBJECT MenuObject, NewMenuObject, SysMenuObject, ret = NULL;
-  PW32THREAD W32Thread;
-  HMENU NewMenu, SysMenu;
-  ROSMENUITEMINFO ItemInfo;
-
-  if(bRevert)
-  {
-    W32Thread = PsGetWin32Thread();
-    
-    if(!W32Thread->Desktop)
-      return NULL;
-      
-    if(WindowObject->SystemMenu)
-    {
-      MenuObject = IntGetMenuObject(WindowObject->SystemMenu);
-      if(MenuObject)
-      {
-        IntDestroyMenuObject(MenuObject, FALSE, TRUE);
-        WindowObject->SystemMenu = (HMENU)0;
-        IntReleaseMenuObject(MenuObject);
-      }
-    }
-      
-    if(W32Thread->Desktop->WindowStation->SystemMenuTemplate)
-    {
-      /* clone system menu */
-      MenuObject = IntGetMenuObject(W32Thread->Desktop->WindowStation->SystemMenuTemplate);
-      if(!MenuObject)
-        return NULL;
-
-      NewMenuObject = IntCloneMenu(MenuObject);
-      if(NewMenuObject)
+   PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
+   PW32THREAD W32Thread;
+   HMENU hNewMenu, hSysMenu;
+   ROSMENUITEMINFO ItemInfo;
+
+   if(bRevert)
+   {
+      W32Thread = PsGetWin32Thread();
+
+      if(!W32Thread->Desktop)
+         return NULL;
+
+      if(Window->SystemMenu)
       {
-        WindowObject->SystemMenu = NewMenuObject->MenuInfo.Self;
-        NewMenuObject->MenuInfo.Flags |= MF_SYSMENU;
-        NewMenuObject->MenuInfo.Wnd = WindowObject->Self;
-        ret = NewMenuObject;
-        //IntReleaseMenuObject(NewMenuObject);
+         Menu = UserGetMenuObject(Window->SystemMenu);
+         if(Menu)
+         {
+            IntDestroyMenuObject(Menu, FALSE, TRUE);
+            Window->SystemMenu = (HMENU)0;
+         }
       }
-      IntReleaseMenuObject(MenuObject);
-    }
-    else
-    {
-      SysMenu = NtUserCreateMenu(FALSE);
-      if (NULL == SysMenu)
+
+      if(W32Thread->Desktop->WindowStation->SystemMenuTemplate)
       {
-        return NULL;
+         /* clone system menu */
+         Menu = UserGetMenuObject(W32Thread->Desktop->WindowStation->SystemMenuTemplate);
+         if(!Menu)
+            return NULL;
+
+         NewMenu = IntCloneMenu(Menu);
+         if(NewMenu)
+         {
+            Window->SystemMenu = NewMenu->MenuInfo.Self;
+            NewMenu->MenuInfo.Flags |= MF_SYSMENU;
+            NewMenu->MenuInfo.Wnd = Window->hSelf;
+            ret = NewMenu;
+            //IntReleaseMenuObject(NewMenu);
+         }
       }
-      SysMenuObject = IntGetMenuObject(SysMenu);
-      if (NULL == SysMenuObject)
+      else
       {
-        NtUserDestroyMenu(SysMenu);
-        return NULL;
+         hSysMenu = UserCreateMenu(FALSE);
+         if (NULL == hSysMenu)
+         {
+            return NULL;
+         }
+         SysMenu = IntGetMenuObject(hSysMenu);
+         if (NULL == SysMenu)
+         {
+            UserDestroyMenu(hSysMenu);
+            return NULL;
+         }
+         SysMenu->MenuInfo.Flags |= MF_SYSMENU;
+         SysMenu->MenuInfo.Wnd = Window->hSelf;
+         hNewMenu = co_IntLoadSysMenuTemplate();
+         if(!hNewMenu)
+         {
+            IntReleaseMenuObject(SysMenu);
+            UserDestroyMenu(hSysMenu);
+            return NULL;
+         }
+         Menu = IntGetMenuObject(hNewMenu);
+         if(!Menu)
+         {
+            IntReleaseMenuObject(SysMenu);
+            UserDestroyMenu(hSysMenu);
+            return NULL;
+         }
+
+         NewMenu = IntCloneMenu(Menu);
+         if(NewMenu)
+         {
+            NewMenu->MenuInfo.Flags |= MF_SYSMENU | MF_POPUP;
+            IntReleaseMenuObject(NewMenu);
+            UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
+
+            ItemInfo.cbSize = sizeof(MENUITEMINFOW);
+            ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
+            ItemInfo.fType = MF_POPUP;
+            ItemInfo.fState = MFS_ENABLED;
+            ItemInfo.dwTypeData = NULL;
+            ItemInfo.cch = 0;
+            ItemInfo.hSubMenu = NewMenu->MenuInfo.Self;
+            IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo);
+
+            Window->SystemMenu = SysMenu->MenuInfo.Self;
+
+            ret = SysMenu;
+         }
+         IntDestroyMenuObject(Menu, FALSE, TRUE);
+         IntReleaseMenuObject(Menu);
       }
-      SysMenuObject->MenuInfo.Flags |= MF_SYSMENU;
-      SysMenuObject->MenuInfo.Wnd = WindowObject->Self;
-      NewMenu = IntLoadSysMenuTemplate();
-      if(!NewMenu)
-      {
-        IntReleaseMenuObject(SysMenuObject);
-        NtUserDestroyMenu(SysMenu);
-        return NULL;
-      }
-      MenuObject = IntGetMenuObject(NewMenu);
-      if(!MenuObject)
+      if(RetMenu)
+         return ret;
+      else
+         return NULL;
+   }
+   else
+   {
+      if(Window->SystemMenu)
+         return IntGetMenuObject((HMENU)Window->SystemMenu);
+      else
+         return NULL;
+   }
+}
+
+
+BOOL FASTCALL
+IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
+{
+   PWINDOW_OBJECT Window;
+
+   Window = BaseWindow;
+   while (Window)
+   {
+      if (Window == Parent)
       {
-        IntReleaseMenuObject(SysMenuObject);
-        NtUserDestroyMenu(SysMenu);
-        return NULL;
+         return(TRUE);
       }
-      
-      NewMenuObject = IntCloneMenu(MenuObject);
-      if(NewMenuObject)
+      if(!(Window->Style & WS_CHILD))
       {
-        NewMenuObject->MenuInfo.Flags |= MF_SYSMENU | MF_POPUP;
-        IntReleaseMenuObject(NewMenuObject);
-       NtUserSetMenuDefaultItem(NewMenuObject->MenuInfo.Self, SC_CLOSE, FALSE);
-
-        ItemInfo.cbSize = sizeof(MENUITEMINFOW);
-        ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
-        ItemInfo.fType = MF_POPUP;
-        ItemInfo.fState = MFS_ENABLED;
-        ItemInfo.dwTypeData = NULL;
-        ItemInfo.cch = 0;
-        ItemInfo.hSubMenu = NewMenuObject->MenuInfo.Self;
-        IntInsertMenuItem(SysMenuObject, (UINT) -1, TRUE, &ItemInfo);
-
-        WindowObject->SystemMenu = SysMenuObject->MenuInfo.Self;
-
-        ret = SysMenuObject;
+         break;
       }
-      IntDestroyMenuObject(MenuObject, FALSE, TRUE);
-      IntReleaseMenuObject(MenuObject);
-    }
-    if(RetMenu)
-      return ret;
-    else
-      return NULL;
-  }
-  else
-  {
-    if(WindowObject->SystemMenu)
-      return IntGetMenuObject((HMENU)WindowObject->SystemMenu);
-    else
-      return NULL;
-  }
-}
 
+      Window = Window->Parent;
+   }
 
-BOOL FASTCALL
-IntIsChildWindow(HWND Parent, HWND Child)
-{
-  PWINDOW_OBJECT BaseWindow, Window, Old;
-  
-  if(!(BaseWindow = IntGetWindowObject(Child)))
-  {
-    return FALSE;
-  }
-  
-  Window = BaseWindow;
-  while (Window)
-  {
-    if (Window->Self == Parent)
-    {
-      if(Window != BaseWindow)
-        IntReleaseWindowObject(Window);
-      IntReleaseWindowObject(BaseWindow);
-      return(TRUE);
-    }
-    if(!(Window->Style & WS_CHILD))
-    {
-      if(Window != BaseWindow)
-        IntReleaseWindowObject(Window);
-      break;
-    }
-    Old = Window;
-    Window = IntGetParentObject(Window);
-    if(Old != BaseWindow)
-      IntReleaseWindowObject(Old);
-  }
-  
-  IntReleaseWindowObject(BaseWindow);
-  return(FALSE);  
+   return(FALSE);
 }
 
 BOOL FASTCALL
-IntIsWindowVisible(HWND hWnd)
+IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
 {
-  PWINDOW_OBJECT BaseWindow, Window, Old;
-  
-  if(!(BaseWindow = IntGetWindowObject(hWnd)))
-  {
-    return FALSE;
-  }
-  
-  Window = BaseWindow;
-  while(Window)
-  {
-    if(!(Window->Style & WS_CHILD))
-    {
-      break;
-    }
-    if(!(Window->Style & WS_VISIBLE))
-    {
-      if(Window != BaseWindow)
-        IntReleaseWindowObject(Window);
-      IntReleaseWindowObject(BaseWindow);
-      return FALSE;
-    }
-    Old = Window;
-    Window = IntGetParentObject(Window);
-    if(Old != BaseWindow)
-      IntReleaseWindowObject(Old);
-  }
-  
-  if(Window)
-  {
-    if(Window->Style & WS_VISIBLE)
-    {
-      if(Window != BaseWindow)
-        IntReleaseWindowObject(Window);
-      IntReleaseWindowObject(BaseWindow);
+   PWINDOW_OBJECT Window;
+
+   Window = BaseWindow;
+   while(Window)
+   {
+      if(!(Window->Style & WS_CHILD))
+      {
+         break;
+      }
+      if(!(Window->Style & WS_VISIBLE))
+      {
+         return FALSE;
+      }
+
+      Window = Window->Parent;
+   }
+
+   if(Window && Window->Style & WS_VISIBLE)
+   {
       return TRUE;
-    }
-    if(Window != BaseWindow)
-      IntReleaseWindowObject(Window);
-  }
-  IntReleaseWindowObject(BaseWindow);
-  return FALSE;
+   }
+
+   return FALSE;
 }
 
 
 /* link the window into siblings and parent. children are kept in place. */
 VOID FASTCALL
 IntLinkWindow(
-  PWINDOW_OBJECT Wnd, 
-  PWINDOW_OBJECT WndParent,
-  PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
-  )
+   PWINDOW_OBJECT Wnd,
+   PWINDOW_OBJECT WndParent,
+   PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
+)
 {
-  PWINDOW_OBJECT Parent;
-  
-  IntLockRelatives(Wnd);
-  Wnd->Parent = WndParent->Self;
-  if ((Wnd->PrevSibling = WndPrevSibling))
-  {
-    /* link after WndPrevSibling */
-    if ((Wnd->NextSibling = WndPrevSibling->NextSibling))
-      Wnd->NextSibling->PrevSibling = Wnd;
-    else if ((Parent = IntGetWindowObject(Wnd->Parent)))
-    {
-      IntLockRelatives(Parent);
-      if(Parent->LastChild == WndPrevSibling) 
-        Parent->LastChild = Wnd;
-      IntUnLockRelatives(Parent);
-      IntReleaseWindowObject(Parent);
-    }
-    Wnd->PrevSibling->NextSibling = Wnd;
-  }
-  else
-  {
-    /* link at top */
-    Parent = IntGetWindowObject(Wnd->Parent);
-    if ((Wnd->NextSibling = WndParent->FirstChild)) 
-      Wnd->NextSibling->PrevSibling = Wnd;
-    else if (Parent)
-    {
-      IntLockRelatives(Parent);
-      Parent->LastChild = Wnd;
-      Parent->FirstChild = Wnd;
-      IntUnLockRelatives(Parent);
-      IntReleaseWindowObject(Parent);
-      IntUnLockRelatives(Wnd);
-      return;
-    }
-    if(Parent)
-    {
-      IntLockRelatives(Parent);
-      Parent->FirstChild = Wnd;
-      IntUnLockRelatives(Parent);
-      IntReleaseWindowObject(Parent);
-    }
-  }
-  IntUnLockRelatives(Wnd);
+   PWINDOW_OBJECT Parent;
+
+   Wnd->Parent = WndParent;
+   if ((Wnd->PrevSibling = WndPrevSibling))
+   {
+      /* link after WndPrevSibling */
+      if ((Wnd->NextSibling = WndPrevSibling->NextSibling))
+         Wnd->NextSibling->PrevSibling = Wnd;
+      else if ((Parent = Wnd->Parent))
+      {
+         if(Parent->LastChild == WndPrevSibling)
+            Parent->LastChild = Wnd;
+      }
+      Wnd->PrevSibling->NextSibling = Wnd;
+   }
+   else
+   {
+      /* link at top */
+      Parent = Wnd->Parent;
+      if ((Wnd->NextSibling = WndParent->FirstChild))
+         Wnd->NextSibling->PrevSibling = Wnd;
+      else if (Parent)
+      {
+         Parent->LastChild = Wnd;
+         Parent->FirstChild = Wnd;
+         return;
+      }
+      if(Parent)
+      {
+         Parent->FirstChild = Wnd;
+      }
+   }
+
 }
 
 HWND FASTCALL
 IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 {
-  PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner;
-  HWND ret;
-  
-  Wnd = IntGetWindowObject(hWnd);
-  if(!Wnd)
-    return NULL;
-  
-  IntLockRelatives(Wnd);
-  WndOldOwner = IntGetWindowObject(Wnd->Owner);
-  if (WndOldOwner)
-  {
-     ret = WndOldOwner->Self;
-     IntReleaseWindowObject(WndOldOwner);
-  }
-  else
-  {
-     ret = 0;
-  }
-  
-  if((WndNewOwner = IntGetWindowObject(hWndNewOwner)))
-  {
-    Wnd->Owner = hWndNewOwner;
-    IntReleaseWindowObject(WndNewOwner);
-  }
-  else
-    Wnd->Owner = NULL;
-  
-  IntUnLockRelatives(Wnd);
-  IntReleaseWindowObject(Wnd);
-  return ret;
+   PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner;
+   HWND ret;
+
+   Wnd = IntGetWindowObject(hWnd);
+   if(!Wnd)
+      return NULL;
+
+   WndOldOwner = IntGetWindowObject(Wnd->hOwner);
+   if (WndOldOwner)
+   {
+      ret = WndOldOwner->hSelf;
+      UserDerefObject(WndOldOwner);
+   }
+   else
+   {
+      ret = 0;
+   }
+
+   if((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
+   {
+      Wnd->hOwner = hWndNewOwner;
+   }
+   else
+      Wnd->hOwner = NULL;
+
+   UserDerefObject(Wnd);
+   return ret;
 }
 
 PWINDOW_OBJECT FASTCALL
-IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
+co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
 {
    PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter;
-   HWND hWnd, hWndNewParent, hWndOldParent;
+//   HWND hWnd, hWndNewParent;
    BOOL WasVisible;
-   BOOL MenuChanged;
-   
+
    ASSERT(Wnd);
    ASSERT(WndNewParent);
-   
-   hWnd = Wnd->Self;
-   hWndNewParent = WndNewParent->Self;
+   ASSERT_REFS_CO(Wnd);
+   ASSERT_REFS_CO(WndNewParent);
+
+//   hWnd = Wnd->hSelf;
+//   hWndNewParent = WndNewParent->hSelf;
 
    /*
     * Windows hides the window first, then shows it again
     * including the WM_SHOWWINDOW messages and all
     */
-   WasVisible = WinPosShowWindow(hWnd, SW_HIDE);
+   WasVisible = co_WinPosShowWindow(Wnd, SW_HIDE);
 
-   /* Validate that window and parent still exist */
-   if (!IntIsWindow(hWnd) || !IntIsWindow(hWndNewParent))
-      return NULL;
+//   /* Validate that window and parent still exist */
+//   if (!IntIsWindow(hWnd) || !IntIsWindow(hWndNewParent))
+//      return NULL;
 
    /* Window must belong to current process */
    if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
       return NULL;
 
-   WndOldParent = IntGetParentObject(Wnd);
-   hWndOldParent = (WndOldParent ? WndOldParent->Self : NULL);
-
+   WndOldParent = Wnd->Parent;
+   
+   if (WndOldParent) UserRefObject(WndOldParent); /* caller must deref */
+   
    if (WndNewParent != WndOldParent)
    {
       IntUnlinkWindow(Wnd);
       InsertAfter = NULL;
       if (0 == (Wnd->ExStyle & WS_EX_TOPMOST))
       {
-        /* Not a TOPMOST window, put after TOPMOSTs of new parent */
-        IntLockRelatives(WndNewParent);
-        Sibling = WndNewParent->FirstChild;
-        while (NULL != Sibling && 0 != (Sibling->ExStyle & WS_EX_TOPMOST))
-        {
-          InsertAfter = Sibling;
-          Sibling = Sibling->NextSibling;
-        }
-        IntUnLockRelatives(WndNewParent);
+         /* Not a TOPMOST window, put after TOPMOSTs of new parent */
+         Sibling = WndNewParent->FirstChild;
+         while (NULL != Sibling && 0 != (Sibling->ExStyle & WS_EX_TOPMOST))
+         {
+            InsertAfter = Sibling;
+            Sibling = Sibling->NextSibling;
+         }
       }
       if (NULL == InsertAfter)
       {
-        IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
+         IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
       }
       else
       {
-        IntReferenceWindowObject(InsertAfter);
-        IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
-        IntReleaseWindowObject(InsertAfter);
-      }
-
-      if (WndNewParent->Self != IntGetDesktopWindow()) /* a child window */
-      {
-         if (!(Wnd->Style & WS_CHILD))
-         {
-            //if ( Wnd->Menu ) DestroyMenu ( Wnd->menu );
-            IntSetMenu(Wnd, NULL, &MenuChanged);
-         }
+//         UserRefObject(InsertAfter);
+         IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
+//         UserDerefObject(InsertAfter);
       }
    }
-   
+
    /*
     * SetParent additionally needs to make hwnd the top window
     * in the z-order and send the expected WM_WINDOWPOSCHANGING and
     * WM_WINDOWPOSCHANGED notification messages.
     */
-   WinPosSetWindowPos(hWnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
-                      0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
-                                | (WasVisible ? SWP_SHOWWINDOW : 0));
+   co_WinPosSetWindowPos(Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
+                         0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
+                         | (WasVisible ? SWP_SHOWWINDOW : 0));
 
    /*
     * FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
     * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE
     */
-   
+
    /*
     * Validate that the old parent still exist, since it migth have been
-    * destroyed during the last callbacks to user-mode 
+    * destroyed during the last callbacks to user-mode
     */
-   if(WndOldParent)
-   {
-     if(!IntIsWindow(WndOldParent->Self))
-     {
-       IntReleaseWindowObject(WndOldParent);
-       return NULL;
-     }
-     
-     /* don't dereference the window object here, it must be done by the caller
-        of IntSetParent() */
-     return WndOldParent;
-   }
-   return NULL;
+//   if(WndOldParent)
+//   {
+//      if(!IntIsWindow(WndOldParent->hSelf))
+//      {
+//         UserDerefObject(WndOldParent);
+//         return NULL;
+//      }
+
+      /* don't dereference the window object here, it must be done by the caller
+         of IntSetParent() */
+//      return WndOldParent;
+//   }
+   
+   return WndOldParent;//NULL;
 }
 
 BOOL FASTCALL
-IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
+IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
 {
-  PMENU_OBJECT OldMenuObject;
-  if(WindowObject->SystemMenu)
-  {
-    OldMenuObject = IntGetMenuObject(WindowObject->SystemMenu);
-    if(OldMenuObject)
-    {
-      OldMenuObject->MenuInfo.Flags &= ~ MF_SYSMENU;
-      IntReleaseMenuObject(OldMenuObject);
-    }
-  }
-  
-  if(MenuObject)
-  {
-    /* FIXME check window style, propably return FALSE ? */
-    WindowObject->SystemMenu = MenuObject->MenuInfo.Self;
-    MenuObject->MenuInfo.Flags |= MF_SYSMENU;
-  }
-  else
-    WindowObject->SystemMenu = (HMENU)0;
-  
-  return TRUE;
+   PMENU_OBJECT OldMenu;
+   if(Window->SystemMenu)
+   {
+      OldMenu = IntGetMenuObject(Window->SystemMenu);
+      if(OldMenu)
+      {
+         OldMenu->MenuInfo.Flags &= ~ MF_SYSMENU;
+         IntReleaseMenuObject(OldMenu);
+      }
+   }
+
+   if(Menu)
+   {
+      /* FIXME check window style, propably return FALSE ? */
+      Window->SystemMenu = Menu->MenuInfo.Self;
+      Menu->MenuInfo.Flags |= MF_SYSMENU;
+   }
+   else
+      Window->SystemMenu = (HMENU)0;
+
+   return TRUE;
 }
 
 
@@ -1063,63 +998,50 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
 VOID FASTCALL
 IntUnlinkWindow(PWINDOW_OBJECT Wnd)
 {
-  PWINDOW_OBJECT WndParent;
-  
-  IntLockRelatives(Wnd);
-  if((WndParent = IntGetWindowObject(Wnd->Parent)))
-  {
-    IntLockRelatives(WndParent);
-  }
-  
-  if (Wnd->NextSibling) Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
-  else if (WndParent && WndParent->LastChild == Wnd) WndParent->LastChild = Wnd->PrevSibling;
-  if (Wnd->PrevSibling) Wnd->PrevSibling->NextSibling = Wnd->NextSibling;
-  else if (WndParent && WndParent->FirstChild == Wnd) WndParent->FirstChild = Wnd->NextSibling;
-  
-  if(WndParent)
-  {
-    IntUnLockRelatives(WndParent);
-    IntReleaseWindowObject(WndParent);
-  }
-  Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL;
-  IntUnLockRelatives(Wnd);
+   PWINDOW_OBJECT WndParent = Wnd->Parent;
+
+   if (Wnd->NextSibling)
+      Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
+   else if (WndParent && WndParent->LastChild == Wnd)
+      WndParent->LastChild = Wnd->PrevSibling;
+
+   if (Wnd->PrevSibling)
+      Wnd->PrevSibling->NextSibling = Wnd->NextSibling;
+   else if (WndParent && WndParent->FirstChild == Wnd)
+      WndParent->FirstChild = Wnd->NextSibling;
+
+   Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL;
 }
 
 BOOL FASTCALL
 IntAnyPopup(VOID)
 {
-  PWINDOW_OBJECT Window, Child;
-  
-  if(!(Window = IntGetWindowObject(IntGetDesktopWindow())))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return FALSE;
-  }
-  
-  IntLockRelatives(Window);
-  for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
-  {
-    if(Child->Owner && Child->Style & WS_VISIBLE)
-    {
-      /*
-       * The desktop has a popup window if one of them has 
-       * an owner window and is visible
-       */
-      IntUnLockRelatives(Window);
-      IntReleaseWindowObject(Window);
-      return TRUE;
-    }
-  }
-  IntUnLockRelatives(Window);
-  IntReleaseWindowObject(Window);
-  return FALSE;
+   PWINDOW_OBJECT Window, Child;
+
+   if(!(Window = UserGetWindowObject(IntGetDesktopWindow())))
+   {
+      return FALSE;
+   }
+
+   for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
+   {
+      if(Child->hOwner && Child->Style & WS_VISIBLE)
+      {
+         /*
+          * The desktop has a popup window if one of them has
+          * an owner window and is visible
+          */
+         return TRUE;
+      }
+   }
+
+   return FALSE;
 }
 
 BOOL FASTCALL
 IntIsWindowInDestroy(PWINDOW_OBJECT Window)
 {
-  return ((Window->Status & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
+   return ((Window->Status & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
 }
 
 /* FUNCTIONS *****************************************************************/
@@ -1129,12 +1051,12 @@ IntIsWindowInDestroy(PWINDOW_OBJECT Window)
  */
 DWORD STDCALL
 NtUserAlterWindowStyle(DWORD Unknown0,
-                      DWORD Unknown1,
-                      DWORD Unknown2)
+                       DWORD Unknown1,
+                       DWORD Unknown2)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return(0);
+   return(0);
 }
 
 
@@ -1152,141 +1074,128 @@ NtUserAlterWindowStyle(DWORD Unknown0,
 ULONG
 STDCALL
 NtUserBuildHwndList(
-  HDESK hDesktop,
-  HWND hwndParent,
-  BOOLEAN bChildren,
-  ULONG dwThreadId,
-  ULONG lParam,
-  HWND* pWnd,
-  ULONG nBufSize)
+   HDESK hDesktop,
+   HWND hwndParent,
+   BOOLEAN bChildren,
+   ULONG dwThreadId,
+   ULONG lParam,
+   HWND* pWnd,
+   ULONG nBufSize)
 {
-  NTSTATUS Status;
-  ULONG dwCount = 0;
+   NTSTATUS Status;
+   ULONG dwCount = 0;
 
-  /* FIXME handle bChildren */
-  
-  if(hwndParent)
-  {
-    PWINDOW_OBJECT Window, Child;
-    if(!(Window = IntGetWindowObject(hwndParent)))
-    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
-      return 0;
-    }
-    
-    IntLockRelatives(Window);
-    for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
-    {
-      if(dwCount++ < nBufSize && pWnd)
+   /* FIXME handle bChildren */
+
+   if(hwndParent)
+   {
+      PWINDOW_OBJECT Window, Child;
+      if(!(Window = UserGetWindowObject(hwndParent)))
       {
-        Status = MmCopyToCaller(pWnd++, &Child->Self, sizeof(HWND));
-        if(!NT_SUCCESS(Status))
-        {
-          SetLastNtError(Status);
-          break;
-        }
+         return 0;
       }
-    }
-    IntUnLockRelatives(Window);
-    
-    IntReleaseWindowObject(Window);
-  }
-  else if(dwThreadId)
-  {
-    PETHREAD Thread;
-    PW32THREAD W32Thread;
-    PLIST_ENTRY Current;
-    PWINDOW_OBJECT Window;
-    
-    Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
-    if(!NT_SUCCESS(Status))
-    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return 0;
-    }
-    if(!(W32Thread = Thread->Tcb.Win32Thread))
-    {
-      ObDereferenceObject(Thread);
-      DPRINT("Thread is not a GUI Thread!\n");
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return 0;
-    }
-    
-    IntLockThreadWindows(W32Thread);
-    Current = W32Thread->WindowListHead.Flink;
-    while(Current != &(W32Thread->WindowListHead))
-    {
-      Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
-      ASSERT(Window);
-      
-      if(dwCount < nBufSize && pWnd)
+
+      for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
       {
-        Status = MmCopyToCaller(pWnd++, &Window->Self, sizeof(HWND));
-        if(!NT_SUCCESS(Status))
-        {
-          SetLastNtError(Status);
-          break;
-        }
+         if(dwCount++ < nBufSize && pWnd)
+         {
+            Status = MmCopyToCaller(pWnd++, &Child->hSelf, sizeof(HWND));
+            if(!NT_SUCCESS(Status))
+            {
+               SetLastNtError(Status);
+               break;
+            }
+         }
       }
-      dwCount++;
-      Current = Current->Flink;
-    }
-    IntUnLockThreadWindows(W32Thread);
-    
-    ObDereferenceObject(Thread);
-  }
-  else
-  {
-    PDESKTOP_OBJECT Desktop;
-    PWINDOW_OBJECT Window, Child;
-    
-    if(hDesktop == NULL && !(Desktop = IntGetActiveDesktop()))
-    {                  
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
-      return 0;
-    }
-    
-    if(hDesktop)
-    {
-      Status = IntValidateDesktopHandle(hDesktop,
-                                        UserMode,
-                                        0,
-                                        &Desktop);
+   }
+   else if(dwThreadId)
+   {
+      PETHREAD Thread;
+      PW32THREAD W32Thread;
+      PLIST_ENTRY Current;
+      PWINDOW_OBJECT Window;
+
+      Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
       if(!NT_SUCCESS(Status))
       {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return 0;
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         return 0;
+      }
+      if(!(W32Thread = (PW32THREAD)Thread->Tcb.Win32Thread))
+      {
+         ObDereferenceObject(Thread);
+         DPRINT("Thread is not a GUI Thread!\n");
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         return 0;
+      }
+
+      Current = W32Thread->WindowListHead.Flink;
+      while(Current != &(W32Thread->WindowListHead))
+      {
+         Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+         ASSERT(Window);
+
+         if(dwCount < nBufSize && pWnd)
+         {
+            Status = MmCopyToCaller(pWnd++, &Window->hSelf, sizeof(HWND));
+            if(!NT_SUCCESS(Status))
+            {
+               SetLastNtError(Status);
+               break;
+            }
+         }
+         dwCount++;
+         Current = Current->Flink;
+      }
+
+      ObDereferenceObject(Thread);
+   }
+   else
+   {
+      PDESKTOP_OBJECT Desktop;
+      PWINDOW_OBJECT Window, Child;
+
+      if(hDesktop == NULL && !(Desktop = IntGetActiveDesktop()))
+      {
+         SetLastWin32Error(ERROR_INVALID_HANDLE);
+         return 0;
       }
-    }
-    if(!(Window = IntGetWindowObject(Desktop->DesktopWindow)))
-    {
+
       if(hDesktop)
-        ObDereferenceObject(Desktop);
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return 0;
-    }
-    
-    IntLockRelatives(Window);
-    for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
-    {
-      if(dwCount++ < nBufSize && pWnd)
       {
-        Status = MmCopyToCaller(pWnd++, &Child->Self, sizeof(HWND));
-        if(!NT_SUCCESS(Status))
-        {
-          SetLastNtError(Status);
-          break;
-        }
+         Status = IntValidateDesktopHandle(hDesktop,
+                                           UserMode,
+                                           0,
+                                           &Desktop);
+         if(!NT_SUCCESS(Status))
+         {
+            SetLastWin32Error(ERROR_INVALID_HANDLE);
+            return 0;
+         }
+      }
+      if(!(Window = UserGetWindowObject(Desktop->DesktopWindow)))
+      {
+         if(hDesktop) ObDereferenceObject(Desktop);
+         return 0;
       }
-    }
-    IntUnLockRelatives(Window);
-    
-    IntReleaseWindowObject(Window);
-    if(hDesktop)
-      ObDereferenceObject(Desktop);
-  }
-  
-  return dwCount;
+
+      for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
+      {
+         if(dwCount++ < nBufSize && pWnd)
+         {
+            Status = MmCopyToCaller(pWnd++, &Child->hSelf, sizeof(HWND));
+            if(!NT_SUCCESS(Status))
+            {
+               SetLastNtError(Status);
+               break;
+            }
+         }
+      }
+
+      if(hDesktop) ObDereferenceObject(Desktop);
+   }
+
+   return dwCount;
 }
 
 
@@ -1295,73 +1204,65 @@ NtUserBuildHwndList(
  */
 HWND STDCALL
 NtUserChildWindowFromPointEx(HWND hwndParent,
-                            LONG x,
-                            LONG y,
-                            UINT uiFlags)
+                             LONG x,
+                             LONG y,
+                             UINT uiFlags)
 {
-  PWINDOW_OBJECT Parent;
-  POINTL Pt;
-  HWND Ret;
-  HWND *List, *phWnd;
-  
-  if(!(Parent = IntGetWindowObject(hwndParent)))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return NULL;
-  }
-  
-  Pt.x = x;
-  Pt.y = y;
-  
-  if(Parent->Self != IntGetDesktopWindow())
-  {
-    Pt.x += Parent->ClientRect.left;
-    Pt.y += Parent->ClientRect.top;
-  }
-  
-  if(!IntPtInWindow(Parent, Pt.x, Pt.y))
-  {
-    IntReleaseWindowObject(Parent);
-    return NULL;
-  }
-  
-  Ret = Parent->Self;
-  if((List = IntWinListChildren(Parent)))
-  {
-    for(phWnd = List; *phWnd; phWnd++)
-    {
-      PWINDOW_OBJECT Child;
-      if((Child = IntGetWindowObject(*phWnd)))
+   PWINDOW_OBJECT Parent;
+   POINTL Pt;
+   HWND Ret;
+   HWND *List, *phWnd;
+
+   if(!(Parent = UserGetWindowObject(hwndParent)))
+   {
+      return NULL;
+   }
+
+   Pt.x = x;
+   Pt.y = y;
+
+   if(Parent->hSelf != IntGetDesktopWindow())
+   {
+      Pt.x += Parent->ClientRect.left;
+      Pt.y += Parent->ClientRect.top;
+   }
+
+   if(!IntPtInWindow(Parent, Pt.x, Pt.y))
+   {
+      return NULL;
+   }
+
+   Ret = Parent->hSelf;
+   if((List = IntWinListChildren(Parent)))
+   {
+      for(phWnd = List; *phWnd; phWnd++)
       {
-        if(!(Child->Style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
-        {
-          IntReleaseWindowObject(Child);
-          continue;
-        }
-        if((Child->Style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
-        {
-          IntReleaseWindowObject(Child);
-          continue;
-        }
-        if((Child->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
-        {
-          IntReleaseWindowObject(Child);
-          continue;
-        }
-        if(IntPtInWindow(Child, Pt.x, Pt.y))
-        {
-          Ret = Child->Self;
-          IntReleaseWindowObject(Child);
-          break;
-        }
-        IntReleaseWindowObject(Child);
+         PWINDOW_OBJECT Child;
+         if((Child = UserGetWindowObject(*phWnd)))
+         {
+            if(!(Child->Style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
+            {
+               continue;
+            }
+            if((Child->Style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
+            {
+               continue;
+            }
+            if((Child->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
+            {
+               continue;
+            }
+            if(IntPtInWindow(Child, Pt.x, Pt.y))
+            {
+               Ret = Child->hSelf;
+               break;
+            }
+         }
       }
-    }
-    ExFreePool(List);
-  }
-  
-  IntReleaseWindowObject(Parent);
-  return Ret;
+      ExFreePool(List);
+   }
+
+   return Ret;
 }
 
 
@@ -1369,46 +1270,46 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
  * calculates the default position of a window
  */
 BOOL FASTCALL
-IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT WindowObject, RECT *rc, BOOL IncPos)
+IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT Window, RECT *rc, BOOL IncPos)
 {
-  SIZE Sz;
-  POINT Pos = {0, 0};
-  
-  if(Parent != NULL)
-  {
-    IntGdiIntersectRect(rc, rc, &Parent->ClientRect);
-    
-    if(IncPos)
-    {
-      Pos.x = Parent->TiledCounter * (NtUserGetSystemMetrics(SM_CXSIZE) + NtUserGetSystemMetrics(SM_CXFRAME));
-      Pos.y = Parent->TiledCounter * (NtUserGetSystemMetrics(SM_CYSIZE) + NtUserGetSystemMetrics(SM_CYFRAME));
-      if(Pos.x > ((rc->right - rc->left) / 4) ||
-         Pos.y > ((rc->bottom - rc->top) / 4))
+   SIZE Sz;
+   POINT Pos = {0, 0};
+
+   if(Parent != NULL)
+   {
+      IntGdiIntersectRect(rc, rc, &Parent->ClientRect);
+
+      if(IncPos)
       {
-        /* reset counter and position */
-        Pos.x = 0;
-        Pos.y = 0;
-        Parent->TiledCounter = 0;
+         Pos.x = Parent->TiledCounter * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
+         Pos.y = Parent->TiledCounter * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
+         if(Pos.x > ((rc->right - rc->left) / 4) ||
+               Pos.y > ((rc->bottom - rc->top) / 4))
+         {
+            /* reset counter and position */
+            Pos.x = 0;
+            Pos.y = 0;
+            Parent->TiledCounter = 0;
+         }
+         Parent->TiledCounter++;
       }
-      Parent->TiledCounter++;
-    }
-    Pos.x += rc->left;
-    Pos.y += rc->top;
-  }
-  else
-  {
-    Pos.x = rc->left;
-    Pos.y = rc->top;
-  }
-  
-  Sz.cx = EngMulDiv(rc->right - rc->left, 3, 4);
-  Sz.cy = EngMulDiv(rc->bottom - rc->top, 3, 4);
-  
-  rc->left = Pos.x;
-  rc->top = Pos.y;
-  rc->right = rc->left + Sz.cx;
-  rc->bottom = rc->top + Sz.cy;
-  return TRUE;
+      Pos.x += rc->left;
+      Pos.y += rc->top;
+   }
+   else
+   {
+      Pos.x = rc->left;
+      Pos.y = rc->top;
+   }
+
+   Sz.cx = EngMulDiv(rc->right - rc->left, 3, 4);
+   Sz.cy = EngMulDiv(rc->bottom - rc->top, 3, 4);
+
+   rc->left = Pos.x;
+   rc->top = Pos.y;
+   rc->right = rc->left + Sz.cx;
+   rc->bottom = rc->top + Sz.cy;
+   return TRUE;
 }
 
 
@@ -1416,705 +1317,696 @@ IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT WindowObject, RECT *rc,
  * @implemented
  */
 HWND STDCALL
-IntCreateWindowEx(DWORD dwExStyle,
-                 PUNICODE_STRING ClassName,
-                 PUNICODE_STRING WindowName,
-                 DWORD dwStyle,
-                 LONG x,
-                 LONG y,
-                 LONG nWidth,
-                 LONG nHeight,
-                 HWND hWndParent,
-                 HMENU hMenu,
-                 HINSTANCE hInstance,
-                 LPVOID lpParam,
-                 DWORD dwShowMode,
-                 BOOL bUnicodeWindow)
+co_IntCreateWindowEx(DWORD dwExStyle,
+                     PUNICODE_STRING ClassName,
+                     PUNICODE_STRING WindowName,
+                     DWORD dwStyle,
+                     LONG x,
+                     LONG y,
+                     LONG nWidth,
+                     LONG nHeight,
+                     HWND hWndParent,
+                     HMENU hMenu,
+                     HINSTANCE hInstance,
+                     LPVOID lpParam,
+                     DWORD dwShowMode,
+                     BOOL bUnicodeWindow)
 {
-  PWINSTATION_OBJECT WinStaObject;
-  PWNDCLASS_OBJECT ClassObject;
-  PWINDOW_OBJECT WindowObject;
-  PWINDOW_OBJECT ParentWindow, OwnerWindow;
-  HWND ParentWindowHandle;
-  HWND OwnerWindowHandle;
-  PMENU_OBJECT SystemMenu;
-  HANDLE Handle;
-  POINT Pos;
-  SIZE Size;
+   PWINSTATION_OBJECT WinSta;
+   PWNDCLASS_OBJECT Class = NULL;
+   PWINDOW_OBJECT Window = NULL;
+   PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
+   HWND ParentWindowHandle;
+   HWND OwnerWindowHandle;
+   PMENU_OBJECT SystemMenu;
+   HWND hWnd;
+   POINT Pos;
+   SIZE Size;
 #if 0
-  POINT MaxSize, MaxPos, MinTrack, MaxTrack;
+
+   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
 #else
-  POINT MaxPos;
+
+   POINT MaxPos;
 #endif
-  CREATESTRUCTW Cs;
-  CBT_CREATEWNDW CbtCreate;
-  LRESULT Result;
-  BOOL MenuChanged;
-  BOOL ClassFound;
 
-  BOOL HasOwner;
+   CREATESTRUCTW Cs;
+   CBT_CREATEWNDW CbtCreate;
+   LRESULT Result;
+   BOOL MenuChanged;
+   DECLARE_RETURN(HWND);
+   BOOL HasOwner;
+   USER_REFERENCE_ENTRY ParentRef, Ref;
 
-  ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
-  OwnerWindowHandle = NULL;
+   ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
+   OwnerWindowHandle = NULL;
 
-  if (hWndParent == HWND_MESSAGE)
-    {
+   if (hWndParent == HWND_MESSAGE)
+   {
       /*
        * native ole32.OleInitialize uses HWND_MESSAGE to create the
        * message window (style: WS_POPUP|WS_DISABLED)
        */
       DPRINT1("FIXME - Parent is HWND_MESSAGE\n");
-    }
-  else if (hWndParent)
-    {
+   }
+   else if (hWndParent)
+   {
       if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
-        ParentWindowHandle = hWndParent;
+         ParentWindowHandle = hWndParent;
       else
-        OwnerWindowHandle = NtUserGetAncestor(hWndParent, GA_ROOT);
-    }
-  else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
-    {
-      return (HWND)0;  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
-    }
-
-  if (NULL != ParentWindowHandle)
-    {
-      ParentWindow = IntGetWindowObject(ParentWindowHandle);
-    }
-  else
-    {
-      ParentWindow = NULL;
-    }
-    
-  /* FIXME: parent must belong to the current process */
-
-  /* Check the class. */
-  ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName->Buffer, hInstance);
-  if (!ClassFound)
-  {
-     if (IS_ATOM(ClassName->Buffer))
-       {
-         DPRINT1("Class 0x%x not found\n", (DWORD_PTR) ClassName->Buffer);
-       }
-     else
-       {
-         DPRINT1("Class %wZ not found\n", ClassName);
-       }
-     if (NULL != ParentWindow)
-     {
-        IntReleaseWindowObject(ParentWindow);
-     }
-     SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
-     return((HWND)0);
-  }
-
-  /* Check the window station. */
-  if (PsGetWin32Thread()->Desktop == NULL)
-    {
-      ClassDereferenceObject(ClassObject);
-      if (NULL != ParentWindow)
-        {
-          IntReleaseWindowObject(ParentWindow);
-        }
+      {
+         //temp hack
+         PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root;
+         if (Par && (Root = UserGetAncestor(Par, GA_ROOT)))
+            OwnerWindowHandle = Root->hSelf;
+      }
+   }
+   else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+   {
+      RETURN( (HWND)0);  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
+   }
+
+//   if (NULL != ParentWindowHandle)
+//   {
+   ParentWindow = UserGetWindowObject(ParentWindowHandle);
+
+   if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
+//   }
+//   else
+//   {
+//      ParentWindow = NULL;
+//   }
+
+   /* FIXME: parent must belong to the current process */
+
+   /* Check the class. */
+   Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
+   if (!Class)
+   {
+      if (IS_ATOM(ClassName->Buffer))
+      {
+         DPRINT1("Class 0x%x not found\n", (DWORD_PTR) ClassName->Buffer);
+      }
+      else
+      {
+         DPRINT1("Class %wZ not found\n", ClassName);
+      }
+
+      SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
+      RETURN((HWND)0);
+   }
+
+   ClassRefObject(Class);
+
+   /* Check the window station. */
+   if (PsGetWin32Thread()->Desktop == NULL)
+   {
       DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
-      return (HWND)0;
-    }
-  WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
-  ObReferenceObjectByPointer(WinStaObject, KernelMode, ExWindowStationObjectType, 0);
-
-  /* Create the window object. */
-  WindowObject = (PWINDOW_OBJECT)
-    ObmCreateObject(PsGetWin32Thread()->Desktop->WindowStation->HandleTable, &Handle,
-        otWindow, sizeof(WINDOW_OBJECT) + ClassObject->cbWndExtra
-        );
-
-  DPRINT("Created object with handle %X\n", Handle);
-  if (!WindowObject)
-    {
-      ObDereferenceObject(WinStaObject);
-      ClassDereferenceObject(ClassObject);
-      if (NULL != ParentWindow)
-        {
-          IntReleaseWindowObject(ParentWindow);
-        }
+      RETURN( (HWND)0);
+   }
+   WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+
+   //FIXME: Reference thread/desktop instead
+   ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
+
+   /* Create the window object. */
+   Window = (PWINDOW_OBJECT)
+            ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
+                            otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
+                           );
+
+   DPRINT("Created object with handle %X\n", hWnd);
+   if (!Window)
+   {
+      ObDereferenceObject(WinSta);
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      return (HWND)0;
-    }
-  ObDereferenceObject(WinStaObject);
+      RETURN( (HWND)0);
+   }
+
+   UserRefObjectCo(Window, &Ref);
+
+   ObDereferenceObject(WinSta);
 
-  if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
-    {
+   if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
+   {
       /* If there is no desktop window yet, we must be creating it */
-      PsGetWin32Thread()->Desktop->DesktopWindow = Handle;
-    }
+      PsGetWin32Thread()->Desktop->DesktopWindow = hWnd;
+   }
 
-  /*
-   * Fill out the structure describing it.
-   */
-  WindowObject->Class = ClassObject;
-  IntLockClassWindows(ClassObject);
-  InsertTailList(&ClassObject->ClassWindowsListHead, &WindowObject->ClassListEntry);
-  IntUnLockClassWindows(ClassObject);
-  
-  WindowObject->ExStyle = dwExStyle;
-  WindowObject->Style = dwStyle & ~WS_VISIBLE;
-  DPRINT("1: Style is now %lx\n", WindowObject->Style);
-  
-  WindowObject->SystemMenu = (HMENU)0;
-  WindowObject->ContextHelpId = 0;
-  WindowObject->IDMenu = 0;
-  WindowObject->Instance = hInstance;
-  WindowObject->Self = Handle;
-  if (0 != (dwStyle & WS_CHILD))
-    {
-      WindowObject->IDMenu = (UINT) hMenu;
-    }
-  else
-    {
-      IntSetMenu(WindowObject, hMenu, &MenuChanged);
-    }
-  WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
-  WindowObject->Parent = (ParentWindow ? ParentWindow->Self : NULL);
-  if((OwnerWindow = IntGetWindowObject(OwnerWindowHandle)))
-  {
-    WindowObject->Owner = OwnerWindowHandle;
-    IntReleaseWindowObject(OwnerWindow);
-    HasOwner = TRUE;
-  } else {
-    WindowObject->Owner = NULL;
-    HasOwner = FALSE;
-  }
-  WindowObject->UserData = 0;
-  if ((((DWORD)ClassObject->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
-      && (((DWORD)ClassObject->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000)) 
-    {
-      WindowObject->Unicode = bUnicodeWindow;
-    }
-  else
-    {
-      WindowObject->Unicode = ClassObject->Unicode;
-    }
-  WindowObject->WndProcA = ClassObject->lpfnWndProcA;
-  WindowObject->WndProcW = ClassObject->lpfnWndProcW;
-  WindowObject->OwnerThread = PsGetCurrentThread();
-  WindowObject->FirstChild = NULL;
-  WindowObject->LastChild = NULL;
-  WindowObject->PrevSibling = NULL;
-  WindowObject->NextSibling = NULL;
-
-  /* extra window data */
-  if (ClassObject->cbWndExtra != 0)
-    {
-      WindowObject->ExtraData = (PCHAR)(WindowObject + 1);
-      WindowObject->ExtraDataSize = ClassObject->cbWndExtra;
-      RtlZeroMemory(WindowObject->ExtraData, WindowObject->ExtraDataSize);
-    }
-  else
-    {
-      WindowObject->ExtraData = NULL;
-      WindowObject->ExtraDataSize = 0;
-    }
-
-  InitializeListHead(&WindowObject->PropListHead);
-  ExInitializeFastMutex(&WindowObject->PropListLock);
-  ExInitializeFastMutex(&WindowObject->RelativesLock);
-  ExInitializeFastMutex(&WindowObject->UpdateLock);
-  InitializeListHead(&WindowObject->WndObjListHead);
-  ExInitializeFastMutex(&WindowObject->WndObjListLock);
-
-  if (NULL != WindowName->Buffer)
-    {  
-      WindowObject->WindowName.MaximumLength = WindowName->MaximumLength;
-      WindowObject->WindowName.Length = WindowName->Length;
-      WindowObject->WindowName.Buffer = ExAllocatePoolWithTag(PagedPool, WindowName->MaximumLength,
-                                                              TAG_STRING);
-      if (NULL == WindowObject->WindowName.Buffer)
-        {
-          ClassDereferenceObject(ClassObject);
-          DPRINT1("Failed to allocate mem for window name\n");
-          SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-          return NULL;
-        }
-      RtlCopyMemory(WindowObject->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength);
-    }
-  else
-    {
-      RtlInitUnicodeString(&WindowObject->WindowName, NULL);
-    }
-
-
-  /*
-   * This has been tested for WS_CHILD | WS_VISIBLE.  It has not been
-   * tested for WS_POPUP
-   */
-  if ((dwExStyle & WS_EX_DLGMODALFRAME) ||
-      ((!(dwExStyle & WS_EX_STATICEDGE)) &&
-      (dwStyle & (WS_DLGFRAME | WS_THICKFRAME))))
-    dwExStyle |= WS_EX_WINDOWEDGE;
-  else
-    dwExStyle &= ~WS_EX_WINDOWEDGE;
-
-  /* Correct the window style. */
-  if (!(dwStyle & WS_CHILD))
-    {
-      WindowObject->Style |= WS_CLIPSIBLINGS;
-      DPRINT("3: Style is now %lx\n", WindowObject->Style);
+   /*
+    * Fill out the structure describing it.
+    */
+   Window->Class = Class;
+   Window->SystemMenu = (HMENU)0;
+   Window->ContextHelpId = 0;
+   Window->IDMenu = 0;
+   Window->Instance = hInstance;
+   Window->hSelf = hWnd;
+   if (0 != (dwStyle & WS_CHILD))
+   {
+      Window->IDMenu = (UINT) hMenu;
+   }
+   else
+   {
+      IntSetMenu(Window, hMenu, &MenuChanged);
+   }
+   
+   Window->MessageQueue = PsGetWin32Thread()->MessageQueue;
+   IntReferenceMessageQueue(Window->MessageQueue);
+   Window->Parent = ParentWindow;
+   
+   if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle)))
+   {
+      Window->hOwner = OwnerWindowHandle;
+      HasOwner = TRUE;
+   }
+   else
+   {
+      Window->hOwner = NULL;
+      HasOwner = FALSE;
+   }
+   
+   Window->UserData = 0;
+   
+   if ((((DWORD)Class->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
+         && (((DWORD)Class->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000))
+   {
+      Window->Unicode = bUnicodeWindow;
+   }
+   else
+   {
+      Window->Unicode = Class->Unicode;
+   }
+   Window->WndProcA = Class->lpfnWndProcA;
+   Window->WndProcW = Class->lpfnWndProcW;
+   Window->OwnerThread = PsGetCurrentThread();
+   Window->FirstChild = NULL;
+   Window->LastChild = NULL;
+   Window->PrevSibling = NULL;
+   Window->NextSibling = NULL;
+   Window->ExtraDataSize = Class->cbWndExtra;
+
+   /* extra window data */
+   if (Class->cbWndExtra)
+      Window->ExtraData = (PCHAR)(Window + 1);
+
+   InitializeListHead(&Window->PropListHead);
+   InitializeListHead(&Window->WndObjListHead);
+
+   if (NULL != WindowName->Buffer)
+   {
+      Window->WindowName.MaximumLength = WindowName->MaximumLength;
+      Window->WindowName.Length = WindowName->Length;
+      Window->WindowName.Buffer = ExAllocatePoolWithTag(PagedPool, WindowName->MaximumLength,
+                                  TAG_STRING);
+      if (NULL == Window->WindowName.Buffer)
+      {
+         DPRINT1("Failed to allocate mem for window name\n");
+         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+         RETURN( NULL);
+      }
+      RtlCopyMemory(Window->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength);
+   }
+   else
+   {
+      RtlInitUnicodeString(&Window->WindowName, NULL);
+   }
+
+
+   /*
+    * This has been tested for WS_CHILD | WS_VISIBLE.  It has not been
+    * tested for WS_POPUP
+    */
+   if ((dwExStyle & WS_EX_DLGMODALFRAME) ||
+         ((!(dwExStyle & WS_EX_STATICEDGE)) &&
+          (dwStyle & (WS_DLGFRAME | WS_THICKFRAME))))
+      dwExStyle |= WS_EX_WINDOWEDGE;
+   else
+      dwExStyle &= ~WS_EX_WINDOWEDGE;
+
+   /* Correct the window style. */
+   if (!(dwStyle & WS_CHILD))
+   {
+      dwStyle |= WS_CLIPSIBLINGS;
+      DPRINT("3: Style is now %lx\n", dwStyle);
       if (!(dwStyle & WS_POPUP))
-       {
-         WindowObject->Style |= WS_CAPTION;
-          WindowObject->Flags |= WINDOWOBJECT_NEED_SIZE;
-          DPRINT("4: Style is now %lx\n", WindowObject->Style);
-       }
-    }
-  
-  /* create system menu */
-  if((WindowObject->Style & WS_SYSMENU) &&
-     (WindowObject->Style & WS_CAPTION) == WS_CAPTION)
-  {
-    SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE);
-    if(SystemMenu)
-    {
-      WindowObject->SystemMenu = SystemMenu->MenuInfo.Self;
-      IntReleaseMenuObject(SystemMenu);
-    }
-  }
-  
-  /* Insert the window into the thread's window list. */
-  IntLockThreadWindows(PsGetWin32Thread());
-  InsertTailList (&PsGetWin32Thread()->WindowListHead, 
-                 &WindowObject->ThreadListEntry);
-  IntUnLockThreadWindows(PsGetWin32Thread());
-
-  /* Allocate a DCE for this window. */
-  if (dwStyle & CS_OWNDC)
-    {
-      WindowObject->Dce = DceAllocDCE(WindowObject->Self, DCE_WINDOW_DC);
-    }
-  /* FIXME:  Handle "CS_CLASSDC" */
-
-  Pos.x = x;
-  Pos.y = y;
-  Size.cx = nWidth;
-  Size.cy = nHeight;
-
-  /* call hook */
-  Cs.lpCreateParams = lpParam;
-  Cs.hInstance = hInstance;
-  Cs.hMenu = hMenu;
-  Cs.hwndParent = ParentWindowHandle;
-  Cs.cx = Size.cx;
-  Cs.cy = Size.cy;
-  Cs.x = Pos.x;
-  Cs.y = Pos.y;
-  Cs.style = dwStyle;
-  Cs.lpszName = (LPCWSTR) WindowName;
-  Cs.lpszClass = (LPCWSTR) ClassName;
-  Cs.dwExStyle = dwExStyle;
-  CbtCreate.lpcs = &Cs;
-  CbtCreate.hwndInsertAfter = HWND_TOP;
-  if (HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
-    {
-      if (NULL != ParentWindow)
-        {
-          IntReleaseWindowObject(ParentWindow);
-        }
-      
-      /* FIXME - Delete window object and remove it from the thread windows list */
-      /* FIXME - delete allocated DCE */
-      
-      ClassDereferenceObject(ClassObject);
-      DPRINT1("CBT-hook returned !0\n");
-      return (HWND) NULL;
-    }
-
-  x = Cs.x;
-  y = Cs.y;
-  nWidth = Cs.cx;
-  nHeight = Cs.cy;
-
-  /* default positioning for overlapped windows */
-  if(!(WindowObject->Style & (WS_POPUP | WS_CHILD)))
-  {
-    RECT rc, WorkArea;
-    PRTL_USER_PROCESS_PARAMETERS ProcessParams;
-    BOOL CalculatedDefPosSize = FALSE;
-    
-    IntGetDesktopWorkArea(WindowObject->OwnerThread->Tcb.Win32Thread->Desktop, &WorkArea);
-    
-    rc = WorkArea;
-    ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
-    
-    if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
-    {
-      CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, WindowObject, &rc, TRUE);
-      
-      if(ProcessParams->dwFlags & STARTF_USEPOSITION)
       {
-        ProcessParams->dwFlags &= ~STARTF_USEPOSITION;
-        Pos.x = WorkArea.left + ProcessParams->dwX;
-        Pos.y = WorkArea.top + ProcessParams->dwY;
+         dwStyle |= WS_CAPTION;
+         Window->Flags |= WINDOWOBJECT_NEED_SIZE;
+         DPRINT("4: Style is now %lx\n", dwStyle);
       }
-      else
+   }
+
+   /* create system menu */
+   if((dwStyle & WS_SYSMENU) &&
+         (dwStyle & WS_CAPTION) == WS_CAPTION)
+   {
+      SystemMenu = IntGetSystemMenu(Window, TRUE, TRUE);
+      if(SystemMenu)
       {
-        Pos.x = rc.left;
-        Pos.y = rc.top;
+         Window->SystemMenu = SystemMenu->MenuInfo.Self;
+         IntReleaseMenuObject(SystemMenu);
       }
-      
-      /* According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
-         y is something else */
-      if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16)
+   }
+
+   /* Insert the window into the thread's window list. */
+   InsertTailList (&PsGetWin32Thread()->WindowListHead, &Window->ThreadListEntry);
+
+   /* Allocate a DCE for this window. */
+   if (dwStyle & CS_OWNDC)
+   {
+      Window->Dce = DceAllocDCE(Window, DCE_WINDOW_DC);
+   }
+   /* FIXME:  Handle "CS_CLASSDC" */
+
+   Pos.x = x;
+   Pos.y = y;
+   Size.cx = nWidth;
+   Size.cy = nHeight;
+
+   Window->ExStyle = dwExStyle;
+   Window->Style = dwStyle & ~WS_VISIBLE;
+
+   /* call hook */
+   Cs.lpCreateParams = lpParam;
+   Cs.hInstance = hInstance;
+   Cs.hMenu = hMenu;
+   Cs.hwndParent = ParentWindowHandle;
+   Cs.cx = Size.cx;
+   Cs.cy = Size.cy;
+   Cs.x = Pos.x;
+   Cs.y = Pos.y;
+   Cs.style = Window->Style;
+   Cs.lpszName = (LPCWSTR) WindowName;
+   Cs.lpszClass = (LPCWSTR) ClassName;
+   Cs.dwExStyle = dwExStyle;
+   CbtCreate.lpcs = &Cs;
+   CbtCreate.hwndInsertAfter = HWND_TOP;
+   if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
+   {
+      /* FIXME - Delete window object and remove it from the thread windows list */
+      /* FIXME - delete allocated DCE */
+      DPRINT1("CBT-hook returned !0\n");
+      RETURN( (HWND) NULL);
+   }
+
+   x = Cs.x;
+   y = Cs.y;
+   nWidth = Cs.cx;
+   nHeight = Cs.cy;
+
+   /* default positioning for overlapped windows */
+   if(!(Window->Style & (WS_POPUP | WS_CHILD)))
+   {
+      RECT rc, WorkArea;
+      PRTL_USER_PROCESS_PARAMETERS ProcessParams;
+      BOOL CalculatedDefPosSize = FALSE;
+
+      IntGetDesktopWorkArea(((PW32THREAD)Window->OwnerThread->Tcb.Win32Thread)->Desktop, &WorkArea);
+
+      rc = WorkArea;
+      ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
+
+      if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
       {
-        dwShowMode = y;
+         CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, Window, &rc, TRUE);
+
+         if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
+         {
+            ProcessParams->WindowFlags &= ~STARTF_USEPOSITION;
+            Pos.x = WorkArea.left + ProcessParams->StartingX;
+            Pos.y = WorkArea.top + ProcessParams->StartingY;
+         }
+         else
+         {
+            Pos.x = rc.left;
+            Pos.y = rc.top;
+         }
+
+         /* According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
+            y is something else */
+         if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16)
+         {
+            dwShowMode = y;
+         }
       }
-    }
-    if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
-    {
-      if(!CalculatedDefPosSize)
+      if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
       {
-        IntCalcDefPosSize(ParentWindow, WindowObject, &rc, FALSE);
+         if(!CalculatedDefPosSize)
+         {
+            IntCalcDefPosSize(ParentWindow, Window, &rc, FALSE);
+         }
+         if(ProcessParams->WindowFlags & STARTF_USESIZE)
+         {
+            ProcessParams->WindowFlags &= ~STARTF_USESIZE;
+            Size.cx = ProcessParams->CountX;
+            Size.cy = ProcessParams->CountY;
+         }
+         else
+         {
+            Size.cx = rc.right - rc.left;
+            Size.cy = rc.bottom - rc.top;
+         }
+
+         /* move the window if necessary */
+         if(Pos.x > rc.left)
+            Pos.x = max(rc.left, 0);
+         if(Pos.y > rc.top)
+            Pos.y = max(rc.top, 0);
       }
-      if(ProcessParams->dwFlags & STARTF_USESIZE)
+   }
+   else
+   {
+      /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
+      if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
       {
-        ProcessParams->dwFlags &= ~STARTF_USESIZE;
-        Size.cx = ProcessParams->dwXSize;
-        Size.cy = ProcessParams->dwYSize;
+         Pos.x = 0;
+         Pos.y = 0;
       }
-      else
+      if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
       {
-        Size.cx = rc.right - rc.left;
-        Size.cy = rc.bottom - rc.top;
+         Size.cx = 0;
+         Size.cy = 0;
       }
-      
-      /* move the window if necessary */
-      if(Pos.x > rc.left)
-        Pos.x = max(rc.left, 0);
-      if(Pos.y > rc.top)
-        Pos.y = max(rc.top, 0);
-    }
-  }
-  else
-  {
-    /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
-    if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
-    {
-      Pos.x = 0;
-      Pos.y = 0;
-    }
-    if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
-    {
-      Size.cx = 0;
-      Size.cy = 0;
-    }
-  }
-
-  /* Initialize the window dimensions. */
-  WindowObject->WindowRect.left = Pos.x;
-  WindowObject->WindowRect.top = Pos.y;
-  WindowObject->WindowRect.right = Pos.x + Size.cx;
-  WindowObject->WindowRect.bottom = Pos.y + Size.cy;
-  if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow)
-    {
-      IntGdiOffsetRect(&(WindowObject->WindowRect), ParentWindow->ClientRect.left,
-                      ParentWindow->ClientRect.top);
-    }
-  WindowObject->ClientRect = WindowObject->WindowRect;
-
-  /*
-   * Get the size and position of the window.
-   */
-  if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
-    {
+   }
+
+   /* Initialize the window dimensions. */
+   Window->WindowRect.left = Pos.x;
+   Window->WindowRect.top = Pos.y;
+   Window->WindowRect.right = Pos.x + Size.cx;
+   Window->WindowRect.bottom = Pos.y + Size.cy;
+   if (0 != (Window->Style & WS_CHILD) && ParentWindow)
+   {
+      IntGdiOffsetRect(&(Window->WindowRect), ParentWindow->ClientRect.left,
+                       ParentWindow->ClientRect.top);
+   }
+   Window->ClientRect = Window->WindowRect;
+
+   /*
+    * Get the size and position of the window.
+    */
+   if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
+   {
       POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-     
+
       /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
-      WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
-                         &MaxTrack);
-      if (MaxSize.x < nWidth) nWidth = MaxSize.x;
-      if (MaxSize.y < nHeight) nHeight = MaxSize.y;
-      if (nWidth < MinTrack.x ) nWidth = MinTrack.x;
-      if (nHeight < MinTrack.y ) nHeight = MinTrack.y;
-      if (nWidth < 0) nWidth = 0;
-      if (nHeight < 0) nHeight = 0;
-    }
-
-  WindowObject->WindowRect.left = Pos.x;
-  WindowObject->WindowRect.top = Pos.y;
-  WindowObject->WindowRect.right = Pos.x + Size.cx;
-  WindowObject->WindowRect.bottom = Pos.y + Size.cy;
-  if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow)
-    {
-      IntGdiOffsetRect(&(WindowObject->WindowRect), ParentWindow->ClientRect.left,
-                      ParentWindow->ClientRect.top);
-    }
-  WindowObject->ClientRect = WindowObject->WindowRect;
-
-  /* FIXME: Initialize the window menu. */
-
-  /* Send a NCCREATE message. */
-  Cs.cx = Size.cx;
-  Cs.cy = Size.cy;
-  Cs.x = Pos.x;
-  Cs.y = Pos.y;
-
-  DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
-  DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
-  DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n");
-  Result = IntSendMessage(WindowObject->Self, WM_NCCREATE, 0, (LPARAM) &Cs);
-  if (!Result)
-    {
+      co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack,
+                             &MaxTrack);
+      if (MaxSize.x < Size.cx)
+         Size.cx = MaxSize.x;
+      if (MaxSize.y < Size.cy)
+         Size.cy = MaxSize.y;
+      if (Size.cx < MinTrack.x )
+         Size.cx = MinTrack.x;
+      if (Size.cy < MinTrack.y )
+         Size.cy = MinTrack.y;
+      if (Size.cx < 0)
+         Size.cx = 0;
+      if (Size.cy < 0)
+         Size.cy = 0;
+   }
+
+   Window->WindowRect.left = Pos.x;
+   Window->WindowRect.top = Pos.y;
+   Window->WindowRect.right = Pos.x + Size.cx;
+   Window->WindowRect.bottom = Pos.y + Size.cy;
+   if (0 != (Window->Style & WS_CHILD) && ParentWindow)
+   {
+      IntGdiOffsetRect(&(Window->WindowRect), ParentWindow->ClientRect.left,
+                       ParentWindow->ClientRect.top);
+   }
+   Window->ClientRect = Window->WindowRect;
+
+   /* FIXME: Initialize the window menu. */
+
+   /* Send a NCCREATE message. */
+   Cs.cx = Size.cx;
+   Cs.cy = Size.cy;
+   Cs.x = Pos.x;
+   Cs.y = Pos.y;
+
+   DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
+   DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, Size.cx, Size.cy);
+   DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n");
+   Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) &Cs);
+   if (!Result)
+   {
       /* FIXME: Cleanup. */
-      if (NULL != ParentWindow)
-        {
-          IntReleaseWindowObject(ParentWindow);
-        }
       DPRINT("IntCreateWindowEx(): NCCREATE message failed.\n");
-      return((HWND)0);
-    }
-  /* Calculate the non-client size. */
-  MaxPos.x = WindowObject->WindowRect.left;
-  MaxPos.y = WindowObject->WindowRect.top;
-  DPRINT("IntCreateWindowEx(): About to get non-client size.\n");
-  /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
-  Result = WinPosGetNonClientSize(WindowObject->Self, 
-                                 &WindowObject->WindowRect,
-                                 &WindowObject->ClientRect);
-  IntGdiOffsetRect(&WindowObject->WindowRect, 
-                MaxPos.x - WindowObject->WindowRect.left,
-                MaxPos.y - WindowObject->WindowRect.top);
-
-  if (NULL != ParentWindow)
-    {
+      RETURN((HWND)0);
+   }
+
+   /* Calculate the non-client size. */
+   MaxPos.x = Window->WindowRect.left;
+   MaxPos.y = Window->WindowRect.top;
+   DPRINT("IntCreateWindowEx(): About to get non-client size.\n");
+   /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
+   Result = co_WinPosGetNonClientSize(Window,
+                                      &Window->WindowRect,
+                                      &Window->ClientRect);
+
+                                      
+   IntGdiOffsetRect(&Window->WindowRect,
+                    MaxPos.x - Window->WindowRect.left,
+                    MaxPos.y - Window->WindowRect.top);
+
+   if (NULL != ParentWindow)
+   {
       /* link the window into the parent's child list */
       if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
-        {
-          PWINDOW_OBJECT PrevSibling;
-          IntLockRelatives(ParentWindow);
-          if((PrevSibling = ParentWindow->LastChild))
-            IntReferenceWindowObject(PrevSibling);
-          IntUnLockRelatives(ParentWindow);
-          /* link window as bottom sibling */
-          IntLinkWindow(WindowObject, ParentWindow, PrevSibling /*prev sibling*/);
-          if(PrevSibling)
-            IntReleaseWindowObject(PrevSibling);
-        }
+      {
+         PWINDOW_OBJECT PrevSibling;
+         
+         PrevSibling = ParentWindow->LastChild;
+         
+         /* link window as bottom sibling */
+         IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/);
+      }
       else
-        {
-          /* link window as top sibling (but after topmost siblings) */
-          PWINDOW_OBJECT InsertAfter, Sibling;
-          if (0 == (dwExStyle & WS_EX_TOPMOST))
-            {
-              IntLockRelatives(ParentWindow);
-              InsertAfter = NULL;
-              Sibling = ParentWindow->FirstChild;
-              while (NULL != Sibling && 0 != (Sibling->ExStyle & WS_EX_TOPMOST))
-                {
-                  InsertAfter = Sibling;
-                  Sibling = Sibling->NextSibling;
-                }
-              IntUnLockRelatives(ParentWindow);
-            }
-          else
-            {
-              InsertAfter = NULL;
-            }
-          if (NULL != InsertAfter)
-            {
-              IntReferenceWindowObject(InsertAfter);
-            }
-          IntLinkWindow(WindowObject, ParentWindow, InsertAfter /* prev sibling */);
-          if (NULL != InsertAfter)
+      {
+         /* link window as top sibling (but after topmost siblings) */
+         PWINDOW_OBJECT InsertAfter, Sibling;
+         if (!(dwExStyle & WS_EX_TOPMOST))
+         {
+            InsertAfter = NULL;
+            Sibling = ParentWindow->FirstChild;
+            while (Sibling && (Sibling->ExStyle & WS_EX_TOPMOST))
             {
-              IntReleaseWindowObject(InsertAfter);
+               InsertAfter = Sibling;
+               Sibling = Sibling->NextSibling;
             }
-        }
-    }
-
-  /* Send the WM_CREATE message. */
-  DPRINT("IntCreateWindowEx(): about to send CREATE message.\n");
-  Result = IntSendMessage(WindowObject->Self, WM_CREATE, 0, (LPARAM) &Cs);
-  if (Result == (LRESULT)-1)
-    {
+         }
+         else
+         {
+            InsertAfter = NULL;
+         }
+         
+         IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */);
+
+      }
+   }
+
+   /* Send the WM_CREATE message. */
+   DPRINT("IntCreateWindowEx(): about to send CREATE message.\n");
+   Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) &Cs);
+
+   
+   if (Result == (LRESULT)-1)
+   {
       /* FIXME: Cleanup. */
-      if (NULL != ParentWindow)
-        {
-          IntReleaseWindowObject(ParentWindow);
-        }
-      ClassDereferenceObject(ClassObject);
       DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
-      return((HWND)0);
-    } 
-  
-  /* Send move and size messages. */
-  if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE))
-    {
+      RETURN((HWND)0);
+   }
+
+
+   /* Send move and size messages. */
+   if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE))
+   {
       LONG lParam;
 
       DPRINT("IntCreateWindow(): About to send WM_SIZE\n");
 
-      if ((WindowObject->ClientRect.right - WindowObject->ClientRect.left) < 0 ||
-          (WindowObject->ClientRect.bottom - WindowObject->ClientRect.top) < 0)
+      if ((Window->ClientRect.right - Window->ClientRect.left) < 0 ||
+            (Window->ClientRect.bottom - Window->ClientRect.top) < 0)
       {
          DPRINT("Sending bogus WM_SIZE\n");
       }
-      
-      lParam = MAKE_LONG(WindowObject->ClientRect.right - 
-                 WindowObject->ClientRect.left,
-                 WindowObject->ClientRect.bottom - 
-                 WindowObject->ClientRect.top);
-      IntSendMessage(WindowObject->Self, WM_SIZE, SIZE_RESTORED, 
-          lParam);
+
+
+      lParam = MAKE_LONG(Window->ClientRect.right -
+                         Window->ClientRect.left,
+                         Window->ClientRect.bottom -
+                         Window->ClientRect.top);
+      co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED,
+                        lParam);
+
 
       DPRINT("IntCreateWindow(): About to send WM_MOVE\n");
 
-      if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow)
-       {
-         lParam = MAKE_LONG(WindowObject->ClientRect.left - ParentWindow->ClientRect.left,
-             WindowObject->ClientRect.top - ParentWindow->ClientRect.top);
-       }
+      if (0 != (Window->Style & WS_CHILD) && ParentWindow)
+      {
+         lParam = MAKE_LONG(Window->ClientRect.left - ParentWindow->ClientRect.left,
+                            Window->ClientRect.top - ParentWindow->ClientRect.top);
+      }
       else
-       {
-         lParam = MAKE_LONG(WindowObject->ClientRect.left,
-             WindowObject->ClientRect.top);
-       }
-      IntSendMessage(WindowObject->Self, WM_MOVE, 0, lParam);
+      {
+         lParam = MAKE_LONG(Window->ClientRect.left,
+                            Window->ClientRect.top);
+      }
+
+      
+      co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam);
+
 
       /* Call WNDOBJ change procs */
-      IntEngWindowChanged(WindowObject, WOC_RGN_CLIENT);
-    }
+      IntEngWindowChanged(Window, WOC_RGN_CLIENT);
 
-  /* Show or maybe minimize or maximize the window. */
-  if (WindowObject->Style & (WS_MINIMIZE | WS_MAXIMIZE))
-    {
+      
+   }
+
+   /* Show or maybe minimize or maximize the window. */
+   if (Window->Style & (WS_MINIMIZE | WS_MAXIMIZE))
+   {
       RECT NewPos;
       UINT16 SwFlag;
 
-      SwFlag = (WindowObject->Style & WS_MINIMIZE) ? SW_MINIMIZE : 
-       SW_MAXIMIZE;
-      WinPosMinMaximize(WindowObject, SwFlag, &NewPos);
-      SwFlag = 
-       ((WindowObject->Style & WS_CHILD) || NtUserGetActiveWindow()) ?
-       SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
-       SWP_NOZORDER | SWP_FRAMECHANGED;
+      SwFlag = (Window->Style & WS_MINIMIZE) ? SW_MINIMIZE :
+               SW_MAXIMIZE;
+      co_WinPosMinMaximize(Window, SwFlag, &NewPos);
+      SwFlag =
+         ((Window->Style & WS_CHILD) || UserGetActiveWindow()) ?
+         SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
+         SWP_NOZORDER | SWP_FRAMECHANGED;
       DPRINT("IntCreateWindow(): About to minimize/maximize\n");
       DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom);
-      WinPosSetWindowPos(WindowObject->Self, 0, NewPos.left, NewPos.top,
-                        NewPos.right, NewPos.bottom, SwFlag);
-    }
-
-  /* Notify the parent window of a new child. */
-  if ((WindowObject->Style & WS_CHILD) &&
-      (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
-    {
+      co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
+                            NewPos.right, NewPos.bottom, SwFlag);
+   }
+
+   /* Notify the parent window of a new child. */
+   if ((Window->Style & WS_CHILD) &&
+         (!(Window->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
+   {
       DPRINT("IntCreateWindow(): About to notify parent\n");
-      IntSendMessage(ParentWindow->Self,
-                     WM_PARENTNOTIFY, 
-                     MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
-                     (LPARAM)WindowObject->Self);
-    }
+      co_IntSendMessage(ParentWindow->hSelf,
+                        WM_PARENTNOTIFY,
+                        MAKEWPARAM(WM_CREATE, Window->IDMenu),
+                        (LPARAM)Window->hSelf);
+   }
 
-  if ((!hWndParent) && (!HasOwner)) {
+   if ((!hWndParent) && (!HasOwner))
+   {
       DPRINT("Sending CREATED notify\n");
-      IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Handle);
-  } else {
+      co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
+   }
+   else
+   {
       DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner);
-  }
+   }
 
-  if (NULL != ParentWindow)
-    {
-      IntReleaseWindowObject(ParentWindow);
-    }
-  
-  /* Initialize and show the window's scrollbars */
-  if (WindowObject->Style & WS_VSCROLL)
-  {
-     NtUserShowScrollBar(WindowObject->Self, SB_VERT, TRUE);
-  }
-  if (WindowObject->Style & WS_HSCROLL)
-  {
-     NtUserShowScrollBar(WindowObject->Self, SB_HORZ, TRUE);
-  }
-  
-  if (dwStyle & WS_VISIBLE)
-    {
+   /* Initialize and show the window's scrollbars */
+   if (Window->Style & WS_VSCROLL)
+   {
+      co_UserShowScrollBar(Window, SB_VERT, TRUE);
+   }
+   if (Window->Style & WS_HSCROLL)
+   {
+      co_UserShowScrollBar(Window, SB_HORZ, TRUE);
+   }
+
+   if (dwStyle & WS_VISIBLE)
+   {
       DPRINT("IntCreateWindow(): About to show window\n");
-      WinPosShowWindow(WindowObject->Self, dwShowMode);
-    }
+      co_WinPosShowWindow(Window, dwShowMode);
+   }
+
+   DPRINT("IntCreateWindow(): = %X\n", hWnd);
+   DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
+   RETURN(hWnd);
 
-  DPRINT("IntCreateWindow(): = %X\n", Handle);
-  DPRINT("WindowObject->SystemMenu = 0x%x\n", WindowObject->SystemMenu);
-  return((HWND)Handle);
+CLEANUP:
+   if (Window) UserDerefObjectCo(Window);
+   if (ParentWindow) UserDerefObjectCo(ParentWindow);
+   if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return 0) */
+   END_CLEANUP;
 }
 
 HWND STDCALL
 NtUserCreateWindowEx(DWORD dwExStyle,
-                    PUNICODE_STRING UnsafeClassName,
-                    PUNICODE_STRING UnsafeWindowName,
-                    DWORD dwStyle,
-                    LONG x,
-                    LONG y,
-                    LONG nWidth,
-                    LONG nHeight,
-                    HWND hWndParent,
-                    HMENU hMenu,
-                    HINSTANCE hInstance,
-                    LPVOID lpParam,
-                    DWORD dwShowMode,
-                    BOOL bUnicodeWindow)
+                     PUNICODE_STRING UnsafeClassName,
+                     PUNICODE_STRING UnsafeWindowName,
+                     DWORD dwStyle,
+                     LONG x,
+                     LONG y,
+                     LONG nWidth,
+                     LONG nHeight,
+                     HWND hWndParent,
+                     HMENU hMenu,
+                     HINSTANCE hInstance,
+                     LPVOID lpParam,
+                     DWORD dwShowMode,
+                     BOOL bUnicodeWindow)
 {
-  NTSTATUS Status;
-  UNICODE_STRING WindowName;
-  UNICODE_STRING ClassName;
-  HWND NewWindow;
+   NTSTATUS Status;
+   UNICODE_STRING WindowName;
+   UNICODE_STRING ClassName;
+   HWND NewWindow;
+   DECLARE_RETURN(HWND);
 
-  DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
+   DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
+   UserEnterExclusive();
 
-  /* Get the class name (string or atom) */
-  Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING));
-  if (! NT_SUCCESS(Status))
-    {
+   /* Get the class name (string or atom) */
+   Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING));
+   if (! NT_SUCCESS(Status))
+   {
       SetLastNtError(Status);
-      return NULL;
-    }
-  if (! IS_ATOM(ClassName.Buffer))
-    {
+      RETURN( NULL);
+   }
+   if (! IS_ATOM(ClassName.Buffer))
+   {
       Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
       if (! NT_SUCCESS(Status))
-        {
-          SetLastNtError(Status);
-          return NULL;
-        }
-    }
-  
-  /* safely copy the window name */
-  if (NULL != UnsafeWindowName)
-    {
+      {
+         SetLastNtError(Status);
+         RETURN( NULL);
+      }
+   }
+
+   /* safely copy the window name */
+   if (NULL != UnsafeWindowName)
+   {
       Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName);
       if (! NT_SUCCESS(Status))
-        {
-          if (! IS_ATOM(ClassName.Buffer))
-            {
-              RtlFreeUnicodeString(&ClassName);
-            }
-          SetLastNtError(Status);
-          return NULL;
-        }
-    }
-  else
-    {
+      {
+         if (! IS_ATOM(ClassName.Buffer))
+         {
+            RtlFreeUnicodeString(&ClassName);
+         }
+         SetLastNtError(Status);
+         RETURN( NULL);
+      }
+   }
+   else
+   {
       RtlInitUnicodeString(&WindowName, NULL);
-    }
+   }
 
-  NewWindow = IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight,
-                               hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow);
+   NewWindow = co_IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight,
+                                    hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow);
 
-  RtlFreeUnicodeString(&WindowName);
-  if (! IS_ATOM(ClassName.Buffer))
-    {
+   RtlFreeUnicodeString(&WindowName);
+   if (! IS_ATOM(ClassName.Buffer))
+   {
       RtlFreeUnicodeString(&ClassName);
-    }
+   }
 
-  return NewWindow;
+   RETURN( NewWindow);
+
+CLEANUP:
+   DPRINT("Leave NtUserCreateWindowEx, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -2122,174 +2014,199 @@ NtUserCreateWindowEx(DWORD dwExStyle,
  */
 HDWP STDCALL
 NtUserDeferWindowPos(HDWP WinPosInfo,
-                    HWND Wnd,
-                    HWND WndInsertAfter,
-                    int x,
-         int y,
-         int cx,
-         int cy,
-                    UINT Flags)
+                     HWND Wnd,
+                     HWND WndInsertAfter,
+                     int x,
+                     int y,
+                     int cx,
+                     int cy,
+                     UINT Flags)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-NtUserDestroyWindow(HWND Wnd)
+BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 {
-  PWINDOW_OBJECT Window;
-  BOOLEAN isChild;
+   BOOLEAN isChild;
 
-  Window = IntGetWindowObject(Wnd);
-  if (Window == NULL)
-    {
-      return FALSE;
-    }
+   ASSERT_REFS_CO(Window); //fixme: temp hack?
 
-  /* Check for owner thread and desktop window */
-  if ((Window->OwnerThread != PsGetCurrentThread()) || IntIsDesktopWindow(Window))
-    {
-      IntReleaseWindowObject(Window);
+   /* Check for owner thread */
+   if ((Window->OwnerThread != PsGetCurrentThread()))
+   {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return FALSE;
-    }
+   }
 
-  /* Look whether the focus is within the tree of windows we will
-   * be destroying.
-   */
-  if (!WinPosShowWindow(Wnd, SW_HIDE))
-    {
-      if (NtUserGetActiveWindow() == Wnd)
-        {
-          WinPosActivateOtherWindow(Window);
-        }
-    }
-  IntLockMessageQueue(Window->MessageQueue);
-  if (Window->MessageQueue->ActiveWindow == Window->Self)
-    Window->MessageQueue->ActiveWindow = NULL;
-  if (Window->MessageQueue->FocusWindow == Window->Self)
-    Window->MessageQueue->FocusWindow = NULL;
-  if (Window->MessageQueue->CaptureWindow == Window->Self)
-    Window->MessageQueue->CaptureWindow = NULL;
-  IntUnLockMessageQueue(Window->MessageQueue);
-
-  /* Call hooks */
+   /* Look whether the focus is within the tree of windows we will
+    * be destroying.
+    */
+   if (!co_WinPosShowWindow(Window, SW_HIDE))
+   {
+      if (UserGetActiveWindow() == Window->hSelf)
+      {
+         co_WinPosActivateOtherWindow(Window);
+      }
+   }
+
+   if (Window->MessageQueue->ActiveWindow == Window->hSelf)
+      Window->MessageQueue->ActiveWindow = NULL;
+   if (Window->MessageQueue->FocusWindow == Window->hSelf)
+      Window->MessageQueue->FocusWindow = NULL;
+   if (Window->MessageQueue->CaptureWindow == Window->hSelf)
+      Window->MessageQueue->CaptureWindow = NULL;
+
+   IntDereferenceMessageQueue(Window->MessageQueue);
+   /* Call hooks */
 #if 0 /* FIXME */
-  if (HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hwnd, 0, TRUE))
-    {
-    return FALSE;
-    }
+
+   if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hwnd, 0, TRUE))
+   {
+      return FALSE;
+   }
 #endif
 
-  IntEngWindowChanged(Window, WOC_DELETE);
-  isChild = (0 != (Window->Style & WS_CHILD));
+   IntEngWindowChanged(Window, WOC_DELETE);
+   isChild = (0 != (Window->Style & WS_CHILD));
 
 #if 0 /* FIXME */
-  if (isChild)
-    {
+
+   if (isChild)
+   {
       if (! USER_IsExitingThread(GetCurrentThreadId()))
-       {
-         send_parent_notify(hwnd, WM_DESTROY);
-       }
-    }
-  else if (NULL != GetWindow(Wnd, GW_OWNER))
-    {
-      HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
+      {
+         send_parent_notify(hwnd, WM_DESTROY);
+      }
+   }
+   else if (NULL != GetWindow(Wnd, GW_OWNER))
+   {
+      co_HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
       /* FIXME: clean up palette - see "Internals" p.352 */
-    }
+   }
 #endif
 
-  if (!IntIsWindow(Wnd))
-    {
-    return TRUE;
-    }
-  
-  /* Recursively destroy owned windows */
-  if (! isChild)
-    {
+   if (!IntIsWindow(Window->hSelf))
+   {
+      return TRUE;
+   }
+
+   /* Recursively destroy owned windows */
+   if (! isChild)
+   {
       for (;;)
-       {
-         BOOL GotOne = FALSE;
-         HWND *Children;
-         HWND *ChildHandle;
-         PWINDOW_OBJECT Child, Desktop;
-
-         Desktop = IntGetWindowObject(IntGetDesktopWindow());
-         Children = IntWinListChildren(Desktop);
-         IntReleaseWindowObject(Desktop);
-         if (Children)
-           {
-             for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
-               {
-                 Child = IntGetWindowObject(*ChildHandle);
-                 if (Child == NULL)
-                   continue;
-                 IntLockRelatives(Child);
-                 if (Child->Owner != Window->Self)
-                   {
-                     IntUnLockRelatives(Child);
-                     IntReleaseWindowObject(Child);
-                     continue;
-                   }
-                 IntUnLockRelatives(Child);
-                 if (IntWndBelongsToThread(Child, PsGetWin32Thread()))
-                   {
-                     IntReleaseWindowObject(Child);
-                     NtUserDestroyWindow(*ChildHandle);
-                     GotOne = TRUE;                  
-                     continue;
-                   }
-                 IntLockRelatives(Child);
-                 if (Child->Owner != NULL)
-                   {
-                     Child->Owner = NULL;
-                   }
-                 IntUnLockRelatives(Child);
-                 IntReleaseWindowObject(Child);
-               }
-             ExFreePool(Children);
-           }
-         if (! GotOne)
-           {
-             break;
-           }
-       }
-    }
-  
-  if (!IntIsWindow(Wnd))
-    {
-      IntReleaseWindowObject(Window);
+      {
+         BOOL GotOne = FALSE;
+         HWND *Children;
+         HWND *ChildHandle;
+         PWINDOW_OBJECT Child, Desktop;
+
+         Desktop = IntIsDesktopWindow(Window) ? Window :
+                   UserGetWindowObject(IntGetDesktopWindow());
+         Children = IntWinListChildren(Desktop);
+
+         if (Children)
+         {
+            for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
+            {
+               Child = UserGetWindowObject(*ChildHandle);
+               if (Child == NULL)
+                  continue;
+               if (Child->hOwner != Window->hSelf)
+               {
+                  continue;
+               }
+
+               if (IntWndBelongsToThread(Child, PsGetWin32Thread()))
+               {
+                  USER_REFERENCE_ENTRY ChildRef;
+                  UserRefObjectCo(Child, &ChildRef);//temp hack?
+                  co_UserDestroyWindow(Child);
+                  UserDerefObjectCo(Child);//temp hack?
+
+                  GotOne = TRUE;
+                  continue;
+               }
+
+               if (Child->hOwner != NULL)
+               {
+                  Child->hOwner = NULL;
+               }
+
+            }
+            ExFreePool(Children);
+         }
+         if (! GotOne)
+         {
+            break;
+         }
+      }
+   }
+
+   if (!IntIsWindow(Window->hSelf))
+   {
       return TRUE;
-    }
+   }
+
+   /* Destroy the window storage */
+   co_UserFreeWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
+
+   return TRUE;
+}
+
+
+
+
+/*
+ * @implemented
+ */
+BOOLEAN STDCALL
+NtUserDestroyWindow(HWND Wnd)
+{
+   PWINDOW_OBJECT Window;
+   DECLARE_RETURN(BOOLEAN);
+   BOOLEAN ret;
+   USER_REFERENCE_ENTRY Ref;
+
+   DPRINT("Enter NtUserDestroyWindow\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(Wnd)))
+   {
+      RETURN(FALSE);
+   }
 
-  /* Destroy the window storage */
-  IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
-  
-  IntReleaseWindowObject(Window);
-  return TRUE;
+   UserRefObjectCo(Window, &Ref);//faxme: dunno if win should be reffed during destroy..
+   ret = co_UserDestroyWindow(Window);
+   UserDerefObjectCo(Window);//faxme: dunno if win should be reffed during destroy..
+
+   RETURN(ret);
+   
+CLEANUP:
+   DPRINT("Leave NtUserDestroyWindow, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
+
 /*
  * @unimplemented
  */
 DWORD
 STDCALL
 NtUserDrawMenuBarTemp(
-  HWND hWnd,
-  HDC hDC,
-  PRECT hRect,
-  HMENU hMenu,
-  HFONT hFont)
+   HWND hWnd,
+   HDC hDC,
+   PRECT hRect,
+   HMENU hMenu,
+   HFONT hFont)
 {
-  /* we'll use this function just for caching the menu bar */
-  UNIMPLEMENTED
-  return 0;
+   /* we'll use this function just for caching the menu bar */
+   UNIMPLEMENTED
+   return 0;
 }
 
 
@@ -2298,11 +2215,11 @@ NtUserDrawMenuBarTemp(
  */
 DWORD STDCALL
 NtUserEndDeferWindowPosEx(DWORD Unknown0,
-                         DWORD Unknown1)
+                          DWORD Unknown1)
 {
-  UNIMPLEMENTED
-    
-  return 0;
+   UNIMPLEMENTED
+
+   return 0;
 }
 
 
@@ -2311,13 +2228,13 @@ NtUserEndDeferWindowPosEx(DWORD Unknown0,
  */
 DWORD STDCALL
 NtUserFillWindow(DWORD Unknown0,
-                DWORD Unknown1,
-                DWORD Unknown2,
-                DWORD Unknown3)
+                 DWORD Unknown1,
+                 DWORD Unknown2,
+                 DWORD Unknown3)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -2327,49 +2244,48 @@ IntFindWindow(PWINDOW_OBJECT Parent,
               RTL_ATOM ClassAtom,
               PUNICODE_STRING WindowName)
 {
-  BOOL CheckWindowName;
-  HWND *List, *phWnd;
-  HWND Ret = NULL;
-  
-  ASSERT(Parent);
-  
-  CheckWindowName = (WindowName && (WindowName->Length > 0));
-  
-  if((List = IntWinListChildren(Parent)))
-  {
-    phWnd = List;
-    if(ChildAfter)
-    {
-      /* skip handles before and including ChildAfter */
-      while(*phWnd && (*(phWnd++) != ChildAfter->Self));
-    }
-    
-    /* search children */
-    while(*phWnd)
-    {
-      PWINDOW_OBJECT Child;
-      if(!(Child = IntGetWindowObject(*(phWnd++))))
+   BOOL CheckWindowName;
+   HWND *List, *phWnd;
+   HWND Ret = NULL;
+
+   ASSERT(Parent);
+
+   CheckWindowName = (WindowName && (WindowName->Length > 0));
+
+   if((List = IntWinListChildren(Parent)))
+   {
+      phWnd = List;
+      if(ChildAfter)
       {
-        continue;
+         /* skip handles before and including ChildAfter */
+         while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+            ;
       }
-      
-      /* Do not send WM_GETTEXT messages in the kernel mode version!
-         The user mode version however calls GetWindowText() which will
-         send WM_GETTEXT messages to windows belonging to its processes */
-      if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), FALSE)) &&
-         (!ClassAtom || Child->Class->Atom == ClassAtom))
+
+      /* search children */
+      while(*phWnd)
       {
-        Ret = Child->Self;
-        IntReleaseWindowObject(Child);
-        break;
+         PWINDOW_OBJECT Child;
+         if(!(Child = UserGetWindowObject(*(phWnd++))))
+         {
+            continue;
+         }
+
+         /* Do not send WM_GETTEXT messages in the kernel mode version!
+            The user mode version however calls GetWindowText() which will
+            send WM_GETTEXT messages to windows belonging to its processes */
+         if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), TRUE)) &&
+               (!ClassAtom || Child->Class->Atom == ClassAtom))
+         {
+            Ret = Child->hSelf;
+            break;
+         }
+
       }
-      
-      IntReleaseWindowObject(Child);
-    }
-    ExFreePool(List);
-  }
-  
-  return Ret;
+      ExFreePool(List);
+   }
+
+   return Ret;
 }
 
 /*
@@ -2377,19 +2293,19 @@ IntFindWindow(PWINDOW_OBJECT Parent,
  *   Searches a window's children for a window with the specified
  *   class and name
  * ARGUMENTS:
- *   hwndParent            = The window whose childs are to be searched. 
- *                                       NULL = desktop
- *                                       HWND_MESSAGE = message-only windows
+ *   hwndParent     = The window whose childs are to be searched.
+ *       NULL = desktop
+ *       HWND_MESSAGE = message-only windows
  *
- *   hwndChildAfter = Search starts after this child window. 
- *                                       NULL = start from beginning
+ *   hwndChildAfter = Search starts after this child window.
+ *       NULL = start from beginning
  *
  *   ucClassName    = Class name to search for
- *                                       Reguired parameter.
+ *       Reguired parameter.
  *
  *   ucWindowName   = Window name
- *                                       ->Buffer == NULL = don't care
- *                       
+ *       ->Buffer == NULL = don't care
+ *
  * RETURNS:
  *   The HWND of the window if it was found, otherwise NULL
  */
@@ -2398,200 +2314,201 @@ IntFindWindow(PWINDOW_OBJECT Parent,
  */
 HWND STDCALL
 NtUserFindWindowEx(HWND hwndParent,
-                  HWND hwndChildAfter,
-                  PUNICODE_STRING ucClassName,
-                  PUNICODE_STRING ucWindowName)
+                   HWND hwndChildAfter,
+                   PUNICODE_STRING ucClassName,
+                   PUNICODE_STRING ucWindowName)
 {
-  PWINDOW_OBJECT Parent, ChildAfter;
-  UNICODE_STRING ClassName, WindowName;
-  NTSTATUS Status;
-  HWND Desktop, Ret = NULL;
-  RTL_ATOM ClassAtom;
-  
-  Desktop = IntGetCurrentThreadDesktopWindow();
-  
-  if(hwndParent == NULL)
-    hwndParent = Desktop;
-  /* FIXME
-  else if(hwndParent == HWND_MESSAGE)
-  {
-    hwndParent = IntGetMessageWindow();
-  }
-  */
-  
-  if(!(Parent = IntGetWindowObject(hwndParent)))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return NULL;
-  }
-  
-  ChildAfter = NULL;
-  if(hwndChildAfter && !(ChildAfter = IntGetWindowObject(hwndChildAfter)))
-  {
-    IntReleaseWindowObject(Parent);
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return NULL;
-  }
-  
-  /* copy the window name */
-  Status = IntSafeCopyUnicodeString(&WindowName, ucWindowName);
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    goto Cleanup3;
-  }
-  
-  /* safely copy the class name */
-  Status = MmCopyFromCaller(&ClassName, ucClassName, sizeof(UNICODE_STRING));
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    goto Cleanup2;
-  }
-  if(ClassName.Length > 0 && ClassName.Buffer)
-  {
-    WCHAR *buf;
-    /* safely copy the class name string (NULL terminated because class-lookup
-       depends on it... */
-    buf = ExAllocatePoolWithTag(PagedPool, ClassName.Length + sizeof(WCHAR), TAG_STRING);
-    if(!buf)
-    {
-      SetLastWin32Error(STATUS_INSUFFICIENT_RESOURCES);
-      goto Cleanup2;
-    }
-    Status = MmCopyFromCaller(buf, ClassName.Buffer, ClassName.Length);
-    if(!NT_SUCCESS(Status))
-    {
-      ExFreePool(buf);
+   PWINDOW_OBJECT Parent, ChildAfter;
+   UNICODE_STRING ClassName, WindowName;
+   NTSTATUS Status;
+   HWND Desktop, Ret = NULL;
+   RTL_ATOM ClassAtom;
+   DECLARE_RETURN(HWND);
+
+   DPRINT("Enter NtUserFindWindowEx\n");
+   UserEnterShared();
+
+   Desktop = IntGetCurrentThreadDesktopWindow();
+
+   if(hwndParent == NULL)
+      hwndParent = Desktop;
+   /* FIXME
+   else if(hwndParent == HWND_MESSAGE)
+   {
+     hwndParent = IntGetMessageWindow();
+   }
+   */
+
+   if(!(Parent = UserGetWindowObject(hwndParent)))
+   {
+      RETURN( NULL);
+   }
+
+   ChildAfter = NULL;
+   if(hwndChildAfter && !(ChildAfter = UserGetWindowObject(hwndChildAfter)))
+   {
+      RETURN( NULL);
+   }
+
+   /* copy the window name */
+   Status = IntSafeCopyUnicodeString(&WindowName, ucWindowName);
+   if(!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      goto Cleanup3;
+   }
+
+   /* safely copy the class name */
+   Status = MmCopyFromCaller(&ClassName, ucClassName, sizeof(UNICODE_STRING));
+   if(!NT_SUCCESS(Status))
+   {
       SetLastNtError(Status);
       goto Cleanup2;
-    }
-    ClassName.Buffer = buf;
-    /* make sure the string is null-terminated */
-    buf += ClassName.Length / sizeof(WCHAR);
-    *buf = L'\0';
-  }
-  
-  /* find the class object */
-  if(ClassName.Buffer)
-    {
+   }
+   if(ClassName.Length > 0 && ClassName.Buffer)
+   {
+      WCHAR *buf;
+      /* safely copy the class name string (NULL terminated because class-lookup
+         depends on it... */
+      buf = ExAllocatePoolWithTag(PagedPool, ClassName.Length + sizeof(WCHAR), TAG_STRING);
+      if(!buf)
+      {
+         SetLastWin32Error(STATUS_INSUFFICIENT_RESOURCES);
+         goto Cleanup2;
+      }
+      Status = MmCopyFromCaller(buf, ClassName.Buffer, ClassName.Length);
+      if(!NT_SUCCESS(Status))
+      {
+         ExFreePool(buf);
+         SetLastNtError(Status);
+         goto Cleanup2;
+      }
+      ClassName.Buffer = buf;
+      /* make sure the string is null-terminated */
+      buf += ClassName.Length / sizeof(WCHAR);
+      *buf = L'\0';
+   }
+
+   /* find the class object */
+   if(ClassName.Buffer)
+   {
       PWINSTATION_OBJECT WinStaObject;
 
       if (PsGetWin32Thread()->Desktop == NULL)
-        {
-          SetLastWin32Error(ERROR_INVALID_HANDLE);
-          goto Cleanup;
-        }
+      {
+         SetLastWin32Error(ERROR_INVALID_HANDLE);
+         goto Cleanup;
+      }
 
       WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
 
       Status = RtlLookupAtomInAtomTable(
-         WinStaObject->AtomTable,
-         ClassName.Buffer,
-         &ClassAtom);
+                  WinStaObject->AtomTable,
+                  ClassName.Buffer,
+                  &ClassAtom);
 
       if (!NT_SUCCESS(Status))
-        {
-          DPRINT1("Failed to lookup class atom!\n");
-          SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
-          goto Cleanup;
-        }
-  }
-  
-  if(Parent->Self == Desktop)
-  {
-    HWND *List, *phWnd;
-    PWINDOW_OBJECT TopLevelWindow;
-    BOOLEAN CheckWindowName;
-    BOOLEAN CheckClassName;
-    BOOLEAN WindowMatches;
-    BOOLEAN ClassMatches;
-    
-    /* windows searches through all top-level windows if the parent is the desktop
-       window */
-    
-    if((List = IntWinListChildren(Parent)))
-    {
-      phWnd = List;
-      
-      if(ChildAfter)
       {
-        /* skip handles before and including ChildAfter */
-        while(*phWnd && (*(phWnd++) != ChildAfter->Self));
+         DPRINT1("Failed to lookup class atom!\n");
+         SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+         goto Cleanup;
       }
-      
-      CheckWindowName = WindowName.Length > 0;
-      CheckClassName = ClassName.Buffer != NULL;
-      
-      /* search children */
-      while(*phWnd)
+   }
+
+   if(Parent->hSelf == Desktop)
+   {
+      HWND *List, *phWnd;
+      PWINDOW_OBJECT TopLevelWindow;
+      BOOLEAN CheckWindowName;
+      BOOLEAN CheckClassName;
+      BOOLEAN WindowMatches;
+      BOOLEAN ClassMatches;
+
+      /* windows searches through all top-level windows if the parent is the desktop
+         window */
+
+      if((List = IntWinListChildren(Parent)))
       {
-        if(!(TopLevelWindow = IntGetWindowObject(*(phWnd++))))
-        {
-          continue;
-        }
-        
-        /* Do not send WM_GETTEXT messages in the kernel mode version!
-           The user mode version however calls GetWindowText() which will
-           send WM_GETTEXT messages to windows belonging to its processes */
-        WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
-                        &WindowName, &TopLevelWindow->WindowName, FALSE);
-        ClassMatches = !CheckClassName ||
-                       ClassAtom == TopLevelWindow->Class->Atom;
-
-        if (WindowMatches && ClassMatches)
-        {
-          Ret = TopLevelWindow->Self;
-          IntReleaseWindowObject(TopLevelWindow);
-          break;
-        }
-        
-        if (IntFindWindow(TopLevelWindow, NULL, ClassAtom, &WindowName))
-        {
-          /* window returns the handle of the top-level window, in case it found
-             the child window */
-          Ret = TopLevelWindow->Self;
-          IntReleaseWindowObject(TopLevelWindow);
-          break;
-        }
-        
-        IntReleaseWindowObject(TopLevelWindow);
+         phWnd = List;
+
+         if(ChildAfter)
+         {
+            /* skip handles before and including ChildAfter */
+            while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+               ;
+         }
+
+         CheckWindowName = WindowName.Length > 0;
+         CheckClassName = ClassName.Buffer != NULL;
+
+         /* search children */
+         while(*phWnd)
+         {
+            if(!(TopLevelWindow = UserGetWindowObject(*(phWnd++))))
+            {
+               continue;
+            }
+
+            /* Do not send WM_GETTEXT messages in the kernel mode version!
+               The user mode version however calls GetWindowText() which will
+               send WM_GETTEXT messages to windows belonging to its processes */
+            WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
+                               &WindowName, &TopLevelWindow->WindowName, TRUE);
+            ClassMatches = !CheckClassName ||
+                           ClassAtom == TopLevelWindow->Class->Atom;
+
+            if (WindowMatches && ClassMatches)
+            {
+               Ret = TopLevelWindow->hSelf;
+               break;
+            }
+
+            if (IntFindWindow(TopLevelWindow, NULL, ClassAtom, &WindowName))
+            {
+               /* window returns the handle of the top-level window, in case it found
+                  the child window */
+               Ret = TopLevelWindow->hSelf;
+               break;
+            }
+
+         }
+         ExFreePool(List);
       }
-      ExFreePool(List);
-    }
-  }
-  else
-    Ret = IntFindWindow(Parent, ChildAfter, ClassAtom, &WindowName);
-  
+   }
+   else
+      Ret = IntFindWindow(Parent, ChildAfter, ClassAtom, &WindowName);
+
 #if 0
-  if(Ret == NULL && hwndParent == NULL && hwndChildAfter == NULL)
-  {
-    /* FIXME - if both hwndParent and hwndChildAfter are NULL, we also should
-               search the message-only windows. Should this also be done if
-               Parent is the desktop window??? */
-    PWINDOW_OBJECT MsgWindows;
-    
-    if((MsgWindows = IntGetWindowObject(IntGetMessageWindow())))
-    {
-      Ret = IntFindWindow(MsgWindows, ChildAfter, ClassAtom, &WindowName);
-      IntReleaseWindowObject(MsgWindows);
-    }
-  }
+
+   if(Ret == NULL && hwndParent == NULL && hwndChildAfter == NULL)
+   {
+      /* FIXME - if both hwndParent and hwndChildAfter are NULL, we also should
+                 search the message-only windows. Should this also be done if
+                 Parent is the desktop window??? */
+      PWINDOW_OBJECT MsgWindows;
+
+      if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
+      {
+         Ret = IntFindWindow(MsgWindows, ChildAfter, ClassAtom, &WindowName);
+      }
+   }
 #endif
-  
-  Cleanup:
-  if(ClassName.Length > 0 && ClassName.Buffer)
-    ExFreePool(ClassName.Buffer);
-  
-  Cleanup2:
-  RtlFreeUnicodeString(&WindowName);
-  
-  Cleanup3:
-  if(ChildAfter)
-    IntReleaseWindowObject(ChildAfter);
-  IntReleaseWindowObject(Parent);
-  
-  return Ret;
+
+Cleanup:
+   if(ClassName.Length > 0 && ClassName.Buffer)
+      ExFreePool(ClassName.Buffer);
+
+Cleanup2:
+   RtlFreeUnicodeString(&WindowName);
+
+Cleanup3:
+
+   RETURN( Ret);
+
+CLEANUP:
+   DPRINT("Leave NtUserFindWindowEx, ret %i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -2601,106 +2518,121 @@ NtUserFindWindowEx(HWND hwndParent,
 DWORD STDCALL
 NtUserFlashWindowEx(DWORD Unknown0)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
 /*
  * @implemented
  */
-HWND STDCALL
-NtUserGetAncestor(HWND hWnd, UINT Type)
+PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 {
-   PWINDOW_OBJECT Wnd, WndAncestor, Parent;
-   HWND hWndAncestor;
-
-   if (hWnd == IntGetDesktopWindow())
-   {
-      return NULL;
-   }
+   PWINDOW_OBJECT WndAncestor, Parent;
 
-   if (!(Wnd = IntGetWindowObject(hWnd)))
+   if (Wnd->hSelf == IntGetDesktopWindow())
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
 
    switch (Type)
    {
       case GA_PARENT:
-      {
-         WndAncestor = IntGetParentObject(Wnd);
-         break;
-      }
+         {
+            WndAncestor = Wnd->Parent;
+            break;
+         }
 
       case GA_ROOT:
-      {
-         PWINDOW_OBJECT tmp;
-         WndAncestor = Wnd;
-         Parent = NULL;
-
-         for(;;)
          {
-           tmp = Parent;
-           if(!(Parent = IntGetParentObject(WndAncestor)))
-           {
-             break;
-           }
-           if(IntIsDesktopWindow(Parent))
-           {
-             IntReleaseWindowObject(Parent);
-             break;
-           }
-           if(tmp)
-             IntReleaseWindowObject(tmp);
-           WndAncestor = Parent;
+            WndAncestor = Wnd;
+            Parent = NULL;
+
+            for(;;)
+            {
+               if(!(Parent = WndAncestor->Parent))
+               {
+                  break;
+               }
+               if(IntIsDesktopWindow(Parent))
+               {
+                  break;
+               }
+
+               WndAncestor = Parent;
+            }
+            break;
          }
-         break;
-      }
-    
+
       case GA_ROOTOWNER:
-      {
-         WndAncestor = Wnd;
-         IntReferenceWindowObject(WndAncestor);
-         for (;;)
          {
-            PWINDOW_OBJECT Old;
-            Old = WndAncestor;
-            Parent = IntGetParent(WndAncestor);
-            IntReleaseWindowObject(Old);
-            if (!Parent)
+            WndAncestor = Wnd;
+
+            for (;;)
             {
-              break;
+               PWINDOW_OBJECT Parent, Old;
+               
+               Old = WndAncestor;
+               Parent = IntGetParent(WndAncestor);
+
+               if (!Parent)
+               {
+                  break;
+               }
+               
+               //temp hack
+//               UserDerefObject(Parent);
+               
+               WndAncestor = Parent;
             }
-            WndAncestor = Parent;
+            break;
          }
-         break;
-      }
 
       default:
-      {
-         IntReleaseWindowObject(Wnd);
-         return NULL;
-      }
+         {
+            return NULL;
+         }
    }
+
+   return WndAncestor;
+}
+
+
+
+/*
+ * @implemented
+ */
+HWND STDCALL
+NtUserGetAncestor(HWND hWnd, UINT Type)
+{
+   PWINDOW_OBJECT Window, Ancestor;
+   DECLARE_RETURN(HWND);
+
+   DPRINT("Enter NtUserGetAncestor\n");
+   UserEnterExclusive();
    
-   hWndAncestor = (WndAncestor ? WndAncestor->Self : NULL);
-   IntReleaseWindowObject(Wnd);
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(NULL);
+   }
+
+   Ancestor = UserGetAncestor(Window, Type);
+   /* faxme: can UserGetAncestor ever return NULL for a valid window? */
    
-   if(WndAncestor && (WndAncestor != Wnd))
-     IntReleaseWindowObject(WndAncestor);
+   RETURN(Ancestor ? Ancestor->hSelf : NULL);
 
-   return hWndAncestor;
+CLEANUP:
+   DPRINT("Leave NtUserGetAncestor, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
-
 /*!
  * Returns client window rectangle relative to the upper-left corner of client area.
  *
- * \param      hWnd    window handle.
- * \param      Rect    pointer to the buffer where the coordinates are returned.
+ * \param hWnd window handle.
+ * \param Rect pointer to the buffer where the coordinates are returned.
  *
 */
 /*
@@ -2709,23 +2641,30 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
 BOOL STDCALL
 NtUserGetClientRect(HWND hWnd, LPRECT Rect)
 {
-  PWINDOW_OBJECT WindowObject;
-  RECT SafeRect;
+   PWINDOW_OBJECT Window;
+   RECT SafeRect;
+   DECLARE_RETURN(BOOL);
 
-  if(!(WindowObject = IntGetWindowObject(hWnd)))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);      
-    return FALSE;
-  }
+   DPRINT("Enter NtUserGetClientRect\n");
+   UserEnterShared();
 
-  IntGetClientRect(WindowObject, &SafeRect);
-  IntReleaseWindowObject(WindowObject);
-  
-  if(!NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
-  {
-    return FALSE;
-  }
-  return TRUE;
+   if(!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( FALSE);
+   }
+
+   IntGetClientRect(Window, &SafeRect);
+
+   if(!NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+   {
+      RETURN( FALSE);
+   }
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetClientRect, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -2735,7 +2674,17 @@ NtUserGetClientRect(HWND hWnd, LPRECT Rect)
 HWND STDCALL
 NtUserGetDesktopWindow()
 {
-   return IntGetDesktopWindow();
+   DECLARE_RETURN(HWND);
+
+   DPRINT("Enter NtUserGetDesktopWindow\n");
+   UserEnterShared();
+
+   RETURN( IntGetDesktopWindow());
+
+CLEANUP:
+   DPRINT("Leave NtUserGetDesktopWindow, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -2744,12 +2693,12 @@ NtUserGetDesktopWindow()
  */
 DWORD STDCALL
 NtUserGetInternalWindowPos(DWORD Unknown0,
-                          DWORD Unknown1,
-                          DWORD Unknown2)
+                           DWORD Unknown1,
+                           DWORD Unknown2)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -2759,30 +2708,25 @@ NtUserGetInternalWindowPos(DWORD Unknown0,
 HWND STDCALL
 NtUserGetLastActivePopup(HWND hWnd)
 {
-/*
- * This code can't work, because hWndLastPopup member of WINDOW_OBJECT is
- * not changed anywhere.
- * -- Filip, 01/nov/2003
- */
+   /*
   * This code can't work, because hWndLastPopup member of WINDOW_OBJECT is
   * not changed anywhere.
   * -- Filip, 01/nov/2003
   */
 #if 0
-  PWINDOW_OBJECT Wnd;
-  HWND hWndLastPopup;
-
-  IntAcquireWinLockShared();
-
-  if (!(Wnd = IntGetWindowObject(hWnd)))
-  {
-    IntReleaseWinLock();
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return NULL;
-  }
+   PWINDOW_OBJECT Wnd;
+   HWND hWndLastPopup;
 
-  hWndLastPopup = Wnd->hWndLastPopup;
+   if (!(Wnd = UserGetWindowObject(hWnd)))
+   {
+      return NULL;
+   }
 
-  IntReleaseWinLock();
+   hWndLastPopup = Wnd->hWndLastPopup;
 
-  return hWndLastPopup;
+   return hWndLastPopup;
 #else
+
    return NULL;
 #endif
 }
@@ -2791,7 +2735,7 @@ NtUserGetLastActivePopup(HWND hWnd)
  * NtUserGetParent
  *
  * The NtUserGetParent function retrieves a handle to the specified window's
- * parent or owner. 
+ * parent or owner.
  *
  * Remarks
  *    Note that, despite its name, this function can return an owner window
@@ -2806,35 +2750,101 @@ NtUserGetParent(HWND hWnd)
 {
    PWINDOW_OBJECT Wnd, WndParent;
    HWND hWndParent = NULL;
+   DECLARE_RETURN(HWND);
 
-   if (!(Wnd = IntGetWindowObject(hWnd)))
+   DPRINT("Enter NtUserGetParent\n");
+   UserEnterExclusive();
+
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return NULL;
+      RETURN( NULL);
    }
 
    WndParent = IntGetParent(Wnd);
    if (WndParent)
    {
-      hWndParent = WndParent->Self;
-      IntReleaseWindowObject(WndParent);
+      hWndParent = WndParent->hSelf;
+   }
+
+   RETURN( hWndParent);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetParent, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
+
+HWND FASTCALL
+co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
+{
+   PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
+   HWND hWndOldParent = NULL;
+   USER_REFERENCE_ENTRY Ref, ParentRef;
+
+   if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return( NULL);
+   }
+
+   if (hWndChild == IntGetDesktopWindow())
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      return( NULL);
+   }
+
+   if (hWndNewParent)
+   {
+      if (!(WndParent = UserGetWindowObject(hWndNewParent)))
+      {
+         return( NULL);
+      }
+   }
+   else
+   {
+      if (!(WndParent = UserGetWindowObject(IntGetDesktopWindow())))
+      {
+         return( NULL);
+      }
+   }
+
+   if (!(Wnd = UserGetWindowObject(hWndChild)))
+   {
+      return( NULL);
    }
 
-   IntReleaseWindowObject(Wnd);
+   UserRefObjectCo(Wnd, &Ref);
+   UserRefObjectCo(WndParent, &ParentRef);
+   
+   WndOldParent = co_IntSetParent(Wnd, WndParent);
+   
+   UserDerefObjectCo(WndParent);
+   UserDerefObjectCo(Wnd);
+
+   if (WndOldParent)
+   {
+      hWndOldParent = WndOldParent->hSelf;
+      UserDerefObject(WndOldParent);
+   }
 
-   return hWndParent;
+   return( hWndOldParent);
 }
 
+
+
 /*
  * NtUserSetParent
  *
  * The NtUserSetParent function changes the parent window of the specified
- * child window. 
+ * child window.
  *
  * Remarks
  *    The new parent window and the child window must belong to the same
  *    application. If the window identified by the hWndChild parameter is
- *    visible, the system performs the appropriate redrawing and repainting. 
+ *    visible, the system performs the appropriate redrawing and repainting.
  *    For compatibility reasons, NtUserSetParent does not modify the WS_CHILD
  *    or WS_POPUP window styles of the window whose parent is being changed.
  *
@@ -2842,62 +2852,48 @@ NtUserGetParent(HWND hWnd)
  *    @implemented
  */
 
-HWND STDCALL
-NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
-{
-   PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
-   HWND hWndOldParent = NULL;
-
-   if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return NULL;
-   }
-  
-   if (hWndChild == IntGetDesktopWindow())
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return NULL;
-   }
-
-   if (hWndNewParent)
-   {
-      if (!(WndParent = IntGetWindowObject(hWndNewParent)))
-      {
-         SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-         return NULL;
-      }
-   }
-   else
-   {
-      if (!(WndParent = IntGetWindowObject(IntGetDesktopWindow())))
-      {
-         SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-         return NULL;
-      }
-   }
+HWND STDCALL
+NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
+{
+   DECLARE_RETURN(HWND);
 
-   if (!(Wnd = IntGetWindowObject(hWndChild)))
-   {
-      IntReleaseWindowObject(WndParent);
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return NULL;
-   }
+   DPRINT("Enter NtUserSetParent\n");
+   UserEnterExclusive();
 
-   WndOldParent = IntSetParent(Wnd, WndParent);
+   RETURN( co_UserSetParent(hWndChild, hWndNewParent));
 
-   if (WndOldParent)
+CLEANUP:
+   DPRINT("Leave NtUserSetParent, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
+
+HWND FASTCALL UserGetShellWindow()
+{
+   PWINSTATION_OBJECT WinStaObject;
+   HWND Ret;
+
+   NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
+                     KernelMode,
+                     0,
+                     &WinStaObject);
+
+   if (!NT_SUCCESS(Status))
    {
-      hWndOldParent = WndOldParent->Self;
-      IntReleaseWindowObject(WndOldParent);
+      SetLastNtError(Status);
+      return( (HWND)0);
    }
 
-   IntReleaseWindowObject(Wnd);
-   IntReleaseWindowObject(WndParent);
+   Ret = (HWND)WinStaObject->ShellWindow;
 
-   return hWndOldParent;
+   ObDereferenceObject(WinStaObject);
+   return( Ret);
 }
 
+
 /*
  * NtUserGetShellWindow
  *
@@ -2910,24 +2906,17 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
 HWND STDCALL
 NtUserGetShellWindow()
 {
-  PWINSTATION_OBJECT WinStaObject;
-  HWND Ret;
+   DECLARE_RETURN(HWND);
 
-  NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
-                                      KernelMode,
-                                      0,
-                                      &WinStaObject);
-  
-  if (!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    return (HWND)0;
-  }
-  
-  Ret = (HWND)WinStaObject->ShellWindow;
-  
-  ObDereferenceObject(WinStaObject);
-  return Ret;
+   DPRINT("Enter NtUserGetShellWindow\n");
+   UserEnterShared();
+
+   RETURN( UserGetShellWindow() );
+
+CLEANUP:
+   DPRINT("Leave NtUserGetShellWindow, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -2943,26 +2932,37 @@ NtUserGetShellWindow()
 BOOL STDCALL
 NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
 {
-  PWINSTATION_OBJECT WinStaObject;
+   PWINSTATION_OBJECT WinStaObject;
+   PWINDOW_OBJECT WndShell;
+   DECLARE_RETURN(BOOL);
+   USER_REFERENCE_ENTRY Ref;
+
+   DPRINT("Enter NtUserSetShellWindowEx\n");
+   UserEnterExclusive();
+
+   if (!(WndShell = UserGetWindowObject(hwndShell)))
+   {
+      RETURN(FALSE);
+   }
+
+   NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
+                     KernelMode,
+                     0,
+                     &WinStaObject);
+
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
 
-  NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
-                                      KernelMode,
-                                      0,
-                                      &WinStaObject);
-  
-  if (!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    return FALSE;
-  }
-  
    /*
     * Test if we are permitted to change the shell window.
     */
    if (WinStaObject->ShellWindow)
    {
       ObDereferenceObject(WinStaObject);
-      return FALSE;
+      RETURN( FALSE);
    }
 
    /*
@@ -2970,34 +2970,42 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
     */
    if (hwndListView && hwndListView != hwndShell)
    {
-/*
- * Disabled for now to get Explorer working.
- * -- Filip, 01/nov/2003
- */
+      /*
      * Disabled for now to get Explorer working.
      * -- Filip, 01/nov/2003
      */
 #if 0
-       WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+      co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
 #endif
 
-      if (NtUserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
+      if (UserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
       {
          ObDereferenceObject(WinStaObject);
-         return FALSE;
+         RETURN( FALSE);
       }
    }
 
-   if (NtUserGetWindowLong(hwndShell, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
+   if (UserGetWindowLong(hwndShell, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
    {
       ObDereferenceObject(WinStaObject);
-      return FALSE;
+      RETURN( FALSE);
    }
 
-   WinPosSetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+   UserRefObjectCo(WndShell, &Ref);
+   co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
 
    WinStaObject->ShellWindow = hwndShell;
    WinStaObject->ShellListView = hwndListView;
-   
+
+   UserDerefObjectCo(WndShell);
+
    ObDereferenceObject(WinStaObject);
-   return TRUE;
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserSetShellWindowEx, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -3005,23 +3013,23 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
  *
  * The NtUserGetSystemMenu function allows the application to access the
  * window menu (also known as the system menu or the control menu) for
- * copying and modifying. 
+ * copying and modifying.
  *
  * Parameters
- *    hWnd 
- *       Handle to the window that will own a copy of the window menu. 
- *    bRevert 
+ *    hWnd
+ *       Handle to the window that will own a copy of the window menu.
+ *    bRevert
  *       Specifies the action to be taken. If this parameter is FALSE,
  *       NtUserGetSystemMenu returns a handle to the copy of the window menu
  *       currently in use. The copy is initially identical to the window menu
- *       but it can be modified. 
+ *       but it can be modified.
  *       If this parameter is TRUE, GetSystemMenu resets the window menu back
  *       to the default state. The previous window menu, if any, is destroyed.
  *
  * Return Value
  *    If the bRevert parameter is FALSE, the return value is a handle to a
  *    copy of the window menu. If the bRevert parameter is TRUE, the return
- *    value is NULL. 
+ *    value is NULL.
  *
  * Status
  *    @implemented
@@ -3030,26 +3038,29 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
 HMENU STDCALL
 NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
 {
-   HMENU Result = 0;
-   PWINDOW_OBJECT WindowObject;
-   PMENU_OBJECT MenuObject;
+   PWINDOW_OBJECT Window;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(HMENU);
+
+   DPRINT("Enter NtUserGetSystemMenu\n");
+   UserEnterShared();
 
-   WindowObject = IntGetWindowObject((HWND)hWnd);
-   if (WindowObject == NULL)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return 0;
+      RETURN(NULL);
    }
-  
-   MenuObject = IntGetSystemMenu(WindowObject, bRevert, FALSE);
-   if (MenuObject)
+
+   if (!(Menu = IntGetSystemMenu(Window, bRevert, FALSE)))
    {
-      Result = MenuObject->MenuInfo.Self;
-      IntReleaseMenuObject(MenuObject);
+      RETURN(NULL);
    }
-  
-   IntReleaseWindowObject(WindowObject);
-   return Result;
+
+   RETURN(Menu->MenuInfo.Self);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetSystemMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -3063,144 +3074,146 @@ BOOL STDCALL
 NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
 {
    BOOL Result = FALSE;
-   PWINDOW_OBJECT WindowObject;
-   PMENU_OBJECT MenuObject;
+   PWINDOW_OBJECT Window;
+   PMENU_OBJECT Menu;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserSetSystemMenu\n");
+   UserEnterExclusive();
 
-   WindowObject = IntGetWindowObject(hWnd);
-   if (!WindowObject)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return FALSE;
+      RETURN( FALSE);
    }
-  
+
    if (hMenu)
    {
       /*
        * Assign new menu handle.
        */
-      MenuObject = IntGetMenuObject(hMenu);
-      if (!MenuObject)
+      if (!(Menu = UserGetMenuObject(hMenu)))
       {
-         IntReleaseWindowObject(WindowObject);
-         SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
-         return FALSE;
+         RETURN( FALSE);
       }
-    
-      Result = IntSetSystemMenu(WindowObject, MenuObject);
-    
-      IntReleaseMenuObject(MenuObject);
+
+      Result = IntSetSystemMenu(Window, Menu);
    }
-  
-   IntReleaseWindowObject(WindowObject);
-   return Result;
+
+   RETURN( Result);
+
+CLEANUP:
+   DPRINT("Leave NtUserSetSystemMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
-/*
- * NtUserGetWindow
- *
- * The NtUserGetWindow function retrieves a handle to a window that has the
- * specified relationship (Z order or owner) to the specified window.
- *
- * Status
- *    @implemented
- */
 
-HWND STDCALL
-NtUserGetWindow(HWND hWnd, UINT Relationship)
+
+
+HWND FASTCALL
+UserGetWindow(HWND hWnd, UINT Relationship)
 {
-   PWINDOW_OBJECT WindowObject, Parent;
+   PWINDOW_OBJECT Parent, Window;
    HWND hWndResult = NULL;
 
-   if (!(WindowObject = IntGetWindowObject(hWnd)))
-   {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+   if (!(Window = UserGetWindowObject(hWnd)))
       return NULL;
-   }
-  
+
    switch (Relationship)
    {
       case GW_HWNDFIRST:
-         if((Parent = IntGetParentObject(WindowObject)))
+         if((Parent = Window->Parent))
          {
-           IntLockRelatives(Parent);
-           if (Parent->FirstChild)
-              hWndResult = Parent->FirstChild->Self;
-           IntUnLockRelatives(Parent);
-           IntReleaseWindowObject(Parent);
+            if (Parent->FirstChild)
+               hWndResult = Parent->FirstChild->hSelf;
          }
          break;
 
       case GW_HWNDLAST:
-         if((Parent = IntGetParentObject(WindowObject)))
+         if((Parent = Window->Parent))
          {
-           IntLockRelatives(Parent);
-           if (Parent->LastChild)
-              hWndResult = Parent->LastChild->Self;
-           IntUnLockRelatives(Parent);
-           IntReleaseWindowObject(Parent);
+            if (Parent->LastChild)
+               hWndResult = Parent->LastChild->hSelf;
          }
          break;
 
       case GW_HWNDNEXT:
-         IntLockRelatives(WindowObject);
-         if (WindowObject->NextSibling)
-            hWndResult = WindowObject->NextSibling->Self;
-         IntUnLockRelatives(WindowObject);
+         if (Window->NextSibling)
+            hWndResult = Window->NextSibling->hSelf;
          break;
 
       case GW_HWNDPREV:
-         IntLockRelatives(WindowObject);
-         if (WindowObject->PrevSibling)
-            hWndResult = WindowObject->PrevSibling->Self;
-         IntUnLockRelatives(WindowObject);
+         if (Window->PrevSibling)
+            hWndResult = Window->PrevSibling->hSelf;
          break;
 
       case GW_OWNER:
-         IntLockRelatives(WindowObject);
-         if((Parent = IntGetWindowObject(WindowObject->Owner)))
+         if((Parent = UserGetWindowObject(Window->hOwner)))
          {
-           hWndResult = Parent->Self;
-           IntReleaseWindowObject(Parent);
+            hWndResult = Parent->hSelf;
          }
-         IntUnLockRelatives(WindowObject);
          break;
       case GW_CHILD:
-         IntLockRelatives(WindowObject);
-         if (WindowObject->FirstChild)
-            hWndResult = WindowObject->FirstChild->Self;
-         IntUnLockRelatives(WindowObject);
+         if (Window->FirstChild)
+            hWndResult = Window->FirstChild->hSelf;
          break;
    }
 
-   IntReleaseWindowObject(WindowObject);
-
    return hWndResult;
 }
 
+
+
+/*
+ * NtUserGetWindow
+ *
+ * The NtUserGetWindow function retrieves a handle to a window that has the
+ * specified relationship (Z order or owner) to the specified window.
+ *
+ * Status
+ *    @implemented
+ */
+
+HWND STDCALL
+NtUserGetWindow(HWND hWnd, UINT Relationship)
+{
+   DECLARE_RETURN(HWND);
+
+   DPRINT("Enter NtUserGetWindow\n");
+   UserEnterShared();
+
+   RETURN(UserGetWindow(hWnd, Relationship));
+
+CLEANUP:
+   DPRINT("Leave NtUserGetWindow, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
+
 /*
  * NtUserGetWindowLong
  *
  * The NtUserGetWindowLong function retrieves information about the specified
  * window. The function also retrieves the 32-bit (long) value at the
- * specified offset into the extra window memory. 
+ * specified offset into the extra window memory.
  *
  * Status
  *    @implemented
  */
 
-LONG STDCALL
-NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
+LONG FASTCALL
+UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
 {
-   PWINDOW_OBJECT WindowObject, Parent;
+   PWINDOW_OBJECT Window, Parent;
    LONG Result = 0;
 
    DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
 
-   WindowObject = IntGetWindowObject(hWnd);
-   if (WindowObject == NULL)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return 0;
    }
 
@@ -3208,7 +3221,7 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
     * WndProc is only available to the owner process
     */
    if (GWL_WNDPROC == Index
-       && WindowObject->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+         && Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return 0;
@@ -3216,58 +3229,55 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
 
    if ((INT)Index >= 0)
    {
-      if ((Index + sizeof(LONG)) > WindowObject->ExtraDataSize)
+      if ((Index + sizeof(LONG)) > Window->ExtraDataSize)
       {
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
          return 0;
       }
-      Result = *((LONG *)(WindowObject->ExtraData + Index));
+      Result = *((LONG *)(Window->ExtraData + Index));
    }
    else
    {
       switch (Index)
       {
          case GWL_EXSTYLE:
-            Result = WindowObject->ExStyle;
+            Result = Window->ExStyle;
             break;
 
          case GWL_STYLE:
-            Result = WindowObject->Style;
+            Result = Window->Style;
             break;
 
          case GWL_WNDPROC:
             if (Ansi)
-               Result = (LONG) WindowObject->WndProcA;
+               Result = (LONG) Window->WndProcA;
             else
-               Result = (LONG) WindowObject->WndProcW;
+               Result = (LONG) Window->WndProcW;
             break;
 
          case GWL_HINSTANCE:
-            Result = (LONG) WindowObject->Instance;
+            Result = (LONG) Window->Instance;
             break;
 
          case GWL_HWNDPARENT:
-            IntLockRelatives(WindowObject);
-            Parent = IntGetWindowObject(WindowObject->Parent);
-            IntUnLockRelatives(WindowObject);
+            Parent = Window->Parent;
             if(Parent)
             {
-              if (Parent && Parent->Self == IntGetDesktopWindow())
-                 Result = (LONG) NtUserGetWindow(WindowObject->Self, GW_OWNER);
-              else
-                 Result = (LONG) Parent->Self;
-              IntReleaseWindowObject(Parent);
+               if (Parent && Parent->hSelf == IntGetDesktopWindow())
+                  Result = (LONG) UserGetWindow(Window->hSelf, GW_OWNER);
+               else
+                  Result = (LONG) Parent->hSelf;
             }
             break;
 
          case GWL_ID:
-            Result = (LONG) WindowObject->IDMenu;
+            Result = (LONG) Window->IDMenu;
             break;
 
          case GWL_USERDATA:
-            Result = WindowObject->UserData;
+            Result = Window->UserData;
             break;
-    
+
          default:
             DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
             SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -3276,26 +3286,46 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
       }
    }
 
-   IntReleaseWindowObject(WindowObject);
-
    return Result;
 }
 
+
+
+
 /*
- * NtUserSetWindowLong
+ * NtUserGetWindowLong
  *
- * The NtUserSetWindowLong function changes an attribute of the specified
- * window. The function also sets the 32-bit (long) value at the specified
- * offset into the extra window memory. 
+ * The NtUserGetWindowLong function retrieves information about the specified
+ * window. The function also retrieves the 32-bit (long) value at the
+ * specified offset into the extra window memory.
  *
  * Status
  *    @implemented
  */
 
 LONG STDCALL
-NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
+NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
+{
+   DECLARE_RETURN(LONG);
+
+   DPRINT("Enter NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
+   UserEnterExclusive();
+
+   RETURN(UserGetWindowLong(hWnd, Index, Ansi));
+
+CLEANUP:
+   DPRINT("Leave NtUserGetWindowLong, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
+
+LONG FASTCALL
+co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 {
-   PWINDOW_OBJECT WindowObject, Parent;
+   PWINDOW_OBJECT Window, Parent;
    PWINSTATION_OBJECT WindowStation;
    LONG OldValue;
    STYLESTRUCT Style;
@@ -3303,103 +3333,98 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
    if (hWnd == IntGetDesktopWindow())
    {
       SetLastWin32Error(STATUS_ACCESS_DENIED);
-      return 0;
+      return( 0);
    }
 
-   WindowObject = IntGetWindowObject(hWnd);
-   if (WindowObject == NULL)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return 0;
+      return( 0);
    }
 
    if ((INT)Index >= 0)
    {
-      if ((Index + sizeof(LONG)) > WindowObject->ExtraDataSize)
+      if ((Index + sizeof(LONG)) > Window->ExtraDataSize)
       {
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-         IntReleaseWindowObject(WindowObject);
-         return 0;
+         return( 0);
       }
-      OldValue = *((LONG *)(WindowObject->ExtraData + Index));
-      *((LONG *)(WindowObject->ExtraData + Index)) = NewValue;
+      OldValue = *((LONG *)(Window->ExtraData + Index));
+      *((LONG *)(Window->ExtraData + Index)) = NewValue;
    }
    else
    {
       switch (Index)
       {
          case GWL_EXSTYLE:
-            OldValue = (LONG) WindowObject->ExStyle;
+            OldValue = (LONG) Window->ExStyle;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
 
             /*
              * Remove extended window style bit WS_EX_TOPMOST for shell windows.
              */
-            WindowStation = WindowObject->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
+            WindowStation = ((PW32THREAD)Window->OwnerThread->Tcb.Win32Thread)->Desktop->WindowStation;
             if(WindowStation)
             {
-              if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
-                 Style.styleNew &= ~WS_EX_TOPMOST;
+               if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
+                  Style.styleNew &= ~WS_EX_TOPMOST;
             }
 
-            IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
-            WindowObject->ExStyle = (DWORD)Style.styleNew;
-            IntSendMessage(hWnd, WM_STYLECHANGED, GWL_EXSTYLE, (LPARAM) &Style);
+            co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
+            Window->ExStyle = (DWORD)Style.styleNew;
+            co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_EXSTYLE, (LPARAM) &Style);
             break;
 
          case GWL_STYLE:
-            OldValue = (LONG) WindowObject->Style;
+            OldValue = (LONG) Window->Style;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
-            IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
-            WindowObject->Style = (DWORD)Style.styleNew;
-            IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
+            co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
+            Window->Style = (DWORD)Style.styleNew;
+            co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
             break;
 
          case GWL_WNDPROC:
             /* FIXME: should check if window belongs to current process */
             if (Ansi)
             {
-               OldValue = (LONG) WindowObject->WndProcA;
-               WindowObject->WndProcA = (WNDPROC) NewValue;
-               WindowObject->WndProcW = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,FALSE);
-               WindowObject->Unicode = FALSE;
+               OldValue = (LONG) Window->WndProcA;
+               Window->WndProcA = (WNDPROC) NewValue;
+               Window->WndProcW = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,FALSE);
+               Window->Unicode = FALSE;
             }
             else
             {
-               OldValue = (LONG) WindowObject->WndProcW;
-               WindowObject->WndProcW = (WNDPROC) NewValue;
-               WindowObject->WndProcA = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,TRUE);
-               WindowObject->Unicode = TRUE;
+               OldValue = (LONG) Window->WndProcW;
+               Window->WndProcW = (WNDPROC) NewValue;
+               Window->WndProcA = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,TRUE);
+               Window->Unicode = TRUE;
             }
             break;
 
          case GWL_HINSTANCE:
-            OldValue = (LONG) WindowObject->Instance;
-            WindowObject->Instance = (HINSTANCE) NewValue;
+            OldValue = (LONG) Window->Instance;
+            Window->Instance = (HINSTANCE) NewValue;
             break;
 
          case GWL_HWNDPARENT:
-            Parent = IntGetParentObject(WindowObject);
-            if (Parent && (Parent->Self == IntGetDesktopWindow()))
-               OldValue = (LONG) IntSetOwner(WindowObject->Self, (HWND) NewValue);
+            Parent = Window->Parent;
+            if (Parent && (Parent->hSelf == IntGetDesktopWindow()))
+               OldValue = (LONG) IntSetOwner(Window->hSelf, (HWND) NewValue);
             else
-               OldValue = (LONG) NtUserSetParent(WindowObject->Self, (HWND) NewValue);
-            if(Parent)
-              IntReleaseWindowObject(Parent);
+               OldValue = (LONG) co_UserSetParent(Window->hSelf, (HWND) NewValue);
             break;
 
          case GWL_ID:
-            OldValue = (LONG) WindowObject->IDMenu;
-            WindowObject->IDMenu = (UINT) NewValue;
+            OldValue = (LONG) Window->IDMenu;
+            Window->IDMenu = (UINT) NewValue;
             break;
 
          case GWL_USERDATA:
-            OldValue = WindowObject->UserData;
-            WindowObject->UserData = NewValue;
+            OldValue = Window->UserData;
+            Window->UserData = NewValue;
             break;
-    
+
          default:
             DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
             SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -3408,9 +3433,36 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
       }
    }
 
-   IntReleaseWindowObject(WindowObject);
-   return OldValue;
+   return( OldValue);
+}
+
+
+
+/*
+ * NtUserSetWindowLong
+ *
+ * The NtUserSetWindowLong function changes an attribute of the specified
+ * window. The function also sets the 32-bit (long) value at the specified
+ * offset into the extra window memory.
+ *
+ * Status
+ *    @implemented
+ */
+
+LONG STDCALL
+NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
+{
+   DECLARE_RETURN(LONG);
+
+   DPRINT("Enter NtUserSetWindowLong\n");
+   UserEnterExclusive();
+
+   RETURN( co_UserSetWindowLong(hWnd, Index, NewValue, Ansi));
+
+CLEANUP:
+   DPRINT("Leave NtUserSetWindowLong, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -3425,43 +3477,47 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 WORD STDCALL
 NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
 {
-   PWINDOW_OBJECT WindowObject;
+   PWINDOW_OBJECT Window;
    WORD OldValue;
+   DECLARE_RETURN(WORD);
+
+   DPRINT("Enter NtUserSetWindowWord\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( 0);
+   }
 
    switch (Index)
    {
       case GWL_ID:
       case GWL_HINSTANCE:
       case GWL_HWNDPARENT:
-         return NtUserSetWindowLong(hWnd, Index, (UINT)NewValue, TRUE);
+         RETURN( co_UserSetWindowLong(Window->hSelf, Index, (UINT)NewValue, TRUE));
       default:
          if (Index < 0)
          {
             SetLastWin32Error(ERROR_INVALID_INDEX);
-            return 0;
+            RETURN( 0);
          }
    }
 
-   WindowObject = IntGetWindowObject(hWnd);
-   if (WindowObject == NULL)
-   {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return 0;
-   }
-
-   if (Index > WindowObject->ExtraDataSize - sizeof(WORD))
+   if (Index > Window->ExtraDataSize - sizeof(WORD))
    {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      IntReleaseWindowObject(WindowObject);
-      return 0;
+      RETURN( 0);
    }
 
-   OldValue = *((WORD *)(WindowObject->ExtraData + Index));
-   *((WORD *)(WindowObject->ExtraData + Index)) = NewValue;
+   OldValue = *((WORD *)(Window->ExtraData + Index));
+   *((WORD *)(Window->ExtraData + Index)) = NewValue;
 
-   IntReleaseWindowObject(WindowObject);
+   RETURN( OldValue);
 
-   return OldValue;
+CLEANUP:
+   DPRINT("Leave NtUserSetWindowWord, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -3469,70 +3525,88 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
  */
 BOOL STDCALL
 NtUserGetWindowPlacement(HWND hWnd,
-                        WINDOWPLACEMENT *lpwndpl)
+                         WINDOWPLACEMENT *lpwndpl)
 {
-  PWINDOW_OBJECT WindowObject;
-  PINTERNALPOS InternalPos;
-  POINT Size;
-  WINDOWPLACEMENT Safepl;
-  NTSTATUS Status;
-  
-  WindowObject = IntGetWindowObject(hWnd);
-  if (WindowObject == NULL)
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return FALSE;
-  }
-  
-  Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    IntReleaseWindowObject(WindowObject);
-    return FALSE;
-  }
-  if(Safepl.length != sizeof(WINDOWPLACEMENT))
-  {
-    IntReleaseWindowObject(WindowObject);
-    return FALSE;
-  }
-  
-  Safepl.flags = 0;
-  Safepl.showCmd = ((WindowObject->Flags & WINDOWOBJECT_RESTOREMAX) ? SW_MAXIMIZE : SW_SHOWNORMAL);
-  
-  Size.x = WindowObject->WindowRect.left;
-  Size.y = WindowObject->WindowRect.top;
-  InternalPos = WinPosInitInternalPos(WindowObject, &Size, 
-                                     &WindowObject->WindowRect);
-  if (InternalPos)
-  {
-    Safepl.rcNormalPosition = InternalPos->NormalRect;
-    Safepl.ptMinPosition = InternalPos->IconPos;
-    Safepl.ptMaxPosition = InternalPos->MaxPos;
-  }
-  else
-  {
-    IntReleaseWindowObject(WindowObject);
-    return FALSE;
-  }
-  
-  Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    IntReleaseWindowObject(WindowObject);
-    return FALSE;
-  }
-  
-  IntReleaseWindowObject(WindowObject);
-  return TRUE;
+   PWINDOW_OBJECT Window;
+   PINTERNALPOS InternalPos;
+   POINT Size;
+   WINDOWPLACEMENT Safepl;
+   NTSTATUS Status;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserGetWindowPlacement\n");
+   UserEnterShared();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( FALSE);
+   }
+
+   Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
+   if(!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
+   if(Safepl.length != sizeof(WINDOWPLACEMENT))
+   {
+      RETURN( FALSE);
+   }
+
+   Safepl.flags = 0;
+   if (0 == (Window->Style & WS_VISIBLE))
+   {
+      Safepl.showCmd = SW_HIDE;
+   }
+   else if (0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+            0 != (Window->Style & WS_MAXIMIZE))
+   {
+      Safepl.showCmd = SW_MAXIMIZE;
+   }
+   else if (0 != (Window->Style & WS_MINIMIZE))
+   {
+      Safepl.showCmd = SW_MINIMIZE;
+   }
+   else if (0 != (Window->Style & WS_MINIMIZE))
+   {
+      Safepl.showCmd = SW_SHOWNORMAL;
+   }
+
+   Size.x = Window->WindowRect.left;
+   Size.y = Window->WindowRect.top;
+   InternalPos = WinPosInitInternalPos(Window, &Size,
+                                       &Window->WindowRect);
+   if (InternalPos)
+   {
+      Safepl.rcNormalPosition = InternalPos->NormalRect;
+      Safepl.ptMinPosition = InternalPos->IconPos;
+      Safepl.ptMaxPosition = InternalPos->MaxPos;
+   }
+   else
+   {
+      RETURN( FALSE);
+   }
+
+   Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
+   if(!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
+
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
 /*!
  * Return the dimension of the window in the screen coordinates.
- * \param      hWnd    window handle.
- * \param      Rect    pointer to the buffer where the coordinates are returned.
+ * \param hWnd window handle.
+ * \param Rect pointer to the buffer where the coordinates are returned.
 */
 /*
  * @implemented
@@ -3540,24 +3614,30 @@ NtUserGetWindowPlacement(HWND hWnd,
 BOOL STDCALL
 NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
 {
-  PWINDOW_OBJECT Wnd;
-  NTSTATUS Status;
-
-  if (!(Wnd = IntGetWindowObject(hWnd)))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);      
-    return FALSE;
-  }
-  Status = MmCopyToCaller(Rect, &Wnd->WindowRect, sizeof(RECT));
-  if (!NT_SUCCESS(Status))
-  {
-    IntReleaseWindowObject(Wnd);
-    SetLastNtError(Status);
-    return FALSE;
-  }
-  
-  IntReleaseWindowObject(Wnd);
-  return TRUE;
+   PWINDOW_OBJECT Wnd;
+   NTSTATUS Status;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserGetWindowRect\n");
+   UserEnterShared();
+
+   if (!(Wnd = UserGetWindowObject(hWnd)))
+   {
+      RETURN(FALSE);
+   }
+   Status = MmCopyToCaller(Rect, &Wnd->WindowRect, sizeof(RECT));
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
+
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetWindowRect, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -3569,19 +3649,28 @@ NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
 {
    PWINDOW_OBJECT Wnd;
    DWORD tid, pid;
-   
-   if (!(Wnd = IntGetWindowObject(hWnd)))
+   DECLARE_RETURN(DWORD);
+
+   DPRINT("Enter NtUserGetWindowThreadProcessId\n");
+   UserEnterShared();
+
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return 0;
+      RETURN( 0);
    }
 
    tid = (DWORD)IntGetWndThreadId(Wnd);
    pid = (DWORD)IntGetWndProcessId(Wnd);
-   
-   if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
-   
-   return tid;
+
+   if (UnsafePid)
+      MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
+
+   RETURN( tid);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetWindowThreadProcessId, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -3591,9 +3680,9 @@ NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
 DWORD STDCALL
 NtUserLockWindowUpdate(DWORD Unknown0)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -3601,27 +3690,27 @@ NtUserLockWindowUpdate(DWORD Unknown0)
  * @implemented
  */
 BOOL STDCALL
-NtUserMoveWindow(      
-    HWND hWnd,
-    int X,
-    int Y,
-    int nWidth,
-    int nHeight,
-    BOOL bRepaint)
+NtUserMoveWindow(
+   HWND hWnd,
+   int X,
+   int Y,
+   int nWidth,
+   int nHeight,
+   BOOL bRepaint)
 {
-       return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, 
-                              (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : 
-                               SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW));
+   return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight,
+                             (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE :
+                              SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW));
 }
 
 /*
      QueryWindow based on KJK::Hyperion and James Tabor.
-
      0 = QWUniqueProcessId
      1 = QWUniqueThreadId
      4 = QWIsHung            Implements IsHungAppWindow found
+ QueryWindow based on KJK::Hyperion and James Tabor.
+ 0 = QWUniqueProcessId
+ 1 = QWUniqueThreadId
+ 4 = QWIsHung            Implements IsHungAppWindow found
                                 by KJK::Hyperion.
-
         9 = QWKillWindow        When I called this with hWnd ==
                                 DesktopWindow, it shutdown the system
                                 and rebooted.
@@ -3632,13 +3721,16 @@ NtUserMoveWindow(
 DWORD STDCALL
 NtUserQueryWindow(HWND hWnd, DWORD Index)
 {
-   PWINDOW_OBJECT Window = IntGetWindowObject(hWnd);
+   PWINDOW_OBJECT Window;
    DWORD Result;
+   DECLARE_RETURN(UINT);
+
+   DPRINT("Enter NtUserQueryWindow\n");
+   UserEnterShared();
 
-   if (Window == NULL)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return 0;
+      RETURN( 0);
    }
 
    switch(Index)
@@ -3660,9 +3752,12 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
          break;
    }
 
-   IntReleaseWindowObject(Window);
+   RETURN( Result);
 
-   return Result;
+CLEANUP:
+   DPRINT("Leave NtUserQueryWindow, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -3671,12 +3766,12 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
  */
 DWORD STDCALL
 NtUserRealChildWindowFromPoint(DWORD Unknown0,
-                              DWORD Unknown1,
-                              DWORD Unknown2)
+                               DWORD Unknown1,
+                               DWORD Unknown2)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -3686,27 +3781,36 @@ NtUserRealChildWindowFromPoint(DWORD Unknown0,
 UINT STDCALL
 NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
 {
-  UNICODE_STRING SafeMessageName;
-  NTSTATUS Status;
-  UINT Ret;
-  
-  if(MessageNameUnsafe == NULL)
-  {
-    SetLastWin32Error(ERROR_INVALID_PARAMETER);
-    return 0;
-  }
-  
-  Status = IntSafeCopyUnicodeStringTerminateNULL(&SafeMessageName, MessageNameUnsafe);
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    return 0;
-  }
-  
-  Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
-  
-  RtlFreeUnicodeString(&SafeMessageName);
-  return Ret;
+   UNICODE_STRING SafeMessageName;
+   NTSTATUS Status;
+   UINT Ret;
+   DECLARE_RETURN(UINT);
+
+   DPRINT("Enter NtUserRegisterWindowMessage\n");
+   UserEnterExclusive();
+
+   if(MessageNameUnsafe == NULL)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN( 0);
+   }
+
+   Status = IntSafeCopyUnicodeStringTerminateNULL(&SafeMessageName, MessageNameUnsafe);
+   if(!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( 0);
+   }
+
+   Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
+
+   RtlFreeUnicodeString(&SafeMessageName);
+   RETURN( Ret);
+
+CLEANUP:
+   DPRINT("Leave NtUserRegisterWindowMessage, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -3715,11 +3819,11 @@ NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
  */
 DWORD STDCALL
 NtUserSetImeOwnerWindow(DWORD Unknown0,
-                       DWORD Unknown1)
+                        DWORD Unknown1)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -3728,13 +3832,13 @@ NtUserSetImeOwnerWindow(DWORD Unknown0,
  */
 DWORD STDCALL
 NtUserSetInternalWindowPos(DWORD Unknown0,
-                          DWORD Unknown1,
-                          DWORD Unknown2,
-                          DWORD Unknown3)
+                           DWORD Unknown1,
+                           DWORD Unknown2,
+                           DWORD Unknown3)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 
 }
 
@@ -3744,13 +3848,13 @@ NtUserSetInternalWindowPos(DWORD Unknown0,
  */
 DWORD STDCALL
 NtUserSetLayeredWindowAttributes(DWORD Unknown0,
-                                DWORD Unknown1,
-                                DWORD Unknown2,
-                                DWORD Unknown3)
+                                 DWORD Unknown1,
+                                 DWORD Unknown2,
+                                 DWORD Unknown3)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -3760,9 +3864,9 @@ NtUserSetLayeredWindowAttributes(DWORD Unknown0,
 DWORD STDCALL
 NtUserSetLogonNotifyWindow(DWORD Unknown0)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -3771,35 +3875,44 @@ NtUserSetLogonNotifyWindow(DWORD Unknown0)
  */
 BOOL STDCALL
 NtUserSetMenu(
-   HWND Wnd,
+   HWND hWnd,
    HMENU Menu,
    BOOL Repaint)
 {
-  PWINDOW_OBJECT WindowObject;
-  BOOL Changed;
+   PWINDOW_OBJECT Window;
+   BOOL Changed;
+   DECLARE_RETURN(BOOL);
 
-  WindowObject = IntGetWindowObject((HWND) Wnd);
-  if (NULL == WindowObject)
-    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return FALSE;
-    }
-  
-  if (! IntSetMenu(WindowObject, Menu, &Changed))
-    {
-      IntReleaseWindowObject(WindowObject);
-      return FALSE;
-    }
-  
-  IntReleaseWindowObject(WindowObject);
-  
-  if (Changed && Repaint)
-    {
-      WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
-                         SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
-    }
-  
-  return TRUE;
+   DPRINT("Enter NtUserSetMenu\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( FALSE);
+   }
+
+   if (! IntSetMenu(Window, Menu, &Changed))
+   {
+      RETURN( FALSE);
+   }
+
+   if (Changed && Repaint)
+   {
+      USER_REFERENCE_ENTRY Ref;
+
+      UserRefObjectCo(Window, &Ref);
+      co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+                            SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
+
+      UserDerefObjectCo(Window);
+   }
+
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserSetMenu, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -3808,11 +3921,11 @@ NtUserSetMenu(
  */
 DWORD STDCALL
 NtUserSetWindowFNID(DWORD Unknown0,
-                   DWORD Unknown1)
+                    DWORD Unknown1)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
@@ -3822,51 +3935,59 @@ NtUserSetWindowFNID(DWORD Unknown0,
  */
 BOOL STDCALL
 NtUserSetWindowPlacement(HWND hWnd,
-                        WINDOWPLACEMENT *lpwndpl)
+                         WINDOWPLACEMENT *lpwndpl)
 {
-  PWINDOW_OBJECT WindowObject;
-  WINDOWPLACEMENT Safepl;
-  NTSTATUS Status;
-
-  WindowObject = IntGetWindowObject(hWnd);
-  if (WindowObject == NULL)
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return FALSE;
-  }
-  Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    IntReleaseWindowObject(WindowObject);
-    return FALSE;
-  }
-  if(Safepl.length != sizeof(WINDOWPLACEMENT))
-  {
-    IntReleaseWindowObject(WindowObject);
-    return FALSE;
-  }
-  
-  if ((WindowObject->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
-  {
-     WinPosSetWindowPos(WindowObject->Self, NULL,
-        Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
-        Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
-        Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
-        SWP_NOZORDER | SWP_NOACTIVATE);
-  }
-  
-  /* FIXME - change window status */
-  WinPosShowWindow(WindowObject->Self, Safepl.showCmd);
+   PWINDOW_OBJECT Window;
+   WINDOWPLACEMENT Safepl;
+   NTSTATUS Status;
+   DECLARE_RETURN(BOOL);
+   USER_REFERENCE_ENTRY Ref;
+
+   DPRINT("Enter NtUserSetWindowPlacement\n");
+   UserEnterExclusive();
 
-  if (WindowObject->InternalPos == NULL)
-     WindowObject->InternalPos = ExAllocatePoolWithTag(PagedPool, sizeof(INTERNALPOS), TAG_WININTLIST);
-  WindowObject->InternalPos->NormalRect = Safepl.rcNormalPosition;
-  WindowObject->InternalPos->IconPos = Safepl.ptMinPosition;
-  WindowObject->InternalPos->MaxPos = Safepl.ptMaxPosition;
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( FALSE);
+   }
+   Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
+   if(!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
+   if(Safepl.length != sizeof(WINDOWPLACEMENT))
+   {
+      RETURN( FALSE);
+   }
+
+   UserRefObjectCo(Window, &Ref);
 
-  IntReleaseWindowObject(WindowObject);
-  return TRUE;
+   if ((Window->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
+   {
+      co_WinPosSetWindowPos(Window, NULL,
+                            Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
+                            Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
+                            Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
+                            SWP_NOZORDER | SWP_NOACTIVATE);
+   }
+
+   /* FIXME - change window status */
+   co_WinPosShowWindow(Window, Safepl.showCmd);
+
+   if (Window->InternalPos == NULL)
+      Window->InternalPos = ExAllocatePoolWithTag(PagedPool, sizeof(INTERNALPOS), TAG_WININTLIST);
+   Window->InternalPos->NormalRect = Safepl.rcNormalPosition;
+   Window->InternalPos->IconPos = Safepl.ptMinPosition;
+   Window->InternalPos->MaxPos = Safepl.ptMaxPosition;
+
+   UserDerefObjectCo(Window);
+   RETURN(TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -3874,100 +3995,114 @@ NtUserSetWindowPlacement(HWND hWnd,
  * @implemented
  */
 BOOL STDCALL
-NtUserSetWindowPos(      
-    HWND hWnd,
-    HWND hWndInsertAfter,
-    int X,
-    int Y,
-    int cx,
-    int cy,
-    UINT uFlags)
+NtUserSetWindowPos(
+   HWND hWnd,
+   HWND hWndInsertAfter,
+   int X,
+   int Y,
+   int cx,
+   int cy,
+   UINT uFlags)
 {
-   return WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
+   DECLARE_RETURN(BOOL);
+   PWINDOW_OBJECT Window;
+   BOOL ret;
+   USER_REFERENCE_ENTRY Ref;
+
+   DPRINT("Enter NtUserSetWindowPos\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(FALSE);
+   }
+
+   UserRefObjectCo(Window, &Ref);
+   ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags);
+   UserDerefObjectCo(Window);
+
+   RETURN(ret);
+
+CLEANUP:
+   DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
 INT FASTCALL
-IntGetWindowRgn(HWND hWnd, HRGN hRgn)
+IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
 {
-  INT Ret;
-  PWINDOW_OBJECT WindowObject;
-  HRGN VisRgn;
-  ROSRGNDATA *pRgn;
-  
-  if(!(WindowObject = IntGetWindowObject(hWnd)))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return ERROR;
-  }
-  if(!hRgn)
-  {
-    IntReleaseWindowObject(WindowObject);
-    return ERROR;
-  }
-  
-  /* Create a new window region using the window rectangle */
-  VisRgn = UnsafeIntCreateRectRgnIndirect(&WindowObject->WindowRect);
-  NtGdiOffsetRgn(VisRgn, -WindowObject->WindowRect.left, -WindowObject->WindowRect.top);
-  /* if there's a region assigned to the window, combine them both */
-  if(WindowObject->WindowRegion && !(WindowObject->Style & WS_MINIMIZE))
-    NtGdiCombineRgn(VisRgn, VisRgn, WindowObject->WindowRegion, RGN_AND);
-  /* Copy the region into hRgn */
-  NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
-  
-  if((pRgn = RGNDATA_LockRgn(hRgn)))
-  {
-    Ret = pRgn->rdh.iType;
-    RGNDATA_UnlockRgn(hRgn);
-  }
-  else
-    Ret = ERROR;
-  
-  NtGdiDeleteObject(VisRgn);
-  
-  IntReleaseWindowObject(WindowObject);
-  return Ret;
+   INT Ret;
+   HRGN VisRgn;
+   ROSRGNDATA *pRgn;
+
+   if(!Window)
+   {
+      return ERROR;
+   }
+   if(!hRgn)
+   {
+      return ERROR;
+   }
+
+   /* Create a new window region using the window rectangle */
+   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
+   NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top);
+   /* if there's a region assigned to the window, combine them both */
+   if(Window->WindowRegion && !(Window->Style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   /* Copy the region into hRgn */
+   NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
+
+   if((pRgn = RGNDATA_LockRgn(hRgn)))
+   {
+      Ret = pRgn->rdh.iType;
+      RGNDATA_UnlockRgn(pRgn);
+   }
+   else
+      Ret = ERROR;
+
+   NtGdiDeleteObject(VisRgn);
+
+   return Ret;
 }
 
 INT FASTCALL
-IntGetWindowRgnBox(HWND hWnd, RECT *Rect)
+IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECT *Rect)
 {
-  INT Ret;
-  PWINDOW_OBJECT WindowObject;
-  HRGN VisRgn;
-  ROSRGNDATA *pRgn;
-  
-  if(!(WindowObject = IntGetWindowObject(hWnd)))
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return ERROR;
-  }
-  if(!Rect)
-  {
-    IntReleaseWindowObject(WindowObject);
-    return ERROR;
-  }
-  
-  /* Create a new window region using the window rectangle */
-  VisRgn = UnsafeIntCreateRectRgnIndirect(&WindowObject->WindowRect);
-  NtGdiOffsetRgn(VisRgn, -WindowObject->WindowRect.left, -WindowObject->WindowRect.top);
-  /* if there's a region assigned to the window, combine them both */
-  if(WindowObject->WindowRegion && !(WindowObject->Style & WS_MINIMIZE))
-    NtGdiCombineRgn(VisRgn, VisRgn, WindowObject->WindowRegion, RGN_AND);
-  
-  if((pRgn = RGNDATA_LockRgn(VisRgn)))
-  {
-    Ret = pRgn->rdh.iType;
-    *Rect = pRgn->rdh.rcBound;
-    RGNDATA_UnlockRgn(VisRgn);
-  }
-  else
-    Ret = ERROR;
-  
-  NtGdiDeleteObject(VisRgn);
-  
-  IntReleaseWindowObject(WindowObject);
-  return Ret;
+   INT Ret;
+   HRGN VisRgn;
+   ROSRGNDATA *pRgn;
+
+   if(!Window)
+   {
+      return ERROR;
+   }
+   if(!Rect)
+   {
+      return ERROR;
+   }
+
+   /* Create a new window region using the window rectangle */
+   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
+   NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top);
+   /* if there's a region assigned to the window, combine them both */
+   if(Window->WindowRegion && !(Window->Style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+
+   if((pRgn = RGNDATA_LockRgn(VisRgn)))
+   {
+      Ret = pRgn->rdh.iType;
+      *Rect = pRgn->rdh.rcBound;
+      RGNDATA_UnlockRgn(pRgn);
+   }
+   else
+      Ret = ERROR;
+
+   NtGdiDeleteObject(VisRgn);
+
+   return Ret;
 }
 
 
@@ -3976,38 +4111,47 @@ IntGetWindowRgnBox(HWND hWnd, RECT *Rect)
  */
 INT STDCALL
 NtUserSetWindowRgn(
-  HWND hWnd,
-  HRGN hRgn,
-  BOOL bRedraw)
+   HWND hWnd,
+   HRGN hRgn,
+   BOOL bRedraw)
 {
-  PWINDOW_OBJECT WindowObject;
-  
-  WindowObject = IntGetWindowObject(hWnd);
-  if (WindowObject == NULL)
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return 0;
-  }
-  
-  /* FIXME - Verify if hRgn is a valid handle!!!!
-             Propably make this operation thread-safe, but maybe it's not necessary */
-  
-  if(WindowObject->WindowRegion)
-  {
-    /* Delete no longer needed region handle */
-    NtGdiDeleteObject(WindowObject->WindowRegion);
-  }
-  WindowObject->WindowRegion = hRgn;
-  
-  /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
-  
-  if(bRedraw)
-  {
-    IntRedrawWindow(WindowObject, NULL, NULL, RDW_INVALIDATE);
-  }
-  
-  IntReleaseWindowObject(WindowObject);
-  return (INT)hRgn;
+   PWINDOW_OBJECT Window;
+   DECLARE_RETURN(INT);
+
+   DPRINT("Enter NtUserSetWindowRgn\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( 0);
+   }
+
+   /* FIXME - Verify if hRgn is a valid handle!!!!
+              Propably make this operation thread-safe, but maybe it's not necessary */
+
+   if(Window->WindowRegion)
+   {
+      /* Delete no longer needed region handle */
+      NtGdiDeleteObject(Window->WindowRegion);
+   }
+   Window->WindowRegion = hRgn;
+
+   /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
+
+   if(bRedraw)
+   {
+      USER_REFERENCE_ENTRY Ref;
+      UserRefObjectCo(Window, &Ref);
+      co_UserRedrawWindow(Window, NULL, NULL, RDW_INVALIDATE);
+      UserDerefObjectCo(Window);
+   }
+
+   RETURN( (INT)hRgn);
+
+CLEANUP:
+   DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
@@ -4015,23 +4159,46 @@ NtUserSetWindowRgn(
  * @implemented
  */
 BOOL STDCALL
-NtUserShowWindow(HWND hWnd,
-                LONG nCmdShow)
+NtUserShowWindow(HWND hWnd, LONG nCmdShow)
 {
-   return WinPosShowWindow(hWnd, nCmdShow);
+   PWINDOW_OBJECT Window;
+   BOOL ret;
+   DECLARE_RETURN(BOOL);
+   USER_REFERENCE_ENTRY Ref;
+
+   DPRINT("Enter NtUserShowWindow\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(FALSE);
+   }
+
+   UserRefObjectCo(Window, &Ref);
+   ret = co_WinPosShowWindow(Window, nCmdShow);
+   UserDerefObjectCo(Window);
+
+   RETURN(ret);
+
+CLEANUP:
+   DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
 /*
  * @unimplemented
  */
-DWORD STDCALL
-NtUserShowWindowAsync(DWORD Unknown0,
-                     DWORD Unknown1)
+BOOL STDCALL
+NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
 {
-  UNIMPLEMENTED
-
-  return 0;
+#if 0
+   UNIMPLEMENTED
+   return 0;
+#else
+   return NtUserShowWindow(hWnd, nCmdShow);
+#endif
 }
 
 
@@ -4040,29 +4207,21 @@ NtUserShowWindowAsync(DWORD Unknown0,
  */
 DWORD STDCALL
 NtUserUpdateLayeredWindow(DWORD Unknown0,
-                         DWORD Unknown1,
-                         DWORD Unknown2,
-                         DWORD Unknown3,
-                         DWORD Unknown4,
-                         DWORD Unknown5,
-                         DWORD Unknown6,
-                         DWORD Unknown7,
-                         DWORD Unknown8)
+                          DWORD Unknown1,
+                          DWORD Unknown2,
+                          DWORD Unknown3,
+                          DWORD Unknown4,
+                          DWORD Unknown5,
+                          DWORD Unknown6,
+                          DWORD Unknown7,
+                          DWORD Unknown8)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 
-/*
- * @implemented
- */
-VOID STDCALL
-NtUserValidateRect(HWND hWnd, const RECT* Rect)
-{
-  return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
-}
 
 
 /*
@@ -4073,29 +4232,44 @@ NtUserWindowFromPoint(LONG X, LONG Y)
 {
    POINT pt;
    HWND Ret;
-   PWINDOW_OBJECT DesktopWindow, Window = NULL;
+   PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
+   DECLARE_RETURN(HWND);
+   USER_REFERENCE_ENTRY Ref;
 
-   if ((DesktopWindow = IntGetWindowObject(IntGetDesktopWindow())))
+   DPRINT("Enter NtUserWindowFromPoint\n");
+   UserEnterExclusive();
+
+   if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
    {
       USHORT Hit;
-      
+
       pt.x = X;
       pt.y = Y;
+
+      //hmm... threads live on desktops thus we have a reference on the desktop and indirectly the desktop window
+      //its possible this referencing is useless, thou it shouldnt hurt...
+      UserRefObjectCo(DesktopWindow, &Ref);
       
-      Hit = WinPosWindowFromPoint(DesktopWindow, PsGetWin32Thread()->MessageQueue, &pt, &Window);
+      Hit = co_WinPosWindowFromPoint(DesktopWindow, PsGetWin32Thread()->MessageQueue, &pt, &Window);
       
       if(Window)
       {
-        Ret = Window->Self;
-        IntReleaseWindowObject(Window);
-        IntReleaseWindowObject(DesktopWindow);
-        return Ret;
+         Ret = Window->hSelf;
+         
+         RETURN( Ret);
       }
-      
-      IntReleaseWindowObject(DesktopWindow);
    }
-  
-   return NULL;
+
+   RETURN( NULL);
+
+CLEANUP:
+   if (Window) UserDerefObject(Window);
+   if (DesktopWindow) UserDerefObjectCo(DesktopWindow);
+
+   DPRINT("Leave NtUserWindowFromPoint, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+
 }
 
 
@@ -4110,61 +4284,52 @@ NtUserWindowFromPoint(LONG X, LONG Y)
  */
 
 BOOL STDCALL
-NtUserDefSetText(HWND WindowHandle, PUNICODE_STRING WindowText)
+NtUserDefSetText(HWND hWnd, PUNICODE_STRING WindowText)
 {
-  PWINDOW_OBJECT WindowObject, Parent, Owner;
-  UNICODE_STRING SafeText;
-  NTSTATUS Status;
-  
-  WindowObject = IntGetWindowObject(WindowHandle);
-  if(!WindowObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return FALSE;
-  }
-  
-  if(WindowText)
-  {
-    Status = IntSafeCopyUnicodeString(&SafeText, WindowText);
-    if(!NT_SUCCESS(Status))
-    {
-      SetLastNtError(Status);
-      IntReleaseWindowObject(WindowObject);
-      return FALSE;
-    }
-  }
-  else
-  {
-    RtlInitUnicodeString(&SafeText, NULL);
-  }
-  
-  /* FIXME - do this thread-safe! otherwise one could crash here! */
-  RtlFreeUnicodeString(&WindowObject->WindowName);
-  
-  WindowObject->WindowName = SafeText;
+   PWINDOW_OBJECT Window;
+   UNICODE_STRING SafeText;
+   NTSTATUS Status;
+   DECLARE_RETURN(INT);
+
+   DPRINT("Enter NtUserDefSetText\n");
+   UserEnterExclusive();
 
-  /* Send shell notifications */
+   if(!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( FALSE);
+   }
 
-  Owner = IntGetOwner(WindowObject);
-  Parent = IntGetParent(WindowObject);
+   if(WindowText)
+   {
+      Status = IntSafeCopyUnicodeString(&SafeText, WindowText);
+      if(!NT_SUCCESS(Status))
+      {
+         SetLastNtError(Status);
+         RETURN( FALSE);
+      }
+   }
+   else
+   {
+      RtlInitUnicodeString(&SafeText, NULL);
+   }
 
-  if ((!Owner) && (!Parent))
-  {
-    IntShellHookNotify(HSHELL_REDRAW, (LPARAM) WindowHandle);
-  }
+   /* FIXME - do this thread-safe! otherwise one could crash here! */
+   RtlFreeUnicodeString(&Window->WindowName);
 
-  if (Owner)
-  {
-    IntReleaseWindowObject(Owner);
-  }
+   Window->WindowName = SafeText;
 
-  if (Parent)
-  {
-    IntReleaseWindowObject(Parent);
-  }
-  
-  IntReleaseWindowObject(WindowObject);
-  return TRUE;
+   /* Send shell notifications */
+   if (!IntGetOwner(Window) && !IntGetParent(Window))
+   {
+      co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
+   }
+
+   RETURN( TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserDefSetText, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -4177,138 +4342,212 @@ NtUserDefSetText(HWND WindowHandle, PUNICODE_STRING WindowText)
 INT STDCALL
 NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
 {
-  PWINDOW_OBJECT WindowObject;
-  NTSTATUS Status;
-  INT Result;
-  
-  if(lpString && (nMaxCount <= 1))
-  {
-    SetLastWin32Error(ERROR_INVALID_PARAMETER);
-    return 0;
-  }
-  
-  WindowObject = IntGetWindowObject(hWnd);
-  if(!WindowObject)
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return 0;
-  }
-  
-  /* FIXME - do this thread-safe! otherwise one could crash here! */
-  Result = WindowObject->WindowName.Length / sizeof(WCHAR);
-  if(lpString)
-  {
-    const WCHAR Terminator = L'\0';
-    INT Copy;
-    WCHAR *Buffer = (WCHAR*)lpString;
-    
-    Copy = min(nMaxCount - 1, Result);
-    if(Copy > 0)
-    {
-      Status = MmCopyToCaller(Buffer, WindowObject->WindowName.Buffer, Copy * sizeof(WCHAR));
+   PWINDOW_OBJECT Window;
+   NTSTATUS Status;
+   INT Result;
+   DECLARE_RETURN(INT);
+
+   DPRINT("Enter NtUserInternalGetWindowText\n");
+   UserEnterShared();
+
+   if(lpString && (nMaxCount <= 1))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN( 0);
+   }
+
+   if(!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN( 0);
+   }
+
+   /* FIXME - do this thread-safe! otherwise one could crash here! */
+   Result = Window->WindowName.Length / sizeof(WCHAR);
+   if(lpString)
+   {
+      const WCHAR Terminator = L'\0';
+      INT Copy;
+      WCHAR *Buffer = (WCHAR*)lpString;
+
+      Copy = min(nMaxCount - 1, Result);
+      if(Copy > 0)
+      {
+         Status = MmCopyToCaller(Buffer, Window->WindowName.Buffer, Copy * sizeof(WCHAR));
+         if(!NT_SUCCESS(Status))
+         {
+            SetLastNtError(Status);
+            RETURN( 0);
+         }
+         Buffer += Copy;
+      }
+
+      Status = MmCopyToCaller(Buffer, &Terminator, sizeof(WCHAR));
       if(!NT_SUCCESS(Status))
       {
-        SetLastNtError(Status);
-        IntReleaseWindowObject(WindowObject);
-        return 0;
+         SetLastNtError(Status);
+         RETURN( 0);
       }
-      Buffer += Copy;
-    }
-    
-    Status = MmCopyToCaller(Buffer, &Terminator, sizeof(WCHAR));
-    if(!NT_SUCCESS(Status))
-    {
-      SetLastNtError(Status);
-      IntReleaseWindowObject(WindowObject);
-      return 0;
-    }
-    
-    Result = Copy;
-  }
-  
-  IntReleaseWindowObject(WindowObject);
-  return Result;
+
+      Result = Copy;
+   }
+
+   RETURN( Result);
+
+CLEANUP:
+   DPRINT("Leave NtUserInternalGetWindowText, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 DWORD STDCALL
 NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data)
 {
-       WndProcHandle Entry;
-       if (((DWORD)wpHandle & 0xFFFF0000) == 0xFFFF0000)
-       {
-               Entry = WndProcHandlesArray[(DWORD)wpHandle & 0x0000FFFF];
-               Data->WindowProc = Entry.WindowProc;
-               Data->IsUnicode = Entry.IsUnicode;
-               Data->ProcessID = Entry.ProcessID;
-               return TRUE;
-       } else {
-               return FALSE;
-       }
-       return FALSE;
+   DECLARE_RETURN(DWORD);
+
+   DPRINT("Enter NtUserDereferenceWndProcHandle\n");
+   UserEnterShared();
+
+   WndProcHandle Entry;
+   if (((DWORD)wpHandle & 0xFFFF0000) == 0xFFFF0000)
+   {
+      Entry = WndProcHandlesArray[(DWORD)wpHandle & 0x0000FFFF];
+      Data->WindowProc = Entry.WindowProc;
+      Data->IsUnicode = Entry.IsUnicode;
+      Data->ProcessID = Entry.ProcessID;
+      RETURN(  TRUE);
+   }
+   else
+   {
+      RETURN(  FALSE);
+   }
+   RETURN( FALSE);
+
+CLEANUP:
+   DPRINT("Leave NtUserDereferenceWndProcHandle, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 DWORD
 IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode)
 {
-       WORD i;
-       WORD FreeSpot = 0;
-       BOOL found;
-       WndProcHandle *OldArray;
-       WORD OldArraySize;
-       found = FALSE;
-       for (i = 0;i < WndProcHandlesArraySize;i++)
-       {
-               if (WndProcHandlesArray[i].WindowProc == NULL)
-               {
-                       FreeSpot = i;
-                       found = TRUE;
-               }
-       }
-       if (!found)
-       {
-               OldArray = WndProcHandlesArray;
-               OldArraySize = WndProcHandlesArraySize;
-        WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,(OldArraySize + WPH_SIZE) * sizeof(WndProcHandle), TAG_WINPROCLST);
-               WndProcHandlesArraySize = OldArraySize + WPH_SIZE;
-               RtlCopyMemory(WndProcHandlesArray,OldArray,OldArraySize * sizeof(WndProcHandle));
-               ExFreePool(OldArray);
-               FreeSpot = OldArraySize + 1;
-       }
-       WndProcHandlesArray[FreeSpot].WindowProc = WindowProc;
-       WndProcHandlesArray[FreeSpot].IsUnicode = IsUnicode;
-       WndProcHandlesArray[FreeSpot].ProcessID = PsGetCurrentProcessId();
-       return FreeSpot + 0xFFFF0000;
+   WORD i;
+   WORD FreeSpot = 0;
+   BOOL found;
+   WndProcHandle *OldArray;
+   WORD OldArraySize;
+   found = FALSE;
+   for (i = 0;i < WndProcHandlesArraySize;i++)
+   {
+      if (WndProcHandlesArray[i].WindowProc == NULL)
+      {
+         FreeSpot = i;
+         found = TRUE;
+      }
+   }
+   if (!found)
+   {
+      OldArray = WndProcHandlesArray;
+      OldArraySize = WndProcHandlesArraySize;
+      WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,(OldArraySize + WPH_SIZE) * sizeof(WndProcHandle), TAG_WINPROCLST);
+      WndProcHandlesArraySize = OldArraySize + WPH_SIZE;
+      RtlCopyMemory(WndProcHandlesArray,OldArray,OldArraySize * sizeof(WndProcHandle));
+      ExFreePool(OldArray);
+      FreeSpot = OldArraySize + 1;
+   }
+   WndProcHandlesArray[FreeSpot].WindowProc = WindowProc;
+   WndProcHandlesArray[FreeSpot].IsUnicode = IsUnicode;
+   WndProcHandlesArray[FreeSpot].ProcessID = PsGetCurrentProcessId();
+   return FreeSpot + 0xFFFF0000;
 }
 
 DWORD
 IntRemoveWndProcHandle(WNDPROC Handle)
 {
-       WORD position;
-       position = (DWORD)Handle & 0x0000FFFF;
-       if (position > WndProcHandlesArraySize)
-       {
-               return FALSE;
-       }
-       WndProcHandlesArray[position].WindowProc = NULL;
-       WndProcHandlesArray[position].IsUnicode = FALSE;
-       WndProcHandlesArray[position].ProcessID = NULL;
-       return TRUE;
+   WORD position;
+   position = (DWORD)Handle & 0x0000FFFF;
+   if (position > WndProcHandlesArraySize)
+   {
+      return FALSE;
+   }
+   WndProcHandlesArray[position].WindowProc = NULL;
+   WndProcHandlesArray[position].IsUnicode = FALSE;
+   WndProcHandlesArray[position].ProcessID = NULL;
+   return TRUE;
 }
 
 DWORD
 IntRemoveProcessWndProcHandles(HANDLE ProcessID)
 {
-       WORD i;
-       for (i = 0;i < WndProcHandlesArraySize;i++)
-       {
-               if (WndProcHandlesArray[i].ProcessID == ProcessID)
-               {
-                       WndProcHandlesArray[i].WindowProc = NULL;
-                       WndProcHandlesArray[i].IsUnicode = FALSE;
-                       WndProcHandlesArray[i].ProcessID = NULL;
-               }
-       }
-       return TRUE;
+   WORD i;
+   for (i = 0;i < WndProcHandlesArraySize;i++)
+   {
+      if (WndProcHandlesArray[i].ProcessID == ProcessID)
+      {
+         WndProcHandlesArray[i].WindowProc = NULL;
+         WndProcHandlesArray[i].IsUnicode = FALSE;
+         WndProcHandlesArray[i].ProcessID = NULL;
+      }
+   }
+   return TRUE;
+}
+
+#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
+
+BOOL
+FASTCALL
+IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
+{
+   int count = 0;
+   PWINDOW_OBJECT pWnd;
+   HWND *win_array;
+
+   ASSERT(OwnerWnd);
+
+   win_array = IntWinListChildren(OwnerWnd);//faxme: use desktop?
+
+   if (!win_array)
+      return TRUE;
+
+   while (win_array[count])
+      count++;
+   while (--count >= 0)
+   {
+      if (UserGetWindow( win_array[count], GW_OWNER ) != OwnerWnd->hSelf)
+         continue;
+      if (!(pWnd = UserGetWindowObject( win_array[count] )))
+         continue;
+      //        if (pWnd == WND_OTHER_PROCESS) continue;
+
+      if (fShow)
+      {
+         if (pWnd->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
+         {
+            /* In Windows, ShowOwnedPopups(TRUE) generates
+             * WM_SHOWWINDOW messages with SW_PARENTOPENING,
+             * regardless of the state of the owner
+             */
+            co_IntSendMessage(win_array[count], WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING);
+            continue;
+         }
+      }
+      else
+      {
+         if (pWnd->Style & WS_VISIBLE)
+         {
+            /* In Windows, ShowOwnedPopups(FALSE) generates
+             * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
+             * regardless of the state of the owner
+             */
+            co_IntSendMessage(win_array[count], WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
+            continue;
+         }
+      }
+
+   }
+   ExFreePool( win_array );
+   return TRUE;
 }
 
+
 /* EOF */