- Update KTHREAD and KUSER_SHARED_DATA to latest versions. This should make 2K3 drive...
[reactos.git] / reactos / subsys / win32k / ntuser / window.c
index ef21d52..7afc46f 100644 (file)
@@ -239,7 +239,8 @@ static void IntSendDestroyMsg(HWND hWnd)
    Window = UserGetWindowObject(hWnd);
    if (Window)
    {
-//      UserRefObjectCo(Window);
+//      USER_REFERENCE_ENTRY Ref;
+//      UserRefObjectCo(Window, &Ref);
       
       if (!IntGetOwner(Window) && !IntGetParent(Window))
       {
@@ -293,8 +294,12 @@ static void IntSendDestroyMsg(HWND hWnd)
  *           IntDestroyWindow
  *
  * Destroy storage associated to a window. "Internals" p.358
+ *
+ * This is the "functional" DestroyWindows function ei. all stuff
+ * done in CreateWindow is undone here and not in DestroyWindow:-P
+  
  */
-static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
+static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
                                    PW32PROCESS ProcessData,
                                    PW32THREAD ThreadData,
                                    BOOLEAN SendMessages)
@@ -343,7 +348,7 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
                IntSendDestroyMsg(Child->hSelf);
             }
             else
-               co_IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
+               co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
             
             UserDerefObject(Child);
          }
@@ -427,11 +432,8 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
 
    IntDestroyScrollBars(Window);
 
-   /* remove the window from the class object */
-   RemoveEntryList(&Window->ClassListEntry);
-
    /* dereference the class */
-   ClassDereferenceObject(Window->Class);
+   ClassDerefObject(Window->Class);
    Window->Class = NULL;
 
    if(Window->WindowRegion)
@@ -568,8 +570,8 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
    PW32THREAD WThread;
    PLIST_ENTRY Current;
    PWINDOW_OBJECT Wnd;
-
-   WThread = Thread->Tcb.Win32Thread;
+   USER_REFERENCE_ENTRY Ref;
+   WThread = (PW32THREAD)Thread->Tcb.Win32Thread;
    
    while (!IsListEmpty(&WThread->WindowListHead))
    {
@@ -587,7 +589,7 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
       
       //ASSERT(co_UserDestroyWindow(Wnd));
       
-      UserRefObjectCo(Wnd);//faxme: temp hack??
+      UserRefObjectCo(Wnd, &Ref);//faxme: temp hack??
       if (!co_UserDestroyWindow(Wnd))
       {
          DPRINT1("Unable to destroy window 0x%x at thread cleanup... This is _VERY_ bad!\n", Wnd);
@@ -878,7 +880,6 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
    PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter;
 //   HWND hWnd, hWndNewParent;
    BOOL WasVisible;
-   BOOL MenuChanged;
 
    ASSERT(Wnd);
    ASSERT(WndNewParent);
@@ -930,15 +931,6 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
          IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
 //         UserDerefObject(InsertAfter);
       }
-
-      if (WndNewParent->hSelf != IntGetDesktopWindow()) /* a child window */
-      {
-         if (!(Wnd->Style & WS_CHILD))
-         {
-            //if ( Wnd->Menu ) DestroyMenu ( Wnd->menu );
-            IntSetMenu(Wnd, NULL, &MenuChanged);
-         }
-      }
    }
 
    /*
@@ -1129,7 +1121,7 @@ NtUserBuildHwndList(
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
          return 0;
       }
-      if(!(W32Thread = Thread->Tcb.Win32Thread))
+      if(!(W32Thread = (PW32THREAD)Thread->Tcb.Win32Thread))
       {
          ObDereferenceObject(Thread);
          DPRINT("Thread is not a GUI Thread!\n");
@@ -1341,13 +1333,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
                      BOOL bUnicodeWindow)
 {
    PWINSTATION_OBJECT WinSta;
-   PWNDCLASS_OBJECT Class;
+   PWNDCLASS_OBJECT Class = NULL;
    PWINDOW_OBJECT Window = NULL;
    PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
    HWND ParentWindowHandle;
    HWND OwnerWindowHandle;
    PMENU_OBJECT SystemMenu;
-   HANDLE Handle;
+   HWND hWnd;
    POINT Pos;
    SIZE Size;
 #if 0
@@ -1362,9 +1354,9 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    CBT_CREATEWNDW CbtCreate;
    LRESULT Result;
    BOOL MenuChanged;
-   BOOL ClassFound;
    DECLARE_RETURN(HWND);
    BOOL HasOwner;
+   USER_REFERENCE_ENTRY ParentRef, Ref;
 
    ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
    OwnerWindowHandle = NULL;
@@ -1384,9 +1376,9 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       else
       {
          //temp hack
-         PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent);
-         if (Par)
-            OwnerWindowHandle = UserGetAncestor(Par, GA_ROOT)->hSelf;
+         PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root;
+         if (Par && (Root = UserGetAncestor(Par, GA_ROOT)))
+            OwnerWindowHandle = Root->hSelf;
       }
    }
    else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
@@ -1398,7 +1390,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
 //   {
    ParentWindow = UserGetWindowObject(ParentWindowHandle);
 
-   if (ParentWindow) UserRefObjectCo(ParentWindow);
+   if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
 //   }
 //   else
 //   {
@@ -1408,8 +1400,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    /* FIXME: parent must belong to the current process */
 
    /* Check the class. */
-   ClassFound = ClassReferenceClassByNameOrAtom(&Class, ClassName->Buffer, hInstance);
-   if (!ClassFound)
+   Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
+   if (!Class)
    {
       if (IS_ATOM(ClassName->Buffer))
       {
@@ -1424,55 +1416,52 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       RETURN((HWND)0);
    }
 
+   ClassRefObject(Class);
+
    /* Check the window station. */
    if (PsGetWin32Thread()->Desktop == NULL)
    {
-      ClassDereferenceObject(Class);
-
       DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
       RETURN( (HWND)0);
    }
    WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+
+   //FIXME: Reference thread/desktop instead
    ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 
    /* Create the window object. */
    Window = (PWINDOW_OBJECT)
-            ObmCreateObject(&gHandleTable, &Handle,
+            ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
                             otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
                            );
 
-   DPRINT("Created object with handle %X\n", Handle);
+   DPRINT("Created object with handle %X\n", hWnd);
    if (!Window)
    {
       ObDereferenceObject(WinSta);
-      ClassDereferenceObject(Class);
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
       RETURN( (HWND)0);
    }
 
-   UserRefObjectCo(Window);
-
+   UserRefObjectCo(Window, &Ref);
 
    ObDereferenceObject(WinSta);
 
    if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
    {
       /* If there is no desktop window yet, we must be creating it */
-      PsGetWin32Thread()->Desktop->DesktopWindow = Handle;
+      PsGetWin32Thread()->Desktop->DesktopWindow = hWnd;
    }
 
    /*
     * Fill out the structure describing it.
     */
    Window->Class = Class;
-
-   InsertTailList(&Class->ClassWindowsListHead, &Window->ClassListEntry);
-
    Window->SystemMenu = (HMENU)0;
    Window->ContextHelpId = 0;
    Window->IDMenu = 0;
    Window->Instance = hInstance;
-   Window->hSelf = Handle;
+   Window->hSelf = hWnd;
    if (0 != (dwStyle & WS_CHILD))
    {
       Window->IDMenu = (UINT) hMenu;
@@ -1515,19 +1504,11 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    Window->LastChild = NULL;
    Window->PrevSibling = NULL;
    Window->NextSibling = NULL;
+   Window->ExtraDataSize = Class->cbWndExtra;
 
    /* extra window data */
-   if (Class->cbWndExtra != 0)
-   {
+   if (Class->cbWndExtra)
       Window->ExtraData = (PCHAR)(Window + 1);
-      Window->ExtraDataSize = Class->cbWndExtra;
-      RtlZeroMemory(Window->ExtraData, Window->ExtraDataSize);
-   }
-   else
-   {
-      Window->ExtraData = NULL;
-      Window->ExtraDataSize = 0;
-   }
 
    InitializeListHead(&Window->PropListHead);
    InitializeListHead(&Window->WndObjListHead);
@@ -1540,7 +1521,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
                                   TAG_STRING);
       if (NULL == Window->WindowName.Buffer)
       {
-         ClassDereferenceObject(Class);
          DPRINT1("Failed to allocate mem for window name\n");
          SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
          RETURN( NULL);
@@ -1622,13 +1602,10 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    Cs.dwExStyle = dwExStyle;
    CbtCreate.lpcs = &Cs;
    CbtCreate.hwndInsertAfter = HWND_TOP;
-   if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
+   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 */
-
-      ClassDereferenceObject(Class);
       DPRINT1("CBT-hook returned !0\n");
       RETURN( (HWND) NULL);
    }
@@ -1645,7 +1622,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       PRTL_USER_PROCESS_PARAMETERS ProcessParams;
       BOOL CalculatedDefPosSize = FALSE;
 
-      IntGetDesktopWorkArea(Window->OwnerThread->Tcb.Win32Thread->Desktop, &WorkArea);
+      IntGetDesktopWorkArea(((PW32THREAD)Window->OwnerThread->Tcb.Win32Thread)->Desktop, &WorkArea);
 
       rc = WorkArea;
       ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
@@ -1735,18 +1712,18 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
       co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack,
                              &MaxTrack);
-      if (MaxSize.x < nWidth)
-         nWidth = MaxSize.x;
-      if (MaxSize.y < nHeight)
-         nHeight = MaxSize.y;
-      if (nWidth < MinTrack.x )
-         nWidth = MinTrack.x;
-      if (nHeight < MinTrack.y )
-         nHeight = MinTrack.y;
-      if (nWidth < 0)
-         nWidth = 0;
-      if (nHeight < 0)
-         nHeight = 0;
+      if (MaxSize.x < Size.cx)
+         Size.cx = MaxSize.x;
+      if (MaxSize.y < Size.cy)
+         Size.cy = MaxSize.y;
+      if (Size.cx < MinTrack.x )
+         Size.cx = MinTrack.x;
+      if (Size.cy < MinTrack.y )
+         Size.cy = MinTrack.y;
+      if (Size.cx < 0)
+         Size.cx = 0;
+      if (Size.cy < 0)
+         Size.cy = 0;
    }
 
    Window->WindowRect.left = Pos.x;
@@ -1769,7 +1746,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    Cs.y = Pos.y;
 
    DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
-   DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
+   DPRINT("IntCreateWindowEx(): (%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)
@@ -1837,7 +1814,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    if (Result == (LRESULT)-1)
    {
       /* FIXME: Cleanup. */
-      ClassDereferenceObject(Class);
       DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
       RETURN((HWND)0);
    }
@@ -1921,7 +1897,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    if ((!hWndParent) && (!HasOwner))
    {
       DPRINT("Sending CREATED notify\n");
-      co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Handle);
+      co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
    }
    else
    {
@@ -1944,14 +1920,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       co_WinPosShowWindow(Window, dwShowMode);
    }
 
-   DPRINT("IntCreateWindow(): = %X\n", Handle);
+   DPRINT("IntCreateWindow(): = %X\n", hWnd);
    DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
-   RETURN((HWND)Handle);
+   RETURN(hWnd);
 
 CLEANUP:
    if (Window) UserDerefObjectCo(Window);
    if (ParentWindow) UserDerefObjectCo(ParentWindow);
-
+   if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return 0) */
    END_CLEANUP;
 }
 
@@ -2058,8 +2034,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 
    ASSERT_REFS_CO(Window); //fixme: temp hack?
 
-   /* Check for owner thread and desktop window */
-   if ((Window->OwnerThread != PsGetCurrentThread()) || IntIsDesktopWindow(Window))
+   /* Check for owner thread */
+   if ((Window->OwnerThread != PsGetCurrentThread()))
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return FALSE;
@@ -2127,7 +2103,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
          HWND *ChildHandle;
          PWINDOW_OBJECT Child, Desktop;
 
-         Desktop = UserGetWindowObject(IntGetDesktopWindow());
+         Desktop = IntIsDesktopWindow(Window) ? Window :
+                   UserGetWindowObject(IntGetDesktopWindow());
          Children = IntWinListChildren(Desktop);
 
          if (Children)
@@ -2144,8 +2121,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 
                if (IntWndBelongsToThread(Child, PsGetWin32Thread()))
                {
-
-                  UserRefObjectCo(Child);//temp hack?
+                  USER_REFERENCE_ENTRY ChildRef;
+                  UserRefObjectCo(Child, &ChildRef);//temp hack?
                   co_UserDestroyWindow(Child);
                   UserDerefObjectCo(Child);//temp hack?
 
@@ -2174,7 +2151,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
    }
 
    /* Destroy the window storage */
-   co_IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
+   co_UserFreeWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
 
    return TRUE;
 }
@@ -2191,6 +2168,7 @@ NtUserDestroyWindow(HWND Wnd)
    PWINDOW_OBJECT Window;
    DECLARE_RETURN(BOOLEAN);
    BOOLEAN ret;
+   USER_REFERENCE_ENTRY Ref;
 
    DPRINT("Enter NtUserDestroyWindow\n");
    UserEnterExclusive();
@@ -2200,7 +2178,7 @@ NtUserDestroyWindow(HWND Wnd)
       RETURN(FALSE);
    }
 
-   UserRefObjectCo(Window);//faxme: dunno if win should be reffed during destroy..
+   UserRefObjectCo(Window, &Ref);//faxme: dunno if win should be reffed during destroy..
    ret = co_UserDestroyWindow(Window);
    UserDerefObjectCo(Window);//faxme: dunno if win should be reffed during destroy..
 
@@ -2296,7 +2274,7 @@ 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->WindowName), FALSE)) &&
+         if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), TRUE)) &&
                (!ClassAtom || Child->Class->Atom == ClassAtom))
          {
             Ret = Child->hSelf;
@@ -2475,7 +2453,7 @@ NtUserFindWindowEx(HWND hwndParent,
                The user mode version however calls GetWindowText() which will
                send WM_GETTEXT messages to windows belonging to its processes */
             WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
-                               &WindowName, &TopLevelWindow->WindowName, FALSE);
+                               &WindowName, &TopLevelWindow->WindowName, TRUE);
             ClassMatches = !CheckClassName ||
                            ClassAtom == TopLevelWindow->Class->Atom;
 
@@ -2804,6 +2782,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
 {
    PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
    HWND hWndOldParent = NULL;
+   USER_REFERENCE_ENTRY Ref, ParentRef;
 
    if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
    {
@@ -2837,8 +2816,8 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
       return( NULL);
    }
 
-   UserRefObjectCo(Wnd);
-   UserRefObjectCo(WndParent);
+   UserRefObjectCo(Wnd, &Ref);
+   UserRefObjectCo(WndParent, &ParentRef);
    
    WndOldParent = co_IntSetParent(Wnd, WndParent);
    
@@ -2956,6 +2935,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
    PWINSTATION_OBJECT WinStaObject;
    PWINDOW_OBJECT WndShell;
    DECLARE_RETURN(BOOL);
+   USER_REFERENCE_ENTRY Ref;
 
    DPRINT("Enter NtUserSetShellWindowEx\n");
    UserEnterExclusive();
@@ -3011,7 +2991,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
       RETURN( FALSE);
    }
 
-   UserRefObjectCo(WndShell);
+   UserRefObjectCo(WndShell, &Ref);
    co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
 
    WinStaObject->ShellWindow = hwndShell;
@@ -3383,7 +3363,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             /*
              * Remove extended window style bit WS_EX_TOPMOST for shell windows.
              */
-            WindowStation = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
+            WindowStation = ((PW32THREAD)Window->OwnerThread->Tcb.Win32Thread)->Desktop->WindowStation;
             if(WindowStation)
             {
                if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
@@ -3574,7 +3554,23 @@ NtUserGetWindowPlacement(HWND hWnd,
    }
 
    Safepl.flags = 0;
-   Safepl.showCmd = ((Window->Flags & WINDOWOBJECT_RESTOREMAX) ? SW_MAXIMIZE : SW_SHOWNORMAL);
+   if (0 == (Window->Style & WS_VISIBLE))
+   {
+      Safepl.showCmd = SW_HIDE;
+   }
+   else if (0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+            0 != (Window->Style & WS_MAXIMIZE))
+   {
+      Safepl.showCmd = SW_MAXIMIZE;
+   }
+   else if (0 != (Window->Style & WS_MINIMIZE))
+   {
+      Safepl.showCmd = SW_MINIMIZE;
+   }
+   else if (0 != (Window->Style & WS_MINIMIZE))
+   {
+      Safepl.showCmd = SW_SHOWNORMAL;
+   }
 
    Size.x = Window->WindowRect.left;
    Size.y = Window->WindowRect.top;
@@ -3902,7 +3898,9 @@ NtUserSetMenu(
 
    if (Changed && Repaint)
    {
-      UserRefObjectCo(Window);
+      USER_REFERENCE_ENTRY Ref;
+
+      UserRefObjectCo(Window, &Ref);
       co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
                             SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
 
@@ -3943,6 +3941,7 @@ NtUserSetWindowPlacement(HWND hWnd,
    WINDOWPLACEMENT Safepl;
    NTSTATUS Status;
    DECLARE_RETURN(BOOL);
+   USER_REFERENCE_ENTRY Ref;
 
    DPRINT("Enter NtUserSetWindowPlacement\n");
    UserEnterExclusive();
@@ -3962,7 +3961,7 @@ NtUserSetWindowPlacement(HWND hWnd,
       RETURN( FALSE);
    }
 
-   UserRefObjectCo(Window);
+   UserRefObjectCo(Window, &Ref);
 
    if ((Window->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
    {
@@ -4008,6 +4007,7 @@ NtUserSetWindowPos(
    DECLARE_RETURN(BOOL);
    PWINDOW_OBJECT Window;
    BOOL ret;
+   USER_REFERENCE_ENTRY Ref;
 
    DPRINT("Enter NtUserSetWindowPos\n");
    UserEnterExclusive();
@@ -4017,7 +4017,7 @@ NtUserSetWindowPos(
       RETURN(FALSE);
    }
 
-   UserRefObjectCo(Window);
+   UserRefObjectCo(Window, &Ref);
    ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags);
    UserDerefObjectCo(Window);
 
@@ -4140,7 +4140,8 @@ NtUserSetWindowRgn(
 
    if(bRedraw)
    {
-      UserRefObjectCo(Window);
+      USER_REFERENCE_ENTRY Ref;
+      UserRefObjectCo(Window, &Ref);
       co_UserRedrawWindow(Window, NULL, NULL, RDW_INVALIDATE);
       UserDerefObjectCo(Window);
    }
@@ -4163,6 +4164,7 @@ NtUserShowWindow(HWND hWnd, LONG nCmdShow)
    PWINDOW_OBJECT Window;
    BOOL ret;
    DECLARE_RETURN(BOOL);
+   USER_REFERENCE_ENTRY Ref;
 
    DPRINT("Enter NtUserShowWindow\n");
    UserEnterExclusive();
@@ -4172,7 +4174,7 @@ NtUserShowWindow(HWND hWnd, LONG nCmdShow)
       RETURN(FALSE);
    }
 
-   UserRefObjectCo(Window);
+   UserRefObjectCo(Window, &Ref);
    ret = co_WinPosShowWindow(Window, nCmdShow);
    UserDerefObjectCo(Window);
 
@@ -4188,13 +4190,15 @@ CLEANUP:
 /*
  * @unimplemented
  */
-DWORD STDCALL
-NtUserShowWindowAsync(DWORD Unknown0,
-                      DWORD Unknown1)
+BOOL STDCALL
+NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
 {
+#if 0
    UNIMPLEMENTED
-
    return 0;
+#else
+   return NtUserShowWindow(hWnd, nCmdShow);
+#endif
 }
 
 
@@ -4218,14 +4222,6 @@ NtUserUpdateLayeredWindow(DWORD Unknown0,
 }
 
 
-/*
- * @implemented
- */
-VOID STDCALL
-NtUserValidateRect(HWND hWnd, const RECT* Rect)
-{
-   return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
-}
 
 
 /*
@@ -4238,6 +4234,7 @@ NtUserWindowFromPoint(LONG X, LONG Y)
    HWND Ret;
    PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
    DECLARE_RETURN(HWND);
+   USER_REFERENCE_ENTRY Ref;
 
    DPRINT("Enter NtUserWindowFromPoint\n");
    UserEnterExclusive();
@@ -4251,7 +4248,7 @@ NtUserWindowFromPoint(LONG X, LONG Y)
 
       //hmm... threads live on desktops thus we have a reference on the desktop and indirectly the desktop window
       //its possible this referencing is useless, thou it shouldnt hurt...
-      UserRefObjectCo(DesktopWindow);
+      UserRefObjectCo(DesktopWindow, &Ref);
       
       Hit = co_WinPosWindowFromPoint(DesktopWindow, PsGetWin32Thread()->MessageQueue, &pt, &Window);