Commit in reactos/subsys/win32k on MAIN
include/class.h+11.24 -> 1.25
       /msgqueue.h+11.41 -> 1.42
ntuser/class.c+32-111.60 -> 1.61
      /message.c+20-21.75 -> 1.76
      /msgqueue.c+81-11.109 -> 1.110
      /window.c+19-451.250 -> 1.251
      /winpos.c+3-21.124 -> 1.125
+157-61
7 modified files
1. don't dispatch sent messages to windows during destruction
2. fixed class lookup in a hacky way (get's rewritten soon anyway)

reactos/subsys/win32k/include
class.h 1.24 -> 1.25
diff -u -r1.24 -r1.25
--- class.h	27 May 2004 11:47:42 -0000	1.24
+++ class.h	11 Dec 2004 19:39:17 -0000	1.25
@@ -27,6 +27,7 @@
   BOOL Unicode;
   BOOL Global;
   LIST_ENTRY ListEntry;
+  LIST_ENTRY GlobalListEntry; /* HACK!!! */
   PCHAR   ExtraData;
   /* list of windows */
   FAST_MUTEX ClassWindowsListLock;

reactos/subsys/win32k/include
msgqueue.h 1.41 -> 1.42
diff -u -r1.41 -r1.42
--- msgqueue.h	8 Aug 2004 17:57:34 -0000	1.41
+++ msgqueue.h	11 Dec 2004 19:39:17 -0000	1.42
@@ -203,6 +203,7 @@
 
 LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
 LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
+VOID STDCALL MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */
 
 #define IntLockMessageQueue(MsgQueue) \
   ExAcquireFastMutex(&(MsgQueue)->Lock)

reactos/subsys/win32k/ntuser
class.c 1.60 -> 1.61
diff -u -r1.60 -r1.61
--- class.c	20 Nov 2004 16:46:06 -0000	1.60
+++ class.c	11 Dec 2004 19:39:18 -0000	1.61
@@ -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: class.c,v 1.60 2004/11/20 16:46:06 weiden Exp $
+/* $Id: class.c,v 1.61 2004/12/11 19:39:18 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -33,11 +33,22 @@
 #define NDEBUG
 #include <debug.h>
 
+/* FIXME: Just a bad hack for now... */
+LIST_ENTRY GlobalClassListHead;
+FAST_MUTEX GlobalClassListLock;
+#define IntLockGlobalClassList() \
+  ExAcquireFastMutex(&GlobalClassListLock)
+#define IntUnlockGlobalClassList() \
+  ExReleaseFastMutex(&GlobalClassListLock)
+
+
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS FASTCALL
 InitClassImpl(VOID)
 {
+  ExInitializeFastMutex(&GlobalClassListLock);
+  InitializeListHead(&GlobalClassListHead);
   return(STATUS_SUCCESS);
 }
 
@@ -55,19 +66,19 @@
 {
    PWNDCLASS_OBJECT Current, BestMatch = NULL;
    PLIST_ENTRY CurrentEntry;
-   PW32PROCESS Process = PsGetWin32Process();
   
-   IntLockProcessClasses(Process);
-   CurrentEntry = Process->ClassListHead.Flink;
-   while (CurrentEntry != &Process->ClassListHead)
+   /* HACK!! */
+   IntLockGlobalClassList();
+   CurrentEntry = GlobalClassListHead.Flink;
+   while (CurrentEntry != &GlobalClassListHead)
    {
-      Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry);
+      Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, GlobalListEntry);
       
       if (Current->Atom == Atom && (hInstance == NULL || Current->hInstance == hInstance))
       {
          *Class = Current;
          ObmReferenceObject(Current);
-         IntUnLockProcessClasses(Process);
+         IntUnlockGlobalClassList();
          return TRUE;
       }
 
@@ -76,7 +87,7 @@
 
       CurrentEntry = CurrentEntry->Flink;
    }
-   IntUnLockProcessClasses(Process);
+   IntUnlockGlobalClassList();
 
    if (BestMatch != NULL)
    {
@@ -111,6 +122,7 @@
 
    if (!NT_SUCCESS(Status))
    {
+      DPRINT1("Failed to lookup class atom!\n");
       return FALSE;
    }
 
@@ -413,16 +425,16 @@
   
   WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
   
-  if (ClassName->Length)
+  if (ClassName->Length > 0)
   {
-    DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
+    DPRINT1("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
     /* FIXME - Safely copy/verify the buffer first!!! */
     Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable,
       ClassName->Buffer,
       &Atom);
     if (!NT_SUCCESS(Status))
     {
-      DPRINT("Failed adding class name (%S) to atom table\n",
+      DPRINT1("Failed adding class name (%S) to atom table\n",
 	ClassName->Buffer);
       SetLastNtError(Status);      
       return((RTL_ATOM)0);
@@ -445,6 +457,11 @@
   IntLockProcessClasses(PsGetWin32Process());
   InsertTailList(&PsGetWin32Process()->ClassListHead, &ClassObject->ListEntry);
   IntUnLockProcessClasses(PsGetWin32Process());
+  
+  /* HACK!!! */
+  IntLockGlobalClassList();
+  InsertTailList(&GlobalClassListHead, &ClassObject->GlobalListEntry);
+  IntUnlockGlobalClassList();
   return(Atom);
 }
 
@@ -681,6 +698,10 @@
    ClassDereferenceObject(Class);
   
    RemoveEntryList(&Class->ListEntry);
+   
+   IntLockGlobalClassList();
+   RemoveEntryList(&Class->GlobalListEntry);
+   IntUnlockGlobalClassList();
 
    RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Class->Atom);
   

reactos/subsys/win32k/ntuser
message.c 1.75 -> 1.76
diff -u -r1.75 -r1.76
--- message.c	20 Nov 2004 16:46:06 -0000	1.75
+++ message.c	11 Dec 2004 19:39:18 -0000	1.76
@@ -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.75 2004/11/20 16:46:06 weiden Exp $
+/* $Id: message.c,v 1.76 2004/12/11 19:39:18 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -519,7 +519,10 @@
           {
             /* post the message to the other window */
             Msg->hwnd = Wnd->Self;
-            MsqPostMessage(Wnd->MessageQueue, Msg, FALSE);
+            if(!(Wnd->Status & WINDOWSTATUS_DESTROYING))
+            {
+              MsqPostMessage(Wnd->MessageQueue, Msg, FALSE);
+            }
             
             /* eat the message */
             IntReleaseWindowObject(Wnd);
@@ -1114,6 +1117,13 @@
           SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
           return FALSE;
         }
+      if(Window->Status & WINDOWSTATUS_DESTROYING)
+      {
+        IntReleaseWindowObject(Window);
+        DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
+        /* FIXME - last error code? */
+        return FALSE;
+      }
 
       UserModeMsg.hwnd = Wnd;
       UserModeMsg.message = Msg;
@@ -1293,6 +1303,14 @@
     return FALSE;
   }
   
+  if(Window->Status & WINDOWSTATUS_DESTROYING)
+  {
+    IntReleaseWindowObject(Window);
+    /* FIXME - last error? */
+    DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+    return FALSE;
+  }
+  
   Status = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam, 
                           uTimeout, (uFlags & SMTO_BLOCK), uResult);
   IntReleaseWindowObject(Window);

reactos/subsys/win32k/ntuser
msgqueue.c 1.109 -> 1.110
diff -u -r1.109 -r1.110
--- msgqueue.c	10 Dec 2004 22:40:29 -0000	1.109
+++ msgqueue.c	11 Dec 2004 19:39:18 -0000	1.110
@@ -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.109 2004/12/10 22:40:29 weiden Exp $
+/* $Id: msgqueue.c,v 1.110 2004/12/11 19:39:18 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -809,6 +809,84 @@
   return(TRUE);
 }
 
+VOID STDCALL
+MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
+{
+  PUSER_SENT_MESSAGE SentMessage;
+  PUSER_MESSAGE PostedMessage;
+  PUSER_MESSAGE_QUEUE MessageQueue;
+  PLIST_ENTRY CurrentEntry, ListHead;
+  PWINDOW_OBJECT Window = pWindow;
+  
+  ASSERT(Window);
+  
+  MessageQueue = Window->MessageQueue;
+  ASSERT(MessageQueue);
+  
+  IntLockMessageQueue(MessageQueue);
+  
+  /* remove the posted messages for this window */
+  CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
+  ListHead = &MessageQueue->PostedMessagesListHead;
+  while (CurrentEntry != ListHead)
+    {
+      PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
+				        ListEntry);
+      if (PostedMessage->Msg.hwnd == Window->Self)
+	{
+	  RemoveEntryList(&PostedMessage->ListEntry);
+	  MsqDestroyMessage(PostedMessage);
+          CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
+	}
+      else
+        {
+          CurrentEntry = CurrentEntry->Flink;
+        }
+    }
+
+  /* remove the sent messages for this window */
+  CurrentEntry = MessageQueue->SentMessagesListHead.Flink;
+  ListHead = &MessageQueue->SentMessagesListHead;
+  while (CurrentEntry != ListHead)
+    {
+      CurrentEntry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
+      SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
+                                      ListEntry);
+      if(SentMessage->Msg.hwnd == Window->Self)
+      {
+        IntLockMessageQueue(SentMessage->SenderQueue);
+        DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
+
+        /* remove the message from the dispatching list */
+        if(SentMessage->DispatchingListEntry.Flink != NULL)
+        {
+          RemoveEntryList(&SentMessage->DispatchingListEntry);
+        }
+
+        /* wake the sender's thread */
+        if (SentMessage->CompletionEvent != NULL)
+        {
+          KeSetEvent(SentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
+        }
+        IntUnLockMessageQueue(SentMessage->SenderQueue);
+
+        /* dereference our and the sender's message queue */
+        IntDereferenceMessageQueue(MessageQueue);
+        IntDereferenceMessageQueue(SentMessage->SenderQueue);
+
+        /* free the message */
+        ExFreePool(SentMessage);
+        
+        CurrentEntry = MessageQueue->SentMessagesListHead.Flink;
+      }
+      else
+      {
+        CurrentEntry = CurrentEntry->Flink;
+      }
+    }
+  IntUnLockMessageQueue(MessageQueue);
+}
+
 VOID FASTCALL
 MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
 		     PUSER_SENT_MESSAGE_NOTIFY NotifyMessage)
@@ -1138,6 +1216,7 @@
       CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, 
                                              ListEntry);
       
+      IntLockMessageQueue(CurrentSentMessage->SenderQueue);
       DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
       
       /* remove the message from the dispatching list */
@@ -1151,6 +1230,7 @@
       {
         KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
+      IntUnLockMessageQueue(CurrentSentMessage->SenderQueue);
       
       /* dereference our and the sender's message queue */
       IntDereferenceMessageQueue(MessageQueue);

reactos/subsys/win32k/ntuser
window.c 1.250 -> 1.251
diff -u -r1.250 -r1.251
--- window.c	20 Nov 2004 19:08:37 -0000	1.250
+++ window.c	11 Dec 2004 19:39:18 -0000	1.251
@@ -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.250 2004/11/20 19:08:37 weiden Exp $
+/* $Id: window.c,v 1.251 2004/12/11 19:39:18 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -278,6 +278,7 @@
     return 0;
   }
   Window->Status |= WINDOWSTATUS_DESTROYING;
+  Window->Flags &= ~WS_VISIBLE;
   /* remove the window already at this point from the thread window list so we
      don't get into trouble when destroying the thread windows while we're still
      in IntDestroyWindow() */
@@ -290,7 +291,18 @@
   {
     /* Send destroy messages */
     IntSendDestroyMsg(Window->Self);
+    if(BelongsToThreadData)
+      IntSendMessage(Window->Self, WM_NCDESTROY, 0, 0);
   }
+  
+  /* from now on no messages can be sent to this window anymore */
+  IntLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
+  Window->Status |= WINDOWSTATUS_DESTROYED;
+  /* don't remove the WINDOWSTATUS_DESTROYING bit */
+  IntUnLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
+  
+  /* flush the message queue */
+  MsqRemoveWindowMessagesFromQueue(Window);
 
   /* free child windows */
   Children = IntWinListChildren(Window);
@@ -313,23 +325,6 @@
       ExFreePool(Children);
     }
 
-  if (SendMessages)
-    {      
-      /*
-       * Clear the update region to make sure no WM_PAINT messages will be
-       * generated for this window while processing the WM_NCDESTROY.
-       */ 
-      IntRedrawWindow(Window, NULL, 0,
-                      RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
-                      RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
-
-      /*
-       * Send the WM_NCDESTROY to the window being destroyed.
-       */
-      if(BelongsToThreadData)
-        IntSendMessage(Window->Self, WM_NCDESTROY, 0, 0);
-    }
-
   /* reset shell window handles */
   if(ThreadData->Desktop)
   {
@@ -385,11 +380,6 @@
   
   IntDestroyScrollBars(Window);
   
-  IntLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-  Window->Status |= WINDOWSTATUS_DESTROYED;
-  /* don't remove the WINDOWSTATUS_DESTROYING bit */
-  IntUnLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
-  
   /* remove the window from the class object */
   IntLockClassWindows(Window->Class);
   RemoveEntryList(&Window->ClassListEntry);
@@ -1403,7 +1393,6 @@
   HWND ParentWindowHandle;
   HWND OwnerWindowHandle;
   PMENU_OBJECT SystemMenu;
-  NTSTATUS Status;
   HANDLE Handle;
   POINT Pos;
   SIZE Size;
@@ -1417,7 +1406,6 @@
   LRESULT Result;
   BOOL MenuChanged;
   BOOL ClassFound;
-  PWSTR ClassNameString;
 
   ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
   OwnerWindowHandle = NULL;
@@ -1454,24 +1442,7 @@
   /* FIXME: parent must belong to the current process */
 
   /* Check the class. */
-  if (IS_ATOM(ClassName->Buffer))
-    {
-      ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName->Buffer, hInstance);
-    }
-  else
-    {
-      Status = IntUnicodeStringToNULLTerminated(&ClassNameString, ClassName);
-      if (! NT_SUCCESS(Status))
-        {
-          if (NULL != ParentWindow)
-            {
-              IntReleaseWindowObject(ParentWindow);
-            }
-          return NULL;
-        }
-      ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassNameString, hInstance);
-      IntFreeNULLTerminatedFromUnicodeString(ClassNameString, ClassName);
-    }
+  ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName->Buffer, hInstance);
   if (!ClassFound)
   {
      if (IS_ATOM(ClassName->Buffer))
@@ -1486,6 +1457,7 @@
      {
         IntReleaseWindowObject(ParentWindow);
      }
+     SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
      return((HWND)0);
   }
 
@@ -2045,7 +2017,7 @@
     }
   if (! IS_ATOM(ClassName.Buffer))
     {
-      Status = IntSafeCopyUnicodeString(&ClassName, UnsafeClassName);
+      Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
       if (! NT_SUCCESS(Status))
         {
           SetLastNtError(Status);
@@ -2111,6 +2083,8 @@
 {
   PWINDOW_OBJECT Window;
   BOOLEAN isChild;
+  
+  DbgPrint("DestroyWindow:0x%x\n", Wnd);
 
   Window = IntGetWindowObject(Wnd);
   if (Window == NULL)
@@ -2453,7 +2427,7 @@
         DPRINT1("Window class not found (%lx)\n", (ULONG_PTR)ClassName.Buffer);
       else
         DPRINT1("Window class not found (%S)\n", ClassName.Buffer);
-      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+      SetLastWin32Error(ERROR_FILE_NOT_FOUND);
       goto Cleanup;
     }
   }

reactos/subsys/win32k/ntuser
winpos.c 1.124 -> 1.125
diff -u -r1.124 -r1.125
--- winpos.c	21 Nov 2004 12:14:34 -0000	1.124
+++ winpos.c	11 Dec 2004 19:39:18 -0000	1.125
@@ -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.124 2004/11/21 12:14:34 navaraf Exp $
+/* $Id: winpos.c,v 1.125 2004/12/11 19:39:18 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -1321,7 +1321,8 @@
 
   /* FIXME: Check for window destruction. */
 
-  if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
+  if ((Window->Flags & WINDOWOBJECT_NEED_SIZE) &&
+      !(Window->Status & WINDOWSTATUS_DESTROYING))
     {
       WPARAM wParam = SIZE_RESTORED;
 
CVSspam 0.2.8