summaryrefslogtreecommitdiff
path: root/plugins/Db_autobackups/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-23 06:41:38 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-23 06:41:38 +0000
commit9126d2b133d00b836fca640f847a0948f7579e02 (patch)
tree7e915c08cc0e52aaa6244e709acffa91a31715a3 /plugins/Db_autobackups/src
parent33e535df429971555b212f4abaff1b6adb8e7c23 (diff)
Db3x_mmap,Db_autobackups: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1107 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Db_autobackups/src')
-rw-r--r--plugins/Db_autobackups/src/backup.cpp230
-rw-r--r--plugins/Db_autobackups/src/headers.h50
-rw-r--r--plugins/Db_autobackups/src/main.cpp247
-rw-r--r--plugins/Db_autobackups/src/options.cpp357
-rw-r--r--plugins/Db_autobackups/src/options.h37
-rw-r--r--plugins/Db_autobackups/src/resource.h35
-rw-r--r--plugins/Db_autobackups/src/version.h8
7 files changed, 964 insertions, 0 deletions
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 <commctrl.h>
+
+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 <m_stdhdr.h>
+#include <windows.h>
+#include <shlobj.h>
+#include <time.h>
+#include <commctrl.h>
+
+#include <m_system.h>
+#include <newpluginapi.h>
+#include <m_clist.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_utils.h>
+#include <m_options.h>
+#include <m_popup.h>
+#include <m_icolib.h>
+#include "m_folders.h"
+#include <win2k.h>
+
+#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<SIZEOF(hHooks); ++i)
+ {
+ if (hHooks[i])
+ UnhookEvent(hHooks[i]);
+ }
+ for (i=0; i<SIZEOF(hServices); ++i)
+ {
+ if (hServices[i])
+ DestroyServiceFunction(hServices[i]);
+ }
+
+ return 0;
+}
+
+void ShowPopup(TCHAR* text, TCHAR* header)
+{
+ POPUPDATAT ppd = {0};
+
+ lstrcpy(ppd.lptzText, text);
+ lstrcpy(ppd.lptzContactName, header);
+ ppd.lchIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"backup");
+
+ PUAddPopUpT(&ppd);
+}
+
+int CreateDirectoryTree(TCHAR *szDir)
+{
+ TCHAR *pszLastBackslash, szTestDir[ MAX_PATH ];
+
+ lstrcpyn( szTestDir, szDir, SIZEOF( szTestDir ));
+ pszLastBackslash = _tcsrchr( szTestDir, '\\' );
+ if ( pszLastBackslash == NULL )
+ return 0;
+
+ *pszLastBackslash = '\0';
+ CreateDirectoryTree( szTestDir );
+ *pszLastBackslash = '\\';
+ return ( CreateDirectory( szTestDir, NULL ) == 0 ) ? GetLastError() : 0;
+}
+
+HWND CreateToolTip(HWND hwndParent, LPTSTR ptszText, LPTSTR ptszTitle)
+{
+ TOOLINFO ti = { 0 };
+ HWND hwndTT;
+ hwndTT = CreateWindowEx(WS_EX_TOPMOST,
+ TOOLTIPS_CLASS, NULL,
+ WS_POPUP | TTS_NOPREFIX,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ hwndParent, NULL, hInst, NULL);
+
+ SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS | TTF_CENTERTIP;
+ ti.hwnd = hwndParent;
+ ti.hinst = hInst;
+ ti.lpszText = ptszText;
+ GetClientRect (hwndParent, &ti.rect);
+ ti.rect.left -= 80;
+
+ SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ SendMessage(hwndTT, TTM_SETTITLE, 1, (LPARAM)ptszTitle);
+ SendMessage(hwndTT, TTM_SETMAXTIPWIDTH, 0, (LPARAM)700);
+ return hwndTT;
+} \ No newline at end of file
diff --git a/plugins/Db_autobackups/src/options.cpp b/plugins/Db_autobackups/src/options.cpp
new file mode 100644
index 0000000000..ef94ab8872
--- /dev/null
+++ b/plugins/Db_autobackups/src/options.cpp
@@ -0,0 +1,357 @@
+#include "headers.h"
+
+Options options;
+static HWND hPathTip;
+
+int LoadOptions(void) {
+ DBVARIANT dbv;
+ TCHAR* tmp;
+
+ options.backup_types = (BackupType)DBGetContactSettingByte(0, "AutoBackups", "BackupType", (BYTE)(BT_PERIODIC));
+ options.period = (unsigned int)DBGetContactSettingWord(0, "AutoBackups", "Period", 1);
+ options.period_type = (PeriodType)DBGetContactSettingByte(0, "AutoBackups", "PeriodType", (BYTE)PT_DAYS);
+
+ if (!ServiceExists(MS_FOLDERS_GET_PATH)) {
+
+ if (!DBGetContactSettingTString(0, "AutoBackups", "Folder", &dbv)) {
+ tmp = Utils_ReplaceVarsT(dbv.ptszVal);
+
+ if(_tcslen(tmp) >= 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"