From 9126d2b133d00b836fca640f847a0948f7579e02 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 23 Jul 2012 06:41:38 +0000 Subject: Db3x_mmap,Db_autobackups: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1107 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Db3x_mmap/src/dbcontacts.cpp | 244 +++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 plugins/Db3x_mmap/src/dbcontacts.cpp (limited to 'plugins/Db3x_mmap/src/dbcontacts.cpp') diff --git a/plugins/Db3x_mmap/src/dbcontacts.cpp b/plugins/Db3x_mmap/src/dbcontacts.cpp new file mode 100644 index 0000000000..b8d4a843b8 --- /dev/null +++ b/plugins/Db3x_mmap/src/dbcontacts.cpp @@ -0,0 +1,244 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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 "commonheaders.h" + +DBCachedContactValueList* CDdxMmap::AddToCachedContactList(HANDLE hContact, int index) +{ + DBCachedContactValueList* VL = (DBCachedContactValueList*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); + VL->hContact = hContact; + if (index == -1) + m_lContacts.insert(VL); + else + m_lContacts.insert(VL,index); + return VL; +} + +#define proto_module "Protocol" +#define proto_setting "p" + +int CDdxMmap::CheckProto(HANDLE hContact, const char *proto) +{ + char protobuf[MAX_PATH] = {0}; + DBVARIANT dbv; + DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv}; + + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = protobuf; + dbv.cchVal = sizeof(protobuf); + + if (GetContactSettingStatic(hContact, &sVal) != 0 || (dbv.type != DBVT_ASCIIZ)) + return 0; + + return !strcmp(protobuf,proto); +} + +STDMETHODIMP_(LONG) CDdxMmap::GetContactCount(void) +{ + mir_cslock lck(m_csDbAccess); + return m_dbHeader.contactCount; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstContact(const char *szProto) +{ + mir_cslock lck(m_csDbAccess); + HANDLE ret = (HANDLE)m_dbHeader.ofsFirstContact; + if (szProto && !CheckProto(ret, szProto)) + ret = FindNextContact(ret, szProto); + return ret; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindNextContact(HANDLE hContact, const char *szProto) +{ + int index; + DBContact *dbc; + DBCachedContactValueList VLtemp, *VL = NULL; + VLtemp.hContact = hContact; + + mir_cslock lck(m_csDbAccess); + while (VLtemp.hContact) { + if (( index = m_lContacts.getIndex(&VLtemp)) != -1) { + VL = m_lContacts[index]; + if (VL->hNext != NULL) { + if (!szProto || CheckProto(VL->hNext, szProto)) + return VL->hNext; + + VLtemp.hContact = VL->hNext; + continue; + } } + + dbc = (DBContact*)DBRead(VLtemp.hContact,sizeof(DBContact),NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + break; + + if ( VL == NULL ) + VL = AddToCachedContactList(VLtemp.hContact,index); + + VL->hNext = (HANDLE)dbc->ofsNext; + if (VL->hNext != NULL && (!szProto || CheckProto(VL->hNext, szProto))) + return VL->hNext; + + VLtemp.hContact = VL->hNext; + } + + return NULL; +} + +STDMETHODIMP_(LONG) CDdxMmap::DeleteContact(HANDLE hContact) +{ + if (hContact == NULL) + return 1; + + mir_cslockfull lck(m_csDbAccess); + DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + return 1; + + if (hContact == (HANDLE)m_dbHeader.ofsUser) { + log0("FATAL: del of user chain attempted."); + return 1; + } + + lck.unlock(); + log0("del contact"); + + // call notifier while outside mutex + NotifyEventHooks(hContactDeletedEvent, (WPARAM)hContact, 0); + + // get back in + lck.lock(); + + DBCachedContactValueList VLtemp; + VLtemp.hContact = hContact; + int index; + if ((index = m_lContacts.getIndex(&VLtemp)) != -1) { + DBCachedContactValueList *VL = m_lContacts[index]; + DBCachedContactValue* V = VL->first; + while ( V != NULL ) { + DBCachedContactValue* V1 = V->next; + FreeCachedVariant(&V->value); + HeapFree( m_hCacheHeap, 0, V ); + V = V1; + } + HeapFree( m_hCacheHeap, 0, VL ); + + if (VLtemp.hContact == m_hLastCachedContact) + m_hLastCachedContact = NULL; + m_lContacts.remove(index); + } + + dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + //delete settings chain + DWORD ofsThis = dbc->ofsFirstSettings; + DWORD ofsFirstEvent = dbc->ofsFirstEvent; + while (ofsThis) { + DBContactSettings *dbcs = (DBContactSettings*)DBRead(ofsThis,sizeof(DBContactSettings),NULL); + DWORD ofsNext = dbcs->ofsNext; + DeleteSpace(ofsThis,offsetof(DBContactSettings,blob)+dbcs->cbBlob); + ofsThis = ofsNext; + } + //delete event chain + ofsThis = ofsFirstEvent; + while (ofsThis) { + DBEvent *dbe = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); + DWORD ofsNext = dbe->ofsNext; + DeleteSpace(ofsThis,offsetof(DBEvent,blob)+dbe->cbBlob); + ofsThis = ofsNext; + } + //find previous contact in chain and change ofsNext + dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + if (m_dbHeader.ofsFirstContact == (DWORD)hContact) { + m_dbHeader.ofsFirstContact = dbc->ofsNext; + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + } + else { + DWORD ofsNext = dbc->ofsNext; + ofsThis = m_dbHeader.ofsFirstContact; + DBContact *dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); + while (dbcPrev->ofsNext != (DWORD)hContact) { + if (dbcPrev->ofsNext == 0) DatabaseCorruption(NULL); + ofsThis = dbcPrev->ofsNext; + dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); + } + dbcPrev->ofsNext = ofsNext; + DBWrite(ofsThis,dbcPrev,sizeof(DBContact)); + + DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)ofsThis; + if ((index = m_lContacts.getIndex(&VLtemp)) != -1) { + DBCachedContactValueList *VL = m_lContacts[index]; + VL->hNext = (HANDLE)ofsNext; + } + } + + //delete contact + DeleteSpace((DWORD)hContact, sizeof(DBContact)); + //decrement contact count + m_dbHeader.contactCount--; + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + DBFlush(0); + return 0; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::AddContact() +{ + DWORD ofsNew; + log0("add contact"); + { + mir_cslock lck(m_csDbAccess); + ofsNew = CreateNewSpace(sizeof(DBContact)); + + DBContact dbc = { 0 }; + dbc.signature = DBCONTACT_SIGNATURE; + dbc.ofsNext = m_dbHeader.ofsFirstContact; + m_dbHeader.ofsFirstContact = ofsNew; + m_dbHeader.contactCount++; + DBWrite(ofsNew,&dbc,sizeof(DBContact)); + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + DBFlush(0); + + AddToCachedContactList((HANDLE)ofsNew, -1); + } + + NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); + return (HANDLE)ofsNew; +} + +STDMETHODIMP_(BOOL) CDdxMmap::IsDbContact(HANDLE hContact) +{ + mir_cslock lck(m_csDbAccess); + + DBCachedContactValueList VLtemp; + VLtemp.hContact = hContact; + int index = m_lContacts.getIndex(&VLtemp); + if (index != -1) + return TRUE; + + DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); + if (dbc->signature == DBCONTACT_SIGNATURE) { + AddToCachedContactList(hContact, index); + return TRUE; + } + + return FALSE; +} -- cgit v1.2.3