From 75115d35a7477110938f056a18edbbd43ac9a840 Mon Sep 17 00:00:00 2001 From: George Hazan <george.hazan@gmail.com> Date: Mon, 23 Jul 2012 21:15:40 +0000 Subject: db3x, finally git-svn-id: http://svn.miranda-ng.org/main/trunk@1144 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Db3x/db3x_10.vcxproj | 21 +- plugins/Db3x/db3x_10.vcxproj.filters | 42 +- plugins/Db3x/src/commonheaders.h | 12 +- plugins/Db3x/src/database.cpp | 153 ------ plugins/Db3x/src/database.h | 217 -------- plugins/Db3x/src/dbcache.cpp | 222 -------- plugins/Db3x/src/dbcache3x.cpp | 198 +++++++ plugins/Db3x/src/dbcontacts.cpp | 276 ---------- plugins/Db3x/src/dbevents.cpp | 407 --------------- plugins/Db3x/src/dbheaders.cpp | 74 --- plugins/Db3x/src/dbintf.cpp | 38 -- plugins/Db3x/src/dbintf.h | 68 --- plugins/Db3x/src/dbintf3x.cpp | 77 +++ plugins/Db3x/src/dbintf3x.h | 74 +++ plugins/Db3x/src/dbmodulechain.cpp | 128 ----- plugins/Db3x/src/dbsettings.cpp | 971 ----------------------------------- plugins/Db3x/src/init.cpp | 156 +++--- 17 files changed, 459 insertions(+), 2675 deletions(-) delete mode 100644 plugins/Db3x/src/database.cpp delete mode 100644 plugins/Db3x/src/database.h delete mode 100644 plugins/Db3x/src/dbcache.cpp create mode 100644 plugins/Db3x/src/dbcache3x.cpp delete mode 100644 plugins/Db3x/src/dbcontacts.cpp delete mode 100644 plugins/Db3x/src/dbevents.cpp delete mode 100644 plugins/Db3x/src/dbheaders.cpp delete mode 100644 plugins/Db3x/src/dbintf.cpp delete mode 100644 plugins/Db3x/src/dbintf.h create mode 100644 plugins/Db3x/src/dbintf3x.cpp create mode 100644 plugins/Db3x/src/dbintf3x.h delete mode 100644 plugins/Db3x/src/dbmodulechain.cpp delete mode 100644 plugins/Db3x/src/dbsettings.cpp (limited to 'plugins/Db3x') diff --git a/plugins/Db3x/db3x_10.vcxproj b/plugins/Db3x/db3x_10.vcxproj index 441e103858..68f34fdd90 100644 --- a/plugins/Db3x/db3x_10.vcxproj +++ b/plugins/Db3x/db3x_10.vcxproj @@ -199,22 +199,23 @@ </PreBuildEvent> </ItemDefinitionGroup> <ItemGroup> - <ClCompile Include="src\database.cpp" /> - <ClCompile Include="src\dbcache.cpp" /> - <ClCompile Include="src\dbcontacts.cpp" /> - <ClCompile Include="src\dbevents.cpp" /> - <ClCompile Include="src\dbheaders.cpp" /> - <ClCompile Include="src\dbintf.cpp" /> - <ClCompile Include="src\dbmodulechain.cpp" /> - <ClCompile Include="src\dbsettings.cpp" /> + <ClCompile Include="..\db3x_mmap\src\database.cpp" /> + <ClCompile Include="..\db3x_mmap\src\dbcontacts.cpp" /> + <ClCompile Include="..\db3x_mmap\src\dbevents.cpp" /> + <ClCompile Include="..\db3x_mmap\src\dbheaders.cpp" /> + <ClCompile Include="..\db3x_mmap\src\dbintf.cpp" /> + <ClCompile Include="..\db3x_mmap\src\dbmodulechain.cpp" /> + <ClCompile Include="..\db3x_mmap\src\dbsettings.cpp" /> + <ClCompile Include="src\dbcache3x.cpp" /> + <ClCompile Include="src\dbintf3x.cpp" /> <ClCompile Include="src\init.cpp"> <PrecompiledHeader>Create</PrecompiledHeader> </ClCompile> </ItemGroup> <ItemGroup> + <ClInclude Include="..\db3x_mmap\dbintf.h" /> <ClInclude Include="src\commonheaders.h" /> - <ClInclude Include="src\database.h" /> - <ClInclude Include="src\dbintf.h" /> + <ClInclude Include="src\dbintf3x.h" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="res\resource.rc" /> diff --git a/plugins/Db3x/db3x_10.vcxproj.filters b/plugins/Db3x/db3x_10.vcxproj.filters index 682ea4edc7..a5829dde98 100644 --- a/plugins/Db3x/db3x_10.vcxproj.filters +++ b/plugins/Db3x/db3x_10.vcxproj.filters @@ -13,45 +13,51 @@ <UniqueIdentifier>{fbaceae7-3e4a-4853-96f3-eec77981b2c9}</UniqueIdentifier> <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions> </Filter> + <Filter Include="Mmap"> + <UniqueIdentifier>{640c5715-0e22-4240-8520-f7dedfc9fb87}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> - <ClCompile Include="src\database.cpp"> + <ClCompile Include="src\init.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="src\dbcache.cpp"> + <ClCompile Include="src\dbintf3x.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="src\dbcontacts.cpp"> - <Filter>Source Files</Filter> + <ClCompile Include="..\db3x_mmap\src\database.cpp"> + <Filter>Mmap</Filter> </ClCompile> - <ClCompile Include="src\dbevents.cpp"> + <ClCompile Include="src\dbcache3x.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="src\dbheaders.cpp"> - <Filter>Source Files</Filter> + <ClCompile Include="..\db3x_mmap\src\dbcontacts.cpp"> + <Filter>Mmap</Filter> </ClCompile> - <ClCompile Include="src\dbmodulechain.cpp"> - <Filter>Source Files</Filter> + <ClCompile Include="..\db3x_mmap\src\dbevents.cpp"> + <Filter>Mmap</Filter> </ClCompile> - <ClCompile Include="src\dbsettings.cpp"> - <Filter>Source Files</Filter> + <ClCompile Include="..\db3x_mmap\src\dbheaders.cpp"> + <Filter>Mmap</Filter> </ClCompile> - <ClCompile Include="src\init.cpp"> - <Filter>Source Files</Filter> + <ClCompile Include="..\db3x_mmap\src\dbintf.cpp"> + <Filter>Mmap</Filter> </ClCompile> - <ClCompile Include="src\dbintf.cpp"> - <Filter>Source Files</Filter> + <ClCompile Include="..\db3x_mmap\src\dbmodulechain.cpp"> + <Filter>Mmap</Filter> + </ClCompile> + <ClCompile Include="..\db3x_mmap\src\dbsettings.cpp"> + <Filter>Mmap</Filter> </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="src\commonheaders.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="src\database.h"> + <ClInclude Include="src\dbintf3x.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="src\dbintf.h"> - <Filter>Header Files</Filter> + <ClInclude Include="..\db3x_mmap\dbintf.h"> + <Filter>Mmap</Filter> </ClInclude> </ItemGroup> <ItemGroup> diff --git a/plugins/Db3x/src/commonheaders.h b/plugins/Db3x/src/commonheaders.h index 52734be2d0..5175ad67b9 100644 --- a/plugins/Db3x/src/commonheaders.h +++ b/plugins/Db3x/src/commonheaders.h @@ -49,17 +49,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <m_langpack.h> #include "version.h" -#include "database.h" -#include "dbintf.h" +#include "dbintf3x.h" #include "resource.h" -extern HANDLE hDbFile; -extern CRITICAL_SECTION csDbAccess; -extern struct DBHeader dbHeader; -extern HANDLE hCacheHeap; -extern SortedList lContacts; -extern TCHAR szDbPath[MAX_PATH]; - #ifdef __GNUC__ #define mir_i64(x) (x##LL) #else @@ -69,3 +61,5 @@ extern TCHAR szDbPath[MAX_PATH]; #ifndef MODULAR void Encrypt(char*msg,BOOL up); #endif + +extern LIST<CDb3x> g_Dbs; diff --git a/plugins/Db3x/src/database.cpp b/plugins/Db3x/src/database.cpp deleted file mode 100644 index 50d51dde81..0000000000 --- a/plugins/Db3x/src/database.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - -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" - -int ProfileManager(char *szDbDest,int cbDbDest); -int ShouldAutoCreate(void); -int CreateDbHeaders(HANDLE hFile); -int InitialiseDbHeaders(void); -int InitSettings(void); -void UninitSettings(void); -int InitContacts(void); -void UninitContacts(void); -int InitEvents(void); -int InitModuleNames(void); -void UninitModuleNames(void); -int InitCache(void); -void UninitCache(void); -int InitIni(void); -void UninitIni(void); - -HANDLE hDbFile = INVALID_HANDLE_VALUE; -CRITICAL_SECTION csDbAccess; -struct DBHeader dbHeader; -TCHAR szDbPath[MAX_PATH]; - -static void UnloadDatabase(void) -{ - CloseHandle(hDbFile); -} - -DWORD CreateNewSpace(int bytes) -{ - DWORD ofsNew; - - ofsNew = dbHeader.ofsFileEnd; - dbHeader.ofsFileEnd += bytes; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - log2("newspace %d@%08x",bytes,ofsNew); - return ofsNew; -} - -void DeleteSpace(DWORD ofs,int bytes) -{ - PBYTE buf; - log2("deletespace %d@%08x",bytes,ofs); - dbHeader.slackSpace += bytes; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - buf = (PBYTE)mir_alloc(bytes); - memset(buf,0,bytes); - DBWrite(ofs,buf,bytes); - mir_free(buf); -} - -void UnloadDatabaseModule(void) -{ - UninitSettings(); - UninitContacts(); - UninitModuleNames(); - UninitCache(); - UnloadDatabase(); - DeleteCriticalSection(&csDbAccess); -} - -int LoadDatabaseModule(void) -{ - InitializeCriticalSection(&csDbAccess); - log0("DB logging running"); - { - DWORD dummy = 0; - hDbFile = CreateFile(szDbPath,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); - if ( hDbFile == INVALID_HANDLE_VALUE ) { - return 1; - } - if ( !ReadFile(hDbFile,&dbHeader,sizeof(dbHeader),&dummy,NULL)) { - CloseHandle(hDbFile); - return 1; - } - } - //if (ParseCommandLine()) return 1; - if (InitCache()) return 1; - if (InitModuleNames()) return 1; - if (InitContacts()) return 1; - if (InitSettings()) return 1; - if (InitEvents()) return 1; - return 0; -} - -static DWORD DatabaseCorrupted = 0; - -void __cdecl dbpanic(void *arg) -{ - MessageBox(0,TranslateT("Miranda has detected corruption in your database. This corruption maybe fixed by DBTool. Please download it from http://nightly.miranda.im/. Miranda will now shutdown."),TranslateT("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); - TerminateProcess(GetCurrentProcess(),255); - return; -} - -void DatabaseCorruption(void) -{ - int kill = 0; - - EnterCriticalSection(&csDbAccess); - if (DatabaseCorrupted == 0) { - DatabaseCorrupted++; - kill++; - } else { - /* db is already corrupted, someone else is dealing with it, wait here - so that we don't do any more damage */ - LeaveCriticalSection(&csDbAccess); - Sleep(INFINITE); - return; - } - LeaveCriticalSection(&csDbAccess); - if (kill) { - _beginthread(dbpanic,0,NULL); - Sleep(INFINITE); - } -} - -#ifdef DBLOGGING -void DBLog(const char *file,int line,const char *fmt,...) -{ - FILE *fp; - va_list vararg; - char str[1024]; - - va_start(vararg,fmt); - mir_vsnprintf(str,sizeof(str),fmt,vararg); - va_end(vararg); - fp = fopen("c:\\mirandadatabase.log.txt","at"); - fprintf(fp,"%u: %s %d: %s\n",GetTickCount(),file,line,str); - fclose(fp); -} -#endif diff --git a/plugins/Db3x/src/database.h b/plugins/Db3x/src/database.h deleted file mode 100644 index 2394655e73..0000000000 --- a/plugins/Db3x/src/database.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - -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. -*/ - - -//all offsets are relative to the start of the file -//offsets are 0 if there is nothing in the chain or this is the last in the -//chain - -/* tree diagram - -DBHeader - |-->end of file (plain offset) - |-->first contact (DBContact) - | |-->next contact (DBContact) - | | \--> ... - | |-->first settings (DBContactSettings) - | | |-->next settings (DBContactSettings) - | | | \--> ... - | | \-->module name (DBModuleName) - | \-->first/last/firstunread event - |-->user contact (DBContact) - | |-->next contact = NULL - | |-->first settings as above - | \-->first/last/firstunread event as above - \-->first module name (DBModuleName) - \-->next module name (DBModuleName) - \--> ... -*/ - -#define DB_RESIZE_GRANULARITY 16384 -#define DB_THIS_VERSION 0x00000700u -#define DB_SETTINGS_RESIZE_GRANULARITY 128 - -#include <pshpack1.h> -struct DBHeader { - BYTE signature[16]; // 'Miranda ICQ DB',0,26 - DWORD version; //as 4 bytes, ie 1.2.3.10 = 0x0102030a - //this version is 0x00000700 - DWORD ofsFileEnd; //offset of the end of the database - place to write - //new structures - DWORD slackSpace; //a counter of the number of bytes that have been - //wasted so far due to deleting structures and/or - //re-making them at the end. We should compact when - //this gets above a threshold - DWORD contactCount; //number of contacts in the chain,excluding the user - DWORD ofsFirstContact; //offset to first DBContact in the chain - DWORD ofsUser; //offset to DBContact representing the user - DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain -}; - -#define DBCONTACT_SIGNATURE 0x43DECADEu -struct DBContact { - DWORD signature; - DWORD ofsNext; //offset to the next contact in the chain. zero if - //this is the 'user' contact or the last contact - //in the chain - DWORD ofsFirstSettings; //offset to the first DBContactSettings in the - //chain for this contact. - DWORD eventCount; //number of events in the chain for this contact - DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in - //the chain for this contact - DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event - //in the chain, 0 if all are read - DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent -}; - -#define DBMODULENAME_SIGNATURE 0x4DDECADEu -struct DBModuleName { - DWORD signature; - DWORD ofsNext; //offset to the next module name in the chain - BYTE cbName; //number of characters in this module name - char name[1]; //name, no nul terminator -}; - -#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu -struct DBContactSettings { - DWORD signature; - DWORD ofsNext; //offset to the next contactsettings in the chain - DWORD ofsModuleName; //offset to the DBModuleName of the owner of these - //settings - DWORD cbBlob; //size of the blob in bytes. May be larger than the - //actual size for reducing the number of moves - //required using granularity in resizing - BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting - //structs, the last has cbName = 0 -}; - -/* not a valid structure, content is figured out on the fly -struct DBSetting { - BYTE cbName; //number of bytes in the name of this setting - //this = 0 marks the end - char szName[...]; //setting name, excluding nul - BYTE dataType; //type of data. see m_database.h, db/contact/getsetting - union { //a load of types of data, length is defined by dataType - BYTE bVal; WORD wVal; DWORD dVal; - struct { - WORD cbString; - char szVal[...]; //excludes nul terminator - }; - struct { - WORD cbBlob; - BYTE blobVal[...]; - }; - }; -}; -*/ - -#define DBEVENT_SIGNATURE 0x45DECADEu -struct DBEvent { - DWORD signature; - DWORD ofsPrev,ofsNext; //offset to the previous and next events in the - //chain. Chain is sorted chronologically - DWORD ofsModuleName; //offset to a DBModuleName struct of the name of - //the owner of this event - DWORD timestamp; //seconds since 00:00:00 01/01/1970 - DWORD flags; //see m_database.h, db/event/add - WORD eventType; //module-defined event type - DWORD cbBlob; //number of bytes in the blob - BYTE blob[1]; //the blob. module-defined formatting -}; -#include <poppack.h> - -typedef struct -{ - BYTE bIsResident; - char name[1]; -} - DBCachedSettingName; - -typedef struct -{ - char* name; - DBVARIANT value; -} - DBCachedGlobalValue; - -typedef struct DBCachedContactValue_tag -{ - char* name; - DBVARIANT value; - struct DBCachedContactValue_tag* next; -} - DBCachedContactValue; - -typedef struct -{ - HANDLE hContact; - HANDLE hNext; - DBCachedContactValue* first; -} - DBCachedContactValueList; - - -//databasecorruption: called if any signatures are broken. very very fatal -void DatabaseCorruption(void); -PBYTE DBRead(DWORD ofs,int bytesRequired,int *bytesAvail); //any preview result could be invalidated by the next call -__forceinline PBYTE DBRead(HANDLE hContact,int bytesRequired,int *bytesAvail) -{ return DBRead((DWORD)hContact, bytesRequired, bytesAvail); -} -void DBWrite(DWORD ofs,PVOID pData,int count); -void DBFlush(int setting); -void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes); -DWORD CreateNewSpace(int bytes); -void DeleteSpace(DWORD ofs,int bytes); -void GetProfileDirectory(char *szPath,int cbPath); -int GetDefaultProfilePath(char *szPath,int cbPath,int *specified); -int ShouldShowProfileManager(void); -int CheckDbHeaders(struct DBHeader * hdr); -int CreateDbHeaders(HANDLE hFile); -int LoadDatabaseModule(void); -void UnloadDatabaseModule(void); - -#ifdef _DEBUG -#define MAXCACHEDREADSIZE 512 -#else -#define MAXCACHEDREADSIZE 2048 //push it to 1K //technically 4096 would work, but I'm not going to push it -#endif - -#ifdef _DEBUG -//#define DBLOGGING -#endif -#ifdef DBLOGGING -void DBLog(const char *file,int line,const char *fmt,...); -#define logg() DBLog(__FILE__,__LINE__,"") -#define log0(s) DBLog(__FILE__,__LINE__,s) -#define log1(s,a) DBLog(__FILE__,__LINE__,s,a) -#define log2(s,a,b) DBLog(__FILE__,__LINE__,s,a,b) -#define log3(s,a,b,c) DBLog(__FILE__,__LINE__,s,a,b,c) -#define log4(s,a,b,c,d) DBLog(__FILE__,__LINE__,s,a,b,c,d) -#else -#define logg() -#define log0(s) -#define log1(s,a) -#define log2(s,a,b) -#define log3(s,a,b,c) -#define log4(s,a,b,c,d) -#endif diff --git a/plugins/Db3x/src/dbcache.cpp b/plugins/Db3x/src/dbcache.cpp deleted file mode 100644 index c68db53a0a..0000000000 --- a/plugins/Db3x/src/dbcache.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - -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" - -#define CACHESECTIONSIZE 4096 -#define CACHESECTIONCOUNT 32 - -static BOOL safetyMode = TRUE; -static PBYTE pDbCache; -static DWORD lastUseCounter; -struct DBCacheSectionInfo { - DWORD ofsBase; - DWORD lastUsed; -} static cacheSectionInfo[CACHESECTIONCOUNT]; - -static __inline int FindSectionForOffset(const DWORD ofs) -{ - int i; - for(i = 0;i<CACHESECTIONCOUNT;i++) - if (ofs >= cacheSectionInfo[i].ofsBase && ofs<cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) - return i; - return -1; -} - -static __inline int FindLRUSection(void) -{ - int i,lru = 0; - DWORD lowestLastUse = cacheSectionInfo[0].lastUsed; - for(i = 1;i<CACHESECTIONCOUNT;i++) if (cacheSectionInfo[i].lastUsed<lowestLastUse) {lru = i; lowestLastUse = cacheSectionInfo[i].lastUsed;} - return lru; -} - -static __inline void LoadSection(const int i,DWORD ofs) -{ - cacheSectionInfo[i].ofsBase = ofs-ofs%CACHESECTIONSIZE; - log1("readsect %08x",ofs); - SetFilePointer(hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN); - ReadFile(hDbFile,pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&ofs,NULL); -} - -static __inline void MoveSection(int *sectId,int dest) -{ - CopyMemory(pDbCache+dest*CACHESECTIONSIZE,pDbCache+(*sectId)*CACHESECTIONSIZE,CACHESECTIONSIZE); - cacheSectionInfo[dest].ofsBase = cacheSectionInfo[*sectId].ofsBase; - *sectId = dest; -} - - - -//we are assumed to be in a mutex here -PBYTE DBRead(DWORD ofs,int bytesRequired,int *bytesAvail) -{ - - int part1sect; - int part2sect; - - - part1sect = FindSectionForOffset(ofs); - if (ofs%CACHESECTIONSIZE+bytesRequired<CACHESECTIONSIZE) { - //only one section required - if (part1sect == -1) { - part1sect = FindLRUSection(); - LoadSection(part1sect,ofs); - } - cacheSectionInfo[part1sect].lastUsed = ++lastUseCounter; - if (bytesAvail!= NULL) *bytesAvail = cacheSectionInfo[part1sect].ofsBase+CACHESECTIONSIZE-ofs; - return pDbCache+part1sect*CACHESECTIONSIZE+(ofs-cacheSectionInfo[part1sect].ofsBase); - } - //two sections are required - part2sect = FindSectionForOffset(ofs+CACHESECTIONSIZE); - if (part1sect!= -1) { - if (part2sect == -1) { //first part in cache, but not second part - if (part1sect == CACHESECTIONCOUNT-1) MoveSection(&part1sect,0); - LoadSection(part1sect+1,ofs+CACHESECTIONSIZE); - } - else if (part2sect!= part1sect+1) { //both parts are in cache, but not already consecutive - if (part1sect == CACHESECTIONCOUNT-1) { - //first part is at end, move to before second part - if (part2sect == 0) //second part is at start: need to move both - MoveSection(&part2sect,1); - MoveSection(&part1sect,part2sect-1); - } - else //move second part to after first part - MoveSection(&part2sect,part1sect+1); - } - } - else { - if (part2sect == -1) { //neither section is in cache - part1sect = 0; part2sect = 1; - LoadSection(part1sect,ofs); LoadSection(part2sect,ofs+CACHESECTIONSIZE); - } - else { //part 2 is in cache, but not part 1 - if (part2sect == 0) MoveSection(&part2sect,1); - part1sect = part2sect-1; - LoadSection(part1sect,ofs); - } - } - //both sections are now consecutive, starting at part1sect - cacheSectionInfo[part1sect].lastUsed = ++lastUseCounter; - cacheSectionInfo[part1sect+1].lastUsed = ++lastUseCounter; - if (bytesAvail!= NULL) *bytesAvail = cacheSectionInfo[part1sect+1].ofsBase+CACHESECTIONSIZE-ofs; - return pDbCache+part1sect*CACHESECTIONSIZE+(ofs-cacheSectionInfo[part1sect].ofsBase); -} - - - -//we are assumed to be in a mutex here -void DBWrite(DWORD ofs,PVOID pData,int bytes) -{ - //write direct, and rely on Windows' write caching - DWORD bytesWritten; - int i; - - log2("write %d@%08x",bytes,ofs); - SetFilePointer(hDbFile,ofs,NULL,FILE_BEGIN); - if (WriteFile(hDbFile,pData,bytes,&bytesWritten,NULL) == 0) - { - DatabaseCorruption(); - } - logg(); - //check if any of the cache sections contain this bit - for(i = 0;i<CACHESECTIONCOUNT;i++) { - if (ofs+bytes >= cacheSectionInfo[i].ofsBase && ofs<cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) { - if (ofs<cacheSectionInfo[i].ofsBase) { //don't start at beginning - if (ofs+bytes >= cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end - CopyMemory(pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,CACHESECTIONSIZE); - else CopyMemory(pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,bytes-(cacheSectionInfo[i].ofsBase-ofs)); - } - else { //start at beginning - if (ofs+bytes >= cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end - CopyMemory(pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE-ofs); - else CopyMemory(pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,bytes); - } - } - } -} - -void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) -{ - DWORD bytesRead; - PBYTE buf; - - log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); - buf = (PBYTE)mir_alloc(bytes); - SetFilePointer(hDbFile,ofsSource,NULL,FILE_BEGIN); - ReadFile(hDbFile,buf,bytes,&bytesRead,NULL); - DBWrite(ofsDest,buf,bytes); - mir_free(buf); - logg(); -} - -static UINT_PTR flushBuffersTimerId; -static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd,UINT message,UINT_PTR idEvent,DWORD dwTime) -{ - KillTimer(NULL,flushBuffersTimerId); - log0("tflush1"); - FlushFileBuffers(hDbFile); - log0("tflush2"); -} - -void DBFlush(int setting) -{ - if (!setting) { - log0("nflush1"); - if (safetyMode) FlushFileBuffers(hDbFile); - log0("nflush2"); - return; - } - KillTimer(NULL,flushBuffersTimerId); - flushBuffersTimerId = SetTimer(NULL,flushBuffersTimerId,50,DoBufferFlushTimerProc); -} - -static INT_PTR CacheSetSafetyMode(WPARAM wParam,LPARAM lParam) -{ - EnterCriticalSection(&csDbAccess); - safetyMode = wParam; - LeaveCriticalSection(&csDbAccess); - if (safetyMode) FlushFileBuffers(hDbFile); - return 0; -} - -int InitCache(void) -{ - pDbCache = (PBYTE)mir_alloc(CACHESECTIONSIZE*CACHESECTIONCOUNT); - lastUseCounter = CACHESECTIONCOUNT; - for(int i = 0; i < CACHESECTIONCOUNT; i++) { - cacheSectionInfo[i].ofsBase = 0; - cacheSectionInfo[i].lastUsed = i; - SetFilePointer(hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN); - - DWORD bytesRead; - ReadFile(hDbFile,pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&bytesRead,NULL); - } - return 0; -} - -void UninitCache(void) -{ - mir_free(pDbCache); - KillTimer(NULL,flushBuffersTimerId); -} diff --git a/plugins/Db3x/src/dbcache3x.cpp b/plugins/Db3x/src/dbcache3x.cpp new file mode 100644 index 0000000000..5688ce0a53 --- /dev/null +++ b/plugins/Db3x/src/dbcache3x.cpp @@ -0,0 +1,198 @@ +/* + +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" + +int CDb3x::FindSectionForOffset(const DWORD ofs) +{ + for (int i = 0; i < CACHESECTIONCOUNT; i++) + if (ofs >= cacheSectionInfo[i].ofsBase && ofs<cacheSectionInfo[i].ofsBase + CACHESECTIONSIZE) + return i; + return -1; +} + +int CDb3x::FindLRUSection(void) +{ + int lru = 0; + DWORD lowestLastUse = cacheSectionInfo[0].lastUsed; + for (int i = 1; i < CACHESECTIONCOUNT; i++) + if (cacheSectionInfo[i].lastUsed < lowestLastUse) { + lru = i; + lowestLastUse = cacheSectionInfo[i].lastUsed; + } + return lru; +} + +void CDb3x::LoadSection(const int i,DWORD ofs) +{ + cacheSectionInfo[i].ofsBase = ofs - ofs%CACHESECTIONSIZE; + log1("readsect %08x",ofs); + SetFilePointer(m_hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN); + ReadFile(m_hDbFile,m_pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&ofs,NULL); +} + +void CDb3x::MoveSection(int *sectId,int dest) +{ + CopyMemory(m_pDbCache+dest*CACHESECTIONSIZE,m_pDbCache+(*sectId)*CACHESECTIONSIZE,CACHESECTIONSIZE); + cacheSectionInfo[dest].ofsBase = cacheSectionInfo[*sectId].ofsBase; + *sectId = dest; +} + +//we are assumed to be in a mutex here +PBYTE CDb3x::DBRead(DWORD ofs,int bytesRequired,int *bytesAvail) +{ + int part1sect = FindSectionForOffset(ofs); + if (ofs%CACHESECTIONSIZE+bytesRequired<CACHESECTIONSIZE) { + //only one section required + if (part1sect == -1) { + part1sect = FindLRUSection(); + LoadSection(part1sect,ofs); + } + cacheSectionInfo[part1sect].lastUsed = ++m_lastUseCounter; + if (bytesAvail!= NULL) *bytesAvail = cacheSectionInfo[part1sect].ofsBase+CACHESECTIONSIZE-ofs; + return m_pDbCache+part1sect*CACHESECTIONSIZE+(ofs-cacheSectionInfo[part1sect].ofsBase); + } + //two sections are required + int part2sect = FindSectionForOffset(ofs+CACHESECTIONSIZE); + if (part1sect != -1) { + if (part2sect == -1) { //first part in cache, but not second part + if (part1sect == CACHESECTIONCOUNT-1) MoveSection(&part1sect,0); + LoadSection(part1sect+1,ofs+CACHESECTIONSIZE); + } + else if (part2sect!= part1sect+1) { //both parts are in cache, but not already consecutive + if (part1sect == CACHESECTIONCOUNT-1) { + //first part is at end, move to before second part + if (part2sect == 0) //second part is at start: need to move both + MoveSection(&part2sect,1); + MoveSection(&part1sect,part2sect-1); + } + else //move second part to after first part + MoveSection(&part2sect,part1sect+1); + } + } + else { + if (part2sect == -1) { //neither section is in cache + part1sect = 0; part2sect = 1; + LoadSection(part1sect,ofs); LoadSection(part2sect,ofs+CACHESECTIONSIZE); + } + else { //part 2 is in cache, but not part 1 + if (part2sect == 0) MoveSection(&part2sect,1); + part1sect = part2sect-1; + LoadSection(part1sect,ofs); + } + } + + //both sections are now consecutive, starting at part1sect + cacheSectionInfo[part1sect].lastUsed = ++m_lastUseCounter; + cacheSectionInfo[part1sect+1].lastUsed = ++m_lastUseCounter; + if (bytesAvail!= NULL) + *bytesAvail = cacheSectionInfo[part1sect+1].ofsBase+CACHESECTIONSIZE-ofs; + return m_pDbCache+part1sect*CACHESECTIONSIZE+(ofs-cacheSectionInfo[part1sect].ofsBase); +} + +//we are assumed to be in a mutex here +void CDb3x::DBWrite(DWORD ofs,PVOID pData,int bytes) +{ + //write direct, and rely on Windows' write caching + log2("write %d@%08x", bytes, ofs); + SetFilePointer(m_hDbFile, ofs, NULL, FILE_BEGIN); + + DWORD bytesWritten; + if ( WriteFile(m_hDbFile, pData, bytes, &bytesWritten, NULL) == 0) + DatabaseCorruption( _T("%s (Write error)")); + + logg(); + + //check if any of the cache sections contain this bit + for(int i = 0; i < CACHESECTIONCOUNT; i++) { + if (ofs+bytes >= cacheSectionInfo[i].ofsBase && ofs<cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) { + if (ofs<cacheSectionInfo[i].ofsBase) { //don't start at beginning + if (ofs+bytes >= cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end + CopyMemory(m_pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,CACHESECTIONSIZE); + else CopyMemory(m_pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,bytes-(cacheSectionInfo[i].ofsBase-ofs)); + } + else { //start at beginning + if (ofs+bytes >= cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end + CopyMemory(m_pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE-ofs); + else CopyMemory(m_pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,bytes); + } + } + } +} + +void CDb3x::DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) +{ + DWORD bytesRead; + PBYTE buf; + + log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); + buf = (PBYTE)mir_alloc(bytes); + SetFilePointer(m_hDbFile,ofsSource,NULL,FILE_BEGIN); + ReadFile(m_hDbFile,buf,bytes,&bytesRead,NULL); + DBWrite(ofsDest,buf,bytes); + mir_free(buf); + logg(); +} + +static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd,UINT message,UINT_PTR idEvent,DWORD dwTime) +{ + for (int i=0; i < g_Dbs.getCount(); i++) { + CDb3x* db = g_Dbs[i]; + + KillTimer(NULL, db->m_flushBuffersTimerId); + log0("tflush1"); + FlushFileBuffers(db->getFile()); + log0("tflush2"); + } +} + +void CDb3x::DBFlush(int setting) +{ + if (!setting) { + log0("nflush1"); + if (m_safetyMode) FlushFileBuffers(m_hDbFile); + log0("nflush2"); + return; + } + KillTimer(NULL,m_flushBuffersTimerId); + m_flushBuffersTimerId = SetTimer(NULL,m_flushBuffersTimerId,50,DoBufferFlushTimerProc); +} + +void CDb3x::DBFill(DWORD ofs,int bytes) +{ +} + +int CDb3x::InitCache(void) +{ + m_pDbCache = (PBYTE)mir_alloc(CACHESECTIONSIZE*CACHESECTIONCOUNT); + m_lastUseCounter = CACHESECTIONCOUNT; + for(int i = 0; i < CACHESECTIONCOUNT; i++) { + cacheSectionInfo[i].ofsBase = 0; + cacheSectionInfo[i].lastUsed = i; + SetFilePointer(m_hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN); + + DWORD bytesRead; + ReadFile(m_hDbFile,m_pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&bytesRead,NULL); + } + return 0; +} diff --git a/plugins/Db3x/src/dbcontacts.cpp b/plugins/Db3x/src/dbcontacts.cpp deleted file mode 100644 index d0fb0bbc97..0000000000 --- a/plugins/Db3x/src/dbcontacts.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - -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" - -static HANDLE hContactDeletedEvent,hContactAddedEvent; - -int InitContacts(void) -{ - hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED); - hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED); - return 0; -} - -void UninitContacts(void) -{ -} - -INT_PTR GetContactSettingStatic(WPARAM wParam,LPARAM lParam); - -STDMETHODIMP_(LONG) CDdxMmap::GetContactCount(void) -{ - mir_cslock lck(csDbAccess); - return dbHeader.contactCount; -} - -#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_(HANDLE) CDdxMmap::FindFirstContact(const char* szProto) -{ - mir_cslock lck(csDbAccess); - - HANDLE ret = (HANDLE)dbHeader.ofsFirstContact; - if (szProto && !CheckProto(ret, szProto)) - ret = FindNextContact(ret, szProto); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindNextContact(HANDLE hContact, const char* szProto) -{ - DBCachedContactValueList VLtemp, *VL = NULL; - VLtemp.hContact = hContact; - - mir_cslock lck(csDbAccess); - - while ( VLtemp.hContact ) { - int index; - if ( List_GetIndex(&lContacts, &VLtemp, &index)) { - VL = ( DBCachedContactValueList* )lContacts.items[index]; - if (VL->hNext != NULL) { - if ( !szProto || CheckProto(VL->hNext, szProto)) - return VL->hNext; - - VLtemp.hContact = VL->hNext; - continue; - } } - - DBContact *dbc = (DBContact*)DBRead(VLtemp.hContact,sizeof(DBContact),NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - break; - - if ( VL == NULL ) { - VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); - VL->hContact = VLtemp.hContact; - List_Insert(&lContacts,VL,index); - } - VL->hNext = (HANDLE)dbc->ofsNext; - if (VL->hNext != NULL && (!szProto || CheckProto(VL->hNext, szProto))) - return VL->hNext; - - VLtemp.hContact = VL->hNext; - } - return 0; -} - -STDMETHODIMP_(LONG) CDdxMmap::DeleteContact(HANDLE hContact) -{ - DBContact *dbcPrev; - DWORD ofsThis,ofsNext,ofsFirstEvent; - DBContactSettings *dbcs; - DBEvent *dbe; - int index; - - if (hContact == NULL) return 1; - { - mir_cslock lck(csDbAccess); - - DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - return 1; - - if ((DWORD)hContact == dbHeader.ofsUser ) { - log0("FATAL: del of user chain attempted."); - return 1; - } - - log0("del contact"); - } - - //call notifier while outside mutex - NotifyEventHooks(hContactDeletedEvent, (WPARAM)hContact, 0); - - //get back in - mir_cslock lck(csDbAccess); - - DBCachedContactValueList VLtemp; - VLtemp.hContact = hContact; - if ( List_GetIndex(&lContacts,&VLtemp,&index)) - { - DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; - DBCachedContactValue* V = VL->first; - while ( V != NULL ) { - DBCachedContactValue* V1 = V->next; - if ( V->value.type == DBVT_ASCIIZ ) - HeapFree( hCacheHeap, 0, V->value.pszVal ); - HeapFree( hCacheHeap, 0, V ); - V = V1; - } - HeapFree( hCacheHeap, 0, VL ); - - List_Remove(&lContacts,index); - } - - DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(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 = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); - 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 (dbHeader.ofsFirstContact == (DWORD)hContact) { - dbHeader.ofsFirstContact = dbc->ofsNext; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - } - else { - ofsNext = dbc->ofsNext; - ofsThis = dbHeader.ofsFirstContact; - dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); - while(dbcPrev->ofsNext!= (DWORD)hContact) { - if (dbcPrev->ofsNext == 0) DatabaseCorruption(); - 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 ( List_GetIndex(&lContacts,&VLtemp,&index)) - { - DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; - VL->hNext = ( HANDLE )ofsNext; - } } - } - //delete contact - DeleteSpace((DWORD)hContact,sizeof(DBContact)); - //decrement contact count - dbHeader.contactCount--; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - DBFlush(0); - - //quit - return 0; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::AddContact(void) -{ - DBContact dbc; - DWORD ofsNew; - - log0("add contact"); - EnterCriticalSection(&csDbAccess); - ofsNew = CreateNewSpace(sizeof(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(DBContact)); - DBWrite(0,&dbHeader,sizeof(dbHeader)); - DBFlush(0); - - { int index; - - DBCachedContactValueList *VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); - VL->hContact = (HANDLE)ofsNew; - - List_GetIndex(&lContacts,VL,&index); - List_Insert(&lContacts,VL,index); - } - - LeaveCriticalSection(&csDbAccess); - NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); - return (HANDLE)ofsNew; -} - -STDMETHODIMP_(BOOL) CDdxMmap::IsDbContact(HANDLE hContact) -{ - DBContact dbc; - DWORD ofsContact = (DWORD)hContact; - INT_PTR ret; - - EnterCriticalSection(&csDbAccess); - { - int index; - DBCachedContactValueList VLtemp,*VL; - VLtemp.hContact = hContact; - if ( List_GetIndex(&lContacts,&VLtemp,&index)) - ret = TRUE; - else { - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - ret = dbc.signature == DBCONTACT_SIGNATURE; - - if (ret) { - VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); - VL->hContact = hContact; - List_Insert(&lContacts,VL,index); - } } } - - LeaveCriticalSection(&csDbAccess); - return ret; -} diff --git a/plugins/Db3x/src/dbevents.cpp b/plugins/Db3x/src/dbevents.cpp deleted file mode 100644 index 2deb70c647..0000000000 --- a/plugins/Db3x/src/dbevents.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - -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" - -DWORD GetModuleNameOfs(const char *szName); -char *GetModuleNameByOfs(DWORD ofs); - -static HANDLE hEventDeletedEvent,hEventAddedEvent,hEventFilterAddedEvent; - -STDMETHODIMP_(LONG) CDdxMmap::GetEventCount(HANDLE hContact) -{ - INT_PTR ret; - DBContact *dbc; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - dbc = (DBContact*)DBRead(hContact, sizeof(DBContact),NULL); - if (dbc->signature!= DBCONTACT_SIGNATURE) ret = -1; - else ret = dbc->eventCount; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::AddEvent(HANDLE hContact, DBEVENTINFO *dbei) -{ - DBContact dbc; - DBEvent dbe,*dbeTest; - DWORD ofsNew,ofsModuleName,ofsContact,ofsThis; - - if (dbei == NULL||dbei->cbSize!= sizeof(DBEVENTINFO)) return 0; - if (dbei->timestamp == 0) return 0; - if (NotifyEventHooks(hEventFilterAddedEvent, (WPARAM)hContact, (LPARAM)dbei)) - return 0; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - else - ofsContact = (DWORD)hContact; - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc.signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 0; - } - ofsNew = CreateNewSpace(offsetof(DBEvent,blob)+dbei->cbBlob); - ofsModuleName = GetModuleNameOfs(dbei->szModule); - - dbe.signature = DBEVENT_SIGNATURE; - dbe.ofsModuleName = ofsModuleName; - dbe.timestamp = dbei->timestamp; - dbe.flags = dbei->flags; - dbe.eventType = dbei->eventType; - dbe.cbBlob = dbei->cbBlob; - //find where to put it - sort by timestamp - if (dbc.eventCount == 0) { - dbe.ofsPrev = (DWORD)hContact; - dbe.ofsNext = 0; - dbe.flags |= DBEF_FIRST; - dbc.ofsFirstEvent = dbc.ofsLastEvent = ofsNew; - } - else { - dbeTest = (DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(DBEvent),NULL); - // Should new event be placed before first event in chain? - if (dbei->timestamp < dbeTest->timestamp) { - dbe.ofsPrev = (DWORD)hContact; - dbe.ofsNext = dbc.ofsFirstEvent; - dbe.flags |= DBEF_FIRST; - dbc.ofsFirstEvent = ofsNew; - dbeTest = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); - dbeTest->flags &= ~DBEF_FIRST; - dbeTest->ofsPrev = ofsNew; - DBWrite(dbe.ofsNext,dbeTest,sizeof(DBEvent)); - } - else { - // Loop through the chain, starting at the end - 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.timestampFirstUnread || dbc.timestampFirstUnread == 0) { - dbc.timestampFirstUnread = dbe.timestamp; - dbc.ofsFirstUnreadEvent = ofsNew; - } - } - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - DBWrite(ofsNew,&dbe,offsetof(DBEvent,blob)); - DBWrite(ofsNew+offsetof(DBEvent,blob),dbei->pBlob,dbei->cbBlob); - DBFlush(0); - LeaveCriticalSection(&csDbAccess); - log1("add event @ %08x",ofsNew); - NotifyEventHooks(hEventAddedEvent,(WPARAM)hContact,(LPARAM)ofsNew); - return (HANDLE)ofsNew; -} - -STDMETHODIMP_(BOOL) CDdxMmap::DeleteEvent(HANDLE hContact, HANDLE hDbEvent) -{ - DBContact dbc; - DWORD ofsContact,ofsThis; - DBEvent dbe,*dbeNext,*dbePrev; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - else - ofsContact = (DWORD)hContact; - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - dbe = *(DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbc.signature!= DBCONTACT_SIGNATURE || dbe.signature!= DBEVENT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - log1("delete event @ %08x",wParam); - LeaveCriticalSection(&csDbAccess); - - //call notifier while outside mutex - NotifyEventHooks(hEventDeletedEvent, (WPARAM)hContact, (LPARAM)hDbEvent); - - //get back in - EnterCriticalSection(&csDbAccess); - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - dbe = *(DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - //check if this was the first unread, if so, recalc the first unread - if (dbc.ofsFirstUnreadEvent == (DWORD)hDbEvent) { - dbeNext = &dbe; - for (;;) { - if (dbeNext->ofsNext == 0) { - dbc.ofsFirstUnreadEvent = 0; - dbc.timestampFirstUnread = 0; - break; - } - ofsThis = dbeNext->ofsNext; - dbeNext = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); - if (!(dbeNext->flags&(DBEF_READ|DBEF_SENT))) { - dbc.ofsFirstUnreadEvent = ofsThis; - dbc.timestampFirstUnread = dbeNext->timestamp; - break; - } - } - } - //get previous and next events in chain and change offsets - if (dbe.flags&DBEF_FIRST) { - if (dbe.ofsNext == 0) { - dbc.ofsFirstEvent = dbc.ofsLastEvent = 0; - } - else { - dbeNext = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); - dbeNext->flags |= DBEF_FIRST; - dbeNext->ofsPrev = dbe.ofsPrev; - DBWrite(dbe.ofsNext,dbeNext,sizeof(DBEvent)); - dbc.ofsFirstEvent = dbe.ofsNext; - } - } - else { - if (dbe.ofsNext == 0) { - dbePrev = (DBEvent*)DBRead(dbe.ofsPrev,sizeof(DBEvent),NULL); - dbePrev->ofsNext = 0; - DBWrite(dbe.ofsPrev,dbePrev,sizeof(DBEvent)); - dbc.ofsLastEvent = dbe.ofsPrev; - } - else { - dbePrev = (DBEvent*)DBRead(dbe.ofsPrev,sizeof(DBEvent),NULL); - dbePrev->ofsNext = dbe.ofsNext; - DBWrite(dbe.ofsPrev,dbePrev,sizeof(DBEvent)); - dbeNext = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); - dbeNext->ofsPrev = dbe.ofsPrev; - DBWrite(dbe.ofsNext,dbeNext,sizeof(DBEvent)); - } - } - //delete event - DeleteSpace((DWORD)hDbEvent,offsetof(DBEvent,blob)+dbe.cbBlob); - //decrement event count - dbc.eventCount--; - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - DBFlush(0); - //quit - LeaveCriticalSection(&csDbAccess); - return 0; -} - -STDMETHODIMP_(LONG) CDdxMmap::GetBlobSize(HANDLE hDbEvent) -{ - INT_PTR ret; - - EnterCriticalSection(&csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature!= DBEVENT_SIGNATURE) ret = -1; - else ret = dbe->cbBlob; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbei) -{ - int bytesToCopy,i; - - if (dbei == NULL||dbei->cbSize!= sizeof(DBEVENTINFO)) return 1; - if (dbei->cbBlob > 0 && dbei->pBlob == NULL) { - dbei->cbBlob = 0; - return 1; - } - EnterCriticalSection(&csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature!= DBEVENT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - dbei->szModule = GetModuleNameByOfs(dbe->ofsModuleName); - dbei->timestamp = dbe->timestamp; - dbei->flags = dbe->flags; - dbei->eventType = dbe->eventType; - if (dbei->cbBlob<dbe->cbBlob) bytesToCopy = dbei->cbBlob; - else bytesToCopy = dbe->cbBlob; - dbei->cbBlob = dbe->cbBlob; - for(i = 0;;i += MAXCACHEDREADSIZE) { - if (bytesToCopy-i <= MAXCACHEDREADSIZE) { - CopyMemory(dbei->pBlob+i,DBRead(DWORD(hDbEvent)+offsetof(DBEvent,blob)+i,bytesToCopy-i,NULL),bytesToCopy-i); - break; - } - CopyMemory(dbei->pBlob+i,DBRead(DWORD(hDbEvent)+offsetof(DBEvent,blob)+i,MAXCACHEDREADSIZE,NULL),MAXCACHEDREADSIZE); - } - LeaveCriticalSection(&csDbAccess); - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::MarkEventRead(HANDLE hContact, HANDLE hDbEvent) -{ - INT_PTR ret; - DWORD ofsThis; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - DBContact dbc = *(DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature!= DBEVENT_SIGNATURE || dbc.signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - if (dbe->flags & DBEF_READ || dbe->flags & DBEF_SENT) { - ret = (INT_PTR)dbe->flags; - LeaveCriticalSection(&csDbAccess); - return ret; - } - log1("mark read @ %08x",wParam); - dbe->flags |= DBEF_READ; - DBWrite((DWORD)hDbEvent, dbe, sizeof(DBEvent)); - ret = (INT_PTR)dbe->flags; - if (dbc.ofsFirstUnreadEvent == (DWORD)hDbEvent) { - for (;;) { - if (dbe->ofsNext == 0) { - dbc.ofsFirstUnreadEvent = 0; - dbc.timestampFirstUnread = 0; - break; - } - ofsThis = dbe->ofsNext; - dbe = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); - if (!(dbe->flags&(DBEF_READ|DBEF_SENT))) { - dbc.ofsFirstUnreadEvent = ofsThis; - dbc.timestampFirstUnread = dbe->timestamp; - break; - } - } - } - DBWrite((DWORD)hContact,&dbc,sizeof(DBContact)); - DBFlush(0); - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::GetEventContact(HANDLE hDbEvent) -{ - HANDLE ret; - - EnterCriticalSection(&csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature!= DBEVENT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return (HANDLE)-1; - } - while(!(dbe->flags & DBEF_FIRST)) - dbe = (DBEvent*)DBRead(dbe->ofsPrev,sizeof(DBEvent),NULL); - ret = (HANDLE)dbe->ofsPrev; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstEvent(HANDLE hContact) -{ - HANDLE ret; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature!= DBCONTACT_SIGNATURE) - ret = 0; - else - ret = (HANDLE)dbc->ofsFirstEvent; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstUnreadEvent(HANDLE hContact) -{ - HANDLE ret; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature!= DBCONTACT_SIGNATURE) ret = 0; - else ret = (HANDLE)dbc->ofsFirstUnreadEvent; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindLastEvent(HANDLE hContact) -{ - HANDLE ret; - - EnterCriticalSection(&csDbAccess); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature!= DBCONTACT_SIGNATURE) ret = 0; - else ret = (HANDLE)dbc->ofsLastEvent; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindNextEvent(HANDLE hDbEvent) -{ - HANDLE ret; - - EnterCriticalSection(&csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature!= DBEVENT_SIGNATURE) ret = 0; - else ret = (HANDLE)dbe->ofsNext; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindPrevEvent(HANDLE hDbEvent) -{ - HANDLE ret; - - EnterCriticalSection(&csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature!= DBEVENT_SIGNATURE) ret = 0; - else if (dbe->flags&DBEF_FIRST) ret = 0; - else ret = (HANDLE)dbe->ofsPrev; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -int InitEvents(void) -{ - hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED); - hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED); - hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); - return 0; -} diff --git a/plugins/Db3x/src/dbheaders.cpp b/plugins/Db3x/src/dbheaders.cpp deleted file mode 100644 index 7092dc4630..0000000000 --- a/plugins/Db3x/src/dbheaders.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - -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" - -struct DBSignature { - char name[15]; - BYTE eof; -}; -static struct DBSignature dbSignature = {"Miranda ICQ DB",0x1A}; - -//the cache has not been loaded when these functions are used - -int CreateDbHeaders(HANDLE hFile) -{ - DBContact user; - DWORD bytesWritten; - - CopyMemory(dbHeader.signature,&dbSignature,sizeof(dbHeader.signature)); - dbHeader.version = DB_THIS_VERSION; - dbHeader.ofsFileEnd = sizeof(struct DBHeader); - dbHeader.slackSpace = 0; - dbHeader.contactCount = 0; - dbHeader.ofsFirstContact = 0; - dbHeader.ofsFirstModuleName = 0; - dbHeader.ofsUser = 0; - //create user - dbHeader.ofsUser = dbHeader.ofsFileEnd; - dbHeader.ofsFileEnd += sizeof(DBContact); - SetFilePointer(hFile,0,NULL,FILE_BEGIN); - WriteFile(hFile,&dbHeader,sizeof(dbHeader),&bytesWritten,NULL); - user.signature = DBCONTACT_SIGNATURE; - user.ofsNext = 0; - user.ofsFirstSettings = 0; - user.eventCount = 0; - user.ofsFirstEvent = user.ofsLastEvent = 0; - SetFilePointer(hFile,dbHeader.ofsUser,NULL,FILE_BEGIN); - WriteFile(hFile,&user,sizeof(DBContact),&bytesWritten,NULL); - FlushFileBuffers(hFile); - return 0; -} - -int CheckDbHeaders(struct DBHeader * hdr) -{ - if (memcmp(hdr->signature,&dbSignature,sizeof(hdr->signature))) return 1; - if (hdr->version!= DB_THIS_VERSION) return 2; - if (hdr->ofsUser == 0) return 3; - return 0; -} - -int InitialiseDbHeaders(void) -{ - return 0; -} diff --git a/plugins/Db3x/src/dbintf.cpp b/plugins/Db3x/src/dbintf.cpp deleted file mode 100644 index c30d8206cc..0000000000 --- a/plugins/Db3x/src/dbintf.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - -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" - -extern BOOL safetyMode; - -CDdxMmap::CDdxMmap(const TCHAR* tszFileName) -{ -} - -STDMETHODIMP_(void) CDdxMmap::SetCacheSafetyMode(BOOL bIsSet) -{ - { mir_cslock lck(csDbAccess); - safetyMode = bIsSet; - } - DBFlush(1); -} diff --git a/plugins/Db3x/src/dbintf.h b/plugins/Db3x/src/dbintf.h deleted file mode 100644 index 6e9714640b..0000000000 --- a/plugins/Db3x/src/dbintf.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - -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 <m_db_int.h> - -struct CDdxMmap : public MIDatabase -{ - CDdxMmap(const TCHAR* tszFileName); - - STDMETHODIMP_(void) SetCacheSafetyMode(BOOL); - - STDMETHODIMP_(LONG) GetContactCount(void); - STDMETHODIMP_(HANDLE) FindFirstContact(const char* szProto = NULL); - STDMETHODIMP_(HANDLE) FindNextContact(HANDLE hContact, const char* szProto = NULL); - STDMETHODIMP_(LONG) DeleteContact(HANDLE hContact); - STDMETHODIMP_(HANDLE) AddContact(void); - STDMETHODIMP_(BOOL) IsDbContact(HANDLE hContact); - - STDMETHODIMP_(LONG) GetEventCount(HANDLE hContact); - STDMETHODIMP_(HANDLE) AddEvent(HANDLE hContact, DBEVENTINFO *dbei); - STDMETHODIMP_(BOOL) DeleteEvent(HANDLE hContact, HANDLE hDbEvent); - STDMETHODIMP_(LONG) GetBlobSize(HANDLE hDbEvent); - STDMETHODIMP_(BOOL) GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbei); - STDMETHODIMP_(BOOL) MarkEventRead(HANDLE hContact, HANDLE hDbEvent); - STDMETHODIMP_(HANDLE) GetEventContact(HANDLE hDbEvent); - STDMETHODIMP_(HANDLE) FindFirstEvent(HANDLE hContact); - STDMETHODIMP_(HANDLE) FindFirstUnreadEvent(HANDLE hContact); - STDMETHODIMP_(HANDLE) FindLastEvent(HANDLE hContact); - STDMETHODIMP_(HANDLE) FindNextEvent(HANDLE hDbEvent); - STDMETHODIMP_(HANDLE) FindPrevEvent(HANDLE hDbEvent); - - STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam); - - STDMETHODIMP_(BOOL) GetContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) GetContactSettingStr(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) GetContactSettingStatic(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv); - STDMETHODIMP_(BOOL) WriteContactSetting(HANDLE hContact, DBCONTACTWRITESETTING *dbcws); - STDMETHODIMP_(BOOL) DeleteContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) EnumContactSettings(HANDLE hContact, DBCONTACTENUMSETTINGS* dbces); - STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName); - STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam); - -private: - int CheckProto(HANDLE hContact, const char *proto); - - BOOL safetyMode; -}; diff --git a/plugins/Db3x/src/dbintf3x.cpp b/plugins/Db3x/src/dbintf3x.cpp new file mode 100644 index 0000000000..fcbfc8ce67 --- /dev/null +++ b/plugins/Db3x/src/dbintf3x.cpp @@ -0,0 +1,77 @@ +/* + +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" + +extern BOOL safetyMode; + +CDb3x::CDb3x(const TCHAR* tszFileName) : + CDb3Base(tszFileName) +{ +} + +CDb3x::~CDb3x() +{ + if (m_pDbCache) { + mir_free(m_pDbCache); + KillTimer(NULL,m_flushBuffersTimerId); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +//this function caches results +DWORD CDb3x::GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsContact,DWORD ofsModuleName) +{ + DBContactSettings *dbcs; + DWORD ofsThis; + + for ( int i=0; i < SETTINGSGROUPOFSCOUNT; i++) + if(settingsGroupOfsCache[i].ofsContact == ofsContact && settingsGroupOfsCache[i].ofsModuleName == ofsModuleName) + return settingsGroupOfsCache[i].ofsSettingsGroup; + + ofsThis = dbc->ofsFirstSettings; + while(ofsThis) { + dbcs = (struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); + if (dbcs->signature != DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption( _T("Invalid database module")); + if (dbcs->ofsModuleName == ofsModuleName) { + settingsGroupOfsCache[nextSGOCacheEntry].ofsContact = ofsContact; + settingsGroupOfsCache[nextSGOCacheEntry].ofsModuleName = ofsModuleName; + settingsGroupOfsCache[nextSGOCacheEntry].ofsSettingsGroup = ofsThis; + if(++nextSGOCacheEntry==SETTINGSGROUPOFSCOUNT) nextSGOCacheEntry = 0; + return ofsThis; + } + ofsThis = dbcs->ofsNext; + } + return 0; +} + +void CDb3x::InvalidateSettingsGroupOfsCacheEntry(DWORD ofsSettingsGroup) +{ + for (int i=0; i < SETTINGSGROUPOFSCOUNT; i++) { + if (settingsGroupOfsCache[i].ofsSettingsGroup == ofsSettingsGroup) { + settingsGroupOfsCache[i].ofsContact = 0; + settingsGroupOfsCache[i].ofsModuleName = 0; + settingsGroupOfsCache[i].ofsSettingsGroup = 0; + break; +} } } diff --git a/plugins/Db3x/src/dbintf3x.h b/plugins/Db3x/src/dbintf3x.h new file mode 100644 index 0000000000..74dad4c4a8 --- /dev/null +++ b/plugins/Db3x/src/dbintf3x.h @@ -0,0 +1,74 @@ +/* + +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 <m_db_int.h> + +#include "..\..\Db3x_mmap\src\database.h" +#include "..\..\Db3x_mmap\src\dbintf.h" + +#define CACHESECTIONSIZE 4096 +#define CACHESECTIONCOUNT 32 + +#define SETTINGSGROUPOFSCOUNT 32 + +struct CDb3x : public CDb3Base +{ + CDb3x(const TCHAR* tszFileName); + ~CDb3x(); + + __inline HANDLE getFile() const { return m_hDbFile; } + +protected: + virtual DWORD GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsContact,DWORD ofsModuleName); + virtual void DBMoveChunk(DWORD ofsDest, DWORD ofsSource, int bytes); + virtual PBYTE DBRead(DWORD ofs, int bytesRequired, int *bytesAvail); + virtual void DBWrite(DWORD ofs, PVOID pData, int bytes); + virtual void DBFill(DWORD ofs, int bytes); + virtual void DBFlush(int setting); + virtual int InitCache(void); + + PBYTE m_pDbCache; + DWORD m_lastUseCounter; + + struct DBCacheSectionInfo + { + DWORD ofsBase; + DWORD lastUsed; + } + cacheSectionInfo[CACHESECTIONCOUNT]; + + int nextSGOCacheEntry; + struct SettingsGroupOfsCacheEntry { + DWORD ofsContact; + DWORD ofsModuleName; + DWORD ofsSettingsGroup; + } + settingsGroupOfsCache[SETTINGSGROUPOFSCOUNT]; + + int FindSectionForOffset(const DWORD ofs); + int FindLRUSection(void); + void LoadSection(const int i,DWORD ofs); + void MoveSection(int *sectId,int dest); + + void InvalidateSettingsGroupOfsCacheEntry(DWORD ofsSettingsGroup); +}; diff --git a/plugins/Db3x/src/dbmodulechain.cpp b/plugins/Db3x/src/dbmodulechain.cpp deleted file mode 100644 index fb7c6e4ce3..0000000000 --- a/plugins/Db3x/src/dbmodulechain.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - -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" - -static INT_PTR EnumModuleNames(WPARAM wParam,LPARAM lParam); - -struct ModuleName { - char *name; - DWORD hash; - DWORD ofs; -}; -static struct ModuleName *moduleName; -static int moduleNameCount; - -int InitModuleNames(void) -{ - struct DBModuleName *dbmn; - DWORD ofsThis,ofsNext; - int nameLen; - - moduleNameCount = 0; - moduleName = NULL; - ofsThis = dbHeader.ofsFirstModuleName; - dbmn = (struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); - while(ofsThis) { - if (dbmn->signature!= DBMODULENAME_SIGNATURE) DatabaseCorruption(); - moduleName = (struct ModuleName*)mir_realloc(moduleName,sizeof(struct ModuleName)*(moduleNameCount+1)); - moduleName[moduleNameCount].ofs = ofsThis; - moduleName[moduleNameCount].hash = dbmn->cbName; //very very simple hash so far - moduleName[moduleNameCount].name = (char*)mir_alloc(dbmn->cbName+1); - ofsNext = dbmn->ofsNext; - nameLen = dbmn->cbName; - CopyMemory(moduleName[moduleNameCount].name,DBRead(ofsThis+offsetof(struct DBModuleName,name),nameLen,NULL),nameLen); - moduleName[moduleNameCount].name[nameLen] = 0; - moduleNameCount++; - ofsThis = ofsNext; - dbmn = (struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); - } - return 0; -} - -void UninitModuleNames(void) -{ - int i; - for(i = 0;i<moduleNameCount;i++) mir_free(moduleName[i].name); - if (moduleNameCount) mir_free(moduleName); -} - -static DWORD FindExistingModuleNameOfs(const char *szName,int nameLen) -{ - int i; - for(i = 0;i<moduleNameCount;i++) - if (moduleName[i].hash == (DWORD)nameLen && !strcmp(moduleName[i].name,szName)) return moduleName[i].ofs; - return 0; -} - -//will create the offset if it needs to -DWORD GetModuleNameOfs(const char *szName) -{ - struct DBModuleName dbmn; - int nameLen = (int)strlen(szName); - DWORD ofsNew,ofsExisting; - - ofsExisting = FindExistingModuleNameOfs(szName,nameLen); - if (ofsExisting) return ofsExisting; - //need to create the module name - ofsNew = CreateNewSpace(nameLen+offsetof(struct DBModuleName,name)); - dbmn.signature = DBMODULENAME_SIGNATURE; - dbmn.cbName = nameLen; - dbmn.ofsNext = dbHeader.ofsFirstModuleName; - dbHeader.ofsFirstModuleName = ofsNew; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - DBWrite(ofsNew,&dbmn,offsetof(struct DBModuleName,name)); - DBWrite(ofsNew+offsetof(struct DBModuleName,name),(PVOID)szName,nameLen); - DBFlush(0); - //add to cache - moduleName = (struct ModuleName*)mir_realloc(moduleName,sizeof(struct ModuleName)*(moduleNameCount+1)); - moduleName[moduleNameCount].ofs = ofsNew; - moduleName[moduleNameCount].hash = nameLen; //very very simple hash so far - moduleName[moduleNameCount].name = (char*)mir_alloc(nameLen+1); - strcpy(moduleName[moduleNameCount].name,szName); - moduleNameCount++; - //quit - return ofsNew; -} - -//it's OK that this is a bit slow - it's rarely used -char *GetModuleNameByOfs(DWORD ofs) -{ - int i; - - for(i = 0;i<moduleNameCount;i++) - if (moduleName[i].ofs == ofs) return moduleName[i].name; - DatabaseCorruption(); - return NULL; -} - -STDMETHODIMP_(BOOL) CDdxMmap::EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) -{ - int i; - INT_PTR ret; - for(i = 0;i<moduleNameCount;i++) { - ret = pFunc(moduleName[i].name,moduleName[i].ofs, (LPARAM)pParam); - if (ret) return ret; - } - return 0; -} diff --git a/plugins/Db3x/src/dbsettings.cpp b/plugins/Db3x/src/dbsettings.cpp deleted file mode 100644 index db21b64db8..0000000000 --- a/plugins/Db3x/src/dbsettings.cpp +++ /dev/null @@ -1,971 +0,0 @@ -/* - -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" - -DWORD GetModuleNameOfs(const char *szName); - -HANDLE hCacheHeap = NULL; -SortedList lContacts; - -static SortedList lSettings, lGlobalSettings; -static HANDLE hSettingChangeEvent = NULL; - -#define SETTINGSGROUPOFSCOUNT 32 -struct SettingsGroupOfsCacheEntry { - DWORD ofsContact; - DWORD ofsModuleName; - DWORD ofsSettingsGroup; -}; -static struct SettingsGroupOfsCacheEntry settingsGroupOfsCache[SETTINGSGROUPOFSCOUNT]; -static int nextSGOCacheEntry; -static int mirCp = CP_ACP; - -//this function caches results -static DWORD GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsContact,DWORD ofsModuleName) -{ - struct DBContactSettings *dbcs; - DWORD ofsThis; - int i; - - for(i = 0;i<SETTINGSGROUPOFSCOUNT;i++) { - if (settingsGroupOfsCache[i].ofsContact == ofsContact && settingsGroupOfsCache[i].ofsModuleName == ofsModuleName) - return settingsGroupOfsCache[i].ofsSettingsGroup; - } - ofsThis = dbc->ofsFirstSettings; - while(ofsThis) { - dbcs = (struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); - if (dbcs->signature!= DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption(); - if (dbcs->ofsModuleName == ofsModuleName) { - settingsGroupOfsCache[nextSGOCacheEntry].ofsContact = ofsContact; - settingsGroupOfsCache[nextSGOCacheEntry].ofsModuleName = ofsModuleName; - settingsGroupOfsCache[nextSGOCacheEntry].ofsSettingsGroup = ofsThis; - if (++nextSGOCacheEntry == SETTINGSGROUPOFSCOUNT) nextSGOCacheEntry = 0; - return ofsThis; - } - ofsThis = dbcs->ofsNext; - } - return 0; -} - -static void InvalidateSettingsGroupOfsCacheEntry(DWORD ofsSettingsGroup) -{ - for(int i = 0;i<SETTINGSGROUPOFSCOUNT;i++) { - if (settingsGroupOfsCache[i].ofsSettingsGroup == ofsSettingsGroup) { - settingsGroupOfsCache[i].ofsContact = 0; - settingsGroupOfsCache[i].ofsModuleName = 0; - settingsGroupOfsCache[i].ofsSettingsGroup = 0; - break; -} } } - -static DWORD __inline GetSettingValueLength(PBYTE pSetting) -{ - if (pSetting[0]&DBVTF_VARIABLELENGTH) return 2+*(PWORD)(pSetting+1); - return pSetting[0]; -} - -static char* InsertCachedSetting( const char* szName, size_t cbNameLen, int index ) -{ - char* newValue = (char*)HeapAlloc( hCacheHeap, 0, cbNameLen ); - *newValue = 0; - strcpy(newValue+1,szName+1); - List_Insert(&lSettings,newValue,index); - return newValue; -} - -static char* GetCachedSetting(const char *szModuleName,const char *szSettingName,int settingNameLen) -{ - static char *lastsetting = NULL; - int moduleNameLen = (int)strlen(szModuleName),index; - char *szFullName = (char*)alloca(moduleNameLen+settingNameLen+3); - - strcpy(szFullName+1,szModuleName); - szFullName[moduleNameLen+1] = '/'; - strcpy(szFullName+moduleNameLen+2,szSettingName); - - if (lastsetting && strcmp(szFullName+1,lastsetting) == 0) - return lastsetting; - - if ( List_GetIndex(&lSettings, szFullName, &index)) - lastsetting = (char*)lSettings.items[index] + 1; - else - lastsetting = InsertCachedSetting( szFullName, moduleNameLen+settingNameLen+3, index )+1; - return lastsetting; -} - -static void SetCachedVariant( DBVARIANT* s /* new */, DBVARIANT* d /* cached */ ) -{ - char* szSave = ( d->type == DBVT_UTF8 || d->type == DBVT_ASCIIZ ) ? d->pszVal : NULL; - - memcpy( d, s, sizeof( DBVARIANT )); - if (( s->type == DBVT_UTF8 || s->type == DBVT_ASCIIZ ) && s->pszVal != NULL ) { - if ( szSave != NULL ) - d->pszVal = (char*)HeapReAlloc(hCacheHeap,0,szSave,strlen(s->pszVal)+1); - else - d->pszVal = (char*)HeapAlloc(hCacheHeap,0,strlen(s->pszVal)+1); - strcpy(d->pszVal,s->pszVal); - } - - switch( d->type ) { - case DBVT_BYTE: log1( "set cached byte: %d", d->bVal ); break; - case DBVT_WORD: log1( "set cached word: %d", d->wVal ); break; - case DBVT_DWORD: log1( "set cached dword: %d", d->dVal ); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: log1( "set cached string: '%s'", d->pszVal ); break; - default: log1( "set cached crap: %d", d->type ); break; -} } - -static void FreeCachedVariant( DBVARIANT* V ) -{ - if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL ) - HeapFree(hCacheHeap,0,V->pszVal); -} - -static DBVARIANT* GetCachedValuePtr( HANDLE hContact, char* szSetting, int bAllocate ) -{ - int index; - - if ( hContact == 0 ) { - DBCachedGlobalValue Vtemp, *V; - Vtemp.name = szSetting; - if ( List_GetIndex(&lGlobalSettings,&Vtemp,&index)) { - V = (DBCachedGlobalValue*)lGlobalSettings.items[index]; - if ( bAllocate == -1 ) { - FreeCachedVariant( &V->value ); - List_Remove(&lGlobalSettings,index); - HeapFree(hCacheHeap,0,V); - return NULL; - } } - else { - if ( bAllocate != 1 ) - return NULL; - - V = (DBCachedGlobalValue*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue)); - V->name = szSetting; - List_Insert(&lGlobalSettings,V,index); - } - - return &V->value; - } - else { - DBCachedContactValue *V, *V1; - DBCachedContactValueList VLtemp,*VL; - - VLtemp.hContact = hContact; - if ( List_GetIndex(&lContacts,&VLtemp,&index)) { - VL = (DBCachedContactValueList*)lContacts.items[index]; - } - else { - if ( bAllocate != 1 ) - return NULL; - - VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); - VL->hContact = hContact; - List_Insert(&lContacts,VL,index); - } - - for ( V = VL->first; V != NULL; V = V->next) - if (strcmp(V->name,szSetting) == 0) - break; - - if ( V == NULL ) { - if ( bAllocate != 1 ) - return NULL; - - V = (DBCachedContactValue *)HeapAlloc(hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContactValue)); - V->next = VL->first; - VL->first = V; - V->name = szSetting; - } - else if ( bAllocate == -1 ) { - FreeCachedVariant(&V->value); - if ( VL->first == V ) - VL->first = V->next; - for ( V1 = VL->first; V1 != NULL; V1 = V1->next ) - if ( V1->next == V ) { - V1->next = V->next; - break; - } - HeapFree(hCacheHeap,0,V); - return NULL; - } - - return &V->value; -} } - -#define NeedBytes(n) if (bytesRemaining<(n)) pBlob = (PBYTE)DBRead(ofsBlobPtr,(n),&bytesRemaining) -#define MoveAlong(n) {int x = n; pBlob += (x); ofsBlobPtr += (x); bytesRemaining -= (x);} -#define VLT(n) ((n == DBVT_UTF8)?DBVT_ASCIIZ:n) -static __inline int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic) -{ - DBContact dbc; - struct DBContactSettings dbcs; - DWORD ofsModuleName,ofsContact,ofsSettingsGroup,ofsBlobPtr; - int settingNameLen; - int bytesRemaining; - PBYTE pBlob; - char* szCachedSettingName; - - if ((!dbcgs->szSetting) || (!dbcgs->szModule)) - return 1; - settingNameLen = (int)strlen(dbcgs->szSetting); - - EnterCriticalSection(&csDbAccess); - - log3("get [%08p] %s/%s",hContact,dbcgs->szModule,dbcgs->szSetting); - - szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,settingNameLen); - { - DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 0 ); - if ( pCachedValue != NULL ) { - if ( pCachedValue->type == DBVT_ASCIIZ || pCachedValue->type == DBVT_UTF8 ) { - int cbOrigLen = dbcgs->pValue->cchVal; - char* cbOrigPtr = dbcgs->pValue->pszVal; - memcpy( dbcgs->pValue, pCachedValue, sizeof( DBVARIANT )); - if ( isStatic ) { - int cbLen = 0; - if ( pCachedValue->pszVal != NULL ) - cbLen = (int)strlen( pCachedValue->pszVal ); - - cbOrigLen--; - dbcgs->pValue->pszVal = cbOrigPtr; - if (cbLen<cbOrigLen) cbOrigLen = cbLen; - CopyMemory(dbcgs->pValue->pszVal,pCachedValue->pszVal,cbOrigLen); - dbcgs->pValue->pszVal[cbOrigLen] = 0; - dbcgs->pValue->cchVal = cbLen; - } - else { - dbcgs->pValue->pszVal = (char*)mir_alloc(strlen(pCachedValue->pszVal)+1); - strcpy(dbcgs->pValue->pszVal,pCachedValue->pszVal); - } - } - else - memcpy( dbcgs->pValue, pCachedValue, sizeof( DBVARIANT )); - - switch( dbcgs->pValue->type ) { - case DBVT_BYTE: log1( "get cached byte: %d", dbcgs->pValue->bVal ); break; - case DBVT_WORD: log1( "get cached word: %d", dbcgs->pValue->wVal ); break; - case DBVT_DWORD: log1( "get cached dword: %d", dbcgs->pValue->dVal ); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: log1( "get cached string: '%s'", dbcgs->pValue->pszVal); break; - default: log1( "get cached crap: %d", dbcgs->pValue->type ); break; - } - - LeaveCriticalSection(&csDbAccess); - return ( pCachedValue->type == DBVT_DELETED ) ? 1 : 0; - } } - - ofsModuleName = GetModuleNameOfs(dbcgs->szModule); - if (hContact == NULL) ofsContact = dbHeader.ofsUser; - else ofsContact = (DWORD)hContact; - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc.signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName); - if (ofsSettingsGroup) { - dbcs = *(struct DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(struct DBContactSettings),&bytesRemaining); - ofsBlobPtr = ofsSettingsGroup+offsetof(struct DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - while(pBlob[0]) { - NeedBytes(1+settingNameLen); - if (pBlob[0] == settingNameLen && !memcmp(pBlob+1,dbcgs->szSetting,settingNameLen)) { - MoveAlong(1+settingNameLen); - NeedBytes(5); - if (isStatic && pBlob[0]&DBVTF_VARIABLELENGTH && VLT(dbcgs->pValue->type) != VLT(pBlob[0])) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - dbcgs->pValue->type = pBlob[0]; - switch(pBlob[0]) { - case DBVT_DELETED: { /* this setting is deleted */ - dbcgs->pValue->type = DBVT_DELETED; - LeaveCriticalSection(&csDbAccess); - return 2; - } - case DBVT_BYTE: dbcgs->pValue->bVal = pBlob[1]; break; - case DBVT_WORD: dbcgs->pValue->wVal = *(PWORD)(pBlob+1); break; - case DBVT_DWORD: dbcgs->pValue->dVal = *(PDWORD)(pBlob+1); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: - NeedBytes(3+*(PWORD)(pBlob+1)); - if (isStatic) { - dbcgs->pValue->cchVal--; - if (*(PWORD)(pBlob+1)<dbcgs->pValue->cchVal) dbcgs->pValue->cchVal = *(PWORD)(pBlob+1); - CopyMemory(dbcgs->pValue->pszVal,pBlob+3,dbcgs->pValue->cchVal); - dbcgs->pValue->pszVal[dbcgs->pValue->cchVal] = 0; - dbcgs->pValue->cchVal = *(PWORD)(pBlob+1); - } - else { - dbcgs->pValue->pszVal = (char*)mir_alloc(1+*(PWORD)(pBlob+1)); - CopyMemory(dbcgs->pValue->pszVal,pBlob+3,*(PWORD)(pBlob+1)); - dbcgs->pValue->pszVal[*(PWORD)(pBlob+1)] = 0; - } - break; - case DBVT_BLOB: - NeedBytes(3+*(PWORD)(pBlob+1)); - if (isStatic) { - if (*(PWORD)(pBlob+1)<dbcgs->pValue->cpbVal) dbcgs->pValue->cpbVal = *(PWORD)(pBlob+1); - CopyMemory(dbcgs->pValue->pbVal,pBlob+3,dbcgs->pValue->cpbVal); - } - else { - dbcgs->pValue->pbVal = (BYTE *)mir_alloc(*(PWORD)(pBlob + 1)); - CopyMemory(dbcgs->pValue->pbVal,pBlob+3,*(PWORD)(pBlob+1)); - } - dbcgs->pValue->cpbVal = *(PWORD)(pBlob+1); - break; - } - - /**** add to cache **********************/ - if ( dbcgs->pValue->type != DBVT_BLOB ) - { - DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 ); - if ( pCachedValue != NULL ) - SetCachedVariant(dbcgs->pValue,pCachedValue); - } - - LeaveCriticalSection(&csDbAccess); - logg(); - return 0; - } - NeedBytes(1); - MoveAlong(pBlob[0]+1); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } } - - /**** add missing setting to cache **********************/ - if ( dbcgs->pValue->type != DBVT_BLOB ) - { - DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 ); - if ( pCachedValue != NULL ) - pCachedValue->type = DBVT_DELETED; - } - - LeaveCriticalSection(&csDbAccess); - logg(); - return 1; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dgs) -{ - dgs->pValue->type = 0; - if ( GetContactSettingWorker(hContact, dgs, 0)) - return 1; - - if ( dgs->pValue->type == DBVT_UTF8 ) { - WCHAR* tmp = NULL; - char* p = NEWSTR_ALLOCA(dgs->pValue->pszVal); - if ( mir_utf8decode( p, &tmp ) != NULL ) { - BOOL bUsed = FALSE; - int result = WideCharToMultiByte( mirCp, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed ); - - mir_free( dgs->pValue->pszVal ); - - if ( bUsed || result == 0 ) { - dgs->pValue->type = DBVT_WCHAR; - dgs->pValue->pwszVal = tmp; - } - else { - dgs->pValue->type = DBVT_ASCIIZ; - dgs->pValue->pszVal = (char *)mir_alloc(result); - WideCharToMultiByte( mirCp, WC_NO_BEST_FIT_CHARS, tmp, -1, dgs->pValue->pszVal, result, NULL, NULL ); - mir_free( tmp ); - } - } - else { - dgs->pValue->type = DBVT_ASCIIZ; - mir_free( tmp ); - } } - - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetContactSettingStr(HANDLE hContact, DBCONTACTGETSETTING *dgs) -{ - int iSaveType = dgs->pValue->type; - - if ( GetContactSettingWorker(hContact, dgs, 0)) - return 1; - - if ( iSaveType == 0 || iSaveType == dgs->pValue->type ) - return 0; - - if ( dgs->pValue->type != DBVT_ASCIIZ && dgs->pValue->type != DBVT_UTF8 ) - return 1; - - if ( iSaveType == DBVT_WCHAR ) { - if ( dgs->pValue->type != DBVT_UTF8 ) { - int len = MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, NULL, 0 ); - wchar_t* wszResult = ( wchar_t* )mir_alloc(( len+1 )*sizeof( wchar_t )); - if ( wszResult == NULL ) - return 1; - - MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, wszResult, len ); - wszResult[ len ] = 0; - mir_free( dgs->pValue->pszVal ); - dgs->pValue->pwszVal = wszResult; - } - else { - char* savePtr = NEWSTR_ALLOCA(dgs->pValue->pszVal); - mir_free( dgs->pValue->pszVal ); - if ( !mir_utf8decode( savePtr, &dgs->pValue->pwszVal )) - return 1; - } - } - else if ( iSaveType == DBVT_UTF8 ) { - char* tmpBuf = mir_utf8encode( dgs->pValue->pszVal ); - if ( tmpBuf == NULL ) - return 1; - - mir_free( dgs->pValue->pszVal ); - dgs->pValue->pszVal = tmpBuf; - } - else if ( iSaveType == DBVT_ASCIIZ ) - mir_utf8decode( dgs->pValue->pszVal, NULL ); - - dgs->pValue->type = iSaveType; - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetContactSettingStatic(HANDLE hContact, DBCONTACTGETSETTING *dgs) -{ - if ( GetContactSettingWorker(hContact, dgs, 1)) - return 1; - - if ( dgs->pValue->type == DBVT_UTF8 ) { - mir_utf8decode( dgs->pValue->pszVal, NULL ); - dgs->pValue->type = DBVT_ASCIIZ; - } - - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::FreeVariant(DBVARIANT *dbv) -{ - if ( dbv == 0 ) return 1; - switch ( dbv->type ) { - case DBVT_ASCIIZ: - case DBVT_UTF8: - case DBVT_WCHAR: - { - if ( dbv->pszVal ) mir_free(dbv->pszVal); - dbv->pszVal = 0; - break; - } - case DBVT_BLOB: - { - if ( dbv->pbVal ) mir_free(dbv->pbVal); - dbv->pbVal = 0; - break; - } - } - dbv->type = 0; - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::SetSettingResident(BOOL bIsResident, const char *pszSettingName) -{ - char* szSetting; - size_t cbSettingNameLen = strlen(pszSettingName); - int idx; - char* szTemp = (char*)alloca( cbSettingNameLen+2 ); - strcpy( szTemp+1, pszSettingName); - - EnterCriticalSection(&csDbAccess); - if ( !List_GetIndex( &lSettings, szTemp, &idx )) - szSetting = InsertCachedSetting( szTemp, cbSettingNameLen+2, idx ); - else - szSetting = (char *)lSettings.items[idx]; - - *szSetting = (char)bIsResident; - - LeaveCriticalSection(&csDbAccess); - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::WriteContactSetting(HANDLE hContact, DBCONTACTWRITESETTING *dbcws) -{ - DBCONTACTWRITESETTING tmp; - DBContact dbc; - DWORD ofsModuleName; - struct DBContactSettings dbcs; - PBYTE pBlob; - int settingNameLen = 0; - int moduleNameLen = 0; - int settingDataLen = 0; - int bytesRequired,bytesRemaining; - DWORD ofsContact,ofsSettingsGroup,ofsBlobPtr; - - if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL ) - return 1; - - tmp = *dbcws; - if (tmp.value.type == DBVT_WCHAR) { - if (tmp.value.pszVal != NULL) { - char* val = mir_utf8encodeW(tmp.value.pwszVal); - if ( val == NULL ) - return 1; - - tmp.value.pszVal = ( char* )alloca( strlen( val )+1 ); - strcpy( tmp.value.pszVal, val ); - mir_free(val); - tmp.value.type = DBVT_UTF8; - } - else return 1; - } - - if (tmp.value.type!= DBVT_BYTE && tmp.value.type!= DBVT_WORD && tmp.value.type!= DBVT_DWORD && tmp.value.type!= DBVT_ASCIIZ && tmp.value.type!= DBVT_UTF8 && tmp.value.type!= DBVT_BLOB) - return 1; - if ((!tmp.szModule) || (!tmp.szSetting) || ((tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8 )&& tmp.value.pszVal == NULL) || (tmp.value.type == DBVT_BLOB && tmp.value.pbVal == NULL)) - return 1; - // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name - settingNameLen = (int)strlen(tmp.szSetting); - moduleNameLen = (int)strlen(tmp.szModule); - if ( settingNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugString(_T("WriteContactSetting() got a > 255 setting name length. \n")); - #endif - return 1; - } - if ( moduleNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugString(_T("WriteContactSetting() got a > 255 module name length. \n")); - #endif - return 1; - } - - // the db can not tolerate strings/blobs longer than 0xFFFF since the format writes 2 lengths - switch( tmp.value.type ) { - case DBVT_ASCIIZ: case DBVT_BLOB: case DBVT_UTF8: - { int len = ( tmp.value.type != DBVT_BLOB ) ? (int)strlen(tmp.value.pszVal) : tmp.value.cpbVal; - if ( len >= 0xFFFF ) { - #ifdef _DEBUG - OutputDebugString(_T("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n")); - #endif - return 1; - } - } - } - - EnterCriticalSection(&csDbAccess); - { - char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, settingNameLen); - if ( tmp.value.type != DBVT_BLOB ) { - DBVARIANT* pCachedValue = GetCachedValuePtr(hContact, szCachedSettingName, 1); - if ( pCachedValue != NULL ) { - BOOL bIsIdentical = FALSE; - if ( pCachedValue->type == tmp.value.type ) { - switch(tmp.value.type) { - case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == tmp.value.bVal; break; - case DBVT_WORD: bIsIdentical = pCachedValue->wVal == tmp.value.wVal; break; - case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == tmp.value.dVal; break; - case DBVT_UTF8: - case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, tmp.value.pszVal ) == 0; break; - } - if ( bIsIdentical ) { - LeaveCriticalSection(&csDbAccess); - return 0; - } - } - SetCachedVariant(&tmp.value, pCachedValue); - } - if ( szCachedSettingName[-1] != 0 ) { - LeaveCriticalSection(&csDbAccess); - NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); - return 0; - } - } - else GetCachedValuePtr(hContact, szCachedSettingName, -1); - } - - ofsModuleName = GetModuleNameOfs(tmp.szModule); - if (hContact == 0) - ofsContact = dbHeader.ofsUser; - else - ofsContact = (DWORD)hContact; - - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc.signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - log0("write setting"); - //make sure the module group exists - ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName); - if (ofsSettingsGroup == 0) { //module group didn't exist - make it - if (tmp.value.type&DBVTF_VARIABLELENGTH) { - if (tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8) bytesRequired = (int)strlen(tmp.value.pszVal)+2; - else if (tmp.value.type == DBVT_BLOB) bytesRequired = tmp.value.cpbVal+2; - } - else bytesRequired = tmp.value.type; - bytesRequired += 2+settingNameLen; - bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY-(bytesRequired%DB_SETTINGS_RESIZE_GRANULARITY))%DB_SETTINGS_RESIZE_GRANULARITY; - ofsSettingsGroup = CreateNewSpace(bytesRequired+offsetof(struct DBContactSettings,blob)); - dbcs.signature = DBCONTACTSETTINGS_SIGNATURE; - dbcs.ofsNext = dbc.ofsFirstSettings; - dbcs.ofsModuleName = ofsModuleName; - dbcs.cbBlob = bytesRequired; - dbcs.blob[0] = 0; - dbc.ofsFirstSettings = ofsSettingsGroup; - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - DBWrite(ofsSettingsGroup,&dbcs,sizeof(struct DBContactSettings)); - ofsBlobPtr = ofsSettingsGroup+offsetof(struct DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - } - else { - dbcs = *(struct DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(struct DBContactSettings),&bytesRemaining); - //find if the setting exists - ofsBlobPtr = ofsSettingsGroup+offsetof(struct DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - while(pBlob[0]) { - NeedBytes(settingNameLen+1); - if (pBlob[0] == settingNameLen && !memcmp(pBlob+1,tmp.szSetting,settingNameLen)) - break; - NeedBytes(1); - MoveAlong(pBlob[0]+1); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - if (pBlob[0]) { //setting already existed, and up to end of name is in cache - MoveAlong(1+settingNameLen); - //if different type or variable length and length is different - NeedBytes(3); - if (pBlob[0]!= tmp.value.type || ((pBlob[0] == DBVT_ASCIIZ || pBlob[0] == DBVT_UTF8) && *(PWORD)(pBlob+1)!= strlen(tmp.value.pszVal)) || (pBlob[0] == DBVT_BLOB && *(PWORD)(pBlob+1)!= tmp.value.cpbVal)) { - //bin it - int nameLen,valLen; - DWORD ofsSettingToCut; - NeedBytes(3); - nameLen = 1+settingNameLen; - valLen = 1+GetSettingValueLength(pBlob); - ofsSettingToCut = ofsBlobPtr-nameLen; - MoveAlong(valLen); - NeedBytes(1); - while(pBlob[0]) { - MoveAlong(pBlob[0]+1); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - DBMoveChunk(ofsSettingToCut,ofsSettingToCut+nameLen+valLen,ofsBlobPtr+1-ofsSettingToCut); - ofsBlobPtr -= nameLen+valLen; - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - } - else { - //replace existing setting at pBlob - MoveAlong(1); //skip data type - switch(tmp.value.type) { - case DBVT_BYTE: DBWrite(ofsBlobPtr,&tmp.value.bVal,1); break; - case DBVT_WORD: DBWrite(ofsBlobPtr,&tmp.value.wVal,2); break; - case DBVT_DWORD: DBWrite(ofsBlobPtr,&tmp.value.dVal,4); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: DBWrite(ofsBlobPtr+2,tmp.value.pszVal,(int)strlen(tmp.value.pszVal)); break; - case DBVT_BLOB: DBWrite(ofsBlobPtr+2,tmp.value.pbVal,tmp.value.cpbVal); break; - } - //quit - DBFlush(1); - LeaveCriticalSection(&csDbAccess); - //notify - NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); - return 0; - } - } - } - //cannot do a simple replace, add setting to end of list - //pBlob already points to end of list - //see if it fits - if (tmp.value.type&DBVTF_VARIABLELENGTH) { - if (tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8) bytesRequired = (int)strlen(tmp.value.pszVal)+2; - else if (tmp.value.type == DBVT_BLOB) bytesRequired = tmp.value.cpbVal+2; - } - else bytesRequired = tmp.value.type; - bytesRequired += 2+settingNameLen; - bytesRequired += ofsBlobPtr+1-(ofsSettingsGroup+offsetof(struct DBContactSettings,blob)); - if ((DWORD)bytesRequired>dbcs.cbBlob) { - //doesn't fit: move entire group - struct DBContactSettings *dbcsPrev; - DWORD ofsDbcsPrev,oldSize,ofsNew; - - InvalidateSettingsGroupOfsCacheEntry(ofsSettingsGroup); - bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY-(bytesRequired%DB_SETTINGS_RESIZE_GRANULARITY))%DB_SETTINGS_RESIZE_GRANULARITY; - //find previous group to change its offset - ofsDbcsPrev = dbc.ofsFirstSettings; - if (ofsDbcsPrev == ofsSettingsGroup) ofsDbcsPrev = 0; - else { - dbcsPrev = (struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); - while(dbcsPrev->ofsNext!= ofsSettingsGroup) { - if (dbcsPrev->ofsNext == 0) DatabaseCorruption(); - ofsDbcsPrev = dbcsPrev->ofsNext; - dbcsPrev = (struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); - } - } - //create the new one - ofsNew = CreateNewSpace(bytesRequired+offsetof(struct DBContactSettings,blob)); - //copy across - DBMoveChunk(ofsNew,ofsSettingsGroup,bytesRequired+offsetof(struct DBContactSettings,blob)); - oldSize = dbcs.cbBlob; - dbcs.cbBlob = bytesRequired; - DBWrite(ofsNew,&dbcs,offsetof(struct DBContactSettings,blob)); - if (ofsDbcsPrev == 0) { - dbc.ofsFirstSettings = ofsNew; - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - } - else { - dbcsPrev = (struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); - dbcsPrev->ofsNext = ofsNew; - DBWrite(ofsDbcsPrev,dbcsPrev,offsetof(struct DBContactSettings,blob)); - } - DeleteSpace(ofsSettingsGroup,oldSize+offsetof(struct DBContactSettings,blob)); - ofsBlobPtr += ofsNew-ofsSettingsGroup; - ofsSettingsGroup = ofsNew; - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - } - //we now have a place to put it and enough space: make it - DBWrite(ofsBlobPtr,&settingNameLen,1); - DBWrite(ofsBlobPtr+1,(PVOID)tmp.szSetting,settingNameLen); - MoveAlong(1+settingNameLen); - DBWrite(ofsBlobPtr,&tmp.value.type,1); - MoveAlong(1); - switch(tmp.value.type) { - case DBVT_BYTE: DBWrite(ofsBlobPtr,&tmp.value.bVal,1); MoveAlong(1); break; - case DBVT_WORD: DBWrite(ofsBlobPtr,&tmp.value.wVal,2); MoveAlong(2); break; - case DBVT_DWORD: DBWrite(ofsBlobPtr,&tmp.value.dVal,4); MoveAlong(4); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: - { int len = (int)strlen(tmp.value.pszVal); - DBWrite(ofsBlobPtr,&len,2); - DBWrite(ofsBlobPtr+2,tmp.value.pszVal,len); - MoveAlong(2+len); - } - break; - case DBVT_BLOB: - DBWrite(ofsBlobPtr,&tmp.value.cpbVal,2); - DBWrite(ofsBlobPtr+2,tmp.value.pbVal,tmp.value.cpbVal); - MoveAlong(2+tmp.value.cpbVal); - break; - } - { BYTE zero = 0; - DBWrite(ofsBlobPtr,&zero,1); - } - //quit - DBFlush(1); - LeaveCriticalSection(&csDbAccess); - //notify - NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::DeleteContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs) -{ - DBContact *dbc; - DWORD ofsModuleName,ofsSettingsGroup,ofsBlobPtr; - struct DBContactSettings dbcs; - PBYTE pBlob; - int settingNameLen = (int)strlen(dbcgs->szSetting),bytesRemaining; - char* szCachedSettingName; - HANDLE saveContact = hContact; - - if ((!dbcgs->szModule) || (!dbcgs->szSetting)) - return 1; - - EnterCriticalSection(&csDbAccess); - ofsModuleName = GetModuleNameOfs(dbcgs->szModule); - if (hContact == 0) - hContact = (HANDLE)dbHeader.ofsUser; - - dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - //make sure the module group exists - ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(dbc, (DWORD)hContact,ofsModuleName); - if (ofsSettingsGroup == 0) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(dbc,(DWORD)hContact,ofsModuleName); - if (ofsSettingsGroup == 0) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - dbcs = *(struct DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(struct DBContactSettings),NULL); - //find if the setting exists - ofsBlobPtr = ofsSettingsGroup+offsetof(struct DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - while(pBlob[0]) { - NeedBytes(settingNameLen+1); - if (pBlob[0] == settingNameLen && !memcmp(pBlob+1,dbcgs->szSetting,settingNameLen)) - break; - NeedBytes(1); - MoveAlong(pBlob[0]+1); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - if (!pBlob[0]) { //setting didn't exist - LeaveCriticalSection(&csDbAccess); - return 1; - } - { //bin it - int nameLen,valLen; - DWORD ofsSettingToCut; - MoveAlong(1+settingNameLen); - NeedBytes(3); - nameLen = 1+settingNameLen; - valLen = 1+GetSettingValueLength(pBlob); - ofsSettingToCut = ofsBlobPtr-nameLen; - MoveAlong(valLen); - NeedBytes(1); - while(pBlob[0]) { - MoveAlong(pBlob[0]+1); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - DBMoveChunk(ofsSettingToCut,ofsSettingToCut+nameLen+valLen,ofsBlobPtr+1-ofsSettingToCut); - } - - szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,settingNameLen); - GetCachedValuePtr(saveContact, szCachedSettingName, -1 ); - - //quit - DBFlush(1); - LeaveCriticalSection(&csDbAccess); - { //notify - DBCONTACTWRITESETTING dbcws; - dbcws.szModule = dbcgs->szModule; - dbcws.szSetting = dbcgs->szSetting; - dbcws.value.type = DBVT_DELETED; - NotifyEventHooks(hSettingChangeEvent,(WPARAM)saveContact,(LPARAM)&dbcws); - } - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::EnumContactSettings(HANDLE hContact, DBCONTACTENUMSETTINGS* dbces) -{ - DBContact dbc; - struct DBContactSettings dbcs; - DWORD ofsModuleName,ofsContact,ofsBlobPtr; - int bytesRemaining, result; - PBYTE pBlob; - char szSetting[256]; - - if (!dbces->szModule) - return -1; - - EnterCriticalSection(&csDbAccess); - - ofsModuleName = GetModuleNameOfs(dbces->szModule); - if (hContact == 0) - ofsContact = dbHeader.ofsUser; - else - ofsContact = (DWORD)hContact; - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc.signature!= DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - dbces->ofsSettings = GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName); - if (!dbces->ofsSettings) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - dbcs = *(struct DBContactSettings*)DBRead(dbces->ofsSettings,sizeof(struct DBContactSettings),&bytesRemaining); - ofsBlobPtr = dbces->ofsSettings+offsetof(struct DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - if (pBlob[0] == 0) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - result = 0; - while(pBlob[0]) { - NeedBytes(1); - NeedBytes(1+pBlob[0]); - CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]] = 0; - result = (dbces->pfnEnumProc)(szSetting,dbces->lParam); - MoveAlong(1+pBlob[0]); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - LeaveCriticalSection(&csDbAccess); - return result; -} - -STDMETHODIMP_(BOOL) CDdxMmap::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) -{ - for(int i = 0; i < lSettings.realCount; i++) { - int ret = pFunc((char *)lSettings.items[i], 0, (LPARAM)pParam); - if (ret) return ret; - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// -// Module initialization procedure - -static int stringCompare( DBCachedSettingName* p1, DBCachedSettingName* p2 ) -{ - return strcmp( p1->name, p2->name ); -} - -static int stringCompare2( DBCachedGlobalValue* p1, DBCachedGlobalValue* p2 ) -{ - return strcmp( p1->name, p2->name ); -} - -int InitSettings(void) -{ - hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); - - mirCp = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ); - - hCacheHeap = HeapCreate(0, 0, 0); - lSettings.sortFunc = (FSortFunc)stringCompare; - lSettings.increment = 50; - lContacts.sortFunc = HandleKeySort; - lContacts.increment = 100; - lGlobalSettings.sortFunc = (FSortFunc)stringCompare2; - lGlobalSettings.increment = 100; - return 0; -} - -void UninitSettings(void) -{ - HeapDestroy(hCacheHeap); - List_Destroy(&lContacts); - List_Destroy(&lSettings); - List_Destroy(&lGlobalSettings); -} diff --git a/plugins/Db3x/src/init.cpp b/plugins/Db3x/src/init.cpp index ab0e6b4357..406db891a6 100644 --- a/plugins/Db3x/src/init.cpp +++ b/plugins/Db3x/src/init.cpp @@ -1,8 +1,8 @@ /* -Miranda IM: the free IM client for Microsoft* Windows* +Miranda NG: the free IM client for Microsoft* Windows* -Copyright 2000-2003 Miranda ICQ/IM project, +Copyright 2012 Miranda NG project, all portions of this codebase are copyrighted to the people listed in contributors.txt. @@ -25,135 +25,116 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int hLangpack; -HINSTANCE g_hInst = NULL; - -static PLUGININFOEX pluginInfo = { +static PLUGININFOEX pluginInfo = +{ sizeof(PLUGININFOEX), - "Miranda database driver", + "Miranda NG database driver", __VERSION_DWORD, "Provides Miranda database support: global settings, contacts, history, settings per contact.", - "Miranda-IM project", - "ghazan@miranda-im.org", - "Copyright 2000-2011 Miranda IM project", + "Miranda NG project", + "ghazan@miranda.im", + "Copyright 2012 Miranda NG project", "", UNICODE_AWARE, {0x1394a3ab, 0x2585, 0x4196, { 0x8f, 0x72, 0xe, 0xae, 0xc2, 0x45, 0xe, 0x11 }} //{1394A3AB-2585-4196-8F72-0EAEC2450E11} }; -CDdxMmap* g_Db = NULL; +HINSTANCE g_hInst = NULL; + +LIST<CDb3x> g_Dbs(1, (LIST<CDb3x>::FTSortFunc)HandleKeySort); ///////////////////////////////////////////////////////////////////////////////////////// // returns 0 if the profile is created, EMKPRF* -static int makeDatabase(const TCHAR *profile, int * error) +static int makeDatabase(const TCHAR *profile, int *error) { - HANDLE hFile = CreateFile(profile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - if ( hFile != INVALID_HANDLE_VALUE ) { - CreateDbHeaders(hFile); - CloseHandle(hFile); + CDb3x *tmp = new CDb3x(profile); + if (tmp->Create() == ERROR_SUCCESS) { + tmp->CreateDbHeaders(); + delete tmp; return 0; } - if ( error != NULL ) *error = EMKPRF_CREATEFAILED; + delete tmp; + if (error != NULL) *error = EMKPRF_CREATEFAILED; return 1; } // returns 0 if the given profile has a valid header -static int grokHeader(const TCHAR *profile, int * error ) +static int grokHeader(const TCHAR *profile, int *error) { - int rc = 1; - int chk = 0; - struct DBHeader hdr; - HANDLE hFile = INVALID_HANDLE_VALUE; - DWORD dummy = 0; - - hFile = CreateFile(profile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if ( hFile == INVALID_HANDLE_VALUE ) { - if ( error != NULL ) *error = EGROKPRF_CANTREAD; - return 1; - } - // read the header, which can fail (for various reasons) - if ( !ReadFile(hFile, &hdr, sizeof(struct DBHeader), &dummy, NULL)) { - if ( error != NULL) *error = EGROKPRF_CANTREAD; - CloseHandle(hFile); + CDb3x *tmp = new CDb3x(profile); + if (tmp->Load(true) != ERROR_SUCCESS) { + delete tmp; + if (error != NULL) *error = EGROKPRF_CANTREAD; return 1; } - chk = CheckDbHeaders(&hdr); + + int chk = tmp->CheckDbHeaders(); + delete tmp; if ( chk == 0 ) { // all the internal tests passed, hurrah - rc = 0; - if ( error != NULL ) *error = 0; - } else { - // didn't pass at all, or some did. - switch ( chk ) { - case 1: - { - // "Miranda ICQ DB" wasn't present - if ( error != NULL ) *error = EGROKPRF_UNKHEADER; - break; - } - case 2: - { - // header was present, but version information newer - if ( error != NULL ) *error = EGROKPRF_VERNEWER; - break; - } - case 3: - { - // header/version OK, internal data missing - if ( error != NULL ) *error = EGROKPRF_DAMAGED; - break; - } - } // switch - } //if - CloseHandle(hFile); - return rc; + if (error != NULL) *error = 0; + return 0; + } + + // didn't pass at all, or some did. + switch ( chk ) { + case 1: + // "Miranda ICQ DB" wasn't present + if (error != NULL) *error = EGROKPRF_UNKHEADER; + break; + + case 2: + // header was present, but version information newer + if (error != NULL) *error = EGROKPRF_VERNEWER; + break; + + case 3: + // header/version OK, internal data missing + if (error != NULL) *error = EGROKPRF_DAMAGED; + break; + } + + return 1; } // returns 0 if all the APIs are injected otherwise, 1 static MIDatabase* LoadDatabase(const TCHAR *profile) { - if (g_Db) delete g_Db; - g_Db = new CDdxMmap(profile); - - // don't need thread notifications - _tcsncpy(szDbPath, profile, SIZEOF(szDbPath)); + // set the memory, lists & UTF8 manager + mir_getLP( &pluginInfo ); - mir_getLP(&pluginInfo); - - // inject all APIs and hooks into the core - LoadDatabaseModule(); + CDb3x* db = new CDb3x(profile); + if (db->Load(false) != ERROR_SUCCESS) { + delete db; + return NULL; + } - return g_Db; + g_Dbs.insert(db); + return db; } static int UnloadDatabase(MIDatabase* db) { - UnloadDatabaseModule(); + g_Dbs.remove((CDb3x*)db); + delete (CDb3x*)db; return 0; } -static DATABASELINK dblink = { +static DATABASELINK dblink = +{ sizeof(DATABASELINK), "db3x driver", _T("db3x database support"), makeDatabase, grokHeader, LoadDatabase, - UnloadDatabase, + UnloadDatabase }; -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) -{ - g_hInst = hInstDLL; - return TRUE; -} - -extern "C" __declspec(dllexport) DATABASELINK* DatabasePluginInfo(void * reserved) -{ - return &dblink; -} +///////////////////////////////////////////////////////////////////////////////////////// -extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { return &pluginInfo; } @@ -168,5 +149,12 @@ extern "C" __declspec(dllexport) int Load(void) extern "C" __declspec(dllexport) int Unload(void) { + g_Dbs.destroy(); return 0; } + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) +{ + g_hInst = hInstDLL; + return TRUE; +} -- cgit v1.2.3