1. get rid of winlock.c
authorThomas Bluemel <thomas@reactsoft.com>
Tue, 24 Feb 2004 01:30:58 +0000 (01:30 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Tue, 24 Feb 2004 01:30:58 +0000 (01:30 +0000)
2. changed the Parent and Object field of the WINDOW_OBJECT structure to HANDLE for easier maintainance and serialize any access to them

svn path=/trunk/; revision=8346

13 files changed:
reactos/subsys/win32k/include/window.h
reactos/subsys/win32k/main/dllmain.c
reactos/subsys/win32k/makefile
reactos/subsys/win32k/misc/object.c
reactos/subsys/win32k/ntuser/focus.c
reactos/subsys/win32k/ntuser/message.c
reactos/subsys/win32k/ntuser/msgqueue.c
reactos/subsys/win32k/ntuser/painting.c
reactos/subsys/win32k/ntuser/vis.c
reactos/subsys/win32k/ntuser/windc.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/ntuser/winlock.c [deleted file]
reactos/subsys/win32k/ntuser/winpos.c

index bcc22d2..09d3a85 100644 (file)
@@ -7,6 +7,7 @@ typedef struct _WINDOW_OBJECT *PWINDOW_OBJECT;
 
 #include <windows.h>
 #include <ddk/ntddk.h>
+#include <include/object.h>
 #include <include/class.h>
 #include <include/msgqueue.h>
 #include <include/winsta.h>
@@ -63,18 +64,18 @@ typedef struct _WINDOW_OBJECT
   FAST_MUTEX UpdateLock;
   /* Pointer to the owning thread's message queue. */
   PUSER_MESSAGE_QUEUE MessageQueue;
+  /* Lock for the list of child windows. */
+  FAST_MUTEX RelativesLock;
   struct _WINDOW_OBJECT* FirstChild;
   struct _WINDOW_OBJECT* LastChild;
-  /* Lock for the list of child windows. */
-  FAST_MUTEX ChildrenListLock;
   struct _WINDOW_OBJECT* NextSibling;
   struct _WINDOW_OBJECT* PrevSibling;
   /* Entry in the list of thread windows. */
   LIST_ENTRY ThreadListEntry;
   /* Pointer to the parent window. */
-  struct _WINDOW_OBJECT* Parent;
+  HANDLE Parent;
   /* Pointer to the owner window. */
-  struct _WINDOW_OBJECT* Owner;
+  HANDLE Owner;
   /* DC Entries (DCE) */
   PDCE Dce;
   /* Property list head.*/
@@ -101,9 +102,40 @@ typedef struct _WINDOW_OBJECT
 #define WINDOWOBJECT_NEED_INTERNALPAINT   (0x00000008)
 #define WINDOWOBJECT_RESTOREMAX           (0x00000020)
 
-inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT WindowObject);
+#define IntIsDesktopWindow(WndObj) \
+  (WndObj->Parent == NULL)
+
+#define IntIsBroadcastHwnd(hWnd) \
+  (hWnd == HWND_BROADCAST || hWnd == HWND_TOPMOST)
+
+#define IntGetWindowObject(hWnd) \
+  IntGetProcessWindowObject(PsGetWin32Process(), hWnd)
+
+#define IntReferenceWindowObject(WndObj) \
+  ObmReferenceObjectByPointer(WndObj, otWindow)
+
+#define IntReleaseWindowObject(WndObj) \
+  ObmDereferenceObject(WndObj)
+
+#define IntWndBelongsToThread(WndObj, W32Thread) \
+  (((WndObj->OwnerThread && WndObj->OwnerThread->Win32Thread)) && \
+   (WndObj->OwnerThread->Win32Thread == W32Thread))
+
+#define IntGetWndThreadId(WndObj) \
+  WndObj->OwnerThread->Cid.UniqueThread
+
+#define IntGetWndProcessId(WndObj) \
+  WndObj->OwnerThread->ThreadsProcess->UniqueProcessId
+
+#define IntLockRelatives(WndObj) \
+  ExAcquireFastMutexUnsafe(&WndObj->RelativesLock)
+
+#define IntUnLockRelatives(WndObj) \
+  ExReleaseFastMutexUnsafe(&WndObj->RelativesLock)
 
-inline BOOL IntIsBroadcastHwnd(HWND hwnd);
+
+PWINDOW_OBJECT FASTCALL
+IntGetProcessWindowObject(PW32PROCESS ProcessData, HWND hWnd);
 
 BOOL FASTCALL
 IntIsWindow(HWND hWnd);
@@ -111,9 +143,6 @@ IntIsWindow(HWND hWnd);
 HWND* FASTCALL
 IntWinListChildren(PWINDOW_OBJECT Window);
 
-BOOLEAN FASTCALL
-IntWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData);
-
 NTSTATUS FASTCALL
 InitWindowImpl (VOID);
 
@@ -123,17 +152,11 @@ CleanupWindowImpl (VOID);
 VOID FASTCALL
 IntGetClientRect (PWINDOW_OBJECT WindowObject, PRECT Rect);
 
-PWINDOW_OBJECT FASTCALL
-IntGetWindowObject (HWND hWnd);
-
-VOID FASTCALL
-IntReleaseWindowObject (PWINDOW_OBJECT Window);
-
 HWND FASTCALL
 IntGetActiveWindow (VOID);
 
 BOOL FASTCALL
-IntIsWindowVisible (HWND Wnd);
+IntIsWindowVisible (HWND hWnd);
 
 BOOL FASTCALL
 IntIsChildWindow (HWND Parent, HWND Child);
@@ -144,9 +167,6 @@ IntSetProp(PWINDOW_OBJECT Wnd, ATOM Atom, HANDLE Data);
 PPROPERTY FASTCALL
 IntGetProp(PWINDOW_OBJECT WindowObject, ATOM Atom);
 
-DWORD FASTCALL
-IntGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid);
-
 VOID FASTCALL
 IntUnlinkWindow(PWINDOW_OBJECT Wnd);
 
@@ -159,24 +179,9 @@ IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type);
 PWINDOW_OBJECT FASTCALL
 IntGetParent(PWINDOW_OBJECT Wnd);
 
-typedef enum _WINLOCK_TYPE
-{
-  None,
-  Any,
-  Shared,
-  Exclusive
-} WINLOCK_TYPE; 
-
-#define ASSERT_WINLOCK(a) assert(IntVerifyWinLock(a))
-
-inline VOID IntAcquireWinLockShared();
-inline VOID IntAcquireWinLockExclusive();
-inline VOID IntReleaseWinLock();
-BOOL FASTCALL IntVerifyWinLock(WINLOCK_TYPE Type);
-WINLOCK_TYPE FASTCALL IntSuspendWinLock();
-VOID FASTCALL IntRestoreWinLock(WINLOCK_TYPE Type);
-inline BOOL IntInitializeWinLock();
-inline VOID IntDeleteWinLock();
+PWINDOW_OBJECT FASTCALL
+IntGetParentObject(PWINDOW_OBJECT Wnd);
+
 DWORD IntRemoveWndProcHandle(WNDPROC Handle);
 DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID);
 DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode);
index 95ab484..13d37e6 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dllmain.c,v 1.66 2004/02/05 20:09:10 gvg Exp $
+/* $Id: dllmain.c,v 1.67 2004/02/24 01:30:57 weiden Exp $
  *
  *  Entry Point for win32k.sys
  */
@@ -194,8 +194,6 @@ DllMain (
   NTSTATUS Status;
   BOOLEAN Result;
 
-  IntInitializeWinLock();
-
   /*
    * Register user mode call interface
    * (system service table index = 1)
index a99cbc0..1a52e0e 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.93 2004/02/19 06:59:50 arty Exp $
+# $Id: makefile,v 1.94 2004/02/24 01:30:57 weiden Exp $
 
 PATH_TO_TOP = ../..
 
@@ -56,8 +56,7 @@ NTUSER_OBJECTS = ntuser/accelerator.o ntuser/callback.o ntuser/caret.o ntuser/cl
                  ntuser/menu.o ntuser/message.o ntuser/metric.o ntuser/misc.o \
                  ntuser/msgqueue.o ntuser/painting.o ntuser/prop.o ntuser/scrollbar.o \
                  ntuser/stubs.o ntuser/timer.o ntuser/useratom.o ntuser/vis.o \
-                 ntuser/windc.o ntuser/window.o ntuser/winlock.o ntuser/winpos.o \
-                 ntuser/winsta.o
+                 ntuser/windc.o ntuser/window.o ntuser/winpos.o ntuser/winsta.o
 
 OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o  \
                   objects/color.o objects/coord.o objects/dc.o  \
index 95b36e9..35b093a 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: object.c,v 1.8 2003/12/17 19:56:13 weiden Exp $
+/* $Id: object.c,v 1.9 2004/02/24 01:30:57 weiden Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
@@ -31,6 +31,7 @@
 
 #include <ddk/ntddk.h>
 #include <include/object.h>
+#include <include/window.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -113,7 +114,7 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
       Current = Current->Flink;
       if (Current == &(HandleTable->ListHead))
        {
-          DPRINT1("Invalid handle 0x%x\n", Handle);
+      DPRINT1("Invalid handle 0x%x\n", Handle);
          return NULL;
        }
     }
@@ -275,6 +276,7 @@ ObmReferenceObject(PVOID ObjectBody)
   
   if (!ObjectBody)
     {
+      DPRINT1("Cannot Reference NULL!\n");
       return;
     }
   
@@ -298,13 +300,17 @@ ObmDereferenceObject(PVOID ObjectBody)
   
   if (!ObjectBody)
     {
+      DPRINT1("Cannot Dereference NULL!\n");
       return;
     }
   
   ObjectHeader = BODY_TO_HEADER(ObjectBody);
   
   ObjectHeader->RefCount--;
-
+  #if 0
+  if(ObjectHeader->Type == otWindow)
+    DbgPrint("Dereference 0x%x: %d\n", ((PWINDOW_OBJECT)ObjectBody)->Self, ObjectHeader->RefCount);
+  #endif
   ObmpPerformRetentionChecks(ObjectHeader);
 }
 
@@ -327,7 +333,10 @@ ObmReferenceObjectByPointer(PVOID ObjectBody,
     {
       return STATUS_INVALID_PARAMETER;
     }
-  
+  #if 0
+  if(ObjectType == otWindow)
+    DbgPrint("Reference 0x%x: %d\n", ((PWINDOW_OBJECT)ObjectBody)->Self, ObjectHeader->RefCount);
+  #endif
   ObjectHeader->RefCount++;
   
   return STATUS_SUCCESS;
index 0a933f1..2efd284 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: focus.c,v 1.17 2004/02/23 12:39:37 gvg Exp $
+ * $Id: focus.c,v 1.18 2004/02/24 01:30:57 weiden Exp $
  */
 
 #include <win32k/win32k.h>
+#include <include/object.h>
 #include <include/window.h>
 #include <include/desktop.h>
 #include <include/focus.h>
@@ -112,20 +113,28 @@ HWND FASTCALL
 IntFindChildWindowToOwner(PWINDOW_OBJECT Root, PWINDOW_OBJECT Owner)
 {
   HWND Ret;
-  PWINDOW_OBJECT Child;
-  ExAcquireFastMutexUnsafe(&Root->ChildrenListLock);
+  PWINDOW_OBJECT Child, OwnerWnd;
+  IntLockRelatives(Root);
   
   for(Child = Root->FirstChild; Child; Child = Child->NextSibling)
   {
-    if(Child->Owner == Owner)
+    IntLockRelatives(Child);
+    OwnerWnd = IntGetWindowObject(Child->Owner);
+    IntUnLockRelatives(Child);
+    if(!OwnerWnd)
+      continue;
+    
+    if(OwnerWnd == Owner)
     {
+      IntUnLockRelatives(Root);
       Ret = Child->Self;
-      ExReleaseFastMutexUnsafe(&Root->ChildrenListLock);
+      IntReleaseWindowObject(OwnerWnd);
       return Ret;
     }
+    IntReleaseWindowObject(OwnerWnd);
   }
   
-  ExReleaseFastMutexUnsafe(&Root->ChildrenListLock);
+  IntUnLockRelatives(Root);
   return NULL;
 }
 
@@ -186,7 +195,7 @@ IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWindow
    }
    IntSendSetFocusMessages(hWndFocusPrev, hWndFocus);
    IntSendActivateMessages(hWndPrev, hWnd, MouseActivate);
-
+   
    return TRUE;
 }
 
@@ -210,8 +219,7 @@ IntMouseActivateWindow(PWINDOW_OBJECT Window)
     if(DesktopWindow)
     {
       Top = IntFindChildWindowToOwner(DesktopWindow, Window);
-      TopWnd = IntGetWindowObject(Top);
-      if(TopWnd)
+      if((TopWnd = IntGetWindowObject(Top)))
       {
         Ret = IntMouseActivateWindow(TopWnd);
         IntReleaseWindowObject(TopWnd);
@@ -283,9 +291,8 @@ IntSetActiveWindow(PWINDOW_OBJECT Window)
 }
 
 HWND FASTCALL
-IntSetFocusWindow(PWINDOW_OBJECT Window)
+IntSetFocusWindow(HWND hWnd)
 {
-   HWND hWnd = Window != 0 ? Window->Self : 0;
    HWND hWndPrev = 0;
    PUSER_MESSAGE_QUEUE ThreadQueue;
 
@@ -453,14 +460,14 @@ NtUserSetFocus(HWND hWnd)
          NtUserSetActiveWindow(hWndTop);
       }
 
-      hWndPrev = IntSetFocusWindow(Window);
+      hWndPrev = IntSetFocusWindow(hWnd);
       IntReleaseWindowObject(Window);
 
       return hWndPrev;
    }
    else
    {
-      return IntSetFocusWindow(0);
+      return IntSetFocusWindow(NULL);
    }
 }
 
index 8d518c8..de41ee9 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: message.c,v 1.50 2004/02/19 21:12:09 weiden Exp $
+/* $Id: message.c,v 1.51 2004/02/24 01:30:57 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -776,13 +776,11 @@ IntSendMessage(HWND hWnd,
       IntReleaseWindowObject(Window);
       return Result;
     }
-  else
-    {
-      Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam);
+  
+  Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam);
 
-      IntReleaseWindowObject(Window);
-      return Result;
-    }
+  IntReleaseWindowObject(Window);
+  return Result;
 }
 
 static NTSTATUS FASTCALL
index 2a3483d..d83d272 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: msgqueue.c,v 1.69 2004/02/23 20:08:35 gvg Exp $
+/* $Id: msgqueue.c,v 1.70 2004/02/24 01:30:57 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -258,11 +258,13 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
     /*
     **Make sure that we have a window that is not already in focus
     */
-    if (0 != Window && Window->Self != IntGetFocusWindow())
+    if (Window)
     {
+      if(Window->Self != IntGetFocusWindow())
+      {
         SpareLParam = MAKELONG(Hit, Msg);
         
-        if(Window && (Hit != (USHORT)HTTRANSPARENT))
+        if(Hit != (USHORT)HTTRANSPARENT)
         {
           Result = IntSendMessage(Window->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(Window->Self), (LPARAM)SpareLParam);
           
@@ -285,16 +287,16 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
                   IntMouseActivateWindow(Window);
                   break;
           }
-          IntReleaseWindowObject(Window);
         }
         else
         {
-          if(Window)
-            IntReleaseWindowObject(Window);
+          IntReleaseWindowObject(Window);
           ExFreePool(Message);
           *Freed = TRUE;
           return(FALSE);
         }
+      }
+      IntReleaseWindowObject(Window);
     }
 
   }
@@ -577,6 +579,7 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
            }
        }
     }
+  IntReleaseWindowObject(DesktopWindow);
   /* Check if the system message queue is now empty. */
   KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql);
   if (SystemMessageQueueCount == 0 && IsListEmpty(&HardwareMessageQueueHead))
index cf5067c..0111b82 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *  $Id: painting.c,v 1.72 2004/02/22 16:56:14 navaraf Exp $
+ *  $Id: painting.c,v 1.73 2004/02/24 01:30:57 weiden Exp $
  *
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel
 VOID FASTCALL
 IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
 {
-   HWND Parent;
-   PWINDOW_OBJECT ParentWindow;
+   PWINDOW_OBJECT ParentWindow = IntGetParentObject(Child), OldWindow;
 
-   Parent = NtUserGetAncestor(Child->Self, GA_PARENT);
-   while (Parent)
+   while (ParentWindow)
    {
-      ParentWindow = IntGetWindowObject(Parent);
-      if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN))
+      if (!(ParentWindow->Style & WS_CLIPCHILDREN))
       {
          ExAcquireFastMutex(&ParentWindow->UpdateLock);
          if (ParentWindow->UpdateRegion != 0)
@@ -87,15 +84,9 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
          }
          ExReleaseFastMutex(&ParentWindow->UpdateLock);
       }
-      if (ParentWindow)
-      {
-         IntReleaseWindowObject(ParentWindow);
-         Parent = NtUserGetAncestor(Parent, GA_PARENT);
-      }
-      else
-      {
-         return;
-      }
+      OldWindow = ParentWindow;
+      ParentWindow = IntGetParentObject(ParentWindow);
+      IntReleaseWindowObject(OldWindow);
    }
 }
 
@@ -422,14 +413,21 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
 BOOL FASTCALL
 IntIsWindowDrawable(PWINDOW_OBJECT Window)
 {
-   PWINDOW_OBJECT Wnd = Window;
+   PWINDOW_OBJECT Old, Wnd = Window;
    
-   for (; Wnd; Wnd = Wnd->Parent)
+   IntReferenceWindowObject(Wnd);
+   do
    {
       if (!(Wnd->Style & WS_VISIBLE) ||
           ((Wnd->Style & WS_MINIMIZE) && (Wnd != Window)))
+      {
+         IntReleaseWindowObject(Wnd);
          return FALSE;
-   }
+      }
+      Old = Wnd;
+      Wnd = IntGetParentObject(Wnd);
+      IntReleaseWindowObject(Old);
+   } while(Wnd);
 
    return TRUE;
 }
@@ -559,7 +557,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
       return hWnd;
    }
 
-   ExAcquireFastMutex(&Window->ChildrenListLock);
+   IntLockRelatives(Window);
    for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
    {
       if (IntIsWindowDirty(Child) &&
@@ -569,7 +567,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
          break;
       }
    }
-   ExReleaseFastMutex(&Window->ChildrenListLock);
+   IntUnLockRelatives(Window);
 
    if (hFoundWnd == NULL)
    {
index c5e600a..9335da8 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: vis.c,v 1.19 2004/02/22 16:56:14 navaraf Exp $
+ * $Id: vis.c,v 1.20 2004/02/24 01:30:57 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -70,7 +70,7 @@ VIS_ComputeVisibleRegion(
     */
 
    PreviousWindow = Window;
-   CurrentWindow = Window->Parent;
+   CurrentWindow = IntGetParentObject(Window);
    while (CurrentWindow)
    {
       if (!(CurrentWindow->Style & WS_VISIBLE))
@@ -85,7 +85,7 @@ VIS_ComputeVisibleRegion(
       if ((CurrentWindow->Style & WS_CLIPSIBLINGS) ||
           (PreviousWindow == Window && ClipSiblings))
       {
-         ExAcquireFastMutexUnsafe(&CurrentWindow->ChildrenListLock);
+         IntLockRelatives(CurrentWindow);
          CurrentSibling = CurrentWindow->FirstChild;
          while (CurrentSibling != PreviousWindow)
          {
@@ -97,16 +97,17 @@ VIS_ComputeVisibleRegion(
             }
             CurrentSibling = CurrentSibling->NextSibling;
          }
-         ExReleaseFastMutexUnsafe(&CurrentWindow->ChildrenListLock);
+         IntUnLockRelatives(CurrentWindow);
       }
 
       PreviousWindow = CurrentWindow;
-      CurrentWindow = CurrentWindow->Parent;
+      CurrentWindow = IntGetParentObject(CurrentWindow);
+      IntReleaseWindowObject(PreviousWindow);
    }
 
    if (ClipChildren)
    {
-      ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
+      IntLockRelatives(Window);
       CurrentWindow = Window->FirstChild;
       while (CurrentWindow)
       {
@@ -118,7 +119,7 @@ VIS_ComputeVisibleRegion(
          }
          CurrentWindow = CurrentWindow->NextSibling;
       }
-      ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
+      IntUnLockRelatives(Window);
    }
 
    NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
@@ -132,18 +133,23 @@ VIS_WindowLayoutChanged(
    HRGN NewlyExposed)
 {
    HRGN Temp;
+   PWINDOW_OBJECT Parent;
    
    Temp = NtGdiCreateRectRgn(0, 0, 0, 0);
    NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY);
-   if (Window->Parent != NULL)
+   
+   Parent = IntGetParentObject(Window);
+   if(Parent)
    {
       NtGdiOffsetRgn(Temp,
-                     Window->WindowRect.left - Window->Parent->ClientRect.left,
-                     Window->WindowRect.top - Window->Parent->ClientRect.top);
+                     Window->WindowRect.left - Parent->ClientRect.left,
+                     Window->WindowRect.top - Parent->ClientRect.top);
    }
-   IntRedrawWindow(Window->Parent, NULL, Temp,
+   IntRedrawWindow(Parent, NULL, Temp,
                    RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | 
                    RDW_ALLCHILDREN);
+   if(Parent)
+     IntReleaseWindowObject(Parent);
    NtGdiDeleteObject(Temp);
 }
 
index 3b37cc1..684f997 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: windc.c,v 1.58 2004/02/22 12:25:35 navaraf Exp $
+/* $Id: windc.c,v 1.59 2004/02/24 01:30:57 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -238,7 +238,13 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
    {
       PWINDOW_OBJECT Parent;
 
-      Parent = Window->Parent;
+      Parent = IntGetParentObject(Window);
+      if(!Parent)
+      {
+        hRgnVisible = NULL;
+        goto noparent;
+      }
+      
       if (Parent->Style & WS_CLIPSIBLINGS)
       {
          DcxFlags = DCX_CLIPSIBLINGS | 
@@ -289,6 +295,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
       hRgnVisible = DceGetVisRgn(Window->Self, Flags, 0, 0);
    }
 
+noparent:
    if (Flags & DCX_INTERSECTRGN)
    {
       NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);
@@ -311,7 +318,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
 HDC STDCALL
 NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
 {
-  PWINDOW_OBJECT Window;
+  PWINDOW_OBJECT Window, Parent;
   ULONG DcxFlags;
   DCE* Dce;
   BOOL UpdateVisRgn = TRUE;
@@ -372,7 +379,9 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
       Flags = (Flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
     }
 
-  if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Window->Parent)
+  Parent = (Window ? IntGetParentObject(Window) : NULL);
+  
+  if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Parent)
     {
       Flags &= ~DCX_PARENTCLIP;
     }
@@ -380,16 +389,19 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
     {
       Flags |= DCX_CACHE;
       if ((Window->Style & WS_VISIBLE) &&
-          (Window->Parent->Style & WS_VISIBLE))
+          (Parent->Style & WS_VISIBLE))
         {
           Flags &= ~DCX_CLIPCHILDREN;
-          if (Window->Parent->Style & WS_CLIPSIBLINGS)
+          if (Parent->Style & WS_CLIPSIBLINGS)
             {
               Flags |= DCX_CLIPSIBLINGS;
             }
         }
     }
 
+  if(Parent)
+    IntReleaseWindowObject(Parent);
+  
   DcxFlags = Flags & DCX_CACHECOMPAREMASK;
 
   if (Flags & DCX_CACHE)
index 5f58d6e..2a38cc6 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: window.c,v 1.190 2004/02/22 23:40:58 gvg Exp $
+/* $Id: window.c,v 1.191 2004/02/24 01:30:57 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -97,36 +97,6 @@ CleanupWindowImpl(VOID)
 
 /* HELPER FUNCTIONS ***********************************************************/
 
-/*
- * IntIsBroadcastHwnd
- *
- * Check if window is a broadcast.
- *
- * Return Value
- *    TRUE if window is broadcast, FALSE otherwise.
- */
-
-inline BOOL
-IntIsBroadcastHwnd(HWND hWnd)
-{
-   return (hWnd == HWND_BROADCAST || hWnd == HWND_TOPMOST);
-}
-
-/*
- * IntIsDesktopWindow
- *
- * Check if window is a desktop. Desktop windows has no parent.
- *
- * Return Value
- *    TRUE if window is desktop, FALSE otherwise.
- */
-
-inline BOOL
-IntIsDesktopWindow(PWINDOW_OBJECT Wnd)
-{
-   return Wnd->Parent == NULL;
-}
-
 /*
  * IntIsWindow
  *
@@ -150,9 +120,8 @@ IntIsWindow(HWND hWnd)
 
    if (!(Window = IntGetWindowObject(hWnd)))
       return FALSE;
-   else
-      IntReleaseWindowObject(Window);
-
+   
+   IntReleaseWindowObject(Window);
    return TRUE;
 }
 
@@ -177,29 +146,40 @@ IntGetProcessWindowObject(PW32PROCESS ProcessData, HWND hWnd)
    return WindowObject;
 }
 
-/*
- * IntGetWindowObject
- *
- * Get window object from handle of current process.
- */
 
 PWINDOW_OBJECT FASTCALL
-IntGetWindowObject(HWND hWnd)
+IntGetParent(PWINDOW_OBJECT Wnd)
 {
-   return IntGetProcessWindowObject(PsGetWin32Process(), hWnd);
+  HWND hWnd;
+  
+  if (Wnd->Style & WS_POPUP)
+  {
+    IntLockRelatives(Wnd);
+    hWnd = Wnd->Owner;
+    IntUnLockRelatives(Wnd);
+    return IntGetWindowObject(hWnd);
+  }
+  else if (Wnd->Style & WS_CHILD) 
+  {
+    IntLockRelatives(Wnd);
+    hWnd = Wnd->Parent;
+    IntUnLockRelatives(Wnd);
+    return IntGetWindowObject(hWnd);
+  }
+
+  return NULL;
 }
 
-/*
- * IntReleaseWindowObject
- *
- * Release window object returned by IntGetWindowObject or
- * IntGetProcessWindowObject.
- */
 
-VOID FASTCALL
-IntReleaseWindowObject(PWINDOW_OBJECT Window)
+PWINDOW_OBJECT FASTCALL
+IntGetParentObject(PWINDOW_OBJECT Wnd)
 {
-   ObmDereferenceObject(Window);
+  HWND hParent;
+  
+  IntLockRelatives(Wnd);
+  hParent = Wnd->Parent;
+  IntUnLockRelatives(Wnd);
+  return IntGetWindowObject(hParent);
 }
 
 /*
@@ -219,7 +199,7 @@ IntWinListChildren(PWINDOW_OBJECT Window)
    HWND *List;
    UINT Index, NumChildren = 0;
 
-   ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
+   IntLockRelatives(Window);
 
    for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
       ++NumChildren;
@@ -227,21 +207,20 @@ IntWinListChildren(PWINDOW_OBJECT Window)
    if (NumChildren != 0)
    {
       List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
-      if (List != NULL)
-      {
-         for (Child = Window->FirstChild, Index = 0;
-              Child != NULL;
-              Child = Child->NextSibling, ++Index)
-            List[Index] = Child->Self;
-         List[Index] = NULL;
-      }
-      else
+      if(!List)
       {
-         DPRINT1("Failed to allocate memory for children array\n");
+        DPRINT1("Failed to allocate memory for children array\n");
+        IntUnLockRelatives(Window);
+        return NULL;
       }
+      for (Child = Window->FirstChild, Index = 0;
+           Child != NULL;
+           Child = Child->NextSibling, ++Index)
+         List[Index] = Child->Self;
+      List[Index] = NULL;
    }
 
-   ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
+   IntUnLockRelatives(Window);
 
    return (NumChildren > 0) ? List : NULL;
 }
@@ -328,8 +307,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
     {
       for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
         {
-          Child = IntGetProcessWindowObject(ProcessData, *ChildHandle);
-          if (NULL != Child)
+          if ((Child = IntGetWindowObject(*ChildHandle)))
             {
               if(IntWndBelongsToThread(Child, ThreadData))
               {
@@ -409,14 +387,8 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
   WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
   CLASS_RemoveWindow(Window->Class);
 #endif
-
-  if (Window->Parent)
-  {
-    PWINDOW_OBJECT Parent = Window->Parent;
-    ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
-    IntUnlinkWindow(Window);
-    ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
-  }
+  
+  IntUnlinkWindow(Window);
 
   ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock);
   RemoveEntryList(&Window->ThreadListEntry);
@@ -545,8 +517,7 @@ IntGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
 
   Rect->left = Rect->top = 0;
   Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
-  Rect->bottom = 
-    WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
+  Rect->bottom = WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
 }
 
 
@@ -569,23 +540,6 @@ IntGetFocusWindow(VOID)
 }
 #endif
 
-PWINDOW_OBJECT FASTCALL
-IntGetParent(PWINDOW_OBJECT Wnd)
-{
-  if (Wnd->Style & WS_POPUP)
-  {
-    return Wnd->Owner;
-  }
-  else if (Wnd->Style & WS_CHILD) 
-  {
-    return Wnd->Parent;
-  }
-
-  return NULL;
-}
-
-
-
 PMENU_OBJECT FASTCALL
 IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
 {
@@ -698,51 +652,54 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
 }
 
 
-
-DWORD FASTCALL
-IntGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid)
-{
-   if (pid) *pid = (DWORD) Wnd->OwnerThread->ThreadsProcess->UniqueProcessId;
-   return (DWORD) Wnd->OwnerThread->Cid.UniqueThread;
-}
-
 BOOL FASTCALL
 IntIsChildWindow(HWND Parent, HWND Child)
 {
   PWINDOW_OBJECT BaseWindow = IntGetWindowObject(Child);
   PWINDOW_OBJECT Window = BaseWindow;
+  
   while (Window != NULL && Window->Style & WS_CHILD)
+  {
+    if (Window->Self == Parent)
     {
-      if (Window->Self == Parent)
-       {
-         IntReleaseWindowObject(BaseWindow);
-         return(TRUE);
-       }
-      Window = Window->Parent;
+      if(Window != BaseWindow)
+        IntReleaseWindowObject(Window);
+      IntReleaseWindowObject(BaseWindow);
+      return(TRUE);
     }
+    if(Window != BaseWindow)
+      IntReleaseWindowObject(Window);
+    Window = IntGetParentObject(Window);
+  }
+  
   IntReleaseWindowObject(BaseWindow);
   return(FALSE);  
 }
 
 BOOL FASTCALL
-IntIsWindowVisible(HWND Wnd)
+IntIsWindowVisible(HWND hWnd)
 {
-  PWINDOW_OBJECT BaseWindow = IntGetWindowObject(Wnd);
+  PWINDOW_OBJECT BaseWindow = IntGetWindowObject(hWnd);
   PWINDOW_OBJECT Window = BaseWindow;
   BOOLEAN Result = FALSE;
+  
   while (Window != NULL && Window->Style & WS_CHILD)
-    {
-      if (!(Window->Style & WS_VISIBLE))
+  {
+    if (!(Window->Style & WS_VISIBLE))
        {
+      if(Window != BaseWindow)
+        IntReleaseWindowObject(Window);
          IntReleaseWindowObject(BaseWindow);
          return(FALSE);
        }
-      Window = Window->Parent;
-    }
+    if(Window != BaseWindow)
+      IntReleaseWindowObject(Window);
+    Window = IntGetParentObject(Window);
+  }
   if (Window != NULL && Window->Style & WS_VISIBLE)
-    {
-      Result = TRUE;
-    }
+  {
+    Result = TRUE;
+  }
   IntReleaseWindowObject(BaseWindow);
   return(Result);
 }
@@ -756,33 +713,64 @@ IntLinkWindow(
   PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
   )
 {
-  Wnd->Parent = WndParent;
-
+  PWINDOW_OBJECT Parent;
+  
+  IntLockRelatives(Wnd);
+  Wnd->Parent = WndParent->Self;
   if ((Wnd->PrevSibling = WndPrevSibling))
   {
     /* link after WndPrevSibling */
-    if ((Wnd->NextSibling = WndPrevSibling->NextSibling)) Wnd->NextSibling->PrevSibling = Wnd;
-    else if (Wnd->Parent->LastChild == WndPrevSibling) Wnd->Parent->LastChild = Wnd;
+    if ((Wnd->NextSibling = WndPrevSibling->NextSibling))
+      Wnd->NextSibling->PrevSibling = Wnd;
+    else if ((Parent = IntGetWindowObject(Wnd->Parent)))
+    {
+      IntLockRelatives(Parent);
+      if(Parent->LastChild == WndPrevSibling) 
+        Parent->LastChild = Wnd;
+      IntUnLockRelatives(Parent);
+      IntReleaseWindowObject(Parent);
+    }
     Wnd->PrevSibling->NextSibling = Wnd;
   }
   else
   {
     /* link at top */
-    if ((Wnd->NextSibling = WndParent->FirstChild)) Wnd->NextSibling->PrevSibling = Wnd;
-    else Wnd->Parent->LastChild = Wnd;
-    WndParent->FirstChild = Wnd;
+    Parent = IntGetWindowObject(Wnd->Parent);
+    if ((Wnd->NextSibling = WndParent->FirstChild)) 
+      Wnd->NextSibling->PrevSibling = Wnd;
+    else if (Parent)
+    {
+      IntLockRelatives(Parent);
+      Parent->LastChild = Wnd;
+      Parent->FirstChild = Wnd;
+      IntUnLockRelatives(Parent);
+      IntReleaseWindowObject(Parent);
+      IntUnLockRelatives(Wnd);
+      return;
+    }
+    if(Parent)
+    {
+      IntLockRelatives(Parent);
+      Parent->FirstChild = Wnd;
+      IntUnLockRelatives(Parent);
+      IntReleaseWindowObject(Parent);
+    }
   }
-
+  IntUnLockRelatives(Wnd);
 }
 
 HWND FASTCALL
 IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 {
-  PWINDOW_OBJECT Wnd, WndOldOwner;
+  PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner;
   HWND ret;
   
   Wnd = IntGetWindowObject(hWnd);
-  WndOldOwner = Wnd->Owner;
+  if(!Wnd)
+    return NULL;
+  
+  IntLockRelatives(Wnd);
+  WndOldOwner = IntGetWindowObject(Wnd->Owner);
   if (WndOldOwner)
   {
      ret = WndOldOwner->Self;
@@ -792,7 +780,16 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
   {
      ret = 0;
   }
-  Wnd->Owner = IntGetWindowObject(hWndNewOwner);
+  
+  if((WndNewOwner = IntGetWindowObject(hWndNewOwner)))
+  {
+    Wnd->Owner = hWndNewOwner;
+    IntReleaseWindowObject(WndNewOwner);
+  }
+  else
+    Wnd->Owner = NULL;
+  
+  IntUnLockRelatives(Wnd);
   IntReleaseWindowObject(Wnd);
   return ret;
 }
@@ -822,17 +819,13 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
    if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
       return NULL;
 
-   WndOldParent = Wnd->Parent;
-   hWndOldParent = WndOldParent->Self;
+   WndOldParent = IntGetParentObject(Wnd);
+   hWndOldParent = (WndOldParent ? WndOldParent->Self : NULL);
 
    if (WndNewParent != WndOldParent)
    {
-      ExAcquireFastMutexUnsafe(&WndOldParent->ChildrenListLock);      
       IntUnlinkWindow(Wnd);
-      ExReleaseFastMutexUnsafe(&WndOldParent->ChildrenListLock);
-      ExAcquireFastMutexUnsafe(&WndNewParent->ChildrenListLock);      
       IntLinkWindow(Wnd, WndNewParent, NULL /*prev sibling*/);
-      ExReleaseFastMutexUnsafe(&WndNewParent->ChildrenListLock);
 
       if (WndNewParent->Self != IntGetDesktopWindow()) /* a child window */
       {
@@ -843,7 +836,9 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
          }
       }
    }
-
+   
+   if(WndOldParent)
+     IntReleaseWindowObject(WndOldParent);
    /*
     * SetParent additionally needs to make hwnd the topmost window
     * in the x-order and send the expected WM_WINDOWPOSCHANGING and
@@ -895,29 +890,29 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
 VOID FASTCALL
 IntUnlinkWindow(PWINDOW_OBJECT Wnd)
 {
-  PWINDOW_OBJECT WndParent = Wnd->Parent; 
+  PWINDOW_OBJECT WndParent;
+  
+  IntLockRelatives(Wnd);
+  if((WndParent = IntGetWindowObject(Wnd->Parent)))
+  {
+    IntLockRelatives(WndParent);
+  }
+  
   if (Wnd->NextSibling) Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
-  else if (WndParent->LastChild == Wnd) WndParent->LastChild = Wnd->PrevSibling;
+  else if (WndParent && WndParent->LastChild == Wnd) WndParent->LastChild = Wnd->PrevSibling;
  
   if (Wnd->PrevSibling) Wnd->PrevSibling->NextSibling = Wnd->NextSibling;
-  else if (WndParent->FirstChild == Wnd) WndParent->FirstChild = Wnd->NextSibling;
+  else if (WndParent && WndParent->FirstChild == Wnd) WndParent->FirstChild = Wnd->NextSibling;
   //else if (parent->first_unlinked == win) parent->first_unlinked = Wnd->NextSibling;
-}
-
-
-BOOLEAN FASTCALL
-IntWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData)
-{
-  if (Window->OwnerThread && Window->OwnerThread->Win32Thread)
+  if(WndParent)
   {
-    return (Window->OwnerThread->Win32Thread == ThreadData);
+    IntUnLockRelatives(WndParent);
+    IntReleaseWindowObject(WndParent);
   }
-
-  return FALSE;
+  Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL;
+  IntUnLockRelatives(Wnd);
 }
 
-
 /* FUNCTIONS *****************************************************************/
 
 /*
@@ -972,7 +967,7 @@ NtUserBuildHwndList(
          return 0;
        }
 
-      ExAcquireFastMutex ( &WindowObject->ChildrenListLock );
+      IntLockRelatives(WindowObject );
       Child = WindowObject->FirstChild;
       while (Child)
        {
@@ -981,7 +976,7 @@ NtUserBuildHwndList(
          dwCount++;
     Child = Child->NextSibling;
        }
-      ExReleaseFastMutex ( &WindowObject->ChildrenListLock );
+      IntUnLockRelatives(WindowObject);
       IntReleaseWindowObject ( WindowObject );
     }
   else if ( dwThreadId )
@@ -1028,7 +1023,7 @@ NtUserBuildHwndList(
                if ( pWnd && dwCount < nBufSize )
                  {
                    pWnd[dwCount] =
-                     (HWND)ObmReferenceObjectByPointer ( ObjectBody, otWindow );
+                     (HWND)IntReferenceWindowObject(ObjectBody);
                  }
                dwCount++;
              }
@@ -1078,13 +1073,15 @@ NtUserBuildHwndList(
 /*
  * @implemented
  */
+ /* FIXME - NEEDS TO BE FIXED - UNSAFE !!! */
 HWND STDCALL
 NtUserChildWindowFromPointEx(HWND hwndParent,
                             LONG x,
                             LONG y,
                             UINT uiFlags)
 {
-    PWINDOW_OBJECT pParent, pCurrent, pLast;
+    PWINDOW_OBJECT pParent, pCurrent, pLast, pPar;
     POINT p = {x,y};
     RECT rc;
     BOOL bFirstRun = TRUE; 
@@ -1094,7 +1091,7 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
         pParent = IntGetWindowObject(hwndParent);
         if(pParent)
         {
-            ExAcquireFastMutexUnsafe (&pParent->ChildrenListLock);
+            IntLockRelatives(pParent);
             
             pLast = IntGetWindowObject(pParent->LastChild->Self);
             pCurrent = IntGetWindowObject(pParent->FirstChild->Self);
@@ -1109,13 +1106,21 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
                 else
                     bFirstRun = FALSE;
                 if(!pCurrent)
+                {
+                    IntUnLockRelatives(pParent);
+                    return (HWND)NULL;
+                }
+                if(!(pPar = IntGetWindowObject(pCurrent->Parent)))
+                {
+                    IntUnLockRelatives(pParent);
                     return (HWND)NULL;
-                
-                rc.left = pCurrent->WindowRect.left - pCurrent->Parent->ClientRect.left;
-                rc.top = pCurrent->WindowRect.top - pCurrent->Parent->ClientRect.top;
+                }
+                rc.left = pCurrent->WindowRect.left - pPar->ClientRect.left;
+                rc.top = pCurrent->WindowRect.top - pPar->ClientRect.top;
                 rc.right = rc.left + (pCurrent->WindowRect.right - pCurrent->WindowRect.left);
                 rc.bottom = rc.top + (pCurrent->WindowRect.bottom - pCurrent->WindowRect.top);
                 DbgPrint("Rect:  %i,%i,%i,%i\n",rc.left, rc.top, rc.right, rc.bottom);
+                IntReleaseWindowObject(pPar);
                 if (POINT_IN_RECT(p,rc)) /* Found a match */
                 {
                     if ( (uiFlags & CWP_SKIPDISABLED) && (pCurrent->Style & WS_DISABLED) )
@@ -1125,13 +1130,13 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
                     if( (uiFlags & CWP_SKIPINVISIBLE) && !(pCurrent->Style & WS_VISIBLE) )
                         continue;
 
-                    ExReleaseFastMutexUnsafe(&pParent->ChildrenListLock);                  
+                    IntUnLockRelatives(pParent);                  
                     return pCurrent->Self;
                 }
             }
             while(pCurrent != pLast);
             
-            ExReleaseFastMutexUnsafe(&pParent->ChildrenListLock);
+            IntUnLockRelatives(pParent);
             return (HWND)NULL;
         }
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -1163,7 +1168,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   PWINSTATION_OBJECT WinStaObject;
   PWNDCLASS_OBJECT ClassObject;
   PWINDOW_OBJECT WindowObject;
-  PWINDOW_OBJECT ParentWindow;
+  PWINDOW_OBJECT ParentWindow, OwnerWindow;
   HWND ParentWindowHandle;
   HWND OwnerWindowHandle;
   PMENU_OBJECT SystemMenu;
@@ -1306,8 +1311,14 @@ NtUserCreateWindowEx(DWORD dwExStyle,
       IntSetMenu(WindowObject, hMenu, &MenuChanged);
     }
   WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
-  WindowObject->Parent = ParentWindow;
-  WindowObject->Owner = IntGetWindowObject(OwnerWindowHandle);
+  WindowObject->Parent = (ParentWindow ? ParentWindow->Self : NULL);
+  if((OwnerWindow = IntGetWindowObject(OwnerWindowHandle)))
+  {
+    WindowObject->Owner = OwnerWindowHandle;
+    IntReleaseWindowObject(OwnerWindow);
+  }
+  else
+    WindowObject->Owner = NULL;
   WindowObject->UserData = 0;
   if ((((DWORD)ClassObject->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
       && (((DWORD)ClassObject->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000)) 
@@ -1341,7 +1352,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
 
   InitializeListHead(&WindowObject->PropListHead);
   ExInitializeFastMutex(&WindowObject->PropListLock);
-  ExInitializeFastMutex(&WindowObject->ChildrenListLock);
+  ExInitializeFastMutex(&WindowObject->RelativesLock);
   ExInitializeFastMutex(&WindowObject->UpdateLock);
 
   RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
@@ -1389,10 +1400,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   WindowObject->WindowRect.top = y;
   WindowObject->WindowRect.right = x + nWidth;
   WindowObject->WindowRect.bottom = y + nHeight;
-  if (0 != (WindowObject->Style & WS_CHILD))
+  if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow)
     {
-      NtGdiOffsetRect(&(WindowObject->WindowRect), WindowObject->Parent->ClientRect.left,
-                      WindowObject->Parent->ClientRect.top);
+      NtGdiOffsetRect(&(WindowObject->WindowRect), ParentWindow->ClientRect.left,
+                      ParentWindow->ClientRect.top);
     }
   WindowObject->ClientRect = WindowObject->WindowRect;
 
@@ -1442,10 +1453,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   WindowObject->WindowRect.top = y;
   WindowObject->WindowRect.right = x + nWidth;
   WindowObject->WindowRect.bottom = y + nHeight;
-  if (0 != (WindowObject->Style & WS_CHILD))
+  if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow)
     {
-      NtGdiOffsetRect(&(WindowObject->WindowRect), WindowObject->Parent->ClientRect.left,
-                      WindowObject->Parent->ClientRect.top);
+      NtGdiOffsetRect(&(WindowObject->WindowRect), ParentWindow->ClientRect.left,
+                      ParentWindow->ClientRect.top);
     }
   WindowObject->ClientRect = WindowObject->WindowRect;
 
@@ -1499,7 +1510,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   if (NULL != ParentWindow)
     {
       /* link the window into the parent's child list */
-      ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
       if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
         {
           /* link window as bottom sibling */
@@ -1510,7 +1520,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
           /* link window as top sibling */
           IntLinkWindow(WindowObject, ParentWindow, NULL /*prev sibling*/);
         }
-      ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
     }
 
   /* Send the WM_CREATE message. */
@@ -1547,10 +1556,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
 
       DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
 
-      if (0 != (WindowObject->Style & WS_CHILD))
+      if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow)
        {
-         lParam = MAKE_LONG(WindowObject->ClientRect.left - WindowObject->Parent->ClientRect.left,
-             WindowObject->ClientRect.top - WindowObject->Parent->ClientRect.top);
+         lParam = MAKE_LONG(WindowObject->ClientRect.left - ParentWindow->ClientRect.left,
+             WindowObject->ClientRect.top - ParentWindow->ClientRect.top);
        }
       else
        {
@@ -1581,15 +1590,20 @@ NtUserCreateWindowEx(DWORD dwExStyle,
 
   /* Notify the parent window of a new child. */
   if ((WindowObject->Style & WS_CHILD) &&
-      (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
+      (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
     {
       DPRINT("NtUserCreateWindow(): About to notify parent\n");
-      IntSendMessage(WindowObject->Parent->Self,
+      IntSendMessage(ParentWindow->Self,
                      WM_PARENTNOTIFY, 
                      MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
                      (LPARAM)WindowObject->Self);
     }
 
+  if (NULL != ParentWindow)
+    {
+      IntReleaseWindowObject(ParentWindow);
+    }
+
   if (dwStyle & WS_VISIBLE)
     {
       DPRINT("NtUserCreateWindow(): About to show window\n");
@@ -1627,7 +1641,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
 BOOLEAN STDCALL
 NtUserDestroyWindow(HWND Wnd)
 {
-  PWINDOW_OBJECT Window, Parent;
+  PWINDOW_OBJECT Window;
   BOOLEAN isChild;
 
   Window = IntGetWindowObject(Wnd);
@@ -1720,7 +1734,7 @@ NtUserDestroyWindow(HWND Wnd)
                    {
                      continue;
                    }
-                 if (Child->Parent != Window)
+                 if (Child->Parent != Window->Self)
                    {
                      IntReleaseWindowObject(Child);
                      continue;
@@ -1734,7 +1748,6 @@ NtUserDestroyWindow(HWND Wnd)
                    }
                  if (Child->Owner != NULL)
                    {
-                     IntReleaseWindowObject(Child->Owner);
                      Child->Owner = NULL;
                    }
                  IntReleaseWindowObject(Child);
@@ -1754,11 +1767,7 @@ NtUserDestroyWindow(HWND Wnd)
     }
 
   /* Unlink now so we won't bother with the children later on */
-  Parent = Window->Parent;
-  ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
   IntUnlinkWindow(Window);
-  Window->Parent = NULL;
-  ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
 
   /* Destroy the window storage */
   IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
@@ -1872,7 +1881,7 @@ NtUserFindWindowEx(HWND hwndParent,
       return NULL;      
     }
 
-  ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock);
+  IntLockRelatives(ParentWindow);
 
   if(hwndChildAfter)
   {
@@ -1883,11 +1892,14 @@ NtUserFindWindowEx(HWND hwndParent,
     }
 
     /* must be a direct child (not a decendant child)*/
-    if (WndChildAfter->Parent != ParentWindow)
+    IntLockRelatives(WndChildAfter);
+    if (WndChildAfter->Parent != ParentWindow->Self)
     {
+      IntUnLockRelatives(WndChildAfter);
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       return NULL;
     }
+    IntUnLockRelatives(WndChildAfter);
     
     WndChild = WndChildAfter->NextSibling;
   }
@@ -1903,7 +1915,7 @@ NtUserFindWindowEx(HWND hwndParent,
     {
       windowHandle = WndChild->Self;
 
-      ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
+      IntUnLockRelatives(ParentWindow);
       IntReleaseWindowObject(ParentWindow);
       ObmDereferenceObject (classObject);
       
@@ -1913,7 +1925,7 @@ NtUserFindWindowEx(HWND hwndParent,
     WndChild = WndChild->NextSibling;
   }
 
-  ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
+  IntUnLockRelatives(ParentWindow);
 
   IntReleaseWindowObject(ParentWindow);
   ObmDereferenceObject (classObject);
@@ -1940,19 +1952,16 @@ NtUserFlashWindowEx(DWORD Unknown0)
 HWND STDCALL
 NtUserGetAncestor(HWND hWnd, UINT Type)
 {
-   PWINDOW_OBJECT Wnd, WndAncestor;
-   HWND hWndAncestor = NULL;
+   PWINDOW_OBJECT Wnd, WndAncestor, Parent;
+   HWND hWndAncestor;
 
    if (hWnd == IntGetDesktopWindow())
    {
       return NULL;
    }
 
-   IntAcquireWinLockShared();
-
    if (!(Wnd = IntGetWindowObject(hWnd)))
    {
-      IntReleaseWinLock();
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
@@ -1960,36 +1969,71 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
    switch (Type)
    {
       case GA_PARENT:
-         WndAncestor = Wnd->Parent;
+         WndAncestor = IntGetParentObject(Wnd);
          break;
 
       case GA_ROOT:
          WndAncestor = Wnd;
-         while (!IntIsDesktopWindow(WndAncestor->Parent))
-            WndAncestor = WndAncestor->Parent;
+         Parent = NULL;
+#if 0
+         while (0 != (WndAncestor->Style & WS_CHILD))
+         {
+           Parent = IntGetParentObject(WndAncestor);
+           if (WndAncestor != Wnd)
+           {
+             IntReleaseWindowObject(WndAncestor);
+           }
+           WndAncestor = Parent;
+         }
+#else
+         for(;;)
+         {
+           if(Parent)
+           {
+             IntReleaseWindowObject(Parent);
+           }
+           if(!(Parent = IntGetParentObject(WndAncestor)) ||
+              !IntIsDesktopWindow(WndAncestor))
+           {
+             break;
+           }
+           WndAncestor = Parent;
+         }
+#endif
          break;
     
       case GA_ROOTOWNER:
          WndAncestor = Wnd;
+         IntReferenceWindowObject(WndAncestor);
          for (;;)
          {
-            PWINDOW_OBJECT Parent = IntGetParent(WndAncestor);
-            if (!Parent) break;
+            PWINDOW_OBJECT Old;
+            Old = WndAncestor;
+            Parent = IntGetParent(WndAncestor);
+            IntReleaseWindowObject(Old);
+            if (!Parent)
+            {
+              break;
+            }
             WndAncestor = Parent;
          }
          break;
 
       default:
-         WndAncestor = NULL;
+         IntReleaseWindowObject(Wnd);
+         return NULL;
    }
-
-   if (WndAncestor)
+   
+   IntReleaseWindowObject(Wnd);
+   
+   if(!WndAncestor)
    {
-      hWndAncestor = WndAncestor->Self;
+     return NULL;
    }
-
-   IntReleaseWindowObject(Wnd);
-   IntReleaseWinLock();
+   
+   hWndAncestor = WndAncestor->Self;
+   if(WndAncestor != Wnd)
+     IntReleaseWindowObject(WndAncestor);
 
    return hWndAncestor;
 }
@@ -2011,16 +2055,13 @@ NtUserGetClientRect(HWND hWnd, LPRECT Rect)
   PWINDOW_OBJECT WindowObject;
   RECT SafeRect;
 
-  IntAcquireWinLockShared();
   if (!(WindowObject = IntGetWindowObject(hWnd)))
   {
-    IntReleaseWinLock();
     SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);      
     return FALSE;
   }
 
   IntGetClientRect(WindowObject, &SafeRect);
-  IntReleaseWinLock();
 
   if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
   {
@@ -2109,11 +2150,8 @@ NtUserGetParent(HWND hWnd)
    PWINDOW_OBJECT Wnd, WndParent;
    HWND hWndParent = NULL;
 
-   IntAcquireWinLockShared();
-
    if (!(Wnd = IntGetWindowObject(hWnd)))
    {
-      IntReleaseWinLock();
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
@@ -2122,10 +2160,10 @@ NtUserGetParent(HWND hWnd)
    if (WndParent)
    {
       hWndParent = WndParent->Self;
+      IntReleaseWindowObject(WndParent);
    }
 
    IntReleaseWindowObject(Wnd);
-   IntReleaseWinLock();
 
    return hWndParent;
 }
@@ -2165,12 +2203,10 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
       return NULL;
    }
 
-   IntAcquireWinLockExclusive();
    if (hWndNewParent)
    {
       if (!(WndParent = IntGetWindowObject(hWndNewParent)))
       {
-         IntReleaseWinLock();
          SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
          return NULL;
       }
@@ -2179,7 +2215,6 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
    {
       if (!(WndParent = IntGetWindowObject(IntGetDesktopWindow())))
       {
-         IntReleaseWinLock();
          SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
          return NULL;
       }
@@ -2187,7 +2222,6 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
 
    if (!(Wnd = IntGetWindowObject(hWndChild)))
    {
-      IntReleaseWinLock();
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
@@ -2201,7 +2235,6 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
 
    IntReleaseWindowObject(Wnd);
    IntReleaseWindowObject(WndParent);
-   IntReleaseWinLock();
 
    return hWndOldParent;
 }
@@ -2417,28 +2450,38 @@ NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
 HWND STDCALL
 NtUserGetWindow(HWND hWnd, UINT Relationship)
 {
-   PWINDOW_OBJECT WindowObject;
+   PWINDOW_OBJECT WindowObject, Parent;
    HWND hWndResult = NULL;
 
-   IntAcquireWinLockShared();
-
    if (!(WindowObject = IntGetWindowObject(hWnd)))
    {
-      IntReleaseWinLock();
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
   
+   IntLockRelatives(WindowObject);
    switch (Relationship)
    {
       case GW_HWNDFIRST:
-         if (WindowObject->Parent && WindowObject->Parent->FirstChild)
-            hWndResult = WindowObject->Parent->FirstChild->Self;
+         if((Parent = IntGetParentObject(WindowObject)))
+         {
+           IntLockRelatives(Parent);
+           if (Parent->FirstChild)
+              hWndResult = Parent->FirstChild->Self;
+           IntUnLockRelatives(Parent);
+           IntReleaseWindowObject(Parent);
+         }
          break;
 
       case GW_HWNDLAST:
-         if (WindowObject->Parent && WindowObject->Parent->LastChild)
-            hWndResult = WindowObject->Parent->LastChild->Self;
+         if((Parent = IntGetParentObject(WindowObject)))
+         {
+           IntLockRelatives(Parent);
+           if (Parent->LastChild)
+              hWndResult = Parent->LastChild->Self;
+           IntUnLockRelatives(Parent);
+           IntReleaseWindowObject(Parent);
+         }
          break;
 
       case GW_HWNDNEXT:
@@ -2452,17 +2495,20 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
          break;
 
       case GW_OWNER:
-         if (WindowObject->Owner)
-            hWndResult = WindowObject->Owner->Self;
+         if((Parent = IntGetWindowObject(WindowObject->Owner)))
+         {
+           hWndResult = Parent->Self;
+           IntReleaseWindowObject(Parent);
+         }
          break;
       case GW_CHILD:
          if (WindowObject->FirstChild)
             hWndResult = WindowObject->FirstChild->Self;
          break;
    }
+   IntUnLockRelatives(WindowObject);
 
    IntReleaseWindowObject(WindowObject);
-   IntReleaseWinLock();
 
    return hWndResult;
 }
@@ -2500,7 +2546,7 @@ NtUserGetWindowDC(HWND hWnd)
 LONG STDCALL
 NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
 {
-   PWINDOW_OBJECT WindowObject;
+   PWINDOW_OBJECT WindowObject, Parent;
    LONG Result;
 
    DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
@@ -2555,10 +2601,17 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
             break;
 
          case GWL_HWNDPARENT:
-            if (WindowObject->Parent->Self == IntGetDesktopWindow())
-               Result = (LONG) NtUserGetWindow(WindowObject->Self, GW_OWNER);
-            else
-               Result = (LONG) NtUserGetAncestor(WindowObject->Self, GA_PARENT);
+            IntLockRelatives(WindowObject);
+            Parent = IntGetWindowObject(WindowObject->Parent);
+            IntUnLockRelatives(WindowObject);
+            if(Parent)
+            {
+              if (Parent && Parent->Self == IntGetDesktopWindow())
+                 Result = (LONG) NtUserGetWindow(WindowObject->Self, GW_OWNER);
+              else
+                 Result = (LONG) Parent->Self;
+              IntReleaseWindowObject(Parent);
+            }
             break;
 
          case GWL_ID:
@@ -2596,7 +2649,7 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
 LONG STDCALL
 NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 {
-   PWINDOW_OBJECT WindowObject;
+   PWINDOW_OBJECT WindowObject, Parent;
    PW32PROCESS Process;
    PWINSTATION_OBJECT WindowStation;
    LONG OldValue;
@@ -2684,10 +2737,13 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             break;
 
          case GWL_HWNDPARENT:
-            if (WindowObject->Parent->Self == IntGetDesktopWindow())
+            Parent = IntGetParentObject(WindowObject);
+            if (Parent && (Parent->Self == IntGetDesktopWindow()))
                OldValue = (LONG) IntSetOwner(WindowObject->Self, (HWND) NewValue);
             else
                OldValue = (LONG) NtUserSetParent(WindowObject->Self, (HWND) NewValue);
+            if(Parent)
+              IntReleaseWindowObject(Parent);
             break;
 
          case GWL_ID:
@@ -2841,24 +2897,22 @@ BOOL STDCALL
 NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
 {
   PWINDOW_OBJECT Wnd;
-  RECT SafeRect;
+  NTSTATUS Status;
 
-  IntAcquireWinLockShared();
   if (!(Wnd = IntGetWindowObject(hWnd)))
   {
-    IntReleaseWinLock();
     SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);      
     return FALSE;
   }
-  
-  SafeRect = Wnd->WindowRect;
-  IntReleaseWinLock();
-
-  if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+  Status = MmCopyToCaller(Rect, &Wnd->WindowRect, sizeof(RECT));
+  if (!NT_SUCCESS(Status))
   {
+    IntReleaseWindowObject(Wnd);
+    SetLastNtError(Status);
     return FALSE;
   }
-
+  
+  IntReleaseWindowObject(Wnd);
   return TRUE;
 }
 
@@ -2871,18 +2925,15 @@ NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
 {
    PWINDOW_OBJECT Wnd;
    DWORD tid, pid;
-
-   IntAcquireWinLockShared();
-
+   
    if (!(Wnd = IntGetWindowObject(hWnd)))
    {
-      IntReleaseWinLock();
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return 0;
    }
 
-   tid = IntGetWindowThreadProcessId(Wnd, &pid);
-   IntReleaseWinLock();
+   tid = (DWORD)IntGetWndThreadId(Wnd);
+   pid = (DWORD)IntGetWndProcessId(Wnd);
    
    if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
    
@@ -2914,11 +2965,9 @@ NtUserMoveWindow(
     int nHeight,
     BOOL bRepaint)
 {
-       UINT    flags = SWP_NOZORDER | SWP_NOACTIVATE;
-
-       if(!bRepaint)
-               flags |= SWP_NOREDRAW;
-       return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, flags);
+       return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, 
+                              (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : 
+                               SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW));
 }
 
 /*
@@ -2951,11 +3000,11 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
    switch(Index)
    {
       case 0x00:
-         Result = (DWORD)Window->OwnerThread->ThreadsProcess->UniqueProcessId;
+         Result = (DWORD)IntGetWndProcessId(Window);
          break;
 
       case 0x01:
-         Result = (DWORD)Window->OwnerThread->Cid.UniqueThread;
+         Result = (DWORD)IntGetWndThreadId(Window);
          break;
 
       default:
@@ -3306,153 +3355,38 @@ NtUserValidateRect(HWND hWnd, const RECT* Rect)
   return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
 }
 
-static BOOL IsStaticClass(PWINDOW_OBJECT Window)
-{
-    BOOL rc = FALSE;
-
-    ASSERT(0 != Window->Class);
-    ASSERT(0 != Window->Class->Atom);
-    
-    DbgPrint("FIXME: Update IsStatic to really check if a window is a static\n");
-    /*
-    if (0 == wcscmp((LPWSTR)Window->Class->lpszClassName, L"Static"))
-        rc = TRUE;
-    */    
-    return rc;
-}
-
-static BOOL IsDisabled(PWINDOW_OBJECT Window)
-{
-    BOOL rc = FALSE;
-    ASSERT(0 != Window);
-
-    rc = (Window->Style & WS_DISABLED);
-    
-    return rc;
-}
-
-static PWINDOW_OBJECT RestrictiveSearchChildWindows(PWINDOW_OBJECT Window, POINT p)
-{
-    PWINDOW_OBJECT ChildWindow = 0;
-    PWINDOW_OBJECT rc          = Window;
-    ASSERT(0 != Window);
-
-    /*
-    **Aquire a mutex to the Child list.
-    */
-    ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
-
-    /*
-    **Now Find the first non-static window.
-    */
-    ChildWindow = Window->FirstChild;
-
-    while (0 != ChildWindow)
-    {
-        /*
-        **Test Restrictions on the window.
-        */
-        if (!IsStaticClass(ChildWindow) &&
-            !IsDisabled(ChildWindow)    &&
-            IntIsWindowVisible(ChildWindow->Self))
-        {
-            /*
-            **Now find the deepest child window
-            */
-            if (POINT_IN_RECT(p, ChildWindow->WindowRect))
-            {
-                rc = RestrictiveSearchChildWindows(ChildWindow, p);
-                break;
-            }
-        }
-        ChildWindow = ChildWindow->NextSibling;
-    }
-   
-    /*
-    **Release mutex.
-    */     
-    ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
-
-    return rc;
-}
 
 /*
- * NtUserWindowFromPoint
- *
- * Return Value
- *    The return value is a handle to the window that contains the point. 
- *    If no window exists at the given point, the return value is NULL. 
- *    If the point is over a static text control, the return value is a handle 
- *    to the window under the static text control. 
- *
- * Remarks
- *    The WindowFromPoint function does not retrieve a handle to a hidden or 
- *    disabled window, even if the point is within the window. An application
- *    should use the ChildWindowFromPoint function for a nonrestrictive search.
- *
- * Author
- *    Mark Tempel
- *
- * Status
  *    @implemented
  */
-
 HWND STDCALL
 NtUserWindowFromPoint(LONG X, LONG Y)
 {
-   HWND hWnd = 0;
-   PWINDOW_OBJECT DesktopWindow = 0;
-   PWINDOW_OBJECT TopWindow = 0;
-   PWINDOW_OBJECT ChildWindow = 0;
    POINT pt;
+   HWND Ret;
+   PWINDOW_OBJECT DesktopWindow, Window = NULL;
 
-   DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
-
-   pt.x = X;
-   pt.y = Y;
-
-   if (DesktopWindow != NULL)
+   if ((DesktopWindow = IntGetWindowObject(IntGetDesktopWindow())))
    {
-      /*
-       * Aquire the mutex to the child window list. (All the topmost windows)
-       */
-      ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
-
-      /*
-       * Spin through the windows looking for the window that contains the 
-       * point. The child windows are in Z-order.
-       */
-      TopWindow = DesktopWindow->FirstChild;
-      while (TopWindow != NULL)
-      {
-         if (POINT_IN_RECT(pt, TopWindow->WindowRect))
-         {
-            break;
-         }
-         TopWindow = TopWindow->NextSibling;
-      }
+      USHORT Hit;
       
-      /*
-       * Search for the child window that contains the point.
-       */
-      if (TopWindow != NULL)
+      pt.x = X;
+      pt.y = Y;
+      
+      Hit = WinPosWindowFromPoint(DesktopWindow, pt, &Window);
+      
+      if(Window)
       {
-         ChildWindow = RestrictiveSearchChildWindows(TopWindow, pt);
-         if (ChildWindow != NULL)
-         {
-            hWnd = ChildWindow->Self;
-         }
+        Ret = Window->Self;
+        IntReleaseWindowObject(Window);
+        IntReleaseWindowObject(DesktopWindow);
+        return Ret;
       }
       
-      /*
-       * Release mutex.
-       */
-      ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
+      IntReleaseWindowObject(DesktopWindow);
    }
-
-   IntReleaseWindowObject(DesktopWindow);
   
-   return hWnd;
+   return NULL;
 }
 
 
diff --git a/reactos/subsys/win32k/ntuser/winlock.c b/reactos/subsys/win32k/ntuser/winlock.c
deleted file mode 100644 (file)
index 3b1bb1d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- *
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * PURPOSE:          Windows++ locking
- * FILE:             subsys/win32k/ntuser/winlock.c
- * PROGRAMER:        Gunnar
- * REVISION HISTORY:
- *
- */
-/* INCLUDES ******************************************************************/
-
-#include <ddk/ntddk.h>
-#include <win32k/win32k.h>
-#include <include/object.h>
-#include <include/guicheck.h>
-#include <include/window.h>
-#include <include/class.h>
-#include <include/error.h>
-#include <include/winsta.h>
-#include <include/winpos.h>
-#include <include/callback.h>
-#include <include/msgqueue.h>
-#include <include/rect.h>
-
-#define NDEBUG
-#include <win32k/debug1.h>
-#include <debug.h>
-
-/* GLOBALS *****************************************************************/
-
-static ERESOURCE WinLock;
-
-/* FUNCTIONS *****************************************************************/
-
-BOOL FASTCALL IntVerifyWinLock(WINLOCK_TYPE Type)
-{
-  switch (Type)
-  {
-    case None:
-      return !ExIsResourceAcquiredSharedLite(&WinLock);
-    case Shared: /* NOTE: an exclusive lock is also a shared lock */
-    case Any: 
-      return ExIsResourceAcquiredSharedLite(&WinLock);
-    case Exclusive:
-      return ExIsResourceAcquiredExclusiveLite(&WinLock);
-  }
-
-  KEBUGCHECK(0);
-  return FALSE;
-}
-
-WINLOCK_TYPE FASTCALL IntSuspendWinLock()
-{
-  ASSERT_WINLOCK(Any);
-
-  if (ExIsResourceAcquiredExclusiveLite(&WinLock)) return Exclusive;
-  
-  return Shared;
-}
-
-VOID FASTCALL IntRestoreWinLock(WINLOCK_TYPE Type)
-{
-  switch (Type)
-  {
-    case Exclusive:
-      return IntAcquireWinLockExclusive(&WinLock);
-    case Shared:
-      return IntAcquireWinLockShared(&WinLock);
-    /* silence warnings */
-    case None:
-    case Any:
-      break;
-  }
-
-  KEBUGCHECK(0);
-}
-
-inline VOID IntAcquireWinLockShared()
-{
-  KeEnterCriticalRegion();
-  ExAcquireResourceSharedLite(&WinLock, TRUE /*Wait*/ );
-}
-
-inline VOID IntAcquireWinLockExclusive()
-{
-  KeEnterCriticalRegion();
-  ExAcquireResourceExclusiveLite(&WinLock, TRUE /*Wait*/  );
-}
-
-inline VOID IntReleaseWinLock()
-{
-  ExReleaseResourceLite(&WinLock ); 
-  KeLeaveCriticalRegion();
-}
-
-inline BOOL IntInitializeWinLock()
-{
-  ExInitializeResourceLite(&WinLock );
-  return TRUE;
-}
-
-inline VOID IntDeleteWinLock()
-{
-  ExDeleteResourceLite(&WinLock );  
-}
-
-/* EOF */
index aa24ea7..7e0c759 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: winpos.c,v 1.97 2004/02/22 14:26:35 navaraf Exp $
+/* $Id: winpos.c,v 1.98 2004/02/24 01:30:58 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -122,34 +122,53 @@ NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
 VOID FASTCALL
 WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
 {
-  PWINDOW_OBJECT Child;
-  PWINDOW_OBJECT TabooWindow = Window;
+  PWINDOW_OBJECT Child, Wnd = Window;
+  HWND *List, *phWnd;
 
-  for (;;)
+  if (!Window || IntIsDesktopWindow(Window))
+  {
+    IntSetFocusMessageQueue(NULL);
+    return;
+  }
+
+  for(;;)
+  {
+    Wnd = IntGetParentObject(Wnd);
+    if(!Wnd)
+    {
+      IntSetFocusMessageQueue(NULL);
+      return;
+    }
+    if(IntIsDesktopWindow(Wnd))
+    {
+      IntReleaseWindowObject(Wnd);
+      IntSetFocusMessageQueue(NULL);
+      return;
+    }
+    if((List = IntWinListChildren(Window)))
     {
-      if (NULL == Window || IntIsDesktopWindow(Window))
+      for(phWnd = List; *phWnd; ++phWnd)
+      {
+        if(*phWnd == Window->Self)
         {
-          IntSetFocusMessageQueue(NULL);
-          return;
+          continue;
         }
-      Window = Window->Parent;
-      ExAcquireFastMutex(&(Window->ChildrenListLock));
-      Child = Window->FirstChild;
-      while (NULL != Child)
+        
+        Child = IntGetWindowObject(*phWnd);
+        if(Child)
         {
-          if (Child != TabooWindow)
-            {
-              ExReleaseFastMutex(&(Window->ChildrenListLock));
-              if (IntSetForegroundWindow(Child))
-                {
-                  return;
-                }
-              ExAcquireFastMutex(&(Window->ChildrenListLock));
-            }
-          Child = Child->NextSibling;
+          if(IntSetForegroundWindow(Child))
+          {
+            IntReleaseWindowObject(Child);
+            ExFreePool(List);
+            return;
+          }
+          IntReleaseWindowObject(Child);
         }
-      ExReleaseFastMutex(&(Window->ChildrenListLock));
+      }
+      ExFreePool(List);
     }
+  }
 }
 
 VOID STATIC FASTCALL
@@ -161,6 +180,7 @@ WinPosFindIconPos(HWND hWnd, POINT *Pos)
 PINTERNALPOS FASTCALL
 WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
 {
+  PWINDOW_OBJECT Parent;
   INT XInc, YInc;
   
   if (WindowObject->InternalPos == NULL)
@@ -168,10 +188,17 @@ WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
       RECT WorkArea;
       PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
       
-      if(IntIsDesktopWindow(WindowObject->Parent))
-        WorkArea = *IntGetDesktopWorkArea(Desktop);
+      Parent = IntGetParentObject(WindowObject);
+      if(Parent)
+      {
+        if(IntIsDesktopWindow(Parent))
+          WorkArea = *IntGetDesktopWorkArea(Desktop);
+        else
+          WorkArea = Parent->ClientRect;
+        IntReleaseWindowObject(Parent);
+      }
       else
-        WorkArea = WindowObject->Parent->ClientRect;
+        WorkArea = *IntGetDesktopWorkArea(Desktop);
       
       WindowObject->InternalPos = ExAllocatePoolWithTag(NonPagedPool, sizeof(INTERNALPOS), TAG_WININTLIST);
       if(!WindowObject->InternalPos)
@@ -402,6 +429,7 @@ LONG STATIC FASTCALL
 WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
                   RECT* WindowRect, RECT* ClientRect)
 {
+  PWINDOW_OBJECT Parent;
   UINT wvrFlags = 0;
 
   /* Send WM_NCCALCSIZE message to get new client area */
@@ -413,14 +441,15 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
       params.rgrc[0] = *WindowRect;
       params.rgrc[1] = Window->WindowRect;
       params.rgrc[2] = Window->ClientRect;
-      if (0 != (Window->Style & WS_CHILD))
+      Parent = IntGetParentObject(Window);
+      if (0 != (Window->Style & WS_CHILD) && Parent)
        {
-         NtGdiOffsetRect(&(params.rgrc[0]), - Window->Parent->ClientRect.left,
-                             - Window->Parent->ClientRect.top);
-         NtGdiOffsetRect(&(params.rgrc[1]), - Window->Parent->ClientRect.left,
-                             - Window->Parent->ClientRect.top);
-         NtGdiOffsetRect(&(params.rgrc[2]), - Window->Parent->ClientRect.left,
-                             - Window->Parent->ClientRect.top);
+         NtGdiOffsetRect(&(params.rgrc[0]), - Parent->ClientRect.left,
+                             - Parent->ClientRect.top);
+         NtGdiOffsetRect(&(params.rgrc[1]), - Parent->ClientRect.left,
+                             - Parent->ClientRect.top);
+         NtGdiOffsetRect(&(params.rgrc[2]), - Parent->ClientRect.left,
+                             - Parent->ClientRect.top);
        }
       params.lppos = &winposCopy;
       winposCopy = *WinPos;
@@ -432,10 +461,10 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
           params.rgrc[0].top <= params.rgrc[0].bottom)
        {
           *ClientRect = params.rgrc[0];
-         if (Window->Style & WS_CHILD)
+         if ((Window->Style & WS_CHILD) && Parent)
            {
-             NtGdiOffsetRect(ClientRect, Window->Parent->ClientRect.left,
-                             Window->Parent->ClientRect.top);
+             NtGdiOffsetRect(ClientRect, Parent->ClientRect.left,
+                             Parent->ClientRect.top);
            }
        }
 
@@ -454,6 +483,8 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
        {
           WinPos->flags &= ~SWP_NOCLIENTSIZE;
        }
+         if(Parent)
+           IntReleaseWindowObject(Parent);
     }
   else
     {
@@ -492,13 +523,17 @@ WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
 
   if (!(WinPos->flags & SWP_NOMOVE))
     {
+      PWINDOW_OBJECT Parent;
       X = WinPos->x;
       Y = WinPos->y;
-      if (0 != (WindowObject->Style & WS_CHILD))
+      Parent = IntGetParentObject(WindowObject);
+      if ((0 != (WindowObject->Style & WS_CHILD)) && Parent)
        {
-         X += WindowObject->Parent->ClientRect.left;
-         Y += WindowObject->Parent->ClientRect.top;
+         X += Parent->ClientRect.left;
+         Y += Parent->ClientRect.top;
        }
+         if(Parent)
+           IntReleaseWindowObject(Parent);
       WindowRect->left = X;
       WindowRect->top = Y;
       WindowRect->right += X - WindowObject->WindowRect.left;
@@ -588,8 +623,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
 VOID STATIC FASTCALL
 WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
 {
-   HWND *Children;
-   UINT Count;
+   PWINDOW_OBJECT Child;
 
    Window->WindowRect.left += MoveX;
    Window->WindowRect.right += MoveX;
@@ -600,18 +634,13 @@ WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
    Window->ClientRect.right += MoveX;
    Window->ClientRect.top += MoveY;
    Window->ClientRect.bottom += MoveY;
-
-   Children = IntWinListChildren(Window);
-   if (Children)
+   
+   IntLockRelatives(Window);
+   for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
    {
-      for (Count = 0; Children[Count] != NULL; Count++)
-      {
-         Window = IntGetWindowObject(Children[Count]);
-         WinPosInternalMoveWindow(Window, MoveX, MoveY);
-         IntReleaseWindowObject(Window);
-      }
-      ExFreePool(Children);
+     WinPosInternalMoveWindow(Child, MoveX, MoveY);
    }
+   IntUnLockRelatives(Window);
 }
 
 /*
@@ -691,13 +720,18 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
       if ((WinPos->hwndInsertAfter != HWND_TOP) &&
           (WinPos->hwndInsertAfter != HWND_BOTTOM))
       {
+         PWINDOW_OBJECT Parent = IntGetParentObject(Window);
          if (NtUserGetAncestor(WinPos->hwndInsertAfter, GA_PARENT) !=
-             Window->Parent->Self)
+             (Parent ? Parent->Self : NULL))
          {
+            if(Parent)
+              IntReleaseWindowObject(Parent);
             return FALSE;
          }
          else
          {
+            if(Parent)
+              IntReleaseWindowObject(Parent);
             /*
              * We don't need to change the Z order of hwnd if it's already
              * inserted after hwndInsertAfter or when inserting hwnd after
@@ -812,26 +846,35 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       PWINDOW_OBJECT ParentWindow;
       PWINDOW_OBJECT InsertAfterWindow;
 
-      ParentWindow = Window->Parent;
-      if (ParentWindow)
+      if ((ParentWindow = IntGetParentObject(Window)))
       {
          if (WinPos.hwndInsertAfter == HWND_TOP)
             InsertAfterWindow = NULL;
          else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
-            InsertAfterWindow = IntGetWindowObject(ParentWindow->LastChild->Self);
+         {
+            IntLockRelatives(ParentWindow);
+            if(ParentWindow->LastChild)
+            {
+               IntReferenceWindowObject(ParentWindow->LastChild);
+               InsertAfterWindow = ParentWindow->LastChild;
+            }
+            else
+              InsertAfterWindow = NULL;
+            IntUnLockRelatives(ParentWindow);
+         }
          else
             InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
          /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
             the last window */
          if (InsertAfterWindow != Window)
          {
-             ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
              IntUnlinkWindow(Window);
              IntLinkWindow(Window, ParentWindow, InsertAfterWindow);
-             ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
          }
          if (InsertAfterWindow != NULL)
             IntReleaseWindowObject(InsertAfterWindow);
+         
+         IntReleaseWindowObject(ParentWindow);
       }
    }
 
@@ -1191,7 +1234,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
       if (Wnd == IntGetThreadFocusWindow() ||
           IntIsChildWindow(Wnd, IntGetThreadFocusWindow()))
         {
-          NtUserSetFocus(Window->Parent->Self);
+          NtUserSetFocus(Window->Parent);
         }
     }
 
@@ -1238,71 +1281,78 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT *Point,
                     PWINDOW_OBJECT* Window, USHORT *HitTest)
 {
   PWINDOW_OBJECT Current;
+  HWND *List, *phWnd;
 
-  ExAcquireFastMutexUnsafe(&ScopeWin->ChildrenListLock);
-  Current = ScopeWin->FirstChild;
-  while (Current)
+  if((List = IntWinListChildren(ScopeWin)))
+  {
+    for(phWnd = List; *phWnd; ++phWnd)
     {
+      if(!(Current = IntGetWindowObject(*phWnd)))
+      {
+        continue;
+      }
+      
       if (Current->Style & WS_VISIBLE &&
-         ((!(Current->Style & WS_DISABLED)) ||
-          (Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
-         (Point->x >= Current->WindowRect.left &&
+             ((!(Current->Style & WS_DISABLED)) ||
+              (Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
+             (Point->x >= Current->WindowRect.left &&
            Point->x < Current->WindowRect.right &&
            Point->y >= Current->WindowRect.top &&
            Point->y < Current->WindowRect.bottom))
            /* FIXME - check if Point is in window region */
-       {
-         if(*Window)
          {
-           ObmDereferenceObject(*Window);
-         }
-         ObmReferenceObjectByPointer(Current, otWindow);
-         *Window = Current;
-         
-         if (Current->Style & WS_DISABLED)
+           if(*Window)
            {
-             ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
-             *HitTest = HTERROR;
-             return TRUE;
+             IntReleaseWindowObject(*Window);
            }
-         if(Current->MessageQueue == PsGetWin32Thread()->MessageQueue)
-         {
-           *HitTest = IntSendMessage(Current->Self, WM_NCHITTEST, 0,
-                                     MAKELONG(Point->x, Point->y));
-           if((*HitTest) == (USHORT)HTTRANSPARENT)
-           {
-             Current = Current->NextSibling;
-             continue;
-           }
-         }
-         else
-         {
-           *HitTest = HTCLIENT;
-         }
-         
-         if (Point->x >= Current->ClientRect.left &&
-             Point->x < Current->ClientRect.right &&
-             Point->y >= Current->ClientRect.top &&
-             Point->y < Current->ClientRect.bottom)
-           {
-             USHORT ChildHitTest;
-             if(WinPosSearchChildren(Current, Point, Window, &ChildHitTest))
-             {
-                ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
-               *HitTest = ChildHitTest;
-               return TRUE;
-             }
-           }
-
-         ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
-         return TRUE;
-       }
-      Current = Current->NextSibling;
+           *Window = Current;
+           
+        if(Current->Style & WS_DISABLED)
+        {
+          *HitTest = HTERROR;
+             ExFreePool(List);
+          return TRUE;
+        }
+        
+        if(Current->MessageQueue == PsGetWin32Thread()->MessageQueue)
+        {
+          *HitTest = IntSendMessage(Current->Self, WM_NCHITTEST, 0,
+                                    MAKELONG(Point->x, Point->y));
+          if((*HitTest) == (USHORT)HTTRANSPARENT)
+          {
+            continue;
+          }
+        }
+        else
+        {
+          *HitTest = HTCLIENT;
+        }
+        
+        if(Point->x >= Current->ClientRect.left &&
+           Point->x < Current->ClientRect.right &&
+           Point->y >= Current->ClientRect.top &&
+           Point->y < Current->ClientRect.bottom)
+        {
+          USHORT ChildHitTest;
+          if(WinPosSearchChildren(Current, Point, Window, &ChildHitTest))
+          {
+            *HitTest = ChildHitTest;
+            ExFreePool(List);
+            return TRUE;
+          }
+        }
+        
+        ExFreePool(List);
+        return TRUE;
+      }
+      IntReleaseWindowObject(Current);
     }
-                 
-  ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
-  if(*Window == NULL)
-    *HitTest = HTNOWHERE;
+    ExFreePool(List);
+  }
+  
+  if((*Window) == NULL)
+    HitTest = HTNOWHERE;
+  
   return FALSE;
 }
 
@@ -1330,15 +1380,18 @@ WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
 
   /* Translate the point to the space of the scope window. */
   DesktopWindowHandle = IntGetDesktopWindow();
-  DesktopWindow = IntGetWindowObject(DesktopWindowHandle);
-  Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left;
-  Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top;
-  IntReleaseWindowObject(DesktopWindow);
-
+  if((DesktopWindow = IntGetWindowObject(DesktopWindowHandle)))
+  {
+    Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left;
+    Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top;
+    IntReleaseWindowObject(DesktopWindow);
+  }
+  
   if(WinPosSearchChildren(ScopeWin, &Point, Window, &HitTest))
   {
     return HitTest;
   }
+
   return HTNOWHERE;
 }