void CJabberProto::IqResultProxyDiscovery( HXML iqNode, CJabberIqInfo* pInfo )
{
	JABBER_BYTE_TRANSFER *jbt = ( JABBER_BYTE_TRANSFER * )pInfo->GetUserData();

	if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) {
		HXML queryNode = xmlGetChild( iqNode , "query" );
		if ( queryNode ) {
			const TCHAR *queryXmlns = xmlGetAttrValue( queryNode, _T( "xmlns" ));
			if (queryXmlns && !_tcscmp( queryXmlns, _T(JABBER_FEAT_BYTESTREAMS))) {
				HXML streamHostNode = xmlGetChild( queryNode , "streamhost" );
				if ( streamHostNode ) {
					const TCHAR *streamJid = xmlGetAttrValue( streamHostNode, _T( "jid" ));
					const TCHAR *streamHost = xmlGetAttrValue( streamHostNode, _T( "host" ));
					const TCHAR *streamPort = xmlGetAttrValue( streamHostNode, _T( "port" ));
					if ( streamJid && streamHost && streamPort ) {
						jbt->szProxyHost = mir_tstrdup( streamHost );
						jbt->szProxyJid = mir_tstrdup( streamJid );
						jbt->szProxyPort = mir_tstrdup( streamPort );
						jbt->bProxyDiscovered = TRUE;
	}	}	}	}	}
	else if ( pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR )
		jbt->state = JBT_ERROR;

	if ( jbt->hProxyEvent )
		SetEvent( jbt->hProxyEvent );
}
BOOL CJabberProto::OnIqHttpAuth(HXML node, CJabberIqInfo *pInfo)
{
	if (!m_options.AcceptHttpAuth)
		return TRUE;

	if (!node || !pInfo->GetChildNode() || !pInfo->GetFrom() || !pInfo->GetIdStr())
		return TRUE;

	HXML pConfirm = xmlGetChild(node , "confirm");
	if (!pConfirm)
		return TRUE;

	const TCHAR *szId = xmlGetAttrValue(pConfirm, _T("id"));
	const TCHAR *szMethod = xmlGetAttrValue(pConfirm, _T("method"));
	const TCHAR *szUrl = xmlGetAttrValue(pConfirm, _T("url"));
	if (!szId || !szMethod || !szUrl)
		return TRUE;

	CJabberHttpAuthParams *pParams = (CJabberHttpAuthParams*)mir_calloc(sizeof(CJabberHttpAuthParams));
	if (pParams) {
		pParams->m_nType = CJabberHttpAuthParams::IQ;
		pParams->m_szFrom = mir_tstrdup(pInfo->GetFrom());
		pParams->m_szId = mir_tstrdup(szId);
		pParams->m_szMethod = mir_tstrdup(szMethod);
		pParams->m_szUrl = mir_tstrdup(szUrl);
		AddClistHttpAuthEvent(pParams);
	}
	return TRUE;
}
BOOL CJabberIqManager::HandleIqPermanent(HXML pNode)
{
	mir_cslock lck(m_cs);
	CJabberIqPermanentInfo *pInfo = m_pPermanentHandlers;
	while (pInfo) {
		// have to get all data here, in the loop, because there's always possibility that previous handler modified it
		const TCHAR *szType = xmlGetAttrValue(pNode, _T("type"));
		if (!szType)
			return FALSE;

		CJabberIqInfo iqInfo;
		iqInfo.m_nIqType = JABBER_IQ_TYPE_FAIL;
		if (!_tcsicmp(szType, _T("get")))
			iqInfo.m_nIqType = JABBER_IQ_TYPE_GET;
		else if (!_tcsicmp(szType, _T("set")))
			iqInfo.m_nIqType = JABBER_IQ_TYPE_SET;
		else
			return FALSE;

		if (pInfo->m_nIqTypes & iqInfo.m_nIqType) {
			HXML pFirstChild = xmlGetChild(pNode , 0);
			if (!pFirstChild || !xmlGetName(pFirstChild))
				return FALSE;

			const TCHAR *szTagName = xmlGetName(pFirstChild);
			const TCHAR *szXmlns = xmlGetAttrValue(pFirstChild, _T("xmlns"));

			if ((!pInfo->m_szXmlns || (szXmlns && !_tcscmp(pInfo->m_szXmlns, szXmlns))) &&
			    (!pInfo->m_szTag || !_tcscmp(pInfo->m_szTag, szTagName)))
			{
				// node suits handler criteria, call the handler
				iqInfo.m_pChildNode = pFirstChild;
				iqInfo.m_szChildTagName = (TCHAR*)szTagName;
				iqInfo.m_szChildTagXmlns = (TCHAR*)szXmlns;
				iqInfo.m_szId = (TCHAR*)xmlGetAttrValue(pNode, _T("id"));
				iqInfo.m_pUserData = pInfo->m_pUserData;

				if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_TO)
					iqInfo.m_szTo = (TCHAR*)xmlGetAttrValue(pNode, _T("to"));

				if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_FROM)
					iqInfo.m_szFrom = (TCHAR*)xmlGetAttrValue(pNode, _T("from"));

				if ((pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_HCONTACT) && (iqInfo.m_szFrom))
					iqInfo.m_hContact = ppro->HContactFromJID(iqInfo.m_szFrom, 3);

				ppro->debugLogA("Handling iq id %S, type %S, from %S", iqInfo.m_szId, szType, iqInfo.m_szFrom);
				if ((ppro->*(pInfo->m_pHandler))(pNode, &iqInfo))
					return TRUE;
			}
		}

		pInfo = pInfo->m_pNext;
	}

	return FALSE;
}
Exemple #4
0
void CJabberProto::OnIqResultGetCollection(HXML iqNode, CJabberIqInfo*)
{
	if ( mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result")))
		return;

	HXML chatNode = xmlGetChild(iqNode, "chat");
	if (!chatNode || mir_tstrcmp( xmlGetAttrValue(chatNode, _T("xmlns")), JABBER_FEAT_ARCHIVE))
		return;

	const TCHAR* start = xmlGetAttrValue(chatNode, _T("start"));
	const TCHAR* with  = xmlGetAttrValue(chatNode, _T("with"));
	if (!start || !with)
		return;

	MCONTACT hContact = HContactFromJID(with);
	time_t tmStart = str2time(start);
	if (hContact == 0 || tmStart == 0)
		return;

	_tzset();

	for (int nodeIdx = 0; ; nodeIdx++) {
		HXML itemNode = xmlGetChild(chatNode, nodeIdx);
		if (!itemNode)
			break;

		int from;
		const TCHAR *itemName = xmlGetName(itemNode);
		if (!mir_tstrcmp(itemName, _T("to")))
			from = DBEF_SENT;
		else if (!mir_tstrcmp(itemName, _T("from")))
			from = 0;
		else
			continue;

		HXML body = xmlGetChild(itemNode, "body");
		if (!body)
			continue;

		const TCHAR *tszBody = xmlGetText(body);
		const TCHAR *tszSecs = xmlGetAttrValue(itemNode, _T("secs"));
		if (!tszBody || !tszSecs)
			continue;

		ptrA szEventText( mir_utf8encodeT(tszBody));

		DBEVENTINFO dbei = { sizeof(DBEVENTINFO) };
		dbei.eventType = EVENTTYPE_MESSAGE;
		dbei.szModule = m_szModuleName;
		dbei.cbBlob = (DWORD)strlen(szEventText);
		dbei.flags = DBEF_READ + DBEF_UTF + from;
		dbei.pBlob = (PBYTE)(char*)szEventText;
		dbei.timestamp = tmStart + _ttol(tszSecs) - timezone;
		if (!IsDuplicateEvent(hContact, dbei))
			db_event_add(hContact, &dbei);
	}
}
BOOL CJabberProto::OnMessageIbb(HXML, ThreadData*, CJabberMessageInfo* pInfo)
{
	BOOL bOk = FALSE;
	const TCHAR *sid = xmlGetAttrValue(pInfo->GetChildNode(), _T("sid"));
	const TCHAR *seq = xmlGetAttrValue(pInfo->GetChildNode(), _T("seq"));
	if (sid && seq && xmlGetText(pInfo->GetChildNode()))
		bOk = OnIbbRecvdData(xmlGetText(pInfo->GetChildNode()), sid, seq);

	return TRUE;
}
Exemple #6
0
BOOL CJabberIqManager::HandleIq(int nIqId, HXML pNode )
{
	if (nIqId == -1 || pNode == NULL)
		return FALSE;

	const TCHAR *szType = xmlGetAttrValue( pNode, _T("type"));
	if ( !szType )
		return FALSE;

	int nIqType = JABBER_IQ_TYPE_FAIL;
	if (!_tcsicmp(szType, _T("result")))
		nIqType = JABBER_IQ_TYPE_RESULT;
	else if (!_tcsicmp(szType, _T("error")))
		nIqType = JABBER_IQ_TYPE_ERROR;
	else
		return FALSE;

	Lock();
	CJabberIqInfo* pInfo = DetachInfo(nIqId);
	Unlock();
	if (pInfo)
	{
		pInfo->m_nIqType = nIqType;
		if (nIqType == JABBER_IQ_TYPE_RESULT) {
			if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_CHILD_TAG_NODE)
				pInfo->m_pChildNode = xmlGetChild( pNode , 0 );
			
			if (pInfo->m_pChildNode && (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_CHILD_TAG_NAME))
				pInfo->m_szChildTagName = ( TCHAR* )xmlGetName( pInfo->m_pChildNode );
			if (pInfo->m_pChildNode && (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_CHILD_TAG_XMLNS))
				pInfo->m_szChildTagXmlns = ( TCHAR* )xmlGetAttrValue( pNode, _T("xmlns"));
		}

		if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_TO)
			pInfo->m_szTo = ( TCHAR* )xmlGetAttrValue( pNode, _T("to"));

		if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_FROM)
			pInfo->m_szFrom = ( TCHAR* )xmlGetAttrValue( pNode, _T("from"));
		if (pInfo->m_szFrom && (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_HCONTACT))
			pInfo->m_hContact = ppro->HContactFromJID( pInfo->m_szFrom, 3 );

		if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_ID_STR)
			pInfo->m_szId = ( TCHAR* )xmlGetAttrValue( pNode, _T("id"));

		(ppro->*(pInfo->m_pHandler))(pNode, pInfo);
		delete pInfo;
		return TRUE;
	}
	return FALSE;
}
void CJabberProto::ByteInitiateResult( HXML iqNode, CJabberIqInfo* pInfo )
{
	JABBER_BYTE_TRANSFER *jbt = ( JABBER_BYTE_TRANSFER * )pInfo->GetUserData();

	if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) {
		HXML queryNode = xmlGetChild( iqNode , "query" );
		if ( queryNode ) {
			const TCHAR* queryXmlns = xmlGetAttrValue( queryNode, _T("xmlns"));
			if ( queryXmlns && !_tcscmp( queryXmlns, _T( JABBER_FEAT_BYTESTREAMS ))) {
				HXML streamHostNode = xmlGetChild( queryNode ,  "streamhost-used" );
				if ( streamHostNode ) {
					const TCHAR* streamJid = xmlGetAttrValue( streamHostNode, _T("jid"));
					if ( streamJid )
						jbt->szStreamhostUsed = mir_tstrdup( streamJid );
	}	}	}	}

	if ( jbt->hProxyEvent )
		SetEvent( jbt->hProxyEvent );
}
Exemple #8
0
XmlNodeIq::XmlNodeIq(const TCHAR *type, HXML node, LPCTSTR to) :
    XmlNode(_T("iq"))
{
    if (type  != NULL) *this << XATTR(_T("type"), type );
    if (to    != NULL) *this << XATTR(_T("to"),   to   );
    if (node  != NULL) {
        const TCHAR *iqId = xmlGetAttrValue(*this, _T("id"));
        if (iqId != NULL) *this << XATTR(_T("id"), iqId);
    }
}
Exemple #9
0
void CJabberProto::OnIqResultGetCollectionList(HXML iqNode, CJabberIqInfo*)
{
	const TCHAR *to = xmlGetAttrValue(iqNode, _T("to"));
	if (to == NULL || mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result")))
		return;

	HXML list = xmlGetChild(iqNode, "list");
	if (!list || mir_tstrcmp( xmlGetAttrValue(list, _T("xmlns")), JABBER_FEAT_ARCHIVE))
		return;

	MCONTACT hContact = NULL;
	time_t tmLast = 0;

	for (int nodeIdx = 1; ; nodeIdx++) {
		HXML itemNode = xmlGetNthChild(list, _T("chat"), nodeIdx);
		if (!itemNode)
			break;

		const TCHAR* start = xmlGetAttrValue(itemNode, _T("start"));
		const TCHAR* with  = xmlGetAttrValue(itemNode, _T("with"));
		if (!start || !with)
			continue;

		if (hContact == NULL) {
			if ((hContact = HContactFromJID(with)) == NULL)
				continue;

			tmLast = getDword(hContact, "LastCollection", 0);
		}

		m_ThreadInfo->send(
			XmlNodeIq( AddIQ(&CJabberProto::OnIqResultGetCollection, JABBER_IQ_TYPE_GET))
				<< XCHILDNS( _T("retrieve"), JABBER_FEAT_ARCHIVE) << XATTR(_T("with"), with) << XATTR(_T("start"), start));

		time_t tmThis = str2time(start);
		if ( tmThis > tmLast) {
			tmLast = tmThis;
			setDword(hContact, "LastCollection", tmLast+1);
		}
	}
}
Exemple #10
0
void CJabberProto::OnIqResultGetMuc( HXML iqNode )
{
	HXML queryNode, xNode;
	const TCHAR *type, *from, *str;

	// RECVED: room config form
	// ACTION: show the form
	Log( "<iq/> iqIdGetMuc" );
	if (( type = xmlGetAttrValue( iqNode, _T("type"))) == NULL ) return;
	if (( from = xmlGetAttrValue( iqNode, _T("from"))) == NULL ) return;

	if ( !_tcscmp( type, _T("result"))) {
		if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) {
			str = xmlGetAttrValue( queryNode, _T("xmlns"));
			if ( !lstrcmp( str, _T("http://jabber.org/protocol/muc#owner" ))) {
				if (( xNode = xmlGetChild( queryNode , "x" )) != NULL ) {
					str = xmlGetAttrValue( xNode, _T("xmlns"));
					if ( !lstrcmp( str, _T(JABBER_FEAT_DATA_FORMS)))
						//LaunchForm(xNode);
						FormCreateDialog( xNode, _T("Jabber Conference Room Configuration"), &CJabberProto::SetMucConfig, mir_tstrdup( from ));
}	}	}	}	}
	void OnSubmit(CCtrlButton*)
	{
		HXML queryNode, xNode;
		const TCHAR *from;

		if (m_agentRegIqNode == NULL) return;
		if ((from = xmlGetAttrValue(m_agentRegIqNode, _T("from"))) == NULL) return;
		if ((queryNode = xmlGetChild(m_agentRegIqNode ,  "query")) == NULL) return;
		HWND hFrame = GetDlgItem(m_hwnd, IDC_FRAME);

		TCHAR *str2 = (TCHAR*)alloca(sizeof(TCHAR) * 128);
		int id = 0;

		XmlNodeIq iq( m_proto->AddIQ(&CJabberProto::OnIqResultSetRegister, JABBER_IQ_TYPE_SET, from));
		HXML query = iq << XQUERY(JABBER_FEAT_REGISTER);

		if ((xNode = xmlGetChild(queryNode , "x")) != NULL) {
			// use new jabber:x:data form
			HXML n = JabberFormGetData(hFrame, xNode);
			xmlAddChild(query, n);
			xi.destroyNode(n);
		}
		else {
			// use old registration information form
			for (int i=0; ; i++) {
				HXML n = xmlGetChild(queryNode ,i);
				if (!n)
					break;

				if (xmlGetName(n)) {
					if (!lstrcmp(xmlGetName(n), _T("key"))) {
						// field that must be passed along with the registration
						if (xmlGetText(n))
							xmlAddChild(query, xmlGetName(n), xmlGetText(n));
						else
							xmlAddChild(query, xmlGetName(n));
					}
					else if (!lstrcmp(xmlGetName(n), _T("registered")) || !lstrcmp(xmlGetName(n), _T("instructions"))) {
						// do nothing, we will skip these
					}
					else {
						GetDlgItemText(hFrame, id, str2, 128);
						xmlAddChild(query, xmlGetName(n), str2);
						id++;
		}	}	}	}

		m_proto->m_ThreadInfo->send(iq);

		CAgentRegProgressDlg(m_proto, m_hwnd).DoModal();

		Close();
	}
Exemple #12
0
BOOL CJabberProto::OnFtHandleIbbIq( HXML iqNode, CJabberIqInfo* pInfo )
{
	if ( !_tcscmp( pInfo->GetChildNodeName(), _T("open")))
		FtHandleIbbRequest( iqNode, TRUE );
	else if ( !_tcscmp( pInfo->GetChildNodeName(), _T("close")))
		FtHandleIbbRequest( iqNode, FALSE );
	else if ( !_tcscmp( pInfo->GetChildNodeName(), _T("data"))) {
		BOOL bOk = FALSE;
		const TCHAR *sid = xmlGetAttrValue( pInfo->GetChildNode(), _T("sid"));
		const TCHAR *seq = xmlGetAttrValue( pInfo->GetChildNode(), _T("seq"));
		if ( sid && seq && xmlGetText( pInfo->GetChildNode()))
			bOk = OnIbbRecvdData( xmlGetText( pInfo->GetChildNode()), sid, seq );

		if ( bOk )
			m_ThreadInfo->send( XmlNodeIq( _T("result"), pInfo ));
		else
			m_ThreadInfo->send( 
				XmlNodeIq( _T("error"), pInfo ) 
					<< XCHILD( _T("error")) << XATTRI( _T("code"), 404 ) << XATTR( _T("type"), _T("cancel"))
						<< XCHILDNS( _T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
	}
	return TRUE;
}
BOOL CJabberProto::OnSiRequest(HXML node, CJabberIqInfo *pInfo)
{
	const TCHAR *szProfile = xmlGetAttrValue(pInfo->GetChildNode(), _T("profile"));

	if (szProfile && !_tcscmp(szProfile, JABBER_FEAT_SI_FT))
		FtHandleSiRequest(node);
	else {
		XmlNodeIq iq(_T("error"), pInfo);
		HXML error = iq << XCHILD(_T("error")) << XATTRI(_T("code"), 400) << XATTR(_T("type"), _T("cancel"));
		error << XCHILDNS(_T("bad-request"), _T("urn:ietf:params:xml:ns:xmpp-stanzas"));
		error << XCHILD(_T("bad-profile"));
		m_ThreadInfo->send(iq);
	}
	return TRUE;
}
Exemple #14
0
void CJabberProto::OnIqResultMucGetJidList( HXML iqNode, JABBER_MUC_JIDLIST_TYPE listType )
{
	const TCHAR* type;
	JABBER_MUC_JIDLIST_INFO *jidListInfo;

	if (( type = xmlGetAttrValue( iqNode, _T("type"))) == NULL ) return;

	if ( !lstrcmp( type, _T("result" ))) {
		if (( jidListInfo = new JABBER_MUC_JIDLIST_INFO ) != NULL ) {
			jidListInfo->type = listType;
			jidListInfo->ppro = this;
			jidListInfo->roomJid = NULL;	// Set in the dialog procedure
			if (( jidListInfo->iqNode = xi.copyNode( iqNode )) != NULL )
				CallFunctionAsync( JabberMucJidListCreateDialogApcProc, jidListInfo );
			else
				mir_free( jidListInfo );
}	}	}
Exemple #15
0
void CJabberProto::IqResultStreamActivate( HXML iqNode )
{
	int id = JabberGetPacketID( iqNode );

	TCHAR listJid[JABBER_MAX_JID_LEN];
	mir_sntprintf(listJid, SIZEOF( listJid ), _T("ftproxy_%d"), id);

	JABBER_LIST_ITEM *item = ListGetItemPtr( LIST_FTIQID, listJid );
	if ( !item )
		return;

	if ( !lstrcmp( xmlGetAttrValue( iqNode, _T("type")), _T( "result" )))
		item->jbt->bStreamActivated = TRUE;

	if ( item->jbt->hProxyEvent )
		SetEvent( item->jbt->hProxyEvent );
}
Exemple #16
0
static void CALLBACK JabberMucJidListCreateDialogApcProc( void* param )
{
	HXML iqNode, queryNode;
	const TCHAR* from;
	HWND *pHwndJidList;
	JABBER_MUC_JIDLIST_INFO *jidListInfo = (JABBER_MUC_JIDLIST_INFO *)param;

	if ( jidListInfo == NULL )                                     return;
	if (( iqNode = jidListInfo->iqNode ) == NULL )                 return;
	if (( from = xmlGetAttrValue( iqNode, _T("from"))) == NULL )   return;
	if (( queryNode = xmlGetChild( iqNode , "query" )) == NULL )   return;

	CJabberProto* ppro = jidListInfo->ppro;
	switch ( jidListInfo->type ) {
	case MUC_VOICELIST:
		pHwndJidList = &ppro->m_hwndMucVoiceList;
		break;
	case MUC_MEMBERLIST:
		pHwndJidList = &ppro->m_hwndMucMemberList;
		break;
	case MUC_MODERATORLIST:
		pHwndJidList = &ppro->m_hwndMucModeratorList;
		break;
	case MUC_BANLIST:
		pHwndJidList = &ppro->m_hwndMucBanList;
		break;
	case MUC_ADMINLIST:
		pHwndJidList = &ppro->m_hwndMucAdminList;
		break;
	case MUC_OWNERLIST:
		pHwndJidList = &ppro->m_hwndMucOwnerList;
		break;
	default:
		mir_free( jidListInfo );
		return;
	}

	if ( *pHwndJidList!=NULL && IsWindow( *pHwndJidList )) {
		SetForegroundWindow( *pHwndJidList );
		SendMessage( *pHwndJidList, WM_JABBER_REFRESH, 0, ( LPARAM )jidListInfo );
	}
	else *pHwndJidList = CreateDialogParam( hInst, MAKEINTRESOURCE( IDD_JIDLIST ), GetForegroundWindow(), JabberMucJidListDlgProc, ( LPARAM )jidListInfo );
}
void CJabberProto::OnIqResultCapsDiscoInfo(HXML, CJabberIqInfo *pInfo)
{
	pResourceStatus r(ResourceInfoFromJID(pInfo->GetFrom()));

	HXML query = pInfo->GetChildNode();
	if (pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT && query) {
		JabberCapsBits jcbCaps = 0;
		HXML feature;
		for (int i = 1; (feature = xmlGetNthChild(query, _T("feature"), i)) != NULL; i++) {
			const TCHAR *featureName = xmlGetAttrValue(feature, _T("var"));
			if (!featureName)
				continue;

			for (int j = 0; g_JabberFeatCapPairs[j].szFeature; j++) {
				if (!_tcscmp(g_JabberFeatCapPairs[j].szFeature, featureName)) {
					jcbCaps |= g_JabberFeatCapPairs[j].jcbCap;
					break;
				}
			}
		}

		// no version info support and no XEP-0115 support?
		if (r && r->m_dwVersionRequestTime == -1 && !r->m_tszSoftwareVersion && !r->m_tszSoftware && !r->m_tszCapsNode) {
			r->m_jcbCachedCaps = jcbCaps;
			r->m_dwDiscoInfoRequestTime = -1;
			return;
		}

		if (r && !m_clientCapsManager.SetClientCaps(pInfo->GetIqId(), jcbCaps))
			r->m_jcbCachedCaps = jcbCaps;

		JabberUserInfoUpdate(pInfo->GetHContact());
	}
	else {
		// no version info support and no XEP-0115 support?
		if (r && r->m_dwVersionRequestTime == -1 && !r->m_tszSoftwareVersion && !r->m_tszSoftware && !r->m_tszCapsNode) {
			r->m_jcbCachedCaps = JABBER_RESOURCE_CAPS_NONE;
			r->m_dwDiscoInfoRequestTime = -1;
		}
		else m_clientCapsManager.SetClientCaps(pInfo->GetIqId(), JABBER_RESOURCE_CAPS_ERROR);
	}
}
BOOL CJabberProto::OnHandleDiscoInfoRequest(HXML iqNode, CJabberIqInfo *pInfo)
{
	if (!pInfo->GetChildNode())
		return TRUE;

	const TCHAR *szNode = xmlGetAttrValue(pInfo->GetChildNode(), _T("node"));
	// caps hack
	if (m_clientCapsManager.HandleInfoRequest(iqNode, pInfo, szNode))
		return TRUE;

	// ad-hoc hack:
	if (szNode && m_adhocManager.HandleInfoRequest(iqNode, pInfo, szNode))
		return TRUE;

	// another request, send empty result
	m_ThreadInfo->send(
		XmlNodeIq(_T("error"), pInfo)
			<< XCHILD(_T("error")) << XATTRI(_T("code"), 404) << XATTR(_T("type"), _T("cancel"))
				<< XCHILDNS(_T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
	return TRUE;
}
BOOL CJabberProto::OnHandleDiscoItemsRequest(HXML iqNode, CJabberIqInfo *pInfo)
{
	if (!pInfo->GetChildNode())
		return TRUE;

	// ad-hoc commands check:
	const TCHAR *szNode = xmlGetAttrValue(pInfo->GetChildNode(), _T("node"));
	if (szNode && m_adhocManager.HandleItemsRequest(iqNode, pInfo, szNode))
		return TRUE;

	// another request, send empty result
	XmlNodeIq iq(_T("result"), pInfo);
	HXML resultQuery = iq << XQUERY(JABBER_FEAT_DISCO_ITEMS);
	if (szNode)
		xmlAddAttr(resultQuery, _T("node"), szNode);

	if (!szNode && m_options.EnableRemoteControl)
		resultQuery << XCHILD(_T("item")) << XATTR(_T("jid"), m_ThreadInfo->fullJID)
			<< XATTR(_T("node"), JABBER_FEAT_COMMANDS) << XATTR(_T("name"), _T("Ad-hoc commands"));

	m_ThreadInfo->send(iq);
	return TRUE;
}
Exemple #20
0
INT_PTR CSkypeProto::GetCallEventText(WPARAM, LPARAM lParam)
{
	DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam;

	INT_PTR nRetVal = 0;

	ptrA pszText;
	
	switch (pEvent->dbei->eventType)
	{
	case SKYPE_DB_EVENT_TYPE_CALL_INFO:
		{
			CMStringA text;
			HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("partlist"));
			if (xml != NULL)
			{
				ptrA type(mir_t2a(xmlGetAttrValue(xml, _T("type"))));
				bool bType = (!mir_strcmpi(type, "started")) ? 1 : 0;

				for (int i = 0; i < xmlGetChildCount(xml); i++)
				{
					HXML xmlPart = xmlGetNthChild(xml, _T("part"), i);
					if (xmlPart != NULL)
					{
						HXML xmlName = xmlGetChildByPath(xmlPart, _T("name"), 0);
						if (xmlName != NULL)
						{
							text.AppendFormat(Translate("%s %s this call.\n"), _T2A(xmlGetText(xmlName)), bType ? Translate("enters") : Translate("leaves"));
							xmlDestroyNode(xmlName);
						}
						xmlDestroyNode(xmlPart);
					}
				}
				xmlDestroyNode(xml);
			}
			pszText = mir_strdup(text.GetBuffer());
			break;
		}
	case SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO:
		{
			CMStringA text;
			HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("files"));
			if (xml != NULL)
			{
				for (int i = 0; i < xmlGetChildCount(xml); i++)
				{
					size_t fileSize = 0;
					HXML xmlNode = xmlGetNthChild(xml, _T("file"), i);
					if (xmlNode != NULL)
					{
						fileSize = _ttoi(ptrT((TCHAR*)xmlGetAttrValue(xmlNode, _T("size"))));
						ptrA fileName(mir_utf8encodeT(ptrT((TCHAR*)xmlGetText(xmlNode))));
						if (fileName != NULL)
						{
							CMStringA msg(FORMAT, Translate("File transfer:\n\tFile name: %s\n\tSize: %d bytes"), fileName, fileSize);
							text.AppendFormat("%s\n", msg);
						}

						xmlDestroyNode(xmlNode);
					}
				}
				xmlDestroyNode(xml);
			}
			pszText = mir_strdup(text.GetBuffer());
			break;
		}
	case SKYPE_DB_EVENT_TYPE_URIOBJ:
		{
			CMStringA text;
			HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("URIObject"));
			if (xml != NULL)
			{
				text.Append(_T2A(xmlGetText(xml)));
				xmlDestroyNode(xml);
			}
			pszText = mir_strdup(text.GetBuffer());
			break;

		}
	case SKYPE_DB_EVENT_TYPE_INCOMING_CALL:
		{
			pszText = Translate("Incoming call.");
			break;
		}
	default:
		{
			pszText = mir_strdup((char*)pEvent->dbei->pBlob);
		}
	}


	if (pEvent->datatype == DBVT_TCHAR)
	{
		TCHAR *pwszText = _A2T(pszText);
		nRetVal = (INT_PTR)mir_tstrdup(pwszText);
	}
	else if (pEvent->datatype == DBVT_ASCIIZ)
		nRetVal = (INT_PTR)mir_strdup(pszText);

	return nRetVal;
}
void CJabberProto::OnIqResultDiscovery(HXML iqNode, CJabberIqInfo *pInfo)
{
	if (!iqNode || !pInfo)
		return;

	HWND hwndList = (HWND)pInfo->GetUserData();
	SendMessage(hwndList, CB_SHOWDROPDOWN, FALSE, 0);
	SendMessage(hwndList, CB_RESETCONTENT, 0, 0);

	if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT )
	{
		HXML query = xmlGetChild( iqNode , "query" );
		if ( !query )
		{
			sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
				TranslateT("Jabber Error"),
				TranslateT("Failed to retrieve room list from server."),
				_T(""));
		} else
		{
			bool found = false;
			HXML item;
			for ( int i = 1; item = xmlGetNthChild( query, _T("item"), i ); i++ )
			{
				const TCHAR *jid = xmlGetAttrValue( item, _T("jid"));
				TCHAR *name = NEWTSTR_ALLOCA(jid);
				if (name)
				{
					if (TCHAR *p = _tcschr(name, _T('@')))
						*p = 0;
				} else
				{
					name = _T("");
				}

				sttRoomListAppend(hwndList,
					ListGetItemPtr(LIST_BOOKMARK, jid) ? RoomInfo::ROOM_BOOKMARK : RoomInfo::ROOM_DEFAULT,
					xmlGetAttrValue( item, _T("name")),
					jid, name);

				found = true;
			}

			if (!found)
			{
				sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
					TranslateT("Jabber Error"),
					TranslateT("No rooms available on server."),
					_T(""));
			}
		}
	} else
	if ( pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR )
	{
		HXML errorNode = xmlGetChild( iqNode , "error" );
		TCHAR* str = JabberErrorMsg( errorNode );
		sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
			TranslateT("Jabber Error"),
			str,
			_T(""));
		mir_free( str );
	} else
	{
		sttRoomListAppend(hwndList, RoomInfo::ROOM_FAIL,
			TranslateT("Jabber Error"),
			TranslateT("Room list request timed out."),
			_T(""));
	}

	SendMessage(hwndList, CB_SHOWDROPDOWN, TRUE, 0);
}
Exemple #22
0
LPCTSTR __fastcall XmlGetAttrValue(HXML hXml, LPCTSTR key)
{
	return xmlGetAttrValue(hXml, key);
}
Exemple #23
0
INT_PTR CSkypeProto::GetEventText(WPARAM, LPARAM lParam)
{
	DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam;

	CMStringA szText; 
	BOOL bUseBB = db_get_b(NULL, pEvent->dbei->szModule, "UseBBCodes", 1);
	switch (pEvent->dbei->eventType)
	{
	case SKYPE_DB_EVENT_TYPE_EDITED_MESSAGE:
		{
			
			JSONNode jMsg = JSONNode::parse((char*)pEvent->dbei->pBlob);
			if (jMsg)
			{
				JSONNode &jOriginalMsg = jMsg["original_message"];
				szText.AppendFormat(bUseBB ? Translate("[b]Original message:[/b]\n%s\n") : Translate("Original message:\n%s\n"), mir_utf8decodeA(jOriginalMsg["text"].as_string().c_str()));
				JSONNode &jEdits = jMsg["edits"];
				for (auto it = jEdits.begin(); it != jEdits.end(); ++it)
				{
					const JSONNode &jEdit = *it;

					time_t time = jEdit["time"].as_int();
					char szTime[MAX_PATH];
					strftime(szTime, sizeof(szTime), "%X %x", localtime(&time));

					szText.AppendFormat(bUseBB ? Translate("[b]Edited at %s:[/b]\n%s\n") : Translate("Edited at %s:\n%s\n"), szTime, mir_utf8decodeA(jEdit["text"].as_string().c_str()));
				}
				
			}
			else 
			{
				szText = INVALID_DATA;
			}
			break;
		}

	case SKYPE_DB_EVENT_TYPE_CALL_INFO:
		{
			HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("partlist"));
			if (xml != NULL)
			{
				ptrA type(mir_t2a(xmlGetAttrValue(xml, _T("type"))));
				bool bType = (!mir_strcmpi(type, "started")) ? 1 : 0;
				time_t callDuration = 0;

				for (int i = 0; i < xmlGetChildCount(xml); i++)
				{
					HXML xmlPart = xmlGetNthChild(xml, _T("part"), i);		
					if (xmlPart != NULL)
					{
						HXML xmlDuration = xmlGetChildByPath(xmlPart, _T("duration"), 0);
						
						if (xmlDuration != NULL)
						{
							callDuration = _ttol(xmlGetText(xmlDuration));
							xmlDestroyNode(xmlDuration);
							xmlDestroyNode(xmlPart);
							break;
						}
						xmlDestroyNode(xmlPart);
					}
				}

				if (bType)
				{
					szText = Translate("Call");
				}
				else 
				{
					if (callDuration == 0)
					{
						szText = Translate("Call missed");
					}
					else
					{
						char szTime[100];
						strftime(szTime, sizeof(szTime), "%X", gmtime(&callDuration));
						szText.Format(Translate("Call ended (%s)"), szTime);
					}
				}
				xmlDestroyNode(xml);
			}
			else
			{
				szText = INVALID_DATA;
			}
			break;
		}
	case SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO:
		{
			HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("files"));
			if (xml != NULL)
			{
				for (int i = 0; i < xmlGetChildCount(xml); i++)
				{
					LONGLONG fileSize = 0;
					HXML xmlNode = xmlGetNthChild(xml, _T("file"), i);
					if (xmlNode != NULL)
					{
						fileSize = _ttol(xmlGetAttrValue(xmlNode, _T("size")));
						char *fileName = _T2A(xmlGetText(xmlNode));
						if (fileName != NULL)
						{
							szText.AppendFormat(Translate("File transfer:\n\tFile name: %s \n\tSize: %lld bytes \n"), fileName, fileSize);
						}

						xmlDestroyNode(xmlNode);
					}
				}
				xmlDestroyNode(xml);
			}
			else
			{
				szText = INVALID_DATA;
			}
			break;
		}
	case SKYPE_DB_EVENT_TYPE_MOJI:
	case SKYPE_DB_EVENT_TYPE_URIOBJ:
		{
			HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("URIObject"));
			if (xml != NULL)
			{
				szText.Append(_T2A(xmlGetText(xml)));
				HXML xmlA = xmlGetChildByPath(xml, _T("a"), 0);
				if (xmlA != NULL)
				{
					szText += _T2A(xmlGetAttrValue(xmlA, _T("href")));
					xmlDestroyNode(xmlA);
				}
				xmlDestroyNode(xml);
			}
			else 
			{
				szText = INVALID_DATA;
			}
			break;

		}

	case SKYPE_DB_EVENT_TYPE_INCOMING_CALL:
		{
			szText = Translate("Incoming call");
			break;
		}
	case SKYPE_DB_EVENT_TYPE_UNKNOWN:
		{
			szText.Format(Translate("Unknown event, please send this text for developer: \"%s\""), mir_utf8decodeA((char*)pEvent->dbei->pBlob));
			break;
		}
	default:
		{
			szText = ptrA(mir_utf8decodeA((char*)pEvent->dbei->pBlob));
		}
	}

	switch(pEvent->datatype)
	{
	case DBVT_TCHAR:
		{
			return (INT_PTR)mir_a2t(szText);
		}
	case DBVT_ASCIIZ:
		{
			return (INT_PTR)szText.Detach();
		}
	case DBVT_UTF8:
		{
			return (INT_PTR)mir_utf8encode(szText);
		}
	default:
		{
			return NULL;
		}
	}
}
Exemple #24
0
BOOL CJabberMessageManager::HandleMessagePermanent(HXML node, ThreadData *pThreadData)
{
	BOOL bStopHandling = FALSE;
	Lock();
	CJabberMessagePermanentInfo *pInfo = m_pPermanentHandlers;
	while ( pInfo && !bStopHandling ) {
	// have to get all data here, in the loop, because there's always possibility that previous handler modified it
		CJabberMessageInfo messageInfo;

		LPCTSTR szType = xmlGetAttrValue(node, _T("type"));
		if ( szType )
		{
			if ( !_tcsicmp( szType, _T("normal")))
				messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL;
			else if ( !_tcsicmp( szType, _T("error")))
				messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_ERROR;
			else if ( !_tcsicmp( szType, _T("chat")))
				messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_CHAT;
			else if ( !_tcsicmp( szType, _T("groupchat")))
				messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_GROUPCHAT;
			else if ( !_tcsicmp( szType, _T("headline")))
				messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_HEADLINE;
			else
				break; // m_nMessageType = JABBER_MESSAGE_TYPE_FAIL;
		}
		else {
			messageInfo.m_nMessageType = JABBER_MESSAGE_TYPE_NORMAL;
		}

		if ( (pInfo->m_nMessageTypes & messageInfo.m_nMessageType )) {
			int i;
			for ( i = xmlGetChildCount( node ) - 1; i >= 0; i-- ) {
			// enumerate all children and see whether this node suits handler criteria
				HXML child = xmlGetChild( node, i );
				
				LPCTSTR szTagName = xmlGetName(child);
				LPCTSTR szXmlns = xmlGetAttrValue( child, _T("xmlns"));

				if ( (!pInfo->m_szXmlns || ( szXmlns && !_tcscmp( pInfo->m_szXmlns, szXmlns ))) &&
				( !pInfo->m_szTag || !_tcscmp( pInfo->m_szTag, szTagName ))) {
				// node suits handler criteria, call the handler
					messageInfo.m_hChildNode = child;
					messageInfo.m_szChildTagName = szTagName;
					messageInfo.m_szChildTagXmlns = szXmlns;
					messageInfo.m_pUserData = pInfo->m_pUserData;
					messageInfo.m_szFrom = xmlGetAttrValue( node, _T("from")); // is necessary for ppro->Log() below, that's why we must parse it even if JABBER_MESSAGE_PARSE_FROM flag is not set

					if (pInfo->m_dwParamsToParse & JABBER_MESSAGE_PARSE_ID_STR)
						messageInfo.m_szId = xmlGetAttrValue( node, _T("id"));

					if (pInfo->m_dwParamsToParse & JABBER_IQ_PARSE_TO)
						messageInfo.m_szTo = xmlGetAttrValue( node, _T("to"));

					if (pInfo->m_dwParamsToParse & JABBER_MESSAGE_PARSE_HCONTACT)
						messageInfo.m_hContact = ppro->HContactFromJID( messageInfo.m_szFrom, 3 );

					if (messageInfo.m_szFrom)
						ppro->Log( "Handling message from " TCHAR_STR_PARAM, messageInfo.m_szFrom );
					if ((ppro->*(pInfo->m_pHandler))(node, pThreadData, &messageInfo)) {
						bStopHandling = TRUE;
						break;
					}
				}
			}
		}
		pInfo = pInfo->m_pNext;
	}
	Unlock();

	return bStopHandling;
}
Exemple #25
0
void CJabberProto::OnIqResultAdvancedSearch( HXML iqNode )
{
	const TCHAR* type;
	int    id;

	U_TCHAR_MAP mColumnsNames(10);
	LIST<void>  SearchResults(2);

	if ((( id = JabberGetPacketID( iqNode )) == -1 ) || (( type = xmlGetAttrValue( iqNode, _T("type"))) == NULL )) {
		JSendBroadcast( NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, ( HANDLE ) id, 0 );
		return;
	}

	if ( !lstrcmp( type, _T("result"))) {
		HXML queryNode = xmlGetNthChild( iqNode, _T("query"), 1 );
		HXML xNode = xmlGetChildByTag( queryNode, "x", "xmlns", _T(JABBER_FEAT_DATA_FORMS));
		if (xNode) {
			//1. Form search results info
			HXML reportNode = xmlGetNthChild( xNode, _T("reported"), 1 );
			if (reportNode) {
				int i = 1;
				while ( HXML fieldNode = xmlGetNthChild( reportNode, _T("field"), i++ )) {
					TCHAR* var = ( TCHAR* )xmlGetAttrValue( fieldNode, _T( "var" ));
					if ( var ) {
						TCHAR* Label = ( TCHAR* )xmlGetAttrValue( fieldNode, _T( "label" ));
						mColumnsNames.insert(var, (Label!=NULL) ? Label : var);
			}	}	}

			int i=1;
			HXML itemNode;
			while ( itemNode = xmlGetNthChild( xNode, _T("item"), i++ )) {
				U_TCHAR_MAP *pUserColumn = new U_TCHAR_MAP(10);
				int j = 1;
				while ( HXML fieldNode = xmlGetNthChild( itemNode, _T("field"), j++ )) {
					if ( TCHAR* var = (TCHAR*)xmlGetAttrValue( fieldNode, _T("var"))) {
						if ( TCHAR* Text = (TCHAR*)xmlGetText( xmlGetChild( fieldNode, _T("value")))) {
							if ( !mColumnsNames[var] )
								mColumnsNames.insert(var,var);
							pUserColumn->insert(var,Text);
				}	}	}

				SearchResults.insert((void*)pUserColumn);
			}
		}
		else {
			//2. Field list search results info
			int i=1;
			while ( HXML itemNode = xmlGetNthChild( queryNode, _T("item"), i++ )) {
				U_TCHAR_MAP *pUserColumn=new U_TCHAR_MAP(10);
				
				TCHAR* jid = (TCHAR*)xmlGetAttrValue( itemNode, _T("jid"));
				TCHAR* keyReturned;
				mColumnsNames.insertCopyKey( _T("jid"),_T("jid"),&keyReturned, CopyKey, DestroyKey );
				mColumnsNames.insert( _T("jid"), keyReturned );
				pUserColumn->insertCopyKey( _T("jid"), jid, NULL, CopyKey, DestroyKey );

				for ( int j=0; ; j++ ) {
					HXML child = xmlGetChild( itemNode, j );
					if ( !child )
						break;

					const TCHAR* szColumnName = xmlGetName( child );
					if ( szColumnName ) {
						if ( xmlGetText( child ) && xmlGetText( child )[0] != _T('\0')) {
							mColumnsNames.insertCopyKey(( TCHAR* )szColumnName,_T(""),&keyReturned, CopyKey, DestroyKey);
							mColumnsNames.insert(( TCHAR* )szColumnName,keyReturned);
							pUserColumn->insertCopyKey(( TCHAR* )szColumnName, ( TCHAR* )xmlGetText( child ),NULL, CopyKey, DestroyKey);
				}	}	}

				SearchResults.insert((void*)pUserColumn);
		}	}
	}
	else if (!lstrcmp( type, _T("error"))) {
		const TCHAR* code=NULL;
		const TCHAR* description=NULL;
		TCHAR buff[255];
		HXML errorNode =  xmlGetChild( iqNode , "error" );
		if (errorNode) {
			code = xmlGetAttrValue( errorNode, _T("code"));
			description = xmlGetText( errorNode );
		}

		_sntprintf(buff,SIZEOF(buff),TranslateT("Error %s %s\r\nTry to specify more detailed"),code ? code : _T(""),description?description:_T(""));
		JSendBroadcast( NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, ( HANDLE ) id, 0 );
		if (searchHandleDlg )
			SetDlgItemText(searchHandleDlg,IDC_INSTRUCTIONS,buff);
		else
			MessageBox(NULL, buff, TranslateT("Search error"), MB_OK|MB_ICONSTOP);
		return;
	}

	SearchReturnResults((HANDLE)id, (void*)&SearchResults, (U_TCHAR_MAP *)&mColumnsNames);

	for (int i=0; i < SearchResults.getCount(); i++ )
		delete ((U_TCHAR_MAP *)SearchResults[i]);

	//send success to finish searching
	JSendBroadcast( NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, ( HANDLE ) id, 0 );
}
Exemple #26
0
void CJabberProto::OnIqResultGetSearchFields( HXML iqNode )
{
	if  ( !searchHandleDlg )
		return;

	LPCTSTR type = xmlGetAttrValue( iqNode, _T("type"));
	if ( !type )
		return;

	if ( !lstrcmp( type, _T("result"))) {
		HXML queryNode = xmlGetNthChild( iqNode, _T("query"), 1 );
		HXML xNode = xmlGetChildByTag( queryNode, "x", "xmlns", _T(JABBER_FEAT_DATA_FORMS));

		ShowWindow(searchHandleDlg,SW_HIDE);
		if ( xNode ) {
			//1. Form
			PostMessage( searchHandleDlg, WM_USER+11, ( WPARAM )xi.copyNode( xNode ), ( LPARAM )0 );
			HXML xcNode = xmlGetNthChild( xNode, _T("instructions"), 1 );
			if ( xcNode )
				SetDlgItemText( searchHandleDlg, IDC_INSTRUCTIONS, xmlGetText( xcNode ));
		}
		else {
			int Order=0;
			for ( int i = 0; ; i++ ) {
				HXML chNode = xmlGetChild( queryNode, i );
				if ( !chNode )
					break;

				if ( !_tcsicmp( xmlGetName( chNode ), _T("instructions")) && xmlGetText( chNode ))
					SetDlgItemText(searchHandleDlg,IDC_INSTRUCTIONS,TranslateTS(xmlGetText( chNode )));
				else if ( xmlGetName( chNode ) ) {
					Data *MyData=(Data*)malloc(sizeof(Data));
					memset(MyData,0,sizeof(Data));

					MyData->Label = mir_tstrdup( xmlGetName( chNode ));
					MyData->Var = mir_tstrdup( xmlGetName( chNode ));
					MyData->defValue = mir_tstrdup(xmlGetText( chNode ));
					MyData->Order = Order;
					if (MyData->defValue) MyData->bReadOnly = TRUE;
					PostMessage(searchHandleDlg,WM_USER+10,(WPARAM)FALSE,(LPARAM)MyData);
					Order++;
		}	}	}
		const TCHAR* szFrom = xmlGetAttrValue( iqNode, _T("from"));
		if (szFrom)
			SearchAddToRecent(szFrom,searchHandleDlg);
		PostMessage(searchHandleDlg,WM_USER+10,(WPARAM)0,(LPARAM)0);
		ShowWindow(searchHandleDlg,SW_SHOW);
	}
	else if ( !lstrcmp( type, _T("error"))) {
		const TCHAR* code=NULL;
		const TCHAR* description=NULL;
		TCHAR buff[255];
		HXML errorNode = xmlGetChild( iqNode, "error");
		if ( errorNode ) {
			code = xmlGetAttrValue( errorNode, _T("code"));
			description=xmlGetText( errorNode );
		}
		_sntprintf(buff,SIZEOF(buff),TranslateT("Error %s %s\r\nPlease select other server"),code ? code : _T(""),description?description:_T(""));
		SetDlgItemText(searchHandleDlg,IDC_INSTRUCTIONS,buff);
	}
	else SetDlgItemText( searchHandleDlg, IDC_INSTRUCTIONS, TranslateT( "Error Unknown reply recieved\r\nPlease select other server" ));
}
BOOL CJabberProto::OnRosterPushRequest(HXML, CJabberIqInfo *pInfo)
{
	HXML queryNode = pInfo->GetChildNode();

	// RFC 3921 #7.2 Business Rules
	if (pInfo->GetFrom()) {
		TCHAR *szFrom = JabberPrepareJid(pInfo->GetFrom());
		if (!szFrom)
			return TRUE;

		TCHAR *szTo = JabberPrepareJid(m_ThreadInfo->fullJID);
		if (!szTo) {
			mir_free(szFrom);
			return TRUE;
		}

		TCHAR *pDelimiter = _tcschr(szFrom, _T('/'));
		if (pDelimiter) *pDelimiter = 0;

		pDelimiter = _tcschr(szTo, _T('/'));
		if (pDelimiter) *pDelimiter = 0;

		BOOL bRetVal = _tcscmp(szFrom, szTo) == 0;

		mir_free(szFrom);
		mir_free(szTo);

		// invalid JID
		if (!bRetVal) {
			debugLogA("<iq/> attempt to hack via roster push from %S", pInfo->GetFrom());
			return TRUE;
		}
	}

	JABBER_LIST_ITEM *item;
	HANDLE hContact = NULL;
	const TCHAR *jid, *str, *name;
	TCHAR *nick;

	debugLogA("<iq/> Got roster push, query has %d children", xmlGetChildCount(queryNode));
	for (int i=0; ; i++) {
		HXML itemNode = xmlGetChild(queryNode ,i);
		if (!itemNode)
			break;

		if (_tcscmp(xmlGetName(itemNode), _T("item")) != 0)
			continue;
		if ((jid = xmlGetAttrValue(itemNode, _T("jid"))) == NULL)
			continue;
		if ((str = xmlGetAttrValue(itemNode, _T("subscription"))) == NULL)
			continue;

		// we will not add new account when subscription=remove
		if (!_tcscmp(str, _T("to")) || !_tcscmp(str, _T("both")) || !_tcscmp(str, _T("from")) || !_tcscmp(str, _T("none"))) {
			if ((name = xmlGetAttrValue(itemNode, _T("name"))) != NULL)
				nick = mir_tstrdup(name);
			else
				nick = JabberNickFromJID(jid);

			if (nick != NULL) {
				if ((item=ListAdd(LIST_ROSTER, jid)) != NULL) {
					replaceStrT(item->nick, nick);

					HXML groupNode = xmlGetChild(itemNode , "group");
					replaceStrT(item->group, xmlGetText(groupNode));

					if ((hContact=HContactFromJID(jid, 0)) == NULL) {
						// Received roster has a new JID.
						// Add the jid (with empty resource) to Miranda contact list.
						hContact = DBCreateContact(jid, nick, FALSE, FALSE);
					}
					else setTString(hContact, "jid", jid);

					if (name != NULL) {
						ptrT tszNick( getTStringA(hContact, "Nick"));
						if (tszNick != NULL) {
							if (_tcscmp(nick, tszNick) != 0)
								db_set_ts(hContact, "CList", "MyHandle", nick);
							else
								db_unset(hContact, "CList", "MyHandle");
						}
						else db_set_ts(hContact, "CList", "MyHandle", nick);
					}
					else db_unset(hContact, "CList", "MyHandle");

					if (!m_options.IgnoreRosterGroups) {
						if (item->group != NULL) {
							Clist_CreateGroup(0, item->group);
							db_set_ts(hContact, "CList", "Group", item->group);
						}
						else db_unset(hContact, "CList", "Group");
					}
				}
				mir_free(nick);
			}
		}

		if ((item=ListGetItemPtr(LIST_ROSTER, jid)) != NULL) {
			if (!_tcscmp(str, _T("both"))) item->subscription = SUB_BOTH;
			else if (!_tcscmp(str, _T("to"))) item->subscription = SUB_TO;
			else if (!_tcscmp(str, _T("from"))) item->subscription = SUB_FROM;
			else item->subscription = SUB_NONE;
			debugLogA("Roster push for jid=%S, set subscription to %S", jid, str);
			// subscription = remove is to remove from roster list
			// but we will just set the contact to offline and not actually
			// remove, so that history will be retained.
			if (!_tcscmp(str, _T("remove"))) {
				if ((hContact=HContactFromJID(jid)) != NULL) {
					SetContactOfflineStatus(hContact);
					ListRemove(LIST_ROSTER, jid);
				}
			}
			else if ( isChatRoom(hContact))
				db_unset(hContact, "CList", "Hidden");
			else
				UpdateSubscriptionInfo(hContact, item);
		}
	}

	UI_SAFE_NOTIFY(m_pDlgServiceDiscovery, WM_JABBER_TRANSPORT_REFRESH);
	RebuildInfoFrame();
	return TRUE;
}
Exemple #28
0
void __cdecl CJabberProto::ByteReceiveThread( JABBER_BYTE_TRANSFER *jbt )
{
	HXML iqNode, queryNode = NULL, n;
	const TCHAR *sid = NULL, *from = NULL, *to = NULL, *szId = NULL, *szHost, *szPort, *str;
	int i;
	WORD port;
	HANDLE hConn;
	char data[3];
	char* buffer;
	int datalen, bytesParsed, recvResult;
	BOOL validStreamhost = FALSE;

	if ( jbt == NULL ) return;

	jbt->state = JBT_INIT;

	if ( iqNode = jbt->iqNode ) {
		from = xmlGetAttrValue( iqNode, _T("from"));
		to = xmlGetAttrValue( iqNode, _T("to"));
		szId = xmlGetAttrValue( iqNode, _T("id"));

		queryNode = xmlGetChild( iqNode , "query" );
		if ( queryNode )
			sid = xmlGetAttrValue( queryNode, _T("sid"));
	}

	if ( szId && from && to && sid && ( n = xmlGetChild( queryNode , "streamhost" ))!=NULL ) {
		jbt->iqId = mir_tstrdup( szId );
		jbt->srcJID = mir_tstrdup( from );
		jbt->dstJID = mir_tstrdup( to );
		jbt->sid = mir_tstrdup( sid );

		if (( buffer=( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE ))) {
			for ( i=1; ( n = xmlGetNthChild( queryNode, _T("streamhost"), i ))!=NULL; i++ ) {
				if (( szHost = xmlGetAttrValue( n, _T("host"))) != NULL &&
					( szPort = xmlGetAttrValue( n, _T("port"))) != NULL &&
					( str = xmlGetAttrValue( n, _T("jid"))) != NULL ) {

						port = ( WORD )_ttoi( szPort );
						if ( jbt->streamhostJID ) mir_free( jbt->streamhostJID );
						jbt->streamhostJID = mir_tstrdup( str );

						Log( "bytestream_recv connecting to " TCHAR_STR_PARAM ":%d", szHost, port );
						NETLIBOPENCONNECTION nloc = { 0 };
						nloc.cbSize = sizeof( nloc );
						nloc.szHost = mir_t2a(szHost);
						nloc.wPort = port;
						hConn = ( HANDLE ) JCallService( MS_NETLIB_OPENCONNECTION, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nloc );
						mir_free((void*)nloc.szHost);

						if ( hConn == NULL ) {
							Log( "bytestream_recv_connection connection failed ( %d ), try next streamhost", WSAGetLastError());
							continue;
						}

						jbt->hConn = hConn;

						data[0] = 5;
						data[1] = 1;
						data[2] = 0;
						Netlib_Send( hConn, data, 3, 0 );

						jbt->state = JBT_INIT;
						datalen = 0;
						while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR && jbt->state!=JBT_SOCKSERR ) {
							recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 );
							if ( recvResult <= 0 ) break;
							datalen += recvResult;
							bytesParsed = ByteReceiveParse( hConn, jbt, buffer, datalen );
							if ( bytesParsed < datalen )
								memmove( buffer, buffer+bytesParsed, datalen-bytesParsed );
							datalen -= bytesParsed;
							if ( jbt->state == JBT_RECVING ) validStreamhost = TRUE;
						}
						Netlib_CloseHandle( hConn );
						Log( "bytestream_recv_connection closing connection" );
				}
				if ( jbt->state==JBT_ERROR || validStreamhost==TRUE )
					break;
				Log( "bytestream_recv_connection stream cannot be established, try next streamhost" );
			}
			mir_free( buffer );
		}
	}

	(this->*jbt->pfnFinal)(( jbt->state==JBT_DONE )?TRUE:FALSE, jbt->ft );
	jbt->ft = NULL;
	if ( !validStreamhost && szId && from ) {
		Log( "bytestream_recv_connection session not completed" );

		m_ThreadInfo->send( XmlNodeIq( _T("error"), szId, from )
			<< XCHILD( _T("error")) << XATTRI( _T("code"), 404 ) << XATTR( _T("type"), _T("cancel"))
			<< XCHILDNS( _T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
	}

	delete jbt;
	Log( "Thread ended: type=bytestream_recv" );
}
Exemple #29
0
static void sttFillJidList(HWND hwndDlg)
{
	JABBER_MUC_JIDLIST_INFO *jidListInfo;
	HXML iqNode, queryNode;
	const TCHAR* from, *jid, *reason, *nick;
	LVITEM lvi;
	HWND hwndList;
	int count, i;

	TCHAR *filter = NULL;
	if (GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA))
	{
		int filterLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_FILTER)) + 1;
		filter = (TCHAR *)_alloca(filterLength * sizeof(TCHAR));
		GetDlgItemText(hwndDlg, IDC_FILTER, filter, filterLength);
	}

	jidListInfo = ( JABBER_MUC_JIDLIST_INFO * ) GetWindowLongPtr( hwndDlg, GWLP_USERDATA );
	if ( !jidListInfo )
		return;

	hwndList = GetDlgItem( hwndDlg, IDC_LIST );
	SendMessage(hwndList, WM_SETREDRAW, FALSE, 0);

	count = ListView_GetItemCount( hwndList );
	lvi.mask = LVIF_PARAM;
	lvi.iSubItem = 0;
	for ( i=0; i<count; i++ ) {
		lvi.iItem = i;
		if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) {
			if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) {
				mir_free(( void * ) lvi.lParam );
			}
		}
	}
	ListView_DeleteAllItems( hwndList );

	// Populate displayed list from iqNode
	if (( iqNode = jidListInfo->iqNode ) != NULL ) {
		if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) {
			if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) {
				lvi.mask = LVIF_TEXT | LVIF_PARAM;
				lvi.iSubItem = 0;
				lvi.iItem = 0;
				for ( i=0; ; i++ ) {
					HXML itemNode = xmlGetChild( queryNode ,i);
					if ( !itemNode )
						break;

					if (( jid = xmlGetAttrValue( itemNode, _T("jid"))) != NULL ) {
						lvi.pszText = ( TCHAR* )jid;
						if ( jidListInfo->type == MUC_BANLIST ) {
							if (( reason = xmlGetText(xmlGetChild( itemNode , "reason" ))) != NULL ) {
								TCHAR jidreason[ JABBER_MAX_JID_LEN + 256 ];
								mir_sntprintf( jidreason, SIZEOF( jidreason ), _T("%s (%s)") , jid, reason );
								lvi.pszText = jidreason;
						}	}

						if ( jidListInfo->type == MUC_VOICELIST || jidListInfo->type == MUC_MODERATORLIST ) {
							if (( nick = xmlGetAttrValue( itemNode, _T("nick"))) != NULL ) {
								TCHAR nickjid[ JABBER_MAX_JID_LEN + 256 ];
								mir_sntprintf( nickjid, SIZEOF( nickjid ), _T("%s (%s)") , nick, jid );
								lvi.pszText = nickjid;
						}	}

						if (filter && *filter && !JabberStrIStr(lvi.pszText, filter))
							continue;

						lvi.lParam = ( LPARAM )mir_tstrdup( jid );

						ListView_InsertItem( hwndList, &lvi );
						lvi.iItem++;
	}	}	}	}	}

	lvi.mask = LVIF_PARAM;
	lvi.lParam = ( LPARAM )( -1 );
	ListView_InsertItem( hwndList, &lvi );

	SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
	RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE);
}
Exemple #30
0
static INT_PTR CALLBACK JabberMucJidListDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
	JABBER_MUC_JIDLIST_INFO* dat = (JABBER_MUC_JIDLIST_INFO*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA );

	switch( msg ) {
	case WM_INITDIALOG:
		{
			LVCOLUMN lvc;
			RECT rc;
			HWND hwndList;

			TranslateDialogDefault( hwndDlg );

			hwndList = GetDlgItem( hwndDlg, IDC_LIST );
			ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
			GetClientRect( hwndList, &rc );
			//rc.right -= GetSystemMetrics( SM_CXVSCROLL );
			lvc.mask = LVCF_WIDTH;
			lvc.cx = rc.right - 20;
			ListView_InsertColumn( hwndList, 0, &lvc );
			lvc.cx = 20;
			ListView_InsertColumn( hwndList, 1, &lvc );
			SendMessage( hwndDlg, WM_JABBER_REFRESH, 0, lParam );
			dat = (JABBER_MUC_JIDLIST_INFO*)lParam;

			static struct
			{
				int idc;
				char *title;
				char *icon;
				bool push;
			} buttons[] =
			{
				{IDC_BTN_FILTERAPPLY,	"Apply filter",		"sd_filter_apply",	false},
				{IDC_BTN_FILTERRESET,	"Reset filter",		"sd_filter_reset",	false},
			};
			for (int i = 0; i < SIZEOF(buttons); ++i)
			{
				SendDlgItemMessage(hwndDlg, buttons[i].idc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)dat->ppro->LoadIconEx(buttons[i].icon));
				SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASFLATBTN, 0, 0);
				SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONADDTOOLTIP, (WPARAM)buttons[i].title, 0);
				if (buttons[i].push)
					SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASPUSHBTN, 0, 0);
			}

			Utils_RestoreWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_");
		}
		return TRUE;
	case WM_SIZE:
		{
			UTILRESIZEDIALOG urd = {0};
			urd.cbSize = sizeof(urd);
			urd.hInstance = hInst;
			urd.hwndDlg = hwndDlg;
			urd.lpTemplate = MAKEINTRESOURCEA(IDD_JIDLIST);
			urd.pfnResizer = sttJidListResizer;
			CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);

			RECT listrc;
			LVCOLUMN lvc;
			HWND hwndList = GetDlgItem( hwndDlg, IDC_LIST );
			GetClientRect( hwndList, &listrc );
			lvc.mask = LVCF_WIDTH;
			//listrc.right -= GetSystemMetrics( SM_CXVSCROLL );
			lvc.cx = listrc.right - 20;
			SendMessage(hwndList, LVM_SETCOLUMN, 0, (LPARAM)&lvc);
			break;
		}
		break;

	case WM_JABBER_REFRESH:
		{
			// lParam is ( JABBER_MUC_JIDLIST_INFO * )
			HXML iqNode, queryNode;
			const TCHAR* from;
			TCHAR title[256];

			// Clear current GWL_USERDATA, if any
			if ( dat != NULL )
				delete dat;

			// Set new GWL_USERDATA
			dat = ( JABBER_MUC_JIDLIST_INFO * ) lParam;
			SetWindowLongPtr( hwndDlg, GWLP_USERDATA, ( LONG_PTR ) dat );

			// Populate displayed list from iqNode
			lstrcpyn( title, TranslateT( "JID List" ), SIZEOF( title ));
			if (( dat=( JABBER_MUC_JIDLIST_INFO * ) lParam ) != NULL ) {
				if (( iqNode = dat->iqNode ) != NULL ) {
					if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) {
						dat->roomJid = mir_tstrdup( from );

						if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) {
							TCHAR* localFrom = mir_tstrdup( from );
							mir_sntprintf( title, SIZEOF( title ), TranslateT("%s, %d items (%s)"),
								( dat->type == MUC_VOICELIST ) ? TranslateT( "Voice List" ) :
								( dat->type == MUC_MEMBERLIST ) ? TranslateT( "Member List" ) :
								( dat->type == MUC_MODERATORLIST ) ? TranslateT( "Moderator List" ) :
								( dat->type == MUC_BANLIST ) ? TranslateT( "Ban List" ) :
								( dat->type == MUC_ADMINLIST ) ? TranslateT( "Admin List" ) :
								( dat->type == MUC_OWNERLIST ) ? TranslateT( "Owner List" ) :
								TranslateT( "JID List" ), xmlGetChildCount(queryNode), localFrom );
							mir_free( localFrom );
			}	}	}	}
			SetWindowText( hwndDlg, title );

			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0);
			sttFillJidList(hwndDlg);
		}
		break;
	case WM_NOTIFY:
		if (( ( LPNMHDR )lParam )->idFrom == IDC_LIST ) {
			switch (( ( LPNMHDR )lParam )->code ) {
			case NM_CUSTOMDRAW:
				{
					NMLVCUSTOMDRAW *nm = ( NMLVCUSTOMDRAW * ) lParam;

					switch ( nm->nmcd.dwDrawStage ) {
					case CDDS_PREPAINT:
					case CDDS_ITEMPREPAINT:
						SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW );
						return TRUE;
					case CDDS_SUBITEM|CDDS_ITEMPREPAINT:
						{
							RECT rc;
							HICON hIcon;

							ListView_GetSubItemRect( nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc );
							if ( nm->iSubItem == 1 ) {
								if( nm->nmcd.lItemlParam == ( LPARAM )( -1 ))
									hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_ADDCONTACT ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 );
								else
									hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_DELETE ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 );
								DrawIconEx( nm->nmcd.hdc, ( rc.left+rc.right-GetSystemMetrics( SM_CXSMICON ))/2, ( rc.top+rc.bottom-GetSystemMetrics( SM_CYSMICON ))/2,hIcon, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL );
								DestroyIcon( hIcon );
								SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT );
								return TRUE;
				}	}	}	}
				break;
			case NM_CLICK:
				{
					NMLISTVIEW *nm = ( NMLISTVIEW * ) lParam;
					LVITEM lvi;
					LVHITTESTINFO hti;
					TCHAR text[128];

					if ( nm->iSubItem < 1 )
						break;

					hti.pt.x = ( short ) LOWORD( GetMessagePos());
					hti.pt.y = ( short ) HIWORD( GetMessagePos());
					ScreenToClient( nm->hdr.hwndFrom, &hti.pt );
					if ( ListView_SubItemHitTest( nm->hdr.hwndFrom, &hti ) == -1 )
						break;

					if ( hti.iSubItem != 1 )
						break;

					lvi.mask = LVIF_PARAM | LVIF_TEXT;
					lvi.iItem = hti.iItem;
					lvi.iSubItem = 0;
					lvi.pszText = text;
					lvi.cchTextMax = sizeof( text );
					ListView_GetItem( nm->hdr.hwndFrom, &lvi );
					if ( lvi.lParam == ( LPARAM )( -1 )) {
						TCHAR szBuffer[ 1024 ];
						_tcscpy( szBuffer, dat->type2str());
						if ( !dat->ppro->EnterString(szBuffer, SIZEOF(szBuffer), NULL, JES_COMBO, "gcAddNick_"))
							break;

						// Trim leading and trailing whitespaces
						TCHAR *p = szBuffer, *q;
						for ( p = szBuffer; *p!='\0' && isspace( BYTE( *p )); p++);
						for ( q = p; *q!='\0' && !isspace( BYTE( *q )); q++);
						if (*q != '\0') *q = '\0';
						if (*p == '\0')
							break;
						TCHAR rsn[ 1024 ];
						_tcscpy( rsn, dat->type2str());
						if ( dat->type == MUC_BANLIST ) {
							dat->ppro->EnterString(rsn, SIZEOF(rsn), TranslateT("Reason to ban") , JES_COMBO, "gcAddReason_");
							if ( szBuffer )
								dat->ppro->AddMucListItem( dat, p , rsn);
							else
								dat->ppro->AddMucListItem( dat, p );
						}
						else dat->ppro->AddMucListItem( dat, p );
					}
					else {
						//delete
						TCHAR msgText[128];

						mir_sntprintf( msgText, SIZEOF( msgText ), _T("%s %s?"), TranslateT( "Removing" ), text );
						if ( MessageBox( hwndDlg, msgText, dat->type2str(), MB_YESNO|MB_SETFOREGROUND ) == IDYES ) {
							dat->ppro->DeleteMucListItem( dat, ( TCHAR* )lvi.lParam );
							mir_free(( void * )lvi.lParam );
							ListView_DeleteItem( nm->hdr.hwndFrom, hti.iItem );
				}	}	}
				break;
			}
			break;
		}
		break;
	case WM_COMMAND:
		if ((LOWORD(wParam) == IDC_BTN_FILTERAPPLY) ||
			((LOWORD(wParam) == IDOK) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER))))
		{
			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 1);
			sttFillJidList(hwndDlg);
		} else
		if ((LOWORD(wParam) == IDC_BTN_FILTERRESET) ||
			((LOWORD(wParam) == IDCANCEL) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER))))
		{
			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0);
			sttFillJidList(hwndDlg);
		}
		break;
/*	case WM_SETCURSOR:
		if ( LOWORD( LPARAM )!= HTCLIENT ) break;
		if ( GetForegroundWindow() == GetParent( hwndDlg )) {
			POINT pt;
			GetCursorPos( &pt );
			ScreenToClient( hwndDlg,&pt );
			SetFocus( ChildWindowFromPoint( hwndDlg,pt ));	  //ugly hack because listviews ignore their first click
		}
		break;
*/	case WM_CLOSE:
		{
			HWND hwndList;
			int count, i;
			LVITEM lvi;

			// Free lParam of the displayed list items
			hwndList = GetDlgItem( hwndDlg, IDC_LIST );
			count = ListView_GetItemCount( hwndList );
			lvi.mask = LVIF_PARAM;
			lvi.iSubItem = 0;
			for ( i=0; i<count; i++ ) {
				lvi.iItem = i;
				if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) {
					if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) {
						mir_free(( void * ) lvi.lParam );
					}
				}
			}
			ListView_DeleteAllItems( hwndList );

			CJabberProto* ppro = dat->ppro;
			switch ( dat->type ) {
			case MUC_VOICELIST:
				ppro->m_hwndMucVoiceList = NULL;
				break;
			case MUC_MEMBERLIST:
				ppro->m_hwndMucMemberList = NULL;
				break;
			case MUC_MODERATORLIST:
				ppro->m_hwndMucModeratorList = NULL;
				break;
			case MUC_BANLIST:
				ppro->m_hwndMucBanList = NULL;
				break;
			case MUC_ADMINLIST:
				ppro->m_hwndMucAdminList = NULL;
				break;
			case MUC_OWNERLIST:
				ppro->m_hwndMucOwnerList = NULL;
				break;
			}

			DestroyWindow( hwndDlg );
		}
		break;

	case WM_DESTROY:
		// Clear GWL_USERDATA
		if ( dat != NULL ) {
			Utils_SaveWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_");
			delete dat;
		}
		break;
	}
	return FALSE;
}