/* * instsup.c (c) 1999,2000 Brian Smith */ #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include #include #include #include #include #include #if defined(__OS2__) || defined(__EMX__) || defined(WIN32) || defined(WINNT) #include #endif #include #ifdef WIN32 #include #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 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,%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, ",%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,%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, ",%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,%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, ",%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,%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, ",%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5); #endif } } #ifdef __cplusplus } #endif