8 modified files
reactos/iface/addsys
diff -u -r1.47 -r1.48
--- w32ksvc.db 8 Feb 2004 21:37:51 -0000 1.47
+++ w32ksvc.db 11 Mar 2004 14:47:43 -0000 1.48
@@ -473,6 +473,7 @@
NtUserSendInput 3
NtUserSendMessage 5
NtUserSendMessageCallback 6
+NtUserSendMessageTimeout 8
NtUserSendNotifyMessage 4
NtUserSetActiveWindow 1
NtUserSetCapture 1
reactos/include
diff -u -r1.81 -r1.82
--- defines.h 10 Mar 2004 15:22:43 -0000 1.81
+++ defines.h 11 Mar 2004 14:47:43 -0000 1.82
@@ -2084,6 +2084,13 @@
/* InitializeSecurityDescriptor */
#define SECURITY_DESCRIPTOR_REVISION (1)
+/* InSendMessageEx */
+#define ISMEX_NOSEND (0)
+#define ISMEX_SEND (1)
+#define ISMEX_NOTIFY (2)
+#define ISMEX_CALLBACK (4)
+#define ISMEX_REPLIED (8)
+
/* JournalPlaybackProc, KeyboardProc */
#define HC_GETNEXT (1)
#define HC_SKIP (2)
reactos/include
diff -u -r1.9 -r1.10
--- errors.h 25 Aug 2003 01:37:47 -0000 1.9
+++ errors.h 11 Mar 2004 14:47:43 -0000 1.10
@@ -570,6 +570,8 @@
#define ERROR_PAGEFILE_QUOTA 1454L
#define ERROR_COMMITMENT_LIMIT 1455L
#define ERROR_MENU_ITEM_NOT_FOUND 1456L
+#define ERROR_TIMEOUT 1460L
+#define ERROR_INVALID_MONITOR_HANDLE 1461L
#define ERROR_EVENTLOG_FILE_CORRUPT 1500L
#define ERROR_EVENTLOG_CANT_START 1501L
#define ERROR_LOG_FILE_FULL 1502L
reactos/include/win32k
diff -u -r1.117 -r1.118
--- ntuser.h 15 Feb 2004 07:39:12 -0000 1.117
+++ ntuser.h 11 Mar 2004 14:47:43 -0000 1.118
@@ -783,10 +783,12 @@
DWORD dwThreadId,
DWORD Unknown1);
+#define THREADSTATE_FOCUSWINDOW (1)
+#define THREADSTATE_INSENDMESSAGE (2)
DWORD
STDCALL
NtUserGetThreadState(
- DWORD Unknown0);
+ DWORD Routine);
DWORD
STDCALL
@@ -1167,6 +1169,16 @@
SENDASYNCPROC lpCallBack,
ULONG_PTR dwData);
+LRESULT STDCALL
+NtUserSendMessageTimeout(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ UINT uFlags,
+ UINT uTimeout,
+ ULONG_PTR *uResult,
+ PNTUSERSENDMESSAGEINFO Info);
+
BOOL
STDCALL
NtUserSendNotifyMessage(
reactos/lib/user32/windows
diff -u -r1.35 -r1.36
--- message.c 28 Jan 2004 20:54:30 -0000 1.35
+++ message.c 11 Mar 2004 14:47:43 -0000 1.36
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.35 2004/01/28 20:54:30 gvg Exp $
+/* $Id: message.c,v 1.36 2004/03/11 14:47:43 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@@ -54,6 +54,8 @@
STDCALL
InSendMessage(VOID)
{
+ /* return(NtUserGetThreadState(THREADSTATE_INSENDMESSAGE) != ISMEX_NOSEND); */
+ UNIMPLEMENTED;
return FALSE;
}
@@ -66,6 +68,7 @@
InSendMessageEx(
LPVOID lpReserved)
{
+ /* return NtUserGetThreadState(THREADSTATE_INSENDMESSAGE); */
UNIMPLEMENTED;
return 0;
}
@@ -834,8 +837,64 @@
UINT uTimeout,
PDWORD_PTR lpdwResult)
{
- UNIMPLEMENTED;
- return (LRESULT)0;
+ MSG AnsiMsg;
+ MSG UcMsg;
+ LRESULT Result;
+ NTUSERSENDMESSAGEINFO Info;
+
+ AnsiMsg.hwnd = hWnd;
+ AnsiMsg.message = Msg;
+ AnsiMsg.wParam = wParam;
+ AnsiMsg.lParam = lParam;
+ if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
+ {
+ return FALSE;
+ }
+
+ Info.Ansi = TRUE;
+ Result = NtUserSendMessageTimeout(UcMsg.hwnd, UcMsg.message,
+ UcMsg.wParam, UcMsg.lParam,
+ fuFlags, uTimeout, (ULONG_PTR*)lpdwResult, &Info);
+ if(!Result)
+ {
+ return FALSE;
+ }
+ if (! Info.HandledByKernel)
+ {
+ /* We need to send the message ourselves */
+ if (Info.Ansi)
+ {
+ /* Ansi message and Ansi window proc, that's easy. Clean up
+ the Unicode message though */
+ MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
+ Result = IntCallWindowProcA(Info.Ansi, Info.Proc, hWnd, Msg, wParam, lParam);
+ }
+ else
+ {
+ /* Unicode winproc. Although we started out with an Ansi message we
+ already converted it to Unicode for the kernel call. Reuse that
+ message to avoid another conversion */
+ Result = IntCallWindowProcW(Info.Ansi, Info.Proc, UcMsg.hwnd,
+ UcMsg.message, UcMsg.wParam, UcMsg.lParam);
+ if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
+ {
+ return FALSE;
+ }
+ }
+ if(lpdwResult)
+ *lpdwResult = Result;
+ Result = TRUE;
+ }
+ else
+ {
+ /* Message sent by kernel. Convert back to Ansi */
+ if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
+ {
+ return FALSE;
+ }
+ }
+
+ return Result;
}
@@ -853,8 +912,22 @@
UINT uTimeout,
PDWORD_PTR lpdwResult)
{
- UNIMPLEMENTED;
- return (LRESULT)0;
+ NTUSERSENDMESSAGEINFO Info;
+ LRESULT Result;
+
+ Info.Ansi = FALSE;
+ Result = NtUserSendMessageTimeout(hWnd, Msg, wParam, lParam, fuFlags, uTimeout,
+ lpdwResult, &Info);
+ if (! Info.HandledByKernel)
+ {
+ /* We need to send the message ourselves */
+ Result = IntCallWindowProcW(Info.Ansi, Info.Proc, hWnd, Msg, wParam, lParam);
+ if(lpdwResult)
+ *lpdwResult = Result;
+ return TRUE;
+ }
+
+ return Result;
}
reactos/subsys/win32k/include
diff -u -r1.28 -r1.29
--- msgqueue.h 28 Feb 2004 00:44:28 -0000 1.28
+++ msgqueue.h 11 Mar 2004 14:47:44 -0000 1.29
@@ -6,6 +6,8 @@
#include "caret.h"
#include "hook.h"
+#define MSQ_HUNG 5000
+
typedef struct _USER_MESSAGE
{
LIST_ENTRY ListEntry;
@@ -59,8 +61,8 @@
ULONG QuitExitCode;
/* Set if there are new messages in any of the queues. */
KEVENT NewMessages;
- /* FIXME: Unknown. */
- ULONG QueueStatus;
+ /* Last time PeekMessage() was called. */
+ ULONG LastMsgRead;
/* Current window with focus (ie. receives keyboard input) for this queue. */
HWND FocusWindow;
/* True if a window needs painting. */
@@ -94,9 +96,12 @@
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
-LRESULT FASTCALL
+BOOL FASTCALL
+MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
+NTSTATUS FASTCALL
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+ HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
+ UINT uTimeout, BOOL Block, ULONG_PTR *uResult);
VOID FASTCALL
MsqInitializeMessage(PUSER_MESSAGE Message,
LPMSG Msg);
@@ -147,6 +152,14 @@
UINT Msg,
WPARAM wParam,
LPARAM lParam);
+LRESULT STDCALL
+IntSendMessageTimeout(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ UINT uFlags,
+ UINT uTimeout,
+ ULONG_PTR *uResult);
LRESULT FASTCALL
IntDispatchMessage(MSG* Msg);
BOOL FASTCALL
reactos/subsys/win32k/ntuser
diff -u -r1.52 -r1.53
--- message.c 24 Feb 2004 13:27:03 -0000 1.52
+++ message.c 11 Mar 2004 14:47:44 -0000 1.53
@@ -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.52 2004/02/24 13:27:03 weiden Exp $
+/* $Id: message.c,v 1.53 2004/03/11 14:47:44 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -47,6 +47,13 @@
#define NDEBUG
#include <debug.h>
+typedef struct
+{
+ UINT uFlags;
+ UINT uTimeout;
+ ULONG_PTR uResult;
+} DOSENDMESSAGE, *PDOSENDMESSAGE;
+
/* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL
@@ -235,6 +242,7 @@
UINT MsgFilterMax,
UINT RemoveMsg)
{
+ LARGE_INTEGER LargeTickCount;
PUSER_MESSAGE_QUEUE ThreadQueue;
BOOLEAN Present;
PUSER_MESSAGE Message;
@@ -244,6 +252,9 @@
article on GetMessage() */
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
+
+ KeQueryTickCount(&LargeTickCount);
+ ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
/* Inspect RemoveMsg flags */
/* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
@@ -706,11 +717,29 @@
LRESULT STDCALL
IntSendMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ LRESULT Result = 0;
+ if(IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
+ {
+ return Result;
+ }
+ return 0;
+}
+
+LRESULT STDCALL
+IntSendMessageTimeout(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ UINT uFlags,
+ UINT uTimeout,
+ ULONG_PTR *uResult)
{
LRESULT Result;
+ NTSTATUS Status;
PWINDOW_OBJECT Window;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
@@ -724,7 +753,7 @@
if (!Window)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return 0;
+ return FALSE;
}
Win32Thread = PsGetWin32Thread();
@@ -736,7 +765,7 @@
{
/* Never send messages to exiting threads */
IntReleaseWindowObject(Window);
- return 0;
+ return FALSE;
}
/* See if this message type is present in the table */
@@ -754,7 +783,7 @@
{
IntReleaseWindowObject(Window);
DPRINT1("Failed to pack message parameters\n");
- return -1;
+ return FALSE;
}
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
{
@@ -770,17 +799,37 @@
{
IntReleaseWindowObject(Window);
DPRINT1("Failed to unpack message parameters\n");
- return Result;
+ if(uResult)
+ *uResult = Result;
+ return TRUE;
}
IntReleaseWindowObject(Window);
- return Result;
+ if(uResult)
+ *uResult = Result;
+ return TRUE;
}
- Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam);
+ if(uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue))
+ {
+ IntReleaseWindowObject(Window);
+ /* FIXME - Set a LastError? */
+ return FALSE;
+ }
+
+ Status = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam,
+ (uFlags & SMTO_BLOCK), uTimeout, &Result);
+ if(Status == STATUS_TIMEOUT)
+ {
+ IntReleaseWindowObject(Window);
+ SetLastWin32Error(ERROR_TIMEOUT);
+ return FALSE;
+ }
IntReleaseWindowObject(Window);
- return Result;
+ if(uResult)
+ *uResult = Result;
+ return TRUE;
}
static NTSTATUS FASTCALL
@@ -878,12 +927,13 @@
return STATUS_SUCCESS;
}
-LRESULT STDCALL
-NtUserSendMessage(HWND Wnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- PNTUSERSENDMESSAGEINFO UnsafeInfo)
+LRESULT FASTCALL
+IntDoSendMessage(HWND Wnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ PDOSENDMESSAGE dsm,
+ PNTUSERSENDMESSAGEINFO UnsafeInfo)
{
LRESULT Result;
NTSTATUS Status;
@@ -957,16 +1007,25 @@
{
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return -1;
+ return (dsm ? 0 : -1);
}
- Result = IntSendMessage(KernelModeMsg.hwnd, KernelModeMsg.message,
- KernelModeMsg.wParam, KernelModeMsg.lParam);
+ if(!dsm)
+ {
+ Result = IntSendMessage(KernelModeMsg.hwnd, KernelModeMsg.message,
+ KernelModeMsg.wParam, KernelModeMsg.lParam);
+ }
+ else
+ {
+ Result = IntSendMessageTimeout(KernelModeMsg.hwnd, KernelModeMsg.message,
+ KernelModeMsg.wParam, KernelModeMsg.lParam,
+ dsm->uFlags, dsm->uTimeout, &dsm->uResult);
+ }
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
{
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return -1;
+ return(dsm ? 0 : -1);
}
}
@@ -979,6 +1038,46 @@
return Result;
}
+LRESULT STDCALL
+NtUserSendMessageTimeout(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ UINT uFlags,
+ UINT uTimeout,
+ ULONG_PTR *uResult,
+ PNTUSERSENDMESSAGEINFO UnsafeInfo)
+{
+ DOSENDMESSAGE dsm;
+ LRESULT Result;
+
+ dsm.uFlags = uFlags;
+ dsm.uTimeout = uTimeout;
+ Result = IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
+ if(uResult)
+ {
+ NTSTATUS Status;
+
+ Status = MmCopyToCaller(uResult, &dsm.uResult, sizeof(ULONG_PTR));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ }
+ return Result;
+}
+
+LRESULT STDCALL
+NtUserSendMessage(HWND Wnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ PNTUSERSENDMESSAGEINFO UnsafeInfo)
+{
+ return IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo);
+}
+
BOOL STDCALL
NtUserSendMessageCallback(HWND hWnd,
UINT Msg,
reactos/subsys/win32k/ntuser
diff -u -r1.74 -r1.75
--- msgqueue.c 28 Feb 2004 00:44:28 -0000 1.74
+++ msgqueue.c 11 Mar 2004 14:47:44 -0000 1.75
@@ -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.74 2004/02/28 00:44:28 weiden Exp $
+/* $Id: msgqueue.c,v 1.75 2004/03/11 14:47:44 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -889,16 +889,17 @@
IntUnLockMessageQueue(MessageQueue);
}
-LRESULT FASTCALL
+NTSTATUS FASTCALL
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+ HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
+ UINT uTimeout, BOOL Block, ULONG_PTR *uResult)
{
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
- PVOID WaitObjects[2];
NTSTATUS WaitStatus;
LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue;
+ LARGE_INTEGER Timeout;
KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
@@ -914,24 +915,44 @@
IntLockMessageQueue(MessageQueue);
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
- KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
IntUnLockMessageQueue(MessageQueue);
-
+ KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+
+ Timeout.QuadPart = uTimeout * -10000;
+
ThreadQueue = PsGetWin32Thread()->MessageQueue;
- WaitObjects[1] = &ThreadQueue->NewMessages;
- WaitObjects[0] = &CompletionEvent;
- do
- {
- WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
- UserMode, TRUE, NULL, NULL);
- while (MsqDispatchOneSentMessage(ThreadQueue))
- {
- ;
- }
- }
- while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
-
- return (STATUS_WAIT_0 == WaitStatus ? Result : -1);
+ if(Block)
+ {
+ /* don't process messages sent to the thread */
+ WaitStatus = KeWaitForSingleObject(&CompletionEvent, UserRequest, UserMode,
+ FALSE, (uTimeout ? &Timeout : NULL));
+ }
+ else
+ {
+ PVOID WaitObjects[2];
+
+ WaitObjects[0] = &CompletionEvent;
+ WaitObjects[1] = &ThreadQueue->NewMessages;
+ do
+ {
+ WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
+ UserMode, FALSE, (uTimeout ? &Timeout : NULL), NULL);
+ if(WaitStatus == STATUS_TIMEOUT)
+ {DbgPrint("MsqSendMessage timed out\n");
+ break;
+ }
+ while (MsqDispatchOneSentMessage(ThreadQueue))
+ {
+ ;
+ }
+ }
+ while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
+ }
+
+ if(WaitStatus != STATUS_TIMEOUT)
+ *uResult = (STATUS_WAIT_0 == WaitStatus ? Result : -1);
+
+ return WaitStatus;
}
VOID FASTCALL
@@ -1014,9 +1035,20 @@
NULL));
}
+BOOL FASTCALL
+MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue)
+{
+ LARGE_INTEGER LargeTickCount;
+
+ KeQueryTickCount(&LargeTickCount);
+ return ((LargeTickCount.u.LowPart - MessageQueue->LastMsgRead) > MSQ_HUNG);
+}
+
VOID FASTCALL
MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue)
{
+ LARGE_INTEGER LargeTickCount;
+
MessageQueue->Thread = Thread;
MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1);
InitializeListHead(&MessageQueue->PostedMessagesListHead);
@@ -1027,7 +1059,8 @@
MessageQueue->QuitPosted = FALSE;
MessageQueue->QuitExitCode = 0;
KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE);
- MessageQueue->QueueStatus = 0;
+ KeQueryTickCount(&LargeTickCount);
+ MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
MessageQueue->FocusWindow = NULL;
MessageQueue->PaintPosted = FALSE;
MessageQueue->PaintCount = 0;
CVSspam 0.2.8