mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 09:52:56 +00:00
[Win32ss]
- Fix remaining DDE issues, re-sync DDE code from wine. Add QOS startup. Moved error debug prints to traces. Over all improvement with test results. svn path=/trunk/; revision=66011
This commit is contained in:
parent
9a959644b3
commit
87a268ef23
8 changed files with 197 additions and 135 deletions
|
@ -122,6 +122,7 @@ typedef struct _DDEPOSTGET_CALLBACK_ARGUMENTS
|
||||||
INT Type;
|
INT Type;
|
||||||
MSG;
|
MSG;
|
||||||
int size;
|
int size;
|
||||||
|
PVOID pvData;
|
||||||
BYTE buffer[1];
|
BYTE buffer[1];
|
||||||
} DDEPOSTGET_CALLBACK_ARGUMENTS, *PDDEPOSTGET_CALLBACK_ARGUMENTS;
|
} DDEPOSTGET_CALLBACK_ARGUMENTS, *PDDEPOSTGET_CALLBACK_ARGUMENTS;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Win32k subsystem
|
||||||
|
* PURPOSE: Dynamic Data Exchange
|
||||||
|
* FILE: win32ss/user/ntuser/dde.c
|
||||||
|
* PROGRAMER:
|
||||||
|
*/
|
||||||
|
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
|
|
||||||
|
@ -5,6 +12,19 @@
|
||||||
|
|
||||||
DBG_DEFAULT_CHANNEL(UserMisc);
|
DBG_DEFAULT_CHANNEL(UserMisc);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default information used to support client impersonation.
|
||||||
|
//
|
||||||
|
SECURITY_QUALITY_OF_SERVICE gqosDefault = {sizeof(SECURITY_QUALITY_OF_SERVICE),SecurityImpersonation,SECURITY_STATIC_TRACKING,TRUE};
|
||||||
|
|
||||||
|
typedef struct _DDEIMP
|
||||||
|
{
|
||||||
|
SECURITY_QUALITY_OF_SERVICE qos;
|
||||||
|
SECURITY_CLIENT_CONTEXT ClientContext;
|
||||||
|
WORD cRefInit;
|
||||||
|
WORD cRefConv;
|
||||||
|
} DDEIMP, *PDDEIMP;
|
||||||
|
|
||||||
typedef struct _DDE_DATA
|
typedef struct _DDE_DATA
|
||||||
{
|
{
|
||||||
LPARAM lParam;
|
LPARAM lParam;
|
||||||
|
@ -16,10 +36,13 @@ typedef struct _DDE_PROP
|
||||||
{
|
{
|
||||||
PWND spwnd;
|
PWND spwnd;
|
||||||
PWND spwndPartner;
|
PWND spwndPartner;
|
||||||
|
PDDEIMP pddei;
|
||||||
} DDE_PROP, *PDDE_PROP;
|
} DDE_PROP, *PDDE_PROP;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DDE Posting message callback to user side.
|
||||||
|
//
|
||||||
int
|
int
|
||||||
APIENTRY
|
APIENTRY
|
||||||
IntDDEPostCallback(
|
IntDDEPostCallback(
|
||||||
|
@ -27,17 +50,15 @@ IntDDEPostCallback(
|
||||||
IN UINT Msg,
|
IN UINT Msg,
|
||||||
IN WPARAM wParam,
|
IN WPARAM wParam,
|
||||||
IN OUT LPARAM *lParam,
|
IN OUT LPARAM *lParam,
|
||||||
IN PVOID Buffer,
|
IN OUT PVOID *Buffer)
|
||||||
IN int size)
|
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG ArgumentLength, ResultLength;
|
ULONG ArgumentLength, ResultLength;
|
||||||
PVOID Argument, ResultPointer;
|
PVOID Argument, ResultPointer;
|
||||||
PDDEPOSTGET_CALLBACK_ARGUMENTS Common;
|
PDDEPOSTGET_CALLBACK_ARGUMENTS Common;
|
||||||
int origSize = size;
|
int size = 0;
|
||||||
|
|
||||||
ResultPointer = NULL;
|
ResultPointer = NULL;
|
||||||
ResultLength = ArgumentLength = sizeof(DDEPOSTGET_CALLBACK_ARGUMENTS)+size;
|
ResultLength = ArgumentLength = sizeof(DDEPOSTGET_CALLBACK_ARGUMENTS);
|
||||||
|
|
||||||
Argument = IntCbAllocateMemory(ArgumentLength);
|
Argument = IntCbAllocateMemory(ArgumentLength);
|
||||||
if (NULL == Argument)
|
if (NULL == Argument)
|
||||||
|
@ -47,12 +68,12 @@ IntDDEPostCallback(
|
||||||
|
|
||||||
Common = (PDDEPOSTGET_CALLBACK_ARGUMENTS) Argument;
|
Common = (PDDEPOSTGET_CALLBACK_ARGUMENTS) Argument;
|
||||||
|
|
||||||
Common->size = size;
|
Common->pvData = 0;
|
||||||
|
Common->size = 0;
|
||||||
Common->hwnd = UserHMGetHandle(pWnd);
|
Common->hwnd = UserHMGetHandle(pWnd);
|
||||||
Common->message = Msg;
|
Common->message = Msg;
|
||||||
Common->wParam = wParam;
|
Common->wParam = wParam;
|
||||||
Common->lParam = *lParam;
|
Common->lParam = *lParam;
|
||||||
RtlCopyMemory(&Common->buffer, Buffer, size);
|
|
||||||
|
|
||||||
UserLeaveCo();
|
UserLeaveCo();
|
||||||
|
|
||||||
|
@ -73,19 +94,26 @@ IntDDEPostCallback(
|
||||||
|
|
||||||
RtlCopyMemory(Common, ResultPointer, ArgumentLength);
|
RtlCopyMemory(Common, ResultPointer, ArgumentLength);
|
||||||
|
|
||||||
if (Common->size != 0 && size <= origSize)
|
///// HAX!
|
||||||
|
if ( Common->size == 0xdeadbeef )
|
||||||
{
|
{
|
||||||
RtlCopyMemory(Buffer, &Common->buffer, size); // ResultLength);
|
ERR("DDE Post callback failed! 2 status %p\n",Status);
|
||||||
|
IntCbFreeMemory(Argument);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = Common->size;
|
size = Common->size;
|
||||||
*lParam = Common->lParam;
|
*lParam = Common->lParam;
|
||||||
|
*Buffer = Common->pvData;
|
||||||
|
|
||||||
IntCbFreeMemory(Argument);
|
IntCbFreeMemory(Argument);
|
||||||
|
|
||||||
return size ? size : -1;
|
return size ? size : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DDE Get/Peek message callback to user side.
|
||||||
|
//
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
IntDDEGetCallback(
|
IntDDEGetCallback(
|
||||||
|
@ -118,7 +146,6 @@ IntDDEGetCallback(
|
||||||
|
|
||||||
if (size && Buffer) RtlCopyMemory(&Common->buffer, Buffer, size);
|
if (size && Buffer) RtlCopyMemory(&Common->buffer, Buffer, size);
|
||||||
|
|
||||||
|
|
||||||
UserLeaveCo();
|
UserLeaveCo();
|
||||||
|
|
||||||
Status = KeUserModeCallback(USER32_CALLBACK_DDEGET,
|
Status = KeUserModeCallback(USER32_CALLBACK_DDEGET,
|
||||||
|
@ -138,6 +165,14 @@ IntDDEGetCallback(
|
||||||
|
|
||||||
RtlMoveMemory(Common, ResultPointer, ArgumentLength);
|
RtlMoveMemory(Common, ResultPointer, ArgumentLength);
|
||||||
|
|
||||||
|
///// HAX!
|
||||||
|
if ( Common->size == 0xdeadbeef )
|
||||||
|
{
|
||||||
|
ERR("DDE Get callback failed! 2 status %p\n",Status);
|
||||||
|
IntCbFreeMemory(Argument);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
pMsg->lParam = Common->lParam;
|
pMsg->lParam = Common->lParam;
|
||||||
|
|
||||||
IntCbFreeMemory(Argument);
|
IntCbFreeMemory(Argument);
|
||||||
|
@ -145,8 +180,9 @@ IntDDEGetCallback(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DDE Post message hook, intercept DDE messages before going on to the target Processes Thread queue.
|
||||||
|
//
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
IntDdePostMessageHook(
|
IntDdePostMessageHook(
|
||||||
|
@ -158,14 +194,15 @@ IntDdePostMessageHook(
|
||||||
{
|
{
|
||||||
PWND pWndClient;
|
PWND pWndClient;
|
||||||
PDDE_DATA pddeData;
|
PDDE_DATA pddeData;
|
||||||
|
int size;
|
||||||
HGDIOBJ Object = NULL;
|
HGDIOBJ Object = NULL;
|
||||||
|
PVOID userBuf = NULL;
|
||||||
PVOID Buffer = NULL;
|
PVOID Buffer = NULL;
|
||||||
int size = 128;
|
|
||||||
LPARAM lp = *lParam;
|
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);
|
TRACE("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)
|
||||||
{
|
{
|
||||||
|
@ -178,14 +215,14 @@ IntDdePostMessageHook(
|
||||||
// This is terminating so post it.
|
// This is terminating so post it.
|
||||||
if ( Msg == WM_DDE_TERMINATE)
|
if ( Msg == WM_DDE_TERMINATE)
|
||||||
{
|
{
|
||||||
ERR("DDE Posted WM_DDE_TERMINATE\n");
|
TRACE("DDE Posted WM_DDE_TERMINATE\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
ERR("Invalid DDE Client Window handle\n");
|
TRACE("Invalid DDE Client Window handle\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Msg == WM_DDE_TERMINATE )
|
if ( Msg == WM_DDE_TERMINATE )
|
||||||
{
|
{
|
||||||
//// FIXME Remove Stuff if any...
|
//// FIXME Remove Stuff if any...
|
||||||
|
|
||||||
|
@ -193,26 +230,34 @@ IntDdePostMessageHook(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer = ExAllocatePoolWithTag(PagedPool, size, USERTAG_DDE);
|
if ( Msg == WM_DDE_EXECUTE && *lParam == 0)
|
||||||
|
{
|
||||||
|
// Do not bother to do a callback.
|
||||||
|
TRACE("DDE Post EXECUTE lParam 0\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((size = IntDDEPostCallback(pWnd, Msg, wParam, &lp, Buffer, size)) == 0)
|
// Callback.
|
||||||
|
if ((size = IntDDEPostCallback(pWnd, Msg, wParam, &lp, &userBuf)) == 0)
|
||||||
{
|
{
|
||||||
ERR("DDE Post Callback return 0 0x%x\n", Msg);
|
ERR("DDE Post Callback return 0 0x%x\n", Msg);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size != -1 && size > 128)
|
// No error HACK.
|
||||||
{
|
|
||||||
ERR("FIXME: DDE Post need more bytes %d\n",size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size == -1)
|
if (size == -1)
|
||||||
{
|
{
|
||||||
size = 0;
|
size = 0;
|
||||||
ExFreePoolWithTag(Buffer, USERTAG_DDE);
|
}
|
||||||
Buffer = NULL;
|
else
|
||||||
|
{
|
||||||
|
// Set buffer with users data size.
|
||||||
|
Buffer = ExAllocatePoolWithTag(PagedPool, size, USERTAG_DDE);
|
||||||
|
// No SEH? Yes, the user memory is freed after the Acknowledgment or at Termination.
|
||||||
|
RtlCopyMemory(Buffer, userBuf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("DDE Post size %d 0x%x\n",size, Msg);
|
TRACE("DDE Post size %d 0x%x\n",size, Msg);
|
||||||
|
|
||||||
switch(Msg)
|
switch(Msg)
|
||||||
{
|
{
|
||||||
|
@ -245,7 +290,6 @@ IntDdePostMessageHook(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -257,13 +301,13 @@ IntDdePostMessageHook(
|
||||||
GreSetObjectOwner(Object, pWnd->head.pti->ppi->W32Pid);
|
GreSetObjectOwner(Object, pWnd->head.pti->ppi->W32Pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
pddeData = ExAllocatePoolWithTag(PagedPool, sizeof(DDE_DATA), USERTAG_DDE2);
|
pddeData = ExAllocatePoolWithTag(PagedPool, sizeof(DDE_DATA), USERTAG_DDE5);
|
||||||
|
|
||||||
pddeData->cbSize = size;
|
pddeData->cbSize = size;
|
||||||
pddeData->pvBuffer = Buffer;
|
pddeData->pvBuffer = Buffer;
|
||||||
pddeData->lParam = lp;
|
pddeData->lParam = lp;
|
||||||
|
|
||||||
ERR("DDE Post lParam c=%08lx\n",lp);
|
TRACE("DDE Post lParam c=%08lx\n",lp);
|
||||||
*lParam = lp;
|
*lParam = lp;
|
||||||
|
|
||||||
// Attach this data packet to the user message.
|
// Attach this data packet to the user message.
|
||||||
|
@ -272,7 +316,10 @@ IntDdePostMessageHook(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID APIENTRY
|
//
|
||||||
|
// DDE Get/Peek message hook, take preprocessed information and recombined it for the current Process Thread.
|
||||||
|
//
|
||||||
|
BOOL APIENTRY
|
||||||
IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
|
IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
|
||||||
{
|
{
|
||||||
PWND pWnd, pWndClient;
|
PWND pWnd, pWndClient;
|
||||||
|
@ -284,7 +331,7 @@ IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
|
||||||
if (pWnd == NULL)
|
if (pWnd == NULL)
|
||||||
{
|
{
|
||||||
ERR("DDE Get Window is dead. %p\n", pMsg->hwnd);
|
ERR("DDE Get Window is dead. %p\n", pMsg->hwnd);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMsg->message == WM_DDE_TERMINATE)
|
if (pMsg->message == WM_DDE_TERMINATE)
|
||||||
|
@ -301,37 +348,37 @@ IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
|
||||||
IntRemoveProp(pWnd, AtomDDETrack);
|
IntRemoveProp(pWnd, AtomDDETrack);
|
||||||
ExFreePoolWithTag(pddeProp, USERTAG_DDE1);
|
ExFreePoolWithTag(pddeProp, USERTAG_DDE1);
|
||||||
}
|
}
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("DDE Get Msg 0x%x\n",pMsg->message);
|
TRACE("DDE Get Msg 0x%x\n",pMsg->message);
|
||||||
|
|
||||||
pddeData = (PDDE_DATA)ExtraInfo;
|
pddeData = (PDDE_DATA)ExtraInfo;
|
||||||
|
|
||||||
if ( pddeData )
|
if ( pddeData )
|
||||||
{
|
{
|
||||||
ERR("DDE Get 1 size %d lParam c=%08lx lp c=%08lx\n",pddeData->cbSize, pMsg->lParam, pddeData->lParam);
|
TRACE("DDE Get 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.
|
|
||||||
|
|
||||||
|
// Callback.
|
||||||
Ret = IntDDEGetCallback( pWnd, pMsg, pddeData->pvBuffer, pddeData->cbSize);
|
Ret = IntDDEGetCallback( pWnd, pMsg, pddeData->pvBuffer, pddeData->cbSize);
|
||||||
if (!Ret)
|
if (!Ret)
|
||||||
{
|
{
|
||||||
ERR("DDE Get CB failed\n");
|
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);
|
if (pddeData->pvBuffer) ExFreePoolWithTag(pddeData->pvBuffer, USERTAG_DDE);
|
||||||
|
|
||||||
ExFreePoolWithTag(pddeData, USERTAG_DDE2);
|
ExFreePoolWithTag(pddeData, USERTAG_DDE5);
|
||||||
|
|
||||||
return;
|
return Ret;
|
||||||
}
|
}
|
||||||
ERR("DDE Get No DDE Data found!\n");
|
TRACE("DDE Get No DDE Data found!\n");
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DDE Send message hook, intercept DDE messages and associate them in a partnership with property.
|
||||||
|
//
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -340,12 +387,12 @@ IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
if (Msg == WM_DDE_ACK)
|
if (Msg == WM_DDE_ACK)
|
||||||
{
|
{
|
||||||
ERR("Sending WM_DDE_ACK Client hwnd %p\n",pWnd->head.h);
|
TRACE("Sending WM_DDE_ACK Client hwnd %p\n",pWnd->head.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pWnd->head.pti->ppi != gptiCurrent->ppi)
|
if (pWnd->head.pti->ppi != gptiCurrent->ppi)
|
||||||
{
|
{
|
||||||
ERR("Sending long DDE 0x%x\n",Msg);
|
TRACE("Sending long DDE 0x%x\n",Msg);
|
||||||
|
|
||||||
// Allow only Acknowledge and Initiate to be sent across borders.
|
// Allow only Acknowledge and Initiate to be sent across borders.
|
||||||
if (Msg != WM_DDE_ACK )
|
if (Msg != WM_DDE_ACK )
|
||||||
|
@ -354,7 +401,7 @@ IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("Sending long WM_DDE_ACK\n");
|
TRACE("Sending long WM_DDE_ACK\n");
|
||||||
|
|
||||||
pWndServer = UserGetWindowObject((HWND)wParam);
|
pWndServer = UserGetWindowObject((HWND)wParam);
|
||||||
if (pWndServer == NULL)
|
if (pWndServer == NULL)
|
||||||
|
@ -387,20 +434,6 @@ NtUserDdeGetQualityOfService(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
|
||||||
APIENTRY
|
|
||||||
NtUserDdeInitialize(
|
|
||||||
DWORD Unknown0,
|
|
||||||
DWORD Unknown1,
|
|
||||||
DWORD Unknown2,
|
|
||||||
DWORD Unknown3,
|
|
||||||
DWORD Unknown4)
|
|
||||||
{
|
|
||||||
STUB
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserDdeSetQualityOfService(
|
NtUserDdeSetQualityOfService(
|
||||||
|
@ -424,3 +457,17 @@ NtUserImpersonateDdeClientWindow(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
APIENTRY
|
||||||
|
NtUserDdeInitialize(
|
||||||
|
DWORD Unknown0,
|
||||||
|
DWORD Unknown1,
|
||||||
|
DWORD Unknown2,
|
||||||
|
DWORD Unknown3,
|
||||||
|
DWORD Unknown4)
|
||||||
|
{
|
||||||
|
STUB
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1017,7 +1017,11 @@ co_IntGetPeekMessage( PMSG pMsg,
|
||||||
|
|
||||||
if ( pMsg->message >= WM_DDE_FIRST && pMsg->message <= WM_DDE_LAST )
|
if ( pMsg->message >= WM_DDE_FIRST && pMsg->message <= WM_DDE_LAST )
|
||||||
{
|
{
|
||||||
IntDdeGetMessageHook(pMsg, ExtraInfo);
|
if (!IntDdeGetMessageHook(pMsg, ExtraInfo))
|
||||||
|
{
|
||||||
|
TRACE("DDE Get return ERROR\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
|
if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
|
||||||
|
@ -1204,10 +1208,10 @@ UserPostMessage( HWND Wnd,
|
||||||
{
|
{
|
||||||
if (!IntDdePostMessageHook(Window, Msg, wParam, &lParam, &ExtraInfo))
|
if (!IntDdePostMessageHook(Window, Msg, wParam, &lParam, &ExtraInfo))
|
||||||
{
|
{
|
||||||
ERR("Posting Exit DDE 0x%x\n",Msg);
|
TRACE("Posting Exit DDE 0x%x\n",Msg);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
ERR("DDE Post lParam c=%08lx\n",lParam);
|
Message.lParam = lParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WM_QUIT == Msg)
|
if (WM_QUIT == Msg)
|
||||||
|
|
|
@ -44,7 +44,7 @@ PWND FASTCALL IntGetWindowObject(HWND hWnd);
|
||||||
|
|
||||||
BOOL FASTCALL IntDdeSendMessageHook(PWND,UINT,WPARAM,LPARAM);
|
BOOL FASTCALL IntDdeSendMessageHook(PWND,UINT,WPARAM,LPARAM);
|
||||||
BOOL APIENTRY IntDdePostMessageHook(IN PWND,IN UINT,IN WPARAM,IN OUT LPARAM*,IN OUT LONG_PTR*);
|
BOOL APIENTRY IntDdePostMessageHook(IN PWND,IN UINT,IN WPARAM,IN OUT LPARAM*,IN OUT LONG_PTR*);
|
||||||
VOID APIENTRY IntDdeGetMessageHook(PMSG,LONG_PTR);
|
BOOL APIENTRY IntDdeGetMessageHook(PMSG,LONG_PTR);
|
||||||
|
|
||||||
/*************** MAIN.C ***************/
|
/*************** MAIN.C ***************/
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS user32.dll
|
||||||
|
* PURPOSE: Dynamic Data Exchange
|
||||||
|
* FILE: win32ss/user/user32/misc/dde.c
|
||||||
|
* PROGRAMER:
|
||||||
|
*/
|
||||||
|
|
||||||
#include <user32.h>
|
#include <user32.h>
|
||||||
#include <wine/debug.h>
|
#include <wine/debug.h>
|
||||||
|
@ -79,13 +86,13 @@ BOOL post_dde_message( struct packed_message *data, UINT message, LPARAM lParam
|
||||||
/* send back the value of h on the other side */
|
/* send back the value of h on the other side */
|
||||||
push_data( data, &hpack, sizeof(hpack) );
|
push_data( data, &hpack, sizeof(hpack) );
|
||||||
*lp = uiLo;
|
*lp = uiLo;
|
||||||
ERR( "send dde-ack %lx %08lx => %p\n", uiLo, uiHi, h );
|
TRACE( "send dde-ack %lx %08lx => %p\n", uiLo, uiHi, h );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* uiHi should contain either an atom or 0 */
|
/* uiHi should contain either an atom or 0 */
|
||||||
ERR( "send dde-ack %lx atom=%lx\n", uiLo, uiHi );
|
TRACE( "send dde-ack %lx atom=%lx\n", uiLo, uiHi );
|
||||||
*lp = MAKELONG( uiLo, uiHi );
|
*lp = MAKELONG( uiLo, uiHi );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -96,12 +103,17 @@ BOOL post_dde_message( struct packed_message *data, UINT message, LPARAM lParam
|
||||||
if (uiLo)
|
if (uiLo)
|
||||||
{
|
{
|
||||||
size = GlobalSize( (HGLOBAL)uiLo ) ;
|
size = GlobalSize( (HGLOBAL)uiLo ) ;
|
||||||
|
TRACE("WM_DDE_A D P size %d\n",size);
|
||||||
if ( (message == WM_DDE_ADVISE && size < sizeof(DDEADVISE)) ||
|
if ( (message == WM_DDE_ADVISE && size < sizeof(DDEADVISE)) ||
|
||||||
(message == WM_DDE_DATA && size < FIELD_OFFSET(DDEDATA, Value)) ||
|
(message == WM_DDE_DATA && size < FIELD_OFFSET(DDEDATA, Value)) ||
|
||||||
(message == WM_DDE_POKE && size < FIELD_OFFSET(DDEPOKE, Value)) )
|
(message == WM_DDE_POKE && size < FIELD_OFFSET(DDEPOKE, Value)) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (message != WM_DDE_DATA) return FALSE;
|
else if (message != WM_DDE_DATA)
|
||||||
|
{
|
||||||
|
TRACE("WM_DDE uiLo 0\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
*lp = uiHi;
|
*lp = uiHi;
|
||||||
if (uiLo)
|
if (uiLo)
|
||||||
|
@ -109,14 +121,14 @@ BOOL post_dde_message( struct packed_message *data, UINT message, LPARAM lParam
|
||||||
if ((ptr = GlobalLock( (HGLOBAL)uiLo) ))
|
if ((ptr = GlobalLock( (HGLOBAL)uiLo) ))
|
||||||
{
|
{
|
||||||
DDEDATA *dde_data = ptr;
|
DDEDATA *dde_data = ptr;
|
||||||
ERR("unused %d, fResponse %d, fRelease %d, fDeferUpd %d, fAckReq %d, cfFormat %d\n",
|
TRACE("unused %d, fResponse %d, fRelease %d, fDeferUpd %d, fAckReq %d, cfFormat %d\n",
|
||||||
dde_data->unused, dde_data->fResponse, dde_data->fRelease,
|
dde_data->unused, dde_data->fResponse, dde_data->fRelease,
|
||||||
dde_data->reserved, dde_data->fAckReq, dde_data->cfFormat);
|
dde_data->reserved, dde_data->fAckReq, dde_data->cfFormat);
|
||||||
push_data( data, ptr, size );
|
push_data( data, ptr, size );
|
||||||
hunlock = (HGLOBAL)uiLo;
|
hunlock = (HGLOBAL)uiLo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ERR( "send ddepack %u %lx\n", size, uiHi );
|
TRACE( "send ddepack %u %lx\n", size, uiHi );
|
||||||
break;
|
break;
|
||||||
case WM_DDE_EXECUTE:
|
case WM_DDE_EXECUTE:
|
||||||
if (lParam)
|
if (lParam)
|
||||||
|
@ -128,7 +140,7 @@ BOOL post_dde_message( struct packed_message *data, UINT message, LPARAM lParam
|
||||||
/* so that the other side can send it back on ACK */
|
/* so that the other side can send it back on ACK */
|
||||||
*lp = lParam;
|
*lp = lParam;
|
||||||
hunlock = (HGLOBAL)lParam;
|
hunlock = (HGLOBAL)lParam;
|
||||||
ERR("WM_DDE_EXECUTE text size %d\n",GlobalSize( (HGLOBAL)lParam ));
|
TRACE("WM_DDE_EXECUTE text size %d\n",GlobalSize( (HGLOBAL)lParam ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -152,7 +164,7 @@ BOOL unpack_dde_message( HWND hwnd, UINT message, LPARAM *lparam, PVOID buffer,
|
||||||
HGLOBAL hMem = 0;
|
HGLOBAL hMem = 0;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
|
|
||||||
ERR("udm : Size %d\n",size);
|
TRACE("udm : Size %d\n",size);
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
|
@ -167,13 +179,13 @@ BOOL unpack_dde_message( HWND hwnd, UINT message, LPARAM *lparam, PVOID buffer,
|
||||||
memcpy( &hpack, buffer, size );
|
memcpy( &hpack, buffer, size );
|
||||||
hMem = unpack_ptr( hpack );
|
hMem = unpack_ptr( hpack );
|
||||||
uiHi = (UINT_PTR)hMem;
|
uiHi = (UINT_PTR)hMem;
|
||||||
ERR("recv dde-ack %lx mem=%lx[%lx]\n", uiLo, uiHi, GlobalSize( hMem ));
|
TRACE("recv dde-ack %lx mem=%lx[%lx]\n", uiLo, uiHi, GlobalSize( hMem ));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uiLo = LOWORD( *lparam );
|
uiLo = LOWORD( *lparam );
|
||||||
uiHi = HIWORD( *lparam );
|
uiHi = HIWORD( *lparam );
|
||||||
ERR("recv dde-ack %lx atom=%lx\n", uiLo, uiHi);
|
TRACE("recv dde-ack %lx atom=%lx\n", uiLo, uiHi);
|
||||||
}
|
}
|
||||||
*lparam = PackDDElParam( WM_DDE_ACK, uiLo, uiHi );
|
*lparam = PackDDElParam( WM_DDE_ACK, uiLo, uiHi );
|
||||||
break;
|
break;
|
||||||
|
@ -210,80 +222,92 @@ BOOL unpack_dde_message( HWND hwnd, UINT message, LPARAM *lparam, PVOID buffer,
|
||||||
{
|
{
|
||||||
memcpy( ptr, buffer, size );
|
memcpy( ptr, buffer, size );
|
||||||
GlobalUnlock( hMem );
|
GlobalUnlock( hMem );
|
||||||
ERR( "exec: pairing c=%08lx s=%p\n", *lparam, hMem );
|
TRACE( "exec: pairing c=%08lx s=%p\n", *lparam, hMem );
|
||||||
if (!DdeAddPair( (HGLOBAL)*lparam, hMem ))
|
if (!DdeAddPair( (HGLOBAL)*lparam, hMem ))
|
||||||
{
|
{
|
||||||
GlobalFree( hMem );
|
GlobalFree( hMem );
|
||||||
ERR("udm exec: GF 1\n");
|
TRACE("udm exec: GF 1\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GlobalFree( hMem );
|
GlobalFree( hMem );
|
||||||
ERR("udm exec: GF 2\n");
|
TRACE("udm exec: GF 2\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("udm exec: No Size\n");
|
TRACE("udm exec: No Size\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR( "exec: exit c=%08lx s=%p\n", *lparam, hMem );
|
TRACE( "exec: exit c=%08lx s=%p\n", *lparam, hMem );
|
||||||
*lparam = (LPARAM)hMem;
|
*lparam = (LPARAM)hMem;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DDE Post kernel callback.
|
||||||
|
//
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
{
|
{
|
||||||
struct packed_message data;
|
struct packed_message data;
|
||||||
BOOL Ret;
|
BOOL Ret;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
|
PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
|
||||||
|
|
||||||
data.data = 0;
|
data.data = 0;
|
||||||
data.size = 0;
|
data.size = 0;
|
||||||
ERR("DDE Post CB\n");
|
TRACE("DDE Post CB\n");
|
||||||
Ret = post_dde_message( &data, Common->message, Common->lParam, &Common->lParam);
|
Ret = post_dde_message( &data, Common->message, Common->lParam, &Common->lParam);
|
||||||
|
|
||||||
if (Ret)
|
if (Ret)
|
||||||
{
|
{
|
||||||
if (Common->size >= data.size)
|
Common->pvData = (PVOID)data.data;
|
||||||
{
|
|
||||||
if (data.data) RtlCopyMemory(&Common->buffer, data.data, data.size);
|
|
||||||
}
|
|
||||||
Common->size = data.size;
|
Common->size = data.size;
|
||||||
ERR("DDE Post CB size %d\n",data.size);
|
TRACE("DDE Post CB size %d\n",data.size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Return bad msg 0x%x Size %d\n",Common->message,Common->size);
|
ERR("DDE Post CB Return bad msg 0x%x Size %d\n",Common->message,Common->size);
|
||||||
|
Common->size = 0xdeadbeef; // HACKSSS!! Return status does not work!
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZwCallbackReturn(Arguments, ArgumentLength, Ret ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
return ZwCallbackReturn(Arguments, ArgumentLength, Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DDE Get/Peek kernel callback.
|
||||||
|
//
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
{
|
{
|
||||||
BOOL Ret;
|
BOOL Ret;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
|
PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
|
||||||
|
|
||||||
ERR("DDE Get CB size %d\n",Common->size);
|
TRACE("DDE Get CB size %d\n",Common->size);
|
||||||
|
|
||||||
Ret = unpack_dde_message( Common->hwnd, Common->message, &Common->lParam, Common->buffer, 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);
|
if (!Ret)
|
||||||
|
{
|
||||||
|
ERR("DDE Get CB Return bad msg 0x%x\n",Common->message);
|
||||||
|
Common->size = 0xdeadbeef; // HACKSSS!! Return status does not work!
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
return ZwCallbackReturn(Arguments, ArgumentLength, Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,7 +31,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
|
||||||
|
|
||||||
static LRESULT CALLBACK WDML_ClientProc(HWND, UINT, WPARAM, LPARAM); /* only for one client, not conv list */
|
static LRESULT CALLBACK WDML_ClientProc(HWND, UINT, WPARAM, LPARAM); /* only for one client, not conv list */
|
||||||
const char WDML_szClientConvClassA[] = "DDEMLAnsiClient";
|
const char WDML_szClientConvClassA[] = "DDEMLAnsiClient";
|
||||||
const WCHAR WDML_szClientConvClassW[] = {'D','D','E','M','L','U','n','i','c','o','d','e','C','l','i','e','n','t',0};
|
const WCHAR WDML_szClientConvClassW[] = L"DDEMLUnicodeClient";
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* DdeConnectList [USER32.@] Establishes conversation with DDE servers
|
* DdeConnectList [USER32.@] Establishes conversation with DDE servers
|
||||||
|
@ -91,7 +91,7 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
||||||
WDML_CONV* pConv = NULL;
|
WDML_CONV* pConv = NULL;
|
||||||
ATOM aSrv = 0, aTpc = 0;
|
ATOM aSrv = 0, aTpc = 0;
|
||||||
|
|
||||||
ERR("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
|
TRACE("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
|
||||||
|
|
||||||
pInstance = WDML_GetInstance(idInst);
|
pInstance = WDML_GetInstance(idInst);
|
||||||
if (!pInstance)
|
if (!pInstance)
|
||||||
|
@ -180,12 +180,12 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
||||||
pConv = WDML_GetConvFromWnd(hwndClient);
|
pConv = WDML_GetConvFromWnd(hwndClient);
|
||||||
if (pConv == NULL || pConv->hwndServer == 0)
|
if (pConv == NULL || pConv->hwndServer == 0)
|
||||||
{
|
{
|
||||||
ERR("Done with INITIATE, but no Server window available %p\n", (pConv ? pConv->hwndServer : NULL));
|
WARN("Done with INITIATE, but no Server window available\n");
|
||||||
pConv = NULL;
|
pConv = NULL;
|
||||||
pInstance->lastError = DMLERR_NO_CONV_ESTABLISHED;
|
pInstance->lastError = DMLERR_NO_CONV_ESTABLISHED;
|
||||||
goto theEnd;
|
goto theEnd;
|
||||||
}
|
}
|
||||||
ERR("Connected to Server window (%p)\n", pConv->hwndServer);
|
TRACE("Connected to Server window (%p)\n", pConv->hwndServer);
|
||||||
pConv->wConvst = XST_CONNECTED;
|
pConv->wConvst = XST_CONNECTED;
|
||||||
|
|
||||||
/* finish init of pConv */
|
/* finish init of pConv */
|
||||||
|
@ -1012,7 +1012,7 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, cons
|
||||||
DWORD err;
|
DWORD err;
|
||||||
WDML_CONV* pConv;
|
WDML_CONV* pConv;
|
||||||
|
|
||||||
ERR("Starting wait for a timeout of %d ms\n", dwTimeout);
|
TRACE("Starting wait for a timeout of %d ms\n", dwTimeout);
|
||||||
|
|
||||||
start = GetTickCount();
|
start = GetTickCount();
|
||||||
while ((elapsed = GetTickCount() - start) < dwTimeout)
|
while ((elapsed = GetTickCount() - start) < dwTimeout)
|
||||||
|
@ -1032,18 +1032,16 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, cons
|
||||||
pConv = WDML_GetConv(hConv, FALSE);
|
pConv = WDML_GetConv(hConv, FALSE);
|
||||||
if (pConv == NULL)
|
if (pConv == NULL)
|
||||||
{
|
{
|
||||||
ERR("conversation no longer available\n");
|
|
||||||
/* conversation no longer available... return failure */
|
/* conversation no longer available... return failure */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ERR("Msg hWnd %p & Client %p\n",msg.hwnd,pConv->hwndClient);
|
|
||||||
if (msg.hwnd == pConv->hwndClient)
|
if (msg.hwnd == pConv->hwndClient)
|
||||||
{
|
{
|
||||||
/* check that either pXAct has been processed or no more xActions are pending */
|
/* check that either pXAct has been processed or no more xActions are pending */
|
||||||
BOOL ret = (pConv->transactions == pXAct);
|
BOOL ret = (pConv->transactions == pXAct);
|
||||||
if (WDML_HandleReply(pConv, &msg, &hdd, ack) == WDML_QS_HANDLED)
|
if (WDML_HandleReply(pConv, &msg, &hdd, ack) == WDML_QS_HANDLED)
|
||||||
{
|
{
|
||||||
ERR("WDML_HandleReply returned WDML_QS_HANDLED\n");
|
TRACE("WDML_HandleReply returned WDML_QS_HANDLED\n");
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1057,14 +1055,13 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, cons
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Dispatching message\n");
|
|
||||||
DispatchMessageW(&msg);
|
DispatchMessageW(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("Timeout !!\n");
|
TRACE("Timeout !!\n");
|
||||||
|
|
||||||
pConv = WDML_GetConv(hConv, FALSE);
|
pConv = WDML_GetConv(hConv, FALSE);
|
||||||
if (pConv != NULL)
|
if (pConv != NULL)
|
||||||
|
@ -1144,7 +1141,6 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS
|
||||||
if (pConv == NULL)
|
if (pConv == NULL)
|
||||||
{
|
{
|
||||||
/* cannot set error... cannot get back to DDE instance */
|
/* cannot set error... cannot get back to DDE instance */
|
||||||
ERR("No Conv!\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,19 +1283,17 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
||||||
UINT uiLo, uiHi;
|
UINT uiLo, uiHi;
|
||||||
WDML_CONV* pConv = NULL;
|
WDML_CONV* pConv = NULL;
|
||||||
HSZ hszSrv, hszTpc;
|
HSZ hszSrv, hszTpc;
|
||||||
|
|
||||||
|
TRACE("%p %04x %08lx %08lx\n", hwnd, iMsg, wParam , lParam);
|
||||||
|
|
||||||
|
if (iMsg == WM_DDE_ACK &&
|
||||||
|
/* in the initial WM_INITIATE sendmessage */
|
||||||
|
((pConv = WDML_GetConvFromWnd(hwnd)) == NULL || pConv->wStatus == XST_INIT1))
|
||||||
|
{
|
||||||
|
/* In response to WM_DDE_INITIATE, save server window */
|
||||||
char buf[256];
|
char buf[256];
|
||||||
WDML_INSTANCE* pInstance;
|
WDML_INSTANCE* pInstance;
|
||||||
|
|
||||||
ERR("%p %04x %08lx %08lx\n", hwnd, iMsg, wParam , lParam);
|
|
||||||
|
|
||||||
/* in the initial WM_INITIATE sendmessage */
|
|
||||||
if (iMsg == WM_DDE_ACK &&
|
|
||||||
(!(pConv = WDML_GetConvFromWnd(hwnd)) || pConv->wStatus == XST_INIT1))
|
|
||||||
{
|
|
||||||
|
|
||||||
ERR("WM_DDE_ACK\n");
|
|
||||||
/* In response to WM_DDE_INITIATE, save server window */
|
|
||||||
|
|
||||||
/* note: sent messages do not need packing */
|
/* note: sent messages do not need packing */
|
||||||
uiLo = LOWORD(lParam);
|
uiLo = LOWORD(lParam);
|
||||||
uiHi = HIWORD(lParam);
|
uiHi = HIWORD(lParam);
|
||||||
|
|
|
@ -36,11 +36,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
|
||||||
|
|
||||||
static WDML_INSTANCE* WDML_InstanceList = NULL;
|
static WDML_INSTANCE* WDML_InstanceList = NULL;
|
||||||
static LONG WDML_MaxInstanceID = 0; /* OK for present, have to worry about wrap-around later */
|
static LONG WDML_MaxInstanceID = 0; /* OK for present, have to worry about wrap-around later */
|
||||||
const WCHAR WDML_szEventClass[] = {'D','D','E','M','L','E','v','e','n','t',0};
|
const WCHAR WDML_szEventClass[] = L"DDEMLEvent";
|
||||||
|
|
||||||
/* protection for instance list */
|
/* protection for instance list */
|
||||||
CRITICAL_SECTION WDML_CritSect;
|
CRITICAL_SECTION WDML_CritSect;
|
||||||
CRITICAL_SECTION_DEBUG critsect_debug =
|
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
{
|
{
|
||||||
0, 0, &WDML_CritSect,
|
0, 0, &WDML_CritSect,
|
||||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||||
|
@ -797,8 +797,8 @@ static LRESULT CALLBACK WDML_EventProc(HWND hwndEvent, UINT uMsg, WPARAM wParam,
|
||||||
/* confirm connection...
|
/* confirm connection...
|
||||||
* lookup for this conv handle
|
* lookup for this conv handle
|
||||||
*/
|
*/
|
||||||
HWND client = (HWND)wParam;
|
HWND client = WIN_GetFullHandle( (HWND)wParam );
|
||||||
HWND server = (HWND)lParam;
|
HWND server = WIN_GetFullHandle( (HWND)lParam );
|
||||||
for (pConv = pInstance->convs[WDML_SERVER_SIDE]; pConv != NULL; pConv = pConv->next)
|
for (pConv = pInstance->convs[WDML_SERVER_SIDE]; pConv != NULL; pConv = pConv->next)
|
||||||
{
|
{
|
||||||
if (pConv->hwndClient == client && pConv->hwndServer == server)
|
if (pConv->hwndClient == client && pConv->hwndServer == server)
|
||||||
|
@ -840,7 +840,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
{
|
{
|
||||||
ERR("Reserved value not zero? What does this mean?\n");
|
ERR("Reserved value not zero? What does this mean?\n");
|
||||||
/* trap this and no more until we know more */
|
/* trap this and no more until we know more */
|
||||||
return DMLERR_INVALIDPARAMETER;
|
return DMLERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* grab enough heap for one control struct - not really necessary for re-initialise
|
/* grab enough heap for one control struct - not really necessary for re-initialise
|
||||||
|
@ -883,12 +883,12 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
(pInstance->CBFflags & CBF_FAIL_ALLSVRXACTIONS) == CBF_FAIL_ALLSVRXACTIONS;
|
(pInstance->CBFflags & CBF_FAIL_ALLSVRXACTIONS) == CBF_FAIL_ALLSVRXACTIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("instance created - checking validity\n");
|
TRACE("instance created - checking validity\n");
|
||||||
|
|
||||||
if (*pidInst == 0)
|
if (*pidInst == 0)
|
||||||
{
|
{
|
||||||
/* Initialisation of new Instance Identifier */
|
/* Initialisation of new Instance Identifier */
|
||||||
ERR("new instance, callback %p flags %X\n",pfnCallback,afCmd);
|
TRACE("new instance, callback %p flags %X\n",pfnCallback,afCmd);
|
||||||
|
|
||||||
EnterCriticalSection(&WDML_CritSect);
|
EnterCriticalSection(&WDML_CritSect);
|
||||||
|
|
||||||
|
@ -907,7 +907,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pInstance->CBFflags = pInstance->CBFflags|APPCMD_FILTERINITS;
|
pInstance->CBFflags = pInstance->CBFflags|APPCMD_FILTERINITS;
|
||||||
ERR("First application instance detected OK\n");
|
TRACE("First application instance detected OK\n");
|
||||||
/* allocate new instance ID */
|
/* allocate new instance ID */
|
||||||
WDML_IncrementInstanceId(pInstance);
|
WDML_IncrementInstanceId(pInstance);
|
||||||
}
|
}
|
||||||
|
@ -916,7 +916,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
/* really need to chain the new one in to the latest here, but after checking conditions
|
/* really need to chain the new one in to the latest here, but after checking conditions
|
||||||
* such as trying to start a conversation from an application trying to monitor */
|
* such as trying to start a conversation from an application trying to monitor */
|
||||||
reference_inst = WDML_InstanceList;
|
reference_inst = WDML_InstanceList;
|
||||||
ERR("Subsequent application instance - starting checks\n");
|
TRACE("Subsequent application instance - starting checks\n");
|
||||||
while (reference_inst->next != NULL)
|
while (reference_inst->next != NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -932,7 +932,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
if (pInstance->clientOnly != reference_inst->clientOnly)
|
if (pInstance->clientOnly != reference_inst->clientOnly)
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize Mustbe Client-only\n");
|
|
||||||
ret = DMLERR_DLL_USAGE;
|
ret = DMLERR_DLL_USAGE;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -941,7 +940,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
if (pInstance->monitor != reference_inst->monitor)
|
if (pInstance->monitor != reference_inst->monitor)
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize cannot use monitor w/any modes\n");
|
|
||||||
ret = DMLERR_INVALIDPARAMETER;
|
ret = DMLERR_INVALIDPARAMETER;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -958,7 +956,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
}
|
}
|
||||||
/* All cleared, add to chain */
|
/* All cleared, add to chain */
|
||||||
|
|
||||||
ERR("Application Instance checks finished\n");
|
TRACE("Application Instance checks finished\n");
|
||||||
WDML_IncrementInstanceId(pInstance);
|
WDML_IncrementInstanceId(pInstance);
|
||||||
reference_inst->next = pInstance;
|
reference_inst->next = pInstance;
|
||||||
}
|
}
|
||||||
|
@ -988,18 +986,17 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
SetWindowLongPtrW(pInstance->hwndEvent, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
|
SetWindowLongPtrW(pInstance->hwndEvent, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
|
||||||
|
|
||||||
ERR("New application instance processing finished OK\n");
|
TRACE("New application instance processing finished OK\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reinitialisation situation --- FIX */
|
/* Reinitialisation situation --- FIX */
|
||||||
ERR("reinitialisation of (%p,%p,0x%x,%d): stub\n", pidInst, pfnCallback, afCmd, ulRes);
|
TRACE("reinitialisation of (%p,%p,0x%x,%d): stub\n", pidInst, pfnCallback, afCmd, ulRes);
|
||||||
|
|
||||||
EnterCriticalSection(&WDML_CritSect);
|
EnterCriticalSection(&WDML_CritSect);
|
||||||
|
|
||||||
if (WDML_InstanceList == NULL)
|
if (WDML_InstanceList == NULL)
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize No instance list\n");
|
|
||||||
ret = DMLERR_INVALIDPARAMETER;
|
ret = DMLERR_INVALIDPARAMETER;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -1024,7 +1021,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
if (!(afCmd & APPCMD_CLIENTONLY))
|
if (!(afCmd & APPCMD_CLIENTONLY))
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize AppCmd Client-only 2\n");
|
|
||||||
ret = DMLERR_INVALIDPARAMETER;
|
ret = DMLERR_INVALIDPARAMETER;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +1030,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
if (pInstance->monitor != reference_inst->monitor)
|
if (pInstance->monitor != reference_inst->monitor)
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize cannot change monitor modes 2\n");
|
|
||||||
ret = DMLERR_INVALIDPARAMETER;
|
ret = DMLERR_INVALIDPARAMETER;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1038,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
if ((afCmd&APPCMD_CLIENTONLY) && !reference_inst->clientOnly)
|
if ((afCmd&APPCMD_CLIENTONLY) && !reference_inst->clientOnly)
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize trying to set Client-only via APPCMD\n");
|
|
||||||
ret = DMLERR_INVALIDPARAMETER;
|
ret = DMLERR_INVALIDPARAMETER;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1047,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
}
|
}
|
||||||
if (reference_inst->next == NULL)
|
if (reference_inst->next == NULL)
|
||||||
{
|
{
|
||||||
ERR("WDML_Initialize Nothing Next\n");
|
|
||||||
ret = DMLERR_INVALIDPARAMETER;
|
ret = DMLERR_INVALIDPARAMETER;
|
||||||
goto theError;
|
goto theError;
|
||||||
}
|
}
|
||||||
|
@ -1070,7 +1063,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
||||||
|
|
||||||
return DMLERR_NO_ERROR;
|
return DMLERR_NO_ERROR;
|
||||||
theError:
|
theError:
|
||||||
ERR("WDML_Initialize error %x\n",ret);
|
|
||||||
HeapFree(GetProcessHeap(), 0, pInstance);
|
HeapFree(GetProcessHeap(), 0, pInstance);
|
||||||
LeaveCriticalSection(&WDML_CritSect);
|
LeaveCriticalSection(&WDML_CritSect);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -380,12 +380,12 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w
|
||||||
LOWORD(lParam) -- application atom
|
LOWORD(lParam) -- application atom
|
||||||
HIWORD(lParam) -- topic atom */
|
HIWORD(lParam) -- topic atom */
|
||||||
|
|
||||||
ERR("WM_DDE_INITIATE message received!\n");
|
TRACE("WM_DDE_INITIATE message received!\n");
|
||||||
hwndClient = (HWND)wParam;
|
hwndClient = (HWND)wParam;
|
||||||
|
|
||||||
pInstance = WDML_GetInstanceFromWnd(hwndServer);
|
pInstance = WDML_GetInstanceFromWnd(hwndServer);
|
||||||
if (!pInstance) return 0;
|
if (!pInstance) return 0;
|
||||||
ERR("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId());
|
TRACE("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId());
|
||||||
|
|
||||||
/* don't free DDEParams, since this is a broadcast */
|
/* don't free DDEParams, since this is a broadcast */
|
||||||
UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi);
|
UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue