user32: Add support for DdeEnableCallback(EC_DISABLE) command
Dmitry Timoshkov
dmitry at codeweavers.com
Tue Nov 21 00:43:48 CST 2006
Hello,
this is almost an year-old patch updated for the current tree.
Changelog:
user32: Add support for DdeEnableCallback(EC_DISABLE) command.
---
dlls/user32/dde_client.c | 70 ++++++++++++++++++++++++++++++---------------
dlls/user32/dde_misc.c | 61 +++++++++++++++++++++++++++++++++++----
dlls/user32/dde_private.h | 3 ++
dlls/user32/dde_server.c | 7 ++++-
4 files changed, 109 insertions(+), 32 deletions(-)
diff --git a/dlls/user32/dde_client.c b/dlls/user32/dde_client.c
index 2d345f0..1441e71 100644
--- a/dlls/user32/dde_client.c
+++ b/dlls/user32/dde_client.c
@@ -792,7 +792,7 @@ static WDML_XACT* WDML_ClientQueueTermin
*
* 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_HandleTermi
}
/******************************************************************
- * WDML_HandleReplyData
+ * WDML_HandleIncomingData
*
*
*/
@@ -934,7 +934,7 @@ static WDML_QUEUE_STATE WDML_HandleReply
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
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
{
*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_SyncWaitTransaction
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(LPB
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;
}
diff --git a/dlls/user32/dde_misc.c b/dlls/user32/dde_misc.c
index 0afb2ed..bcb4cea 100644
--- a/dlls/user32/dde_misc.c
+++ b/dlls/user32/dde_misc.c
@@ -382,6 +382,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PF
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* p
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* p
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_CON
{
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_CON
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 idIn
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;
}
diff --git a/dlls/user32/dde_private.h b/dlls/user32/dde_private.h
index f784938..00882e4 100644
--- a/dlls/user32/dde_private.h
+++ b/dlls/user32/dde_private.h
@@ -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_INST
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);
diff --git a/dlls/user32/dde_server.c b/dlls/user32/dde_server.c
index 545b80e..2789450 100644
--- a/dlls/user32/dde_server.c
+++ b/dlls/user32/dde_server.c
@@ -1051,13 +1051,16 @@ static LRESULT CALLBACK WDML_ServerConvP
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_ServerConvP
WDML_FreeTransaction(pInstance, pXAct, TRUE);
}
}
+ else
+ pConv->instance->lastError = DMLERR_MEMORY_ERROR;
return 0;
}
--
1.4.2
More information about the wine-patches
mailing list