mirror of
https://github.com/reactos/reactos.git
synced 2025-06-12 11:38:41 +00:00
[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. svn path=/trunk/; revision=66000
This commit is contained in:
parent
418366bf44
commit
2d94b2173f
11 changed files with 671 additions and 159 deletions
|
@ -14,7 +14,9 @@
|
||||||
#define USER32_CALLBACK_COPYIMAGE (10)
|
#define USER32_CALLBACK_COPYIMAGE (10)
|
||||||
#define USER32_CALLBACK_SETWNDICONS (11)
|
#define USER32_CALLBACK_SETWNDICONS (11)
|
||||||
#define USER32_CALLBACK_DELIVERUSERAPC (12)
|
#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
|
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
|
||||||
{
|
{
|
||||||
|
@ -115,6 +117,14 @@ typedef struct _SETWNDICONS_CALLBACK_ARGUMENTS
|
||||||
HICON hIconWindows;
|
HICON hIconWindows;
|
||||||
} SETWNDICONS_CALLBACK_ARGUMENTS, *PSETWNDICONS_CALLBACK_ARGUMENTS;
|
} 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
|
NTSTATUS WINAPI
|
||||||
User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
NTSTATUS WINAPI
|
NTSTATUS WINAPI
|
||||||
|
@ -141,4 +151,8 @@ NTSTATUS WINAPI
|
||||||
User32CallGetCharsetInfo(PVOID Arguments, ULONG ArgumentLength);
|
User32CallGetCharsetInfo(PVOID Arguments, ULONG ArgumentLength);
|
||||||
NTSTATUS WINAPI
|
NTSTATUS WINAPI
|
||||||
User32DeliverUserAPC(PVOID Arguments, ULONG ArgumentLength);
|
User32DeliverUserAPC(PVOID Arguments, ULONG ArgumentLength);
|
||||||
|
NTSTATUS WINAPI
|
||||||
|
User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
|
NTSTATUS WINAPI
|
||||||
|
User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
#endif /* __INCLUDE_USER32_CALLBACK_H */
|
#endif /* __INCLUDE_USER32_CALLBACK_H */
|
||||||
|
|
|
@ -301,6 +301,12 @@ C_ASSERT(sizeof(CLIENTINFO) <= sizeof(((PTEB)0)->Win32ClientInfo));
|
||||||
|
|
||||||
#define GetWin32ClientInfo() ((PCLIENTINFO)(NtCurrentTeb()->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_NULL ( (HRGN) 0) // NULL empty region
|
||||||
#define HRGN_WINDOW ( (HRGN) 1) // region from window rcWindow
|
#define HRGN_WINDOW ( (HRGN) 1) // region from window rcWindow
|
||||||
#define HRGN_MONITOR ( (HRGN) 2) // region from monitor region.
|
#define HRGN_MONITOR ( (HRGN) 2) // region from monitor region.
|
||||||
|
@ -3417,19 +3423,7 @@ DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserYieldTask(VOID);
|
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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1052,6 +1052,7 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
|
||||||
/* FIXME: The class was created before being connected
|
/* FIXME: The class was created before being connected
|
||||||
to a desktop. It is possible for the desktop window,
|
to a desktop. It is possible for the desktop window,
|
||||||
but should it be allowed for any other case? */
|
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);
|
Class = UserHeapAlloc(ClassSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2367,7 +2368,7 @@ UserGetClassInfo(IN PCLS Class,
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// ???
|
// Register System Classes....
|
||||||
//
|
//
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
|
|
@ -5,39 +5,167 @@
|
||||||
|
|
||||||
DBG_DEFAULT_CHANNEL(UserMisc);
|
DBG_DEFAULT_CHANNEL(UserMisc);
|
||||||
|
|
||||||
|
typedef struct _DDE_DATA
|
||||||
BOOL FASTCALL
|
|
||||||
IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
PWND pWndServer;
|
LPARAM lParam;
|
||||||
|
int cbSize;
|
||||||
|
PVOID pvBuffer;
|
||||||
|
} DDE_DATA, *PDDE_DATA;
|
||||||
|
|
||||||
if (pWnd->head.pti->ppi != gptiCurrent->ppi)
|
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)
|
||||||
{
|
{
|
||||||
// Allow only Acknowledge and Initiate to be sent across borders.
|
return FALSE;
|
||||||
if (Msg != WM_DDE_ACK )
|
|
||||||
{
|
|
||||||
if (Msg == WM_DDE_INITIATE) return TRUE;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pWndServer = UserGetWindowObject((HWND)wParam);
|
|
||||||
if (pWndServer == NULL)
|
|
||||||
{
|
|
||||||
ERR("Invalid DDE Server Window handle\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
ERR("Sending DDE 0x%x\n",Msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
|
||||||
IntDdePostMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
|
BOOL
|
||||||
|
APIENTRY
|
||||||
|
IntDdePostMessageHook(
|
||||||
|
IN PWND pWnd,
|
||||||
|
IN UINT Msg,
|
||||||
|
IN WPARAM wParam,
|
||||||
|
IN OUT LPARAM *lParam,
|
||||||
|
IN OUT LONG_PTR *ExtraInfo)
|
||||||
{
|
{
|
||||||
PWND pWndClient;
|
PWND pWndClient;
|
||||||
|
PDDE_DATA pddeData;
|
||||||
|
HGDIOBJ Object = NULL;
|
||||||
|
PVOID Buffer = NULL;
|
||||||
|
int size = 128;
|
||||||
|
LPARAM lp = *lParam;
|
||||||
|
|
||||||
if (pWnd->head.pti->ppi != gptiCurrent->ppi)
|
if (pWnd->head.pti->ppi != gptiCurrent->ppi)
|
||||||
{
|
{
|
||||||
|
ERR("Posting long DDE 0x%x\n",Msg);
|
||||||
// Initiate is sent only across borders.
|
// Initiate is sent only across borders.
|
||||||
if (Msg == WM_DDE_INITIATE)
|
if (Msg == WM_DDE_INITIATE)
|
||||||
{
|
{
|
||||||
|
@ -47,26 +175,206 @@ IntDdePostMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
pWndClient = UserGetWindowObject((HWND)wParam);
|
pWndClient = UserGetWindowObject((HWND)wParam);
|
||||||
if (pWndClient == NULL)
|
if (pWndClient == NULL)
|
||||||
{
|
{
|
||||||
// This is terminating so post it.
|
// This is terminating so post it.
|
||||||
if ( Msg == WM_DDE_TERMINATE) return TRUE;
|
if ( Msg == WM_DDE_TERMINATE)
|
||||||
ERR("Invalid DDE Client Window handle\n");
|
{
|
||||||
return FALSE;
|
ERR("DDE Posted WM_DDE_TERMINATE\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
ERR("Invalid DDE Client Window handle\n");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
ERR("Posting and do CB DDE 0x%x\n",Msg);
|
|
||||||
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID APIENTRY
|
||||||
IntDdeGetMessageHook(PMSG pMsg)
|
IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
|
||||||
{
|
{
|
||||||
if (pMsg->message == WM_DDE_TERMINATE)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
ERR("Do Callback Msg 0x%x\n",pMsg->message);
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
if (Msg == WM_DDE_INITIATE) return TRUE;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserDdeGetQualityOfService(
|
NtUserDdeGetQualityOfService(
|
||||||
|
|
|
@ -122,8 +122,6 @@ MSGMEMORY, *PMSGMEMORY;
|
||||||
static MSGMEMORY g_MsgMemory[] =
|
static MSGMEMORY g_MsgMemory[] =
|
||||||
{
|
{
|
||||||
{ WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
|
{ 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_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
|
||||||
{ WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
|
{ WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
|
||||||
{ WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
|
{ WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
|
||||||
|
@ -1014,14 +1012,12 @@ co_IntGetPeekMessage( PMSG pMsg,
|
||||||
bGMSG );
|
bGMSG );
|
||||||
if (Present)
|
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 )
|
if ( pMsg->message >= WM_DDE_FIRST && pMsg->message <= WM_DDE_LAST )
|
||||||
{
|
{
|
||||||
IntDdeGetMessageHook(pMsg);
|
IntDdeGetMessageHook(pMsg, ExtraInfo);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* GetMessage or PostMessage must never get messages that contain pointers */
|
|
||||||
ASSERT(FindMsgMemory(pMsg->message) == NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
|
if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
|
||||||
|
@ -1206,11 +1202,12 @@ UserPostMessage( HWND Wnd,
|
||||||
|
|
||||||
if ( Msg >= WM_DDE_FIRST && Msg <= WM_DDE_LAST )
|
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);
|
ERR("Posting Exit DDE 0x%x\n",Msg);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
ERR("DDE Post lParam c=%08lx\n",lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WM_QUIT == Msg)
|
if (WM_QUIT == Msg)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
ATOM AtomQOS;/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* PURPOSE: ntuser init. and main funcs.
|
* PURPOSE: ntuser init. and main funcs.
|
||||||
|
@ -15,11 +15,12 @@ BOOL FASTCALL RegisterControlAtoms(VOID);
|
||||||
PTHREADINFO gptiCurrent = NULL;
|
PTHREADINFO gptiCurrent = NULL;
|
||||||
PPROCESSINFO gppiInputProvider = NULL;
|
PPROCESSINFO gppiInputProvider = NULL;
|
||||||
ERESOURCE UserLock;
|
ERESOURCE UserLock;
|
||||||
ATOM AtomMessage; // Window Message atom.
|
ATOM AtomMessage; // Window Message atom.
|
||||||
ATOM AtomWndObj; // Window Object atom.
|
ATOM AtomWndObj; // Window Object atom.
|
||||||
ATOM AtomLayer; // Window Layer atom.
|
ATOM AtomLayer; // Window Layer atom.
|
||||||
ATOM AtomFlashWndState; // Window Flash State 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;
|
HINSTANCE hModClient = NULL;
|
||||||
BOOL ClientPfnInit = FALSE;
|
BOOL ClientPfnInit = FALSE;
|
||||||
ATOM gaGuiConsoleWndClass;
|
ATOM gaGuiConsoleWndClass;
|
||||||
|
@ -52,6 +53,7 @@ InitUserAtoms(VOID)
|
||||||
gpsi->atomFrostedWindowProp = IntAddGlobalAtom(L"SysFrostedWindow", TRUE);
|
gpsi->atomFrostedWindowProp = IntAddGlobalAtom(L"SysFrostedWindow", TRUE);
|
||||||
|
|
||||||
AtomDDETrack = IntAddGlobalAtom(L"SysDT", 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
|
* FIXME: AddPropW uses the global kernel atom table, thus leading to conflicts if we use
|
||||||
|
|
|
@ -15,6 +15,8 @@ extern PPROCESSINFO gppiList;
|
||||||
extern PPROCESSINFO ppiScrnSaver;
|
extern PPROCESSINFO ppiScrnSaver;
|
||||||
extern PPROCESSINFO gppiInputProvider;
|
extern PPROCESSINFO gppiInputProvider;
|
||||||
extern ATOM gaGuiConsoleWndClass;
|
extern ATOM gaGuiConsoleWndClass;
|
||||||
|
extern ATOM AtomDDETrack;
|
||||||
|
extern ATOM AtomQOS;
|
||||||
|
|
||||||
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
|
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
|
||||||
VOID FASTCALL CleanupUserImpl(VOID);
|
VOID FASTCALL CleanupUserImpl(VOID);
|
||||||
|
|
|
@ -43,8 +43,8 @@ PWND FASTCALL IntGetWindowObject(HWND hWnd);
|
||||||
/*************** DDE.C ****************/
|
/*************** DDE.C ****************/
|
||||||
|
|
||||||
BOOL FASTCALL IntDdeSendMessageHook(PWND,UINT,WPARAM,LPARAM);
|
BOOL FASTCALL IntDdeSendMessageHook(PWND,UINT,WPARAM,LPARAM);
|
||||||
BOOL FASTCALL IntDdePostMessageHook(PWND,UINT,WPARAM,LPARAM);
|
BOOL APIENTRY IntDdePostMessageHook(IN PWND,IN UINT,IN WPARAM,IN OUT LPARAM*,IN OUT LONG_PTR*);
|
||||||
VOID FASTCALL IntDdeGetMessageHook(PMSG);
|
VOID APIENTRY IntDdeGetMessageHook(PMSG,LONG_PTR);
|
||||||
|
|
||||||
/*************** MAIN.C ***************/
|
/*************** MAIN.C ***************/
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,286 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
|
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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -203,6 +203,8 @@ PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] =
|
||||||
User32CallCopyImageFromKernel,
|
User32CallCopyImageFromKernel,
|
||||||
User32CallSetWndIconsFromKernel,
|
User32CallSetWndIconsFromKernel,
|
||||||
User32DeliverUserAPC,
|
User32DeliverUserAPC,
|
||||||
|
User32CallDDEPostFromKernel,
|
||||||
|
User32CallDDEGetFromKernel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ static unsigned DdeNumAlloc = 0;
|
||||||
static unsigned DdeNumUsed = 0;
|
static unsigned DdeNumUsed = 0;
|
||||||
static CRITICAL_SECTION DdeCrst;
|
static CRITICAL_SECTION DdeCrst;
|
||||||
|
|
||||||
static BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
|
DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -213,7 +213,7 @@ DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HGLOBAL FASTCALL
|
HGLOBAL FASTCALL
|
||||||
DdeGetPair(HGLOBAL ServerMem)
|
DdeGetPair(HGLOBAL ServerMem)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -357,67 +357,12 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
|
||||||
|
|
||||||
switch (UMMsg->message)
|
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:
|
case WM_COPYDATA:
|
||||||
{
|
{
|
||||||
PCOPYDATASTRUCT pUMCopyData = (PCOPYDATASTRUCT)UMMsg->lParam;
|
PCOPYDATASTRUCT pUMCopyData = (PCOPYDATASTRUCT)UMMsg->lParam;
|
||||||
PCOPYDATASTRUCT pKMCopyData;
|
PCOPYDATASTRUCT pKMCopyData;
|
||||||
|
|
||||||
pKMCopyData = HeapAlloc(GetProcessHeap(), 0,
|
pKMCopyData = HeapAlloc(GetProcessHeap(), 0, sizeof(COPYDATASTRUCT) + pUMCopyData->cbData);
|
||||||
sizeof(COPYDATASTRUCT) + pUMCopyData->cbData);
|
|
||||||
if (!pKMCopyData)
|
if (!pKMCopyData)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
@ -428,8 +373,7 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
|
||||||
pKMCopyData->cbData = pUMCopyData->cbData;
|
pKMCopyData->cbData = pUMCopyData->cbData;
|
||||||
pKMCopyData->lpData = pKMCopyData + 1;
|
pKMCopyData->lpData = pKMCopyData + 1;
|
||||||
|
|
||||||
RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData,
|
RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData, pUMCopyData->cbData);
|
||||||
pUMCopyData->cbData);
|
|
||||||
|
|
||||||
KMMsg->lParam = (LPARAM)pKMCopyData;
|
KMMsg->lParam = (LPARAM)pKMCopyData;
|
||||||
}
|
}
|
||||||
|
@ -448,8 +392,6 @@ MsgiUMToKMCleanup(PMSG UMMsg, PMSG KMMsg)
|
||||||
{
|
{
|
||||||
switch (KMMsg->message)
|
switch (KMMsg->message)
|
||||||
{
|
{
|
||||||
case WM_DDE_ACK:
|
|
||||||
case WM_DDE_EXECUTE:
|
|
||||||
case WM_COPYDATA:
|
case WM_COPYDATA:
|
||||||
HeapFree(GetProcessHeap(), 0, (LPVOID) KMMsg->lParam);
|
HeapFree(GetProcessHeap(), 0, (LPVOID) KMMsg->lParam);
|
||||||
break;
|
break;
|
||||||
|
@ -465,6 +407,8 @@ MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg)
|
||||||
{
|
{
|
||||||
*UMMsg = *KMMsg;
|
*UMMsg = *KMMsg;
|
||||||
|
|
||||||
|
if (KMMsg->lParam == 0) return TRUE;
|
||||||
|
|
||||||
switch (UMMsg->message)
|
switch (UMMsg->message)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
|
@ -488,43 +432,6 @@ MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg)
|
||||||
}
|
}
|
||||||
break;
|
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;
|
|
||||||
|
|
||||||
case WM_COPYDATA:
|
case WM_COPYDATA:
|
||||||
{
|
{
|
||||||
PCOPYDATASTRUCT pKMCopyData = (PCOPYDATASTRUCT)KMMsg->lParam;
|
PCOPYDATASTRUCT pKMCopyData = (PCOPYDATASTRUCT)KMMsg->lParam;
|
||||||
|
@ -2967,6 +2874,11 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
KMMsg.lParam = (LPARAM) ((char *) CallbackArgs + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS));
|
KMMsg.lParam = (LPARAM) ((char *) CallbackArgs + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS));
|
||||||
switch(KMMsg.message)
|
switch(KMMsg.message)
|
||||||
{
|
{
|
||||||
|
case WM_SYSTIMER:
|
||||||
|
{
|
||||||
|
ERR("WM_SYSTIMER %p\n",KMMsg.hwnd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WM_SIZING:
|
case WM_SIZING:
|
||||||
{
|
{
|
||||||
PRECT prect = (PRECT) KMMsg.lParam;
|
PRECT prect = (PRECT) KMMsg.lParam;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue