wxWidgets/utils/Install/instsup.cpp
Bryan Petty f6bcfd974e merged 2.2 branch
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2000-07-15 19:51:35 +00:00

717 lines
14 KiB
C++

/*
* 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