Commit 3a7bd674 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

user32: Add support for DdeEnableCallback(EC_DISABLE) command.

parent 5b670b68
......@@ -792,7 +792,7 @@ static WDML_XACT* WDML_ClientQueueTerminate(WDML_CONV* pConv)
*
* handles the reply to a terminate request
*/
static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct)
static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg)
{
if (msg->message != WM_DDE_TERMINATE)
{
......@@ -815,7 +815,7 @@ static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WD
}
/******************************************************************
* WDML_HandleReplyData
* WDML_HandleIncomingData
*
*
*/
......@@ -934,7 +934,7 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h
qs = WDML_HandlePokeReply(pConv, msg, pXAct, ack);
break;
case WM_DDE_TERMINATE:
qs = WDML_HandleTerminateReply(pConv, msg, pXAct);
qs = WDML_HandleTerminateReply(pConv, msg);
break;
default:
qs = WDML_QS_ERROR;
......@@ -955,9 +955,8 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h
break;
case WDML_QS_HANDLED:
/* ok, we have resolved a pending transaction
* notify callback if asynchronous, and remove it in any case
* notify callback if asynchronous.
*/
WDML_UnQueueTransaction(pConv, pXAct);
if (pXAct->dwTimeout == TIMEOUT_ASYNC && pXAct->ddeMsg != WM_DDE_TERMINATE)
{
WDML_InvokeCallback(pConv->instance, XTYP_XACT_COMPLETE, pXAct->wFmt,
......@@ -969,7 +968,6 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h
{
*hdd = pXAct->hDdeData;
}
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
break;
case WDML_QS_PASS:
/* no pending transaction found, try a warm/hot link or a termination request */
......@@ -1078,6 +1076,39 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML
return 0;
}
/*****************************************************************
* WDML_ClientHandle
*/
HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, LPDWORD pdwResult)
{
HDDEDATA hDdeData;
if (!PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam))
{
WARN("Failed posting message %x to %p (error=0x%x)\n",
pXAct->ddeMsg, pConv->hwndServer, GetLastError());
pConv->wStatus &= ~ST_CONNECTED;
pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
return 0;
}
pXAct->dwTimeout = dwTimeout;
/* FIXME: should set the app bits on *pdwResult */
if (dwTimeout == TIMEOUT_ASYNC)
{
if (pdwResult)
*pdwResult = MAKELONG(0, pXAct->xActID);
hDdeData = (HDDEDATA)1;
}
else
hDdeData = WDML_SyncWaitTransactionReply((HCONV)pConv, dwTimeout, pXAct, pdwResult);
return hDdeData;
}
/*****************************************************************
* DdeClientTransaction (USER32.@)
*/
......@@ -1155,29 +1186,20 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS
WDML_QueueTransaction(pConv, pXAct);
if (!PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam))
TRACE("pConv->wStatus %04x\n", pConv->wStatus);
if (pConv->wStatus & ST_BLOCKED)
{
WARN("Failed posting message %x to %p (error=0x%x)\n",
pXAct->ddeMsg, pConv->hwndServer, GetLastError());
pConv->wStatus &= ~ST_CONNECTED;
WDML_UnQueueTransaction(pConv, pXAct);
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
pConv->instance->lastError = DMLERR_POSTMSG_FAILED;
return 0;
TRACE("Transactions are blocked, add to the queue and exit\n");
return (HDDEDATA)1;
}
pXAct->dwTimeout = dwTimeout;
/* FIXME: should set the app bits on *pdwResult */
if (dwTimeout == TIMEOUT_ASYNC)
hDdeData = WDML_ClientHandle(pConv, pXAct, dwTimeout, pdwResult);
if (dwTimeout != TIMEOUT_ASYNC)
{
if (pdwResult)
{
*pdwResult = MAKELONG(0, pXAct->xActID);
}
hDdeData = (HDDEDATA)1;
WDML_UnQueueTransaction(pConv, pXAct);
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
}
else
hDdeData = WDML_SyncWaitTransactionReply(hConv, dwTimeout, pXAct, pdwResult);
return hDdeData;
}
......
......@@ -382,6 +382,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
pInstance->win16 = b16;
pInstance->nodeList = NULL; /* node will be added later */
pInstance->monitorFlags = afCmd & MF_MASK;
pInstance->wStatus = 0;
pInstance->servers = NULL;
pInstance->convs[0] = NULL;
pInstance->convs[1] = NULL;
......@@ -1740,6 +1741,7 @@ WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
pConv->transactions = NULL;
pConv->hUser = 0;
pConv->wStatus = (side == WDML_CLIENT_SIDE) ? ST_CLIENT : 0L;
pConv->wStatus |= pInstance->wStatus;
/* check if both side of the conversation are of the same instance */
if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) &&
WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer))
......@@ -1751,6 +1753,8 @@ WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
pConv->next = pInstance->convs[side];
pInstance->convs[side] = pConv;
TRACE("pConv->wStatus %04x\n", pConv->wStatus);
return pConv;
}
......@@ -1842,7 +1846,8 @@ static BOOL WDML_EnableCallback(WDML_CONV *pConv, UINT wCmd)
{
if (wCmd == EC_DISABLE)
{
FIXME("EC_DISABLE is not implemented\n");
pConv->wStatus |= ST_BLOCKED;
TRACE("EC_DISABLE: conv %p status flags %04x\n", pConv, pConv->wStatus);
return TRUE;
}
......@@ -1855,18 +1860,28 @@ static BOOL WDML_EnableCallback(WDML_CONV *pConv, UINT wCmd)
return FALSE;
}
if (wCmd == EC_ENABLEALL)
{
pConv->wStatus &= ~ST_BLOCKED;
TRACE("EC_ENABLEALL: conv %p status flags %04x\n", pConv, pConv->wStatus);
}
while (pConv->transactions)
{
WDML_XACT *pXAct = pConv->transactions;
WDML_UnQueueTransaction(pConv, pXAct);
if (pConv->wStatus & ST_CLIENT)
{
/*WDML_ClientHandle(pConv, pXAct);*/
FIXME("Client delayed transaction queue handling is not supported\n");
/* transaction should be in the queue until handled */
WDML_ClientHandle(pConv, pXAct, 0, NULL);
WDML_UnQueueTransaction(pConv, pXAct);
}
else
{
/* transaction should be removed from the queue before handling */
WDML_UnQueueTransaction(pConv, pXAct);
WDML_ServerHandle(pConv, pXAct);
}
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
......@@ -1885,10 +1900,42 @@ BOOL WINAPI DdeEnableCallback(DWORD idInst, HCONV hConv, UINT wCmd)
TRACE("(%d, %p, %04x)\n", idInst, hConv, wCmd);
pConv = WDML_GetConv(hConv, TRUE);
if (hConv)
{
pConv = WDML_GetConv(hConv, TRUE);
if (pConv && pConv->instance->instanceID == idInst)
ret = WDML_EnableCallback(pConv, wCmd);
}
else
{
WDML_INSTANCE *pInstance = WDML_GetInstance(idInst);
if (pConv && pConv->instance->instanceID == idInst)
ret = WDML_EnableCallback(pConv, wCmd);
if (!pInstance)
return FALSE;
TRACE("adding flags %04x to instance %p\n", wCmd, pInstance);
pInstance->wStatus |= wCmd;
if (wCmd == EC_DISABLE)
{
pInstance->wStatus |= ST_BLOCKED;
TRACE("EC_DISABLE: inst %p status flags %04x\n", pInstance, pInstance->wStatus);
}
else if (wCmd == EC_ENABLEALL)
{
pInstance->wStatus &= ~ST_BLOCKED;
TRACE("EC_ENABLEALL: inst %p status flags %04x\n", pInstance, pInstance->wStatus);
}
ret = TRUE;
for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv != NULL; pConv = pConv->next)
{
ret = WDML_EnableCallback(pConv, wCmd);
if (ret && wCmd == EC_QUERYWAITING) break;
}
}
return ret;
}
......
......@@ -164,6 +164,7 @@ typedef struct tagWDML_INSTANCE
DWORD monitorFlags;
DWORD lastError;
HWND hwndEvent;
DWORD wStatus; /* global instance status */
WDML_SERVER* servers; /* list of registered servers */
WDML_CONV* convs[2]; /* active conversations for this instance (client and server) */
WDML_LINK* links[2]; /* active links for this instance (client and server) */
......@@ -196,6 +197,8 @@ extern void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hsz
extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
/* transaction handler on the server side */
extern WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct);
/* transaction handler on the client side */
HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, LPDWORD pdwResult);
/* called both in DdeClientTransaction and server side. */
extern UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes, BOOL bUnicode, BOOL b16);
......
......@@ -1051,13 +1051,16 @@ static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM w
default:
FIXME("Unsupported message %x\n", iMsg);
break;
}
if (pXAct)
{
pXAct->lParam = lParam;
if (WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK)
if ((pConv->wStatus & ST_BLOCKED) || WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK)
{
TRACE("Transactions are blocked, add to the queue and exit\n");
WDML_QueueTransaction(pConv, pXAct);
}
else
......@@ -1065,6 +1068,8 @@ static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM w
WDML_FreeTransaction(pInstance, pXAct, TRUE);
}
}
else
pConv->instance->lastError = DMLERR_MEMORY_ERROR;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment