Mercurial > install
view uninst/uninst.c @ 0:879c2819a48d
Initial commit.
author | Brian Smith <brian@dbsoft.org> |
---|---|
date | Fri, 18 Feb 2011 08:45:38 -0600 |
parents | |
children | 821abb186ec1 |
line wrap: on
line source
/* $Id: uninst.c,v 1.24 2003/05/10 09:18:10 bsmith Exp $ */ /* * uninst.c (c) 2002-2003 Brian Smith */ #ifdef __UNIX__ #include "config.h" #endif #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <stdarg.h> #include <fcntl.h> #ifndef __UNIX__ #include <process.h> #endif #include <sys/types.h> #include <sys/stat.h> #include "dw.h" #include "compat.h" #include <string.h> #ifndef __UNIX__ #define strcasecmp stricmp #endif #ifdef __OS2__ #include <direct.h> #include <ctype.h> #endif /* I know I am being excessive but... better safe than sorry ;) */ char *configsys[8196]; int configfilecount=-1; /* Config.Sys -- Note the drive letter gets replaced with the boot drive letter It is just a place holder. (For the next 3 entries) */ char csfile[] = "C:\\CONFIG.SYS"; /* Backup Config.Sys filename */ char bufile[] = "C:\\CONFIG.NST"; /* Installation Log Database -- Used for uninstallation and aborting */ #ifdef __WIN32__ char instlog[MAX_PATH+1] = "C:\\DBINST.LOG"; #elif defined(__OS2__) char instlog[] = "C:\\OS2\\INSTALL\\DBINST.LOG"; #else char instlog[] = "/var/log/dbinst"; #endif char installdir[_MAX_PATH]; char bootdrive[2] = "C"; char empty_string[] = ""; char currentcf[_MAX_PATH] = ""; char *INSTALLER_APPLICATION, *INSTALLER_VERSION; HWND mainwindow, mainbox, slider, stext, bigbox, logo, custombox, groupbox, buttonbox, status, exitbutton, nextbutton, blanktext; #ifdef __OS2__ #define UNINSTALL_SCRIPT "uninstal.cmd" #elif defined(__WIN32__) #define UNINSTALL_SCRIPT "uninstal.bat" #else #define UNINSTALL_SCRIPT "Uninstall.sh" #endif /* Undocumented functions */ #if defined(__OS2__) || defined(__EMX__) APIRET APIENTRY DosReplaceModule(PSZ pszOldModule,PSZ pszNewModule,PSZ pszBackupModule); #endif /* * Removes a folder on the desktop. */ void RemoveFolder(char Title[], char *Icon, char *dest, char *id, char *setup, char *platform) { #ifdef __OS2__ if(id) { HOBJECT ho = WinQueryObject(id); if(ho != NULLHANDLE) WinDestroyObject(ho); } #elif defined(__WIN32__) if(platform && *platform) { int res; res = rmdir(platform); if(res == -1) MoveFileEx(platform, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } #else /* Unix? */ #endif } /* * Makes a Program object on the desktop. */ void RemoveProgram(char *Title, char *Program, char *Icon, char *dest, char *id, char *setup, char *platform) { #ifdef __OS2__ if(id) { HOBJECT ho = WinQueryObject(id); if(ho != NULLHANDLE) WinDestroyObject(ho); } #elif defined(__WIN32__) if(platform && *platform) { int res; res = remove(platform); if(res == -1) MoveFileEx(platform, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } #else /* Unix? */ #endif } /* * Makes a user defined object on the desktop. */ void RemoveObject(char *Title, char *oclass, char *dest, char *id, char *setup, char *platform) { #ifdef __OS2__ if(id) { HOBJECT ho = WinQueryObject(id); if(ho != NULLHANDLE) WinDestroyObject(ho); } #elif defined(WIN32) /* Not sure if there is an equivilent on Windows */ #else /* Unix? */ #endif } /* * Makes a shadow on the desktop. */ void RemoveShadow(char *Title, char *reference, char *dest, char *id, char *platform) { #ifdef __OS2__ if(id) { HOBJECT ho = WinQueryObject(id); if(ho != NULLHANDLE) WinDestroyObject(ho); } #elif defined(WIN32) if(platform && *platform) { int res; res = remove(platform); if(res == -1) MoveFileEx(platform, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } #else /* Unix? */ #endif } void update_percent(int current, int total) { static int pixels = 0; ULONG sliderpos = 0; if(total && (pixels = dw_percent_query_range(slider))) { sliderpos = (int)(((float)current/(float)total)*pixels); dw_percent_set_pos(slider, sliderpos); } } /* * Read the generated log file and anything installed. */ void do_uninstall(void) { char tmpbuf[8196], *fileptr, **lines; FILE *tmplf; int linenum=0, found=-1, theend = 0, count = 0, z; if((tmplf=fopen(instlog, "rb"))==NULL) { dw_messagebox("Uninstall", DW_MB_OK | DW_MB_ERROR, "Could not open install log."); return; } while(!feof(tmplf)) { fgets(tmpbuf, 8196, tmplf); linenum++; if(tmpbuf[0]=='[' && (char *)strstr(tmpbuf, INSTALLER_APPLICATION) != NULL && !feof(tmplf)) { fgets(tmpbuf, 8196, tmplf); linenum++; if((char *)strstr(tmpbuf, "<Version>") != NULL && (char *)strstr(tmpbuf, INSTALLER_VERSION) != NULL) { found=linenum; theend = 0; } } if(found != -1 && !theend && ((char *)strstr(tmpbuf, "<End>") != NULL || tmpbuf[0] == '[')) theend=linenum; } if(found != -1) { if(!theend) theend = linenum; if(theend - found > 0) lines = calloc(theend - found, sizeof(char *)); else lines = calloc(8096, sizeof(char *)); rewind(tmplf); for (z=0;z<found;z++) fgets(tmpbuf, 8196, tmplf); while(!feof(tmplf) && count < (theend - found)) { tmpbuf[0] = 0; fgets(tmpbuf, 8196, tmplf); lines[count] = strdup(tmpbuf); count++; } fclose(tmplf); /* The first NewDir should be the installation directory */ for(z=0;z<count;z++) { if(lines[z]) { int res; fileptr = lines[z]; /* Remove trailing CRLFs */ if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n') fileptr[strlen(fileptr)-1]=0; if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n') fileptr[strlen(fileptr)-1]=0; if((char *)strstr(lines[z], "<NewDir>") != NULL) { char path[_MAX_PATH]; struct stat sb; fileptr = (char *)strchr(lines[z], ',')+1; #ifndef __UNIX__ if(fileptr[1] == ':') { char drive = toupper(fileptr[0]); _chdrive((drive - 'A')+1); } #endif chdir(fileptr); #ifdef __UNIX__ sprintf(path, "%s/%s", fileptr, UNINSTALL_SCRIPT); #else sprintf(path, "%s\\%s", fileptr, UNINSTALL_SCRIPT); #endif if(!stat(path, &sb)) system(path); z = count; } } } for(z=count-1;z>-1;z--) { if(lines[z]) { int res; fileptr = lines[z]; /* Remove trailing CRLFs */ if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n') fileptr[strlen(fileptr)-1]=0; if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n') fileptr[strlen(fileptr)-1]=0; if((char *)strstr(lines[z], "<FileInst>") != NULL) { fileptr = (char *)strchr(lines[z], ',')+1; #ifdef __OS2__ DosReplaceModule(fileptr,NULL,NULL); #endif res = remove(fileptr); #ifdef __WIN32__ if(res == -1) MoveFileEx(fileptr, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); #endif } if((char *)strstr(lines[z], "<NewDir>") != NULL) { fileptr = (char *)strchr(lines[z], ',')+1; res = rmdir(fileptr); #ifdef __WIN32__ if(res == -1) MoveFileEx(fileptr, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); #endif } if((char *)strstr(lines[z], "<WPSFolderAdd>") != NULL) { char *args[6], *ptr = lines[z]; int x; for(x=0;x<6;x++) { if(ptr) ptr = strstr(ptr, ","); if(ptr) { ptr[0] = 0; ptr = args[x] = &ptr[1]; } else args[x] = NULL; } RemoveFolder(args[0],args[1],args[2],args[3],args[4],args[5]); } if((char *)strstr(lines[z], "<WPSProgramAdd>") != NULL) { char *args[7], *ptr = lines[z]; int x; for(x=0;x<7;x++) { if(ptr) ptr = strstr(ptr, ","); if(ptr) { ptr[0] = 0; ptr = args[x] = &ptr[1]; } else args[x] = NULL; } RemoveProgram(args[0],args[1],args[2],args[3],args[4],args[5],args[6]); } if((char *)strstr(lines[z], "<WPSObjectAdd>") != NULL) { char *args[6], *ptr = lines[z]; int x; for(x=0;x<6;x++) { if(ptr) ptr = strstr(ptr, ","); if(ptr) { ptr[0] = 0; ptr = args[x] = &ptr[1]; } else args[x] = NULL; } RemoveObject(args[0],args[1],args[2],args[3],args[4],args[5]); } if((char *)strstr(lines[z], "<WPSShadowAdd>") != NULL) { char *args[5], *ptr = lines[z]; int x; for(x=0;x<5;x++) { if(ptr) ptr = strstr(ptr, ","); if(ptr) { ptr[0] = 0; ptr = args[x] = &ptr[1]; } else args[x] = NULL; } RemoveShadow(args[0],args[1],args[2],args[3],args[4]); } free(lines[z]); update_percent(count-z, count); } } free(lines); return; } else dw_messagebox("Uninstall", DW_MB_OK | DW_MB_ERROR, "Could not find section in install log."); fclose(tmplf); return; } /* * 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; } } } /* * Adds or replaces a SET variable based on the flags (CONFIG.SYS) */ #if 0 void updateset(char *setname, char *newvalue, int flag) { char *cmpbuf1, *cmpbuf2, *tmpptr, *tmpptr2, *nv; int i, z, t; nv=replaceem(newvalue); cmpbuf1=malloc(strlen(setname)+2); strcpy(cmpbuf1, setname); strcat(cmpbuf1, "="); for(i=0;i<configfilecount;i++) { if(strlen(cmpbuf1) <= strlen(configsys[i])) { tmpptr=(char *)strdup(configsys[i]); strupr(tmpptr); if((tmpptr2=(char*)strstr(tmpptr, "SET "))!=NULL) { tmpptr2 += 4; cmpbuf2=malloc(strlen(tmpptr2)+1); /* Remove any spaces from the string */ z=0; for (t=0;t<strlen(tmpptr2) && z < strlen(cmpbuf1);t++) { if(tmpptr2[t] != ' ') { cmpbuf2[z]=tmpptr2[t]; z++; } } cmpbuf2[z]=0; if(strcasecmp(cmpbuf1, cmpbuf2) == 0) { /* Ok we found the entry, and if UPDATE_ALWAYS change it to the new entry, otherwise exit */ if(flag == UPDATE_ALWAYS) { free(configsys[i]); configsys[i] = malloc(strlen(setname)+strlen(nv)+6); strcpy(configsys[i], "SET "); strcat(configsys[i], setname); strcat(configsys[i], "="); strcat(configsys[i], nv); free(cmpbuf1);free(cmpbuf2);free(tmpptr); } return; } free(cmpbuf2); } free(tmpptr); } } /* Couldn't find the line so we'll add it */ configsys[configfilecount]=malloc(strlen(cmpbuf1)+strlen(nv)+6); strcpy(configsys[configfilecount], "SET "); strcat(configsys[configfilecount], setname); strcat(configsys[configfilecount], "="); strcat(configsys[configfilecount], nv); configfilecount++; free(cmpbuf1); free(nv); } /* * Adds an entry to a system variable (CONFIG.SYS) */ void updatesys(char *sysname, char *newvalue) { char *cmpbuf1, *cmpbuf2, *tmpptr, *tmpptr2, *capbuf1, *capbuf2, *nv, *brian; int i, z, t; nv=replaceem(newvalue); cmpbuf1=malloc(strlen(sysname)+2); strcpy(cmpbuf1, sysname); strcat(cmpbuf1, "="); for(i=0;i<configfilecount;i++) { if(strlen(cmpbuf1) <= strlen(configsys[i])) { cmpbuf2=malloc(strlen(configsys[i])+1); /* Remove any spaces from the string */ z=0; for (t=0;t<strlen(configsys[i]) && z < strlen(cmpbuf1);t++) { if(configsys[i][t] != ' ') { cmpbuf2[z]=configsys[i][t]; z++; } } cmpbuf2[z]=0; if(strcasecmp(cmpbuf1, cmpbuf2) == 0) { /* Do a case insensitive comparison but preserve the case */ tmpptr = &configsys[i][t]; capbuf1=malloc(strlen(tmpptr)+1); capbuf2=malloc(strlen(nv)+1); strcpy(capbuf1, tmpptr); strcpy(capbuf2, nv); strupr(capbuf1); strupr(capbuf2); /* Ok, we found the line, and it doesn't have an entry so we'll add it */ if((tmpptr2=(char *)strstr(capbuf1, capbuf2)) == NULL) { brian = configsys[i]; configsys[i] = malloc(strlen(configsys[i])+strlen(nv)+4); strcpy(configsys[i], brian); free(brian); /* Remove any trailing CRLFs */ if(configsys[i][strlen(configsys[i])-1]!=';') strcat(configsys[i], ";"); strcat(configsys[i], nv); strcat(configsys[i], ";"); } free(cmpbuf1);free(cmpbuf2);free(capbuf1);free(capbuf2); return; } free(cmpbuf2); } } /* Couldn't find the line so we'll add it */ configsys[configfilecount]=malloc(strlen(cmpbuf1)+strlen(nv)+3); strcpy(configsys[configfilecount], cmpbuf1); strcat(configsys[configfilecount], nv); strcat(configsys[configfilecount], ";"); configfilecount++; free(cmpbuf1); free(nv); } #endif /* * Removes a line from a config file. */ void removeline(char *text) { int z; for(z=0;z<configfilecount;z++) { if(strcasecmp(configsys[z], text) == 0) { int t; free(configsys[z]); for(t=z;t<(configfilecount-1);t++) configsys[t] = configsys[t+1]; configfilecount--; } } } /* * Reads a line from a file and returns it in raw. */ void getline(FILE *f, char *raw) { memset(raw, 0, 256); fgets(raw, 255, f); stripcrlf(raw); } /* * Removes a character from a buffer by advancing the buffer to the left. */ void removechar(char *buffer, int thisone, int len) { int x; for(x=thisone;x<len;x++) buffer[x] = buffer[x+1]; } void getbootdrive(void) { #ifdef __OS2__ ULONG ulSysInfo; DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&ulSysInfo, sizeof(ULONG)); bootdrive[0]=installdir[0]=instlog[0]=csfile[0]=bufile[0]=(char)('A'+(ulSysInfo-1)); #elif defined(__WIN32__) char winpath[MAX_PATH+1] = ""; GetWindowsDirectory(winpath, MAX_PATH); if(winpath[0] && winpath[1] == ':') { bootdrive[0]=installdir[0]=csfile[0]=bufile[0]=winpath[0]; strcpy(instlog, winpath); if(instlog[strlen(instlog)-1] != '\\') strcat(instlog, "\\"); strcat(instlog, "DBINST.LOG"); } #endif } void remove_uninstall_object(void) { #ifdef __OS2__ char binpath[8096], *objectid = strdup(INSTALLER_APPLICATION); HOBJECT ho; int z; for(z=0;z<strlen(objectid);z++) { if(objectid[z] == ' ') objectid[z] = '_'; } sprintf(binpath, "<DBUNINST_%s>", objectid); ho = WinQueryObject(binpath); if(ho != NULLHANDLE) WinDestroyObject(ho); free(objectid); #elif defined( __WIN32__) char keyname[1024]; sprintf(keyname, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", INSTALLER_APPLICATION); if(RegDeleteKey(HKEY_LOCAL_MACHINE, keyname)) return; #endif } void actual_install(void *data) { getbootdrive(); do_uninstall(); remove_uninstall_object(); dw_messagebox("Uninstall", DW_MB_OK | DW_MB_INFORMATION, "Finished uninstalling."); dw_window_destroy(mainwindow); exit(0); } void DWSIGNAL start_callback(HWND window, void *data) { dw_window_disable(exitbutton); dw_window_disable(nextbutton); dw_thread_new((void *)actual_install, NULL, 10000); } void DWSIGNAL exit_callback(HWND window, void *data) { dw_window_destroy(mainwindow); exit(0); } void uninstall_dialog(void) { ULONG flStyle = DW_FCF_SYSMENU | DW_FCF_TITLEBAR | DW_FCF_SHELLPOSITION | DW_FCF_TASKLIST | DW_FCF_DLGBORDER; char text[1024]; mainwindow = dw_window_new(HWND_DESKTOP, "Uninstall", flStyle); /* This number must corespond to a resource ID in the bound resources */ dw_window_set_icon(mainwindow, 2000); bigbox = dw_box_new(BOXVERT, 10); dw_box_pack_start(mainwindow, bigbox, 0, 0, TRUE, TRUE, 0); mainbox = dw_box_new(BOXHORZ, 0); dw_box_pack_start(bigbox, mainbox, 0, 0, TRUE, TRUE, 0); logo = dw_bitmap_new(1001); /* This number must corespond to a resource ID in the bound resources */ dw_window_set_bitmap(logo, 2001, NULL); dw_box_pack_start(mainbox, logo, 100, 275, FALSE, FALSE, 10); custombox = dw_box_new(BOXVERT, 0); dw_box_pack_start(mainbox, custombox, 0, 0, TRUE, TRUE, 0); sprintf(text, "Ready to Uninstall %s %s", INSTALLER_APPLICATION, INSTALLER_VERSION); stext = dw_text_new(text, 0); dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER); dw_box_pack_start(custombox, stext, 300, 50, TRUE, TRUE, 10); groupbox = dw_groupbox_new(BOXHORZ, 10, "Progress"); dw_box_pack_start(custombox, groupbox, 0, 0, TRUE, FALSE, 10); slider = dw_percent_new(1010); dw_box_pack_start(groupbox, slider, 300, 20, TRUE, FALSE, 10); status = dw_text_new("", 0); dw_box_pack_start(custombox, status, 300, 50, TRUE, TRUE, 10); dw_box_pack_start(custombox, 0, 300, 100, TRUE, TRUE, 10); buttonbox = dw_box_new(BOXHORZ, 5); dw_box_pack_start(bigbox, buttonbox, 0, 0, TRUE, FALSE, 0); exitbutton = dw_button_new("Exit Uninstall", 1003); dw_box_pack_start(buttonbox, exitbutton, 100, 30, TRUE, FALSE, 0); blanktext = dw_text_new("", 0); dw_box_pack_start(buttonbox, blanktext, 150, 30, TRUE, FALSE, 0); nextbutton = dw_button_new("Begin >>", 1001); dw_box_pack_start(buttonbox, nextbutton, 60, 30, TRUE, FALSE, 0); /* Set some nice fonts and colors */ #ifdef __OS2__ dw_window_set_font(stext, "9.WarpSans Bold"); #elif defined(__WIN32__) dw_window_set_font(stext, "14.Arial Bold"); #endif dw_signal_connect(exitbutton, "clicked", DW_SIGNAL_FUNC(exit_callback), NULL); dw_signal_connect(nextbutton, "clicked", DW_SIGNAL_FUNC(start_callback), NULL); dw_window_set_pos_size(mainwindow, (dw_screen_width()-550)/2, (dw_screen_height()-375)/2, 550, 375); dw_window_show(mainwindow); } /* * Main function */ int main(int argc, char *argv[]) { dw_init(TRUE, argc, argv); if(argc > 2) { INSTALLER_APPLICATION = argv[1]; INSTALLER_VERSION = argv[2]; } else { dw_messagebox("Uninstall", DW_MB_OK | DW_MB_ERROR, "Error in uninstaller."); return 0; } uninstall_dialog(); dw_main(); return 0; }