summaryrefslogtreecommitdiff
path: root/src/modules/database/dbini.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /src/modules/database/dbini.cpp
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/modules/database/dbini.cpp')
-rw-r--r--src/modules/database/dbini.cpp490
1 files changed, 490 insertions, 0 deletions
diff --git a/src/modules/database/dbini.cpp b/src/modules/database/dbini.cpp
new file mode 100644
index 0000000000..01e6645593
--- /dev/null
+++ b/src/modules/database/dbini.cpp
@@ -0,0 +1,490 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "commonheaders.h"
+#include "../srfile/file.h"
+
+static bool bModuleInitialized = false;
+static HANDLE hIniChangeNotification;
+
+extern TCHAR mirandabootini[MAX_PATH];
+extern bool dbCreated;
+
+static INT_PTR CALLBACK InstallIniDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
+{
+ switch(message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemText(hwndDlg, IDC_ININAME, (TCHAR*)lParam);
+ {
+ TCHAR szSecurity[11];
+ const TCHAR *pszSecurityInfo;
+
+ GetPrivateProfileString(_T("AutoExec"), _T("Warn"), _T("notsafe"), szSecurity, SIZEOF(szSecurity), mirandabootini);
+ if(!lstrcmpi(szSecurity, _T("all")))
+ pszSecurityInfo = LPGENT("Security systems to prevent malicious changes are in place and you will be warned before every change that is made.");
+ else if (!lstrcmpi(szSecurity, _T("onlyunsafe")))
+ pszSecurityInfo = LPGENT("Security systems to prevent malicious changes are in place and you will be warned before changes that are known to be unsafe.");
+ else if (!lstrcmpi(szSecurity, _T("none")))
+ pszSecurityInfo = LPGENT("Security systems to prevent malicious changes have been disabled. You will receive no further warnings.");
+ else pszSecurityInfo = NULL;
+ if (pszSecurityInfo) SetDlgItemText(hwndDlg, IDC_SECURITYINFO, TranslateTS(pszSecurityInfo));
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_VIEWINI:
+ { TCHAR szPath[MAX_PATH];
+ GetDlgItemText(hwndDlg, IDC_ININAME, szPath, SIZEOF(szPath));
+ ShellExecute(hwndDlg, _T("open"), szPath, NULL, NULL, SW_SHOW);
+ break;
+ }
+ case IDOK:
+ case IDCANCEL:
+ case IDC_NOTOALL:
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static bool IsInSpaceSeparatedList(const char *szWord,const char *szList)
+{
+ const char *szItem,*szEnd;
+ int wordLen = lstrlenA(szWord);
+
+ for(szItem = szList;;) {
+ szEnd = strchr(szItem,' ');
+ if (szEnd == NULL)
+ return !lstrcmpA( szItem, szWord );
+ if ( szEnd - szItem == wordLen ) {
+ if ( !strncmp( szItem, szWord, wordLen ))
+ return true;
+ }
+ szItem = szEnd+1;
+} }
+
+struct warnSettingChangeInfo_t {
+ TCHAR *szIniPath;
+ char *szSection;
+ char *szSafeSections;
+ char *szUnsafeSections;
+ char *szName;
+ char *szValue;
+ int warnNoMore,cancel;
+};
+
+static INT_PTR CALLBACK WarnIniChangeDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
+{
+ static struct warnSettingChangeInfo_t *warnInfo;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ { char szSettingName[256];
+ const TCHAR *pszSecurityInfo;
+ warnInfo = (warnSettingChangeInfo_t*)lParam;
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemText(hwndDlg, IDC_ININAME, warnInfo->szIniPath);
+ lstrcpyA(szSettingName, warnInfo->szSection);
+ lstrcatA(szSettingName," / ");
+ lstrcatA(szSettingName,warnInfo->szName);
+ SetDlgItemTextA(hwndDlg,IDC_SETTINGNAME,szSettingName);
+ SetDlgItemTextA(hwndDlg,IDC_NEWVALUE,warnInfo->szValue);
+ if(IsInSpaceSeparatedList(warnInfo->szSection,warnInfo->szSafeSections))
+ pszSecurityInfo=LPGENT("This change is known to be safe.");
+ else if(IsInSpaceSeparatedList(warnInfo->szSection,warnInfo->szUnsafeSections))
+ pszSecurityInfo=LPGENT("This change is known to be potentially hazardous.");
+ else
+ pszSecurityInfo=LPGENT("This change is not known to be safe.");
+ SetDlgItemText(hwndDlg,IDC_SECURITYINFO,TranslateTS(pszSecurityInfo));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDCANCEL:
+ warnInfo->cancel=1;
+ case IDYES:
+ case IDNO:
+ warnInfo->warnNoMore=IsDlgButtonChecked(hwndDlg,IDC_WARNNOMORE);
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK IniImportDoneDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
+{
+ switch(message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemText(hwndDlg,IDC_ININAME,(TCHAR*)lParam);
+ SetDlgItemText(hwndDlg,IDC_NEWNAME,(TCHAR*)lParam);
+ return TRUE;
+ case WM_COMMAND:
+ { TCHAR szIniPath[MAX_PATH];
+ GetDlgItemText(hwndDlg,IDC_ININAME,szIniPath,SIZEOF(szIniPath));
+ switch(LOWORD(wParam)) {
+ case IDC_DELETE:
+ DeleteFile(szIniPath);
+ case IDC_LEAVE:
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ case IDC_RECYCLE:
+ { SHFILEOPSTRUCT shfo={0};
+ shfo.wFunc=FO_DELETE;
+ shfo.pFrom=szIniPath;
+ szIniPath[lstrlen(szIniPath)+1]='\0';
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;
+ SHFileOperation(&shfo);
+ }
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ case IDC_MOVE:
+ { TCHAR szNewPath[MAX_PATH];
+ GetDlgItemText(hwndDlg,IDC_NEWNAME,szNewPath,SIZEOF(szNewPath));
+ MoveFile(szIniPath,szNewPath);
+ }
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+// settings:
+struct SettingsList
+{
+ char *name;
+ SettingsList *next;
+} *setting_items = NULL;
+
+int SettingsEnumProc(const char *szSetting, LPARAM lParam)
+{
+ SettingsList *newItem = (SettingsList *)mir_alloc(sizeof(SettingsList));
+ newItem->name = mir_strdup(szSetting);
+ newItem->next = setting_items;
+ setting_items = newItem;
+ return 0;
+}
+
+void ConvertBackslashes(char *, UINT);
+static void ProcessIniFile(TCHAR* szIniPath, char *szSafeSections, char *szUnsafeSections, int secur, bool secFN)
+{
+ FILE *fp = _tfopen(szIniPath, _T("rt"));
+ if ( fp == NULL )
+ return;
+
+ bool warnThisSection = false;
+ char szSection[128]; szSection[0] = 0;
+
+ while(!feof(fp)) {
+ char szLine[2048];
+ if (fgets(szLine,sizeof(szLine),fp) == NULL)
+ break;
+
+ int lineLength = lstrlenA(szLine);
+ while (lineLength && (BYTE)(szLine[lineLength-1])<=' ')
+ szLine[--lineLength]='\0';
+
+ if (szLine[0]==';' || szLine[0]<=' ')
+ continue;
+
+ if (szLine[0]=='[') {
+ char *szEnd = strchr(szLine+1,']');
+ if (szEnd == NULL)
+ continue;
+
+ if (szLine[1] == '!')
+ szSection[0] = '\0';
+ else {
+ lstrcpynA(szSection,szLine+1,min(sizeof(szSection),(int)(szEnd-szLine)));
+ switch (secur) {
+ case 0:
+ warnThisSection = false;
+ break;
+
+ case 1:
+ warnThisSection = !IsInSpaceSeparatedList(szSection, szSafeSections);
+ break;
+
+ case 2:
+ warnThisSection = IsInSpaceSeparatedList(szSection, szUnsafeSections);
+ break;
+
+ default:
+ warnThisSection = true;
+ break;
+ }
+ if (secFN) warnThisSection=0;
+ }
+ if (szLine[1] == '?') {
+ DBCONTACTENUMSETTINGS dbces;
+ dbces.pfnEnumProc=SettingsEnumProc;
+ lstrcpynA(szSection,szLine+2,min(sizeof(szSection),(int)(szEnd-szLine-1)));
+ dbces.szModule=szSection;
+ dbces.ofsSettings=0;
+ CallService(MS_DB_CONTACT_ENUMSETTINGS,0,(LPARAM)&dbces);
+ while (setting_items) {
+ SettingsList *next = setting_items->next;
+
+ DBCONTACTGETSETTING dbcgs;
+ dbcgs.szModule = szSection;
+ dbcgs.szSetting = setting_items->name;
+ CallService(MS_DB_CONTACT_DELETESETTING, 0, (LPARAM)&dbcgs);
+
+ mir_free(setting_items->name);
+ mir_free(setting_items);
+ setting_items = next;
+ }
+ }
+ continue;
+ }
+
+ if(szSection[0]=='\0')
+ continue;
+
+ char *szValue=strchr(szLine,'=');
+ if ( szValue == NULL )
+ continue;
+
+ char szName[128];
+ lstrcpynA(szName,szLine,min(sizeof(szName),(int)(szValue-szLine+1)));
+ szValue++;
+ {
+ warnSettingChangeInfo_t warnInfo;
+ warnInfo.szIniPath=szIniPath;
+ warnInfo.szName=szName;
+ warnInfo.szSafeSections=szSafeSections;
+ warnInfo.szSection=szSection;
+ warnInfo.szUnsafeSections=szUnsafeSections;
+ warnInfo.szValue=szValue;
+ warnInfo.warnNoMore=0;
+ warnInfo.cancel=0;
+ if(warnThisSection && IDNO==DialogBoxParam(hMirandaInst,MAKEINTRESOURCE(IDD_WARNINICHANGE),NULL,WarnIniChangeDlgProc,(LPARAM)&warnInfo))
+ continue;
+ if(warnInfo.cancel)
+ break;
+ if(warnInfo.warnNoMore)
+ warnThisSection=0;
+ }
+
+ switch(szValue[0]) {
+ case 'b':
+ case 'B':
+ DBWriteContactSettingByte(NULL,szSection,szName,(BYTE)strtol(szValue+1,NULL,0));
+ break;
+ case 'w':
+ case 'W':
+ DBWriteContactSettingWord(NULL,szSection,szName,(WORD)strtol(szValue+1,NULL,0));
+ break;
+ case 'd':
+ case 'D':
+ DBWriteContactSettingDword(NULL,szSection,szName,(DWORD)strtoul(szValue+1,NULL,0));
+ break;
+ case 'l':
+ case 'L':
+ DBDeleteContactSetting(NULL,szSection,szName);
+ break;
+ case 'e':
+ case 'E':
+ ConvertBackslashes(szValue+1, LangPackGetDefaultCodePage());
+ case 's':
+ case 'S':
+ DBWriteContactSettingString(NULL,szSection,szName,szValue+1);
+ break;
+ case 'g':
+ case 'G':
+ { char *pstr;
+ for(pstr=szValue+1;*pstr;pstr++){
+ if(*pstr=='\\'){
+ switch(pstr[1]){
+ case 'n': *pstr='\n'; break;
+ case 't': *pstr='\t'; break;
+ case 'r': *pstr='\r'; break;
+ default: *pstr=pstr[1]; break;
+ }
+ MoveMemory(pstr+1,pstr+2,lstrlenA(pstr+2)+1);
+ } } }
+ case 'u':
+ case 'U':
+ DBWriteContactSettingStringUtf(NULL,szSection,szName,szValue+1);
+ break;
+ case 'n':
+ case 'h':
+ case 'N':
+ case 'H':
+ { PBYTE buf;
+ int len;
+ char *pszValue,*pszEnd;
+ DBCONTACTWRITESETTING cws;
+
+ buf=(PBYTE)mir_alloc(lstrlenA(szValue+1));
+ for(len=0,pszValue=szValue+1;;len++) {
+ buf[len]=(BYTE)strtol(pszValue,&pszEnd,0x10);
+ if(pszValue==pszEnd) break;
+ pszValue=pszEnd;
+ }
+ cws.szModule=szSection;
+ cws.szSetting=szName;
+ cws.value.type=DBVT_BLOB;
+ cws.value.pbVal=buf;
+ cws.value.cpbVal=len;
+ CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)(HANDLE)NULL,(LPARAM)&cws);
+ mir_free(buf);
+ }
+ break;
+ default:
+ MessageBox(NULL,TranslateT("Invalid setting type. The first character of every value must be b, w, d, l, s, e, u, g, h or n."),TranslateT("Install Database Settings"),MB_OK);
+ break;
+ }
+ }
+ fclose(fp);
+}
+
+static void DoAutoExec(void)
+{
+ TCHAR szUse[7], szIniPath[MAX_PATH], szFindPath[MAX_PATH];
+ TCHAR *str2;
+ TCHAR buf[2048], szSecurity[11], szOverrideSecurityFilename[MAX_PATH], szOnCreateFilename[MAX_PATH];
+ char *szSafeSections, *szUnsafeSections;
+ int secur;
+
+ GetPrivateProfileString(_T("AutoExec"),_T("Use"),_T("prompt"),szUse,SIZEOF(szUse),mirandabootini);
+ if(!lstrcmpi(szUse,_T("no"))) return;
+ GetPrivateProfileString(_T("AutoExec"),_T("Safe"),_T("CLC Icons CLUI CList SkinSounds"),buf,SIZEOF(buf),mirandabootini);
+ szSafeSections = mir_t2a(buf);
+ GetPrivateProfileString(_T("AutoExec"),_T("Unsafe"),_T("ICQ MSN"),buf,SIZEOF(buf),mirandabootini);
+ szUnsafeSections = mir_t2a(buf);
+ GetPrivateProfileString(_T("AutoExec"),_T("Warn"),_T("notsafe"),szSecurity,SIZEOF(szSecurity),mirandabootini);
+ if (!lstrcmpi(szSecurity,_T("none"))) secur = 0;
+ else if (!lstrcmpi(szSecurity,_T("notsafe"))) secur = 1;
+ else if (!lstrcmpi(szSecurity,_T("onlyunsafe"))) secur = 2;
+
+ GetPrivateProfileString(_T("AutoExec"),_T("OverrideSecurityFilename"),_T(""),szOverrideSecurityFilename,SIZEOF(szOverrideSecurityFilename),mirandabootini);
+ GetPrivateProfileString(_T("AutoExec"),_T("OnCreateFilename"),_T(""),szOnCreateFilename,SIZEOF(szOnCreateFilename),mirandabootini);
+ GetPrivateProfileString(_T("AutoExec"),_T("Glob"),_T("autoexec_*.ini"),szFindPath,SIZEOF(szFindPath),mirandabootini);
+
+ if (dbCreated && szOnCreateFilename[0]) {
+ str2 = Utils_ReplaceVarsT(szOnCreateFilename);
+ pathToAbsoluteT(str2, szIniPath, NULL);
+ mir_free(str2);
+
+ ProcessIniFile(szIniPath, szSafeSections, szUnsafeSections, 0, 1);
+ }
+
+ str2 = Utils_ReplaceVarsT(szFindPath);
+ pathToAbsoluteT(str2, szFindPath, NULL);
+ mir_free(str2);
+
+ WIN32_FIND_DATA fd;
+ HANDLE hFind = FindFirstFile(szFindPath, &fd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ mir_free(szSafeSections);
+ mir_free(szUnsafeSections);
+ return;
+ }
+
+ str2 = _tcsrchr(szFindPath, '\\');
+ if (str2 == NULL) szFindPath[0] = 0;
+ else str2[1] = 0;
+
+ do {
+ bool secFN = lstrcmpi(fd.cFileName,szOverrideSecurityFilename) == 0;
+
+ mir_sntprintf(szIniPath, SIZEOF(szIniPath), _T("%s%s"), szFindPath, fd.cFileName);
+ if(!lstrcmpi(szUse,_T("prompt")) && !secFN) {
+ int result=DialogBoxParam(hMirandaInst,MAKEINTRESOURCE(IDD_INSTALLINI),NULL,InstallIniDlgProc,(LPARAM)szIniPath);
+ if(result==IDC_NOTOALL) break;
+ if(result==IDCANCEL) continue;
+ }
+
+ ProcessIniFile(szIniPath, szSafeSections, szUnsafeSections, secur, secFN);
+
+ if(secFN)
+ DeleteFile(szIniPath);
+ else {
+ TCHAR szOnCompletion[8];
+ GetPrivateProfileString(_T("AutoExec"),_T("OnCompletion"),_T("recycle"),szOnCompletion,SIZEOF(szOnCompletion),mirandabootini);
+ if(!lstrcmpi(szOnCompletion,_T("delete")))
+ DeleteFile(szIniPath);
+ else if(!lstrcmpi(szOnCompletion,_T("recycle"))) {
+ SHFILEOPSTRUCT shfo={0};
+ shfo.wFunc=FO_DELETE;
+ shfo.pFrom=szIniPath;
+ szIniPath[lstrlen(szIniPath)+1]=0;
+ shfo.fFlags=FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;
+ SHFileOperation(&shfo);
+ }
+ else if(!lstrcmpi(szOnCompletion,_T("rename"))) {
+ TCHAR szRenamePrefix[MAX_PATH];
+ TCHAR szNewPath[MAX_PATH];
+ GetPrivateProfileString(_T("AutoExec"),_T("RenamePrefix"),_T("done_"),szRenamePrefix,SIZEOF(szRenamePrefix),mirandabootini);
+ lstrcpy(szNewPath,szFindPath);
+ lstrcat(szNewPath,szRenamePrefix);
+ lstrcat(szNewPath,fd.cFileName);
+ MoveFile(szIniPath,szNewPath);
+ }
+ else if(!lstrcmpi(szOnCompletion,_T("ask")))
+ DialogBoxParam(hMirandaInst,MAKEINTRESOURCE(IDD_INIIMPORTDONE),NULL,IniImportDoneDlgProc,(LPARAM)szIniPath);
+ }
+ } while (FindNextFile(hFind, &fd));
+ FindClose(hFind);
+ mir_free(szSafeSections);
+ mir_free(szUnsafeSections);
+}
+
+static INT_PTR CheckIniImportNow(WPARAM, LPARAM)
+{
+ DoAutoExec();
+ FindNextChangeNotification(hIniChangeNotification);
+ return 0;
+}
+
+int InitIni(void)
+{
+ TCHAR szMirandaDir[MAX_PATH];
+
+ bModuleInitialized = true;
+
+ DoAutoExec();
+ pathToAbsoluteT(_T("."), szMirandaDir, NULL);
+ hIniChangeNotification=FindFirstChangeNotification(szMirandaDir, 0, FILE_NOTIFY_CHANGE_FILE_NAME);
+ if (hIniChangeNotification != INVALID_HANDLE_VALUE) {
+ CreateServiceFunction("DB/Ini/CheckImportNow", CheckIniImportNow);
+ CallService(MS_SYSTEM_WAITONHANDLE, (WPARAM)hIniChangeNotification, (LPARAM)"DB/Ini/CheckImportNow");
+ }
+ return 0;
+}
+
+void UninitIni(void)
+{
+ if ( !bModuleInitialized ) return;
+ CallService(MS_SYSTEM_REMOVEWAIT,(WPARAM)hIniChangeNotification,0);
+ FindCloseChangeNotification(hIniChangeNotification);
+}