Author: jimtabor
Date: Thu Jan 8 00:56:51 2015
New Revision: 66000
URL:
http://svn.reactos.org/svn/reactos?rev=66000&view=rev
Log:
[Win32s]
- Implement DDE from wine. Leaving debug errors on the run and later move to trace. See
CORE-7447.
- Use callbacks to User32 to convert the data and track it in Win32k.
- Add a new Quality of Service atom.
- Add things to class.c.
- Shell32 tests run now too, or only 4 run. This might be fixed too, since locating a
lParam write back issue.
Modified:
trunk/reactos/win32ss/include/callback.h
trunk/reactos/win32ss/include/ntuser.h
trunk/reactos/win32ss/user/ntuser/class.c
trunk/reactos/win32ss/user/ntuser/dde.c
trunk/reactos/win32ss/user/ntuser/message.c
trunk/reactos/win32ss/user/ntuser/ntuser.c
trunk/reactos/win32ss/user/ntuser/ntuser.h
trunk/reactos/win32ss/user/ntuser/userfuncs.h
trunk/reactos/win32ss/user/user32/misc/dde.c
trunk/reactos/win32ss/user/user32/misc/dllmain.c
trunk/reactos/win32ss/user/user32/windows/message.c
Modified: trunk/reactos/win32ss/include/callback.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/callback.h…
==============================================================================
--- trunk/reactos/win32ss/include/callback.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/include/callback.h [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -14,7 +14,9 @@
#define USER32_CALLBACK_COPYIMAGE (10)
#define USER32_CALLBACK_SETWNDICONS (11)
#define USER32_CALLBACK_DELIVERUSERAPC (12)
-#define USER32_CALLBACK_MAXIMUM (12)
+#define USER32_CALLBACK_DDEPOST (13)
+#define USER32_CALLBACK_DDEGET (14)
+#define USER32_CALLBACK_MAXIMUM (14)
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
{
@@ -115,6 +117,14 @@
HICON hIconWindows;
} SETWNDICONS_CALLBACK_ARGUMENTS, *PSETWNDICONS_CALLBACK_ARGUMENTS;
+typedef struct _DDEPOSTGET_CALLBACK_ARGUMENTS
+{
+ INT Type;
+ MSG;
+ int size;
+ BYTE buffer[1];
+} DDEPOSTGET_CALLBACK_ARGUMENTS, *PDDEPOSTGET_CALLBACK_ARGUMENTS;
+
NTSTATUS WINAPI
User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS WINAPI
@@ -141,4 +151,8 @@
User32CallGetCharsetInfo(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS WINAPI
User32DeliverUserAPC(PVOID Arguments, ULONG ArgumentLength);
+NTSTATUS WINAPI
+User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength);
+NTSTATUS WINAPI
+User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */
Modified: trunk/reactos/win32ss/include/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/ntuser.h?r…
==============================================================================
--- trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -300,6 +300,12 @@
C_ASSERT(sizeof(CLIENTINFO) <= sizeof(((PTEB)0)->Win32ClientInfo));
#define GetWin32ClientInfo() ((PCLIENTINFO)(NtCurrentTeb()->Win32ClientInfo))
+
+typedef struct tagDDEPACK
+{
+ UINT_PTR uiLo;
+ UINT_PTR uiHi;
+} DDEPACK, *PDDEPACK;
#define HRGN_NULL ( (HRGN) 0) // NULL empty region
#define HRGN_WINDOW ( (HRGN) 1) // region from window rcWindow
@@ -3417,19 +3423,7 @@
NTAPI
NtUserYieldTask(VOID);
-/* lParam of DDE messages */
-typedef struct tagKMDDEEXECUTEDATA
-{
- HWND Sender;
- HGLOBAL ClientMem;
- /* BYTE Data[DataSize] */
-} KMDDEEXECUTEDATA, *PKMDDEEXECUTEDATA;
-
-typedef struct tagDDEPACK
-{
- UINT_PTR uiLo;
- UINT_PTR uiHi;
-} DDEPACK, *PDDEPACK;
+
Modified: trunk/reactos/win32ss/user/ntuser/class.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/class.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/class.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/class.c [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -1052,6 +1052,7 @@
/* FIXME: The class was created before being connected
to a desktop. It is possible for the desktop window,
but should it be allowed for any other case? */
+ TRACE("This CLASS has no Desktop to heap from! Atom %d\n",Atom);
Class = UserHeapAlloc(ClassSize);
}
@@ -2367,7 +2368,7 @@
}
//
-// ???
+// Register System Classes....
//
BOOL
FASTCALL
Modified: trunk/reactos/win32ss/user/ntuser/dde.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/dde.c?…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/dde.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/dde.c [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -5,14 +5,348 @@
DBG_DEFAULT_CHANNEL(UserMisc);
+typedef struct _DDE_DATA
+{
+ LPARAM lParam;
+ int cbSize;
+ PVOID pvBuffer;
+} DDE_DATA, *PDDE_DATA;
+
+typedef struct _DDE_PROP
+{
+ PWND spwnd;
+ PWND spwndPartner;
+} DDE_PROP, *PDDE_PROP;
+
+
+
+int
+APIENTRY
+IntDDEPostCallback(
+ IN PWND pWnd,
+ IN UINT Msg,
+ IN WPARAM wParam,
+ IN OUT LPARAM *lParam,
+ IN PVOID Buffer,
+ IN int size)
+{
+ NTSTATUS Status;
+ ULONG ArgumentLength, ResultLength;
+ PVOID Argument, ResultPointer;
+ PDDEPOSTGET_CALLBACK_ARGUMENTS Common;
+ int origSize = size;
+
+ ResultPointer = NULL;
+ ResultLength = ArgumentLength = sizeof(DDEPOSTGET_CALLBACK_ARGUMENTS)+size;
+
+ Argument = IntCbAllocateMemory(ArgumentLength);
+ if (NULL == Argument)
+ {
+ return FALSE;
+ }
+
+ Common = (PDDEPOSTGET_CALLBACK_ARGUMENTS) Argument;
+
+ Common->size = size;
+ Common->hwnd = UserHMGetHandle(pWnd);
+ Common->message = Msg;
+ Common->wParam = wParam;
+ Common->lParam = *lParam;
+ RtlCopyMemory(&Common->buffer, Buffer, size);
+
+ UserLeaveCo();
+
+ Status = KeUserModeCallback(USER32_CALLBACK_DDEPOST,
+ Argument,
+ ArgumentLength,
+ &ResultPointer,
+ &ResultLength);
+
+ UserEnterCo();
+
+ if (!NT_SUCCESS(Status) || ResultPointer == NULL )
+ {
+ ERR("DDE Post callback failed!\n");
+ IntCbFreeMemory(Argument);
+ return 0;
+ }
+
+ RtlCopyMemory(Common, ResultPointer, ArgumentLength);
+
+ if (Common->size != 0 && size <= origSize)
+ {
+ RtlCopyMemory(Buffer, &Common->buffer, size); // ResultLength);
+ }
+
+ size = Common->size;
+ *lParam = Common->lParam;
+
+ IntCbFreeMemory(Argument);
+
+ return size ? size : -1;
+}
+
+BOOL
+APIENTRY
+IntDDEGetCallback(
+ IN PWND pWnd,
+ IN OUT PMSG pMsg,
+ IN PVOID Buffer,
+ IN int size)
+{
+ NTSTATUS Status;
+ ULONG ArgumentLength, ResultLength;
+ PVOID Argument, ResultPointer;
+ PDDEPOSTGET_CALLBACK_ARGUMENTS Common;
+
+ ResultPointer = NULL;
+ ResultLength = ArgumentLength = sizeof(DDEPOSTGET_CALLBACK_ARGUMENTS)+size;
+
+ Argument = IntCbAllocateMemory(ArgumentLength);
+ if (NULL == Argument)
+ {
+ return FALSE;
+ }
+
+ Common = (PDDEPOSTGET_CALLBACK_ARGUMENTS) Argument;
+
+ Common->size = size;
+ Common->hwnd = pMsg->hwnd;
+ Common->message = pMsg->message;
+ Common->wParam = pMsg->wParam;
+ Common->lParam = pMsg->lParam;
+
+ if (size && Buffer) RtlCopyMemory(&Common->buffer, Buffer, size);
+
+
+ UserLeaveCo();
+
+ Status = KeUserModeCallback(USER32_CALLBACK_DDEGET,
+ Argument,
+ ArgumentLength,
+ &ResultPointer,
+ &ResultLength);
+
+ UserEnterCo();
+
+ if (!NT_SUCCESS(Status) || ResultPointer == NULL )
+ {
+ ERR("DDE Get callback failed!\n");
+ IntCbFreeMemory(Argument);
+ return FALSE;
+ }
+
+ RtlMoveMemory(Common, ResultPointer, ArgumentLength);
+
+ pMsg->lParam = Common->lParam;
+
+ IntCbFreeMemory(Argument);
+
+ return TRUE;
+}
+
+
+
+BOOL
+APIENTRY
+IntDdePostMessageHook(
+ IN PWND pWnd,
+ IN UINT Msg,
+ IN WPARAM wParam,
+ IN OUT LPARAM *lParam,
+ IN OUT LONG_PTR *ExtraInfo)
+{
+ PWND pWndClient;
+ PDDE_DATA pddeData;
+ HGDIOBJ Object = NULL;
+ PVOID Buffer = NULL;
+ int size = 128;
+ LPARAM lp = *lParam;
+
+ if (pWnd->head.pti->ppi != gptiCurrent->ppi)
+ {
+ ERR("Posting long DDE 0x%x\n",Msg);
+ // Initiate is sent only across borders.
+ if (Msg == WM_DDE_INITIATE)
+ {
+ return FALSE;
+ }
+
+ pWndClient = UserGetWindowObject((HWND)wParam);
+ if (pWndClient == NULL)
+ {
+ // This is terminating so post it.
+ if ( Msg == WM_DDE_TERMINATE)
+ {
+ ERR("DDE Posted WM_DDE_TERMINATE\n");
+ return TRUE;
+ }
+ ERR("Invalid DDE Client Window handle\n");
+ return FALSE;
+ }
+
+ if (Msg == WM_DDE_TERMINATE )
+ {
+ //// FIXME Remove Stuff if any...
+
+ // Do not bother to callback.
+ return TRUE;
+ }
+
+ Buffer = ExAllocatePoolWithTag(PagedPool, size, USERTAG_DDE);
+
+ if ((size = IntDDEPostCallback(pWnd, Msg, wParam, &lp, Buffer, size)) == 0)
+ {
+ ERR("DDE Post Callback return 0 0x%x\n", Msg);
+ }
+
+ if (size != -1 && size > 128)
+ {
+ ERR("FIXME: DDE Post need more bytes %d\n",size);
+ }
+
+ if (size == -1)
+ {
+ size = 0;
+ ExFreePoolWithTag(Buffer, USERTAG_DDE);
+ Buffer = NULL;
+ }
+
+ ERR("DDE Post size %d 0x%x\n",size, Msg);
+
+ switch(Msg)
+ {
+ case WM_DDE_POKE:
+ {
+ DDEPOKE *pddePoke = Buffer;
+ switch(pddePoke->cfFormat)
+ {
+ case CF_BITMAP:
+ case CF_DIB:
+ case CF_PALETTE:
+ RtlCopyMemory(&Object, pddePoke->Value, sizeof(HGDIOBJ));
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case WM_DDE_DATA:
+ {
+ DDEDATA *pddeData = Buffer;
+ switch(pddeData->cfFormat)
+ {
+ case CF_BITMAP:
+ case CF_DIB:
+ case CF_PALETTE:
+ RtlCopyMemory(&Object, pddeData->Value, sizeof(HGDIOBJ));
+ break;
+ default:
+ break;
+ }
+ break;
+
+ }
+ default:
+ break;
+ }
+
+ if (Object)
+ {
+ // Give gdi object to the other process.
+ GreSetObjectOwner(Object, pWnd->head.pti->ppi->W32Pid);
+ }
+
+ pddeData = ExAllocatePoolWithTag(PagedPool, sizeof(DDE_DATA), USERTAG_DDE2);
+
+ pddeData->cbSize = size;
+ pddeData->pvBuffer = Buffer;
+ pddeData->lParam = lp;
+
+ ERR("DDE Post lParam c=%08lx\n",lp);
+ *lParam = lp;
+
+ // Attach this data packet to the user message.
+ *ExtraInfo = (LONG_PTR)pddeData;
+ }
+ return TRUE;
+}
+
+VOID APIENTRY
+IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
+{
+ PWND pWnd, pWndClient;
+ PDDE_DATA pddeData;
+ PDDE_PROP pddeProp;
+ BOOL Ret;
+
+ pWnd = UserGetWindowObject(pMsg->hwnd);
+ if (pWnd == NULL)
+ {
+ ERR("DDE Get Window is dead. %p\n", pMsg->hwnd);
+ return;
+ }
+
+ if (pMsg->message == WM_DDE_TERMINATE)
+ {
+ pddeProp = (PDDE_PROP)UserGetProp(pWnd, AtomDDETrack);
+ if (pddeProp)
+ {
+ pWndClient = UserGetWindowObject((HWND)pMsg->wParam);
+ if (pWndClient == NULL)
+ {
+ ERR("DDE Get Client WM_DDE_TERMINATE\n");
+ }
+
+ IntRemoveProp(pWnd, AtomDDETrack);
+ ExFreePoolWithTag(pddeProp, USERTAG_DDE1);
+ }
+ return;
+ }
+
+ ERR("DDE Get Msg 0x%x\n",pMsg->message);
+
+ pddeData = (PDDE_DATA)ExtraInfo;
+
+ if ( pddeData )
+ {
+ ERR("DDE Get 1 size %d lParam c=%08lx lp c=%08lx\n",pddeData->cbSize,
pMsg->lParam, pddeData->lParam);
+
+ pMsg->lParam = pddeData->lParam; // This might be a hack... Need to backtrace
lParam from post queue.
+
+ Ret = IntDDEGetCallback( pWnd, pMsg, pddeData->pvBuffer, pddeData->cbSize);
+ if (!Ret)
+ {
+ ERR("DDE Get CB failed\n");
+ }
+
+ ERR("DDE Get 2 size %d lParam c=%08lx\n",pddeData->cbSize,
pMsg->lParam);
+
+ if (pddeData->pvBuffer) ExFreePoolWithTag(pddeData->pvBuffer, USERTAG_DDE);
+
+ ExFreePoolWithTag(pddeData, USERTAG_DDE2);
+
+ return;
+ }
+ ERR("DDE Get No DDE Data found!\n");
+ return;
+}
BOOL FASTCALL
IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
PWND pWndServer;
+ PDDE_PROP pddeProp;
+
+ if (Msg == WM_DDE_ACK)
+ {
+ ERR("Sending WM_DDE_ACK Client hwnd %p\n",pWnd->head.h);
+ }
if (pWnd->head.pti->ppi != gptiCurrent->ppi)
{
+ ERR("Sending long DDE 0x%x\n",Msg);
+
// Allow only Acknowledge and Initiate to be sent across borders.
if (Msg != WM_DDE_ACK )
{
@@ -20,52 +354,26 @@
return FALSE;
}
+ ERR("Sending long WM_DDE_ACK\n");
+
pWndServer = UserGetWindowObject((HWND)wParam);
if (pWndServer == NULL)
{
ERR("Invalid DDE Server Window handle\n");
return FALSE;
}
- ERR("Sending DDE 0x%x\n",Msg);
+
+ // Setup property so this conversation can be tracked.
+ pddeProp = ExAllocatePoolWithTag(PagedPool, sizeof(DDE_PROP), USERTAG_DDE1);
+
+ pddeProp->spwnd = pWndServer;
+ pddeProp->spwndPartner = pWnd;
+
+ IntSetProp(pWndServer, AtomDDETrack, (HANDLE)pddeProp);
}
return TRUE;
}
-BOOL FASTCALL
-IntDdePostMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- PWND pWndClient;
-
- if (pWnd->head.pti->ppi != gptiCurrent->ppi)
- {
- // Initiate is sent only across borders.
- if (Msg == WM_DDE_INITIATE)
- {
- return FALSE;
- }
-
- pWndClient = UserGetWindowObject((HWND)wParam);
- if (pWndClient == NULL)
- {
- // This is terminating so post it.
- if ( Msg == WM_DDE_TERMINATE) return TRUE;
- ERR("Invalid DDE Client Window handle\n");
- return FALSE;
- }
- ERR("Posting and do CB DDE 0x%x\n",Msg);
- }
- return TRUE;
-}
-
-VOID FASTCALL
-IntDdeGetMessageHook(PMSG pMsg)
-{
- if (pMsg->message == WM_DDE_TERMINATE)
- {
- return;
- }
- ERR("Do Callback Msg 0x%x\n",pMsg->message);
-}
BOOL
APIENTRY
Modified: trunk/reactos/win32ss/user/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/messag…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -122,8 +122,6 @@
static MSGMEMORY g_MsgMemory[] =
{
{ WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
- { WM_DDE_ACK, sizeof(DDEPACK), 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 },
@@ -1014,14 +1012,12 @@
bGMSG );
if (Present)
{
+ /* GetMessage or PostMessage must never get messages that contain pointers */
+ ASSERT(FindMsgMemory(pMsg->message) == NULL);
+
if ( pMsg->message >= WM_DDE_FIRST && pMsg->message <=
WM_DDE_LAST )
{
- IntDdeGetMessageHook(pMsg);
- }
- else
- {
- /* GetMessage or PostMessage must never get messages that contain pointers
*/
- ASSERT(FindMsgMemory(pMsg->message) == NULL);
+ IntDdeGetMessageHook(pMsg, ExtraInfo);
}
if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
@@ -1206,11 +1202,12 @@
if ( Msg >= WM_DDE_FIRST && Msg <= WM_DDE_LAST )
{
- if (!IntDdePostMessageHook(Window, Msg, wParam, lParam))
+ if (!IntDdePostMessageHook(Window, Msg, wParam, &lParam, &ExtraInfo))
{
ERR("Posting Exit DDE 0x%x\n",Msg);
return FALSE;
}
+ ERR("DDE Post lParam c=%08lx\n",lParam);
}
if (WM_QUIT == Msg)
Modified: trunk/reactos/win32ss/user/ntuser/ntuser.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntuser…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/ntuser.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/ntuser.c [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -1,4 +1,4 @@
-/*
+ATOM AtomQOS;/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: ntuser init. and main funcs.
@@ -15,11 +15,12 @@
PTHREADINFO gptiCurrent = NULL;
PPROCESSINFO gppiInputProvider = NULL;
ERESOURCE UserLock;
-ATOM AtomMessage; // Window Message atom.
-ATOM AtomWndObj; // Window Object atom.
-ATOM AtomLayer; // Window Layer atom.
+ATOM AtomMessage; // Window Message atom.
+ATOM AtomWndObj; // Window Object atom.
+ATOM AtomLayer; // Window Layer atom.
ATOM AtomFlashWndState; // Window Flash State atom.
-ATOM AtomDDETrack; // Window DDE Tracking atom.
+ATOM AtomDDETrack; // Window DDE Tracking atom.
+ATOM AtomQOS; // Window DDE Quality of Service atom.
HINSTANCE hModClient = NULL;
BOOL ClientPfnInit = FALSE;
ATOM gaGuiConsoleWndClass;
@@ -52,6 +53,7 @@
gpsi->atomFrostedWindowProp = IntAddGlobalAtom(L"SysFrostedWindow",
TRUE);
AtomDDETrack = IntAddGlobalAtom(L"SysDT", TRUE);
+ AtomQOS = IntAddGlobalAtom(L"SysQOS", TRUE);
/*
* FIXME: AddPropW uses the global kernel atom table, thus leading to conflicts if we
use
Modified: trunk/reactos/win32ss/user/ntuser/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntuser…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/ntuser.h [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -15,6 +15,8 @@
extern PPROCESSINFO ppiScrnSaver;
extern PPROCESSINFO gppiInputProvider;
extern ATOM gaGuiConsoleWndClass;
+extern ATOM AtomDDETrack;
+extern ATOM AtomQOS;
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
VOID FASTCALL CleanupUserImpl(VOID);
Modified: trunk/reactos/win32ss/user/ntuser/userfuncs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/userfu…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -43,8 +43,8 @@
/*************** DDE.C ****************/
BOOL FASTCALL IntDdeSendMessageHook(PWND,UINT,WPARAM,LPARAM);
-BOOL FASTCALL IntDdePostMessageHook(PWND,UINT,WPARAM,LPARAM);
-VOID FASTCALL IntDdeGetMessageHook(PMSG);
+BOOL APIENTRY IntDdePostMessageHook(IN PWND,IN UINT,IN WPARAM,IN OUT LPARAM*,IN OUT
LONG_PTR*);
+VOID APIENTRY IntDdeGetMessageHook(PMSG,LONG_PTR);
/*************** MAIN.C ***************/
Modified: trunk/reactos/win32ss/user/user32/misc/dde.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/d…
==============================================================================
--- trunk/reactos/win32ss/user/user32/misc/dde.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/misc/dde.c [iso-8859-1] Thu Jan 8 00:56:51 2015
@@ -3,6 +3,286 @@
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
+
+
+BOOL FASTCALL DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem);
+HGLOBAL FASTCALL DdeGetPair(HGLOBAL ServerMem);
+
+
+/* description of the data fields that need to be packed along with a sent message */
+struct packed_message
+{
+ //union packed_structs ps;
+ int count;
+ const void *data;
+ int size;
+};
+
+/* add a data field to a packed message */
+static inline void push_data( struct packed_message *data, const void *ptr, int size )
+{
+ data->data = ptr;
+ data->size = size;
+ data->count++;
+}
+
+/* pack a pointer into a 32/64 portable format */
+static inline ULONGLONG pack_ptr( const void *ptr )
+{
+ return (ULONG_PTR)ptr;
+}
+
+/* unpack a potentially 64-bit pointer, returning 0 when truncated */
+static inline void *unpack_ptr( ULONGLONG ptr64 )
+{
+ if ((ULONG_PTR)ptr64 != ptr64) return 0;
+ return (void *)(ULONG_PTR)ptr64;
+}
+
+
+/***********************************************************************
+ * post_dde_message
+ *
+ * Post a DDE message
+ */
+BOOL post_dde_message( struct packed_message *data, UINT message, LPARAM lParam , LPARAM
*lp)
+{
+ void* ptr = NULL;
+ int size = 0;
+ UINT_PTR uiLo, uiHi;
+ HGLOBAL hunlock = 0;
+ ULONGLONG hpack;
+
+ if (!UnpackDDElParam( message, lParam, &uiLo, &uiHi ))
+ {
+ ERR("Unpack failed %x\n",message);
+ return FALSE;
+ }
+
+ *lp = lParam;
+ switch (message)
+ {
+ /* DDE messages which don't require packing are:
+ * WM_DDE_INITIATE
+ * WM_DDE_TERMINATE
+ * WM_DDE_REQUEST
+ * WM_DDE_UNADVISE
+ */
+ case WM_DDE_ACK:
+ if (HIWORD(uiHi))
+ {
+ /* uiHi should contain a hMem from WM_DDE_EXECUTE */
+ HGLOBAL h = DdeGetPair( (HANDLE)uiHi );
+ if (h)
+ {
+ hpack = pack_ptr( h );
+ /* send back the value of h on the other side */
+ push_data( data, &hpack, sizeof(hpack) );
+ *lp = uiLo;
+ ERR( "send dde-ack %lx %08lx => %p\n", uiLo, uiHi, h );
+ }
+ }
+ else
+ {
+ /* uiHi should contain either an atom or 0 */
+ ERR( "send dde-ack %lx atom=%lx\n", uiLo, uiHi );
+ *lp = MAKELONG( uiLo, uiHi );
+ }
+ break;
+ case WM_DDE_ADVISE:
+ case WM_DDE_DATA:
+ case WM_DDE_POKE:
+ size = 0;
+ if (uiLo)
+ {
+ size = GlobalSize( (HGLOBAL)uiLo ) ;
+ if ( (message == WM_DDE_ADVISE && size < sizeof(DDEADVISE)) ||
+ (message == WM_DDE_DATA && size < FIELD_OFFSET(DDEDATA,
Value)) ||
+ (message == WM_DDE_POKE && size < FIELD_OFFSET(DDEPOKE,
Value)) )
+ return FALSE;
+ }
+ else if (message != WM_DDE_DATA) return FALSE;
+
+ *lp = uiHi;
+ if (uiLo)
+ {
+ if ((ptr = GlobalLock( (HGLOBAL)uiLo) ))
+ {
+ DDEDATA *dde_data = ptr;
+ ERR("unused %d, fResponse %d, fRelease %d, fDeferUpd %d, fAckReq %d,
cfFormat %d\n",
+ dde_data->unused, dde_data->fResponse,
dde_data->fRelease,
+ dde_data->reserved, dde_data->fAckReq,
dde_data->cfFormat);
+ push_data( data, ptr, size );
+ hunlock = (HGLOBAL)uiLo;
+ }
+ }
+ ERR( "send ddepack %u %lx\n", size, uiHi );
+ break;
+ case WM_DDE_EXECUTE:
+ if (lParam)
+ {
+ if ((ptr = GlobalLock( (HGLOBAL)lParam) ))
+ {
+ size = GlobalSize( (HGLOBAL)lParam );
+ push_data(data, ptr, size);
+ /* so that the other side can send it back on ACK */
+ *lp = lParam;
+ hunlock = (HGLOBAL)lParam;
+ ERR("WM_DDE_EXECUTE text size %d\n",GlobalSize( (HGLOBAL)lParam
));
+ }
+ }
+ break;
+ }
+
+ FreeDDElParam(message, lParam);
+
+ if (hunlock) GlobalUnlock(hunlock);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * unpack_dde_message
+ *
+ * Unpack a posted DDE message received from another process.
+ */
+BOOL unpack_dde_message( HWND hwnd, UINT message, LPARAM *lparam, PVOID buffer, int size
)
+{
+ UINT_PTR uiLo, uiHi;
+ HGLOBAL hMem = 0;
+ void* ptr;
+
+ ERR("udm : Size %d\n",size);
+
+ switch (message)
+ {
+ case WM_DDE_ACK:
+ if (size)
+ {
+ ULONGLONG hpack;
+ /* hMem is being passed */
+ if (size != sizeof(hpack)) return FALSE;
+ if (!buffer) return FALSE;
+ uiLo = *lparam;
+ memcpy( &hpack, buffer, size );
+ hMem = unpack_ptr( hpack );
+ uiHi = (UINT_PTR)hMem;
+ ERR("recv dde-ack %lx mem=%lx[%lx]\n", uiLo, uiHi, GlobalSize( hMem
));
+ }
+ else
+ {
+ uiLo = LOWORD( *lparam );
+ uiHi = HIWORD( *lparam );
+ ERR("recv dde-ack %lx atom=%lx\n", uiLo, uiHi);
+ }
+ *lparam = PackDDElParam( WM_DDE_ACK, uiLo, uiHi );
+ break;
+ case WM_DDE_ADVISE:
+ case WM_DDE_DATA:
+ case WM_DDE_POKE:
+ if ((!buffer) && message != WM_DDE_DATA) return FALSE;
+ uiHi = *lparam;
+ if (size)
+ {
+ if (!(hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, size )))
+ return FALSE;
+ if ((ptr = GlobalLock( hMem )))
+ {
+ memcpy( ptr, buffer, size );
+ GlobalUnlock( hMem );
+ }
+ else
+ {
+ GlobalFree( hMem );
+ return FALSE;
+ }
+ }
+ uiLo = (UINT_PTR)hMem;
+
+ *lparam = PackDDElParam( message, uiLo, uiHi );
+ break;
+ case WM_DDE_EXECUTE:
+ if (size)
+ {
+ if (!buffer) return FALSE;
+ if (!(hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, size ))) return
FALSE;
+ if ((ptr = GlobalLock( hMem )))
+ {
+ memcpy( ptr, buffer, size );
+ GlobalUnlock( hMem );
+ ERR( "exec: pairing c=%08lx s=%p\n", *lparam, hMem );
+ if (!DdeAddPair( (HGLOBAL)*lparam, hMem ))
+ {
+ GlobalFree( hMem );
+ ERR("udm exec: GF 1\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ GlobalFree( hMem );
+ ERR("udm exec: GF 2\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ ERR("udm exec: No Size\n");
+ return FALSE;
+ }
+
+ ERR( "exec: exit c=%08lx s=%p\n", *lparam, hMem );
+ *lparam = (LPARAM)hMem;
+ break;
+ }
+ return TRUE;
+}
+
+NTSTATUS
+WINAPI
+User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+ struct packed_message data;
+ BOOL Ret;
+ PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
+
+ data.data = 0;
+ data.size = 0;
+ ERR("DDE Post CB\n");
+ Ret = post_dde_message( &data, Common->message, Common->lParam,
&Common->lParam);
+
+ if (Ret)
+ {
+ if (Common->size >= data.size)
+ {
+ if (data.data) RtlCopyMemory(&Common->buffer, data.data, data.size);
+ }
+ Common->size = data.size;
+ ERR("DDE Post CB size %d\n",data.size);
+ }
+ else
+ {
+ ERR("Return bad msg 0x%x Size %d\n",Common->message,Common->size);
+ }
+
+ return ZwCallbackReturn(Arguments, ArgumentLength, Ret ? STATUS_SUCCESS :
STATUS_UNSUCCESSFUL);
+}
+
+NTSTATUS
+WINAPI
+User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+ BOOL Ret;
+ PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
+
+ ERR("DDE Get CB size %d\n",Common->size);
+
+ Ret = unpack_dde_message( Common->hwnd, Common->message, &Common->lParam,
Common->buffer, Common->size );
+
+ return ZwCallbackReturn(Arguments, ArgumentLength, Ret ? STATUS_SUCCESS :
STATUS_UNSUCCESSFUL);
+}
+
+
/*
* @unimplemented
Modified: trunk/reactos/win32ss/user/user32/misc/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/d…
==============================================================================
--- trunk/reactos/win32ss/user/user32/misc/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/misc/dllmain.c [iso-8859-1] Thu Jan 8 00:56:51
2015
@@ -203,6 +203,8 @@
User32CallCopyImageFromKernel,
User32CallSetWndIconsFromKernel,
User32DeliverUserAPC,
+ User32CallDDEPostFromKernel,
+ User32CallDDEGetFromKernel,
};
Modified: trunk/reactos/win32ss/user/user32/windows/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/window…
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/message.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/message.c [iso-8859-1] Thu Jan 8 00:56:51
2015
@@ -163,7 +163,7 @@
static unsigned DdeNumUsed = 0;
static CRITICAL_SECTION DdeCrst;
-static BOOL FASTCALL
+BOOL FASTCALL
DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
{
unsigned i;
@@ -213,7 +213,7 @@
return TRUE;
}
-static HGLOBAL FASTCALL
+HGLOBAL FASTCALL
DdeGetPair(HGLOBAL ServerMem)
{
unsigned i;
@@ -357,67 +357,12 @@
switch (UMMsg->message)
{
- case WM_DDE_ACK:
- {
- PDDEPACK DdeLparam;
- DdeLparam = HeapAlloc(GetProcessHeap(), 0, sizeof(DDEPACK));
- if (!DdeLparam ||
- !UnpackDDElParam( UMMsg->message, UMMsg->lParam,
&DdeLparam->uiLo, &DdeLparam->uiHi))
- return FALSE;
- /*
- If this is a reply to WM_DDE_EXECUTE then
- uiHi will contain a hMem, hence >= 0x10000.
- Otherwise, it will be be an atom, a 16-bit value.
- */
- if (!IS_ATOM(DdeLparam->uiHi))
- {
- HGLOBAL h = DdeGetPair((HGLOBAL)(ULONG_PTR)DdeLparam->uiHi);
- if (h)
- {
- GlobalFree((HGLOBAL)(ULONG_PTR)DdeLparam->uiHi);
- DdeLparam->uiHi = (UINT_PTR) h;
- }
- }
- FreeDDElParam(UMMsg->message, 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 (!Data)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- KMDdeExecuteData = HeapAlloc(GetProcessHeap(), 0, sizeof(KMDDEEXECUTEDATA) +
Size);
- if (!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;
-
case WM_COPYDATA:
{
PCOPYDATASTRUCT pUMCopyData = (PCOPYDATASTRUCT)UMMsg->lParam;
PCOPYDATASTRUCT pKMCopyData;
- pKMCopyData = HeapAlloc(GetProcessHeap(), 0,
- sizeof(COPYDATASTRUCT) + pUMCopyData->cbData);
+ pKMCopyData = HeapAlloc(GetProcessHeap(), 0, sizeof(COPYDATASTRUCT) +
pUMCopyData->cbData);
if (!pKMCopyData)
{
SetLastError(ERROR_OUTOFMEMORY);
@@ -428,8 +373,7 @@
pKMCopyData->cbData = pUMCopyData->cbData;
pKMCopyData->lpData = pKMCopyData + 1;
- RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData,
- pUMCopyData->cbData);
+ RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData,
pUMCopyData->cbData);
KMMsg->lParam = (LPARAM)pKMCopyData;
}
@@ -448,8 +392,6 @@
{
switch (KMMsg->message)
{
- case WM_DDE_ACK:
- case WM_DDE_EXECUTE:
case WM_COPYDATA:
HeapFree(GetProcessHeap(), 0, (LPVOID) KMMsg->lParam);
break;
@@ -464,6 +406,8 @@
MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg)
{
*UMMsg = *KMMsg;
+
+ if (KMMsg->lParam == 0) return TRUE;
switch (UMMsg->message)
{
@@ -485,43 +429,6 @@
Class += sizeof(WCHAR);
Cs->lpszClass = (LPCWSTR) Class;
}
- }
- break;
-
- case WM_DDE_ACK:
- {
- PDDEPACK DdeLparam = (PDDEPACK) KMMsg->lParam;
- UMMsg->lParam = PackDDElParam(KMMsg->message, DdeLparam->uiLo,
DdeLparam->uiHi);
- }
- break;
-
- case WM_DDE_EXECUTE:
- {
- PKMDDEEXECUTEDATA KMDdeExecuteData;
- HGLOBAL GlobalData;
- PVOID Data;
-
- KMDdeExecuteData = (PKMDDEEXECUTEDATA) KMMsg->lParam;
- GlobalData = GlobalAlloc(GMEM_MOVEABLE, KMMsg->wParam -
sizeof(KMDDEEXECUTEDATA));
- if (!GlobalData)
- {
- return FALSE;
- }
- Data = GlobalLock(GlobalData);
- if (!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;
@@ -2967,6 +2874,11 @@
KMMsg.lParam = (LPARAM) ((char *) CallbackArgs +
sizeof(WINDOWPROC_CALLBACK_ARGUMENTS));
switch(KMMsg.message)
{
+ case WM_SYSTIMER:
+ {
+ ERR("WM_SYSTIMER %p\n",KMMsg.hwnd);
+ break;
+ }
case WM_SIZING:
{
PRECT prect = (PRECT) KMMsg.lParam;