diff options
Diffstat (limited to 'miranda-wine/src/modules/database')
-rw-r--r-- | miranda-wine/src/modules/database/database.c | 377 | ||||
-rw-r--r-- | miranda-wine/src/modules/database/dbini.c | 495 | ||||
-rw-r--r-- | miranda-wine/src/modules/database/dblists.c | 149 | ||||
-rw-r--r-- | miranda-wine/src/modules/database/dblists.h | 36 | ||||
-rw-r--r-- | miranda-wine/src/modules/database/dbtime.c | 239 | ||||
-rw-r--r-- | miranda-wine/src/modules/database/profilemanager.c | 696 | ||||
-rw-r--r-- | miranda-wine/src/modules/database/profilemanager.h | 37 |
7 files changed, 2029 insertions, 0 deletions
diff --git a/miranda-wine/src/modules/database/database.c b/miranda-wine/src/modules/database/database.c new file mode 100644 index 0000000..ead8acd --- /dev/null +++ b/miranda-wine/src/modules/database/database.c @@ -0,0 +1,377 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 "profilemanager.h"
+
+
+// from the plugin loader, hate extern but the db frontend is pretty much tied
+extern PLUGINLINK pluginCoreLink;
+// contains the location of mirandaboot.ini
+extern char mirandabootini[MAX_PATH];
+
+// returns 1 if the profile path was returned, without trailing slash
+int getProfilePath(char * buf, size_t cch)
+{
+ char profiledir[MAX_PATH];
+ char exprofiledir[MAX_PATH];
+ char * p = 0;
+ // grab the base location now
+ GetModuleFileNameA(NULL, buf, cch);
+ p = strrchr(buf, '\\');
+ if ( p != 0 ) *p=0;
+ // change to this location, or "." wont expand properly
+ _chdir(buf);
+ GetPrivateProfileStringA("Database", "ProfileDir", ".", profiledir, SIZEOF(profiledir), mirandabootini);
+ // get the string containing envars and maybe relative paths
+ // get rid of the vars
+ ExpandEnvironmentStringsA(profiledir, exprofiledir, SIZEOF(exprofiledir));
+ if ( _fullpath(profiledir, exprofiledir, SIZEOF(profiledir)) != 0 ) {
+ /* XXX: really use CreateDirectory()? it only creates the last dir given a\b\c, SHCreateDirectory()
+ does what we want however thats 2000+ only */
+ DWORD dw = INVALID_FILE_ATTRIBUTES;
+ CreateDirectoryA(profiledir, NULL);
+ dw=GetFileAttributesA(profiledir);
+ if ( dw != INVALID_FILE_ATTRIBUTES && dw&FILE_ATTRIBUTE_DIRECTORY ) {
+ strncpy(buf, profiledir, cch);
+ p = strrchr(buf, '\\');
+ // if the char after '\' is null then change '\' to null
+ if ( p != 0 && *(++p)==0 ) *(--p)=0;
+ return 1;
+ }
+ }
+ // this never happens, usually C:\ is always returned
+ return 0;
+}
+
+// returns 1 if *.dat spec is matched
+int isValidProfileName(char * name)
+{
+ char * p = strrchr(name, '.');
+ if ( p ) {
+ p++;
+ if ( lstrcmpiA( p, "dat" ) == 0 ) {
+ if ( p[3] == 0 ) return 1;
+ }
+ }
+ return 0;
+}
+
+// returns 1 if a single profile (full path) is found within the profile dir
+static int getProfile1(char * szProfile, size_t cch, char * profiledir, BOOL * noProfiles)
+{
+ int rc = 1;
+ char searchspec[MAX_PATH];
+ WIN32_FIND_DATAA ffd;
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+ unsigned int found=0;
+ mir_snprintf(searchspec,SIZEOF(searchspec),"%s\\*.dat", profiledir);
+ hFind = FindFirstFileA(searchspec, &ffd);
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ // make sure the first hit is actually a *.dat file
+ if ( !(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && isValidProfileName(ffd.cFileName) )
+ {
+ // copy the profile name early cos it might be the only one
+ mir_snprintf(szProfile, cch, "%s\\%s", profiledir, ffd.cFileName);
+ found++;
+ // this might be the only dat but there might be a few wrong things returned before another *.dat
+ while ( FindNextFileA(hFind,&ffd) ) {
+ // found another *.dat, but valid?
+ if ( !(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && isValidProfileName(ffd.cFileName) ) {
+ rc=0;
+ found++;
+ break;
+ } //if
+ } // while
+ } //if
+ FindClose(hFind);
+ }
+ if ( found == 0 && noProfiles != 0 ) {
+ *noProfiles=TRUE;
+ rc=0;
+ }
+ return rc;
+}
+
+// returns 1 if something that looks like a profile is there
+static int getProfileCmdLineArgs(char * szProfile, size_t cch)
+{
+ char *szCmdLine=GetCommandLineA();
+ char *szEndOfParam;
+ char szThisParam[1024];
+ int firstParam=1;
+
+ while(szCmdLine[0]) {
+ if(szCmdLine[0]=='"') {
+ szEndOfParam=strchr(szCmdLine+1,'"');
+ if(szEndOfParam==NULL) break;
+ lstrcpynA(szThisParam,szCmdLine+1,min( SIZEOF(szThisParam),szEndOfParam-szCmdLine));
+ szCmdLine=szEndOfParam+1;
+ }
+ else {
+ szEndOfParam=szCmdLine+strcspn(szCmdLine," \t");
+ lstrcpynA(szThisParam,szCmdLine,min( SIZEOF(szThisParam),szEndOfParam-szCmdLine+1));
+ szCmdLine=szEndOfParam;
+ }
+ while(*szCmdLine && *szCmdLine<=' ') szCmdLine++;
+ if(firstParam) {firstParam=0; continue;} //first param is executable name
+ if(szThisParam[0]=='/' || szThisParam[0]=='-') continue; //no switches supported
+ ExpandEnvironmentStringsA(szThisParam,szProfile,cch);
+ return 1;
+ }
+ return 0;
+}
+
+// returns 1 if a valid filename (incl. dat) is found, includes fully qualified path
+static int getProfileCmdLine(char * szProfile, size_t cch, char * profiledir)
+{
+ char buf[MAX_PATH];
+ HANDLE hFile;
+ int rc;
+ if ( getProfileCmdLineArgs(buf, SIZEOF(buf)) ) {
+ // have something that looks like a .dat, with or without .dat in the filename
+ if ( !isValidProfileName(buf) ) mir_snprintf(buf, SIZEOF(buf)-5,"%s.dat",buf);
+ // expand the relative to a full path , which might fail
+ if ( _fullpath(szProfile, buf, cch) != 0 ) {
+ hFile=CreateFileA(szProfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+ rc=hFile != INVALID_HANDLE_VALUE;
+ CloseHandle(hFile);
+ return rc;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+// returns 1 if the profile manager should be shown
+static int showProfileManager(void)
+{
+ char Mgr[32];
+ // is control pressed?
+ if (GetAsyncKeyState(VK_CONTROL)&0x8000) return 1;
+ // wanna show it?
+ GetPrivateProfileStringA("Database", "ShowProfileMgr", "never", Mgr, SIZEOF(Mgr), mirandabootini);
+ if ( _strcmpi(Mgr,"yes") == 0 ) return 1;
+ return 0;
+}
+
+// returns 1 if a default profile should be selected instead of showing the manager.
+static int getProfileAutoRun(char * szProfile, size_t cch, char * profiledir)
+{
+ char Mgr[32];
+ char env_profile[MAX_PATH];
+ char exp_profile[MAX_PATH];
+ GetPrivateProfileStringA("Database", "ShowProfileMgr", "", Mgr, SIZEOF(Mgr), mirandabootini);
+ if ( lstrcmpiA(Mgr,"never") ) return 0;
+ GetPrivateProfileStringA("Database", "DefaultProfile", "", env_profile, SIZEOF(env_profile), mirandabootini);
+ if ( lstrlenA(env_profile) == 0 ) return 0;
+ ExpandEnvironmentStringsA(env_profile, exp_profile, SIZEOF(exp_profile));
+ mir_snprintf(szProfile, cch, "%s\\%s.dat", profiledir, exp_profile);
+ return 1;
+}
+
+
+
+// returns 1 if a profile was selected
+static int getProfile(char * szProfile, size_t cch)
+{
+ char profiledir[MAX_PATH];
+ PROFILEMANAGERDATA pd;
+ ZeroMemory(&pd,sizeof(pd));
+ getProfilePath(profiledir,SIZEOF(profiledir));
+ if ( getProfileCmdLine(szProfile, cch, profiledir) ) return 1;
+ if ( getProfileAutoRun(szProfile, cch, profiledir) ) return 1;
+ if ( !showProfileManager() && getProfile1(szProfile, cch, profiledir, &pd.noProfiles) ) return 1;
+ else {
+ pd.szProfile=szProfile;
+ pd.szProfileDir=profiledir;
+ return getProfileManager(&pd);
+ }
+}
+
+// called by the UI, return 1 on success, use link to create profile, set error if any
+int makeDatabase(char * profile, DATABASELINK * link, HWND hwndDlg)
+{
+ char buf[256];
+ int err=0;
+ // check if the file already exists
+ HANDLE hFile=CreateFileA(profile, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ char * file = strrchr(profile,'\\');
+ file++;
+ if ( hFile != INVALID_HANDLE_VALUE ) {
+ CloseHandle(hFile);
+ mir_snprintf(buf, SIZEOF(buf), Translate("The profile '%s' already exists. Do you want to move it to the "
+ "Recycle Bin? \n\nWARNING: The profile will be deleted if Recycle Bin is disabled.\nWARNING: A profile may contain confidential information and should be properly deleted."),file);
+ // file already exists!
+ if ( MessageBoxA(hwndDlg, buf, Translate("The profile already exists"), MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2) != IDYES ) return 0;
+ // move the file
+ {
+ char szName[MAX_PATH]; // SHFileOperation needs a "double null"
+ SHFILEOPSTRUCTA sf;
+ ZeroMemory(&sf,sizeof(sf));
+ sf.wFunc=FO_DELETE;
+ sf.pFrom=szName;
+ sf.fFlags=FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_SILENT;
+ mir_snprintf(szName, SIZEOF(szName),"%s\0",profile);
+ if ( SHFileOperationA(&sf) != 0 ) {
+ mir_snprintf(buf, SIZEOF(buf),Translate("Couldn't move '%s' to the Recycle Bin, Please select another profile name."),file);
+ MessageBoxA(0,buf,Translate("Problem moving profile"),MB_ICONINFORMATION|MB_OK);
+ return 0;
+ }
+ }
+ // now the file should be gone!
+ }
+ // ask the database to create the profile
+ if ( link->makeDatabase(profile,&err) ) {
+ mir_snprintf(buf, SIZEOF(buf),Translate("Unable to create the profile '%s', the error was %x"),file, err);
+ MessageBoxA(hwndDlg,buf,Translate("Problem creating profile"),MB_ICONERROR|MB_OK);
+ return 0;
+ }
+ // the profile has been created! woot
+ return 1;
+}
+
+// enumerate all plugins that had valid DatabasePluginInfo()
+static int FindDbPluginForProfile(char * pluginname, DATABASELINK * dblink, LPARAM lParam)
+{
+ char * szProfile = (char *) lParam;
+ if ( dblink && dblink->cbSize == sizeof(DATABASELINK) ) {
+ int err=0;
+ int rc=0;
+ // liked the profile?
+ rc=dblink->grokHeader(szProfile,&err);
+ if ( rc == 0 ) {
+ // added APIs?
+ if ( dblink->Load(szProfile, &pluginCoreLink) == 0 ) return DBPE_DONE;
+ return DBPE_HALT;
+ } else {
+ switch ( err ) {
+ case EGROKPRF_CANTREAD:
+ case EGROKPRF_UNKHEADER:
+ {
+ // just not supported.
+ return DBPE_CONT;
+ }
+ case EGROKPRF_VERNEWER:
+ case EGROKPRF_DAMAGED:
+ {
+ break;
+ }
+ }
+ return DBPE_HALT;
+ } //if
+ }
+ return DBPE_CONT;
+}
+
+typedef struct {
+ char * profile;
+ UINT msg;
+ ATOM aPath;
+ int found;
+} ENUMMIRANDAWINDOW;
+
+static BOOL CALLBACK EnumMirandaWindows(HWND hwnd, LPARAM lParam)
+{
+ TCHAR classname[256];
+ ENUMMIRANDAWINDOW * x = (ENUMMIRANDAWINDOW *)lParam;
+ DWORD res=0;
+ if ( GetClassName(hwnd,classname,SIZEOF(classname)) && lstrcmp( _T("Miranda"),classname)==0 ) {
+ if ( SendMessageTimeout(hwnd, x->msg, (WPARAM)x->aPath, 0, SMTO_ABORTIFHUNG, 100, &res) && res ) {
+ x->found++;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static int FindMirandaForProfile(char * szProfile)
+{
+ ENUMMIRANDAWINDOW x={0};
+ x.profile=szProfile;
+ x.msg=RegisterWindowMessage( _T( "Miranda::ProcessProfile" ));
+ x.aPath=GlobalAddAtomA(szProfile);
+ EnumWindows(EnumMirandaWindows, (LPARAM)&x);
+ GlobalDeleteAtom(x.aPath);
+ return x.found;
+}
+
+int LoadDatabaseModule(void)
+{
+ int iReturn = 0;
+ char szProfile[MAX_PATH];
+ szProfile[0]=0;
+
+ // load the older basic services of the db
+ InitTime();
+
+ // find out which profile to load
+ if ( getProfile(szProfile, SIZEOF(szProfile)) )
+ {
+ int rc;
+ PLUGIN_DB_ENUM dbe;
+
+ dbe.cbSize=sizeof(PLUGIN_DB_ENUM);
+ dbe.pfnEnumCallback=( int(*) (char*,void*,LPARAM) )FindDbPluginForProfile;
+ dbe.lParam=(LPARAM)szProfile;
+
+ // find a driver to support the given profile
+ rc=CallService(MS_PLUGINS_ENUMDBPLUGINS, 0, (LPARAM)&dbe);
+ switch ( rc ) {
+ case -1: {
+ // no plugins at all
+ char buf[256];
+ char * p = strrchr(szProfile,'\\');
+ mir_snprintf(buf,SIZEOF(buf),Translate("Miranda is unable to open '%s' because you do not have any profile plugins installed.\nYou need to install dbx_3x.dll or equivalent."), p ? ++p : szProfile );
+ MessageBoxA(0,buf,Translate("No profile support installed!"),MB_OK | MB_ICONERROR);
+ break;
+ }
+ case 1: {
+ // if there were drivers but they all failed cos the file is locked, try and find the miranda which locked it
+ HANDLE hFile;
+ hFile=CreateFileA(szProfile,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
+ if ( hFile == INVALID_HANDLE_VALUE ) {
+ if ( !FindMirandaForProfile(szProfile) ) {
+ // file is locked, tried to find miranda window, but that failed too.
+ }
+ } else {
+ // file isn't locked, just no driver could open it.
+ char buf[256];
+ char * p = strrchr(szProfile,'\\');
+ mir_snprintf(buf,SIZEOF(buf),Translate("Miranda was unable to open '%s', its in an unknown format.\nThis profile might also be damaged, please run DB-tool which should be installed."), p ? ++p : szProfile);
+ MessageBoxA(0,buf,Translate("Miranda can't understand that profile"),MB_OK | MB_ICONERROR);
+ CloseHandle(hFile);
+ }
+ break;
+ }
+ }
+ iReturn = (rc != 0);
+ }
+ else
+ {
+ iReturn = 1;
+ }
+
+ return iReturn;
+}
+
diff --git a/miranda-wine/src/modules/database/dbini.c b/miranda-wine/src/modules/database/dbini.c new file mode 100644 index 0000000..0717080 --- /dev/null +++ b/miranda-wine/src/modules/database/dbini.c @@ -0,0 +1,495 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 "../../core/commonheaders.h"
+//#include "database.h"
+
+static HANDLE hIniChangeNotification;
+extern char mirandabootini[MAX_PATH];
+
+int GetCommandLineDbName(char *szName,int cbName)
+{
+ char *szCmdLine=GetCommandLineA();
+ char *szEndOfParam;
+ char szThisParam[1024];
+ int firstParam=1;
+
+ while(szCmdLine[0]) {
+ if(szCmdLine[0]=='"') {
+ szEndOfParam=strchr(szCmdLine+1,'"');
+ if(szEndOfParam==NULL) break;
+ lstrcpynA(szThisParam,szCmdLine+1,min(sizeof(szThisParam),szEndOfParam-szCmdLine));
+ szCmdLine=szEndOfParam+1;
+ }
+ else {
+ szEndOfParam=szCmdLine+strcspn(szCmdLine," \t");
+ lstrcpynA(szThisParam,szCmdLine,min(sizeof(szThisParam),szEndOfParam-szCmdLine+1));
+ szCmdLine=szEndOfParam;
+ }
+ while(*szCmdLine && *szCmdLine<=' ') szCmdLine++;
+ if(firstParam) {firstParam=0; continue;} //first param is executable name
+ if(szThisParam[0]=='/' || szThisParam[0]=='-') continue; //no switches supported
+ lstrcpynA(szName,szThisParam,cbName);
+ return 0;
+ }
+ return 1;
+}
+
+void GetProfileDirectory(char *szPath,int cbPath)
+{
+ char *str2;
+ char szMirandaDir[MAX_PATH],szProfileDir[MAX_PATH],szExpandedProfileDir[MAX_PATH];
+ DWORD dwAttributes;
+
+ GetModuleFileNameA(GetModuleHandle(NULL),szMirandaDir,sizeof(szMirandaDir));
+ str2=strrchr(szMirandaDir,'\\');
+ if(str2!=NULL) *str2=0;
+ GetPrivateProfileStringA("Database","ProfileDir",".",szProfileDir,sizeof(szProfileDir),mirandabootini);
+ ExpandEnvironmentStringsA(szProfileDir,szExpandedProfileDir,sizeof(szExpandedProfileDir));
+ _chdir(szMirandaDir);
+ if(!_fullpath(szPath,szExpandedProfileDir,cbPath))
+ lstrcpynA(szPath,szMirandaDir,cbPath);
+ if(szPath[lstrlenA(szPath)-1]=='\\') szPath[lstrlenA(szPath)-1]='\0';
+ if((dwAttributes=GetFileAttributesA(szPath))!=0xffffffff&&dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return;
+ CreateDirectoryA(szPath,NULL);
+}
+
+int ShouldAutoCreate(void)
+{
+ char szAutoCreate[4];
+ GetPrivateProfileStringA("Database","AutoCreate","no",szAutoCreate,sizeof(szAutoCreate),mirandabootini);
+ return !lstrcmpiA(szAutoCreate,"yes");
+}
+
+int GetDefaultProfilePath(char *szPath,int cbPath,int *specified)
+{
+ char szProfileDir[MAX_PATH],szDefaultName[MAX_PATH],szExpandedDefaultName[MAX_PATH];
+ HANDLE hFind;
+ char szSearchPath[MAX_PATH],szSingleExistingPath[MAX_PATH];
+ WIN32_FIND_DATAA fd;
+
+ if(specified) *specified=1;
+ GetProfileDirectory(szProfileDir,sizeof(szProfileDir));
+ if(GetCommandLineDbName(szDefaultName,sizeof(szDefaultName))) {
+ if(specified) *specified=0;
+ GetPrivateProfileStringA("Database","DefaultProfile","",szDefaultName,sizeof(szDefaultName),mirandabootini);
+ }
+ ExpandEnvironmentStringsA(szDefaultName,szExpandedDefaultName,sizeof(szExpandedDefaultName));
+
+ _chdir(szProfileDir);
+
+ szSingleExistingPath[0]='\0';
+ lstrcpyA(szSearchPath,szProfileDir);
+ lstrcatA(szSearchPath,"\\*.dat");
+ hFind=FindFirstFileA(szSearchPath,&fd);
+ if(hFind!=INVALID_HANDLE_VALUE) {
+ if(FindNextFileA(hFind,&fd)==0)
+ if(_fullpath(szSingleExistingPath,fd.cFileName,cbPath)==NULL)
+ szSingleExistingPath[0]='\0';
+ FindClose(hFind);
+ }
+
+ if(szExpandedDefaultName[0]) {
+ lstrcatA(szExpandedDefaultName,".dat");
+ if(_fullpath(szPath,szExpandedDefaultName,cbPath)!=NULL) {
+ if(specified && !lstrcmpiA(szSingleExistingPath,szPath)) *specified=1;
+ if(!_access(szPath,0)) return 0;
+ if(ShouldAutoCreate()) {
+ HANDLE hFile;
+ if(specified && szSingleExistingPath[0]=='\0') *specified=1;
+ hFile=CreateFileA(szPath,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,0,NULL);
+ CloseHandle(hFile);
+ return 0;
+ }
+ }
+ }
+
+ if(szSingleExistingPath[0]) {
+ if(specified && szExpandedDefaultName[0]=='\0') *specified=1;
+ lstrcpynA(szPath,szSingleExistingPath,cbPath);
+ return 0;
+ }
+ return 1;
+}
+
+int ShouldShowProfileManager(void)
+{
+ char szShowValue[7];
+ char szDefaultProfile[MAX_PATH];
+ int defaultProfileSpecified;
+
+ if(GetAsyncKeyState(VK_CONTROL)&0x8000) return 1;
+ GetPrivateProfileStringA("Database","ShowProfileMgr","smart",szShowValue,sizeof(szShowValue),mirandabootini);
+ if(!lstrcmpiA(szShowValue,"always")) return 1;
+ if(!lstrcmpiA(szShowValue,"never")) {
+ return GetDefaultProfilePath(szDefaultProfile,sizeof(szDefaultProfile),NULL);
+ }
+ return GetDefaultProfilePath(szDefaultProfile,sizeof(szDefaultProfile),&defaultProfileSpecified)
+ || !defaultProfileSpecified;
+}
+
+static BOOL CALLBACK InstallIniDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
+{
+ switch(message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemTextA(hwndDlg,IDC_ININAME,(char*)lParam);
+ { char szSecurity[11],*pszSecurityInfo;
+ GetPrivateProfileStringA("AutoExec","Warn","notsafe",szSecurity,sizeof(szSecurity),mirandabootini);
+ if(!lstrcmpiA(szSecurity,"all"))
+ pszSecurityInfo="Security systems to prevent malicious changes are in place and you will be warned before every change that is made.";
+ else if(!lstrcmpiA(szSecurity,"onlyunsafe"))
+ pszSecurityInfo="Security systems to prevent malicious changes are in place and you will be warned before changes that are known to be unsafe.";
+ else if(!lstrcmpiA(szSecurity,"none"))
+ pszSecurityInfo="Security systems to prevent malicious changes have been disabled. You will receive no further warnings.";
+ else pszSecurityInfo=NULL;
+ if(pszSecurityInfo) SetDlgItemTextA(hwndDlg,IDC_SECURITYINFO,ServiceExists(MS_LANGPACK_TRANSLATESTRING)?Translate(pszSecurityInfo):pszSecurityInfo);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_VIEWINI:
+ { char szPath[MAX_PATH];
+ GetDlgItemTextA(hwndDlg,IDC_ININAME,szPath,sizeof(szPath));
+ ShellExecuteA(hwndDlg,"open",szPath,NULL,NULL,SW_SHOW);
+ break;
+ }
+ case IDOK:
+ case IDCANCEL:
+ case IDC_NOTOALL:
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static int IsInSpaceSeparatedList(const char *szWord,const char *szList)
+{
+ char *szItem,*szEnd;
+ int wordLen=lstrlenA(szWord);
+
+ for(szItem=(char*)szList;;) {
+ szEnd=strchr(szItem,' ');
+ if(szEnd==NULL) return !lstrcmpA(szItem,szWord);
+ if(szEnd-szItem==wordLen) {
+ if(!strncmp(szItem,szWord,wordLen)) return 1;
+ }
+ szItem=szEnd+1;
+ }
+ return 0;
+}
+
+struct warnSettingChangeInfo_t {
+ char *szIniPath;
+ char *szSection;
+ char *szSafeSections;
+ char *szUnsafeSections;
+ char *szName;
+ char *szValue;
+ int warnNoMore,cancel;
+};
+
+static BOOL CALLBACK WarnIniChangeDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
+{
+ static struct warnSettingChangeInfo_t *warnInfo;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ { char szSettingName[256];
+ char *pszSecurityInfo;
+ warnInfo=(struct warnSettingChangeInfo_t*)lParam;
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemTextA(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="This change is known to be safe.";
+ else if(IsInSpaceSeparatedList(warnInfo->szSection,warnInfo->szUnsafeSections))
+ pszSecurityInfo="This change is known to be potentially hazardous.";
+ else
+ pszSecurityInfo="This change is not known to be safe.";
+ SetDlgItemTextA(hwndDlg,IDC_SECURITYINFO,ServiceExists(MS_LANGPACK_TRANSLATESTRING)?Translate(pszSecurityInfo):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 BOOL CALLBACK IniImportDoneDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
+{
+ switch(message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemTextA(hwndDlg,IDC_ININAME,(char*)lParam);
+ SetDlgItemTextA(hwndDlg,IDC_NEWNAME,(char*)lParam);
+ return TRUE;
+ case WM_COMMAND:
+ { char szIniPath[MAX_PATH];
+ GetDlgItemTextA(hwndDlg,IDC_ININAME,szIniPath,sizeof(szIniPath));
+ switch(LOWORD(wParam)) {
+ case IDC_DELETE:
+ DeleteFileA(szIniPath);
+ case IDC_LEAVE:
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ case IDC_RECYCLE:
+ { SHFILEOPSTRUCTA shfo={0};
+ shfo.wFunc=FO_DELETE;
+ shfo.pFrom=szIniPath;
+ szIniPath[lstrlenA(szIniPath)+1]='\0';
+ shfo.fFlags=FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_SILENT;
+ SHFileOperationA(&shfo);
+ }
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ case IDC_MOVE:
+ { char szNewPath[MAX_PATH];
+ GetDlgItemTextA(hwndDlg,IDC_NEWNAME,szNewPath,sizeof(szNewPath));
+ MoveFileA(szIniPath,szNewPath);
+ }
+ EndDialog(hwndDlg,LOWORD(wParam));
+ break;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+static void DoAutoExec(void)
+{
+ HANDLE hFind;
+ char szMirandaDir[MAX_PATH],szUse[7],szIniPath[MAX_PATH],szFindPath[MAX_PATH],szExpandedFindPath[MAX_PATH];
+ char szLine[2048];
+ char *str2;
+ WIN32_FIND_DATAA fd;
+ FILE *fp;
+ char szSection[128];
+ int lineLength;
+ char szSafeSections[2048],szUnsafeSections[2048],szSecurity[11],szOverrideSecurityFilename[MAX_PATH];
+ int warnThisSection=0;
+
+ GetPrivateProfileStringA("AutoExec","Use","prompt",szUse,sizeof(szUse),mirandabootini);
+ if(!lstrcmpiA(szUse,"no")) return;
+ GetPrivateProfileStringA("AutoExec","Safe","CLC Icons CLUI CList SkinSounds",szSafeSections,sizeof(szSafeSections),mirandabootini);
+ GetPrivateProfileStringA("AutoExec","Unsafe","ICQ MSN",szUnsafeSections,sizeof(szUnsafeSections),mirandabootini);
+ GetPrivateProfileStringA("AutoExec","Warn","notsafe",szSecurity,sizeof(szSecurity),mirandabootini);
+ GetPrivateProfileStringA("AutoExec","OverrideSecurityFilename","",szOverrideSecurityFilename,sizeof(szOverrideSecurityFilename),mirandabootini);
+ GetModuleFileNameA(GetModuleHandle(NULL),szMirandaDir,sizeof(szMirandaDir));
+ str2=strrchr(szMirandaDir,'\\');
+ if(str2!=NULL) *str2=0;
+ _chdir(szMirandaDir);
+ GetPrivateProfileStringA("AutoExec","Glob","autoexec_*.ini",szFindPath,sizeof(szFindPath),mirandabootini);
+ ExpandEnvironmentStringsA(szFindPath,szExpandedFindPath,sizeof(szExpandedFindPath));
+ hFind=FindFirstFileA(szExpandedFindPath,&fd);
+ if(hFind==INVALID_HANDLE_VALUE) return;
+ str2=strrchr(szExpandedFindPath,'\\');
+ if(str2==NULL) str2=szExpandedFindPath;
+ else str2++;
+ *str2='\0';
+ szSection[0]='\0';
+ do {
+ lstrcpyA(szIniPath,szExpandedFindPath);
+ lstrcatA(szIniPath,fd.cFileName);
+ if(!lstrcmpiA(szUse,"prompt") && lstrcmpiA(fd.cFileName,szOverrideSecurityFilename)) {
+ int result=DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_INSTALLINI),NULL,InstallIniDlgProc,(LPARAM)szIniPath);
+ if(result==IDC_NOTOALL) break;
+ if(result==IDCANCEL) continue;
+ }
+ fp=fopen(szIniPath,"rt");
+ while(!feof(fp)) {
+ if(fgets(szLine,sizeof(szLine),fp)==NULL) break;
+ lineLength=lstrlenA(szLine);
+ while(lineLength && (BYTE)(szLine[lineLength-1])<=' ') szLine[--lineLength]='\0';
+ if(szLine[0]==';' || szLine[0]<=' ') continue;
+ if(szLine[0]=='[') {
+ char *szEnd=strchr(szLine+1,']');
+ if(szEnd==NULL) continue;
+ if(szLine[1]=='!')
+ szSection[0]='\0';
+ else {
+ lstrcpynA(szSection,szLine+1,min(sizeof(szSection),szEnd-szLine));
+ if(!lstrcmpiA(szSecurity,"none")) warnThisSection=0;
+ else if(!lstrcmpiA(szSecurity,"notsafe"))
+ warnThisSection=!IsInSpaceSeparatedList(szSection,szSafeSections);
+ else if(!lstrcmpiA(szSecurity,"onlyunsafe"))
+ warnThisSection=IsInSpaceSeparatedList(szSection,szUnsafeSections);
+ else warnThisSection=1;
+ if(!lstrcmpiA(fd.cFileName,szOverrideSecurityFilename)) warnThisSection=0;
+ }
+ }
+ else {
+ char *szValue;
+ char szName[128];
+ struct warnSettingChangeInfo_t warnInfo;
+
+ if(szSection[0]=='\0') continue;
+ szValue=strchr(szLine,'=');
+ if(szValue==NULL) continue;
+ lstrcpynA(szName,szLine,min(sizeof(szName),szValue-szLine+1));
+ szValue++;
+ 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(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_WARNINICHANGE),NULL,WarnIniChangeDlgProc,(LPARAM)&warnInfo)) {
+ 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 's':
+ case 'S':
+ DBWriteContactSettingString(NULL,szSection,szName,szValue+1);
+ break;
+ case 'u':
+ case 'U':
+ DBWriteContactSettingStringUtf(NULL,szSection,szName,szValue+1);
+ break;
+ case 'n':
+ case 'N':
+ { 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:
+ if(ServiceExists(MS_LANGPACK_TRANSLATESTRING))
+ MessageBox(NULL,TranslateT("Invalid setting type. The first character of every value must be b, w, d, l, s or n."),TranslateT("Install Database Settings"),MB_OK);
+ else
+ MessageBoxA(NULL,"Invalid setting type. The first character of every value must be b, w, d, l, s or n.","Install Database Settings",MB_OK);
+ break;
+ }
+ }
+ }
+ }
+ fclose(fp);
+ if(!lstrcmpiA(fd.cFileName,szOverrideSecurityFilename))
+ DeleteFileA(szIniPath);
+ else {
+ char szOnCompletion[8];
+ GetPrivateProfileStringA("AutoExec","OnCompletion","recycle",szOnCompletion,sizeof(szOnCompletion),mirandabootini);
+ if(!lstrcmpiA(szOnCompletion,"delete"))
+ DeleteFileA(szIniPath);
+ else if(!lstrcmpiA(szOnCompletion,"recycle")) {
+ SHFILEOPSTRUCTA shfo={0};
+ shfo.wFunc=FO_DELETE;
+ shfo.pFrom=szIniPath;
+ szIniPath[lstrlenA(szIniPath)+1]='\0';
+ shfo.fFlags=FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_SILENT;
+ SHFileOperationA(&shfo);
+ }
+ else if(!lstrcmpiA(szOnCompletion,"rename")) {
+ char szRenamePrefix[MAX_PATH];
+ char szNewPath[MAX_PATH];
+ GetPrivateProfileStringA("AutoExec","RenamePrefix","done_",szRenamePrefix,sizeof(szRenamePrefix),mirandabootini);
+ lstrcpyA(szNewPath,szExpandedFindPath);
+ lstrcatA(szNewPath,szRenamePrefix);
+ lstrcatA(szNewPath,fd.cFileName);
+ MoveFileA(szIniPath,szNewPath);
+ }
+ else if(!lstrcmpiA(szOnCompletion,"ask"))
+ DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_INIIMPORTDONE),NULL,IniImportDoneDlgProc,(LPARAM)szIniPath);
+ }
+ } while(FindNextFileA(hFind,&fd));
+ FindClose(hFind);
+}
+
+static int CheckIniImportNow(WPARAM wParam,LPARAM lParam)
+{
+ DoAutoExec();
+ FindNextChangeNotification(hIniChangeNotification);
+ return 0;
+}
+
+int InitIni(void)
+{
+ char szMirandaDir[MAX_PATH];
+ char *str2;
+
+ DoAutoExec();
+ GetModuleFileNameA(GetModuleHandle(NULL),szMirandaDir,sizeof(szMirandaDir));
+ str2=strrchr(szMirandaDir,'\\');
+ if(str2!=NULL) *str2=0;
+ hIniChangeNotification=FindFirstChangeNotificationA(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)
+{
+ CallService(MS_SYSTEM_REMOVEWAIT,(WPARAM)hIniChangeNotification,0);
+ FindCloseChangeNotification(hIniChangeNotification);
+}
\ No newline at end of file diff --git a/miranda-wine/src/modules/database/dblists.c b/miranda-wine/src/modules/database/dblists.c new file mode 100644 index 0000000..ab656ff --- /dev/null +++ b/miranda-wine/src/modules/database/dblists.c @@ -0,0 +1,149 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 "dblists.h"
+
+/* a simple sorted list implementation */
+
+SortedList* List_Create( int p_limit, int p_increment )
+{
+ SortedList* result = ( SortedList* )mir_calloc( sizeof( SortedList ));
+ if ( result == NULL )
+ return(NULL);
+
+ result->increment = p_increment;
+ result->limit = p_limit;
+ return(result);
+}
+
+void List_Destroy( SortedList* p_list )
+{
+ if ( p_list == NULL )
+ return;
+
+ if ( p_list->items != NULL ) {
+ mir_free( p_list->items );
+ p_list->items = NULL;
+ }
+
+ p_list->realCount = p_list->limit = 0;
+}
+
+void* List_Find( SortedList* p_list, void* p_value )
+{
+ int index;
+
+ if ( !List_GetIndex( p_list, p_value, &index ))
+ return(NULL);
+
+ return(p_list->items[ index ]);
+}
+
+int List_GetIndex( SortedList* p_list, void* p_value, int* p_index )
+{
+ if ( p_list->sortFunc != NULL )
+ {
+ int low = 0;
+ int high = p_list->realCount-1;
+
+ while( low <= high )
+ {
+ int i = ( low+high )/2;
+ int result = p_list->sortFunc( p_list->items[ i ], p_value );
+ if ( result == 0 )
+ { *p_index = i;
+ return 1;
+ }
+
+ if ( result < 0 )
+ low = i+1;
+ else
+ high = i-1;
+ }
+
+ *p_index = low;
+ }
+ return 0;
+}
+
+int List_IndexOf( SortedList* p_list, void* p_value )
+{
+ int i;
+ for ( i=0; i < p_list->realCount; i++ )
+ if ( p_list->items[i] == p_value )
+ return i;
+
+ return -1;
+}
+
+int List_Insert( SortedList* p_list, void* p_value, int p_index)
+{
+ if ( p_value == NULL || p_index > p_list->realCount )
+ return 0;
+
+ if ( p_list->realCount == p_list->limit )
+ {
+ p_list->items = ( void** )mir_realloc( p_list->items, sizeof( void* )*(p_list->realCount + p_list->increment));
+ p_list->limit += p_list->increment;
+ }
+
+ if ( p_index < p_list->realCount )
+ memmove( p_list->items+p_index+1, p_list->items+p_index, sizeof( void* )*( p_list->realCount-p_index ));
+
+ p_list->realCount++;
+
+ p_list->items[ p_index ] = p_value;
+ return 1;
+}
+
+int List_InsertPtr( SortedList* list, void* p )
+{
+ int idx;
+ List_GetIndex( list, p, &idx );
+ return List_Insert( list, p, idx );
+}
+
+int List_Remove( SortedList* p_list, int index )
+{
+ if ( index < 0 || index > p_list->realCount )
+ return(0);
+
+ p_list->realCount--;
+ if ( p_list->realCount > index )
+ {
+ memmove( p_list->items+index, p_list->items+index+1, sizeof( void* )*( p_list->realCount-index ));
+ p_list->items[ p_list->realCount ] = NULL;
+ }
+
+ return 1;
+}
+
+int List_RemovePtr( SortedList* list, void* p )
+{
+ int idx = -1;
+ if ( List_GetIndex( list, p, &idx ))
+ List_Remove( list, idx );
+
+ return idx;
+}
diff --git a/miranda-wine/src/modules/database/dblists.h b/miranda-wine/src/modules/database/dblists.h new file mode 100644 index 0000000..c3397ab --- /dev/null +++ b/miranda-wine/src/modules/database/dblists.h @@ -0,0 +1,36 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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.
+*/
+
+/* a simple sorted list implementation */
+
+SortedList* List_Create( int, int );
+void List_Destroy( SortedList* );
+
+void* List_Find( SortedList*, void* );
+int List_GetIndex( SortedList*, void*, int* );
+int List_Insert( SortedList*, void*, int );
+int List_Remove( SortedList*, int );
+int List_IndexOf( SortedList*, void* );
+
+int List_InsertPtr( SortedList* list, void* p );
+int List_RemovePtr( SortedList* list, void* p );
diff --git a/miranda-wine/src/modules/database/dbtime.c b/miranda-wine/src/modules/database/dbtime.c new file mode 100644 index 0000000..b2c9eb1 --- /dev/null +++ b/miranda-wine/src/modules/database/dbtime.c @@ -0,0 +1,239 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 "database.h"
+
+static int daysInMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
+static int IsLeapYear(int year)
+{
+ if(year&3) return 0;
+ if(year%100) return 1;
+ if(year%400) return 0;
+ return 1;
+}
+
+static int CompareSystemTimes(SYSTEMTIME *st,SYSTEMTIME *switchDate)
+{
+ FILETIME ft1,ft2;
+
+ if(switchDate->wYear==0) { //strange day-in-month thing
+ SYSTEMTIME tempst;
+
+ //short-circuit if the months aren't the same
+ if(st->wMonth<switchDate->wMonth) return -1;
+ if(st->wMonth>switchDate->wMonth) return 1;
+
+ tempst=*switchDate;
+ tempst.wYear=st->wYear;
+ tempst.wDay=1;
+ SystemTimeToFileTime(&tempst,&ft1);
+ FileTimeToSystemTime(&ft1,&tempst); //gets the day of week of the first of the month
+ tempst.wDay=1+(7+switchDate->wDayOfWeek-tempst.wDayOfWeek)%7;
+ if(switchDate->wDay==5) { //last wDayOfWeek in month
+ if(tempst.wMonth==2) {
+ if(IsLeapYear(tempst.wYear)) daysInMonth[1]=29;
+ else daysInMonth[1]=28;
+ }
+ tempst.wDay+=7*3; //can't be less than 4 of that day in the month
+ if(tempst.wDay+7<=daysInMonth[switchDate->wMonth-1]) tempst.wDay+=7;
+ }
+ else tempst.wDay+=7*(switchDate->wDay-1); //nth of month
+ SystemTimeToFileTime(&tempst,&ft2);
+ }
+ else {
+ switchDate->wYear=st->wYear;
+ SystemTimeToFileTime(switchDate,&ft2);
+ }
+ SystemTimeToFileTime(st,&ft1);
+ return CompareFileTime(&ft1,&ft2);
+}
+
+static int TimestampToLocal(WPARAM wParam,LPARAM lParam)
+{
+ TIME_ZONE_INFORMATION tzInfo;
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+ int iReturn = 0;
+
+ GetTimeZoneInformation(&tzInfo);
+ if(tzInfo.StandardDate.wMonth==0)
+ {
+ //no daylight savings time
+ iReturn = (int)(wParam-tzInfo.Bias*60);
+ }
+ else
+ {
+ //this huge number is the difference between 1970 and 1601 in seconds
+ liFiletime.QuadPart=((__int64)11644473600+(__int64)wParam)*10000000;
+ filetime.dwHighDateTime=liFiletime.HighPart;
+ filetime.dwLowDateTime=liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime,&st);
+
+ if(tzInfo.DaylightDate.wMonth<tzInfo.StandardDate.wMonth)
+ {
+ //northern hemisphere
+ if(CompareSystemTimes(&st,&tzInfo.DaylightDate)<0 ||
+ CompareSystemTimes(&st,&tzInfo.StandardDate)>0)
+ {
+ iReturn = (int)(wParam-(tzInfo.Bias+tzInfo.StandardBias)*60);
+ }
+ else
+ {
+ iReturn = (int)(wParam-(tzInfo.Bias+tzInfo.DaylightBias)*60);
+ }
+ }
+ else
+ {
+ //southern hemisphere
+ if(CompareSystemTimes(&st,&tzInfo.StandardDate)<0 ||
+ CompareSystemTimes(&st,&tzInfo.DaylightDate)>0)
+ {
+ iReturn = (int)(wParam-(tzInfo.Bias+tzInfo.DaylightBias)*60);
+ }
+ else
+ {
+ iReturn = (int)(wParam-(tzInfo.Bias+tzInfo.StandardBias)*60);
+ }
+ }
+ }
+
+ return iReturn;
+}
+
+static int TimestampToString(WPARAM wParam,LPARAM lParam)
+{
+ DBTIMETOSTRING *tts=(DBTIMETOSTRING*)lParam;
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+ char dateTimeStr[64];
+ char *pDest,*pFormat;
+ int destCharsLeft,dateTimeStrLen;
+
+ //this huge number is the difference between 1970 and 1601 in seconds
+ liFiletime.QuadPart=((__int64)11644473600+(__int64)(DWORD)TimestampToLocal(wParam,0))*10000000;
+ filetime.dwHighDateTime=liFiletime.HighPart;
+ filetime.dwLowDateTime=liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime,&st);
+ destCharsLeft=tts->cbDest;
+ for(pFormat=tts->szFormat,pDest=tts->szDest;*pFormat;pFormat++) {
+ switch(*pFormat) {
+ case 't':
+ GetTimeFormatA(LOCALE_USER_DEFAULT,TIME_NOSECONDS,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 's':
+ GetTimeFormatA(LOCALE_USER_DEFAULT,0,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 'm':
+ GetTimeFormatA(LOCALE_USER_DEFAULT,TIME_NOMINUTESORSECONDS,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 'd':
+ GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 'D':
+ GetDateFormatA(LOCALE_USER_DEFAULT,DATE_LONGDATE,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ default:
+ if(destCharsLeft) {
+ *pDest++=*pFormat;
+ destCharsLeft--;
+ }
+ continue;
+ }
+ dateTimeStrLen=strlen(dateTimeStr);
+ if(destCharsLeft<dateTimeStrLen) dateTimeStrLen=destCharsLeft;
+ CopyMemory(pDest,dateTimeStr,dateTimeStrLen);
+ destCharsLeft-=dateTimeStrLen;
+ pDest+=dateTimeStrLen;
+ }
+ if(destCharsLeft) *pDest=0;
+ else tts->szDest[tts->cbDest-1]=0;
+ return 0;
+}
+
+#if defined( _UNICODE )
+static int TimestampToStringW(WPARAM wParam,LPARAM lParam)
+{
+ DBTIMETOSTRINGT *tts = ( DBTIMETOSTRINGT* )lParam;
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+ TCHAR dateTimeStr[64];
+ TCHAR *pDest,*pFormat;
+ int destCharsLeft, dateTimeStrLen;
+
+ //this huge number is the difference between 1970 and 1601 in seconds
+ liFiletime.QuadPart = (11644473600i64+(__int64)(DWORD)TimestampToLocal(wParam,0))*10000000;
+ filetime.dwHighDateTime = liFiletime.HighPart;
+ filetime.dwLowDateTime = liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime,&st);
+ destCharsLeft = tts->cbDest;
+ for ( pFormat = tts->szFormat, pDest=tts->szDest; *pFormat; pFormat++ ) {
+ switch(*pFormat) {
+ case 't':
+ GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOSECONDS,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 's':
+ GetTimeFormat(LOCALE_USER_DEFAULT,0,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 'm':
+ GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOMINUTESORSECONDS,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 'd':
+ GetDateFormat(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ case 'D':
+ GetDateFormat(LOCALE_USER_DEFAULT,DATE_LONGDATE,&st,NULL,dateTimeStr,SIZEOF(dateTimeStr));
+ break;
+ default:
+ if ( destCharsLeft ) {
+ *pDest++ = *pFormat;
+ destCharsLeft--;
+ }
+ continue;
+ }
+ dateTimeStrLen = _tcslen(dateTimeStr);
+ if (destCharsLeft < dateTimeStrLen) dateTimeStrLen = destCharsLeft;
+ CopyMemory(pDest, dateTimeStr, dateTimeStrLen*sizeof(TCHAR));
+ destCharsLeft -= dateTimeStrLen;
+ pDest += dateTimeStrLen;
+ }
+ if ( destCharsLeft ) *pDest=0;
+ else tts->szDest[ tts->cbDest-1 ] = 0;
+ return 0;
+}
+#endif
+
+int InitTime(void)
+{
+ CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOLOCAL, TimestampToLocal);
+ CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOSTRING, TimestampToString);
+ #if defined( _UNICODE )
+ CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOSTRINGT, TimestampToStringW);
+ #else
+ CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOSTRINGT, TimestampToString);
+ #endif
+ return 0;
+}
diff --git a/miranda-wine/src/modules/database/profilemanager.c b/miranda-wine/src/modules/database/profilemanager.c new file mode 100644 index 0000000..8eeaa09 --- /dev/null +++ b/miranda-wine/src/modules/database/profilemanager.c @@ -0,0 +1,696 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 "profilemanager.h"
+#include <sys/stat.h>
+
+#define WM_INPUTCHANGED (WM_USER + 0x3000)
+#define WM_FOCUSTEXTBOX (WM_USER + 0x3001)
+
+typedef BOOL (__cdecl *ENUMPROFILECALLBACK) (char * fullpath, char * profile, LPARAM lParam);
+
+struct DetailsPageInit {
+ int pageCount;
+ OPTIONSDIALOGPAGE *odp;
+};
+
+struct DetailsPageData {
+ DLGTEMPLATE *pTemplate;
+ HINSTANCE hInst;
+ DLGPROC dlgProc;
+ HWND hwnd;
+ int changed;
+};
+
+struct DlgProfData {
+ PROPSHEETHEADER * psh;
+ HWND hwndOK; // handle to OK button
+ PROFILEMANAGERDATA * pd;
+};
+
+struct DetailsData {
+ HINSTANCE hInstIcmp;
+ HFONT hBoldFont;
+ int pageCount;
+ int currentPage;
+ struct DetailsPageData *opd;
+ RECT rcDisplay;
+ struct DlgProfData * prof;
+};
+
+extern char mirandabootini[MAX_PATH]; // bad bad bad bad!
+static char szDefaultMirandaProfile[MAX_PATH];
+
+static void ThemeDialogBackground(HWND hwnd) {
+ if (IsWinVerXPPlus()) {
+ static HMODULE hThemeAPI = NULL;
+ if (!hThemeAPI) hThemeAPI = GetModuleHandleA("uxtheme");
+ if (hThemeAPI) {
+ HRESULT (STDAPICALLTYPE *MyEnableThemeDialogTexture)(HWND,DWORD) = (HRESULT (STDAPICALLTYPE*)(HWND,DWORD))GetProcAddress(hThemeAPI,"EnableThemeDialogTexture");
+ if (MyEnableThemeDialogTexture)
+ MyEnableThemeDialogTexture(hwnd,0x00000002|0x00000004); //0x00000002|0x00000004=ETDT_ENABLETAB
+ }
+ }
+}
+
+static int findProfiles(char * szProfileDir, ENUMPROFILECALLBACK callback, LPARAM lParam)
+{
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATAA ffd;
+ char searchspec[MAX_PATH];
+ mir_snprintf(searchspec, SIZEOF(searchspec), "%s\\*.dat", szProfileDir);
+ hFind = FindFirstFileA(searchspec, &ffd);
+ if ( hFind != INVALID_HANDLE_VALUE ) {
+ do {
+ if ( !(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && isValidProfileName(ffd.cFileName) )
+ {
+ char buf[MAX_PATH];
+ mir_snprintf(buf,SIZEOF(buf),"%s\\%s",szProfileDir, ffd.cFileName);
+ if ( !callback(buf, ffd.cFileName, lParam) ) break;
+ }
+ } while ( FindNextFileA(hFind, &ffd) );
+ FindClose(hFind);
+ return 1;
+ }
+ return 0;
+}
+
+static LRESULT CALLBACK ProfileNameValidate(HWND edit, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if ( msg==WM_CHAR ) {
+ if ( strchr(".?/\\#' ",(char)wParam&0xFF) != 0 ) return 0;
+ PostMessage(GetParent(edit),WM_INPUTCHANGED,0,0);
+ }
+ return CallWindowProc((WNDPROC)GetWindowLong(edit,GWL_USERDATA),edit,msg,wParam,lParam);
+}
+
+static int FindDbProviders(char * pluginname, DATABASELINK * dblink, LPARAM lParam)
+{
+ HWND hwndDlg = (HWND)lParam;
+ HWND hwndCombo = GetDlgItem(hwndDlg, IDC_PROFILEDRIVERS);
+ char szName[64];
+
+ if ( dblink->getFriendlyName(szName,SIZEOF(szName),1) == 0 ) {
+ // add to combo box
+ LRESULT index = SendMessageA(hwndCombo, CB_ADDSTRING, 0, (LPARAM)Translate(szName));
+ SendMessage(hwndCombo, CB_SETITEMDATA, index, (LPARAM)dblink);
+ }
+ return DBPE_CONT;
+}
+
+// returns 1 if autocreation of the profile is setup, profile has to be at least MAX_PATH!
+static int checkAutoCreateProfile(char * profile)
+{
+ char ac[MAX_PATH];
+ char env_profile[MAX_PATH];
+ GetPrivateProfileStringA("Database", "AutoCreate", "no", ac, SIZEOF(ac), mirandabootini);
+ if ( lstrcmpiA(ac,"yes") != 0 ) return 0;
+ GetPrivateProfileStringA("Database", "DefaultProfile", "", ac, SIZEOF(ac), mirandabootini);
+ ExpandEnvironmentStringsA(ac, env_profile, SIZEOF(env_profile));
+ if ( profile != NULL ) strcpy(profile, env_profile);
+ return lstrlenA(env_profile) > 0;
+}
+
+static BOOL CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct DlgProfData * dat = (struct DlgProfData *)GetWindowLong(hwndDlg,GWL_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ // lParam = (struct DlgProfData *)
+ SetWindowLong(hwndDlg, GWL_USERDATA, lParam);
+ dat=(struct DlgProfData *)lParam;
+ {
+ // fill in the db plugins present
+ PLUGIN_DB_ENUM dbe;
+ dbe.cbSize=sizeof(dbe);
+ dbe.pfnEnumCallback=(int(*)(char*,void*,LPARAM))FindDbProviders;
+ dbe.lParam=(LPARAM)hwndDlg;
+ if ( CallService(MS_PLUGINS_ENUMDBPLUGINS,0,(LPARAM)&dbe) == (-1) ) {
+ // no plugins?!
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PROFILEDRIVERS),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PROFILENAME),FALSE);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_NODBDRIVERS),TRUE);
+ } //if
+ // default item
+ SendDlgItemMessage(hwndDlg, IDC_PROFILEDRIVERS, CB_SETCURSEL, 0, 0);
+ }
+ // subclass the profile name box
+ {
+ HWND hwndProfile=GetDlgItem(hwndDlg, IDC_PROFILENAME);
+ WNDPROC proc = (WNDPROC)GetWindowLong(hwndProfile, GWL_WNDPROC);
+ SetWindowLong(hwndProfile,GWL_USERDATA,(LONG)proc);
+ SetWindowLong(hwndProfile,GWL_WNDPROC,(LONG)ProfileNameValidate);
+ }
+ // decide if there is a default profile name given in the INI and if it should be used
+ {
+ char profile[MAX_PATH];
+ if ( checkAutoCreateProfile((char*)&profile) ) SetDlgItemTextA(hwndDlg, IDC_PROFILENAME, profile);
+ }
+ // focus on the textbox
+ PostMessage(hwndDlg,WM_FOCUSTEXTBOX,0,0);
+ return TRUE;
+ }
+ case WM_FOCUSTEXTBOX:
+ {
+ SetFocus(GetDlgItem(hwndDlg,IDC_PROFILENAME));
+ break;
+ }
+ case WM_INPUTCHANGED: // when input in the edit box changes
+ {
+ SendMessage(GetParent(hwndDlg),PSM_CHANGED,0,0);
+ EnableWindow(dat->hwndOK, GetWindowTextLength(GetDlgItem(hwndDlg,IDC_PROFILENAME)) > 0 );
+ break;
+ }
+ case WM_SHOWWINDOW:
+ {
+ if ( wParam ) {
+ SetWindowText( dat->hwndOK, TranslateT("&Create"));
+ SendMessage(hwndDlg,WM_INPUTCHANGED,0,0);
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ NMHDR * hdr = (NMHDR *)lParam;
+ if ( hdr && hdr->code == PSN_APPLY && dat && IsWindowVisible(hwndDlg) ) {
+ char szName[MAX_PATH];
+ LRESULT curSel = SendDlgItemMessage(hwndDlg,IDC_PROFILEDRIVERS,CB_GETCURSEL,0,0);
+ if ( curSel == CB_ERR ) break; // should never happen
+ GetWindowTextA(GetDlgItem(hwndDlg,IDC_PROFILENAME),szName,SIZEOF(szName));
+ if ( lstrlenA(szName) == 0 ) break;
+ mir_snprintf(dat->pd->szProfile,MAX_PATH,"%s\\%s.dat",dat->pd->szProfileDir,szName);
+ dat->pd->newProfile=1;
+ dat->pd->dblink=(DATABASELINK *)SendDlgItemMessage(hwndDlg,IDC_PROFILEDRIVERS,CB_GETITEMDATA,(WPARAM)curSel,0);
+
+ if ( makeDatabase(dat->pd->szProfile, dat->pd->dblink, hwndDlg) == 0 ) {
+ SetWindowLong(hwndDlg,DWL_MSGRESULT,PSNRET_INVALID_NOCHANGEPAGE);
+ return FALSE;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+TCHAR* rtrim( TCHAR *string )
+{
+ TCHAR* p = string + _tcslen( string ) - 1;
+
+ while ( p >= string )
+ { if ( *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' )
+ break;
+
+ *p-- = 0;
+ }
+ return string;
+}
+
+static int DetectDbProvider(char * pluginname, DATABASELINK * dblink, LPARAM lParam)
+{
+ char* fullPath = (char*)lParam;
+ int error;
+
+ if ( dblink->grokHeader( fullPath, &error ) == 0 ) {
+ dblink->getFriendlyName( fullPath, MAX_PATH, 1 );
+ //strncpy( fullPath, pluginname, MAX_PATH );
+ return DBPE_HALT;
+ }
+
+ return DBPE_CONT;
+}
+
+BOOL EnumProfilesForList(char * fullpath, char * profile, LPARAM lParam)
+{
+ HWND hwndDlg = (HWND) lParam;
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PROFILELIST);
+ char sizeBuf[64];
+ LVITEMA item;
+ int iItem=0;
+ struct stat statbuf;
+ int bFileExists = FALSE;
+ char * p = strrchr(profile, '.');
+ strcpy(sizeBuf, "0 KB");
+ if ( p != NULL ) *p=0;
+ ZeroMemory(&item,sizeof(item));
+ item.mask = LVIF_TEXT | LVIF_IMAGE;
+ item.pszText = profile;
+ item.iItem=0;
+ item.iImage=0;
+ {
+ FILE * fp = fopen(fullpath, "r+");
+ item.iImage = fp != NULL ? 0 : 1;
+ if ( stat(fullpath, &statbuf) == 0) {
+ mir_snprintf(sizeBuf,SIZEOF(sizeBuf),"%u KB", statbuf.st_size / 1024);
+ bFileExists = TRUE;
+ }
+ if ( fp ) fclose(fp);
+ }
+ iItem=SendMessageA( hwndList, LVM_INSERTITEMA, 0, (LPARAM)&item);
+ if ( lstrcmpiA(szDefaultMirandaProfile, profile) == 0 )
+ ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED);
+
+ item.iItem = iItem;
+ item.iSubItem = 2;
+ item.pszText = sizeBuf;
+ SendMessageA( hwndList, LVM_SETITEMTEXTA, iItem, (LPARAM)&item );
+
+ if ( bFileExists ) {
+ PLUGIN_DB_ENUM dbe;
+ char szPath[ MAX_PATH ];
+
+ LVITEM item2;
+ item2.mask = LVIF_TEXT;
+ item2.iItem = iItem;
+
+ dbe.cbSize=sizeof(dbe);
+ dbe.pfnEnumCallback=(int(*)(char*,void*,LPARAM))DetectDbProvider;
+ dbe.lParam=(LPARAM)szPath;
+ strncpy( szPath, fullpath, sizeof(szPath));
+ if (CallService(MS_PLUGINS_ENUMDBPLUGINS,0,(LPARAM)&dbe)==1) {
+ HANDLE hFile;
+
+ hFile=CreateFileA(fullpath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ // file locked
+ item.pszText = Translate("<In Use>");
+ }
+ else {
+ CloseHandle(hFile);
+ item.pszText = szPath;
+ }
+ item.iSubItem = 1;
+ SendMessageA( hwndList, LVM_SETITEMTEXTA, iItem, (LPARAM)&item );
+ }
+
+ item2.iSubItem = 3;
+ item2.pszText = rtrim( _tctime( &statbuf.st_ctime ));
+ SendMessage( hwndList, LVM_SETITEMTEXT, iItem, (LPARAM)&item2 );
+
+ item2.iSubItem = 4;
+ item2.pszText = rtrim( _tctime( &statbuf.st_mtime ));
+ SendMessage( hwndList, LVM_SETITEMTEXT, iItem, (LPARAM)&item2 );
+ }
+ return TRUE;
+}
+
+static BOOL CALLBACK DlgProfileSelect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct DlgProfData * dat = (struct DlgProfData *)GetWindowLong(hwndDlg, GWL_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PROFILELIST);
+ HIMAGELIST hImgList=0;
+ LVCOLUMN col;
+
+ TranslateDialogDefault(hwndDlg);
+
+ dat = (struct DlgProfData *) lParam;
+ SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)dat);
+
+ // set columns
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.pszText = TranslateT("Profile");
+ col.cx=122;
+ ListView_InsertColumn( hwndList, 0, &col );
+
+ col.pszText = TranslateT("Driver");
+ col.cx=100;
+ ListView_InsertColumn( hwndList, 1, &col );
+
+ col.pszText = TranslateT("Size");
+ col.cx=60;
+ ListView_InsertColumn( hwndList, 2, &col );
+
+ col.pszText = TranslateT("Created");
+ col.cx=145;
+ ListView_InsertColumn( hwndList, 3, &col );
+
+ col.pszText = TranslateT("Accessed");
+ col.cx=145;
+ ListView_InsertColumn( hwndList, 4, &col );
+
+ // icons
+ hImgList=ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16), 1, 1);
+ ImageList_AddIcon(hImgList, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_USERDETAILS)) );
+ ImageList_AddIcon(hImgList, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_DELETE)) );
+ // LV will destroy the image list
+ ListView_SetImageList(hwndList, hImgList, LVSIL_SMALL);
+ // find all the profiles
+ findProfiles(dat->pd->szProfileDir, EnumProfilesForList, (LPARAM)hwndDlg);
+ PostMessage(hwndDlg,WM_FOCUSTEXTBOX,0,0);
+ return TRUE;
+ }
+ case WM_FOCUSTEXTBOX:
+ {
+ HWND hwndList=GetDlgItem(hwndDlg,IDC_PROFILELIST);
+ SetFocus(hwndList);
+ if ( lstrlenA(szDefaultMirandaProfile) == 0 || ListView_GetSelectedCount(GetDlgItem(hwndDlg,IDC_PROFILELIST)) == 0 )
+ ListView_SetItemState(hwndList, 0, LVIS_SELECTED, LVIS_SELECTED);
+ break;
+ }
+ case WM_SHOWWINDOW:
+ {
+ if ( wParam ) {
+ SetWindowText(dat->hwndOK,TranslateT("&Run"));
+ EnableWindow(dat->hwndOK, ListView_GetSelectedCount(GetDlgItem(hwndDlg,IDC_PROFILELIST))==1);
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR hdr = (LPNMHDR) lParam;
+ if ( hdr && hdr->code == PSN_INFOCHANGED) {
+ break;
+ }
+ if ( hdr && hdr->idFrom == IDC_PROFILELIST ) {
+ switch ( hdr->code ) {
+ case LVN_ITEMCHANGED:
+ {
+ EnableWindow(dat->hwndOK, ListView_GetSelectedCount(hdr->hwndFrom)==1);
+ }
+ case NM_DBLCLK:
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PROFILELIST);
+ LVITEMA item;
+ char profile[MAX_PATH];
+
+ if ( dat == NULL ) break;
+ ZeroMemory(&item,sizeof(item));
+ item.mask = LVIF_TEXT;
+ item.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED | LVNI_ALL);
+ item.pszText = profile;
+ item.cchTextMax = SIZEOF(profile);
+ if ( SendMessageA(hwndList, LVM_GETITEMA, 0, (LPARAM)&item) && dat ) {
+ mir_snprintf(dat->pd->szProfile, MAX_PATH, "%s\\%s.dat", dat->pd->szProfileDir, profile);
+ if ( hdr->code == NM_DBLCLK ) EndDialog(GetParent(hwndDlg), 1);
+ }
+ return TRUE;
+ }
+ }
+ }
+ break;
+ }
+ } //switch
+ return FALSE;
+}
+
+static BOOL CALLBACK DlgProfileManager(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct DetailsData *dat;
+
+ dat=(struct DetailsData*)GetWindowLong(hwndDlg,GWL_USERDATA);
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ struct DlgProfData * prof = (struct DlgProfData *)lParam;
+ PROPSHEETHEADER *psh = prof->psh;
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_USERDETAILS)));
+ dat=(struct DetailsData*)mir_alloc(sizeof(struct DetailsData));
+ dat->prof = prof;
+ prof->hwndOK=GetDlgItem(hwndDlg,IDOK);
+ EnableWindow(prof->hwndOK, FALSE);
+ SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)dat);
+ SetDlgItemTextA(hwndDlg,IDC_NAME,"Miranda IM Profile Manager");
+ { LOGFONT lf;
+ HFONT hNormalFont=(HFONT)SendDlgItemMessage(hwndDlg,IDC_NAME,WM_GETFONT,0,0);
+ GetObject(hNormalFont,sizeof(lf),&lf);
+ lf.lfWeight=FW_BOLD;
+ dat->hBoldFont=CreateFontIndirect(&lf);
+ SendDlgItemMessage(hwndDlg,IDC_NAME,WM_SETFONT,(WPARAM)dat->hBoldFont,0);
+ }
+ { OPTIONSDIALOGPAGE *odp;
+ int i;
+ TCITEM tci;
+
+ dat->currentPage=0;
+ dat->pageCount=psh->nPages;
+ dat->opd=(struct DetailsPageData*)mir_alloc(sizeof(struct DetailsPageData)*dat->pageCount);
+ odp=(OPTIONSDIALOGPAGE*)psh->ppsp;
+
+ tci.mask=TCIF_TEXT;
+ for(i=0;i<dat->pageCount;i++) {
+ dat->opd[i].pTemplate=(DLGTEMPLATE *)LockResource(LoadResource(odp[i].hInstance,FindResourceA(odp[i].hInstance,odp[i].pszTemplate,MAKEINTRESOURCEA(5))));
+ dat->opd[i].dlgProc=odp[i].pfnDlgProc;
+ dat->opd[i].hInst=odp[i].hInstance;
+ dat->opd[i].hwnd=NULL;
+ dat->opd[i].changed=0;
+ tci.pszText=(TCHAR*)odp[i].ptszTitle;
+ if ( dat->prof->pd->noProfiles || checkAutoCreateProfile(NULL) ) dat->currentPage=1;
+ TabCtrl_InsertItem( GetDlgItem(hwndDlg,IDC_TABS), i, &tci );
+ } }
+
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_TABS),&dat->rcDisplay);
+ TabCtrl_AdjustRect(GetDlgItem(hwndDlg,IDC_TABS),FALSE,&dat->rcDisplay);
+ {
+ POINT pt={0,0};
+ ClientToScreen(hwndDlg,&pt);
+ OffsetRect(&dat->rcDisplay,-pt.x,-pt.y);
+ }
+
+ TabCtrl_SetCurSel(GetDlgItem(hwndDlg,IDC_TABS),dat->currentPage);
+ dat->opd[dat->currentPage].hwnd=CreateDialogIndirectParam(dat->opd[dat->currentPage].hInst,dat->opd[dat->currentPage].pTemplate,hwndDlg,dat->opd[dat->currentPage].dlgProc,(LPARAM)dat->prof);
+ ThemeDialogBackground(dat->opd[dat->currentPage].hwnd);
+ SetWindowPos(dat->opd[dat->currentPage].hwnd,HWND_TOP,dat->rcDisplay.left,dat->rcDisplay.top,0,0,SWP_NOSIZE);
+ { PSHNOTIFY pshn;
+ pshn.hdr.code=PSN_INFOCHANGED;
+ pshn.hdr.hwndFrom=dat->opd[dat->currentPage].hwnd;
+ pshn.hdr.idFrom=0;
+ pshn.lParam=(LPARAM)0;
+ SendMessage(dat->opd[dat->currentPage].hwnd,WM_NOTIFY,0,(LPARAM)&pshn);
+ }
+ ShowWindow(dat->opd[dat->currentPage].hwnd,SW_SHOW);
+ return TRUE;
+ }
+ case WM_CTLCOLORSTATIC:
+ switch (GetDlgCtrlID((HWND)lParam)) {
+ case IDC_WHITERECT:
+ case IDC_LOGO:
+ case IDC_NAME:
+ case IDC_DESCRIPTION:
+ SetBkColor((HDC)wParam,RGB(255,255,255));
+ return (BOOL)GetStockObject(WHITE_BRUSH);
+ }
+ break;
+ case PSM_CHANGED:
+ dat->opd[dat->currentPage].changed=1;
+ return TRUE;
+ case PSM_FORCECHANGED:
+ { PSHNOTIFY pshn;
+ int i;
+
+ pshn.hdr.code=PSN_INFOCHANGED;
+ pshn.hdr.idFrom=0;
+ pshn.lParam=(LPARAM)0;
+ for(i=0;i<dat->pageCount;i++) {
+ pshn.hdr.hwndFrom=dat->opd[i].hwnd;
+ if(dat->opd[i].hwnd!=NULL)
+ SendMessage(dat->opd[i].hwnd,WM_NOTIFY,0,(LPARAM)&pshn);
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ switch(wParam) {
+ case IDC_TABS:
+ switch(((LPNMHDR)lParam)->code) {
+ case TCN_SELCHANGING:
+ { PSHNOTIFY pshn;
+ if(dat->currentPage==-1 || dat->opd[dat->currentPage].hwnd==NULL) break;
+ pshn.hdr.code=PSN_KILLACTIVE;
+ pshn.hdr.hwndFrom=dat->opd[dat->currentPage].hwnd;
+ pshn.hdr.idFrom=0;
+ pshn.lParam=(LPARAM)0;
+ if(SendMessage(dat->opd[dat->currentPage].hwnd,WM_NOTIFY,0,(LPARAM)&pshn)) {
+ SetWindowLong(hwndDlg,DWL_MSGRESULT,TRUE);
+ return TRUE;
+ }
+ break;
+ }
+ case TCN_SELCHANGE:
+ if(dat->currentPage!=-1 && dat->opd[dat->currentPage].hwnd!=NULL) ShowWindow(dat->opd[dat->currentPage].hwnd,SW_HIDE);
+ dat->currentPage=TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_TABS));
+ if(dat->currentPage!=-1) {
+ if(dat->opd[dat->currentPage].hwnd==NULL) {
+ PSHNOTIFY pshn;
+ dat->opd[dat->currentPage].hwnd=CreateDialogIndirectParam(dat->opd[dat->currentPage].hInst,dat->opd[dat->currentPage].pTemplate,hwndDlg,dat->opd[dat->currentPage].dlgProc,(LPARAM)dat->prof);
+ ThemeDialogBackground(dat->opd[dat->currentPage].hwnd);
+ SetWindowPos(dat->opd[dat->currentPage].hwnd,HWND_TOP,dat->rcDisplay.left,dat->rcDisplay.top,0,0,SWP_NOSIZE);
+ pshn.hdr.code=PSN_INFOCHANGED;
+ pshn.hdr.hwndFrom=dat->opd[dat->currentPage].hwnd;
+ pshn.hdr.idFrom=0;
+ pshn.lParam=(LPARAM)0;
+ SendMessage(dat->opd[dat->currentPage].hwnd,WM_NOTIFY,0,(LPARAM)&pshn);
+ }
+ ShowWindow(dat->opd[dat->currentPage].hwnd,SW_SHOW);
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDCANCEL:
+ { int i;
+ PSHNOTIFY pshn;
+ pshn.hdr.idFrom=0;
+ pshn.lParam=0;
+ pshn.hdr.code=PSN_RESET;
+ for(i=0;i<dat->pageCount;i++) {
+ if(dat->opd[i].hwnd==NULL || !dat->opd[i].changed) continue;
+ pshn.hdr.hwndFrom=dat->opd[i].hwnd;
+ SendMessage(dat->opd[i].hwnd,WM_NOTIFY,0,(LPARAM)&pshn);
+ }
+ EndDialog(hwndDlg,0);
+ break;
+ }
+ case IDOK:
+ {
+ int i;
+ PSHNOTIFY pshn;
+ pshn.hdr.idFrom=0;
+ pshn.lParam=(LPARAM)0;
+ if(dat->currentPage!=-1) {
+ pshn.hdr.code=PSN_KILLACTIVE;
+ pshn.hdr.hwndFrom=dat->opd[dat->currentPage].hwnd;
+ if(SendMessage(dat->opd[dat->currentPage].hwnd,WM_NOTIFY,0,(LPARAM)&pshn))
+ break;
+ }
+
+ pshn.hdr.code=PSN_APPLY;
+ for(i=0;i<dat->pageCount;i++) {
+ if(dat->opd[i].hwnd==NULL || !dat->opd[i].changed) continue;
+ pshn.hdr.hwndFrom=dat->opd[i].hwnd;
+ SendMessage(dat->opd[i].hwnd,WM_NOTIFY,0,(LPARAM)&pshn);
+ if ( GetWindowLong(dat->opd[i].hwnd,DWL_MSGRESULT) == PSNRET_INVALID_NOCHANGEPAGE) {
+ TabCtrl_SetCurSel(GetDlgItem(hwndDlg,IDC_TABS),i);
+ if(dat->currentPage!=-1) ShowWindow(dat->opd[dat->currentPage].hwnd,SW_HIDE);
+ dat->currentPage=i;
+ ShowWindow(dat->opd[dat->currentPage].hwnd,SW_SHOW);
+ return 0;
+ }
+ }
+ EndDialog(hwndDlg,1);
+ break;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ SendDlgItemMessage(hwndDlg,IDC_NAME,WM_SETFONT,SendDlgItemMessage(hwndDlg,IDC_WHITERECT,WM_GETFONT,0,0),0);
+ DeleteObject(dat->hBoldFont);
+ { int i;
+ for(i=0;i<dat->pageCount;i++)
+ if(dat->opd[i].hwnd!=NULL) DestroyWindow(dat->opd[i].hwnd);
+ }
+ mir_free(dat->opd);
+ mir_free(dat);
+ break;
+ }
+ return FALSE;
+}
+
+static int AddProfileManagerPage(struct DetailsPageInit * opi, OPTIONSDIALOGPAGE * odp)
+{
+ if(opi==NULL||odp==NULL);
+ if(odp->cbSize!=sizeof(OPTIONSDIALOGPAGE)) return 1;
+ opi->odp=(OPTIONSDIALOGPAGE*)mir_realloc(opi->odp,sizeof(OPTIONSDIALOGPAGE)*(opi->pageCount+1));
+ opi->odp[opi->pageCount].cbSize=sizeof(OPTIONSDIALOGPAGE);
+ opi->odp[opi->pageCount].hInstance=odp->hInstance;
+ opi->odp[opi->pageCount].pfnDlgProc=odp->pfnDlgProc;
+ opi->odp[opi->pageCount].position=odp->position;
+ opi->odp[opi->pageCount].ptszTitle=LangPackPcharToTchar(odp->pszTitle);
+ if((DWORD)odp->pszTemplate&0xFFFF0000) opi->odp[opi->pageCount].pszTemplate=mir_strdup(odp->pszTemplate);
+ else opi->odp[opi->pageCount].pszTemplate=odp->pszTemplate;
+ opi->odp[opi->pageCount].pszGroup=NULL;
+ opi->odp[opi->pageCount].groupPosition=odp->groupPosition;
+ opi->odp[opi->pageCount].hGroupIcon=odp->hGroupIcon;
+ opi->odp[opi->pageCount].hIcon=odp->hIcon;
+ opi->pageCount++;
+ return 0;
+}
+
+
+int getProfileManager(PROFILEMANAGERDATA * pd)
+{
+ PROPSHEETHEADER psh;
+ struct DlgProfData prof;
+ struct DetailsPageInit opi;
+ int rc=0;
+ int i;
+
+ opi.pageCount=0;
+ opi.odp=NULL;
+
+ { // remember what the default profile is, if any.
+ char defaultProfile[MAX_PATH];
+ GetPrivateProfileStringA("Database", "DefaultProfile", "", defaultProfile, SIZEOF(defaultProfile), mirandabootini);
+ ExpandEnvironmentStringsA(defaultProfile, szDefaultMirandaProfile, SIZEOF(szDefaultMirandaProfile));
+ }
+
+ {
+ OPTIONSDIALOGPAGE odp;
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.pszTitle=Translate("My Profiles");
+ odp.pfnDlgProc=DlgProfileSelect;
+ odp.pszTemplate=MAKEINTRESOURCEA(IDD_PROFILE_SELECTION);
+ odp.hInstance=GetModuleHandle(NULL);
+ AddProfileManagerPage(&opi, &odp);
+
+ odp.pszTitle=Translate("New Profile");
+ odp.pszTemplate=MAKEINTRESOURCEA(IDD_PROFILE_NEW);
+ odp.pfnDlgProc=DlgProfileNew;
+ AddProfileManagerPage(&opi, &odp);
+ }
+
+ ZeroMemory(&psh,sizeof(psh));
+ psh.dwSize = sizeof(psh);
+ psh.dwFlags = PSH_PROPSHEETPAGE|PSH_NOAPPLYNOW;
+ psh.hwndParent = NULL;
+ psh.nPages = opi.pageCount;
+ psh.pStartPage = 0;
+ psh.ppsp = (PROPSHEETPAGE*)opi.odp;
+ prof.pd=pd;
+ prof.psh=&psh;
+ rc=DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PROFILEMANAGER),NULL,DlgProfileManager,(LPARAM)&prof);
+
+ if (rc != -1)
+ {
+ for(i=0;i<opi.pageCount;i++)
+ {
+ mir_free((char*)opi.odp[i].pszTitle);
+ if(opi.odp[i].pszGroup!=NULL) mir_free(opi.odp[i].pszGroup);
+ if((DWORD)opi.odp[i].pszTemplate&0xFFFF0000) mir_free((char*)opi.odp[i].pszTemplate);
+ }
+ }
+ if ( opi.odp != NULL )
+ mir_free(opi.odp);
+
+ return rc;
+}
diff --git a/miranda-wine/src/modules/database/profilemanager.h b/miranda-wine/src/modules/database/profilemanager.h new file mode 100644 index 0000000..5cf9191 --- /dev/null +++ b/miranda-wine/src/modules/database/profilemanager.h @@ -0,0 +1,37 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 struct {
+ char * szProfile; // in/out
+ char * szProfileDir; // in/out
+ BOOL noProfiles; // in
+ BOOL newProfile; // out
+ DATABASELINK * dblink; // out
+} PROFILEMANAGERDATA;
+
+int InitTime(void);
+int makeDatabase(char * profile, DATABASELINK * link, HWND hwndDlg);
+int getProfileManager(PROFILEMANAGERDATA * pd);
+int getProfilePath(char * buf, size_t cch);
+int isValidProfileName(char * name);
+
|