]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/Install/instsup.cpp
merged 2.2 branch
[wxWidgets.git] / utils / Install / instsup.cpp
diff --git a/utils/Install/instsup.cpp b/utils/Install/instsup.cpp
new file mode 100644 (file)
index 0000000..c076769
--- /dev/null
@@ -0,0 +1,717 @@
+/*
+ *  instsup.c (c) 1999,2000 Brian Smith
+ */
+
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <fcntl.h>
+#if defined(__OS2__) || defined(__EMX__) || defined(WIN32) || defined(WINNT)
+#include <process.h>
+#endif
+#include <sys/types.h>
+#ifdef WIN32
+#include <shlobj.h>
+#endif
+#include "install.h"
+#include "instsup.h"
+
+extern char *INSTALLER_TITLE;
+extern char *INSTALLER_PROGRAM;
+extern char *INSTALLER_FOLDER;
+extern char *INSTALLER_SHADOW;
+extern char *INSTALLER_OBJECT;
+extern char tempPath[], installdir[], csfile[], bufile[], bootdrive[], instlog[], installdir2[];
+extern int installstate, success;
+
+extern FILE *self;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *replaceem(char *orig);
+
+int sendmessage(int destination, int messid)
+{
+#if 0
+       /* Update percentage bar */
+       if(messid == 1)
+       {
+               wxMutexGuiEnter();
+
+               updatepercent();
+
+               wxMutexGuiLeave();
+       }
+       if(messid == 2)
+       {
+               extern wxCondition *InstCond;
+
+               InstCond->Broadcast();
+       }
+
+#endif
+       return 0;
+}
+
+void DoGUI(void)
+{
+       updatepercent();
+       wxYield();
+}
+/* This should return the current color depth */
+unsigned long color_depth(void)
+{
+#if __OS2__
+       HDC hdc = WinOpenWindowDC(HWND_DESKTOP);
+       LONG colors;
+
+       DevQueryCaps(hdc, CAPS_COLORS, 1, &colors);
+       DevCloseDC(hdc);
+       return colors;
+#endif
+       return 0;
+}
+
+/*
+ * Call the reboot vector.
+ */
+void sysreboot(void)
+{
+#if __OS2__
+#define SYSFUNC               0xD5
+#define REBOOT                0xAB
+#define REBOOTDEV             "\\DEV\\DOS$"
+
+       APIRET rc;
+       HFILE  hREBOOT;
+       ULONG  ulAction;
+
+       rc = DosOpen(REBOOTDEV,
+                                &hREBOOT,
+                                &ulAction,
+                                0L,
+                                FILE_NORMAL,
+                                FILE_OPEN,
+                                OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
+                                0L);
+       if (rc == 0)
+       {
+               DosDevIOCtl(hREBOOT,
+                                       SYSFUNC,
+                                       REBOOT,
+                                       NULL,
+                                       0L,
+                                       NULL,
+                                       NULL,
+                                       0L,
+                                       NULL);
+               DosClose(hREBOOT);
+       }
+#endif
+}
+
+/*
+ * Display an informational dialog box to the user with the given text.
+ */
+int mesg(char *format, ...) {
+       va_list args;
+       char outbuf[4096];
+
+       va_start(args, format);
+       vsprintf(outbuf, format, args);
+       va_end(args);
+
+       wxMessageBox(outbuf, INSTALLER_TITLE,
+                                wxOK | wxICON_EXCLAMATION, NULL);
+
+       return strlen(outbuf);
+}
+
+int checktext(char *text, char *buffer, int buflen)
+{
+       int z, len = strlen(text);
+
+       for(z=0;z<(buflen-len);z++)
+       {
+               if(memcmp(text, &buffer[z], len) == 0)
+                       return z;
+       }
+       return -1;
+
+}
+
+/*
+ * Returns the offset withing the executable to the specified text.
+ */
+long findtext(char *text)
+{
+       char buffer[512];
+       int offset;
+       unsigned long curpos = 0;
+
+       fseek(self, 0, SEEK_SET);
+       fread(buffer, 1, 512, self);
+       if((offset = checktext(text, buffer, 512)) > -1)
+               return offset;
+       while(!feof(self))
+       {
+               memcpy(buffer, &buffer[256], 256);
+               fread(&buffer[256], 1, 256, self);
+               curpos += 256;
+               if((offset = checktext(text, buffer, 512)) > -1)
+                       return offset+curpos;
+
+       }
+       return -1;
+}
+
+/* We encode archive search text so we don't get confused
+ * by the string table - I was using LXLite to take care
+ * of this problem on OS/2 but in portable code this may
+ * not be an option. */
+char *decode(char *input)
+{
+       char    *result;
+       int     i = 0;
+
+       result = (char *)malloc(strlen(input) / 2 + 1);
+
+       while (input[0] && input[1])
+       {
+               result[i] = ((input[0] - 0x41) << 4) | (input[1] - 0x41);
+               input += 2;
+               i++;
+       }
+       result[i] = '\0';
+
+       return result;
+}
+
+/*
+ * Removes any carriage returns or line feeds from the buffer.
+ */
+void stripcrlf(char *buffer)
+{
+       int z, len = strlen(buffer);
+
+       for(z=0;z<len;z++)
+       {
+               if(buffer[z] == '\r' || buffer[z] == '\n')
+               {
+                       buffer[z] = 0;
+                       return;
+               }
+       }
+}
+
+/*
+ * Returns the space free on a given drive... where 0 is A: in MB
+ */
+unsigned long drivefree(int drive)
+{
+#if __OS2__
+       ULONG   aulFSInfoBuf[40] = {0};
+       APIRET  rc               = NO_ERROR;
+       double  bytesFree;
+
+       DosError(FERR_DISABLEHARDERR);
+       rc = DosQueryFSInfo(drive,
+                                               FSIL_ALLOC,
+                                               (PVOID)aulFSInfoBuf,
+                                               sizeof(aulFSInfoBuf));
+
+       DosError(FERR_ENABLEHARDERR);
+       if (rc != NO_ERROR)
+               return 0;
+
+       bytesFree = (double)aulFSInfoBuf[3] * (double)aulFSInfoBuf[1] * (USHORT)aulFSInfoBuf[4];
+       return (unsigned long)(bytesFree / (1024.0 * 1024.0));
+#endif
+       return 0;
+}
+
+
+/*
+ * Display a fatal error message and set the abort flag in case we are in a secondary thread.
+ */
+void error(char *format, ...) {
+       va_list args;
+       char errstring[1024];
+
+       va_start(args, format);
+       vsprintf(errstring, format, args);
+       va_end(args);
+
+       if(installstate != ABORTED)
+       {
+               success=1;
+               installstate=ABORTED;
+       }
+       wxMessageBox(errstring, INSTALLER_TITLE,
+                       wxOK | wxICON_EXCLAMATION, NULL);
+}
+
+void setdrivedir(char *drivedir)
+{
+       wxSetWorkingDirectory(drivedir);
+}
+
+/*
+ * Make the TEMP directory the current directory, or the root directory of the boot drive.
+ */
+void settempdir(void)
+{
+#if defined(__EMX__) || defined(__OS2__) || defined(WIN32) || defined(WINNT)
+    /* Windows or OS/2 */
+       char *envdir = getenv("TMP");
+       int len;
+
+       if (!envdir)
+               envdir = getenv("TEMP");
+       if (!envdir)
+               envdir = replaceem("%BOOTDRIVE%:\\");
+       strcpy(tempPath,envdir);
+       len = strlen(tempPath);
+       if (len > 3 && tempPath[len-1] == '\\')
+               tempPath[len-1] = 0;
+       strupr(tempPath);
+       setdrivedir(tempPath);
+#else
+    /* Unix */
+       setdrivedir("/tmp");
+#endif
+}
+
+void getbootdrive(void)
+{
+       /* On windows I don't think you can boot from anything
+          except C: drive.  So I am not going to do anything here. */
+}
+
+void PM_backslash(char *s)
+{
+       unsigned int pos = strlen(s);
+       if (s[pos-1] != '\\') {
+               s[pos] = '\\';
+               s[pos+1] = '\0';
+       }
+}
+
+/*
+ * Makes a folder on the desktop.
+ */
+void MakeFolder(char Title[], char Icon[], char dest[], char id[], char setup[])
+{
+#ifdef __OS2__
+       char szArg[200];
+
+       memset(szArg,0,sizeof(szArg));
+
+       if ((Icon != NULL) && (strlen(Icon) != 0))
+       {
+               strcat(szArg,"ICONFILE=");
+               strcat(szArg,Icon);
+       }
+
+       if ((id != NULL) && (strlen(id) != 0))
+       {
+               strcat(szArg,";OBJECTID=");
+               strcat(szArg,id);
+       }
+
+       if ((setup != NULL) && (strlen(setup) != 0))
+       {
+               strcat(szArg,";");
+               strcat(szArg,setup);
+       }
+
+       WinCreateObject("WPFolder",Title,szArg,dest,CO_REPLACEIFEXISTS);
+#elif defined(WIN32)
+       char startpath[MAX_PATH];
+       LPITEMIDLIST  pidl;
+
+       if(!SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidl))
+       {
+               SHGetPathFromIDList(pidl, startpath);
+
+               if(startpath[strlen(startpath)-1] != '\\')
+                       strcat(startpath, "\\");
+               strcat(startpath, Title);
+               CreateDirectory(startpath, NULL);
+       }
+#else
+    /* Unix? */
+#endif
+}
+
+#ifdef WIN32
+HRESULT CreateLink(LPCSTR lpszPathObj, 
+    LPSTR lpszPathLink, LPSTR lpszDesc) 
+{ 
+       HRESULT hres;
+       IShellLink* psl;
+
+       // Get a pointer to the IShellLink interface.
+       hres = CoCreateInstance(CLSID_ShellLink, NULL,
+                                                       CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+       if (SUCCEEDED(hres)) {
+               IPersistFile* ppf;
+
+               // Set the path to the shortcut target, and add the
+               // description.
+               psl->SetPath(lpszPathObj);
+
+        psl->SetDescription(lpszDesc);
+       // Query IShellLink for the IPersistFile interface for saving the 
+       // shortcut in persistent storage. 
+        hres = psl->QueryInterface(IID_IPersistFile,
+            (void **)&ppf);
+        if (SUCCEEDED(hres)) { 
+            WCHAR wsz[MAX_PATH];
+            // Ensure that the string is ANSI. 
+            MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, 
+                wsz, MAX_PATH); 
+
+            // Save the link by calling IPersistFile::Save. 
+            hres = ppf->Save(wsz, TRUE);
+            ppf->Release();
+        } 
+        psl->Release();
+    } 
+    return hres; 
+}
+#endif
+
+/*
+ * Makes a Program object on the desktop.
+ */
+void MakeProgram(char Title[], char Program[], char Icon[], char dest[], char id[], char setup[])
+{
+#ifdef __OS2__
+       char szArg[200];
+
+       memset(szArg,0,sizeof(szArg));
+
+       strcat(szArg,"EXENAME=");
+       strcat(szArg,Program);
+
+       if ((Icon != NULL) && (strlen(Icon) != 0))
+       {
+               strcat(szArg,";ICONFILE=");
+               strcat(szArg,Icon);
+       }
+
+       if ((id != NULL) && (strlen(id) != 0))
+       {
+               strcat(szArg,";OBJECTID=");
+               strcat(szArg,id);
+       }
+
+       if ((setup != NULL) && (strlen(setup) != 0))
+       {
+               strcat(szArg,";");
+               strcat(szArg,setup);
+       }
+
+       WinCreateObject("WPProgram",Title,szArg,dest,CO_REPLACEIFEXISTS);
+#elif defined(WIN32)
+       char startpath[MAX_PATH];
+       LPITEMIDLIST  pidl;
+
+       if(!SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidl))
+       {
+               SHGetPathFromIDList(pidl, startpath);
+
+               if(startpath[strlen(startpath)-1] != '\\')
+                       strcat(startpath, "\\");
+               strcat(startpath, dest);
+               strcat(startpath, "\\");
+               strcat(startpath, Title);
+               strcat(startpath, ".lnk");
+
+               CoInitialize(NULL);
+               CreateLink(Program, startpath, Title);
+               CoUninitialize();
+       }
+
+
+#else
+       /* Unix? */
+#endif
+}
+/*
+ * Makes a user defined object on the desktop.
+ */
+void MakeObject(char Title[], char oclass[], char dest[], char id[], char setup[])
+{
+#ifdef __OS2__
+       char szArg[200];
+
+       memset(szArg,0,sizeof(szArg));
+
+       if ((oclass == NULL) || (strlen(oclass) == 0))
+               return;
+
+       if ((id != NULL) && (strlen(id) != 0))
+       {
+               strcat(szArg,"OBJECTID=");
+               strcat(szArg,id);
+       }
+
+       if ((setup != NULL) && (strlen(setup) != 0))
+       {
+               if ((id != NULL) && (strlen(id) != 0))
+                       strcat(szArg,";");
+               strcat(szArg,setup);
+       }
+
+       WinCreateObject(oclass,Title,szArg,dest,CO_REPLACEIFEXISTS);
+#elif defined(WIN32)
+    /* Not sure if there is an equivilent on Windows */
+#else
+       /* Unix? */
+#endif
+}
+/*
+ * Makes a shadow on the desktop.
+ */
+void MakeShadow(char Title[], char reference[], char dest[], char id[])
+{
+#ifdef __OS2__
+       char szArg[400];
+
+       memset(szArg,0,sizeof(szArg));
+
+       strcpy(szArg,"SHADOWID=");
+       strcat(szArg,reference);
+       if ((id != NULL) && (strlen(id) != 0))
+       {
+               strcat(szArg,";OBJECTID=");
+               strcat(szArg,id);
+       }
+    strcat(szArg,";");
+       WinCreateObject("WPShadow",Title,szArg,dest,CO_REPLACEIFEXISTS);
+#elif defined(WIN32)
+    /* Nothing like this on Windows9x anyway */
+#else
+       /* Unix? */
+#endif
+}
+
+/* This creates program objects on the desktop, it was originally designed
+ * for the OS/2 Workplace Shell so it may be somewhat different in use on
+ * other platforms.
+ */
+void create_wps_objects(void)
+{
+       char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
+       char temp[5000];
+       char zerotext[2] = "";
+       int z, argn, len;
+
+    /* No distinction for the moment... this may change.. */
+       strcpy(installdir2, installdir);
+
+       /* Create Folder Objects */
+       if(strlen(INSTALLER_FOLDER)>0)
+       {
+               strcpy(temp, replaceem(INSTALLER_FOLDER));
+               argn=0;
+               arg1=&temp[0];
+               arg2=arg3=arg4=arg5=&zerotext[0];
+        len = strlen(temp);
+               for(z=0;z<len;z++)
+               {
+                       if(temp[z]==',')
+                       {
+                               argn++;
+                               temp[z]=0;
+                               switch(argn)
+                               {
+                               case 1:
+                                       arg2=&temp[z+1];
+                                       break;
+                               case 2:
+                                       arg3=&temp[z+1];
+                                       break;
+                               case 3:
+                                       arg4=&temp[z+1];
+                                       break;
+                               case 4:
+                                       arg5=&temp[z+1];
+                                       break;
+                               case 5:
+                                       argn=0;
+                                       MakeFolder(arg1, arg2, arg3, arg4, arg5);
+#ifdef ENABLE_LOGGING
+                                       fprintf(logfile, "<WPSFolderAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
+#endif
+                                       arg1=&temp[z+1];
+                                       arg2=arg3=arg4=arg5=&zerotext[0];
+                                       break;
+                               }
+                       }
+               }
+               MakeFolder(arg1, arg2, arg3, arg4, arg5);
+#ifdef ENABLE_LOGGING
+               fprintf(logfile, "<WPSFolderAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
+#endif
+       }
+
+       /* Create Program Objects */
+       if(strlen(INSTALLER_PROGRAM)>0)
+       {
+               strcpy(temp, replaceem(INSTALLER_PROGRAM));
+               argn=0;
+               arg1=&temp[0];
+               arg2=arg3=arg4=arg5=arg6=&zerotext[0];
+        len = strlen(temp);
+               for(z=0;z<len;z++)
+               {
+                       if(temp[z]==',')
+                       {
+                               argn++;
+                               temp[z]=0;
+                               switch(argn)
+                               {
+                               case 1:
+                                       arg2=&temp[z+1];
+                                       break;
+                               case 2:
+                                       arg3=&temp[z+1];
+                                       break;
+                               case 3:
+                                       arg4=&temp[z+1];
+                                       break;
+                               case 4:
+                                       arg5=&temp[z+1];
+                                       break;
+                               case 5:
+                                       arg6=&temp[z+1];
+                                       break;
+                               case 6:
+                                       argn=0;
+                                       MakeProgram(arg1, arg2, arg3, arg4, arg5, arg6);
+#ifdef ENABLE_LOGGING
+                                       fprintf(logfile, "<WPSProgramAdd>,%s,%s,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4,arg5,arg6);
+#endif
+                                       arg1=&temp[z+1];
+                                       arg2=arg3=arg4=arg5=arg6=&zerotext[0];
+                                       break;
+                               }
+                       }
+               }
+               MakeProgram(arg1, arg2, arg3, arg4, arg5, arg6);
+#ifdef ENABLE_LOGGING
+               fprintf(logfile, "<WPSProgramAdd>,%s,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5,arg6);
+#endif
+       }
+
+       /* Create Shadow Objects */
+       if(strlen(INSTALLER_SHADOW)>0)
+       {
+               strcpy(temp, replaceem(INSTALLER_SHADOW));
+               argn=0;
+               arg1=&temp[0];
+               arg2=arg3=arg4=&zerotext[0];
+        len = strlen(temp);
+               for(z=0;z<len;z++)
+               {
+                       if(temp[z]==',')
+                       {
+                               argn++;
+                               temp[z]=0;
+                               switch(argn)
+                               {
+                               case 1:
+                                       arg2=&temp[z+1];
+                                       break;
+                               case 2:
+                                       arg3=&temp[z+1];
+                                       break;
+                               case 3:
+                                       arg4=&temp[z+1];
+                                       break;
+                               case 4:
+                                       argn=0;
+                                       MakeShadow(arg1, arg2, arg3, arg4);
+#ifdef ENABLE_LOGGING
+                                       fprintf(logfile, "<WPSShadowAdd>,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4);
+#endif
+                                       arg1=&temp[z+1];
+                                       arg2=arg3=arg4=&zerotext[0];
+                                       break;
+                               }
+                       }
+               }
+               MakeShadow(arg1, arg2, arg3, arg4);
+#ifdef ENABLE_LOGGING
+               fprintf(logfile, "<WPSShadowAdd>,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4);
+#endif
+       }
+
+       /* Create Generic Objects */
+       if(strlen(INSTALLER_OBJECT)>0)
+       {
+               strcpy(temp, replaceem(INSTALLER_OBJECT));
+               argn=0;
+               arg1=&temp[0];
+               arg2=arg3=arg4=arg5=&zerotext[0];
+        len = strlen(temp);
+               for(z=0;z<len;z++)
+               {
+                       if(temp[z]==',')
+                       {
+                               argn++;
+                               temp[z]=0;
+                               switch(argn)
+                               {
+                               case 1:
+                                       arg2=&temp[z+1];
+                                       break;
+                               case 2:
+                                       arg3=&temp[z+1];
+                                       break;
+                               case 3:
+                                       arg4=&temp[z+1];
+                                       break;
+                               case 4:
+                                       arg5=&temp[z+1];
+                                       break;
+                               case 5:
+                                       argn=0;
+                                       MakeObject(arg1, arg2, arg3, arg4, arg5);
+#ifdef ENABLE_LOGGING
+                                       fprintf(logfile, "<WPSObjectAdd>,%s,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4,arg5);
+#endif
+                                       arg1=&temp[z+1];
+                                       arg2=arg3=arg4=arg5=&zerotext[0];
+                                       break;
+                               }
+                       }
+               }
+               MakeObject(arg1, arg2, arg3, arg4, arg5);
+#ifdef ENABLE_LOGGING
+               fprintf(logfile, "<WPSObjectAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
+#endif
+       }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file