[CMAKE]
[reactos.git] / subsystems / win32 / win32k / ntuser / window.c
index 896a9f9..046515c 100644 (file)
@@ -10,7 +10,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -29,7 +29,9 @@
  * Initialize windowing implementation.
  */
 
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
 InitWindowImpl(VOID)
 {
    return STATUS_SUCCESS;
@@ -84,27 +86,27 @@ BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
     return TRUE;
 }
 
-PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
+PWND FASTCALL IntGetWindowObject(HWND hWnd)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
 
    if (!hWnd) return NULL;
 
    Window = UserGetWindowObject(hWnd);
    if (Window)
    {
-      ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+      ASSERT(Window->head.cLockObj >= 0);
 
-      USER_BODY_TO_HEADER(Window)->RefCount++;
+      Window->head.cLockObj++;
    }
    return Window;
 }
 
 /* temp hack */
-PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
+PWND FASTCALL UserGetWindowObject(HWND hWnd)
 {
    PTHREADINFO ti;
-   PWINDOW_OBJECT Window;
+   PWND Window;
 
    if (PsGetCurrentProcess() != PsInitialSystemProcess)
    {
@@ -122,14 +124,15 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
       return NULL;
    }
 
-   Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
-   if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
+   Window = (PWND)UserGetObject(gHandleTable, hWnd, otWindow);
+   if (!Window || 0 != (Window->state & WNDS_DESTROYED))
    {
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
 
-   ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+   ASSERT(Window->head.cLockObj >= 0);
+
    return Window;
 }
 
@@ -153,7 +156,7 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
 BOOL FASTCALL
 IntIsWindow(HWND hWnd)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
 
    if (!(Window = UserGetWindowObject(hWnd)))
       return FALSE;
@@ -162,45 +165,21 @@ IntIsWindow(HWND hWnd)
 }
 
 
-
-/*
-  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
-IntGetParent(PWINDOW_OBJECT Wnd)
+PWND FASTCALL
+IntGetParent(PWND Wnd)
 {
-   if (!Wnd->Wnd) return NULL;
-
-   if (Wnd->Wnd->style & WS_POPUP)
+   if (Wnd->style & WS_POPUP)
    {
-      return UserGetWindowObject(Wnd->hOwner);
+       return Wnd->spwndOwner;
    }
-   else if (Wnd->Wnd->style & WS_CHILD)
+   else if (Wnd->style & WS_CHILD)
    {
-      return Wnd->Parent;
+      return Wnd->spwndParent;
    }
 
    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)
-{
-   return UserGetWindowObject(Wnd->hOwner);
-}
-
-
-
 /*
  * IntWinListChildren
  *
@@ -212,15 +191,15 @@ IntGetOwner(PWINDOW_OBJECT Wnd)
  */
 
 HWND* FASTCALL
-IntWinListChildren(PWINDOW_OBJECT Window)
+IntWinListChildren(PWND Window)
 {
-   PWINDOW_OBJECT Child;
+   PWND Child;
    HWND *List;
    UINT Index, NumChildren = 0;
 
    if (!Window) return NULL;
 
-   for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
+   for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       ++NumChildren;
 
    List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
@@ -230,10 +209,10 @@ IntWinListChildren(PWINDOW_OBJECT Window)
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
       return NULL;
    }
-   for (Child = Window->FirstChild, Index = 0;
+   for (Child = Window->spwndChild, Index = 0;
          Child != NULL;
-         Child = Child->NextSibling, ++Index)
-      List[Index] = Child->hSelf;
+         Child = Child->spwndNext, ++Index)
+      List[Index] = Child->head.h;
    List[Index] = NULL;
 
    return List;
@@ -245,7 +224,7 @@ IntWinListChildren(PWINDOW_OBJECT Window)
 static void IntSendDestroyMsg(HWND hWnd)
 {
 
-   PWINDOW_OBJECT Window;
+   PWND Window;
 #if 0 /* FIXME */
 
    GUITHREADINFO info;
@@ -265,7 +244,7 @@ static void IntSendDestroyMsg(HWND hWnd)
 //      USER_REFERENCE_ENTRY Ref;
 //      UserRefObjectCo(Window, &Ref);
 
-      if (!IntGetOwner(Window) && !IntGetParent(Window))
+      if (!Window->spwndOwner && !IntGetParent(Window))
       {
          co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd);
       }
@@ -314,17 +293,16 @@ static void IntSendDestroyMsg(HWND hWnd)
 }
 
 static VOID
-UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
+UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd)
 {
     PCLIENTINFO ClientInfo = GetWin32ClientInfo();
-    PWND Wnd = WindowObject->Wnd;
 
     if (!Wnd) return;
     
-    if (ClientInfo->CallbackWnd.pvWnd == DesktopHeapAddressToUser(WindowObject->Wnd))
+    if (ClientInfo->CallbackWnd.pWnd == DesktopHeapAddressToUser(Wnd))
     {
         ClientInfo->CallbackWnd.hWnd = NULL;
-        ClientInfo->CallbackWnd.pvWnd = NULL;
+        ClientInfo->CallbackWnd.pWnd = NULL;
     }
 
    if (Wnd->strName.Buffer != NULL)
@@ -336,8 +314,8 @@ UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
        Wnd->strName.Buffer = NULL;
    }
 
-    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
-    WindowObject->Wnd = NULL;
+//    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
+//    WindowObject->Wnd = NULL;
 }
 
 /***********************************************************************
@@ -349,31 +327,28 @@ UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
  * done in CreateWindow is undone here and not in DestroyWindow:-P
 
  */
-static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
+static LRESULT co_UserFreeWindow(PWND Window,
                                    PPROCESSINFO ProcessData,
                                    PTHREADINFO ThreadData,
                                    BOOLEAN SendMessages)
 {
    HWND *Children;
    HWND *ChildHandle;
-   PWINDOW_OBJECT Child;
+   PWND Child;
    PMENU_OBJECT Menu;
    BOOLEAN BelongsToThreadData;
-   PWND Wnd;
 
    ASSERT(Window);
 
-   Wnd = Window->Wnd;
-
-   if(Window->Status & WINDOWSTATUS_DESTROYING)
+   if(Window->state2 & WNDS2_INDESTROY)
    {
       DPRINT("Tried to call IntDestroyWindow() twice\n");
       return 0;
    }
-   Window->Status |= WINDOWSTATUS_DESTROYING;
-   Wnd->style &= ~WS_VISIBLE;
+   Window->state2 |= WNDS2_INDESTROY;
+   Window->style &= ~WS_VISIBLE;
 
-   IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Wnd, OBJID_WINDOW, 0);
+   IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 
    /* 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
@@ -382,12 +357,12 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 
    BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
 
-   IntDeRegisterShellHookWindow(Window->hSelf);
+   IntDeRegisterShellHookWindow(Window->head.h);
 
    if(SendMessages)
    {
       /* Send destroy messages */
-      IntSendDestroyMsg(Window->hSelf);
+      IntSendDestroyMsg(Window->head.h);
    }
 
    /* free child windows */
@@ -401,7 +376,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
             if(!IntWndBelongsToThread(Child, ThreadData))
             {
                /* send WM_DESTROY messages to windows not belonging to the same thread */
-               IntSendDestroyMsg(Child->hSelf);
+               IntSendDestroyMsg(Child->head.h);
             }
             else
                co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
@@ -422,29 +397,28 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
                           RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
                           RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
       if(BelongsToThreadData)
-         co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0);
+         co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
    }
-   MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf);
-   HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
+
+   DestroyTimersForWindow(ThreadData, Window);
 
    /* flush the message queue */
    MsqRemoveWindowMessagesFromQueue(Window);
 
    /* from now on no messages can be sent to this window anymore */
-   Window->Status |= WINDOWSTATUS_DESTROYED;
-   Wnd->state |= WNDS_DESTROYED;
-   Wnd->fnid |= FNID_FREED;
+   Window->state |= WNDS_DESTROYED;
+   Window->fnid |= FNID_FREED;
 
    /* don't remove the WINDOWSTATUS_DESTROYING bit */
 
    /* reset shell window handles */
-   if(ThreadData->Desktop)
+   if(ThreadData->rpdesk)
    {
-      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellWindow)
-         ThreadData->Desktop->WindowStation->ShellWindow = NULL;
+      if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
+         ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
 
-      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellListView)
-         ThreadData->Desktop->WindowStation->ShellListView = NULL;
+      if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellListView)
+         ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
    }
 
    /* Unregister hot keys */
@@ -454,21 +428,21 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 
 #if 0 /* FIXME */
 
-   WinPosCheckInternalPos(Window->hSelf);
-   if (Window->hSelf == GetCapture())
+   WinPosCheckInternalPos(Window->head.h);
+   if (Window->head.h == GetCapture())
    {
       ReleaseCapture();
    }
 
    /* free resources associated with the window */
-   TIMER_RemoveWindowTimers(Window->hSelf);
+   TIMER_RemoveWindowTimers(Window->head.h);
 #endif
 
-   if (!(Wnd->style & WS_CHILD) && Wnd->IDMenu
-       && (Menu = UserGetMenuObject((HMENU)Wnd->IDMenu)))
+   if (!(Window->style & WS_CHILD) && Window->IDMenu
+       && (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
    {
       IntDestroyMenuObject(Menu, TRUE, TRUE);
-      Wnd->IDMenu = 0;
+      Window->IDMenu = 0;
    }
 
    if(Window->SystemMenu
@@ -488,23 +462,23 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
    IntUnlinkWindow(Window);
 
    UserReferenceObject(Window);
-   UserDeleteObject(Window->hSelf, otWindow);
+   UserDeleteObject(Window->head.h, otWindow);
 
    IntDestroyScrollBars(Window);
 
    /* dereference the class */
-   IntDereferenceClass(Wnd->pcls,
-                       Window->ti->pDeskInfo,
-                       Window->ti->ppi);
-   Wnd->pcls = NULL;
+   IntDereferenceClass(Window->pcls,
+                       Window->head.pti->pDeskInfo,
+                       Window->head.pti->ppi);
+   Window->pcls = NULL;
 
-   if(Window->WindowRegion)
+   if(Window->hrgnClip)
    {
-      GreDeleteObject(Window->WindowRegion);
+      GreDeleteObject(Window->hrgnClip);
    }
 
-   ASSERT(Window->Wnd != NULL);
-   UserFreeWindowInfo(Window->ti, Window);
+//   ASSERT(Window != NULL);
+   UserFreeWindowInfo(Window->head.pti, Window);
 
    UserDereferenceObject(Window);
 
@@ -514,9 +488,8 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 }
 
 VOID FASTCALL
-IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
+IntGetWindowBorderMeasures(PWND Wnd, UINT *cx, UINT *cy)
 {
-   PWND Wnd = Window->Wnd;
    if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style & WS_MINIMIZE))
    {
       *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
@@ -663,6 +636,8 @@ IntSetWindowProc(PWND pWnd,
       if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
          pWnd->state &= ~WNDS_SERVERSIDEWINDOWPROC;
 
+      if (!NewWndProc) NewWndProc = pWnd->lpfnWndProc;
+
       if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
       {
          if (Ansi)
@@ -684,17 +659,15 @@ IntSetWindowProc(PWND pWnd,
 
 // Move this to user space!
 BOOL FASTCALL
-IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
+IntGetWindowInfo(PWND Wnd, PWINDOWINFO pwi)
 {
-   PWND Wnd = Window->Wnd;
-
    pwi->cbSize = sizeof(WINDOWINFO);
-   pwi->rcWindow = Window->Wnd->rcWindow;
-   pwi->rcClient = Window->Wnd->rcClient;
+   pwi->rcWindow = Wnd->rcWindow;
+   pwi->rcClient = Wnd->rcClient;
    pwi->dwStyle = Wnd->style;
    pwi->dwExStyle = Wnd->ExStyle;
-   pwi->dwWindowStatus = (UserGetForegroundWindow() == Window->hSelf); /* WS_ACTIVECAPTION */
-   IntGetWindowBorderMeasures(Window, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
+   pwi->dwWindowStatus = (UserGetForegroundWindow() == Wnd->head.h); /* WS_ACTIVECAPTION */
+   IntGetWindowBorderMeasures(Wnd, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
    pwi->atomWindowType = (Wnd->pcls ? Wnd->pcls->atomClassName : 0);
    pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
    return TRUE;
@@ -702,12 +675,11 @@ IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
 
 static BOOL FASTCALL
 IntSetMenu(
-   PWINDOW_OBJECT Window,
+   PWND Wnd,
    HMENU Menu,
    BOOL *Changed)
 {
    PMENU_OBJECT OldMenu, NewMenu = NULL;
-   PWND Wnd = Window->Wnd;
 
    if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
    {
@@ -724,7 +696,7 @@ IntSetMenu(
    if (Wnd->IDMenu)
    {
       OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu);
-      ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Window->hSelf);
+      ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Wnd->head.h);
    }
    else
    {
@@ -759,7 +731,7 @@ IntSetMenu(
    Wnd->IDMenu = (UINT) Menu;
    if (NULL != NewMenu)
    {
-      NewMenu->MenuInfo.Wnd = Window->hSelf;
+      NewMenu->MenuInfo.Wnd = Wnd->head.h;
       IntReleaseMenuObject(NewMenu);
    }
    if (NULL != OldMenu)
@@ -780,14 +752,14 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
 {
    PTHREADINFO WThread;
    PLIST_ENTRY Current;
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    USER_REFERENCE_ENTRY Ref;
    WThread = (PTHREADINFO)Thread->Tcb.Win32Thread;
 
    while (!IsListEmpty(&WThread->WindowListHead))
    {
       Current = WThread->WindowListHead.Flink;
-      Wnd = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+      Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
 
       DPRINT("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
 
@@ -818,14 +790,14 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
  * \note Does not check the validity of the parameters
 */
 VOID FASTCALL
-IntGetClientRect(PWINDOW_OBJECT Window, RECTL *Rect)
+IntGetClientRect(PWND Window, RECTL *Rect)
 {
    ASSERT( Window );
    ASSERT( Rect );
 
    Rect->left = Rect->top = 0;
-   Rect->right = Window->Wnd->rcClient.right - Window->Wnd->rcClient.left;
-   Rect->bottom = Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top;
+   Rect->right = Window->rcClient.right - Window->rcClient.left;
+   Rect->bottom = Window->rcClient.bottom - Window->rcClient.top;
 }
 
 
@@ -849,7 +821,7 @@ IntGetFocusWindow(VOID)
 #endif
 
 PMENU_OBJECT FASTCALL
-IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
+IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
 {
    PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
    PTHREADINFO W32Thread;
@@ -860,7 +832,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
    {
       W32Thread = PsGetCurrentThreadWin32Thread();
 
-      if(!W32Thread->Desktop)
+      if(!W32Thread->rpdesk)
          return NULL;
 
       if(Window->SystemMenu)
@@ -873,10 +845,10 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
          }
       }
 
-      if(W32Thread->Desktop->WindowStation->SystemMenuTemplate)
+      if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
       {
          /* clone system menu */
-         Menu = UserGetMenuObject(W32Thread->Desktop->WindowStation->SystemMenuTemplate);
+         Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
          if(!Menu)
             return NULL;
 
@@ -885,7 +857,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
          {
             Window->SystemMenu = NewMenu->MenuInfo.Self;
             NewMenu->MenuInfo.Flags |= MF_SYSMENU;
-            NewMenu->MenuInfo.Wnd = Window->hSelf;
+            NewMenu->MenuInfo.Wnd = Window->head.h;
             ret = NewMenu;
             //IntReleaseMenuObject(NewMenu);
          }
@@ -904,7 +876,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
             return NULL;
          }
          SysMenu->MenuInfo.Flags |= MF_SYSMENU;
-         SysMenu->MenuInfo.Wnd = Window->hSelf;
+         SysMenu->MenuInfo.Wnd = Window->head.h;
          hNewMenu = co_IntLoadSysMenuTemplate();
          if(!hNewMenu)
          {
@@ -958,53 +930,49 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
 
 
 BOOL FASTCALL
-IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
+IntIsChildWindow(PWND Parent, PWND BaseWindow)
 {
-   PWINDOW_OBJECT Window;
-   PWND Wnd;
+   PWND Window;
 
    Window = BaseWindow;
    while (Window)
    {
-      Wnd = Window->Wnd;
       if (Window == Parent)
       {
          return(TRUE);
       }
-      if(!(Wnd->style & WS_CHILD))
+      if(!(Window->style & WS_CHILD))
       {
          break;
       }
 
-      Window = Window->Parent;
+      Window = Window->spwndParent;
    }
 
    return(FALSE);
 }
 
 BOOL FASTCALL
-IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
+IntIsWindowVisible(PWND BaseWindow)
 {
-   PWINDOW_OBJECT Window;
-   PWND Wnd;
+   PWND Window;
 
    Window = BaseWindow;
    while(Window)
    {
-      Wnd = Window->Wnd;
-      if(!(Wnd->style & WS_CHILD))
+      if(!(Window->style & WS_CHILD))
       {
          break;
       }
-      if(!(Wnd->style & WS_VISIBLE))
+      if(!(Window->style & WS_VISIBLE))
       {
          return FALSE;
       }
 
-      Window = Window->Parent;
+      Window = Window->spwndParent;
    }
 
-   if(Window && Wnd->style & WS_VISIBLE)
+   if(Window && Window->style & WS_VISIBLE)
    {
       return TRUE;
    }
@@ -1013,91 +981,152 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
 }
 
 
-/* link the window into siblings and parent. children are kept in place. */
+/* 
+   link the window into siblings list 
+   children and parent are kept in place.
+*/
 VOID FASTCALL
 IntLinkWindow(
-   PWINDOW_OBJECT Wnd,
-   PWINDOW_OBJECT WndParent,
-   PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
+   PWND Wnd,
+   PWND WndInsertAfter /* set to NULL if top sibling */
 )
 {
-   PWINDOW_OBJECT Parent;
-
-   Wnd->Parent = WndParent;
-   Wnd->Wnd->spwndParent = WndParent ? WndParent->Wnd : NULL;
-   if ((Wnd->PrevSibling = WndPrevSibling))
+  if ((Wnd->spwndPrev = WndInsertAfter))
    {
-      /* 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;
+      /* link after WndInsertAfter */
+      if ((Wnd->spwndNext = WndInsertAfter->spwndNext))
+         Wnd->spwndNext->spwndPrev = Wnd;
+
+      Wnd->spwndPrev->spwndNext = 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;
-      }
+     if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild))
+         Wnd->spwndNext->spwndPrev = Wnd;
+
+     Wnd->spwndParent->spwndChild = Wnd;
    }
+}
+
+
+VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
+{
+    if (hWndPrev == HWND_NOTOPMOST)
+    {
+        if (!(Wnd->ExStyle & WS_EX_TOPMOST) && 
+            (Wnd->ExStyle2 & WS_EX2_LINKED)) return;  /* nothing to do */
+        Wnd->ExStyle &= ~WS_EX_TOPMOST;
+        hWndPrev = HWND_TOP;  /* fallback to the HWND_TOP case */
+    }
+
+    IntUnlinkWindow(Wnd);  /* unlink it from the previous location */
+    
+    if (hWndPrev == HWND_BOTTOM)
+    {
+        /* Link in the bottom of the list */
+        PWND WndInsertAfter;
 
+        WndInsertAfter = Wnd->spwndParent->spwndChild;
+        while( WndInsertAfter && WndInsertAfter->spwndNext)
+            WndInsertAfter = WndInsertAfter->spwndNext;
+
+        IntLinkWindow(Wnd, WndInsertAfter);
+        Wnd->ExStyle &= ~WS_EX_TOPMOST;
+    }
+    else if (hWndPrev == HWND_TOPMOST)
+    {
+        /* Link in the top of the list */
+        IntLinkWindow(Wnd, NULL);
+
+        Wnd->ExStyle |= WS_EX_TOPMOST;
+    }
+    else if (hWndPrev == HWND_TOP)
+    {
+        /* Link it after the last topmost window */
+        PWND WndInsertBefore;
+
+        WndInsertBefore = Wnd->spwndParent->spwndChild;
+
+        if (!(Wnd->ExStyle & WS_EX_TOPMOST))  /* put it above the first non-topmost window */
+        {
+            while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL)
+            {
+                if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST)) break;
+                if (WndInsertBefore == Wnd->spwndOwner)  /* keep it above owner */
+                {
+                    Wnd->ExStyle |= WS_EX_TOPMOST;
+                    break;
+                }
+                WndInsertBefore = WndInsertBefore->spwndNext;
+            }
+        }
+
+        IntLinkWindow(Wnd, WndInsertBefore ? WndInsertBefore->spwndPrev : NULL);
+    }
+    else
+    {
+        /* Link it after hWndPrev */
+        PWND WndInsertAfter;
+
+        WndInsertAfter = UserGetWindowObject(hWndPrev);
+        /* Are we called with an erroneous handle */
+        if(WndInsertAfter == NULL)
+        {
+            /* Link in a default position */
+            IntLinkHwnd(Wnd, HWND_TOP);
+            return;
+        }
+
+        IntLinkWindow(Wnd, WndInsertAfter);
+
+        /* Fix the WS_EX_TOPMOST flag */
+        if (!(WndInsertAfter->ExStyle & WS_EX_TOPMOST)) 
+        {
+            Wnd->ExStyle &= ~WS_EX_TOPMOST;
+        }
+        else
+        {
+            if(WndInsertAfter->spwndNext &&
+               WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST)
+            {
+                Wnd->ExStyle |= WS_EX_TOPMOST;
+            }
+        }
+    }
 }
 
 HWND FASTCALL
 IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 {
-   PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner;
+   PWND Wnd, WndOldOwner, WndNewOwner;
    HWND ret;
 
    Wnd = IntGetWindowObject(hWnd);
    if(!Wnd)
       return NULL;
 
-   WndOldOwner = IntGetWindowObject(Wnd->hOwner);
-   if (WndOldOwner)
-   {
-      ret = WndOldOwner->hSelf;
-      UserDereferenceObject(WndOldOwner);
-   }
-   else
-   {
-      ret = 0;
-   }
+   WndOldOwner = Wnd->spwndOwner;
+
+   ret = WndOldOwner ? WndOldOwner->head.h : 0;
 
    if((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
    {
-      Wnd->hOwner = hWndNewOwner;
-      Wnd->Wnd->spwndOwner = WndNewOwner->Wnd;
+       Wnd->spwndOwner= WndNewOwner;
    }
    else
    {
-      Wnd->hOwner = NULL;
-      Wnd->Wnd->spwndOwner = NULL;
+       Wnd->spwndOwner = NULL;
    }
 
    UserDereferenceObject(Wnd);
    return ret;
 }
 
-PWINDOW_OBJECT FASTCALL
-co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
+PWND FASTCALL
+co_IntSetParent(PWND Wnd, PWND WndNewParent)
 {
-   PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter;
-//   HWND hWnd, hWndNewParent;
+   PWND WndOldParent;
    BOOL WasVisible;
 
    ASSERT(Wnd);
@@ -1105,9 +1134,6 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
    ASSERT_REFS_CO(Wnd);
    ASSERT_REFS_CO(WndNewParent);
 
-//   hWnd = Wnd->hSelf;
-//   hWndNewParent = WndNewParent->hSelf;
-
    /* Some applications try to set a child as a parent */
    if (IntIsChildWindow(Wnd, WndNewParent))
    {
@@ -1121,50 +1147,34 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
     */
    WasVisible = co_WinPosShowWindow(Wnd, SW_HIDE);
 
-//   /* 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())
+   if (Wnd->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
       return NULL;
 
-   WndOldParent = Wnd->Parent;
+   WndOldParent = Wnd->spwndParent;
 
    if (WndOldParent) UserReferenceObject(WndOldParent); /* caller must deref */
 
    if (WndNewParent != WndOldParent)
    {
+      /* Unlink the window from the siblings list */
       IntUnlinkWindow(Wnd);
-      InsertAfter = NULL;
-      if (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST))
-      {
-         /* Not a TOPMOST window, put after TOPMOSTs of new parent */
-         Sibling = WndNewParent->FirstChild;
-         while (NULL != Sibling && 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
-         {
-            InsertAfter = Sibling;
-            Sibling = Sibling->NextSibling;
-         }
-      }
-      if (NULL == InsertAfter)
-      {
-         IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
-      }
-      else
-      {
-//         UserReferenceObject(InsertAfter);
-         IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
-//         UserDereferenceObject(InsertAfter);
-      }
+
+      /* Set the new parent */
+      Wnd->spwndParent = WndNewParent;
+
+      /* Link the window with its new siblings*/
+      IntLinkHwnd(Wnd, HWND_TOP);
+
    }
 
+   IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
    /*
     * SetParent additionally needs to make hwnd the top window
     * in the z-order and send the expected WM_WINDOWPOSCHANGING and
     * WM_WINDOWPOSCHANGED notification messages.
     */
-   co_WinPosSetWindowPos(Wnd, (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
+   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));
 
@@ -1173,28 +1183,11 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
     * 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
-    */
-//   if(WndOldParent)
-//   {
-//      if(!IntIsWindow(WndOldParent->hSelf))
-//      {
-//         UserDereferenceObject(WndOldParent);
-//         return NULL;
-//      }
-
-      /* don't dereference the window object here, it must be done by the caller
-         of IntSetParent() */
-//      return WndOldParent;
-//   }
-
-   return WndOldParent;//NULL;
+   return WndOldParent;
 }
 
 BOOL FASTCALL
-IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
+IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
 {
    PMENU_OBJECT OldMenu;
    if(Window->SystemMenu)
@@ -1219,68 +1212,28 @@ IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
    return TRUE;
 }
 
-
-/* unlink the window from siblings and parent. children are kept in place. */
+/* unlink the window from siblings. children and parent are kept in place. */
 VOID FASTCALL
-IntUnlinkWindow(PWINDOW_OBJECT Wnd)
+IntUnlinkWindow(PWND 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;
-   if (Wnd->Wnd)
-       Wnd->Wnd->spwndParent = NULL;
-}
-
-BOOL FASTCALL
-IntAnyPopup(VOID)
-{
-   PWINDOW_OBJECT Window, Child;
-
-   if(!(Window = UserGetWindowObject(IntGetDesktopWindow())))
-   {
-      return FALSE;
-   }
-
-   for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
-   {
-      if(Child->hOwner && Child->Wnd->style & WS_VISIBLE)
-      {
-         /*
-          * The desktop has a popup window if one of them has
-          * an owner window and is visible
-          */
-         return TRUE;
-      }
-   }
-
-   return FALSE;
+   if (Wnd->spwndNext)
+       Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
+   if (Wnd->spwndPrev)
+       Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
+
+   if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
+       Wnd->spwndParent->spwndChild = Wnd->spwndNext;
+   Wnd->spwndPrev = Wnd->spwndNext = NULL;
 }
 
-BOOL FASTCALL
-IntIsWindowInDestroy(PWINDOW_OBJECT Window)
-{
-   return ((Window->Status & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
-}
-
-
 BOOL
 FASTCALL
-IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
+IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
 {
-   PWND Wnd;
    POINT Size;
 
-   Wnd = Window->Wnd;
    if (!Wnd) return FALSE;
 
    if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
@@ -1293,7 +1246,7 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
    {
       lpwndpl->showCmd = SW_HIDE;
    }
-   else if (0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+   else if (0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
             0 != (Wnd->style & WS_MAXIMIZE))
    {
       lpwndpl->showCmd = SW_MAXIMIZE;
@@ -1309,7 +1262,7 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
 
    Size.x = Wnd->rcWindow.left;
    Size.y = Wnd->rcWindow.top;
-   WinPosInitInternalPos(Window, &Size,
+   WinPosInitInternalPos(Wnd, &Size,
                          &Wnd->rcWindow);
 
    lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
@@ -1366,7 +1319,7 @@ NtUserBuildHwndList(
    if (hwndParent || !dwThreadId)
    {
       PDESKTOP Desktop;
-      PWINDOW_OBJECT Parent, Window;
+      PWND Parent, Window;
 
       if(!hwndParent)
       {
@@ -1394,7 +1347,7 @@ NtUserBuildHwndList(
       }
 
       if((Parent = UserGetWindowObject(hwndParent)) &&
-         (Window = Parent->FirstChild))
+         (Window = Parent->spwndChild))
       {
          BOOL bGoDown = TRUE;
 
@@ -1408,7 +1361,7 @@ NtUserBuildHwndList(
                   _SEH2_TRY
                   {
                      ProbeForWrite(pWnd, sizeof(HWND), 1);
-                     *pWnd = Window->hSelf;
+                     *pWnd = Window->head.h;
                      pWnd++;
                   }
                   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -1422,20 +1375,20 @@ NtUserBuildHwndList(
                      break;
                   }
                }
-               if (Window->FirstChild && bChildren)
+               if (Window->spwndChild && bChildren)
                {
-                  Window = Window->FirstChild;
+                  Window = Window->spwndChild;
                   continue;
                }
                bGoDown = FALSE;
             }
-            if (Window->NextSibling)
+            if (Window->spwndNext)
             {
-               Window = Window->NextSibling;
+               Window = Window->spwndNext;
                bGoDown = TRUE;
                continue;
             }
-            Window = Window->Parent;
+            Window = Window->spwndParent;
             if (Window == Parent)
             {
                break;
@@ -1453,7 +1406,7 @@ NtUserBuildHwndList(
       PETHREAD Thread;
       PTHREADINFO W32Thread;
       PLIST_ENTRY Current;
-      PWINDOW_OBJECT Window;
+      PWND Window;
 
       Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
       if(!NT_SUCCESS(Status))
@@ -1470,14 +1423,14 @@ NtUserBuildHwndList(
       Current = W32Thread->WindowListHead.Flink;
       while(Current != &(W32Thread->WindowListHead))
       {
-         Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+         Window = CONTAINING_RECORD(Current, WND, ThreadListEntry);
          ASSERT(Window);
 
-         if(bChildren || Window->hOwner != NULL)
+         if(bChildren || Window->spwndOwner != NULL)
          {
              if(dwCount < *pBufSize && pWnd)
              {
-                Status = MmCopyToCaller(pWnd++, &Window->hSelf, sizeof(HWND));
+                Status = MmCopyToCaller(pWnd++, &Window->head.h, sizeof(HWND));
                 if(!NT_SUCCESS(Status))
                 {
                    SetLastNtError(Status);
@@ -1506,7 +1459,7 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
                              LONG y,
                              UINT uiFlags)
 {
-   PWINDOW_OBJECT Parent;
+   PWND Parent;
    POINTL Pt;
    HWND Ret;
    HWND *List, *phWnd;
@@ -1519,10 +1472,10 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
    Pt.x = x;
    Pt.y = y;
 
-   if(Parent->hSelf != IntGetDesktopWindow())
+   if(Parent->head.h != IntGetDesktopWindow())
    {
-      Pt.x += Parent->Wnd->rcClient.left;
-      Pt.y += Parent->Wnd->rcClient.top;
+      Pt.x += Parent->rcClient.left;
+      Pt.y += Parent->rcClient.top;
    }
 
    if(!IntPtInWindow(Parent, Pt.x, Pt.y))
@@ -1530,31 +1483,29 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
       return NULL;
    }
 
-   Ret = Parent->hSelf;
+   Ret = Parent->head.h;
    if((List = IntWinListChildren(Parent)))
    {
       for(phWnd = List; *phWnd; phWnd++)
       {
-         PWINDOW_OBJECT Child;
-         PWND ChildWnd;
+         PWND Child;
          if((Child = UserGetWindowObject(*phWnd)))
          {
-            ChildWnd = Child->Wnd;
-            if(!(ChildWnd->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
+            if(!(Child->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
             {
                continue;
             }
-            if((ChildWnd->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
+            if((Child->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
             {
                continue;
             }
-            if((ChildWnd->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
+            if((Child->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
             {
                continue;
             }
             if(IntPtInWindow(Child, Pt.x, Pt.y))
             {
-               Ret = Child->hSelf;
+               Ret = Child->head.h;
                break;
             }
          }
@@ -1565,287 +1516,203 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
    return Ret;
 }
 
-
-/*
- * calculates the default position of a window
- */
-BOOL FASTCALL
-IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT Window, RECTL *rc, BOOL IncPos)
+static void IntSendParentNotify( PWND pWindow, UINT msg )
 {
-   SIZE Sz;
-   POINT Pos = {0, 0};
-
-   if(Parent != NULL)
-   {
-      RECTL_bIntersectRect(rc, rc, &Parent->Wnd->rcClient);
-
-      if(IncPos)
-      {
-         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++;
-      }
-      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;
+    if ( (pWindow->style & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
+         !(pWindow->style & WS_EX_NOPARENTNOTIFY))
+    {
+        if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow())
+        {
+            co_IntSendMessage( pWindow->spwndParent->head.h,
+                               WM_PARENTNOTIFY,
+                               MAKEWPARAM( msg, pWindow->IDMenu), 
+                               (LPARAM)pWindow->head.h );
+        }
+    }
 }
 
-
-/*
- * @implemented
- */
-PWND APIENTRY
-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)
+void FASTCALL
+IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
 {
-   PWINSTATION_OBJECT WinSta;
-   PWND Wnd = NULL;
-   PCLS *ClassLink, Class = NULL;
-   RTL_ATOM ClassAtom;
-   PWINDOW_OBJECT Window = NULL;
-   PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
-   HWND ParentWindowHandle = NULL;
-   HWND OwnerWindowHandle;
-   PMENU_OBJECT SystemMenu;
-   HWND hWnd;
-   POINT Pos;
-   SIZE Size;
-   PTHREADINFO ti = NULL;
-#if 0
-
-   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-#else
+#define IS_DEFAULT(x)  ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000)
 
-   POINT MaxPos;
-#endif
-   CREATESTRUCTW Cs;
-   CBT_CREATEWNDW CbtCreate;
-   LRESULT Result;
-   BOOL MenuChanged;
-   DECLARE_RETURN(PWND);
-   BOOL HasOwner;
-   USER_REFERENCE_ENTRY ParentRef, Ref;
-   PTHREADINFO pti;
-
-   pti = PsGetCurrentThreadWin32Thread();
-
-   if (pti->Desktop)
+   /* default positioning for overlapped windows */
+    if(!(Cs->style & (WS_POPUP | WS_CHILD)))
    {
-       ParentWindowHandle = pti->Desktop->DesktopWindow;
-   }
+      PMONITOR pMonitor;
+      PRTL_USER_PROCESS_PARAMETERS ProcessParams;
 
+      pMonitor = IntGetPrimaryMonitor();
+      ASSERT(pMonitor);
 
-   if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
-   {
-      UserRegisterSystemClasses();
-   }
-   
-   OwnerWindowHandle = NULL;
+      ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
 
-   DPRINT("co_IntCreateWindowEx %wZ\n", ClassName);
+      if (IS_DEFAULT(Cs->x))
+      {
+          if (!IS_DEFAULT(Cs->y)) *dwShowMode = Cs->y;
 
-   if (hWndParent == HWND_MESSAGE)
-   {
-      /*
-       * native ole32.OleInitialize uses HWND_MESSAGE to create the
-       * message window (style: WS_POPUP|WS_DISABLED)
-       */
-      ParentWindowHandle = IntGetMessageWindow();
-      DPRINT("Parent is HWND_MESSAGE 0x%x\n", ParentWindowHandle);
-   }
-   else if (hWndParent)
-   {
-      if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
-      {  //temp hack
-         PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root;
-         if (Par && (Root = UserGetAncestor(Par, GA_ROOT)))
-            OwnerWindowHandle = Root->hSelf;
+          if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
+          {
+              Cs->x = ProcessParams->StartingX;
+              Cs->y = ProcessParams->StartingY;
+          }
+          else
+          {
+               Cs->x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
+               Cs->y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
+               if (Cs->x > ((pMonitor->rcWork.right - pMonitor->rcWork.left) / 4) ||
+                   Cs->y > ((pMonitor->rcWork.bottom - pMonitor->rcWork.top) / 4))
+               {
+                  /* reset counter and position */
+                  Cs->x = 0;
+                  Cs->y = 0;
+                  pMonitor->cWndStack = 0;
+               }
+               pMonitor->cWndStack++;
+          }
       }
-      else
-         ParentWindowHandle = hWndParent;
-   }
-   else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
-   {
-      SetLastWin32Error(ERROR_TLW_WITH_WSCHILD);
-      RETURN( (PWND)0);  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
-   }
 
-   if (ParentWindowHandle)
-   {
-      ParentWindow = UserGetWindowObject(ParentWindowHandle);
-
-      if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
+      if (IS_DEFAULT(Cs->cx))
+      {
+          if (ProcessParams->WindowFlags & STARTF_USEPOSITION)
+          {
+              Cs->cx = ProcessParams->CountX;
+              Cs->cy = ProcessParams->CountY;
+          }
+          else
+          {
+              Cs->cx = (pMonitor->rcWork.right - pMonitor->rcWork.left) * 3 / 4;
+              Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
+          }
+      }
+      /* neither x nor cx are default. Check the y values .
+       * In the trace we see Outlook and Outlook Express using
+       * cy set to CW_USEDEFAULT when opening the address book.
+       */
+      else if (IS_DEFAULT(Cs->cy))
+      {
+          DPRINT("Strange use of CW_USEDEFAULT in nHeight\n");
+          Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
+      }
    }
    else
    {
-      ParentWindow = NULL;
-   }
-
-   /* FIXME: parent must belong to the current process */
-
-   /* Check the window station. */
-   ti = GetW32ThreadInfo();
-   if (ti == NULL || pti->Desktop == NULL)
-   {
-      DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
-      RETURN( (PWND)0);
+      /* if CW_USEDEFAULT is set for non-overlapped windows, both values are set to zero */
+      if(IS_DEFAULT(Cs->x))
+      {
+         Cs->x = 0;
+         Cs->y = 0;
+      }
+      if(IS_DEFAULT(Cs->cx))
+      {
+         Cs->cx = 0;
+         Cs->cy = 0;
+      }
    }
 
-   /* Check the class. */
+#undef IS_DEFAULT
+}
 
-   DPRINT("Class %wZ\n", ClassName);
+/* Allocates and initializes a window*/
+PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, 
+                                        PLARGE_STRING WindowName, 
+                                        PCLS Class,
+                                        PWND ParentWindow,
+                                        PWND OwnerWindow)
+{
+   PWND pWnd = NULL;
+   HWND hWnd;
+   PTHREADINFO pti = NULL;
+   PMENU_OBJECT SystemMenu;
+   BOOL MenuChanged;
+   BOOL bUnicodeWindow;
 
-   ClassAtom = IntGetClassAtom(ClassName,
-                               hInstance,
-                               ti->ppi,
-                               &Class,
-                               &ClassLink);
+   pti = PsGetCurrentThreadWin32Thread();
 
-   if (ClassAtom == (RTL_ATOM)0)
+   if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
    {
-      if (IS_ATOM(ClassName->Buffer))
+      if (ParentWindow)
       {
-         DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer);
+         if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
+              ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
+             !(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) )
+            Cs->dwExStyle |= WS_EX_LAYOUTRTL;
       }
       else
-      {
-         DPRINT1("Class \"%wZ\" not found\n", ClassName);
-      }
+      {/* 
+        Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
 
-      SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
-      RETURN((PWND)0);
-   }
-   DPRINT("ClassAtom %x\n", ClassAtom);
-   Class = IntReferenceClass(Class,
-                             ClassLink,
-                             pti->Desktop);
-   if (Class == NULL)
-   {
-       DPRINT1("Failed to reference window class!\n");
-       RETURN(NULL);
+        Dialog boxes and message boxes do not inherit layout, so you must
+        set the layout explicitly.
+       */
+         if ( Class && Class->fnid != FNID_DIALOG)
+         {
+            PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+            if (ppi->dwLayout & LAYOUT_RTL)
+            {
+               Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+            }
+         }
+      }      
    }
 
-   WinSta = pti->Desktop->WindowStation;
+   /* Automatically add WS_EX_WINDOWEDGE */
+   if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
+         ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
+         (Cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
+      Cs->dwExStyle |= WS_EX_WINDOWEDGE;
+   else
+      Cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
 
-   //FIXME: Reference thread/desktop instead
-   ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
+   /* Is it a unicode window? */
+   bUnicodeWindow =!(Cs->dwExStyle & WS_EX_SETANSICREATOR);
+   Cs->dwExStyle &= ~WS_EX_SETANSICREATOR;
 
-   /* Create the window object. */
-   Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
-                                               (PHANDLE)&hWnd,
-                                               otWindow,
-                                               sizeof(WINDOW_OBJECT));
-   if (Window)
-   {
-       Window->Wnd = DesktopHeapAlloc(pti->Desktop,
-                                      sizeof(WND) + Class->cbwndExtra);
-       if (!Window->Wnd)
-           goto AllocErr;
-       RtlZeroMemory(Window->Wnd,
-                     sizeof(WND) + Class->cbwndExtra);
-       Window->Wnd->head.h = hWnd;
-       Wnd = Window->Wnd;
-       Wnd->fnid = 0;
+   /* Allocate the new window */
+   pWnd = (PWND) UserCreateObject( gHandleTable,
+                                   pti->rpdesk,
+                                  (PHANDLE)&hWnd,
+                                   otWindow,
+                                   sizeof(WND) + Class->cbwndExtra);
 
-       Wnd->head.pti = ti;
-       Wnd->head.rpdesk = pti->Desktop;
-       Wnd->hWndLastActive = hWnd;
-       Wnd->state2 |= WNDS2_WIN40COMPAT;
-   }
-
-   DPRINT("Created object with handle %X\n", hWnd);
-   if (!Window)
+   if (!pWnd)
    {
-AllocErr:
-      ObDereferenceObject(WinSta);
-      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      RETURN( (PWND)0);
+      goto AllocError;
    }
 
-   UserRefObjectCo(Window, &Ref);
-
-   ObDereferenceObject(WinSta);
+   DPRINT("Created object with handle %X\n", hWnd);
 
-   if (NULL == pti->Desktop->DesktopWindow)
+   if (NULL == pti->rpdesk->DesktopWindow)
    {
       /* If there is no desktop window yet, we must be creating it */
-      pti->Desktop->DesktopWindow = hWnd;
-      pti->Desktop->DesktopInfo->Wnd = Wnd;
+      pti->rpdesk->DesktopWindow = hWnd;
+      pti->rpdesk->pDeskInfo->spwnd = pWnd;
    }
 
    /*
     * Fill out the structure describing it.
     */
-   Window->ti = ti;
-   Wnd->pcls = Class;
-   Class = NULL;
-
-   Window->SystemMenu = (HMENU)0;
-   Wnd->IDMenu = 0;
-   Wnd->hModule = hInstance;
-   Window->hSelf = hWnd;
-
-   Window->MessageQueue = pti->MessageQueue;
-   IntReferenceMessageQueue(Window->MessageQueue);
-   Window->Parent = ParentWindow;
-   Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL;
-   if (Wnd->spwndParent != NULL && hWndParent != 0)
-   {
-       Wnd->HideFocus = Wnd->spwndParent->HideFocus;
-       Wnd->HideAccel = Wnd->spwndParent->HideAccel;
-   }
-
-   if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle)))
-   {
-      Window->hOwner = OwnerWindowHandle;
-      Wnd->spwndOwner = OwnerWindow->Wnd;
-      HasOwner = TRUE;
-   }
-   else
-   {
-      Window->hOwner = NULL;
-      Wnd->spwndOwner = NULL;
-      HasOwner = FALSE;
-   }
-
-   Wnd->dwUserData = 0;
-
-   if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
-      Wnd->state |= WNDS_SERVERSIDEWINDOWPROC;
+   /* Remember, pWnd->head is setup in object.c ...*/
+   pWnd->spwndParent = ParentWindow;
+   pWnd->spwndOwner = OwnerWindow;
+   pWnd->fnid = 0;
+   pWnd->hWndLastActive = hWnd;
+   pWnd->state2 |= WNDS2_WIN40COMPAT;
+   pWnd->pcls = Class;
+   pWnd->hModule = Cs->hInstance;
+   pWnd->style = Cs->style & ~WS_VISIBLE;
+   pWnd->ExStyle = Cs->dwExStyle;
+   pWnd->cbwndExtra = pWnd->pcls->cbwndExtra;
+
+   IntReferenceMessageQueue(pWnd->head.pti->MessageQueue);
+   if (pWnd->spwndParent != NULL && Cs->hwndParent != 0)
+   {
+       pWnd->HideFocus = pWnd->spwndParent->HideFocus;
+       pWnd->HideAccel = pWnd->spwndParent->HideAccel;
+   }
+
+   if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
+      pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 
  /* BugBoy Comments: Comment below say that System classes are always created
     as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
@@ -1856,31 +1723,31 @@ AllocErr:
     see what problems this would cause.*/
 
    // Set WndProc from Class.
-   Wnd->lpfnWndProc  = Wnd->pcls->lpfnWndProc;
+   pWnd->lpfnWndProc  = pWnd->pcls->lpfnWndProc;
 
    // GetWindowProc, test for non server side default classes and set WndProc.
-    if ( Wnd->pcls->fnid <= FNID_GHOST && Wnd->pcls->fnid >= FNID_BUTTON )
+    if ( pWnd->pcls->fnid <= FNID_GHOST && pWnd->pcls->fnid >= FNID_BUTTON )
     {
       if (bUnicodeWindow)
       {
-         if (GETPFNCLIENTA(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
-            Wnd->lpfnWndProc = GETPFNCLIENTW(Wnd->pcls->fnid);  
+         if (GETPFNCLIENTA(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
+            pWnd->lpfnWndProc = GETPFNCLIENTW(pWnd->pcls->fnid);  
       }
       else
       {
-         if (GETPFNCLIENTW(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
-            Wnd->lpfnWndProc = GETPFNCLIENTA(Wnd->pcls->fnid);
+         if (GETPFNCLIENTW(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
+            pWnd->lpfnWndProc = GETPFNCLIENTA(pWnd->pcls->fnid);
       }
     }
 
    // If not an Unicode caller, set Ansi creator bit.
-   if (!bUnicodeWindow) Wnd->state |= WNDS_ANSICREATOR;
+   if (!bUnicodeWindow) pWnd->state |= WNDS_ANSICREATOR;
 
    // Clone Class Ansi/Unicode proc type.
-   if (Wnd->pcls->CSF_flags & CSF_ANSIPROC)
+   if (pWnd->pcls->CSF_flags & CSF_ANSIPROC)
    {
-      Wnd->state |= WNDS_ANSIWINDOWPROC;
-      Wnd->Unicode = FALSE;
+      pWnd->state |= WNDS_ANSIWINDOWPROC;
+      pWnd->Unicode = FALSE;
    }
    else
    { /*
@@ -1888,656 +1755,663 @@ AllocErr:
        WndProc, unless the following overriding conditions occur:
      */
       if ( !bUnicodeWindow &&
-          ( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON]    ||
-            ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX]  ||
-            ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
-            ClassAtom == gpsi->atomSysClass[ICLS_DIALOG]    ||
-            ClassAtom == gpsi->atomSysClass[ICLS_EDIT]      ||
-            ClassAtom == gpsi->atomSysClass[ICLS_IME]       ||
-            ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX]   ||
-            ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] ||
-            ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) )
+          ( Class->atomClassName == gpsi->atomSysClass[ICLS_BUTTON]    ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX]  ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_DIALOG]    ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT]      ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_IME]       ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_LISTBOX]   ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_MDICLIENT] ||
+            Class->atomClassName == gpsi->atomSysClass[ICLS_STATIC] ) )
       { // Override Class and set the window Ansi WndProc.
-         Wnd->state |= WNDS_ANSIWINDOWPROC;
-         Wnd->Unicode = FALSE;
+         pWnd->state |= WNDS_ANSIWINDOWPROC;
+         pWnd->Unicode = FALSE;
       }
       else
       { // Set the window Unicode WndProc.
-         Wnd->state &= ~WNDS_ANSIWINDOWPROC;
-         Wnd->Unicode = TRUE;
+         pWnd->state &= ~WNDS_ANSIWINDOWPROC;
+         pWnd->Unicode = TRUE;
       }
    }
 
-   Window->OwnerThread = PsGetCurrentThread();
-   Window->FirstChild = NULL;
-   Window->LastChild = NULL;
-   Window->PrevSibling = NULL;
-   Window->NextSibling = NULL;
-   Wnd->cbwndExtra = Wnd->pcls->cbwndExtra;
-
-   InitializeListHead(&Wnd->PropListHead);
-   InitializeListHead(&Window->WndObjListHead);
-
-   if ( NULL != WindowName->Buffer && WindowName->Length > 0 )
+   /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
+      then my testing shows that windows (2k and XP) creates a CallProc for it immediately 
+      Dont understand why it does this. */
+   if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
    {
-      Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk,
-                                                WindowName->Length + sizeof(UNICODE_NULL));
-      if (Wnd->strName.Buffer == NULL)
-      {
-          SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-          RETURN( (PWND)0);
-      }
+      PCALLPROCDATA CallProc;
+      CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
 
-      Wnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
-      _SEH2_TRY
+      if (!CallProc)
       {
-          RtlCopyMemory(Wnd->strName.Buffer,
-                        WindowName->Buffer,
-                        WindowName->Length);
-          Wnd->strName.Length = WindowName->Length;
+         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+         DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
       }
-      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+      else
       {
-          WindowName->Length = 0;
-          Wnd->strName.Buffer[0] = L'\0';
+         UserAddCallProcToClass(pWnd->pcls, CallProc);
       }
-      _SEH2_END;
    }
 
-   /*
-    * 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;
+   InitializeListHead(&pWnd->PropListHead);
+
+   if ( WindowName->Buffer != NULL && WindowName->Length > 0 )
+   {
+      pWnd->strName.Buffer = DesktopHeapAlloc(pWnd->head.rpdesk,
+                                             WindowName->Length + sizeof(UNICODE_NULL));
+      if (pWnd->strName.Buffer == NULL)
+      {
+          goto AllocError;
+      }
+
+      RtlCopyMemory(pWnd->strName.Buffer, WindowName->Buffer, WindowName->Length);
+      pWnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
+      pWnd->strName.Length = WindowName->Length;
+   }
 
    /* Correct the window style. */
-   if (!(dwStyle & WS_CHILD))
+   if ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
    {
-      dwStyle |= WS_CLIPSIBLINGS;
-      DPRINT("3: Style is now %lx\n", dwStyle);
-      if (!(dwStyle & WS_POPUP))
+      pWnd->style |= WS_CLIPSIBLINGS;
+      if (!(pWnd->style & WS_POPUP))
       {
-         dwStyle |= WS_CAPTION;
-         Window->Flags |= WINDOWOBJECT_NEED_SIZE;
-         DPRINT("4: Style is now %lx\n", dwStyle);
+         pWnd->style |= WS_CAPTION;
+         pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
       }
    }
 
+   if ((pWnd->ExStyle & WS_EX_DLGMODALFRAME) ||
+          (pWnd->style & (WS_DLGFRAME | WS_THICKFRAME)))
+        pWnd->ExStyle |= WS_EX_WINDOWEDGE;
+    else
+        pWnd->ExStyle &= ~WS_EX_WINDOWEDGE;
+
    /* create system menu */
-   if((dwStyle & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION)
+   if((Cs->style & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION)
    {
-      SystemMenu = IntGetSystemMenu(Window, TRUE, TRUE);
+      SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
       if(SystemMenu)
       {
-         Window->SystemMenu = SystemMenu->MenuInfo.Self;
+         pWnd->SystemMenu = SystemMenu->MenuInfo.Self;
          IntReleaseMenuObject(SystemMenu);
       }
    }
 
    /* Set the window menu */
-   if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
+   if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
    {
-      if (hMenu)
-         IntSetMenu(Window, hMenu, &MenuChanged);
-      else if (Wnd->pcls->lpszMenuName) // Take it from the parent.
+       if (Cs->hMenu)
+         IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
+      else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
       {
           UNICODE_STRING MenuName;
-          if (IS_INTRESOURCE(Wnd->pcls->lpszMenuName))
+          HMENU hMenu;
+
+          if (IS_INTRESOURCE(pWnd->pcls->lpszMenuName))
           {
              MenuName.Length = 0;
              MenuName.MaximumLength = 0;
-             MenuName.Buffer = Wnd->pcls->lpszMenuName;
+             MenuName.Buffer = pWnd->pcls->lpszMenuName;
           }
           else
           {
-             RtlInitUnicodeString( &MenuName, Wnd->pcls->lpszMenuName);
+             RtlInitUnicodeString( &MenuName, pWnd->pcls->lpszMenuName);
           }
-          hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
-          if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
+          hMenu = co_IntCallLoadMenu( pWnd->pcls->hModule, &MenuName);
+          if (hMenu) IntSetMenu(pWnd, hMenu, &MenuChanged);
       }
    }
    else // Not a child
-      Wnd->IDMenu = (UINT) hMenu;
+      pWnd->IDMenu = (UINT) Cs->hMenu;
 
    /* Insert the window into the thread's window list. */
-   InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry);
+   InsertTailList (&pti->WindowListHead, &pWnd->ThreadListEntry);
 
    /*  Handle "CS_CLASSDC", it is tested first. */
-   if ((Wnd->pcls->style & CS_CLASSDC) && !(Wnd->pcls->pdce)) // One DCE per class to have CLASS.
-      Wnd->pcls->pdce = DceAllocDCE(Window, DCE_CLASS_DC);
-   /* Allocate a DCE for this window. */
-   else if ( Wnd->pcls->style & CS_OWNDC)
-      Window->Dce = DceAllocDCE(Window, DCE_WINDOW_DC);
-
-   Pos.x = x;
-   Pos.y = y;
-   Size.cx = nWidth;
-   Size.cy = nHeight;
-
-   Wnd->ExStyle = dwExStyle;
-   Wnd->style = dwStyle & ~WS_VISIBLE;
-
-   /* call hook */
-   Cs.lpCreateParams = lpParam;
-   Cs.hInstance = hInstance;
-   Cs.hMenu = hMenu;
-   Cs.hwndParent = hWndParent; //Pass the original Parent handle!
-   Cs.cx = Size.cx;
-   Cs.cy = Size.cy;
-   Cs.x = Pos.x;
-   Cs.y = Pos.y;
-   Cs.style = Wnd->style;
-//   Cs.lpszName = (LPCWSTR) WindowName->Buffer;
-//   Cs.lpszClass = (LPCWSTR) ClassName->Buffer;
-   Cs.lpszName = (LPCWSTR) WindowName;
-   Cs.lpszClass = (LPCWSTR) ClassName;
-   Cs.dwExStyle = dwExStyle;
-   CbtCreate.lpcs = &Cs;
-   CbtCreate.hwndInsertAfter = HWND_TOP;
-   if (ISITHOOKED(WH_CBT))
-   {
-      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( (PWND) NULL);
-      }
+   if ( (pWnd->pcls->style & CS_CLASSDC) && !(pWnd->pcls->pdce) )
+   {  /* One DCE per class to have CLASS. */
+      pWnd->pcls->pdce = DceAllocDCE( pWnd, DCE_CLASS_DC );
+   }
+   else if ( pWnd->pcls->style & CS_OWNDC)
+   {  /* Allocate a DCE for this window. */
+      DceAllocDCE(pWnd, DCE_WINDOW_DC);
    }
-   x = Cs.x;
-   y = Cs.y;
-   nWidth = Cs.cx;
-   nHeight = Cs.cy;
-// FIXME: Need to set the Z order in the window link list if the hook callback changed it!
-//   hwndInsertAfter = CbtCreate.hwndInsertAfter;
 
-   /* default positioning for overlapped windows */
-   if(!(Wnd->style & (WS_POPUP | WS_CHILD)))
+   return pWnd;
+
+AllocError:
+
+   if(pWnd)
+      UserDereferenceObject(pWnd);
+   
+   SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+   return NULL;
+}
+
+/*
+ * @implemented
+ */
+PWND FASTCALL
+co_UserCreateWindowEx(CREATESTRUCTW* Cs,
+                     PUNICODE_STRING ClassName,
+                     PLARGE_STRING WindowName)
+{
+   PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
+   HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
+   DWORD dwStyle;
+   PWINSTATION_OBJECT WinSta;
+   PCLS Class = NULL;
+   SIZE Size;
+   POINT MaxPos;
+   CBT_CREATEWNDW * pCbtCreate;
+   LRESULT Result;
+   USER_REFERENCE_ENTRY ParentRef, Ref;
+   PTHREADINFO pti;
+   DWORD dwShowMode = SW_SHOW;
+   CREATESTRUCTW *pCsw;
+   PVOID pszClass = NULL, pszName = NULL;
+   DECLARE_RETURN(PWND);
+
+   /* Get the current window station and reference it */
+   pti = GetW32ThreadInfo();
+   if (pti == NULL || pti->rpdesk == NULL)
    {
-      RECTL rc, WorkArea;
-      PRTL_USER_PROCESS_PARAMETERS ProcessParams;
-      BOOL CalculatedDefPosSize = FALSE;
+      DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
+      return NULL; //There is nothing to cleanup
+   }
+   WinSta = pti->rpdesk->rpwinstaParent;
+   ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 
-      IntGetDesktopWorkArea(((PTHREADINFO)Window->OwnerThread->Tcb.Win32Thread)->Desktop, &WorkArea);
+   pCsw = NULL;
+   pCbtCreate = NULL;
 
-      rc = WorkArea;
-      ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
+   /* Get the class and reference it*/
+   Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
+   if(!Class)
+   {
+       DPRINT1("Failed to find class %wZ\n", ClassName);
+       RETURN(NULL);
+   }
 
-      if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
-      {
-         CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, Window, &rc, TRUE);
+   /* Now find the parent and the owner window */
+   hWndParent = IntGetDesktopWindow();
+   hWndOwner = NULL;
 
-         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;
-         }
+    if (Cs->hwndParent == HWND_MESSAGE)
+    {
+        Cs->hwndParent = hWndParent = IntGetMessageWindow();
+    }
+    else if (Cs->hwndParent)
+    {
+        if ((Cs->style & (WS_CHILD|WS_POPUP)) != WS_CHILD)
+            hWndOwner = Cs->hwndParent;
+        else
+            hWndParent = Cs->hwndParent;
+    }
+    else if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+    {
+         DPRINT1("Cannot create a child window without a parrent!\n");
+         SetLastWin32Error(ERROR_TLW_WITH_WSCHILD);
+         RETURN(NULL);  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
+    }
 
-/*
-   According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
-   y is something else. and Quote!
- */
+    ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL;
+    OwnerWindow = hWndOwner ? UserGetWindowObject(hWndOwner): NULL;
 
-/* Never believe Microsoft's documentation... CreateWindowEx doc says
- * that if an overlapped window is created with WS_VISIBLE style bit
- * set and the x parameter is set to CW_USEDEFAULT, the system ignores
- * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
- * reveals that
- *
- * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
- * 2) it does not ignore the y parameter as the docs claim; instead, it
- *    uses it as second parameter to ShowWindow() unless y is either
- *    CW_USEDEFAULT or CW_USEDEFAULT16.
- *
- * The fact that we didn't do 2) caused bogus windows pop up when wine
- * was running apps that were using this obscure feature. Example -
- * calc.exe that comes with Win98 (only Win98, it's different from
- * the one that comes with Win95 and NT)
- */
-         if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16)
-         {
-            dwShowMode = y;
-         }
+    /* FIXME: is this correct?*/
+    if(OwnerWindow)
+        OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT);
+
+   /* Fix the position and the size of the window */
+   if (ParentWindow) 
+   {
+       UserRefObjectCo(ParentWindow, &ParentRef);
+       IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode);
+   }
+
+   /* Allocate and initialize the new window */
+   Window = IntCreateWindow(Cs, 
+                            WindowName, 
+                            Class, 
+                            ParentWindow, 
+                            OwnerWindow);
+   if(!Window)
+   {
+       DPRINT1("IntCreateWindow failed!\n");
+       RETURN(0);
+   }
+
+   hWnd = UserHMGetHandle(Window);
+
+   UserRefObjectCo(Window, &Ref);
+   ObDereferenceObject(WinSta);
+
+   //// Call the WH_CBT hook ////
+
+   // Allocate the calling structures Justin Case this goes Global.
+   pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK);
+   pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK);
+
+   /* Fill the new CREATESTRUCTW */
+   pCsw->lpCreateParams = Cs->lpCreateParams;
+   pCsw->hInstance = Cs->hInstance;
+   pCsw->hMenu = Cs->hMenu;
+   pCsw->hwndParent = Cs->hwndParent;
+   pCsw->cx = Cs->cx;
+   pCsw->cy = Cs->cy;
+   pCsw->x = Cs->x;
+   pCsw->y = Cs->y;
+   pCsw->dwExStyle = Cs->dwExStyle;
+   dwStyle = Cs->style;       // Save it anyway.
+   pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
+   pCsw->lpszName  = Cs->lpszName;
+   pCsw->lpszClass = Cs->lpszClass;
+
+   // Based on the assumption this is from "unicode source" user32, ReactOS, answer is yes.
+   if (!IS_ATOM(ClassName->Buffer))
+   {
+      if (Window->state & WNDS_ANSICREATOR)
+      {
+         ANSI_STRING AnsiString;
+         AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR);
+         pszClass = UserHeapAlloc(AnsiString.MaximumLength);
+         RtlZeroMemory(pszClass, AnsiString.MaximumLength);
+         AnsiString.Buffer = (PCHAR)pszClass;
+         RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE);
       }
-      if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
+      else
       {
-         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);
+         UNICODE_STRING UnicodeString;
+         UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL);
+         pszClass = UserHeapAlloc(UnicodeString.MaximumLength);
+         RtlZeroMemory(pszClass, UnicodeString.MaximumLength);
+         UnicodeString.Buffer = (PWSTR)pszClass;
+         RtlCopyUnicodeString(&UnicodeString, ClassName);
       }
+      if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass);
    }
-   else
+   if (WindowName->Length)
    {
-      /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
-      if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
+      UNICODE_STRING Name;
+      Name.Buffer = WindowName->Buffer;
+      Name.Length = WindowName->Length;
+      Name.MaximumLength = WindowName->MaximumLength;
+
+      if (Window->state & WNDS_ANSICREATOR)
       {
-         Pos.x = 0;
-         Pos.y = 0;
+         ANSI_STRING AnsiString;
+         AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR);
+         pszName = UserHeapAlloc(AnsiString.MaximumLength);
+         RtlZeroMemory(pszName, AnsiString.MaximumLength);
+         AnsiString.Buffer = (PCHAR)pszName;
+         RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE);
       }
-      if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
+      else
       {
-         Size.cx = 0;
-         Size.cy = 0;
+         UNICODE_STRING UnicodeString;
+         UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
+         pszName = UserHeapAlloc(UnicodeString.MaximumLength);
+         RtlZeroMemory(pszName, UnicodeString.MaximumLength);
+         UnicodeString.Buffer = (PWSTR)pszName; 
+         RtlCopyUnicodeString(&UnicodeString, &Name);
       }
+      if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName);
    }
 
-   /* Initialize the window dimensions. */
-   Wnd->rcWindow.left = Pos.x;
-   Wnd->rcWindow.top = Pos.y;
-   Wnd->rcWindow.right = Pos.x + Size.cx;
-   Wnd->rcWindow.bottom = Pos.y + Size.cy;
-   if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
+   pCbtCreate->lpcs = pCsw;
+   pCbtCreate->hwndInsertAfter = HWND_TOP;
+
+   Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate);
+   if (Result != 0)
    {
-      RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
-                       ParentWindow->Wnd->rcClient.top);
+      DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result);
+      RETURN( (PWND) NULL);
    }
-   Wnd->rcClient = Wnd->rcWindow;
+   // Write back changes.
+   Cs->cx = pCsw->cx;
+   Cs->cy = pCsw->cy;
+   Cs->x = pCsw->x;
+   Cs->y = pCsw->y;
+   hwndInsertAfter = pCbtCreate->hwndInsertAfter;
+
+   /* NCCREATE and WM_NCCALCSIZE need the original values */
+   Cs->style = dwStyle;
+   Cs->lpszName = (LPCWSTR) WindowName;
+   Cs->lpszClass = (LPCWSTR) ClassName;
+
+   /* Send the WM_GETMINMAXINFO message*/
+   Size.cx = Cs->cx;
+   Size.cy = Cs->cy;
 
-   /*
-    * 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 */
-      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;
-   }
-
-   Wnd->rcWindow.left = Pos.x;
-   Wnd->rcWindow.top = Pos.y;
-   Wnd->rcWindow.right = Pos.x + Size.cx;
-   Wnd->rcWindow.bottom = Pos.y + Size.cy;
-   if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
-   {
-      RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
-                       ParentWindow->Wnd->rcClient.top);
-   }
-   Wnd->rcClient = Wnd->rcWindow;
-
-   /* 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. */
-      DPRINT1("IntCreateWindowEx(): NCCREATE message failed. No cleanup performed!\n");
-      RETURN((PWND)0);
+      co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack, &MaxTrack);
+      if (Size.cx > MaxTrack.x) Size.cx = MaxTrack.x;
+      if (Size.cy > MaxTrack.y) Size.cy = MaxTrack.y;
+      if (Size.cx < MinTrack.x) Size.cx = MinTrack.x;
+      if (Size.cy < MinTrack.y) Size.cy = MinTrack.y;
    }
 
-   /* Calculate the non-client size. */
-   MaxPos.x = Window->Wnd->rcWindow.left;
-   MaxPos.y = Window->Wnd->rcWindow.top;
-
-
-   DPRINT("IntCreateWindowEx(): About to get non-client size.\n");
-   /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
-   Result = co_WinPosGetNonClientSize(Window,
-                                      &Window->Wnd->rcWindow,
-                                      &Window->Wnd->rcClient);
-
-   RECTL_vOffsetRect(&Window->Wnd->rcWindow,
-                    MaxPos.x - Window->Wnd->rcWindow.left,
-                    MaxPos.y - Window->Wnd->rcWindow.top);
+   Window->rcWindow.left = Cs->x;
+   Window->rcWindow.top = Cs->y;
+   Window->rcWindow.right = Cs->x + Size.cx;
+   Window->rcWindow.bottom = Cs->y + Size.cy;
+   if (0 != (Window->style & WS_CHILD) && ParentWindow)
+   {
+      RECTL_vOffsetRect(&Window->rcWindow, 
+                        ParentWindow->rcClient.left,
+                        ParentWindow->rcClient.top);
+   }
+   Window->rcClient = Window->rcWindow;
 
 
+   /* Link the window*/
    if (NULL != ParentWindow)
    {
-      /* link the window into the parent's child list */
+      /* link the window into the siblings list */
       if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
-      {
-         PWINDOW_OBJECT PrevSibling;
-
-         PrevSibling = ParentWindow->LastChild;
-
-         /* link window as bottom sibling */
-         IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/);
-      }
+          IntLinkHwnd(Window, HWND_BOTTOM);
       else
-      {
-         /* 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->Wnd->ExStyle & WS_EX_TOPMOST))
-            {
-               InsertAfter = Sibling;
-               Sibling = Sibling->NextSibling;
-            }
-         }
-         else
-         {
-            InsertAfter = NULL;
-         }
-
-         IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */);
-
-      }
+          IntLinkHwnd(Window, HWND_TOP);
    }
-
-   /* 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)
+   
+   /* Send the NCCREATE message */
+   Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
+   if (!Result)
    {
-      /* FIXME: Cleanup. */
-      DPRINT1("IntCreateWindowEx(): send CREATE message failed. No cleanup performed!\n");
-      IntUnlinkWindow(Window);
+      DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
       RETURN((PWND)0);
    }
 
-   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
-
-   /* Send move and size messages. */
-   if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE))
-   {
-      LONG lParam;
+   /* Send the WM_NCCALCSIZE message */
+   MaxPos.x = Window->rcWindow.left;
+   MaxPos.y = Window->rcWindow.top;
 
-      DPRINT("IntCreateWindow(): About to send WM_SIZE\n");
+   Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient);
 
-      if ((Window->Wnd->rcClient.right - Window->Wnd->rcClient.left) < 0 ||
-            (Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top) < 0)
-      {
-         DPRINT("Sending bogus WM_SIZE\n");
-      }
+   RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left,
+                                     MaxPos.y - Window->rcWindow.top);
 
-      lParam = MAKE_LONG(Window->Wnd->rcClient.right -
-                         Window->Wnd->rcClient.left,
-                         Window->Wnd->rcClient.bottom -
-                         Window->Wnd->rcClient.top);
-      co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED,
-                        lParam);
 
-      DPRINT("IntCreateWindow(): About to send WM_MOVE\n");
+   /* Send the WM_CREATE message. */
+   Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
+   if (Result == (LRESULT)-1)
+   {
+      DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n");
+      RETURN((PWND)0);
+   }
 
-      if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
-      {
-         lParam = MAKE_LONG(Wnd->rcClient.left - ParentWindow->Wnd->rcClient.left,
-                            Wnd->rcClient.top - ParentWindow->Wnd->rcClient.top);
-      }
-      else
-      {
-         lParam = MAKE_LONG(Wnd->rcClient.left,
-                            Wnd->rcClient.top);
-      }
+   /* Send the EVENT_OBJECT_CREATE event*/
+   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 
-      co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam);
+   /* By setting the flag below it can be examined to determine if the window
+      was created successfully and a valid pwnd was passed back to caller since
+      from here the function has to succeed. */
+   Window->state2 |= WNDS2_WMCREATEMSGPROCESSED;
 
-      /* Call WNDOBJ change procs */
-      IntEngWindowChanged(Window, WOC_RGN_CLIENT);
+   /* Send the WM_SIZE and WM_MOVE messages. */
+   if (!(Window->state & WNDS_SENDSIZEMOVEMSGS))
+   {
+        co_WinPosSendSizeMove(Window);
    }
 
    /* Show or maybe minimize or maximize the window. */
-   if (Wnd->style & (WS_MINIMIZE | WS_MAXIMIZE))
+   if (Window->style & (WS_MINIMIZE | WS_MAXIMIZE))
    {
       RECTL NewPos;
       UINT16 SwFlag;
 
-      SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE :
-               SW_MAXIMIZE;
+      SwFlag = (Window->style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
 
       co_WinPosMinMaximize(Window, SwFlag, &NewPos);
 
-      SwFlag = ((Wnd->style & WS_CHILD) || UserGetActiveWindow()) ?
+      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);
       co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
                             NewPos.right, NewPos.bottom, SwFlag);
    }
 
-   /* Notify the parent window of a new child. */
-   if ((Wnd->style & WS_CHILD) &&
-       (!(Wnd->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
-   {
-      DPRINT("IntCreateWindow(): About to notify parent\n");
-      co_IntSendMessage(ParentWindow->hSelf,
-                        WM_PARENTNOTIFY,
-                        MAKEWPARAM(WM_CREATE, Wnd->IDMenu),
-                        (LPARAM)Window->hSelf);
-   }
+   /* Send the WM_PARENTNOTIFY message */
+   IntSendParentNotify(Window, WM_CREATE);
 
-   if ((!hWndParent) && (!HasOwner))
+   /* Notify the shell that a new window was created */
+   if ((!hWndParent) && (!hWndOwner))
    {
-      DPRINT("Sending CREATED notify\n");
       co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
    }
-   else
-   {
-      DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner);
-   }
 
    /* Initialize and show the window's scrollbars */
-   if (Wnd->style & WS_VSCROLL)
+   if (Window->style & WS_VSCROLL)
    {
       co_UserShowScrollBar(Window, SB_VERT, TRUE);
    }
-   if (Wnd->style & WS_HSCROLL)
+   if (Window->style & WS_HSCROLL)
    {
       co_UserShowScrollBar(Window, SB_HORZ, TRUE);
    }
 
-   if (dwStyle & WS_VISIBLE)
+   /* Show the new window */
+   if (Cs->style & WS_VISIBLE)
    {
-      if (Wnd->style & WS_MAXIMIZE)
+      if (Window->style & WS_MAXIMIZE)
          dwShowMode = SW_SHOW;
-      else if (Wnd->style & WS_MINIMIZE)
+      else if (Window->style & WS_MINIMIZE)
          dwShowMode = SW_SHOWMINIMIZED;
 
-      DPRINT("IntCreateWindow(): About to show window\n");
       co_WinPosShowWindow(Window, dwShowMode);
 
-      if (Wnd->ExStyle & WS_EX_MDICHILD)
-      {
-        co_IntSendMessage(ParentWindow->hSelf, WM_MDIREFRESHMENU, 0, 0);
-        /* ShowWindow won't activate child windows */
-        co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
-      }
-   }
-
-   /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
-      then my testing shows that windows (2k and XP) creates a CallProc for it immediately 
-      Dont understand why it does this. */
-   if (ClassAtom == gpsi->atomSysClass[ICLS_EDIT])
-   {
-      PCALLPROCDATA CallProc;
-      //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi);
-      CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi);
-
-      if (!CallProc)
-      {
-         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-         DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
-      }
-      else
-      {
-         UserAddCallProcToClass(Wnd->pcls, CallProc);
-      }
-   }
-
-   DPRINT("IntCreateWindow(): = %X\n", hWnd);
-   DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
-   RETURN( Wnd);
-
-CLEANUP:
-   if (!_ret_ && Window && Window->Wnd && ti)
-       UserFreeWindowInfo(ti, Window);
-   if (Window)
-   {
-      UserDerefObjectCo(Window);
-      UserDereferenceObject(Window);
-   }
-   if (ParentWindow) UserDerefObjectCo(ParentWindow);
-   if (!_ret_ && ti != NULL)
-   {
-       if (Class != NULL)
-       {
-           IntDereferenceClass(Class,
-                               ti->pDeskInfo,
-                               ti->ppi);
-       }
-   }
-   END_CLEANUP;
-}
-
-HWND APIENTRY
-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,
-                     DWORD dwUnknown)
-{
-   NTSTATUS Status;
-   UNICODE_STRING WindowName;
-   UNICODE_STRING ClassName;
-   HWND NewWindow = NULL;
-   PWND pNewWindow;
-   DECLARE_RETURN(HWND);
-
-   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))
-   {
-      SetLastNtError(Status);
-      RETURN( NULL);
-   }
-   if (ClassName.Length != 0)
-   {
-      Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
-      if (! NT_SUCCESS(Status))
-      {
-         SetLastNtError(Status);
-         RETURN( NULL);
-      }
-   }
-   else if (! IS_ATOM(ClassName.Buffer))
-   {
-       SetLastWin32Error(ERROR_INVALID_PARAMETER);
-       RETURN(NULL);
-   }
-
-   /* safely copy the window name */
-   if (NULL != UnsafeWindowName)
-   {
-      Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName);
-      if (! NT_SUCCESS(Status))
+      if (Window->ExStyle & WS_EX_MDICHILD)
       {
-         if (! IS_ATOM(ClassName.Buffer))
-         {
-            ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
-         }
-         SetLastNtError(Status);
-         RETURN( NULL);
+        co_IntSendMessage(UserHMGetHandle(ParentWindow), WM_MDIREFRESHMENU, 0, 0);
+        /* ShowWindow won't activate child windows */
+        co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
       }
    }
-   else
-   {
-      RtlInitUnicodeString(&WindowName, NULL);
-   }
 
-   pNewWindow = co_IntCreateWindowEx( dwExStyle,
-                                     &ClassName,
-                                     &WindowName,
-                                      dwStyle,
-                                      x,
-                                      y,
-                                      nWidth,
-                                      nHeight,
-                                      hWndParent,
-                                      hMenu,
-                                      hInstance,
-                                      lpParam,
-                                      dwShowMode,
-                                      bUnicodeWindow);
+   DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd);
+   RETURN( Window);
 
-   if (pNewWindow) NewWindow = UserHMGetHandle(pNewWindow);
-
-   if (WindowName.Buffer)
+CLEANUP:
+   if (!_ret_)
    {
-      ExFreePoolWithTag(WindowName.Buffer, TAG_STRING);
+       /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */
+       if (Window) 
+            co_UserDestroyWindow(Window);
+       else if (Class)
+           IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
    }
-   if (! IS_ATOM(ClassName.Buffer))
+
+   if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
+   if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
+   if (pszName) UserHeapFree(pszName);
+   if (pszClass) UserHeapFree(pszClass);
+
+   if (Window)
    {
-      ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
+      UserDerefObjectCo(Window);
+      UserDereferenceObject(Window);
    }
+   if (ParentWindow) UserDerefObjectCo(ParentWindow);
 
-   RETURN( NewWindow);
-
-CLEANUP:
-   DPRINT("Leave NtUserCreateWindowEx, ret=%i\n",_ret_);
-   UserLeave();
    END_CLEANUP;
 }
 
+NTSTATUS
+NTAPI
+ProbeAndCaptureLargeString(
+    OUT PLARGE_STRING plstrSafe,
+    IN PLARGE_STRING plstrUnsafe)
+{
+    LARGE_STRING lstrTemp;
+    PVOID pvBuffer = NULL;
+
+    _SEH2_TRY
+    {
+        /* Probe and copy the string */
+        ProbeForRead(plstrUnsafe, sizeof(LARGE_STRING), sizeof(ULONG));
+        lstrTemp = *plstrUnsafe;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Fail */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode();)
+    }
+    _SEH2_END
+
+    if (lstrTemp.Length != 0)
+    {
+        /* Allocate a buffer from paged pool */
+        pvBuffer = ExAllocatePoolWithTag(PagedPool, lstrTemp.Length, TAG_STRING);
+        if (!pvBuffer)
+        {
+            return STATUS_NO_MEMORY;
+        }
+
+        _SEH2_TRY
+        {
+            /* Probe and copy the buffer */
+            ProbeForRead(lstrTemp.Buffer, lstrTemp.Length, sizeof(WCHAR));
+            RtlCopyMemory(pvBuffer, lstrTemp.Buffer, lstrTemp.Length);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Cleanup and fail */
+            ExFreePool(pvBuffer);
+            _SEH2_YIELD(return _SEH2_GetExceptionCode();)
+        }
+        _SEH2_END
+    }
+
+    /* Set the output string */
+    plstrSafe->Buffer = pvBuffer;
+    plstrSafe->Length = lstrTemp.Length;
+    plstrSafe->MaximumLength = lstrTemp.Length;
+
+    return STATUS_SUCCESS;
+}
+
+/**
+ * \todo Allow passing plstrClassName as ANSI.
+ */
+HWND
+NTAPI
+NtUserCreateWindowEx(
+    DWORD dwExStyle,
+    PLARGE_STRING plstrClassName,
+    PLARGE_STRING plstrClsVersion,
+    PLARGE_STRING plstrWindowName,
+    DWORD dwStyle,
+    int x,
+    int y,
+    int nWidth,
+    int nHeight,
+    HWND hWndParent,
+    HMENU hMenu,
+    HINSTANCE hInstance,
+    LPVOID lpParam,
+    DWORD dwFlags,
+    PVOID acbiBuffer)
+{
+    NTSTATUS Status;
+    LARGE_STRING lstrWindowName;
+    LARGE_STRING lstrClassName;
+    UNICODE_STRING ustrClassName;
+    CREATESTRUCTW Cs;
+    HWND hwnd = NULL;
+    PWND pwnd;
+
+    lstrWindowName.Buffer = NULL;
+    lstrClassName.Buffer = NULL;
+
+    /* Check if we got a Window name */
+    if (plstrWindowName)
+    {
+        /* Copy the string to kernel mode */
+        Status = ProbeAndCaptureLargeString(&lstrWindowName, plstrWindowName);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("NtUserCreateWindowEx: failed to capture plstrWindowName\n");
+            SetLastNtError(Status);
+            return NULL;
+        }
+        plstrWindowName = &lstrWindowName;
+    }
+
+    /* Check if the class is an atom */
+    if (IS_ATOM(plstrClassName))
+    {
+        /* It is, pass the atom in the UNICODE_STRING */
+        ustrClassName.Buffer = (PVOID)plstrClassName;
+        ustrClassName.Length = 0;
+        ustrClassName.MaximumLength = 0;
+    }
+    else
+    {
+        /* It's not, capture the class name */
+        Status = ProbeAndCaptureLargeString(&lstrClassName, plstrClassName);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("NtUserCreateWindowEx: failed to capture plstrClassName\n");
+            /* Set last error, cleanup and return */
+            SetLastNtError(Status);
+            goto cleanup;
+        }
+
+        /* We pass it on as a UNICODE_STRING */
+        ustrClassName.Buffer = lstrClassName.Buffer;
+        ustrClassName.Length = lstrClassName.Length;
+        ustrClassName.MaximumLength = lstrClassName.MaximumLength;
+    }
+
+    /* Fill the CREATESTRUCTW */
+    /* we will keep here the original parameters */
+    Cs.style = dwStyle;
+    Cs.lpCreateParams = lpParam;
+    Cs.hInstance = hInstance;
+    Cs.hMenu = hMenu;
+    Cs.hwndParent = hWndParent;
+    Cs.cx = nWidth;
+    Cs.cy = nHeight;
+    Cs.x = x;
+    Cs.y = y;
+    Cs.lpszName = (LPCWSTR) plstrWindowName->Buffer;
+    if (IS_ATOM(plstrClassName))
+       Cs.lpszClass = (LPCWSTR) plstrClassName;
+    else
+       Cs.lpszClass = (LPCWSTR) plstrClassName->Buffer;
+    Cs.dwExStyle = dwExStyle;
+
+    UserEnterExclusive();
+
+    /* Call the internal function */
+    pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName);
+
+    if(!pwnd)
+    {
+        DPRINT1("co_UserCreateWindowEx failed!\n");
+    }
+    hwnd = pwnd ? UserHMGetHandle(pwnd) : NULL;
+
+    UserLeave();
+
+cleanup:
+    if (lstrWindowName.Buffer)
+    {
+        ExFreePoolWithTag(lstrWindowName.Buffer, TAG_STRING);
+    }
+    if (lstrClassName.Buffer)
+    {
+        ExFreePoolWithTag(lstrClassName.Buffer, TAG_STRING);
+    }
+
+   return hwnd;
+}
+
 /*
  * @unimplemented
  */
@@ -2557,33 +2431,40 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
 }
 
 
-BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
+BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
 {
-   BOOLEAN isChild;
-   PWND Wnd;
    HWND hWnd;
+   PTHREADINFO ti;
+   MSG msg;
 
    ASSERT_REFS_CO(Window); // FIXME: temp hack?
 
-   hWnd = Window->hSelf;
-
-   Wnd = Window->Wnd;
-
-   if (!Wnd) return TRUE; // FIXME: Need to finish object rewrite or lock the thread when killing the window!
+   hWnd = Window->head.h;
 
    DPRINT("co_UserDestroyWindow \n");
 
    /* Check for owner thread */
-   if ((Window->OwnerThread != PsGetCurrentThread()))
+   if ( (Window->head.pti->pEThread != PsGetCurrentThread()) ||
+        Window->head.pti != PsGetCurrentThreadWin32Thread() )
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return FALSE;
    }
 
-   /* Call hooks */
-   if (ISITHOOKED(WH_CBT))
+   /* If window was created successfully and it is hooked */
+   if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED))
+   {
+      if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0))
+      {
+         DPRINT1("Destroy Window WH_CBT Call Hook return!\n");
+         return FALSE;
+      }
+   }
+
+   /* Inform the parent */
+   if (Window->style & WS_CHILD)
    {
-      if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
+      IntSendParentNotify(Window, WM_DESTROY);
    }
 
    /* Look whether the focus is within the tree of windows we will
@@ -2591,54 +2472,53 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
     */
    if (!co_WinPosShowWindow(Window, SW_HIDE))
    {
-      if (UserGetActiveWindow() == Window->hSelf)
+      if (UserGetActiveWindow() == Window->head.h)
       {
          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;
+   if (Window->head.pti->MessageQueue->ActiveWindow == Window->head.h)
+      Window->head.pti->MessageQueue->ActiveWindow = NULL;
+   if (Window->head.pti->MessageQueue->FocusWindow == Window->head.h)
+      Window->head.pti->MessageQueue->FocusWindow = NULL;
+   if (Window->head.pti->MessageQueue->CaptureWindow == Window->head.h)
+      Window->head.pti->MessageQueue->CaptureWindow = NULL;
 
-   IntDereferenceMessageQueue(Window->MessageQueue);
-
-   IntEngWindowChanged(Window, WOC_DELETE);
-   isChild = (0 != (Wnd->style & WS_CHILD));
+   /*
+    * Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
+    */
 
-#if 0 /* FIXME */
+   ti = PsGetCurrentThreadWin32Thread();
 
-   if (isChild)
+   if ((ti != NULL) & (ti->pDeskInfo != NULL))
    {
-      if (! USER_IsExitingThread(GetCurrentThreadId()))
+      if (ti->pDeskInfo->hShellWindow == hWnd)
       {
-         send_parent_notify(hwnd, WM_DESTROY);
+         DPRINT1("Destroying the ShellWindow!\n");
+         ti->pDeskInfo->hShellWindow = NULL;
       }
    }
-   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(Window->hSelf))
+   IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
+
+   IntEngWindowChanged(Window, WOC_DELETE);
+
+   if (!IntIsWindow(Window->head.h))
    {
       return TRUE;
    }
 
    /* Recursively destroy owned windows */
-   if (! isChild)
+
+   if (! (Window->style & WS_CHILD))
    {
       for (;;)
       {
          BOOL GotOne = FALSE;
          HWND *Children;
          HWND *ChildHandle;
-         PWINDOW_OBJECT Child, Desktop;
+         PWND Child, Desktop;
 
          Desktop = IntIsDesktopWindow(Window) ? Window :
                    UserGetWindowObject(IntGetDesktopWindow());
@@ -2651,7 +2531,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
                Child = UserGetWindowObject(*ChildHandle);
                if (Child == NULL)
                   continue;
-               if (Child->hOwner != Window->hSelf)
+               if (Child->spwndOwner != Window)
                {
                   continue;
                }
@@ -2667,10 +2547,9 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
                   continue;
                }
 
-               if (Child->hOwner != NULL)
+               if (Child->spwndOwner != NULL)
                {
-                  Child->hOwner = NULL;
-                  Child->Wnd->spwndOwner = NULL;
+                  Child->spwndOwner = NULL;
                }
 
             }
@@ -2683,7 +2562,14 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
       }
    }
 
-   if (!IntIsWindow(Window->hSelf))
+    /* Generate mouse move message for the next window */
+    msg.message = WM_MOUSEMOVE;
+    msg.wParam = IntGetSysCursorInfo()->ButtonsDown;
+    msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
+    msg.pt = gpsi->ptCursor;
+    MsqInsertMouseMessage(&msg);
+
+   if (!IntIsWindow(Window->head.h))
    {
       return TRUE;
    }
@@ -2701,7 +2587,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 BOOLEAN APIENTRY
 NtUserDestroyWindow(HWND Wnd)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    DECLARE_RETURN(BOOLEAN);
    BOOLEAN ret;
    USER_REFERENCE_ENTRY Ref;
@@ -2778,14 +2664,15 @@ NtUserFillWindow(HWND hWndPaint,
 
 
 static HWND FASTCALL
-IntFindWindow(PWINDOW_OBJECT Parent,
-              PWINDOW_OBJECT ChildAfter,
+IntFindWindow(PWND Parent,
+              PWND ChildAfter,
               RTL_ATOM ClassAtom,
               PUNICODE_STRING WindowName)
 {
    BOOL CheckWindowName;
    HWND *List, *phWnd;
    HWND Ret = NULL;
+   UNICODE_STRING CurrentWindowName;
 
    ASSERT(Parent);
 
@@ -2797,14 +2684,14 @@ IntFindWindow(PWINDOW_OBJECT Parent,
       if(ChildAfter)
       {
          /* skip handles before and including ChildAfter */
-         while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+         while(*phWnd && (*(phWnd++) != ChildAfter->head.h))
             ;
       }
 
       /* search children */
       while(*phWnd)
       {
-         PWINDOW_OBJECT Child;
+         PWND Child;
          if(!(Child = UserGetWindowObject(*(phWnd++))))
          {
             continue;
@@ -2813,13 +2700,20 @@ IntFindWindow(PWINDOW_OBJECT Parent,
          /* 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->Wnd->strName), TRUE)) &&
-               (!ClassAtom || Child->Wnd->pcls->atomClassName == ClassAtom))
+         if (!ClassAtom || Child->pcls->atomClassName == ClassAtom)
          {
-            Ret = Child->hSelf;
+             // HACK: use UNICODE_STRING instead of LARGE_STRING
+             CurrentWindowName.Buffer = Child->strName.Buffer;
+             CurrentWindowName.Length = Child->strName.Length;
+             CurrentWindowName.MaximumLength = Child->strName.MaximumLength;
+             if(!CheckWindowName || 
+                (Child->strName.Length < 0xFFFF &&
+                 !RtlCompareUnicodeString(WindowName, &CurrentWindowName, TRUE)))
+             {
+            Ret = Child->head.h;
             break;
          }
-
+      }
       }
       ExFreePool(List);
    }
@@ -2858,7 +2752,7 @@ NtUserFindWindowEx(HWND hwndParent,
                    PUNICODE_STRING ucWindowName,
                    DWORD dwUnknown)
 {
-   PWINDOW_OBJECT Parent, ChildAfter;
+   PWND Parent, ChildAfter;
    UNICODE_STRING ClassName = {0}, WindowName = {0};
    HWND Desktop, Ret = NULL;
    RTL_ATOM ClassAtom = (RTL_ATOM)0;
@@ -2949,10 +2843,10 @@ NtUserFindWindowEx(HWND hwndParent,
 
    _SEH2_TRY
    {
-       if(Parent->hSelf == Desktop)
+       if(Parent->head.h == Desktop)
        {
           HWND *List, *phWnd;
-          PWINDOW_OBJECT TopLevelWindow;
+          PWND TopLevelWindow;
           BOOLEAN CheckWindowName;
           BOOLEAN WindowMatches;
           BOOLEAN ClassMatches;
@@ -2967,7 +2861,7 @@ NtUserFindWindowEx(HWND hwndParent,
              if(ChildAfter)
              {
                 /* skip handles before and including ChildAfter */
-                while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+                while(*phWnd && (*(phWnd++) != ChildAfter->head.h))
                    ;
              }
 
@@ -2976,6 +2870,8 @@ NtUserFindWindowEx(HWND hwndParent,
              /* search children */
              while(*phWnd)
              {
+                 UNICODE_STRING ustr;
+
                 if(!(TopLevelWindow = UserGetWindowObject(*(phWnd++))))
                 {
                    continue;
@@ -2984,14 +2880,18 @@ NtUserFindWindowEx(HWND hwndParent,
                 /* 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->Wnd->strName, TRUE);
+                ustr.Buffer = TopLevelWindow->strName.Buffer;
+                ustr.Length = TopLevelWindow->strName.Length;
+                ustr.MaximumLength = TopLevelWindow->strName.MaximumLength;
+                WindowMatches = !CheckWindowName || 
+                                (TopLevelWindow->strName.Length < 0xFFFF && 
+                                 !RtlCompareUnicodeString(&WindowName, &ustr, TRUE));
                 ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
-                               ClassAtom == TopLevelWindow->Wnd->pcls->atomClassName;
+                               ClassAtom == TopLevelWindow->pcls->atomClassName;
 
                 if (WindowMatches && ClassMatches)
                 {
-                   Ret = TopLevelWindow->hSelf;
+                   Ret = TopLevelWindow->head.h;
                    break;
                 }
 
@@ -2999,7 +2899,7 @@ NtUserFindWindowEx(HWND hwndParent,
                 {
                    /* window returns the handle of the top-level window, in case it found
                       the child window */
-                   Ret = TopLevelWindow->hSelf;
+                   Ret = TopLevelWindow->head.h;
                    break;
                 }
 
@@ -3017,7 +2917,7 @@ NtUserFindWindowEx(HWND hwndParent,
           /* 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;
+          PWND MsgWindows;
 
           if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
           {
@@ -3057,11 +2957,11 @@ NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
 /*
  * @implemented
  */
-PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
+PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
 {
-   PWINDOW_OBJECT WndAncestor, Parent;
+   PWND WndAncestor, Parent;
 
-   if (Wnd->hSelf == IntGetDesktopWindow())
+   if (Wnd->head.h == IntGetDesktopWindow())
    {
       return NULL;
    }
@@ -3070,7 +2970,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
    {
       case GA_PARENT:
          {
-            WndAncestor = Wnd->Parent;
+            WndAncestor = Wnd->spwndParent;
             break;
          }
 
@@ -3081,7 +2981,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 
             for(;;)
             {
-               if(!(Parent = WndAncestor->Parent))
+               if(!(Parent = WndAncestor->spwndParent))
                {
                   break;
                }
@@ -3101,9 +3001,8 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 
             for (;;)
             {
-               PWINDOW_OBJECT Parent, Old;
+               PWND Parent;
 
-               Old = WndAncestor;
                Parent = IntGetParent(WndAncestor);
 
                if (!Parent)
@@ -3111,9 +3010,6 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
                   break;
                }
 
-               //temp hack
-//               UserDereferenceObject(Parent);
-
                WndAncestor = Parent;
             }
             break;
@@ -3134,7 +3030,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 HWND APIENTRY
 NtUserGetAncestor(HWND hWnd, UINT Type)
 {
-   PWINDOW_OBJECT Window, Ancestor;
+   PWND Window, Ancestor;
    DECLARE_RETURN(HWND);
 
    DPRINT("Enter NtUserGetAncestor\n");
@@ -3148,7 +3044,7 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
    Ancestor = UserGetAncestor(Window, Type);
    /* faxme: can UserGetAncestor ever return NULL for a valid window? */
 
-   RETURN(Ancestor ? Ancestor->hSelf : NULL);
+   RETURN(Ancestor ? Ancestor->head.h : NULL);
 
 CLEANUP:
    DPRINT("Leave NtUserGetAncestor, ret=%i\n",_ret_);
@@ -3163,7 +3059,7 @@ NtUserGetComboBoxInfo(
    HWND hWnd,
    PCOMBOBOXINFO pcbi)
 {
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserGetComboBoxInfo\n");
@@ -3190,7 +3086,7 @@ NtUserGetComboBoxInfo(
    _SEH2_END;
 
    // Pass the user pointer, it was already probed.
-   RETURN( (BOOL) co_IntSendMessage( Wnd->hSelf, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+   RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
 
 CLEANUP:
    DPRINT("Leave NtUserGetComboBoxInfo, ret=%i\n",_ret_);
@@ -3207,20 +3103,18 @@ NtUserGetInternalWindowPos( HWND hWnd,
                             LPRECT rectWnd,
                             LPPOINT ptIcon)
 {
-   PWINDOW_OBJECT Window;
-   PWND Wnd;
+   PWND Window;
    DWORD Ret = 0;
    BOOL Hit = FALSE;
    WINDOWPLACEMENT wndpl;
 
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
       Hit = FALSE;
       goto Exit;
    }
-   Wnd = Window->Wnd;
 
    _SEH2_TRY
    {
@@ -3280,7 +3174,7 @@ APIENTRY
 NtUserGetListBoxInfo(
    HWND hWnd)
 {
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    DECLARE_RETURN(DWORD);
 
    DPRINT("Enter NtUserGetListBoxInfo\n");
@@ -3291,7 +3185,7 @@ NtUserGetListBoxInfo(
       RETURN( 0 );
    }
 
-   RETURN( (DWORD) co_IntSendMessage( Wnd->hSelf, LB_GETLISTBOXINFO, 0, 0 ));
+   RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
 
 CLEANUP:
    DPRINT("Leave NtUserGetListBoxInfo, ret=%i\n",_ret_);
@@ -3303,7 +3197,7 @@ CLEANUP:
 HWND FASTCALL
 co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
 {
-   PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
+   PWND Wnd = NULL, WndParent = NULL, WndOldParent;
    HWND hWndOldParent = NULL;
    USER_REFERENCE_ENTRY Ref, ParentRef;
 
@@ -3349,7 +3243,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
 
    if (WndOldParent)
    {
-      hWndOldParent = WndOldParent->hSelf;
+      hWndOldParent = WndOldParent->head.h;
       UserDereferenceObject(WndOldParent);
    }
 
@@ -3444,7 +3338,7 @@ BOOL APIENTRY
 NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
 {
    PWINSTATION_OBJECT WinStaObject;
-   PWINDOW_OBJECT WndShell;
+   PWND WndShell, WndListView;
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
    NTSTATUS Status;
@@ -3458,6 +3352,11 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
       RETURN(FALSE);
    }
 
+   if(!(WndListView = UserGetWindowObject(hwndListView)))
+   {
+      RETURN(FALSE);
+   }
+
    Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
                      KernelMode,
                      0,
@@ -3491,14 +3390,14 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
       co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
 #endif
 
-      if (UserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
+      if (WndListView->ExStyle & WS_EX_TOPMOST)
       {
          ObDereferenceObject(WinStaObject);
          RETURN( FALSE);
       }
    }
 
-   if (UserGetWindowLong(hwndShell, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
+   if (WndShell->ExStyle & WS_EX_TOPMOST)
    {
       ObDereferenceObject(WinStaObject);
       RETURN( FALSE);
@@ -3554,7 +3453,7 @@ CLEANUP:
 HMENU APIENTRY
 NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    PMENU_OBJECT Menu;
    DECLARE_RETURN(HMENU);
 
@@ -3590,7 +3489,7 @@ BOOL APIENTRY
 NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
 {
    BOOL Result = FALSE;
-   PWINDOW_OBJECT Window;
+   PWND Window;
    PMENU_OBJECT Menu;
    DECLARE_RETURN(BOOL);
 
@@ -3623,214 +3522,10 @@ CLEANUP:
    END_CLEANUP;
 }
 
-HWND FASTCALL
-UserGetWindow(HWND hWnd, UINT Relationship)
-{
-   PWINDOW_OBJECT Parent, Window;
-   HWND hWndResult = NULL;
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-      return NULL;
-
-   switch (Relationship)
-   {
-      case GW_HWNDFIRST:
-         if((Parent = Window->Parent))
-         {
-            if (Parent->FirstChild)
-               hWndResult = Parent->FirstChild->hSelf;
-         }
-         break;
-
-      case GW_HWNDLAST:
-         if((Parent = Window->Parent))
-         {
-            if (Parent->LastChild)
-               hWndResult = Parent->LastChild->hSelf;
-         }
-         break;
-
-      case GW_HWNDNEXT:
-         if (Window->NextSibling)
-            hWndResult = Window->NextSibling->hSelf;
-         break;
-
-      case GW_HWNDPREV:
-         if (Window->PrevSibling)
-            hWndResult = Window->PrevSibling->hSelf;
-         break;
-
-      case GW_OWNER:
-         if((Parent = UserGetWindowObject(Window->hOwner)))
-         {
-            hWndResult = Parent->hSelf;
-         }
-         break;
-      case GW_CHILD:
-         if (Window->FirstChild)
-            hWndResult = Window->FirstChild->hSelf;
-         break;
-   }
-
-   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 APIENTRY
-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.
- *
- * Status
- *    @implemented
- */
-
-LONG FASTCALL
-UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
-{
-   PWINDOW_OBJECT Window, Parent;
-   PWND Wnd;
-   LONG Result = 0;
-
-   DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
-
-   if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
-   {
-      return 0;
-   }
-
-   Wnd = Window->Wnd;
-
-   /*
-    * WndProc is only available to the owner process
-    */
-   if (GWL_WNDPROC == Index
-         && Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return 0;
-   }
-
-   if ((INT)Index >= 0)
-   {
-      if ((Index + sizeof(LONG)) > Window->Wnd->cbwndExtra)
-      {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
-         return 0;
-      }
-      Result = *((LONG *)((PCHAR)(Window->Wnd + 1) + Index));
-   }
-   else
-   {
-      switch (Index)
-      {
-         case GWL_EXSTYLE:
-            Result = Wnd->ExStyle;
-            break;
-
-         case GWL_STYLE:
-            Result = Wnd->style;
-            break;
-
-         case GWL_WNDPROC:
-            Result = (LONG)IntGetWindowProc(Wnd, Ansi);
-            break;
-
-         case GWL_HINSTANCE:
-            Result = (LONG) Wnd->hModule;
-            break;
-
-         case GWL_HWNDPARENT:
-            Parent = Window->Parent;
-            if(Parent)
-            {
-               if (Parent && Parent->hSelf == IntGetDesktopWindow())
-                  Result = (LONG) UserGetWindow(Window->hSelf, GW_OWNER);
-               else
-                  Result = (LONG) Parent->hSelf;
-            }
-            break;
-
-         case GWL_ID:
-            Result = (LONG) Wnd->IDMenu;
-            break;
-
-         case GWL_USERDATA:
-            Result = Wnd->dwUserData;
-            break;
-
-         default:
-            DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
-            Result = 0;
-            break;
-      }
-   }
-
-   return Result;
-}
-
-/*
- * 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.
- *
- * Status
- *    @implemented
- */
-
-LONG APIENTRY
-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 Window, Parent;
-   PWND Wnd;
+   PWND Window, Parent;
    PWINSTATION_OBJECT WindowStation;
    LONG OldValue;
    STYLESTRUCT Style;
@@ -3846,19 +3541,15 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
       return( 0);
    }
 
-   Wnd = Window->Wnd;
-
-   if (!Wnd) return 0; // No go on zero.
-
    if ((INT)Index >= 0)
    {
-      if ((Index + sizeof(LONG)) > Wnd->cbwndExtra)
+      if ((Index + sizeof(LONG)) > Window->cbwndExtra)
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         SetLastWin32Error(ERROR_INVALID_INDEX);
          return( 0);
       }
 
-      OldValue = *((LONG *)((PCHAR)(Wnd + 1) + Index));
+      OldValue = *((LONG *)((PCHAR)(Window + 1) + Index));
 /*
       if ( Index == DWLP_DLGPROC && Wnd->state & WNDS_DIALOGWINDOW)
       {
@@ -3868,21 +3559,21 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
          if (!OldValue) return 0;
       }
 */
-      *((LONG *)((PCHAR)(Wnd + 1) + Index)) = NewValue;
+      *((LONG *)((PCHAR)(Window + 1) + Index)) = NewValue;
    }
    else
    {
       switch (Index)
       {
          case GWL_EXSTYLE:
-            OldValue = (LONG) Wnd->ExStyle;
+            OldValue = (LONG) Window->ExStyle;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
 
             /*
              * Remove extended window style bit WS_EX_TOPMOST for shell windows.
              */
-            WindowStation = ((PTHREADINFO)Window->OwnerThread->Tcb.Win32Thread)->Desktop->WindowStation;
+            WindowStation = Window->head.pti->rpdesk->rpwinstaParent;
             if(WindowStation)
             {
                if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
@@ -3890,59 +3581,59 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             }
 
             co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
-            Wnd->ExStyle = (DWORD)Style.styleNew;
+            Window->ExStyle = (DWORD)Style.styleNew;
             co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_EXSTYLE, (LPARAM) &Style);
             break;
 
          case GWL_STYLE:
-            OldValue = (LONG) Wnd->style;
+            OldValue = (LONG) Window->style;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
             co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
-            Wnd->style = (DWORD)Style.styleNew;
+            Window->style = (DWORD)Style.styleNew;
             co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
             break;
 
          case GWL_WNDPROC:
          {
-            if ( Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
-                 Wnd->fnid & FNID_FREED)
+            if ( Window->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
+                 Window->fnid & FNID_FREED)
             {
                SetLastWin32Error(ERROR_ACCESS_DENIED);
                return( 0);
             }
-            OldValue = (LONG)IntSetWindowProc(Wnd,
+            OldValue = (LONG)IntSetWindowProc(Window,
                                               (WNDPROC)NewValue,
                                               Ansi);
             break;
          }
 
          case GWL_HINSTANCE:
-            OldValue = (LONG) Wnd->hModule;
-            Wnd->hModule = (HINSTANCE) NewValue;
+            OldValue = (LONG) Window->hModule;
+            Window->hModule = (HINSTANCE) NewValue;
             break;
 
          case GWL_HWNDPARENT:
-            Parent = Window->Parent;
-            if (Parent && (Parent->hSelf == IntGetDesktopWindow()))
-               OldValue = (LONG) IntSetOwner(Window->hSelf, (HWND) NewValue);
+            Parent = Window->spwndParent;
+            if (Parent && (Parent->head.h == IntGetDesktopWindow()))
+               OldValue = (LONG) IntSetOwner(Window->head.h, (HWND) NewValue);
             else
-               OldValue = (LONG) co_UserSetParent(Window->hSelf, (HWND) NewValue);
+               OldValue = (LONG) co_UserSetParent(Window->head.h, (HWND) NewValue);
             break;
 
          case GWL_ID:
-            OldValue = (LONG) Wnd->IDMenu;
-            Wnd->IDMenu = (UINT) NewValue;
+            OldValue = (LONG) Window->IDMenu;
+            Window->IDMenu = (UINT) NewValue;
             break;
 
          case GWL_USERDATA:
-            OldValue = Wnd->dwUserData;
-            Wnd->dwUserData = NewValue;
+            OldValue = Window->dwUserData;
+            Window->dwUserData = NewValue;
             break;
 
          default:
             DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            SetLastWin32Error(ERROR_INVALID_INDEX);
             OldValue = 0;
             break;
       }
@@ -3990,7 +3681,7 @@ CLEANUP:
 WORD APIENTRY
 NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    WORD OldValue;
    DECLARE_RETURN(WORD);
 
@@ -4007,7 +3698,7 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
       case GWL_ID:
       case GWL_HINSTANCE:
       case GWL_HWNDPARENT:
-         RETURN( co_UserSetWindowLong(Window->hSelf, Index, (UINT)NewValue, TRUE));
+         RETURN( co_UserSetWindowLong(Window->head.h, Index, (UINT)NewValue, TRUE));
       default:
          if (Index < 0)
          {
@@ -4016,14 +3707,14 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
          }
    }
 
-   if (Index > Window->Wnd->cbwndExtra - sizeof(WORD))
+   if (Index > Window->cbwndExtra - sizeof(WORD))
    {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       RETURN( 0);
    }
 
-   OldValue = *((WORD *)((PCHAR)(Window->Wnd + 1) + Index));
-   *((WORD *)((PCHAR)(Window->Wnd + 1) + Index)) = NewValue;
+   OldValue = *((WORD *)((PCHAR)(Window + 1) + Index));
+   *((WORD *)((PCHAR)(Window + 1) + Index)) = NewValue;
 
    RETURN( OldValue);
 
@@ -4040,7 +3731,6 @@ BOOL APIENTRY
 NtUserGetWindowPlacement(HWND hWnd,
                          WINDOWPLACEMENT *lpwndpl)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    POINT Size;
    WINDOWPLACEMENT Safepl;
@@ -4050,11 +3740,10 @@ NtUserGetWindowPlacement(HWND hWnd,
    DPRINT("Enter NtUserGetWindowPlacement\n");
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)))
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( FALSE);
    }
-   Wnd = Window->Wnd;
 
    Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
    if(!NT_SUCCESS(Status))
@@ -4072,7 +3761,7 @@ NtUserGetWindowPlacement(HWND hWnd,
    {
       Safepl.showCmd = SW_HIDE;
    }
-   else if ((0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+   else if ((0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
             0 != (Wnd->style & WS_MAXIMIZE)) &&
             0 == (Wnd->style & WS_MINIMIZE))
    {
@@ -4089,7 +3778,7 @@ NtUserGetWindowPlacement(HWND hWnd,
 
    Size.x = Wnd->rcWindow.left;
    Size.y = Wnd->rcWindow.top;
-   WinPosInitInternalPos(Window, &Size,
+   WinPosInitInternalPos(Wnd, &Size,
                          &Wnd->rcWindow);
 
    Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
@@ -4161,7 +3850,6 @@ NtUserMoveWindow(
 DWORD APIENTRY
 NtUserQueryWindow(HWND hWnd, DWORD Index)
 {
-   PWINDOW_OBJECT Window;
    PWND pWnd;
    DWORD Result;
    DECLARE_RETURN(UINT);
@@ -4169,21 +3857,19 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
    DPRINT("Enter NtUserQueryWindow\n");
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+   if (!(pWnd = UserGetWindowObject(hWnd)))
    {
       RETURN( 0);
    }
 
-   pWnd = Window->Wnd;
-
    switch(Index)
    {
       case QUERY_WINDOW_UNIQUE_PROCESS_ID:
-         Result = (DWORD)IntGetWndProcessId(Window);
+         Result = (DWORD)IntGetWndProcessId(pWnd);
          break;
 
       case QUERY_WINDOW_UNIQUE_THREAD_ID:
-         Result = (DWORD)IntGetWndThreadId(Window);
+         Result = (DWORD)IntGetWndThreadId(pWnd);
          break;
 
       case QUERY_WINDOW_ACTIVE:
@@ -4195,7 +3881,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
          break;
 
       case QUERY_WINDOW_ISHUNG:
-         Result = (DWORD)MsqIsHung(Window->MessageQueue);
+         Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
          break;
 
       case QUERY_WINDOW_REAL_ID:
@@ -4257,8 +3943,8 @@ NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
    }
 
    Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
-
-   ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
+   if (SafeMessageName.Buffer)
+      ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
    RETURN( Ret);
 
 CLEANUP:
@@ -4333,7 +4019,7 @@ NtUserSetMenu(
    HMENU Menu,
    BOOL Repaint)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    BOOL Changed;
    DECLARE_RETURN(BOOL);
 
@@ -4377,18 +4063,16 @@ BOOL APIENTRY
 NtUserSetWindowFNID(HWND hWnd,
                     WORD fnID)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserSetWindowFNID\n");
    UserEnterExclusive();
 
-   if (!(Window = UserGetWindowObject(hWnd)))
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( FALSE);
    }
-   Wnd = Window->Wnd;
 
    if (Wnd->pcls)
    {  // From user land we only set these.
@@ -4415,7 +4099,6 @@ BOOL APIENTRY
 NtUserSetWindowPlacement(HWND hWnd,
                          WINDOWPLACEMENT *lpwndpl)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    WINDOWPLACEMENT Safepl;
    NTSTATUS Status;
@@ -4425,11 +4108,10 @@ NtUserSetWindowPlacement(HWND hWnd,
    DPRINT("Enter NtUserSetWindowPlacement\n");
    UserEnterExclusive();
 
-   if (!(Window = UserGetWindowObject(hWnd)))
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( FALSE);
    }
-   Wnd = Window->Wnd;
 
    Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
    if(!NT_SUCCESS(Status))
@@ -4442,11 +4124,11 @@ NtUserSetWindowPlacement(HWND hWnd,
       RETURN( FALSE);
    }
 
-   UserRefObjectCo(Window, &Ref);
+   UserRefObjectCo(Wnd, &Ref);
 
    if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
    {
-      co_WinPosSetWindowPos(Window, NULL,
+      co_WinPosSetWindowPos(Wnd, NULL,
                             Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
                             Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
                             Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
@@ -4454,14 +4136,14 @@ NtUserSetWindowPlacement(HWND hWnd,
    }
 
    /* FIXME - change window status */
-   co_WinPosShowWindow(Window, Safepl.showCmd);
+   co_WinPosShowWindow(Wnd, Safepl.showCmd);
 
    Wnd->InternalPosInitialized = TRUE;
    Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition;
    Wnd->InternalPos.IconPos = Safepl.ptMinPosition;
    Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition;
 
-   UserDerefObjectCo(Window);
+   UserDerefObjectCo(Wnd);
    RETURN(TRUE);
 
 CLEANUP:
@@ -4485,7 +4167,7 @@ NtUserSetWindowPos(
    UINT uFlags)
 {
    DECLARE_RETURN(BOOL);
-   PWINDOW_OBJECT Window;
+   PWND Window;
    BOOL ret;
    USER_REFERENCE_ENTRY Ref;
 
@@ -4527,12 +4209,11 @@ CLEANUP:
 
 
 INT FASTCALL
-IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
+IntGetWindowRgn(PWND Window, HRGN hRgn)
 {
    INT Ret;
    HRGN VisRgn;
    ROSRGNDATA *pRgn;
-   PWND Wnd;
 
    if(!Window)
    {
@@ -4543,37 +4224,34 @@ IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
       return ERROR;
    }
 
-   Wnd = Window->Wnd;
-
    /* Create a new window region using the window rectangle */
-   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcWindow);
-   NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
+   VisRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
+   NtGdiOffsetRgn(VisRgn, -Window->rcWindow.left, -Window->rcWindow.top);
    /* if there's a region assigned to the window, combine them both */
-   if(Window->WindowRegion && !(Wnd->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   if(Window->hrgnClip && !(Window->style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
    /* Copy the region into hRgn */
    NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
 
-   if((pRgn = REGION_LockRgn(hRgn)))
+   if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
    {
-      Ret = pRgn->rdh.iType;
-      REGION_UnlockRgn(pRgn);
+      Ret = REGION_Complexity(pRgn);
+      RGNOBJAPI_Unlock(pRgn);
    }
    else
       Ret = ERROR;
 
-   GreDeleteObject(VisRgn);
+   REGION_FreeRgnByHandle(VisRgn);
 
    return Ret;
 }
 
 INT FASTCALL
-IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
+IntGetWindowRgnBox(PWND Window, RECTL *Rect)
 {
    INT Ret;
    HRGN VisRgn;
    ROSRGNDATA *pRgn;
-   PWND Wnd;
 
    if(!Window)
    {
@@ -4584,25 +4262,23 @@ IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
       return ERROR;
    }
 
-   Wnd = Window->Wnd;
-
    /* Create a new window region using the window rectangle */
-   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcWindow);
-   NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
+   VisRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
+   NtGdiOffsetRgn(VisRgn, -Window->rcWindow.left, -Window->rcWindow.top);
    /* if there's a region assigned to the window, combine them both */
-   if(Window->WindowRegion && !(Wnd->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   if(Window->hrgnClip && !(Window->style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
 
-   if((pRgn = REGION_LockRgn(VisRgn)))
+   if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
    {
-      Ret = pRgn->rdh.iType;
+      Ret = REGION_Complexity(pRgn);
       *Rect = pRgn->rdh.rcBound;
-      REGION_UnlockRgn(pRgn);
+      RGNOBJAPI_Unlock(pRgn);
    }
    else
       Ret = ERROR;
 
-   GreDeleteObject(VisRgn);
+   REGION_FreeRgnByHandle(VisRgn);
 
    return Ret;
 }
@@ -4617,7 +4293,8 @@ NtUserSetWindowRgn(
    HRGN hRgn,
    BOOL bRedraw)
 {
-   PWINDOW_OBJECT Window;
+   HRGN hrgnCopy;
+   PWND Window;
    DECLARE_RETURN(INT);
 
    DPRINT("Enter NtUserSetWindowRgn\n");
@@ -4628,15 +4305,25 @@ NtUserSetWindowRgn(
       RETURN( 0);
    }
 
-   /* FIXME - Verify if hRgn is a valid handle!!!!
-              Propably make this operation thread-safe, but maybe it's not necessary */
+   if (hRgn) // The region will be deleted in user32.
+   {
+      if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
+      {
+         hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
+         NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
+      }
+      else
+         RETURN( 0);
+   }
+   else
+      hrgnCopy = (HRGN) 1;
 
-   if(Window->WindowRegion)
+   if (Window->hrgnClip)
    {
       /* Delete no longer needed region handle */
-      GreDeleteObject(Window->WindowRegion);
+      GreDeleteObject(Window->hrgnClip);
    }
-   Window->WindowRegion = hRgn;
+   Window->hrgnClip = hrgnCopy;
 
    /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
 
@@ -4663,7 +4350,7 @@ CLEANUP:
 BOOL APIENTRY
 NtUserShowWindow(HWND hWnd, LONG nCmdShow)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    BOOL ret;
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
@@ -4745,7 +4432,7 @@ NtUserWindowFromPoint(LONG X, LONG Y)
 {
    POINT pt;
    HWND Ret;
-   PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
+   PWND DesktopWindow = NULL, Window = NULL;
    DECLARE_RETURN(HWND);
    USER_REFERENCE_ENTRY Ref;
 
@@ -4755,7 +4442,6 @@ NtUserWindowFromPoint(LONG X, LONG Y)
    if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
    {
       PTHREADINFO pti;
-      USHORT Hit;
 
       pt.x = X;
       pt.y = Y;
@@ -4765,11 +4451,11 @@ NtUserWindowFromPoint(LONG X, LONG Y)
       UserRefObjectCo(DesktopWindow, &Ref);
 
       pti = PsGetCurrentThreadWin32Thread();
-      Hit = co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
+      co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
 
       if(Window)
       {
-         Ret = Window->hSelf;
+         Ret = Window->head.h;
 
          RETURN( Ret);
       }
@@ -4800,7 +4486,6 @@ CLEANUP:
 BOOL APIENTRY
 NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    LARGE_STRING SafeText;
    UNICODE_STRING UnicodeString;
@@ -4829,12 +4514,11 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
 
    UserEnterExclusive();
 
-   if(!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+   if(!(Wnd = UserGetWindowObject(hWnd)))
    {
       UserLeave();
       return FALSE;
    }
-   Wnd = Window->Wnd;
 
    // ReactOS uses Unicode and not mixed. Up/Down converting will take time.
    // Brought to you by: The Wine Project! Dysfunctional Thought Processes!
@@ -4913,7 +4597,7 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
    // In User32, these are called after: NotifyWinEvent EVENT_OBJECT_NAMECHANGE than
    // RepaintButton, StaticRepaint, NtUserCallHwndLock HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK, etc.
    /* Send shell notifications */
-   if (!IntGetOwner(Window) && !IntGetParent(Window))
+   if (!Wnd->spwndOwner && !IntGetParent(Wnd))
    {
       co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
    }
@@ -4936,7 +4620,6 @@ Exit:
 INT APIENTRY
 NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    NTSTATUS Status;
    INT Result;
@@ -4951,11 +4634,10 @@ NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
       RETURN( 0);
    }
 
-   if(!(Window = UserGetWindowObject(hWnd)))
+   if(!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( 0);
    }
-   Wnd = Window->Wnd;
 
    Result = Wnd->strName.Length / sizeof(WCHAR);
    if(lpString)
@@ -4997,10 +4679,10 @@ CLEANUP:
 
 BOOL
 FASTCALL
-IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
+IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
 {
    int count = 0;
-   PWINDOW_OBJECT pWnd;
+   PWND pWnd;
    HWND *win_array;
 
 //   ASSERT(OwnerWnd);
@@ -5014,15 +4696,14 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
       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 (pWnd->spwndOwner != OwnerWnd)
+         continue;
 
       if (fShow)
       {
-         if (pWnd->Wnd->state & WNDS_HIDDENPOPUP)
+         if (pWnd->state & WNDS_HIDDENPOPUP)
          {
             /* In Windows, ShowOwnedPopups(TRUE) generates
              * WM_SHOWWINDOW messages with SW_PARENTOPENING,
@@ -5034,7 +4715,7 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
       }
       else
       {
-         if (pWnd->Wnd->style & WS_VISIBLE)
+         if (pWnd->style & WS_VISIBLE)
          {
             /* In Windows, ShowOwnedPopups(FALSE) generates
              * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
@@ -5079,7 +4760,7 @@ NtUserValidateHandleSecure(
      {
        case otWindow:
        {
-         PWINDOW_OBJECT Window;
+         PWND Window;
          if ((Window = UserGetWindowObject((HWND) handle))) return TRUE;
          return FALSE;
        }
@@ -5109,7 +4790,7 @@ NtUserValidateHandleSecure(
        }
        case otMonitor:
        {
-         PMONITOR_OBJECT Monitor;
+         PMONITOR Monitor;
          if ((Monitor = UserGetMonitorObject((HMONITOR) handle))) return TRUE;
          return FALSE;
        }