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));
		}
	}
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}