1 added + 13 modified, total 14 files
reactos/include/win32k
diff -u -r1.128 -r1.129
--- ntuser.h 29 Apr 2004 20:26:34 -0000 1.128
+++ ntuser.h 29 Apr 2004 21:13:15 -0000 1.129
@@ -384,9 +384,17 @@
BOOLEAN STDCALL
NtUserDestroyWindow(HWND Wnd);
+typedef struct tagNTUSERDISPATCHMESSAGEINFO
+{
+ BOOL HandledByKernel;
+ BOOL Ansi;
+ WNDPROC Proc;
+ MSG Msg;
+} NTUSERDISPATCHMESSAGEINFO, *PNTUSERDISPATCHMESSAGEINFO;
+
LRESULT
STDCALL
-NtUserDispatchMessage(CONST MSG* lpmsg);
+NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO MsgInfo);
BOOL
STDCALL
@@ -734,10 +742,16 @@
NtUserGetListBoxInfo(
DWORD Unknown0);
+typedef struct tagNTUSERGETMESSAGEINFO
+{
+ MSG Msg;
+ ULONG LParamSize;
+} NTUSERGETMESSAGEINFO, *PNTUSERGETMESSAGEINFO;
+
BOOL
STDCALL
NtUserGetMessage(
- LPMSG lpMsg,
+ PNTUSERGETMESSAGEINFO MsgInfo,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax);
@@ -1036,7 +1050,7 @@
BOOL
STDCALL
NtUserPeekMessage(
- LPMSG lpMsg,
+ PNTUSERGETMESSAGEINFO MsgInfo,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
@@ -1717,6 +1731,28 @@
LONG idObject,
SETSCROLLBARINFO *info);
+/* lParam of DDE messages */
+typedef struct tagKMDDEEXECUTEDATA
+{
+ HWND Sender;
+ HGLOBAL ClientMem;
+ /* BYTE Data[DataSize] */
+} KMDDEEXECUTEDATA, *PKMDDEEXECUTEDATA;
+
+typedef struct tagKMDDELPARAM
+{
+ BOOL Packed;
+ union
+ {
+ struct
+ {
+ UINT uiLo;
+ UINT uiHi;
+ } Packed;
+ LPARAM Unpacked;
+ } Value;
+} KMDDELPARAM, *PKMDDELPARAM;
+
#endif /* __WIN32K_NTUSER_H */
/* EOF */
reactos/lib/user32/include
diff -N message.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ message.h 29 Apr 2004 21:13:16 -0000 1.1
@@ -0,0 +1,14 @@
+/* $Id: message.h,v 1.1 2004/04/29 21:13:16 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS user32.dll
+ * FILE: include/message.h
+ * PURPOSE: Message management definitions
+ */
+
+#ifndef LIB_USER32_INCLUDE_MESSAGE_H
+#define LIB_USER32_INCLUDE_MESSAGE_H
+
+BOOL FASTCALL MessageInit(VOID);
+
+#endif /* LIB_USER32_INCLUDE_MESSAGE_H */
reactos/lib/user32/misc
diff -u -r1.1 -r1.2
--- ddeclient.c 8 Dec 2003 18:21:24 -0000 1.1
+++ ddeclient.c 29 Apr 2004 21:13:16 -0000 1.2
@@ -1340,7 +1340,7 @@
}
return (IsWindowUnicode(hwnd)) ?
- DefWindowProcA(hwnd, iMsg, wParam, lParam) : DefWindowProcW(hwnd, iMsg, wParam, lParam);
+ DefWindowProcW(hwnd, iMsg, wParam, lParam) : DefWindowProcA(hwnd, iMsg, wParam, lParam);
}
/*****************************************************************
reactos/lib/user32/misc
diff -u -r1.1 -r1.2
--- ddeserver.c 8 Dec 2003 18:21:24 -0000 1.1
+++ ddeserver.c 29 Apr 2004 21:13:16 -0000 1.2
@@ -994,7 +994,8 @@
}
if (iMsg < WM_DDE_FIRST || iMsg > WM_DDE_LAST)
{
- return DefWindowProcA(hwndServer, iMsg, wParam, lParam);
+ return IsWindowUnicode(hwndServer) ? DefWindowProcW(hwndServer, iMsg, wParam, lParam) :
+ DefWindowProcA(hwndServer, iMsg, wParam, lParam);
}
EnterCriticalSection(&WDML_CritSect);
reactos/lib/user32/misc
diff -u -r1.39 -r1.40
--- dllmain.c 9 Apr 2004 21:22:18 -0000 1.39
+++ dllmain.c 29 Apr 2004 21:13:16 -0000 1.40
@@ -6,6 +6,7 @@
#include <user32/accel.h>
#include <window.h>
#include <menu.h>
+#include <message.h>
#define _WIN32K_KAPI_H
#include <user32.h>
#include <strpool.h>
@@ -73,6 +74,7 @@
User32TlsIndex = TlsAlloc();
MenuInit();
+ MessageInit();
InitializeCriticalSection(&U32AccelCacheLock);
InitializeCriticalSection(&gcsMPH);
reactos/lib/user32/windows
diff -u -r1.38 -r1.39
--- message.c 10 Apr 2004 00:54:35 -0000 1.38
+++ message.c 29 Apr 2004 21:13:16 -0000 1.39
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.38 2004/04/10 00:54:35 navaraf Exp $
+/* $Id: message.c,v 1.39 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@@ -12,96 +12,329 @@
#include <user32.h>
#include <string.h>
#include <debug.h>
+#include <user32/callback.h>
+#include <message.h>
#define NTOS_MODE_USER
#include <ntos.h>
-/*
- * @implemented
- */
-LPARAM
-STDCALL
-GetMessageExtraInfo(VOID)
-{
- return (LPARAM)NtUserCallNoParam(NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO);
-}
+/* DDE message exchange
+ *
+ * - Session initialization
+ * Client sends a WM_DDE_INITIATE message, usually a broadcast message. lParam of
+ * this message contains a pair of global atoms, the Application and Topic atoms.
+ * The client must destroy the atoms.
+ * Server window proc handles the WM_DDE_INITIATE message and if the Application
+ * and Topic atoms are recognized sends a WM_DDE_ACK message to the client. lParam
+ * of the reply message contains another pair of global atoms (Application and
+ * Topic again), which must be destroyed by the server.
+ *
+ * - Execute
+ * Client posts a WM_DDE_EXECUTE message to the server window. lParam of that message
+ * is a global memory handle containing the string to execute. After the command has
+ * been executed the server posts a WM_DDE_ACK message to the client, which contains
+ * a packed lParam which in turn contains that global memory handle. The client takes
+ * ownership of both the packed lParam (meaning it needs to call FreeDDElParam() on
+ * it and the global memory handle.
+ * This might work nice and easy in Win3.1, but things are more complicated for NT.
+ * Global memory handles in NT are not really global, they're still local to the
+ * process. So, what happens under the hood is that PostMessage must handle the
+ * WM_DDE_EXECUTE message specially. It will obtain the contents of the global memory
+ * area, repack that into a new structure together with the original memory handle
+ * and pass that off to the win32k. Win32k will marshall that data over to the target
+ * (server) process where it will be unpacked and stored in a newly allocated global
+ * memory area. The handle of that area will then be sent to the window proc, after
+ * storing it together with the "original" (client) handle in a table.
+ * The server will eventually post the WM_DDE_ACK response, containing the global
+ * memory handle it received. PostMessage must then lookup that memory handle (only
+ * valid in the server process) and replace it with the corresponding client memory
+ * handle. To avoid memory leaks, the server-side global memory block must be freed.
+ * Also, the WM_DDE_ACK lParam (a PackDDElParam() result) is unpacked and the
+ * individual components are handed to win32k.sys to post to the client side. Since
+ * the server side app hands over ownership of the packed lParam when it calls
+ * PostMessage(), the packed lParam needs to be freed on the server side too.
+ * When the WM_DDE_ACK message (containing the client-side global memory handle)
+ * arrives at the client side a new lParam is PackDDElParam()'ed and this is handed
+ * to the client side window proc which is expected to free/reuse it.
+ */
+
+/* since the WM_DDE_ACK response to a WM_DDE_EXECUTE message should contain the handle
+ * to the memory handle, we keep track (in the server side) of all pairs of handle
+ * used (the client passes its value and the content of the memory handle), and
+ * the server stored both values (the client, and the local one, created after the
+ * content). When a ACK message is generated, the list of pair is searched for a
+ * matching pair, so that the client memory handle can be returned.
+ */
+typedef struct tagDDEPAIR
+{
+ HGLOBAL ClientMem;
+ HGLOBAL ServerMem;
+} DDEPAIR, *PDDEPAIR;
+
+static PDDEPAIR DdePairs = NULL;
+static unsigned DdeNumAlloc = 0;
+static unsigned DdeNumUsed = 0;
+static CRITICAL_SECTION DdeCrst;
+
+static BOOL FASTCALL
+DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
+{
+ unsigned i;
+
+ EnterCriticalSection(&DdeCrst);
+
+ /* now remember the pair of hMem on both sides */
+ if (DdeNumUsed == DdeNumAlloc)
+ {
+#define GROWBY 4
+ PDDEPAIR New;
+ if (NULL != DdePairs)
+ {
+ New = HeapReAlloc(GetProcessHeap(), 0, DdePairs,
+ (DdeNumAlloc + GROWBY) * sizeof(DDEPAIR));
+ }
+ else
+ {
+ New = HeapAlloc(GetProcessHeap(), 0,
+ (DdeNumAlloc + GROWBY) * sizeof(DDEPAIR));
+ }
+ if (NULL == New)
+ {
+ LeaveCriticalSection(&DdeCrst);
+ return FALSE;
+ }
+ DdePairs = New;
+ /* zero out newly allocated part */
+ memset(&DdePairs[DdeNumAlloc], 0, GROWBY * sizeof(DDEPAIR));
+ DdeNumAlloc += GROWBY;
+#undef GROWBY
+ }
-/*
- * @implemented
- */
-DWORD
-STDCALL
-GetMessagePos(VOID)
-{
- PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
- return(MAKELONG(ThreadData->LastMessage.pt.x, ThreadData->LastMessage.pt.y));
-}
+ for (i = 0; i < DdeNumAlloc; i++)
+ {
+ if (NULL == DdePairs[i].ServerMem)
+ {
+ DdePairs[i].ClientMem = ClientMem;
+ DdePairs[i].ServerMem = ServerMem;
+ DdeNumUsed++;
+ break;
+ }
+ }
+ LeaveCriticalSection(&DdeCrst);
+ return TRUE;
+}
-/*
- * @implemented
- */
-LONG STDCALL
-GetMessageTime(VOID)
+static HGLOBAL FASTCALL
+DdeGetPair(HGLOBAL ServerMem)
{
- PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
- return(ThreadData->LastMessage.time);
-}
+ unsigned i;
+ HGLOBAL Ret = NULL;
+ EnterCriticalSection(&DdeCrst);
+ for (i = 0; i < DdeNumAlloc; i++)
+ {
+ if (DdePairs[i].ServerMem == ServerMem)
+ {
+ /* free this pair */
+ DdePairs[i].ServerMem = 0;
+ DdeNumUsed--;
+ Ret = DdePairs[i].ClientMem;
+ break;
+ }
+ }
+ LeaveCriticalSection(&DdeCrst);
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-InSendMessage(VOID)
-{
- /* return(NtUserGetThreadState(THREADSTATE_INSENDMESSAGE) != ISMEX_NOSEND); */
- UNIMPLEMENTED;
- return FALSE;
+ return Ret;
}
-
-/*
- * @unimplemented
- */
-DWORD
-STDCALL
-InSendMessageEx(
- LPVOID lpReserved)
+static BOOL FASTCALL
+MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
{
- /* return NtUserGetThreadState(THREADSTATE_INSENDMESSAGE); */
- UNIMPLEMENTED;
- return 0;
+ *KMMsg = *UMMsg;
+
+ switch (UMMsg->message)
+ {
+ case WM_DDE_ACK:
+ {
+ PKMDDELPARAM DdeLparam;
+ DdeLparam = HeapAlloc(GetProcessHeap(), 0, sizeof(KMDDELPARAM));
+ if (NULL == DdeLparam)
+ {
+ return FALSE;
+ }
+ if (Posted)
+ {
+ DdeLparam->Packed = TRUE;
+ if (! UnpackDDElParam(UMMsg->message, UMMsg->lParam,
+ &DdeLparam->Value.Packed.uiLo,
+ &DdeLparam->Value.Packed.uiHi))
+ {
+ return FALSE;
+ }
+ if (0 != HIWORD(DdeLparam->Value.Packed.uiHi))
+ {
+ /* uiHi should contain a hMem from WM_DDE_EXECUTE */
+ HGLOBAL h = DdeGetPair((HGLOBAL) DdeLparam->Value.Packed.uiHi);
+ if (NULL != h)
+ {
+ GlobalFree((HGLOBAL) DdeLparam->Value.Packed.uiHi);
+ DdeLparam->Value.Packed.uiHi = (UINT) h;
+ }
+ }
+ FreeDDElParam(UMMsg->message, UMMsg->lParam);
+ }
+ else
+ {
+ DdeLparam->Packed = FALSE;
+ DdeLparam->Value.Unpacked = UMMsg->lParam;
+ }
+ KMMsg->lParam = (LPARAM) DdeLparam;
+ }
+ break;
+ case WM_DDE_EXECUTE:
+ {
+ SIZE_T Size;
+ PKMDDEEXECUTEDATA KMDdeExecuteData;
+ PVOID Data;
+
+ Size = GlobalSize((HGLOBAL) UMMsg->lParam);
+ Data = GlobalLock((HGLOBAL) UMMsg->lParam);
+ if (NULL == Data)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ KMDdeExecuteData = HeapAlloc(GetProcessHeap(), 0, sizeof(KMDDEEXECUTEDATA) + Size);
+ if (NULL == KMDdeExecuteData)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+ KMDdeExecuteData->Sender = (HWND) UMMsg->wParam;
+ KMDdeExecuteData->ClientMem = (HGLOBAL) UMMsg->lParam;
+ memcpy((PVOID) (KMDdeExecuteData + 1), Data, Size);
+ KMMsg->wParam = sizeof(KMDDEEXECUTEDATA) + Size;
+ KMMsg->lParam = (LPARAM) KMDdeExecuteData;
+ GlobalUnlock((HGLOBAL) UMMsg->lParam);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
}
+static VOID FASTCALL
+MsgiUMToKMCleanup(PMSG UMMsg, PMSG KMMsg)
+{
+ switch (KMMsg->message)
+ {
+ case WM_DDE_ACK:
+ case WM_DDE_EXECUTE:
+ HeapFree(GetProcessHeap(), 0, (LPVOID) KMMsg->lParam);
+ break;
+ default:
+ break;
+ }
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-ReplyMessage(
- LRESULT lResult)
+ return;
+}
+
+static BOOL FASTCALL
+MsgiUMToKMReply(PMSG UMMsg, PMSG KMMsg, LRESULT *Result)
{
- UNIMPLEMENTED;
- return FALSE;
+ MsgiUMToKMCleanup(UMMsg, KMMsg);
+
+ return TRUE;
}
+static BOOL FASTCALL
+MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg)
+{
+ *UMMsg = *KMMsg;
-/*
- * @implemented
- */
-LPARAM
-STDCALL
-SetMessageExtraInfo(
- LPARAM lParam)
+ switch (UMMsg->message)
+ {
+ case WM_DDE_ACK:
+ {
+ PKMDDELPARAM DdeLparam = (PKMDDELPARAM) KMMsg->lParam;
+ if (DdeLparam->Packed)
+ {
+ UMMsg->lParam = PackDDElParam(KMMsg->message,
+ DdeLparam->Value.Packed.uiLo,
+ DdeLparam->Value.Packed.uiHi);
+ }
+ else
+ {
+ UMMsg->lParam = DdeLparam->Value.Unpacked;
+ }
+ break;
+ }
+ case WM_DDE_EXECUTE:
+ {
+ PKMDDEEXECUTEDATA KMDdeExecuteData;
+ HGLOBAL GlobalData;
+ PVOID Data;
+
+ KMDdeExecuteData = (PKMDDEEXECUTEDATA) KMMsg->lParam;
+ GlobalData = GlobalAlloc(GMEM_MOVEABLE, KMMsg->wParam - sizeof(KMDDEEXECUTEDATA));
+ if (NULL == GlobalData)
+ {
+ return FALSE;
+ }
+ Data = GlobalLock(GlobalData);
+ if (NULL == Data)
+ {
+ GlobalFree(GlobalData);
+ return FALSE;
+ }
+ memcpy(Data, (PVOID) (KMDdeExecuteData + 1), KMMsg->wParam - sizeof(KMDDEEXECUTEDATA));
+ GlobalUnlock(GlobalData);
+ if (! DdeAddPair(KMDdeExecuteData->ClientMem, GlobalData))
+ {
+ GlobalFree(GlobalData);
+ return FALSE;
+ }
+ UMMsg->wParam = (WPARAM) KMDdeExecuteData->Sender;
+ UMMsg->lParam = (LPARAM) GlobalData;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static VOID FASTCALL
+MsgiKMToUMCleanup(PMSG KMMsg, PMSG UMMsg)
{
- return NtUserSetMessageExtraInfo(lParam);
+ switch (KMMsg->message)
+ {
+ case WM_DDE_EXECUTE:
+#ifdef TODO
+ HeapFree(GetProcessHeap(), 0, (LPVOID) KMMsg->lParam);
+ GlobalUnlock((HGLOBAL) UMMsg->lParam);
+#endif
+ break;
+ default:
+ break;
+ }
+
+ return;
}
+static BOOL FASTCALL
+MsgiKMToUMReply(PMSG KMMsg, PMSG UMMsg, LRESULT *Result)
+{
+ MsgiKMToUMCleanup(KMMsg, UMMsg);
+
+ return TRUE;
+}
-BOOL
+static BOOL FASTCALL
MsgiAnsiToUnicodeMessage(LPMSG UnicodeMsg, LPMSG AnsiMsg)
{
*UnicodeMsg = *AnsiMsg;
@@ -196,7 +429,7 @@
}
-BOOL
+static BOOL FASTCALL
MsgiAnsiToUnicodeCleanup(LPMSG UnicodeMsg, LPMSG AnsiMsg)
{
switch (AnsiMsg->message)
@@ -269,7 +502,7 @@
}
-BOOL
+static BOOL FASTCALL
MsgiAnsiToUnicodeReply(LPMSG UnicodeMsg, LPMSG AnsiMsg, LRESULT *Result)
{
switch (AnsiMsg->message)
@@ -304,104 +537,341 @@
}
-VOID STATIC
-User32ConvertToAsciiMessage(UINT* Msg, WPARAM* wParam, LPARAM* lParam)
+static BOOL FASTCALL
+MsgiUnicodeToAnsiMessage(LPMSG AnsiMsg, LPMSG UnicodeMsg)
{
- switch((*Msg))
+ *AnsiMsg = *UnicodeMsg;
+
+ switch(UnicodeMsg->message)
{
- case WM_CREATE:
- case WM_NCCREATE:
- {
- CREATESTRUCTA* CsA;
- CREATESTRUCTW* CsW;
- UNICODE_STRING UString;
- ANSI_STRING AString;
-
- CsW = (CREATESTRUCTW*)(*lParam);
- CsA = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(CREATESTRUCTA));
- memcpy(CsA, CsW, sizeof(CREATESTRUCTW));
-
- RtlInitUnicodeString(&UString, CsW->lpszName);
- RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
- CsA->lpszName = AString.Buffer;
- if (HIWORD((ULONG)CsW->lpszClass) != 0)
- {
- RtlInitUnicodeString(&UString, CsW->lpszClass);
- RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
- CsA->lpszClass = AString.Buffer;
- }
- (*lParam) = (LPARAM)CsA;
- break;
- }
- case WM_SETTEXT:
- {
- ANSI_STRING AnsiString;
- UNICODE_STRING UnicodeString;
- RtlInitUnicodeString(&UnicodeString, (PWSTR) *lParam);
- if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString,
- &UnicodeString,
- TRUE)))
- {
- *lParam = (LPARAM) AnsiString.Buffer;
- }
- break;
- }
+ case WM_CREATE:
+ case WM_NCCREATE:
+ {
+ CREATESTRUCTA* CsA;
+ CREATESTRUCTW* CsW;
+ UNICODE_STRING UString;
+ ANSI_STRING AString;
+ NTSTATUS Status;
+
+ CsW = (CREATESTRUCTW*)(UnicodeMsg->lParam);
+ CsA = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(CREATESTRUCTA));
+ if (NULL == CsA)
+ {
+ return FALSE;
+ }
+ memcpy(CsA, CsW, sizeof(CREATESTRUCTW));
+
+ RtlInitUnicodeString(&UString, CsW->lpszName);
+ Status = RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
+ if (! NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(GetProcessHeap(), 0, CsA);
+ return FALSE;
+ }
+ CsA->lpszName = AString.Buffer;
+ if (HIWORD((ULONG)CsW->lpszClass) != 0)
+ {
+ RtlInitUnicodeString(&UString, CsW->lpszClass);
+ Status = RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
+ if (! NT_SUCCESS(Status))
+ {
+ RtlInitAnsiString(&AString, CsA->lpszName);
+ RtlFreeAnsiString(&AString);
+ RtlFreeHeap(GetProcessHeap(), 0, CsA);
+ return FALSE;
+ }
+ CsA->lpszClass = AString.Buffer;
+ }
+ UnicodeMsg->lParam = (LPARAM)CsA;
+ break;
+ }
+ case WM_SETTEXT:
+ {
+ ANSI_STRING AnsiString;
+ UNICODE_STRING UnicodeString;
+ RtlInitUnicodeString(&UnicodeString, (PWSTR) UnicodeMsg->lParam);
+ if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString,
+ &UnicodeString,
+ TRUE)))
+ {
+ return FALSE;
+ }
+ AnsiMsg->lParam = (LPARAM) AnsiString.Buffer;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static BOOL FASTCALL
+MsgiUnicodeToAnsiCleanup(LPMSG AnsiMsg, LPMSG UnicodeMsg)
+{
+ switch(UnicodeMsg->message)
+ {
+ case WM_GETTEXT:
+ case WM_SETTEXT:
+ {
+ ANSI_STRING AString;
+ RtlInitAnsiString(&AString, (PSTR) AnsiMsg->lParam);
+ RtlFreeAnsiString(&AString);
+ break;
+ }
+ case WM_CREATE:
+ case WM_NCCREATE:
+ {
+ CREATESTRUCTA* Cs;
+ ANSI_STRING AString;
+
+ Cs = (CREATESTRUCTA*) AnsiMsg->lParam;
+ RtlInitAnsiString(&AString, Cs->lpszName);
+ RtlFreeAnsiString(&AString);
+ if (HIWORD((ULONG)Cs->lpszClass) != 0)
+ {
+ RtlInitAnsiString(&AString, Cs->lpszClass);
+ RtlFreeAnsiString(&AString);
+ }
+ RtlFreeHeap(GetProcessHeap(), 0, Cs);
+ break;
+ }
}
+
+ return TRUE;
}
-VOID STATIC
-User32FreeAsciiConvertedMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
+static BOOL FASTCALL
+MsgiUnicodeToAnsiReply(LPMSG AnsiMsg, LPMSG UnicodeMsg, LRESULT *Result)
{
- switch(Msg)
+ switch (UnicodeMsg->message)
{
case WM_GETTEXT:
+ case WM_ASKCBFORMATNAME:
{
- ANSI_STRING AnsiString;
- UNICODE_STRING UnicodeString;
- LPSTR TempString;
- LPSTR InString;
- InString = (LPSTR)lParam;
- TempString = RtlAllocateHeap(GetProcessHeap(), 0, strlen(InString) + 1);
- strcpy(TempString, InString);
- RtlInitAnsiString(&AnsiString, TempString);
- UnicodeString.Length = wParam * sizeof(WCHAR);
- UnicodeString.MaximumLength = wParam * sizeof(WCHAR);
- UnicodeString.Buffer = (PWSTR)lParam;
- if (! NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
- &AnsiString,
- FALSE)))
- {
- if (1 <= wParam)
- {
- UnicodeString.Buffer[0] = L'\0';
- }
- }
- RtlFreeHeap(GetProcessHeap(), 0, TempString);
- break;
+ LPSTR Buffer = (LPSTR) AnsiMsg->lParam;
+ LPWSTR UBuffer = (LPWSTR) UnicodeMsg->lParam;
+ if (0 < AnsiMsg->wParam &&
+ ! MultiByteToWideChar(CP_ACP, 0, Buffer, -1, UBuffer, UnicodeMsg->wParam))
+ {
+ UBuffer[AnsiMsg->wParam - 1] = L'\0';
+ }
+ break;
}
- case WM_SETTEXT:
+
+ case WM_GETTEXTLENGTH:
+ case CB_GETLBTEXTLEN:
+ case LB_GETTEXTLEN:
{
- ANSI_STRING AnsiString;
- RtlInitAnsiString(&AnsiString, (PSTR) lParam);
- RtlFreeAnsiString(&AnsiString);
- break;
+ /* FIXME: There may be one DBCS char for each Unicode char */
+ *Result /= sizeof(WCHAR);
+ break;
}
- case WM_CREATE:
- case WM_NCCREATE:
- {
- CREATESTRUCTA* Cs;
+ }
- Cs = (CREATESTRUCTA*)lParam;
- RtlFreeHeap(GetProcessHeap(), 0, (LPSTR)Cs->lpszName);
- if (HIWORD((ULONG)Cs->lpszClass) != 0)
- {
- RtlFreeHeap(GetProcessHeap(), 0, (LPSTR)Cs->lpszClass);
- }
- RtlFreeHeap(GetProcessHeap(), 0, Cs);
- break;
- }
+ MsgiUnicodeToAnsiCleanup(UnicodeMsg, AnsiMsg);
+
+ return TRUE;
+}
+
+typedef struct tagMSGCONVERSION
+{
+ BOOL InUse;
+ BOOL Ansi;
+ MSG KMMsg;
+ MSG UnicodeMsg;
+ MSG AnsiMsg;
+ PMSG FinalMsg;
+ ULONG LParamSize;
+} MSGCONVERSION, *PMSGCONVERSION;
+
+static PMSGCONVERSION MsgConversions = NULL;
+static unsigned MsgConversionNumAlloc = 0;
+static unsigned MsgConversionNumUsed = 0;
+static CRITICAL_SECTION MsgConversionCrst;
+
+static BOOL FASTCALL
+MsgConversionAdd(PMSGCONVERSION Conversion)
+{
+ unsigned i;
+
+ EnterCriticalSection(&MsgConversionCrst);
+
+ if (MsgConversionNumUsed == MsgConversionNumAlloc)
+ {
+#define GROWBY 4
+ PMSGCONVERSION New;
+ if (NULL != MsgConversions)
+ {
+ New = HeapReAlloc(GetProcessHeap(), 0, MsgConversions,
+ (MsgConversionNumAlloc + GROWBY) * sizeof(MSGCONVERSION));
+ }
+ else
+ {
+ New = HeapAlloc(GetProcessHeap(), 0,
+ (MsgConversionNumAlloc + GROWBY) * sizeof(MSGCONVERSION));
+ }
+
+ if (NULL == New)
+ {
+ LeaveCriticalSection(&MsgConversionCrst);
+ return FALSE;
+ }
+ MsgConversions = New;
+ /* zero out newly allocated part */
+ memset(MsgConversions + MsgConversionNumAlloc, 0, GROWBY * sizeof(MSGCONVERSION));
+ MsgConversionNumAlloc += GROWBY;
+#undef GROWBY
+ }
+
+ for (i = 0; i < MsgConversionNumAlloc; i++)
+ {
+ if (! MsgConversions[i].InUse)
+ {
+ MsgConversions[i] = *Conversion;
+ MsgConversions[i].InUse = TRUE;
+ MsgConversionNumUsed++;
+ break;
+ }
+ }
+ LeaveCriticalSection(&MsgConversionCrst);
+
+ return TRUE;
+}
+
+static void FASTCALL
+MsgConversionCleanup(CONST MSG *Msg, BOOL Ansi, BOOL CheckMsgContents, LRESULT *Result)
+{
+ BOOL Found;
+ PMSGCONVERSION Conversion;
+ LRESULT Dummy;
+
+ EnterCriticalSection(&MsgConversionCrst);
+ for (Conversion = MsgConversions;
+ Conversion < MsgConversions + MsgConversionNumAlloc;
+ Conversion++)
+ {
+ if (Conversion->InUse &&
+ ((Ansi && Conversion->Ansi) ||
+ (! Ansi && ! Conversion->Ansi)))
+ {
+ Found = (Conversion->FinalMsg == Msg);
+ if (! Found && CheckMsgContents)
+ {
+ if (Ansi)
+ {
+ Found = (0 == memcmp(Msg, &Conversion->AnsiMsg, sizeof(MSG)));
+ }
+ else
+ {
+ Found = (0 == memcmp(Msg, &Conversion->UnicodeMsg, sizeof(MSG)));
+ }
+ }
+ if (Found)
+ {
+ if (Ansi)
+ {
+ MsgiUnicodeToAnsiReply(&Conversion->AnsiMsg, &Conversion->UnicodeMsg,
+ NULL == Result ? &Dummy : Result);
+ }
+ MsgiKMToUMReply(&Conversion->KMMsg, &Conversion->UnicodeMsg,
+ NULL == Result ? &Dummy : Result);
+ if (0 != Conversion->LParamSize)
+ {
+ NtFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &Conversion->KMMsg.lParam,
+ &Conversion->LParamSize, MEM_DECOMMIT);
+ }
+ Conversion->InUse = FALSE;
+ MsgConversionNumUsed--;
+ }
+ }
}
+ LeaveCriticalSection(&MsgConversionCrst);
+}
+
+/*
+ * @implemented
+ */
+LPARAM
+STDCALL
+GetMessageExtraInfo(VOID)
+{
+ return (LPARAM)NtUserCallNoParam(NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO);
+}
+
+
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+GetMessagePos(VOID)
+{
+ PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
+ return(MAKELONG(ThreadData->LastMessage.pt.x, ThreadData->LastMessage.pt.y));
+}
+
+
+/*
+ * @implemented
+ */
+LONG STDCALL
+GetMessageTime(VOID)
+{
+ PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
+ return(ThreadData->LastMessage.time);
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL
+STDCALL
+InSendMessage(VOID)
+{
+ /* return(NtUserGetThreadState(THREADSTATE_INSENDMESSAGE) != ISMEX_NOSEND); */
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD
+STDCALL
+InSendMessageEx(
+ LPVOID lpReserved)
+{
+ /* return NtUserGetThreadState(THREADSTATE_INSENDMESSAGE); */
+ UNIMPLEMENTED;
+ return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL
+STDCALL
+ReplyMessage(
+ LRESULT lResult)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+LPARAM
+STDCALL
+SetMessageExtraInfo(
+ LPARAM lParam)
+{
+ return NtUserSetMessageExtraInfo(lParam);
}
LRESULT FASTCALL
@@ -412,13 +882,25 @@
WPARAM wParam,
LPARAM lParam)
{
+ MSG AnsiMsg;
+ MSG UnicodeMsg;
LRESULT Result;
if (IsAnsiProc)
{
- User32ConvertToAsciiMessage(&Msg, &wParam, &lParam);
- Result = WndProc(hWnd, Msg, wParam, lParam);
- User32FreeAsciiConvertedMessage(Msg, wParam, lParam);
+ UnicodeMsg.hwnd = hWnd;
+ UnicodeMsg.message = Msg;
+ UnicodeMsg.wParam = wParam;
+ UnicodeMsg.lParam = lParam;
+ if (! MsgiUnicodeToAnsiMessage(&AnsiMsg, &UnicodeMsg))
+ {
+ return FALSE;
+ }
+ Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
+ if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
+ {
+ return FALSE;
+ }
return Result;
}
else
@@ -525,7 +1007,21 @@
LRESULT STDCALL
DispatchMessageA(CONST MSG *lpmsg)
{
- return(NtUserDispatchMessage(lpmsg));
+ NTUSERDISPATCHMESSAGEINFO Info;
+ LRESULT Result;
+
+ Info.Ansi = TRUE;
+ Info.Msg = *lpmsg;
+ Result = NtUserDispatchMessage(&Info);
+ if (! Info.HandledByKernel)
+ {
+ /* We need to send the message ourselves */
+ Result = IntCallWindowProcA(Info.Ansi, Info.Proc, Info.Msg.hwnd,
+ Info.Msg.message, Info.Msg.wParam, Info.Msg.lParam);
+ }
+ MsgConversionCleanup(lpmsg, TRUE, TRUE, &Result);
+
+ return Result;
}
@@ -535,7 +1031,21 @@
LRESULT STDCALL
DispatchMessageW(CONST MSG *lpmsg)
{
- return(NtUserDispatchMessage((LPMSG)lpmsg));
+ NTUSERDISPATCHMESSAGEINFO Info;
+ LRESULT Result;
+
+ Info.Ansi = FALSE;
+ Info.Msg = *lpmsg;
+ Result = NtUserDispatchMessage(&Info);
+ if (! Info.HandledByKernel)
+ {
+ /* We need to send the message ourselves */
+ Result = IntCallWindowProcW(Info.Ansi, Info.Proc, Info.Msg.hwnd,
+ Info.Msg.message, Info.Msg.wParam, Info.Msg.lParam);
+ }
+ MsgConversionCleanup(lpmsg, FALSE, TRUE, &Result);
+
+ return Result;
}
@@ -549,14 +1059,38 @@
UINT wMsgFilterMax)
{
BOOL Res;
+ MSGCONVERSION Conversion;
+ NTUSERGETMESSAGEINFO Info;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
- Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+ MsgConversionCleanup(lpMsg, TRUE, FALSE, NULL);
+ Res = NtUserGetMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax);
+ if (-1 == (int) Res)
+ {
+ return Res;
+ }
+ Conversion.LParamSize = Info.LParamSize;
+ Conversion.KMMsg = Info.Msg;
+
+ if (! MsgiKMToUMMessage(&Conversion.KMMsg, &Conversion.UnicodeMsg))
+ {
+ return (BOOL) -1;
+ }
+ if (! MsgiUnicodeToAnsiMessage(&Conversion.AnsiMsg, &Conversion.UnicodeMsg))
+ {
+ MsgiKMToUMCleanup(&Info.Msg, &Conversion.UnicodeMsg);
+ return (BOOL) -1;
+ }
+ *lpMsg = Conversion.AnsiMsg;
+ Conversion.Ansi = TRUE;
+ Conversion.FinalMsg = lpMsg;
+ MsgConversionAdd(&Conversion);
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
- ThreadData->LastMessage = *lpMsg;
+ ThreadData->LastMessage = Info.Msg;
}
- return(Res);
+
+ return Res;
}
@@ -570,14 +1104,33 @@
UINT wMsgFilterMax)
{
BOOL Res;
+ MSGCONVERSION Conversion;
+ NTUSERGETMESSAGEINFO Info;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
- Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+ MsgConversionCleanup(lpMsg, FALSE, FALSE, NULL);
+ Res = NtUserGetMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax);
+ if (-1 == (int) Res)
+ {
+ return Res;
+ }
+ Conversion.LParamSize = Info.LParamSize;
+ Conversion.KMMsg = Info.Msg;
+
+ if (! MsgiKMToUMMessage(&Conversion.KMMsg, &Conversion.UnicodeMsg))
+ {
+ return (BOOL) -1;
+ }
+ *lpMsg = Conversion.UnicodeMsg;
+ Conversion.Ansi = FALSE;
+ Conversion.FinalMsg = lpMsg;
+ MsgConversionAdd(&Conversion);
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
- ThreadData->LastMessage = *lpMsg;
+ ThreadData->LastMessage = Info.Msg;
}
- return(Res);
+
+ return Res;
}
[truncated at 1000 lines; 314 more skipped]
reactos/lib/user32/windows
diff -u -r1.112 -r1.113
--- window.c 15 Apr 2004 23:36:02 -0000 1.112
+++ window.c 29 Apr 2004 21:13:16 -0000 1.113
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.112 2004/04/15 23:36:02 weiden Exp $
+/* $Id: window.c,v 1.113 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@@ -48,53 +48,6 @@
}
-NTSTATUS STDCALL
-User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
-{
- PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
- LPARAM lParam;
-
- /* Make sure we don't try to access mem beyond what we were given */
- if (ArgumentLength < sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
- {
- return STATUS_INFO_LENGTH_MISMATCH;
- }
-
- CallbackArgs = (PWINDOWPROC_CALLBACK_ARGUMENTS) Arguments;
- /* Check if lParam is really a pointer and adjust it if it is */
- if (0 <= CallbackArgs->lParamBufferSize)
- {
- if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)
- + CallbackArgs->lParamBufferSize)
- {
- return STATUS_INFO_LENGTH_MISMATCH;
- }
- lParam = (LPARAM) ((char *) CallbackArgs + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS));
- }
- else
- {
- if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
- {
- return STATUS_INFO_LENGTH_MISMATCH;
- }
- lParam = CallbackArgs->lParam;
- }
-
- if (WM_NCCALCSIZE == CallbackArgs->Msg && CallbackArgs->wParam)
- {
- NCCALCSIZE_PARAMS *Params = (NCCALCSIZE_PARAMS *) lParam;
- Params->lppos = (PWINDOWPOS) (Params + 1);
- }
-
-
- CallbackArgs->Result = IntCallWindowProcW(CallbackArgs->IsAnsiProc, CallbackArgs->Proc,
- CallbackArgs->Wnd, CallbackArgs->Msg,
- CallbackArgs->wParam, lParam);
-
- return ZwCallbackReturn(CallbackArgs, ArgumentLength, STATUS_SUCCESS);
-}
-
-
/*
* @unimplemented
*/
reactos/subsys/win32k/include
diff -u -r1.34 -r1.35
--- msgqueue.h 16 Apr 2004 18:53:53 -0000 1.34
+++ msgqueue.h 29 Apr 2004 21:13:16 -0000 1.35
@@ -11,6 +11,7 @@
typedef struct _USER_MESSAGE
{
LIST_ENTRY ListEntry;
+ BOOLEAN FreeLParam;
MSG Msg;
} USER_MESSAGE, *PUSER_MESSAGE;
@@ -103,12 +104,12 @@
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
UINT uTimeout, BOOL Block, ULONG_PTR *uResult);
PUSER_MESSAGE FASTCALL
-MsqCreateMessage(LPMSG Msg);
+MsqCreateMessage(LPMSG Msg, BOOLEAN FreeLParam);
VOID FASTCALL
MsqDestroyMessage(PUSER_MESSAGE Message);
VOID FASTCALL
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- MSG* Msg);
+ MSG* Msg, BOOLEAN FreeLParam);
VOID FASTCALL
MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode);
BOOLEAN STDCALL
reactos/subsys/win32k/include
diff -u -r1.13 -r1.14
--- painting.h 24 Feb 2004 13:27:02 -0000 1.13
+++ painting.h 29 Apr 2004 21:13:16 -0000 1.14
@@ -12,7 +12,8 @@
BOOL FASTCALL
IntRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, ULONG Flags);
BOOL FASTCALL
-IntGetPaintMessage(HWND hWnd, PW32THREAD Thread, MSG *Message, BOOL Remove);
+IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, PW32THREAD Thread,
+ MSG *Message, BOOL Remove);
BOOL STDCALL
NtUserValidateRgn(HWND hWnd, HRGN hRgn);
reactos/subsys/win32k/ntuser
diff -u -r1.27 -r1.28
--- keyboard.c 15 Mar 2004 19:06:35 -0000 1.27
+++ keyboard.c 29 Apr 2004 21:13:16 -0000 1.28
@@ -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: keyboard.c,v 1.27 2004/03/15 19:06:35 dwelch Exp $
+/* $Id: keyboard.c,v 1.28 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -659,14 +659,14 @@
NewMsg.wParam = dead_char;
NewMsg.lParam = lpMsg->lParam;
dead_char = 0;
- MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg);
+ MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE);
}
NewMsg.hwnd = lpMsg->hwnd;
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
- MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg);
+ MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE);
Result = TRUE;
}
else if (UState == -1)
@@ -677,7 +677,7 @@
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
dead_char = wp[0];
- MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg);
+ MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE);
Result = TRUE;
}
reactos/subsys/win32k/ntuser
diff -u -r1.59 -r1.60
--- message.c 15 Apr 2004 23:36:03 -0000 1.59
+++ message.c 29 Apr 2004 21:13:16 -0000 1.60
@@ -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.59 2004/04/15 23:36:03 weiden Exp $
+/* $Id: message.c,v 1.60 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -70,91 +70,242 @@
return STATUS_SUCCESS;
}
-LRESULT FASTCALL
-IntDispatchMessage(MSG* Msg)
-{
- LRESULT Result;
- PWINDOW_OBJECT WindowObject;
- /* Process timer messages. */
- if (Msg->message == WM_TIMER)
+#define MMS_SIZE_WPARAM -1
+#define MMS_SIZE_WPARAMWCHAR -2
+#define MMS_SIZE_LPARAMSZ -3
+#define MMS_SIZE_SPECIAL -4
+#define MMS_FLAG_READ 0x01
+#define MMS_FLAG_WRITE 0x02
+#define MMS_FLAG_READWRITE (MMS_FLAG_READ | MMS_FLAG_WRITE)
+typedef struct tagMSGMEMORY
+ {
+ UINT Message;
+ UINT Size;
+ INT Flags;
+ } MSGMEMORY, *PMSGMEMORY;
+
+static MSGMEMORY MsgMemory[] =
+ {
+ { WM_CREATE, sizeof(CREATESTRUCTW), MMS_FLAG_READWRITE },
+ { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
+ { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
+ { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
+ { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
+ { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+ { WM_NCCREATE, sizeof(CREATESTRUCTW), MMS_FLAG_READWRITE },
+ { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
+ { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
+ { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
+ { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
+ { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
+ };
+
+static PMSGMEMORY FASTCALL
+FindMsgMemory(UINT Msg)
+ {
+ PMSGMEMORY MsgMemoryEntry;
+
+ /* See if this message type is present in the table */
+ for (MsgMemoryEntry = MsgMemory;
+ MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
+ MsgMemoryEntry++)
{
- if (Msg->lParam)
- {
- LARGE_INTEGER LargeTickCount;
- /* FIXME: Call hooks. */
+ if (Msg == MsgMemoryEntry->Message)
+ {
+ return MsgMemoryEntry;
+ }
+ }
- /* FIXME: Check for continuing validity of timer. */
-
- KeQueryTickCount(&LargeTickCount);
- return IntCallWindowProc((WNDPROC)Msg->lParam,
- FALSE,
- Msg->hwnd,
- Msg->message,
- Msg->wParam,
- (LPARAM)LargeTickCount.u.LowPart,
- -1);
- }
+ return NULL;
+}
+
+static UINT FASTCALL
+MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
+{
+ if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
+ {
+ return (UINT) wParam;
+ }
+ else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
+ {
+ return (UINT) (wParam * sizeof(WCHAR));
+ }
+ else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
+ {
+ return (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
+ }
+ else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
+ {
+ switch(MsgMemoryEntry->Message)
+ {
+ case WM_NCCALCSIZE:
+ return wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
+ break;
+ default:
+ assert(FALSE);
+ return 0;
+ break;
+ }
+ }
+ else
+ {
+ return MsgMemoryEntry->Size;
}
+}
- if( Msg->hwnd == 0 ) return 0;
+static FASTCALL NTSTATUS
+PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ NCCALCSIZE_PARAMS *UnpackedParams;
+ NCCALCSIZE_PARAMS *PackedParams;
- /* Get the window object. */
- WindowObject = IntGetWindowObject(Msg->hwnd);
- if(!WindowObject)
+ *lParamPacked = lParam;
+ if (WM_NCCALCSIZE == Msg && wParam)
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return 0;
+ UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
+ if (UnpackedParams->lppos != (PWINDOWPOS) (UnpackedParams + 1))
+ {
+ PackedParams = ExAllocatePoolWithTag(PagedPool,
+ sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
+ TAG_MSG);
+ if (NULL == PackedParams)
+ {
+ DPRINT1("Not enough memory to pack lParam\n");
+ return STATUS_NO_MEMORY;
+ }
+ RtlCopyMemory(PackedParams, UnpackedParams, sizeof(NCCALCSIZE_PARAMS));
+ PackedParams->lppos = (PWINDOWPOS) (PackedParams + 1);
+ RtlCopyMemory(PackedParams->lppos, UnpackedParams->lppos, sizeof(WINDOWPOS));
+ *lParamPacked = (LPARAM) PackedParams;
+ }
}
- if(WindowObject->OwnerThread != PsGetCurrentThread())
- {
- IntReleaseWindowObject(WindowObject);
- DPRINT1("Window doesn't belong to the calling thread!\n");
- return 0;
- }
- /* FIXME: Call hook procedures. */
- /* Call the window procedure. */
- if (0xFFFF0000 != ((DWORD) WindowObject->WndProcW & 0xFFFF0000))
+ return STATUS_SUCCESS;
+}
+
+static FASTCALL NTSTATUS
+UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ NCCALCSIZE_PARAMS *UnpackedParams;
+ NCCALCSIZE_PARAMS *PackedParams;
+ PWINDOWPOS UnpackedWindowPos;
+
+ if (lParamPacked == lParam)
{
- Result = IntCallWindowProc(WindowObject->WndProcW,
- FALSE,
- Msg->hwnd,
- Msg->message,
- Msg->wParam,
- Msg->lParam,
- -1);
+ return STATUS_SUCCESS;
}
- else
+
+ if (WM_NCCALCSIZE == Msg && wParam)
{
- Result = IntCallWindowProc(WindowObject->WndProcA,
- TRUE,
- Msg->hwnd,
- Msg->message,
- Msg->wParam,
- Msg->lParam,
- -1);
+ PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
+ UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
+ UnpackedWindowPos = UnpackedParams->lppos;
+ RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
+ UnpackedParams->lppos = UnpackedWindowPos;
+ RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
+ ExFreePool((PVOID) lParamPacked);
+
+ return STATUS_SUCCESS;
}
-
- IntReleaseWindowObject(WindowObject);
-
- return Result;
+
+ assert(FALSE);
+
+ return STATUS_INVALID_PARAMETER;
}
LRESULT STDCALL
-NtUserDispatchMessage(CONST MSG* UnsafeMsg)
+NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
{
NTSTATUS Status;
- MSG Msg;
+ NTUSERDISPATCHMESSAGEINFO MsgInfo;
+ PWINDOW_OBJECT WindowObject;
+ LRESULT Result;
- Status = MmCopyFromCaller(&Msg, (PVOID) UnsafeMsg, sizeof(MSG));
+ Status = MmCopyFromCaller(&MsgInfo, UnsafeMsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
if (! NT_SUCCESS(Status))
{
- SetLastNtError(Status);
- return 0;
+ SetLastNtError(Status);
+ return 0;
+ }
+
+ /* Process timer messages. */
+ if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
+ {
+ LARGE_INTEGER LargeTickCount;
+ /* FIXME: Call hooks. */
+
+ /* FIXME: Check for continuing validity of timer. */
+
+ MsgInfo.HandledByKernel = FALSE;
+ KeQueryTickCount(&LargeTickCount);
+ MsgInfo.Proc = (WNDPROC) MsgInfo.Msg.lParam;
+ MsgInfo.Msg.lParam = (LPARAM)LargeTickCount.u.LowPart;
+ }
+ else if (NULL == MsgInfo.Msg.hwnd)
+ {
+ MsgInfo.HandledByKernel = TRUE;
+ Result = 0;
+ }
+ else
+ {
+ /* Get the window object. */
+ WindowObject = IntGetWindowObject(MsgInfo.Msg.hwnd);
+ if (NULL == WindowObject)
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ MsgInfo.HandledByKernel = TRUE;
+ Result = 0;
+ }
+ else
+ {
+ if (WindowObject->OwnerThread != PsGetCurrentThread())
+ {
+ IntReleaseWindowObject(WindowObject);
+ DPRINT1("Window doesn't belong to the calling thread!\n");
+ MsgInfo.HandledByKernel = TRUE;
+ Result = 0;
+ }
+ else
+ {
+ /* FIXME: Call hook procedures. */
+
+ MsgInfo.HandledByKernel = FALSE;
+ Result = 0;
+ if (0xFFFF0000 != ((DWORD) WindowObject->WndProcW & 0xFFFF0000))
+ {
+ if (0xFFFF0000 != ((DWORD) WindowObject->WndProcA & 0xFFFF0000))
+ {
+ /* Both Unicode and Ansi winprocs are real, use whatever
+ usermode prefers */
+ MsgInfo.Proc = (MsgInfo.Ansi ? WindowObject->WndProcA
+ : WindowObject->WndProcW);
+ }
+ else
+ {
+ /* Real Unicode winproc */
+ MsgInfo.Ansi = FALSE;
+ MsgInfo.Proc = WindowObject->WndProcW;
+ }
+ }
+ else
+ {
+ /* Must have real Ansi winproc */
+ MsgInfo.Ansi = TRUE;
+ MsgInfo.Proc = WindowObject->WndProcA;
+ }
+ }
+ IntReleaseWindowObject(WindowObject);
+ }
+ }
+ Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return 0;
}
- return IntDispatchMessage(&Msg);
+ return Result;
}
@@ -336,7 +487,7 @@
* Internal version of PeekMessage() doing all the work
*/
BOOL FASTCALL
-IntPeekMessage(LPMSG Msg,
+IntPeekMessage(PUSER_MESSAGE Msg,
HWND Wnd,
UINT MsgFilterMin,
UINT MsgFilterMax,
@@ -372,10 +523,11 @@
{
/* According to the PSDK, WM_QUIT messages are always returned, regardless
of the filter specified */
- Msg->hwnd = NULL;
- Msg->message = WM_QUIT;
- Msg->wParam = ThreadQueue->QuitExitCode;
- Msg->lParam = 0;
+ Msg->Msg.hwnd = NULL;
+ Msg->Msg.message = WM_QUIT;
+ Msg->Msg.wParam = ThreadQueue->QuitExitCode;
+ Msg->Msg.lParam = 0;
+ Msg->FreeLParam = FALSE;
if (RemoveMessages)
{
ThreadQueue->QuitPosted = FALSE;
@@ -393,7 +545,7 @@
&Message);
if (Present)
{
- RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG));
+ RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
if (RemoveMessages)
{
MsqDestroyMessage(Message);
@@ -411,7 +563,7 @@
&Message);
if (Present)
{
- RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG));
+ RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
if (RemoveMessages)
{
MsqDestroyMessage(Message);
@@ -423,8 +575,9 @@
while (MsqDispatchOneSentMessage(ThreadQueue));
/* Check for paint messages. */
- if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg, RemoveMessages))
+ if (IntGetPaintMessage(Wnd, MsgFilterMin, MsgFilterMax, PsGetWin32Thread(), &Msg->Msg, RemoveMessages))
{
+ Msg->FreeLParam = FALSE;
return TRUE;
}
@@ -438,12 +591,12 @@
{
PWINDOW_OBJECT MsgWindow = NULL;;
- if(Msg->hwnd && (MsgWindow = IntGetWindowObject(Msg->hwnd)) &&
- Msg->message >= WM_MOUSEFIRST && Msg->message <= WM_MOUSELAST)
+ if(Msg->Msg.hwnd && (MsgWindow = IntGetWindowObject(Msg->Msg.hwnd)) &&
+ Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST)
{
USHORT HitTest;
- if(IntTranslateMouseMessage(ThreadQueue, Msg, &HitTest, TRUE))
+ if(IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, TRUE))
/* FIXME - check message filter again, if the message doesn't match anymore,
search again */
{
@@ -453,10 +606,10 @@
}
if(ThreadQueue->CaptureWindow == NULL)
{
- IntSendHitTestMessages(ThreadQueue, Msg);
- if((Msg->message != WM_MOUSEMOVE && Msg->message != WM_NCMOUSEMOVE) &&
- IS_BTN_MESSAGE(Msg->message, DOWN) &&
- IntActivateWindowMouse(ThreadQueue, Msg, MsgWindow, &HitTest))
+ IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
+ if((Msg->Msg.message != WM_MOUSEMOVE && Msg->Msg.message != WM_NCMOUSEMOVE) &&
+ IS_BTN_MESSAGE(Msg->Msg.message, DOWN) &&
+ IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest))
{
IntReleaseWindowObject(MsgWindow);
/* eat the message, search again */
@@ -466,7 +619,7 @@
}
else
{
- IntSendHitTestMessages(ThreadQueue, Msg);
+ IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
}
if(MsgWindow)
@@ -478,8 +631,8 @@
}
USHORT HitTest;
- if((Msg->hwnd && Msg->message >= WM_MOUSEFIRST && Msg->message <= WM_MOUSELAST) &&
- IntTranslateMouseMessage(ThreadQueue, Msg, &HitTest, FALSE))
+ if((Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) &&
+ IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, FALSE))
/* FIXME - check message filter again, if the message doesn't match anymore,
search again */
{
@@ -494,43 +647,88 @@
}
BOOL STDCALL
-NtUserPeekMessage(LPMSG UnsafeMsg,
+NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
HWND Wnd,
UINT MsgFilterMin,
UINT MsgFilterMax,
UINT RemoveMsg)
{
- MSG SafeMsg;
NTSTATUS Status;
BOOL Present;
+ NTUSERGETMESSAGEINFO Info;
PWINDOW_OBJECT Window;
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID UserMem;
+ UINT Size;
+ USER_MESSAGE Msg;
/* Validate input */
if (NULL != Wnd)
{
Window = IntGetWindowObject(Wnd);
- if(!Window)
- Wnd = NULL;
+ if (NULL == Window)
+ {
+ Wnd = NULL;
+ }
else
- IntReleaseWindowObject(Window);
+ {
+ IntReleaseWindowObject(Window);
+ }
}
+
if (MsgFilterMax < MsgFilterMin)
{
MsgFilterMin = 0;
MsgFilterMax = 0;
}
- Present = IntPeekMessage(&SafeMsg, Wnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
+ Present = IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
if (Present)
{
- Status = MmCopyToCaller(UnsafeMsg, &SafeMsg, sizeof(MSG));
+ Info.Msg = Msg.Msg;
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ Info.LParamSize = 0;
+ }
+ else
+ {
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
+ Info.Msg.lParam);
+ /* Allocate required amount of user-mode memory */
+ Info.LParamSize = Size;
+ UserMem = NULL;
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
+ &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return (BOOL) -1;
+ }
+ /* Transfer lParam data to user-mode mem */
+ Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
+ &Info.LParamSize, MEM_DECOMMIT);
+ SetLastNtError(Status);
+ return (BOOL) -1;
+ }
+ Info.Msg.lParam = (LPARAM) UserMem;
+ }
+ if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
+ {
+ ExFreePool((void *) Msg.Msg.lParam);
+ }
+ Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
if (! NT_SUCCESS(Status))
- {
- /* There is error return documented for PeekMessage().
- Do the best we can */
- SetLastNtError(Status);
- return FALSE;
- }
+ {
+ SetLastNtError(Status);
+ return (BOOL) -1;
+ }
}
return Present;
@@ -543,7 +741,7 @@
{
PUSER_MESSAGE_QUEUE ThreadQueue;
NTSTATUS Status;
- MSG Msg;
+ USER_MESSAGE Msg;
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
@@ -565,7 +763,7 @@
}
BOOL STDCALL
-NtUserGetMessage(LPMSG UnsafeMsg,
+NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
HWND Wnd,
UINT MsgFilterMin,
UINT MsgFilterMax)
@@ -581,9 +779,13 @@
*/
{
BOOL GotMessage;
- MSG SafeMsg;
+ NTUSERGETMESSAGEINFO Info;
NTSTATUS Status;
PWINDOW_OBJECT Window;
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID UserMem;
+ UINT Size;
+ USER_MESSAGE Msg;
/* Validate input */
if (NULL != Wnd)
@@ -602,10 +804,49 @@
do
{
- GotMessage = IntPeekMessage(&SafeMsg, Wnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
+ GotMessage = IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
if (GotMessage)
{
- Status = MmCopyToCaller(UnsafeMsg, &SafeMsg, sizeof(MSG));
+ Info.Msg = Msg.Msg;
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ Info.LParamSize = 0;
+ }
+ else
+ {
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
+ Info.Msg.lParam);
+ /* Allocate required amount of user-mode memory */
+ Info.LParamSize = Size;
+ UserMem = NULL;
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
+ &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return (BOOL) -1;
+ }
+ /* Transfer lParam data to user-mode mem */
+ Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
+ &Info.LParamSize, MEM_DECOMMIT);
+ SetLastNtError(Status);
+ return (BOOL) -1;
+ }
+ Info.Msg.lParam = (LPARAM) UserMem;
+ }
+ if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
+ {
+ ExFreePool((void *) Msg.Msg.lParam);
+ }
+ Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
@@ -619,7 +860,7 @@
}
while (! GotMessage);
- return WM_QUIT != SafeMsg.message;
+ return WM_QUIT != Info.Msg.message;
}
DWORD
@@ -638,28 +879,124 @@
return 0;
}
-BOOL STDCALL
-NtUserPostMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+static NTSTATUS FASTCALL
+CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
{
- PWINDOW_OBJECT Window;
- MSG Mesg;
- LARGE_INTEGER LargeTickCount;
+ NTSTATUS Status;
+
+ PVOID KernelMem;
+ UINT Size;
- if (WM_QUIT == Msg)
+ *KernelModeMsg = *UserModeMsg;
+
+ /* See if this message type is present in the table */
+ if (NULL == MsgMemoryEntry)
{
- MsqPostQuitMessage(PsGetWin32Thread()->MessageQueue, wParam);
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
}
- else if (hWnd == HWND_BROADCAST)
- {
- HWND *List;
- PWINDOW_OBJECT DesktopWindow;
- ULONG i;
- DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
- List = IntWinListChildren(DesktopWindow);
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+
+ if (0 != Size)
+ {
+ /* Allocate kernel mem */
+ KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
+ if (NULL == KernelMem)
+ {
+ DPRINT1("Not enough memory to copy message to kernel mem\n");
+ return STATUS_NO_MEMORY;
+ }
+ KernelModeMsg->lParam = (LPARAM) KernelMem;
+
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
+ {
+ Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
+ ExFreePool(KernelMem);
+ return Status;
+ }
+ }
+ else
+ {
+ /* Make sure we don't pass any secrets to usermode */
+ RtlZeroMemory(KernelMem, Size);
+ }
+ }
+ else
+ {
+ KernelModeMsg->lParam = 0;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS FASTCALL
+CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
+{
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+ UINT Size;
+
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
+
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+
+ if (0 != Size)
+ {
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
+ {
+ Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ return Status;
+ }
+ }
+
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+BOOL STDCALL
+NtUserPostMessage(HWND Wnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ PWINDOW_OBJECT Window;
+ MSG UserModeMsg, KernelModeMsg;
+ LARGE_INTEGER LargeTickCount;
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+
+ if (WM_QUIT == Msg)
+ {
+ MsqPostQuitMessage(PsGetWin32Thread()->MessageQueue, wParam);
+ }
+ else if (Wnd == HWND_BROADCAST)
+ {
+ HWND *List;
+ PWINDOW_OBJECT DesktopWindow;
+ ULONG i;
+
+ DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
IntReleaseWindowObject(DesktopWindow);
if (List != NULL)
{
@@ -670,21 +1007,30 @@
}
else
{
- Window = IntGetWindowObject(hWnd);
- if (!Window)
+ Window = IntGetWindowObject(Wnd);
+ if (NULL == Window)
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ UserModeMsg.hwnd = Wnd;
+ UserModeMsg.message = Msg;
+ UserModeMsg.wParam = wParam;
+ UserModeMsg.lParam = lParam;
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
+ Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
+ if (! NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
- Mesg.hwnd = hWnd;
- Mesg.message = Msg;
- Mesg.wParam = wParam;
- Mesg.lParam = lParam;
- Mesg.pt.x = PsGetWin32Process()->WindowStation->SystemCursor.x;
- Mesg.pt.y = PsGetWin32Process()->WindowStation->SystemCursor.y;
+ KernelModeMsg.pt.x = PsGetWin32Process()->WindowStation->SystemCursor.x;
+ KernelModeMsg.pt.y = PsGetWin32Process()->WindowStation->SystemCursor.y;
KeQueryTickCount(&LargeTickCount);
- Mesg.time = LargeTickCount.u.LowPart;
- MsqPostMessage(Window->MessageQueue, &Mesg);
+ KernelModeMsg.time = LargeTickCount.u.LowPart;
+ MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
+ NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam);
IntReleaseWindowObject(Window);
}
@@ -697,11 +1043,11 @@
WPARAM wParam,
LPARAM lParam)
{
- MSG Mesg;
-
+ MSG UserModeMsg, KernelModeMsg;
PETHREAD peThread;
PW32THREAD pThread;
NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
Status = PsLookupThreadByThreadId((void *)idThread,&peThread);
@@ -712,11 +1058,20 @@
ObDereferenceObject( peThread );
return FALSE;
}
- Mesg.hwnd = 0;
- Mesg.message = Msg;
- Mesg.wParam = wParam;
- Mesg.lParam = lParam;
- MsqPostMessage(pThread->MessageQueue, &Mesg);
+
+ UserModeMsg.hwnd = NULL;
+ UserModeMsg.message = Msg;
+ UserModeMsg.wParam = wParam;
+ UserModeMsg.lParam = lParam;
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
+ Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
+ NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam);
ObDereferenceObject( peThread );
return TRUE;
} else {
@@ -733,147 +1088,6 @@
return 0;
}
-#define MMS_SIZE_WPARAM -1
-#define MMS_SIZE_WPARAMWCHAR -2
-#define MMS_SIZE_LPARAMSZ -3
-#define MMS_SIZE_SPECIAL -4
-#define MMS_FLAG_READ 0x01
-#define MMS_FLAG_WRITE 0x02
-#define MMS_FLAG_READWRITE (MMS_FLAG_READ | MMS_FLAG_WRITE)
-typedef struct tagMSGMEMORY
- {
- UINT Message;
- UINT Size;
- INT Flags;
- } MSGMEMORY, *PMSGMEMORY;
-
-static MSGMEMORY MsgMemory[] =
- {
- { WM_CREATE, sizeof(CREATESTRUCTW), MMS_FLAG_READWRITE },
- { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
- { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
- { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
- { WM_NCCREATE, sizeof(CREATESTRUCTW), MMS_FLAG_READWRITE },
- { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
- { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
- { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
- { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
- { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
- };
-
-static PMSGMEMORY FASTCALL
-FindMsgMemory(UINT Msg)
- {
- PMSGMEMORY MsgMemoryEntry;
-
- /* See if this message type is present in the table */
- for (MsgMemoryEntry = MsgMemory;
- MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
- MsgMemoryEntry++)
- {
- if (Msg == MsgMemoryEntry->Message)
- {
- return MsgMemoryEntry;
- }
- }
-
- return NULL;
-}
-
-static UINT FASTCALL
-MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
-{
- if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
- {
- return (UINT) wParam;
- }
- else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
- {
- return (UINT) (wParam * sizeof(WCHAR));
- }
- else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
- {
- return (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
- }
- else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
- {
- switch(MsgMemoryEntry->Message)
- {
- case WM_NCCALCSIZE:
- return wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
- break;
- default:
- assert(FALSE);
- return 0;
- break;
- }
- }
- else
- {
- return MsgMemoryEntry->Size;
- }
-}
-
-static NTSTATUS FASTCALL
-PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- NCCALCSIZE_PARAMS *UnpackedParams;
- NCCALCSIZE_PARAMS *PackedParams;
-
- *lParamPacked = lParam;
- if (WM_NCCALCSIZE == Msg && wParam)
- {
- UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
- if (UnpackedParams->lppos != (PWINDOWPOS) (UnpackedParams + 1))
- {
- PackedParams = ExAllocatePoolWithTag(PagedPool,
- sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
- TAG_MSG);
- if (NULL == PackedParams)
- {
- DPRINT1("Not enough memory to pack lParam\n");
- return STATUS_NO_MEMORY;
- }
- RtlCopyMemory(PackedParams, UnpackedParams, sizeof(NCCALCSIZE_PARAMS));
- PackedParams->lppos = (PWINDOWPOS) (PackedParams + 1);
- RtlCopyMemory(PackedParams->lppos, UnpackedParams->lppos, sizeof(WINDOWPOS));
- *lParamPacked = (LPARAM) PackedParams;
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-static FASTCALL NTSTATUS
-UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- NCCALCSIZE_PARAMS *UnpackedParams;
- NCCALCSIZE_PARAMS *PackedParams;
- PWINDOWPOS UnpackedWindowPos;
-
- if (lParamPacked == lParam)
- {
- return STATUS_SUCCESS;
- }
-
- if (WM_NCCALCSIZE == Msg && wParam)
- {
- PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
- UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
- UnpackedWindowPos = UnpackedParams->lppos;
- RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
- UnpackedParams->lppos = UnpackedWindowPos;
- RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
- ExFreePool((PVOID) lParamPacked);
-
- return STATUS_SUCCESS;
- }
-
- assert(FALSE);
-
- return STATUS_INVALID_PARAMETER;
-}
-
LRESULT FASTCALL
IntSendMessage(HWND hWnd,
UINT Msg,
@@ -1030,62 +1244,6 @@
return (LRESULT) TRUE;
}
-static NTSTATUS FASTCALL
-CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg)
-{
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- PVOID KernelMem;
[truncated at 1000 lines; 116 more skipped]
reactos/subsys/win32k/ntuser
diff -u -r1.90 -r1.91
--- msgqueue.c 16 Apr 2004 18:53:53 -0000 1.90
+++ msgqueue.c 29 Apr 2004 21:13:16 -0000 1.91
@@ -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.90 2004/04/16 18:53:53 weiden Exp $
+/* $Id: msgqueue.c,v 1.91 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -493,6 +493,7 @@
UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
/* What to do if out of memory? For now we just panic a bit in debug */
ASSERT(UserMsg);
+ UserMsg->FreeLParam = FALSE;
UserMsg->Msg = Msg;
InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
IntLockSystemMessageQueue(OldIrql);
@@ -597,7 +598,7 @@
FocusMessageQueue = IntGetFocusMessageQueue();
if( !IntGetScreenDC() ) {
if( W32kGetPrimitiveMessageQueue() ) {
- MsqPostMessage(W32kGetPrimitiveMessageQueue(), &Msg);
+ MsqPostMessage(W32kGetPrimitiveMessageQueue(), &Msg, FALSE);
}
} else {
if (FocusMessageQueue == NULL)
@@ -610,7 +611,7 @@
{
Msg.hwnd = FocusMessageQueue->FocusWindow;
DPRINT("Msg.hwnd = %x\n", Msg.hwnd);
- MsqPostMessage(FocusMessageQueue, &Msg);
+ MsqPostMessage(FocusMessageQueue, &Msg, FALSE);
}
else
{
@@ -665,7 +666,7 @@
// Mesg.pt.y = PsGetWin32Process()->WindowStation->SystemCursor.y;
// KeQueryTickCount(&LargeTickCount);
// Mesg.time = LargeTickCount.u.LowPart;
- MsqPostMessage(Window->MessageQueue, &Mesg);
+ MsqPostMessage(Window->MessageQueue, &Mesg, FALSE);
ObmDereferenceObject(Window);
ObDereferenceObject (Thread);
@@ -678,7 +679,7 @@
}
PUSER_MESSAGE FASTCALL
-MsqCreateMessage(LPMSG Msg)
+MsqCreateMessage(LPMSG Msg, BOOLEAN FreeLParam)
{
PUSER_MESSAGE Message;
@@ -688,6 +689,7 @@
return NULL;
}
+ Message->FreeLParam = FreeLParam;
RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
return Message;
@@ -875,11 +877,11 @@
}
VOID FASTCALL
-MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg)
+MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN FreeLParam)
{
PUSER_MESSAGE Message;
- if(!(Message = MsqCreateMessage(Msg)))
+ if(!(Message = MsqCreateMessage(Msg, FreeLParam)))
{
return;
}
reactos/subsys/win32k/ntuser
diff -u -r1.80 -r1.81
--- painting.c 9 Apr 2004 20:03:19 -0000 1.80
+++ painting.c 29 Apr 2004 21:13:16 -0000 1.81
@@ -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.80 2004/04/09 20:03:19 navaraf Exp $
+ * $Id: painting.c,v 1.81 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -609,8 +609,8 @@
}
BOOL FASTCALL
-IntGetPaintMessage(HWND hWnd, PW32THREAD Thread, MSG *Message,
- BOOL Remove)
+IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax,
+ PW32THREAD Thread, MSG *Message, BOOL Remove)
{
PWINDOW_OBJECT Window;
PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
@@ -625,13 +625,14 @@
if (Message->hwnd == NULL)
{
-#if 0
- DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
-#endif
- IntLockMessageQueue(MessageQueue);
- MessageQueue->PaintPosted = 0;
- MessageQueue->PaintCount = 0;
- IntUnLockMessageQueue(MessageQueue);
+ if (NULL == hWnd)
+ {
+ DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
+ IntLockMessageQueue(MessageQueue);
+ MessageQueue->PaintPosted = 0;
+ MessageQueue->PaintCount = 0;
+ IntUnLockMessageQueue(MessageQueue);
+ }
return FALSE;
}
@@ -639,7 +640,10 @@
if (Window != NULL)
{
IntLockWindowUpdate(Window);
- if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
+ if (0 != (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
+ && ((0 == MsgFilterMin && 0 == MsgFilterMax) ||
+ (MsgFilterMin <= WM_NCPAINT &&
+ WM_NCPAINT <= MsgFilterMax)))
{
Message->message = WM_NCPAINT;
Message->wParam = (WPARAM)Window->NCUpdateRegion;
@@ -651,7 +655,9 @@
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
MsqDecPaintCountQueue(Window->MessageQueue);
}
- } else
+ } else if ((0 == MsgFilterMin && 0 == MsgFilterMax) ||
+ (MsgFilterMin <= WM_PAINT &&
+ WM_PAINT <= MsgFilterMax))
{
Message->message = WM_PAINT;
Message->wParam = Message->lParam = 0;
reactos/subsys/win32k/ntuser
diff -u -r1.30 -r1.31
--- timer.c 9 Apr 2004 20:03:19 -0000 1.30
+++ timer.c 29 Apr 2004 21:13:16 -0000 1.31
@@ -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: timer.c,v 1.30 2004/04/09 20:03:19 navaraf Exp $
+/* $Id: timer.c,v 1.31 2004/04/29 21:13:16 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -418,7 +418,7 @@
continue;
}
- MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, &MsgTimer->Msg);
+ MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, &MsgTimer->Msg, FALSE);
ThreadsToDereference[ThreadsToDereferencePos] = Thread;
++ThreadsToDereferencePos;
CVSspam 0.2.8