From 7578f068b6dd10641ced7d08d5eebb4654c4911c Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 14 Feb 2014 15:34:14 +0000 Subject: Dbx_tree moved to deprecated git-svn-id: http://svn.miranda-ng.org/main/trunk@8122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/!Deprecated/Dbx_tree/src/Compatibility.cpp | 853 +++++++++++++++++++++ 1 file changed, 853 insertions(+) create mode 100644 plugins/!Deprecated/Dbx_tree/src/Compatibility.cpp (limited to 'plugins/!Deprecated/Dbx_tree/src/Compatibility.cpp') diff --git a/plugins/!Deprecated/Dbx_tree/src/Compatibility.cpp b/plugins/!Deprecated/Dbx_tree/src/Compatibility.cpp new file mode 100644 index 0000000000..bc42386664 --- /dev/null +++ b/plugins/!Deprecated/Dbx_tree/src/Compatibility.cpp @@ -0,0 +1,853 @@ +/* + +dbx_tree: tree database driver for Miranda IM + +Copyright 2007-2010 Michael "Protogenes" Kunz, + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "Interface.h" +#include "Compatibility.h" +#include "Logger.h" +#define DB_NOHELPERFUNCTIONS +#include "m_database.h" +#include "m_db_int.h" +#undef DB_NOHELPERFUNCTIONS + +HANDLE gEvents[6] = {0,0,0,0,0,0}; + +HANDLE hEventDeletedEvent, + hEventAddedEvent, + hEventFilterAddedEvent, + hSettingChangeEvent, + hContactDeletedEvent, + hContactAddedEvent; + +int CDataBase::CheckProto(DBCachedContact *cc, const char *proto) +{ + if (cc->szProto == NULL) { + char protobuf[MAX_PATH] = {0}; + DBVARIANT dbv; + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = protobuf; + dbv.cchVal = sizeof(protobuf); + if (GetContactSettingStatic(cc->contactID, "Protocol", "p", &dbv) != 0 || (dbv.type != DBVT_ASCIIZ)) + return 0; + + cc->szProto = m_cache->GetCachedSetting(NULL, protobuf, 0, (int)strlen(protobuf)); + } + + return !strcmp(cc->szProto, proto); +} + +STDMETHODIMP_(HANDLE) CDataBase::AddContact(void) +{ + TDBTEntity entity = {0,0,0,0}; + entity.hParentEntity = DBEntityGetRoot(0, 0); + entity.hAccountEntity = entity.hParentEntity; + + TDBTEntityHandle res = getEntities().CreateEntity(entity); + if (res == DBT_INVALIDPARAM) + return (HANDLE)1; + + m_cache->AddContactToCache(res); + + NotifyEventHooks(hContactAddedEvent, res, 0); + return (HANDLE)res; +} + +STDMETHODIMP_(LONG) CDataBase::DeleteContact(MCONTACT contactID) +{ + NotifyEventHooks(hContactDeletedEvent, contactID, 0); + + int res = DBEntityDelete(contactID, 0); + if (res == DBT_INVALIDPARAM) + return 1; + + if (res == 0) + m_cache->FreeCachedContact(contactID); + + return res; +} + +STDMETHODIMP_(BOOL) CDataBase::IsDbContact(MCONTACT contactID) +{ + int flags = DBEntityGetFlags(contactID, 0); + return (flags != DBT_INVALIDPARAM) && + ((flags & DBT_NFM_SpecialEntity) == 0); +} + +STDMETHODIMP_(LONG) CDataBase::GetContactCount(void) +{ + TDBTEntityIterFilter f = {0,0,0,0}; + f.cbSize = sizeof(f); + f.fDontHasFlags = DBT_NF_IsGroup | DBT_NF_IsVirtual | DBT_NF_IsAccount | DBT_NF_IsRoot; + f.Options = DBT_NIFO_OSC_AC | DBT_NIFO_OC_AC; + + TDBTEntityIterationHandle hiter = DBEntityIterInit((WPARAM)&f, getEntities().getRootEntity()); + int c = 0; + if ((hiter != 0) && (hiter != DBT_INVALIDPARAM)) + { + TDBTEntityHandle con = DBEntityIterNext(hiter, 0); + + while ((con != DBT_INVALIDPARAM) && (con != 0)) + { + if ((con != 0) && (con != DBT_INVALIDPARAM)) + c++; + + con = DBEntityIterNext(hiter, 0); + } + DBEntityIterClose(hiter, 0); + } + return c; +} + +STDMETHODIMP_(MCONTACT) CDataBase::FindFirstContact(const char* szProto) +{ + DBCachedContact *cc = m_cache->GetFirstContact(); + if (cc == NULL) + return NULL; + + if (!szProto || CheckProto(cc, szProto)) + return cc->contactID; + + return FindNextContact(cc->contactID, szProto); +} + +STDMETHODIMP_(MCONTACT) CDataBase::FindNextContact(MCONTACT contactID, const char* szProto) +{ + while (contactID) { + DBCachedContact *cc = m_cache->GetNextContact(contactID); + if (cc == NULL) + break; + + if (!szProto || CheckProto(cc, szProto)) + return cc->contactID; + + contactID = cc->contactID; + continue; + } + + return NULL; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static bool isEncrypted(LPCSTR szModule, LPCSTR szSetting) +{ + if (!_strnicmp(szSetting, "password", 8)) return true; + if (!strcmp(szSetting, "NLProxyAuthPassword")) return true; + if (!strcmp(szSetting, "LNPassword")) return true; + if (!strcmp(szSetting, "FileProxyPassword")) return true; + if (!strcmp(szSetting, "TokenSecret")) return true; + + if (!strcmp(szModule, "SecureIM")) { + if (!strcmp(szSetting, "pgp")) return true; + if (!strcmp(szSetting, "pgpPrivKey")) return true; + } + return false; +} + +//VERY VERY VERY BASIC ENCRYPTION FUNCTION + +static void Encrypt(char *msg, BOOL up) +{ + int jump = (up) ? 5 : -5; + for (int i = 0; msg[i]; i++) + msg[i] = msg[i] + jump; +} + +__forceinline void EncodeString(LPSTR buf) +{ + Encrypt(buf, TRUE); +} + +__forceinline void DecodeString(LPSTR buf) +{ + Encrypt(buf, FALSE); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP_(BOOL) CDataBase::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) +{ + dbv->type = 0; + + char namebuf[512]; + namebuf[0] = 0; + + if (!(szModule || szSetting)) + return -1; + + if (szModule) + strcpy_s(namebuf, szModule); + strcat_s(namebuf, "/"); + if (szSetting) + strcat_s(namebuf, szSetting); + + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + TDBTSetting set = {0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.Entity = contactID; + desc.pszSettingName = namebuf; + + set.cbSize = sizeof(set); + set.Descriptor = &desc; + + if (DBSettingRead(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) + return -1; + + switch (set.Type) { + case DBT_ST_ANSI: + dbv->type = DBVT_ASCIIZ; + dbv->pszVal = set.Value.pAnsi; + dbv->cchVal = set.Value.Length - 1; + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + break; + case DBT_ST_UTF8: + if (isEncrypted(szModule, szSetting)) + DecodeString(set.Value.pUTF8); + dbv->type = DBVT_WCHAR; + dbv->pwszVal = mir_utf8decodeW(set.Value.pUTF8); + if (dbv->pwszVal) + dbv->cchVal = static_cast(wcslen(dbv->pwszVal)); + else + dbv->cchVal = 0; + mir_free(set.Value.pUTF8); + break; + case DBT_ST_WCHAR: + dbv->type = DBVT_WCHAR; + dbv->pwszVal = set.Value.pWide; + dbv->cchVal = set.Value.Length - 1; + break; + case DBT_ST_BLOB: + dbv->type = DBVT_BLOB; + dbv->pbVal = set.Value.pBlob; + dbv->cpbVal = set.Value.Length; + break; + case DBT_ST_BOOL: + dbv->type = DBVT_BYTE; + dbv->bVal = (uint8_t)set.Value.Bool; + break; + case DBT_ST_BYTE: case DBT_ST_CHAR: + dbv->type = DBVT_BYTE; + dbv->bVal = set.Value.Byte; + break; + case DBT_ST_SHORT: case DBT_ST_WORD: + dbv->type = DBVT_WORD; + dbv->wVal = set.Value.Word; + break; + case DBT_ST_INT: case DBT_ST_DWORD: + dbv->type = DBVT_DWORD; + dbv->dVal = set.Value.DWord; + break; + case DBT_ST_INT64: case DBT_ST_QWORD: + case DBT_ST_DOUBLE: case DBT_ST_FLOAT: + dbv->type = DBVT_BLOB; + dbv->cpbVal = sizeof(set.Value); + dbv->pbVal = reinterpret_cast(mir_alloc(sizeof(set.Value))); + memcpy(dbv->pbVal, &set.Value, sizeof(set.Value)); + break; + + default: + return -1; + } + + return 0; +} + +STDMETHODIMP_(BOOL) CDataBase::GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) +{ + if ((dbv->type & DBVTF_VARIABLELENGTH) == 0) + { + FreeVariant(dbv); + dbv->type = 0; + } + + char namebuf[512]; + namebuf[0] = 0; + if (szModule) + strcpy_s(namebuf, szModule); + strcat_s(namebuf, "/"); + if (szSetting) + strcat_s(namebuf, szSetting); + + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + TDBTSetting set = {0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.Entity = contactID; + desc.pszSettingName = namebuf; + + set.cbSize = sizeof(set); + set.Descriptor = &desc; + + switch (dbv->type) { + case DBVT_ASCIIZ: set.Type = DBT_ST_ANSI; break; + case DBVT_BLOB: set.Type = DBT_ST_BLOB; break; + case DBVT_UTF8: set.Type = DBT_ST_UTF8; break; + case DBVT_WCHAR: set.Type = DBT_ST_WCHAR; break; + } + + if (DBSettingRead(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) + return -1; + + switch (set.Type) { + case DBT_ST_ANSI: + dbv->type = DBVT_ASCIIZ; + dbv->pszVal = set.Value.pAnsi; + dbv->cchVal = set.Value.Length - 1; + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + break; + case DBT_ST_UTF8: + dbv->type = DBVT_UTF8; + dbv->pszVal = set.Value.pUTF8; + dbv->cchVal = set.Value.Length - 1; + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + break; + case DBT_ST_WCHAR: + if (dbv->type == DBVT_WCHAR) { + dbv->pwszVal = set.Value.pWide; + dbv->cchVal = set.Value.Length - 1; + } + else { + dbv->type = DBVT_UTF8; + dbv->pszVal = mir_utf8encodeW(set.Value.pWide); + dbv->cchVal = static_cast(strlen(dbv->pszVal)); + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + mir_free(set.Value.pWide); + } + break; + case DBT_ST_BLOB: + dbv->type = DBVT_BLOB; + dbv->pbVal = set.Value.pBlob; + dbv->cpbVal = set.Value.Length; + break; + case DBT_ST_BOOL: + dbv->type = DBVT_BYTE; + dbv->bVal = (uint8_t)set.Value.Bool; + break; + case DBT_ST_BYTE: case DBT_ST_CHAR: + dbv->type = DBVT_BYTE; + dbv->bVal = set.Value.Byte; + break; + case DBT_ST_SHORT: case DBT_ST_WORD: + dbv->type = DBVT_WORD; + dbv->wVal = set.Value.Word; + break; + case DBT_ST_INT: case DBT_ST_DWORD: + dbv->type = DBVT_DWORD; + dbv->dVal = set.Value.DWord; + break; + case DBT_ST_INT64: case DBT_ST_QWORD: + case DBT_ST_DOUBLE: case DBT_ST_FLOAT: + dbv->type = DBVT_BLOB; + dbv->cpbVal = sizeof(set.Value); + dbv->pbVal = reinterpret_cast(mir_alloc(sizeof(set.Value))); + memcpy(dbv->pbVal, &set.Value, sizeof(set.Value)); + break; + default: + return -1; + } + + return 0; +} + +STDMETHODIMP_(BOOL) CDataBase::GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) +{ + char namebuf[512]; + namebuf[0] = 0; + if (szModule) + strcpy_s(namebuf, szModule); + strcat_s(namebuf, "/"); + if (szSetting) + strcat_s(namebuf, szSetting); + + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + TDBTSetting set = {0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.Entity = contactID; + desc.pszSettingName = namebuf; + + set.cbSize = sizeof(set); + set.Descriptor = &desc; + + if (DBSettingRead(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) + return -1; + + if ((set.Type & DBT_STF_VariableLength) ^ (dbv->type & DBVTF_VARIABLELENGTH)) + { + if (set.Type & DBT_STF_VariableLength) + mir_free(set.Value.pBlob); + return -1; + } + + switch (set.Type) { + case DBT_ST_ANSI: + if (dbv->cchVal < set.Value.Length) { + memcpy(dbv->pszVal, set.Value.pAnsi, dbv->cchVal); + dbv->pszVal[dbv->cchVal - 1] = 0; + } + else memcpy(dbv->pszVal, set.Value.pAnsi, set.Value.Length); + + dbv->type = DBVT_ASCIIZ; + dbv->cchVal = set.Value.Length - 1; + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + + mir_free(set.Value.pAnsi); + break; + case DBT_ST_UTF8: + set.Value.pUTF8 = mir_utf8decode(set.Value.pUTF8, NULL); + set.Value.Length = static_cast(strlen(set.Value.pUTF8)); + + if (dbv->cchVal < set.Value.Length) { + memcpy(dbv->pszVal, set.Value.pUTF8, dbv->cchVal); + dbv->pszVal[dbv->cchVal - 1] = 0; + } + else memcpy(dbv->pszVal, set.Value.pUTF8, set.Value.Length); + + dbv->type = DBVT_ASCIIZ; + dbv->cchVal = set.Value.Length - 1; + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + + mir_free(set.Value.pUTF8); + break; + case DBT_ST_WCHAR: + { + char *tmp = mir_u2a(set.Value.pWide); + WORD l = static_cast(strlen(tmp)); + mir_free(set.Value.pWide); + + if (dbv->cchVal < l + 1) { + memcpy(dbv->pszVal, tmp, dbv->cchVal); + dbv->pszVal[l] = 0; + } + else memcpy(dbv->pszVal, tmp, l + 1); + + dbv->type = DBVT_ASCIIZ; + dbv->cchVal = l; + if (isEncrypted(szModule, szSetting)) + DecodeString(dbv->pszVal); + + mir_free(tmp); + } + break; + case DBT_ST_BLOB: + if (dbv->cchVal < set.Value.Length) + memcpy(dbv->pbVal, set.Value.pBlob, dbv->cchVal); + else + memcpy(dbv->pbVal, set.Value.pBlob, set.Value.Length); + + dbv->type = DBVT_BLOB; + dbv->cchVal = set.Value.Length; + mir_free(set.Value.pBlob); + break; + case DBT_ST_BOOL: + dbv->type = DBVT_BYTE; + dbv->bVal = set.Value.Bool ? TRUE : FALSE; + break; + case DBT_ST_BYTE: case DBT_ST_CHAR: + dbv->type = DBVT_BYTE; + dbv->bVal = set.Value.Byte; + break; + case DBT_ST_SHORT: case DBT_ST_WORD: + dbv->type = DBVT_WORD; + dbv->wVal = set.Value.Word; + break; + case DBT_ST_INT: case DBT_ST_DWORD: + dbv->type = DBVT_DWORD; + dbv->dVal = set.Value.DWord; + break; + default: + return -1; + } + + return 0; +} + +STDMETHODIMP_(BOOL) CDataBase::FreeVariant(DBVARIANT *dbv) +{ + if (dbv->type == DBVT_BLOB && dbv->pbVal) { + mir_free(dbv->pbVal); + dbv->pbVal = 0; + } + else if ((dbv->type & DBVTF_VARIABLELENGTH) && (dbv->pszVal)) { + mir_free(dbv->pszVal); + dbv->pszVal = NULL; + } + dbv->type = 0; + return 0; +} + +STDMETHODIMP_(BOOL) CDataBase::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws) +{ + char namebuf[512]; + namebuf[0] = 0; + if (dbcws->szModule) + strcpy_s(namebuf, dbcws->szModule); + strcat_s(namebuf, "/"); + if (dbcws->szSetting) + strcat_s(namebuf, dbcws->szSetting); + + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + TDBTSetting set = {0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.Entity = contactID; + desc.pszSettingName = namebuf; + + set.cbSize = sizeof(set); + set.Descriptor = &desc; + + switch (dbcws->value.type) { + case DBVT_ASCIIZ: + set.Type = DBT_ST_ANSI; + set.Value.pAnsi = dbcws->value.pszVal; + if (isEncrypted(dbcws->szModule, dbcws->szSetting)) + EncodeString(dbcws->value.pszVal); + break; + case DBVT_UTF8: + if (isEncrypted(dbcws->szModule, dbcws->szSetting)) + EncodeString(dbcws->value.pszVal); + { + wchar_t * tmp = mir_utf8decodeW(dbcws->value.pszVal); + if (tmp == 0) { + if (IsDebuggerPresent()) + { + DebugBreak(); +#ifdef _DEBUG + } + else { + LOG(logWARNING, _T("Trying to write malformed UTF8 setting \"%hs\" in module \"%hs\""), dbcws->szSetting, dbcws->szModule); + CLogger::Instance().ShowMessage(); +#endif + } + return -1; + } + else mir_free(tmp); + } + + set.Type = DBT_ST_UTF8; + set.Value.pUTF8 = dbcws->value.pszVal; + break; + case DBVT_WCHAR: + set.Type = DBT_ST_WCHAR; + set.Value.pWide = dbcws->value.pwszVal; + break; + case DBVT_BLOB: + set.Type = DBT_ST_BLOB; + set.Value.pBlob = dbcws->value.pbVal; + set.Value.Length = dbcws->value.cpbVal; + break; + case DBVT_BYTE: + set.Type = DBT_ST_BYTE; + set.Value.Byte = dbcws->value.bVal; + break; + case DBVT_WORD: + set.Type = DBT_ST_WORD; + set.Value.Word = dbcws->value.wVal; + break; + case DBVT_DWORD: + set.Type = DBT_ST_DWORD; + set.Value.DWord = dbcws->value.dVal; + break; + default: + return -1; + } + + if (DBSettingWrite(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) + return -1; + + if (dbcws->value.type == DBVT_WCHAR) { + dbcws->value.type = DBVT_UTF8; + wchar_t * tmp = dbcws->value.pwszVal; + dbcws->value.pszVal = mir_utf8encodeW(dbcws->value.pwszVal); + NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)dbcws); + mir_free(dbcws->value.pszVal); + dbcws->value.type = DBVT_WCHAR; + dbcws->value.pwszVal = tmp; + } + else NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)dbcws); + + return 0; +} + +STDMETHODIMP_(BOOL) CDataBase::DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting) +{ + char namebuf[512]; + namebuf[0] = 0; + if (szModule) + strcpy_s(namebuf, szModule); + strcat_s(namebuf, "/"); + if (szSetting) + strcat_s(namebuf, szSetting); + + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.Entity = contactID; + desc.pszSettingName = namebuf; + + if (DBSettingDelete(reinterpret_cast(&desc), 0) == DBT_INVALIDPARAM) + return -1; + + { + DBCONTACTWRITESETTING tmp = {0,0,0,0}; + tmp.szModule = szModule; + tmp.szSetting = szSetting; + tmp.value.type = 0; + NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&tmp); + } + + return 0; +} + +STDMETHODIMP_(BOOL) CDataBase::EnumContactSettings(MCONTACT contactID, DBCONTACTENUMSETTINGS* pces) +{ + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.Entity = contactID; + + char namebuf[512]; + namebuf[0] = 0; + if (pces->szModule) + strcpy_s(namebuf, pces->szModule); + strcat_s(namebuf, "/"); + + TDBTSettingIterFilter filter = {0,0,0,0,0,0,0,0}; + filter.cbSize = sizeof(filter); + filter.Descriptor = &desc; + filter.hEntity = (WPARAM)contactID; + filter.NameStart = namebuf; + + TDBTSettingIterationHandle hiter = DBSettingIterInit(reinterpret_cast(&filter), 0); + if ((hiter == 0) || (hiter == DBT_INVALIDPARAM)) + return -1; + + int res = 0; + TDBTSettingHandle hset = DBSettingIterNext(hiter, 0); + while (hset != 0) + { + char * p = strchr(desc.pszSettingName, '/'); + if (p) { + ++p; + } else { + p = desc.pszSettingName; + } + + res = pces->pfnEnumProc(p, pces->lParam); + if (res == 0) + { + hset = DBSettingIterNext(hiter, 0); + } else { + hset = 0; + } + } + + DBSettingIterClose(hiter, 0); + + if (desc.pszSettingName) + mir_free(desc.pszSettingName); + + return res; +} + +STDMETHODIMP_(LONG) CDataBase::GetEventCount(MCONTACT contactID) +{ + if (contactID == 0) + contactID = getEntities().getRootEntity(); + + return DBEventGetCount(contactID, 0); +} + +STDMETHODIMP_(HANDLE) CDataBase::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei) +{ + if (dbei->cbSize < sizeof(DBEVENTINFO)) + return (HANDLE)-1; + + int tmp = NotifyEventHooks(hEventFilterAddedEvent, contactID, (LPARAM)dbei); + if (tmp != 0) + return (HANDLE)tmp; + + if (contactID == 0) + contactID = getEntities().getRootEntity(); + + TDBTEvent ev = {0,0,0,0,0,0,0}; + ev.cbSize = sizeof(ev); + ev.ModuleName = dbei->szModule; + ev.Timestamp = dbei->timestamp; + ev.Flags = dbei->flags; + if (ev.Flags & DBEF_SENT) + ev.Flags = ev.Flags | DBEF_READ; + ev.EventType = dbei->eventType; + ev.cbBlob = dbei->cbBlob; + ev.pBlob = dbei->pBlob; + + int res = DBEventAdd(contactID, reinterpret_cast(&ev)); + if (res != DBT_INVALIDPARAM) + { + NotifyEventHooks(hEventAddedEvent, contactID, res); + return (HANDLE)res; + } + return NULL; +} + +STDMETHODIMP_(BOOL) CDataBase::DeleteEvent(MCONTACT contactID, HANDLE hDbEvent) +{ + int res = NotifyEventHooks(hEventDeletedEvent, contactID, (WPARAM)hDbEvent); + + if (contactID == 0) + contactID = getEntities().getRootEntity(); + + if (res == 0) + return DBEventDelete((WPARAM)hDbEvent, 0); + + return res; +} + +STDMETHODIMP_(LONG) CDataBase::GetBlobSize(HANDLE hDbEvent) +{ + int res = DBEventGetBlobSize((WPARAM)hDbEvent, 0); + if (res == DBT_INVALIDPARAM) + return -1; + + return res; +} + +STDMETHODIMP_(BOOL) CDataBase::GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbei) +{ + if (dbei->cbSize < sizeof(DBEVENTINFO)) + return -1; + + TDBTEvent ev = {0,0,0,0,0,0,0}; + ev.cbSize = sizeof(ev); + ev.cbBlob = 0; + ev.pBlob = NULL; + + int res = DBEventGet((WPARAM)hDbEvent, reinterpret_cast(&ev)); + + dbei->szModule = ev.ModuleName; + dbei->timestamp = ev.Timestamp; + dbei->flags = ev.Flags; + if (dbei->flags & DBEF_SENT) + dbei->flags = dbei->flags & ~DBEF_READ; + dbei->eventType = ev.EventType; + + if (dbei->cbBlob && dbei->pBlob) + { + if (dbei->cbBlob >= ev.cbBlob) + memcpy(dbei->pBlob, ev.pBlob, ev.cbBlob); + else + memcpy(dbei->pBlob, ev.pBlob, dbei->cbBlob); + } + mir_free(ev.pBlob); + dbei->cbBlob = ev.cbBlob; + + if (res == DBT_INVALIDPARAM) + return 1; + + return res; +} + +STDMETHODIMP_(BOOL) CDataBase::MarkEventRead(MCONTACT contactID, HANDLE hDbEvent) +{ + int res = DBEventMarkRead((WPARAM)hDbEvent, 0); + if ((res != DBT_INVALIDPARAM) && (res & DBEF_SENT)) + res = res & ~DBEF_READ; + return res; +} + +STDMETHODIMP_(MCONTACT) CDataBase::GetEventContact(HANDLE hDbEvent) +{ + TDBTEntityHandle res = DBEventGetEntity((WPARAM)hDbEvent, 0); + if (res == getEntities().getRootEntity()) + res = 0; + + return res; +} + +STDMETHODIMP_(HANDLE) CDataBase::FindFirstEvent(MCONTACT contactID) +{ + if (contactID == 0) + contactID = getEntities().getRootEntity(); + + return (HANDLE)getEvents().compFirstEvent(contactID); +} + +STDMETHODIMP_(HANDLE) CDataBase::FindFirstUnreadEvent(MCONTACT contactID) +{ + if (contactID == 0) + contactID = getEntities().getRootEntity(); + return (HANDLE)getEvents().compFirstUnreadEvent(contactID); +} + +STDMETHODIMP_(HANDLE) CDataBase::FindLastEvent(MCONTACT contactID) +{ + if (contactID == 0) + contactID = getEntities().getRootEntity(); + return (HANDLE)getEvents().compLastEvent(contactID); +} + +STDMETHODIMP_(HANDLE) CDataBase::FindNextEvent(HANDLE hDbEvent) +{ + return (HANDLE)getEvents().compNextEvent((WPARAM)hDbEvent); +} + +STDMETHODIMP_(HANDLE) CDataBase::FindPrevEvent(HANDLE hDbEvent) +{ + return (HANDLE)getEvents().compPrevEvent((WPARAM)hDbEvent); +} + +STDMETHODIMP_(BOOL) CDataBase::EnumModuleNames(DBMODULEENUMPROC pCallback, void *pParam) +{ + if (!pCallback) + return -1; + + return getSettings().CompEnumModules(pCallback, (WPARAM)pParam); +} + +STDMETHODIMP_(BOOL) CDataBase::SetSettingResident(BOOL bIsResident, const char *pszSettingName) +{ + return FALSE; +} + +STDMETHODIMP_(BOOL) CDataBase::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) +{ + return FALSE; +} + +STDMETHODIMP_(void) CDataBase::SetCacheSafetyMode(BOOL) {} + + +STDMETHODIMP_(BOOL) CDataBase::IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting) +{ + return FALSE; +} + +bool CompatibilityRegister() +{ + hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED); + hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED); + hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); + hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); + hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED); + hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED); + return true; +} -- cgit v1.2.3