]> git.saurik.com Git - wxWidgets.git/blob - utils/Install/instsup.cpp
rewrite to avoid unnecessary redraws
[wxWidgets.git] / utils / Install / instsup.cpp
1 /*
2 * instsup.c (c) 1999,2000 Brian Smith
3 */
4
5 #include "wx/wxprec.h"
6
7 #ifndef WX_PRECOMP
8 #include "wx/wx.h"
9 #endif
10
11 #include <stdio.h>
12 #include <stddef.h>
13 #include <stdlib.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <fcntl.h>
17 #if defined(__OS2__) || defined(__EMX__) || defined(WIN32) || defined(WINNT)
18 #include <process.h>
19 #endif
20 #include <sys/types.h>
21 #ifdef WIN32
22 #include <shlobj.h>
23 #endif
24 #include "install.h"
25 #include "instsup.h"
26
27 extern char *INSTALLER_TITLE;
28 extern char *INSTALLER_PROGRAM;
29 extern char *INSTALLER_FOLDER;
30 extern char *INSTALLER_SHADOW;
31 extern char *INSTALLER_OBJECT;
32 extern char tempPath[], installdir[], csfile[], bufile[], bootdrive[], instlog[], installdir2[];
33 extern int installstate, success;
34
35 extern FILE *self;
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 char *replaceem(char *orig);
42
43 int sendmessage(int destination, int messid)
44 {
45 #if 0
46 /* Update percentage bar */
47 if(messid == 1)
48 {
49 wxMutexGuiEnter();
50
51 updatepercent();
52
53 wxMutexGuiLeave();
54 }
55 if(messid == 2)
56 {
57 extern wxCondition *InstCond;
58
59 InstCond->Broadcast();
60 }
61
62 #endif
63 return 0;
64 }
65
66 void DoGUI(void)
67 {
68 updatepercent();
69 wxYield();
70 }
71 /* This should return the current color depth */
72 unsigned long color_depth(void)
73 {
74 #if __OS2__
75 HDC hdc = WinOpenWindowDC(HWND_DESKTOP);
76 LONG colors;
77
78 DevQueryCaps(hdc, CAPS_COLORS, 1, &colors);
79 DevCloseDC(hdc);
80 return colors;
81 #endif
82 return 0;
83 }
84
85 /*
86 * Call the reboot vector.
87 */
88 void sysreboot(void)
89 {
90 #if __OS2__
91 #define SYSFUNC 0xD5
92 #define REBOOT 0xAB
93 #define REBOOTDEV "\\DEV\\DOS$"
94
95 APIRET rc;
96 HFILE hREBOOT;
97 ULONG ulAction;
98
99 rc = DosOpen(REBOOTDEV,
100 &hREBOOT,
101 &ulAction,
102 0L,
103 FILE_NORMAL,
104 FILE_OPEN,
105 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
106 0L);
107 if (rc == 0)
108 {
109 DosDevIOCtl(hREBOOT,
110 SYSFUNC,
111 REBOOT,
112 NULL,
113 0L,
114 NULL,
115 NULL,
116 0L,
117 NULL);
118 DosClose(hREBOOT);
119 }
120 #endif
121 }
122
123 /*
124 * Display an informational dialog box to the user with the given text.
125 */
126 int mesg(char *format, ...) {
127 va_list args;
128 char outbuf[4096];
129
130 va_start(args, format);
131 vsprintf(outbuf, format, args);
132 va_end(args);
133
134 wxMessageBox(outbuf, INSTALLER_TITLE,
135 wxOK | wxICON_EXCLAMATION, NULL);
136
137 return strlen(outbuf);
138 }
139
140 int checktext(char *text, char *buffer, int buflen)
141 {
142 int z, len = strlen(text);
143
144 for(z=0;z<(buflen-len);z++)
145 {
146 if(memcmp(text, &buffer[z], len) == 0)
147 return z;
148 }
149 return -1;
150
151 }
152
153 /*
154 * Returns the offset withing the executable to the specified text.
155 */
156 long findtext(char *text)
157 {
158 char buffer[512];
159 int offset;
160 unsigned long curpos = 0;
161
162 fseek(self, 0, SEEK_SET);
163 fread(buffer, 1, 512, self);
164 if((offset = checktext(text, buffer, 512)) > -1)
165 return offset;
166 while(!feof(self))
167 {
168 memcpy(buffer, &buffer[256], 256);
169 fread(&buffer[256], 1, 256, self);
170 curpos += 256;
171 if((offset = checktext(text, buffer, 512)) > -1)
172 return offset+curpos;
173
174 }
175 return -1;
176 }
177
178 /* We encode archive search text so we don't get confused
179 * by the string table - I was using LXLite to take care
180 * of this problem on OS/2 but in portable code this may
181 * not be an option. */
182 char *decode(char *input)
183 {
184 char *result;
185 int i = 0;
186
187 result = (char *)malloc(strlen(input) / 2 + 1);
188
189 while (input[0] && input[1])
190 {
191 result[i] = ((input[0] - 0x41) << 4) | (input[1] - 0x41);
192 input += 2;
193 i++;
194 }
195 result[i] = '\0';
196
197 return result;
198 }
199
200 /*
201 * Removes any carriage returns or line feeds from the buffer.
202 */
203 void stripcrlf(char *buffer)
204 {
205 int z, len = strlen(buffer);
206
207 for(z=0;z<len;z++)
208 {
209 if(buffer[z] == '\r' || buffer[z] == '\n')
210 {
211 buffer[z] = 0;
212 return;
213 }
214 }
215 }
216
217 /*
218 * Returns the space free on a given drive... where 0 is A: in MB
219 */
220 unsigned long drivefree(int drive)
221 {
222 #if __OS2__
223 ULONG aulFSInfoBuf[40] = {0};
224 APIRET rc = NO_ERROR;
225 double bytesFree;
226
227 DosError(FERR_DISABLEHARDERR);
228 rc = DosQueryFSInfo(drive,
229 FSIL_ALLOC,
230 (PVOID)aulFSInfoBuf,
231 sizeof(aulFSInfoBuf));
232
233 DosError(FERR_ENABLEHARDERR);
234 if (rc != NO_ERROR)
235 return 0;
236
237 bytesFree = (double)aulFSInfoBuf[3] * (double)aulFSInfoBuf[1] * (USHORT)aulFSInfoBuf[4];
238 return (unsigned long)(bytesFree / (1024.0 * 1024.0));
239 #endif
240 return 0;
241 }
242
243
244 /*
245 * Display a fatal error message and set the abort flag in case we are in a secondary thread.
246 */
247 void error(char *format, ...) {
248 va_list args;
249 char errstring[1024];
250
251 va_start(args, format);
252 vsprintf(errstring, format, args);
253 va_end(args);
254
255 if(installstate != ABORTED)
256 {
257 success=1;
258 installstate=ABORTED;
259 }
260 wxMessageBox(errstring, INSTALLER_TITLE,
261 wxOK | wxICON_EXCLAMATION, NULL);
262 }
263
264 void setdrivedir(char *drivedir)
265 {
266 wxSetWorkingDirectory(drivedir);
267 }
268
269 /*
270 * Make the TEMP directory the current directory, or the root directory of the boot drive.
271 */
272 void settempdir(void)
273 {
274 #if defined(__EMX__) || defined(__OS2__) || defined(WIN32) || defined(WINNT)
275 /* Windows or OS/2 */
276 char *envdir = getenv("TMP");
277 int len;
278
279 if (!envdir)
280 envdir = getenv("TEMP");
281 if (!envdir)
282 envdir = replaceem("%BOOTDRIVE%:\\");
283 strcpy(tempPath,envdir);
284 len = strlen(tempPath);
285 if (len > 3 && tempPath[len-1] == '\\')
286 tempPath[len-1] = 0;
287 strupr(tempPath);
288 setdrivedir(tempPath);
289 #else
290 /* Unix */
291 setdrivedir("/tmp");
292 #endif
293 }
294
295 void getbootdrive(void)
296 {
297 /* On windows I don't think you can boot from anything
298 except C: drive. So I am not going to do anything here. */
299 }
300
301 void PM_backslash(char *s)
302 {
303 unsigned int pos = strlen(s);
304 if (s[pos-1] != '\\') {
305 s[pos] = '\\';
306 s[pos+1] = '\0';
307 }
308 }
309
310 /*
311 * Makes a folder on the desktop.
312 */
313 void MakeFolder(char Title[], char Icon[], char dest[], char id[], char setup[])
314 {
315 #ifdef __OS2__
316 char szArg[200];
317
318 memset(szArg,0,sizeof(szArg));
319
320 if ((Icon != NULL) && (strlen(Icon) != 0))
321 {
322 strcat(szArg,"ICONFILE=");
323 strcat(szArg,Icon);
324 }
325
326 if ((id != NULL) && (strlen(id) != 0))
327 {
328 strcat(szArg,";OBJECTID=");
329 strcat(szArg,id);
330 }
331
332 if ((setup != NULL) && (strlen(setup) != 0))
333 {
334 strcat(szArg,";");
335 strcat(szArg,setup);
336 }
337
338 WinCreateObject("WPFolder",Title,szArg,dest,CO_REPLACEIFEXISTS);
339 #elif defined(WIN32)
340 char startpath[MAX_PATH];
341 LPITEMIDLIST pidl;
342
343 if(!SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidl))
344 {
345 SHGetPathFromIDList(pidl, startpath);
346
347 if(startpath[strlen(startpath)-1] != '\\')
348 strcat(startpath, "\\");
349 strcat(startpath, Title);
350 CreateDirectory(startpath, NULL);
351 }
352 #else
353 /* Unix? */
354 #endif
355 }
356
357 #ifdef WIN32
358 HRESULT CreateLink(LPCSTR lpszPathObj,
359 LPSTR lpszPathLink, LPSTR lpszDesc)
360 {
361 HRESULT hres;
362 IShellLink* psl;
363
364 // Get a pointer to the IShellLink interface.
365 hres = CoCreateInstance(CLSID_ShellLink, NULL,
366 CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
367 if (SUCCEEDED(hres)) {
368 IPersistFile* ppf;
369
370 // Set the path to the shortcut target, and add the
371 // description.
372 psl->SetPath(lpszPathObj);
373
374 psl->SetDescription(lpszDesc);
375
376 // Query IShellLink for the IPersistFile interface for saving the
377 // shortcut in persistent storage.
378 hres = psl->QueryInterface(IID_IPersistFile,
379 (void **)&ppf);
380
381 if (SUCCEEDED(hres)) {
382 WCHAR wsz[MAX_PATH];
383
384 // Ensure that the string is ANSI.
385 MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,
386 wsz, MAX_PATH);
387
388
389 // Save the link by calling IPersistFile::Save.
390 hres = ppf->Save(wsz, TRUE);
391 ppf->Release();
392 }
393 psl->Release();
394 }
395 return hres;
396 }
397 #endif
398
399 /*
400 * Makes a Program object on the desktop.
401 */
402 void MakeProgram(char Title[], char Program[], char Icon[], char dest[], char id[], char setup[])
403 {
404 #ifdef __OS2__
405 char szArg[200];
406
407 memset(szArg,0,sizeof(szArg));
408
409 strcat(szArg,"EXENAME=");
410 strcat(szArg,Program);
411
412 if ((Icon != NULL) && (strlen(Icon) != 0))
413 {
414 strcat(szArg,";ICONFILE=");
415 strcat(szArg,Icon);
416 }
417
418 if ((id != NULL) && (strlen(id) != 0))
419 {
420 strcat(szArg,";OBJECTID=");
421 strcat(szArg,id);
422 }
423
424 if ((setup != NULL) && (strlen(setup) != 0))
425 {
426 strcat(szArg,";");
427 strcat(szArg,setup);
428 }
429
430 WinCreateObject("WPProgram",Title,szArg,dest,CO_REPLACEIFEXISTS);
431 #elif defined(WIN32)
432 char startpath[MAX_PATH];
433 LPITEMIDLIST pidl;
434
435 if(!SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidl))
436 {
437 SHGetPathFromIDList(pidl, startpath);
438
439 if(startpath[strlen(startpath)-1] != '\\')
440 strcat(startpath, "\\");
441 strcat(startpath, dest);
442 strcat(startpath, "\\");
443 strcat(startpath, Title);
444 strcat(startpath, ".lnk");
445
446 CoInitialize(NULL);
447 CreateLink(Program, startpath, Title);
448 CoUninitialize();
449 }
450
451
452 #else
453 /* Unix? */
454 #endif
455 }
456 /*
457 * Makes a user defined object on the desktop.
458 */
459 void MakeObject(char Title[], char oclass[], char dest[], char id[], char setup[])
460 {
461 #ifdef __OS2__
462 char szArg[200];
463
464 memset(szArg,0,sizeof(szArg));
465
466 if ((oclass == NULL) || (strlen(oclass) == 0))
467 return;
468
469 if ((id != NULL) && (strlen(id) != 0))
470 {
471 strcat(szArg,"OBJECTID=");
472 strcat(szArg,id);
473 }
474
475 if ((setup != NULL) && (strlen(setup) != 0))
476 {
477 if ((id != NULL) && (strlen(id) != 0))
478 strcat(szArg,";");
479 strcat(szArg,setup);
480 }
481
482 WinCreateObject(oclass,Title,szArg,dest,CO_REPLACEIFEXISTS);
483 #elif defined(WIN32)
484 /* Not sure if there is an equivilent on Windows */
485 #else
486 /* Unix? */
487 #endif
488 }
489 /*
490 * Makes a shadow on the desktop.
491 */
492 void MakeShadow(char Title[], char reference[], char dest[], char id[])
493 {
494 #ifdef __OS2__
495 char szArg[400];
496
497 memset(szArg,0,sizeof(szArg));
498
499 strcpy(szArg,"SHADOWID=");
500 strcat(szArg,reference);
501 if ((id != NULL) && (strlen(id) != 0))
502 {
503 strcat(szArg,";OBJECTID=");
504 strcat(szArg,id);
505 }
506 strcat(szArg,";");
507 WinCreateObject("WPShadow",Title,szArg,dest,CO_REPLACEIFEXISTS);
508 #elif defined(WIN32)
509 /* Nothing like this on Windows9x anyway */
510 #else
511 /* Unix? */
512 #endif
513 }
514
515 /* This creates program objects on the desktop, it was originally designed
516 * for the OS/2 Workplace Shell so it may be somewhat different in use on
517 * other platforms.
518 */
519 void create_wps_objects(void)
520 {
521 char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
522 char temp[5000];
523 char zerotext[2] = "";
524 int z, argn, len;
525
526 /* No distinction for the moment... this may change.. */
527 strcpy(installdir2, installdir);
528
529 /* Create Folder Objects */
530 if(strlen(INSTALLER_FOLDER)>0)
531 {
532 strcpy(temp, replaceem(INSTALLER_FOLDER));
533 argn=0;
534 arg1=&temp[0];
535 arg2=arg3=arg4=arg5=&zerotext[0];
536 len = strlen(temp);
537 for(z=0;z<len;z++)
538 {
539 if(temp[z]==',')
540 {
541 argn++;
542 temp[z]=0;
543 switch(argn)
544 {
545 case 1:
546 arg2=&temp[z+1];
547 break;
548 case 2:
549 arg3=&temp[z+1];
550 break;
551 case 3:
552 arg4=&temp[z+1];
553 break;
554 case 4:
555 arg5=&temp[z+1];
556 break;
557 case 5:
558 argn=0;
559 MakeFolder(arg1, arg2, arg3, arg4, arg5);
560 #ifdef ENABLE_LOGGING
561 fprintf(logfile, "<WPSFolderAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
562 #endif
563 arg1=&temp[z+1];
564 arg2=arg3=arg4=arg5=&zerotext[0];
565 break;
566 }
567 }
568 }
569 MakeFolder(arg1, arg2, arg3, arg4, arg5);
570 #ifdef ENABLE_LOGGING
571 fprintf(logfile, "<WPSFolderAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
572 #endif
573 }
574
575 /* Create Program Objects */
576 if(strlen(INSTALLER_PROGRAM)>0)
577 {
578 strcpy(temp, replaceem(INSTALLER_PROGRAM));
579 argn=0;
580 arg1=&temp[0];
581 arg2=arg3=arg4=arg5=arg6=&zerotext[0];
582 len = strlen(temp);
583 for(z=0;z<len;z++)
584 {
585 if(temp[z]==',')
586 {
587 argn++;
588 temp[z]=0;
589 switch(argn)
590 {
591 case 1:
592 arg2=&temp[z+1];
593 break;
594 case 2:
595 arg3=&temp[z+1];
596 break;
597 case 3:
598 arg4=&temp[z+1];
599 break;
600 case 4:
601 arg5=&temp[z+1];
602 break;
603 case 5:
604 arg6=&temp[z+1];
605 break;
606 case 6:
607 argn=0;
608 MakeProgram(arg1, arg2, arg3, arg4, arg5, arg6);
609 #ifdef ENABLE_LOGGING
610 fprintf(logfile, "<WPSProgramAdd>,%s,%s,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4,arg5,arg6);
611 #endif
612 arg1=&temp[z+1];
613 arg2=arg3=arg4=arg5=arg6=&zerotext[0];
614 break;
615 }
616 }
617 }
618 MakeProgram(arg1, arg2, arg3, arg4, arg5, arg6);
619 #ifdef ENABLE_LOGGING
620 fprintf(logfile, "<WPSProgramAdd>,%s,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5,arg6);
621 #endif
622 }
623
624 /* Create Shadow Objects */
625 if(strlen(INSTALLER_SHADOW)>0)
626 {
627 strcpy(temp, replaceem(INSTALLER_SHADOW));
628 argn=0;
629 arg1=&temp[0];
630 arg2=arg3=arg4=&zerotext[0];
631 len = strlen(temp);
632 for(z=0;z<len;z++)
633 {
634 if(temp[z]==',')
635 {
636 argn++;
637 temp[z]=0;
638 switch(argn)
639 {
640 case 1:
641 arg2=&temp[z+1];
642 break;
643 case 2:
644 arg3=&temp[z+1];
645 break;
646 case 3:
647 arg4=&temp[z+1];
648 break;
649 case 4:
650 argn=0;
651 MakeShadow(arg1, arg2, arg3, arg4);
652 #ifdef ENABLE_LOGGING
653 fprintf(logfile, "<WPSShadowAdd>,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4);
654 #endif
655 arg1=&temp[z+1];
656 arg2=arg3=arg4=&zerotext[0];
657 break;
658 }
659 }
660 }
661 MakeShadow(arg1, arg2, arg3, arg4);
662 #ifdef ENABLE_LOGGING
663 fprintf(logfile, "<WPSShadowAdd>,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4);
664 #endif
665 }
666
667 /* Create Generic Objects */
668 if(strlen(INSTALLER_OBJECT)>0)
669 {
670 strcpy(temp, replaceem(INSTALLER_OBJECT));
671 argn=0;
672 arg1=&temp[0];
673 arg2=arg3=arg4=arg5=&zerotext[0];
674 len = strlen(temp);
675 for(z=0;z<len;z++)
676 {
677 if(temp[z]==',')
678 {
679 argn++;
680 temp[z]=0;
681 switch(argn)
682 {
683 case 1:
684 arg2=&temp[z+1];
685 break;
686 case 2:
687 arg3=&temp[z+1];
688 break;
689 case 3:
690 arg4=&temp[z+1];
691 break;
692 case 4:
693 arg5=&temp[z+1];
694 break;
695 case 5:
696 argn=0;
697 MakeObject(arg1, arg2, arg3, arg4, arg5);
698 #ifdef ENABLE_LOGGING
699 fprintf(logfile, "<WPSObjectAdd>,%s,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4,arg5);
700 #endif
701 arg1=&temp[z+1];
702 arg2=arg3=arg4=arg5=&zerotext[0];
703 break;
704 }
705 }
706 }
707 MakeObject(arg1, arg2, arg3, arg4, arg5);
708 #ifdef ENABLE_LOGGING
709 fprintf(logfile, "<WPSObjectAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
710 #endif
711 }
712 }
713
714
715 #ifdef __cplusplus
716 }
717 #endif