[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:
James Tabor 2015-01-08 22:57:09 +00:00
parent 9a959644b3
commit 87a268ef23
8 changed files with 197 additions and 135 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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)

View file

@ -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 ***************/

View file

@ -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
*/ */

View file

@ -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);

View file

@ -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;

View file

@ -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);