From 9126d2b133d00b836fca640f847a0948f7579e02 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 23 Jul 2012 06:41:38 +0000 Subject: Db3x_mmap,Db_autobackups: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1107 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Db3x_mmap/commonheaders.h | 61 -- plugins/Db3x_mmap/database.cpp | 121 --- plugins/Db3x_mmap/database.h | 70 -- plugins/Db3x_mmap/db3x_mmap-translation.txt | 35 - plugins/Db3x_mmap/db3x_mmap.rc | 174 ---- plugins/Db3x_mmap/db3x_mmap_10.vcxproj | 32 +- plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters | 28 +- plugins/Db3x_mmap/dbcache.cpp | 175 ---- plugins/Db3x_mmap/dbcontacts.cpp | 244 ------ plugins/Db3x_mmap/dbevents.cpp | 355 -------- plugins/Db3x_mmap/dbheaders.cpp | 65 -- plugins/Db3x_mmap/dbintf.cpp | 174 ---- plugins/Db3x_mmap/dbintf.h | 289 ------- plugins/Db3x_mmap/dbmodulechain.cpp | 138 --- plugins/Db3x_mmap/dbsettings.cpp | 933 --------------------- plugins/Db3x_mmap/docs/db3x_mmap-translation.txt | 35 + plugins/Db3x_mmap/init.cpp | 160 ---- plugins/Db3x_mmap/res/db3x_mmap.rc | 174 ++++ plugins/Db3x_mmap/res/version.rc | 42 + plugins/Db3x_mmap/resource.h | 30 - plugins/Db3x_mmap/src/commonheaders.h | 62 ++ plugins/Db3x_mmap/src/database.cpp | 121 +++ plugins/Db3x_mmap/src/database.h | 70 ++ plugins/Db3x_mmap/src/dbcache.cpp | 175 ++++ plugins/Db3x_mmap/src/dbcontacts.cpp | 244 ++++++ plugins/Db3x_mmap/src/dbevents.cpp | 355 ++++++++ plugins/Db3x_mmap/src/dbheaders.cpp | 65 ++ plugins/Db3x_mmap/src/dbintf.cpp | 174 ++++ plugins/Db3x_mmap/src/dbintf.h | 289 +++++++ plugins/Db3x_mmap/src/dbmodulechain.cpp | 138 +++ plugins/Db3x_mmap/src/dbsettings.cpp | 933 +++++++++++++++++++++ plugins/Db3x_mmap/src/init.cpp | 160 ++++ plugins/Db3x_mmap/src/resource.h | 30 + plugins/Db3x_mmap/src/version.h | 5 + plugins/Db3x_mmap/version.h | 5 - plugins/Db3x_mmap/version.rc | 42 - plugins/Db_autobackups/backup.cpp | 230 ----- .../Db_autobackups/db_autobackups-translation.txt | 50 -- plugins/Db_autobackups/db_autobackups.rc | 182 ---- plugins/Db_autobackups/db_autobackups_10.vcxproj | 42 +- .../db_autobackups_10.vcxproj.filters | 23 +- .../docs/db_autobackups-translation.txt | 50 ++ plugins/Db_autobackups/headers.h | 50 -- plugins/Db_autobackups/icos/backup.ico | Bin 2550 -> 0 bytes plugins/Db_autobackups/main.cpp | 247 ------ plugins/Db_autobackups/options.cpp | 357 -------- plugins/Db_autobackups/options.h | 37 - plugins/Db_autobackups/res/backup.ico | Bin 0 -> 2550 bytes plugins/Db_autobackups/res/db_autobackups.rc | 182 ++++ plugins/Db_autobackups/res/version.rc | 42 + plugins/Db_autobackups/resource.h | 35 - plugins/Db_autobackups/src/backup.cpp | 230 +++++ plugins/Db_autobackups/src/headers.h | 50 ++ plugins/Db_autobackups/src/main.cpp | 247 ++++++ plugins/Db_autobackups/src/options.cpp | 357 ++++++++ plugins/Db_autobackups/src/options.h | 37 + plugins/Db_autobackups/src/resource.h | 35 + plugins/Db_autobackups/src/version.h | 8 + plugins/Db_autobackups/version.h | 8 - plugins/Db_autobackups/version.rc | 42 - 60 files changed, 4369 insertions(+), 4375 deletions(-) delete mode 100644 plugins/Db3x_mmap/commonheaders.h delete mode 100644 plugins/Db3x_mmap/database.cpp delete mode 100644 plugins/Db3x_mmap/database.h delete mode 100644 plugins/Db3x_mmap/db3x_mmap-translation.txt delete mode 100644 plugins/Db3x_mmap/db3x_mmap.rc delete mode 100644 plugins/Db3x_mmap/dbcache.cpp delete mode 100644 plugins/Db3x_mmap/dbcontacts.cpp delete mode 100644 plugins/Db3x_mmap/dbevents.cpp delete mode 100644 plugins/Db3x_mmap/dbheaders.cpp delete mode 100644 plugins/Db3x_mmap/dbintf.cpp delete mode 100644 plugins/Db3x_mmap/dbintf.h delete mode 100644 plugins/Db3x_mmap/dbmodulechain.cpp delete mode 100644 plugins/Db3x_mmap/dbsettings.cpp create mode 100644 plugins/Db3x_mmap/docs/db3x_mmap-translation.txt delete mode 100644 plugins/Db3x_mmap/init.cpp create mode 100644 plugins/Db3x_mmap/res/db3x_mmap.rc create mode 100644 plugins/Db3x_mmap/res/version.rc delete mode 100644 plugins/Db3x_mmap/resource.h create mode 100644 plugins/Db3x_mmap/src/commonheaders.h create mode 100644 plugins/Db3x_mmap/src/database.cpp create mode 100644 plugins/Db3x_mmap/src/database.h create mode 100644 plugins/Db3x_mmap/src/dbcache.cpp create mode 100644 plugins/Db3x_mmap/src/dbcontacts.cpp create mode 100644 plugins/Db3x_mmap/src/dbevents.cpp create mode 100644 plugins/Db3x_mmap/src/dbheaders.cpp create mode 100644 plugins/Db3x_mmap/src/dbintf.cpp create mode 100644 plugins/Db3x_mmap/src/dbintf.h create mode 100644 plugins/Db3x_mmap/src/dbmodulechain.cpp create mode 100644 plugins/Db3x_mmap/src/dbsettings.cpp create mode 100644 plugins/Db3x_mmap/src/init.cpp create mode 100644 plugins/Db3x_mmap/src/resource.h create mode 100644 plugins/Db3x_mmap/src/version.h delete mode 100644 plugins/Db3x_mmap/version.h delete mode 100644 plugins/Db3x_mmap/version.rc delete mode 100644 plugins/Db_autobackups/backup.cpp delete mode 100644 plugins/Db_autobackups/db_autobackups-translation.txt delete mode 100644 plugins/Db_autobackups/db_autobackups.rc create mode 100644 plugins/Db_autobackups/docs/db_autobackups-translation.txt delete mode 100644 plugins/Db_autobackups/headers.h delete mode 100644 plugins/Db_autobackups/icos/backup.ico delete mode 100644 plugins/Db_autobackups/main.cpp delete mode 100644 plugins/Db_autobackups/options.cpp delete mode 100644 plugins/Db_autobackups/options.h create mode 100644 plugins/Db_autobackups/res/backup.ico create mode 100644 plugins/Db_autobackups/res/db_autobackups.rc create mode 100644 plugins/Db_autobackups/res/version.rc delete mode 100644 plugins/Db_autobackups/resource.h create mode 100644 plugins/Db_autobackups/src/backup.cpp create mode 100644 plugins/Db_autobackups/src/headers.h create mode 100644 plugins/Db_autobackups/src/main.cpp create mode 100644 plugins/Db_autobackups/src/options.cpp create mode 100644 plugins/Db_autobackups/src/options.h create mode 100644 plugins/Db_autobackups/src/resource.h create mode 100644 plugins/Db_autobackups/src/version.h delete mode 100644 plugins/Db_autobackups/version.h delete mode 100644 plugins/Db_autobackups/version.rc diff --git a/plugins/Db3x_mmap/commonheaders.h b/plugins/Db3x_mmap/commonheaders.h deleted file mode 100644 index 4a31de1cc2..0000000000 --- a/plugins/Db3x_mmap/commonheaders.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define _WIN32_WINNT 0x0501 - -#include "m_stdhdr.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef __GNUC__ -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "database.h" -#include "dbintf.h" -#include "resource.h" -#include "version.h" - -extern LIST g_Dbs; - -#ifdef __GNUC__ -#define mir_i64(x) (x##LL) -#else -#define mir_i64(x) (x##i64) -#endif diff --git a/plugins/Db3x_mmap/database.cpp b/plugins/Db3x_mmap/database.cpp deleted file mode 100644 index 1962805a35..0000000000 --- a/plugins/Db3x_mmap/database.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -int InitModuleNames(void); -int InitCache(void); -int InitIni(void); -void UninitIni(void); - -DWORD CDdxMmap::CreateNewSpace(int bytes) -{ - DWORD ofsNew = m_dbHeader.ofsFileEnd; - m_dbHeader.ofsFileEnd += bytes; - DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); - log2("newspace %d@%08x", bytes, ofsNew); - return ofsNew; -} - -void CDdxMmap::DeleteSpace(DWORD ofs, int bytes) -{ - if (ofs+bytes == m_dbHeader.ofsFileEnd) { - log2("freespace %d@%08x",bytes,ofs); - m_dbHeader.ofsFileEnd = ofs; - } - else { - log2("deletespace %d@%08x",bytes,ofs); - m_dbHeader.slackSpace += bytes; - } - DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); - DBFill(ofs, bytes); -} - -DWORD CDdxMmap::ReallocSpace(DWORD ofs, int oldSize, int newSize) -{ - if (oldSize >= newSize) - return ofs; - - DWORD ofsNew; - if (ofs+oldSize == m_dbHeader.ofsFileEnd) { - ofsNew = ofs; - m_dbHeader.ofsFileEnd += newSize-oldSize; - DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); - log3("adding newspace %d@%08x+%d", newSize, ofsNew, oldSize); - } - else { - ofsNew = CreateNewSpace(newSize); - DBMoveChunk(ofsNew,ofs,oldSize); - DeleteSpace(ofs,oldSize); - } - return ofsNew; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -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://nightly.miranda.im/. Miranda will now shutdown."), - TranslateT("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); - TerminateProcess(GetCurrentProcess(),255); -} - -void CDdxMmap::DatabaseCorruption(TCHAR *text) -{ - int kill = 0; - - EnterCriticalSection(&m_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(&m_csDbAccess); - Sleep(INFINITE); - return; - } - LeaveCriticalSection(&m_csDbAccess); - if (kill) { - _beginthread(dbpanic,0,NULL); - Sleep(INFINITE); - } -} diff --git a/plugins/Db3x_mmap/database.h b/plugins/Db3x_mmap/database.h deleted file mode 100644 index 83c2fcaea9..0000000000 --- a/plugins/Db3x_mmap/database.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - - -//all offsets are relative to the start of the file -//offsets are 0 if there is nothing in the chain or this is the last in the -//chain - -/* tree diagram - -DBHeader - |-->end of file (plain offset) - |-->first contact (DBContact) - | |-->next contact (DBContact) - | | \--> ... - | |-->first settings (DBContactSettings) - | | |-->next settings (DBContactSettings) - | | | \--> ... - | | \-->module name (DBModuleName) - | \-->first/last/firstunread event - |-->user contact (DBContact) - | |-->next contact = NULL - | |-->first settings as above - | \-->first/last/firstunread event as above - \-->first module name (DBModuleName) - \-->next module name (DBModuleName) - \--> ... -*/ - -//#define DBLOGGING - -#ifdef _DEBUG -//#define DBLOGGING -#endif -#ifdef DBLOGGING -void DBLog(const char *file,int line,const char *fmt,...); -#define logg() DBLog(__FILE__,__LINE__,"") -#define log0(s) DBLog(__FILE__,__LINE__,s) -#define log1(s,a) DBLog(__FILE__,__LINE__,s,a) -#define log2(s,a,b) DBLog(__FILE__,__LINE__,s,a,b) -#define log3(s,a,b,c) DBLog(__FILE__,__LINE__,s,a,b,c) -#define log4(s,a,b,c,d) DBLog(__FILE__,__LINE__,s,a,b,c,d) -#else -#define logg() -#define log0(s) -#define log1(s,a) -#define log2(s,a,b) -#define log3(s,a,b,c) -#define log4(s,a,b,c,d) -#endif diff --git a/plugins/Db3x_mmap/db3x_mmap-translation.txt b/plugins/Db3x_mmap/db3x_mmap-translation.txt deleted file mode 100644 index cd23ce15ba..0000000000 --- a/plugins/Db3x_mmap/db3x_mmap-translation.txt +++ /dev/null @@ -1,35 +0,0 @@ -; Common strings that belong to many files -;[] - -; ../../plugins/Db3x_mmap/database.cpp -;[Database Error] -;[Database Panic] -;[Database failure. Miranda will now shutdown.] -;[Disk is full. Miranda will now shutdown.] -;[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.] - -; ../../plugins/Db3x_mmap/db3x_mmap.rc -;[&Allow all further changes to this section] -;[&Delete] -;[&Leave] -;[&Move/Rename] -;[&No] -;[&Recycle] -;[&View contents] -;[&Yes] -;[A file containing new database settings has been placed in the Miranda IM directory.] -;[Cancel Import] -;[Database Import Complete] -;[Database Setting Change] -;[Database settings are being imported from] -;[Do you want to allow this change?] -;[Do you want to import the settings now?] -;[Install Database Settings] -;[No] -;[No to all] -;[Security systems to prevent malicious changes are in place and you will be warned before changes that are not known to be safe.] -;[The import has completed from] -;[This file wishes to change the setting] -;[What do you want to do with the file now?] -;[Yes] -;[to the value] diff --git a/plugins/Db3x_mmap/db3x_mmap.rc b/plugins/Db3x_mmap/db3x_mmap.rc deleted file mode 100644 index 434e5437b5..0000000000 --- a/plugins/Db3x_mmap/db3x_mmap.rc +++ /dev/null @@ -1,174 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_INSTALLINI DIALOGEX 0, 0, 212, 102 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | - DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Install Database Settings" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "Yes",IDOK,26,83,50,14 - PUSHBUTTON "No",IDCANCEL,81,83,50,14 - LTEXT "A file containing new database settings has been placed in the Miranda IM directory.", - IDC_STATIC,5,5,202,16 - LTEXT "Do you want to import the settings now?",IDC_STATIC,5, - 69,202,8 - PUSHBUTTON "No to all",IDC_NOTOALL,136,83,50,14 - LTEXT "",IDC_ININAME,5,24,143,16,SS_NOPREFIX | SS_CENTERIMAGE - PUSHBUTTON "&View contents",IDC_VIEWINI,149,25,58,14 - LTEXT "Security systems to prevent malicious changes are in place and you will be warned before changes that are not known to be safe.", - IDC_SECURITYINFO,5,43,202,24 -END - -IDD_WARNINICHANGE DIALOGEX 0, 0, 187, 113 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | - DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Database Setting Change" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Database settings are being imported from",IDC_STATIC,5, - 5,177,8 - CONTROL "",IDC_ININAME,"Static",SS_SIMPLE | SS_NOPREFIX | - WS_GROUP,5,13,177,8 - LTEXT "This file wishes to change the setting",IDC_STATIC,5,24, - 177,8 - CONTROL "",IDC_SETTINGNAME,"Static",SS_SIMPLE | SS_NOPREFIX | - WS_GROUP,12,33,170,8 - LTEXT "to the value",IDC_STATIC,5,42,177,8 - CONTROL "",IDC_NEWVALUE,"Static",SS_SIMPLE | SS_NOPREFIX | - WS_GROUP,12,51,170,8 - LTEXT "",IDC_SECURITYINFO,5,60,177,8 - LTEXT "Do you want to allow this change?",IDC_STATIC,5,71,177, - 8 - CONTROL "&Allow all further changes to this section", - IDC_WARNNOMORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13, - 80,169,10 - DEFPUSHBUTTON "&Yes",IDYES,5,94,50,14 - PUSHBUTTON "&No",IDNO,59,94,50,14 - PUSHBUTTON "Cancel Import",IDCANCEL,123,94,59,14 -END - -IDD_INIIMPORTDONE DIALOGEX 0, 0, 186, 73 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | - DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Database Import Complete" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "The import has completed from",IDC_STATIC,5,5,176,8 - CONTROL "",IDC_ININAME,"Static",SS_SIMPLE | SS_NOPREFIX | - WS_GROUP,5,13,176,8 - LTEXT "What do you want to do with the file now?",IDC_STATIC,5, - 24,176,8 - PUSHBUTTON "&Recycle",IDC_RECYCLE,5,36,50,14 - PUSHBUTTON "&Delete",IDC_DELETE,68,36,50,14 - EDITTEXT IDC_NEWNAME,5,55,117,12,ES_AUTOHSCROLL - PUSHBUTTON "&Move/Rename",IDC_MOVE,124,54,57,14 - PUSHBUTTON "&Leave",IDC_LEAVE,131,36,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_INSTALLINI, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 207 - TOPMARGIN, 5 - BOTTOMMARGIN, 97 - END - - IDD_WARNINICHANGE, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 182 - TOPMARGIN, 5 - BOTTOMMARGIN, 108 - END - - IDD_INIIMPORTDONE, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 181 - TOPMARGIN, 5 - BOTTOMMARGIN, 68 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include \0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj index 22cbaeca69..5e19ec66f3 100644 --- a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj +++ b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj @@ -82,7 +82,6 @@ commonheaders.h Level3 EditAndContinue - 4996;%(DisableSpecificWarnings) false @@ -114,7 +113,6 @@ Use commonheaders.h Level3 - 4996;%(DisableSpecificWarnings) _DEBUG;%(PreprocessorDefinitions) @@ -147,7 +145,6 @@ Use commonheaders.h Level3 - 4996;%(DisableSpecificWarnings) NDEBUG;%(PreprocessorDefinitions) @@ -182,7 +179,6 @@ Use commonheaders.h Level3 - 4996;%(DisableSpecificWarnings) NDEBUG;%(PreprocessorDefinitions) @@ -203,26 +199,26 @@ - - - - - - - - - + + + + + + + + + Create - - - + + + - - + + diff --git a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters index 2f8143f35e..a087e1d883 100644 --- a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters +++ b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters @@ -15,50 +15,50 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Header Files - + Header Files - + Header Files - + Resource Files - + Resource Files diff --git a/plugins/Db3x_mmap/dbcache.cpp b/plugins/Db3x_mmap/dbcache.cpp deleted file mode 100644 index 466aa7a00d..0000000000 --- a/plugins/Db3x_mmap/dbcache.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -void CDdxMmap::Map() -{ - m_hMap = CreateFileMapping(m_hDbFile, NULL, PAGE_READWRITE, 0, m_dwFileSize, NULL); - - if (m_hMap) - { - m_pDbCache = (PBYTE)MapViewOfFile(m_hMap, FILE_MAP_ALL_ACCESS/*FILE_MAP_WRITE*/, 0, 0 ,0); - if (!m_pDbCache) - DatabaseCorruption( _T("%s (MapViewOfFile failed. Code: %d)")); - } - else - DatabaseCorruption( _T("%s (CreateFileMapping failed. Code: %d)")); -} - -void CDdxMmap::ReMap(DWORD needed) -{ - KillTimer(NULL,m_flushBuffersTimerId); - - log3("remapping %d + %d (file end: %d)",m_dwFileSize,needed,m_dbHeader.ofsFileEnd); - - if (needed > m_ChunkSize) - { - if (needed + m_dwFileSize > m_dbHeader.ofsFileEnd + m_ChunkSize) - DatabaseCorruption( _T("%s (Too large increment)")); - else - { - DWORD x = m_dbHeader.ofsFileEnd/m_ChunkSize; - m_dwFileSize = (x+1)*m_ChunkSize; - } - } - else - m_dwFileSize += m_ChunkSize; - -// FlushViewOfFile(m_pDbCache, 0); - UnmapViewOfFile(m_pDbCache); - m_pDbCache = NULL; - CloseHandle(m_hMap); - - Map(); -} - -void CDdxMmap::DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) -{ - int x = 0; - log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); - if (ofsDest+bytes > m_dwFileSize) ReMap(ofsDest+bytes-m_dwFileSize); - if (ofsSource+bytes > m_dwFileSize) { - x = ofsSource+bytes-m_dwFileSize; - log0("buggy move!"); - _ASSERT(0); - } - if (x > 0) - ZeroMemory(m_pDbCache+ofsDest+bytes-x, x); - if (ofsSource < m_dwFileSize) - MoveMemory(m_pDbCache+ofsDest,m_pDbCache+ofsSource, bytes-x); - - logg(); -} - -//we are assumed to be in a mutex here -PBYTE CDdxMmap::DBRead(DWORD ofs,int bytesRequired,int *bytesAvail) -{ - // buggy read - if (ofs>= m_dwFileSize) { - log2("read from outside %d@%08x",bytesRequired,ofs); - if (bytesAvail != NULL) *bytesAvail = m_ChunkSize; - return m_pNull; - } - log3((ofs+bytesRequired > m_dwFileSize)?"read %d@%08x, only %d avaliable":"read %d@%08x",bytesRequired,ofs,m_dwFileSize-ofs); - if (bytesAvail != NULL) *bytesAvail = m_dwFileSize - ofs; - return m_pDbCache+ofs; -} - -//we are assumed to be in a mutex here -void CDdxMmap::DBWrite(DWORD ofs,PVOID pData,int bytes) -{ - log2("write %d@%08x",bytes,ofs); - if (ofs+bytes > m_dwFileSize) ReMap(ofs+bytes-m_dwFileSize); - MoveMemory(m_pDbCache+ofs,pData,bytes); - logg(); -} - -//we are assumed to be in a mutex here -void CDdxMmap::DBFill(DWORD ofs,int bytes) -{ - log2("zerofill %d@%08x",bytes,ofs); - if (ofs+bytes <= m_dwFileSize) - ZeroMemory(m_pDbCache+ofs,bytes); - logg(); -} - -static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) -{ - for (int i=0; i < g_Dbs.getCount(); i++) { - CDdxMmap* db = g_Dbs[i]; - if (db->m_flushBuffersTimerId != idEvent) - continue; - - if (!db->m_pDbCache) - return; - - KillTimer(NULL, db->m_flushBuffersTimerId); - log0("tflush1"); - if (FlushViewOfFile(db->m_pDbCache, 0) == 0) { - if (db->m_flushFailTick == 0) - db->m_flushFailTick = GetTickCount(); - else if (GetTickCount() - db->m_flushFailTick > 5000) - db->DatabaseCorruption(NULL); - } - else db->m_flushFailTick = 0; - log0("tflush2"); - } -} - -void CDdxMmap::DBFlush(int setting) -{ - if (!setting) { - log0("nflush1"); - if (m_safetyMode && m_pDbCache) { - if (FlushViewOfFile(m_pDbCache, 0) == 0) { - if (m_flushFailTick == 0) - m_flushFailTick = GetTickCount(); - else if (GetTickCount() - m_flushFailTick > 5000) - DatabaseCorruption(NULL); - } - else - m_flushFailTick = 0; - } - log0("nflush2"); - return; - } - KillTimer(NULL, m_flushBuffersTimerId); - m_flushBuffersTimerId = SetTimer(NULL, m_flushBuffersTimerId, 50, DoBufferFlushTimerProc); -} - -int CDdxMmap::InitCache(void) -{ - m_dwFileSize = GetFileSize(m_hDbFile, NULL); - - // Align to chunk - DWORD x = m_dwFileSize % m_ChunkSize; - if (x) - m_dwFileSize += m_ChunkSize - x; - - Map(); - - // zero region for reads outside the file - m_pNull = (PBYTE)calloc(m_ChunkSize, 1); - return 0; -} diff --git a/plugins/Db3x_mmap/dbcontacts.cpp b/plugins/Db3x_mmap/dbcontacts.cpp deleted file mode 100644 index b8d4a843b8..0000000000 --- a/plugins/Db3x_mmap/dbcontacts.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -DBCachedContactValueList* CDdxMmap::AddToCachedContactList(HANDLE hContact, int index) -{ - DBCachedContactValueList* VL = (DBCachedContactValueList*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); - VL->hContact = hContact; - if (index == -1) - m_lContacts.insert(VL); - else - m_lContacts.insert(VL,index); - return VL; -} - -#define proto_module "Protocol" -#define proto_setting "p" - -int CDdxMmap::CheckProto(HANDLE hContact, const char *proto) -{ - char protobuf[MAX_PATH] = {0}; - DBVARIANT dbv; - DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv}; - - dbv.type = DBVT_ASCIIZ; - dbv.pszVal = protobuf; - dbv.cchVal = sizeof(protobuf); - - if (GetContactSettingStatic(hContact, &sVal) != 0 || (dbv.type != DBVT_ASCIIZ)) - return 0; - - return !strcmp(protobuf,proto); -} - -STDMETHODIMP_(LONG) CDdxMmap::GetContactCount(void) -{ - mir_cslock lck(m_csDbAccess); - return m_dbHeader.contactCount; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstContact(const char *szProto) -{ - mir_cslock lck(m_csDbAccess); - HANDLE ret = (HANDLE)m_dbHeader.ofsFirstContact; - if (szProto && !CheckProto(ret, szProto)) - ret = FindNextContact(ret, szProto); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindNextContact(HANDLE hContact, const char *szProto) -{ - int index; - DBContact *dbc; - DBCachedContactValueList VLtemp, *VL = NULL; - VLtemp.hContact = hContact; - - mir_cslock lck(m_csDbAccess); - while (VLtemp.hContact) { - if (( index = m_lContacts.getIndex(&VLtemp)) != -1) { - VL = m_lContacts[index]; - if (VL->hNext != NULL) { - if (!szProto || CheckProto(VL->hNext, szProto)) - return VL->hNext; - - VLtemp.hContact = VL->hNext; - continue; - } } - - dbc = (DBContact*)DBRead(VLtemp.hContact,sizeof(DBContact),NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - break; - - if ( VL == NULL ) - VL = AddToCachedContactList(VLtemp.hContact,index); - - VL->hNext = (HANDLE)dbc->ofsNext; - if (VL->hNext != NULL && (!szProto || CheckProto(VL->hNext, szProto))) - return VL->hNext; - - VLtemp.hContact = VL->hNext; - } - - return NULL; -} - -STDMETHODIMP_(LONG) CDdxMmap::DeleteContact(HANDLE hContact) -{ - if (hContact == NULL) - return 1; - - mir_cslockfull lck(m_csDbAccess); - DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - return 1; - - if (hContact == (HANDLE)m_dbHeader.ofsUser) { - log0("FATAL: del of user chain attempted."); - return 1; - } - - lck.unlock(); - log0("del contact"); - - // call notifier while outside mutex - NotifyEventHooks(hContactDeletedEvent, (WPARAM)hContact, 0); - - // get back in - lck.lock(); - - DBCachedContactValueList VLtemp; - VLtemp.hContact = hContact; - int index; - if ((index = m_lContacts.getIndex(&VLtemp)) != -1) { - DBCachedContactValueList *VL = m_lContacts[index]; - DBCachedContactValue* V = VL->first; - while ( V != NULL ) { - DBCachedContactValue* V1 = V->next; - FreeCachedVariant(&V->value); - HeapFree( m_hCacheHeap, 0, V ); - V = V1; - } - HeapFree( m_hCacheHeap, 0, VL ); - - if (VLtemp.hContact == m_hLastCachedContact) - m_hLastCachedContact = NULL; - m_lContacts.remove(index); - } - - dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); - //delete settings chain - DWORD ofsThis = dbc->ofsFirstSettings; - DWORD ofsFirstEvent = dbc->ofsFirstEvent; - while (ofsThis) { - DBContactSettings *dbcs = (DBContactSettings*)DBRead(ofsThis,sizeof(DBContactSettings),NULL); - DWORD ofsNext = dbcs->ofsNext; - DeleteSpace(ofsThis,offsetof(DBContactSettings,blob)+dbcs->cbBlob); - ofsThis = ofsNext; - } - //delete event chain - ofsThis = ofsFirstEvent; - while (ofsThis) { - DBEvent *dbe = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); - DWORD ofsNext = dbe->ofsNext; - DeleteSpace(ofsThis,offsetof(DBEvent,blob)+dbe->cbBlob); - ofsThis = ofsNext; - } - //find previous contact in chain and change ofsNext - dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); - if (m_dbHeader.ofsFirstContact == (DWORD)hContact) { - m_dbHeader.ofsFirstContact = dbc->ofsNext; - DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); - } - else { - DWORD ofsNext = dbc->ofsNext; - ofsThis = m_dbHeader.ofsFirstContact; - DBContact *dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); - while (dbcPrev->ofsNext != (DWORD)hContact) { - if (dbcPrev->ofsNext == 0) DatabaseCorruption(NULL); - ofsThis = dbcPrev->ofsNext; - dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); - } - dbcPrev->ofsNext = ofsNext; - DBWrite(ofsThis,dbcPrev,sizeof(DBContact)); - - DBCachedContactValueList VLtemp; - VLtemp.hContact = (HANDLE)ofsThis; - if ((index = m_lContacts.getIndex(&VLtemp)) != -1) { - DBCachedContactValueList *VL = m_lContacts[index]; - VL->hNext = (HANDLE)ofsNext; - } - } - - //delete contact - DeleteSpace((DWORD)hContact, sizeof(DBContact)); - //decrement contact count - m_dbHeader.contactCount--; - DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); - DBFlush(0); - return 0; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::AddContact() -{ - DWORD ofsNew; - log0("add contact"); - { - mir_cslock lck(m_csDbAccess); - ofsNew = CreateNewSpace(sizeof(DBContact)); - - DBContact dbc = { 0 }; - dbc.signature = DBCONTACT_SIGNATURE; - dbc.ofsNext = m_dbHeader.ofsFirstContact; - m_dbHeader.ofsFirstContact = ofsNew; - m_dbHeader.contactCount++; - DBWrite(ofsNew,&dbc,sizeof(DBContact)); - DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); - DBFlush(0); - - AddToCachedContactList((HANDLE)ofsNew, -1); - } - - NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); - return (HANDLE)ofsNew; -} - -STDMETHODIMP_(BOOL) CDdxMmap::IsDbContact(HANDLE hContact) -{ - mir_cslock lck(m_csDbAccess); - - DBCachedContactValueList VLtemp; - VLtemp.hContact = hContact; - int index = m_lContacts.getIndex(&VLtemp); - if (index != -1) - return TRUE; - - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature == DBCONTACT_SIGNATURE) { - AddToCachedContactList(hContact, index); - return TRUE; - } - - return FALSE; -} diff --git a/plugins/Db3x_mmap/dbevents.cpp b/plugins/Db3x_mmap/dbevents.cpp deleted file mode 100644 index 917d1680b2..0000000000 --- a/plugins/Db3x_mmap/dbevents.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -extern BOOL m_safetyMode; - -DWORD GetModuleNameOfs(const char *szName); -char *GetModuleNameByOfs(DWORD ofs); - -static HANDLE hEventDeletedEvent,hEventAddedEvent,hEventFilterAddedEvent; - -STDMETHODIMP_(LONG) CDdxMmap::GetEventCount(HANDLE hContact) -{ - mir_cslock lck(m_csDbAccess); - if (hContact == 0) - hContact = (HANDLE)m_dbHeader.ofsUser; - - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - return (dbc->signature != DBCONTACT_SIGNATURE) ? -1 : dbc->eventCount; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::AddEvent(HANDLE hContact, DBEVENTINFO *dbei) -{ - if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0; - if (dbei->timestamp == 0) return 0; - if (NotifyEventHooks(hEventFilterAddedEvent, (WPARAM)hContact, (LPARAM)dbei)) - return 0; - - BOOL neednotify; - mir_cslockfull lck(m_csDbAccess); - - DWORD ofsContact = (hContact == 0) ? m_dbHeader.ofsUser : (DWORD)hContact; - DBContact dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc.signature != DBCONTACT_SIGNATURE) - return 0; - - DWORD ofsNew = CreateNewSpace(offsetof(DBEvent,blob) + dbei->cbBlob); - DWORD ofsModuleName = GetModuleNameOfs(dbei->szModule); - - DBEvent dbe; - dbe.signature = DBEVENT_SIGNATURE; - dbe.ofsModuleName = ofsModuleName; - dbe.timestamp = dbei->timestamp; - dbe.flags = dbei->flags; - dbe.eventType = dbei->eventType; - dbe.cbBlob = dbei->cbBlob; - //find where to put it - sort by timestamp - if (dbc.eventCount == 0) { - dbe.ofsPrev = (DWORD)hContact; - dbe.ofsNext = 0; - dbe.flags |= DBEF_FIRST; - dbc.ofsFirstEvent = dbc.ofsLastEvent = ofsNew; - } - else { - DBEvent *dbeTest = (DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(DBEvent),NULL); - // Should new event be placed before first event in chain? - if (dbei->timestamp < dbeTest->timestamp) { - dbe.ofsPrev = (DWORD)hContact; - dbe.ofsNext = dbc.ofsFirstEvent; - dbe.flags |= DBEF_FIRST; - dbc.ofsFirstEvent = ofsNew; - dbeTest = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); - dbeTest->flags &= ~DBEF_FIRST; - dbeTest->ofsPrev = ofsNew; - DBWrite(dbe.ofsNext,dbeTest,sizeof(DBEvent)); - } - else { - // Loop through the chain, starting at the end - DWORD ofsThis = dbc.ofsLastEvent; - dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); - for (;;) { - // If the new event's timesstamp is equal to or greater than the - // current dbevent, it will be inserted after. If not, continue - // with the previous dbevent in chain. - if (dbe.timestamp >= dbeTest->timestamp) { - dbe.ofsPrev = ofsThis; - dbe.ofsNext = dbeTest->ofsNext; - dbeTest->ofsNext = ofsNew; - DBWrite(ofsThis, dbeTest, sizeof(DBEvent)); - if (dbe.ofsNext == 0) - dbc.ofsLastEvent = ofsNew; - else { - dbeTest = (DBEvent*)DBRead(dbe.ofsNext, sizeof(DBEvent), NULL); - dbeTest->ofsPrev = ofsNew; - DBWrite(dbe.ofsNext, dbeTest, sizeof(DBEvent)); - } - break; - } - ofsThis = dbeTest->ofsPrev; - dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); - } - } - } - dbc.eventCount++; - - if (!(dbe.flags&(DBEF_READ|DBEF_SENT))) { - if (dbe.timestamppBlob,dbei->cbBlob); - DBFlush(0); - lck.unlock(); - - log1("add event @ %08x",ofsNew); - - // Notify only in safe mode or on really new events - if (neednotify) - NotifyEventHooks(hEventAddedEvent, (WPARAM)hContact, (LPARAM)ofsNew); - - return (HANDLE)ofsNew; -} - -STDMETHODIMP_(BOOL) CDdxMmap::DeleteEvent(HANDLE hContact, HANDLE hDbEvent) -{ - mir_cslockfull lck(m_csDbAccess); - - DWORD ofsContact = (hContact == 0) ? m_dbHeader.ofsUser : (DWORD)hContact; - DBContact dbc = *(DBContact*)DBRead(ofsContact, sizeof(DBContact), NULL); - DBEvent dbe = *(DBEvent*)DBRead(hDbEvent, sizeof(DBEvent), NULL); - if (dbc.signature != DBCONTACT_SIGNATURE || dbe.signature != DBEVENT_SIGNATURE) - return 1; - - lck.unlock(); - log1("delete event @ %08x",wParam); - - //call notifier while outside mutex - NotifyEventHooks(hEventDeletedEvent,(WPARAM)hContact, (LPARAM)hDbEvent); - - //get back in - lck.lock(); - dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - dbe = *(DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - - //check if this was the first unread, if so, recalc the first unread - if (dbc.ofsFirstUnreadEvent == (DWORD)hDbEvent) { - DBEvent *dbeNext = &dbe; - for (;;) { - if (dbeNext->ofsNext == 0) { - dbc.ofsFirstUnreadEvent = 0; - dbc.timestampFirstUnread = 0; - break; - } - DWORD ofsThis = dbeNext->ofsNext; - dbeNext = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); - if ( !(dbeNext->flags & (DBEF_READ | DBEF_SENT))) { - dbc.ofsFirstUnreadEvent = ofsThis; - dbc.timestampFirstUnread = dbeNext->timestamp; - break; - } - } - } - - //get previous and next events in chain and change offsets - if (dbe.flags&DBEF_FIRST) { - if (dbe.ofsNext == 0) - dbc.ofsFirstEvent = dbc.ofsLastEvent = 0; - else { - DBEvent *dbeNext = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); - dbeNext->flags |= DBEF_FIRST; - dbeNext->ofsPrev = dbe.ofsPrev; - DBWrite(dbe.ofsNext,dbeNext,sizeof(DBEvent)); - dbc.ofsFirstEvent = dbe.ofsNext; - } - } - else { - if (dbe.ofsNext == 0) { - DBEvent *dbePrev = (DBEvent*)DBRead(dbe.ofsPrev,sizeof(DBEvent),NULL); - dbePrev->ofsNext = 0; - DBWrite(dbe.ofsPrev,dbePrev,sizeof(DBEvent)); - dbc.ofsLastEvent = dbe.ofsPrev; - } - else { - DBEvent *dbePrev = (DBEvent*)DBRead(dbe.ofsPrev,sizeof(DBEvent),NULL); - dbePrev->ofsNext = dbe.ofsNext; - DBWrite(dbe.ofsPrev,dbePrev,sizeof(DBEvent)); - - DBEvent *dbeNext = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); - dbeNext->ofsPrev = dbe.ofsPrev; - DBWrite(dbe.ofsNext,dbeNext,sizeof(DBEvent)); - } - } - //delete event - DeleteSpace((DWORD)hDbEvent, offsetof(DBEvent,blob)+dbe.cbBlob); - //decrement event count - dbc.eventCount--; - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - DBFlush(0); - return 0; -} - -STDMETHODIMP_(LONG) CDdxMmap::GetBlobSize(HANDLE hDbEvent) -{ - mir_cslock lck(m_csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent, sizeof(DBEvent), NULL); - return (dbe->signature != DBEVENT_SIGNATURE) ? -1 : dbe->cbBlob; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbei) -{ - if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 1; - if (dbei->cbBlob > 0 && dbei->pBlob == NULL) { - dbei->cbBlob = 0; - return 1; - } - - mir_cslock lck(m_csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature != DBEVENT_SIGNATURE) - return 1; - - dbei->szModule = GetModuleNameByOfs(dbe->ofsModuleName); - dbei->timestamp = dbe->timestamp; - dbei->flags = dbe->flags; - dbei->eventType = dbe->eventType; - int bytesToCopy = (dbei->cbBlob < dbe->cbBlob) ? dbei->cbBlob : dbe->cbBlob; - dbei->cbBlob = dbe->cbBlob; - if (bytesToCopy && dbei->pBlob) { - for (int i = 0;;i += MAXCACHEDREADSIZE) { - if (bytesToCopy-i <= MAXCACHEDREADSIZE) { - DecodeCopyMemory(dbei->pBlob+i, DBRead(DWORD(hDbEvent)+offsetof(DBEvent,blob)+i,bytesToCopy-i,NULL), bytesToCopy-i); - break; - } - DecodeCopyMemory(dbei->pBlob+i, DBRead(DWORD(hDbEvent)+offsetof(DBEvent,blob)+i, MAXCACHEDREADSIZE, NULL), MAXCACHEDREADSIZE); - } - } - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::MarkEventRead(HANDLE hContact, HANDLE hDbEvent) -{ - DBEvent *dbe; - DBContact dbc; - DWORD ofsThis; - - mir_cslock lck(m_csDbAccess); - if (hContact == 0) - hContact = (HANDLE)m_dbHeader.ofsUser; - dbc = *(DBContact*)DBRead(hContact, sizeof(DBContact), NULL); - dbe = (DBEvent*)DBRead(hDbEvent, sizeof(DBEvent), NULL); - if (dbe->signature != DBEVENT_SIGNATURE || dbc.signature != DBCONTACT_SIGNATURE) - return -1; - - if ((dbe->flags & DBEF_READ) || (dbe->flags & DBEF_SENT)) - return (INT_PTR)dbe->flags; - - log1("mark read @ %08x",wParam); - dbe->flags |= DBEF_READ; - DBWrite((DWORD)hDbEvent,dbe,sizeof(DBEvent)); - BOOL ret = dbe->flags; - if (dbc.ofsFirstUnreadEvent == (DWORD)hDbEvent) { - for (;;) { - if (dbe->ofsNext == 0) { - dbc.ofsFirstUnreadEvent = 0; - dbc.timestampFirstUnread = 0; - break; - } - ofsThis = dbe->ofsNext; - dbe = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); - if ( !(dbe->flags & (DBEF_READ | DBEF_SENT))) { - dbc.ofsFirstUnreadEvent = ofsThis; - dbc.timestampFirstUnread = dbe->timestamp; - break; - } - } - } - DBWrite((DWORD)hContact, &dbc, sizeof(DBContact)); - DBFlush(0); - return ret; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::GetEventContact(HANDLE hDbEvent) -{ - mir_cslock lck(m_csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature != DBEVENT_SIGNATURE) - return (HANDLE)-1; - - while (!(dbe->flags & DBEF_FIRST)) - dbe = (DBEvent*)DBRead(dbe->ofsPrev,sizeof(DBEvent),NULL); - - return (HANDLE)dbe->ofsPrev; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstEvent(HANDLE hContact) -{ - mir_cslock lck(m_csDbAccess); - if (hContact == 0) - hContact = (HANDLE)m_dbHeader.ofsUser; - - DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); - return (dbc->signature != DBCONTACT_SIGNATURE) ? 0 : (HANDLE)dbc->ofsFirstEvent; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstUnreadEvent(HANDLE hContact) -{ - mir_cslock lck(m_csDbAccess); - if (hContact == 0) - hContact = (HANDLE)m_dbHeader.ofsUser; - - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - return (dbc->signature != DBCONTACT_SIGNATURE) ? 0 : (HANDLE)dbc->ofsFirstUnreadEvent; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindLastEvent(HANDLE hContact) -{ - mir_cslock lck(m_csDbAccess); - if (hContact == 0) - hContact = (HANDLE)m_dbHeader.ofsUser; - - DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - return (dbc->signature != DBCONTACT_SIGNATURE) ? 0 : (HANDLE)dbc->ofsLastEvent; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindNextEvent(HANDLE hDbEvent) -{ - mir_cslock lck(m_csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - return (dbe->signature != DBEVENT_SIGNATURE) ? 0 : (HANDLE)dbe->ofsNext; -} - -STDMETHODIMP_(HANDLE) CDdxMmap::FindPrevEvent(HANDLE hDbEvent) -{ - mir_cslock lck(m_csDbAccess); - DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); - if (dbe->signature != DBEVENT_SIGNATURE) return 0; - return (dbe->flags & DBEF_FIRST) ? 0 : (HANDLE)dbe->ofsPrev; -} diff --git a/plugins/Db3x_mmap/dbheaders.cpp b/plugins/Db3x_mmap/dbheaders.cpp deleted file mode 100644 index 3d18a373fa..0000000000 --- a/plugins/Db3x_mmap/dbheaders.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -//the cache has not been loaded when these functions are used - -extern DBSignature dbSignature; - -int CDdxMmap::CreateDbHeaders() -{ - DBContact user; - DWORD bytesWritten; - - CopyMemory(m_dbHeader.signature, &dbSignature,sizeof(m_dbHeader.signature)); - m_dbHeader.version = DB_THIS_VERSION; - m_dbHeader.ofsFileEnd = sizeof(struct DBHeader); - m_dbHeader.slackSpace = 0; - m_dbHeader.contactCount = 0; - m_dbHeader.ofsFirstContact = 0; - m_dbHeader.ofsFirstModuleName = 0; - m_dbHeader.ofsUser = 0; - //create user - m_dbHeader.ofsUser = m_dbHeader.ofsFileEnd; - m_dbHeader.ofsFileEnd += sizeof(DBContact); - SetFilePointer(m_hDbFile,0,NULL,FILE_BEGIN); - WriteFile(m_hDbFile,&m_dbHeader,sizeof(m_dbHeader),&bytesWritten,NULL); - user.signature = DBCONTACT_SIGNATURE; - user.ofsNext = 0; - user.ofsFirstSettings = 0; - user.eventCount = 0; - user.ofsFirstEvent = user.ofsLastEvent = 0; - SetFilePointer(m_hDbFile,m_dbHeader.ofsUser,NULL,FILE_BEGIN); - WriteFile(m_hDbFile,&user,sizeof(DBContact),&bytesWritten,NULL); - FlushFileBuffers(m_hDbFile); - return 0; -} - -int CDdxMmap::CheckDbHeaders() -{ - if (memcmp(m_dbHeader.signature, &dbSignature, sizeof(m_dbHeader.signature))) return 1; - if (m_dbHeader.version != DB_THIS_VERSION) return 2; - if (m_dbHeader.ofsUser == 0) return 3; - return 0; -} diff --git a/plugins/Db3x_mmap/dbintf.cpp b/plugins/Db3x_mmap/dbintf.cpp deleted file mode 100644 index 83ae3aa4ca..0000000000 --- a/plugins/Db3x_mmap/dbintf.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -DBSignature dbSignature = {"Miranda ICQ DB",0x1A}; - -static int stringCompare(const char* p1, const char* p2) -{ - return strcmp(p1+1, p2+1); -} - -static int stringCompare2(const char* p1, const char* p2) -{ - return strcmp(p1, p2); -} - -static int compareGlobals(const DBCachedGlobalValue* p1, const DBCachedGlobalValue* p2) -{ - return strcmp(p1->name, p2->name); -} - -static int ModCompare(const ModuleName *mn1, const ModuleName *mn2 ) -{ - return strcmp( mn1->name, mn2->name ); -} - -static int OfsCompare(const ModuleName *mn1, const ModuleName *mn2 ) -{ - return ( mn1->ofs - mn2->ofs ); -} - -CDdxMmap::CDdxMmap(const TCHAR* tszFileName) : - m_hDbFile(INVALID_HANDLE_VALUE), - m_safetyMode(TRUE), - m_lSettings(100, stringCompare), - m_lContacts(50, LIST::FTSortFunc(HandleKeySort)), - m_lGlobalSettings(50, compareGlobals), - m_lResidentSettings(50, stringCompare2), - m_lMods(50, ModCompare), - m_lOfs(50, OfsCompare) -{ - m_tszProfileName = mir_tstrdup(tszFileName); - - InitializeCriticalSection(&m_csDbAccess); - - SYSTEM_INFO sinf; - GetSystemInfo(&sinf); - m_ChunkSize = sinf.dwAllocationGranularity; - - m_codePage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0); - m_hCacheHeap = HeapCreate(0, 0, 0); - m_hModHeap = HeapCreate(0,0,0); -} - -CDdxMmap::~CDdxMmap() -{ - // destroy settings - HeapDestroy(m_hCacheHeap); - m_lContacts.destroy(); - m_lSettings.destroy(); - m_lGlobalSettings.destroy(); - m_lResidentSettings.destroy(); - - // destroy modules - HeapDestroy(m_hModHeap); - m_lMods.destroy(); - m_lOfs.destroy(); - - // destroy map - KillTimer(NULL,m_flushBuffersTimerId); - if (m_pDbCache) { - FlushViewOfFile(m_pDbCache, 0); - UnmapViewOfFile(m_pDbCache); - } - if (m_hMap) - CloseHandle(m_hMap); - if (m_pNull) - free(m_pNull); - - // update profile last modified time - DWORD bytesWritten; - SetFilePointer(m_hDbFile, 0, NULL, FILE_BEGIN); - WriteFile(m_hDbFile, &dbSignature, 1, &bytesWritten, NULL); - CloseHandle(m_hDbFile); - - DeleteCriticalSection(&m_csDbAccess); - - mir_free(m_tszProfileName); -} - -int CDdxMmap::Load(bool bSkipInit) -{ - log0("DB logging running"); - - DWORD dummy = 0; - m_hDbFile = CreateFile(m_tszProfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); - if ( m_hDbFile == INVALID_HANDLE_VALUE ) - return 1; - - if ( !ReadFile(m_hDbFile,&m_dbHeader,sizeof(m_dbHeader),&dummy,NULL)) { - CloseHandle(m_hDbFile); - return 1; - } - - if ( !bSkipInit) { - if (InitCache()) return 1; - if (InitModuleNames()) return 1; - - hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED); - hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED); - hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); - - hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED); - hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED); - hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); - } - return 0; -} - -int CDdxMmap::Create() -{ - m_hDbFile = CreateFile(m_tszProfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); - return ( m_hDbFile == INVALID_HANDLE_VALUE ); -} - -STDMETHODIMP_(void) CDdxMmap::SetCacheSafetyMode(BOOL bIsSet) -{ - { mir_cslock lck(m_csDbAccess); - m_safetyMode = bIsSet; - } - DBFlush(1); -} - -void CDdxMmap::EncodeCopyMemory(void *dst, void *src, size_t size) -{ - MoveMemory(dst, src, size); -} - -void CDdxMmap::DecodeCopyMemory(void *dst, void *src, size_t size) -{ - MoveMemory(dst, src, size); -} - -void CDdxMmap::EncodeDBWrite(DWORD ofs, void *src, int size) -{ - DBWrite(ofs, src, size); -} - -void CDdxMmap::DecodeDBWrite(DWORD ofs, void *src, int size) -{ - DBWrite(ofs, src, size); -} - diff --git a/plugins/Db3x_mmap/dbintf.h b/plugins/Db3x_mmap/dbintf.h deleted file mode 100644 index 4dff427516..0000000000 --- a/plugins/Db3x_mmap/dbintf.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include - -/* tree diagram - -DBHeader - |-->end of file (plain offset) - |-->first contact (DBContact) - | |-->next contact (DBContact) - | | \--> ... - | |-->first settings (DBContactSettings) - | | |-->next settings (DBContactSettings) - | | | \--> ... - | | \-->module name (DBModuleName) - | \-->first/last/firstunread event - |-->user contact (DBContact) - | |-->next contact = NULL - | |-->first settings as above - | \-->first/last/firstunread event as above - \-->first module name (DBModuleName) - \-->next module name (DBModuleName) - \--> ... -*/ - -#define DB_THIS_VERSION 0x00000700u -#define DB_SETTINGS_RESIZE_GRANULARITY 128 - -struct DBSignature { - char name[15]; - BYTE eof; -}; - -struct ModuleName -{ - char *name; - DWORD ofs; -}; - -#include -struct DBHeader { - BYTE signature[16]; // 'Miranda ICQ DB',0,26 - DWORD version; //as 4 bytes, ie 1.2.3.10 = 0x0102030a - //this version is 0x00000700 - DWORD ofsFileEnd; //offset of the end of the database - place to write - //new structures - DWORD slackSpace; //a counter of the number of bytes that have been - //wasted so far due to deleting structures and/or - //re-making them at the end. We should compact when - //this gets above a threshold - DWORD contactCount; //number of contacts in the chain,excluding the user - DWORD ofsFirstContact; //offset to first DBContact in the chain - DWORD ofsUser; //offset to DBContact representing the user - DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain -}; - -#define DBCONTACT_SIGNATURE 0x43DECADEu - -struct DBContact -{ - DWORD signature; - DWORD ofsNext; //offset to the next contact in the chain. zero if - //this is the 'user' contact or the last contact - //in the chain - DWORD ofsFirstSettings; //offset to the first DBContactSettings in the - //chain for this contact. - DWORD eventCount; //number of events in the chain for this contact - DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in - //the chain for this contact - DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event - //in the chain, 0 if all are read - DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent -}; - -#define DBMODULENAME_SIGNATURE 0x4DDECADEu -struct DBModuleName -{ - DWORD signature; - DWORD ofsNext; //offset to the next module name in the chain - BYTE cbName; //number of characters in this module name - char name[1]; //name, no nul terminator -}; - -#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu -struct DBContactSettings -{ - DWORD signature; - DWORD ofsNext; //offset to the next contactsettings in the chain - DWORD ofsModuleName; //offset to the DBModuleName of the owner of these - //settings - DWORD cbBlob; //size of the blob in bytes. May be larger than the - //actual size for reducing the number of moves - //required using granularity in resizing - BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting - //structs, the last has cbName = 0 -}; - -#define DBEVENT_SIGNATURE 0x45DECADEu -struct DBEvent -{ - DWORD signature; - DWORD ofsPrev,ofsNext; //offset to the previous and next events in the - //chain. Chain is sorted chronologically - DWORD ofsModuleName; //offset to a DBModuleName struct of the name of - //the owner of this event - DWORD timestamp; //seconds since 00:00:00 01/01/1970 - DWORD flags; //see m_database.h, db/event/add - WORD eventType; //module-defined event type - DWORD cbBlob; //number of bytes in the blob - BYTE blob[1]; //the blob. module-defined formatting -}; - -#include - -struct DBCachedGlobalValue -{ - char* name; - DBVARIANT value; -}; - -struct DBCachedContactValue -{ - char* name; - DBVARIANT value; - DBCachedContactValue* next; -}; - -struct DBCachedContactValueList -{ - HANDLE hContact; - HANDLE hNext; - DBCachedContactValue* first; - DBCachedContactValue* last; -}; - -#define MAXCACHEDREADSIZE 65536 - -struct CDdxMmap : public MIDatabase, public MZeroedObject -{ - CDdxMmap(const TCHAR* tszFileName); - ~CDdxMmap(); - - int Load(bool bSkipInit); - int Create(void); - int CreateDbHeaders(); - int CheckDbHeaders(); - void DatabaseCorruption(TCHAR *text); -protected: - STDMETHODIMP_(void) SetCacheSafetyMode(BOOL); - - STDMETHODIMP_(LONG) GetContactCount(void); - STDMETHODIMP_(HANDLE) FindFirstContact(const char* szProto = NULL); - STDMETHODIMP_(HANDLE) FindNextContact(HANDLE hContact, const char* szProto = NULL); - STDMETHODIMP_(LONG) DeleteContact(HANDLE hContact); - STDMETHODIMP_(HANDLE) AddContact(void); - STDMETHODIMP_(BOOL) IsDbContact(HANDLE hContact); - - STDMETHODIMP_(LONG) GetEventCount(HANDLE hContact); - STDMETHODIMP_(HANDLE) AddEvent(HANDLE hContact, DBEVENTINFO *dbe); - STDMETHODIMP_(BOOL) DeleteEvent(HANDLE hContact, HANDLE hDbEvent); - STDMETHODIMP_(LONG) GetBlobSize(HANDLE hDbEvent); - STDMETHODIMP_(BOOL) GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbe); - STDMETHODIMP_(BOOL) MarkEventRead(HANDLE hContact, HANDLE hDbEvent); - STDMETHODIMP_(HANDLE) GetEventContact(HANDLE hDbEvent); - STDMETHODIMP_(HANDLE) FindFirstEvent(HANDLE hContact); - STDMETHODIMP_(HANDLE) FindFirstUnreadEvent(HANDLE hContact); - STDMETHODIMP_(HANDLE) FindLastEvent(HANDLE hContact); - STDMETHODIMP_(HANDLE) FindNextEvent(HANDLE hDbEvent); - STDMETHODIMP_(HANDLE) FindPrevEvent(HANDLE hDbEvent); - - STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam); - - STDMETHODIMP_(BOOL) GetContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) GetContactSettingStr(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) GetContactSettingStatic(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv); - STDMETHODIMP_(BOOL) WriteContactSetting(HANDLE hContact, DBCONTACTWRITESETTING *dbcws); - STDMETHODIMP_(BOOL) DeleteContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); - STDMETHODIMP_(BOOL) EnumContactSettings(HANDLE hContact, DBCONTACTENUMSETTINGS* dbces); - STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName); - STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam); - -protected: - virtual void EncodeCopyMemory(void *dst, void *src, size_t size); - virtual void DecodeCopyMemory(void *dst, void *src, size_t size); - virtual void EncodeDBWrite(DWORD ofs, void *src, int size); - virtual void DecodeDBWrite(DWORD ofs, void *src, int size); - -protected: - TCHAR* m_tszProfileName; - HANDLE m_hDbFile; - DBHeader m_dbHeader; - DWORD m_ChunkSize; - BOOL m_safetyMode; - - //////////////////////////////////////////////////////////////////////////// - // database stuff -public: - UINT_PTR m_flushBuffersTimerId; - DWORD m_flushFailTick; - PBYTE m_pDbCache; -protected: - PBYTE m_pNull; - HANDLE m_hMap; - DWORD m_dwFileSize; - - CRITICAL_SECTION m_csDbAccess; - - int CheckProto(HANDLE hContact, const char *proto); - DWORD CreateNewSpace(int bytes); - void DeleteSpace(DWORD ofs, int bytes); - DWORD ReallocSpace(DWORD ofs, int oldSize, int newSize); - - void Map(); - void ReMap(DWORD needed); - void DBMoveChunk(DWORD ofsDest, DWORD ofsSource, int bytes); - PBYTE DBRead(DWORD ofs, int bytesRequired, int *bytesAvail); - void DBWrite(DWORD ofs, PVOID pData, int bytes); - void DBFill(DWORD ofs, int bytes); - void DBFlush(int setting); - int InitCache(void); - - __forceinline PBYTE DBRead(HANDLE hContact, int bytesRequired, int *bytesAvail) - { return DBRead((DWORD)hContact, bytesRequired, bytesAvail); - } - - //////////////////////////////////////////////////////////////////////////// - // settings - - int m_codePage; - - HANDLE m_hCacheHeap; - HANDLE m_hLastCachedContact; - char* m_lastSetting; - DBCachedContactValueList *m_lastVL; - - LIST m_lContacts; - LIST m_lGlobalSettings; - LIST m_lSettings, m_lResidentSettings; - HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent; - - DWORD GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsModuleName); - char* InsertCachedSetting(const char* szName, size_t cbNameLen); - char* GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen); - void SetCachedVariant(DBVARIANT* s, DBVARIANT* d); - void FreeCachedVariant(DBVARIANT* V); - DBVARIANT* GetCachedValuePtr(HANDLE hContact, char* szSetting, int bAllocate); - int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic); - - //////////////////////////////////////////////////////////////////////////// - // contacts - - DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index); - - //////////////////////////////////////////////////////////////////////////// - // modules - - HANDLE m_hModHeap; - LIST m_lMods, m_lOfs; - HANDLE hEventAddedEvent, hEventDeletedEvent, hEventFilterAddedEvent; - ModuleName *m_lastmn; - - void AddToList(char *name, DWORD len, DWORD ofs); - DWORD FindExistingModuleNameOfs(const char *szName); - int InitModuleNames(void); - DWORD GetModuleNameOfs(const char *szName); - char *GetModuleNameByOfs(DWORD ofs); -}; diff --git a/plugins/Db3x_mmap/dbmodulechain.cpp b/plugins/Db3x_mmap/dbmodulechain.cpp deleted file mode 100644 index f8b25ef879..0000000000 --- a/plugins/Db3x_mmap/dbmodulechain.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -void CDdxMmap::AddToList(char *name, DWORD len, DWORD ofs) -{ - ModuleName *mn = (ModuleName*)HeapAlloc(m_hModHeap,0,sizeof(ModuleName)); - mn->name = name; - mn->ofs = ofs; - - if (m_lMods.getIndex(mn) != -1) - DatabaseCorruption( _T("%s (Module Name not unique)")); - m_lMods.insert(mn); - - if (m_lOfs.getIndex(mn) != -1) - DatabaseCorruption( _T("%s (Module Offset not unique)")); - m_lOfs.insert(mn); -} - -int CDdxMmap::InitModuleNames(void) -{ - DWORD ofsThis = m_dbHeader.ofsFirstModuleName; - DBModuleName *dbmn = (struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); - while (ofsThis) { - if (dbmn->signature != DBMODULENAME_SIGNATURE) - DatabaseCorruption(NULL); - - int nameLen = dbmn->cbName; - - char *mod = (char*)HeapAlloc(m_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); - } - return 0; -} - -DWORD CDdxMmap::FindExistingModuleNameOfs(const char *szName) -{ - ModuleName mn = { (char*)szName, 0 }; - if (m_lastmn && !strcmp(mn.name, m_lastmn->name)) - return m_lastmn->ofs; - - int index = m_lMods.getIndex(&mn); - if (index != -1) { - ModuleName *pmn = m_lMods[index]; - m_lastmn = pmn; - return pmn->ofs; - } - - return 0; -} - -//will create the offset if it needs to -DWORD CDdxMmap::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 = m_dbHeader.ofsFirstModuleName; - m_dbHeader.ofsFirstModuleName = ofsNew; - DBWrite(0,&m_dbHeader,sizeof(m_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(m_hModHeap,0,nameLen+1); - strcpy(mod,szName); - AddToList(mod, nameLen, ofsNew); - - //quit - return ofsNew; -} - -char* CDdxMmap::GetModuleNameByOfs(DWORD ofs) -{ - if (m_lastmn && m_lastmn->ofs == ofs) - return m_lastmn->name; - - ModuleName mn = {NULL, ofs}; - int index = m_lOfs.getIndex(&mn); - if (index != -1) { - ModuleName *pmn = m_lOfs[index]; - m_lastmn = pmn; - return pmn->name; - } - - DatabaseCorruption(NULL); - return NULL; -} - -STDMETHODIMP_(BOOL) CDdxMmap::EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) -{ - for (int i = 0; i < m_lMods.getCount(); i++) { - ModuleName *pmn = m_lMods[i]; - int ret = pFunc(pmn->name, pmn->ofs, (LPARAM)pParam); - if (ret) - return ret; - } - return 0; -} diff --git a/plugins/Db3x_mmap/dbsettings.cpp b/plugins/Db3x_mmap/dbsettings.cpp deleted file mode 100644 index 49ac018047..0000000000 --- a/plugins/Db3x_mmap/dbsettings.cpp +++ /dev/null @@ -1,933 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -DWORD GetModuleNameOfs(const char *szName); -DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index); - -int DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); - -DWORD CDdxMmap::GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsModuleName) -{ - DWORD ofsThis = dbc->ofsFirstSettings; - while (ofsThis) { - DBContactSettings *dbcs = (DBContactSettings*)DBRead(ofsThis,sizeof(DBContactSettings),NULL); - if (dbcs->signature != DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption(NULL); - if (dbcs->ofsModuleName == ofsModuleName) - return ofsThis; - - ofsThis = dbcs->ofsNext; - } - return 0; -} - -DWORD __forceinline GetSettingValueLength(PBYTE pSetting) -{ - if (pSetting[0] & DBVTF_VARIABLELENGTH) - return 2+*(PWORD)(pSetting+1); - return pSetting[0]; -} - -char* CDdxMmap::InsertCachedSetting(const char* szName, size_t cbNameLen) -{ - char* newValue = (char*)HeapAlloc(m_hCacheHeap, 0, cbNameLen); - *newValue = 0; - strcpy(newValue+1, szName+1); - m_lSettings.insert(newValue); - return newValue; -} - -char* CDdxMmap::GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen) -{ - char szFullName[512]; - strcpy(szFullName+1,szModuleName); - szFullName[moduleNameLen+1] = '/'; - strcpy(szFullName+moduleNameLen+2,szSettingName); - - if (m_lastSetting && strcmp(szFullName+1, m_lastSetting) == 0) - return m_lastSetting; - - int index = m_lSettings.getIndex(szFullName); - if (index != -1) - m_lastSetting = m_lSettings[index]+1; - else - m_lastSetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+3)+1; - - return m_lastSetting; -} - -void CDdxMmap::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(m_hCacheHeap,0,szSave,strlen(s->pszVal)+1); - else - d->pszVal = (char*)HeapAlloc(m_hCacheHeap,0,strlen(s->pszVal)+1); - strcpy(d->pszVal,s->pszVal); - } - else if ( szSave != NULL ) - HeapFree(m_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 CDdxMmap::FreeCachedVariant( DBVARIANT* V ) -{ - if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL ) - HeapFree(m_hCacheHeap,0,V->pszVal); -} - -DBVARIANT* CDdxMmap::GetCachedValuePtr( HANDLE hContact, char* szSetting, int bAllocate ) -{ - if ( hContact == 0 ) { - DBCachedGlobalValue Vtemp, *V; - Vtemp.name = szSetting; - int index = m_lGlobalSettings.getIndex(&Vtemp); - if (index != -1) { - V = m_lGlobalSettings[index]; - if ( bAllocate == -1 ) { - FreeCachedVariant( &V->value ); - m_lGlobalSettings.remove(index); - HeapFree(m_hCacheHeap,0,V); - return NULL; - } - } - else { - if ( bAllocate != 1 ) - return NULL; - - V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue)); - V->name = szSetting; - m_lGlobalSettings.insert(V); - } - - return &V->value; - } - else { - DBCachedContactValue *V, *V1; - DBCachedContactValueList VLtemp,*VL; - - if (m_hLastCachedContact == hContact && m_lastVL) - VL = m_lastVL; - else { - VLtemp.hContact = hContact; - - int index = m_lContacts.getIndex(&VLtemp); - if (index == -1) { - if ( bAllocate != 1 ) - return NULL; - - VL = AddToCachedContactList(hContact, index); - } - else VL = m_lContacts[index]; - - m_lastVL = VL; - m_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 = (DBCachedContactValue *)HeapAlloc(m_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 ) { - m_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(m_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) - -int CDdxMmap::GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic) -{ - 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; - } - - mir_cslock lck(m_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; - } - - return ( pCachedValue->type == DBVT_DELETED ) ? 1 : 0; - } } - - ofsModuleName = GetModuleNameOfs(dbcgs->szModule); - if (hContact == NULL) ofsContact = m_dbHeader.ofsUser; - else ofsContact = (DWORD)hContact; - dbc = (DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - return 1; - - ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); - if (ofsSettingsGroup) { - ofsBlobPtr = ofsSettingsGroup+offsetof(DBContactSettings,blob); - pBlob = DBRead(ofsBlobPtr,sizeof(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])) - return 1; - - dbcgs->pValue->type = pBlob[0]; - switch(pBlob[0]) { - case DBVT_DELETED: /* this setting is deleted */ - dbcgs->pValue->type = DBVT_DELETED; - 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 = (BYTE *)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); - } - - logg(); - return 0; - } - NeedBytes(1); - MoveAlong(pBlob[0]+1); - NeedBytes(3); - MoveAlong(1+GetSettingValueLength(pBlob)); - NeedBytes(1); - } } - - #ifndef DB3X_EXPORTS - /**** 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; - } - #endif - - /**** add missing setting to cache **********************/ - if ( dbcgs->pValue->type != DBVT_BLOB ) - { - DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 ); - if ( pCachedValue != NULL ) - pCachedValue->type = DBVT_DELETED; - } - - logg(); - return 1; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dgs) -{ - dgs->pValue->type = 0; - if ( GetContactSettingWorker(hContact, dgs, 0 )) - return 1; - - if ( dgs->pValue->type == DBVT_UTF8 ) { - WCHAR* tmp = NULL; - char* p = NEWSTR_ALLOCA(dgs->pValue->pszVal); - if ( mir_utf8decode( p, &tmp ) != NULL ) { - BOOL bUsed = FALSE; - int result = WideCharToMultiByte( m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed ); - - mir_free( dgs->pValue->pszVal ); - - if ( bUsed || result == 0 ) { - dgs->pValue->type = DBVT_WCHAR; - dgs->pValue->pwszVal = tmp; - } - else { - dgs->pValue->type = DBVT_ASCIIZ; - dgs->pValue->pszVal = (char *)mir_alloc(result); - WideCharToMultiByte( m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dgs->pValue->pszVal, result, NULL, NULL ); - mir_free( tmp ); - } - } - else { - dgs->pValue->type = DBVT_ASCIIZ; - mir_free( tmp ); - } } - - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetContactSettingStr(HANDLE hContact, DBCONTACTGETSETTING *dgs) -{ - int iSaveType = dgs->pValue->type; - - if ( GetContactSettingWorker(hContact, dgs, 0 )) - return 1; - - if ( iSaveType == 0 || iSaveType == dgs->pValue->type ) - return 0; - - if ( dgs->pValue->type != DBVT_ASCIIZ && dgs->pValue->type != DBVT_UTF8 ) - return 1; - - if ( iSaveType == DBVT_WCHAR ) { - if ( dgs->pValue->type != DBVT_UTF8 ) { - int len = MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, NULL, 0 ); - wchar_t* wszResult = ( wchar_t* )mir_alloc(( len+1 )*sizeof( wchar_t )); - if ( wszResult == NULL ) - return 1; - - MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, wszResult, len ); - wszResult[ len ] = 0; - mir_free( dgs->pValue->pszVal ); - dgs->pValue->pwszVal = wszResult; - } - else { - char* savePtr = NEWSTR_ALLOCA(dgs->pValue->pszVal); - mir_free( dgs->pValue->pszVal ); - if ( !mir_utf8decode( savePtr, &dgs->pValue->pwszVal )) - return 1; - } - } - else if ( iSaveType == DBVT_UTF8 ) { - char* tmpBuf = mir_utf8encode( dgs->pValue->pszVal ); - if ( tmpBuf == NULL ) - return 1; - - mir_free( dgs->pValue->pszVal ); - dgs->pValue->pszVal = tmpBuf; - } - else if ( iSaveType == DBVT_ASCIIZ ) - mir_utf8decode( dgs->pValue->pszVal, NULL ); - - dgs->pValue->type = iSaveType; - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::GetContactSettingStatic(HANDLE hContact, DBCONTACTGETSETTING *dgs) -{ - if ( GetContactSettingWorker(hContact, dgs, 1 )) - return 1; - - if ( dgs->pValue->type == DBVT_UTF8 ) { - mir_utf8decode( dgs->pValue->pszVal, NULL ); - dgs->pValue->type = DBVT_ASCIIZ; - } - - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::FreeVariant(DBVARIANT *dbv) -{ - if ( dbv == 0 ) return 1; - switch ( dbv->type ) { - case DBVT_ASCIIZ: - case DBVT_UTF8: - case DBVT_WCHAR: - { - if ( dbv->pszVal ) mir_free(dbv->pszVal); - dbv->pszVal = 0; - break; - } - case DBVT_BLOB: - { - if ( dbv->pbVal ) mir_free(dbv->pbVal); - dbv->pbVal = 0; - break; - } - } - dbv->type = 0; - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::SetSettingResident(BOOL bIsResident, const char *pszSettingName) -{ - size_t cbSettingNameLen = strlen(pszSettingName) + 2; - if (cbSettingNameLen < 512) { - char* szSetting; - char szTemp[512]; - strcpy( szTemp+1, pszSettingName); - - mir_cslock lck(m_csDbAccess); - int idx = m_lSettings.getIndex(szTemp); - if (idx == -1) - szSetting = InsertCachedSetting( szTemp, cbSettingNameLen); - else - szSetting = m_lSettings[idx]; - - *szSetting = (char)bIsResident; - - idx = m_lResidentSettings.getIndex(szSetting+1); - if (idx == -1) { - if (bIsResident) - m_lResidentSettings.insert(szSetting+1); - } - else if (!bIsResident) - m_lResidentSettings.remove(idx); - } - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::WriteContactSetting(HANDLE hContact, DBCONTACTWRITESETTING *dbcws) -{ - DBCONTACTWRITESETTING tmp; - DWORD ofsModuleName; - 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 ) ? strlen(tmp.value.pszVal) : tmp.value.cpbVal; - if ( len >= 0xFFFF ) { - #ifdef _DEBUG - OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n"); - #endif - return 1; - } - } - } - - mir_cslockfull lck(m_csDbAccess); - - char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen); - if ( tmp.value.type != DBVT_BLOB ) { - DBVARIANT* pCachedValue = GetCachedValuePtr(hContact, szCachedSettingName, 1); - if ( pCachedValue != NULL ) { - BOOL bIsIdentical = FALSE; - if ( pCachedValue->type == tmp.value.type ) { - switch(tmp.value.type) { - case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == tmp.value.bVal; break; - case DBVT_WORD: bIsIdentical = pCachedValue->wVal == tmp.value.wVal; break; - case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == tmp.value.dVal; break; - case DBVT_UTF8: - case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, tmp.value.pszVal ) == 0; break; - } - if ( bIsIdentical ) - return 0; - } - SetCachedVariant(&tmp.value, pCachedValue); - } - if ( szCachedSettingName[-1] != 0 ) { - lck.unlock(); - NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); - return 0; - } - } - else GetCachedValuePtr(hContact, szCachedSettingName, -1); - - ofsModuleName = GetModuleNameOfs(tmp.szModule); - if (hContact == 0) ofsContact = m_dbHeader.ofsUser; - else ofsContact = (DWORD)hContact; - - DBContact dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc.signature != DBCONTACT_SIGNATURE) - 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(DBContactSettings,blob)); - dbcs.signature = DBCONTACTSETTINGS_SIGNATURE; - dbcs.ofsNext = dbc.ofsFirstSettings; - dbcs.ofsModuleName = ofsModuleName; - dbcs.cbBlob = bytesRequired; - dbcs.blob[0] = 0; - dbc.ofsFirstSettings = ofsSettingsGroup; - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - DBWrite(ofsSettingsGroup,&dbcs,sizeof(DBContactSettings)); - ofsBlobPtr = ofsSettingsGroup+offsetof(DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - } - else { - dbcs = *(DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(DBContactSettings),&bytesRemaining); - //find if the setting exists - ofsBlobPtr = ofsSettingsGroup+offsetof(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); - lck.unlock(); - //notify - NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); - return 0; - } - } - } - //cannot do a simple replace, add setting to end of list - //pBlob already points to end of list - //see if it fits - if (tmp.value.type&DBVTF_VARIABLELENGTH) { - if (tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8) bytesRequired = (int)strlen(tmp.value.pszVal)+2; - else if (tmp.value.type == DBVT_BLOB) bytesRequired = tmp.value.cpbVal+2; - } - else bytesRequired = tmp.value.type; - bytesRequired += 2+settingNameLen; - bytesRequired += ofsBlobPtr+1-(ofsSettingsGroup+offsetof(DBContactSettings,blob)); - if ((DWORD)bytesRequired > dbcs.cbBlob) { - //doesn't fit: move entire group - 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 = (DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(DBContactSettings),NULL); - while (dbcsPrev->ofsNext != ofsSettingsGroup) { - if (dbcsPrev->ofsNext == 0) DatabaseCorruption(NULL); - ofsDbcsPrev = dbcsPrev->ofsNext; - dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(DBContactSettings),NULL); - } - } - - //create the new one - ofsNew = ReallocSpace(ofsSettingsGroup, dbcs.cbBlob+offsetof(DBContactSettings,blob), bytesRequired+offsetof(DBContactSettings,blob)); - - dbcs.cbBlob = bytesRequired; - - DBWrite(ofsNew,&dbcs,offsetof(DBContactSettings,blob)); - if (ofsDbcsPrev == 0) { - dbc.ofsFirstSettings = ofsNew; - DBWrite(ofsContact,&dbc,sizeof(DBContact)); - } - else { - dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(DBContactSettings),NULL); - dbcsPrev->ofsNext = ofsNew; - DBWrite(ofsDbcsPrev,dbcsPrev,offsetof(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); - lck.unlock(); - - //notify - NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp ); - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::DeleteContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs) -{ - DBContact *dbc; - DWORD ofsModuleName,ofsSettingsGroup,ofsBlobPtr; - PBYTE pBlob; - int settingNameLen,moduleNameLen,bytesRemaining; - char* szCachedSettingName; - WPARAM saveWparam = (WPARAM)hContact; - - 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; - } - - mir_cslockfull lck(m_csDbAccess); - ofsModuleName = GetModuleNameOfs(dbcgs->szModule); - if (hContact == 0) - hContact = (HANDLE)m_dbHeader.ofsUser; - - dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - return 1; - - //make sure the module group exists - ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); - if (ofsSettingsGroup == 0) - return 1; - - //find if the setting exists - ofsBlobPtr = ofsSettingsGroup+offsetof(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 - 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); - lck.unlock(); - - //notify - DBCONTACTWRITESETTING dbcws = {0}; - dbcws.szModule = dbcgs->szModule; - dbcws.szSetting = dbcgs->szSetting; - dbcws.value.type = DBVT_DELETED; - NotifyEventHooks(hSettingChangeEvent,saveWparam,(LPARAM)&dbcws); - return 0; -} - -STDMETHODIMP_(BOOL) CDdxMmap::EnumContactSettings(HANDLE hContact, DBCONTACTENUMSETTINGS* dbces) -{ - DBContact *dbc; - DWORD ofsModuleName,ofsContact,ofsBlobPtr; - int bytesRemaining, result; - PBYTE pBlob; - char szSetting[256]; - - if (!dbces->szModule) - return -1; - - mir_cslock lck(m_csDbAccess); - - ofsModuleName = GetModuleNameOfs(dbces->szModule); - if (hContact == 0) ofsContact = m_dbHeader.ofsUser; - else ofsContact = (DWORD)hContact; - dbc = (DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); - if (dbc->signature != DBCONTACT_SIGNATURE) - return -1; - - dbces->ofsSettings = GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); - if ( !dbces->ofsSettings) - return -1; - - ofsBlobPtr = dbces->ofsSettings+offsetof(DBContactSettings,blob); - pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); - if (pBlob[0] == 0) - 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); - } - return result; -} - -STDMETHODIMP_(BOOL) CDdxMmap::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) -{ - for(int i = 0; i < m_lResidentSettings.getCount(); i++) { - int ret = pFunc(m_lResidentSettings[i], 0, (LPARAM)pParam); - if (ret) return ret; - } - return 0; -} diff --git a/plugins/Db3x_mmap/docs/db3x_mmap-translation.txt b/plugins/Db3x_mmap/docs/db3x_mmap-translation.txt new file mode 100644 index 0000000000..cd23ce15ba --- /dev/null +++ b/plugins/Db3x_mmap/docs/db3x_mmap-translation.txt @@ -0,0 +1,35 @@ +; Common strings that belong to many files +;[] + +; ../../plugins/Db3x_mmap/database.cpp +;[Database Error] +;[Database Panic] +;[Database failure. Miranda will now shutdown.] +;[Disk is full. Miranda will now shutdown.] +;[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.] + +; ../../plugins/Db3x_mmap/db3x_mmap.rc +;[&Allow all further changes to this section] +;[&Delete] +;[&Leave] +;[&Move/Rename] +;[&No] +;[&Recycle] +;[&View contents] +;[&Yes] +;[A file containing new database settings has been placed in the Miranda IM directory.] +;[Cancel Import] +;[Database Import Complete] +;[Database Setting Change] +;[Database settings are being imported from] +;[Do you want to allow this change?] +;[Do you want to import the settings now?] +;[Install Database Settings] +;[No] +;[No to all] +;[Security systems to prevent malicious changes are in place and you will be warned before changes that are not known to be safe.] +;[The import has completed from] +;[This file wishes to change the setting] +;[What do you want to do with the file now?] +;[Yes] +;[to the value] diff --git a/plugins/Db3x_mmap/init.cpp b/plugins/Db3x_mmap/init.cpp deleted file mode 100644 index b38fab0ce2..0000000000 --- a/plugins/Db3x_mmap/init.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -int hLangpack; - -static PLUGININFOEX pluginInfo = -{ - sizeof(PLUGININFOEX), - "Miranda NG mmap database driver", - __VERSION_DWORD, - "Provides Miranda database support: global settings, contacts, history, settings per contact.", - "Miranda-NG project", - "bio@msx.ru; ghazan@miranda.im", - "Copyright 2012 Miranda NG project", - "", - UNICODE_AWARE, - {0xf7a6b27c, 0x9d9c, 0x4a42, { 0xbe, 0x86, 0xa4, 0x48, 0xae, 0x10, 0x91, 0x61 }} //{F7A6B27C-9D9C-4a42-BE86-A448AE109161} -}; - -HINSTANCE g_hInst = NULL; - -LIST g_Dbs(1, (LIST::FTSortFunc)HandleKeySort); - -///////////////////////////////////////////////////////////////////////////////////////// - -// returns 0 if the profile is created, EMKPRF* -static int makeDatabase(const TCHAR *profile, int *error) -{ - CDdxMmap *tmp = new CDdxMmap(profile); - if (tmp->Create() == ERROR_SUCCESS) { - tmp->CreateDbHeaders(); - delete tmp; - return 0; - } - delete tmp; - if (error != NULL) *error = EMKPRF_CREATEFAILED; - return 1; -} - -// returns 0 if the given profile has a valid header -static int grokHeader(const TCHAR *profile, int *error) -{ - CDdxMmap *tmp = new CDdxMmap(profile); - if (tmp->Load(true) != ERROR_SUCCESS) { - delete tmp; - if (error != NULL) *error = EGROKPRF_CANTREAD; - return 1; - } - - int chk = tmp->CheckDbHeaders(); - delete tmp; - if ( chk == 0 ) { - // all the internal tests passed, hurrah - if (error != NULL) *error = 0; - return 0; - } - - // didn't pass at all, or some did. - switch ( chk ) { - case 1: - // "Miranda ICQ DB" wasn't present - if (error != NULL) *error = EGROKPRF_UNKHEADER; - break; - - case 2: - // header was present, but version information newer - if (error != NULL) *error = EGROKPRF_VERNEWER; - break; - - case 3: - // header/version OK, internal data missing - if (error != NULL) *error = EGROKPRF_DAMAGED; - break; - } - - return 1; -} - -// returns 0 if all the APIs are injected otherwise, 1 -static MIDatabase* LoadDatabase(const TCHAR *profile) -{ - // set the memory, lists & UTF8 manager - mir_getLP( &pluginInfo ); - - CDdxMmap* db = new CDdxMmap(profile); - if (db->Load(false) != ERROR_SUCCESS) { - delete db; - return NULL; - } - - g_Dbs.insert(db); - return db; -} - -static int UnloadDatabase(MIDatabase* db) -{ - g_Dbs.remove((CDdxMmap*)db); - delete (CDdxMmap*)db; - return 0; -} - -static DATABASELINK dblink = -{ - sizeof(DATABASELINK), - "db3x mmap driver", - _T("db3x mmap database support"), - makeDatabase, - grokHeader, - LoadDatabase, - UnloadDatabase -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_DATABASE, MIID_LAST}; - -extern "C" __declspec(dllexport) int Load(void) -{ - RegisterDatabasePlugin(&dblink); - return 0; -} - -extern "C" __declspec(dllexport) int Unload(void) -{ - g_Dbs.destroy(); - return 0; -} - -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) -{ - g_hInst = hInstDLL; - return TRUE; -} diff --git a/plugins/Db3x_mmap/res/db3x_mmap.rc b/plugins/Db3x_mmap/res/db3x_mmap.rc new file mode 100644 index 0000000000..9c2727f53b --- /dev/null +++ b/plugins/Db3x_mmap/res/db3x_mmap.rc @@ -0,0 +1,174 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_INSTALLINI DIALOGEX 0, 0, 212, 102 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | + DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Install Database Settings" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Yes",IDOK,26,83,50,14 + PUSHBUTTON "No",IDCANCEL,81,83,50,14 + LTEXT "A file containing new database settings has been placed in the Miranda IM directory.", + IDC_STATIC,5,5,202,16 + LTEXT "Do you want to import the settings now?",IDC_STATIC,5, + 69,202,8 + PUSHBUTTON "No to all",IDC_NOTOALL,136,83,50,14 + LTEXT "",IDC_ININAME,5,24,143,16,SS_NOPREFIX | SS_CENTERIMAGE + PUSHBUTTON "&View contents",IDC_VIEWINI,149,25,58,14 + LTEXT "Security systems to prevent malicious changes are in place and you will be warned before changes that are not known to be safe.", + IDC_SECURITYINFO,5,43,202,24 +END + +IDD_WARNINICHANGE DIALOGEX 0, 0, 187, 113 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | + DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Database Setting Change" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Database settings are being imported from",IDC_STATIC,5, + 5,177,8 + CONTROL "",IDC_ININAME,"Static",SS_SIMPLE | SS_NOPREFIX | + WS_GROUP,5,13,177,8 + LTEXT "This file wishes to change the setting",IDC_STATIC,5,24, + 177,8 + CONTROL "",IDC_SETTINGNAME,"Static",SS_SIMPLE | SS_NOPREFIX | + WS_GROUP,12,33,170,8 + LTEXT "to the value",IDC_STATIC,5,42,177,8 + CONTROL "",IDC_NEWVALUE,"Static",SS_SIMPLE | SS_NOPREFIX | + WS_GROUP,12,51,170,8 + LTEXT "",IDC_SECURITYINFO,5,60,177,8 + LTEXT "Do you want to allow this change?",IDC_STATIC,5,71,177, + 8 + CONTROL "&Allow all further changes to this section", + IDC_WARNNOMORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13, + 80,169,10 + DEFPUSHBUTTON "&Yes",IDYES,5,94,50,14 + PUSHBUTTON "&No",IDNO,59,94,50,14 + PUSHBUTTON "Cancel Import",IDCANCEL,123,94,59,14 +END + +IDD_INIIMPORTDONE DIALOGEX 0, 0, 186, 73 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | + DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Database Import Complete" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "The import has completed from",IDC_STATIC,5,5,176,8 + CONTROL "",IDC_ININAME,"Static",SS_SIMPLE | SS_NOPREFIX | + WS_GROUP,5,13,176,8 + LTEXT "What do you want to do with the file now?",IDC_STATIC,5, + 24,176,8 + PUSHBUTTON "&Recycle",IDC_RECYCLE,5,36,50,14 + PUSHBUTTON "&Delete",IDC_DELETE,68,36,50,14 + EDITTEXT IDC_NEWNAME,5,55,117,12,ES_AUTOHSCROLL + PUSHBUTTON "&Move/Rename",IDC_MOVE,124,54,57,14 + PUSHBUTTON "&Leave",IDC_LEAVE,131,36,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_INSTALLINI, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 207 + TOPMARGIN, 5 + BOTTOMMARGIN, 97 + END + + IDD_WARNINICHANGE, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 182 + TOPMARGIN, 5 + BOTTOMMARGIN, 108 + END + + IDD_INIIMPORTDONE, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 181 + TOPMARGIN, 5 + BOTTOMMARGIN, 68 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/plugins/Db3x_mmap/res/version.rc b/plugins/Db3x_mmap/res/version.rc new file mode 100644 index 0000000000..d49f35ded0 --- /dev/null +++ b/plugins/Db3x_mmap/res/version.rc @@ -0,0 +1,42 @@ +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + +#include +#include "..\src\version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041904b0" + BEGIN + VALUE "FileDescription", "Miranda NG Mmap DataBase Engine 3x" + VALUE "FileVersion", __VERSION_STRING + VALUE "LegalCopyright", "Copyright (C) 2012" + VALUE "OriginalFilename", "dbx_mmap.dll" + VALUE "ProductName", "Miranda NG Mmap DataBase Engine 3x" + VALUE "ProductVersion", __VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x419, 1200 + END +END diff --git a/plugins/Db3x_mmap/resource.h b/plugins/Db3x_mmap/resource.h deleted file mode 100644 index 96abbfff99..0000000000 --- a/plugins/Db3x_mmap/resource.h +++ /dev/null @@ -1,30 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by resource.rc -// -#define IDC_NOTOALL 3 -#define IDD_INSTALLINI 235 -#define IDD_WARNINICHANGE 236 -#define IDD_INIIMPORTDONE 237 -#define IDC_ININAME 1333 -#define IDC_VIEWINI 1334 -#define IDC_SECURITYINFO 1335 -#define IDC_SETTINGNAME 1336 -#define IDC_NEWVALUE 1337 -#define IDC_WARNNOMORE 1338 -#define IDC_DELETE 1339 -#define IDC_RECYCLE 1340 -#define IDC_NEWNAME 1341 -#define IDC_MOVE 1342 -#define IDC_LEAVE 1343 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 269 -#define _APS_NEXT_COMMAND_VALUE 40018 -#define _APS_NEXT_CONTROL_VALUE 1657 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/plugins/Db3x_mmap/src/commonheaders.h b/plugins/Db3x_mmap/src/commonheaders.h new file mode 100644 index 0000000000..ea615956e1 --- /dev/null +++ b/plugins/Db3x_mmap/src/commonheaders.h @@ -0,0 +1,62 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#define _CRT_SECURE_NO_WARNINGS +#define _WIN32_WINNT 0x0501 + +#include "m_stdhdr.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __GNUC__ +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "database.h" +#include "dbintf.h" +#include "resource.h" +#include "version.h" + +extern LIST g_Dbs; + +#ifdef __GNUC__ +#define mir_i64(x) (x##LL) +#else +#define mir_i64(x) (x##i64) +#endif diff --git a/plugins/Db3x_mmap/src/database.cpp b/plugins/Db3x_mmap/src/database.cpp new file mode 100644 index 0000000000..1962805a35 --- /dev/null +++ b/plugins/Db3x_mmap/src/database.cpp @@ -0,0 +1,121 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +int InitModuleNames(void); +int InitCache(void); +int InitIni(void); +void UninitIni(void); + +DWORD CDdxMmap::CreateNewSpace(int bytes) +{ + DWORD ofsNew = m_dbHeader.ofsFileEnd; + m_dbHeader.ofsFileEnd += bytes; + DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); + log2("newspace %d@%08x", bytes, ofsNew); + return ofsNew; +} + +void CDdxMmap::DeleteSpace(DWORD ofs, int bytes) +{ + if (ofs+bytes == m_dbHeader.ofsFileEnd) { + log2("freespace %d@%08x",bytes,ofs); + m_dbHeader.ofsFileEnd = ofs; + } + else { + log2("deletespace %d@%08x",bytes,ofs); + m_dbHeader.slackSpace += bytes; + } + DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); + DBFill(ofs, bytes); +} + +DWORD CDdxMmap::ReallocSpace(DWORD ofs, int oldSize, int newSize) +{ + if (oldSize >= newSize) + return ofs; + + DWORD ofsNew; + if (ofs+oldSize == m_dbHeader.ofsFileEnd) { + ofsNew = ofs; + m_dbHeader.ofsFileEnd += newSize-oldSize; + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + log3("adding newspace %d@%08x+%d", newSize, ofsNew, oldSize); + } + else { + ofsNew = CreateNewSpace(newSize); + DBMoveChunk(ofsNew,ofs,oldSize); + DeleteSpace(ofs,oldSize); + } + return ofsNew; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +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://nightly.miranda.im/. Miranda will now shutdown."), + TranslateT("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); + TerminateProcess(GetCurrentProcess(),255); +} + +void CDdxMmap::DatabaseCorruption(TCHAR *text) +{ + int kill = 0; + + EnterCriticalSection(&m_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(&m_csDbAccess); + Sleep(INFINITE); + return; + } + LeaveCriticalSection(&m_csDbAccess); + if (kill) { + _beginthread(dbpanic,0,NULL); + Sleep(INFINITE); + } +} diff --git a/plugins/Db3x_mmap/src/database.h b/plugins/Db3x_mmap/src/database.h new file mode 100644 index 0000000000..83c2fcaea9 --- /dev/null +++ b/plugins/Db3x_mmap/src/database.h @@ -0,0 +1,70 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +//all offsets are relative to the start of the file +//offsets are 0 if there is nothing in the chain or this is the last in the +//chain + +/* tree diagram + +DBHeader + |-->end of file (plain offset) + |-->first contact (DBContact) + | |-->next contact (DBContact) + | | \--> ... + | |-->first settings (DBContactSettings) + | | |-->next settings (DBContactSettings) + | | | \--> ... + | | \-->module name (DBModuleName) + | \-->first/last/firstunread event + |-->user contact (DBContact) + | |-->next contact = NULL + | |-->first settings as above + | \-->first/last/firstunread event as above + \-->first module name (DBModuleName) + \-->next module name (DBModuleName) + \--> ... +*/ + +//#define DBLOGGING + +#ifdef _DEBUG +//#define DBLOGGING +#endif +#ifdef DBLOGGING +void DBLog(const char *file,int line,const char *fmt,...); +#define logg() DBLog(__FILE__,__LINE__,"") +#define log0(s) DBLog(__FILE__,__LINE__,s) +#define log1(s,a) DBLog(__FILE__,__LINE__,s,a) +#define log2(s,a,b) DBLog(__FILE__,__LINE__,s,a,b) +#define log3(s,a,b,c) DBLog(__FILE__,__LINE__,s,a,b,c) +#define log4(s,a,b,c,d) DBLog(__FILE__,__LINE__,s,a,b,c,d) +#else +#define logg() +#define log0(s) +#define log1(s,a) +#define log2(s,a,b) +#define log3(s,a,b,c) +#define log4(s,a,b,c,d) +#endif diff --git a/plugins/Db3x_mmap/src/dbcache.cpp b/plugins/Db3x_mmap/src/dbcache.cpp new file mode 100644 index 0000000000..466aa7a00d --- /dev/null +++ b/plugins/Db3x_mmap/src/dbcache.cpp @@ -0,0 +1,175 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +void CDdxMmap::Map() +{ + m_hMap = CreateFileMapping(m_hDbFile, NULL, PAGE_READWRITE, 0, m_dwFileSize, NULL); + + if (m_hMap) + { + m_pDbCache = (PBYTE)MapViewOfFile(m_hMap, FILE_MAP_ALL_ACCESS/*FILE_MAP_WRITE*/, 0, 0 ,0); + if (!m_pDbCache) + DatabaseCorruption( _T("%s (MapViewOfFile failed. Code: %d)")); + } + else + DatabaseCorruption( _T("%s (CreateFileMapping failed. Code: %d)")); +} + +void CDdxMmap::ReMap(DWORD needed) +{ + KillTimer(NULL,m_flushBuffersTimerId); + + log3("remapping %d + %d (file end: %d)",m_dwFileSize,needed,m_dbHeader.ofsFileEnd); + + if (needed > m_ChunkSize) + { + if (needed + m_dwFileSize > m_dbHeader.ofsFileEnd + m_ChunkSize) + DatabaseCorruption( _T("%s (Too large increment)")); + else + { + DWORD x = m_dbHeader.ofsFileEnd/m_ChunkSize; + m_dwFileSize = (x+1)*m_ChunkSize; + } + } + else + m_dwFileSize += m_ChunkSize; + +// FlushViewOfFile(m_pDbCache, 0); + UnmapViewOfFile(m_pDbCache); + m_pDbCache = NULL; + CloseHandle(m_hMap); + + Map(); +} + +void CDdxMmap::DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) +{ + int x = 0; + log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); + if (ofsDest+bytes > m_dwFileSize) ReMap(ofsDest+bytes-m_dwFileSize); + if (ofsSource+bytes > m_dwFileSize) { + x = ofsSource+bytes-m_dwFileSize; + log0("buggy move!"); + _ASSERT(0); + } + if (x > 0) + ZeroMemory(m_pDbCache+ofsDest+bytes-x, x); + if (ofsSource < m_dwFileSize) + MoveMemory(m_pDbCache+ofsDest,m_pDbCache+ofsSource, bytes-x); + + logg(); +} + +//we are assumed to be in a mutex here +PBYTE CDdxMmap::DBRead(DWORD ofs,int bytesRequired,int *bytesAvail) +{ + // buggy read + if (ofs>= m_dwFileSize) { + log2("read from outside %d@%08x",bytesRequired,ofs); + if (bytesAvail != NULL) *bytesAvail = m_ChunkSize; + return m_pNull; + } + log3((ofs+bytesRequired > m_dwFileSize)?"read %d@%08x, only %d avaliable":"read %d@%08x",bytesRequired,ofs,m_dwFileSize-ofs); + if (bytesAvail != NULL) *bytesAvail = m_dwFileSize - ofs; + return m_pDbCache+ofs; +} + +//we are assumed to be in a mutex here +void CDdxMmap::DBWrite(DWORD ofs,PVOID pData,int bytes) +{ + log2("write %d@%08x",bytes,ofs); + if (ofs+bytes > m_dwFileSize) ReMap(ofs+bytes-m_dwFileSize); + MoveMemory(m_pDbCache+ofs,pData,bytes); + logg(); +} + +//we are assumed to be in a mutex here +void CDdxMmap::DBFill(DWORD ofs,int bytes) +{ + log2("zerofill %d@%08x",bytes,ofs); + if (ofs+bytes <= m_dwFileSize) + ZeroMemory(m_pDbCache+ofs,bytes); + logg(); +} + +static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) +{ + for (int i=0; i < g_Dbs.getCount(); i++) { + CDdxMmap* db = g_Dbs[i]; + if (db->m_flushBuffersTimerId != idEvent) + continue; + + if (!db->m_pDbCache) + return; + + KillTimer(NULL, db->m_flushBuffersTimerId); + log0("tflush1"); + if (FlushViewOfFile(db->m_pDbCache, 0) == 0) { + if (db->m_flushFailTick == 0) + db->m_flushFailTick = GetTickCount(); + else if (GetTickCount() - db->m_flushFailTick > 5000) + db->DatabaseCorruption(NULL); + } + else db->m_flushFailTick = 0; + log0("tflush2"); + } +} + +void CDdxMmap::DBFlush(int setting) +{ + if (!setting) { + log0("nflush1"); + if (m_safetyMode && m_pDbCache) { + if (FlushViewOfFile(m_pDbCache, 0) == 0) { + if (m_flushFailTick == 0) + m_flushFailTick = GetTickCount(); + else if (GetTickCount() - m_flushFailTick > 5000) + DatabaseCorruption(NULL); + } + else + m_flushFailTick = 0; + } + log0("nflush2"); + return; + } + KillTimer(NULL, m_flushBuffersTimerId); + m_flushBuffersTimerId = SetTimer(NULL, m_flushBuffersTimerId, 50, DoBufferFlushTimerProc); +} + +int CDdxMmap::InitCache(void) +{ + m_dwFileSize = GetFileSize(m_hDbFile, NULL); + + // Align to chunk + DWORD x = m_dwFileSize % m_ChunkSize; + if (x) + m_dwFileSize += m_ChunkSize - x; + + Map(); + + // zero region for reads outside the file + m_pNull = (PBYTE)calloc(m_ChunkSize, 1); + return 0; +} diff --git a/plugins/Db3x_mmap/src/dbcontacts.cpp b/plugins/Db3x_mmap/src/dbcontacts.cpp new file mode 100644 index 0000000000..b8d4a843b8 --- /dev/null +++ b/plugins/Db3x_mmap/src/dbcontacts.cpp @@ -0,0 +1,244 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +DBCachedContactValueList* CDdxMmap::AddToCachedContactList(HANDLE hContact, int index) +{ + DBCachedContactValueList* VL = (DBCachedContactValueList*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList)); + VL->hContact = hContact; + if (index == -1) + m_lContacts.insert(VL); + else + m_lContacts.insert(VL,index); + return VL; +} + +#define proto_module "Protocol" +#define proto_setting "p" + +int CDdxMmap::CheckProto(HANDLE hContact, const char *proto) +{ + char protobuf[MAX_PATH] = {0}; + DBVARIANT dbv; + DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv}; + + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = protobuf; + dbv.cchVal = sizeof(protobuf); + + if (GetContactSettingStatic(hContact, &sVal) != 0 || (dbv.type != DBVT_ASCIIZ)) + return 0; + + return !strcmp(protobuf,proto); +} + +STDMETHODIMP_(LONG) CDdxMmap::GetContactCount(void) +{ + mir_cslock lck(m_csDbAccess); + return m_dbHeader.contactCount; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstContact(const char *szProto) +{ + mir_cslock lck(m_csDbAccess); + HANDLE ret = (HANDLE)m_dbHeader.ofsFirstContact; + if (szProto && !CheckProto(ret, szProto)) + ret = FindNextContact(ret, szProto); + return ret; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindNextContact(HANDLE hContact, const char *szProto) +{ + int index; + DBContact *dbc; + DBCachedContactValueList VLtemp, *VL = NULL; + VLtemp.hContact = hContact; + + mir_cslock lck(m_csDbAccess); + while (VLtemp.hContact) { + if (( index = m_lContacts.getIndex(&VLtemp)) != -1) { + VL = m_lContacts[index]; + if (VL->hNext != NULL) { + if (!szProto || CheckProto(VL->hNext, szProto)) + return VL->hNext; + + VLtemp.hContact = VL->hNext; + continue; + } } + + dbc = (DBContact*)DBRead(VLtemp.hContact,sizeof(DBContact),NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + break; + + if ( VL == NULL ) + VL = AddToCachedContactList(VLtemp.hContact,index); + + VL->hNext = (HANDLE)dbc->ofsNext; + if (VL->hNext != NULL && (!szProto || CheckProto(VL->hNext, szProto))) + return VL->hNext; + + VLtemp.hContact = VL->hNext; + } + + return NULL; +} + +STDMETHODIMP_(LONG) CDdxMmap::DeleteContact(HANDLE hContact) +{ + if (hContact == NULL) + return 1; + + mir_cslockfull lck(m_csDbAccess); + DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + return 1; + + if (hContact == (HANDLE)m_dbHeader.ofsUser) { + log0("FATAL: del of user chain attempted."); + return 1; + } + + lck.unlock(); + log0("del contact"); + + // call notifier while outside mutex + NotifyEventHooks(hContactDeletedEvent, (WPARAM)hContact, 0); + + // get back in + lck.lock(); + + DBCachedContactValueList VLtemp; + VLtemp.hContact = hContact; + int index; + if ((index = m_lContacts.getIndex(&VLtemp)) != -1) { + DBCachedContactValueList *VL = m_lContacts[index]; + DBCachedContactValue* V = VL->first; + while ( V != NULL ) { + DBCachedContactValue* V1 = V->next; + FreeCachedVariant(&V->value); + HeapFree( m_hCacheHeap, 0, V ); + V = V1; + } + HeapFree( m_hCacheHeap, 0, VL ); + + if (VLtemp.hContact == m_hLastCachedContact) + m_hLastCachedContact = NULL; + m_lContacts.remove(index); + } + + dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + //delete settings chain + DWORD ofsThis = dbc->ofsFirstSettings; + DWORD ofsFirstEvent = dbc->ofsFirstEvent; + while (ofsThis) { + DBContactSettings *dbcs = (DBContactSettings*)DBRead(ofsThis,sizeof(DBContactSettings),NULL); + DWORD ofsNext = dbcs->ofsNext; + DeleteSpace(ofsThis,offsetof(DBContactSettings,blob)+dbcs->cbBlob); + ofsThis = ofsNext; + } + //delete event chain + ofsThis = ofsFirstEvent; + while (ofsThis) { + DBEvent *dbe = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); + DWORD ofsNext = dbe->ofsNext; + DeleteSpace(ofsThis,offsetof(DBEvent,blob)+dbe->cbBlob); + ofsThis = ofsNext; + } + //find previous contact in chain and change ofsNext + dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + if (m_dbHeader.ofsFirstContact == (DWORD)hContact) { + m_dbHeader.ofsFirstContact = dbc->ofsNext; + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + } + else { + DWORD ofsNext = dbc->ofsNext; + ofsThis = m_dbHeader.ofsFirstContact; + DBContact *dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); + while (dbcPrev->ofsNext != (DWORD)hContact) { + if (dbcPrev->ofsNext == 0) DatabaseCorruption(NULL); + ofsThis = dbcPrev->ofsNext; + dbcPrev = (DBContact*)DBRead(ofsThis,sizeof(DBContact),NULL); + } + dbcPrev->ofsNext = ofsNext; + DBWrite(ofsThis,dbcPrev,sizeof(DBContact)); + + DBCachedContactValueList VLtemp; + VLtemp.hContact = (HANDLE)ofsThis; + if ((index = m_lContacts.getIndex(&VLtemp)) != -1) { + DBCachedContactValueList *VL = m_lContacts[index]; + VL->hNext = (HANDLE)ofsNext; + } + } + + //delete contact + DeleteSpace((DWORD)hContact, sizeof(DBContact)); + //decrement contact count + m_dbHeader.contactCount--; + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + DBFlush(0); + return 0; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::AddContact() +{ + DWORD ofsNew; + log0("add contact"); + { + mir_cslock lck(m_csDbAccess); + ofsNew = CreateNewSpace(sizeof(DBContact)); + + DBContact dbc = { 0 }; + dbc.signature = DBCONTACT_SIGNATURE; + dbc.ofsNext = m_dbHeader.ofsFirstContact; + m_dbHeader.ofsFirstContact = ofsNew; + m_dbHeader.contactCount++; + DBWrite(ofsNew,&dbc,sizeof(DBContact)); + DBWrite(0,&m_dbHeader,sizeof(m_dbHeader)); + DBFlush(0); + + AddToCachedContactList((HANDLE)ofsNew, -1); + } + + NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); + return (HANDLE)ofsNew; +} + +STDMETHODIMP_(BOOL) CDdxMmap::IsDbContact(HANDLE hContact) +{ + mir_cslock lck(m_csDbAccess); + + DBCachedContactValueList VLtemp; + VLtemp.hContact = hContact; + int index = m_lContacts.getIndex(&VLtemp); + if (index != -1) + return TRUE; + + DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); + if (dbc->signature == DBCONTACT_SIGNATURE) { + AddToCachedContactList(hContact, index); + return TRUE; + } + + return FALSE; +} diff --git a/plugins/Db3x_mmap/src/dbevents.cpp b/plugins/Db3x_mmap/src/dbevents.cpp new file mode 100644 index 0000000000..917d1680b2 --- /dev/null +++ b/plugins/Db3x_mmap/src/dbevents.cpp @@ -0,0 +1,355 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +extern BOOL m_safetyMode; + +DWORD GetModuleNameOfs(const char *szName); +char *GetModuleNameByOfs(DWORD ofs); + +static HANDLE hEventDeletedEvent,hEventAddedEvent,hEventFilterAddedEvent; + +STDMETHODIMP_(LONG) CDdxMmap::GetEventCount(HANDLE hContact) +{ + mir_cslock lck(m_csDbAccess); + if (hContact == 0) + hContact = (HANDLE)m_dbHeader.ofsUser; + + DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); + return (dbc->signature != DBCONTACT_SIGNATURE) ? -1 : dbc->eventCount; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::AddEvent(HANDLE hContact, DBEVENTINFO *dbei) +{ + if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0; + if (dbei->timestamp == 0) return 0; + if (NotifyEventHooks(hEventFilterAddedEvent, (WPARAM)hContact, (LPARAM)dbei)) + return 0; + + BOOL neednotify; + mir_cslockfull lck(m_csDbAccess); + + DWORD ofsContact = (hContact == 0) ? m_dbHeader.ofsUser : (DWORD)hContact; + DBContact dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); + if (dbc.signature != DBCONTACT_SIGNATURE) + return 0; + + DWORD ofsNew = CreateNewSpace(offsetof(DBEvent,blob) + dbei->cbBlob); + DWORD ofsModuleName = GetModuleNameOfs(dbei->szModule); + + DBEvent dbe; + dbe.signature = DBEVENT_SIGNATURE; + dbe.ofsModuleName = ofsModuleName; + dbe.timestamp = dbei->timestamp; + dbe.flags = dbei->flags; + dbe.eventType = dbei->eventType; + dbe.cbBlob = dbei->cbBlob; + //find where to put it - sort by timestamp + if (dbc.eventCount == 0) { + dbe.ofsPrev = (DWORD)hContact; + dbe.ofsNext = 0; + dbe.flags |= DBEF_FIRST; + dbc.ofsFirstEvent = dbc.ofsLastEvent = ofsNew; + } + else { + DBEvent *dbeTest = (DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(DBEvent),NULL); + // Should new event be placed before first event in chain? + if (dbei->timestamp < dbeTest->timestamp) { + dbe.ofsPrev = (DWORD)hContact; + dbe.ofsNext = dbc.ofsFirstEvent; + dbe.flags |= DBEF_FIRST; + dbc.ofsFirstEvent = ofsNew; + dbeTest = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); + dbeTest->flags &= ~DBEF_FIRST; + dbeTest->ofsPrev = ofsNew; + DBWrite(dbe.ofsNext,dbeTest,sizeof(DBEvent)); + } + else { + // Loop through the chain, starting at the end + DWORD ofsThis = dbc.ofsLastEvent; + dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); + for (;;) { + // If the new event's timesstamp is equal to or greater than the + // current dbevent, it will be inserted after. If not, continue + // with the previous dbevent in chain. + if (dbe.timestamp >= dbeTest->timestamp) { + dbe.ofsPrev = ofsThis; + dbe.ofsNext = dbeTest->ofsNext; + dbeTest->ofsNext = ofsNew; + DBWrite(ofsThis, dbeTest, sizeof(DBEvent)); + if (dbe.ofsNext == 0) + dbc.ofsLastEvent = ofsNew; + else { + dbeTest = (DBEvent*)DBRead(dbe.ofsNext, sizeof(DBEvent), NULL); + dbeTest->ofsPrev = ofsNew; + DBWrite(dbe.ofsNext, dbeTest, sizeof(DBEvent)); + } + break; + } + ofsThis = dbeTest->ofsPrev; + dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); + } + } + } + dbc.eventCount++; + + if (!(dbe.flags&(DBEF_READ|DBEF_SENT))) { + if (dbe.timestamppBlob,dbei->cbBlob); + DBFlush(0); + lck.unlock(); + + log1("add event @ %08x",ofsNew); + + // Notify only in safe mode or on really new events + if (neednotify) + NotifyEventHooks(hEventAddedEvent, (WPARAM)hContact, (LPARAM)ofsNew); + + return (HANDLE)ofsNew; +} + +STDMETHODIMP_(BOOL) CDdxMmap::DeleteEvent(HANDLE hContact, HANDLE hDbEvent) +{ + mir_cslockfull lck(m_csDbAccess); + + DWORD ofsContact = (hContact == 0) ? m_dbHeader.ofsUser : (DWORD)hContact; + DBContact dbc = *(DBContact*)DBRead(ofsContact, sizeof(DBContact), NULL); + DBEvent dbe = *(DBEvent*)DBRead(hDbEvent, sizeof(DBEvent), NULL); + if (dbc.signature != DBCONTACT_SIGNATURE || dbe.signature != DBEVENT_SIGNATURE) + return 1; + + lck.unlock(); + log1("delete event @ %08x",wParam); + + //call notifier while outside mutex + NotifyEventHooks(hEventDeletedEvent,(WPARAM)hContact, (LPARAM)hDbEvent); + + //get back in + lck.lock(); + dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); + dbe = *(DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); + + //check if this was the first unread, if so, recalc the first unread + if (dbc.ofsFirstUnreadEvent == (DWORD)hDbEvent) { + DBEvent *dbeNext = &dbe; + for (;;) { + if (dbeNext->ofsNext == 0) { + dbc.ofsFirstUnreadEvent = 0; + dbc.timestampFirstUnread = 0; + break; + } + DWORD ofsThis = dbeNext->ofsNext; + dbeNext = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); + if ( !(dbeNext->flags & (DBEF_READ | DBEF_SENT))) { + dbc.ofsFirstUnreadEvent = ofsThis; + dbc.timestampFirstUnread = dbeNext->timestamp; + break; + } + } + } + + //get previous and next events in chain and change offsets + if (dbe.flags&DBEF_FIRST) { + if (dbe.ofsNext == 0) + dbc.ofsFirstEvent = dbc.ofsLastEvent = 0; + else { + DBEvent *dbeNext = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); + dbeNext->flags |= DBEF_FIRST; + dbeNext->ofsPrev = dbe.ofsPrev; + DBWrite(dbe.ofsNext,dbeNext,sizeof(DBEvent)); + dbc.ofsFirstEvent = dbe.ofsNext; + } + } + else { + if (dbe.ofsNext == 0) { + DBEvent *dbePrev = (DBEvent*)DBRead(dbe.ofsPrev,sizeof(DBEvent),NULL); + dbePrev->ofsNext = 0; + DBWrite(dbe.ofsPrev,dbePrev,sizeof(DBEvent)); + dbc.ofsLastEvent = dbe.ofsPrev; + } + else { + DBEvent *dbePrev = (DBEvent*)DBRead(dbe.ofsPrev,sizeof(DBEvent),NULL); + dbePrev->ofsNext = dbe.ofsNext; + DBWrite(dbe.ofsPrev,dbePrev,sizeof(DBEvent)); + + DBEvent *dbeNext = (DBEvent*)DBRead(dbe.ofsNext,sizeof(DBEvent),NULL); + dbeNext->ofsPrev = dbe.ofsPrev; + DBWrite(dbe.ofsNext,dbeNext,sizeof(DBEvent)); + } + } + //delete event + DeleteSpace((DWORD)hDbEvent, offsetof(DBEvent,blob)+dbe.cbBlob); + //decrement event count + dbc.eventCount--; + DBWrite(ofsContact,&dbc,sizeof(DBContact)); + DBFlush(0); + return 0; +} + +STDMETHODIMP_(LONG) CDdxMmap::GetBlobSize(HANDLE hDbEvent) +{ + mir_cslock lck(m_csDbAccess); + DBEvent *dbe = (DBEvent*)DBRead(hDbEvent, sizeof(DBEvent), NULL); + return (dbe->signature != DBEVENT_SIGNATURE) ? -1 : dbe->cbBlob; +} + +STDMETHODIMP_(BOOL) CDdxMmap::GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbei) +{ + if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 1; + if (dbei->cbBlob > 0 && dbei->pBlob == NULL) { + dbei->cbBlob = 0; + return 1; + } + + mir_cslock lck(m_csDbAccess); + DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); + if (dbe->signature != DBEVENT_SIGNATURE) + return 1; + + dbei->szModule = GetModuleNameByOfs(dbe->ofsModuleName); + dbei->timestamp = dbe->timestamp; + dbei->flags = dbe->flags; + dbei->eventType = dbe->eventType; + int bytesToCopy = (dbei->cbBlob < dbe->cbBlob) ? dbei->cbBlob : dbe->cbBlob; + dbei->cbBlob = dbe->cbBlob; + if (bytesToCopy && dbei->pBlob) { + for (int i = 0;;i += MAXCACHEDREADSIZE) { + if (bytesToCopy-i <= MAXCACHEDREADSIZE) { + DecodeCopyMemory(dbei->pBlob+i, DBRead(DWORD(hDbEvent)+offsetof(DBEvent,blob)+i,bytesToCopy-i,NULL), bytesToCopy-i); + break; + } + DecodeCopyMemory(dbei->pBlob+i, DBRead(DWORD(hDbEvent)+offsetof(DBEvent,blob)+i, MAXCACHEDREADSIZE, NULL), MAXCACHEDREADSIZE); + } + } + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::MarkEventRead(HANDLE hContact, HANDLE hDbEvent) +{ + DBEvent *dbe; + DBContact dbc; + DWORD ofsThis; + + mir_cslock lck(m_csDbAccess); + if (hContact == 0) + hContact = (HANDLE)m_dbHeader.ofsUser; + dbc = *(DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + dbe = (DBEvent*)DBRead(hDbEvent, sizeof(DBEvent), NULL); + if (dbe->signature != DBEVENT_SIGNATURE || dbc.signature != DBCONTACT_SIGNATURE) + return -1; + + if ((dbe->flags & DBEF_READ) || (dbe->flags & DBEF_SENT)) + return (INT_PTR)dbe->flags; + + log1("mark read @ %08x",wParam); + dbe->flags |= DBEF_READ; + DBWrite((DWORD)hDbEvent,dbe,sizeof(DBEvent)); + BOOL ret = dbe->flags; + if (dbc.ofsFirstUnreadEvent == (DWORD)hDbEvent) { + for (;;) { + if (dbe->ofsNext == 0) { + dbc.ofsFirstUnreadEvent = 0; + dbc.timestampFirstUnread = 0; + break; + } + ofsThis = dbe->ofsNext; + dbe = (DBEvent*)DBRead(ofsThis,sizeof(DBEvent),NULL); + if ( !(dbe->flags & (DBEF_READ | DBEF_SENT))) { + dbc.ofsFirstUnreadEvent = ofsThis; + dbc.timestampFirstUnread = dbe->timestamp; + break; + } + } + } + DBWrite((DWORD)hContact, &dbc, sizeof(DBContact)); + DBFlush(0); + return ret; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::GetEventContact(HANDLE hDbEvent) +{ + mir_cslock lck(m_csDbAccess); + DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); + if (dbe->signature != DBEVENT_SIGNATURE) + return (HANDLE)-1; + + while (!(dbe->flags & DBEF_FIRST)) + dbe = (DBEvent*)DBRead(dbe->ofsPrev,sizeof(DBEvent),NULL); + + return (HANDLE)dbe->ofsPrev; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstEvent(HANDLE hContact) +{ + mir_cslock lck(m_csDbAccess); + if (hContact == 0) + hContact = (HANDLE)m_dbHeader.ofsUser; + + DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL); + return (dbc->signature != DBCONTACT_SIGNATURE) ? 0 : (HANDLE)dbc->ofsFirstEvent; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindFirstUnreadEvent(HANDLE hContact) +{ + mir_cslock lck(m_csDbAccess); + if (hContact == 0) + hContact = (HANDLE)m_dbHeader.ofsUser; + + DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); + return (dbc->signature != DBCONTACT_SIGNATURE) ? 0 : (HANDLE)dbc->ofsFirstUnreadEvent; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindLastEvent(HANDLE hContact) +{ + mir_cslock lck(m_csDbAccess); + if (hContact == 0) + hContact = (HANDLE)m_dbHeader.ofsUser; + + DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); + return (dbc->signature != DBCONTACT_SIGNATURE) ? 0 : (HANDLE)dbc->ofsLastEvent; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindNextEvent(HANDLE hDbEvent) +{ + mir_cslock lck(m_csDbAccess); + DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); + return (dbe->signature != DBEVENT_SIGNATURE) ? 0 : (HANDLE)dbe->ofsNext; +} + +STDMETHODIMP_(HANDLE) CDdxMmap::FindPrevEvent(HANDLE hDbEvent) +{ + mir_cslock lck(m_csDbAccess); + DBEvent *dbe = (DBEvent*)DBRead(hDbEvent,sizeof(DBEvent),NULL); + if (dbe->signature != DBEVENT_SIGNATURE) return 0; + return (dbe->flags & DBEF_FIRST) ? 0 : (HANDLE)dbe->ofsPrev; +} diff --git a/plugins/Db3x_mmap/src/dbheaders.cpp b/plugins/Db3x_mmap/src/dbheaders.cpp new file mode 100644 index 0000000000..3d18a373fa --- /dev/null +++ b/plugins/Db3x_mmap/src/dbheaders.cpp @@ -0,0 +1,65 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +//the cache has not been loaded when these functions are used + +extern DBSignature dbSignature; + +int CDdxMmap::CreateDbHeaders() +{ + DBContact user; + DWORD bytesWritten; + + CopyMemory(m_dbHeader.signature, &dbSignature,sizeof(m_dbHeader.signature)); + m_dbHeader.version = DB_THIS_VERSION; + m_dbHeader.ofsFileEnd = sizeof(struct DBHeader); + m_dbHeader.slackSpace = 0; + m_dbHeader.contactCount = 0; + m_dbHeader.ofsFirstContact = 0; + m_dbHeader.ofsFirstModuleName = 0; + m_dbHeader.ofsUser = 0; + //create user + m_dbHeader.ofsUser = m_dbHeader.ofsFileEnd; + m_dbHeader.ofsFileEnd += sizeof(DBContact); + SetFilePointer(m_hDbFile,0,NULL,FILE_BEGIN); + WriteFile(m_hDbFile,&m_dbHeader,sizeof(m_dbHeader),&bytesWritten,NULL); + user.signature = DBCONTACT_SIGNATURE; + user.ofsNext = 0; + user.ofsFirstSettings = 0; + user.eventCount = 0; + user.ofsFirstEvent = user.ofsLastEvent = 0; + SetFilePointer(m_hDbFile,m_dbHeader.ofsUser,NULL,FILE_BEGIN); + WriteFile(m_hDbFile,&user,sizeof(DBContact),&bytesWritten,NULL); + FlushFileBuffers(m_hDbFile); + return 0; +} + +int CDdxMmap::CheckDbHeaders() +{ + if (memcmp(m_dbHeader.signature, &dbSignature, sizeof(m_dbHeader.signature))) return 1; + if (m_dbHeader.version != DB_THIS_VERSION) return 2; + if (m_dbHeader.ofsUser == 0) return 3; + return 0; +} diff --git a/plugins/Db3x_mmap/src/dbintf.cpp b/plugins/Db3x_mmap/src/dbintf.cpp new file mode 100644 index 0000000000..83ae3aa4ca --- /dev/null +++ b/plugins/Db3x_mmap/src/dbintf.cpp @@ -0,0 +1,174 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +DBSignature dbSignature = {"Miranda ICQ DB",0x1A}; + +static int stringCompare(const char* p1, const char* p2) +{ + return strcmp(p1+1, p2+1); +} + +static int stringCompare2(const char* p1, const char* p2) +{ + return strcmp(p1, p2); +} + +static int compareGlobals(const DBCachedGlobalValue* p1, const DBCachedGlobalValue* p2) +{ + return strcmp(p1->name, p2->name); +} + +static int ModCompare(const ModuleName *mn1, const ModuleName *mn2 ) +{ + return strcmp( mn1->name, mn2->name ); +} + +static int OfsCompare(const ModuleName *mn1, const ModuleName *mn2 ) +{ + return ( mn1->ofs - mn2->ofs ); +} + +CDdxMmap::CDdxMmap(const TCHAR* tszFileName) : + m_hDbFile(INVALID_HANDLE_VALUE), + m_safetyMode(TRUE), + m_lSettings(100, stringCompare), + m_lContacts(50, LIST::FTSortFunc(HandleKeySort)), + m_lGlobalSettings(50, compareGlobals), + m_lResidentSettings(50, stringCompare2), + m_lMods(50, ModCompare), + m_lOfs(50, OfsCompare) +{ + m_tszProfileName = mir_tstrdup(tszFileName); + + InitializeCriticalSection(&m_csDbAccess); + + SYSTEM_INFO sinf; + GetSystemInfo(&sinf); + m_ChunkSize = sinf.dwAllocationGranularity; + + m_codePage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0); + m_hCacheHeap = HeapCreate(0, 0, 0); + m_hModHeap = HeapCreate(0,0,0); +} + +CDdxMmap::~CDdxMmap() +{ + // destroy settings + HeapDestroy(m_hCacheHeap); + m_lContacts.destroy(); + m_lSettings.destroy(); + m_lGlobalSettings.destroy(); + m_lResidentSettings.destroy(); + + // destroy modules + HeapDestroy(m_hModHeap); + m_lMods.destroy(); + m_lOfs.destroy(); + + // destroy map + KillTimer(NULL,m_flushBuffersTimerId); + if (m_pDbCache) { + FlushViewOfFile(m_pDbCache, 0); + UnmapViewOfFile(m_pDbCache); + } + if (m_hMap) + CloseHandle(m_hMap); + if (m_pNull) + free(m_pNull); + + // update profile last modified time + DWORD bytesWritten; + SetFilePointer(m_hDbFile, 0, NULL, FILE_BEGIN); + WriteFile(m_hDbFile, &dbSignature, 1, &bytesWritten, NULL); + CloseHandle(m_hDbFile); + + DeleteCriticalSection(&m_csDbAccess); + + mir_free(m_tszProfileName); +} + +int CDdxMmap::Load(bool bSkipInit) +{ + log0("DB logging running"); + + DWORD dummy = 0; + m_hDbFile = CreateFile(m_tszProfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); + if ( m_hDbFile == INVALID_HANDLE_VALUE ) + return 1; + + if ( !ReadFile(m_hDbFile,&m_dbHeader,sizeof(m_dbHeader),&dummy,NULL)) { + CloseHandle(m_hDbFile); + return 1; + } + + if ( !bSkipInit) { + if (InitCache()) return 1; + if (InitModuleNames()) return 1; + + hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED); + hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED); + hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); + + hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED); + hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED); + hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); + } + return 0; +} + +int CDdxMmap::Create() +{ + m_hDbFile = CreateFile(m_tszProfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); + return ( m_hDbFile == INVALID_HANDLE_VALUE ); +} + +STDMETHODIMP_(void) CDdxMmap::SetCacheSafetyMode(BOOL bIsSet) +{ + { mir_cslock lck(m_csDbAccess); + m_safetyMode = bIsSet; + } + DBFlush(1); +} + +void CDdxMmap::EncodeCopyMemory(void *dst, void *src, size_t size) +{ + MoveMemory(dst, src, size); +} + +void CDdxMmap::DecodeCopyMemory(void *dst, void *src, size_t size) +{ + MoveMemory(dst, src, size); +} + +void CDdxMmap::EncodeDBWrite(DWORD ofs, void *src, int size) +{ + DBWrite(ofs, src, size); +} + +void CDdxMmap::DecodeDBWrite(DWORD ofs, void *src, int size) +{ + DBWrite(ofs, src, size); +} + diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h new file mode 100644 index 0000000000..4dff427516 --- /dev/null +++ b/plugins/Db3x_mmap/src/dbintf.h @@ -0,0 +1,289 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +/* tree diagram + +DBHeader + |-->end of file (plain offset) + |-->first contact (DBContact) + | |-->next contact (DBContact) + | | \--> ... + | |-->first settings (DBContactSettings) + | | |-->next settings (DBContactSettings) + | | | \--> ... + | | \-->module name (DBModuleName) + | \-->first/last/firstunread event + |-->user contact (DBContact) + | |-->next contact = NULL + | |-->first settings as above + | \-->first/last/firstunread event as above + \-->first module name (DBModuleName) + \-->next module name (DBModuleName) + \--> ... +*/ + +#define DB_THIS_VERSION 0x00000700u +#define DB_SETTINGS_RESIZE_GRANULARITY 128 + +struct DBSignature { + char name[15]; + BYTE eof; +}; + +struct ModuleName +{ + char *name; + DWORD ofs; +}; + +#include +struct DBHeader { + BYTE signature[16]; // 'Miranda ICQ DB',0,26 + DWORD version; //as 4 bytes, ie 1.2.3.10 = 0x0102030a + //this version is 0x00000700 + DWORD ofsFileEnd; //offset of the end of the database - place to write + //new structures + DWORD slackSpace; //a counter of the number of bytes that have been + //wasted so far due to deleting structures and/or + //re-making them at the end. We should compact when + //this gets above a threshold + DWORD contactCount; //number of contacts in the chain,excluding the user + DWORD ofsFirstContact; //offset to first DBContact in the chain + DWORD ofsUser; //offset to DBContact representing the user + DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain +}; + +#define DBCONTACT_SIGNATURE 0x43DECADEu + +struct DBContact +{ + DWORD signature; + DWORD ofsNext; //offset to the next contact in the chain. zero if + //this is the 'user' contact or the last contact + //in the chain + DWORD ofsFirstSettings; //offset to the first DBContactSettings in the + //chain for this contact. + DWORD eventCount; //number of events in the chain for this contact + DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in + //the chain for this contact + DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event + //in the chain, 0 if all are read + DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent +}; + +#define DBMODULENAME_SIGNATURE 0x4DDECADEu +struct DBModuleName +{ + DWORD signature; + DWORD ofsNext; //offset to the next module name in the chain + BYTE cbName; //number of characters in this module name + char name[1]; //name, no nul terminator +}; + +#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu +struct DBContactSettings +{ + DWORD signature; + DWORD ofsNext; //offset to the next contactsettings in the chain + DWORD ofsModuleName; //offset to the DBModuleName of the owner of these + //settings + DWORD cbBlob; //size of the blob in bytes. May be larger than the + //actual size for reducing the number of moves + //required using granularity in resizing + BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting + //structs, the last has cbName = 0 +}; + +#define DBEVENT_SIGNATURE 0x45DECADEu +struct DBEvent +{ + DWORD signature; + DWORD ofsPrev,ofsNext; //offset to the previous and next events in the + //chain. Chain is sorted chronologically + DWORD ofsModuleName; //offset to a DBModuleName struct of the name of + //the owner of this event + DWORD timestamp; //seconds since 00:00:00 01/01/1970 + DWORD flags; //see m_database.h, db/event/add + WORD eventType; //module-defined event type + DWORD cbBlob; //number of bytes in the blob + BYTE blob[1]; //the blob. module-defined formatting +}; + +#include + +struct DBCachedGlobalValue +{ + char* name; + DBVARIANT value; +}; + +struct DBCachedContactValue +{ + char* name; + DBVARIANT value; + DBCachedContactValue* next; +}; + +struct DBCachedContactValueList +{ + HANDLE hContact; + HANDLE hNext; + DBCachedContactValue* first; + DBCachedContactValue* last; +}; + +#define MAXCACHEDREADSIZE 65536 + +struct CDdxMmap : public MIDatabase, public MZeroedObject +{ + CDdxMmap(const TCHAR* tszFileName); + ~CDdxMmap(); + + int Load(bool bSkipInit); + int Create(void); + int CreateDbHeaders(); + int CheckDbHeaders(); + void DatabaseCorruption(TCHAR *text); +protected: + STDMETHODIMP_(void) SetCacheSafetyMode(BOOL); + + STDMETHODIMP_(LONG) GetContactCount(void); + STDMETHODIMP_(HANDLE) FindFirstContact(const char* szProto = NULL); + STDMETHODIMP_(HANDLE) FindNextContact(HANDLE hContact, const char* szProto = NULL); + STDMETHODIMP_(LONG) DeleteContact(HANDLE hContact); + STDMETHODIMP_(HANDLE) AddContact(void); + STDMETHODIMP_(BOOL) IsDbContact(HANDLE hContact); + + STDMETHODIMP_(LONG) GetEventCount(HANDLE hContact); + STDMETHODIMP_(HANDLE) AddEvent(HANDLE hContact, DBEVENTINFO *dbe); + STDMETHODIMP_(BOOL) DeleteEvent(HANDLE hContact, HANDLE hDbEvent); + STDMETHODIMP_(LONG) GetBlobSize(HANDLE hDbEvent); + STDMETHODIMP_(BOOL) GetEvent(HANDLE hDbEvent, DBEVENTINFO *dbe); + STDMETHODIMP_(BOOL) MarkEventRead(HANDLE hContact, HANDLE hDbEvent); + STDMETHODIMP_(HANDLE) GetEventContact(HANDLE hDbEvent); + STDMETHODIMP_(HANDLE) FindFirstEvent(HANDLE hContact); + STDMETHODIMP_(HANDLE) FindFirstUnreadEvent(HANDLE hContact); + STDMETHODIMP_(HANDLE) FindLastEvent(HANDLE hContact); + STDMETHODIMP_(HANDLE) FindNextEvent(HANDLE hDbEvent); + STDMETHODIMP_(HANDLE) FindPrevEvent(HANDLE hDbEvent); + + STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam); + + STDMETHODIMP_(BOOL) GetContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); + STDMETHODIMP_(BOOL) GetContactSettingStr(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); + STDMETHODIMP_(BOOL) GetContactSettingStatic(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); + STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv); + STDMETHODIMP_(BOOL) WriteContactSetting(HANDLE hContact, DBCONTACTWRITESETTING *dbcws); + STDMETHODIMP_(BOOL) DeleteContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs); + STDMETHODIMP_(BOOL) EnumContactSettings(HANDLE hContact, DBCONTACTENUMSETTINGS* dbces); + STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName); + STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam); + +protected: + virtual void EncodeCopyMemory(void *dst, void *src, size_t size); + virtual void DecodeCopyMemory(void *dst, void *src, size_t size); + virtual void EncodeDBWrite(DWORD ofs, void *src, int size); + virtual void DecodeDBWrite(DWORD ofs, void *src, int size); + +protected: + TCHAR* m_tszProfileName; + HANDLE m_hDbFile; + DBHeader m_dbHeader; + DWORD m_ChunkSize; + BOOL m_safetyMode; + + //////////////////////////////////////////////////////////////////////////// + // database stuff +public: + UINT_PTR m_flushBuffersTimerId; + DWORD m_flushFailTick; + PBYTE m_pDbCache; +protected: + PBYTE m_pNull; + HANDLE m_hMap; + DWORD m_dwFileSize; + + CRITICAL_SECTION m_csDbAccess; + + int CheckProto(HANDLE hContact, const char *proto); + DWORD CreateNewSpace(int bytes); + void DeleteSpace(DWORD ofs, int bytes); + DWORD ReallocSpace(DWORD ofs, int oldSize, int newSize); + + void Map(); + void ReMap(DWORD needed); + void DBMoveChunk(DWORD ofsDest, DWORD ofsSource, int bytes); + PBYTE DBRead(DWORD ofs, int bytesRequired, int *bytesAvail); + void DBWrite(DWORD ofs, PVOID pData, int bytes); + void DBFill(DWORD ofs, int bytes); + void DBFlush(int setting); + int InitCache(void); + + __forceinline PBYTE DBRead(HANDLE hContact, int bytesRequired, int *bytesAvail) + { return DBRead((DWORD)hContact, bytesRequired, bytesAvail); + } + + //////////////////////////////////////////////////////////////////////////// + // settings + + int m_codePage; + + HANDLE m_hCacheHeap; + HANDLE m_hLastCachedContact; + char* m_lastSetting; + DBCachedContactValueList *m_lastVL; + + LIST m_lContacts; + LIST m_lGlobalSettings; + LIST m_lSettings, m_lResidentSettings; + HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent; + + DWORD GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsModuleName); + char* InsertCachedSetting(const char* szName, size_t cbNameLen); + char* GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen); + void SetCachedVariant(DBVARIANT* s, DBVARIANT* d); + void FreeCachedVariant(DBVARIANT* V); + DBVARIANT* GetCachedValuePtr(HANDLE hContact, char* szSetting, int bAllocate); + int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic); + + //////////////////////////////////////////////////////////////////////////// + // contacts + + DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index); + + //////////////////////////////////////////////////////////////////////////// + // modules + + HANDLE m_hModHeap; + LIST m_lMods, m_lOfs; + HANDLE hEventAddedEvent, hEventDeletedEvent, hEventFilterAddedEvent; + ModuleName *m_lastmn; + + void AddToList(char *name, DWORD len, DWORD ofs); + DWORD FindExistingModuleNameOfs(const char *szName); + int InitModuleNames(void); + DWORD GetModuleNameOfs(const char *szName); + char *GetModuleNameByOfs(DWORD ofs); +}; diff --git a/plugins/Db3x_mmap/src/dbmodulechain.cpp b/plugins/Db3x_mmap/src/dbmodulechain.cpp new file mode 100644 index 0000000000..f8b25ef879 --- /dev/null +++ b/plugins/Db3x_mmap/src/dbmodulechain.cpp @@ -0,0 +1,138 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +void CDdxMmap::AddToList(char *name, DWORD len, DWORD ofs) +{ + ModuleName *mn = (ModuleName*)HeapAlloc(m_hModHeap,0,sizeof(ModuleName)); + mn->name = name; + mn->ofs = ofs; + + if (m_lMods.getIndex(mn) != -1) + DatabaseCorruption( _T("%s (Module Name not unique)")); + m_lMods.insert(mn); + + if (m_lOfs.getIndex(mn) != -1) + DatabaseCorruption( _T("%s (Module Offset not unique)")); + m_lOfs.insert(mn); +} + +int CDdxMmap::InitModuleNames(void) +{ + DWORD ofsThis = m_dbHeader.ofsFirstModuleName; + DBModuleName *dbmn = (struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL); + while (ofsThis) { + if (dbmn->signature != DBMODULENAME_SIGNATURE) + DatabaseCorruption(NULL); + + int nameLen = dbmn->cbName; + + char *mod = (char*)HeapAlloc(m_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); + } + return 0; +} + +DWORD CDdxMmap::FindExistingModuleNameOfs(const char *szName) +{ + ModuleName mn = { (char*)szName, 0 }; + if (m_lastmn && !strcmp(mn.name, m_lastmn->name)) + return m_lastmn->ofs; + + int index = m_lMods.getIndex(&mn); + if (index != -1) { + ModuleName *pmn = m_lMods[index]; + m_lastmn = pmn; + return pmn->ofs; + } + + return 0; +} + +//will create the offset if it needs to +DWORD CDdxMmap::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 = m_dbHeader.ofsFirstModuleName; + m_dbHeader.ofsFirstModuleName = ofsNew; + DBWrite(0,&m_dbHeader,sizeof(m_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(m_hModHeap,0,nameLen+1); + strcpy(mod,szName); + AddToList(mod, nameLen, ofsNew); + + //quit + return ofsNew; +} + +char* CDdxMmap::GetModuleNameByOfs(DWORD ofs) +{ + if (m_lastmn && m_lastmn->ofs == ofs) + return m_lastmn->name; + + ModuleName mn = {NULL, ofs}; + int index = m_lOfs.getIndex(&mn); + if (index != -1) { + ModuleName *pmn = m_lOfs[index]; + m_lastmn = pmn; + return pmn->name; + } + + DatabaseCorruption(NULL); + return NULL; +} + +STDMETHODIMP_(BOOL) CDdxMmap::EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) +{ + for (int i = 0; i < m_lMods.getCount(); i++) { + ModuleName *pmn = m_lMods[i]; + int ret = pFunc(pmn->name, pmn->ofs, (LPARAM)pParam); + if (ret) + return ret; + } + return 0; +} diff --git a/plugins/Db3x_mmap/src/dbsettings.cpp b/plugins/Db3x_mmap/src/dbsettings.cpp new file mode 100644 index 0000000000..49ac018047 --- /dev/null +++ b/plugins/Db3x_mmap/src/dbsettings.cpp @@ -0,0 +1,933 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +DWORD GetModuleNameOfs(const char *szName); +DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index); + +int DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); + +DWORD CDdxMmap::GetSettingsGroupOfsByModuleNameOfs(DBContact *dbc,DWORD ofsModuleName) +{ + DWORD ofsThis = dbc->ofsFirstSettings; + while (ofsThis) { + DBContactSettings *dbcs = (DBContactSettings*)DBRead(ofsThis,sizeof(DBContactSettings),NULL); + if (dbcs->signature != DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption(NULL); + if (dbcs->ofsModuleName == ofsModuleName) + return ofsThis; + + ofsThis = dbcs->ofsNext; + } + return 0; +} + +DWORD __forceinline GetSettingValueLength(PBYTE pSetting) +{ + if (pSetting[0] & DBVTF_VARIABLELENGTH) + return 2+*(PWORD)(pSetting+1); + return pSetting[0]; +} + +char* CDdxMmap::InsertCachedSetting(const char* szName, size_t cbNameLen) +{ + char* newValue = (char*)HeapAlloc(m_hCacheHeap, 0, cbNameLen); + *newValue = 0; + strcpy(newValue+1, szName+1); + m_lSettings.insert(newValue); + return newValue; +} + +char* CDdxMmap::GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen) +{ + char szFullName[512]; + strcpy(szFullName+1,szModuleName); + szFullName[moduleNameLen+1] = '/'; + strcpy(szFullName+moduleNameLen+2,szSettingName); + + if (m_lastSetting && strcmp(szFullName+1, m_lastSetting) == 0) + return m_lastSetting; + + int index = m_lSettings.getIndex(szFullName); + if (index != -1) + m_lastSetting = m_lSettings[index]+1; + else + m_lastSetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+3)+1; + + return m_lastSetting; +} + +void CDdxMmap::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(m_hCacheHeap,0,szSave,strlen(s->pszVal)+1); + else + d->pszVal = (char*)HeapAlloc(m_hCacheHeap,0,strlen(s->pszVal)+1); + strcpy(d->pszVal,s->pszVal); + } + else if ( szSave != NULL ) + HeapFree(m_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 CDdxMmap::FreeCachedVariant( DBVARIANT* V ) +{ + if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL ) + HeapFree(m_hCacheHeap,0,V->pszVal); +} + +DBVARIANT* CDdxMmap::GetCachedValuePtr( HANDLE hContact, char* szSetting, int bAllocate ) +{ + if ( hContact == 0 ) { + DBCachedGlobalValue Vtemp, *V; + Vtemp.name = szSetting; + int index = m_lGlobalSettings.getIndex(&Vtemp); + if (index != -1) { + V = m_lGlobalSettings[index]; + if ( bAllocate == -1 ) { + FreeCachedVariant( &V->value ); + m_lGlobalSettings.remove(index); + HeapFree(m_hCacheHeap,0,V); + return NULL; + } + } + else { + if ( bAllocate != 1 ) + return NULL; + + V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue)); + V->name = szSetting; + m_lGlobalSettings.insert(V); + } + + return &V->value; + } + else { + DBCachedContactValue *V, *V1; + DBCachedContactValueList VLtemp,*VL; + + if (m_hLastCachedContact == hContact && m_lastVL) + VL = m_lastVL; + else { + VLtemp.hContact = hContact; + + int index = m_lContacts.getIndex(&VLtemp); + if (index == -1) { + if ( bAllocate != 1 ) + return NULL; + + VL = AddToCachedContactList(hContact, index); + } + else VL = m_lContacts[index]; + + m_lastVL = VL; + m_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 = (DBCachedContactValue *)HeapAlloc(m_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 ) { + m_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(m_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) + +int CDdxMmap::GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic) +{ + 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; + } + + mir_cslock lck(m_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; + } + + return ( pCachedValue->type == DBVT_DELETED ) ? 1 : 0; + } } + + ofsModuleName = GetModuleNameOfs(dbcgs->szModule); + if (hContact == NULL) ofsContact = m_dbHeader.ofsUser; + else ofsContact = (DWORD)hContact; + dbc = (DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + return 1; + + ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); + if (ofsSettingsGroup) { + ofsBlobPtr = ofsSettingsGroup+offsetof(DBContactSettings,blob); + pBlob = DBRead(ofsBlobPtr,sizeof(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])) + return 1; + + dbcgs->pValue->type = pBlob[0]; + switch(pBlob[0]) { + case DBVT_DELETED: /* this setting is deleted */ + dbcgs->pValue->type = DBVT_DELETED; + 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 = (BYTE *)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); + } + + logg(); + return 0; + } + NeedBytes(1); + MoveAlong(pBlob[0]+1); + NeedBytes(3); + MoveAlong(1+GetSettingValueLength(pBlob)); + NeedBytes(1); + } } + + #ifndef DB3X_EXPORTS + /**** 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; + } + #endif + + /**** add missing setting to cache **********************/ + if ( dbcgs->pValue->type != DBVT_BLOB ) + { + DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 ); + if ( pCachedValue != NULL ) + pCachedValue->type = DBVT_DELETED; + } + + logg(); + return 1; +} + +STDMETHODIMP_(BOOL) CDdxMmap::GetContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dgs) +{ + dgs->pValue->type = 0; + if ( GetContactSettingWorker(hContact, dgs, 0 )) + return 1; + + if ( dgs->pValue->type == DBVT_UTF8 ) { + WCHAR* tmp = NULL; + char* p = NEWSTR_ALLOCA(dgs->pValue->pszVal); + if ( mir_utf8decode( p, &tmp ) != NULL ) { + BOOL bUsed = FALSE; + int result = WideCharToMultiByte( m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed ); + + mir_free( dgs->pValue->pszVal ); + + if ( bUsed || result == 0 ) { + dgs->pValue->type = DBVT_WCHAR; + dgs->pValue->pwszVal = tmp; + } + else { + dgs->pValue->type = DBVT_ASCIIZ; + dgs->pValue->pszVal = (char *)mir_alloc(result); + WideCharToMultiByte( m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dgs->pValue->pszVal, result, NULL, NULL ); + mir_free( tmp ); + } + } + else { + dgs->pValue->type = DBVT_ASCIIZ; + mir_free( tmp ); + } } + + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::GetContactSettingStr(HANDLE hContact, DBCONTACTGETSETTING *dgs) +{ + int iSaveType = dgs->pValue->type; + + if ( GetContactSettingWorker(hContact, dgs, 0 )) + return 1; + + if ( iSaveType == 0 || iSaveType == dgs->pValue->type ) + return 0; + + if ( dgs->pValue->type != DBVT_ASCIIZ && dgs->pValue->type != DBVT_UTF8 ) + return 1; + + if ( iSaveType == DBVT_WCHAR ) { + if ( dgs->pValue->type != DBVT_UTF8 ) { + int len = MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, NULL, 0 ); + wchar_t* wszResult = ( wchar_t* )mir_alloc(( len+1 )*sizeof( wchar_t )); + if ( wszResult == NULL ) + return 1; + + MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, wszResult, len ); + wszResult[ len ] = 0; + mir_free( dgs->pValue->pszVal ); + dgs->pValue->pwszVal = wszResult; + } + else { + char* savePtr = NEWSTR_ALLOCA(dgs->pValue->pszVal); + mir_free( dgs->pValue->pszVal ); + if ( !mir_utf8decode( savePtr, &dgs->pValue->pwszVal )) + return 1; + } + } + else if ( iSaveType == DBVT_UTF8 ) { + char* tmpBuf = mir_utf8encode( dgs->pValue->pszVal ); + if ( tmpBuf == NULL ) + return 1; + + mir_free( dgs->pValue->pszVal ); + dgs->pValue->pszVal = tmpBuf; + } + else if ( iSaveType == DBVT_ASCIIZ ) + mir_utf8decode( dgs->pValue->pszVal, NULL ); + + dgs->pValue->type = iSaveType; + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::GetContactSettingStatic(HANDLE hContact, DBCONTACTGETSETTING *dgs) +{ + if ( GetContactSettingWorker(hContact, dgs, 1 )) + return 1; + + if ( dgs->pValue->type == DBVT_UTF8 ) { + mir_utf8decode( dgs->pValue->pszVal, NULL ); + dgs->pValue->type = DBVT_ASCIIZ; + } + + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::FreeVariant(DBVARIANT *dbv) +{ + if ( dbv == 0 ) return 1; + switch ( dbv->type ) { + case DBVT_ASCIIZ: + case DBVT_UTF8: + case DBVT_WCHAR: + { + if ( dbv->pszVal ) mir_free(dbv->pszVal); + dbv->pszVal = 0; + break; + } + case DBVT_BLOB: + { + if ( dbv->pbVal ) mir_free(dbv->pbVal); + dbv->pbVal = 0; + break; + } + } + dbv->type = 0; + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::SetSettingResident(BOOL bIsResident, const char *pszSettingName) +{ + size_t cbSettingNameLen = strlen(pszSettingName) + 2; + if (cbSettingNameLen < 512) { + char* szSetting; + char szTemp[512]; + strcpy( szTemp+1, pszSettingName); + + mir_cslock lck(m_csDbAccess); + int idx = m_lSettings.getIndex(szTemp); + if (idx == -1) + szSetting = InsertCachedSetting( szTemp, cbSettingNameLen); + else + szSetting = m_lSettings[idx]; + + *szSetting = (char)bIsResident; + + idx = m_lResidentSettings.getIndex(szSetting+1); + if (idx == -1) { + if (bIsResident) + m_lResidentSettings.insert(szSetting+1); + } + else if (!bIsResident) + m_lResidentSettings.remove(idx); + } + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::WriteContactSetting(HANDLE hContact, DBCONTACTWRITESETTING *dbcws) +{ + DBCONTACTWRITESETTING tmp; + DWORD ofsModuleName; + 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 ) ? strlen(tmp.value.pszVal) : tmp.value.cpbVal; + if ( len >= 0xFFFF ) { + #ifdef _DEBUG + OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n"); + #endif + return 1; + } + } + } + + mir_cslockfull lck(m_csDbAccess); + + char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen); + if ( tmp.value.type != DBVT_BLOB ) { + DBVARIANT* pCachedValue = GetCachedValuePtr(hContact, szCachedSettingName, 1); + if ( pCachedValue != NULL ) { + BOOL bIsIdentical = FALSE; + if ( pCachedValue->type == tmp.value.type ) { + switch(tmp.value.type) { + case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == tmp.value.bVal; break; + case DBVT_WORD: bIsIdentical = pCachedValue->wVal == tmp.value.wVal; break; + case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == tmp.value.dVal; break; + case DBVT_UTF8: + case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, tmp.value.pszVal ) == 0; break; + } + if ( bIsIdentical ) + return 0; + } + SetCachedVariant(&tmp.value, pCachedValue); + } + if ( szCachedSettingName[-1] != 0 ) { + lck.unlock(); + NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); + return 0; + } + } + else GetCachedValuePtr(hContact, szCachedSettingName, -1); + + ofsModuleName = GetModuleNameOfs(tmp.szModule); + if (hContact == 0) ofsContact = m_dbHeader.ofsUser; + else ofsContact = (DWORD)hContact; + + DBContact dbc = *(DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); + if (dbc.signature != DBCONTACT_SIGNATURE) + 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(DBContactSettings,blob)); + dbcs.signature = DBCONTACTSETTINGS_SIGNATURE; + dbcs.ofsNext = dbc.ofsFirstSettings; + dbcs.ofsModuleName = ofsModuleName; + dbcs.cbBlob = bytesRequired; + dbcs.blob[0] = 0; + dbc.ofsFirstSettings = ofsSettingsGroup; + DBWrite(ofsContact,&dbc,sizeof(DBContact)); + DBWrite(ofsSettingsGroup,&dbcs,sizeof(DBContactSettings)); + ofsBlobPtr = ofsSettingsGroup+offsetof(DBContactSettings,blob); + pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); + } + else { + dbcs = *(DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(DBContactSettings),&bytesRemaining); + //find if the setting exists + ofsBlobPtr = ofsSettingsGroup+offsetof(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); + lck.unlock(); + //notify + NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp); + return 0; + } + } + } + //cannot do a simple replace, add setting to end of list + //pBlob already points to end of list + //see if it fits + if (tmp.value.type&DBVTF_VARIABLELENGTH) { + if (tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8) bytesRequired = (int)strlen(tmp.value.pszVal)+2; + else if (tmp.value.type == DBVT_BLOB) bytesRequired = tmp.value.cpbVal+2; + } + else bytesRequired = tmp.value.type; + bytesRequired += 2+settingNameLen; + bytesRequired += ofsBlobPtr+1-(ofsSettingsGroup+offsetof(DBContactSettings,blob)); + if ((DWORD)bytesRequired > dbcs.cbBlob) { + //doesn't fit: move entire group + 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 = (DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(DBContactSettings),NULL); + while (dbcsPrev->ofsNext != ofsSettingsGroup) { + if (dbcsPrev->ofsNext == 0) DatabaseCorruption(NULL); + ofsDbcsPrev = dbcsPrev->ofsNext; + dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(DBContactSettings),NULL); + } + } + + //create the new one + ofsNew = ReallocSpace(ofsSettingsGroup, dbcs.cbBlob+offsetof(DBContactSettings,blob), bytesRequired+offsetof(DBContactSettings,blob)); + + dbcs.cbBlob = bytesRequired; + + DBWrite(ofsNew,&dbcs,offsetof(DBContactSettings,blob)); + if (ofsDbcsPrev == 0) { + dbc.ofsFirstSettings = ofsNew; + DBWrite(ofsContact,&dbc,sizeof(DBContact)); + } + else { + dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(DBContactSettings),NULL); + dbcsPrev->ofsNext = ofsNew; + DBWrite(ofsDbcsPrev,dbcsPrev,offsetof(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); + lck.unlock(); + + //notify + NotifyEventHooks(hSettingChangeEvent, (WPARAM)hContact, (LPARAM)&tmp ); + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::DeleteContactSetting(HANDLE hContact, DBCONTACTGETSETTING *dbcgs) +{ + DBContact *dbc; + DWORD ofsModuleName,ofsSettingsGroup,ofsBlobPtr; + PBYTE pBlob; + int settingNameLen,moduleNameLen,bytesRemaining; + char* szCachedSettingName; + WPARAM saveWparam = (WPARAM)hContact; + + 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; + } + + mir_cslockfull lck(m_csDbAccess); + ofsModuleName = GetModuleNameOfs(dbcgs->szModule); + if (hContact == 0) + hContact = (HANDLE)m_dbHeader.ofsUser; + + dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + return 1; + + //make sure the module group exists + ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); + if (ofsSettingsGroup == 0) + return 1; + + //find if the setting exists + ofsBlobPtr = ofsSettingsGroup+offsetof(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 + 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); + lck.unlock(); + + //notify + DBCONTACTWRITESETTING dbcws = {0}; + dbcws.szModule = dbcgs->szModule; + dbcws.szSetting = dbcgs->szSetting; + dbcws.value.type = DBVT_DELETED; + NotifyEventHooks(hSettingChangeEvent,saveWparam,(LPARAM)&dbcws); + return 0; +} + +STDMETHODIMP_(BOOL) CDdxMmap::EnumContactSettings(HANDLE hContact, DBCONTACTENUMSETTINGS* dbces) +{ + DBContact *dbc; + DWORD ofsModuleName,ofsContact,ofsBlobPtr; + int bytesRemaining, result; + PBYTE pBlob; + char szSetting[256]; + + if (!dbces->szModule) + return -1; + + mir_cslock lck(m_csDbAccess); + + ofsModuleName = GetModuleNameOfs(dbces->szModule); + if (hContact == 0) ofsContact = m_dbHeader.ofsUser; + else ofsContact = (DWORD)hContact; + dbc = (DBContact*)DBRead(ofsContact,sizeof(DBContact),NULL); + if (dbc->signature != DBCONTACT_SIGNATURE) + return -1; + + dbces->ofsSettings = GetSettingsGroupOfsByModuleNameOfs(dbc,ofsModuleName); + if ( !dbces->ofsSettings) + return -1; + + ofsBlobPtr = dbces->ofsSettings+offsetof(DBContactSettings,blob); + pBlob = (PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); + if (pBlob[0] == 0) + 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); + } + return result; +} + +STDMETHODIMP_(BOOL) CDdxMmap::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) +{ + for(int i = 0; i < m_lResidentSettings.getCount(); i++) { + int ret = pFunc(m_lResidentSettings[i], 0, (LPARAM)pParam); + if (ret) return ret; + } + return 0; +} diff --git a/plugins/Db3x_mmap/src/init.cpp b/plugins/Db3x_mmap/src/init.cpp new file mode 100644 index 0000000000..b38fab0ce2 --- /dev/null +++ b/plugins/Db3x_mmap/src/init.cpp @@ -0,0 +1,160 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +int hLangpack; + +static PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + "Miranda NG mmap database driver", + __VERSION_DWORD, + "Provides Miranda database support: global settings, contacts, history, settings per contact.", + "Miranda-NG project", + "bio@msx.ru; ghazan@miranda.im", + "Copyright 2012 Miranda NG project", + "", + UNICODE_AWARE, + {0xf7a6b27c, 0x9d9c, 0x4a42, { 0xbe, 0x86, 0xa4, 0x48, 0xae, 0x10, 0x91, 0x61 }} //{F7A6B27C-9D9C-4a42-BE86-A448AE109161} +}; + +HINSTANCE g_hInst = NULL; + +LIST g_Dbs(1, (LIST::FTSortFunc)HandleKeySort); + +///////////////////////////////////////////////////////////////////////////////////////// + +// returns 0 if the profile is created, EMKPRF* +static int makeDatabase(const TCHAR *profile, int *error) +{ + CDdxMmap *tmp = new CDdxMmap(profile); + if (tmp->Create() == ERROR_SUCCESS) { + tmp->CreateDbHeaders(); + delete tmp; + return 0; + } + delete tmp; + if (error != NULL) *error = EMKPRF_CREATEFAILED; + return 1; +} + +// returns 0 if the given profile has a valid header +static int grokHeader(const TCHAR *profile, int *error) +{ + CDdxMmap *tmp = new CDdxMmap(profile); + if (tmp->Load(true) != ERROR_SUCCESS) { + delete tmp; + if (error != NULL) *error = EGROKPRF_CANTREAD; + return 1; + } + + int chk = tmp->CheckDbHeaders(); + delete tmp; + if ( chk == 0 ) { + // all the internal tests passed, hurrah + if (error != NULL) *error = 0; + return 0; + } + + // didn't pass at all, or some did. + switch ( chk ) { + case 1: + // "Miranda ICQ DB" wasn't present + if (error != NULL) *error = EGROKPRF_UNKHEADER; + break; + + case 2: + // header was present, but version information newer + if (error != NULL) *error = EGROKPRF_VERNEWER; + break; + + case 3: + // header/version OK, internal data missing + if (error != NULL) *error = EGROKPRF_DAMAGED; + break; + } + + return 1; +} + +// returns 0 if all the APIs are injected otherwise, 1 +static MIDatabase* LoadDatabase(const TCHAR *profile) +{ + // set the memory, lists & UTF8 manager + mir_getLP( &pluginInfo ); + + CDdxMmap* db = new CDdxMmap(profile); + if (db->Load(false) != ERROR_SUCCESS) { + delete db; + return NULL; + } + + g_Dbs.insert(db); + return db; +} + +static int UnloadDatabase(MIDatabase* db) +{ + g_Dbs.remove((CDdxMmap*)db); + delete (CDdxMmap*)db; + return 0; +} + +static DATABASELINK dblink = +{ + sizeof(DATABASELINK), + "db3x mmap driver", + _T("db3x mmap database support"), + makeDatabase, + grokHeader, + LoadDatabase, + UnloadDatabase +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_DATABASE, MIID_LAST}; + +extern "C" __declspec(dllexport) int Load(void) +{ + RegisterDatabasePlugin(&dblink); + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + g_Dbs.destroy(); + return 0; +} + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) +{ + g_hInst = hInstDLL; + return TRUE; +} diff --git a/plugins/Db3x_mmap/src/resource.h b/plugins/Db3x_mmap/src/resource.h new file mode 100644 index 0000000000..96abbfff99 --- /dev/null +++ b/plugins/Db3x_mmap/src/resource.h @@ -0,0 +1,30 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDC_NOTOALL 3 +#define IDD_INSTALLINI 235 +#define IDD_WARNINICHANGE 236 +#define IDD_INIIMPORTDONE 237 +#define IDC_ININAME 1333 +#define IDC_VIEWINI 1334 +#define IDC_SECURITYINFO 1335 +#define IDC_SETTINGNAME 1336 +#define IDC_NEWVALUE 1337 +#define IDC_WARNNOMORE 1338 +#define IDC_DELETE 1339 +#define IDC_RECYCLE 1340 +#define IDC_NEWNAME 1341 +#define IDC_MOVE 1342 +#define IDC_LEAVE 1343 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 269 +#define _APS_NEXT_COMMAND_VALUE 40018 +#define _APS_NEXT_CONTROL_VALUE 1657 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/Db3x_mmap/src/version.h b/plugins/Db3x_mmap/src/version.h new file mode 100644 index 0000000000..2d10138fcf --- /dev/null +++ b/plugins/Db3x_mmap/src/version.h @@ -0,0 +1,5 @@ +#include "m_version.h" + +#define __FILEVERSION_STRING MIRANDA_VERSION_FILEVERSION +#define __VERSION_STRING MIRANDA_VERSION_STRING +#define __VERSION_DWORD MIRANDA_VERSION_DWORD diff --git a/plugins/Db3x_mmap/version.h b/plugins/Db3x_mmap/version.h deleted file mode 100644 index 2d10138fcf..0000000000 --- a/plugins/Db3x_mmap/version.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "m_version.h" - -#define __FILEVERSION_STRING MIRANDA_VERSION_FILEVERSION -#define __VERSION_STRING MIRANDA_VERSION_STRING -#define __VERSION_DWORD MIRANDA_VERSION_DWORD diff --git a/plugins/Db3x_mmap/version.rc b/plugins/Db3x_mmap/version.rc deleted file mode 100644 index 21a71416b5..0000000000 --- a/plugins/Db3x_mmap/version.rc +++ /dev/null @@ -1,42 +0,0 @@ -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - -#include -#include "version.h" - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION __FILEVERSION_STRING - PRODUCTVERSION __FILEVERSION_STRING - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "041904b0" - BEGIN - VALUE "FileDescription", "Miranda NG Mmap DataBase Engine 3x" - VALUE "FileVersion", __VERSION_STRING - VALUE "LegalCopyright", "Copyright (C) 2012" - VALUE "OriginalFilename", "dbx_mmap.dll" - VALUE "ProductName", "Miranda NG Mmap DataBase Engine 3x" - VALUE "ProductVersion", __VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x419, 1200 - END -END diff --git a/plugins/Db_autobackups/backup.cpp b/plugins/Db_autobackups/backup.cpp deleted file mode 100644 index a6b78dace2..0000000000 --- a/plugins/Db_autobackups/backup.cpp +++ /dev/null @@ -1,230 +0,0 @@ -#include "headers.h" -#include - -TCHAR dbname[MAX_PATH]; - -static UINT_PTR timer_id; - -INT_PTR CALLBACK DlgProcProgress(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) { - case WM_INITDIALOG: - { - HWND prog = GetDlgItem(hwndDlg, IDC_PROGRESS); - TranslateDialogDefault( hwndDlg ); - SendMessage(prog, PBM_SETPOS, 0, 0); - } - break; - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == IDCANCEL ) { - // in the progress dialog, use the user data to indicate that the user has pressed cancel - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)1); - return TRUE; - } - break; - } - return FALSE; -} - -INT_PTR DBSaveAs(WPARAM wParam, LPARAM lParam) -{ - HWND progress_dialog = 0; - TCHAR fname_buff[MAX_PATH], szFilter[128]; - int i; - OPENFILENAME ofn = {0}; - CallService(MS_DB_GETPROFILENAMET,MAX_PATH,(LPARAM)fname_buff); - - i = mir_sntprintf(szFilter, 64, _T("%s (*.dat)"), TranslateT("Miranda Databases")) + 1; - _tcscpy(szFilter + i, _T("*.dat")); - i += 6; - i += mir_sntprintf(szFilter + i, 48, _T("%s (*.*)"), TranslateT("All Files")) + 1; - _tcscpy(szFilter + i, _T("*")); - szFilter[i + 2] = 0; - - ofn.lStructSize = sizeof(ofn); - ofn.lpstrFile = fname_buff; - ofn.nMaxFile = MAX_PATH; - ofn.Flags = OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT; - ofn.lpstrFilter = szFilter; - ofn.nFilterIndex = 1; - ofn.lpstrDefExt = _T("dat"); - - if (GetSaveFileName(&ofn)) - Backup(fname_buff); - - return 0; -} - -struct FileNameFound_Tag -{ - TCHAR Name[MAX_PATH]; - FILETIME CreationTime; -}FileNameFound; - -int RotateBackups(HWND progress_dialog, DWORD start_time) -{ - TCHAR backupfilename1[MAX_PATH] = {0}, backupfilename2[MAX_PATH] = {0}, backupfolderTmp[MAX_PATH] = {0}; - TCHAR* backupfolder; - unsigned int i = 0; - HWND prog = GetDlgItem(progress_dialog, IDC_PROGRESS); - MSG msg; - - WIN32_FIND_DATA FindFileData; - HANDLE hFind; - - backupfolder = Utils_ReplaceVarsT(options.folder); - - mir_sntprintf(backupfolderTmp, SIZEOF(backupfolderTmp), _T("%s\\*"), backupfolder); - hFind = FindFirstFile(backupfolderTmp, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) - return 0; - _tcscpy(FileNameFound.Name, _T("")); - while (FindNextFile(hFind, &FindFileData)) - { - if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - else if (_tcsicmp(&FindFileData.cFileName[_tcslen(FindFileData.cFileName)-4], _T(".bak")) == 0) - { - if (_tcsicmp(FileNameFound.Name, _T("")) == 0) - { - _tcscpy(FileNameFound.Name, FindFileData.cFileName); - FileNameFound.CreationTime = FindFileData.ftCreationTime; - } - else if ((FindFileData.ftCreationTime.dwHighDateTime < FileNameFound.CreationTime.dwHighDateTime) || (FindFileData.ftCreationTime.dwHighDateTime == FileNameFound.CreationTime.dwHighDateTime && FindFileData.ftCreationTime.dwLowDateTime < FileNameFound.CreationTime.dwLowDateTime)) - { - _tcscpy(FileNameFound.Name, FindFileData.cFileName); - FileNameFound.CreationTime = FindFileData.ftCreationTime; - } - i++; - while(PeekMessage(&msg, progress_dialog, 0, 0, PM_REMOVE) != 0) - { - if (!IsDialogMessage(progress_dialog, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - SendMessage(prog, PBM_SETPOS, (WPARAM)(int)(100 * (options.num_backups - i) / options.num_backups), 0); - UpdateWindow(progress_dialog); - } - } - - FindClose(hFind); - if (i >= options.num_backups) - { - mir_sntprintf(backupfilename1, MAX_PATH, _T("%s\\%s"), backupfolder, FileNameFound.Name); - DeleteFile(backupfilename1); - } - mir_free(backupfolder); - return 0; -} - -int Backup(TCHAR* backup_filename) -{ - TCHAR source_file[MAX_PATH] = {0}, dest_file[MAX_PATH] = {0}; - TCHAR* backupfolder,* pathtmp,* puText; - HWND progress_dialog; - DWORD start_time = GetTickCount(); - int i; - size_t dest_file_len; - - CallService(MS_DB_GETPROFILENAMET, MAX_PATH, (LPARAM)dbname); - - if (backup_filename == NULL) - { - int err = 0; - - SYSTEMTIME st; - TCHAR buffer[MAX_COMPUTERNAME_LENGTH+1]; - DWORD size = sizeof(buffer); - - backupfolder = Utils_ReplaceVarsT(options.folder); - // ensure the backup folder exists (either create it or return non-zero signifying error) - err = CreateDirectoryTree(backupfolder); - if(err != ERROR_ALREADY_EXISTS && err != 0) { - return 1; - } - - GetLocalTime(&st); - GetComputerName(buffer, &size); - mir_sntprintf(dest_file, MAX_PATH, _T("%s\\%s_%02d.%02d.%02d@%02d-%02d-%02d_%s.bak"), backupfolder, dbname, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, buffer); - mir_free(backupfolder); - } - else - lstrcpyn(dest_file, backup_filename, MAX_PATH); - - if (!options.disable_popups) - ShowPopup(dbname, TranslateT("Backup in Progress")); - - if (!options.disable_progress) { - progress_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_COPYPROGRESS), 0, (DLGPROC)DlgProcProgress); - SetDlgItemText(progress_dialog, IDC_PROGRESSMESSAGE, TranslateT("Rotating backup files...")); - } - - RotateBackups(progress_dialog, start_time); - - SetDlgItemText(progress_dialog, 0xDAED, TranslateT("Copying database file...")); - SendMessage(progress_dialog, PBM_SETPOS, (WPARAM)(int)(0), 0); - UpdateWindow(progress_dialog); - - mir_sntprintf(source_file, MAX_PATH, _T("%s\\%s"), profilePath, dbname); - pathtmp = Utils_ReplaceVarsT(source_file); - if (CopyFile(pathtmp, dest_file, 0)) - { - SendMessage(progress_dialog, PBM_SETPOS, (WPARAM)(int)(100), 0); - UpdateWindow(progress_dialog); - DBWriteContactSettingDword(0, "AutoBackups", "LastBackupTimestamp", (DWORD)time(0)); - if (!options.disable_popups) - { - dest_file_len = lstrlen(dest_file); - if(dest_file_len > 50) - { - puText = (TCHAR*)mir_alloc(sizeof(TCHAR) * (dest_file_len + 2)); - for(i = (int)dest_file_len - 1; dest_file[i] != _T('\\'); i--); - - lstrcpyn(puText, dest_file, i + 2); - lstrcat(puText, _T("\n")); - lstrcat(puText, dest_file + i + 1); - } - else - puText = mir_tstrdup(dest_file); - - ShowPopup(puText, TranslateT("Database backuped")); - mir_free(puText); - } - } - else - DeleteFile(dest_file); - mir_free(pathtmp); - - DestroyWindow(progress_dialog); - return 0; -} - -VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { - time_t t = time(0), diff = t - (time_t)DBGetContactSettingDword(0, "AutoBackups", "LastBackupTimestamp", (DWORD)t); - if(diff > (time_t)(options.period * (options.period_type == PT_MINUTES ? 60 : (options.period_type == PT_HOURS ? 60 * 60 : 60 * 60 * 24 )))) - Backup(NULL); -} - -int SetBackupTimer(void) -{ - if(options.backup_types & BT_PERIODIC) - { - if(timer_id == 0) - timer_id = SetTimer(0, 0, 1000 * 60, TimerProc); - } - else if(timer_id != 0) - { - KillTimer(0, timer_id); - timer_id = 0; - } - return 0; -} - -INT_PTR ABService(WPARAM wParam, LPARAM lParam) -{ - Backup((TCHAR*)wParam); - return 0; -} diff --git a/plugins/Db_autobackups/db_autobackups-translation.txt b/plugins/Db_autobackups/db_autobackups-translation.txt deleted file mode 100644 index c9281a611a..0000000000 --- a/plugins/Db_autobackups/db_autobackups-translation.txt +++ /dev/null @@ -1,50 +0,0 @@ -; Common strings that belong to many files -;[] - -; ../../plugins/Db_autobackups/backup.cpp -;[All Files] -;[Backup in Progress] -;[Copying database file...] -;[Database backuped] -;[Miranda Databases] -;[Rotating backup files...] - -; ../../plugins/Db_autobackups/db_autobackups.rc -;[Automatic Backups] -;[Backup NOW] -;[Backup progress] -;[Backup to folder:] -;[Browse...] -;[Cancel] -;[Disable Popups] -;[Disable progress bar] -;[Disabled] -;[Every:] -;[Go to the \"Customize -> Folders\" to change settings] -;[Number of backups to keep:] -;[When Miranda exits] -;[When Miranda starts] - -; ../../plugins/Db_autobackups/main.cpp -;[Backup Profile] -;[Database] -;[Save Profile As...] - -; ../../plugins/Db_autobackups/options.cpp -;[Database AutoBackups] -;[Days] -;[Error Creating Backup Folder] -;[Hours] -;[Minutes] -;[Select Backup Folder] -;[Services] -;[Variables] -;[\"Desktop\" folder for currently logged-on Windows user] -;[\"My Documents\" folder for currently logged-on Windows user] -;[any environment variable defined in current Windows session (like %systemroot%, %allusersprofile%, etc.)] -;[name of current miranda profile (filename, without extension)] -;[path to current miranda profile] -;[path to root miranda folder] -;[same as environment variable %APPDATA% for currently logged-on Windows user] -;[username for currently logged-on Windows user] -;[will return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%] diff --git a/plugins/Db_autobackups/db_autobackups.rc b/plugins/Db_autobackups/db_autobackups.rc deleted file mode 100644 index 714f4a3505..0000000000 --- a/plugins/Db_autobackups/db_autobackups.rc +++ /dev/null @@ -1,182 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_COPYPROGRESS DIALOGEX 0, 0, 186, 58 -STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Backup progress" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,24,172,9 - CTEXT "",IDC_PROGRESSMESSAGE,31,7,114,13 - PUSHBUTTON "Cancel",IDCANCEL,58,39,67,12 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_COPYPROGRESS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 179 - TOPMARGIN, 7 - BOTTOMMARGIN, 51 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON1 ICON "icos\\backup.ico" -#endif // Russian resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPTIONS DIALOGEX 0, 0, 271, 193 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x0 -BEGIN - GROUPBOX "Automatic Backups",IDC_STATIC,6,7,258,179,WS_GROUP - RTEXT "Number of backups to keep:",IDC_STATIC,13,94,132,8 - EDITTEXT IDC_ED_NUMBACKUPS,164,90,30,12,ES_NUMBER,WS_EX_RIGHT - CONTROL "",SPIN_NUMBACKUPS,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,182,90,10, - 12 - PUSHBUTTON "Backup NOW",IDC_BUT_NOW,173,19,75,14 - CONTROL "Disabled",IDC_RAD_DISABLED,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,17,19,128,10 - CONTROL "When Miranda starts",IDC_RAD_START,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,17,35,156,10 - CONTROL "When Miranda exits",IDC_RAD_EXIT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,17,51,156,10 - CONTROL "Every:",IDC_RAD_PERIODIC,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,17,67,43,10 - COMBOBOX IDC_PT,148,67,46,30,CBS_DROPDOWNLIST | WS_TABSTOP - EDITTEXT IDC_ED_PERIOD,106,67,30,12,ES_NUMBER,WS_EX_RIGHT - CONTROL "",SPIN_PERIOD,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,126,67,10, - 12 - LTEXT "Backup to folder:",IDC_STATIC,18,120,124,11 - EDITTEXT IDC_ED_FOLDER,26,133,168,13,ES_AUTOHSCROLL - PUSHBUTTON "Browse...",IDC_BUT_BROWSE,199,132,49,14 - CONTROL "Go to the ""Customize -> Folders"" to change settings", - IDC_LNK_FOLDERS,"Hyperlink",NOT WS_VISIBLE | WS_TABSTOP, - 18,129,231,21 - CONTROL "Disable progress bar",IDC_CHK_NOPROG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,17,152,182,11 - CONTROL "Disable Popups",IDC_CHK_NOPOPUP,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,17,168,182,11 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_OPTIONS, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 264 - VERTGUIDE, 17 - VERTGUIDE, 193 - VERTGUIDE, 248 - TOPMARGIN, 38 - BOTTOMMARGIN, 186 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include \0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/plugins/Db_autobackups/db_autobackups_10.vcxproj b/plugins/Db_autobackups/db_autobackups_10.vcxproj index 5caee2aeb0..8019261e55 100644 --- a/plugins/Db_autobackups/db_autobackups_10.vcxproj +++ b/plugins/Db_autobackups/db_autobackups_10.vcxproj @@ -73,7 +73,7 @@ Disabled ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;DB_AUTOBACKUPS_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -90,6 +90,7 @@ $(SolutionDir)\lib + _DEBUG;%(PreprocessorDefinitions) ..\..\include\msapi @@ -97,10 +98,12 @@ Disabled ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN64;_DEBUG;_WINDOWS;_USRDLL;DB_AUTOBACKUPS_EXPORTS;%(PreprocessorDefinitions) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL Level3 + Use + headers.h true @@ -110,13 +113,14 @@ $(SolutionDir)\lib + _DEBUG;%(PreprocessorDefinitions) ..\..\include\msapi ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;DB_AUTOBACKUPS_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) Level3 Size Full @@ -133,17 +137,20 @@ $(SolutionDir)\lib + NDEBUG;%(PreprocessorDefinitions) ..\..\include\msapi ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN64;NDEBUG;_WINDOWS;_USRDLL;DB_AUTOBACKUPS_EXPORTS;%(PreprocessorDefinitions) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) Level3 Full OnlyExplicitInline Size + Use + headers.h true @@ -155,31 +162,26 @@ $(SolutionDir)\lib + NDEBUG;%(PreprocessorDefinitions) ..\..\include\msapi - - - - Create - Create - headers.h - headers.h + + + + Create - - - - - - - + + + + - - + + diff --git a/plugins/Db_autobackups/db_autobackups_10.vcxproj.filters b/plugins/Db_autobackups/db_autobackups_10.vcxproj.filters index 52d562b3c9..ed336c2e02 100644 --- a/plugins/Db_autobackups/db_autobackups_10.vcxproj.filters +++ b/plugins/Db_autobackups/db_autobackups_10.vcxproj.filters @@ -15,40 +15,35 @@ - + Source Files - + Source Files - + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - - Resource Files - - - - + Resource Files - + Resource Files diff --git a/plugins/Db_autobackups/docs/db_autobackups-translation.txt b/plugins/Db_autobackups/docs/db_autobackups-translation.txt new file mode 100644 index 0000000000..c9281a611a --- /dev/null +++ b/plugins/Db_autobackups/docs/db_autobackups-translation.txt @@ -0,0 +1,50 @@ +; Common strings that belong to many files +;[] + +; ../../plugins/Db_autobackups/backup.cpp +;[All Files] +;[Backup in Progress] +;[Copying database file...] +;[Database backuped] +;[Miranda Databases] +;[Rotating backup files...] + +; ../../plugins/Db_autobackups/db_autobackups.rc +;[Automatic Backups] +;[Backup NOW] +;[Backup progress] +;[Backup to folder:] +;[Browse...] +;[Cancel] +;[Disable Popups] +;[Disable progress bar] +;[Disabled] +;[Every:] +;[Go to the \"Customize -> Folders\" to change settings] +;[Number of backups to keep:] +;[When Miranda exits] +;[When Miranda starts] + +; ../../plugins/Db_autobackups/main.cpp +;[Backup Profile] +;[Database] +;[Save Profile As...] + +; ../../plugins/Db_autobackups/options.cpp +;[Database AutoBackups] +;[Days] +;[Error Creating Backup Folder] +;[Hours] +;[Minutes] +;[Select Backup Folder] +;[Services] +;[Variables] +;[\"Desktop\" folder for currently logged-on Windows user] +;[\"My Documents\" folder for currently logged-on Windows user] +;[any environment variable defined in current Windows session (like %systemroot%, %allusersprofile%, etc.)] +;[name of current miranda profile (filename, without extension)] +;[path to current miranda profile] +;[path to root miranda folder] +;[same as environment variable %APPDATA% for currently logged-on Windows user] +;[username for currently logged-on Windows user] +;[will return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%] diff --git a/plugins/Db_autobackups/headers.h b/plugins/Db_autobackups/headers.h deleted file mode 100644 index eab2ffc667..0000000000 --- a/plugins/Db_autobackups/headers.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _HEADERS_H -#define _HEADERS_H - -#define _CRT_SECURE_NO_DEPRECATE -#define MIRANDA_VER 0x0A00 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "m_folders.h" -#include - -#include "options.h" -#include "resource.h" - -#define MS_AB_BACKUP "AB/Backup" -#define MS_AB_BACKUPTRGR "AB/Backuptrg" -#define MS_AB_SAVEAS "AB/SaveAs" - - -#define SUB_DIR L"\\AutoBackups" -#define DIR L"%miranda_userdata%" - - -void ShowPopup(TCHAR* text, TCHAR* header); -INT_PTR DBSaveAs(WPARAM wParam, LPARAM lParam); -INT_PTR ABService(WPARAM wParam, LPARAM lParam); -int CreateDirectoryTree(TCHAR *szDir); -int Backup(TCHAR* backup_filename); -int SetBackupTimer(void); -int OptionsInit(WPARAM wParam, LPARAM lParam); -int LoadOptions(void); -HWND CreateToolTip(HWND hwndParent, LPTSTR ptszText, LPTSTR ptszTitle); - -extern HINSTANCE hInst; -extern TCHAR* profilePath; - -#endif diff --git a/plugins/Db_autobackups/icos/backup.ico b/plugins/Db_autobackups/icos/backup.ico deleted file mode 100644 index 2bd78218d8..0000000000 Binary files a/plugins/Db_autobackups/icos/backup.ico and /dev/null differ diff --git a/plugins/Db_autobackups/main.cpp b/plugins/Db_autobackups/main.cpp deleted file mode 100644 index f771261202..0000000000 --- a/plugins/Db_autobackups/main.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "headers.h" -#include "version.h" -#include "m_trigger.h" - -HINSTANCE hInst; - -int hLangpack; -TCHAR* profilePath; - -HANDLE hFolder; -HANDLE hHooks[4]; -HANDLE hServices[3]; - -PLUGININFOEX pluginInfo={ - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - __VERSION_DWORD, - __PLUGIN_DESC, - "chaos.persei, sje, Kildor, Billy_Bons", - "chaos.persei@gmail.com", - __COPYRIGHTS, - "http://mods.mirandaim.ru/", - UNICODE_AWARE, //doesn't replace anything built-in - // Generate your own unique id for your plugin. - // Do not use this UUID! - // Use uuidgen.exe to generate the uuuid - // {81C220A6-0226-4ad6-BFCA-217B17A16053} - { 0x81c220a6, 0x226, 0x4ad6, { 0xbf, 0xca, 0x21, 0x7b, 0x17, 0xa1, 0x60, 0x53 } } -}; - -struct -{ - TCHAR* szDescr; - char* szName; - int defIconID; -} -static const iconList[] = { - { _T("Backup Profile"), "backup", IDI_ICON1 }, - { _T("Save Profile As..."), "saveas", IDI_ICON1 } -}; - -INT_PTR BackupServiceTrgr(WPARAM wParam, LPARAM lParam) -{ - if(wParam & ACT_PERFORM) { - return Backup(NULL); - } - return 0; -} - -static int FoldersGetBackupPath(WPARAM wParam, LPARAM lParam) -{ - FoldersGetCustomPathT(hFolder, options.folder, MAX_PATH, DIR SUB_DIR); - return 0; -} - -static int FoldersInit(void) -{ - hFolder = (HANDLE) FoldersRegisterCustomPathT("Database Backups", "Backup Folder", DIR SUB_DIR); - hHooks[0] = HookEvent(ME_FOLDERS_PATH_CHANGED, FoldersGetBackupPath); - FoldersGetBackupPath(0, 0); - return 0; -} - -static void IcoLibInit(void) -{ - TCHAR tszFile[MAX_PATH]; - GetModuleFileName(hInst, tszFile, MAX_PATH); - - SKINICONDESC sid = {0}; - sid.cbSize = sizeof(SKINICONDESC); - sid.ptszDefaultFile = tszFile; - sid.ptszSection = _T("Database/Database Backups"); - sid.flags = SIDF_ALL_TCHAR; - - for (int i = 0; i < SIZEOF(iconList); i++) { - sid.pszName = iconList[i].szName; - sid.ptszDescription = iconList[i].szDescr; - sid.iDefaultIndex = -iconList[i].defIconID; - Skin_AddIcon(&sid); - } -} - -static void MenuInit(void) -{ - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.flags = CMIF_TCHAR; - mi.hIcon=(HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"backup"); - mi.ptszPopupName = LPGENT("Database"); - - mi.ptszName = LPGENT("Backup Profile"); - mi.pszService = MS_AB_BACKUP; - mi.position = 500100000; - Menu_AddMainMenuItem(&mi); - - mi.hIcon=(HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"saveas"); - mi.ptszName = LPGENT("Save Profile As..."); - mi.pszService = MS_AB_SAVEAS; - mi.position = 500100001; - Menu_AddMainMenuItem(&mi); -} - -static void TriggerActionInit(void) -{ - ACTIONREGISTER ar = {0}; - ar.cbSize = sizeof(ACTIONREGISTER); - ar.pszName = "Backup Database"; - ar.pszService = MS_AB_BACKUPTRGR; - - CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); -} - -static int ModulesLoad(WPARAM wParam, LPARAM lParam) -{ - profilePath = Utils_ReplaceVarsT(_T("%miranda_userdata%")); - - IcoLibInit(); - if(ServiceExists(MS_FOLDERS_REGISTER_PATH)) - FoldersInit(); - LoadOptions(); - MenuInit(); - - // register trigger action for triggerplugin - if(ServiceExists(MS_TRIGGER_REGISTERACTION)) - TriggerActionInit(); - - hHooks[1] = HookEvent(ME_OPT_INITIALISE, OptionsInit); - if(options.backup_types & BT_START) - Backup(NULL); - return 0; -} - -// can't do this on unload, since other plugins will be have already been unloaded, but their hooks -// for setting changed event not cleared. the backup on exit function will write to the db, calling those hooks. -int PreShutdown(WPARAM wParam, LPARAM lParam) { - if(options.backup_types & BT_EXIT) - { - options.disable_popups = 1; // Don't try to show popups on exit - Backup(NULL); - } - return 0; -} - -void SysInit() -{ - mir_getLP( &pluginInfo ); - OleInitialize(0); - - hServices[0] = CreateServiceFunction(MS_AB_BACKUP, ABService); - hServices[1] = CreateServiceFunction(MS_AB_BACKUPTRGR, BackupServiceTrgr); - hServices[2] = CreateServiceFunction(MS_AB_SAVEAS, DBSaveAs); - - hHooks[2] = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); - hHooks[3] = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoad); -} - -BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - hInst=hinstDLL; - return TRUE; -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) int Load(void) -{ - - SysInit(); - return 0; -} - -extern "C" __declspec(dllexport) int Unload(void) -{ - int i; - - OleUninitialize(); - - for (i=0; i= 2 && tmp[1] == ':') - _tcsncpy(options.folder, dbv.ptszVal, MAX_PATH-1); - else - mir_sntprintf(options.folder, MAX_PATH, _T("%s\\%s"), profilePath, dbv.ptszVal); - - DBFreeVariant(&dbv); - mir_free(tmp); - } else - mir_sntprintf(options.folder, MAX_PATH, _T("%s%s"), DIR, SUB_DIR); - } - options.num_backups = (unsigned int)DBGetContactSettingWord(0, "AutoBackups", "NumBackups", 3); - - options.disable_progress = (BOOL)DBGetContactSettingByte(0, "AutoBackups", "NoProgress", 0); - options.disable_popups = (BOOL)DBGetContactSettingByte(0, "AutoBackups", "NoPopups", 0); - - SetBackupTimer(); - return 0; -} - -int SaveOptions(void) { - TCHAR prof_dir[MAX_PATH]; - TCHAR* buf,* tmp; - size_t prof_len, opt_len; - - DBWriteContactSettingByte(0, "AutoBackups", "BackupType", (BYTE)options.backup_types); - if (options.period < 1) options.period = 1; - DBWriteContactSettingWord(0, "AutoBackups", "Period", (WORD)options.period); - DBWriteContactSettingByte(0, "AutoBackups", "PeriodType", (BYTE)options.period_type); - - mir_sntprintf(prof_dir, MAX_PATH, _T("%s\\"), profilePath); - prof_len = _tcslen(prof_dir); - opt_len = _tcslen(options.folder); - - if(opt_len > prof_len && _tcsncmp(options.folder, prof_dir, prof_len) == 0) { - DBWriteContactSettingTString(0, "AutoBackups", "Folder", (options.folder + prof_len)); - } else - DBWriteContactSettingTString(0, "AutoBackups", "Folder", options.folder); - - tmp = Utils_ReplaceVarsT(options.folder); - if(_tcslen(tmp) < 2 || tmp[1] != ':') - { - buf = mir_tstrdup(options.folder); - mir_sntprintf(options.folder, MAX_PATH, _T("%s\\%s"), profilePath, buf); - mir_free(buf); - } - mir_free(tmp); - DBWriteContactSettingWord(0, "AutoBackups", "NumBackups", (WORD)options.num_backups); - DBWriteContactSettingByte(0, "AutoBackups", "NoProgress", (BYTE)options.disable_progress); - DBWriteContactSettingByte(0, "AutoBackups", "NoPopups", (BYTE)options.disable_popups); - - SetBackupTimer(); - return 0; -} - -Options new_options; - -int SetDlgState(HWND hwndDlg) { - TCHAR buff[10]; - - if(new_options.backup_types == BT_DISABLED) { - CheckDlgButton(hwndDlg, IDC_RAD_DISABLED, BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_RAD_DISABLED), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_NUMBACKUPS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_FOLDER), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BUT_BROWSE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_LNK_FOLDERS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPROG), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPOPUP), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PERIOD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PT), FALSE); - - CheckDlgButton(hwndDlg, IDC_RAD_START, BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_RAD_EXIT, BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_RAD_PERIODIC, BST_UNCHECKED); - } else { - EnableWindow(GetDlgItem(hwndDlg, IDC_RAD_DISABLED), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_NUMBACKUPS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_FOLDER), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BUT_BROWSE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_LNK_FOLDERS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPROG), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPOPUP), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PERIOD), new_options.backup_types & BT_PERIODIC); - EnableWindow(GetDlgItem(hwndDlg, IDC_PT), new_options.backup_types & BT_PERIODIC); - - CheckDlgButton(hwndDlg, IDC_RAD_DISABLED, BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_RAD_START, new_options.backup_types & BT_START ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_RAD_EXIT, new_options.backup_types & BT_EXIT ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_RAD_PERIODIC, new_options.backup_types & BT_PERIODIC ? BST_CHECKED : BST_UNCHECKED); - } - - SendDlgItemMessage(hwndDlg, SPIN_PERIOD, UDM_SETRANGE32, (WPARAM)1, (LPARAM)60); - SetDlgItemText(hwndDlg, IDC_ED_PERIOD, _itot(new_options.period, buff, 10)); - - SendDlgItemMessage(hwndDlg, SPIN_NUMBACKUPS, UDM_SETRANGE32, (WPARAM)1, (LPARAM)100); - SetDlgItemText(hwndDlg, IDC_ED_NUMBACKUPS, _itot(new_options.num_backups, buff, 10)); - - SetDlgItemText(hwndDlg, IDC_ED_FOLDER, new_options.folder); - - CheckDlgButton(hwndDlg, IDC_CHK_NOPROG, new_options.disable_progress ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHK_NOPOPUP, new_options.disable_popups ? BST_CHECKED : BST_UNCHECKED); - if (!ServiceExists(MS_POPUP_ADDPOPUP)) - ShowWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPOPUP), SW_HIDE); - - return 0; -} - -int CALLBACK BrowseProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData ) -{ - TCHAR* folder; - switch(uMsg) - { - case BFFM_INITIALIZED: - folder = Utils_ReplaceVarsT(options.folder); - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)folder); - mir_free(folder); - break; - } - return 0; -} - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TCHAR buff[10]; - TCHAR folder_buff[MAX_PATH] = {0}, backupfolder[MAX_PATH] = {0}; - TCHAR tszTooltipText[1024]; - TCHAR* tmp; - BROWSEINFO bi; - LPCITEMIDLIST pidl; - OPENOPTIONSDIALOG ood = {0}; - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - memcpy(&new_options, &options, sizeof(Options)); - - if (ServiceExists(MS_FOLDERS_GET_PATH)) - { - ShowWindow(GetDlgItem(hwndDlg, IDC_ED_FOLDER), SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg, IDC_BUT_BROWSE), SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg, IDC_LNK_FOLDERS), SW_SHOW); - } - else - { - mir_sntprintf(tszTooltipText, SIZEOF(tszTooltipText), _T("%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s"), - _T("%miranda_path%"), TranslateT("path to root miranda folder"), - _T("%miranda_profile%"), TranslateT("path to current miranda profile"), - _T("%miranda_profilename%"), TranslateT("name of current miranda profile (filename, without extension)"), - _T("%miranda_userdata%"), TranslateT("will return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%"), - _T("%appdata%"), TranslateT("same as environment variable %APPDATA% for currently logged-on Windows user"), - _T("%username%"), TranslateT("username for currently logged-on Windows user"), - _T("%mydocuments%"), TranslateT("\"My Documents\" folder for currently logged-on Windows user"), - _T("%desktop%"), TranslateT("\"Desktop\" folder for currently logged-on Windows user"), - _T("%xxxxxxx%"), TranslateT("any environment variable defined in current Windows session (like %systemroot%, %allusersprofile%, etc.)") - ); - hPathTip = CreateToolTip(GetDlgItem(hwndDlg, IDC_ED_FOLDER), tszTooltipText, TranslateT("Variables")); - } - - SetDlgState(hwndDlg); - - SendMessage(GetDlgItem(hwndDlg, IDC_PT), CB_ADDSTRING, 0, (LPARAM) TranslateT("Days")); - SendMessage(GetDlgItem(hwndDlg, IDC_PT), CB_ADDSTRING, 0, (LPARAM) TranslateT("Hours")); - SendMessage(GetDlgItem(hwndDlg, IDC_PT), CB_ADDSTRING, 0, (LPARAM) TranslateT("Minutes")); - switch(new_options.period_type){ - case PT_DAYS: SendDlgItemMessage(hwndDlg, IDC_PT, CB_SETCURSEL, 0, 0); break; - case PT_HOURS: SendDlgItemMessage(hwndDlg, IDC_PT, CB_SETCURSEL, 1, 0); break; - case PT_MINUTES: SendDlgItemMessage(hwndDlg, IDC_PT, CB_SETCURSEL, 2, 0); break; - } - if (hPathTip) - SetTimer(hwndDlg, 0, 3000, NULL); - return TRUE; - case WM_COMMAND: - if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { - switch( LOWORD( wParam )) { - case IDC_ED_PERIOD: - case IDC_ED_FOLDER: - case IDC_ED_NUMBACKUPS: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - if ( HIWORD( wParam ) == CBN_SELCHANGE) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_RAD_DISABLED: - if(IsDlgButtonChecked(hwndDlg, IDC_RAD_DISABLED)) { - new_options.backup_types = BT_DISABLED; - } - SetDlgState(hwndDlg); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_RAD_START: - if(IsDlgButtonChecked(hwndDlg, IDC_RAD_START)) - new_options.backup_types |= BT_START; - else - new_options.backup_types &= ~BT_START; - SetDlgState(hwndDlg); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_RAD_EXIT: - if(IsDlgButtonChecked(hwndDlg, IDC_RAD_EXIT)) - new_options.backup_types |= BT_EXIT; - else - new_options.backup_types &= ~BT_EXIT; - SetDlgState(hwndDlg); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_RAD_PERIODIC: - if(IsDlgButtonChecked(hwndDlg, IDC_RAD_PERIODIC)) - new_options.backup_types |= BT_PERIODIC; - else - new_options.backup_types &= ~BT_PERIODIC; - SetDlgState(hwndDlg); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case IDC_BUT_BROWSE: - bi.hwndOwner = hwndDlg; - bi.pidlRoot = 0; - bi.pszDisplayName = folder_buff; - bi.lpszTitle = TranslateT("Select Backup Folder"); - bi.ulFlags = BIF_NEWDIALOGSTYLE; - bi.lpfn = BrowseProc; - bi.lParam = 0; - bi.iImage = 0; - - if ((pidl = SHBrowseForFolder(&bi)) != 0) { - SHGetPathFromIDList(pidl, folder_buff); - - SetDlgItemText(hwndDlg, IDC_ED_FOLDER, folder_buff); - - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - - CoTaskMemFree((void *)pidl); - } - break; - case IDC_BUT_NOW: - Backup(NULL); - break; - case IDC_CHK_NOPROG: - new_options.disable_progress = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOPROG); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_CHK_NOPOPUP: - new_options.disable_popups = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOPOPUP); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_LNK_FOLDERS: - ood.cbSize = sizeof(ood); - ood.pszGroup = "Customize"; - ood.pszPage = "Folders"; - CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood ); - break; - } - } - - break; - - case WM_TIMER: - if(IsWindow(hPathTip)) - KillTimer(hPathTip, 4); // It will prevent tooltip autoclosing - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == PSN_APPLY ) { - GetDlgItemText(hwndDlg, IDC_ED_PERIOD, buff, sizeof(buff)); - new_options.period = _ttoi(buff); - GetDlgItemText(hwndDlg, IDC_ED_NUMBACKUPS, buff, sizeof(buff)); - new_options.num_backups = _ttoi(buff); - - switch(SendDlgItemMessage(hwndDlg, IDC_PT, CB_GETCURSEL, 0, 0)) { - case 0: new_options.period_type = PT_DAYS; break; - case 1: new_options.period_type = PT_HOURS; break; - case 2: new_options.period_type = PT_MINUTES; break; - } - - GetDlgItemText(hwndDlg, IDC_ED_FOLDER, folder_buff, MAX_PATH); - { - BOOL folder_ok = TRUE; - int err = 0; - tmp = Utils_ReplaceVarsT(folder_buff); - - if(_tcslen(tmp) >= 2 && tmp[1] == ':') - _tcsncpy(backupfolder, tmp, MAX_PATH-1); - else - mir_sntprintf(backupfolder, MAX_PATH, _T("%s\\%s"), profilePath, tmp); - mir_free(tmp); - - err = CreateDirectoryTree(backupfolder); - if(err != ERROR_ALREADY_EXISTS && err != 0) { - TCHAR msg_buff[512]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, msg_buff, 512, 0); - MessageBox(0, msg_buff, TranslateT("Error Creating Backup Folder"), MB_OK | MB_ICONERROR); - folder_ok = FALSE; - } - - if(folder_ok) { - _tcsncpy(new_options.folder, folder_buff, MAX_PATH-1); - memcpy(&options, &new_options, sizeof(Options)); - SaveOptions(); - } else { - memcpy(&new_options, &options, sizeof(Options)); - SetDlgState(hwndDlg); - } - } - return TRUE; - - } - break; - - case WM_DESTROY: - if (hPathTip) - { - KillTimer(hwndDlg, 0); - DestroyWindow(hPathTip); - hPathTip = 0; - } - return FALSE; - } - - return FALSE; -} - -int OptionsInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.cbSize = sizeof(odp); - odp.position = -790000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszTitle = LPGEN("Database AutoBackups"); - odp.pszGroup = LPGEN("Services"); - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = DlgProcOptions; - Options_AddPage(wParam, &odp); - - return 0; -} diff --git a/plugins/Db_autobackups/options.h b/plugins/Db_autobackups/options.h deleted file mode 100644 index 240fc9566e..0000000000 --- a/plugins/Db_autobackups/options.h +++ /dev/null @@ -1,37 +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. -*/ - -typedef enum { BT_DISABLED = 0, BT_START = 1, BT_EXIT = 2, BT_PERIODIC = 4} BackupType; -typedef enum { PT_DAYS, PT_HOURS, PT_MINUTES} PeriodType; - -typedef struct Options_tag { - int backup_types; - unsigned int period; - PeriodType period_type; - TCHAR folder[MAX_PATH]; - unsigned int num_backups; - BOOL disable_progress; - BOOL disable_popups; -} Options; - -extern Options options; \ No newline at end of file diff --git a/plugins/Db_autobackups/res/backup.ico b/plugins/Db_autobackups/res/backup.ico new file mode 100644 index 0000000000..2bd78218d8 Binary files /dev/null and b/plugins/Db_autobackups/res/backup.ico differ diff --git a/plugins/Db_autobackups/res/db_autobackups.rc b/plugins/Db_autobackups/res/db_autobackups.rc new file mode 100644 index 0000000000..2fb8964153 --- /dev/null +++ b/plugins/Db_autobackups/res/db_autobackups.rc @@ -0,0 +1,182 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_COPYPROGRESS DIALOGEX 0, 0, 186, 58 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | + WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Backup progress" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,24,172,9 + CTEXT "",IDC_PROGRESSMESSAGE,31,7,114,13 + PUSHBUTTON "Cancel",IDCANCEL,58,39,67,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_COPYPROGRESS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 51 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "backup.ico" +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 271, 193 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "Automatic Backups",IDC_STATIC,6,7,258,179,WS_GROUP + RTEXT "Number of backups to keep:",IDC_STATIC,13,94,132,8 + EDITTEXT IDC_ED_NUMBACKUPS,164,90,30,12,ES_NUMBER,WS_EX_RIGHT + CONTROL "",SPIN_NUMBACKUPS,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,182,90,10, + 12 + PUSHBUTTON "Backup NOW",IDC_BUT_NOW,173,19,75,14 + CONTROL "Disabled",IDC_RAD_DISABLED,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,17,19,128,10 + CONTROL "When Miranda starts",IDC_RAD_START,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,35,156,10 + CONTROL "When Miranda exits",IDC_RAD_EXIT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,51,156,10 + CONTROL "Every:",IDC_RAD_PERIODIC,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,17,67,43,10 + COMBOBOX IDC_PT,148,67,46,30,CBS_DROPDOWNLIST | WS_TABSTOP + EDITTEXT IDC_ED_PERIOD,106,67,30,12,ES_NUMBER,WS_EX_RIGHT + CONTROL "",SPIN_PERIOD,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,126,67,10, + 12 + LTEXT "Backup to folder:",IDC_STATIC,18,120,124,11 + EDITTEXT IDC_ED_FOLDER,26,133,168,13,ES_AUTOHSCROLL + PUSHBUTTON "Browse...",IDC_BUT_BROWSE,199,132,49,14 + CONTROL "Go to the ""Customize -> Folders"" to change settings", + IDC_LNK_FOLDERS,"Hyperlink",NOT WS_VISIBLE | WS_TABSTOP, + 18,129,231,21 + CONTROL "Disable progress bar",IDC_CHK_NOPROG,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,152,182,11 + CONTROL "Disable Popups",IDC_CHK_NOPOPUP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,168,182,11 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 264 + VERTGUIDE, 17 + VERTGUIDE, 193 + VERTGUIDE, 248 + TOPMARGIN, 38 + BOTTOMMARGIN, 186 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/Db_autobackups/res/version.rc b/plugins/Db_autobackups/res/version.rc new file mode 100644 index 0000000000..30fac5ce35 --- /dev/null +++ b/plugins/Db_autobackups/res/version.rc @@ -0,0 +1,42 @@ +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + +#include +#include "..\src\version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041904b0" + BEGIN + VALUE "FileDescription", __PLUGIN_DESC + VALUE "FileVersion", __VERSION_STRING + VALUE "LegalCopyright", __COPYRIGHTS + VALUE "OriginalFilename", "db_autobackups.dll" + VALUE "ProductName", __PLUGIN_NAME + VALUE "ProductVersion", __VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x419, 1200 + END +END diff --git a/plugins/Db_autobackups/resource.h b/plugins/Db_autobackups/resource.h deleted file mode 100644 index fe3f28621c..0000000000 --- a/plugins/Db_autobackups/resource.h +++ /dev/null @@ -1,35 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by db_autobackups.rc -// -#define IDD_OPTIONS 101 -#define IDI_ICON1 270 -#define IDD_COPYPROGRESS 271 -#define SPIN_PERIOD 1369 -#define SPIN_NUMBACKUPS 1370 -#define IDC_PT 1371 -#define IDC_ED_PERIOD 1658 -#define IDC_RAD_DISABLED 1660 -#define IDC_RAD_START 1663 -#define IDC_RAD_EXIT 1664 -#define IDC_RAD_PERIODIC 1665 -#define IDC_ED_NUMBACKUPS 1666 -#define IDC_ED_FOLDER 1667 -#define IDC_BUT_BROWSE 1668 -#define IDC_LNK_FOLDERS 1669 -#define IDC_CHK_NOPROG 1670 -#define IDC_BUT_NOW 1671 -#define IDC_CHK_NOPOPUP 1672 -#define IDC_PROGRESSMESSAGE 0xDAED -#define IDC_PROGRESS 0xDEAD - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 272 -#define _APS_NEXT_COMMAND_VALUE 40018 -#define _APS_NEXT_CONTROL_VALUE 1673 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/plugins/Db_autobackups/src/backup.cpp b/plugins/Db_autobackups/src/backup.cpp new file mode 100644 index 0000000000..a6b78dace2 --- /dev/null +++ b/plugins/Db_autobackups/src/backup.cpp @@ -0,0 +1,230 @@ +#include "headers.h" +#include + +TCHAR dbname[MAX_PATH]; + +static UINT_PTR timer_id; + +INT_PTR CALLBACK DlgProcProgress(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_INITDIALOG: + { + HWND prog = GetDlgItem(hwndDlg, IDC_PROGRESS); + TranslateDialogDefault( hwndDlg ); + SendMessage(prog, PBM_SETPOS, 0, 0); + } + break; + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == IDCANCEL ) { + // in the progress dialog, use the user data to indicate that the user has pressed cancel + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)1); + return TRUE; + } + break; + } + return FALSE; +} + +INT_PTR DBSaveAs(WPARAM wParam, LPARAM lParam) +{ + HWND progress_dialog = 0; + TCHAR fname_buff[MAX_PATH], szFilter[128]; + int i; + OPENFILENAME ofn = {0}; + CallService(MS_DB_GETPROFILENAMET,MAX_PATH,(LPARAM)fname_buff); + + i = mir_sntprintf(szFilter, 64, _T("%s (*.dat)"), TranslateT("Miranda Databases")) + 1; + _tcscpy(szFilter + i, _T("*.dat")); + i += 6; + i += mir_sntprintf(szFilter + i, 48, _T("%s (*.*)"), TranslateT("All Files")) + 1; + _tcscpy(szFilter + i, _T("*")); + szFilter[i + 2] = 0; + + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFile = fname_buff; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT; + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 1; + ofn.lpstrDefExt = _T("dat"); + + if (GetSaveFileName(&ofn)) + Backup(fname_buff); + + return 0; +} + +struct FileNameFound_Tag +{ + TCHAR Name[MAX_PATH]; + FILETIME CreationTime; +}FileNameFound; + +int RotateBackups(HWND progress_dialog, DWORD start_time) +{ + TCHAR backupfilename1[MAX_PATH] = {0}, backupfilename2[MAX_PATH] = {0}, backupfolderTmp[MAX_PATH] = {0}; + TCHAR* backupfolder; + unsigned int i = 0; + HWND prog = GetDlgItem(progress_dialog, IDC_PROGRESS); + MSG msg; + + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + + backupfolder = Utils_ReplaceVarsT(options.folder); + + mir_sntprintf(backupfolderTmp, SIZEOF(backupfolderTmp), _T("%s\\*"), backupfolder); + hFind = FindFirstFile(backupfolderTmp, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + return 0; + _tcscpy(FileNameFound.Name, _T("")); + while (FindNextFile(hFind, &FindFileData)) + { + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + else if (_tcsicmp(&FindFileData.cFileName[_tcslen(FindFileData.cFileName)-4], _T(".bak")) == 0) + { + if (_tcsicmp(FileNameFound.Name, _T("")) == 0) + { + _tcscpy(FileNameFound.Name, FindFileData.cFileName); + FileNameFound.CreationTime = FindFileData.ftCreationTime; + } + else if ((FindFileData.ftCreationTime.dwHighDateTime < FileNameFound.CreationTime.dwHighDateTime) || (FindFileData.ftCreationTime.dwHighDateTime == FileNameFound.CreationTime.dwHighDateTime && FindFileData.ftCreationTime.dwLowDateTime < FileNameFound.CreationTime.dwLowDateTime)) + { + _tcscpy(FileNameFound.Name, FindFileData.cFileName); + FileNameFound.CreationTime = FindFileData.ftCreationTime; + } + i++; + while(PeekMessage(&msg, progress_dialog, 0, 0, PM_REMOVE) != 0) + { + if (!IsDialogMessage(progress_dialog, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + SendMessage(prog, PBM_SETPOS, (WPARAM)(int)(100 * (options.num_backups - i) / options.num_backups), 0); + UpdateWindow(progress_dialog); + } + } + + FindClose(hFind); + if (i >= options.num_backups) + { + mir_sntprintf(backupfilename1, MAX_PATH, _T("%s\\%s"), backupfolder, FileNameFound.Name); + DeleteFile(backupfilename1); + } + mir_free(backupfolder); + return 0; +} + +int Backup(TCHAR* backup_filename) +{ + TCHAR source_file[MAX_PATH] = {0}, dest_file[MAX_PATH] = {0}; + TCHAR* backupfolder,* pathtmp,* puText; + HWND progress_dialog; + DWORD start_time = GetTickCount(); + int i; + size_t dest_file_len; + + CallService(MS_DB_GETPROFILENAMET, MAX_PATH, (LPARAM)dbname); + + if (backup_filename == NULL) + { + int err = 0; + + SYSTEMTIME st; + TCHAR buffer[MAX_COMPUTERNAME_LENGTH+1]; + DWORD size = sizeof(buffer); + + backupfolder = Utils_ReplaceVarsT(options.folder); + // ensure the backup folder exists (either create it or return non-zero signifying error) + err = CreateDirectoryTree(backupfolder); + if(err != ERROR_ALREADY_EXISTS && err != 0) { + return 1; + } + + GetLocalTime(&st); + GetComputerName(buffer, &size); + mir_sntprintf(dest_file, MAX_PATH, _T("%s\\%s_%02d.%02d.%02d@%02d-%02d-%02d_%s.bak"), backupfolder, dbname, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, buffer); + mir_free(backupfolder); + } + else + lstrcpyn(dest_file, backup_filename, MAX_PATH); + + if (!options.disable_popups) + ShowPopup(dbname, TranslateT("Backup in Progress")); + + if (!options.disable_progress) { + progress_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_COPYPROGRESS), 0, (DLGPROC)DlgProcProgress); + SetDlgItemText(progress_dialog, IDC_PROGRESSMESSAGE, TranslateT("Rotating backup files...")); + } + + RotateBackups(progress_dialog, start_time); + + SetDlgItemText(progress_dialog, 0xDAED, TranslateT("Copying database file...")); + SendMessage(progress_dialog, PBM_SETPOS, (WPARAM)(int)(0), 0); + UpdateWindow(progress_dialog); + + mir_sntprintf(source_file, MAX_PATH, _T("%s\\%s"), profilePath, dbname); + pathtmp = Utils_ReplaceVarsT(source_file); + if (CopyFile(pathtmp, dest_file, 0)) + { + SendMessage(progress_dialog, PBM_SETPOS, (WPARAM)(int)(100), 0); + UpdateWindow(progress_dialog); + DBWriteContactSettingDword(0, "AutoBackups", "LastBackupTimestamp", (DWORD)time(0)); + if (!options.disable_popups) + { + dest_file_len = lstrlen(dest_file); + if(dest_file_len > 50) + { + puText = (TCHAR*)mir_alloc(sizeof(TCHAR) * (dest_file_len + 2)); + for(i = (int)dest_file_len - 1; dest_file[i] != _T('\\'); i--); + + lstrcpyn(puText, dest_file, i + 2); + lstrcat(puText, _T("\n")); + lstrcat(puText, dest_file + i + 1); + } + else + puText = mir_tstrdup(dest_file); + + ShowPopup(puText, TranslateT("Database backuped")); + mir_free(puText); + } + } + else + DeleteFile(dest_file); + mir_free(pathtmp); + + DestroyWindow(progress_dialog); + return 0; +} + +VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { + time_t t = time(0), diff = t - (time_t)DBGetContactSettingDword(0, "AutoBackups", "LastBackupTimestamp", (DWORD)t); + if(diff > (time_t)(options.period * (options.period_type == PT_MINUTES ? 60 : (options.period_type == PT_HOURS ? 60 * 60 : 60 * 60 * 24 )))) + Backup(NULL); +} + +int SetBackupTimer(void) +{ + if(options.backup_types & BT_PERIODIC) + { + if(timer_id == 0) + timer_id = SetTimer(0, 0, 1000 * 60, TimerProc); + } + else if(timer_id != 0) + { + KillTimer(0, timer_id); + timer_id = 0; + } + return 0; +} + +INT_PTR ABService(WPARAM wParam, LPARAM lParam) +{ + Backup((TCHAR*)wParam); + return 0; +} diff --git a/plugins/Db_autobackups/src/headers.h b/plugins/Db_autobackups/src/headers.h new file mode 100644 index 0000000000..eab2ffc667 --- /dev/null +++ b/plugins/Db_autobackups/src/headers.h @@ -0,0 +1,50 @@ +#ifndef _HEADERS_H +#define _HEADERS_H + +#define _CRT_SECURE_NO_DEPRECATE +#define MIRANDA_VER 0x0A00 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "m_folders.h" +#include + +#include "options.h" +#include "resource.h" + +#define MS_AB_BACKUP "AB/Backup" +#define MS_AB_BACKUPTRGR "AB/Backuptrg" +#define MS_AB_SAVEAS "AB/SaveAs" + + +#define SUB_DIR L"\\AutoBackups" +#define DIR L"%miranda_userdata%" + + +void ShowPopup(TCHAR* text, TCHAR* header); +INT_PTR DBSaveAs(WPARAM wParam, LPARAM lParam); +INT_PTR ABService(WPARAM wParam, LPARAM lParam); +int CreateDirectoryTree(TCHAR *szDir); +int Backup(TCHAR* backup_filename); +int SetBackupTimer(void); +int OptionsInit(WPARAM wParam, LPARAM lParam); +int LoadOptions(void); +HWND CreateToolTip(HWND hwndParent, LPTSTR ptszText, LPTSTR ptszTitle); + +extern HINSTANCE hInst; +extern TCHAR* profilePath; + +#endif diff --git a/plugins/Db_autobackups/src/main.cpp b/plugins/Db_autobackups/src/main.cpp new file mode 100644 index 0000000000..f771261202 --- /dev/null +++ b/plugins/Db_autobackups/src/main.cpp @@ -0,0 +1,247 @@ +#include "headers.h" +#include "version.h" +#include "m_trigger.h" + +HINSTANCE hInst; + +int hLangpack; +TCHAR* profilePath; + +HANDLE hFolder; +HANDLE hHooks[4]; +HANDLE hServices[3]; + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + __VERSION_DWORD, + __PLUGIN_DESC, + "chaos.persei, sje, Kildor, Billy_Bons", + "chaos.persei@gmail.com", + __COPYRIGHTS, + "http://mods.mirandaim.ru/", + UNICODE_AWARE, //doesn't replace anything built-in + // Generate your own unique id for your plugin. + // Do not use this UUID! + // Use uuidgen.exe to generate the uuuid + // {81C220A6-0226-4ad6-BFCA-217B17A16053} + { 0x81c220a6, 0x226, 0x4ad6, { 0xbf, 0xca, 0x21, 0x7b, 0x17, 0xa1, 0x60, 0x53 } } +}; + +struct +{ + TCHAR* szDescr; + char* szName; + int defIconID; +} +static const iconList[] = { + { _T("Backup Profile"), "backup", IDI_ICON1 }, + { _T("Save Profile As..."), "saveas", IDI_ICON1 } +}; + +INT_PTR BackupServiceTrgr(WPARAM wParam, LPARAM lParam) +{ + if(wParam & ACT_PERFORM) { + return Backup(NULL); + } + return 0; +} + +static int FoldersGetBackupPath(WPARAM wParam, LPARAM lParam) +{ + FoldersGetCustomPathT(hFolder, options.folder, MAX_PATH, DIR SUB_DIR); + return 0; +} + +static int FoldersInit(void) +{ + hFolder = (HANDLE) FoldersRegisterCustomPathT("Database Backups", "Backup Folder", DIR SUB_DIR); + hHooks[0] = HookEvent(ME_FOLDERS_PATH_CHANGED, FoldersGetBackupPath); + FoldersGetBackupPath(0, 0); + return 0; +} + +static void IcoLibInit(void) +{ + TCHAR tszFile[MAX_PATH]; + GetModuleFileName(hInst, tszFile, MAX_PATH); + + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(SKINICONDESC); + sid.ptszDefaultFile = tszFile; + sid.ptszSection = _T("Database/Database Backups"); + sid.flags = SIDF_ALL_TCHAR; + + for (int i = 0; i < SIZEOF(iconList); i++) { + sid.pszName = iconList[i].szName; + sid.ptszDescription = iconList[i].szDescr; + sid.iDefaultIndex = -iconList[i].defIconID; + Skin_AddIcon(&sid); + } +} + +static void MenuInit(void) +{ + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIF_TCHAR; + mi.hIcon=(HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"backup"); + mi.ptszPopupName = LPGENT("Database"); + + mi.ptszName = LPGENT("Backup Profile"); + mi.pszService = MS_AB_BACKUP; + mi.position = 500100000; + Menu_AddMainMenuItem(&mi); + + mi.hIcon=(HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"saveas"); + mi.ptszName = LPGENT("Save Profile As..."); + mi.pszService = MS_AB_SAVEAS; + mi.position = 500100001; + Menu_AddMainMenuItem(&mi); +} + +static void TriggerActionInit(void) +{ + ACTIONREGISTER ar = {0}; + ar.cbSize = sizeof(ACTIONREGISTER); + ar.pszName = "Backup Database"; + ar.pszService = MS_AB_BACKUPTRGR; + + CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); +} + +static int ModulesLoad(WPARAM wParam, LPARAM lParam) +{ + profilePath = Utils_ReplaceVarsT(_T("%miranda_userdata%")); + + IcoLibInit(); + if(ServiceExists(MS_FOLDERS_REGISTER_PATH)) + FoldersInit(); + LoadOptions(); + MenuInit(); + + // register trigger action for triggerplugin + if(ServiceExists(MS_TRIGGER_REGISTERACTION)) + TriggerActionInit(); + + hHooks[1] = HookEvent(ME_OPT_INITIALISE, OptionsInit); + if(options.backup_types & BT_START) + Backup(NULL); + return 0; +} + +// can't do this on unload, since other plugins will be have already been unloaded, but their hooks +// for setting changed event not cleared. the backup on exit function will write to the db, calling those hooks. +int PreShutdown(WPARAM wParam, LPARAM lParam) { + if(options.backup_types & BT_EXIT) + { + options.disable_popups = 1; // Don't try to show popups on exit + Backup(NULL); + } + return 0; +} + +void SysInit() +{ + mir_getLP( &pluginInfo ); + OleInitialize(0); + + hServices[0] = CreateServiceFunction(MS_AB_BACKUP, ABService); + hServices[1] = CreateServiceFunction(MS_AB_BACKUPTRGR, BackupServiceTrgr); + hServices[2] = CreateServiceFunction(MS_AB_SAVEAS, DBSaveAs); + + hHooks[2] = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + hHooks[3] = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoad); +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst=hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) int Load(void) +{ + + SysInit(); + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + int i; + + OleUninitialize(); + + for (i=0; i= 2 && tmp[1] == ':') + _tcsncpy(options.folder, dbv.ptszVal, MAX_PATH-1); + else + mir_sntprintf(options.folder, MAX_PATH, _T("%s\\%s"), profilePath, dbv.ptszVal); + + DBFreeVariant(&dbv); + mir_free(tmp); + } else + mir_sntprintf(options.folder, MAX_PATH, _T("%s%s"), DIR, SUB_DIR); + } + options.num_backups = (unsigned int)DBGetContactSettingWord(0, "AutoBackups", "NumBackups", 3); + + options.disable_progress = (BOOL)DBGetContactSettingByte(0, "AutoBackups", "NoProgress", 0); + options.disable_popups = (BOOL)DBGetContactSettingByte(0, "AutoBackups", "NoPopups", 0); + + SetBackupTimer(); + return 0; +} + +int SaveOptions(void) { + TCHAR prof_dir[MAX_PATH]; + TCHAR* buf,* tmp; + size_t prof_len, opt_len; + + DBWriteContactSettingByte(0, "AutoBackups", "BackupType", (BYTE)options.backup_types); + if (options.period < 1) options.period = 1; + DBWriteContactSettingWord(0, "AutoBackups", "Period", (WORD)options.period); + DBWriteContactSettingByte(0, "AutoBackups", "PeriodType", (BYTE)options.period_type); + + mir_sntprintf(prof_dir, MAX_PATH, _T("%s\\"), profilePath); + prof_len = _tcslen(prof_dir); + opt_len = _tcslen(options.folder); + + if(opt_len > prof_len && _tcsncmp(options.folder, prof_dir, prof_len) == 0) { + DBWriteContactSettingTString(0, "AutoBackups", "Folder", (options.folder + prof_len)); + } else + DBWriteContactSettingTString(0, "AutoBackups", "Folder", options.folder); + + tmp = Utils_ReplaceVarsT(options.folder); + if(_tcslen(tmp) < 2 || tmp[1] != ':') + { + buf = mir_tstrdup(options.folder); + mir_sntprintf(options.folder, MAX_PATH, _T("%s\\%s"), profilePath, buf); + mir_free(buf); + } + mir_free(tmp); + DBWriteContactSettingWord(0, "AutoBackups", "NumBackups", (WORD)options.num_backups); + DBWriteContactSettingByte(0, "AutoBackups", "NoProgress", (BYTE)options.disable_progress); + DBWriteContactSettingByte(0, "AutoBackups", "NoPopups", (BYTE)options.disable_popups); + + SetBackupTimer(); + return 0; +} + +Options new_options; + +int SetDlgState(HWND hwndDlg) { + TCHAR buff[10]; + + if(new_options.backup_types == BT_DISABLED) { + CheckDlgButton(hwndDlg, IDC_RAD_DISABLED, BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_RAD_DISABLED), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_NUMBACKUPS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_FOLDER), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BUT_BROWSE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LNK_FOLDERS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPROG), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPOPUP), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PERIOD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PT), FALSE); + + CheckDlgButton(hwndDlg, IDC_RAD_START, BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_RAD_EXIT, BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_RAD_PERIODIC, BST_UNCHECKED); + } else { + EnableWindow(GetDlgItem(hwndDlg, IDC_RAD_DISABLED), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_NUMBACKUPS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_FOLDER), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BUT_BROWSE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LNK_FOLDERS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPROG), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPOPUP), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PERIOD), new_options.backup_types & BT_PERIODIC); + EnableWindow(GetDlgItem(hwndDlg, IDC_PT), new_options.backup_types & BT_PERIODIC); + + CheckDlgButton(hwndDlg, IDC_RAD_DISABLED, BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_RAD_START, new_options.backup_types & BT_START ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_RAD_EXIT, new_options.backup_types & BT_EXIT ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_RAD_PERIODIC, new_options.backup_types & BT_PERIODIC ? BST_CHECKED : BST_UNCHECKED); + } + + SendDlgItemMessage(hwndDlg, SPIN_PERIOD, UDM_SETRANGE32, (WPARAM)1, (LPARAM)60); + SetDlgItemText(hwndDlg, IDC_ED_PERIOD, _itot(new_options.period, buff, 10)); + + SendDlgItemMessage(hwndDlg, SPIN_NUMBACKUPS, UDM_SETRANGE32, (WPARAM)1, (LPARAM)100); + SetDlgItemText(hwndDlg, IDC_ED_NUMBACKUPS, _itot(new_options.num_backups, buff, 10)); + + SetDlgItemText(hwndDlg, IDC_ED_FOLDER, new_options.folder); + + CheckDlgButton(hwndDlg, IDC_CHK_NOPROG, new_options.disable_progress ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHK_NOPOPUP, new_options.disable_popups ? BST_CHECKED : BST_UNCHECKED); + if (!ServiceExists(MS_POPUP_ADDPOPUP)) + ShowWindow(GetDlgItem(hwndDlg, IDC_CHK_NOPOPUP), SW_HIDE); + + return 0; +} + +int CALLBACK BrowseProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData ) +{ + TCHAR* folder; + switch(uMsg) + { + case BFFM_INITIALIZED: + folder = Utils_ReplaceVarsT(options.folder); + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)folder); + mir_free(folder); + break; + } + return 0; +} + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TCHAR buff[10]; + TCHAR folder_buff[MAX_PATH] = {0}, backupfolder[MAX_PATH] = {0}; + TCHAR tszTooltipText[1024]; + TCHAR* tmp; + BROWSEINFO bi; + LPCITEMIDLIST pidl; + OPENOPTIONSDIALOG ood = {0}; + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + memcpy(&new_options, &options, sizeof(Options)); + + if (ServiceExists(MS_FOLDERS_GET_PATH)) + { + ShowWindow(GetDlgItem(hwndDlg, IDC_ED_FOLDER), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_BUT_BROWSE), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_LNK_FOLDERS), SW_SHOW); + } + else + { + mir_sntprintf(tszTooltipText, SIZEOF(tszTooltipText), _T("%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s"), + _T("%miranda_path%"), TranslateT("path to root miranda folder"), + _T("%miranda_profile%"), TranslateT("path to current miranda profile"), + _T("%miranda_profilename%"), TranslateT("name of current miranda profile (filename, without extension)"), + _T("%miranda_userdata%"), TranslateT("will return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%"), + _T("%appdata%"), TranslateT("same as environment variable %APPDATA% for currently logged-on Windows user"), + _T("%username%"), TranslateT("username for currently logged-on Windows user"), + _T("%mydocuments%"), TranslateT("\"My Documents\" folder for currently logged-on Windows user"), + _T("%desktop%"), TranslateT("\"Desktop\" folder for currently logged-on Windows user"), + _T("%xxxxxxx%"), TranslateT("any environment variable defined in current Windows session (like %systemroot%, %allusersprofile%, etc.)") + ); + hPathTip = CreateToolTip(GetDlgItem(hwndDlg, IDC_ED_FOLDER), tszTooltipText, TranslateT("Variables")); + } + + SetDlgState(hwndDlg); + + SendMessage(GetDlgItem(hwndDlg, IDC_PT), CB_ADDSTRING, 0, (LPARAM) TranslateT("Days")); + SendMessage(GetDlgItem(hwndDlg, IDC_PT), CB_ADDSTRING, 0, (LPARAM) TranslateT("Hours")); + SendMessage(GetDlgItem(hwndDlg, IDC_PT), CB_ADDSTRING, 0, (LPARAM) TranslateT("Minutes")); + switch(new_options.period_type){ + case PT_DAYS: SendDlgItemMessage(hwndDlg, IDC_PT, CB_SETCURSEL, 0, 0); break; + case PT_HOURS: SendDlgItemMessage(hwndDlg, IDC_PT, CB_SETCURSEL, 1, 0); break; + case PT_MINUTES: SendDlgItemMessage(hwndDlg, IDC_PT, CB_SETCURSEL, 2, 0); break; + } + if (hPathTip) + SetTimer(hwndDlg, 0, 3000, NULL); + return TRUE; + case WM_COMMAND: + if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + switch( LOWORD( wParam )) { + case IDC_ED_PERIOD: + case IDC_ED_FOLDER: + case IDC_ED_NUMBACKUPS: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + if ( HIWORD( wParam ) == CBN_SELCHANGE) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_RAD_DISABLED: + if(IsDlgButtonChecked(hwndDlg, IDC_RAD_DISABLED)) { + new_options.backup_types = BT_DISABLED; + } + SetDlgState(hwndDlg); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_START: + if(IsDlgButtonChecked(hwndDlg, IDC_RAD_START)) + new_options.backup_types |= BT_START; + else + new_options.backup_types &= ~BT_START; + SetDlgState(hwndDlg); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_EXIT: + if(IsDlgButtonChecked(hwndDlg, IDC_RAD_EXIT)) + new_options.backup_types |= BT_EXIT; + else + new_options.backup_types &= ~BT_EXIT; + SetDlgState(hwndDlg); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_PERIODIC: + if(IsDlgButtonChecked(hwndDlg, IDC_RAD_PERIODIC)) + new_options.backup_types |= BT_PERIODIC; + else + new_options.backup_types &= ~BT_PERIODIC; + SetDlgState(hwndDlg); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_BUT_BROWSE: + bi.hwndOwner = hwndDlg; + bi.pidlRoot = 0; + bi.pszDisplayName = folder_buff; + bi.lpszTitle = TranslateT("Select Backup Folder"); + bi.ulFlags = BIF_NEWDIALOGSTYLE; + bi.lpfn = BrowseProc; + bi.lParam = 0; + bi.iImage = 0; + + if ((pidl = SHBrowseForFolder(&bi)) != 0) { + SHGetPathFromIDList(pidl, folder_buff); + + SetDlgItemText(hwndDlg, IDC_ED_FOLDER, folder_buff); + + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + + CoTaskMemFree((void *)pidl); + } + break; + case IDC_BUT_NOW: + Backup(NULL); + break; + case IDC_CHK_NOPROG: + new_options.disable_progress = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOPROG); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_NOPOPUP: + new_options.disable_popups = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOPOPUP); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_LNK_FOLDERS: + ood.cbSize = sizeof(ood); + ood.pszGroup = "Customize"; + ood.pszPage = "Folders"; + CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood ); + break; + } + } + + break; + + case WM_TIMER: + if(IsWindow(hPathTip)) + KillTimer(hPathTip, 4); // It will prevent tooltip autoclosing + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + GetDlgItemText(hwndDlg, IDC_ED_PERIOD, buff, sizeof(buff)); + new_options.period = _ttoi(buff); + GetDlgItemText(hwndDlg, IDC_ED_NUMBACKUPS, buff, sizeof(buff)); + new_options.num_backups = _ttoi(buff); + + switch(SendDlgItemMessage(hwndDlg, IDC_PT, CB_GETCURSEL, 0, 0)) { + case 0: new_options.period_type = PT_DAYS; break; + case 1: new_options.period_type = PT_HOURS; break; + case 2: new_options.period_type = PT_MINUTES; break; + } + + GetDlgItemText(hwndDlg, IDC_ED_FOLDER, folder_buff, MAX_PATH); + { + BOOL folder_ok = TRUE; + int err = 0; + tmp = Utils_ReplaceVarsT(folder_buff); + + if(_tcslen(tmp) >= 2 && tmp[1] == ':') + _tcsncpy(backupfolder, tmp, MAX_PATH-1); + else + mir_sntprintf(backupfolder, MAX_PATH, _T("%s\\%s"), profilePath, tmp); + mir_free(tmp); + + err = CreateDirectoryTree(backupfolder); + if(err != ERROR_ALREADY_EXISTS && err != 0) { + TCHAR msg_buff[512]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, msg_buff, 512, 0); + MessageBox(0, msg_buff, TranslateT("Error Creating Backup Folder"), MB_OK | MB_ICONERROR); + folder_ok = FALSE; + } + + if(folder_ok) { + _tcsncpy(new_options.folder, folder_buff, MAX_PATH-1); + memcpy(&options, &new_options, sizeof(Options)); + SaveOptions(); + } else { + memcpy(&new_options, &options, sizeof(Options)); + SetDlgState(hwndDlg); + } + } + return TRUE; + + } + break; + + case WM_DESTROY: + if (hPathTip) + { + KillTimer(hwndDlg, 0); + DestroyWindow(hPathTip); + hPathTip = 0; + } + return FALSE; + } + + return FALSE; +} + +int OptionsInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.position = -790000000; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = LPGEN("Database AutoBackups"); + odp.pszGroup = LPGEN("Services"); + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = DlgProcOptions; + Options_AddPage(wParam, &odp); + + return 0; +} diff --git a/plugins/Db_autobackups/src/options.h b/plugins/Db_autobackups/src/options.h new file mode 100644 index 0000000000..240fc9566e --- /dev/null +++ b/plugins/Db_autobackups/src/options.h @@ -0,0 +1,37 @@ +/* + +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. +*/ + +typedef enum { BT_DISABLED = 0, BT_START = 1, BT_EXIT = 2, BT_PERIODIC = 4} BackupType; +typedef enum { PT_DAYS, PT_HOURS, PT_MINUTES} PeriodType; + +typedef struct Options_tag { + int backup_types; + unsigned int period; + PeriodType period_type; + TCHAR folder[MAX_PATH]; + unsigned int num_backups; + BOOL disable_progress; + BOOL disable_popups; +} Options; + +extern Options options; \ No newline at end of file diff --git a/plugins/Db_autobackups/src/resource.h b/plugins/Db_autobackups/src/resource.h new file mode 100644 index 0000000000..fe3f28621c --- /dev/null +++ b/plugins/Db_autobackups/src/resource.h @@ -0,0 +1,35 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by db_autobackups.rc +// +#define IDD_OPTIONS 101 +#define IDI_ICON1 270 +#define IDD_COPYPROGRESS 271 +#define SPIN_PERIOD 1369 +#define SPIN_NUMBACKUPS 1370 +#define IDC_PT 1371 +#define IDC_ED_PERIOD 1658 +#define IDC_RAD_DISABLED 1660 +#define IDC_RAD_START 1663 +#define IDC_RAD_EXIT 1664 +#define IDC_RAD_PERIODIC 1665 +#define IDC_ED_NUMBACKUPS 1666 +#define IDC_ED_FOLDER 1667 +#define IDC_BUT_BROWSE 1668 +#define IDC_LNK_FOLDERS 1669 +#define IDC_CHK_NOPROG 1670 +#define IDC_BUT_NOW 1671 +#define IDC_CHK_NOPOPUP 1672 +#define IDC_PROGRESSMESSAGE 0xDAED +#define IDC_PROGRESS 0xDEAD + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 272 +#define _APS_NEXT_COMMAND_VALUE 40018 +#define _APS_NEXT_CONTROL_VALUE 1673 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/Db_autobackups/src/version.h b/plugins/Db_autobackups/src/version.h new file mode 100644 index 0000000000..e7151dfccb --- /dev/null +++ b/plugins/Db_autobackups/src/version.h @@ -0,0 +1,8 @@ +#define __FILEVERSION_STRING 0,0,0,8 +#define __VERSION_STRING "0.0.0.8" +#define __VERSION_DWORD 0x00000008 + +#define __PLUGIN_NAME_BASE "DB Autobackuper" +#define __PLUGIN_NAME __PLUGIN_NAME_BASE +#define __PLUGIN_DESC __PLUGIN_NAME_BASE " plugin." +#define __COPYRIGHTS "© 2005-2011 chaos.persei, sje, Kildor, Billy_Bons, Vasilich" diff --git a/plugins/Db_autobackups/version.h b/plugins/Db_autobackups/version.h deleted file mode 100644 index e7151dfccb..0000000000 --- a/plugins/Db_autobackups/version.h +++ /dev/null @@ -1,8 +0,0 @@ -#define __FILEVERSION_STRING 0,0,0,8 -#define __VERSION_STRING "0.0.0.8" -#define __VERSION_DWORD 0x00000008 - -#define __PLUGIN_NAME_BASE "DB Autobackuper" -#define __PLUGIN_NAME __PLUGIN_NAME_BASE -#define __PLUGIN_DESC __PLUGIN_NAME_BASE " plugin." -#define __COPYRIGHTS "© 2005-2011 chaos.persei, sje, Kildor, Billy_Bons, Vasilich" diff --git a/plugins/Db_autobackups/version.rc b/plugins/Db_autobackups/version.rc deleted file mode 100644 index 542d0a8f6c..0000000000 --- a/plugins/Db_autobackups/version.rc +++ /dev/null @@ -1,42 +0,0 @@ -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - -#include -#include "version.h" - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION __FILEVERSION_STRING - PRODUCTVERSION __FILEVERSION_STRING - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "041904b0" - BEGIN - VALUE "FileDescription", __PLUGIN_DESC - VALUE "FileVersion", __VERSION_STRING - VALUE "LegalCopyright", __COPYRIGHTS - VALUE "OriginalFilename", "db_autobackups.dll" - VALUE "ProductName", __PLUGIN_NAME - VALUE "ProductVersion", __VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x419, 1200 - END -END -- cgit v1.2.3