From 7aff1e4cb053394db57c2814d5fe1e6493e0cc75 Mon Sep 17 00:00:00 2001 From: watcherhd Date: Sat, 26 Nov 2011 14:19:43 +0000 Subject: Project folders rename part 2 git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@214 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- Dbx_mmap_SA/dbcontacts.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 Dbx_mmap_SA/dbcontacts.c (limited to 'Dbx_mmap_SA/dbcontacts.c') diff --git a/Dbx_mmap_SA/dbcontacts.c b/Dbx_mmap_SA/dbcontacts.c new file mode 100644 index 0000000..0803f1f --- /dev/null +++ b/Dbx_mmap_SA/dbcontacts.c @@ -0,0 +1,299 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM 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" + +extern HANDLE hCacheHeap; +extern SortedList lContacts; +extern HANDLE hLastCachedContact; + +INT_PTR GetContactSettingStatic(WPARAM wParam,LPARAM lParam); +void FreeCachedVariant( DBVARIANT* V ); + +static INT_PTR GetContactCount(WPARAM wParam,LPARAM lParam); +static INT_PTR FindFirstContact(WPARAM wParam,LPARAM lParam); +static INT_PTR FindNextContact(WPARAM wParam,LPARAM lParam); +static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam); +static INT_PTR AddContact(WPARAM wParam,LPARAM lParam); +static INT_PTR IsDbContact(WPARAM wParam,LPARAM lParam); + +static HANDLE hContactDeletedEvent,hContactAddedEvent; + + +int InitContacts(void) +{ + CreateServiceFunction(MS_DB_CONTACT_GETCOUNT,GetContactCount); + CreateServiceFunction(MS_DB_CONTACT_FINDFIRST,FindFirstContact); + CreateServiceFunction(MS_DB_CONTACT_FINDNEXT,FindNextContact); + CreateServiceFunction(MS_DB_CONTACT_DELETE,DeleteContact); + CreateServiceFunction(MS_DB_CONTACT_ADD,AddContact); + CreateServiceFunction(MS_DB_CONTACT_IS,IsDbContact); + hContactDeletedEvent=CreateHookableEvent(ME_DB_CONTACT_DELETED); + hContactAddedEvent=CreateHookableEvent(ME_DB_CONTACT_ADDED); + return 0; +} + +void UninitContacts(void) +{ +} + +DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index) +{ + DBCachedContactValueList* VL; + VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); + VL->hContact = hContact; + if (index == -1) li.List_GetIndex(&lContacts,VL,&index); + li.List_Insert(&lContacts,VL,index); + return VL; +} + +static INT_PTR GetContactCount(WPARAM wParam,LPARAM lParam) +{ + int ret; + + EnterCriticalSection(&csDbAccess); + ret=dbHeader.contactCount; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +#define proto_module "Protocol" +#define proto_setting "p" + +static int CheckProto(HANDLE hContact, const char *proto) +{ + static char protobuf[MAX_PATH] = {0}; + static DBVARIANT dbv; + static DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv}; + + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = protobuf; + dbv.cchVal = sizeof(protobuf); + + if (GetContactSettingStatic((WPARAM)hContact, (LPARAM )&sVal) != 0 + || (dbv.type != DBVT_ASCIIZ)) return 0; + + return !strcmp(protobuf,proto); +} + +static INT_PTR FindFirstContact(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret = 0; + EnterCriticalSection(&csDbAccess); + ret = (INT_PTR)dbHeader.ofsFirstContact; + if (lParam && !CheckProto((HANDLE)ret,(const char*)lParam)) + ret = FindNextContact((WPARAM)ret,lParam); + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindNextContact(WPARAM wParam,LPARAM lParam) +{ + int index; + struct DBContact *dbc; + DBCachedContactValueList VLtemp, *VL = NULL; + VLtemp.hContact = (HANDLE)wParam; + EnterCriticalSection(&csDbAccess); + while(VLtemp.hContact) { + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) { + VL = ( DBCachedContactValueList* )lContacts.items[index]; + if (VL->hNext != NULL) { + if (!lParam || CheckProto(VL->hNext,(const char*)lParam)) { + LeaveCriticalSection(&csDbAccess); + return (INT_PTR)VL->hNext; + } + else { + VLtemp.hContact = VL->hNext; + continue; + } } } + + dbc=(struct DBContact*)DBRead((DWORD)VLtemp.hContact,sizeof(struct DBContact),NULL); + if (dbc->signature!=DBCONTACT_SIGNATURE) + break; + else { + if ( VL == NULL ) + VL = AddToCachedContactList(VLtemp.hContact,index); + + VL->hNext = (HANDLE)dbc->ofsNext; + if (VL->hNext != NULL && (!lParam || CheckProto(VL->hNext,(const char*)lParam))) { + LeaveCriticalSection(&csDbAccess); + return (INT_PTR)VL->hNext; + } + VLtemp.hContact = VL->hNext; + } } + LeaveCriticalSection(&csDbAccess); + return 0; +} + +static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam) +{ + struct DBContact *dbc,*dbcPrev; + DWORD ofsThis,ofsNext,ofsFirstEvent; + struct DBContactSettings *dbcs; + struct DBEvent *dbe; + int index; + + if((HANDLE)wParam==NULL) return 1; + EnterCriticalSection(&csDbAccess); + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return 1; + } + if ( (HANDLE)wParam == (HANDLE)dbHeader.ofsUser ) { + LeaveCriticalSection(&csDbAccess); + log0("FATAL: del of user chain attempted."); + return 1; + } + log0("del contact"); + LeaveCriticalSection(&csDbAccess); + //call notifier while outside mutex + NotifyEventHooks(hContactDeletedEvent,wParam,0); + //get back in + EnterCriticalSection(&csDbAccess); + + { DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)wParam; + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) + { + DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; + DBCachedContactValue* V = VL->first; + while ( V != NULL ) { + DBCachedContactValue* V1 = V->next; + FreeCachedVariant(&V->value); + HeapFree( hCacheHeap, 0, V ); + V = V1; + } + HeapFree( hCacheHeap, 0, VL ); + + if (VLtemp.hContact == hLastCachedContact) + hLastCachedContact = NULL; + li.List_Remove(&lContacts,index); + } } + + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + //delete settings chain + ofsThis=dbc->ofsFirstSettings; + ofsFirstEvent=dbc->ofsFirstEvent; + while(ofsThis) { + dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); + ofsNext=dbcs->ofsNext; + DeleteSpace(ofsThis,offsetof(struct DBContactSettings,blob)+dbcs->cbBlob); + ofsThis=ofsNext; + } + //delete event chain + ofsThis=ofsFirstEvent; + while(ofsThis) { + dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); + ofsNext=dbe->ofsNext; + DeleteSpace(ofsThis,offsetof(struct DBEvent,blob)+dbe->cbBlob); + ofsThis=ofsNext; + } + //find previous contact in chain and change ofsNext + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbHeader.ofsFirstContact==wParam) { + dbHeader.ofsFirstContact=dbc->ofsNext; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + } + else { + ofsNext=dbc->ofsNext; + ofsThis=dbHeader.ofsFirstContact; + dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); + while(dbcPrev->ofsNext!=wParam) { + if(dbcPrev->ofsNext==0) DatabaseCorruption(NULL); + ofsThis=dbcPrev->ofsNext; + dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); + } + dbcPrev->ofsNext=ofsNext; + DBWrite(ofsThis,dbcPrev,sizeof(struct DBContact)); + { + DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)ofsThis; + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) + { + DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; + VL->hNext = ( HANDLE )ofsNext; + } } + } + //delete contact + DeleteSpace(wParam,sizeof(struct DBContact)); + //decrement contact count + dbHeader.contactCount--; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + DBFlush(0); + //quit + LeaveCriticalSection(&csDbAccess); + return 0; +} + +static INT_PTR AddContact(WPARAM wParam,LPARAM lParam) +{ + struct DBContact dbc; + DWORD ofsNew; + + log0("add contact"); + EnterCriticalSection(&csDbAccess); + ofsNew=CreateNewSpace(sizeof(struct DBContact)); + dbc.signature=DBCONTACT_SIGNATURE; + dbc.eventCount=0; + dbc.ofsFirstEvent=dbc.ofsLastEvent=0; + dbc.ofsFirstSettings=0; + dbc.ofsNext=dbHeader.ofsFirstContact; + dbc.ofsFirstUnreadEvent=0; + dbc.timestampFirstUnread=0; + dbHeader.ofsFirstContact=ofsNew; + dbHeader.contactCount++; + DBWrite(ofsNew,&dbc,sizeof(struct DBContact)); + DBWrite(0,&dbHeader,sizeof(dbHeader)); + DBFlush(0); + + AddToCachedContactList((HANDLE)ofsNew, -1); + + LeaveCriticalSection(&csDbAccess); + NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); + return (INT_PTR)ofsNew; +} + +static INT_PTR IsDbContact(WPARAM wParam,LPARAM lParam) +{ + struct DBContact *dbc; + DWORD ofsContact=(DWORD)wParam; + int ret; + + EnterCriticalSection(&csDbAccess); + { + int index; + DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)wParam; + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) + ret = TRUE; + else { + dbc=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + ret=dbc->signature==DBCONTACT_SIGNATURE; + if (ret) + AddToCachedContactList((HANDLE)wParam, index); + } } + + LeaveCriticalSection(&csDbAccess); + return ret; +} -- cgit v1.2.3