/****************************************************************** * WDML_HandleRequestReply * * */ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct, DWORD *ack) { DDEACK ddeAck; WINE_DDEHEAD wdh; UINT_PTR uiLo, uiHi; HSZ hsz; if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) return WDML_QS_PASS; switch (msg->message) { case WM_DDE_ACK: UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi); FreeDDElParam(WM_DDE_ACK, msg->lParam); GlobalDeleteAtom(uiHi); if (ack) *ack = uiLo; WDML_ExtractAck(uiLo, &ddeAck); pXAct->hDdeData = 0; if (ddeAck.fAck) ERR("Positive answer should appear in NACK for a request, assuming negative\n"); TRACE("Negative answer...\n"); break; case WM_DDE_DATA: UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi); TRACE("Got the result (%08lx)\n", uiLo); hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi); if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0) return WDML_QS_PASS; pXAct->hDdeData = WDML_Global2DataHandle(pConv, (HGLOBAL)uiLo, &wdh); if (wdh.fRelease) { GlobalFree((HGLOBAL)uiLo); } if (wdh.fAckReq) { pConv->instance->lastError = DMLERR_MEMORY_ERROR; } else { GlobalDeleteAtom(uiHi); FreeDDElParam(WM_DDE_ACK, msg->lParam); } break; default: FreeDDElParam(msg->message, msg->lParam); return WDML_QS_PASS; } return WDML_QS_HANDLED; }
/****************************************************************** * WDML_HandleExecuteReply * * */ static WDML_QUEUE_STATE WDML_HandleExecuteReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct, DWORD *ack) { DDEACK ddeAck; UINT_PTR uiLo, uiHi; if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi); FreeDDElParam(WM_DDE_ACK, msg->lParam); if ((HANDLE)uiHi != pXAct->hMem) { return WDML_QS_PASS; } if (ack) *ack = uiLo; WDML_ExtractAck(uiLo, &ddeAck); pXAct->hDdeData = (HDDEDATA)(UINT_PTR)ddeAck.fAck; TRACE("hDdeData = %p\n", pXAct->hDdeData); pConv->instance->lastError = (pXAct->hDdeData != 0) ? DMLERR_NO_ERROR : DMLERR_NOTPROCESSED; return WDML_QS_HANDLED; }
/****************************************************************** * WDML_HandlePokeReply * * */ static WDML_QUEUE_STATE WDML_HandlePokeReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct, DWORD *ack) { UINT_PTR uiLo, uiHi; HSZ hsz; if (msg->message != WM_DDE_ACK && WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi); hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi); if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0) { return WDML_QS_PASS; } FreeDDElParam(WM_DDE_ACK, msg->lParam); GlobalDeleteAtom(uiHi); if (ack) *ack = uiLo; pXAct->hMem = GlobalFree(pXAct->hMem); pXAct->hDdeData = (HDDEDATA)TRUE; return TRUE; }
static LRESULT DdeMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { UINT_PTR hSzItem; switch(msg) { case WM_DDE_ACK: ddeAcked = 1; hwndDde = (HWND)wParam; break; case WM_DDE_DATA: UnpackDDElParam(msg, lParam, (PUINT_PTR)&hGlobalDdeData, (PUINT_PTR)&hSzItem); ddeData = 1; if (hGlobalDdeData) { DDEDATA* data = (DDEDATA*)GlobalLock(hGlobalDdeData); if (data->fAckReq) { DDEACK ack = {0}; PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwndDlg, PackDDElParam(WM_DDE_ACK, *(PUINT)&ack, hSzItem)); } else GlobalDeleteAtom((ATOM)hSzItem); GlobalUnlock(hGlobalDdeData); } else GlobalDeleteAtom((ATOM)hSzItem); break; } return 0; }
/****************************************************************** * WDML_HandleIncomingData * * */ static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd) { UINT_PTR uiLo, uiHi; HDDEDATA hDdeDataIn, hDdeDataOut; WDML_LINK* pLink; WINE_DDEHEAD wdh; HSZ hsz; TRACE("WM_DDE_DATA message received in the Client Proc!\n"); /* wParam -- sending window handle */ /* lParam -- hDdeData & item HSZ */ UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi); hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi); hDdeDataIn = WDML_Global2DataHandle(pConv, (HGLOBAL)uiLo, &wdh); /* billx: * For hot link, data should be passed to its callback with * XTYP_ADVDATA and callback should return the proper status. */ pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz, uiLo != 0, wdh.cfFormat); if (!pLink) { WDML_DecHSZ(pConv->instance, hsz); DdeFreeDataHandle(hDdeDataIn); return WDML_QS_PASS; } if (hDdeDataIn != 0 && wdh.fAckReq) { WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA); if (msg->lParam) msg->lParam = 0; } else { GlobalDeleteAtom(uiHi); } hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_ADVDATA, pLink->uFmt, pLink->hConv, pConv->hszTopic, pLink->hszItem, hDdeDataIn, 0, 0); if (hDdeDataOut != (HDDEDATA)DDE_FACK || wdh.fRelease) { if (uiLo) GlobalFree((HANDLE)uiLo); } DdeFreeDataHandle(hDdeDataIn); WDML_DecHSZ(pConv->instance, hsz); if (msg->lParam) FreeDDElParam(WM_DDE_DATA, msg->lParam); return WDML_QS_HANDLED; }
/****************************************************************** * WDML_ServerQueueRequest * * */ static WDML_XACT* WDML_ServerQueueRequest(WDML_CONV* pConv, LPARAM lParam) { UINT_PTR uiLo, uiHi; WDML_XACT* pXAct; UnpackDDElParam(WM_DDE_REQUEST, lParam, &uiLo, &uiHi); pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_REQUEST, uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) pXAct->atom = uiHi; return pXAct; }
/****************************************************************** * WDML_ServerQueueUnadvise * * */ static WDML_XACT* WDML_ServerQueueUnadvise(WDML_CONV* pConv, LPARAM lParam) { UINT uiLo, uiHi; WDML_XACT* pXAct; UnpackDDElParam(WM_DDE_UNADVISE, lParam, &uiLo, &uiHi); pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_UNADVISE, uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) pXAct->atom = uiHi; return pXAct; }
/****************************************************************** * WDML_HandleAdviseReply * * handles the reply to an advise request */ static WDML_QUEUE_STATE WDML_HandleAdviseReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct, DWORD *ack) { DDEACK ddeAck; UINT_PTR uiLo, uiHi; HSZ hsz; if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi); hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi); if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0) return WDML_QS_PASS; GlobalDeleteAtom(uiHi); FreeDDElParam(WM_DDE_ACK, msg->lParam); if (ack) *ack = uiLo; WDML_ExtractAck(uiLo, &ddeAck); if (ddeAck.fAck) { WDML_LINK* pLink; /* billx: first to see if the link is already created. */ pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, pXAct->hszItem, TRUE, pXAct->wFmt); if (pLink != NULL) { /* we found a link, and only need to modify it in case it changes */ pLink->transactionType = pXAct->wType; } else { WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, pXAct->wType, pXAct->hszItem, pXAct->wFmt); } pXAct->hDdeData = (HDDEDATA)1; } else { TRACE("Returning FALSE on XTYP_ADVSTART - fAck was FALSE\n"); GlobalFree(pXAct->hMem); pXAct->hDdeData = NULL; } return WDML_QS_HANDLED; }
/****************************************************************** * WDML_ServerQueuePoke * * */ static WDML_XACT* WDML_ServerQueuePoke(WDML_CONV* pConv, LPARAM lParam) { UINT uiLo, uiHi; WDML_XACT* pXAct; UnpackDDElParam(WM_DDE_POKE, lParam, &uiLo, &uiHi); pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE, 0, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) { pXAct->atom = uiHi; pXAct->hMem = (HGLOBAL)uiLo; } return pXAct; }
/***************************************************************************\ * _ClientGetDDEHookData * * Description: * Callback from server to extract data from lParam and place it into * the pdmhd for use by DDESPY apps. This does a very similar thing * to the CopyDDEDataIn/Out apis but this only grabs a limited amount * of the data suitable for posting to the DDESPY app(s). This should * be merged with the Copy APIs eventually. * * History: * 12-16-91 sanfords Created. \***************************************************************************/ DWORD _ClientGetDDEHookData( UINT message, LONG lParam, PDDEML_MSG_HOOK_DATA pdmhd) { PBYTE pb; HANDLE hDDE; UnpackDDElParam(message, lParam, &pdmhd->uiLo, &pdmhd->uiHi); switch (message) { case WM_DDE_DATA: case WM_DDE_POKE: case WM_DDE_ADVISE: hDDE = (HANDLE)pdmhd->uiLo; break; case WM_DDE_EXECUTE: hDDE = (HANDLE)pdmhd->uiHi; break; case WM_DDE_ACK: case WM_DDE_REQUEST: case WM_DDE_UNADVISE: case WM_DDE_TERMINATE: pdmhd->cbData = 0; return (1); } pdmhd->cbData = UserGlobalSize(hDDE); if (pdmhd->cbData) { USERGLOBALLOCK(hDDE, pb); if (pb == NULL) { pdmhd->cbData = 0; } else { RtlCopyMemory(&pdmhd->Data, pb, min(pdmhd->cbData, sizeof(DDEML_MSG_HOOK_DATA) - FIELDOFFSET(DDEML_MSG_HOOK_DATA, Data))); USERGLOBALUNLOCK(hDDE); } } return (1); }
/****************************************************************** * WDML_ServerQueueAdvise * * */ static WDML_XACT* WDML_ServerQueueAdvise(WDML_CONV* pConv, LPARAM lParam) { UINT uiLo, uiHi; WDML_XACT* pXAct; /* XTYP_ADVSTART transaction: establish link and save link info to InstanceInfoTable */ if (!UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi)) return NULL; pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE, 0, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) { pXAct->hMem = (HGLOBAL)uiLo; pXAct->atom = uiHi; } return pXAct; }
LRESULT OnDDExecute(HWND hwnd, WPARAM wparam, LPARAM lparam) { UINT_PTR lo, hi; UnpackDDElParam(WM_DDE_EXECUTE, lparam, &lo, &hi); ScopedMem<WCHAR> cmd; DDEACK ack = { 0 }; LPVOID command = GlobalLock((HGLOBAL)hi); if (!command) goto Exit; if (IsWindowUnicode((HWND)wparam)) cmd.Set(str::Dup((const WCHAR*)command)); else cmd.Set(str::conv::FromAnsi((const char*)command)); const WCHAR *currCmd = cmd; while (!str::IsEmpty(currCmd)) { const WCHAR *nextCmd = NULL; if (!nextCmd) nextCmd = HandleSyncCmd(currCmd, ack); if (!nextCmd) nextCmd = HandleOpenCmd(currCmd, ack); if (!nextCmd) nextCmd = HandleGotoCmd(currCmd, ack); if (!nextCmd) nextCmd = HandlePageCmd(currCmd, ack); if (!nextCmd) nextCmd = HandleSetViewCmd(currCmd, ack); if (!nextCmd) { ScopedMem<WCHAR> tmp; nextCmd = str::Parse(currCmd, L"%S]", &tmp); } currCmd = nextCmd; } Exit: GlobalUnlock((HGLOBAL)hi); lparam = ReuseDDElParam(lparam, WM_DDE_EXECUTE, WM_DDE_ACK, *(WORD *)&ack, hi); PostMessage((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, lparam); return 0; }
/****************************************************************** * WDML_HandleUnadviseReply * * */ static WDML_QUEUE_STATE WDML_HandleUnadviseReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct, DWORD *ack) { DDEACK ddeAck; UINT_PTR uiLo, uiHi; HSZ hsz; if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi); hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi); if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0) return WDML_QS_PASS; FreeDDElParam(WM_DDE_ACK, msg->lParam); GlobalDeleteAtom(uiHi); if (ack) *ack = uiLo; WDML_ExtractAck(uiLo, &ddeAck); TRACE("WM_DDE_ACK received while waiting for a timeout\n"); if (!ddeAck.fAck) { TRACE("Returning FALSE on XTYP_ADVSTOP - fAck was FALSE\n"); pXAct->hDdeData = NULL; } else { /* billx: remove the link */ WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, pXAct->hszItem, pXAct->wFmt); pXAct->hDdeData = (HDDEDATA)1; } return WDML_QS_HANDLED; }
static long ProcessShellDDE(HWND w, UINT msg, WPARAM wp, LPARAM lp) { char *command; ATOM app,top,a; WPARAM hi,lo; unsigned short ack; char buffer[256]; switch (msg) { case WM_DDE_INITIATE: /* * Initiate DDE command */ a = (ATOM)LOWORD(lp); if (a == NULL) return 0; ::GlobalGetAtomName(a,buffer,sizeof(buffer)); if (::strcmp(_GDDEAppName,buffer)) return 0; a = (ATOM)HIWORD(lp); if (a != NULL) { ::GlobalGetAtomName(a,buffer,sizeof(buffer)); if (::strcmp(_GDDETopicName,buffer)) return 0; } /* * Respond with ACK of only conversation I do */ app = ::GlobalAddAtom(_GDDEAppName); top = ::GlobalAddAtom(_GDDETopicName); ::SendMessage((HWND)wp,WM_DDE_ACK,(WPARAM)w,MAKELPARAM(app,top)); ::GlobalDeleteAtom(app); ::GlobalDeleteAtom(top); return 0; case WM_DDE_TERMINATE: /* * Terminate DDE connection */ ::PostMessage((HWND)wp,WM_DDE_TERMINATE,(WPARAM)w,0); return 0; case WM_DDE_EXECUTE: /* * Extract command string */ command = (char *)GlobalLock((HANDLE)lp); ExecuteDDE(command); ::GlobalUnlock((HANDLE)lp); ack = 1; lo = *(WPARAM *)&ack; lp = PackDDElParam(WM_DDE_ACK,lo,lp); PostMessage((HWND)wp,WM_DDE_ACK,(LPARAM)w,lp); return 0; case WM_DDE_UNADVISE: case WM_DDE_ADVISE: case WM_DDE_DATA: case WM_DDE_POKE: case WM_DDE_REQUEST: /* * Don't do 'em, don't ack 'em! */ UnpackDDElParam(msg,lp,&lo,&hi); if ((msg == WM_DDE_ADVISE) || (msg == WM_DDE_DATA) || (msg == WM_DDE_POKE)) { ::GlobalFree((HANDLE)lo); } ack = 0; lo = *(WPARAM *)(&ack); ReuseDDElParam(lp,msg,WM_DDE_ACK,lo,hi); PostMessage((HWND)wp,WM_DDE_ACK,(WPARAM)w,lp); return 0; default: return -1; } }
static void AFXAPI TraceDDE(LPCTSTR lpszPrefix, const MSG* pMsg) { ENSURE_ARG(pMsg != NULL); if (pMsg->message == WM_DDE_EXECUTE) { UINT_PTR nDummy; HGLOBAL hCommands; if (!UnpackDDElParam(WM_DDE_EXECUTE, pMsg->lParam, &nDummy, (UINT_PTR*)&hCommands)) { TRACE(traceAppMsg, 0, "Warning: Unable to unpack WM_DDE_EXECUTE lParam %08lX.\n", pMsg->lParam); return; } ASSERT(hCommands != NULL); LPCTSTR lpszCommands = (LPCTSTR)::GlobalLock(hCommands); ENSURE_THROW(lpszCommands != NULL, ::AfxThrowMemoryException() ); TRACE(traceAppMsg, 0, _T("%s: Execute '%s'.\n"), lpszPrefix, lpszCommands); ::GlobalUnlock(hCommands); } else if (pMsg->message == WM_DDE_ADVISE) { UINT_PTR nItem; ATOM aItem; HGLOBAL hAdvise; if (!UnpackDDElParam(WM_DDE_ADVISE, pMsg->lParam, (UINT_PTR*)&hAdvise, &nItem)) { TRACE(traceAppMsg, 0, "Warning: Unable to unpack WM_DDE_ADVISE lParam %08lX.\n", pMsg->lParam); return; } aItem = (ATOM)nItem; ASSERT(aItem != NULL); ASSERT(hAdvise != NULL); DDEADVISE* lpAdvise = (DDEADVISE*)::GlobalLock(hAdvise); ENSURE_THROW(lpAdvise != NULL, ::AfxThrowMemoryException() ); TCHAR szItem[80]; szItem[0] = '\0'; if (aItem != 0) ::GlobalGetAtomName(aItem, szItem, _countof(szItem)); TCHAR szFormat[80]; szFormat[0] = '\0'; if (((UINT)0xC000 <= (UINT)lpAdvise->cfFormat) && ((UINT)lpAdvise->cfFormat <= (UINT)0xFFFF)) { ::GetClipboardFormatName(lpAdvise->cfFormat, szFormat, _countof(szFormat)); // User defined clipboard formats have a range of 0xC000->0xFFFF // System clipboard formats have other ranges, but no printable // format names. } AfxTrace( _T("%s: Advise item='%s', Format='%s', Ack=%d, Defer Update= %d\n"), lpszPrefix, szItem, szFormat, lpAdvise->fAckReq, lpAdvise->fDeferUpd); ::GlobalUnlock(hAdvise); } }
/****************************************************************** * WDML_ServerNameProc * * */ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam) { HWND hwndClient; HSZ hszApp, hszTop; HDDEDATA hDdeData = 0; WDML_INSTANCE* pInstance; UINT uiLo, uiHi; switch (iMsg) { case WM_DDE_INITIATE: /* wParam -- sending window handle LOWORD(lParam) -- application atom HIWORD(lParam) -- topic atom */ TRACE("WM_DDE_INITIATE message received!\n"); hwndClient = (HWND)wParam; pInstance = WDML_GetInstanceFromWnd(hwndServer); TRACE("idInst=%ld, threadID=0x%lx\n", pInstance->instanceID, GetCurrentThreadId()); if (!pInstance) return 0; /* don't free DDEParams, since this is a broadcast */ UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi); hszApp = WDML_MakeHszFromAtom(pInstance, uiLo); hszTop = WDML_MakeHszFromAtom(pInstance, uiHi); if (!(pInstance->CBFflags & CBF_FAIL_CONNECTIONS)) { BOOL self = FALSE; CONVCONTEXT cc; CONVCONTEXT* pcc = NULL; WDML_CONV* pConv; char buf[256]; if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) && WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer)) { self = TRUE; } /* FIXME: so far, we don't grab distant convcontext, so only check if remote is * handled under DDEML, and if so build a default context */ if ((GetClassNameA(hwndClient, buf, sizeof(buf)) && strcmp(buf, WDML_szClientConvClassA) == 0) || (GetClassNameW(hwndClient, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)) && lstrcmpW((LPWSTR)buf, WDML_szClientConvClassW) == 0)) { pcc = &cc; memset(pcc, 0, sizeof(*pcc)); pcc->cb = sizeof(*pcc); pcc->iCodePage = IsWindowUnicode(hwndClient) ? CP_WINUNICODE : CP_WINANSI; } if ((pInstance->CBFflags & CBF_FAIL_SELFCONNECTIONS) && self) { TRACE("Don't do self connection as requested\n"); } else if (hszApp && hszTop) { WDML_SERVER* pServer = (WDML_SERVER*)GetWindowLongA(hwndServer, GWL_WDML_SERVER); /* check filters for name service */ if (!pServer->filterOn || DdeCmpStringHandles(pServer->hszService, hszApp) == 0) { /* pass on to the callback */ hDdeData = WDML_InvokeCallback(pInstance, XTYP_CONNECT, 0, 0, hszTop, hszApp, 0, (DWORD)pcc, self); if ((UINT)hDdeData) { pConv = WDML_CreateServerConv(pInstance, hwndClient, hwndServer, hszApp, hszTop); if (pConv && pcc) pConv->wStatus |= ST_ISLOCAL; } } } else if (pInstance->servers) { /* pass on to the callback */ hDdeData = WDML_InvokeCallback(pInstance, XTYP_WILDCONNECT, 0, 0, hszTop, hszApp, 0, (DWORD)pcc, self); if (hDdeData == (HDDEDATA)CBR_BLOCK) { /* MS doc is not consistent here */ FIXME("CBR_BLOCK returned for WILDCONNECT\n"); } else if ((UINT)hDdeData != 0) { HSZPAIR* hszp; hszp = (HSZPAIR*)DdeAccessData(hDdeData, NULL); if (hszp) { int i; for (i = 0; hszp[i].hszSvc && hszp[i].hszTopic; i++) { pConv = WDML_CreateServerConv(pInstance, hwndClient, hwndServer, hszp[i].hszSvc, hszp[i].hszTopic); if (pConv && pcc) pConv->wStatus |= ST_ISLOCAL; } DdeUnaccessData(hDdeData); } if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData); } } } return 0; case WM_DDE_REQUEST: FIXME("WM_DDE_REQUEST message received!\n"); return 0; case WM_DDE_ADVISE: FIXME("WM_DDE_ADVISE message received!\n"); return 0; case WM_DDE_UNADVISE: FIXME("WM_DDE_UNADVISE message received!\n"); return 0; case WM_DDE_EXECUTE: FIXME("WM_DDE_EXECUTE message received!\n"); return 0; case WM_DDE_POKE: FIXME("WM_DDE_POKE message received!\n"); return 0; case WM_DDE_TERMINATE: FIXME("WM_DDE_TERMINATE message received!\n"); return 0; } return DefWindowProcA(hwndServer, iMsg, wParam, lParam); }
static LRESULT CALLBACK DdeMessageWindow(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DDE_INITIATE: { ATOM hSzApp = LOWORD(lParam); /* no UnpackDDElParam() here */ ATOM hSzTopic = HIWORD(lParam); if ((hSzApp == GlobalFindAtom(DDEAPP) && hSzTopic == GlobalFindAtom(DDETOPIC)) || !hSzApp) { hSzApp = GlobalAddAtom(DDEAPP); hSzTopic = GlobalAddAtom(DDETOPIC); if (hSzApp && hSzTopic) /* PackDDElParam() only for posted msgs */ SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, MAKELPARAM(hSzApp, hSzTopic)); if (hSzApp) GlobalDeleteAtom(hSzApp); if (hSzTopic) GlobalDeleteAtom(hSzTopic); } } return 0; case WM_DDE_EXECUTE: /* posted message */ HGLOBAL hCommand; if (UnpackDDElParam(msg, lParam, NULL, (PUINT_PTR)&hCommand)) { /* ANSI execute command can't happen for shell */ if (IsWindowUnicode((HWND)wParam)) { TCHAR *pszCommand = (TCHAR*)GlobalLock(hCommand); if (pszCommand != NULL) { TCHAR *pszAction = GetExecuteParam(&pszCommand); TCHAR *pszArg = GetExecuteParam(&pszCommand); if (pszArg != NULL) { /* we are inside miranda here, we make it async so the shell does * not timeout regardless what the plugins try to do. */ if (!mir_tstrcmpi(pszAction, _T("file"))) CallFunctionAsync(FileActionAsync, mir_tstrdup(pszArg)); else if (!mir_tstrcmpi(pszAction, _T("url"))) CallFunctionAsync(UrlActionAsync, mir_tstrdup(pszArg)); } GlobalUnlock(hCommand); } } DDEACK ack; memset(&ack, 0, sizeof(ack)); lParam = ReuseDDElParam(lParam, msg, WM_DDE_ACK, *(PUINT)&ack, (UINT_PTR)hCommand); if (!PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, lParam)) { GlobalFree(hCommand); FreeDDElParam(WM_DDE_ACK, lParam); } } return 0; case WM_DDE_TERMINATE: PostMessage((HWND)wParam, msg, (WPARAM)hwnd, 0); /* ack reply */ return 0; case WM_DDE_REQUEST: case WM_DDE_ADVISE: case WM_DDE_UNADVISE: case WM_DDE_POKE: /* fail safely for those to avoid memory leak in lParam */ { ATOM hSzItem; DDEACK ack; memset(&ack, 0, sizeof(ack)); if (UnpackDDElParam(msg, lParam, NULL, (PUINT_PTR)&hSzItem)) { lParam = ReuseDDElParam(lParam, msg, WM_DDE_ACK, *(PUINT)&ack, (UINT)hSzItem); if (!PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, lParam)) { if (hSzItem) GlobalDeleteAtom(hSzItem); FreeDDElParam(WM_DDE_ACK, lParam); } } return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); }