Пример #1
0
INT_PTR Meta_Default(WPARAM hSub, LPARAM)
{
	DBCachedContact *cc = currDb->m_cache->GetCachedContact(db_mc_getMeta(hSub));
	if (cc && cc->IsMeta())
		db_mc_setDefault(cc->contactID, hSub, true);
	return 0;
}
Пример #2
0
// we assume that it could be called only for the metacontacts
static int Meta_SrmmIconClicked(WPARAM hMeta, LPARAM lParam)
{
	StatusIconClickData *sicd = (StatusIconClickData*)lParam;
	if (lstrcmpA(sicd->szModule, META_PROTO))
		return 0;

	DBCachedContact *cc = CheckMeta(hMeta);
	if (cc == NULL)
		return 0;

	HMENU hMenu = CreatePopupMenu();
	int iDefault = Meta_GetContactNumber(cc, db_mc_getSrmmSub(cc->contactID));

	MENUITEMINFO mii = { sizeof(mii) };
	mii.fMask = MIIM_ID | MIIM_STATE | MIIM_STRING;
	for (int i = 0; i < cc->nSubs; i++)	{
		char *szProto = GetContactProto(cc->pSubs[i]);
		if (szProto == NULL) continue;

		PROTOACCOUNT *pa = ProtoGetAccount(szProto);
		if (pa == NULL)
			continue;

		CMString tszNick;
		if (options.menu_contact_label == DNT_DID)
			tszNick = cli.pfnGetContactDisplayName(cc->pSubs[i], 0);
		else
			Meta_GetSubNick(hMeta, i, tszNick);
		tszNick.AppendFormat(_T(" [%s]"), pa->tszAccountName);

		mii.wID = i + 1;
		mii.fState = (i == iDefault) ? MFS_CHECKED : MFS_ENABLED;
		mii.dwTypeData = tszNick.GetBuffer();
		mii.cch = tszNick.GetLength();
		InsertMenuItem(hMenu, i, TRUE, &mii);
	}

	UINT res = TrackPopupMenu(hMenu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_BOTTOMALIGN | TPM_LEFTALIGN, sicd->clickLocation.x, sicd->clickLocation.y, 0, cli.hwndContactTree, NULL);
	if (res > 0) {
		MCONTACT hChosen = Meta_GetContactHandle(cc, res - 1);

		MetaSrmmData tmp = { cc->contactID };
		if (MetaSrmmData *p = arMetaWindows.find(&tmp))
			p->m_hSub = hChosen;

		db_mc_setDefault(cc->contactID, hChosen, true);
	}
	return 0;
}
Пример #3
0
STDMETHODIMP_(MEVENT) CDbxKyoto::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei)
{
	if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0;
	if (dbei->timestamp == 0) return 0;

	DBEvent dbe;
	dbe.dwSignature = DBEVENT_SIGNATURE;
	dbe.contactID = contactID; // store native or subcontact's id
	dbe.ofsModuleName = GetModuleNameOfs(dbei->szModule);
	dbe.timestamp = dbei->timestamp;
	dbe.flags = dbei->flags;
	dbe.wEventType = dbei->eventType;
	dbe.cbBlob = dbei->cbBlob;
	BYTE *pBlob = dbei->pBlob;

	MCONTACT contactNotifyID = contactID;
	DBCachedContact *cc, *ccSub = NULL;
	if ((cc = m_cache->GetCachedContact(contactID)) == NULL)
		return 0;

	if (cc->IsSub()) {
		ccSub = cc;
		if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
			return 0;

		// set default sub to the event's source
		if (!(dbei->flags & DBEF_SENT))
			db_mc_setDefault(cc->contactID, contactID, false);
		contactID = cc->contactID; // and add an event to a metahistory
		if (db_mc_isEnabled())
			contactNotifyID = contactID;
	}

	if (m_safetyMode)
		if (NotifyEventHooks(hEventFilterAddedEvent, contactNotifyID, (LPARAM)dbei))
			return NULL;

	mir_ptr<BYTE> pCryptBlob;
	if (m_bEncrypted) {
		size_t len;
		BYTE *pResult = m_crypto->encodeBuffer(pBlob, dbe.cbBlob, &len);
		if (pResult != NULL) {
			pCryptBlob = pBlob = pResult;
			dbe.cbBlob = (DWORD)len;
			dbe.flags |= DBEF_ENCRYPTED;
		}
	}
	DWORD dwEventId;
	{
		mir_cslock lck(m_csDbAccess);
		dwEventId = ++m_dwMaxEventId;

		BYTE *pDest = (BYTE*)_alloca(sizeof(DBEvent) + dbe.cbBlob);
		memcpy(pDest, &dbe, sizeof(DBEvent));
		memcpy(pDest + sizeof(DBEvent), pBlob, dbe.cbBlob);
		m_dbEvents.set((LPCSTR)&dwEventId, sizeof(int), (LPCSTR)pDest, sizeof(DBEvent) + dbe.cbBlob);

		// add a sorting key
		DBEventSortingKey key2 = { contactID, dbe.timestamp, dwEventId };
		m_dbEventsSort.set((LPCSTR)&key2, sizeof(key2), "", 1);

		cc->Advance(dwEventId, dbe);
		m_dbContacts.set((LPCSTR)&contactID, sizeof(int), (LPCSTR)&cc->dbc, sizeof(DBContact));

		// insert an event into a sub's history too
		if (ccSub != NULL) {
			key2.dwContactId = ccSub->contactID;
			m_dbEventsSort.set((LPCSTR)&key2, sizeof(key2), "", 1);

			ccSub->Advance(dwEventId, dbe);
			m_dbContacts.set((LPCSTR)&ccSub->contactID, sizeof(int), (LPCSTR)&ccSub->dbc, sizeof(DBContact));
		}
	}

	// Notify only in safe mode or on really new events
	if (m_safetyMode)
		NotifyEventHooks(hEventAddedEvent, contactNotifyID, dwEventId);

	return dwEventId;
}
Пример #4
0
STDMETHODIMP_(HANDLE) CDb3Mmap::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei)
{
	if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0;
	if (dbei->timestamp == 0) return 0;

	DBEvent dbe;
	dbe.signature = DBEVENT_SIGNATURE;
	dbe.contactID = contactID; // store native or subcontact's id
	dbe.timestamp = dbei->timestamp;
	dbe.flags = dbei->flags;
	dbe.wEventType = dbei->eventType;
	dbe.cbBlob = dbei->cbBlob;
	BYTE *pBlob = dbei->pBlob;

	MCONTACT contactNotifyID = contactID;
	DBCachedContact *ccSub = NULL;
	if (contactID != 0) {
		DBCachedContact *cc = m_cache->GetCachedContact(contactID);
		if (cc == NULL)
			return NULL;

		if (cc->IsSub()) {
			ccSub = cc;
			// set default sub to the event's source
			db_mc_setDefault(cc->parentID, contactID, false);
			contactID = cc->parentID; // and add an event to a metahistory
			if (db_mc_isEnabled())
				contactNotifyID = contactID;
		}
	}

	if (NotifyEventHooks(hEventFilterAddedEvent, contactNotifyID, (LPARAM)dbei))
		return NULL;

	mir_ptr<BYTE> pCryptBlob;
	if (m_bEncrypted) {
		size_t len;
		BYTE *pResult = m_crypto->encodeBuffer(pBlob, dbe.cbBlob, &len);
		if (pResult != NULL) {
			pCryptBlob = pBlob = pResult;
			dbe.cbBlob = (DWORD)len;
			dbe.flags |= DBEF_ENCRYPTED;
		}
	}

	bool neednotify;
	mir_cslockfull lck(m_csDbAccess);

	DWORD ofsContact = GetContactOffset(contactID);
	DBContact dbc = *(DBContact*)DBRead(ofsContact, sizeof(DBContact), NULL);
	if (dbc.signature != DBCONTACT_SIGNATURE)
		return NULL;

	DWORD ofsNew = CreateNewSpace(offsetof(DBEvent, blob) + dbe.cbBlob);

	dbe.ofsModuleName = GetModuleNameOfs(dbei->szModule);
	// find where to put it - sort by timestamp
	if (dbc.eventCount == 0) {
		dbe.ofsPrev = dbe.ofsNext = 0;
		dbc.ofsFirstEvent = dbc.ofsLastEvent = ofsNew;
	}
	else {
		DBEvent *dbeTest = (DBEvent*)DBRead(dbc.ofsFirstEvent, sizeof(DBEvent), NULL);
		// Should new event be placed before first event in chain?
		if (dbe.timestamp < dbeTest->timestamp) {
			dbe.ofsPrev = 0;
			dbe.ofsNext = dbc.ofsFirstEvent;
			dbc.ofsFirstEvent = ofsNew;
			dbeTest = (DBEvent*)DBRead(dbe.ofsNext, sizeof(DBEvent), NULL);
			dbeTest->ofsPrev = ofsNew;
			DBWrite(dbe.ofsNext, dbeTest, sizeof(DBEvent));
		}
		else {
			// Loop through the chain, starting at the end
			DWORD ofsThis = dbc.ofsLastEvent;
			dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL);
			for (;;) {
				// If the new event's timesstamp is equal to or greater than the
				// current dbevent, it will be inserted after. If not, continue
				// with the previous dbevent in chain.
				if (dbe.timestamp >= dbeTest->timestamp) {
					dbe.ofsPrev = ofsThis;
					dbe.ofsNext = dbeTest->ofsNext;
					dbeTest->ofsNext = ofsNew;
					DBWrite(ofsThis, dbeTest, sizeof(DBEvent));
					if (dbe.ofsNext == 0)
						dbc.ofsLastEvent = ofsNew;
					else {
						dbeTest = (DBEvent*)DBRead(dbe.ofsNext, sizeof(DBEvent), NULL);
						dbeTest->ofsPrev = ofsNew;
						DBWrite(dbe.ofsNext, dbeTest, sizeof(DBEvent));
					}
					break;
				}
				ofsThis = dbeTest->ofsPrev;
				dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL);
			}
		}
	}
	dbc.eventCount++;

	if (!(dbe.flags & (DBEF_READ | DBEF_SENT))) {
		if (dbe.timestamp < dbc.tsFirstUnread || dbc.tsFirstUnread == 0) {
			dbc.tsFirstUnread = dbe.timestamp;
			dbc.ofsFirstUnread = ofsNew;
		}
		neednotify = true;
	}
	else neednotify = m_safetyMode;

	if (ccSub != NULL) {
		DBContact *pSub = (DBContact*)DBRead(ccSub->dwDriverData, sizeof(DBContact), NULL);
		pSub->eventCount++;
	}

	DBWrite(ofsContact, &dbc, sizeof(DBContact));
	DBWrite(ofsNew, &dbe, offsetof(DBEvent, blob));
	DBWrite(ofsNew + offsetof(DBEvent, blob), pBlob, dbe.cbBlob);
	DBFlush(0);
	lck.unlock();

	log1("add event @ %08x", ofsNew);

	// Notify only in safe mode or on really new events
	if (neednotify)
		NotifyEventHooks(hEventAddedEvent, contactNotifyID, (LPARAM)ofsNew);

	return (HANDLE)ofsNew;
}