mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[User32]
- Update and sync DDE code with wine. Make name space close to what it should be. svn path=/trunk/; revision=63386
This commit is contained in:
parent
4c4205442e
commit
e387cb4358
3 changed files with 900 additions and 822 deletions
File diff suppressed because it is too large
Load diff
|
@ -30,8 +30,8 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
|
||||
|
||||
static LRESULT CALLBACK WDML_ClientProc(HWND, UINT, WPARAM, LPARAM); /* only for one client, not conv list */
|
||||
const char WDML_szClientConvClassA[] = "DdeClientAnsi";
|
||||
const WCHAR WDML_szClientConvClassW[] = {'D','d','e','C','l','i','e','n','t','U','n','i','c','o','d','e',0};
|
||||
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};
|
||||
|
||||
/******************************************************************************
|
||||
* DdeConnectList [USER32.@] Establishes conversation with DDE servers
|
||||
|
@ -91,7 +91,7 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
|||
WDML_CONV* pConv = NULL;
|
||||
ATOM aSrv = 0, aTpc = 0;
|
||||
|
||||
TRACE("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
|
||||
ERR("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
|
||||
|
||||
pInstance = WDML_GetInstance(idInst);
|
||||
if (!pInstance)
|
||||
|
@ -166,7 +166,7 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
|||
|
||||
/* note: sent messages shall not use packing */
|
||||
SendMessageTimeoutW( HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, MAKELPARAM(aSrv, aTpc),
|
||||
SMTO_ABORTIFHUNG, 2000, NULL );
|
||||
SMTO_ABORTIFHUNG, 0, NULL );
|
||||
|
||||
pInstance = WDML_GetInstance(idInst);
|
||||
if (!pInstance)
|
||||
|
@ -180,12 +180,12 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
|||
pConv = WDML_GetConvFromWnd(hwndClient);
|
||||
if (pConv == NULL || pConv->hwndServer == 0)
|
||||
{
|
||||
WARN("Done with INITIATE, but no Server window available\n");
|
||||
ERR("Done with INITIATE, but no Server window available %p\n", (pConv ? pConv->hwndServer : NULL));
|
||||
pConv = NULL;
|
||||
pInstance->lastError = DMLERR_NO_CONV_ESTABLISHED;
|
||||
goto theEnd;
|
||||
}
|
||||
TRACE("Connected to Server window (%p)\n", pConv->hwndServer);
|
||||
ERR("Connected to Server window (%p)\n", pConv->hwndServer);
|
||||
pConv->wConvst = XST_CONNECTED;
|
||||
|
||||
/* finish init of pConv */
|
||||
|
@ -312,8 +312,8 @@ static WDML_XACT* WDML_ClientQueueAdvise(WDML_CONV* pConv, UINT wType, UINT wFmt
|
|||
|
||||
/* pack DdeAdvise */
|
||||
pDdeAdvise = GlobalLock(pXAct->hMem);
|
||||
pDdeAdvise->fAckReq = (wType & XTYPF_ACKREQ) ? TRUE : FALSE;
|
||||
pDdeAdvise->fDeferUpd = (wType & XTYPF_NODATA) ? TRUE : FALSE;
|
||||
pDdeAdvise->fAckReq = (wType & XTYPF_ACKREQ) != 0;
|
||||
pDdeAdvise->fDeferUpd = (wType & XTYPF_NODATA) != 0;
|
||||
pDdeAdvise->cfFormat = wFmt;
|
||||
GlobalUnlock(pXAct->hMem);
|
||||
|
||||
|
@ -848,7 +848,7 @@ static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDE
|
|||
* XTYP_ADVDATA and callback should return the proper status.
|
||||
*/
|
||||
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz,
|
||||
uiLo ? TRUE : FALSE, wdh.cfFormat);
|
||||
uiLo != 0, wdh.cfFormat);
|
||||
if (!pLink)
|
||||
{
|
||||
WDML_DecHSZ(pConv->instance, hsz);
|
||||
|
@ -1008,22 +1008,20 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h
|
|||
*/
|
||||
static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, const WDML_XACT* pXAct, DWORD *ack)
|
||||
{
|
||||
DWORD dwTime;
|
||||
DWORD start, elapsed;
|
||||
DWORD err;
|
||||
WDML_CONV* pConv;
|
||||
|
||||
TRACE("Starting wait for a timeout of %d ms\n", dwTimeout);
|
||||
ERR("Starting wait for a timeout of %d ms\n", dwTimeout);
|
||||
|
||||
/* FIXME: time 32 bit wrap around */
|
||||
dwTimeout += GetCurrentTime();
|
||||
|
||||
while ((dwTime = GetCurrentTime()) < dwTimeout)
|
||||
start = GetTickCount();
|
||||
while ((elapsed = GetTickCount() - start) < dwTimeout)
|
||||
{
|
||||
/* we cannot be in the crit sect all the time because when client and server run in a
|
||||
* single process they need to share the access to the internal data
|
||||
*/
|
||||
if (MsgWaitForMultipleObjects(0, NULL, FALSE,
|
||||
dwTimeout - dwTime, QS_POSTMESSAGE) == WAIT_OBJECT_0)
|
||||
dwTimeout - elapsed, QS_POSTMESSAGE) == WAIT_OBJECT_0)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
|
@ -1034,16 +1032,18 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, cons
|
|||
pConv = WDML_GetConv(hConv, FALSE);
|
||||
if (pConv == NULL)
|
||||
{
|
||||
ERR("conversation no longer available\n");
|
||||
/* conversation no longer available... return failure */
|
||||
return 0;
|
||||
}
|
||||
ERR("Msg hWnd %p & Client %p\n",msg.hwnd,pConv->hwndClient);
|
||||
if (msg.hwnd == pConv->hwndClient)
|
||||
{
|
||||
/* check that either pXAct has been processed or no more xActions are pending */
|
||||
BOOL ret = (pConv->transactions == pXAct);
|
||||
if (WDML_HandleReply(pConv, &msg, &hdd, ack) == WDML_QS_HANDLED)
|
||||
{
|
||||
TRACE("WDML_HandleReply returned WDML_QS_HANDLED\n");
|
||||
ERR("WDML_HandleReply returned WDML_QS_HANDLED\n");
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -1057,13 +1057,14 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, cons
|
|||
}
|
||||
else
|
||||
{
|
||||
ERR("Dispatching message\n");
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Timeout !!\n");
|
||||
ERR("Timeout !!\n");
|
||||
|
||||
pConv = WDML_GetConv(hConv, FALSE);
|
||||
if (pConv != NULL)
|
||||
|
@ -1143,6 +1144,7 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS
|
|||
if (pConv == NULL)
|
||||
{
|
||||
/* cannot set error... cannot get back to DDE instance */
|
||||
ERR("No Conv!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1237,14 +1239,18 @@ BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction
|
|||
{
|
||||
if ((pConv = WDML_GetConv(hConv, TRUE)) && pConv->instance == pInstance)
|
||||
{
|
||||
for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
|
||||
{
|
||||
|
||||
pXAct = pConv->transactions;
|
||||
while (pXAct) {
|
||||
WDML_XACT *nextXAct = pXAct->next;
|
||||
|
||||
if (pXAct->dwTimeout == TIMEOUT_ASYNC &&
|
||||
(idTransaction == 0 || pXAct->xActID == idTransaction))
|
||||
{
|
||||
WDML_UnQueueTransaction(pConv, pXAct);
|
||||
WDML_FreeTransaction(pInstance, pXAct, TRUE);
|
||||
}
|
||||
pXAct = nextXAct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1253,13 +1259,16 @@ BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction
|
|||
for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv; pConv = pConv->next)
|
||||
{
|
||||
if (!(pConv->wStatus & ST_CONNECTED)) continue;
|
||||
for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
|
||||
{
|
||||
pXAct = pConv->transactions;
|
||||
while (pXAct) {
|
||||
WDML_XACT *nextXAct = pXAct->next;
|
||||
|
||||
if (pXAct->dwTimeout == TIMEOUT_ASYNC)
|
||||
{
|
||||
WDML_UnQueueTransaction(pConv, pXAct);
|
||||
WDML_FreeTransaction(pInstance, pXAct, TRUE);
|
||||
}
|
||||
pXAct = nextXAct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1278,16 +1287,18 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
|||
UINT uiLo, uiHi;
|
||||
WDML_CONV* pConv = NULL;
|
||||
HSZ hszSrv, hszTpc;
|
||||
char buf[256];
|
||||
WDML_INSTANCE* pInstance;
|
||||
|
||||
TRACE("%p %04x %08lx %08lx\n", hwnd, iMsg, wParam , lParam);
|
||||
ERR("%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))
|
||||
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 */
|
||||
char buf[256];
|
||||
WDML_INSTANCE* pInstance;
|
||||
|
||||
/* note: sent messages do not need packing */
|
||||
uiLo = LOWORD(lParam);
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
|
||||
|
||||
static const WCHAR szServerNameClass[] = {'D','d','e','S','e','r','v','e','r','N','a','m','e',0};
|
||||
const char WDML_szServerConvClassA[] = "DdeServerConvAnsi";
|
||||
const WCHAR WDML_szServerConvClassW[] = {'D','d','e','S','e','r','v','e','r','C','o','n','v','U','n','i','c','o','d','e',0};
|
||||
const char WDML_szServerConvClassA[] = "DdeServerConvA";
|
||||
const WCHAR WDML_szServerConvClassW[] = {'D','d','e','S','e','r','v','e','r','C','o','n','v','W',0};
|
||||
|
||||
static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static LRESULT CALLBACK WDML_ServerConvProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
@ -62,7 +62,7 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
|
|||
|
||||
pInstance = WDML_GetInstance(idInst);
|
||||
|
||||
if (pInstance == NULL || pInstance->links == NULL)
|
||||
if (pInstance == NULL)
|
||||
return FALSE;
|
||||
|
||||
atom = WDML_MakeAtomFromHsz(hszItem);
|
||||
|
@ -135,7 +135,7 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
|
|||
return TRUE;
|
||||
|
||||
theError:
|
||||
if (atom) GlobalDeleteAtom(atom);
|
||||
GlobalDeleteAtom(atom);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -380,12 +380,12 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w
|
|||
LOWORD(lParam) -- application atom
|
||||
HIWORD(lParam) -- topic atom */
|
||||
|
||||
TRACE("WM_DDE_INITIATE message received!\n");
|
||||
ERR("WM_DDE_INITIATE message received!\n");
|
||||
hwndClient = (HWND)wParam;
|
||||
|
||||
pInstance = WDML_GetInstanceFromWnd(hwndServer);
|
||||
TRACE("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId());
|
||||
if (!pInstance) return 0;
|
||||
ERR("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId());
|
||||
|
||||
/* don't free DDEParams, since this is a broadcast */
|
||||
UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi);
|
||||
|
@ -708,7 +708,7 @@ static WDML_QUEUE_STATE WDML_ServerHandleUnadvise(WDML_CONV* pConv, WDML_XACT* p
|
|||
pXAct->hszItem, TRUE, pXAct->wFmt);
|
||||
if (pLink == NULL)
|
||||
{
|
||||
ERR("Couln'd find link for %p, dropping request\n", pXAct->hszItem);
|
||||
ERR("Couldn't find link for %p, dropping request\n", pXAct->hszItem);
|
||||
FreeDDElParam(WM_DDE_UNADVISE, pXAct->lParam);
|
||||
return WDML_QS_ERROR;
|
||||
}
|
||||
|
@ -748,6 +748,54 @@ static WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam)
|
|||
return pXAct;
|
||||
}
|
||||
|
||||
static BOOL data_looks_unicode( const WCHAR *data, DWORD size )
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if (size % sizeof(WCHAR)) return FALSE;
|
||||
for (i = 0; i < size / sizeof(WCHAR); i++) if (data[i] > 255) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* convert data to Unicode, unless it looks like it's already Unicode */
|
||||
static HDDEDATA map_A_to_W( DWORD instance, void *ptr, DWORD size )
|
||||
{
|
||||
HDDEDATA ret;
|
||||
DWORD len;
|
||||
const char *end;
|
||||
|
||||
if (!data_looks_unicode( ptr, size ))
|
||||
{
|
||||
if ((end = memchr( ptr, 0, size ))) size = end + 1 - (const char *)ptr;
|
||||
len = MultiByteToWideChar( CP_ACP, 0, ptr, size, NULL, 0 );
|
||||
ret = DdeCreateDataHandle( instance, NULL, len * sizeof(WCHAR), 0, 0, CF_TEXT, 0);
|
||||
MultiByteToWideChar( CP_ACP, 0, ptr, size, (WCHAR *)DdeAccessData(ret, NULL), len );
|
||||
}
|
||||
else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert data to ASCII, unless it looks like it's not in Unicode format */
|
||||
static HDDEDATA map_W_to_A( DWORD instance, void *ptr, DWORD size )
|
||||
{
|
||||
HDDEDATA ret;
|
||||
DWORD len;
|
||||
const WCHAR *end;
|
||||
|
||||
if (data_looks_unicode( ptr, size ))
|
||||
{
|
||||
size /= sizeof(WCHAR);
|
||||
if ((end = memchrW( ptr, 0, size ))) size = end + 1 - (const WCHAR *)ptr;
|
||||
len = WideCharToMultiByte( CP_ACP, 0, ptr, size, NULL, 0, NULL, NULL );
|
||||
ret = DdeCreateDataHandle( instance, NULL, len, 0, 0, CF_TEXT, 0);
|
||||
WideCharToMultiByte( CP_ACP, 0, ptr, size, (char *)DdeAccessData(ret, NULL), len, NULL, NULL );
|
||||
}
|
||||
else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* WDML_ServerHandleExecute
|
||||
*
|
||||
|
@ -761,11 +809,16 @@ static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pX
|
|||
if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES))
|
||||
{
|
||||
LPVOID ptr = GlobalLock(pXAct->hMem);
|
||||
DWORD size = GlobalSize(pXAct->hMem);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, GlobalSize(pXAct->hMem),
|
||||
0, 0, CF_TEXT, 0);
|
||||
if (pConv->instance->unicode) /* Unicode server, try to map A->W */
|
||||
hDdeData = map_A_to_W( pConv->instance->instanceID, ptr, size );
|
||||
else if (!IsWindowUnicode( pConv->hwndClient )) /* ASCII server and client, try to map W->A */
|
||||
hDdeData = map_W_to_A( pConv->instance->instanceID, ptr, size );
|
||||
else
|
||||
hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, size, 0, 0, CF_TEXT, 0);
|
||||
GlobalUnlock(pXAct->hMem);
|
||||
}
|
||||
hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv,
|
||||
|
|
Loading…
Reference in a new issue