summaryrefslogtreecommitdiff
path: root/plugins/AssocMgr/reg.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-06-06 20:28:25 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-06-06 20:28:25 +0000
commit6259dc6f9fcd6ee828555bdebd9a344fa62b0801 (patch)
tree5d6c92762f61132cdedb78ba1847d347e6120709 /plugins/AssocMgr/reg.cpp
parentab92c2a5cd5427bf8a33d06afdb64b88d2d640ed (diff)
AssocMgr reverted to rev333
git-svn-id: http://svn.miranda-ng.org/main/trunk@338 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/AssocMgr/reg.cpp')
-rw-r--r--plugins/AssocMgr/reg.cpp1298
1 files changed, 0 insertions, 1298 deletions
diff --git a/plugins/AssocMgr/reg.cpp b/plugins/AssocMgr/reg.cpp
deleted file mode 100644
index 6d10421493..0000000000
--- a/plugins/AssocMgr/reg.cpp
+++ /dev/null
@@ -1,1298 +0,0 @@
-/*
-
-'File Association Manager'-Plugin for Miranda IM
-
-Copyright (C) 2005-2007 H. Herkenrath
-
-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 (AssocMgr-License.txt); if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "common.h"
-
-#ifdef _DEBUG
-/* Debug: Ensure all registry calls do succeed and have valid parameters.
- * Shows a details message box otherwise. */
-static __inline LONG regchk(LONG res,const char *pszFunc,const void *pszInfo,BOOL fInfoUnicode,const char *pszFile,unsigned int nLine)
-{
- if(res!=ERROR_SUCCESS && res!=ERROR_FILE_NOT_FOUND && res!=ERROR_NO_MORE_ITEMS) {
- TCHAR szMsg[1024],*pszInfo2;
- char *pszErr;
- pszErr=GetWinErrorDescription(res);
- pszInfo2=s2t(pszInfo,fInfoUnicode,FALSE); /* does NULL check */
- mir_sntprintf(szMsg,SIZEOF(szMsg),_T("Access failed:\n%.64hs(%.128s)\n%.250hs(%u)\n%.256hs (%u)"),pszFunc,pszInfo2,pszFile,nLine,pszErr,res);
- MessageBox(NULL,szMsg,_T("Registry Warning"),MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
- if(pszErr!=NULL) LocalFree(pszErr);
- mir_free(pszInfo2); /* does NULL check */
- }
- return res;
-}
-#undef RegCloseKey
-#define RegCloseKey(hKey) \
- regchk(RegCloseKey(hKey),"RegCloseKey",NULL,FALSE,__FILE__,__LINE__)
-#undef RegOpenKeyExA
-#define RegOpenKeyExA(hKey,szSubkey,opt,rights,phKey) \
- regchk(RegOpenKeyExA(hKey,szSubkey,opt,rights,phKey),"RegOpenKeyExA",szSubkey,FALSE,__FILE__,__LINE__)
-#undef RegCreateKeyExA
-#define RegCreateKeyExA(hKey,szSubkey,x,y,opt,rights,sec,phKey,pDisp) \
- regchk(RegCreateKeyExA(hKey,szSubkey,x,y,opt,rights,sec,phKey,pDisp),"RegCreateKeyExA",szSubkey,FALSE,__FILE__,__LINE__)
-#undef RegDeleteKeyA
-#define RegDeleteKeyA(hKey,szName) \
- regchk(RegDeleteKeyA(hKey,szName),"RegDeleteKeyA",szName,FALSE,__FILE__,__LINE__)
-#undef RegSetValueExA
-#define RegSetValueExA(hSubKey,szName,x,type,pVal,size) \
- regchk(RegSetValueExA(hSubKey,szName,x,type,pVal,size),"RegSetValueExA",szName,FALSE,__FILE__,__LINE__)
-#undef RegQueryValueExA
-#define RegQueryValueExA(hKey,szName,x,pType,pVal,pSize) \
- regchk(RegQueryValueExA(hKey,szName,x,pType,pVal,pSize),"RegQueryValueExA",szName,FALSE,__FILE__,__LINE__)
-#undef RegQueryInfoKeyA
-#define RegQueryInfoKeyA(hKey,x,y,z,pnKeys,pnKeyLen,a,pnVals,pnNames,pnValLen,sec,pTime) \
- regchk(RegQueryInfoKeyA(hKey,x,y,z,pnKeys,pnKeyLen,a,pnVals,pnNames,pnValLen,sec,pTime),"RegQueryInfoKeyA",NULL,FALSE,__FILE__,__LINE__)
-#undef RegEnumKeyExA
-#define RegEnumKeyExA(hKey,idx,pName,pnName,x,y,z,pTime) \
- regchk(RegEnumKeyExA(hKey,idx,pName,pnName,x,y,z,pTime),"RegEnumKeyExA",NULL,FALSE,__FILE__,__LINE__)
-#undef RegDeleteValueA
-#define RegDeleteValueA(hKey,szName) \
- regchk(RegDeleteValueA(hKey,szName),"RegDeleteValueA",szName,FALSE,__FILE__,__LINE__)
-#undef RegOpenKeyExW
-#define RegOpenKeyExW(hKey,szSubkey,x,sam,phKey) \
- regchk(RegOpenKeyExW(hKey,szSubkey,x,sam,phKey),"RegOpenKeyExW",szSubkey,TRUE,__FILE__,__LINE__)
-#undef RegCreateKeyExW
-#define RegCreateKeyExW(hKey,szSubkey,x,y,z,rights,p,phKey,q) \
- regchk(RegCreateKeyExW(hKey,szSubkey,x,y,z,rights,p,phKey,q),"RegCreateKeyExW",szSubkey,TRUE,__FILE__,__LINE__)
-#undef RegDeleteKeyW
-#define RegDeleteKeyW(hKey,szName) \
- regchk(RegDeleteKeyW(hKey,szName),"RegDeleteKeyW",szName,TRUE,__FILE__,__LINE__)
-#undef RegSetValueExW
-#define RegSetValueExW(hSubKey,szName,x,type,pVal,size) \
- regchk(RegSetValueExW(hSubKey,szName,x,type,pVal,size),"RegSetValueExW",szName,TRUE,__FILE__,__LINE__)
-#undef RegQueryValueExW
-#define RegQueryValueExW(hKey,szName,x,pType,pVal,pSize) \
- regchk(RegQueryValueExW(hKey,szName,x,pType,pVal,pSize),"RegQueryValueExW",szName,TRUE,__FILE__,__LINE__)
-#undef RegQueryInfoKeyW
-#define RegQueryInfoKeyW(hKey,x,y,z,pnKeys,pnKeyLen,a,pnVals,pnNames,pnValLen,sec,pTime) \
- regchk(RegQueryInfoKeyW(hKey,x,y,z,pnKeys,pnKeyLen,a,pnVals,pnNames,pnValLen,sec,pTime),"RegQueryInfoKeyW",NULL,TRUE,__FILE__,__LINE__)
-#undef RegEnumKeyExW
-#define RegEnumKeyExW(hKey,idx,pName,pnName,x,y,z,pTime) \
- regchk(RegEnumKeyExW(hKey,idx,pName,pnName,x,y,z,pTime),"RegEnumKeyExW",NULL,TRUE,__FILE__,__LINE__)
-#undef RegDeleteValueW
-#define RegDeleteValueW(hKey,szName) \
- regchk(RegDeleteValueW(hKey,szName),"RegDeleteValueW",szName,TRUE,__FILE__,__LINE__)
-#endif // _DEBUG
-
-/************************* Strings ********************************/
-
-// mir_free() the return value
-char *MakeFileClassName(const char *pszFileExt)
-{
- char *pszClass;
- pszClass=(char*)mir_alloc((lstrlenA(pszFileExt)+12)*sizeof(TCHAR));
- if(pszClass!=NULL)
- /* using correctly formated PROGID */
- wsprintfA(pszClass,"miranda%sfile",pszFileExt); /* includes dot, buffer safe */
- return pszClass;
-}
-
-// mir_free() the return value
-char *MakeUrlClassName(const char *pszUrl)
-{
- char *pszClass;
- pszClass=mir_strdup(pszUrl);
- if(pszClass!=NULL)
- /* remove trailing : */
- pszClass[lstrlenA(pszClass)-1]=0;
- return pszClass;
-}
-
-static BOOL IsFileClassName(char *pszClassName, char **ppszFileExt)
-{
- *ppszFileExt=strchr(pszClassName,'.');
- return *ppszFileExt!=NULL;
-}
-
-// mir_free() the return value
-TCHAR *MakeRunCommand(BOOL fMirExe,BOOL fFixedDbProfile)
-{
- extern HINSTANCE hInst;
- TCHAR szExe[MAX_PATH],*pszFmt,*pszRunCmd=NULL;
- char szDbFile[MAX_PATH];
- int cch;
- if (!fFixedDbProfile || !CallService(MS_DB_GETPROFILENAME,SIZEOF(szDbFile),(LPARAM)szDbFile))
- if(GetModuleFileNameWorkaround(fMirExe?NULL:hInst,szExe,SIZEOF(szExe))) {
- /* db file */
- if (!fFixedDbProfile)
- lstrcpyA(szDbFile,"%1"); /* buffer safe */
- /* size */
- cch=lstrlen(szExe)+lstrlenA(szDbFile);
- if(fMirExe) {
- /* run command for miranda32.exe */
- cch+=7;
- pszFmt=_T("\"%s\" \"%hs\"");
- } else {
- DWORD len;
- /* run command for rundll32.exe calling WaitForDDE */
- cch+=28;
- pszFmt=_T("rundll32.exe %s,WaitForDDE \"%hs\"");
- /* ensure the command line is not too long */
- GetShortPathName(szExe,szExe,SIZEOF(szExe));
- /* surround by quotes if failed */
- len=lstrlen(szExe);
- if(_tcschr(szExe,_T(' '))!=NULL && (len+2)<SIZEOF(szExe)) {
- MoveMemory(szExe,szExe+1,(len+1)*sizeof(TCHAR));
- szExe[len+2]=szExe[0]=_T('\"');
- szExe[len+3]=0;
- }
- }
- pszRunCmd=(TCHAR*)mir_alloc(cch*sizeof(TCHAR));
- if(pszRunCmd!=NULL)
- mir_sntprintf(pszRunCmd,cch,pszFmt,szExe,szDbFile);
- }
- return pszRunCmd;
-}
-
-static BOOL IsValidRunCommand(const TCHAR *pszRunCmd)
-{
- TCHAR *buf,*pexe,*pargs;
- TCHAR szFullExe[MAX_PATH],*pszFilePart;
- buf=lstrcpy((TCHAR*)_alloca((lstrlen(pszRunCmd)+1)*sizeof(TCHAR)),pszRunCmd);
- /* split into executable path and arguments */
- if(buf[0]==_T('\"')) {
- pargs=_tcschr(&buf[1],_T('\"'));
- if(pargs!=NULL) *(pargs++)=0;
- pexe=&buf[1];
- if (*pargs==_T(' ')) ++pargs;
- } else {
- pargs=_tcschr(buf,_T(' '));
- if(pargs!=NULL) *pargs=0;
- pexe=buf;
- }
- if(SearchPath(NULL,pexe,_T(".exe"),SIZEOF(szFullExe),szFullExe,&pszFilePart)) {
- if(pszFilePart!=NULL)
- if (!lstrcmpi(pszFilePart,_T("rundll32.exe")) || !lstrcmpi(pszFilePart,_T("rundll.exe"))) {
- /* split into dll path and arguments */
- if(pargs[0]==_T('\"')) {
- ++pargs;
- pexe=_tcschr(&pargs[1],_T('\"'));
- if(pexe!=NULL) *pexe=0;
- } else {
- pexe=_tcschr(pargs,_T(','));
- if(pexe!=NULL) *pexe=0;
- }
- return SearchPath(NULL,pargs,_T(".dll"),0,NULL,NULL)!=0;
- }
- return TRUE;
- }
- return FALSE;
-}
-
-// mir_free() the return value
-TCHAR *MakeIconLocation(HMODULE hModule,WORD nIconResID)
-{
- TCHAR szModule[MAX_PATH],*pszIconLoc=NULL;
- int cch;
- if ((cch=GetModuleFileNameWorkaround(hModule,szModule,SIZEOF(szModule)))!=0) {
- pszIconLoc=(TCHAR*)mir_alloc((cch+=8)*sizeof(TCHAR));
- if(pszIconLoc!=NULL)
- wsprintf(pszIconLoc,_T("%s,%i"),szModule,-(int)nIconResID); /* id may be 0, buffer safe */
- }
- return pszIconLoc;
-}
-
-// mir_free() the return value
-TCHAR *MakeAppFileName(BOOL fMirExe)
-{
- extern HINSTANCE hInst;
- TCHAR szExe[MAX_PATH],*psz;
- if(GetModuleFileNameWorkaround(fMirExe?NULL:hInst,szExe,SIZEOF(szExe))) {
- psz=_tcsrchr(szExe,_T('\\'));
- if(psz!=NULL) ++psz;
- else psz=szExe;
- return mir_tstrdup(psz);
- }
- return NULL;
-}
-
-/************************* Helpers ********************************/
-
-static LONG DeleteRegSubTree(HKEY hKey,const TCHAR *pszSubKey)
-{
- LONG res;
- DWORD nMaxSubKeyLen,cchSubKey;
- TCHAR *pszSubKeyBuf;
- HKEY hSubKey;
- if ((res=RegOpenKeyEx(hKey,pszSubKey,0,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS|DELETE,&hSubKey))==ERROR_SUCCESS) {
- if ((res=RegQueryInfoKey(hSubKey,NULL,NULL,NULL,NULL,&nMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL))==ERROR_SUCCESS) {
- pszSubKeyBuf=(TCHAR*)mir_alloc((nMaxSubKeyLen+1)*sizeof(TCHAR));
- if(pszSubKeyBuf==NULL) res=ERROR_NOT_ENOUGH_MEMORY;
- while(!res) {
- cchSubKey=nMaxSubKeyLen+1;
- if ((res=RegEnumKeyEx(hSubKey,0,pszSubKeyBuf,&cchSubKey,NULL,NULL,NULL,NULL))==ERROR_SUCCESS)
- res=DeleteRegSubTree(hSubKey,pszSubKeyBuf); /* recursion */
- }
- mir_free(pszSubKeyBuf); /* does NULL check */
- if(res==ERROR_NO_MORE_ITEMS) res=ERROR_SUCCESS;
- }
- RegCloseKey(hSubKey);
- }
- if (!res) res=RegDeleteKey(hKey,pszSubKey);
- return res;
-}
-
-// hMainKey must have been opened with KEY_CREATE_SUB_KEY access right
-static LONG SetRegSubKeyStrDefValue(HKEY hMainKey,const TCHAR *pszSubKey,const TCHAR *pszVal)
-{
- HKEY hSubKey;
- LONG res;
- res=RegCreateKeyEx(hMainKey,pszSubKey,0,NULL,0,KEY_SET_VALUE|KEY_QUERY_VALUE,NULL,&hSubKey,NULL);
- if (!res) {
- res=RegSetValueEx(hSubKey,NULL,0,REG_SZ,(BYTE*)pszVal,(lstrlen(pszVal)+1)*sizeof(TCHAR));
- RegCloseKey(hSubKey);
- }
- return res;
-}
-
-// hKey must have been opened with KEY_SET_VALUE access right
-static void SetRegStrPrefixValue(HKEY hKey,const TCHAR *pszValPrefix,const TCHAR *pszVal)
-{
- TCHAR *pszStr;
- DWORD dwSize;
- dwSize=(lstrlen(pszVal)+lstrlen(pszValPrefix)+1)*sizeof(TCHAR);
- pszStr=(TCHAR*)mir_alloc(dwSize);
- if(pszStr==NULL) return;
- lstrcat(lstrcpy(pszStr,pszValPrefix),pszVal); /* buffer safe */
- RegSetValueEx(hKey,NULL,0,REG_SZ,(BYTE*)pszStr,dwSize);
- mir_free(pszStr);
-}
-
-// hKey must have been opened with KEY_QUERY_VALUE access right
-// mir_free() the return value
-static TCHAR *GetRegStrValue(HKEY hKey,const TCHAR *pszValName)
-{
- TCHAR *pszVal,*pszVal2;
- DWORD dwSize,dwType;
- /* get size */
- if (!RegQueryValueEx(hKey,pszValName,NULL,NULL,NULL,&dwSize) && dwSize>sizeof(TCHAR)) {
- pszVal=(TCHAR*)mir_alloc(dwSize+sizeof(TCHAR));
- if(pszVal!=NULL) {
- /* get value */
- if (!RegQueryValueEx(hKey,pszValName,NULL,&dwType,(BYTE*)pszVal,&dwSize)) {
- pszVal[dwSize/sizeof(TCHAR)]=0;
- if(dwType==REG_EXPAND_SZ) {
- dwSize=MAX_PATH;
- pszVal2=(TCHAR*)mir_alloc(dwSize*sizeof(TCHAR));
- if(ExpandEnvironmentStrings(pszVal,pszVal2,dwSize)) {
- mir_free(pszVal);
- return pszVal2;
- }
- mir_free(pszVal2);
- } else if(dwType==REG_SZ)
- return pszVal;
- }
- mir_free(pszVal);
- }
- }
- return NULL;
-}
-
-// hKey must have been opened with KEY_QUERY_VALUE access right
-static BOOL IsRegStrValue(HKEY hKey,const TCHAR *pszValName,const TCHAR *pszCmpVal)
-{
- BOOL fSame=FALSE;
- TCHAR *pszVal;
- pszVal=GetRegStrValue(hKey,pszValName);
- if(pszVal!=NULL) {
- fSame=!lstrcmp(pszVal,pszCmpVal);
- mir_free(pszVal);
- }
- return fSame;
-}
-
-// hKey must have been opened with KEY_QUERY_VALUE access right
-static BOOL IsRegStrValueA(HKEY hKey,const TCHAR *pszValName,const char *pszCmpVal)
-{
- BOOL fSame=FALSE;
- TCHAR *pszVal;
- char *pszValA;
- pszVal=GetRegStrValue(hKey,pszValName);
- if(pszVal!=NULL) {
- pszValA=t2a(pszVal);
- if(pszValA!=NULL)
- fSame=!lstrcmpA(pszValA,pszCmpVal);
- mir_free(pszValA); /* does NULL check */
- mir_free(pszVal);
- }
- return fSame;
-}
-
-/************************* Backup to DB ***************************/
-
-#define REGF_ANSI 0x80000000 /* this bit is set in dwType for ANSI registry data */
-
-// pData must always be Unicode data, registry supports Unicode even on Win95
-static void WriteDbBackupData(const char *pszSetting,DWORD dwType,BYTE *pData,DWORD cbData)
-{
- DBCONTACTWRITESETTING dbcws;
- dbcws.szModule="AssocMgr";
- dbcws.szSetting=pszSetting;
- dbcws.value.type=DBVT_BLOB;
- dbcws.value.cpbVal=(WORD)(cbData+sizeof(DWORD));
- dbcws.value.pbVal=(BYTE*)mir_alloc(cbData+sizeof(DWORD));
- if(dbcws.value.pbVal==NULL) return;
- *(DWORD*)dbcws.value.pbVal=dwType;
- CopyMemory(dbcws.value.pbVal+sizeof(DWORD),pData,cbData);
- CallService(MS_DB_CONTACT_WRITESETTING,0,(LPARAM)&dbcws);
- mir_free(dbcws.value.pbVal);
-}
-
-// mir_free() the value returned in ppData
-static BOOL ReadDbBackupData(const char *pszSetting,DWORD *pdwType,BYTE **ppData,DWORD *pcbData)
-{
- DBCONTACTGETSETTING dbcgs;
- DBVARIANT dbv;
- dbcgs.szModule="AssocMgr";
- dbcgs.szSetting=pszSetting;
- dbcgs.pValue=&dbv;
- if (!CallService(MS_DB_CONTACT_GETSETTING,0,(LPARAM)&dbcgs)) {
- if(dbv.type==DBVT_BLOB && dbv.cpbVal>=sizeof(DWORD)) {
- *pdwType=*(DWORD*)dbv.pbVal;
- *ppData=dbv.pbVal;
- *pcbData=dbv.cpbVal-sizeof(DWORD);
- MoveMemory(*ppData,*ppData+sizeof(DWORD),*pcbData);
- return TRUE;
- }
- CallService(MS_DB_CONTACT_FREEVARIANT,0,(LPARAM)&dbv);
- }
- return FALSE;
-}
-
-struct BackupRegTreeParam {
- char **ppszDbPrefix;
- DWORD *pdwDbPrefixSize;
- int level;
-};
-
-static void BackupRegTree_Worker(HKEY hKey,const char *pszSubKey,struct BackupRegTreeParam *param)
-{
- LONG res;
- DWORD nMaxSubKeyLen,nMaxValNameLen,nMaxValSize;
- DWORD index,cchName,dwType,cbData;
- BYTE *pData;
- char *pszName;
- register TCHAR *ptszName;
- DWORD nDbPrefixLen;
- if ((res=RegOpenKeyExA(hKey,pszSubKey,0,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,&hKey))==ERROR_SUCCESS) {
- if ((res=RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,&nMaxSubKeyLen,NULL,NULL,&nMaxValNameLen,&nMaxValSize,NULL,NULL))==ERROR_SUCCESS) {
- if(nMaxSubKeyLen>nMaxValNameLen) nMaxValNameLen=nMaxSubKeyLen;
- /* prepare buffer */
- nDbPrefixLen=(DWORD)lstrlenA(*param->ppszDbPrefix)+lstrlenA(pszSubKey)+1;
- cchName=nDbPrefixLen+nMaxValNameLen+3;
- if(cchName>*param->pdwDbPrefixSize) {
- pszName=(char*)mir_realloc(*param->ppszDbPrefix,cchName);
- if(pszName==NULL) return;
- *param->ppszDbPrefix=pszName;
- *param->pdwDbPrefixSize=cchName;
- }
- lstrcatA(lstrcatA(*param->ppszDbPrefix,pszSubKey),"\\"); /* buffer safe */
- /* enum values */
- pszName=(char*)mir_alloc(nMaxValNameLen+1);
- if(nMaxValSize==0) nMaxValSize=1;
- pData=(BYTE*)mir_alloc(nMaxValSize);
- if(pszName!=NULL && pData!=NULL) {
- index=0;
- while(!res) {
- cchName=nMaxValNameLen+1;
- cbData=nMaxValSize;
- if ((res=RegEnumValueA(hKey,index++,pszName,&cchName,NULL,NULL,NULL,NULL))==ERROR_SUCCESS) {
- (*param->ppszDbPrefix)[nDbPrefixLen]=0;
- lstrcatA(*param->ppszDbPrefix,pszName); /* buffer safe */
- ptszName=a2t(pszName);
- if(ptszName!=NULL) {
- if (!RegQueryValueEx(hKey,ptszName,NULL,&dwType,pData,&cbData)) {
- #ifdef _UNICODE
- WriteDbBackupData(*param->ppszDbPrefix,dwType,pData,cbData);
- #else
- if (!(dwType&REGF_ANSI)) /* sanity check, never happens */
- WriteDbBackupData(*param->ppszDbPrefix,dwType&REGF_ANSI,pData,cbData);
- #endif
- }
- mir_free(ptszName);
- }
- }
- }
- if(res==ERROR_NO_MORE_ITEMS) res=ERROR_SUCCESS;
- }
- mir_free(pData); /* does NULL check */
- /* enum subkeys */
- if(param->level<32 && pszName!=NULL) {
- ++param->level; /* can be max 32 levels deep (after prefix), restriction of RegCreateKeyEx() */
- index=0;
- while(!res) {
- cchName=nMaxSubKeyLen+1;
- if ((res=RegEnumKeyExA(hKey,index++,pszName,&cchName,NULL,NULL,NULL,NULL))==ERROR_SUCCESS) {
- (*param->ppszDbPrefix)[nDbPrefixLen]=0;
- BackupRegTree_Worker(hKey,pszName,param); /* recursion */
- }
- }
- }
- if(res==ERROR_NO_MORE_ITEMS) res=ERROR_SUCCESS;
- mir_free(pszName); /* does NULL check */
- }
- RegCloseKey(hKey);
- }
-}
-
-static void BackupRegTree(HKEY hKey,const char *pszSubKey,const char *pszDbPrefix)
-{
- struct BackupRegTreeParam param;
- DWORD dwDbPrefixSize;
- param.level=0;
- param.pdwDbPrefixSize=&dwDbPrefixSize;
- param.ppszDbPrefix=(char**)&pszDbPrefix;
- pszDbPrefix=mir_strdup(pszDbPrefix);
- if(pszDbPrefix!=NULL) {
- dwDbPrefixSize=lstrlenA(pszDbPrefix)+1;
- BackupRegTree_Worker(hKey,pszSubKey,&param);
- mir_free((char*)pszDbPrefix);
- }
-}
-
-static LONG RestoreRegTree(HKEY hKey,const char *pszSubKey,const char *pszDbPrefix)
-{
- char **ppszSettings,*pszSuffix,*pszPrefixWithSubKey;
- int nSettingsCount,i,nDbPrefixLen,nPrefixWithSubKeyLen;
- char *pslash=NULL,*pnext,*pkeys;
- char *pszValName;
- WCHAR *pwszValName;
- HKEY hSubKey;
- DWORD dwType,cbData;
- BYTE *pData;
- LONG res;
-
- nDbPrefixLen=lstrlenA(pszDbPrefix);
- nPrefixWithSubKeyLen=nDbPrefixLen+lstrlenA(pszSubKey)+1;
- pszPrefixWithSubKey=(char*)mir_alloc(nPrefixWithSubKeyLen+1);
- if(pszPrefixWithSubKey==NULL) return ERROR_OUTOFMEMORY;
- lstrcatA(lstrcatA(lstrcpyA(pszPrefixWithSubKey,pszDbPrefix),pszSubKey),"\\"); /* buffer safe */
- res=ERROR_NO_MORE_ITEMS;
- if(pszPrefixWithSubKey!=NULL) {
- if(EnumDbPrefixSettings("AssocMgr",pszPrefixWithSubKey,&ppszSettings,&nSettingsCount)) {
- for(i=0;i<nSettingsCount;++i) {
- pszSuffix=&ppszSettings[i][nDbPrefixLen];
- /* key hierachy */
- pkeys=lstrcpyA((char*)_alloca(lstrlenA(pszSuffix)+1),pszSuffix);
- pnext=pkeys;
- while((pnext=strchr(pnext+1,_T('\\')))!=NULL) pslash=pnext;
- if(pslash!=NULL) {
- /* create subkey */
- *(pslash++)=0;
- hSubKey=hKey;
- if(pslash!=pkeys+1)
- if ((res=RegCreateKeyExA(hKey,pkeys,0,NULL,0,KEY_SET_VALUE,NULL,&hSubKey,NULL))!=ERROR_SUCCESS)
- break;
- pszValName=pslash;
- /* read data */
- if(ReadDbBackupData(ppszSettings[i],&dwType,&pData,&cbData)) {
- /* set value */
- if (!(dwType&REGF_ANSI)) {
- pwszValName=a2u(pszValName,FALSE);
- if(pwszValName!=NULL) res=RegSetValueExW(hSubKey,pwszValName,0,dwType,pData,cbData);
- else res=ERROR_NOT_ENOUGH_MEMORY;
- mir_free(pwszValName); /* does NULL check */
- } else res=RegSetValueExA(hSubKey,pszValName,0,dwType&~REGF_ANSI,pData,cbData);
- mir_free(pData);
- } else res=ERROR_INVALID_DATA;
- if(res) break;
- DBDeleteContactSetting(NULL,"AssocMgr",ppszSettings[i]);
- if(hSubKey!=hKey) RegCloseKey(hSubKey);
- }
- mir_free(ppszSettings[i]);
- }
- mir_free(ppszSettings);
- }
- mir_free(pszPrefixWithSubKey);
- }
- return res;
-}
-
-static void DeleteRegTreeBackup(const char *pszSubKey,const char *pszDbPrefix)
-{
- char **ppszSettings,*pszPrefixWithSubKey;
- int nSettingsCount,i;
-
- pszPrefixWithSubKey=(char*)mir_alloc(lstrlenA(pszDbPrefix)+lstrlenA(pszSubKey)+2);
- if(pszPrefixWithSubKey==NULL) return;
- lstrcatA(lstrcatA(lstrcpyA(pszPrefixWithSubKey,pszDbPrefix),pszSubKey),"\\"); /* buffer safe */
- if(pszPrefixWithSubKey!=NULL) {
- if(EnumDbPrefixSettings("AssocMgr",pszPrefixWithSubKey,&ppszSettings,&nSettingsCount)) {
- for(i=0;i<nSettingsCount;++i) {
- DBDeleteContactSetting(NULL,"AssocMgr",ppszSettings[i]);
- mir_free(ppszSettings[i]);
- }
- mir_free(ppszSettings);
- }
- mir_free(pszPrefixWithSubKey);
- }
-}
-
-void CleanupRegTreeBackupSettings(void)
-{
- int nSettingsCount;
- char **ppszSettings;
- char *pszClassName,*pszBuf,*pszFileExt;
- int i,j;
-
- /* delete old bak_* settings and try to restore backups */
- if(EnumDbPrefixSettings("AssocMgr","bak_",&ppszSettings,&nSettingsCount)) {
- for(i=0;i<nSettingsCount;++i) {
- pszClassName=&ppszSettings[i][4];
- pszBuf=strchr(pszClassName,'\\');
- if(pszBuf!=NULL) {
- *pszBuf='\0';
- /* remove others in list with same class name */
- for(j=i;j<nSettingsCount;++j) {
- pszBuf=strchr(&ppszSettings[j][4],'\\');
- if(pszBuf!=NULL) *pszBuf='\0';
- if(lstrcmpA(pszClassName,&ppszSettings[j][4])) continue;
- MoveMemory(&ppszSettings[j],&ppszSettings[j+1],((--nSettingsCount)-j)*sizeof(TCHAR*));
- --j; /* reiterate current index */
- }
- /* no longer registered? */
- if (!IsRegisteredAssocItem(pszClassName)) {
- if(IsFileClassName(pszClassName,&pszFileExt))
- RemoveRegFileExt(pszFileExt,pszClassName);
- else RemoveRegClass(pszClassName);
- }
- }
- mir_free(ppszSettings[i]);
- }
- mir_free(ppszSettings);
- }
-}
-
-/************************* Opera Support **************************/
-
-/*
- * These are helpers accessing the Opera settings file.
- * Should work with Opera 6 up to 9.10 (current)
- */
-
-static BOOL Opera6_GetIniFilePath(TCHAR *szIniFile)
-{
- HKEY hExeKey;
- TCHAR szPath[MAX_PATH],*p;
- BOOL fSuccess=FALSE;
- DWORD len;
-
- /* Info: http://opera-info.de/forum/thread.php?threadid=2905 */
- /* app path */
- if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Netscape.exe",0,KEY_QUERY_VALUE,&hExeKey)) {
- /* exe name */
- p=GetRegStrValue(hExeKey,NULL);
- if(p!=NULL && _tcsstr(p,_T("Opera.exe"))!=NULL) {
- /* path */
- mir_free(p);
- p=GetRegStrValue(hExeKey,_T("Path"));
- len=lstrlen(p);
- if(p[len-1]==_T('\\')) p[len-1]=0;
- fSuccess=(p!=NULL && ExpandEnvironmentStrings(p,szPath,MAX_PATH));
- }
- mir_free(p); /* does NULL check */
- RegCloseKey(hExeKey);
- }
- if(fSuccess) {
- TCHAR szFileBuf[MAX_PATH+34];
- /* operadef6.ini */
- lstrcat(lstrcpy(szFileBuf,szPath),_T("\\operadef6.ini")); /* buffer safe */
- /* If enabled Opera will use Windows profiles to store individual user settings */
- if(GetPrivateProfileInt(_T("System"),_T("Multi User"),0,szFileBuf)==1) {
- p=_tcsrchr(szPath,'\\');
- lstrcpy(szFileBuf,_T("%APPDATA%\\Opera")); /* buffer safe */
- if(p!=NULL) lstrcat(szFileBuf,p); /* buffer safe */
- } else lstrcpy(szFileBuf,szPath);
- /* opera6.ini */
- lstrcat(szFileBuf,_T("\\profile\\opera6.ini")); /* buffer safe */
- fSuccess=ExpandEnvironmentStrings(szFileBuf,szIniFile,MAX_PATH)!=0;
- }
- /* check file existstance */
- if(fSuccess) {
- HANDLE hFile;
- hFile=CreateFile(szIniFile,0,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
- if(hFile==INVALID_HANDLE_VALUE) fSuccess=FALSE;
- else CloseHandle(hFile);
- }
- return fSuccess;
-}
-
-// pszProtoPrefix is expected to have no trailing :
-static void Opera6_AddTrustedProto(const char *pszProtoPrefix)
-{
- TCHAR szIniFile[MAX_PATH],*ptszProtoPrefix;
- if(Opera6_GetIniFilePath(szIniFile)) {
- /* trusted protocols */
- ptszProtoPrefix=a2t(pszProtoPrefix);
- if(ptszProtoPrefix!=NULL) {
- WritePrivateProfileString(_T("Trusted Protocols"),ptszProtoPrefix,_T("1,0,"),szIniFile);
- mir_free(ptszProtoPrefix);
- }
- }
-}
-
-static void Opera6_AddKnownMimeType(const char *pszMimeType,const char *pszFileExt,const TCHAR *pszDescription)
-{
- TCHAR szIniFile[MAX_PATH],szVal[256],*ptszMimeType;
- if(Opera6_GetIniFilePath(szIniFile)) {
- /* section version */
- if(GetPrivateProfileInt(_T("File Types Section Info"),_T("Version"),0,szIniFile)==2) {
- ptszMimeType=a2t(pszMimeType);
- if(ptszMimeType!=NULL) {
- /* file type */
- mir_sntprintf(szVal,SIZEOF(szVal),_T("4,,,,%.15hs,|%.128s (%.16hs)"),&pszFileExt[1],pszDescription,pszFileExt);
- WritePrivateProfileString(_T("File Types"),ptszMimeType,szVal,szIniFile);
- /* file type extension */
- WritePrivateProfileString(_T("File Types Extension"),ptszMimeType,_T(",0"),szIniFile);
- mir_free(ptszMimeType);
- }
- }
- }
-}
-
-/************************* Class **********************************/
-
-/*
- * Add a new file class to the class list.
- * This either represents a superclass for several file extensions or
- * the the url object.
- * Urls just need a class named after their prefix e.g. "http".
- * File extensions should follow the rule "appname.extension".
- */
-
-// pszIconLoc, pszVerbDesc and pszDdeCmd are allowed to be NULL
-// call GetLastError() on error to get more error details
-BOOL AddRegClass(const char *pszClassName,const TCHAR *pszTypeDescription,const TCHAR *pszIconLoc,const TCHAR *pszAppName,const TCHAR *pszRunCmd,const TCHAR *pszDdeCmd,const TCHAR *pszDdeApp,const TCHAR *pszDdeTopic,const TCHAR *pszVerbDesc,BOOL fBrowserAutoOpen,BOOL fUrlProto,BOOL fIsShortcut)
-{
- LONG res;
- HKEY hRootKey,hClassKey,hShellKey,hVerbKey,hDdeKey;
-
- /* some error checking for disallowed values (to avoid errors in registry) */
- if(strchr(pszClassName,'\\')!=NULL || strchr(pszClassName,' ')!=NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_CREATE_SUB_KEY,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT; /* might be write protected by security settings */
-
- /* class */
- if ((res=RegCreateKeyExA(hRootKey,pszClassName,0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY|DELETE|KEY_QUERY_VALUE,NULL,&hClassKey,NULL))==ERROR_SUCCESS) {
- /* backup class if shared */
- if(fUrlProto) BackupRegTree(hRootKey,pszClassName,"bak_");
- /* type description */
- if(fUrlProto) SetRegStrPrefixValue(hClassKey,_T("URL:"),pszTypeDescription);
- else RegSetValueEx(hClassKey,NULL,0,REG_SZ,(BYTE*)pszTypeDescription,(lstrlen(pszTypeDescription)+1)*sizeof(TCHAR));
- /* default icon */
- if(pszIconLoc!=NULL) SetRegSubKeyStrDefValue(hClassKey,_T("DefaultIcon"),pszIconLoc);
- /* url protocol */
- if (!fUrlProto) RegDeleteValue(hClassKey,_T("URL Protocol"));
- else RegSetValueEx(hClassKey,_T("URL Protocol"),0,REG_SZ,NULL,0);
- /* moniker clsid */
- RegDeleteKey(hClassKey,_T("CLSID"));
- /* edit flags */
- { DWORD dwFlags=0,dwSize=sizeof(dwFlags);
- RegQueryValueEx(hClassKey,_T("EditFlags"),NULL,NULL,(BYTE*)&dwFlags,&dwSize);
- if(fBrowserAutoOpen) dwFlags=(dwFlags&~FTA_AlwaysUnsafe)|FTA_OpenIsSafe;
- if (!fUrlProto) dwFlags|=FTA_HasExtension;
- else dwFlags=(dwFlags&~FTA_HasExtension)|FTA_Show; /* show classes without extension */
- RegSetValueEx(hClassKey,_T("EditFlags"),0,REG_DWORD,(BYTE*)&dwFlags,sizeof(dwFlags));
- }
- if(fIsShortcut) {
- RegSetValueExA(hClassKey,"IsShortcut",0,REG_SZ,NULL,0);
- RegSetValueExA(hClassKey,"NeverShowExt",0,REG_SZ,NULL,0);
- }
- /* shell */
- if ((res=RegCreateKeyEx(hClassKey,_T("shell"),0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY,NULL,&hShellKey,NULL))==ERROR_SUCCESS) {
- /* default verb (when empty "open" is used) */
- RegSetValueEx(hShellKey,NULL,0,REG_SZ,(BYTE*)_T("open"),5*sizeof(TCHAR));
- /* verb */
- if ((res=RegCreateKeyEx(hShellKey,_T("open"),0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY|DELETE,NULL,&hVerbKey,NULL))==ERROR_SUCCESS) {
- /* verb description */
- if(pszVerbDesc==NULL) RegDeleteValue(hVerbKey,NULL);
- else RegSetValueEx(hVerbKey,NULL,0,REG_SZ,(BYTE*)pszVerbDesc,(lstrlen(pszVerbDesc)+1)*sizeof(TCHAR));
- /* friendly appname (mui string) */
- RegSetValueEx(hVerbKey,_T("FriendlyAppName"),0,REG_SZ,(BYTE*)pszAppName,(lstrlen(pszAppName)+1)*sizeof(TCHAR));
- /* command */
- SetRegSubKeyStrDefValue(hVerbKey,_T("command"),pszRunCmd);
- /* ddeexec */
- if(pszDdeCmd!=NULL) {
- if (!RegCreateKeyEx(hVerbKey,_T("ddeexec"),0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY|DELETE,NULL,&hDdeKey,NULL)) {
- /* command */
- RegSetValueEx(hDdeKey,NULL,0,REG_SZ,(BYTE*)pszDdeCmd,(lstrlen(pszDdeCmd)+1)*sizeof(TCHAR));
- /* application */
- SetRegSubKeyStrDefValue(hDdeKey,_T("application"),pszDdeApp);
- /* topic */
- SetRegSubKeyStrDefValue(hDdeKey,_T("topic"),pszDdeTopic);
- /* ifexec */
- RegDeleteKey(hDdeKey,_T("ifexec"));
- RegCloseKey(hDdeKey);
- }
- } else {
- if (!RegOpenKeyEx(hVerbKey,_T("ddeexec"),0,DELETE,&hDdeKey)) {
- /* application */
- RegDeleteKey(hDdeKey,_T("application"));
- /* topic */
- RegDeleteKey(hDdeKey,_T("topic"));
- /* ifexec */
- RegDeleteKey(hDdeKey,_T("ifexec"));
- RegCloseKey(hDdeKey);
- }
- RegDeleteKey(hVerbKey,_T("ddeexec"));
- }
- /* drop target (WinXP+) */
- RegDeleteKey(hVerbKey,_T("DropTarget"));
- RegCloseKey(hVerbKey);
- }
- RegCloseKey(hShellKey);
- /* Opera support */
- if(fUrlProto) Opera6_AddTrustedProto(pszClassName);
- }
- RegCloseKey(hClassKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-
- if(res) SetLastError(res);
- return !res;
-}
-
-BOOL RemoveRegClass(const char *pszClassName)
-{
- LONG res;
- HKEY hRootKey,hClassKey,hShellKey,hVerbKey;
- TCHAR *ptszClassName,*ptszPrevRunCmd;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,DELETE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* class name */
- ptszClassName=a2t(pszClassName);
- if(ptszClassName!=NULL)
- res=DeleteRegSubTree(hRootKey,ptszClassName);
- else res=ERROR_OUTOFMEMORY;
- mir_free(ptszClassName); /* does NULL check */
-
- /* backup only saved/restored for fUrlProto */
- if (!res) {
- if ((res=RestoreRegTree(hRootKey,pszClassName,"bak_"))==ERROR_SUCCESS)
- /* class */
- if (!RegOpenKeyExA(hRootKey,pszClassName,0,KEY_QUERY_VALUE,&hClassKey)) {
- /* shell */
- if (!RegOpenKeyEx(hClassKey,_T("shell"),0,KEY_QUERY_VALUE,&hShellKey)) {
- /* verb */
- if (!RegOpenKeyEx(hShellKey,_T("open"),0,KEY_QUERY_VALUE,&hVerbKey)) {
- /* command */
- ptszPrevRunCmd=GetRegStrValue(hVerbKey,_T("command"));
- if(ptszPrevRunCmd!=NULL && !IsValidRunCommand(ptszPrevRunCmd))
- res=DeleteRegSubTree(hRootKey,ptszClassName); /* backup outdated, remove all */
- mir_free(ptszPrevRunCmd); /* does NULL check */
- RegCloseKey(hShellKey);
- }
- RegCloseKey(hVerbKey);
- }
- RegCloseKey(hClassKey);
- }
- } else DeleteRegTreeBackup(pszClassName,"bak_");
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-
- if(res==ERROR_SUCCESS || res==ERROR_FILE_NOT_FOUND || res==ERROR_NO_MORE_ITEMS) return TRUE;
- SetLastError(res);
- return FALSE;
-}
-
-/*
- * Test if a given class belongs to the current process
- * specified via its run command.
- * This is especially needed for Urls where the same class name "http" can be
- * registered and thus be overwritten by multiple applications.
- */
-
-BOOL IsRegClass(const char *pszClassName,const TCHAR *pszRunCmd)
-{
- BOOL fSuccess=FALSE;
- HKEY hClassKey,hShellKey,hVerbKey,hCmdKey;
-
- /* using the merged view classes key for reading */
- /* class */
- if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,pszClassName,0,KEY_QUERY_VALUE,&hClassKey)) {
- /* shell */
- if (!RegOpenKeyEx(hClassKey,_T("shell"),0,KEY_QUERY_VALUE,&hShellKey)) {
- /* verb */
- if (!RegOpenKeyEx(hShellKey,_T("open"),0,KEY_QUERY_VALUE,&hVerbKey)) {
- /* command */
- if (!RegOpenKeyEx(hVerbKey,_T("command"),0,KEY_QUERY_VALUE,&hCmdKey)) {
- /* it is enough to check if the command is right */
- fSuccess=IsRegStrValue(hCmdKey,NULL,pszRunCmd);
- RegCloseKey(hCmdKey);
- }
- RegCloseKey(hVerbKey);
- }
- RegCloseKey(hShellKey);
- }
- RegCloseKey(hClassKey);
- }
- return fSuccess;
-}
-
-/*
- * Extract the icon name of the class from the registry and load it.
- * For uses especially with url classes.
- */
-
-// DestroyIcon() the return value
-HICON LoadRegClassSmallIcon(const char *pszClassName)
-{
- HICON hIcon=NULL;
- HKEY hClassKey,hIconKey;
- TCHAR *pszIconLoc,*p;
-
- /* using the merged view classes key for reading */
- /* class */
- if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,pszClassName,0,KEY_QUERY_VALUE,&hClassKey)) {
- /* default icon */
- if (!RegOpenKeyEx(hClassKey,_T("DefaultIcon"),0,KEY_QUERY_VALUE,&hIconKey)) {
- /* extract icon */
- pszIconLoc=GetRegStrValue(hIconKey,NULL);
- if(pszIconLoc!=NULL) {
- p=_tcsrchr(pszIconLoc,_T(','));
- if(p!=NULL) {
- *(p++)=0;
- ExtractIconEx(pszIconLoc,_ttoi(p),NULL,&hIcon,1);
- }
- mir_free(pszIconLoc);
- }
- RegCloseKey(hIconKey);
- }
- RegCloseKey(hClassKey);
- }
-
- return hIcon;
-}
-
-/************************* Extension ******************************/
-
-/*
- * Add a new file extension to the class list.
- * The file extension needs to be associated with a class
- * that has been registered previously.
- * Multiple file extensions can be assigned to the same class.
- * The class contains most settings as the run command etc.
- */
-
-// pszMimeType is allowed to be NULL
-BOOL AddRegFileExt(const char *pszFileExt,const char *pszClassName,const char *pszMimeType,BOOL fIsText)
-{
- BOOL fSuccess=FALSE;
- HKEY hRootKey,hExtKey,hOpenWithKey;
-
- /* some error checking for disallowed values (to avoid errors in registry) */
- if(strchr(pszFileExt,'\\')!=NULL || strchr(pszFileExt,' ')!=NULL)
- return FALSE;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_CREATE_SUB_KEY,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* file ext */
- if (!RegCreateKeyExA(hRootKey,pszFileExt,0,NULL,0,KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY,NULL,&hExtKey,NULL)) {
- TCHAR *pszPrevClass;
- /* backup previous app */
- BackupRegTree(hRootKey,pszFileExt,"bak_");
- /* remove any no-open flag */
- RegDeleteValue(hExtKey,_T("NoOpen"));
- /* open with progids */
- pszPrevClass=GetRegStrValue(hExtKey,NULL);
- if(pszPrevClass!=NULL && !IsRegStrValueA(hExtKey,NULL,pszClassName))
- if (!RegCreateKeyEx(hExtKey,_T("OpenWithProgids"),0,NULL,0,KEY_SET_VALUE,NULL,&hOpenWithKey,NULL)) {
- /* previous class (backup) */
- RegSetValueEx(hOpenWithKey,pszPrevClass,0,REG_NONE,NULL,0);
- RegCloseKey(hOpenWithKey);
- }
- mir_free(pszPrevClass); /* does NULL check */
- /* class name */
- fSuccess=!RegSetValueExA(hExtKey,NULL,0,REG_SZ,(BYTE*)pszClassName,lstrlenA(pszClassName)+1);
- /* mime type e.g. "application/x-icq" */
- if(pszMimeType!=NULL) RegSetValueExA(hExtKey,"Content Type",0,REG_SZ,(BYTE*)pszMimeType,lstrlenA(pszMimeType)+1);
- /* perceived type e.g. text (WinXP+) */
- if(fIsText) RegSetValueEx(hExtKey,_T("PerceivedType"),0,REG_SZ,(BYTE*)_T("text"),5*sizeof(TCHAR));
- RegCloseKey(hExtKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
- return fSuccess;
-}
-
-void RemoveRegFileExt(const char *pszFileExt,const char *pszClassName)
-{
- HKEY hRootKey,hExtKey,hSubKey;
- DWORD nOpenWithCount;
- TCHAR *pszPrevClassName=NULL;
- BOOL fRestored=FALSE;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,DELETE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* file ext */
- if (!RegOpenKeyExA(hRootKey,pszFileExt,0,KEY_QUERY_VALUE|KEY_SET_VALUE|DELETE,&hExtKey)) {
- /* class name (the important part) */
- if (!RestoreRegTree(hRootKey,pszFileExt,"bak_")) {
- pszPrevClassName=GetRegStrValue(hExtKey,NULL);
- if(pszPrevClassName!=NULL) {
- /* previous class name still exists? */
- /* using the merged view classes key for reading */
- if (!RegOpenKeyEx(HKEY_CLASSES_ROOT,pszPrevClassName,0,KEY_QUERY_VALUE,&hSubKey)) {
- fRestored=TRUE;
- RegCloseKey(hSubKey);
- } else RegDeleteValue(hExtKey,NULL);
- mir_free(pszPrevClassName);
- }
- }
- if(pszPrevClassName==NULL) RegDeleteValue(hExtKey,NULL);
- /* open with progids (remove if empty) */
- nOpenWithCount=0;
- if (!RegOpenKeyEx(hExtKey,_T("OpenWithProgids"),0,KEY_SET_VALUE|KEY_QUERY_VALUE,&hSubKey)) {
- /* remove current class (if set by another app) */
- RegDeleteValueA(hSubKey,pszClassName);
- RegQueryInfoKey(hSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&nOpenWithCount,NULL,NULL,NULL);
- RegCloseKey(hSubKey);
- }
- if (!nOpenWithCount) RegDeleteKey(hExtKey,_T("OpenWithProgids")); /* delete if no values */
- RegCloseKey(hExtKey);
- } else DeleteRegTreeBackup(pszFileExt,"bak_");
- if (!fRestored) RegDeleteKeyA(hRootKey,pszFileExt); /* try to remove it all */
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-}
-
-/*
- * Test if a given file extension belongs to the given class name.
- * If it does not belong to the class name, it got reassigned and thus
- * overwritten by another application.
- */
-
-BOOL IsRegFileExt(const char *pszFileExt,const char *pszClassName)
-{
- BOOL fSuccess=FALSE;
- HKEY hExtKey;
-
- /* using the merged view classes key for reading */
- /* file ext */
- if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,pszFileExt,0,KEY_QUERY_VALUE,&hExtKey)) {
- /* class name */
- /* it is enough to check if the class is right */
- fSuccess=IsRegStrValueA(hExtKey,NULL,pszClassName);
- RegCloseKey(hExtKey);
- }
- return fSuccess;
-}
-
-/************************* Mime Type ******************************/
-
-/*
- * Add a given mime type to the global mime database.
- */
-
-// returns TRUE if the mime type was not yet registered on the system,
-// it needs to be removed when the file extension gets removed
-BOOL AddRegMimeType(const char *pszMimeType,const char *pszFileExt,const TCHAR *pszDescription)
-{
- BOOL fSuccess=FALSE;
- HKEY hRootKey,hDbKey,hTypeKey;
-
- /* some error checking for disallowed values (to avoid errors in registry) */
- if(strchr(pszMimeType,'\\')!=NULL || strchr(pszMimeType,' ')!=NULL)
- return FALSE;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_QUERY_VALUE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* database */
- if (!RegOpenKeyEx(hRootKey,_T("MIME\\Database\\Content Type"),0,KEY_CREATE_SUB_KEY,&hDbKey)) {
- /* mime type */
- if (!RegCreateKeyExA(hDbKey,pszMimeType,0,NULL,0,KEY_QUERY_VALUE|KEY_SET_VALUE,NULL,&hTypeKey,NULL)) {
- /* file ext */
- if(RegQueryValueExA(hTypeKey,"Extension",NULL,NULL,NULL,NULL)) /* only set if not present */
- fSuccess=!RegSetValueExA(hTypeKey,"Extension",0,REG_SZ,(BYTE*)pszFileExt,lstrlenA(pszFileExt)+1);
- RegCloseKey(hTypeKey);
- /* Opera support */
- Opera6_AddKnownMimeType(pszMimeType,pszFileExt,pszDescription);
- }
- RegCloseKey(hDbKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
- return fSuccess;
-}
-
-void RemoveRegMimeType(const char *pszMimeType,const char *pszFileExt)
-{
- HKEY hRootKey,hDbKey,hTypeKey;
- BOOL fDelete=TRUE;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_QUERY_VALUE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* database */
- if (!RegOpenKeyEx(hRootKey,_T("MIME\\Database\\Content Type"),0,DELETE,&hDbKey)) {
- /* mime type */
- if (!RegOpenKeyExA(hDbKey,pszMimeType,0,KEY_QUERY_VALUE,&hTypeKey)) {
- /* file ext */
- fDelete=IsRegStrValueA(hTypeKey,_T("Extension"),pszFileExt);
- RegCloseKey(hTypeKey);
- }
- if(fDelete) RegDeleteKeyA(hDbKey,pszMimeType);
- RegCloseKey(hDbKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-}
-
-/************************* Open-With App **************************/
-
-/*
- * Add Miranda as an option to the advanced "Open With..." dialog.
- */
-
-// pszDdeCmd is allowed to be NULL
-void AddRegOpenWith(const TCHAR *pszAppFileName,BOOL fAllowOpenWith,const TCHAR *pszAppName,const TCHAR *pszIconLoc,const TCHAR *pszRunCmd,const TCHAR *pszDdeCmd,const TCHAR *pszDdeApp,const TCHAR *pszDdeTopic)
-{
- HKEY hRootKey,hAppsKey,hExeKey,hShellKey,hVerbKey,hDdeKey;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_QUERY_VALUE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* database */
- if (!RegCreateKeyEx(hRootKey,_T("Applications"),0,NULL,0,KEY_CREATE_SUB_KEY,NULL,&hAppsKey,NULL)) {
- /* filename */
- if (!RegCreateKeyEx(hAppsKey,pszAppFileName,0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY,NULL,&hExeKey,NULL)) {
- /* appname */
- RegSetValueEx(hExeKey,NULL,0,REG_SZ,(BYTE*)pszAppName,(lstrlen(pszAppName)+1)*sizeof(TCHAR));
- /* no open-with flag */
- if(fAllowOpenWith) RegDeleteValue(hExeKey,_T("NoOpenWith"));
- else RegSetValueEx(hExeKey,_T("NoOpenWith"),0,REG_SZ,NULL,0);
- /* default icon */
- if(pszIconLoc!=NULL) SetRegSubKeyStrDefValue(hExeKey,_T("DefaultIcon"),pszIconLoc);
- /* shell */
- if (!RegCreateKeyEx(hExeKey,_T("shell"),0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY,NULL,&hShellKey,NULL)) {
- /* default verb (when empty "open" is used) */
- RegSetValueEx(hShellKey,NULL,0,REG_SZ,(BYTE*)_T("open"),5*sizeof(TCHAR));
- /* verb */
- if (!RegCreateKeyEx(hShellKey,_T("open"),0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY,NULL,&hVerbKey,NULL)) {
- /* friendly appname (mui string) */
- RegSetValueEx(hVerbKey,_T("FriendlyAppName"),0,REG_SZ,(BYTE*)pszAppName,(lstrlen(pszAppName)+1)*sizeof(TCHAR));
- /* command */
- SetRegSubKeyStrDefValue(hVerbKey,_T("command"),pszRunCmd);
- /* ddeexec */
- if(pszDdeCmd!=NULL)
- if (!RegCreateKeyEx(hVerbKey,_T("ddeexec"),0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY,NULL,&hDdeKey,NULL)) {
- /* command */
- RegSetValueEx(hDdeKey,NULL,0,REG_SZ,(BYTE*)pszDdeCmd,(lstrlen(pszDdeCmd)+1)*sizeof(TCHAR));
- /* application */
- SetRegSubKeyStrDefValue(hDdeKey,_T("application"),pszDdeApp);
- /* topic */
- SetRegSubKeyStrDefValue(hDdeKey,_T("topic"),pszDdeTopic);
- RegCloseKey(hDdeKey);
- }
- RegCloseKey(hVerbKey);
- }
- RegCloseKey(hShellKey);
- }
- RegCloseKey(hExeKey);
- }
- RegCloseKey(hAppsKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-}
-
-void RemoveRegOpenWith(const TCHAR *pszAppFileName)
-{
- HKEY hRootKey,hAppsKey,hExeKey,hShellKey,hVerbKey,hDdeKey;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_QUERY_VALUE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* applications */
- if (!RegOpenKeyEx(hRootKey,_T("Applications"),0,DELETE,&hAppsKey)) {
- /* filename */
- if (!RegOpenKeyEx(hAppsKey,pszAppFileName,0,DELETE,&hExeKey)) {
- /* default icon */
- RegDeleteKey(hExeKey,_T("DefaultIcon"));
- /* shell */
- if (!RegOpenKeyEx(hExeKey,_T("shell"),0,DELETE,&hShellKey)) {
- /* verb */
- if (!RegOpenKeyEx(hShellKey,_T("open"),0,DELETE,&hVerbKey)) {
- /* command */
- RegDeleteKey(hVerbKey,_T("command"));
- /* ddeexec */
- if (!RegOpenKeyEx(hVerbKey,_T("ddeexec"),0,DELETE,&hDdeKey)) {
- /* application */
- RegDeleteKey(hDdeKey,_T("application"));
- /* topic */
- RegDeleteKey(hDdeKey,_T("topic"));
- RegCloseKey(hDdeKey);
- }
- RegDeleteKey(hVerbKey,_T("ddeexec"));
- RegCloseKey(hVerbKey);
- }
- RegDeleteKey(hShellKey,_T("open"));
- RegCloseKey(hShellKey);
- }
- RegDeleteKey(hExeKey,_T("shell"));
- /* supported types */
- RegDeleteKey(hExeKey,_T("SupportedTypes"));
- RegCloseKey(hExeKey);
- }
- RegDeleteKey(hAppsKey,pszAppFileName);
- RegCloseKey(hAppsKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-}
-
-/*
- * Tell the "Open With..." dialog we support a given file extension.
- */
-
-void AddRegOpenWithExtEntry(const TCHAR *pszAppFileName,const char *pszFileExt,const TCHAR *pszFileDesc)
-{
- HKEY hRootKey,hAppsKey,hExeKey,hTypesKey;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_QUERY_VALUE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* applications */
- if (!RegOpenKeyEx(hRootKey,_T("Applications"),0,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,&hAppsKey)) {
- /* filename */
- if (!RegOpenKeyEx(hAppsKey,pszAppFileName,0,KEY_CREATE_SUB_KEY,&hExeKey)) {
- /* supported types */
- if (!RegCreateKeyEx(hExeKey,_T("SupportedTypes"),0,NULL,0,KEY_SET_VALUE,NULL,&hTypesKey,NULL)) {
- TCHAR *ptszFileExt;
- ptszFileExt=a2t(pszFileExt);
- if(ptszFileExt!=NULL)
- RegSetValueEx(hTypesKey,ptszFileExt,0,REG_SZ,(BYTE*)pszFileDesc,(lstrlen(pszFileDesc)+1)*sizeof(TCHAR));
- mir_free(ptszFileExt); /* does NULL check */
- RegCloseKey(hTypesKey);
- }
- RegCloseKey(hExeKey);
- }
- RegCloseKey(hAppsKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-}
-
-void RemoveRegOpenWithExtEntry(const TCHAR *pszAppFileName,const char *pszFileExt)
-{
- HKEY hRootKey,hAppsKey,hExeKey,hTypesKey;
-
- /* try to open interactive user's classes key */
- if (!IsWinVer2000Plus() || RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Classes"),0,KEY_QUERY_VALUE,&hRootKey))
- hRootKey=HKEY_CLASSES_ROOT;
-
- /* applications */
- if (!RegOpenKeyEx(hRootKey,_T("Applications"),0,KEY_QUERY_VALUE,&hAppsKey)) {
- /* filename */
- if (!RegOpenKeyEx(hAppsKey,pszAppFileName,0,KEY_QUERY_VALUE,&hExeKey)) {
- /* supported types */
- if (!RegOpenKeyEx(hExeKey,_T("SupportedTypes"),0,KEY_SET_VALUE,&hTypesKey)) {
- RegDeleteValueA(hTypesKey,pszFileExt);
- RegCloseKey(hTypesKey);
- }
- RegCloseKey(hExeKey);
- }
- RegCloseKey(hAppsKey);
- }
-
- if(hRootKey!=HKEY_CLASSES_ROOT)
- RegCloseKey(hRootKey);
-}
-
-/************************* Autostart ******************************/
-
-/*
- * Add Miranda to the autostart list in the registry.
- */
-
-BOOL AddRegRunEntry(const TCHAR *pszAppName,const TCHAR *pszRunCmd)
-{
- BOOL fSuccess=FALSE;
- HKEY hRunKey;
-
- /* run */
- if (!RegCreateKeyEx(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),0,NULL,0,KEY_SET_VALUE,NULL,&hRunKey,NULL)) {
- /* appname */
- fSuccess=!RegSetValueEx(hRunKey,pszAppName,0,REG_SZ,(BYTE*)pszRunCmd,(lstrlen(pszRunCmd)+1)*sizeof(TCHAR));
- RegCloseKey(hRunKey);
- }
- return fSuccess;
-}
-
-BOOL RemoveRegRunEntry(const TCHAR *pszAppName,const TCHAR *pszRunCmd)
-{
- LONG res;
- HKEY hRunKey;
-
- /* run */
- res=RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),0,KEY_QUERY_VALUE|KEY_SET_VALUE,&hRunKey);
- if (!res) {
- /* appname */
- if(IsRegStrValue(hRunKey,pszAppName,pszRunCmd))
- res=RegDeleteValue(hRunKey,pszAppName); /* only remove if current */
- RegCloseKey(hRunKey);
- }
- return res==ERROR_SUCCESS || res==ERROR_FILE_NOT_FOUND;
-}
-
-/*
- * Check if the autostart item belongs to the current instance of Miranda.
- */
-
-BOOL IsRegRunEntry(const TCHAR *pszAppName,const TCHAR *pszRunCmd)
-{
- BOOL fState=FALSE;
- HKEY hRunKey;
-
- /* Run */
- if (!RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),0,KEY_QUERY_VALUE,&hRunKey)) {
- /* appname */
- fState=IsRegStrValue(hRunKey,pszAppName,pszRunCmd);
- RegCloseKey(hRunKey);
- }
- return fState;
-}