From eda27f234053df69a304848c91aba90897d7d097 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 23 Jun 2012 17:51:43 +0000 Subject: Dbx_mmap_SA: renamed to .cpp git-svn-id: http://svn.miranda-ng.org/main/trunk@579 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_mmap_SA/commonheaders.c | 1 - plugins/Dbx_mmap_SA/commonheaders.cpp | 1 + plugins/Dbx_mmap_SA/database.c | 224 ------- plugins/Dbx_mmap_SA/database.cpp | 224 +++++++ plugins/Dbx_mmap_SA/dbcache.c | 206 ------ plugins/Dbx_mmap_SA/dbcache.cpp | 206 ++++++ plugins/Dbx_mmap_SA/dbcontacts.c | 299 --------- plugins/Dbx_mmap_SA/dbcontacts.cpp | 299 +++++++++ plugins/Dbx_mmap_SA/dbevents.c | 499 -------------- plugins/Dbx_mmap_SA/dbevents.cpp | 499 ++++++++++++++ plugins/Dbx_mmap_SA/dbheaders.c | 75 --- plugins/Dbx_mmap_SA/dbheaders.cpp | 75 +++ plugins/Dbx_mmap_SA/dbmodulechain.c | 192 ------ plugins/Dbx_mmap_SA/dbmodulechain.cpp | 192 ++++++ plugins/Dbx_mmap_SA/dbpreset.c | 299 --------- plugins/Dbx_mmap_SA/dbpreset.cpp | 299 +++++++++ plugins/Dbx_mmap_SA/dbsettings.c | 1170 --------------------------------- plugins/Dbx_mmap_SA/dbsettings.cpp | 1170 +++++++++++++++++++++++++++++++++ plugins/Dbx_mmap_SA/dialogs.c | 618 ----------------- plugins/Dbx_mmap_SA/dialogs.cpp | 618 +++++++++++++++++ plugins/Dbx_mmap_SA/encrypt.c | 66 -- plugins/Dbx_mmap_SA/encrypt.cpp | 66 ++ plugins/Dbx_mmap_SA/init.c | 216 ------ plugins/Dbx_mmap_SA/init.cpp | 216 ++++++ plugins/Dbx_mmap_SA/security.c | 424 ------------ plugins/Dbx_mmap_SA/security.cpp | 424 ++++++++++++ 26 files changed, 4289 insertions(+), 4289 deletions(-) delete mode 100644 plugins/Dbx_mmap_SA/commonheaders.c create mode 100644 plugins/Dbx_mmap_SA/commonheaders.cpp delete mode 100644 plugins/Dbx_mmap_SA/database.c create mode 100644 plugins/Dbx_mmap_SA/database.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbcache.c create mode 100644 plugins/Dbx_mmap_SA/dbcache.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbcontacts.c create mode 100644 plugins/Dbx_mmap_SA/dbcontacts.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbevents.c create mode 100644 plugins/Dbx_mmap_SA/dbevents.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbheaders.c create mode 100644 plugins/Dbx_mmap_SA/dbheaders.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbmodulechain.c create mode 100644 plugins/Dbx_mmap_SA/dbmodulechain.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbpreset.c create mode 100644 plugins/Dbx_mmap_SA/dbpreset.cpp delete mode 100644 plugins/Dbx_mmap_SA/dbsettings.c create mode 100644 plugins/Dbx_mmap_SA/dbsettings.cpp delete mode 100644 plugins/Dbx_mmap_SA/dialogs.c create mode 100644 plugins/Dbx_mmap_SA/dialogs.cpp delete mode 100644 plugins/Dbx_mmap_SA/encrypt.c create mode 100644 plugins/Dbx_mmap_SA/encrypt.cpp delete mode 100644 plugins/Dbx_mmap_SA/init.c create mode 100644 plugins/Dbx_mmap_SA/init.cpp delete mode 100644 plugins/Dbx_mmap_SA/security.c create mode 100644 plugins/Dbx_mmap_SA/security.cpp (limited to 'plugins') diff --git a/plugins/Dbx_mmap_SA/commonheaders.c b/plugins/Dbx_mmap_SA/commonheaders.c deleted file mode 100644 index c9fe1b2686..0000000000 --- a/plugins/Dbx_mmap_SA/commonheaders.c +++ /dev/null @@ -1 +0,0 @@ -#include "commonheaders.h" \ No newline at end of file diff --git a/plugins/Dbx_mmap_SA/commonheaders.cpp b/plugins/Dbx_mmap_SA/commonheaders.cpp new file mode 100644 index 0000000000..c9fe1b2686 --- /dev/null +++ b/plugins/Dbx_mmap_SA/commonheaders.cpp @@ -0,0 +1 @@ +#include "commonheaders.h" \ No newline at end of file diff --git a/plugins/Dbx_mmap_SA/database.c b/plugins/Dbx_mmap_SA/database.c deleted file mode 100644 index c1e1483fb0..0000000000 --- a/plugins/Dbx_mmap_SA/database.c +++ /dev/null @@ -1,224 +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); -void UninitEvents(void); -int InitCrypt(void); -int InitModuleNames(void); -void UninitModuleNames(void); -int InitCache(void); -void UninitCache(void); -int InitIni(void); -void UninitIni(void); -int InitPreset(void); -void UninitPreset(void); -int InitDialogs(void); -void InitSecurity(void); -void UnloadSecurity(void); - -HANDLE hDbFile=INVALID_HANDLE_VALUE; -CRITICAL_SECTION csDbAccess; -struct DBHeader dbHeader; -char szDbPath[MAX_PATH]; - -static void UnloadDatabase(void) -{ - // update profile last modified time - DWORD bytesWritten; - SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); - WriteFile(hDbFile,dbHeader.signature,sizeof(1),&bytesWritten,NULL); - - 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) -{ - if (ofs+bytes == dbHeader.ofsFileEnd) { - log2("freespace %d@%08x",bytes,ofs); - dbHeader.ofsFileEnd=ofs; - } else { - log2("deletespace %d@%08x",bytes,ofs); - dbHeader.slackSpace+=bytes; - } - DBWrite(0,&dbHeader,sizeof(dbHeader)); - DBFill(ofs,bytes); -} - -DWORD ReallocSpace(DWORD ofs,int oldSize,int newSize) -{ - DWORD ofsNew; - - if (oldSize >= newSize) return ofs; - - if (ofs+oldSize == dbHeader.ofsFileEnd) { - ofsNew = ofs; - dbHeader.ofsFileEnd+=newSize-oldSize; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - log3("adding newspace %d@%08x+%d",newSize,ofsNew,oldSize); - } else { - ofsNew=CreateNewSpace(newSize); - DBMoveChunk(ofsNew,ofs,oldSize); - DeleteSpace(ofs,oldSize); - } - return ofsNew; -} - -void UnloadDatabaseModule(void) -{ - //UninitIni(); - UninitPreset(); - UninitEvents(); - UninitSettings(); - UninitContacts(); - UninitModuleNames(); - UninitCache(); - UnloadDatabase(); - UnloadSecurity(); - DeleteCriticalSection(&csDbAccess); -} - -INT_PTR GetProfileName(WPARAM wParam, LPARAM lParam) -{ - char * p = 0; - p = strrchr(szDbPath, '\\'); - if ( p == 0 ) return 1; - p++; - strncpy((char*)lParam, p, (size_t) wParam); - return 0; -} - -int LoadDatabaseModule(void) -{ - char szDBName[255]; - InitializeCriticalSection(&csDbAccess); - log0("DB logging running"); - { - DWORD dummy=0; - hDbFile=CreateFileA(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; - } - } - InitSecurity(); - CheckDbHeaders(&dbHeader); - GetProfileName((WPARAM)50, (LPARAM)szDBName); - if(bEncoding && !CheckPassword(dbHeader.checkWord, szDBName)) 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; - if(InitCrypt()) return 1; - if(InitPreset()) return 1; - if(InitDialogs()) return 1; - //EncryptDB(); - return 0; -} - -static DWORD DatabaseCorrupted=0; -static TCHAR *msg = NULL; -static DWORD dwErr = 0; - -void __cdecl dbpanic(void *arg) -{ - if (msg) - { - TCHAR err[256]; - - if (dwErr==ERROR_DISK_FULL) - msg = TranslateT("Disk is full. Miranda will now shutdown."); - - mir_sntprintf(err, SIZEOF(err), msg, TranslateT("Database failure. Miranda will now shutdown."), dwErr); - - MessageBox(0,err,TranslateT("Database Error"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); - } - else - MessageBox(0,TranslateT("Miranda has detected corruption in your database. This corruption maybe fixed by DBTool. Please download it from http://www.miranda-im.org. Miranda will now shutdown."), - TranslateT("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); - - TerminateProcess(GetCurrentProcess(),255); -} - -void DatabaseCorruption(TCHAR *text) -{ - int kill=0; - - EnterCriticalSection(&csDbAccess); - if (DatabaseCorrupted==0) { - DatabaseCorrupted++; - kill++; - msg = text; - dwErr = GetLastError(); - } 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/Dbx_mmap_SA/database.cpp b/plugins/Dbx_mmap_SA/database.cpp new file mode 100644 index 0000000000..c1e1483fb0 --- /dev/null +++ b/plugins/Dbx_mmap_SA/database.cpp @@ -0,0 +1,224 @@ +/* + +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); +void UninitEvents(void); +int InitCrypt(void); +int InitModuleNames(void); +void UninitModuleNames(void); +int InitCache(void); +void UninitCache(void); +int InitIni(void); +void UninitIni(void); +int InitPreset(void); +void UninitPreset(void); +int InitDialogs(void); +void InitSecurity(void); +void UnloadSecurity(void); + +HANDLE hDbFile=INVALID_HANDLE_VALUE; +CRITICAL_SECTION csDbAccess; +struct DBHeader dbHeader; +char szDbPath[MAX_PATH]; + +static void UnloadDatabase(void) +{ + // update profile last modified time + DWORD bytesWritten; + SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); + WriteFile(hDbFile,dbHeader.signature,sizeof(1),&bytesWritten,NULL); + + 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) +{ + if (ofs+bytes == dbHeader.ofsFileEnd) { + log2("freespace %d@%08x",bytes,ofs); + dbHeader.ofsFileEnd=ofs; + } else { + log2("deletespace %d@%08x",bytes,ofs); + dbHeader.slackSpace+=bytes; + } + DBWrite(0,&dbHeader,sizeof(dbHeader)); + DBFill(ofs,bytes); +} + +DWORD ReallocSpace(DWORD ofs,int oldSize,int newSize) +{ + DWORD ofsNew; + + if (oldSize >= newSize) return ofs; + + if (ofs+oldSize == dbHeader.ofsFileEnd) { + ofsNew = ofs; + dbHeader.ofsFileEnd+=newSize-oldSize; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + log3("adding newspace %d@%08x+%d",newSize,ofsNew,oldSize); + } else { + ofsNew=CreateNewSpace(newSize); + DBMoveChunk(ofsNew,ofs,oldSize); + DeleteSpace(ofs,oldSize); + } + return ofsNew; +} + +void UnloadDatabaseModule(void) +{ + //UninitIni(); + UninitPreset(); + UninitEvents(); + UninitSettings(); + UninitContacts(); + UninitModuleNames(); + UninitCache(); + UnloadDatabase(); + UnloadSecurity(); + DeleteCriticalSection(&csDbAccess); +} + +INT_PTR GetProfileName(WPARAM wParam, LPARAM lParam) +{ + char * p = 0; + p = strrchr(szDbPath, '\\'); + if ( p == 0 ) return 1; + p++; + strncpy((char*)lParam, p, (size_t) wParam); + return 0; +} + +int LoadDatabaseModule(void) +{ + char szDBName[255]; + InitializeCriticalSection(&csDbAccess); + log0("DB logging running"); + { + DWORD dummy=0; + hDbFile=CreateFileA(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; + } + } + InitSecurity(); + CheckDbHeaders(&dbHeader); + GetProfileName((WPARAM)50, (LPARAM)szDBName); + if(bEncoding && !CheckPassword(dbHeader.checkWord, szDBName)) 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; + if(InitCrypt()) return 1; + if(InitPreset()) return 1; + if(InitDialogs()) return 1; + //EncryptDB(); + return 0; +} + +static DWORD DatabaseCorrupted=0; +static TCHAR *msg = NULL; +static DWORD dwErr = 0; + +void __cdecl dbpanic(void *arg) +{ + if (msg) + { + TCHAR err[256]; + + if (dwErr==ERROR_DISK_FULL) + msg = TranslateT("Disk is full. Miranda will now shutdown."); + + mir_sntprintf(err, SIZEOF(err), msg, TranslateT("Database failure. Miranda will now shutdown."), dwErr); + + MessageBox(0,err,TranslateT("Database Error"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); + } + else + MessageBox(0,TranslateT("Miranda has detected corruption in your database. This corruption maybe fixed by DBTool. Please download it from http://www.miranda-im.org. Miranda will now shutdown."), + TranslateT("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); + + TerminateProcess(GetCurrentProcess(),255); +} + +void DatabaseCorruption(TCHAR *text) +{ + int kill=0; + + EnterCriticalSection(&csDbAccess); + if (DatabaseCorrupted==0) { + DatabaseCorrupted++; + kill++; + msg = text; + dwErr = GetLastError(); + } 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/Dbx_mmap_SA/dbcache.c b/plugins/Dbx_mmap_SA/dbcache.c deleted file mode 100644 index 625d8aa775..0000000000 --- a/plugins/Dbx_mmap_SA/dbcache.c +++ /dev/null @@ -1,206 +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" - -BOOL safetyMode = TRUE; -static UINT_PTR flushBuffersTimerId; - -static PBYTE pNull = 0; -static PBYTE pDbCache = NULL; -static HANDLE hMap = NULL; -static DWORD dwFileSize = 0; -static DWORD ChunkSize = 65536; -static DWORD flushFailTick = 0; - - -void Map() -{ - hMap = CreateFileMapping(hDbFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL); - - if (hMap) - { - pDbCache = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS/*FILE_MAP_WRITE*/, 0, 0 ,0); - if (!pDbCache) - DatabaseCorruption( _T("%s (MapViewOfFile failed. Code: %d)")); - } - else - DatabaseCorruption( _T("%s (CreateFileMapping failed. Code: %d)")); -} - -void ReMap(DWORD needed) -{ - KillTimer(NULL,flushBuffersTimerId); - - log3("remapping %d + %d (file end: %d)",dwFileSize,needed,dbHeader.ofsFileEnd); - - if (needed > ChunkSize) - { - if (needed + dwFileSize > dbHeader.ofsFileEnd + ChunkSize) - DatabaseCorruption( _T("%s (Too large increment)")); - else - { - DWORD x = dbHeader.ofsFileEnd/ChunkSize; - dwFileSize = (x+1)*ChunkSize; - } - } - else - dwFileSize += ChunkSize; - -// FlushViewOfFile(pDbCache, 0); - UnmapViewOfFile(pDbCache); - pDbCache = NULL; - CloseHandle(hMap); - - Map(); -} - -void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) -{ - int x = 0; - log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); - if (ofsDest+bytes>dwFileSize) ReMap(ofsDest+bytes-dwFileSize); - if (ofsSource+bytes>dwFileSize) { - x = ofsSource+bytes-dwFileSize; - log0("buggy move!"); - _ASSERT(0); - } - if (x > 0) - ZeroMemory(pDbCache+ofsDest+bytes-x, x); - if (ofsSource < dwFileSize) - MoveMemory(pDbCache+ofsDest,pDbCache+ofsSource, bytes-x); - - logg(); -} - -//we are assumed to be in a mutex here -PBYTE DBRead(DWORD ofs,int bytesRequired,int *bytesAvail) -{ - // buggy read - if (ofs>=dwFileSize) { - log2("read from outside %d@%08x",bytesRequired,ofs); - if (bytesAvail!=NULL) *bytesAvail = ChunkSize; - return pNull; - } - log3((ofs+bytesRequired>dwFileSize)?"read %d@%08x, only %d avaliable":"read %d@%08x",bytesRequired,ofs,dwFileSize-ofs); - if (bytesAvail!=NULL) *bytesAvail = dwFileSize - ofs; - return pDbCache+ofs; -} - -//we are assumed to be in a mutex here -void DBWrite(DWORD ofs,PVOID pData,int bytes) -{ - log2("write %d@%08x",bytes,ofs); - if (ofs+bytes>dwFileSize) ReMap(ofs+bytes-dwFileSize); - MoveMemory(pDbCache+ofs,pData,bytes); - logg(); -} - -//we are assumed to be in a mutex here -void DBFill(DWORD ofs,int bytes) -{ - log2("zerofill %d@%08x",bytes,ofs); - if (ofs+bytes<=dwFileSize) - ZeroMemory(pDbCache+ofs,bytes); - logg(); -} - -static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) -{ - if (!pDbCache) return; - - KillTimer(NULL,flushBuffersTimerId); - log0("tflush1"); - if (FlushViewOfFile(pDbCache, 0) == 0) { - if (flushFailTick == 0) - flushFailTick = GetTickCount(); - else if (GetTickCount() - flushFailTick > 5000) - DatabaseCorruption(NULL); - } - else - flushFailTick = 0; - log0("tflush2"); -} - -void DBFlush(int setting) -{ - if (!setting) { - log0("nflush1"); - if(safetyMode && pDbCache) { - if (FlushViewOfFile(pDbCache, 0) == 0) { - if (flushFailTick == 0) - flushFailTick = GetTickCount(); - else if (GetTickCount() - flushFailTick > 5000) - DatabaseCorruption(NULL); - } - else - flushFailTick = 0; - } - 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); - DBFlush(1); - return 0; -} - -int InitCache(void) -{ - DWORD x; - SYSTEM_INFO sinf; - - GetSystemInfo(&sinf); - ChunkSize = sinf.dwAllocationGranularity; - - dwFileSize = GetFileSize(hDbFile, NULL); - - // Align to chunk - x = dwFileSize % ChunkSize; - if (x) dwFileSize += ChunkSize - x; - - Map(); - - // zero region for reads outside the file - pNull = calloc(ChunkSize,1); - - CreateServiceFunction(MS_DB_SETSAFETYMODE,CacheSetSafetyMode); - - return 0; -} - -void UninitCache(void) -{ - KillTimer(NULL,flushBuffersTimerId); - FlushViewOfFile(pDbCache, 0); - UnmapViewOfFile(pDbCache); - CloseHandle(hMap); - if (pNull) free(pNull); -} diff --git a/plugins/Dbx_mmap_SA/dbcache.cpp b/plugins/Dbx_mmap_SA/dbcache.cpp new file mode 100644 index 0000000000..625d8aa775 --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbcache.cpp @@ -0,0 +1,206 @@ +/* + +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" + +BOOL safetyMode = TRUE; +static UINT_PTR flushBuffersTimerId; + +static PBYTE pNull = 0; +static PBYTE pDbCache = NULL; +static HANDLE hMap = NULL; +static DWORD dwFileSize = 0; +static DWORD ChunkSize = 65536; +static DWORD flushFailTick = 0; + + +void Map() +{ + hMap = CreateFileMapping(hDbFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL); + + if (hMap) + { + pDbCache = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS/*FILE_MAP_WRITE*/, 0, 0 ,0); + if (!pDbCache) + DatabaseCorruption( _T("%s (MapViewOfFile failed. Code: %d)")); + } + else + DatabaseCorruption( _T("%s (CreateFileMapping failed. Code: %d)")); +} + +void ReMap(DWORD needed) +{ + KillTimer(NULL,flushBuffersTimerId); + + log3("remapping %d + %d (file end: %d)",dwFileSize,needed,dbHeader.ofsFileEnd); + + if (needed > ChunkSize) + { + if (needed + dwFileSize > dbHeader.ofsFileEnd + ChunkSize) + DatabaseCorruption( _T("%s (Too large increment)")); + else + { + DWORD x = dbHeader.ofsFileEnd/ChunkSize; + dwFileSize = (x+1)*ChunkSize; + } + } + else + dwFileSize += ChunkSize; + +// FlushViewOfFile(pDbCache, 0); + UnmapViewOfFile(pDbCache); + pDbCache = NULL; + CloseHandle(hMap); + + Map(); +} + +void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) +{ + int x = 0; + log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); + if (ofsDest+bytes>dwFileSize) ReMap(ofsDest+bytes-dwFileSize); + if (ofsSource+bytes>dwFileSize) { + x = ofsSource+bytes-dwFileSize; + log0("buggy move!"); + _ASSERT(0); + } + if (x > 0) + ZeroMemory(pDbCache+ofsDest+bytes-x, x); + if (ofsSource < dwFileSize) + MoveMemory(pDbCache+ofsDest,pDbCache+ofsSource, bytes-x); + + logg(); +} + +//we are assumed to be in a mutex here +PBYTE DBRead(DWORD ofs,int bytesRequired,int *bytesAvail) +{ + // buggy read + if (ofs>=dwFileSize) { + log2("read from outside %d@%08x",bytesRequired,ofs); + if (bytesAvail!=NULL) *bytesAvail = ChunkSize; + return pNull; + } + log3((ofs+bytesRequired>dwFileSize)?"read %d@%08x, only %d avaliable":"read %d@%08x",bytesRequired,ofs,dwFileSize-ofs); + if (bytesAvail!=NULL) *bytesAvail = dwFileSize - ofs; + return pDbCache+ofs; +} + +//we are assumed to be in a mutex here +void DBWrite(DWORD ofs,PVOID pData,int bytes) +{ + log2("write %d@%08x",bytes,ofs); + if (ofs+bytes>dwFileSize) ReMap(ofs+bytes-dwFileSize); + MoveMemory(pDbCache+ofs,pData,bytes); + logg(); +} + +//we are assumed to be in a mutex here +void DBFill(DWORD ofs,int bytes) +{ + log2("zerofill %d@%08x",bytes,ofs); + if (ofs+bytes<=dwFileSize) + ZeroMemory(pDbCache+ofs,bytes); + logg(); +} + +static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) +{ + if (!pDbCache) return; + + KillTimer(NULL,flushBuffersTimerId); + log0("tflush1"); + if (FlushViewOfFile(pDbCache, 0) == 0) { + if (flushFailTick == 0) + flushFailTick = GetTickCount(); + else if (GetTickCount() - flushFailTick > 5000) + DatabaseCorruption(NULL); + } + else + flushFailTick = 0; + log0("tflush2"); +} + +void DBFlush(int setting) +{ + if (!setting) { + log0("nflush1"); + if(safetyMode && pDbCache) { + if (FlushViewOfFile(pDbCache, 0) == 0) { + if (flushFailTick == 0) + flushFailTick = GetTickCount(); + else if (GetTickCount() - flushFailTick > 5000) + DatabaseCorruption(NULL); + } + else + flushFailTick = 0; + } + 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); + DBFlush(1); + return 0; +} + +int InitCache(void) +{ + DWORD x; + SYSTEM_INFO sinf; + + GetSystemInfo(&sinf); + ChunkSize = sinf.dwAllocationGranularity; + + dwFileSize = GetFileSize(hDbFile, NULL); + + // Align to chunk + x = dwFileSize % ChunkSize; + if (x) dwFileSize += ChunkSize - x; + + Map(); + + // zero region for reads outside the file + pNull = calloc(ChunkSize,1); + + CreateServiceFunction(MS_DB_SETSAFETYMODE,CacheSetSafetyMode); + + return 0; +} + +void UninitCache(void) +{ + KillTimer(NULL,flushBuffersTimerId); + FlushViewOfFile(pDbCache, 0); + UnmapViewOfFile(pDbCache); + CloseHandle(hMap); + if (pNull) free(pNull); +} diff --git a/plugins/Dbx_mmap_SA/dbcontacts.c b/plugins/Dbx_mmap_SA/dbcontacts.c deleted file mode 100644 index 51e533266d..0000000000 --- a/plugins/Dbx_mmap_SA/dbcontacts.c +++ /dev/null @@ -1,299 +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" - -extern HANDLE hCacheHeap; -extern SortedList lContacts; -extern HANDLE hLastCachedContact; - -INT_PTR GetContactSettingStatic(WPARAM wParam,LPARAM lParam); -void FreeCachedVariant( DBVARIANT* V ); - -static INT_PTR GetContactCount(WPARAM wParam,LPARAM lParam); -static INT_PTR FindFirstContact(WPARAM wParam,LPARAM lParam); -static INT_PTR FindNextContact(WPARAM wParam,LPARAM lParam); -static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam); -static INT_PTR AddContact(WPARAM wParam,LPARAM lParam); -static INT_PTR IsDbContact(WPARAM wParam,LPARAM lParam); - -static HANDLE hContactDeletedEvent,hContactAddedEvent; - - -int InitContacts(void) -{ - CreateServiceFunction(MS_DB_CONTACT_GETCOUNT,GetContactCount); - CreateServiceFunction(MS_DB_CONTACT_FINDFIRST,FindFirstContact); - CreateServiceFunction(MS_DB_CONTACT_FINDNEXT,FindNextContact); - CreateServiceFunction(MS_DB_CONTACT_DELETE,DeleteContact); - CreateServiceFunction(MS_DB_CONTACT_ADD,AddContact); - CreateServiceFunction(MS_DB_CONTACT_IS,IsDbContact); - hContactDeletedEvent=CreateHookableEvent(ME_DB_CONTACT_DELETED); - hContactAddedEvent=CreateHookableEvent(ME_DB_CONTACT_ADDED); - return 0; -} - -void UninitContacts(void) -{ -} - -DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index) -{ - DBCachedContactValueList* VL; - VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); - VL->hContact = hContact; - if (index == -1) li.List_GetIndex(&lContacts,VL,&index); - li.List_Insert(&lContacts,VL,index); - return VL; -} - -static INT_PTR GetContactCount(WPARAM wParam,LPARAM lParam) -{ - int ret; - - EnterCriticalSection(&csDbAccess); - ret=dbHeader.contactCount; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -#define proto_module "Protocol" -#define proto_setting "p" - -static int CheckProto(HANDLE hContact, const char *proto) -{ - static char protobuf[MAX_PATH] = {0}; - static DBVARIANT dbv; - static DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv}; - - dbv.type = DBVT_ASCIIZ; - dbv.pszVal = protobuf; - dbv.cchVal = sizeof(protobuf); - - if (GetContactSettingStatic((WPARAM)hContact, (LPARAM )&sVal) != 0 - || (dbv.type != DBVT_ASCIIZ)) return 0; - - return !strcmp(protobuf,proto); -} - -static INT_PTR FindFirstContact(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret = 0; - EnterCriticalSection(&csDbAccess); - ret = (INT_PTR)dbHeader.ofsFirstContact; - if (lParam && !CheckProto((HANDLE)ret,(const char*)lParam)) - ret = FindNextContact((WPARAM)ret,lParam); - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR FindNextContact(WPARAM wParam,LPARAM lParam) -{ - int index; - struct DBContact *dbc; - DBCachedContactValueList VLtemp, *VL = NULL; - VLtemp.hContact = (HANDLE)wParam; - EnterCriticalSection(&csDbAccess); - while(VLtemp.hContact) { - if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) { - VL = ( DBCachedContactValueList* )lContacts.items[index]; - if (VL->hNext != NULL) { - if (!lParam || CheckProto(VL->hNext,(const char*)lParam)) { - LeaveCriticalSection(&csDbAccess); - return (INT_PTR)VL->hNext; - } - else { - VLtemp.hContact = VL->hNext; - continue; - } } } - - dbc=(struct DBContact*)DBRead((DWORD)VLtemp.hContact,sizeof(struct DBContact),NULL); - if (dbc->signature!=DBCONTACT_SIGNATURE) - break; - else { - if ( VL == NULL ) - VL = AddToCachedContactList(VLtemp.hContact,index); - - VL->hNext = (HANDLE)dbc->ofsNext; - if (VL->hNext != NULL && (!lParam || CheckProto(VL->hNext,(const char*)lParam))) { - LeaveCriticalSection(&csDbAccess); - return (INT_PTR)VL->hNext; - } - VLtemp.hContact = VL->hNext; - } } - LeaveCriticalSection(&csDbAccess); - return 0; -} - -static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam) -{ - struct DBContact *dbc,*dbcPrev; - DWORD ofsThis,ofsNext,ofsFirstEvent; - struct DBContactSettings *dbcs; - struct DBEvent *dbe; - int index; - - if ((HANDLE)wParam==NULL) return 1; - EnterCriticalSection(&csDbAccess); - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - if ( (HANDLE)wParam == (HANDLE)dbHeader.ofsUser ) { - LeaveCriticalSection(&csDbAccess); - log0("FATAL: del of user chain attempted."); - return 1; - } - log0("del contact"); - LeaveCriticalSection(&csDbAccess); - //call notifier while outside mutex - NotifyEventHooks(hContactDeletedEvent,wParam,0); - //get back in - EnterCriticalSection(&csDbAccess); - - { DBCachedContactValueList VLtemp; - VLtemp.hContact = (HANDLE)wParam; - if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) - { - DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; - DBCachedContactValue* V = VL->first; - while ( V != NULL ) { - DBCachedContactValue* V1 = V->next; - FreeCachedVariant(&V->value); - HeapFree( hCacheHeap, 0, V ); - V = V1; - } - HeapFree( hCacheHeap, 0, VL ); - - if (VLtemp.hContact == hLastCachedContact) - hLastCachedContact = NULL; - li.List_Remove(&lContacts,index); - } } - - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - //delete settings chain - ofsThis=dbc->ofsFirstSettings; - ofsFirstEvent=dbc->ofsFirstEvent; - while(ofsThis) { - dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); - ofsNext=dbcs->ofsNext; - DeleteSpace(ofsThis,offsetof(struct DBContactSettings,blob)+dbcs->cbBlob); - ofsThis=ofsNext; - } - //delete event chain - ofsThis=ofsFirstEvent; - while(ofsThis) { - dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); - ofsNext=dbe->ofsNext; - DeleteSpace(ofsThis,offsetof(struct DBEvent,blob)+dbe->cbBlob); - ofsThis=ofsNext; - } - //find previous contact in chain and change ofsNext - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbHeader.ofsFirstContact==wParam) { - dbHeader.ofsFirstContact=dbc->ofsNext; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - } - else { - ofsNext=dbc->ofsNext; - ofsThis=dbHeader.ofsFirstContact; - dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); - while(dbcPrev->ofsNext!=wParam) { - if(dbcPrev->ofsNext==0) DatabaseCorruption(NULL); - ofsThis=dbcPrev->ofsNext; - dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); - } - dbcPrev->ofsNext=ofsNext; - DBWrite(ofsThis,dbcPrev,sizeof(struct DBContact)); - { - DBCachedContactValueList VLtemp; - VLtemp.hContact = (HANDLE)ofsThis; - if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) - { - DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; - VL->hNext = ( HANDLE )ofsNext; - } } - } - //delete contact - DeleteSpace(wParam,sizeof(struct DBContact)); - //decrement contact count - dbHeader.contactCount--; - DBWrite(0,&dbHeader,sizeof(dbHeader)); - DBFlush(0); - //quit - LeaveCriticalSection(&csDbAccess); - return 0; -} - -static INT_PTR AddContact(WPARAM wParam,LPARAM lParam) -{ - struct DBContact dbc; - DWORD ofsNew; - - log0("add contact"); - EnterCriticalSection(&csDbAccess); - ofsNew=CreateNewSpace(sizeof(struct DBContact)); - dbc.signature=DBCONTACT_SIGNATURE; - dbc.eventCount=0; - dbc.ofsFirstEvent=dbc.ofsLastEvent=0; - dbc.ofsFirstSettings=0; - dbc.ofsNext=dbHeader.ofsFirstContact; - dbc.ofsFirstUnreadEvent=0; - dbc.timestampFirstUnread=0; - dbHeader.ofsFirstContact=ofsNew; - dbHeader.contactCount++; - DBWrite(ofsNew,&dbc,sizeof(struct DBContact)); - DBWrite(0,&dbHeader,sizeof(dbHeader)); - DBFlush(0); - - AddToCachedContactList((HANDLE)ofsNew, -1); - - LeaveCriticalSection(&csDbAccess); - NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); - return (INT_PTR)ofsNew; -} - -static INT_PTR IsDbContact(WPARAM wParam,LPARAM lParam) -{ - struct DBContact *dbc; - DWORD ofsContact=(DWORD)wParam; - int ret; - - EnterCriticalSection(&csDbAccess); - { - int index; - DBCachedContactValueList VLtemp; - VLtemp.hContact = (HANDLE)wParam; - if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) - ret = TRUE; - else { - dbc=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - ret=dbc->signature==DBCONTACT_SIGNATURE; - if (ret) - AddToCachedContactList((HANDLE)wParam, index); - } } - - LeaveCriticalSection(&csDbAccess); - return ret; -} diff --git a/plugins/Dbx_mmap_SA/dbcontacts.cpp b/plugins/Dbx_mmap_SA/dbcontacts.cpp new file mode 100644 index 0000000000..51e533266d --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbcontacts.cpp @@ -0,0 +1,299 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +extern HANDLE hCacheHeap; +extern SortedList lContacts; +extern HANDLE hLastCachedContact; + +INT_PTR GetContactSettingStatic(WPARAM wParam,LPARAM lParam); +void FreeCachedVariant( DBVARIANT* V ); + +static INT_PTR GetContactCount(WPARAM wParam,LPARAM lParam); +static INT_PTR FindFirstContact(WPARAM wParam,LPARAM lParam); +static INT_PTR FindNextContact(WPARAM wParam,LPARAM lParam); +static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam); +static INT_PTR AddContact(WPARAM wParam,LPARAM lParam); +static INT_PTR IsDbContact(WPARAM wParam,LPARAM lParam); + +static HANDLE hContactDeletedEvent,hContactAddedEvent; + + +int InitContacts(void) +{ + CreateServiceFunction(MS_DB_CONTACT_GETCOUNT,GetContactCount); + CreateServiceFunction(MS_DB_CONTACT_FINDFIRST,FindFirstContact); + CreateServiceFunction(MS_DB_CONTACT_FINDNEXT,FindNextContact); + CreateServiceFunction(MS_DB_CONTACT_DELETE,DeleteContact); + CreateServiceFunction(MS_DB_CONTACT_ADD,AddContact); + CreateServiceFunction(MS_DB_CONTACT_IS,IsDbContact); + hContactDeletedEvent=CreateHookableEvent(ME_DB_CONTACT_DELETED); + hContactAddedEvent=CreateHookableEvent(ME_DB_CONTACT_ADDED); + return 0; +} + +void UninitContacts(void) +{ +} + +DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index) +{ + DBCachedContactValueList* VL; + VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); + VL->hContact = hContact; + if (index == -1) li.List_GetIndex(&lContacts,VL,&index); + li.List_Insert(&lContacts,VL,index); + return VL; +} + +static INT_PTR GetContactCount(WPARAM wParam,LPARAM lParam) +{ + int ret; + + EnterCriticalSection(&csDbAccess); + ret=dbHeader.contactCount; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +#define proto_module "Protocol" +#define proto_setting "p" + +static int CheckProto(HANDLE hContact, const char *proto) +{ + static char protobuf[MAX_PATH] = {0}; + static DBVARIANT dbv; + static DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv}; + + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = protobuf; + dbv.cchVal = sizeof(protobuf); + + if (GetContactSettingStatic((WPARAM)hContact, (LPARAM )&sVal) != 0 + || (dbv.type != DBVT_ASCIIZ)) return 0; + + return !strcmp(protobuf,proto); +} + +static INT_PTR FindFirstContact(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret = 0; + EnterCriticalSection(&csDbAccess); + ret = (INT_PTR)dbHeader.ofsFirstContact; + if (lParam && !CheckProto((HANDLE)ret,(const char*)lParam)) + ret = FindNextContact((WPARAM)ret,lParam); + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindNextContact(WPARAM wParam,LPARAM lParam) +{ + int index; + struct DBContact *dbc; + DBCachedContactValueList VLtemp, *VL = NULL; + VLtemp.hContact = (HANDLE)wParam; + EnterCriticalSection(&csDbAccess); + while(VLtemp.hContact) { + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) { + VL = ( DBCachedContactValueList* )lContacts.items[index]; + if (VL->hNext != NULL) { + if (!lParam || CheckProto(VL->hNext,(const char*)lParam)) { + LeaveCriticalSection(&csDbAccess); + return (INT_PTR)VL->hNext; + } + else { + VLtemp.hContact = VL->hNext; + continue; + } } } + + dbc=(struct DBContact*)DBRead((DWORD)VLtemp.hContact,sizeof(struct DBContact),NULL); + if (dbc->signature!=DBCONTACT_SIGNATURE) + break; + else { + if ( VL == NULL ) + VL = AddToCachedContactList(VLtemp.hContact,index); + + VL->hNext = (HANDLE)dbc->ofsNext; + if (VL->hNext != NULL && (!lParam || CheckProto(VL->hNext,(const char*)lParam))) { + LeaveCriticalSection(&csDbAccess); + return (INT_PTR)VL->hNext; + } + VLtemp.hContact = VL->hNext; + } } + LeaveCriticalSection(&csDbAccess); + return 0; +} + +static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam) +{ + struct DBContact *dbc,*dbcPrev; + DWORD ofsThis,ofsNext,ofsFirstEvent; + struct DBContactSettings *dbcs; + struct DBEvent *dbe; + int index; + + if ((HANDLE)wParam==NULL) return 1; + EnterCriticalSection(&csDbAccess); + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return 1; + } + if ( (HANDLE)wParam == (HANDLE)dbHeader.ofsUser ) { + LeaveCriticalSection(&csDbAccess); + log0("FATAL: del of user chain attempted."); + return 1; + } + log0("del contact"); + LeaveCriticalSection(&csDbAccess); + //call notifier while outside mutex + NotifyEventHooks(hContactDeletedEvent,wParam,0); + //get back in + EnterCriticalSection(&csDbAccess); + + { DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)wParam; + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) + { + DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; + DBCachedContactValue* V = VL->first; + while ( V != NULL ) { + DBCachedContactValue* V1 = V->next; + FreeCachedVariant(&V->value); + HeapFree( hCacheHeap, 0, V ); + V = V1; + } + HeapFree( hCacheHeap, 0, VL ); + + if (VLtemp.hContact == hLastCachedContact) + hLastCachedContact = NULL; + li.List_Remove(&lContacts,index); + } } + + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + //delete settings chain + ofsThis=dbc->ofsFirstSettings; + ofsFirstEvent=dbc->ofsFirstEvent; + while(ofsThis) { + dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); + ofsNext=dbcs->ofsNext; + DeleteSpace(ofsThis,offsetof(struct DBContactSettings,blob)+dbcs->cbBlob); + ofsThis=ofsNext; + } + //delete event chain + ofsThis=ofsFirstEvent; + while(ofsThis) { + dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); + ofsNext=dbe->ofsNext; + DeleteSpace(ofsThis,offsetof(struct DBEvent,blob)+dbe->cbBlob); + ofsThis=ofsNext; + } + //find previous contact in chain and change ofsNext + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbHeader.ofsFirstContact==wParam) { + dbHeader.ofsFirstContact=dbc->ofsNext; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + } + else { + ofsNext=dbc->ofsNext; + ofsThis=dbHeader.ofsFirstContact; + dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); + while(dbcPrev->ofsNext!=wParam) { + if(dbcPrev->ofsNext==0) DatabaseCorruption(NULL); + ofsThis=dbcPrev->ofsNext; + dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); + } + dbcPrev->ofsNext=ofsNext; + DBWrite(ofsThis,dbcPrev,sizeof(struct DBContact)); + { + DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)ofsThis; + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) + { + DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; + VL->hNext = ( HANDLE )ofsNext; + } } + } + //delete contact + DeleteSpace(wParam,sizeof(struct DBContact)); + //decrement contact count + dbHeader.contactCount--; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + DBFlush(0); + //quit + LeaveCriticalSection(&csDbAccess); + return 0; +} + +static INT_PTR AddContact(WPARAM wParam,LPARAM lParam) +{ + struct DBContact dbc; + DWORD ofsNew; + + log0("add contact"); + EnterCriticalSection(&csDbAccess); + ofsNew=CreateNewSpace(sizeof(struct DBContact)); + dbc.signature=DBCONTACT_SIGNATURE; + dbc.eventCount=0; + dbc.ofsFirstEvent=dbc.ofsLastEvent=0; + dbc.ofsFirstSettings=0; + dbc.ofsNext=dbHeader.ofsFirstContact; + dbc.ofsFirstUnreadEvent=0; + dbc.timestampFirstUnread=0; + dbHeader.ofsFirstContact=ofsNew; + dbHeader.contactCount++; + DBWrite(ofsNew,&dbc,sizeof(struct DBContact)); + DBWrite(0,&dbHeader,sizeof(dbHeader)); + DBFlush(0); + + AddToCachedContactList((HANDLE)ofsNew, -1); + + LeaveCriticalSection(&csDbAccess); + NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); + return (INT_PTR)ofsNew; +} + +static INT_PTR IsDbContact(WPARAM wParam,LPARAM lParam) +{ + struct DBContact *dbc; + DWORD ofsContact=(DWORD)wParam; + int ret; + + EnterCriticalSection(&csDbAccess); + { + int index; + DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)wParam; + if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) + ret = TRUE; + else { + dbc=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + ret=dbc->signature==DBCONTACT_SIGNATURE; + if (ret) + AddToCachedContactList((HANDLE)wParam, index); + } } + + LeaveCriticalSection(&csDbAccess); + return ret; +} diff --git a/plugins/Dbx_mmap_SA/dbevents.c b/plugins/Dbx_mmap_SA/dbevents.c deleted file mode 100644 index 6ecde67a55..0000000000 --- a/plugins/Dbx_mmap_SA/dbevents.c +++ /dev/null @@ -1,499 +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" - -extern BOOL safetyMode; - -DWORD GetModuleNameOfs(const char *szName); -char *GetModuleNameByOfs(DWORD ofs); - -static INT_PTR GetEventCount(WPARAM wParam,LPARAM lParam); -static INT_PTR AddEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR DeleteEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR GetBlobSize(WPARAM wParam,LPARAM lParam); -static INT_PTR GetEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR MarkEventRead(WPARAM wParam,LPARAM lParam); -static INT_PTR GetEventContact(WPARAM wParam,LPARAM lParam); -static INT_PTR FindFirstEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR FindFirstUnreadEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR FindLastEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR FindNextEvent(WPARAM wParam,LPARAM lParam); -static INT_PTR FindPrevEvent(WPARAM wParam,LPARAM lParam); - -static HANDLE hEventDeletedEvent,hEventAddedEvent,hEventFilterAddedEvent; - -int InitEvents(void) -{ - CreateServiceFunction(MS_DB_EVENT_GETCOUNT,GetEventCount); - CreateServiceFunction(MS_DB_EVENT_ADD,AddEvent); - CreateServiceFunction(MS_DB_EVENT_DELETE,DeleteEvent); - CreateServiceFunction(MS_DB_EVENT_GETBLOBSIZE,GetBlobSize); - CreateServiceFunction(MS_DB_EVENT_GET,GetEvent); - CreateServiceFunction(MS_DB_EVENT_MARKREAD,MarkEventRead); - CreateServiceFunction(MS_DB_EVENT_GETCONTACT,GetEventContact); - CreateServiceFunction(MS_DB_EVENT_FINDFIRST,FindFirstEvent); - CreateServiceFunction(MS_DB_EVENT_FINDFIRSTUNREAD,FindFirstUnreadEvent); - CreateServiceFunction(MS_DB_EVENT_FINDLAST,FindLastEvent); - CreateServiceFunction(MS_DB_EVENT_FINDNEXT,FindNextEvent); - CreateServiceFunction(MS_DB_EVENT_FINDPREV,FindPrevEvent); - hEventDeletedEvent=CreateHookableEvent(ME_DB_EVENT_DELETED); - hEventAddedEvent=CreateHookableEvent(ME_DB_EVENT_ADDED); - hEventFilterAddedEvent=CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); - return 0; -} - -void UninitEvents(void) -{ -} - -static INT_PTR GetEventCount(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBContact *dbc; - - EnterCriticalSection(&csDbAccess); - if(wParam==0) wParam=dbHeader.ofsUser; - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) ret=-1; - else ret=dbc->eventCount; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR AddEvent(WPARAM wParam,LPARAM lParam) -{ - DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; - struct DBContact dbc; - struct DBEvent dbe,*dbeTest; - DWORD ofsNew,ofsModuleName,ofsContact,ofsThis; - BOOL neednotify; - - if(dbei==NULL||dbei->cbSize!=sizeof(DBEVENTINFO)) return 0; - if(dbei->timestamp==0) return 0; - if (NotifyEventHooks(hEventFilterAddedEvent,wParam,lParam)) { - return 0; - } - EnterCriticalSection(&csDbAccess); - if(wParam==0) ofsContact=dbHeader.ofsUser; - else ofsContact=(DWORD)wParam; - dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - if(dbc.signature!=DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 0; - } - ofsNew=CreateNewSpace(offsetof(struct 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=wParam; - dbe.ofsNext=0; - dbe.flags|=DBEF_FIRST; - dbc.ofsFirstEvent=dbc.ofsLastEvent=ofsNew; - } - else { - dbeTest=(struct DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(struct DBEvent),NULL); - // Should new event be placed before first event in chain? - if (dbei->timestamp < dbeTest->timestamp) { - dbe.ofsPrev=wParam; - dbe.ofsNext=dbc.ofsFirstEvent; - dbe.flags|=DBEF_FIRST; - dbc.ofsFirstEvent=ofsNew; - dbeTest=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); - dbeTest->flags&=~DBEF_FIRST; - dbeTest->ofsPrev=ofsNew; - DBWrite(dbe.ofsNext,dbeTest,sizeof(struct DBEvent)); - } - else { - // Loop through the chain, starting at the end - ofsThis = dbc.ofsLastEvent; - dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct 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(struct DBEvent)); - if (dbe.ofsNext == 0) - dbc.ofsLastEvent = ofsNew; - else { - dbeTest = (struct DBEvent*)DBRead(dbe.ofsNext, sizeof(struct DBEvent), NULL); - dbeTest->ofsPrev = ofsNew; - DBWrite(dbe.ofsNext, dbeTest, sizeof(struct DBEvent)); - } - break; - } - ofsThis = dbeTest->ofsPrev; - dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct DBEvent), NULL); - } - } - } - dbc.eventCount++; - if (!(dbe.flags&(DBEF_READ|DBEF_SENT))) { - if(dbe.timestamppBlob,dbei->cbBlob); - DBFlush(0); - - LeaveCriticalSection(&csDbAccess); - log1("add event @ %08x",ofsNew); - - // Notify only in safe mode or on really new events - if (neednotify) - NotifyEventHooks(hEventAddedEvent,wParam,(LPARAM)ofsNew); - - return (INT_PTR)ofsNew; -} - -static INT_PTR DeleteEvent(WPARAM wParam,LPARAM lParam) -{ - struct DBContact dbc; - DWORD ofsContact,ofsThis; - struct DBEvent dbe,*dbeNext,*dbePrev; - - EnterCriticalSection(&csDbAccess); - if(wParam==0) ofsContact=dbHeader.ofsUser; - else ofsContact=wParam; - dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct 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,lParam); - //get back in - EnterCriticalSection(&csDbAccess); - dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL); - //check if this was the first unread, if so, recalc the first unread - if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) { - dbeNext=&dbe; - for (;;) { - if(dbeNext->ofsNext==0) { - dbc.ofsFirstUnreadEvent=0; - dbc.timestampFirstUnread=0; - break; - } - ofsThis=dbeNext->ofsNext; - dbeNext=(struct DBEvent*)DBRead(ofsThis,sizeof(struct 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=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); - dbeNext->flags|=DBEF_FIRST; - dbeNext->ofsPrev=dbe.ofsPrev; - DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent)); - dbc.ofsFirstEvent=dbe.ofsNext; - } - } - else { - if(dbe.ofsNext==0) { - dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL); - dbePrev->ofsNext=0; - DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent)); - dbc.ofsLastEvent=dbe.ofsPrev; - } - else { - dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL); - dbePrev->ofsNext=dbe.ofsNext; - DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent)); - dbeNext=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); - dbeNext->ofsPrev=dbe.ofsPrev; - DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent)); - } - } - //delete event - DeleteSpace(lParam,offsetof(struct DBEvent,blob)+dbe.cbBlob); - //decrement event count - dbc.eventCount--; - DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); - DBFlush(0); - //quit - LeaveCriticalSection(&csDbAccess); - return 0; -} - -static INT_PTR GetBlobSize(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBEvent *dbe; - - EnterCriticalSection(&csDbAccess); - dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); - if(dbe->signature!=DBEVENT_SIGNATURE) ret=-1; - else ret=dbe->cbBlob; - - LeaveCriticalSection(&csDbAccess); - return ret; -} - -void EncodeContactEvents(HANDLE hContact) -{ - HANDLE hEvent; - - hEvent = (HANDLE)FindFirstEvent((WPARAM)hContact, 0); - if(hEvent == 0) return; - do{ - EncodeEvent(hEvent); - }while (hEvent = (HANDLE)FindNextEvent((WPARAM)hEvent, 0)); -} - -extern Cryptor* CryptoEngine; -extern void* key; - -void EncodeEvent(HANDLE hEvent) -{ - struct DBEvent *dbe; - - dbe=(struct DBEvent*)DBRead((DWORD)hEvent,sizeof(struct DBEvent),NULL); - if(dbe->signature=DBEVENT_SIGNATURE){ - CryptoEngine->EncryptMem(DBRead((DWORD)hEvent + offsetof(struct DBEvent,blob), dbe->cbBlob, NULL), dbe->cbBlob, key); - //EncodeDBWrite((DWORD)hEvent + offsetof(struct DBEvent,blob), DBRead((DWORD)hEvent + offsetof(struct DBEvent,blob), dbe->cbBlob, NULL), dbe->cbBlob); - } - -} - -void DecodeEvent(HANDLE hEvent) -{ - struct DBEvent *dbe; - - dbe=(struct DBEvent*)DBRead((DWORD)hEvent,sizeof(struct DBEvent),NULL); - if(dbe->signature=DBEVENT_SIGNATURE){ - CryptoEngine->DecryptMem(DBRead((DWORD)hEvent + offsetof(struct DBEvent,blob), dbe->cbBlob, NULL), dbe->cbBlob, key); - } - -} - -void DecodeContactEvents(HANDLE hContact) -{ - HANDLE hEvent; - - hEvent = (HANDLE)FindFirstEvent((WPARAM)hContact, 0); - if(hEvent == 0) return; - do{ - DecodeEvent(hEvent); - }while (hEvent = (HANDLE)FindNextEvent((WPARAM)hEvent, 0)); -} - - -INT_PTR GetEvent(WPARAM wParam, LPARAM lParam) -{ - struct DBEvent *dbe; - DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; - 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); - dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct 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->cbBlobcbBlob) bytesToCopy=dbei->cbBlob; - else bytesToCopy=dbe->cbBlob; - dbei->cbBlob=dbe->cbBlob; - if (bytesToCopy && dbei->pBlob) - { - for(i=0;;i+=MAXCACHEDREADSIZE) { - if(bytesToCopy-i<=MAXCACHEDREADSIZE) { - DecodeCopyMemory(dbei->pBlob+i,DBRead(wParam+offsetof(struct DBEvent,blob)+i,bytesToCopy-i,NULL),bytesToCopy-i); - break; - } - DecodeCopyMemory(dbei->pBlob+i,DBRead(wParam+offsetof(struct DBEvent,blob)+i,MAXCACHEDREADSIZE,NULL),MAXCACHEDREADSIZE); - } - } - LeaveCriticalSection(&csDbAccess); - return 0; -} - -static INT_PTR MarkEventRead(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBEvent *dbe; - struct DBContact dbc; - DWORD ofsThis; - - EnterCriticalSection(&csDbAccess); - if(wParam==0) wParam=dbHeader.ofsUser; - dbc=*(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - dbe=(struct DBEvent*)DBRead(lParam,sizeof(struct 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(lParam,dbe,sizeof(struct DBEvent)); - ret=(int)dbe->flags; - if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) { - for (;;) { - if(dbe->ofsNext==0) { - dbc.ofsFirstUnreadEvent=0; - dbc.timestampFirstUnread=0; - break; - } - ofsThis=dbe->ofsNext; - dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); - if (!(dbe->flags&(DBEF_READ|DBEF_SENT))) { - dbc.ofsFirstUnreadEvent=ofsThis; - dbc.timestampFirstUnread=dbe->timestamp; - break; - } - } - } - DBWrite(wParam,&dbc,sizeof(struct DBContact)); - DBFlush(0); - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR GetEventContact(WPARAM wParam,LPARAM lParam) -{ - int ret; - struct DBEvent *dbe; - - EnterCriticalSection(&csDbAccess); - dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); - if(dbe->signature!=DBEVENT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - while(!(dbe->flags&DBEF_FIRST)) - dbe=(struct DBEvent*)DBRead(dbe->ofsPrev,sizeof(struct DBEvent),NULL); - ret=(INT_PTR)dbe->ofsPrev; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR FindFirstEvent(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBContact *dbc; - - EnterCriticalSection(&csDbAccess); - if(wParam==0) wParam=dbHeader.ofsUser; - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) ret=0; - else ret=(INT_PTR)dbc->ofsFirstEvent; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR FindFirstUnreadEvent(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBContact *dbc; - - EnterCriticalSection(&csDbAccess); - if(wParam==0) wParam=dbHeader.ofsUser; - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) ret=0; - else ret=(INT_PTR)dbc->ofsFirstUnreadEvent; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR FindLastEvent(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBContact *dbc; - - EnterCriticalSection(&csDbAccess); - if(wParam==0) wParam=dbHeader.ofsUser; - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) ret=0; - else ret=(INT_PTR)dbc->ofsLastEvent; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR FindNextEvent(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBEvent *dbe; - - EnterCriticalSection(&csDbAccess); - dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); - if(dbe->signature!=DBEVENT_SIGNATURE) ret=0; - else ret=(INT_PTR)dbe->ofsNext; - LeaveCriticalSection(&csDbAccess); - return ret; -} - -static INT_PTR FindPrevEvent(WPARAM wParam,LPARAM lParam) -{ - INT_PTR ret; - struct DBEvent *dbe; - - EnterCriticalSection(&csDbAccess); - dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); - if(dbe->signature!=DBEVENT_SIGNATURE) ret=0; - else if(dbe->flags&DBEF_FIRST) ret=0; - else ret=(INT_PTR)dbe->ofsPrev; - LeaveCriticalSection(&csDbAccess); - return ret; -} diff --git a/plugins/Dbx_mmap_SA/dbevents.cpp b/plugins/Dbx_mmap_SA/dbevents.cpp new file mode 100644 index 0000000000..6ecde67a55 --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbevents.cpp @@ -0,0 +1,499 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +extern BOOL safetyMode; + +DWORD GetModuleNameOfs(const char *szName); +char *GetModuleNameByOfs(DWORD ofs); + +static INT_PTR GetEventCount(WPARAM wParam,LPARAM lParam); +static INT_PTR AddEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR DeleteEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR GetBlobSize(WPARAM wParam,LPARAM lParam); +static INT_PTR GetEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR MarkEventRead(WPARAM wParam,LPARAM lParam); +static INT_PTR GetEventContact(WPARAM wParam,LPARAM lParam); +static INT_PTR FindFirstEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR FindFirstUnreadEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR FindLastEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR FindNextEvent(WPARAM wParam,LPARAM lParam); +static INT_PTR FindPrevEvent(WPARAM wParam,LPARAM lParam); + +static HANDLE hEventDeletedEvent,hEventAddedEvent,hEventFilterAddedEvent; + +int InitEvents(void) +{ + CreateServiceFunction(MS_DB_EVENT_GETCOUNT,GetEventCount); + CreateServiceFunction(MS_DB_EVENT_ADD,AddEvent); + CreateServiceFunction(MS_DB_EVENT_DELETE,DeleteEvent); + CreateServiceFunction(MS_DB_EVENT_GETBLOBSIZE,GetBlobSize); + CreateServiceFunction(MS_DB_EVENT_GET,GetEvent); + CreateServiceFunction(MS_DB_EVENT_MARKREAD,MarkEventRead); + CreateServiceFunction(MS_DB_EVENT_GETCONTACT,GetEventContact); + CreateServiceFunction(MS_DB_EVENT_FINDFIRST,FindFirstEvent); + CreateServiceFunction(MS_DB_EVENT_FINDFIRSTUNREAD,FindFirstUnreadEvent); + CreateServiceFunction(MS_DB_EVENT_FINDLAST,FindLastEvent); + CreateServiceFunction(MS_DB_EVENT_FINDNEXT,FindNextEvent); + CreateServiceFunction(MS_DB_EVENT_FINDPREV,FindPrevEvent); + hEventDeletedEvent=CreateHookableEvent(ME_DB_EVENT_DELETED); + hEventAddedEvent=CreateHookableEvent(ME_DB_EVENT_ADDED); + hEventFilterAddedEvent=CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); + return 0; +} + +void UninitEvents(void) +{ +} + +static INT_PTR GetEventCount(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBContact *dbc; + + EnterCriticalSection(&csDbAccess); + if(wParam==0) wParam=dbHeader.ofsUser; + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) ret=-1; + else ret=dbc->eventCount; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR AddEvent(WPARAM wParam,LPARAM lParam) +{ + DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; + struct DBContact dbc; + struct DBEvent dbe,*dbeTest; + DWORD ofsNew,ofsModuleName,ofsContact,ofsThis; + BOOL neednotify; + + if(dbei==NULL||dbei->cbSize!=sizeof(DBEVENTINFO)) return 0; + if(dbei->timestamp==0) return 0; + if (NotifyEventHooks(hEventFilterAddedEvent,wParam,lParam)) { + return 0; + } + EnterCriticalSection(&csDbAccess); + if(wParam==0) ofsContact=dbHeader.ofsUser; + else ofsContact=(DWORD)wParam; + dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + if(dbc.signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return 0; + } + ofsNew=CreateNewSpace(offsetof(struct 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=wParam; + dbe.ofsNext=0; + dbe.flags|=DBEF_FIRST; + dbc.ofsFirstEvent=dbc.ofsLastEvent=ofsNew; + } + else { + dbeTest=(struct DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(struct DBEvent),NULL); + // Should new event be placed before first event in chain? + if (dbei->timestamp < dbeTest->timestamp) { + dbe.ofsPrev=wParam; + dbe.ofsNext=dbc.ofsFirstEvent; + dbe.flags|=DBEF_FIRST; + dbc.ofsFirstEvent=ofsNew; + dbeTest=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); + dbeTest->flags&=~DBEF_FIRST; + dbeTest->ofsPrev=ofsNew; + DBWrite(dbe.ofsNext,dbeTest,sizeof(struct DBEvent)); + } + else { + // Loop through the chain, starting at the end + ofsThis = dbc.ofsLastEvent; + dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct 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(struct DBEvent)); + if (dbe.ofsNext == 0) + dbc.ofsLastEvent = ofsNew; + else { + dbeTest = (struct DBEvent*)DBRead(dbe.ofsNext, sizeof(struct DBEvent), NULL); + dbeTest->ofsPrev = ofsNew; + DBWrite(dbe.ofsNext, dbeTest, sizeof(struct DBEvent)); + } + break; + } + ofsThis = dbeTest->ofsPrev; + dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct DBEvent), NULL); + } + } + } + dbc.eventCount++; + if (!(dbe.flags&(DBEF_READ|DBEF_SENT))) { + if(dbe.timestamppBlob,dbei->cbBlob); + DBFlush(0); + + LeaveCriticalSection(&csDbAccess); + log1("add event @ %08x",ofsNew); + + // Notify only in safe mode or on really new events + if (neednotify) + NotifyEventHooks(hEventAddedEvent,wParam,(LPARAM)ofsNew); + + return (INT_PTR)ofsNew; +} + +static INT_PTR DeleteEvent(WPARAM wParam,LPARAM lParam) +{ + struct DBContact dbc; + DWORD ofsContact,ofsThis; + struct DBEvent dbe,*dbeNext,*dbePrev; + + EnterCriticalSection(&csDbAccess); + if(wParam==0) ofsContact=dbHeader.ofsUser; + else ofsContact=wParam; + dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct 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,lParam); + //get back in + EnterCriticalSection(&csDbAccess); + dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL); + //check if this was the first unread, if so, recalc the first unread + if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) { + dbeNext=&dbe; + for (;;) { + if(dbeNext->ofsNext==0) { + dbc.ofsFirstUnreadEvent=0; + dbc.timestampFirstUnread=0; + break; + } + ofsThis=dbeNext->ofsNext; + dbeNext=(struct DBEvent*)DBRead(ofsThis,sizeof(struct 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=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); + dbeNext->flags|=DBEF_FIRST; + dbeNext->ofsPrev=dbe.ofsPrev; + DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent)); + dbc.ofsFirstEvent=dbe.ofsNext; + } + } + else { + if(dbe.ofsNext==0) { + dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL); + dbePrev->ofsNext=0; + DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent)); + dbc.ofsLastEvent=dbe.ofsPrev; + } + else { + dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL); + dbePrev->ofsNext=dbe.ofsNext; + DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent)); + dbeNext=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); + dbeNext->ofsPrev=dbe.ofsPrev; + DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent)); + } + } + //delete event + DeleteSpace(lParam,offsetof(struct DBEvent,blob)+dbe.cbBlob); + //decrement event count + dbc.eventCount--; + DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); + DBFlush(0); + //quit + LeaveCriticalSection(&csDbAccess); + return 0; +} + +static INT_PTR GetBlobSize(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBEvent *dbe; + + EnterCriticalSection(&csDbAccess); + dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); + if(dbe->signature!=DBEVENT_SIGNATURE) ret=-1; + else ret=dbe->cbBlob; + + LeaveCriticalSection(&csDbAccess); + return ret; +} + +void EncodeContactEvents(HANDLE hContact) +{ + HANDLE hEvent; + + hEvent = (HANDLE)FindFirstEvent((WPARAM)hContact, 0); + if(hEvent == 0) return; + do{ + EncodeEvent(hEvent); + }while (hEvent = (HANDLE)FindNextEvent((WPARAM)hEvent, 0)); +} + +extern Cryptor* CryptoEngine; +extern void* key; + +void EncodeEvent(HANDLE hEvent) +{ + struct DBEvent *dbe; + + dbe=(struct DBEvent*)DBRead((DWORD)hEvent,sizeof(struct DBEvent),NULL); + if(dbe->signature=DBEVENT_SIGNATURE){ + CryptoEngine->EncryptMem(DBRead((DWORD)hEvent + offsetof(struct DBEvent,blob), dbe->cbBlob, NULL), dbe->cbBlob, key); + //EncodeDBWrite((DWORD)hEvent + offsetof(struct DBEvent,blob), DBRead((DWORD)hEvent + offsetof(struct DBEvent,blob), dbe->cbBlob, NULL), dbe->cbBlob); + } + +} + +void DecodeEvent(HANDLE hEvent) +{ + struct DBEvent *dbe; + + dbe=(struct DBEvent*)DBRead((DWORD)hEvent,sizeof(struct DBEvent),NULL); + if(dbe->signature=DBEVENT_SIGNATURE){ + CryptoEngine->DecryptMem(DBRead((DWORD)hEvent + offsetof(struct DBEvent,blob), dbe->cbBlob, NULL), dbe->cbBlob, key); + } + +} + +void DecodeContactEvents(HANDLE hContact) +{ + HANDLE hEvent; + + hEvent = (HANDLE)FindFirstEvent((WPARAM)hContact, 0); + if(hEvent == 0) return; + do{ + DecodeEvent(hEvent); + }while (hEvent = (HANDLE)FindNextEvent((WPARAM)hEvent, 0)); +} + + +INT_PTR GetEvent(WPARAM wParam, LPARAM lParam) +{ + struct DBEvent *dbe; + DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; + 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); + dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct 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->cbBlobcbBlob) bytesToCopy=dbei->cbBlob; + else bytesToCopy=dbe->cbBlob; + dbei->cbBlob=dbe->cbBlob; + if (bytesToCopy && dbei->pBlob) + { + for(i=0;;i+=MAXCACHEDREADSIZE) { + if(bytesToCopy-i<=MAXCACHEDREADSIZE) { + DecodeCopyMemory(dbei->pBlob+i,DBRead(wParam+offsetof(struct DBEvent,blob)+i,bytesToCopy-i,NULL),bytesToCopy-i); + break; + } + DecodeCopyMemory(dbei->pBlob+i,DBRead(wParam+offsetof(struct DBEvent,blob)+i,MAXCACHEDREADSIZE,NULL),MAXCACHEDREADSIZE); + } + } + LeaveCriticalSection(&csDbAccess); + return 0; +} + +static INT_PTR MarkEventRead(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBEvent *dbe; + struct DBContact dbc; + DWORD ofsThis; + + EnterCriticalSection(&csDbAccess); + if(wParam==0) wParam=dbHeader.ofsUser; + dbc=*(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + dbe=(struct DBEvent*)DBRead(lParam,sizeof(struct 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(lParam,dbe,sizeof(struct DBEvent)); + ret=(int)dbe->flags; + if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) { + for (;;) { + if(dbe->ofsNext==0) { + dbc.ofsFirstUnreadEvent=0; + dbc.timestampFirstUnread=0; + break; + } + ofsThis=dbe->ofsNext; + dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); + if (!(dbe->flags&(DBEF_READ|DBEF_SENT))) { + dbc.ofsFirstUnreadEvent=ofsThis; + dbc.timestampFirstUnread=dbe->timestamp; + break; + } + } + } + DBWrite(wParam,&dbc,sizeof(struct DBContact)); + DBFlush(0); + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR GetEventContact(WPARAM wParam,LPARAM lParam) +{ + int ret; + struct DBEvent *dbe; + + EnterCriticalSection(&csDbAccess); + dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); + if(dbe->signature!=DBEVENT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return -1; + } + while(!(dbe->flags&DBEF_FIRST)) + dbe=(struct DBEvent*)DBRead(dbe->ofsPrev,sizeof(struct DBEvent),NULL); + ret=(INT_PTR)dbe->ofsPrev; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindFirstEvent(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBContact *dbc; + + EnterCriticalSection(&csDbAccess); + if(wParam==0) wParam=dbHeader.ofsUser; + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) ret=0; + else ret=(INT_PTR)dbc->ofsFirstEvent; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindFirstUnreadEvent(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBContact *dbc; + + EnterCriticalSection(&csDbAccess); + if(wParam==0) wParam=dbHeader.ofsUser; + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) ret=0; + else ret=(INT_PTR)dbc->ofsFirstUnreadEvent; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindLastEvent(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBContact *dbc; + + EnterCriticalSection(&csDbAccess); + if(wParam==0) wParam=dbHeader.ofsUser; + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) ret=0; + else ret=(INT_PTR)dbc->ofsLastEvent; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindNextEvent(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBEvent *dbe; + + EnterCriticalSection(&csDbAccess); + dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); + if(dbe->signature!=DBEVENT_SIGNATURE) ret=0; + else ret=(INT_PTR)dbe->ofsNext; + LeaveCriticalSection(&csDbAccess); + return ret; +} + +static INT_PTR FindPrevEvent(WPARAM wParam,LPARAM lParam) +{ + INT_PTR ret; + struct DBEvent *dbe; + + EnterCriticalSection(&csDbAccess); + dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL); + if(dbe->signature!=DBEVENT_SIGNATURE) ret=0; + else if(dbe->flags&DBEF_FIRST) ret=0; + else ret=(INT_PTR)dbe->ofsPrev; + LeaveCriticalSection(&csDbAccess); + return ret; +} diff --git a/plugins/Dbx_mmap_SA/dbheaders.c b/plugins/Dbx_mmap_SA/dbheaders.c deleted file mode 100644 index 16c33dff2f..0000000000 --- a/plugins/Dbx_mmap_SA/dbheaders.c +++ /dev/null @@ -1,75 +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" - -//the cache has not been loaded when these functions are used - -int CreateDbHeaders(HANDLE hFile) -{ - struct DBContact user; - DWORD bytesWritten; - - CopyMemory(dbHeader.signature,&dbSignature,sizeof(dbHeader.signature)); - dbHeader.checkWord = 0x0700; - dbHeader.cryptorUID = 0x0000; - 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(struct 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(struct DBContact),&bytesWritten,NULL); - FlushFileBuffers(hFile); - return 0; -} - -int CheckDbHeaders(struct DBHeader * hdr) -{ - if(memcmp(hdr->signature,&dbSignatureSecured,sizeof(hdr->signature)) == 0){ - bEncoding = 1; - }else{ - bEncoding = 0; - if(memcmp(hdr->signature,&dbSignature,sizeof(hdr->signature))) return 1; - if(hdr->checkWord!=0x0700) return 2; - } - if(hdr->ofsUser==0) return 3; - return 0; -} - -int InitialiseDbHeaders(void) -{ - return 0; -} diff --git a/plugins/Dbx_mmap_SA/dbheaders.cpp b/plugins/Dbx_mmap_SA/dbheaders.cpp new file mode 100644 index 0000000000..16c33dff2f --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbheaders.cpp @@ -0,0 +1,75 @@ +/* + +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" + +//the cache has not been loaded when these functions are used + +int CreateDbHeaders(HANDLE hFile) +{ + struct DBContact user; + DWORD bytesWritten; + + CopyMemory(dbHeader.signature,&dbSignature,sizeof(dbHeader.signature)); + dbHeader.checkWord = 0x0700; + dbHeader.cryptorUID = 0x0000; + 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(struct 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(struct DBContact),&bytesWritten,NULL); + FlushFileBuffers(hFile); + return 0; +} + +int CheckDbHeaders(struct DBHeader * hdr) +{ + if(memcmp(hdr->signature,&dbSignatureSecured,sizeof(hdr->signature)) == 0){ + bEncoding = 1; + }else{ + bEncoding = 0; + if(memcmp(hdr->signature,&dbSignature,sizeof(hdr->signature))) return 1; + if(hdr->checkWord!=0x0700) return 2; + } + if(hdr->ofsUser==0) return 3; + return 0; +} + +int InitialiseDbHeaders(void) +{ + return 0; +} diff --git a/plugins/Dbx_mmap_SA/dbmodulechain.c b/plugins/Dbx_mmap_SA/dbmodulechain.c deleted file mode 100644 index 1af4226419..0000000000 --- a/plugins/Dbx_mmap_SA/dbmodulechain.c +++ /dev/null @@ -1,192 +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); - -typedef struct { - char *name; - DWORD ofs; -} ModuleName; - -HANDLE hModHeap = NULL; -static SortedList lMods, lOfs; - -static int ModCompare( ModuleName *mn1, ModuleName *mn2 ) -{ - return strcmp( mn1->name, mn2->name ); -} - -static int OfsCompare( ModuleName *mn1, ModuleName *mn2 ) -{ - return ( mn1->ofs - mn2->ofs ); -} - -void AddToList(char *name, DWORD len, DWORD ofs) -{ - int index; - ModuleName *mn = (ModuleName*)HeapAlloc(hModHeap,0,sizeof(ModuleName)); - mn->name = name; - mn->ofs = ofs; - - if (li.List_GetIndex(&lMods,mn,&index)) - DatabaseCorruption( _T("%s (Module Name not unique)")); - - li.List_Insert(&lMods,mn,index); - - if (li.List_GetIndex(&lOfs,mn,&index)) - DatabaseCorruption( _T("%s (Module Offset not unique)")); - - li.List_Insert(&lOfs,mn,index); -} - - -int InitModuleNames(void) -{ - struct DBModuleName *dbmn; - DWORD ofsThis; - int nameLen; - char *mod; - - hModHeap=HeapCreate(0,0,0); - lMods.sortFunc=ModCompare; - lMods.increment=50; - lOfs.sortFunc=OfsCompare; - lOfs.increment=50; - - ofsThis=dbHeader.ofsFirstModuleName; - dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); - while(ofsThis) { - if(dbmn->signature!=DBMODULENAME_SIGNATURE) DatabaseCorruption(NULL); - - nameLen=dbmn->cbName; - - mod = (char*)HeapAlloc(hModHeap,0,nameLen+1); - CopyMemory(mod,DBRead(ofsThis+offsetof(struct DBModuleName,name),nameLen,NULL),nameLen); - mod[nameLen] = 0; - - AddToList(mod, nameLen, ofsThis); - - ofsThis=dbmn->ofsNext; - dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); - } - CreateServiceFunction(MS_DB_MODULES_ENUM,EnumModuleNames); - return 0; -} - -void UninitModuleNames(void) -{ - HeapDestroy(hModHeap); - li.List_Destroy(&lMods); - li.List_Destroy(&lOfs); -} - -static DWORD FindExistingModuleNameOfs(const char *szName) -{ - static ModuleName *lastmn = NULL; - ModuleName mn, *pmn; - int index; - - mn.name = (char*)szName; - mn.ofs = 0; - - if (lastmn && ModCompare(&mn,lastmn) == 0) - return lastmn->ofs; - - if (li.List_GetIndex(&lMods,&mn,&index)) { - pmn = (ModuleName*)lMods.items[index]; - lastmn = pmn; - return pmn->ofs; - } - - return 0; -} - -//will create the offset if it needs to -DWORD GetModuleNameOfs(const char *szName) -{ - struct DBModuleName dbmn; - int nameLen; - DWORD ofsNew,ofsExisting; - char *mod; - - ofsExisting=FindExistingModuleNameOfs(szName); - if(ofsExisting) return ofsExisting; - - nameLen = (int)strlen(szName); - - //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 - mod = (char*)HeapAlloc(hModHeap,0,nameLen+1); - strcpy(mod,szName); - AddToList(mod, nameLen, ofsNew); - - //quit - return ofsNew; -} - -char *GetModuleNameByOfs(DWORD ofs) -{ - static ModuleName *lastmn = NULL; - ModuleName mn, *pmn; - int index; - - if (lastmn && lastmn->ofs == ofs) - return lastmn->name; - - mn.name = NULL; - mn.ofs = ofs; - - if (li.List_GetIndex(&lOfs,&mn,&index)) { - pmn = (ModuleName*)lOfs.items[index]; - lastmn = pmn; - return pmn->name; - } - - DatabaseCorruption(NULL); - return NULL; -} - -static INT_PTR EnumModuleNames(WPARAM wParam,LPARAM lParam) -{ - int i; - int ret; - ModuleName *pmn; - for(i = 0; i < lMods.realCount; i++) { - pmn = (ModuleName *)lMods.items[i]; - ret=((DBMODULEENUMPROC)lParam)(pmn->name,pmn->ofs,wParam); - if(ret) return ret; - } - return 0; -} diff --git a/plugins/Dbx_mmap_SA/dbmodulechain.cpp b/plugins/Dbx_mmap_SA/dbmodulechain.cpp new file mode 100644 index 0000000000..1af4226419 --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbmodulechain.cpp @@ -0,0 +1,192 @@ +/* + +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); + +typedef struct { + char *name; + DWORD ofs; +} ModuleName; + +HANDLE hModHeap = NULL; +static SortedList lMods, lOfs; + +static int ModCompare( ModuleName *mn1, ModuleName *mn2 ) +{ + return strcmp( mn1->name, mn2->name ); +} + +static int OfsCompare( ModuleName *mn1, ModuleName *mn2 ) +{ + return ( mn1->ofs - mn2->ofs ); +} + +void AddToList(char *name, DWORD len, DWORD ofs) +{ + int index; + ModuleName *mn = (ModuleName*)HeapAlloc(hModHeap,0,sizeof(ModuleName)); + mn->name = name; + mn->ofs = ofs; + + if (li.List_GetIndex(&lMods,mn,&index)) + DatabaseCorruption( _T("%s (Module Name not unique)")); + + li.List_Insert(&lMods,mn,index); + + if (li.List_GetIndex(&lOfs,mn,&index)) + DatabaseCorruption( _T("%s (Module Offset not unique)")); + + li.List_Insert(&lOfs,mn,index); +} + + +int InitModuleNames(void) +{ + struct DBModuleName *dbmn; + DWORD ofsThis; + int nameLen; + char *mod; + + hModHeap=HeapCreate(0,0,0); + lMods.sortFunc=ModCompare; + lMods.increment=50; + lOfs.sortFunc=OfsCompare; + lOfs.increment=50; + + ofsThis=dbHeader.ofsFirstModuleName; + dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); + while(ofsThis) { + if(dbmn->signature!=DBMODULENAME_SIGNATURE) DatabaseCorruption(NULL); + + nameLen=dbmn->cbName; + + mod = (char*)HeapAlloc(hModHeap,0,nameLen+1); + CopyMemory(mod,DBRead(ofsThis+offsetof(struct DBModuleName,name),nameLen,NULL),nameLen); + mod[nameLen] = 0; + + AddToList(mod, nameLen, ofsThis); + + ofsThis=dbmn->ofsNext; + dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); + } + CreateServiceFunction(MS_DB_MODULES_ENUM,EnumModuleNames); + return 0; +} + +void UninitModuleNames(void) +{ + HeapDestroy(hModHeap); + li.List_Destroy(&lMods); + li.List_Destroy(&lOfs); +} + +static DWORD FindExistingModuleNameOfs(const char *szName) +{ + static ModuleName *lastmn = NULL; + ModuleName mn, *pmn; + int index; + + mn.name = (char*)szName; + mn.ofs = 0; + + if (lastmn && ModCompare(&mn,lastmn) == 0) + return lastmn->ofs; + + if (li.List_GetIndex(&lMods,&mn,&index)) { + pmn = (ModuleName*)lMods.items[index]; + lastmn = pmn; + return pmn->ofs; + } + + return 0; +} + +//will create the offset if it needs to +DWORD GetModuleNameOfs(const char *szName) +{ + struct DBModuleName dbmn; + int nameLen; + DWORD ofsNew,ofsExisting; + char *mod; + + ofsExisting=FindExistingModuleNameOfs(szName); + if(ofsExisting) return ofsExisting; + + nameLen = (int)strlen(szName); + + //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 + mod = (char*)HeapAlloc(hModHeap,0,nameLen+1); + strcpy(mod,szName); + AddToList(mod, nameLen, ofsNew); + + //quit + return ofsNew; +} + +char *GetModuleNameByOfs(DWORD ofs) +{ + static ModuleName *lastmn = NULL; + ModuleName mn, *pmn; + int index; + + if (lastmn && lastmn->ofs == ofs) + return lastmn->name; + + mn.name = NULL; + mn.ofs = ofs; + + if (li.List_GetIndex(&lOfs,&mn,&index)) { + pmn = (ModuleName*)lOfs.items[index]; + lastmn = pmn; + return pmn->name; + } + + DatabaseCorruption(NULL); + return NULL; +} + +static INT_PTR EnumModuleNames(WPARAM wParam,LPARAM lParam) +{ + int i; + int ret; + ModuleName *pmn; + for(i = 0; i < lMods.realCount; i++) { + pmn = (ModuleName *)lMods.items[i]; + ret=((DBMODULEENUMPROC)lParam)(pmn->name,pmn->ofs,wParam); + if(ret) return ret; + } + return 0; +} diff --git a/plugins/Dbx_mmap_SA/dbpreset.c b/plugins/Dbx_mmap_SA/dbpreset.c deleted file mode 100644 index 0bb6ebd3a0..0000000000 --- a/plugins/Dbx_mmap_SA/dbpreset.c +++ /dev/null @@ -1,299 +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. -*/ -// Miranda Memory-Mapped Secured DataBase -// (C) Artem Shpynov aka FYR, Igonin Vitaliy aka chaos.persei, Victor Pavlychko aka nullbie, 2007 - 2008 - -#include "commonheaders.h" - -/* Public API */ -int InitPreset(); -void UninitPreset(); - -int DBPreset_QuerySetting (const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); -int DBPreset_CompareSetting (const char *szModule, const char *szSetting, DBVARIANT *dbv); - -/* Preset cache item */ -typedef struct -{ - DWORD dwHash; - char *szModule; - char *szSetting; - DBVARIANT dbv; -} DBPresetItem; - -static DBPresetItem * DBPresetItem_Create (char *szModule, char *szSetting, BYTE bType); -static void DBPresetItem_Destroy (DBPresetItem *item); -static void DBPresetItem_Hash (DBPresetItem *item); -static int DBPresetItem_Cmp (DBPresetItem *item1, DBPresetItem *item2); - -SortedList *lstPresets = NULL; - -int InitPreset() -{ - char szIniPath[MAX_PATH]; - char szLine[2048]; - int lineLength; - char szSection[128]; - FILE *fp; - - GetModuleFileNameA(GetModuleHandle(NULL), szIniPath, SIZEOF(szIniPath)); - strcpy(strrchr(szIniPath, '\\')+1, "dbpreset.ini"); - - fp=fopen(szIniPath,"rt"); - - // no preset - if (!fp) return 0; - - lstPresets = li.List_Create(0, 50); - lstPresets->sortFunc = DBPresetItem_Cmp; - - while(!feof(fp)) - { - if(fgets(szLine,sizeof(szLine),fp)==NULL) break; - lineLength=lstrlenA(szLine); - while(lineLength && (BYTE)(szLine[lineLength-1])<=' ') szLine[--lineLength]='\0'; - if(szLine[0]==';' || szLine[0]<=' ') continue; - if(szLine[0]=='[') - { - char *szEnd=strchr(szLine+1,']'); - if(szEnd==NULL) continue; - if(szLine[1]=='!') - szSection[0]='\0'; - else - lstrcpynA(szSection, szLine+1, (int)min(sizeof(szSection), szEnd-szLine)); - } else - { - char *szValue; - char szName[128]; - DBPresetItem *item; - - if(szSection[0]=='\0') continue; - szValue=strchr(szLine,'='); - if(szValue==NULL) continue; - lstrcpynA(szName, szLine, (int)min(sizeof(szName), szValue-szLine+1)); - szValue++; - - switch(szValue[0]) - { - case 'b': - case 'B': - item = DBPresetItem_Create(szSection, szName, DBVT_BYTE); - item->dbv.bVal = (BYTE)strtol(szValue+1,NULL,0); - li.List_InsertPtr(lstPresets, item); - break; - case 'w': - case 'W': - item = DBPresetItem_Create(szSection, szName, DBVT_WORD); - item->dbv.wVal = (WORD)strtol(szValue+1,NULL,0); - li.List_InsertPtr(lstPresets, item); - break; - case 'd': - case 'D': - item = DBPresetItem_Create(szSection, szName, DBVT_DWORD); - item->dbv.dVal = (DWORD)strtoul(szValue+1,NULL,0); - li.List_InsertPtr(lstPresets, item); - break; - case 's': - case 'S': - item = DBPresetItem_Create(szSection, szName, DBVT_ASCIIZ); - item->dbv.pszVal = mir_strdup(szValue+1); - li.List_InsertPtr(lstPresets, item); - break; - case 'u': - case 'U': - item = DBPresetItem_Create(szSection, szName, DBVT_UTF8); - item->dbv.pszVal = mir_strdup(szValue+1); - li.List_InsertPtr(lstPresets, item); - break; - case 'n': - case 'N': - { - PBYTE buf; - int len; - char *pszValue,*pszEnd; - - buf=(PBYTE)mir_alloc(lstrlenA(szValue+1)); - for(len=0,pszValue=szValue+1;;len++) { - buf[len]=(BYTE)strtol(pszValue,&pszEnd,0x10); - if(pszValue==pszEnd) break; - pszValue=pszEnd; - } - - item = DBPresetItem_Create(szSection, szName, DBVT_BLOB); - item->dbv.pbVal = buf; - item->dbv.cpbVal = len; - li.List_InsertPtr(lstPresets, item); - break; - } - } - } - } - fclose(fp); - - return 0; -} - -void UninitPreset() -{ - int i; - if (!lstPresets) return; - for (i = 0; i < lstPresets->realCount; ++i) - DBPresetItem_Destroy(lstPresets->items[i]); - li.List_Destroy(lstPresets); -} - -int DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic) -{ - DBPresetItem *item; - DBPresetItem search = {0}; - - if (!lstPresets) return FALSE; - - search.szModule = (char *)szModule; - search.szSetting = (char *)szSetting; - DBPresetItem_Hash(&search); - item = li.List_Find(lstPresets, &search); - - if (!item) return FALSE; - - dbv->type = item->dbv.type; - switch (item->dbv.type) - { - case DBVT_BYTE: dbv->bVal = item->dbv.bVal; return TRUE; - case DBVT_WORD: dbv->wVal = item->dbv.wVal; return TRUE; - case DBVT_DWORD: dbv->dVal = item->dbv.dVal; return TRUE; - - case DBVT_UTF8: - case DBVT_ASCIIZ: - if (isStatic && dbv->pszVal) - lstrcpynA(dbv->pszVal, item->dbv.pszVal, dbv->cchVal); - else if (!isStatic) - dbv->pszVal = mir_strdup(item->dbv.pszVal); - return TRUE; - - default: - return FALSE; - } - - return FALSE; -} - -int DBPreset_CompareSetting(const char *szModule, const char *szSetting, DBVARIANT *dbv) -{ - DBPresetItem *item; - DBPresetItem search = {0}; - - if (!lstPresets) return FALSE; - - search.szModule = (char *)szModule; - search.szSetting = (char *)szSetting; - DBPresetItem_Hash(&search); - item = li.List_Find(lstPresets, &search); - - if (!item) return FALSE; - if (item->dbv.type != item->dbv.type) return FALSE; - switch (item->dbv.type) - { - case DBVT_BYTE: return dbv->bVal == item->dbv.bVal ? TRUE : FALSE; - case DBVT_WORD: return dbv->wVal == item->dbv.wVal ? TRUE : FALSE; - case DBVT_DWORD: return dbv->dVal == item->dbv.dVal ? TRUE : FALSE; - case DBVT_UTF8: - case DBVT_ASCIIZ: return strcmp(dbv->pszVal, item->dbv.pszVal) ? FALSE : TRUE; - } - - return FALSE; -} - -static DBPresetItem *DBPresetItem_Create(char *szModule, char *szSetting, BYTE bType) -{ - DBPresetItem *item = (DBPresetItem *)mir_alloc(sizeof(DBPresetItem)); - item->szModule = mir_strdup(szModule); - item->szSetting = mir_strdup(szSetting); - DBPresetItem_Hash(item); - item->dbv.type = bType; - return item; -} - -static void DBPresetItem_Destroy(DBPresetItem *item) -{ - if (!item) return; - if (item->szModule) - { - mir_free(item->szModule); - item->szModule = NULL; - } - if (item->szSetting) - { - mir_free(item->szSetting); - item->szSetting = NULL; - } - - switch (item->dbv.type) - { - case DBVT_ASCIIZ: - case DBVT_UTF8: - case DBVT_WCHAR: - { - if (item->dbv.pszVal) - mir_free(item->dbv.pszVal); - item->dbv.pszVal=0; - break; - } - case DBVT_BLOB: - { - if (item->dbv.pbVal) - mir_free(item->dbv.pbVal); - item->dbv.pbVal=0; - break; - } - } - item->dbv.type = 0; -} - -static void DBPresetItem_Hash(DBPresetItem *item) -{ - int i; - int shift=0; - item->dwHash=0; - for(i=0;item->szModule[i];i++) - { - item->dwHash^=item->szModule[i]<24) item->dwHash^=(item->szModule[i]>>(32-shift))&0x7F; - shift=(shift+5)&0x1F; - } - for(i=0;item->szSetting[i];i++) - { - item->dwHash^=item->szSetting[i]<24) item->dwHash^=(item->szSetting[i]>>(32-shift))&0x7F; - shift=(shift+5)&0x1F; - } -} - -static int DBPresetItem_Cmp(DBPresetItem *item1, DBPresetItem *item2) -{ - int cmp; - if (item1->dwHash < item2->dwHash) return -1; - if (item1->dwHash > item2->dwHash) return 1; - if (cmp = strcmp(item1->szModule, item2->szModule)) return cmp; - return strcmp(item1->szSetting, item2->szSetting); -} diff --git a/plugins/Dbx_mmap_SA/dbpreset.cpp b/plugins/Dbx_mmap_SA/dbpreset.cpp new file mode 100644 index 0000000000..0bb6ebd3a0 --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbpreset.cpp @@ -0,0 +1,299 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// Miranda Memory-Mapped Secured DataBase +// (C) Artem Shpynov aka FYR, Igonin Vitaliy aka chaos.persei, Victor Pavlychko aka nullbie, 2007 - 2008 + +#include "commonheaders.h" + +/* Public API */ +int InitPreset(); +void UninitPreset(); + +int DBPreset_QuerySetting (const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); +int DBPreset_CompareSetting (const char *szModule, const char *szSetting, DBVARIANT *dbv); + +/* Preset cache item */ +typedef struct +{ + DWORD dwHash; + char *szModule; + char *szSetting; + DBVARIANT dbv; +} DBPresetItem; + +static DBPresetItem * DBPresetItem_Create (char *szModule, char *szSetting, BYTE bType); +static void DBPresetItem_Destroy (DBPresetItem *item); +static void DBPresetItem_Hash (DBPresetItem *item); +static int DBPresetItem_Cmp (DBPresetItem *item1, DBPresetItem *item2); + +SortedList *lstPresets = NULL; + +int InitPreset() +{ + char szIniPath[MAX_PATH]; + char szLine[2048]; + int lineLength; + char szSection[128]; + FILE *fp; + + GetModuleFileNameA(GetModuleHandle(NULL), szIniPath, SIZEOF(szIniPath)); + strcpy(strrchr(szIniPath, '\\')+1, "dbpreset.ini"); + + fp=fopen(szIniPath,"rt"); + + // no preset + if (!fp) return 0; + + lstPresets = li.List_Create(0, 50); + lstPresets->sortFunc = DBPresetItem_Cmp; + + while(!feof(fp)) + { + if(fgets(szLine,sizeof(szLine),fp)==NULL) break; + lineLength=lstrlenA(szLine); + while(lineLength && (BYTE)(szLine[lineLength-1])<=' ') szLine[--lineLength]='\0'; + if(szLine[0]==';' || szLine[0]<=' ') continue; + if(szLine[0]=='[') + { + char *szEnd=strchr(szLine+1,']'); + if(szEnd==NULL) continue; + if(szLine[1]=='!') + szSection[0]='\0'; + else + lstrcpynA(szSection, szLine+1, (int)min(sizeof(szSection), szEnd-szLine)); + } else + { + char *szValue; + char szName[128]; + DBPresetItem *item; + + if(szSection[0]=='\0') continue; + szValue=strchr(szLine,'='); + if(szValue==NULL) continue; + lstrcpynA(szName, szLine, (int)min(sizeof(szName), szValue-szLine+1)); + szValue++; + + switch(szValue[0]) + { + case 'b': + case 'B': + item = DBPresetItem_Create(szSection, szName, DBVT_BYTE); + item->dbv.bVal = (BYTE)strtol(szValue+1,NULL,0); + li.List_InsertPtr(lstPresets, item); + break; + case 'w': + case 'W': + item = DBPresetItem_Create(szSection, szName, DBVT_WORD); + item->dbv.wVal = (WORD)strtol(szValue+1,NULL,0); + li.List_InsertPtr(lstPresets, item); + break; + case 'd': + case 'D': + item = DBPresetItem_Create(szSection, szName, DBVT_DWORD); + item->dbv.dVal = (DWORD)strtoul(szValue+1,NULL,0); + li.List_InsertPtr(lstPresets, item); + break; + case 's': + case 'S': + item = DBPresetItem_Create(szSection, szName, DBVT_ASCIIZ); + item->dbv.pszVal = mir_strdup(szValue+1); + li.List_InsertPtr(lstPresets, item); + break; + case 'u': + case 'U': + item = DBPresetItem_Create(szSection, szName, DBVT_UTF8); + item->dbv.pszVal = mir_strdup(szValue+1); + li.List_InsertPtr(lstPresets, item); + break; + case 'n': + case 'N': + { + PBYTE buf; + int len; + char *pszValue,*pszEnd; + + buf=(PBYTE)mir_alloc(lstrlenA(szValue+1)); + for(len=0,pszValue=szValue+1;;len++) { + buf[len]=(BYTE)strtol(pszValue,&pszEnd,0x10); + if(pszValue==pszEnd) break; + pszValue=pszEnd; + } + + item = DBPresetItem_Create(szSection, szName, DBVT_BLOB); + item->dbv.pbVal = buf; + item->dbv.cpbVal = len; + li.List_InsertPtr(lstPresets, item); + break; + } + } + } + } + fclose(fp); + + return 0; +} + +void UninitPreset() +{ + int i; + if (!lstPresets) return; + for (i = 0; i < lstPresets->realCount; ++i) + DBPresetItem_Destroy(lstPresets->items[i]); + li.List_Destroy(lstPresets); +} + +int DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic) +{ + DBPresetItem *item; + DBPresetItem search = {0}; + + if (!lstPresets) return FALSE; + + search.szModule = (char *)szModule; + search.szSetting = (char *)szSetting; + DBPresetItem_Hash(&search); + item = li.List_Find(lstPresets, &search); + + if (!item) return FALSE; + + dbv->type = item->dbv.type; + switch (item->dbv.type) + { + case DBVT_BYTE: dbv->bVal = item->dbv.bVal; return TRUE; + case DBVT_WORD: dbv->wVal = item->dbv.wVal; return TRUE; + case DBVT_DWORD: dbv->dVal = item->dbv.dVal; return TRUE; + + case DBVT_UTF8: + case DBVT_ASCIIZ: + if (isStatic && dbv->pszVal) + lstrcpynA(dbv->pszVal, item->dbv.pszVal, dbv->cchVal); + else if (!isStatic) + dbv->pszVal = mir_strdup(item->dbv.pszVal); + return TRUE; + + default: + return FALSE; + } + + return FALSE; +} + +int DBPreset_CompareSetting(const char *szModule, const char *szSetting, DBVARIANT *dbv) +{ + DBPresetItem *item; + DBPresetItem search = {0}; + + if (!lstPresets) return FALSE; + + search.szModule = (char *)szModule; + search.szSetting = (char *)szSetting; + DBPresetItem_Hash(&search); + item = li.List_Find(lstPresets, &search); + + if (!item) return FALSE; + if (item->dbv.type != item->dbv.type) return FALSE; + switch (item->dbv.type) + { + case DBVT_BYTE: return dbv->bVal == item->dbv.bVal ? TRUE : FALSE; + case DBVT_WORD: return dbv->wVal == item->dbv.wVal ? TRUE : FALSE; + case DBVT_DWORD: return dbv->dVal == item->dbv.dVal ? TRUE : FALSE; + case DBVT_UTF8: + case DBVT_ASCIIZ: return strcmp(dbv->pszVal, item->dbv.pszVal) ? FALSE : TRUE; + } + + return FALSE; +} + +static DBPresetItem *DBPresetItem_Create(char *szModule, char *szSetting, BYTE bType) +{ + DBPresetItem *item = (DBPresetItem *)mir_alloc(sizeof(DBPresetItem)); + item->szModule = mir_strdup(szModule); + item->szSetting = mir_strdup(szSetting); + DBPresetItem_Hash(item); + item->dbv.type = bType; + return item; +} + +static void DBPresetItem_Destroy(DBPresetItem *item) +{ + if (!item) return; + if (item->szModule) + { + mir_free(item->szModule); + item->szModule = NULL; + } + if (item->szSetting) + { + mir_free(item->szSetting); + item->szSetting = NULL; + } + + switch (item->dbv.type) + { + case DBVT_ASCIIZ: + case DBVT_UTF8: + case DBVT_WCHAR: + { + if (item->dbv.pszVal) + mir_free(item->dbv.pszVal); + item->dbv.pszVal=0; + break; + } + case DBVT_BLOB: + { + if (item->dbv.pbVal) + mir_free(item->dbv.pbVal); + item->dbv.pbVal=0; + break; + } + } + item->dbv.type = 0; +} + +static void DBPresetItem_Hash(DBPresetItem *item) +{ + int i; + int shift=0; + item->dwHash=0; + for(i=0;item->szModule[i];i++) + { + item->dwHash^=item->szModule[i]<24) item->dwHash^=(item->szModule[i]>>(32-shift))&0x7F; + shift=(shift+5)&0x1F; + } + for(i=0;item->szSetting[i];i++) + { + item->dwHash^=item->szSetting[i]<24) item->dwHash^=(item->szSetting[i]>>(32-shift))&0x7F; + shift=(shift+5)&0x1F; + } +} + +static int DBPresetItem_Cmp(DBPresetItem *item1, DBPresetItem *item2) +{ + int cmp; + if (item1->dwHash < item2->dwHash) return -1; + if (item1->dwHash > item2->dwHash) return 1; + if (cmp = strcmp(item1->szModule, item2->szModule)) return cmp; + return strcmp(item1->szSetting, item2->szSetting); +} diff --git a/plugins/Dbx_mmap_SA/dbsettings.c b/plugins/Dbx_mmap_SA/dbsettings.c deleted file mode 100644 index 53717ecafb..0000000000 --- a/plugins/Dbx_mmap_SA/dbsettings.c +++ /dev/null @@ -1,1170 +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 DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); -int DBPreset_CompareSetting(const char *szModule, const char *szSetting, DBVARIANT *dbv); - -DWORD GetModuleNameOfs(const char *szName); -DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index); - -HANDLE hCacheHeap = NULL; -SortedList lContacts = {0}; -HANDLE hLastCachedContact = NULL; -static DBCachedContactValueList *LastVL = NULL; - -static int mirCp = CP_ACP; - -static SortedList lSettings={0}, lGlobalSettings={0}, lResidentSettings={0}; -static HANDLE hSettingChangeEvent = NULL; - - -static DWORD GetSettingsGroupOfsByModuleNameOfs(struct DBContact *dbc,DWORD ofsModuleName) -{ - struct DBContactSettings *dbcs; - DWORD ofsThis; - - ofsThis=dbc->ofsFirstSettings; - while(ofsThis) { - dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); - if(dbcs->signature!=DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption(NULL); - if(dbcs->ofsModuleName==ofsModuleName) - return ofsThis; - - ofsThis=dbcs->ofsNext; - } - return 0; -} - -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); - li.List_Insert(&lSettings,newValue,index); - return newValue; -} - -static char* GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen) -{ - static char *lastsetting = NULL; - int index; - char szFullName[512]; - - strcpy(szFullName+1,szModuleName); - szFullName[moduleNameLen+1]='/'; - strcpy(szFullName+moduleNameLen+2,szSettingName); - - if (lastsetting && strcmp(szFullName+1,lastsetting) == 0) - return lastsetting; - - if (li.List_GetIndex(&lSettings,szFullName,&index)) - lastsetting = (char*)lSettings.items[index]+1; - else - lastsetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+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); - } - else if ( szSave != NULL ) - HeapFree(hCacheHeap,0,szSave); - -#ifdef DBLOGGING - 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; - } -#endif -} - -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 ( li.List_GetIndex(&lGlobalSettings,&Vtemp,&index)) { - V = (DBCachedGlobalValue*)lGlobalSettings.items[index]; - if ( bAllocate == -1 ) { - FreeCachedVariant( &V->value ); - li.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; - li.List_Insert(&lGlobalSettings,V,index); - } - - return &V->value; - } - else { - DBCachedContactValue *V, *V1; - DBCachedContactValueList VLtemp,*VL; - - if (hLastCachedContact==hContact && LastVL) { - VL = LastVL; - } - else { - VLtemp.hContact=hContact; - - if ( !li.List_GetIndex(&lContacts,&VLtemp,&index)) - { - if ( bAllocate != 1 ) - return NULL; - - VL = AddToCachedContactList(hContact,index); - } - else VL = (DBCachedContactValueList*)lContacts.items[index]; - - LastVL = VL; - hLastCachedContact = hContact; - } - - for ( V = VL->first; V != NULL; V = V->next) - if (V->name == szSetting) - break; - - if ( V == NULL ) { - if ( bAllocate != 1 ) - return NULL; - - V = HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValue)); - if (VL->last) - VL->last->next = V; - else - VL->first = V; - VL->last = V; - V->name = szSetting; - } - else if ( bAllocate == -1 ) { - LastVL = NULL; - FreeCachedVariant(&V->value); - if ( VL->first == V ) { - VL->first = V->next; - if (VL->last == V) - VL->last = V->next; // NULL - } - else - for ( V1 = VL->first; V1 != NULL; V1 = V1->next ) - if ( V1->next == V ) { - V1->next = V->next; - if (VL->last == V) - VL->last = V1; - 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) -{ - struct DBContact *dbc; - DWORD ofsModuleName,ofsContact,ofsSettingsGroup,ofsBlobPtr; - int settingNameLen,moduleNameLen; - int bytesRemaining; - PBYTE pBlob; - char* szCachedSettingName; - - if ((!dbcgs->szSetting) || (!dbcgs->szModule)) - return 1; - // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name - settingNameLen = (int)strlen(dbcgs->szSetting); - moduleNameLen = (int)strlen(dbcgs->szModule); - if ( settingNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugStringA("GetContactSettingWorker() got a > 255 setting name length. \n"); - #endif - return 1; - } - if ( moduleNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugStringA("GetContactSettingWorker() got a > 255 module name length. \n"); - #endif - return 1; - } - - EnterCriticalSection(&csDbAccess); - - log3("get [%08p] %s/%s",hContact,dbcgs->szModule,dbcgs->szSetting); - - szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,moduleNameLen,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(cbLenpValue->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=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); - if(ofsSettingsGroup) { - ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob); - pBlob = DBRead(ofsBlobPtr,sizeof(struct DBContactSettings),&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: DecodeCopyMemory(&(dbcgs->pValue->wVal), (PWORD)(pBlob+1), 2); break; - case DBVT_DWORD: DecodeCopyMemory(&(dbcgs->pValue->dVal), (PDWORD)(pBlob+1), 4); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: - NeedBytes(3+*(PWORD)(pBlob+1)); - if(isStatic) { - dbcgs->pValue->cchVal--; - if (*(PWORD)(pBlob+1)pValue->cchVal) dbcgs->pValue->cchVal=*(PWORD)(pBlob+1); - DecodeCopyMemory(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)); - DecodeCopyMemory(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)pValue->cpbVal) dbcgs->pValue->cpbVal=*(PWORD)(pBlob+1); - DecodeCopyMemory(dbcgs->pValue->pbVal,pBlob+3,dbcgs->pValue->cpbVal); - } - else { - dbcgs->pValue->pbVal=(char*)mir_alloc(*(PWORD)(pBlob+1)); - DecodeCopyMemory(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); - } } - - /**** nullbie: query info from preset **********************/ - if (!hContact && DBPreset_QuerySetting(dbcgs->szModule, dbcgs->szSetting, dbcgs->pValue, isStatic)) - { - /**** add to cache **********************/ - if ( dbcgs->pValue->type != DBVT_BLOB ) - { - DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 ); - if ( pCachedValue != NULL ) - SetCachedVariant(dbcgs->pValue,pCachedValue); - } - return 0; - } - - /**** 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; -} - -static INT_PTR GetContactSetting(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTGETSETTING* dgs = ( DBCONTACTGETSETTING* )lParam; - dgs->pValue->type = 0; - if ( GetContactSettingWorker(( HANDLE )wParam, 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 = 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; -} - -static INT_PTR GetContactSettingStr(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam; - int iSaveType = dgs->pValue->type; - - if ( GetContactSettingWorker(( HANDLE )wParam, 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; -} - -INT_PTR GetContactSettingStatic(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam; - if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 1 )) - return 1; - - if ( dgs->pValue->type == DBVT_UTF8 ) { - mir_utf8decode( dgs->pValue->pszVal, NULL ); - dgs->pValue->type = DBVT_ASCIIZ; - } - - return 0; -} - -static INT_PTR FreeVariant(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT *dbv=(DBVARIANT*)lParam; - 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; -} - -static INT_PTR SetSettingResident(WPARAM wParam, LPARAM lParam) -{ - size_t cbSettingNameLen = strlen(( char* )lParam) + 2; - if (cbSettingNameLen < 512) - { - char* szSetting; - int idx; - char szTemp[512]; - strcpy( szTemp+1, ( char* )lParam ); - - EnterCriticalSection(&csDbAccess); - if ( !li.List_GetIndex( &lSettings, szTemp, &idx )) - szSetting = InsertCachedSetting( szTemp, cbSettingNameLen, idx ); - else - szSetting = lSettings.items[ idx ]; - - *szSetting = (char)wParam; - - if ( !li.List_GetIndex( &lResidentSettings, szSetting+1, &idx )) - { - if (wParam) - li.List_Insert(&lResidentSettings,szSetting+1,idx); - } - else if (!wParam) - li.List_Remove(&lResidentSettings,idx); - - LeaveCriticalSection(&csDbAccess); - } - return 0; -} - -static INT_PTR WriteContactSetting(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; - DBCONTACTWRITESETTING tmp; - struct 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; - - // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name - settingNameLen=(int)strlen(dbcws->szSetting); - moduleNameLen=(int)strlen(dbcws->szModule); - if ( settingNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); - #endif - return 1; - } - if ( moduleNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); - #endif - 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 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: - { size_t len = ( tmp.value.type != DBVT_BLOB ) ? (int)strlen(tmp.value.pszVal) : tmp.value.cpbVal; - if ( len >= 0xFFFF ) { - #ifdef _DEBUG - OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n"); - #endif - return 1; - } - } - } - - EnterCriticalSection(&csDbAccess); - { - char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen); - if ( tmp.value.type != DBVT_BLOB ) { - DBVARIANT* pCachedValue = GetCachedValuePtr((HANDLE)wParam, 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,(LPARAM)&tmp); - return 0; - } - } - else GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, -1); - } - - ofsModuleName=GetModuleNameOfs(tmp.szModule); - if(wParam==0) ofsContact=dbHeader.ofsUser; - else ofsContact=wParam; - - dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - if(dbc.signature!=DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - log0("write setting"); - //make sure the module group exists - ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,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(struct 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: EncodeDBWrite(ofsBlobPtr,&tmp.value.wVal,2); break; - case DBVT_DWORD: EncodeDBWrite(ofsBlobPtr,&tmp.value.dVal,4); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: EncodeDBWrite(ofsBlobPtr+2,tmp.value.pszVal,(int)strlen(tmp.value.pszVal)); break; - case DBVT_BLOB: EncodeDBWrite(ofsBlobPtr+2,tmp.value.pbVal,tmp.value.cpbVal); break; - } - //quit - DBFlush(1); - LeaveCriticalSection(&csDbAccess); - //notify - NotifyEventHooks(hSettingChangeEvent,wParam,(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,ofsNew; - - 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(NULL); - ofsDbcsPrev=dbcsPrev->ofsNext; - dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); - } - } - - //create the new one - ofsNew=ReallocSpace(ofsSettingsGroup, dbcs.cbBlob+offsetof(struct DBContactSettings,blob), bytesRequired+offsetof(struct DBContactSettings,blob)); - - dbcs.cbBlob=bytesRequired; - - DBWrite(ofsNew,&dbcs,offsetof(struct DBContactSettings,blob)); - if(ofsDbcsPrev==0) { - dbc.ofsFirstSettings=ofsNew; - DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); - } - else { - dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); - dbcsPrev->ofsNext=ofsNew; - DBWrite(ofsDbcsPrev,dbcsPrev,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: EncodeDBWrite(ofsBlobPtr,&tmp.value.wVal,2); MoveAlong(2); break; - case DBVT_DWORD: EncodeDBWrite(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); - EncodeDBWrite(ofsBlobPtr+2,tmp.value.pszVal,len); - MoveAlong(2+len); - } - break; - case DBVT_BLOB: - DBWrite(ofsBlobPtr,&tmp.value.cpbVal,2); - EncodeDBWrite(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, (LPARAM)&tmp); - return 0; -} - -static INT_PTR DeleteContactSetting(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTGETSETTING *dbcgs=(DBCONTACTGETSETTING*)lParam; - struct DBContact *dbc; - DWORD ofsModuleName,ofsSettingsGroup,ofsBlobPtr; - PBYTE pBlob; - int settingNameLen,moduleNameLen,bytesRemaining; - char* szCachedSettingName; - WPARAM saveWparam = wParam; - - if ((!dbcgs->szModule) || (!dbcgs->szSetting)) - return 1; - // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name - settingNameLen = (int)strlen(dbcgs->szSetting); - moduleNameLen = (int)strlen(dbcgs->szModule); - if ( settingNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugStringA("DeleteContactSetting() got a > 255 setting name length. \n"); - #endif - return 1; - } - if ( moduleNameLen > 0xFE ) - { - #ifdef _DEBUG - OutputDebugStringA("DeleteContactSetting() got a > 255 module name length. \n"); - #endif - return 1; - } - - EnterCriticalSection(&csDbAccess); - ofsModuleName=GetModuleNameOfs(dbcgs->szModule); - if(wParam==0) wParam=dbHeader.ofsUser; - - dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - //make sure the module group exists - ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); - if(ofsSettingsGroup==0) { - LeaveCriticalSection(&csDbAccess); - return 1; - } - //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,moduleNameLen,settingNameLen); - GetCachedValuePtr((HANDLE)saveWparam, szCachedSettingName, -1 ); - - //quit - DBFlush(1); - LeaveCriticalSection(&csDbAccess); - { //notify - DBCONTACTWRITESETTING dbcws={0}; - dbcws.szModule=dbcgs->szModule; - dbcws.szSetting=dbcgs->szSetting; - dbcws.value.type=DBVT_DELETED; - NotifyEventHooks(hSettingChangeEvent,saveWparam,(LPARAM)&dbcws); - } - return 0; -} - -static INT_PTR EnumContactSettings(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTENUMSETTINGS *dbces=(DBCONTACTENUMSETTINGS*)lParam; - struct DBContact *dbc; - DWORD ofsModuleName,ofsContact,ofsBlobPtr; - int bytesRemaining, result; - PBYTE pBlob; - char szSetting[256]; - - if (!dbces->szModule) - return -1; - - EnterCriticalSection(&csDbAccess); - - ofsModuleName=GetModuleNameOfs(dbces->szModule); - if(wParam==0) ofsContact=dbHeader.ofsUser; - else ofsContact=wParam; - dbc=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); - if(dbc->signature!=DBCONTACT_SIGNATURE) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - dbces->ofsSettings=GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); - if (!dbces->ofsSettings) { - LeaveCriticalSection(&csDbAccess); - return -1; - } - 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; -} - -static INT_PTR EnumResidentSettings(WPARAM wParam, LPARAM lParam) -{ - int i; - int ret; - for(i = 0; i < lResidentSettings.realCount; i++) { - ret=((DBMODULEENUMPROC)lParam)(lResidentSettings.items[i],0,wParam); - if(ret) return ret; - } - return 0; -} - -extern Cryptor* CryptoEngine; -extern void* key; - -void EncodeContactSettings(HANDLE hContact) -{ - struct DBContact * contact; - struct DBContactSettings * setting; - DWORD offset; - - if (!hContact) hContact = (HANDLE)dbHeader.ofsUser; - contact = (struct DBContact *)DBRead((DWORD)hContact, sizeof(struct DBContact), NULL); - if(contact -> ofsFirstSettings){ - setting = (struct DBContactSettings *)DBRead(contact -> ofsFirstSettings, sizeof(struct DBContactSettings), NULL); - offset = contact -> ofsFirstSettings; - do{ - DWORD ofsBlobPtr; - PBYTE pBlob; - int bytesRemaining; - DWORD len; - /*struct DBModuleName * name; - char namestr[100]; - name = DBRead(setting->ofsModuleName, sizeof(struct DBModuleName), &bytesRemaining); - memcpy(namestr, name->name, name->cbName); - namestr[name->cbName] = '\0'; - MessageBox(0, namestr, "Module", MB_OK);*/ - ofsBlobPtr = offset + offsetof(struct DBContactSettings,blob); - pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - while(pBlob[0]) { - NeedBytes(1); - NeedBytes(1+pBlob[0]); - //CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]]=0; - MoveAlong(1+pBlob[0]); - - NeedBytes(5); - - switch(pBlob[0]) { - case DBVT_DELETED: break; - case DBVT_BYTE: break; - case DBVT_WORD: - { - CryptoEngine->EncryptMem(pBlob+1, 2, key); - break; - } - case DBVT_DWORD: - { - CryptoEngine->EncryptMem(pBlob+1, 4, key); - break; - } - case DBVT_UTF8: - case DBVT_ASCIIZ: - case DBVT_BLOB: - { - NeedBytes(3+*(PWORD)(pBlob+1)); - len = *(PWORD)(pBlob+1); - - CryptoEngine->EncryptMem(pBlob+3, len, key); - break; - } - } - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - - if(setting -> ofsNext){ - offset = setting -> ofsNext; - setting = (struct DBContactSettings *)DBRead(setting -> ofsNext, sizeof(struct DBContactSettings), NULL); - } - else - break; - }while(1); - } - - -} -void DecodeContactSettings(HANDLE hContact) -{ - struct DBContact * contact; - struct DBContactSettings * setting; - DWORD offset; - - - if (!hContact) hContact = (HANDLE)dbHeader.ofsUser; - contact = (struct DBContact *)DBRead((DWORD)hContact, sizeof(struct DBContact), NULL); - if(contact -> ofsFirstSettings){ - setting = (struct DBContactSettings *)DBRead(contact -> ofsFirstSettings, sizeof(struct DBContactSettings), NULL); - offset = contact -> ofsFirstSettings; - do{ - DWORD ofsBlobPtr; - PBYTE pBlob; - int bytesRemaining; - DWORD len; - ofsBlobPtr = offset + offsetof(struct DBContactSettings,blob); - pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - while(pBlob[0]) { - NeedBytes(1); - NeedBytes(1+pBlob[0]); - //CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]]=0; - MoveAlong(1+pBlob[0]); - - NeedBytes(5); - - switch(pBlob[0]) { - case DBVT_DELETED: break; - case DBVT_BYTE: break; - case DBVT_WORD: - { - CryptoEngine->DecryptMem(pBlob+1, 2, key); - break; - } - case DBVT_DWORD: - { - CryptoEngine->DecryptMem(pBlob+1, 4, key); - break; - } - case DBVT_UTF8: - case DBVT_ASCIIZ: - case DBVT_BLOB: - { - NeedBytes(3+*(PWORD)(pBlob+1)); - len = *(PWORD)(pBlob+1); - - CryptoEngine->DecryptMem(pBlob+3, len, key); - break; - } - } - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } - - if(setting -> ofsNext){ - offset = setting -> ofsNext; - setting = (struct DBContactSettings *)DBRead(setting -> ofsNext, sizeof(struct DBContactSettings), NULL); - } - else - break; - }while(1); - } - -} -///////////////////////////////////////////////////////////////////////////////////////// -// -// Module initialization procedure - -static int stringCompare( DBCachedSettingName* p1, DBCachedSettingName* p2 ) -{ - return strcmp( p1->name, p2->name ); -} - -static int stringCompare2( char* p1, char* p2 ) -{ - return strcmp( p1, p2); -} - -int InitSettings(void) -{ - CreateServiceFunction(MS_DB_CONTACT_GETSETTING, GetContactSetting); - CreateServiceFunction(MS_DB_CONTACT_GETSETTING_STR, GetContactSettingStr); - CreateServiceFunction(MS_DB_CONTACT_GETSETTINGSTATIC, GetContactSettingStatic); - CreateServiceFunction(MS_DB_CONTACT_FREEVARIANT, FreeVariant); - CreateServiceFunction(MS_DB_CONTACT_WRITESETTING, WriteContactSetting); - CreateServiceFunction(MS_DB_CONTACT_DELETESETTING, DeleteContactSetting); - CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS, EnumContactSettings); - CreateServiceFunction(MS_DB_SETSETTINGRESIDENT, SetSettingResident); - CreateServiceFunction("DB/ResidentSettings/Enum", EnumResidentSettings); - - hSettingChangeEvent=CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); - - hCacheHeap=HeapCreate(0,0,0); - lSettings.sortFunc=stringCompare; - lSettings.increment=100; - lContacts.sortFunc=HandleKeySort; - lContacts.increment=50; - lGlobalSettings.sortFunc=HandleKeySort; - lGlobalSettings.increment=50; - lResidentSettings.sortFunc=stringCompare2; - lResidentSettings.increment=50; - - mirCp = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ); - return 0; -} - -void UninitSettings(void) -{ - HeapDestroy(hCacheHeap); - li.List_Destroy(&lContacts); - li.List_Destroy(&lSettings); - li.List_Destroy(&lGlobalSettings); - li.List_Destroy(&lResidentSettings); -} diff --git a/plugins/Dbx_mmap_SA/dbsettings.cpp b/plugins/Dbx_mmap_SA/dbsettings.cpp new file mode 100644 index 0000000000..53717ecafb --- /dev/null +++ b/plugins/Dbx_mmap_SA/dbsettings.cpp @@ -0,0 +1,1170 @@ +/* + +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 DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); +int DBPreset_CompareSetting(const char *szModule, const char *szSetting, DBVARIANT *dbv); + +DWORD GetModuleNameOfs(const char *szName); +DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index); + +HANDLE hCacheHeap = NULL; +SortedList lContacts = {0}; +HANDLE hLastCachedContact = NULL; +static DBCachedContactValueList *LastVL = NULL; + +static int mirCp = CP_ACP; + +static SortedList lSettings={0}, lGlobalSettings={0}, lResidentSettings={0}; +static HANDLE hSettingChangeEvent = NULL; + + +static DWORD GetSettingsGroupOfsByModuleNameOfs(struct DBContact *dbc,DWORD ofsModuleName) +{ + struct DBContactSettings *dbcs; + DWORD ofsThis; + + ofsThis=dbc->ofsFirstSettings; + while(ofsThis) { + dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); + if(dbcs->signature!=DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption(NULL); + if(dbcs->ofsModuleName==ofsModuleName) + return ofsThis; + + ofsThis=dbcs->ofsNext; + } + return 0; +} + +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); + li.List_Insert(&lSettings,newValue,index); + return newValue; +} + +static char* GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen) +{ + static char *lastsetting = NULL; + int index; + char szFullName[512]; + + strcpy(szFullName+1,szModuleName); + szFullName[moduleNameLen+1]='/'; + strcpy(szFullName+moduleNameLen+2,szSettingName); + + if (lastsetting && strcmp(szFullName+1,lastsetting) == 0) + return lastsetting; + + if (li.List_GetIndex(&lSettings,szFullName,&index)) + lastsetting = (char*)lSettings.items[index]+1; + else + lastsetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+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); + } + else if ( szSave != NULL ) + HeapFree(hCacheHeap,0,szSave); + +#ifdef DBLOGGING + 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; + } +#endif +} + +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 ( li.List_GetIndex(&lGlobalSettings,&Vtemp,&index)) { + V = (DBCachedGlobalValue*)lGlobalSettings.items[index]; + if ( bAllocate == -1 ) { + FreeCachedVariant( &V->value ); + li.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; + li.List_Insert(&lGlobalSettings,V,index); + } + + return &V->value; + } + else { + DBCachedContactValue *V, *V1; + DBCachedContactValueList VLtemp,*VL; + + if (hLastCachedContact==hContact && LastVL) { + VL = LastVL; + } + else { + VLtemp.hContact=hContact; + + if ( !li.List_GetIndex(&lContacts,&VLtemp,&index)) + { + if ( bAllocate != 1 ) + return NULL; + + VL = AddToCachedContactList(hContact,index); + } + else VL = (DBCachedContactValueList*)lContacts.items[index]; + + LastVL = VL; + hLastCachedContact = hContact; + } + + for ( V = VL->first; V != NULL; V = V->next) + if (V->name == szSetting) + break; + + if ( V == NULL ) { + if ( bAllocate != 1 ) + return NULL; + + V = HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValue)); + if (VL->last) + VL->last->next = V; + else + VL->first = V; + VL->last = V; + V->name = szSetting; + } + else if ( bAllocate == -1 ) { + LastVL = NULL; + FreeCachedVariant(&V->value); + if ( VL->first == V ) { + VL->first = V->next; + if (VL->last == V) + VL->last = V->next; // NULL + } + else + for ( V1 = VL->first; V1 != NULL; V1 = V1->next ) + if ( V1->next == V ) { + V1->next = V->next; + if (VL->last == V) + VL->last = V1; + 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) +{ + struct DBContact *dbc; + DWORD ofsModuleName,ofsContact,ofsSettingsGroup,ofsBlobPtr; + int settingNameLen,moduleNameLen; + int bytesRemaining; + PBYTE pBlob; + char* szCachedSettingName; + + if ((!dbcgs->szSetting) || (!dbcgs->szModule)) + return 1; + // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name + settingNameLen = (int)strlen(dbcgs->szSetting); + moduleNameLen = (int)strlen(dbcgs->szModule); + if ( settingNameLen > 0xFE ) + { + #ifdef _DEBUG + OutputDebugStringA("GetContactSettingWorker() got a > 255 setting name length. \n"); + #endif + return 1; + } + if ( moduleNameLen > 0xFE ) + { + #ifdef _DEBUG + OutputDebugStringA("GetContactSettingWorker() got a > 255 module name length. \n"); + #endif + return 1; + } + + EnterCriticalSection(&csDbAccess); + + log3("get [%08p] %s/%s",hContact,dbcgs->szModule,dbcgs->szSetting); + + szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,moduleNameLen,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(cbLenpValue->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=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return 1; + } + ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); + if(ofsSettingsGroup) { + ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob); + pBlob = DBRead(ofsBlobPtr,sizeof(struct DBContactSettings),&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: DecodeCopyMemory(&(dbcgs->pValue->wVal), (PWORD)(pBlob+1), 2); break; + case DBVT_DWORD: DecodeCopyMemory(&(dbcgs->pValue->dVal), (PDWORD)(pBlob+1), 4); break; + case DBVT_UTF8: + case DBVT_ASCIIZ: + NeedBytes(3+*(PWORD)(pBlob+1)); + if(isStatic) { + dbcgs->pValue->cchVal--; + if (*(PWORD)(pBlob+1)pValue->cchVal) dbcgs->pValue->cchVal=*(PWORD)(pBlob+1); + DecodeCopyMemory(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)); + DecodeCopyMemory(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)pValue->cpbVal) dbcgs->pValue->cpbVal=*(PWORD)(pBlob+1); + DecodeCopyMemory(dbcgs->pValue->pbVal,pBlob+3,dbcgs->pValue->cpbVal); + } + else { + dbcgs->pValue->pbVal=(char*)mir_alloc(*(PWORD)(pBlob+1)); + DecodeCopyMemory(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); + } } + + /**** nullbie: query info from preset **********************/ + if (!hContact && DBPreset_QuerySetting(dbcgs->szModule, dbcgs->szSetting, dbcgs->pValue, isStatic)) + { + /**** add to cache **********************/ + if ( dbcgs->pValue->type != DBVT_BLOB ) + { + DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 ); + if ( pCachedValue != NULL ) + SetCachedVariant(dbcgs->pValue,pCachedValue); + } + return 0; + } + + /**** 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; +} + +static INT_PTR GetContactSetting(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTGETSETTING* dgs = ( DBCONTACTGETSETTING* )lParam; + dgs->pValue->type = 0; + if ( GetContactSettingWorker(( HANDLE )wParam, 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 = 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; +} + +static INT_PTR GetContactSettingStr(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam; + int iSaveType = dgs->pValue->type; + + if ( GetContactSettingWorker(( HANDLE )wParam, 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; +} + +INT_PTR GetContactSettingStatic(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam; + if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 1 )) + return 1; + + if ( dgs->pValue->type == DBVT_UTF8 ) { + mir_utf8decode( dgs->pValue->pszVal, NULL ); + dgs->pValue->type = DBVT_ASCIIZ; + } + + return 0; +} + +static INT_PTR FreeVariant(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT *dbv=(DBVARIANT*)lParam; + 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; +} + +static INT_PTR SetSettingResident(WPARAM wParam, LPARAM lParam) +{ + size_t cbSettingNameLen = strlen(( char* )lParam) + 2; + if (cbSettingNameLen < 512) + { + char* szSetting; + int idx; + char szTemp[512]; + strcpy( szTemp+1, ( char* )lParam ); + + EnterCriticalSection(&csDbAccess); + if ( !li.List_GetIndex( &lSettings, szTemp, &idx )) + szSetting = InsertCachedSetting( szTemp, cbSettingNameLen, idx ); + else + szSetting = lSettings.items[ idx ]; + + *szSetting = (char)wParam; + + if ( !li.List_GetIndex( &lResidentSettings, szSetting+1, &idx )) + { + if (wParam) + li.List_Insert(&lResidentSettings,szSetting+1,idx); + } + else if (!wParam) + li.List_Remove(&lResidentSettings,idx); + + LeaveCriticalSection(&csDbAccess); + } + return 0; +} + +static INT_PTR WriteContactSetting(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; + DBCONTACTWRITESETTING tmp; + struct 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; + + // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name + settingNameLen=(int)strlen(dbcws->szSetting); + moduleNameLen=(int)strlen(dbcws->szModule); + if ( settingNameLen > 0xFE ) + { + #ifdef _DEBUG + OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); + #endif + return 1; + } + if ( moduleNameLen > 0xFE ) + { + #ifdef _DEBUG + OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); + #endif + 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 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: + { size_t len = ( tmp.value.type != DBVT_BLOB ) ? (int)strlen(tmp.value.pszVal) : tmp.value.cpbVal; + if ( len >= 0xFFFF ) { + #ifdef _DEBUG + OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n"); + #endif + return 1; + } + } + } + + EnterCriticalSection(&csDbAccess); + { + char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen); + if ( tmp.value.type != DBVT_BLOB ) { + DBVARIANT* pCachedValue = GetCachedValuePtr((HANDLE)wParam, 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,(LPARAM)&tmp); + return 0; + } + } + else GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, -1); + } + + ofsModuleName=GetModuleNameOfs(tmp.szModule); + if(wParam==0) ofsContact=dbHeader.ofsUser; + else ofsContact=wParam; + + dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + if(dbc.signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return 1; + } + log0("write setting"); + //make sure the module group exists + ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,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(struct 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: EncodeDBWrite(ofsBlobPtr,&tmp.value.wVal,2); break; + case DBVT_DWORD: EncodeDBWrite(ofsBlobPtr,&tmp.value.dVal,4); break; + case DBVT_UTF8: + case DBVT_ASCIIZ: EncodeDBWrite(ofsBlobPtr+2,tmp.value.pszVal,(int)strlen(tmp.value.pszVal)); break; + case DBVT_BLOB: EncodeDBWrite(ofsBlobPtr+2,tmp.value.pbVal,tmp.value.cpbVal); break; + } + //quit + DBFlush(1); + LeaveCriticalSection(&csDbAccess); + //notify + NotifyEventHooks(hSettingChangeEvent,wParam,(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,ofsNew; + + 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(NULL); + ofsDbcsPrev=dbcsPrev->ofsNext; + dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); + } + } + + //create the new one + ofsNew=ReallocSpace(ofsSettingsGroup, dbcs.cbBlob+offsetof(struct DBContactSettings,blob), bytesRequired+offsetof(struct DBContactSettings,blob)); + + dbcs.cbBlob=bytesRequired; + + DBWrite(ofsNew,&dbcs,offsetof(struct DBContactSettings,blob)); + if(ofsDbcsPrev==0) { + dbc.ofsFirstSettings=ofsNew; + DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); + } + else { + dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL); + dbcsPrev->ofsNext=ofsNew; + DBWrite(ofsDbcsPrev,dbcsPrev,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: EncodeDBWrite(ofsBlobPtr,&tmp.value.wVal,2); MoveAlong(2); break; + case DBVT_DWORD: EncodeDBWrite(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); + EncodeDBWrite(ofsBlobPtr+2,tmp.value.pszVal,len); + MoveAlong(2+len); + } + break; + case DBVT_BLOB: + DBWrite(ofsBlobPtr,&tmp.value.cpbVal,2); + EncodeDBWrite(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, (LPARAM)&tmp); + return 0; +} + +static INT_PTR DeleteContactSetting(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTGETSETTING *dbcgs=(DBCONTACTGETSETTING*)lParam; + struct DBContact *dbc; + DWORD ofsModuleName,ofsSettingsGroup,ofsBlobPtr; + PBYTE pBlob; + int settingNameLen,moduleNameLen,bytesRemaining; + char* szCachedSettingName; + WPARAM saveWparam = wParam; + + if ((!dbcgs->szModule) || (!dbcgs->szSetting)) + return 1; + // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name + settingNameLen = (int)strlen(dbcgs->szSetting); + moduleNameLen = (int)strlen(dbcgs->szModule); + if ( settingNameLen > 0xFE ) + { + #ifdef _DEBUG + OutputDebugStringA("DeleteContactSetting() got a > 255 setting name length. \n"); + #endif + return 1; + } + if ( moduleNameLen > 0xFE ) + { + #ifdef _DEBUG + OutputDebugStringA("DeleteContactSetting() got a > 255 module name length. \n"); + #endif + return 1; + } + + EnterCriticalSection(&csDbAccess); + ofsModuleName=GetModuleNameOfs(dbcgs->szModule); + if(wParam==0) wParam=dbHeader.ofsUser; + + dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return 1; + } + //make sure the module group exists + ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); + if(ofsSettingsGroup==0) { + LeaveCriticalSection(&csDbAccess); + return 1; + } + //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,moduleNameLen,settingNameLen); + GetCachedValuePtr((HANDLE)saveWparam, szCachedSettingName, -1 ); + + //quit + DBFlush(1); + LeaveCriticalSection(&csDbAccess); + { //notify + DBCONTACTWRITESETTING dbcws={0}; + dbcws.szModule=dbcgs->szModule; + dbcws.szSetting=dbcgs->szSetting; + dbcws.value.type=DBVT_DELETED; + NotifyEventHooks(hSettingChangeEvent,saveWparam,(LPARAM)&dbcws); + } + return 0; +} + +static INT_PTR EnumContactSettings(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTENUMSETTINGS *dbces=(DBCONTACTENUMSETTINGS*)lParam; + struct DBContact *dbc; + DWORD ofsModuleName,ofsContact,ofsBlobPtr; + int bytesRemaining, result; + PBYTE pBlob; + char szSetting[256]; + + if (!dbces->szModule) + return -1; + + EnterCriticalSection(&csDbAccess); + + ofsModuleName=GetModuleNameOfs(dbces->szModule); + if(wParam==0) ofsContact=dbHeader.ofsUser; + else ofsContact=wParam; + dbc=(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); + if(dbc->signature!=DBCONTACT_SIGNATURE) { + LeaveCriticalSection(&csDbAccess); + return -1; + } + dbces->ofsSettings=GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); + if (!dbces->ofsSettings) { + LeaveCriticalSection(&csDbAccess); + return -1; + } + 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; +} + +static INT_PTR EnumResidentSettings(WPARAM wParam, LPARAM lParam) +{ + int i; + int ret; + for(i = 0; i < lResidentSettings.realCount; i++) { + ret=((DBMODULEENUMPROC)lParam)(lResidentSettings.items[i],0,wParam); + if(ret) return ret; + } + return 0; +} + +extern Cryptor* CryptoEngine; +extern void* key; + +void EncodeContactSettings(HANDLE hContact) +{ + struct DBContact * contact; + struct DBContactSettings * setting; + DWORD offset; + + if (!hContact) hContact = (HANDLE)dbHeader.ofsUser; + contact = (struct DBContact *)DBRead((DWORD)hContact, sizeof(struct DBContact), NULL); + if(contact -> ofsFirstSettings){ + setting = (struct DBContactSettings *)DBRead(contact -> ofsFirstSettings, sizeof(struct DBContactSettings), NULL); + offset = contact -> ofsFirstSettings; + do{ + DWORD ofsBlobPtr; + PBYTE pBlob; + int bytesRemaining; + DWORD len; + /*struct DBModuleName * name; + char namestr[100]; + name = DBRead(setting->ofsModuleName, sizeof(struct DBModuleName), &bytesRemaining); + memcpy(namestr, name->name, name->cbName); + namestr[name->cbName] = '\0'; + MessageBox(0, namestr, "Module", MB_OK);*/ + ofsBlobPtr = offset + offsetof(struct DBContactSettings,blob); + pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); + while(pBlob[0]) { + NeedBytes(1); + NeedBytes(1+pBlob[0]); + //CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]]=0; + MoveAlong(1+pBlob[0]); + + NeedBytes(5); + + switch(pBlob[0]) { + case DBVT_DELETED: break; + case DBVT_BYTE: break; + case DBVT_WORD: + { + CryptoEngine->EncryptMem(pBlob+1, 2, key); + break; + } + case DBVT_DWORD: + { + CryptoEngine->EncryptMem(pBlob+1, 4, key); + break; + } + case DBVT_UTF8: + case DBVT_ASCIIZ: + case DBVT_BLOB: + { + NeedBytes(3+*(PWORD)(pBlob+1)); + len = *(PWORD)(pBlob+1); + + CryptoEngine->EncryptMem(pBlob+3, len, key); + break; + } + } + NeedBytes(3); + MoveAlong(1+GetSettingValueLength(pBlob)); + NeedBytes(1); + } + + if(setting -> ofsNext){ + offset = setting -> ofsNext; + setting = (struct DBContactSettings *)DBRead(setting -> ofsNext, sizeof(struct DBContactSettings), NULL); + } + else + break; + }while(1); + } + + +} +void DecodeContactSettings(HANDLE hContact) +{ + struct DBContact * contact; + struct DBContactSettings * setting; + DWORD offset; + + + if (!hContact) hContact = (HANDLE)dbHeader.ofsUser; + contact = (struct DBContact *)DBRead((DWORD)hContact, sizeof(struct DBContact), NULL); + if(contact -> ofsFirstSettings){ + setting = (struct DBContactSettings *)DBRead(contact -> ofsFirstSettings, sizeof(struct DBContactSettings), NULL); + offset = contact -> ofsFirstSettings; + do{ + DWORD ofsBlobPtr; + PBYTE pBlob; + int bytesRemaining; + DWORD len; + ofsBlobPtr = offset + offsetof(struct DBContactSettings,blob); + pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); + while(pBlob[0]) { + NeedBytes(1); + NeedBytes(1+pBlob[0]); + //CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]]=0; + MoveAlong(1+pBlob[0]); + + NeedBytes(5); + + switch(pBlob[0]) { + case DBVT_DELETED: break; + case DBVT_BYTE: break; + case DBVT_WORD: + { + CryptoEngine->DecryptMem(pBlob+1, 2, key); + break; + } + case DBVT_DWORD: + { + CryptoEngine->DecryptMem(pBlob+1, 4, key); + break; + } + case DBVT_UTF8: + case DBVT_ASCIIZ: + case DBVT_BLOB: + { + NeedBytes(3+*(PWORD)(pBlob+1)); + len = *(PWORD)(pBlob+1); + + CryptoEngine->DecryptMem(pBlob+3, len, key); + break; + } + } + NeedBytes(3); + MoveAlong(1+GetSettingValueLength(pBlob)); + NeedBytes(1); + } + + if(setting -> ofsNext){ + offset = setting -> ofsNext; + setting = (struct DBContactSettings *)DBRead(setting -> ofsNext, sizeof(struct DBContactSettings), NULL); + } + else + break; + }while(1); + } + +} +///////////////////////////////////////////////////////////////////////////////////////// +// +// Module initialization procedure + +static int stringCompare( DBCachedSettingName* p1, DBCachedSettingName* p2 ) +{ + return strcmp( p1->name, p2->name ); +} + +static int stringCompare2( char* p1, char* p2 ) +{ + return strcmp( p1, p2); +} + +int InitSettings(void) +{ + CreateServiceFunction(MS_DB_CONTACT_GETSETTING, GetContactSetting); + CreateServiceFunction(MS_DB_CONTACT_GETSETTING_STR, GetContactSettingStr); + CreateServiceFunction(MS_DB_CONTACT_GETSETTINGSTATIC, GetContactSettingStatic); + CreateServiceFunction(MS_DB_CONTACT_FREEVARIANT, FreeVariant); + CreateServiceFunction(MS_DB_CONTACT_WRITESETTING, WriteContactSetting); + CreateServiceFunction(MS_DB_CONTACT_DELETESETTING, DeleteContactSetting); + CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS, EnumContactSettings); + CreateServiceFunction(MS_DB_SETSETTINGRESIDENT, SetSettingResident); + CreateServiceFunction("DB/ResidentSettings/Enum", EnumResidentSettings); + + hSettingChangeEvent=CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); + + hCacheHeap=HeapCreate(0,0,0); + lSettings.sortFunc=stringCompare; + lSettings.increment=100; + lContacts.sortFunc=HandleKeySort; + lContacts.increment=50; + lGlobalSettings.sortFunc=HandleKeySort; + lGlobalSettings.increment=50; + lResidentSettings.sortFunc=stringCompare2; + lResidentSettings.increment=50; + + mirCp = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ); + return 0; +} + +void UninitSettings(void) +{ + HeapDestroy(hCacheHeap); + li.List_Destroy(&lContacts); + li.List_Destroy(&lSettings); + li.List_Destroy(&lGlobalSettings); + li.List_Destroy(&lResidentSettings); +} diff --git a/plugins/Dbx_mmap_SA/dialogs.c b/plugins/Dbx_mmap_SA/dialogs.c deleted file mode 100644 index df13214b62..0000000000 --- a/plugins/Dbx_mmap_SA/dialogs.c +++ /dev/null @@ -1,618 +0,0 @@ -#include "commonheaders.h" -#include -#include -#include -#include - -#include - -#define MS_DB_CHANGEPASSWORD "DB/ChangePassword" - -extern char encryptKey[255]; -extern size_t encryptKeyLength; -extern HANDLE g_hInst; -HANDLE hSetPwdMenu; - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -BOOL ShowDlgItem(HWND hwndDlg, int iIDCtrl, BOOL bShow) -{ - HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); - if (!hwndCtrl) return FALSE; - - // Avoid flickering - if (bShow && IsWindowVisible(hwndCtrl)) - return TRUE; - - return ShowWindow(hwndCtrl, (bShow ? SW_SHOW : SW_HIDE)); -} - -BOOL EnableDlgItem(HWND hwndDlg, int iIDCtrl, BOOL bEnable) -{ - HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); - if (!hwndCtrl) return FALSE; - - // Avoid flickering - if (IsWindowEnabled(hwndCtrl) == bEnable) - return (bEnable == FALSE); - - return EnableWindow(hwndCtrl, bEnable); -} - -BOOL IsDlgItemEnabled(HWND hwndDlg, int iIDCtrl) -{ - HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); - if (!hwndCtrl) return FALSE; - return IsWindowEnabled(hwndCtrl); -} - - -static int OptionsInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.cbSize = sizeof(odp); - odp.position = -790000000; - odp.hInstance = g_hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.flags = ODPF_BOLDGROUPS; - odp.pszTitle = LPGEN("Database Features"); - odp.pszGroup = LPGEN("Services"); - odp.pfnDlgProc = DlgProcOptions; - Options_AddPage(wParam, &odp); - - return 0; -} - -INT_PTR ChangePassword(WPARAM wParam, LPARAM lParam) -{ - if(bEncoding){ - ChangePwd(); - }else{ - EncryptDB(); - } - return 0; -} - -void xModifyMenu(HANDLE hMenu,long flags,const TCHAR* name, HICON hIcon) -{ - CLISTMENUITEM menu; - ZeroMemory(&menu,sizeof(menu)); - menu.cbSize = sizeof(menu); - menu.flags = CMIM_FLAGS | CMIF_TCHAR; - menu.flags |= name ? CMIM_NAME : 0; - menu.flags |= hIcon ? CMIM_ICON : 0; - menu.flags |= flags; - menu.ptszName = (TCHAR*)name; - menu.hIcon=hIcon; - - CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenu,(LPARAM)&menu); -} - -static int ModulesLoad(WPARAM wParam, LPARAM lParam) -{ - CLISTMENUITEM menu = {0}; - SKINICONDESC sid = {0}; - TCHAR szFile[MAX_PATH]; - //HANDLE hFirst; - - HookEvent(ME_OPT_INITIALISE, OptionsInit); - - // icolib init - GetModuleFileName(g_hInst, szFile, MAX_PATH); - - sid.cbSize = sizeof(sid); - sid.ptszDefaultFile = szFile; - sid.flags = SIDF_ALL_TCHAR; - sid.ptszSection = LPGENT("Database"); - sid.ptszDescription = LPGENT("Database"); - sid.pszName = "database"; - sid.iDefaultIndex = -IDI_ICON2; - Skin_AddIcon(&sid); - - sid.ptszDescription = LPGENT("Change Password"); - sid.pszName = "password"; - sid.iDefaultIndex = -IDI_ICON3; - Skin_AddIcon(&sid); - - menu.cbSize = sizeof(menu); - menu.flags = CMIM_ALL | CMIF_TCHAR; - - menu.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"database"); - - // main menu item - menu.ptszName = (bEncoding) ? LPGENT("Change password") : LPGENT("Set password"); - menu.ptszPopupName = LPGENT("Database"); - menu.pszService = MS_DB_CHANGEPASSWORD; - menu.position = 500100000; - - hSetPwdMenu = Menu_AddMainMenuItem(&menu); - - ZeroMemory(&menu,sizeof(menu)); - menu.cbSize = sizeof(menu); - menu.flags = CMIM_ICON; - menu.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"password"); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hSetPwdMenu, (LPARAM)&menu); - - return 0; -} - -int UnloadOptions() -{ - OleUninitialize(); - return 0; -} - - -int InitDialogs() -{ - OleInitialize(0); - CreateServiceFunction(MS_DB_CHANGEPASSWORD, ChangePassword); - HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoad); - - return 0; -} - -extern Cryptor* CryptoEngine; - -extern int ModulesCount; -extern CryptoModule* Modules[100]; - -//ugly, i know -#undef LVM_SETITEMTEXT -#define LVM_SETITEMTEXT LVM_SETITEMTEXTA - -int ImageList_AddIcon_IconLibLoaded(HIMAGELIST hIml, char* name) -{ - HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON, (WPARAM)NULL, (LPARAM)name); - int res = ImageList_AddIcon(hIml, hIcon); - return res; -} - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_MODULES); - LVCOLUMN col; - LVITEM item; - int i, iRow, iIndex; - NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; - WORD uid; - HIMAGELIST hIml; - - switch ( msg ) { - case WM_INITDIALOG: - hIml = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 2, 0); - TranslateDialogDefault( hwndDlg ); - - ImageList_AddIcon_IconLibLoaded( hIml, "core_main_29" ); - ImageList_AddIcon_IconLibLoaded( hIml, "core_main_30" ); - ListView_SetImageList( hwndList, hIml, LVSIL_SMALL ); - - col.pszText = NULL; - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 50; - ListView_InsertColumn(hwndList, 1, &col); - - col.pszText = TranslateT("Dll"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 1000; - ListView_InsertColumn(hwndList, 2, &col); - - col.pszText = TranslateT("Name"); - col.cx = 1000; - ListView_InsertColumn(hwndList, 3, &col); - - col.pszText = TranslateT("Version"); - col.cx = 1000; - ListView_InsertColumn(hwndList, 4, &col); - - ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES); - - uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); - - for(i = 0; i < ModulesCount; i++) { - char buf[100]; - - item.mask = LVIF_TEXT; - item.iItem = i; - item.iSubItem = 0; - item.pszText = NULL; - iRow = ListView_InsertItem(hwndList, &item); - - ListView_SetItemText(hwndList, iRow, 1, (LPWSTR)Modules[i]->dllname); - ListView_SetItemText(hwndList, iRow, 2, (LPWSTR)Modules[i]->cryptor->Name); - mir_snprintf(buf,SIZEOF(buf),"%d.%d.%d.%d", HIBYTE(HIWORD(Modules[i]->cryptor->Version)), LOBYTE(HIWORD(Modules[i]->cryptor->Version)), HIBYTE(LOWORD(Modules[i]->cryptor->Version)), LOBYTE(LOWORD(Modules[i]->cryptor->Version))); - ListView_SetItemText(hwndList, iRow, 3, (LPWSTR)buf); - - if(uid == Modules[i]->cryptor->uid && bEncoding) - ListView_SetCheckState(hwndList, i, 1); - - item.mask = LVIF_IMAGE; - item.iItem = iRow; - item.iSubItem = 0; - item.iImage = ( CryptoEngine == Modules[i]->cryptor && bEncoding ) ? 0 : 1; - ListView_SetItem( hwndList, &item ); - } - - ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); - return TRUE; - - case WM_COMMAND: - if ( HIWORD(wParam) == STN_CLICKED ) { - switch (LOWORD(wParam)) { - case IDC_EMAIL: - case IDC_SITE: - { - char buf[512]; - char * p = &buf[7]; - lstrcpyA(buf,"mailto:"); - if ( GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), p, SIZEOF(buf) - 7)) { - CallService(MS_UTILS_OPENURL,0,(LPARAM) (LOWORD(wParam)==IDC_EMAIL ? buf : p)); - } - break; - } } } - break; - - case WM_NOTIFY: - if ( hdr && hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1)) { - iIndex = hdr->iItem; - if(hdr->uNewState & 0x2000){ - for(i = 0; i < ModulesCount; i++) { - if(i != iIndex) ListView_SetCheckState(hwndList, i, 0); - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - if(hdr->uNewState & 0x1000){ - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - if(hdr->uNewState & LVIS_SELECTED){ - SetDlgItemTextA(hwndDlg, IDC_AUTHOR, Modules[iIndex]->cryptor->Author); - { - TCHAR* info_t = mir_a2t((char*)(Modules[iIndex]->cryptor->Info)); - SetDlgItemText(hwndDlg, IDC_INFO, TranslateTS(info_t)); - mir_free(info_t); - } - SetDlgItemTextA(hwndDlg, IDC_SITE, Modules[iIndex]->cryptor->Site); - SetDlgItemTextA(hwndDlg, IDC_EMAIL, Modules[iIndex]->cryptor->Email); - SetDlgItemTextA(hwndDlg, IDC_ENC, Modules[iIndex]->cryptor->Name); - SetDlgItemInt(hwndDlg, IDC_UID, Modules[iIndex]->cryptor->uid, 0); - } else { - SetDlgItemTextA(hwndDlg, IDC_AUTHOR, ""); - SetDlgItemTextA(hwndDlg, IDC_INFO, ""); - SetDlgItemTextA(hwndDlg, IDC_SITE, ""); - SetDlgItemTextA(hwndDlg, IDC_EMAIL, ""); - SetDlgItemTextA(hwndDlg, IDC_ENC, ""); - SetDlgItemTextA(hwndDlg, IDC_UID, ""); - } - - break; - } - if (((LPNMHDR)lParam)->code == PSN_APPLY ) { - int alg = -1; - for(i = 0; i < ModulesCount; i++) { - if(ListView_GetCheckState(hwndList, i)) { - alg = i; - break; - } - } - - if(alg > -1){ - if (!bEncoding){ - DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[alg]->cryptor->uid); - EncryptDB(); - }else{ - if(Modules[alg]->cryptor->uid != DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", -1)) { - DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[alg]->cryptor->uid); - RecryptDB(); - } - } - }else{ - if(bEncoding){ - DecryptDB(); - } - } - - uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); - - for(i = 0; i < ModulesCount; i++) { - if(uid == Modules[i]->cryptor->uid && bEncoding) - ListView_SetCheckState(hwndList, i, 1); - - item.mask = LVIF_IMAGE; - item.iItem = i; - item.iSubItem = 0; - item.iImage = ( CryptoEngine == Modules[i]->cryptor && bEncoding ) ? 0 : 1; - - ListView_SetItem( hwndList, &item ); - } - - return TRUE; - - } - break; - } - - return FALSE; -} -UINT oldLangID = 0; -void LanguageChanged(HWND hDlg) -{ - UINT LangID = (UINT)GetKeyboardLayout(0); - char Lang[3] = {0}; - if (LangID != oldLangID) - { - oldLangID = LangID; - GetLocaleInfoA(MAKELCID((LangID & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2); - Lang[0] = toupper(Lang[0]); - Lang[1] = tolower(Lang[1]); - SetDlgItemTextA(hDlg, IDC_LANG, Lang); - } -} - -extern BOOL wrongPass; - -BOOL CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) -{ - HICON hIcon = 0; - TCHAR tszHeaderTxt[256]; - TCHAR* tszDbName; - switch(uMsg) - { - case WM_INITDIALOG: - { - HWND hwndCtrl; -// if(pluginLink && ServiceExists(MS_LANGPACK_TRANSLATEDIALOG)) - TranslateDialogDefault(hDlg); - - hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); - - if (!wrongPass) - { - tszDbName = mir_a2t((char*)lParam); - mir_sntprintf(tszHeaderTxt, SIZEOF(tszHeaderTxt), _T("%s\n%s"), TranslateT("Please type in your password for"), tszDbName); - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), tszHeaderTxt); - mir_free(tszDbName); - } - else - { - if (wrongPass > 2) - { - hwndCtrl = GetDlgItem(hDlg, IDC_USERPASS); - EnableWindow(hwndCtrl, FALSE); - hwndCtrl = GetDlgItem(hDlg, IDOK); - EnableWindow(hwndCtrl, FALSE); - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Too many errors!")); - } - else - { - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is not correct!")); - } - } - oldLangID = 0; - SetTimer(hDlg,1,200,NULL); - LanguageChanged(hDlg); - return TRUE; - } - - case WM_CTLCOLORSTATIC: - { - if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) - { - SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode((HDC)wParam, TRANSPARENT); - return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); - } - - return FALSE; - } - - case WM_COMMAND: - { - UINT uid = LOWORD(wParam); - - if(uid == IDOK){ - if (!GetWindowLongPtr(hDlg,GWLP_USERDATA)) - { - encryptKeyLength = GetDlgItemTextA(hDlg, IDC_USERPASS, encryptKey, 254); - EndDialog(hDlg,IDOK); - }else{ - - } - }else if(uid == IDCANCEL){ - EndDialog(hDlg,IDCANCEL); - } - } - case WM_TIMER: - { - LanguageChanged(hDlg); - return FALSE; - } - case WM_DESTROY: - { - KillTimer(hDlg, 1); - DestroyIcon(hIcon); - } - } - - return FALSE; -} - -BOOL CALLBACK DlgStdNewPass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) -{ - HICON hIcon = 0; - - switch(uMsg) - { - case WM_INITDIALOG: - { - //if(pluginLink && ServiceExists(MS_LANGPACK_TRANSLATEDIALOG)) - TranslateDialogDefault(hDlg); - - hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); - - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Please enter your new password")); - - oldLangID = 0; - SetTimer(hDlg,1,200,NULL); - LanguageChanged(hDlg); - - return TRUE; - } - - case WM_CTLCOLORSTATIC: - { - if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) - { - SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode((HDC)wParam, TRANSPARENT); - return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); - } - - return FALSE; - } - - case WM_COMMAND: - { - UINT uid = LOWORD(wParam); - - if(uid == IDOK){ - if (!GetWindowLongPtr(hDlg,GWLP_USERDATA)) - { - char pass1[255], pass2[255]; - if(GetDlgItemTextA(hDlg, IDC_USERPASS1, pass1, 254) < 3){ - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is too short!")); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); - SetDlgItemTextA(hDlg,IDC_USERPASS1,""); - SetDlgItemTextA(hDlg,IDC_USERPASS2,""); - }else{ - - GetDlgItemTextA(hDlg, IDC_USERPASS2, pass2, 254); - if (!strcmp(pass1, pass2)) { - encryptKeyLength = strlen(pass1); - strcpy(encryptKey, pass1); - EndDialog(hDlg,IDOK); - }else{ - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Passwords do not match!")); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); - SetDlgItemTextA(hDlg,IDC_USERPASS1,""); - SetDlgItemTextA(hDlg,IDC_USERPASS2,""); - } - } - }else{ - - } - }else if(uid == IDCANCEL){ - EndDialog(hDlg,IDCANCEL); - } - } - case WM_TIMER: - { - LanguageChanged(hDlg); - return FALSE; - } - case WM_DESTROY: - { - KillTimer(hDlg, 1); - DestroyIcon(hIcon); - return FALSE; - } - } - return FALSE; -} - -char* newPass; - -BOOL CALLBACK DlgChangePass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) -{ - HICON hIcon = 0; - - switch(uMsg) - { - case WM_INITDIALOG: - { - //if(pluginLink && ServiceExists(MS_LANGPACK_TRANSLATEDIALOG)) - TranslateDialogDefault(hDlg); - - hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Change password")); - - newPass = (char*)lParam; - oldLangID = 0; - SetTimer(hDlg,1,200,NULL); - LanguageChanged(hDlg); - - return TRUE; - } - - case WM_CTLCOLORSTATIC: - { - if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) - { - SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode((HDC)wParam, TRANSPARENT); - return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); - } - - return FALSE; - } - - case WM_COMMAND: - { - UINT uid = LOWORD(wParam); - - if(uid == IDOK){ - char pass1[255], pass2[255], oldpass[255]; - GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); - if(strcmp(oldpass, encryptKey)) { - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Wrong password!")); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); - break; - } - if(GetDlgItemTextA(hDlg, IDC_NEWPASS1, pass1, 254) < 3){ - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is too short!")); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); - - }else{ - GetDlgItemTextA(hDlg, IDC_NEWPASS2, pass2, 254); - if (!strcmp(pass1, pass2)) { - strcpy(newPass, pass1); - EndDialog(hDlg,IDOK); - }else{ - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Passwords do not match!")); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); - } - } - }else if(uid == IDCANCEL){ - EndDialog(hDlg,IDCANCEL); - }else if(uid == IDREMOVE){ - char oldpass[255]; - GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); - if(strcmp(oldpass, encryptKey)) { - SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Wrong password!")); - SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); - break; - } - EndDialog(hDlg, IDREMOVE); - } - } - case WM_TIMER: - { - LanguageChanged(hDlg); - return FALSE; - } - case WM_DESTROY: - { - KillTimer(hDlg, 1); - return FALSE; - } - } - return FALSE; -} diff --git a/plugins/Dbx_mmap_SA/dialogs.cpp b/plugins/Dbx_mmap_SA/dialogs.cpp new file mode 100644 index 0000000000..df13214b62 --- /dev/null +++ b/plugins/Dbx_mmap_SA/dialogs.cpp @@ -0,0 +1,618 @@ +#include "commonheaders.h" +#include +#include +#include +#include + +#include + +#define MS_DB_CHANGEPASSWORD "DB/ChangePassword" + +extern char encryptKey[255]; +extern size_t encryptKeyLength; +extern HANDLE g_hInst; +HANDLE hSetPwdMenu; + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL ShowDlgItem(HWND hwndDlg, int iIDCtrl, BOOL bShow) +{ + HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); + if (!hwndCtrl) return FALSE; + + // Avoid flickering + if (bShow && IsWindowVisible(hwndCtrl)) + return TRUE; + + return ShowWindow(hwndCtrl, (bShow ? SW_SHOW : SW_HIDE)); +} + +BOOL EnableDlgItem(HWND hwndDlg, int iIDCtrl, BOOL bEnable) +{ + HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); + if (!hwndCtrl) return FALSE; + + // Avoid flickering + if (IsWindowEnabled(hwndCtrl) == bEnable) + return (bEnable == FALSE); + + return EnableWindow(hwndCtrl, bEnable); +} + +BOOL IsDlgItemEnabled(HWND hwndDlg, int iIDCtrl) +{ + HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); + if (!hwndCtrl) return FALSE; + return IsWindowEnabled(hwndCtrl); +} + + +static int OptionsInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.position = -790000000; + odp.hInstance = g_hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.flags = ODPF_BOLDGROUPS; + odp.pszTitle = LPGEN("Database Features"); + odp.pszGroup = LPGEN("Services"); + odp.pfnDlgProc = DlgProcOptions; + Options_AddPage(wParam, &odp); + + return 0; +} + +INT_PTR ChangePassword(WPARAM wParam, LPARAM lParam) +{ + if(bEncoding){ + ChangePwd(); + }else{ + EncryptDB(); + } + return 0; +} + +void xModifyMenu(HANDLE hMenu,long flags,const TCHAR* name, HICON hIcon) +{ + CLISTMENUITEM menu; + ZeroMemory(&menu,sizeof(menu)); + menu.cbSize = sizeof(menu); + menu.flags = CMIM_FLAGS | CMIF_TCHAR; + menu.flags |= name ? CMIM_NAME : 0; + menu.flags |= hIcon ? CMIM_ICON : 0; + menu.flags |= flags; + menu.ptszName = (TCHAR*)name; + menu.hIcon=hIcon; + + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenu,(LPARAM)&menu); +} + +static int ModulesLoad(WPARAM wParam, LPARAM lParam) +{ + CLISTMENUITEM menu = {0}; + SKINICONDESC sid = {0}; + TCHAR szFile[MAX_PATH]; + //HANDLE hFirst; + + HookEvent(ME_OPT_INITIALISE, OptionsInit); + + // icolib init + GetModuleFileName(g_hInst, szFile, MAX_PATH); + + sid.cbSize = sizeof(sid); + sid.ptszDefaultFile = szFile; + sid.flags = SIDF_ALL_TCHAR; + sid.ptszSection = LPGENT("Database"); + sid.ptszDescription = LPGENT("Database"); + sid.pszName = "database"; + sid.iDefaultIndex = -IDI_ICON2; + Skin_AddIcon(&sid); + + sid.ptszDescription = LPGENT("Change Password"); + sid.pszName = "password"; + sid.iDefaultIndex = -IDI_ICON3; + Skin_AddIcon(&sid); + + menu.cbSize = sizeof(menu); + menu.flags = CMIM_ALL | CMIF_TCHAR; + + menu.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"database"); + + // main menu item + menu.ptszName = (bEncoding) ? LPGENT("Change password") : LPGENT("Set password"); + menu.ptszPopupName = LPGENT("Database"); + menu.pszService = MS_DB_CHANGEPASSWORD; + menu.position = 500100000; + + hSetPwdMenu = Menu_AddMainMenuItem(&menu); + + ZeroMemory(&menu,sizeof(menu)); + menu.cbSize = sizeof(menu); + menu.flags = CMIM_ICON; + menu.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"password"); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hSetPwdMenu, (LPARAM)&menu); + + return 0; +} + +int UnloadOptions() +{ + OleUninitialize(); + return 0; +} + + +int InitDialogs() +{ + OleInitialize(0); + CreateServiceFunction(MS_DB_CHANGEPASSWORD, ChangePassword); + HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoad); + + return 0; +} + +extern Cryptor* CryptoEngine; + +extern int ModulesCount; +extern CryptoModule* Modules[100]; + +//ugly, i know +#undef LVM_SETITEMTEXT +#define LVM_SETITEMTEXT LVM_SETITEMTEXTA + +int ImageList_AddIcon_IconLibLoaded(HIMAGELIST hIml, char* name) +{ + HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON, (WPARAM)NULL, (LPARAM)name); + int res = ImageList_AddIcon(hIml, hIcon); + return res; +} + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndList = GetDlgItem(hwndDlg, IDC_MODULES); + LVCOLUMN col; + LVITEM item; + int i, iRow, iIndex; + NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; + WORD uid; + HIMAGELIST hIml; + + switch ( msg ) { + case WM_INITDIALOG: + hIml = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 2, 0); + TranslateDialogDefault( hwndDlg ); + + ImageList_AddIcon_IconLibLoaded( hIml, "core_main_29" ); + ImageList_AddIcon_IconLibLoaded( hIml, "core_main_30" ); + ListView_SetImageList( hwndList, hIml, LVSIL_SMALL ); + + col.pszText = NULL; + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 50; + ListView_InsertColumn(hwndList, 1, &col); + + col.pszText = TranslateT("Dll"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 1000; + ListView_InsertColumn(hwndList, 2, &col); + + col.pszText = TranslateT("Name"); + col.cx = 1000; + ListView_InsertColumn(hwndList, 3, &col); + + col.pszText = TranslateT("Version"); + col.cx = 1000; + ListView_InsertColumn(hwndList, 4, &col); + + ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES); + + uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + for(i = 0; i < ModulesCount; i++) { + char buf[100]; + + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = NULL; + iRow = ListView_InsertItem(hwndList, &item); + + ListView_SetItemText(hwndList, iRow, 1, (LPWSTR)Modules[i]->dllname); + ListView_SetItemText(hwndList, iRow, 2, (LPWSTR)Modules[i]->cryptor->Name); + mir_snprintf(buf,SIZEOF(buf),"%d.%d.%d.%d", HIBYTE(HIWORD(Modules[i]->cryptor->Version)), LOBYTE(HIWORD(Modules[i]->cryptor->Version)), HIBYTE(LOWORD(Modules[i]->cryptor->Version)), LOBYTE(LOWORD(Modules[i]->cryptor->Version))); + ListView_SetItemText(hwndList, iRow, 3, (LPWSTR)buf); + + if(uid == Modules[i]->cryptor->uid && bEncoding) + ListView_SetCheckState(hwndList, i, 1); + + item.mask = LVIF_IMAGE; + item.iItem = iRow; + item.iSubItem = 0; + item.iImage = ( CryptoEngine == Modules[i]->cryptor && bEncoding ) ? 0 : 1; + ListView_SetItem( hwndList, &item ); + } + + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + return TRUE; + + case WM_COMMAND: + if ( HIWORD(wParam) == STN_CLICKED ) { + switch (LOWORD(wParam)) { + case IDC_EMAIL: + case IDC_SITE: + { + char buf[512]; + char * p = &buf[7]; + lstrcpyA(buf,"mailto:"); + if ( GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), p, SIZEOF(buf) - 7)) { + CallService(MS_UTILS_OPENURL,0,(LPARAM) (LOWORD(wParam)==IDC_EMAIL ? buf : p)); + } + break; + } } } + break; + + case WM_NOTIFY: + if ( hdr && hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1)) { + iIndex = hdr->iItem; + if(hdr->uNewState & 0x2000){ + for(i = 0; i < ModulesCount; i++) { + if(i != iIndex) ListView_SetCheckState(hwndList, i, 0); + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + if(hdr->uNewState & 0x1000){ + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + if(hdr->uNewState & LVIS_SELECTED){ + SetDlgItemTextA(hwndDlg, IDC_AUTHOR, Modules[iIndex]->cryptor->Author); + { + TCHAR* info_t = mir_a2t((char*)(Modules[iIndex]->cryptor->Info)); + SetDlgItemText(hwndDlg, IDC_INFO, TranslateTS(info_t)); + mir_free(info_t); + } + SetDlgItemTextA(hwndDlg, IDC_SITE, Modules[iIndex]->cryptor->Site); + SetDlgItemTextA(hwndDlg, IDC_EMAIL, Modules[iIndex]->cryptor->Email); + SetDlgItemTextA(hwndDlg, IDC_ENC, Modules[iIndex]->cryptor->Name); + SetDlgItemInt(hwndDlg, IDC_UID, Modules[iIndex]->cryptor->uid, 0); + } else { + SetDlgItemTextA(hwndDlg, IDC_AUTHOR, ""); + SetDlgItemTextA(hwndDlg, IDC_INFO, ""); + SetDlgItemTextA(hwndDlg, IDC_SITE, ""); + SetDlgItemTextA(hwndDlg, IDC_EMAIL, ""); + SetDlgItemTextA(hwndDlg, IDC_ENC, ""); + SetDlgItemTextA(hwndDlg, IDC_UID, ""); + } + + break; + } + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + int alg = -1; + for(i = 0; i < ModulesCount; i++) { + if(ListView_GetCheckState(hwndList, i)) { + alg = i; + break; + } + } + + if(alg > -1){ + if (!bEncoding){ + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[alg]->cryptor->uid); + EncryptDB(); + }else{ + if(Modules[alg]->cryptor->uid != DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", -1)) { + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[alg]->cryptor->uid); + RecryptDB(); + } + } + }else{ + if(bEncoding){ + DecryptDB(); + } + } + + uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + for(i = 0; i < ModulesCount; i++) { + if(uid == Modules[i]->cryptor->uid && bEncoding) + ListView_SetCheckState(hwndList, i, 1); + + item.mask = LVIF_IMAGE; + item.iItem = i; + item.iSubItem = 0; + item.iImage = ( CryptoEngine == Modules[i]->cryptor && bEncoding ) ? 0 : 1; + + ListView_SetItem( hwndList, &item ); + } + + return TRUE; + + } + break; + } + + return FALSE; +} +UINT oldLangID = 0; +void LanguageChanged(HWND hDlg) +{ + UINT LangID = (UINT)GetKeyboardLayout(0); + char Lang[3] = {0}; + if (LangID != oldLangID) + { + oldLangID = LangID; + GetLocaleInfoA(MAKELCID((LangID & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2); + Lang[0] = toupper(Lang[0]); + Lang[1] = tolower(Lang[1]); + SetDlgItemTextA(hDlg, IDC_LANG, Lang); + } +} + +extern BOOL wrongPass; + +BOOL CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = 0; + TCHAR tszHeaderTxt[256]; + TCHAR* tszDbName; + switch(uMsg) + { + case WM_INITDIALOG: + { + HWND hwndCtrl; +// if(pluginLink && ServiceExists(MS_LANGPACK_TRANSLATEDIALOG)) + TranslateDialogDefault(hDlg); + + hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); + + if (!wrongPass) + { + tszDbName = mir_a2t((char*)lParam); + mir_sntprintf(tszHeaderTxt, SIZEOF(tszHeaderTxt), _T("%s\n%s"), TranslateT("Please type in your password for"), tszDbName); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), tszHeaderTxt); + mir_free(tszDbName); + } + else + { + if (wrongPass > 2) + { + hwndCtrl = GetDlgItem(hDlg, IDC_USERPASS); + EnableWindow(hwndCtrl, FALSE); + hwndCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hwndCtrl, FALSE); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Too many errors!")); + } + else + { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is not correct!")); + } + } + oldLangID = 0; + SetTimer(hDlg,1,200,NULL); + LanguageChanged(hDlg); + return TRUE; + } + + case WM_CTLCOLORSTATIC: + { + if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) + { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); + } + + return FALSE; + } + + case WM_COMMAND: + { + UINT uid = LOWORD(wParam); + + if(uid == IDOK){ + if (!GetWindowLongPtr(hDlg,GWLP_USERDATA)) + { + encryptKeyLength = GetDlgItemTextA(hDlg, IDC_USERPASS, encryptKey, 254); + EndDialog(hDlg,IDOK); + }else{ + + } + }else if(uid == IDCANCEL){ + EndDialog(hDlg,IDCANCEL); + } + } + case WM_TIMER: + { + LanguageChanged(hDlg); + return FALSE; + } + case WM_DESTROY: + { + KillTimer(hDlg, 1); + DestroyIcon(hIcon); + } + } + + return FALSE; +} + +BOOL CALLBACK DlgStdNewPass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = 0; + + switch(uMsg) + { + case WM_INITDIALOG: + { + //if(pluginLink && ServiceExists(MS_LANGPACK_TRANSLATEDIALOG)) + TranslateDialogDefault(hDlg); + + hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); + + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Please enter your new password")); + + oldLangID = 0; + SetTimer(hDlg,1,200,NULL); + LanguageChanged(hDlg); + + return TRUE; + } + + case WM_CTLCOLORSTATIC: + { + if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) + { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); + } + + return FALSE; + } + + case WM_COMMAND: + { + UINT uid = LOWORD(wParam); + + if(uid == IDOK){ + if (!GetWindowLongPtr(hDlg,GWLP_USERDATA)) + { + char pass1[255], pass2[255]; + if(GetDlgItemTextA(hDlg, IDC_USERPASS1, pass1, 254) < 3){ + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is too short!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + SetDlgItemTextA(hDlg,IDC_USERPASS1,""); + SetDlgItemTextA(hDlg,IDC_USERPASS2,""); + }else{ + + GetDlgItemTextA(hDlg, IDC_USERPASS2, pass2, 254); + if (!strcmp(pass1, pass2)) { + encryptKeyLength = strlen(pass1); + strcpy(encryptKey, pass1); + EndDialog(hDlg,IDOK); + }else{ + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Passwords do not match!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + SetDlgItemTextA(hDlg,IDC_USERPASS1,""); + SetDlgItemTextA(hDlg,IDC_USERPASS2,""); + } + } + }else{ + + } + }else if(uid == IDCANCEL){ + EndDialog(hDlg,IDCANCEL); + } + } + case WM_TIMER: + { + LanguageChanged(hDlg); + return FALSE; + } + case WM_DESTROY: + { + KillTimer(hDlg, 1); + DestroyIcon(hIcon); + return FALSE; + } + } + return FALSE; +} + +char* newPass; + +BOOL CALLBACK DlgChangePass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = 0; + + switch(uMsg) + { + case WM_INITDIALOG: + { + //if(pluginLink && ServiceExists(MS_LANGPACK_TRANSLATEDIALOG)) + TranslateDialogDefault(hDlg); + + hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Change password")); + + newPass = (char*)lParam; + oldLangID = 0; + SetTimer(hDlg,1,200,NULL); + LanguageChanged(hDlg); + + return TRUE; + } + + case WM_CTLCOLORSTATIC: + { + if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) + { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); + } + + return FALSE; + } + + case WM_COMMAND: + { + UINT uid = LOWORD(wParam); + + if(uid == IDOK){ + char pass1[255], pass2[255], oldpass[255]; + GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); + if(strcmp(oldpass, encryptKey)) { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Wrong password!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + break; + } + if(GetDlgItemTextA(hDlg, IDC_NEWPASS1, pass1, 254) < 3){ + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is too short!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + + }else{ + GetDlgItemTextA(hDlg, IDC_NEWPASS2, pass2, 254); + if (!strcmp(pass1, pass2)) { + strcpy(newPass, pass1); + EndDialog(hDlg,IDOK); + }else{ + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Passwords do not match!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + } + } + }else if(uid == IDCANCEL){ + EndDialog(hDlg,IDCANCEL); + }else if(uid == IDREMOVE){ + char oldpass[255]; + GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); + if(strcmp(oldpass, encryptKey)) { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Wrong password!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + break; + } + EndDialog(hDlg, IDREMOVE); + } + } + case WM_TIMER: + { + LanguageChanged(hDlg); + return FALSE; + } + case WM_DESTROY: + { + KillTimer(hDlg, 1); + return FALSE; + } + } + return FALSE; +} diff --git a/plugins/Dbx_mmap_SA/encrypt.c b/plugins/Dbx_mmap_SA/encrypt.c deleted file mode 100644 index a42d79eae2..0000000000 --- a/plugins/Dbx_mmap_SA/encrypt.c +++ /dev/null @@ -1,66 +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" - -//VERY VERY VERY BASIC ENCRYPTION FUNCTION - - -void Encrypt(char*msg,BOOL up) -{ - int i; - int jump; - if (up) - { - jump=5; - } - else - { - jump=-5; - } - - for (i=0;msg[i];i++) - { - msg[i]=msg[i]+jump; - } - -} - -static INT_PTR EncodeString(WPARAM wParam,LPARAM lParam) -{ - Encrypt((char*)lParam,TRUE); - return 0; -} - -static INT_PTR DecodeString(WPARAM wParam,LPARAM lParam) -{ - Encrypt((char*)lParam,FALSE); - return 0; -} - -int InitCrypt(void) -{ - CreateServiceFunction(MS_DB_CRYPT_ENCODESTRING,EncodeString); - CreateServiceFunction(MS_DB_CRYPT_DECODESTRING,DecodeString); - return 0; -} diff --git a/plugins/Dbx_mmap_SA/encrypt.cpp b/plugins/Dbx_mmap_SA/encrypt.cpp new file mode 100644 index 0000000000..a42d79eae2 --- /dev/null +++ b/plugins/Dbx_mmap_SA/encrypt.cpp @@ -0,0 +1,66 @@ +/* + +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" + +//VERY VERY VERY BASIC ENCRYPTION FUNCTION + + +void Encrypt(char*msg,BOOL up) +{ + int i; + int jump; + if (up) + { + jump=5; + } + else + { + jump=-5; + } + + for (i=0;msg[i];i++) + { + msg[i]=msg[i]+jump; + } + +} + +static INT_PTR EncodeString(WPARAM wParam,LPARAM lParam) +{ + Encrypt((char*)lParam,TRUE); + return 0; +} + +static INT_PTR DecodeString(WPARAM wParam,LPARAM lParam) +{ + Encrypt((char*)lParam,FALSE); + return 0; +} + +int InitCrypt(void) +{ + CreateServiceFunction(MS_DB_CRYPT_ENCODESTRING,EncodeString); + CreateServiceFunction(MS_DB_CRYPT_DECODESTRING,DecodeString); + return 0; +} diff --git a/plugins/Dbx_mmap_SA/init.c b/plugins/Dbx_mmap_SA/init.c deleted file mode 100644 index f13a4b5667..0000000000 --- a/plugins/Dbx_mmap_SA/init.c +++ /dev/null @@ -1,216 +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 MM_INTERFACE mmi; -struct LIST_INTERFACE li; -struct UTF8_INTERFACE utfi; -int hLangpack; - -extern char szDbPath[MAX_PATH]; - -HINSTANCE g_hInst=NULL; -PLUGINLINK *pluginLink; - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - __VERSION_DWORD, - "Provides Miranda database support: global settings, contacts, history, settings per contact. Enhanced modification with Encryption support.", - "Miranda-IM project, modification by FYR and chaos.persei, nullbie, Billy_Bons", - "chaos.persei@gmail.com; ashpynov@gmail.com; bio@msx.ru; ghazan@miranda-im.org", - "Copyright 2000-2011 Miranda IM project, FYR, chaos.persei, induction, nullbie", - "http://dbmmapmod.googlecode.com/", - UNICODE_AWARE, - DEFMOD_DB, - // {28FF9B91-3E4D-4f1c-B47C-C641B037FF40} - { 0x28ff9b91, 0x3e4d, 0x4f1c, { 0xb4, 0x7c, 0xc6, 0x41, 0xb0, 0x37, 0xff, 0x40 } } -}; - -static int getCapability( int flag ) -{ - return 0; -} - -// returns 0 if the profile is created, EMKPRF* -static int makeDatabase(char * profile, int * error) -{ - HANDLE hFile=CreateFileA(profile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - if ( hFile != INVALID_HANDLE_VALUE ) { - CreateDbHeaders(hFile); - CloseHandle(hFile); - return 0; - } - if ( error != NULL ) *error=EMKPRF_CREATEFAILED; - return 1; -} - -// returns 0 if the given profile has a valid header -static int grokHeader( char * profile, int * error ) -{ - int rc=1; - int chk=0; - struct DBHeader hdr; - HANDLE hFile = INVALID_HANDLE_VALUE; - DWORD dummy=0; - - hFile = CreateFileA(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); - return 1; - } - chk=CheckDbHeaders(&hdr); - 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; -} - -// returns 0 if all the APIs are injected otherwise, 1 -static int LoadDatabase( char * profile, void * plink ) -{ - PLUGINLINK *link = plink; -#ifdef _DEBUG - _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); -#endif - // don't need thread notifications - strncpy(szDbPath, profile, sizeof(szDbPath)); - - // this is like Load()'s pluginLink - pluginLink=link; - - // set the memory, lists & UTF8 manager - mir_getLI( &li ); - mir_getMMI( &mmi ); - mir_getUTFI( &utfi ); - mir_getLP( &pluginInfo ); - - { // Are we running under unicode Miranda core ? - char szVer[MAX_PATH]; - CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); - _strlwr(szVer); // make sure it is lowercase - - /* WARNING!!! You CANNOT remove this code */ - if (strstr(szVer, "coffee") != NULL) - { - // We are running under damn violators - void (*f)(); - - MessageBox(0, TranslateT("Running mmap_sa is forbidden under license violating products, sorry"), TranslateT("Warning!"), MB_OK); - - f = NULL; - f(); - } - /* end of protected code */ - } - - // inject all APIs and hooks into the core - return LoadDatabaseModule(); -} - -static int UnloadDatabase(int wasLoaded) -{ - if ( !wasLoaded) return 0; - UnloadDatabaseModule(); - return 0; -} - -static int getFriendlyName( char * buf, size_t cch, int shortName ) -{ - strncpy(buf,shortName ? "db3x secured_mmap driver" : "db3x mmap database support",cch); - return 0; -} - -static DATABASELINK dblink = { - sizeof(DATABASELINK), - getCapability, - getFriendlyName, - makeDatabase, - grokHeader, - LoadDatabase, - UnloadDatabase, -}; - -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) -{ - g_hInst=hInstDLL; - return TRUE; -} - -__declspec(dllexport) DATABASELINK* DatabasePluginInfo(void * reserved) -{ - return &dblink; -} - -__declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -static const MUUID interfaces[] = {MIID_DATABASE, MIID_LAST}; -__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - -int __declspec(dllexport) Load(PLUGINLINK * link) -{ - return 1; -} - -int __declspec(dllexport) Unload(void) -{ - return 0; -} diff --git a/plugins/Dbx_mmap_SA/init.cpp b/plugins/Dbx_mmap_SA/init.cpp new file mode 100644 index 0000000000..f13a4b5667 --- /dev/null +++ b/plugins/Dbx_mmap_SA/init.cpp @@ -0,0 +1,216 @@ +/* + +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 MM_INTERFACE mmi; +struct LIST_INTERFACE li; +struct UTF8_INTERFACE utfi; +int hLangpack; + +extern char szDbPath[MAX_PATH]; + +HINSTANCE g_hInst=NULL; +PLUGINLINK *pluginLink; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + __VERSION_DWORD, + "Provides Miranda database support: global settings, contacts, history, settings per contact. Enhanced modification with Encryption support.", + "Miranda-IM project, modification by FYR and chaos.persei, nullbie, Billy_Bons", + "chaos.persei@gmail.com; ashpynov@gmail.com; bio@msx.ru; ghazan@miranda-im.org", + "Copyright 2000-2011 Miranda IM project, FYR, chaos.persei, induction, nullbie", + "http://dbmmapmod.googlecode.com/", + UNICODE_AWARE, + DEFMOD_DB, + // {28FF9B91-3E4D-4f1c-B47C-C641B037FF40} + { 0x28ff9b91, 0x3e4d, 0x4f1c, { 0xb4, 0x7c, 0xc6, 0x41, 0xb0, 0x37, 0xff, 0x40 } } +}; + +static int getCapability( int flag ) +{ + return 0; +} + +// returns 0 if the profile is created, EMKPRF* +static int makeDatabase(char * profile, int * error) +{ + HANDLE hFile=CreateFileA(profile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if ( hFile != INVALID_HANDLE_VALUE ) { + CreateDbHeaders(hFile); + CloseHandle(hFile); + return 0; + } + if ( error != NULL ) *error=EMKPRF_CREATEFAILED; + return 1; +} + +// returns 0 if the given profile has a valid header +static int grokHeader( char * profile, int * error ) +{ + int rc=1; + int chk=0; + struct DBHeader hdr; + HANDLE hFile = INVALID_HANDLE_VALUE; + DWORD dummy=0; + + hFile = CreateFileA(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); + return 1; + } + chk=CheckDbHeaders(&hdr); + 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; +} + +// returns 0 if all the APIs are injected otherwise, 1 +static int LoadDatabase( char * profile, void * plink ) +{ + PLUGINLINK *link = plink; +#ifdef _DEBUG + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif + // don't need thread notifications + strncpy(szDbPath, profile, sizeof(szDbPath)); + + // this is like Load()'s pluginLink + pluginLink=link; + + // set the memory, lists & UTF8 manager + mir_getLI( &li ); + mir_getMMI( &mmi ); + mir_getUTFI( &utfi ); + mir_getLP( &pluginInfo ); + + { // Are we running under unicode Miranda core ? + char szVer[MAX_PATH]; + CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); + _strlwr(szVer); // make sure it is lowercase + + /* WARNING!!! You CANNOT remove this code */ + if (strstr(szVer, "coffee") != NULL) + { + // We are running under damn violators + void (*f)(); + + MessageBox(0, TranslateT("Running mmap_sa is forbidden under license violating products, sorry"), TranslateT("Warning!"), MB_OK); + + f = NULL; + f(); + } + /* end of protected code */ + } + + // inject all APIs and hooks into the core + return LoadDatabaseModule(); +} + +static int UnloadDatabase(int wasLoaded) +{ + if ( !wasLoaded) return 0; + UnloadDatabaseModule(); + return 0; +} + +static int getFriendlyName( char * buf, size_t cch, int shortName ) +{ + strncpy(buf,shortName ? "db3x secured_mmap driver" : "db3x mmap database support",cch); + return 0; +} + +static DATABASELINK dblink = { + sizeof(DATABASELINK), + getCapability, + getFriendlyName, + makeDatabase, + grokHeader, + LoadDatabase, + UnloadDatabase, +}; + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) +{ + g_hInst=hInstDLL; + return TRUE; +} + +__declspec(dllexport) DATABASELINK* DatabasePluginInfo(void * reserved) +{ + return &dblink; +} + +__declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +static const MUUID interfaces[] = {MIID_DATABASE, MIID_LAST}; +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +int __declspec(dllexport) Load(PLUGINLINK * link) +{ + return 1; +} + +int __declspec(dllexport) Unload(void) +{ + return 0; +} diff --git a/plugins/Dbx_mmap_SA/security.c b/plugins/Dbx_mmap_SA/security.c deleted file mode 100644 index f4b9b06004..0000000000 --- a/plugins/Dbx_mmap_SA/security.c +++ /dev/null @@ -1,424 +0,0 @@ -// (C) Artem Shpynov aka FYR and Igonin Vitaliy aka chaos.persei, 2007 - 2008 - -#include "commonheaders.h" - -BOOL bEncoding; -BOOL bEncProcess = 0; - -extern HINSTANCE g_hInst; - -extern HANDLE hSetPwdMenu = NULL; - -char encryptKey[255]; -size_t encryptKeyLength; - -int wrongPass = 0; -void* key; - -Cryptor* CryptoEngine = NULL; - -int ModulesCount = 0; -CryptoModule* Modules[100]; - - -void zero_fill(BYTE * pBuf, size_t bufSize) -{ - size_t i; - for(i = 0; i < bufSize; i++) - pBuf[i] = 0; -} - -void InitSecurity() -{ - HMODULE hLib; - WIN32_FIND_DATAA fd; - - Cryptor* (__stdcall *GetCryptor)(); - - HANDLE hFile = FindFirstFileA(".\\plugins\\cryptors\\*.dll", &fd); - - ModulesCount = 0; - while (hFile != INVALID_HANDLE_VALUE) - { - char tmp[255]; - strcpy(tmp, ".\\plugins\\cryptors\\"); - strcat(tmp, fd.cFileName); - - hLib = LoadLibraryA(tmp); - if(hLib){ - GetCryptor = (Cryptor* (__stdcall *)()) GetProcAddress(hLib, "GetCryptor"); - if(GetCryptor){ - Modules[ModulesCount] = (CryptoModule*) malloc(sizeof(CryptoModule)); - Modules[ModulesCount]->cryptor = GetCryptor(); - strcpy(Modules[ModulesCount]->dllname, fd.cFileName); - Modules[ModulesCount]->hLib = hLib; - - ModulesCount++; - }else{ - FreeLibrary(hLib); - } - } - if(ModulesCount >= 100) break; - if (!FindNextFileA(hFile, &fd)) break; - } -} - -void UnloadSecurity() -{ - int i; - - if(CryptoEngine) CryptoEngine->FreeKey(key); - - for(i = 0; i < ModulesCount; i++) - { - FreeLibrary(Modules[i]->hLib); - free(Modules[i]); - } -} - -void EncoderInit() -{ - if (!bEncoding) return; - - encryptKey[encryptKeyLength] = 0; - key = CryptoEngine->GenerateKey(encryptKey); -} - -void EncodeCopyMemory(void * dst, void * src, size_t size ) -{ - memcpy(dst, src, size); - - if (!bEncoding) - return; - - CryptoEngine->EncryptMem(dst, (int)size, key); -} - -void DecodeCopyMemory(void * dst, void * src, size_t size ) -{ - memcpy(dst, src, size); - - if (!bEncoding) - return; - - CryptoEngine->DecryptMem(dst, (int)size, key); -} - -void EncodeDBWrite(DWORD ofs, void * src, size_t size) -{ - if(bEncoding) - { - BYTE * buf; - - buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); - EncodeCopyMemory(buf, src, size); - DBWrite(ofs, buf, (int)size); - GlobalFree(buf); - } - else - { - DBWrite(ofs, src, (int)size); - } -} - -void DecodeDBWrite(DWORD ofs, void * src, size_t size) -{ - - if(bEncoding) - { - BYTE * buf; - - buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); - DecodeCopyMemory(buf, src, size); - DBWrite(ofs, buf, (int)size); - GlobalFree(buf); - } - else - { - DBWrite(ofs, src, (int)size); - } -} - -int bCheckingPass = 0; - -int CheckPassword(WORD checkWord, char * szDBName) -{ - WORD ver; - int res; - - if(bCheckingPass) return 0; - bCheckingPass = 1; - - { - int i; - int Found = 0; - for(i = 0; i < ModulesCount; i++) { - if(dbHeader.cryptorUID == Modules[i]->cryptor->uid){ - CryptoEngine = Modules[i]->cryptor; - Found = 1; - break; - } - } - if (!Found){ - MessageBoxA(0, "Sorry, but your database encrypted with unknown module", "Error", MB_OK); - bCheckingPass = 0; - return 0; - } - } - - while(1){ - res = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_LOGIN), NULL, (DLGPROC)DlgStdInProc, (LPARAM)szDBName); - if(res == IDCANCEL) - { - wrongPass = 0; - bCheckingPass = 0; - return 0; - } - if(encryptKeyLength < 1) continue; - EncoderInit(); - DecodeCopyMemory(&ver, &checkWord, sizeof(checkWord)); - if(ver == 0x5195) - { - wrongPass = 0; - bCheckingPass = 0; - return 1; - } - wrongPass++; - } - - bCheckingPass = 0; -} - -int SelectEncoder() -{ - WORD uid; - int i; - - if(ModulesCount == 0){ - MessageBox(0, TranslateT("Crypto modules not found"), TranslateT("Error"), MB_OK); - return 1; - } - - uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); - - if(uid == 0){ - MessageBox(0, TranslateT("Crypto module hasn't been chosen, using first one found"), TranslateT("Notice"), MB_OK); - DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[0]->cryptor->uid); - CryptoEngine = Modules[0]->cryptor; - } - else{ - int Found = 0; - for(i = 0; i < ModulesCount; i++) { - if(Modules[i]->cryptor->uid == uid){ - CryptoEngine = Modules[i]->cryptor; - Found = 1; - break; - } - } - if (!Found){ - MessageBox(0, TranslateT("Crypto module hasn't been chosen, using first one found"), TranslateT("Notice"), MB_OK); - DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[0]->cryptor->uid); - CryptoEngine = Modules[0]->cryptor; - } - } - - return 0; -} - -void EncodeAll() -{ - HANDLE hContact; - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - if(hContact){ - do{ - EncodeContactEvents(hContact); - EncodeContactSettings(hContact); - }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); - } - - EncodeContactEvents(NULL); - EncodeContactSettings(NULL); -} - -void DecodeAll() -{ - HANDLE hContact; - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - if(hContact){ - do{ - DecodeContactEvents(hContact); - DecodeContactSettings(hContact); - }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); - } - DecodeContactEvents(NULL); - DecodeContactSettings(NULL); -} - -void WritePlainHeader() -{ - DWORD bytesWritten; - - memcpy(dbHeader.signature, &dbSignature, sizeof(dbHeader.signature)); - SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); - WriteFile(hDbFile,dbHeader.signature,sizeof(dbHeader.signature),&bytesWritten,NULL); - { - WORD checkWord; - checkWord = 0x0700; - memcpy(&dbHeader.checkWord, &checkWord, sizeof(checkWord)); - WriteFile(hDbFile,&dbHeader.checkWord,sizeof(dbHeader.checkWord),&bytesWritten,NULL); - - dbHeader.cryptorUID = 0x0000; //no encryption - WriteFile(hDbFile,&dbHeader.cryptorUID,sizeof(dbHeader.cryptorUID),&bytesWritten,NULL); - } -} - -void WriteCryptHeader() -{ - DWORD bytesWritten; - - memcpy(dbHeader.signature, &dbSignatureSecured, sizeof(dbHeader.signature)); - SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); - WriteFile(hDbFile,dbHeader.signature,sizeof(dbHeader.signature),&bytesWritten,NULL); - { - WORD checkWord; - checkWord = 0x5195; - EncodeCopyMemory(&dbHeader.checkWord, &checkWord, sizeof(checkWord)); - WriteFile(hDbFile,&dbHeader.checkWord,sizeof(dbHeader.checkWord),&bytesWritten,NULL); - - dbHeader.cryptorUID = CryptoEngine->uid; - WriteFile(hDbFile,&dbHeader.cryptorUID,sizeof(dbHeader.cryptorUID),&bytesWritten,NULL); - } -} - -void EncryptDB() -{ - int action = 0; - if(bEncProcess) return; - - if(memcmp(dbHeader.signature, &dbSignatureSecured, sizeof(dbHeader.signature)) == 0){ - MessageBox(0, TranslateT("DB is already secured!"), TranslateT("Error"), MB_OK); - return; - } - - if(SelectEncoder()) { - return; - } - - bEncProcess = 1; - - action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_NEWPASS), NULL, (DLGPROC)DlgStdNewPass, (LPARAM)NULL); - if(action != IDOK || !strlen(encryptKey)) { - bEncProcess = 0; - DBWriteContactSettingByte(NULL, "SecureMMAP", "CryptoModule", 0); - return; - } - - EnterCriticalSection(&csDbAccess); - - bEncoding = 1; - EncoderInit(); - - EncodeAll(); - - LeaveCriticalSection(&csDbAccess); - - WriteCryptHeader(); - - xModifyMenu(hSetPwdMenu, 0, LPGENT("Change Password"), 0); - - bEncProcess = 0; -} - -void DecryptDB() -{ - char oldKey[255]; - strcpy(oldKey, encryptKey); - - if (!CheckPassword(dbHeader.checkWord, Translate("current database"))){strcpy(encryptKey, oldKey); encryptKeyLength = strlen(oldKey); return;} - - WritePlainHeader(); - - EnterCriticalSection(&csDbAccess); - DecodeAll(); - LeaveCriticalSection(&csDbAccess); - - bEncoding = 0; - - zero_fill(encryptKey, sizeof encryptKey); - - xModifyMenu(hSetPwdMenu, 0, LPGENT("Set Password"), 0); - - DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); - - CryptoEngine->FreeKey(key); - - CryptoEngine = NULL; -} - -void RecryptDB() -{ - EnterCriticalSection(&csDbAccess); - - DecodeAll(); - - CryptoEngine->FreeKey(key); - - SelectEncoder(); - - bEncoding = 1; - - EncoderInit(); - - EncodeAll(); - - WriteCryptHeader(); - - LeaveCriticalSection(&csDbAccess); -} - -void ChangePwd() -{ - char newpass[255] = {0}; - - int action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHANGEPASS), NULL, (DLGPROC)DlgChangePass, (LPARAM)newpass); - - if(action == IDCANCEL || (action == IDOK && !strlen(newpass))) - return; - - EnterCriticalSection(&csDbAccess); - - DecodeAll(); - - CryptoEngine->FreeKey(key); - - if(action == IDREMOVE){ - WritePlainHeader(); - - bEncoding = 0; - CryptoEngine = NULL; - DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); - - zero_fill(encryptKey, sizeof encryptKey); - - xModifyMenu(hSetPwdMenu, 0, LPGENT("Set Password"), 0); - } - - if(action == IDOK){ - strcpy(encryptKey, newpass); - encryptKeyLength = strlen(newpass); - - bEncoding = 1; - - EncoderInit(); - - EncodeAll(); - - WriteCryptHeader(); - } - - zero_fill(newpass, sizeof newpass); - - LeaveCriticalSection(&csDbAccess); -} \ No newline at end of file diff --git a/plugins/Dbx_mmap_SA/security.cpp b/plugins/Dbx_mmap_SA/security.cpp new file mode 100644 index 0000000000..f4b9b06004 --- /dev/null +++ b/plugins/Dbx_mmap_SA/security.cpp @@ -0,0 +1,424 @@ +// (C) Artem Shpynov aka FYR and Igonin Vitaliy aka chaos.persei, 2007 - 2008 + +#include "commonheaders.h" + +BOOL bEncoding; +BOOL bEncProcess = 0; + +extern HINSTANCE g_hInst; + +extern HANDLE hSetPwdMenu = NULL; + +char encryptKey[255]; +size_t encryptKeyLength; + +int wrongPass = 0; +void* key; + +Cryptor* CryptoEngine = NULL; + +int ModulesCount = 0; +CryptoModule* Modules[100]; + + +void zero_fill(BYTE * pBuf, size_t bufSize) +{ + size_t i; + for(i = 0; i < bufSize; i++) + pBuf[i] = 0; +} + +void InitSecurity() +{ + HMODULE hLib; + WIN32_FIND_DATAA fd; + + Cryptor* (__stdcall *GetCryptor)(); + + HANDLE hFile = FindFirstFileA(".\\plugins\\cryptors\\*.dll", &fd); + + ModulesCount = 0; + while (hFile != INVALID_HANDLE_VALUE) + { + char tmp[255]; + strcpy(tmp, ".\\plugins\\cryptors\\"); + strcat(tmp, fd.cFileName); + + hLib = LoadLibraryA(tmp); + if(hLib){ + GetCryptor = (Cryptor* (__stdcall *)()) GetProcAddress(hLib, "GetCryptor"); + if(GetCryptor){ + Modules[ModulesCount] = (CryptoModule*) malloc(sizeof(CryptoModule)); + Modules[ModulesCount]->cryptor = GetCryptor(); + strcpy(Modules[ModulesCount]->dllname, fd.cFileName); + Modules[ModulesCount]->hLib = hLib; + + ModulesCount++; + }else{ + FreeLibrary(hLib); + } + } + if(ModulesCount >= 100) break; + if (!FindNextFileA(hFile, &fd)) break; + } +} + +void UnloadSecurity() +{ + int i; + + if(CryptoEngine) CryptoEngine->FreeKey(key); + + for(i = 0; i < ModulesCount; i++) + { + FreeLibrary(Modules[i]->hLib); + free(Modules[i]); + } +} + +void EncoderInit() +{ + if (!bEncoding) return; + + encryptKey[encryptKeyLength] = 0; + key = CryptoEngine->GenerateKey(encryptKey); +} + +void EncodeCopyMemory(void * dst, void * src, size_t size ) +{ + memcpy(dst, src, size); + + if (!bEncoding) + return; + + CryptoEngine->EncryptMem(dst, (int)size, key); +} + +void DecodeCopyMemory(void * dst, void * src, size_t size ) +{ + memcpy(dst, src, size); + + if (!bEncoding) + return; + + CryptoEngine->DecryptMem(dst, (int)size, key); +} + +void EncodeDBWrite(DWORD ofs, void * src, size_t size) +{ + if(bEncoding) + { + BYTE * buf; + + buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); + EncodeCopyMemory(buf, src, size); + DBWrite(ofs, buf, (int)size); + GlobalFree(buf); + } + else + { + DBWrite(ofs, src, (int)size); + } +} + +void DecodeDBWrite(DWORD ofs, void * src, size_t size) +{ + + if(bEncoding) + { + BYTE * buf; + + buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); + DecodeCopyMemory(buf, src, size); + DBWrite(ofs, buf, (int)size); + GlobalFree(buf); + } + else + { + DBWrite(ofs, src, (int)size); + } +} + +int bCheckingPass = 0; + +int CheckPassword(WORD checkWord, char * szDBName) +{ + WORD ver; + int res; + + if(bCheckingPass) return 0; + bCheckingPass = 1; + + { + int i; + int Found = 0; + for(i = 0; i < ModulesCount; i++) { + if(dbHeader.cryptorUID == Modules[i]->cryptor->uid){ + CryptoEngine = Modules[i]->cryptor; + Found = 1; + break; + } + } + if (!Found){ + MessageBoxA(0, "Sorry, but your database encrypted with unknown module", "Error", MB_OK); + bCheckingPass = 0; + return 0; + } + } + + while(1){ + res = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_LOGIN), NULL, (DLGPROC)DlgStdInProc, (LPARAM)szDBName); + if(res == IDCANCEL) + { + wrongPass = 0; + bCheckingPass = 0; + return 0; + } + if(encryptKeyLength < 1) continue; + EncoderInit(); + DecodeCopyMemory(&ver, &checkWord, sizeof(checkWord)); + if(ver == 0x5195) + { + wrongPass = 0; + bCheckingPass = 0; + return 1; + } + wrongPass++; + } + + bCheckingPass = 0; +} + +int SelectEncoder() +{ + WORD uid; + int i; + + if(ModulesCount == 0){ + MessageBox(0, TranslateT("Crypto modules not found"), TranslateT("Error"), MB_OK); + return 1; + } + + uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + if(uid == 0){ + MessageBox(0, TranslateT("Crypto module hasn't been chosen, using first one found"), TranslateT("Notice"), MB_OK); + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[0]->cryptor->uid); + CryptoEngine = Modules[0]->cryptor; + } + else{ + int Found = 0; + for(i = 0; i < ModulesCount; i++) { + if(Modules[i]->cryptor->uid == uid){ + CryptoEngine = Modules[i]->cryptor; + Found = 1; + break; + } + } + if (!Found){ + MessageBox(0, TranslateT("Crypto module hasn't been chosen, using first one found"), TranslateT("Notice"), MB_OK); + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", Modules[0]->cryptor->uid); + CryptoEngine = Modules[0]->cryptor; + } + } + + return 0; +} + +void EncodeAll() +{ + HANDLE hContact; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + if(hContact){ + do{ + EncodeContactEvents(hContact); + EncodeContactSettings(hContact); + }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); + } + + EncodeContactEvents(NULL); + EncodeContactSettings(NULL); +} + +void DecodeAll() +{ + HANDLE hContact; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + if(hContact){ + do{ + DecodeContactEvents(hContact); + DecodeContactSettings(hContact); + }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); + } + DecodeContactEvents(NULL); + DecodeContactSettings(NULL); +} + +void WritePlainHeader() +{ + DWORD bytesWritten; + + memcpy(dbHeader.signature, &dbSignature, sizeof(dbHeader.signature)); + SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); + WriteFile(hDbFile,dbHeader.signature,sizeof(dbHeader.signature),&bytesWritten,NULL); + { + WORD checkWord; + checkWord = 0x0700; + memcpy(&dbHeader.checkWord, &checkWord, sizeof(checkWord)); + WriteFile(hDbFile,&dbHeader.checkWord,sizeof(dbHeader.checkWord),&bytesWritten,NULL); + + dbHeader.cryptorUID = 0x0000; //no encryption + WriteFile(hDbFile,&dbHeader.cryptorUID,sizeof(dbHeader.cryptorUID),&bytesWritten,NULL); + } +} + +void WriteCryptHeader() +{ + DWORD bytesWritten; + + memcpy(dbHeader.signature, &dbSignatureSecured, sizeof(dbHeader.signature)); + SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); + WriteFile(hDbFile,dbHeader.signature,sizeof(dbHeader.signature),&bytesWritten,NULL); + { + WORD checkWord; + checkWord = 0x5195; + EncodeCopyMemory(&dbHeader.checkWord, &checkWord, sizeof(checkWord)); + WriteFile(hDbFile,&dbHeader.checkWord,sizeof(dbHeader.checkWord),&bytesWritten,NULL); + + dbHeader.cryptorUID = CryptoEngine->uid; + WriteFile(hDbFile,&dbHeader.cryptorUID,sizeof(dbHeader.cryptorUID),&bytesWritten,NULL); + } +} + +void EncryptDB() +{ + int action = 0; + if(bEncProcess) return; + + if(memcmp(dbHeader.signature, &dbSignatureSecured, sizeof(dbHeader.signature)) == 0){ + MessageBox(0, TranslateT("DB is already secured!"), TranslateT("Error"), MB_OK); + return; + } + + if(SelectEncoder()) { + return; + } + + bEncProcess = 1; + + action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_NEWPASS), NULL, (DLGPROC)DlgStdNewPass, (LPARAM)NULL); + if(action != IDOK || !strlen(encryptKey)) { + bEncProcess = 0; + DBWriteContactSettingByte(NULL, "SecureMMAP", "CryptoModule", 0); + return; + } + + EnterCriticalSection(&csDbAccess); + + bEncoding = 1; + EncoderInit(); + + EncodeAll(); + + LeaveCriticalSection(&csDbAccess); + + WriteCryptHeader(); + + xModifyMenu(hSetPwdMenu, 0, LPGENT("Change Password"), 0); + + bEncProcess = 0; +} + +void DecryptDB() +{ + char oldKey[255]; + strcpy(oldKey, encryptKey); + + if (!CheckPassword(dbHeader.checkWord, Translate("current database"))){strcpy(encryptKey, oldKey); encryptKeyLength = strlen(oldKey); return;} + + WritePlainHeader(); + + EnterCriticalSection(&csDbAccess); + DecodeAll(); + LeaveCriticalSection(&csDbAccess); + + bEncoding = 0; + + zero_fill(encryptKey, sizeof encryptKey); + + xModifyMenu(hSetPwdMenu, 0, LPGENT("Set Password"), 0); + + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + CryptoEngine->FreeKey(key); + + CryptoEngine = NULL; +} + +void RecryptDB() +{ + EnterCriticalSection(&csDbAccess); + + DecodeAll(); + + CryptoEngine->FreeKey(key); + + SelectEncoder(); + + bEncoding = 1; + + EncoderInit(); + + EncodeAll(); + + WriteCryptHeader(); + + LeaveCriticalSection(&csDbAccess); +} + +void ChangePwd() +{ + char newpass[255] = {0}; + + int action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHANGEPASS), NULL, (DLGPROC)DlgChangePass, (LPARAM)newpass); + + if(action == IDCANCEL || (action == IDOK && !strlen(newpass))) + return; + + EnterCriticalSection(&csDbAccess); + + DecodeAll(); + + CryptoEngine->FreeKey(key); + + if(action == IDREMOVE){ + WritePlainHeader(); + + bEncoding = 0; + CryptoEngine = NULL; + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + zero_fill(encryptKey, sizeof encryptKey); + + xModifyMenu(hSetPwdMenu, 0, LPGENT("Set Password"), 0); + } + + if(action == IDOK){ + strcpy(encryptKey, newpass); + encryptKeyLength = strlen(newpass); + + bEncoding = 1; + + EncoderInit(); + + EncodeAll(); + + WriteCryptHeader(); + } + + zero_fill(newpass, sizeof newpass); + + LeaveCriticalSection(&csDbAccess); +} \ No newline at end of file -- cgit v1.2.3