From 955d4e00adc9f39ab93bf21f07506eb75b013c70 Mon Sep 17 00:00:00 2001 From: Michael Krelin Date: Mon, 05 Jul 2004 01:53:09 +0000 Subject: initial commit into svn repository git-svn-id: http://svn.klever.net/kin/T42/trunk@1 fe716a7a-6dde-0310-88d9-d003556173a8 --- (limited to 'shared-code/install.h') diff --git a/shared-code/install.h b/shared-code/install.h new file mode 100644 index 0000000..8c55ca9 --- a/dev/null +++ b/shared-code/install.h @@ -0,0 +1,370 @@ +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN +#define WIN32_EXTRALEAN +#include +#include +#include +#include +#include +#include + +extern "C" WINSHELLAPI void WINAPI SHFree( LPVOID); + +template class Smart { +public: + T *pT; + + Smart() : pT(NULL) {} + Smart(int cb) : pT(new T[cb]) {} + Smart(T* p) : pT(p) {} + ~Smart() { if(pT)delete pT; } + + Smart& operator=(T* p) { if(pT)delete pT; pT=p; return *this; } + operator T* () { return pT; } + +// T& operator[](int ndx) { return pT[ndx]; } + + T* Detach() { T* rv = pT; pT=NULL; return rv; } +}; +typedef Smart STRING; + +#define APPEND_SLASH(str) if((str)[strlen(str)-1]!='\\')strcat(str,"\\") + +HINSTANCE theInstance; + +LPSTR strFETCH_REG_KEY(HKEY hRoot,LPCSTR subKey,LPCSTR val) +{ +HKEY hkey; + if(RegOpenKeyEx(hRoot,subKey,0,KEY_QUERY_VALUE,&hkey)!=ERROR_SUCCESS) + return NULL; +DWORD kType,cb=0; +STRING rv; + if(RegQueryValueEx(hkey,val,NULL,&kType,NULL,&cb)==ERROR_SUCCESS && kType==REG_SZ){ + rv= new char[cb]; + _ASSERT(rv!=NULL); + if(RegQueryValueEx(hkey,val,NULL,&kType,(LPBYTE)(LPSTR)rv,&cb)!=ERROR_SUCCESS) + rv=NULL; + } + RegCloseKey(hkey); + return rv.Detach(); +} + +BOOL strSET_REG_KEY(HKEY hRoot,LPCSTR subKey,LPCSTR valName,LPCSTR val) +{ +HKEY hkey; +DWORD dw; + if(RegCreateKeyEx(hRoot,subKey,0,REG_NONE,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&hkey,&dw)!=ERROR_SUCCESS) + return FALSE; +BOOL rv = (RegSetValueEx(hkey,valName,0,REG_SZ,(LPBYTE)val,strlen(val)+1)==ERROR_SUCCESS); + RegCloseKey(hkey); + return rv; +} + +void MAKE_PATH(LPCSTR path) +{ +STRING tmp(strlen(path)+1); +LPCSTR t0=path; +LPSTR t1=tmp; + while(*t0){ + if((*t0)=='\\'){ + *t1=0; + CreateDirectory(tmp,NULL); + } + *(t1++)=*(t0++); + } + *t1=0; + CreateDirectory(tmp,NULL); +} + +BOOL ADDMENU(LPCSTR menu,LPCSTR item,LPCSTR path,LPCSTR program) +{ +STRING stm = strFETCH_REG_KEY(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders","Programs"); + if(!stm) + return FALSE; +int pil = 1+strlen(path)+1+strlen(program)+1+1; +STRING pi(pil); + strcpy(pi,path); + APPEND_SLASH(pi); + strcat(pi,program); +int ipl = strlen(stm)+1+strlen(menu)+1+strlen(item)+4+1; +STRING ip(ipl); + memmove(ip,stm,strlen(stm)+1); + APPEND_SLASH(ip); + strcat(ip,menu); + MAKE_PATH(ip); + APPEND_SLASH(ip); + strcat(ip,item); + strcat(ip,".lnk"); +IShellLink* sl = NULL; +IPersistFile* pf = NULL; +BOOL rv = FALSE; + do{ + HRESULT hrv = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&sl); + if(!SUCCEEDED(hrv)) + break; + sl->SetDescription(item); + sl->SetPath(pi); + hrv = sl->QueryInterface(IID_IPersistFile,(LPVOID*)&pf); + if(!SUCCEEDED(hrv)) + break; + WORD wsz[MAX_PATH]; + MultiByteToWideChar(CP_ACP,0,ip,-1,wsz,MAX_PATH); + hrv = pf->Save(wsz,TRUE); + if(SUCCEEDED(hrv)) + rv=TRUE; + }while(FALSE); + if(pf) + pf->Release(); + if(sl) + sl->Release(); + return rv; +} + +FILE* CREATE_INF_FILE(LPCSTR path,LPCSTR file) +{ +STRING fn(strlen(path)+1+strlen(file)+1); + strcpy(fn,path); + APPEND_SLASH(fn); + strcat(fn,file); + return fopen(fn,"wt"); +} + +BOOL INSTALLFILE(LPCSTR res,LPCSTR path,LPCSTR file) +{ +STRING temp(MAX_PATH); + if(!GetTempPath(MAX_PATH,temp)) return FALSE; +STRING tf(MAX_PATH); + if(!GetTempFileName(temp,"KGI",0,tf)) return FALSE; +HRSRC hrsrc = FindResource(NULL,res,MAKEINTRESOURCE(RT_RCDATA)); + if(!hrsrc) return FALSE; +DWORD sor = SizeofResource(NULL,hrsrc); + if(!sor) return FALSE; +HGLOBAL hglobal = LoadResource(NULL,hrsrc); + if(!hglobal) return FALSE; +LPVOID lpv = LockResource(hglobal); + if(!lpv) return FALSE; +HANDLE hf = CreateFile(tf,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,NULL); + if(!hf) return FALSE; +DWORD written = 0; + if(!WriteFile(hf,lpv,sor,&written,NULL) || written!=sor){ + CloseHandle(hf); + return FALSE; + } + CloseHandle(hf); +STRING toKill(strlen(tf)+1); + strcpy(toKill,tf); + for(int tmp=strlen(tf)-1;tmp>0 && ((tf[tmp])!='\\');tmp--); + if(tf[tmp]=='\\') + tf[tmp++]=0; +STRING nothing(_MAX_PATH); +UINT nothingLength=_MAX_PATH; + if(VerInstallFile(0,&tf[tmp],(LPSTR)file,tf,(LPSTR)path,NULL,nothing,¬hingLength)){ + DeleteFile(toKill); + return FALSE; + } + DeleteFile(toKill); + return TRUE; +} + +LPCSTR pdTitle, pdPrompt; +char pdPath[_MAX_PATH]; +BOOL CALLBACK pathDlgProc(HWND hwnd,UINT uMsg,WPARAM wP,LPARAM lP) +{ + switch(uMsg){ + case WM_INITDIALOG: + SetWindowText(hwnd,pdTitle); + SetDlgItemText(hwnd,IDC_PROMPT,pdPrompt); + SetDlgItemText(hwnd,IDC_PATH,pdPath); + SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + return 1; + case WM_COMMAND: + switch(LOWORD(wP)){ // ID + case IDC_BROWSE: + switch(HIWORD(wP)){ + case BN_CLICKED: + { + BROWSEINFO bi; + memset(&bi,0,sizeof(bi)); + bi.hwndOwner=hwnd; + bi.pszDisplayName=pdPath; + bi.lpszTitle="Select Folder.."; + bi.ulFlags=BIF_RETURNONLYFSDIRS; + LPITEMIDLIST lpidl=SHBrowseForFolder(&bi); + if(lpidl){ + SHGetPathFromIDList(lpidl,pdPath); + SHFree(lpidl); + SetDlgItemText(hwnd,IDC_PATH,pdPath); + } + } + return 1; + } + break; + case IDOK: + switch(HIWORD(wP)){ + case BN_CLICKED: + if(GetDlgItemText(hwnd,IDC_PATH,pdPath,sizeof(pdPath))) + EndDialog(hwnd,IDOK); + else + // *** Error message + EndDialog(hwnd,IDCANCEL); + return 1; + } + break; + case IDCANCEL: + switch(HIWORD(wP)){ + case BN_CLICKED: + EndDialog(hwnd,IDCANCEL); + return 1; + } + break; + }; + break; + } + return 0; +} + +LPSTR REQUESTPATH(LPCSTR title,LPCSTR prompt,LPCSTR defPath) +{ + pdTitle=title;pdPrompt=prompt; + strcpy(pdPath,defPath); + if(DialogBox(NULL,MAKEINTRESOURCE(IDD_PATH),NULL/*Parent*/,(DLGPROC)&pathDlgProc)!=IDOK) + return NULL; +STRING rv(strlen(pdPath)+1); + strcpy(rv,pdPath); + return rv.Detach(); +} + +HKEY uninstallKey(LPCSTR regKey) { + STRING rk(100+strlen(regKey)+1); + sprintf(rk,"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s",regKey); + HKEY rv = NULL; + DWORD dw; + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,rk,0,REG_NONE,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&rv,&dw)!=ERROR_SUCCESS) + return NULL; + return rv; +} + +BOOL REG_UNINSTALL_COMMAND(LPCSTR regKey,LPCSTR dName,LPCSTR iPath,LPCSTR iFile,LPCSTR iSection) +{ + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + BOOL rv=FALSE; + do{ + if(RegSetValueEx(hKey,"DisplayName",0,REG_SZ,(LPBYTE)dName,strlen(dName)+1)!=ERROR_SUCCESS) + break; + STRING us(50+strlen(iPath)+1+strlen(iFile)+strlen(iSection)+1); + strcpy(us,"RunDll32 setupapi.dll,InstallHinfSection "); + strcat(us,iSection); + strcat(us," 132 "); + strcat(us,iPath); + APPEND_SLASH(us); + strcat(us,iFile); + if(RegSetValueEx(hKey,"UninstallString",0,REG_SZ,(LPBYTE)(LPCSTR)us,strlen(us)+1)!=ERROR_SUCCESS) + break; + rv=TRUE; + }while(FALSE); + RegCloseKey(hKey); + return rv; +} +BOOL REG_UNINSTALL_ICON(LPCSTR regKey,LPCSTR path,LPCSTR file,int n) { + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + STRING uis(strlen(path)+1+strlen(file)+7); + strcpy(uis,path); + APPEND_SLASH(uis); + strcat(uis,file); + char tmp[8]; + sprintf(tmp,";%d",n); + strcat(uis,tmp); + BOOL rv = TRUE; + if(RegSetValueEx(hKey,"DisplayIcon",0,REG_SZ,(LPBYTE)(LPCSTR)uis,strlen(uis)+1)!=ERROR_SUCCESS) + rv = FALSE; + RegCloseKey(hKey); + return rv; +} +BOOL REG_UNINSTALL_COMMENT(LPCSTR regKey,LPCSTR comment) { + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + BOOL rv = TRUE; + if(RegSetValueEx(hKey,"lComment",0,REG_SZ,(LPBYTE)comment,strlen(comment)+1)!=ERROR_SUCCESS) + rv = FALSE; + RegCloseKey(hKey); + return rv; +} +BOOL REG_UNINSTALL_VERSION(LPCSTR regKey,LPCSTR version) { + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + BOOL rv = TRUE; + if(RegSetValueEx(hKey,"DisplayVersion",0,REG_SZ,(LPBYTE)version,strlen(version)+1)!=ERROR_SUCCESS) + rv = FALSE; + RegCloseKey(hKey); + return rv; +} +BOOL REG_UNINSTALL_LOCATION(LPCSTR regKey,LPCSTR location) { + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + BOOL rv = TRUE; + if(RegSetValueEx(hKey,"InstallLocation",0,REG_SZ,(LPBYTE)location,strlen(location)+1)!=ERROR_SUCCESS) + rv = FALSE; + RegCloseKey(hKey); + return rv; +} +BOOL REG_UNINSTALL_PUBLISHER(LPCSTR regKey,LPCSTR publisher) { + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + BOOL rv = TRUE; + if(RegSetValueEx(hKey,"Publisher",0,REG_SZ,(LPBYTE)publisher,strlen(publisher)+1)!=ERROR_SUCCESS) + rv = FALSE; + RegCloseKey(hKey); + return rv; +} +BOOL REG_UNINSTALL_URLS(LPCSTR regKey,LPCSTR about,LPCSTR update) { + HKEY hKey = uninstallKey(regKey); + if(!hKey) + return FALSE; + BOOL rv = TRUE; + if(RegSetValueEx(hKey,"URLInfoAbout",0,REG_SZ,(LPBYTE)about,strlen(about)+1)!=ERROR_SUCCESS) + rv = FALSE; + if(RegSetValueEx(hKey,"URLUpdateInfo",0,REG_SZ,(LPBYTE)update,strlen(update)+1)!=ERROR_SUCCESS) + rv = FALSE; + RegCloseKey(hKey); + return rv; +} + +#define INF_FILE_HEADER(i) fprintf(i,"[Version]\nSignature=\"$CHICAGO$\"\n\n") +#define INF_FILE_SECTION(i,s) fprintf(i,"\n[%s]\n",s) +#define INF_UNINSTALL_REG(i,p) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s\nHKLM,Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s,DisplayName\nHKLM,Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s,UninstallString\n",p,p,p) +#define INF_MENU_GROUP(i,n,m) fprintf(i,"setup.ini, progman.groups,,\"group%d=%s\"\n",n,m) +#define INF_MENU_ITEM(i,n,m) fprintf(i,"setup.ini, group%d,, \"\"\"%s\"\"\"\n",n,m); +#define INF_REMOVE_ROOT(i,g,r) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\DeleteFiles\\%s,,,\"%s\"\n",g,r) +#define INF_REMOVE_FILE(i,g,f) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\DeleteFiles\\%s,%s,,\"%s\"\n",g,f,f) +#define INF_REMOVE_HELP_FILE(i,g,f) {INF_REMOVE_FILE(i,g,f".hlp");INF_REMOVE_FILE(i,g,f".cnt");INF_REMOVE_FILE(i,g,f".GID");INF_REMOVE_FILE(i,g,f".FTS");} + +LPSTR GET_SHORT_PATH(LPCSTR path) +{ +char tmp; +DWORD len = GetShortPathName(path,&tmp,1); + if(!len) + return NULL; +STRING rv(len+1); + if(!GetShortPathName(path,rv,len+1)) + return NULL; + return rv.Detach(); +} + +BOOL Install(void); + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int) +{ + theInstance=hInstance; + CoInitialize(NULL); + Install(); + CoUninitialize(); + return 0; +} -- cgit v0.9.0.2