summaryrefslogtreecommitdiffabout
path: root/shared-code/install.h
Unidiff
Diffstat (limited to 'shared-code/install.h') (more/less context) (ignore whitespace changes)
-rw-r--r--shared-code/install.h370
1 files changed, 370 insertions, 0 deletions
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 @@
1 #defineWIN32_LEAN_AND_MEAN
2#define VC_EXTRALEAN
3#define WIN32_EXTRALEAN
4#include <windows.h>
5#include <shlobj.h>
6#include <winver.h>
7#include <crtdbg.h>
8#include <string.h>
9#include <stdio.h>
10
11extern "C" WINSHELLAPI void WINAPI SHFree( LPVOID);
12
13 template<class T> class Smart{
14public:
15 T *pT;
16
17 Smart() : pT(NULL) {}
18 Smart(int cb) : pT(new T[cb]) {}
19 Smart(T* p) : pT(p) {}
20 ~Smart() { if(pT)delete pT; }
21
22 Smart& operator=(T* p) { if(pT)delete pT; pT=p; return *this; }
23 operator T* () { return pT; }
24
25 //T& operator[](int ndx) { return pT[ndx]; }
26
27 T* Detach() { T* rv = pT; pT=NULL; return rv; }
28};
29 typedefSmart<char> STRING;
30
31 #define APPEND_SLASH(str) if((str)[strlen(str)-1]!='\\')strcat(str,"\\")
32
33HINSTANCE theInstance;
34
35LPSTR strFETCH_REG_KEY(HKEY hRoot,LPCSTR subKey,LPCSTR val)
36{
37HKEY hkey;
38 if(RegOpenKeyEx(hRoot,subKey,0,KEY_QUERY_VALUE,&hkey)!=ERROR_SUCCESS)
39 return NULL;
40DWORD kType,cb=0;
41STRING rv;
42 if(RegQueryValueEx(hkey,val,NULL,&kType,NULL,&cb)==ERROR_SUCCESS && kType==REG_SZ){
43 rv= new char[cb];
44 _ASSERT(rv!=NULL);
45 if(RegQueryValueEx(hkey,val,NULL,&kType,(LPBYTE)(LPSTR)rv,&cb)!=ERROR_SUCCESS)
46 rv=NULL;
47 }
48 RegCloseKey(hkey);
49 return rv.Detach();
50}
51
52BOOL strSET_REG_KEY(HKEY hRoot,LPCSTR subKey,LPCSTR valName,LPCSTR val)
53{
54HKEY hkey;
55DWORD dw;
56 if(RegCreateKeyEx(hRoot,subKey,0,REG_NONE,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&hkey,&dw)!=ERROR_SUCCESS)
57 return FALSE;
58BOOL rv = (RegSetValueEx(hkey,valName,0,REG_SZ,(LPBYTE)val,strlen(val)+1)==ERROR_SUCCESS);
59 RegCloseKey(hkey);
60 return rv;
61}
62
63void MAKE_PATH(LPCSTR path)
64{
65STRING tmp(strlen(path)+1);
66LPCSTR t0=path;
67LPSTR t1=tmp;
68 while(*t0){
69 if((*t0)=='\\'){
70 *t1=0;
71 CreateDirectory(tmp,NULL);
72 }
73 *(t1++)=*(t0++);
74 }
75 *t1=0;
76 CreateDirectory(tmp,NULL);
77}
78
79BOOL ADDMENU(LPCSTR menu,LPCSTR item,LPCSTR path,LPCSTR program)
80{
81STRING stm = strFETCH_REG_KEY(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders","Programs");
82 if(!stm)
83 return FALSE;
84int pil = 1+strlen(path)+1+strlen(program)+1+1;
85STRING pi(pil);
86 strcpy(pi,path);
87 APPEND_SLASH(pi);
88 strcat(pi,program);
89int ipl = strlen(stm)+1+strlen(menu)+1+strlen(item)+4+1;
90STRING ip(ipl);
91 memmove(ip,stm,strlen(stm)+1);
92 APPEND_SLASH(ip);
93 strcat(ip,menu);
94 MAKE_PATH(ip);
95 APPEND_SLASH(ip);
96 strcat(ip,item);
97 strcat(ip,".lnk");
98IShellLink* sl = NULL;
99IPersistFile* pf = NULL;
100BOOL rv = FALSE;
101 do{
102 HRESULT hrv = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&sl);
103 if(!SUCCEEDED(hrv))
104 break;
105 sl->SetDescription(item);
106 sl->SetPath(pi);
107 hrv = sl->QueryInterface(IID_IPersistFile,(LPVOID*)&pf);
108 if(!SUCCEEDED(hrv))
109 break;
110 WORD wsz[MAX_PATH];
111 MultiByteToWideChar(CP_ACP,0,ip,-1,wsz,MAX_PATH);
112 hrv = pf->Save(wsz,TRUE);
113 if(SUCCEEDED(hrv))
114 rv=TRUE;
115 }while(FALSE);
116 if(pf)
117 pf->Release();
118 if(sl)
119 sl->Release();
120 return rv;
121}
122
123FILE* CREATE_INF_FILE(LPCSTR path,LPCSTR file)
124{
125STRING fn(strlen(path)+1+strlen(file)+1);
126 strcpy(fn,path);
127 APPEND_SLASH(fn);
128 strcat(fn,file);
129 return fopen(fn,"wt");
130}
131
132BOOL INSTALLFILE(LPCSTR res,LPCSTR path,LPCSTR file)
133{
134STRING temp(MAX_PATH);
135 if(!GetTempPath(MAX_PATH,temp)) return FALSE;
136STRING tf(MAX_PATH);
137 if(!GetTempFileName(temp,"KGI",0,tf)) return FALSE;
138HRSRC hrsrc = FindResource(NULL,res,MAKEINTRESOURCE(RT_RCDATA));
139 if(!hrsrc) return FALSE;
140DWORD sor = SizeofResource(NULL,hrsrc);
141 if(!sor) return FALSE;
142HGLOBAL hglobal = LoadResource(NULL,hrsrc);
143 if(!hglobal) return FALSE;
144LPVOID lpv = LockResource(hglobal);
145 if(!lpv) return FALSE;
146HANDLE hf = CreateFile(tf,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,NULL);
147 if(!hf) return FALSE;
148DWORD written = 0;
149 if(!WriteFile(hf,lpv,sor,&written,NULL) || written!=sor){
150 CloseHandle(hf);
151 return FALSE;
152 }
153 CloseHandle(hf);
154STRING toKill(strlen(tf)+1);
155 strcpy(toKill,tf);
156 for(int tmp=strlen(tf)-1;tmp>0 && ((tf[tmp])!='\\');tmp--);
157 if(tf[tmp]=='\\')
158 tf[tmp++]=0;
159STRING nothing(_MAX_PATH);
160UINT nothingLength=_MAX_PATH;
161 if(VerInstallFile(0,&tf[tmp],(LPSTR)file,tf,(LPSTR)path,NULL,nothing,&nothingLength)){
162 DeleteFile(toKill);
163 return FALSE;
164 }
165 DeleteFile(toKill);
166 return TRUE;
167}
168
169LPCSTR pdTitle, pdPrompt;
170char pdPath[_MAX_PATH];
171BOOL CALLBACK pathDlgProc(HWND hwnd,UINT uMsg,WPARAM wP,LPARAM lP)
172{
173 switch(uMsg){
174 case WM_INITDIALOG:
175 SetWindowText(hwnd,pdTitle);
176 SetDlgItemText(hwnd,IDC_PROMPT,pdPrompt);
177 SetDlgItemText(hwnd,IDC_PATH,pdPath);
178 SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
179 return 1;
180 case WM_COMMAND:
181 switch(LOWORD(wP)){ // ID
182 case IDC_BROWSE:
183 switch(HIWORD(wP)){
184 case BN_CLICKED:
185 {
186 BROWSEINFO bi;
187 memset(&bi,0,sizeof(bi));
188 bi.hwndOwner=hwnd;
189 bi.pszDisplayName=pdPath;
190 bi.lpszTitle="Select Folder..";
191 bi.ulFlags=BIF_RETURNONLYFSDIRS;
192 LPITEMIDLIST lpidl=SHBrowseForFolder(&bi);
193 if(lpidl){
194 SHGetPathFromIDList(lpidl,pdPath);
195 SHFree(lpidl);
196 SetDlgItemText(hwnd,IDC_PATH,pdPath);
197 }
198 }
199 return 1;
200 }
201 break;
202 case IDOK:
203 switch(HIWORD(wP)){
204 case BN_CLICKED:
205 if(GetDlgItemText(hwnd,IDC_PATH,pdPath,sizeof(pdPath)))
206 EndDialog(hwnd,IDOK);
207 else
208 // *** Error message
209 EndDialog(hwnd,IDCANCEL);
210 return 1;
211 }
212 break;
213 case IDCANCEL:
214 switch(HIWORD(wP)){
215 case BN_CLICKED:
216 EndDialog(hwnd,IDCANCEL);
217 return 1;
218 }
219 break;
220 };
221 break;
222 }
223 return 0;
224}
225
226LPSTR REQUESTPATH(LPCSTR title,LPCSTR prompt,LPCSTR defPath)
227{
228 pdTitle=title;pdPrompt=prompt;
229 strcpy(pdPath,defPath);
230 if(DialogBox(NULL,MAKEINTRESOURCE(IDD_PATH),NULL/*Parent*/,(DLGPROC)&pathDlgProc)!=IDOK)
231 return NULL;
232STRING rv(strlen(pdPath)+1);
233 strcpy(rv,pdPath);
234 return rv.Detach();
235}
236
237HKEY uninstallKey(LPCSTR regKey) {
238 STRING rk(100+strlen(regKey)+1);
239 sprintf(rk,"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s",regKey);
240 HKEY rv = NULL;
241 DWORD dw;
242 if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,rk,0,REG_NONE,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&rv,&dw)!=ERROR_SUCCESS)
243 return NULL;
244 return rv;
245}
246
247BOOL REG_UNINSTALL_COMMAND(LPCSTR regKey,LPCSTR dName,LPCSTR iPath,LPCSTR iFile,LPCSTR iSection)
248{
249 HKEY hKey = uninstallKey(regKey);
250 if(!hKey)
251 return FALSE;
252 BOOL rv=FALSE;
253 do{
254 if(RegSetValueEx(hKey,"DisplayName",0,REG_SZ,(LPBYTE)dName,strlen(dName)+1)!=ERROR_SUCCESS)
255 break;
256 STRING us(50+strlen(iPath)+1+strlen(iFile)+strlen(iSection)+1);
257 strcpy(us,"RunDll32 setupapi.dll,InstallHinfSection ");
258 strcat(us,iSection);
259 strcat(us," 132 ");
260 strcat(us,iPath);
261 APPEND_SLASH(us);
262 strcat(us,iFile);
263 if(RegSetValueEx(hKey,"UninstallString",0,REG_SZ,(LPBYTE)(LPCSTR)us,strlen(us)+1)!=ERROR_SUCCESS)
264 break;
265 rv=TRUE;
266 }while(FALSE);
267 RegCloseKey(hKey);
268 return rv;
269}
270BOOL REG_UNINSTALL_ICON(LPCSTR regKey,LPCSTR path,LPCSTR file,int n) {
271 HKEY hKey = uninstallKey(regKey);
272 if(!hKey)
273 return FALSE;
274 STRING uis(strlen(path)+1+strlen(file)+7);
275 strcpy(uis,path);
276 APPEND_SLASH(uis);
277 strcat(uis,file);
278 char tmp[8];
279 sprintf(tmp,";%d",n);
280 strcat(uis,tmp);
281 BOOL rv = TRUE;
282 if(RegSetValueEx(hKey,"DisplayIcon",0,REG_SZ,(LPBYTE)(LPCSTR)uis,strlen(uis)+1)!=ERROR_SUCCESS)
283 rv = FALSE;
284 RegCloseKey(hKey);
285 return rv;
286}
287BOOL REG_UNINSTALL_COMMENT(LPCSTR regKey,LPCSTR comment) {
288 HKEY hKey = uninstallKey(regKey);
289 if(!hKey)
290 return FALSE;
291 BOOL rv = TRUE;
292 if(RegSetValueEx(hKey,"lComment",0,REG_SZ,(LPBYTE)comment,strlen(comment)+1)!=ERROR_SUCCESS)
293 rv = FALSE;
294 RegCloseKey(hKey);
295 return rv;
296}
297BOOL REG_UNINSTALL_VERSION(LPCSTR regKey,LPCSTR version) {
298 HKEY hKey = uninstallKey(regKey);
299 if(!hKey)
300 return FALSE;
301 BOOL rv = TRUE;
302 if(RegSetValueEx(hKey,"DisplayVersion",0,REG_SZ,(LPBYTE)version,strlen(version)+1)!=ERROR_SUCCESS)
303 rv = FALSE;
304 RegCloseKey(hKey);
305 return rv;
306}
307BOOL REG_UNINSTALL_LOCATION(LPCSTR regKey,LPCSTR location) {
308 HKEY hKey = uninstallKey(regKey);
309 if(!hKey)
310 return FALSE;
311 BOOL rv = TRUE;
312 if(RegSetValueEx(hKey,"InstallLocation",0,REG_SZ,(LPBYTE)location,strlen(location)+1)!=ERROR_SUCCESS)
313 rv = FALSE;
314 RegCloseKey(hKey);
315 return rv;
316}
317BOOL REG_UNINSTALL_PUBLISHER(LPCSTR regKey,LPCSTR publisher) {
318 HKEY hKey = uninstallKey(regKey);
319 if(!hKey)
320 return FALSE;
321 BOOL rv = TRUE;
322 if(RegSetValueEx(hKey,"Publisher",0,REG_SZ,(LPBYTE)publisher,strlen(publisher)+1)!=ERROR_SUCCESS)
323 rv = FALSE;
324 RegCloseKey(hKey);
325 return rv;
326}
327BOOL REG_UNINSTALL_URLS(LPCSTR regKey,LPCSTR about,LPCSTR update) {
328 HKEY hKey = uninstallKey(regKey);
329 if(!hKey)
330 return FALSE;
331 BOOL rv = TRUE;
332 if(RegSetValueEx(hKey,"URLInfoAbout",0,REG_SZ,(LPBYTE)about,strlen(about)+1)!=ERROR_SUCCESS)
333 rv = FALSE;
334 if(RegSetValueEx(hKey,"URLUpdateInfo",0,REG_SZ,(LPBYTE)update,strlen(update)+1)!=ERROR_SUCCESS)
335 rv = FALSE;
336 RegCloseKey(hKey);
337 return rv;
338}
339
340 #defineINF_FILE_HEADER(i) fprintf(i,"[Version]\nSignature=\"$CHICAGO$\"\n\n")
341#define INF_FILE_SECTION(i,s) fprintf(i,"\n[%s]\n",s)
342 #defineINF_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)
343#define INF_MENU_GROUP(i,n,m) fprintf(i,"setup.ini, progman.groups,,\"group%d=%s\"\n",n,m)
344#define INF_MENU_ITEM(i,n,m) fprintf(i,"setup.ini, group%d,, \"\"\"%s\"\"\"\n",n,m);
345#define INF_REMOVE_ROOT(i,g,r) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\DeleteFiles\\%s,,,\"%s\"\n",g,r)
346#define INF_REMOVE_FILE(i,g,f) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\DeleteFiles\\%s,%s,,\"%s\"\n",g,f,f)
347#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");}
348
349LPSTR GET_SHORT_PATH(LPCSTR path)
350{
351char tmp;
352DWORD len = GetShortPathName(path,&tmp,1);
353 if(!len)
354 return NULL;
355STRING rv(len+1);
356 if(!GetShortPathName(path,rv,len+1))
357 return NULL;
358 return rv.Detach();
359}
360
361BOOL Install(void);
362
363int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
364{
365 theInstance=hInstance;
366 CoInitialize(NULL);
367 Install();
368 CoUninitialize();
369 return 0;
370}