예제 #1
0
	void MetaEntry::handleRealGotMessage (QObject *msgObj)
	{
		IMessage *msg = qobject_cast<IMessage*> (msgObj);
		if (!msg)
		{
			qWarning () << Q_FUNC_INFO
					<< msgObj
					<< "doesn't implement IMessage";
			return;
		}

		MetaMessage *message = new MetaMessage (msgObj, this);

		const bool shouldSort = !Messages_.isEmpty () &&
				Messages_.last ()->GetDateTime () > msg->GetDateTime ();

		Messages_ << message;
		if (shouldSort)
			std::stable_sort (Messages_.begin (), Messages_.end (),
					[] (IMessage *left, IMessage *right)
					{
						return left->GetDateTime () < right->GetDateTime ();
					});

		emit gotMessage (message);
	}
예제 #2
0
	void UnreadQueueManager::AddMessage (QObject *msgObj)
	{
		IMessage *msg = qobject_cast<IMessage*> (msgObj);
		QObject *entryObj = msg->ParentCLEntry ();
		if (!Queue_.contains (entryObj))
			Queue_ << entryObj;
	}
예제 #3
0
파일: packet.cpp 프로젝트: LuaxY/CawotteSrv
void Packet::serialize(IMessage& message, ByteArray& buffer)
{
    BinaryWriter writer(buffer);
    BinaryWriter messageWriter(_data);
    message.serialize(messageWriter);

    _id = message.getId();
    _length = static_cast<uint>(_data.size());
    _lengthType = computeLengthType(_length);
    _header = computeHeader(_id, _lengthType);

    if (_header == 0)
    {
        throw std::logic_error("header must be non null");
    }

    writer.writeShort(_header);

    switch (_lengthType)
    {
        case 1:
            writer.writeByte(static_cast<char>(_length));
            break;
        case 2:
            writer.writeUShort(static_cast<ushort>(_length));
            break;
        case 3:
            // TODO: Write for 3 bytes length
            break;
        default:
            break;
    }

    writer.writeBytes(_data, false);
}
예제 #4
0
IMessage* SSLSession::CreateRequest()
{
	IMessage* req = NULL;
	
	switch (msgType)
	{
	case MSG_TYPE_TCP_OLD:
		req = new TcpMessageOld();
		break;
	case MSG_TYPE_SSL_PB:
		req = new SslMessagePB();
		break;
	case MSG_TYPE_TCP_NEW:
		req = new CustomMessage(MSG_TYPE_TCP_NEW);
		break;
	case MSG_TYPE_SSL_NEW:
		req = new CustomMessage(MSG_TYPE_SSL_NEW);
		break;
	}
			
	req->SetSslSession(shared_from_this());

	return req;
	/*
	ssl_session_ptr sess = shared_from_this();
	ssl_request_ptr req = boost::factory<ssl_request_ptr>()(sess);
	return req;
	*/
}
예제 #5
0
IMessage* SSLSession::create_request()
{
	IMessage* req = NULL;
	
	switch (m_msgType)
	{
	case MSG_TYPE_HTTP:
		req = new http_message();
		break;
	case MSG_TYPE_TCP_OLD:
		req = new tcp_message_old();
		break;
	case MSG_TYPE_SSL_PB:
		req = new ssl_message();
		break;
	case MSG_TYPE_TCP_NEW:
		req = new CustomMessage(MSG_TYPE_TCP_NEW);
		break;
	case MSG_TYPE_SSL_NEW:
		req = new CustomMessage(MSG_TYPE_SSL_NEW);
		break;
	}
			
	req->SetSslSession(shared_from_this());
	return req;
	/*
	ssl_session_ptr sess = shared_from_this();
	ssl_request_ptr req = boost::factory<ssl_request_ptr>()(sess);
	return req;
	*/
}
예제 #6
0
IMessage *CmReponseHander::GetQueryRspByResult(int result)
{
  CM_TRACE_DEBUG(gettext("Handle message return. result=") << result);
  IMessage *pRsp = IMessageFactory::CreateMessage("ubp.cm." + msgType_ + "List");
  const Descriptor *descriptor = pRsp->GetDescriptor();
  const Reflection *reflection = pRsp->GetReflection();
  const FieldDescriptor *field = descriptor->FindFieldByName("result");
  reflection->SetInt32(pRsp, field, result);
  return pRsp;
}
예제 #7
0
파일: plug.cpp 프로젝트: eriser/Voltex
//------------------------------------------------------------------------
tresult Plug::sendTextMessage (const char16* text)
{
	IMessage* message = allocateMessage ();
	if (!message)
		return kResultFalse;
	FReleaser msgReleaser (message);
	message->setMessageID ("TextMessage");
	message->getAttributes ()->setString ("Text", text);
	return sendMessage (message);
}
예제 #8
0
//------------------------------------------------------------------------
tresult ComponentBase::sendTextMessage (const char8* text)
{
	IMessage* message = allocateMessage ();
	if (!message)
		return kResultFalse;

	FReleaser msgReleaser (message);
	message->setMessageID ("TextMessage");
	message->getAttributes ()->setString ("Text", STR (text));
	return sendMessage (message);
}
예제 #9
0
// 读请求
void SSLSession::read()
{
	IMessage* req = create_request();			

	boost::asio::async_read(socket_, 
		boost::asio::buffer(req->GetMsgHeader(), req->GetMsgHeaderSize()), 
		boost::asio::transfer_all(),
		strand_.wrap(
			boost::bind(&SSLSession::handle_read_head, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, req)
		)
	);
}
예제 #10
0
void amqp::Sender::_addAnnotationsToMessage(pn_message_t *pnmessage, IMessage const &message)
{
	pn_data_t *pnmessage_annotations = pn_message_annotations(pnmessage);
	pn_data_put_map(pnmessage_annotations);
	pn_data_enter(pnmessage_annotations);

	MessageMeta::const_iterator i = message.getAnnotations().begin();
	for (; i != message.getAnnotations().end(); ++i) {
		_serializeMessageMeta(pnmessage_annotations, (*i));
	}

	pn_data_exit(pnmessage_annotations);
}
예제 #11
0
	void Plugin::handleMetadata ()
	{
		QNetworkReply *reply = qobject_cast<QNetworkReply*> (sender ());
		if (!reply)
		{
			qWarning () << Q_FUNC_INFO
					<< "sender is not a QNetworkReply:"
					<< sender ();
			return;
		}

		const QString& pasteUrl = reply->header (QNetworkRequest::LocationHeader).toString ();
		QPointer<QObject> entryObj = Reply2Entry_ [reply];
		if (!entryObj)
		{
			QApplication::clipboard ()->setText (pasteUrl, QClipboard::Clipboard);
			QApplication::clipboard ()->setText (pasteUrl, QClipboard::Selection);
			const Entity& e = Util::MakeNotification (tr ("Text pasted"),
					tr ("Your text has been pasted: %1. The URL has "
						"been copied to the clipboard."),
					PInfo_);
			emit gotEntity (e);
			return;
		}

		ICLEntry *entry = qobject_cast<ICLEntry*> (entryObj);
		if (!entry)
		{
			qWarning () << Q_FUNC_INFO
					<< "unable to cast"
					<< entryObj
					<< "to ICLEntry";
			return;
		}

		IMessage::MessageType type =
				entry->GetEntryType () == ICLEntry::ETMUC ?
						IMessage::MTMUCMessage :
						IMessage::MTChatMessage;
		QObject *msgObj = entry->CreateMessage (type, QString (), pasteUrl);
		IMessage *msg = qobject_cast<IMessage*> (msgObj);
		if (!msg)
		{
			qWarning () << Q_FUNC_INFO
					<< "unable to cast"
					<< msgObj
					<< "to IMessage";
			return;
		}
		msg->Send ();
	}
예제 #12
0
파일: p100q.cpp 프로젝트: Apkawa/leechcraft
void Plugin::hookFormatBodyEnd (IHookProxy_ptr proxy,
                                QObject *chatTab, QString body, QObject *msgObj)
{
    IMessage *msg = qobject_cast<IMessage*> (msgObj);
    if (msg->GetDirection () != IMessage::DIn ||
            msg->GetMessageType () != IMessage::MTChatMessage)
        return;

    ICLEntry *other = qobject_cast<ICLEntry*> (msg->OtherPart ());
    if (!other->GetEntryID ().contains ("*****@*****.**"))
        return;

    proxy->SetValue ("body", FormatBody (body));
}
void Sender::startSending()
{
	std::thread SendThread(
		[&]()
	{
		do
		{
			try
			{
				IMessage *msg = sendQ.deQ();
				/*Message* msg = dynamic_cast<Message*>(imsg);
				map<string, string> header = msg->getHeader();*/

				if (msg->getCommand() == "send_stop")
					break;
				else if (msg->getCommand() == "file_upload")
				{
					if (connectToPeer(msg->getRecvIP(), stoi(msg->getRecvPort())))
					{
						if (sendFile(msg))
						{	}
					}
					else
						Verbose::show("Connection failed!\n");
				}
				else if (msg->getCommand() == "ack")
				{
					if (connectToPeer(msg->getRecvIP(), stoi(msg->getRecvPort())))
						sendHeader(msg);
				}
				else
				{
					if (connectToPeer(msg->getRecvIP(), stoi(msg->getRecvPort())))
					{
						sendHeader(msg);
						sendBody(msg);
					}
				}
			}
			catch (exception ex)
			{
				string s = ex.what();
				Verbose::show("\n In send Thread: " + s);
			}
		} while (1);
	}
	);
	SendThread.detach();
}
예제 #14
0
// 读请求
void SSLSession::read()
{
	IMessage* req = CreateRequest();			

	int size = req->GetMsgHeaderSize();
	

	boost::asio::async_read(shared_from_this()->socket, 
		boost::asio::buffer(req->GetMsgHeader(), req->GetMsgHeaderSize()), 
		boost::asio::transfer_all(),
		strand.wrap(
			boost::bind(&SSLSession::OnReadHead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, req)
		)
	);
}
예제 #15
0
void TrackSearchLayout::ProcessMessage(IMessage &message) {
    int type = message.Type();

    if (type == message::RequeryTrackList) {
        this->Requery();
    }
}
예제 #16
0
	void Plugin::hookMessageCreated (IHookProxy_ptr proxy,
			QObject*, QObject *msgObj)
	{
		if (ConvScriptPath_.isEmpty ())
			return;
		
		if (!XmlSettingsManager::Instance ()
				.property ("SubstituteOutgoing").toBool ())
			return;
		
		if (HandledObjects_.contains (msgObj))
			return;
		
		IMessage *msg = qobject_cast<IMessage*> (msgObj);
		if (!msg)
		{
			qWarning () << Q_FUNC_INFO
					<< "message"
					<< msgObj
					<< "doesn't implement IMessage";
			return;
		}
		
		IRichTextMessage *richMsg = qobject_cast<IRichTextMessage*> (msgObj);
		if (!richMsg)
			return;
		
		QString body = richMsg->GetRichBody ();
		if (body.isEmpty ())
			body = msg->GetBody ();
		
		if (!body.contains ("$$"))
			return;
		
		const QString newBody = HandleBody (body);
		if (newBody == body)
			return;

		if (XmlSettingsManager::Instance ()
				.property ("WarnInOutgoing").toBool ())
			msg->SetBody (msg->GetBody () + " (this message contains "
						"inline formulas, enable XHTML-IM to view them)");

		richMsg->SetRichBody (newBody);
		HandledObjects_ << msgObj;
	}
예제 #17
0
//-----------------------------------------------------------------------------
void HostCheckerProcessor::sendLogEventMessage (const LogEvent& logEvent)
{
	IMessage* message = allocateMessage ();
	FReleaser msgReleaser (message);
	if (message)
	{
		message->setMessageID ("LogEvent");
		IAttributeList* attributes = message->getAttributes ();
		if (attributes)
		{
			ASSERT (logEvent.id >= 0);
			attributes->setInt ("ID", logEvent.id);
			attributes->setInt ("Count", logEvent.count);
			sendMessage (message);
		}
	}
}
예제 #18
0
//-----------------------------------------------------------------------------
tresult PLUGIN_API HostCheckerController::connect (IConnectionPoint* other)
{
	Steinberg::tresult tResult = ComponentBase::connect (other);
	if (peerConnection)
	{
		for (Steinberg::int32 paramIdx = 0; paramIdx < getParameterCount (); ++paramIdx)
		{
			Steinberg::Vst::ParameterInfo paramInfo = {0};
			if (getParameterInfo (paramIdx, paramInfo) == Steinberg::kResultOk)
			{
				IMessage* newMsg = allocateMessage ();
				if (newMsg)
				{
					newMsg->setMessageID ("Parameter");
					Steinberg::Vst::IAttributeList* attr = newMsg->getAttributes ();
					if (attr)
					{
						attr->setInt ("ID", paramInfo.id);
					}

					sendMessage (newMsg);
				}
			}
		}

		FUnknownPtr<IAudioProcessor> proc (other);
		if (proc)
		{
			OPtr<IMessage> newMsg = allocateMessage ();
			if (newMsg)
			{
				newMsg->setMessageID ("LogEvent");
				Steinberg::Vst::IAttributeList* attr = newMsg->getAttributes ();
				if (attr)
				{
					attr->setInt ("ID", kLogIdProcessorControllerConnection);
					attr->setInt ("Count", 1);
				}

				notify (newMsg);
			}
		}
	}

	return tResult;
}
IMessage* ClientHandler::receiveHeader(Socket& socket_)
{
	vector<string> received;
	while (true)
	{
		string command = socket_.recvString('\n');
		// interpret test command
		if (command == "\n" || command.size() == 0)
		{
			command = socket_.recvString('\n');
			break;			//header received
		}
		received.push_back(command);
	}
	IMessage *msg = new Message();
	msg->parseMessage(received);
	return msg;
}
예제 #20
0
void ServerDaemonImpl::flushMessage() {
	if (m_HomeConnection == NULL) {
		return;
	}

	while (m_MessageQueue->Size() > 0) {
		IMessage * msg = m_MessageQueue->Front();
		std::string _msg = msg->GetMessage();
		delete msg;
		m_MessageQueue->Pop();
		if (m_HomeConnection->IsConnected()) {
			Log("notify home -> %s", _msg.c_str());
			m_HomeConnection->WriteData(_msg);
		} else {
			Log("notify home failed, reason: socket closed.");
		}
	}
}
    std::string MessageDispatchedEvent::createDetail(IMessage& message)
    {
        auto detail = std::string("Command Content:");
        for (auto& c : message.getCommand().content)
        {
            detail += std::string(" ");
            detail += std::to_string((unsigned int)c);
        }

        return detail;
    }
예제 #22
0
IMessage* MessagePasserImpl::Retrieve()
{
	// (It should be fairly easy to use a more efficient thread-safe queue,
	// since there's only one thread adding items and one thread consuming;
	// but it's not worthwhile yet.)

	IMessage* msg = NULL;

	{
		CScopeLock lock(m_Mutex);
		if (! m_Queue.empty())
		{
			msg = m_Queue.front();
			m_Queue.pop();
		}
	}

	if (m_Trace && msg)
		debug_printf("%8.3f retrieved message: %s\n", timer_Time(), msg->GetName());

	return msg;
}
예제 #23
0
void amqp::Sender::send(IMessage const &message, Address const &address)
{
	pn_data_t *pnmessage_body = NULL;
	pn_message_t *pnmessage = pn_message();

	if (pnmessage == NULL) {
		throw std::exception("ERROR: Message could not be created.");
	}

	pn_message_set_address(pnmessage, address.toString().c_str());
	_addMetaToMessage(pnmessage, message);

	pnmessage_body = pn_message_body(pnmessage);
	pn_data_put_binary(pnmessage_body, pn_bytes(message.getSize(), message.getBytes()));
	pn_messenger_put(m_messenger, pnmessage);

	if (isError()) {
		_throwError();
	}

	// To avoid traffic flud and speed up the solution better to use blocking scokets in tracking mode
	if (isTraking()) {
		Log("Sending messages to %s\n", address.toString().c_str());
		m_tracker = pn_messenger_outgoing_tracker(m_messenger);
		pn_messenger_send(m_messenger, -1); // sync
	} 
	else {
		pn_messenger_send(m_messenger, 1); // async
	}

	if (isError()) {
		_throwError();
	}

	_checkTracking();

	pn_message_free(pnmessage);
}
예제 #24
0
파일: p100q.cpp 프로젝트: Zereal/leechcraft
	void Plugin::hookFormatBodyEnd (IHookProxy_ptr proxy,
			QObject*, QString body, QObject *msgObj)
	{
		IMessage *msg = qobject_cast<IMessage*> (msgObj);
		if (msg->GetDirection () != IMessage::DIn ||
				msg->GetMessageType () != IMessage::MTChatMessage)
			return;

		ICLEntry *other = qobject_cast<ICLEntry*> (msg->OtherPart ());
		if (!other)
		{
			qWarning () << Q_FUNC_INFO
					<< "NULL other part for message"
					<< msgObj
					<< msg->GetBody ();
			return;
		}

		if (!other->GetEntryID ().contains ("*****@*****.**"))
			return;

		proxy->SetValue ("body", FormatBody (body));
	}
예제 #25
0
	bool Plugin::ShouldHandle (QObject* msgObj,
			IMessage::Direction direction, IMessage::Type type)
	{
		IMessage *msg = qobject_cast<IMessage*> (msgObj);

		if (!msg)
		{
			qWarning () << Q_FUNC_INFO
				<< "unable to cast"
				<< msgObj
				<< "to IMessage";
			return false;
		}

		if (msg->GetDirection () != direction ||
			msg->GetMessageType () != type)
		{
			return false;
		}

		ICLEntry *other = qobject_cast<ICLEntry*> (msg->OtherPart ());

		if (!other)
		{
			qWarning () << Q_FUNC_INFO
				<< "unable to cast"
				<< msg->OtherPart ()
				<< "to ICLEntry";
			return false;
		}

		if (!other->GetEntryID ().contains ("*****@*****.**"))
			return false;

		return true;

	}
예제 #26
0
void amqp::Sender::_addMetaToMessage(pn_message_t *pnmessage, IMessage const &message)
{
	pn_timestamp_t utcTime;
	time(&utcTime);

	_addPropertiesToMessage(pnmessage, message);
	_addAnnotationsToMessage(pnmessage, message);

	pn_message_set_content_type(pnmessage, message.getContentType().c_str());
	pn_message_set_inferred(pnmessage, true);
	pn_message_set_subject(pnmessage, message.getSubject().c_str());
	pn_message_set_ttl(pnmessage, 86400000);
	pn_message_set_creation_time(pnmessage, utcTime);
	switch (message.getEncoding())
	{
	case IMessage::UTF8: 
		pn_message_set_content_encoding(pnmessage, "UTF-8");
		break;
	case IMessage::UTF16:
		pn_message_set_content_encoding(pnmessage, "UTF-16");
		break;
	}
	
}
void ClientHandler::operator()(Socket& socket_)
{
	try
	{
		IMessage *msg = receiveHeader(socket_);
		if (msg->getCommand() == "send_string")
			Verbose::show("\nString received: " + msg->getValue() + "\n");
		else if (msg->getCommand() == "file_upload")
		{
			using HighResolutionClock = chrono::high_resolution_clock;
			HighResolutionClock::time_point t1 = HighResolutionClock::now();

			if (acceptFile(msg, socket_))
			{	}
			else
				Verbose::show("\nFile Upload Failed!\n");
			HighResolutionClock::time_point t2 = HighResolutionClock::now();
			auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
			msg->setTime(to_string(duration));
		}
		else if (msg->getCommand() == "ack")
		{
			string s = "\n  Reply from " + msg->getSendIP() + msg->getSendPort();
			s += ": " + msg->getValue() + " uploaded successfully!\n";
			Verbose::show(s);
		}
		else //(msg->getCommand() == "ack_get_dir")
		{
			receiveBody(socket_,msg);
		}
		recvr->postMessage(msg);
	}
	catch (std::exception& ex)
	{
		Verbose::show("  Exception caught:", always);
		Verbose::show(std::string("\n  ") + ex.what() + "\n\n");
	}
	socket_.shutDown();
	socket_.close();
}
예제 #28
0
	void Plugin::hookGotMessage (LeechCraft::IHookProxy_ptr proxy,
			QObject *message)
	{
		IMessage *msg = qobject_cast<IMessage*> (message);
		if (!msg)
			return;

		if (msg->GetMessageType () != IMessage::MTChatMessage &&
				msg->GetMessageType () != IMessage::MTMUCMessage)
			return;

		if ((msg->GetMessageType () == IMessage::MTChatMessage &&
				!XmlSettingsManager::Instance ().property ("EnableForChats").toBool ()) ||
			(msg->GetMessageType () == IMessage::MTMUCMessage &&
				!XmlSettingsManager::Instance ().property ("EnableForMUCs").toBool ()))
			return;

		QString str = msg->GetBody ();
		if (str.length () < 3)
			return;

		int caps = 0;
		int alphaLength = 0;
		for (int i = 0, size = str.length (); i < size; ++i)
		{
			if (!str.at (i).isLetter ())
				continue;

			++alphaLength;
			if (str.at (i).isUpper ())
				++caps;
		}

		double ratio = static_cast<double> (XmlSettingsManager::Instance ()
					.property ("CapsPercentage").toInt ()) / 100;
		if (alphaLength > 3 &&
				static_cast<double> (caps) / alphaLength < ratio)
			return;

		for (int i = 0, size = str.length (); i < size; ++i)
			str [i] = str.at (i).toLower ();

		msg->SetBody (str);
	}
예제 #29
0
STDMETHODIMP CExtImpl::OnWriteComplete(IExchExtCallback* pecb, ULONG ulFlags)
{
	if (_context != EECONTEXT_SENDNOTEMESSAGE)
		return S_FALSE;

	if (ulFlags == EEME_COMPLETE_FAILED) // Nothing to unwind
		return S_FALSE;

	if (!_fInSubmitState)	// This is not a submission.
		return S_FALSE;

	if (_bEncrypt || _bSign)
	{
		IMessage *pmsg = 0;
		RECIPIENTDIALOGSTRUCT *prds;
		PGPOptionListRef signOptions = NULL;
		HWND hwnd;
		PGPError nError = kPGPError_NoErr;

		pecb->GetWindow(&hwnd);
		if (!hwnd)
			hwnd = GetTopWindow(NULL);
		
		CWaitCursor wait; // Mark busy
		
		HRESULT hr = pecb->GetObject(NULL, (IMAPIProp**)&pmsg);
		if (FAILED(hr))
		{
			UIDisplayStringID(hwnd, IDS_E_NOMESSAGE);
			return E_ABORT;
		}

		prds = (RECIPIENTDIALOGSTRUCT *) 
				calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);	

		nError = PGPsdkLoadDefaultPrefs(_pgpContext);
		if (IsPGPError(nError))
		{
			UIDisplayErrorCode(__FILE__, __LINE__, NULL, nError);
			return E_ABORT;
		}

		nError = PGPOpenDefaultKeyRings(_pgpContext, (PGPKeyRingOpenFlags)0, 
					&(prds->OriginalKeySetRef));

		if (IsPGPError(nError))
		{
			UIDisplayErrorCode(__FILE__, __LINE__, NULL, nError);
			return E_ABORT;
		}

		if (_bEncrypt)
			nError = GetRecipients(pecb, _pgpContext, _tlsContext, prds);

		if (IsPGPError(nError))
		{
			if (nError != kPGPError_UserAbort)
				UIDisplayErrorCode(__FILE__, __LINE__, NULL, 
					nError);
			return E_ABORT;
		}

		nError = EncryptSignMessage(hwnd, pmsg, prds, &signOptions);

		if (signOptions != NULL)
		{
			PGPFreeOptionList(signOptions);
			signOptions = NULL;
		}

		FreeRecipients(prds);

		if (NULL!=(int)(prds->OriginalKeySetRef))
		{
			PGPFreeKeySet(prds->OriginalKeySetRef);
			prds->OriginalKeySetRef = NULL;
		}

		free(prds);
		pmsg->Release();

		if (IsPGPError(nError))
			return E_ABORT;
	}

	return S_FALSE;
}
예제 #30
0
STDMETHODIMP CExtImpl::OnRead(IExchExtCallback* peecb)
{
	HWND hwnd;

	peecb->GetWindow(&hwnd);
	if (!hwnd)
		hwnd = GetTopWindow(NULL);

	switch (_context)
	{
	case EECONTEXT_SENDNOTEMESSAGE:
		{
			BOOL fAddButtons = TRUE;
			int nNumButtons;
			int nIndex;
			TBBUTTON tbbNew[5];
			TBBUTTON tbbCheck;
			
			// Check to make sure the buttons aren't already on the toolbar

			nNumButtons = SendMessage(_hwndSendToolbar, TB_BUTTONCOUNT, 0, 0);
			for (nIndex=0; nIndex<nNumButtons; nIndex++)
			{
				SendMessage(_hwndSendToolbar, TB_GETBUTTON, (WPARAM) nIndex, 
							(LPARAM) &tbbCheck);

				// If a button exists with the same bitmap ID and command ID
				// as the Encrypt button, odds are good that the button is
				// already on the toolbar
				if ((tbbCheck.iBitmap == (int)_itbmEncrypt) && 
					(tbbCheck.idCommand == (int)_cmdidEncrypt))
				{
					fAddButtons = FALSE;
					nIndex = nNumButtons;
				}
			}

			if (fAddButtons)
			{
				tbbNew[0].iBitmap = 0;
				tbbNew[0].idCommand = 0;
				tbbNew[0].fsState = 0;
				tbbNew[0].fsStyle = TBSTYLE_SEP;
				tbbNew[0].dwData = 0;
				tbbNew[0].iString = -1;
			
				tbbNew[1].iBitmap = _itbmEncrypt;
				tbbNew[1].idCommand = _cmdidEncrypt;
				tbbNew[1].fsState = TBSTATE_ENABLED;
				tbbNew[1].fsStyle = TBSTYLE_CHECK;
				tbbNew[1].dwData = 0;
				tbbNew[1].iString = -1;
			
				tbbNew[2].iBitmap = _itbmSign;
				tbbNew[2].idCommand = _cmdidSign;
				tbbNew[2].fsState = TBSTATE_ENABLED;
				tbbNew[2].fsStyle = TBSTYLE_CHECK;
				tbbNew[2].dwData = 0;
				tbbNew[2].iString = -1;

				tbbNew[3].iBitmap = 0;
				tbbNew[3].idCommand = 0;
				tbbNew[3].fsState = 0;
				tbbNew[3].fsStyle = TBSTYLE_SEP;
				tbbNew[3].dwData = 0;
				tbbNew[3].iString = -1;
			
				tbbNew[4].iBitmap = _itbmPgpKeys;
				tbbNew[4].idCommand = _cmdidPgpKeys;
				tbbNew[4].fsState = TBSTATE_ENABLED;
				tbbNew[4].fsStyle = TBSTYLE_BUTTON;
				tbbNew[4].dwData = 0;
				tbbNew[4].iString = -1;
			
				SendMessage(_hwndSendToolbar, TB_ADDBUTTONS, 5, 
					(LPARAM) tbbNew);
			}
		}
		break;

    case EECONTEXT_SENDPOSTMESSAGE:
		break;
    
	case EECONTEXT_READNOTEMESSAGE:
		{
			BOOL fAddButtons = TRUE;
			int nNumButtons;
			int nIndex;
			TBBUTTON tbbNew[5];
			TBBUTTON tbbCheck;
			BOOL FYEO;

			// Check to make sure the buttons aren't already on the toolbar

			nNumButtons = SendMessage(_hwndReadToolbar, TB_BUTTONCOUNT, 0, 0);
			for (nIndex=0; nIndex<nNumButtons; nIndex++)
			{
				SendMessage(_hwndReadToolbar, TB_GETBUTTON, 
							(WPARAM) nIndex, (LPARAM) &tbbCheck);

				// If a button exists with the same bitmap ID and command ID
				// as the Decrypt button, odds are good that the button is
				// already on the toolbar
				if ((tbbCheck.iBitmap == (int)_itbmDecrypt) && 
					(tbbCheck.idCommand == (int)_cmdidDecrypt))
				{
					fAddButtons = FALSE;
					nIndex = nNumButtons;
				}
			}

			if (fAddButtons)
			{
				tbbNew[0].iBitmap = 0;
				tbbNew[0].idCommand = 0;
				tbbNew[0].fsState = 0;
				tbbNew[0].fsStyle = TBSTYLE_SEP;
				tbbNew[0].dwData = 0;
				tbbNew[0].iString = -1;
			
				tbbNew[1].iBitmap = _itbmDecrypt;
				tbbNew[1].idCommand = _cmdidDecrypt;
				tbbNew[1].fsState = TBSTATE_ENABLED;
				tbbNew[1].fsStyle = TBSTYLE_BUTTON;
				tbbNew[1].dwData = 0;
				tbbNew[1].iString = -1;
			
				tbbNew[2].iBitmap = 0;
				tbbNew[2].idCommand = 0;
				tbbNew[2].fsState = 0;
				tbbNew[2].fsStyle = TBSTYLE_SEP;
				tbbNew[2].dwData = 0;
				tbbNew[2].iString = -1;
			
				tbbNew[3].iBitmap = _itbmPgpKeys;
				tbbNew[3].idCommand = _cmdidPgpKeys;
				tbbNew[3].fsState = TBSTATE_ENABLED;
				tbbNew[3].fsStyle = TBSTYLE_BUTTON;
				tbbNew[3].dwData = 0;
				tbbNew[3].iString = -1;
			
				SendMessage(_hwndReadToolbar, TB_ADDBUTTONS, 4, 
					(LPARAM) tbbNew);
			}

			IMAPISession* psess;

			HRESULT hr = peecb->GetSession(&psess, NULL);
			if (FAILED(hr))
			{
				UIDisplayStringID(hwnd, IDS_E_NOSESSION);
				return S_FALSE;
			}
			
			if (AutoDecrypt(_memoryMgr))
			{
				IMessage *pmsg = 0;
				STATSTG StreamStats;
				DWORD dwInSize;
				UINT nOutSize;
				char *pInput;
				char *pOutput = NULL;
				BOOL bGotHTML = FALSE;
				PGPError nError = kPGPError_NoErr;
				char szFile[256];
				char szName[256];

				UIGetString(szName, sizeof(szName), IDS_LOGNAME);
				UIGetString(szFile, sizeof(szFile), IDS_DLL);
				
				CWaitCursor wait; // Mark busy
				
				hr = peecb->GetObject(NULL, (IMAPIProp**)&pmsg);
				if (FAILED(hr))
				{
					return S_FALSE;
				}
				
				IStream *pstrmBody = 0;

				hr = pmsg->OpenProperty(PR_BODY_HTML, &IID_IStream, 
					STGM_READWRITE, MAPI_MODIFY, (IUnknown**)&pstrmBody);
				
				if (FAILED(hr))
				{
					hr = pmsg->OpenProperty(PR_BODY, &IID_IStream, 
						STGM_READWRITE, MAPI_MODIFY, (IUnknown**)&pstrmBody);
				}
				else
					bGotHTML = TRUE;

				if (FAILED(hr))
				{
					pmsg->Release();
					psess->Release();
					return S_FALSE;
				}
				
				pstrmBody->Stat(&StreamStats, STATFLAG_NONAME);
				dwInSize = StreamStats.cbSize.LowPart;
				
				pInput = (char *) calloc(dwInSize+1, sizeof(char));
				if (!pInput)
				{
					UIDisplayStringID(hwnd, IDS_E_NOMEMORY);
					pstrmBody->Release();
					pmsg->Release();
					psess->Release();
					return S_FALSE;
				}
				pstrmBody->Read(pInput, dwInSize, &dwInSize);
				pInput[dwInSize] = 0;
				
				if (AutoDecrypt(_memoryMgr))
				{
					nError = DecryptVerifyBuffer(UIGetInstance(), hwnd, 
								_pgpContext, _tlsContext, szName, 
								szFile, pInput, dwInSize, 
								FALSE, (VOID ** )&pOutput, &nOutSize, &FYEO);

					if (IsntPGPError(nError) && (nOutSize > 0) && 
						(pOutput != NULL))
					{
						LARGE_INTEGER li = {0,0};
						ULARGE_INTEGER uli = {nOutSize, 0};
						BOOL fPartied;
						char *szBuffer = NULL;
						
						// Alter only the block of encrypted/signed text
						// if this is not HTML

						if((FYEO)||(GetSecureViewerPref(_pgpContext)))
						{
							TempestViewer((void *)_pgpContext,hwnd,
								pOutput,nOutSize,FYEO);
						}
						else
						{
							szBuffer = (char *) calloc(dwInSize+nOutSize+1, 
													sizeof(char));

							strcpy(szBuffer, pOutput);

							if (strlen(szBuffer) > 0)
							{
								uli.LowPart = strlen(szBuffer);
								pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
								pstrmBody->Write(szBuffer, strlen(szBuffer), 
											NULL);
								pstrmBody->SetSize(uli);
								pstrmBody->Commit(STGC_DEFAULT);
								pstrmBody->Release();
								RTFSync(pmsg, RTF_SYNC_BODY_CHANGED, 
									&fPartied);
							}
	
							free(szBuffer);
						}

						PGPFreeData(pOutput);
					}
					else
						pstrmBody->Release();
				}
				else
					pstrmBody->Release();

				free(pInput);
				pmsg->Release();
			}
			
			psess->Release();
		}
		break;

	case EECONTEXT_READPOSTMESSAGE:
		break;

	default:
		// This way, the function defends itself against unknown future
		// variants, as FindREOnNote is less robust than it might be.
		return S_FALSE;
	}

	return S_FALSE;
}