7 modified files
reactos/subsys/win32k/include
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
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
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
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
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
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
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