]> git.saurik.com Git - wxWidgets.git/blame_incremental - utils/Install/instsup.cpp
Added possibility of 2-step initialisation, and wxWIZARD_EX_HELPBUTTON style.
[wxWidgets.git] / utils / Install / instsup.cpp
... / ...
CommitLineData
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
27extern char *INSTALLER_TITLE;
28extern char *INSTALLER_PROGRAM;
29extern char *INSTALLER_FOLDER;
30extern char *INSTALLER_SHADOW;
31extern char *INSTALLER_OBJECT;
32extern char tempPath[], installdir[], csfile[], bufile[], bootdrive[], instlog[], installdir2[];
33extern int installstate, success;
34
35extern FILE *self;
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41char *replaceem(char *orig);
42
43int 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
66void DoGUI(void)
67{
68 updatepercent();
69 wxYield();
70}
71/* This should return the current color depth */
72unsigned 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 */
88void 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 */
126int 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
140int 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 */
156long 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. */
182char *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 */
203void 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 */
220unsigned 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 */
247void 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
264void 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 */
272void 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
295void 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
301void 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 */
313void 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
358HRESULT 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 */
402void 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 */
459void 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 */
492void 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 */
519void 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