/****************************************************************** * WDML_ServerHandleTerminate * * */ static WDML_QUEUE_STATE WDML_ServerHandleTerminate(WDML_CONV* pConv, WDML_XACT* pXAct) { /* billx: two things to remove: the conv, and associated links. * Respond with another WM_DDE_TERMINATE iMsg. */ if (!(pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)) { WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, 0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0); } PostMessageA(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0); WDML_RemoveConv(pConv, WDML_SERVER_SIDE); return WDML_QS_HANDLED; }
/***************************************************************** * DdeDisconnect (USER32.@) */ BOOL WINAPI DdeDisconnect(HCONV hConv) { WDML_CONV* pConv = NULL; WDML_XACT* pXAct; DWORD count, i; BOOL ret = FALSE; TRACE("(%p)\n", hConv); if (hConv == 0) { WARN("DdeDisconnect(): hConv = 0\n"); return FALSE; } EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, TRUE); if (pConv != NULL) { if (pConv->wStatus & ST_CLIENT) { /* FIXME: should abandon all pending transactions */ pXAct = WDML_ClientQueueTerminate(pConv); if (pXAct != NULL) { count = WDML_CritSect.RecursionCount; for (i = 0; i < count; i++) LeaveCriticalSection(&WDML_CritSect); if (PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam)) WDML_SyncWaitTransactionReply(hConv, 10000, pXAct, NULL); for (i = 0; i < count; i++) EnterCriticalSection(&WDML_CritSect); ret = TRUE; WDML_FreeTransaction(pConv->instance, pXAct, TRUE); /* still have to destroy data assosiated with conversation */ WDML_RemoveConv(pConv, WDML_CLIENT_SIDE); } else { FIXME("Not implemented yet for a server side conversation\n"); } } } LeaveCriticalSection(&WDML_CritSect); return ret; }
/***************************************************************** * DdeDisconnect (USER32.@) */ BOOL WINAPI DdeDisconnect(HCONV hConv) { WDML_CONV* pConv; WDML_XACT* pXAct; BOOL ret = FALSE; TRACE("(%p)\n", hConv); if (hConv == 0) { WARN("DdeDisconnect(): hConv = 0\n"); return FALSE; } pConv = WDML_GetConv(hConv, TRUE); if (pConv != NULL) { if (pConv->wStatus & ST_CLIENT) { /* FIXME: should abandon all pending transactions */ pXAct = WDML_ClientQueueTerminate(pConv); if (pXAct != NULL) { if (PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam)) { WDML_SyncWaitTransactionReply(hConv, 10000, pXAct, NULL); ret = TRUE; } else pConv->instance->lastError = DMLERR_POSTMSG_FAILED; WDML_FreeTransaction(pConv->instance, pXAct, TRUE); /* still have to destroy data associated with conversation */ WDML_RemoveConv(pConv, WDML_CLIENT_SIDE); } else { FIXME("Not implemented yet for a server side conversation\n"); } } } return ret; }
/****************************************************************** * WDML_HandleTerminateReply * * handles the reply to a terminate request */ static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg) { if (msg->message != WM_DDE_TERMINATE) { /* FIXME: should delete data passed here */ return WDML_QS_SWALLOWED; } if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { FIXME("hmmm shouldn't happen\n"); return WDML_QS_PASS; } if (!(pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)) { WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, 0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0); } WDML_RemoveConv(pConv, WDML_CLIENT_SIDE); return WDML_QS_HANDLED; }