void CNetDDESvrApp::OnDDEDestroyConversation(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_DESTROY_CONVERSATION); HCONV hConv; uint32 nConvID; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream.Close(); if (App.m_bTraceConvs) App.Trace(TXT("DDE_DESTROY_CONVERSATION: 0x%p [#%u]"), hConv, nConvID); // Locate the conversation. CDDECltConv* pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { CNetDDEConv* pNetConv = oConnection.FindNetConv(pConv, nConvID); ASSERT(pNetConv != NULL); try { // Not final reference? if (pNetConv->m_pSvrConv->RefCount() != 1) { // Destroy NetDDE conversations' links. for (size_t i = 0; i < pNetConv->m_aoLinks.Size(); ++i) pConv->DestroyLink(pNetConv->m_aoLinks[i]); } // Purge link cache, if last reference. if (pNetConv->m_pSvrConv->RefCount() == 1) m_oLinkCache.Purge(pConv); // Call DDE to terminate the conversation. m_pDDEClient->DestroyConversation(pConv); } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Detach from the connection. oConnection.m_aoNetConvs.Delete(oConnection.m_aoNetConvs.Find(pNetConv)); } }
void CNetDDESvrApp::OnDDEStopAdvise(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_STOP_ADVISE); HCONV hConv; uint32 nConvID; CString strItem; uint32 nFormat; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream >> strItem; oStream >> nFormat; oStream.Close(); if (App.m_bTraceAdvises) App.Trace(TXT("DDE_STOP_ADVISE: %s %s"), strItem, CClipboard::FormatName(nFormat)); // Locate the conversation. CDDECltConv* pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { // Locate the link. (May not exist, if async advised). CDDELink* pLink = pConv->FindLink(strItem, nFormat); if (pLink != NULL) { CNetDDEConv* pNetConv = oConnection.FindNetConv(pConv, nConvID); ASSERT(pNetConv != NULL); try { // Call DDE to destroy the link. pConv->DestroyLink(pLink); } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Detach from the connection. pNetConv->m_aoLinks.Remove(pNetConv->m_aoLinks.Find(pLink)); } } }
DDE::IDDECltConv* CDDEClient::FindConversation(HCONV hConv) const { // Search the conversation list. for (size_t i = 0, n = m_aoConvs.size(); i != n; ++i) { CDDECltConv* pConv = static_cast<CDDECltConv*>(m_aoConvs[i]); if (pConv->Handle() == hConv) return pConv; } return nullptr; }
void CDDEClient::OnAdvise(HCONV hConv, const tchar* /*pszTopic*/, const tchar* pszItem, uint nFormat, const CDDEData* pData) { // Find the conversation for the handle. CDDECltConv* pConv = static_cast<CDDECltConv*>(FindConversation(hConv)); ASSERT(pConv != nullptr); // Find the link. CDDELink* pLink = pConv->FindLink(pszItem, nFormat); // May still be in the Advise Start. if (pLink == nullptr) { // TRACE3("OnAdvise('%s|%s', '%s') - Failed to find link\n", pConv->Service(), pConv->Topic(), pszItem); return; } for (size_t i = 0, n = m_aoListeners.size(); i != n; ++i) m_aoListeners[i]->OnAdvise(pLink, pData); }
void CDDEClient::DestroyConversation(DDE::IDDECltConv* pIConv) { ASSERT(pIConv != nullptr); ASSERT(std::find(m_aoConvs.begin(), m_aoConvs.end(), pIConv) != m_aoConvs.end()); CDDECltConv* pConv = static_cast<CDDECltConv*>(pIConv); // Last reference? if (--pConv->m_nRefCount == 0) { // Disconnect from service/topic. pConv->Disconnect(); // Remove from collection. m_aoConvs.erase(std::find(m_aoConvs.begin(), m_aoConvs.end(), pConv)); // Delete conversation. delete pConv; } }
void CNetDDESvrApp::OnDDECreateConversation(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_CREATE_CONVERSATION); bool bResult = false; CString strService; CString strTopic; HCONV hConv = NULL; uint32 nConvID = m_nNextConvID++; // Decode request message. CMemStream oReqStream(oReqPacket.Buffer()); oReqStream.Open(); oReqStream.Seek(sizeof(CNetDDEPacket::Header)); oReqStream >> strService; oReqStream >> strTopic; oReqStream.Close(); if (App.m_bTraceConvs) App.Trace(TXT("DDE_CREATE_CONVERSATION: %s %s [#%u]"), strService, strTopic, nConvID); try { // Call DDE to create the conversation. CDDECltConv* pConv = m_pDDEClient->CreateConversation(strService, strTopic); bResult = true; hConv = pConv->Handle(); // Attach to the connection. oConnection.m_aoNetConvs.Add(new CNetDDEConv(pConv, nConvID)); // Apply settings. pConv->SetTimeout(App.m_nDDETimeOut); } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream << bResult; oRspStream.Write(&hConv, sizeof(hConv)); oRspStream << nConvID; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_CREATE_CONVERSATION, oReqPacket.PacketID(), oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; }
void CNetDDESvrApp::OnDDEPoke(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_POKE); bool bResult = false; HCONV hConv; uint32 nConvID; CString strItem; uint32 nFormat; CBuffer oData; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream >> strItem; oStream >> nFormat; oStream >> oData; oStream.Close(); if (App.m_bTraceRequests) { CString strData; if (nFormat == CF_TEXT) strData = oData.ToString(ANSI_TEXT); else if (nFormat == CF_UNICODETEXT) strData = oData.ToString(UNICODE_TEXT); else strData = CClipboard::FormatName(nFormat); App.Trace(TXT("DDE_POKE: %s %s [%s]"), strItem, CClipboard::FormatName(nFormat), strData); } try { // Locate the conversation. CDDECltConv* pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { // Call DDE to do the poke. pConv->Poke(strItem, nFormat, oData.Buffer(), oData.Size()); bResult = true; } } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream << bResult; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_POKE, oReqPacket.PacketID(), oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; }
void CNetDDESvrApp::OnDDEExecute(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_EXECUTE); bool bResult = false; HCONV hConv; uint32 nConvID; CString strCmd; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream >> strCmd; oStream.Close(); if (App.m_bTraceRequests) App.Trace(TXT("DDE_EXECUTE: 0x%p [%s]"), hConv, strCmd); try { // Locate the conversation. CDDECltConv* pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { // Call DDE to do the execute. pConv->ExecuteString(strCmd); bResult = true; } } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream << bResult; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_EXECUTE, oReqPacket.PacketID(), oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; }
void CNetDDESvrApp::OnDDEStartAdvise(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_START_ADVISE); bool bResult = false; CDDECltConv* pConv = NULL; CDDELink* pLink = NULL; HCONV hConv; uint32 nConvID; CString strItem; uint32 nFormat; bool bAsync; bool bReqVal; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream >> strItem; oStream >> nFormat; oStream >> bAsync; oStream >> bReqVal; oStream.Close(); if (App.m_bTraceAdvises) App.Trace(TXT("DDE_START_ADVISE: %s %s %s"), strItem, CClipboard::FormatName(nFormat), (bAsync) ? TXT("[ASYNC]") : TXT("")); try { // Locate the conversation. pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { CNetDDEConv* pNetConv = oConnection.FindNetConv(pConv, nConvID); ASSERT(pNetConv != NULL); // Call DDE to create the link. pLink = pConv->CreateLink(strItem, nFormat); // Attach to the connection. pNetConv->m_aoLinks.Add(pLink); bResult = true; } } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Sync advise start? if (!bAsync) { // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream << bResult; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_START_ADVISE, oReqPacket.PacketID(), oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; } // Failed async advise start? if ((bAsync) && (!bResult)) { // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream.Write(&hConv, sizeof(hConv)); oRspStream << strItem; oRspStream << nFormat; oRspStream << true; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_START_ADVISE_FAILED, oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; } CLinkValue* pLinkValue = NULL; // Link established AND 1st link AND need to request value? if ( (bResult) && (pLink->RefCount() == 1) && (bReqVal) ) { try { // Request links current value. CDDEData oData = pConv->Request(strItem, nFormat); // Find the links' value cache. if ((pLinkValue = m_oLinkCache.Find(pConv, pLink)) == NULL) pLinkValue = m_oLinkCache.Create(pConv, pLink); ASSERT(pLinkValue != NULL); // Update links' value cache. pLinkValue->m_oLastValue = oData.GetBuffer();; pLinkValue->m_tLastUpdate = CDateTime::Current(); } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } } // Link established AND not 1st real link? else if ( (bResult) && (pLink->RefCount() > 1) ) { // Find last advise value. pLinkValue = m_oLinkCache.Find(pConv, pLink); } // Send initial advise? if (pLinkValue != NULL) { CBuffer oBuffer; CMemStream oStream(oBuffer); oStream.Create(); oStream.Write(&hConv, sizeof(hConv)); oStream << strItem; oStream << nFormat; oStream << pLinkValue->m_oLastValue; oStream << true; oStream.Close(); CNetDDEPacket oPacket(CNetDDEPacket::DDE_ADVISE, oBuffer); // Send links' last advise data. oConnection.SendPacket(oPacket); // Update stats. ++m_nPktsSent; if (App.m_bTraceUpdates) { CString strData; if (nFormat == CF_TEXT) strData = pLinkValue->m_oLastValue.ToString(ANSI_TEXT); else if (nFormat == CF_UNICODETEXT) strData = pLinkValue->m_oLastValue.ToString(UNICODE_TEXT); else strData = CClipboard::FormatName(nFormat); App.Trace(TXT("DDE_ADVISE: %s %u"), strItem, nFormat); } } }
void CNetDDESvrApp::OnDDERequest(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_REQUEST); bool bResult = false; HCONV hConv; uint32 nConvID; CString strItem; uint32 nFormat; CBuffer oBuffer; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream >> strItem; oStream >> nFormat; oStream.Close(); if (App.m_bTraceRequests) App.Trace(TXT("DDE_REQUEST: %s %s"), strItem, CClipboard::FormatName(nFormat)); try { // Locate the conversation. CDDECltConv* pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { // Call DDE to make the request. CDDEData oData = pConv->Request(strItem, nFormat); oBuffer = oData.GetBuffer(); bResult = true; } } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream << bResult; oRspStream << oBuffer; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_REQUEST, oReqPacket.PacketID(), oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; }