From 5b28670bc36f1ad85f20019c377b59a04e524547 Mon Sep 17 00:00:00 2001 From: "ben%bengoodger.com" Date: Thu, 9 Oct 2003 02:02:08 +0000 Subject: [PATCH] Next Gen App Wizard Front End... forking Seamonkey Installer FE. --- toolkit/mozapps/installer/Makefile.in | 32 + toolkit/mozapps/installer/windows/Makefile.in | 32 + .../installer/windows/wizard/Makefile.in | 32 + .../windows/wizard/setup/Makefile.in | 85 + .../installer/windows/wizard/setup/dialogs.c | 3199 ++++++ .../installer/windows/wizard/setup/dialogs.h | 71 + .../installer/windows/wizard/setup/extern.h | 109 + .../installer/windows/wizard/setup/extra.c | 9101 +++++++++++++++++ .../installer/windows/wizard/setup/extra.h | 236 + .../installer/windows/wizard/setup/ifuncns.c | 2383 +++++ .../installer/windows/wizard/setup/ifuncns.h | 110 + .../installer/windows/wizard/setup/logging.c | 655 ++ .../installer/windows/wizard/setup/logging.h | 58 + .../windows/wizard/setup/nsEscape.cpp | 201 + .../installer/windows/wizard/setup/nsEscape.h | 82 + .../installer/windows/wizard/setup/process.c | 0 .../installer/windows/wizard/setup/process.h | 0 .../installer/windows/wizard/setup/resource.h | 48 + .../installer/windows/wizard/setup/setup.c | 215 + .../installer/windows/wizard/setup/setup.h | 655 ++ .../installer/windows/wizard/setup/setup.ico | Bin 0 -> 1078 bytes .../installer/windows/wizard/setup/setup.ini | 0 .../installer/windows/wizard/setup/setup.rc | 157 + .../windows/wizard/setup/shortcut.cpp | 93 + .../installer/windows/wizard/setup/shortcut.h | 43 + .../windows/wizard/setup/supersede.c | 467 + .../windows/wizard/setup/supersede.h | 0 .../installer/windows/wizard/setup/version.c | 0 .../installer/windows/wizard/setup/version.h | 0 .../windows/wizard/setup/wizverreg.h | 31 + .../installer/windows/wizard/setup/xperr.h | 80 + .../installer/windows/wizard/setup/xpi.c | 832 ++ .../installer/windows/wizard/setup/xpi.h | 40 + .../installer/windows/wizard/setup/xpistub.h | 119 + .../windows/wizard/setup/xpnetHook.cpp | 1523 +++ .../windows/wizard/setup/xpnetHook.h | 44 + .../installer/windows/wizard/setup/zipfile.h | 92 + .../windows/wizard/setuprsc/Makefile.in | 62 + .../windows/wizard/setuprsc/bitmap1.bmp | 0 .../windows/wizard/setuprsc/box_ch_d.bmp | 0 .../windows/wizard/setuprsc/box_chec.bmp | 0 .../windows/wizard/setuprsc/box_unch.bmp | 0 .../windows/wizard/setuprsc/downloadLogo.bmp | 0 .../windows/wizard/setuprsc/setup.ico | Bin 0 -> 1078 bytes .../windows/wizard/setuprsc/setuprsc.cpp | 29 + .../windows/wizard/setuprsc/setuprsc.h | 149 + .../windows/wizard/setuprsc/setuprsc.rc | 480 + .../windows/wizard/setuprsc/turbo-systray.bmp | 0 .../windows/wizard/uninstall/Makefile.in | 70 + .../windows/wizard/uninstall/dialogs.c | 526 + .../windows/wizard/uninstall/dialogs.h | 40 + .../windows/wizard/uninstall/extern.h | 63 + .../windows/wizard/uninstall/extra.c | 2623 +++++ .../windows/wizard/uninstall/extra.h | 106 + .../windows/wizard/uninstall/ifuncns.c | 393 + .../windows/wizard/uninstall/ifuncns.h | 41 + .../windows/wizard/uninstall/logkeys.h | 45 + .../windows/wizard/uninstall/parser.c | 791 ++ .../windows/wizard/uninstall/parser.h | 46 + .../windows/wizard/uninstall/process.c | 0 .../windows/wizard/uninstall/process.h | 0 .../installer/windows/wizard/uninstall/rdi.c | 587 ++ .../installer/windows/wizard/uninstall/rdi.h | 31 + .../windows/wizard/uninstall/resource.h | 50 + .../windows/wizard/uninstall/uninstall.c | 149 + .../windows/wizard/uninstall/uninstall.h | 179 + .../windows/wizard/uninstall/uninstall.ico | Bin 0 -> 1078 bytes .../windows/wizard/uninstall/uninstall.rc | 171 + 68 files changed, 27456 insertions(+) create mode 100644 toolkit/mozapps/installer/Makefile.in create mode 100644 toolkit/mozapps/installer/windows/Makefile.in create mode 100644 toolkit/mozapps/installer/windows/wizard/Makefile.in create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/Makefile.in create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/dialogs.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/dialogs.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/extern.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/extra.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/extra.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/ifuncns.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/ifuncns.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/logging.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/logging.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/nsEscape.cpp create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/nsEscape.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/process.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/process.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/resource.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/setup.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/setup.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/setup.ico create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/setup.ini create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/setup.rc create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/shortcut.cpp create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/shortcut.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/supersede.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/supersede.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/version.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/version.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/wizverreg.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/xperr.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/xpi.c create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/xpi.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/xpistub.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.cpp create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setup/zipfile.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/Makefile.in create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/bitmap1.bmp create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/box_ch_d.bmp create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/box_chec.bmp create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/box_unch.bmp create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/downloadLogo.bmp create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/setup.ico create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.cpp create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.h create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.rc create mode 100644 toolkit/mozapps/installer/windows/wizard/setuprsc/turbo-systray.bmp create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/Makefile.in create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/extern.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/extra.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/extra.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/logkeys.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/parser.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/parser.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/process.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/process.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/rdi.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/rdi.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/resource.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.c create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.h create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.ico create mode 100644 toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.rc diff --git a/toolkit/mozapps/installer/Makefile.in b/toolkit/mozapps/installer/Makefile.in new file mode 100644 index 00000000000..84277c4f19b --- /dev/null +++ b/toolkit/mozapps/installer/Makefile.in @@ -0,0 +1,32 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = windows + +include $(topsrcdir)/config/rules.mk + diff --git a/toolkit/mozapps/installer/windows/Makefile.in b/toolkit/mozapps/installer/windows/Makefile.in new file mode 100644 index 00000000000..1922c7cbc38 --- /dev/null +++ b/toolkit/mozapps/installer/windows/Makefile.in @@ -0,0 +1,32 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = wizard + +include $(topsrcdir)/config/rules.mk + diff --git a/toolkit/mozapps/installer/windows/wizard/Makefile.in b/toolkit/mozapps/installer/windows/wizard/Makefile.in new file mode 100644 index 00000000000..a6272bd8b9b --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/Makefile.in @@ -0,0 +1,32 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = uninstall setuprsc setup + +include $(topsrcdir)/config/rules.mk + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/Makefile.in b/toolkit/mozapps/installer/windows/wizard/setup/Makefile.in new file mode 100644 index 00000000000..4e6d4adef14 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/Makefile.in @@ -0,0 +1,85 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +PROGRAM = setup$(BIN_SUFFIX) +RESFILE = setup.res +REQUIRES = \ + setuprsc \ + xpnet \ + $(NULL) + +EXTRA_DSO_LIBS = \ + mozregsa_s \ + jar50_s \ + mozz_s \ + xpnet_s \ + $(NULL) + +USE_NON_MT_LIBS = 1 + +CSRCS = \ + dialogs.c \ + extra.c \ + ifuncns.c \ + setup.c \ + xpi.c \ + logging.c \ + supersede.c \ + version.c \ + process.c \ + +CPPSRCS = \ + shortcut.cpp \ + xpnetHook.cpp \ + nsEscape.cpp \ + $(NULL) + +LIBS = $(EXTRA_DSO_LIBS) + +LOCAL_INCLUDES = -I$(srcdir) -I$(srcdir)/../uninstall + +NO_DIST_INSTALL = 1 + +MOZ_WINCONSOLE = 0 + +include $(topsrcdir)/config/rules.mk + +_OS_LIBS = ole32 comdlg32 shell32 version +ifdef GNU_CC +_OS_LIBS += gdi32 ws2_32 uuid +endif +OS_LIBS += $(call EXPAND_LIBNAME,$(_OS_LIBS)) + +libs:: $(PROGRAM) + $(INSTALL) $(PROGRAM) $(DIST)/install + +install:: $(PROGRAM) + $(INSTALL) $(PROGRAM) $(DESTDIR)$(mozappdir)/install + +clean clobber realclean clobber_all:: + $(RM) $(DIST)/install/$(PROGRAM) diff --git a/toolkit/mozapps/installer/windows/wizard/setup/dialogs.c b/toolkit/mozapps/installer/windows/wizard/setup/dialogs.c new file mode 100644 index 00000000000..1f5b05b2b18 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/dialogs.c @@ -0,0 +1,3199 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + * Curt Patrick + */ + +#include "extern.h" +#include "extra.h" +#include "dialogs.h" +#include "ifuncns.h" +#include "xpistub.h" +#include "xpi.h" +#include "logging.h" +#include +#include + +// commdlg.h is needed to build with WIN32_LEAN_AND_MEAN +#include + +static WNDPROC OldListBoxWndProc; +static BOOL gbProcessingXpnstallFiles; +static DWORD gdwACFlag; +static DWORD gdwIndexLastSelected; + +/* List of Dialog Item IDs from the Download dialog + * that need to be repositioned (up) when the banner + * in the dialog is hidden. + */ +const int DownloadDlgItemList[] = {IDPAUSE, + IDRESUME, + IDCANCEL, + IDC_MESSAGE0, + IDC_STATIC3, + IDC_STATUS_URL, + IDC_STATIC1, + IDC_STATUS_STATUS, + IDC_STATIC2, + IDC_STATUS_FILE, + IDC_GAUGE_FILE, + IDC_PERCENTAGE, + IDC_STATIC4, + IDC_STATUS_TO, + -2}; /* -1 is used by IDC_STATIC. Even though + * there shouldn't be any IDC_STATIC in + * list, we shouldn't use it. + */ + +/* List of Dialog Item IDs from the Install Progress dialog + * that need to be repositioned (up) when the banner + * in the dialog is hidden. +*/ +const int InstallProgressDlgItemList[] = {IDC_STATUS0, + IDC_GAUGE_ARCHIVE, + IDC_STATUS3, + IDC_GAUGE_FILE, + -2}; /* -1 is used by IDC_STATIC. Even though + * there shouldn't be any IDC_STATIC in + * list, we shouldn't use it. + */ + +BOOL AskCancelDlg(HWND hDlg) +{ + char szDlgQuitTitle[MAX_BUF]; + char szDlgQuitMsg[MAX_BUF]; + char szMsg[MAX_BUF]; + BOOL bRv = FALSE; + + if((sgProduct.mode != SILENT) && (sgProduct.mode != AUTO)) + { + if(!GetPrivateProfileString("Messages", "DLGQUITTITLE", "", szDlgQuitTitle, sizeof(szDlgQuitTitle), szFileIniInstall)) + PostQuitMessage(1); + else if(!GetPrivateProfileString("Messages", "DLGQUITMSG", "", szDlgQuitMsg, sizeof(szDlgQuitMsg), szFileIniInstall)) + PostQuitMessage(1); + else if(MessageBox(hDlg, szDlgQuitMsg, szDlgQuitTitle, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 | MB_APPLMODAL | MB_SETFOREGROUND) == IDYES) + { + DestroyWindow(hDlg); + PostQuitMessage(0); + bRv = TRUE; + } + } + else + { + GetPrivateProfileString("Strings", "Message Cancel Setup AUTO mode", "", szMsg, sizeof(szMsg), szFileIniConfig); + ShowMessage(szMsg, TRUE); + Delay(5); + ShowMessage(szMsg, FALSE); + bRv = TRUE; + } + + return(bRv); +} + +void DisableSystemMenuItems(HWND hWnd, BOOL bDisableClose) +{ + EnableMenuItem(GetSystemMenu(hWnd, FALSE), SC_RESTORE, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(GetSystemMenu(hWnd, FALSE), SC_SIZE, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(GetSystemMenu(hWnd, FALSE), SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); + + if(bDisableClose) + EnableMenuItem(GetSystemMenu(hWnd, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); +} + +/* Function: MoveDlgItem() + * + * in: HWND aWndDlg : handle to a dialog containing items in aIDList. + * const int *aIDList: list of dlg item IDs that require moving. + * DWORD aWidth : width to move the dlg items by (+/-). + * DWORD aHeight : height to move the dlg items by (+/-). + * + * purpose: To move dialog items (given a list of item ids) +aWidth/+aHeight from + * its current position. + * This is for when the banner logo in the download/install process + * dialogs are not to be displayed, it leaves an empty area above + * the dialog items/controls. So this helps move them up by the + * height of the banner. + * The resizing of the window given the lack of the banner is done + * RepositionWindow(). + */ +void MoveDlgItem(HWND aWndDlg, const int *aIDList, DWORD aWidth, DWORD aHeight) +{ + RECT rect; + HWND hDlgItem; + int i; + int id; + + i = 0; + id = aIDList[i]; + while(id != -2) + { + hDlgItem = GetDlgItem(aWndDlg, id); + if(hDlgItem) + { + GetWindowRect(hDlgItem, &rect); + SetWindowPos(hDlgItem, NULL, rect.left + aWidth, rect.top + aHeight, + -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + id = aIDList[++i]; + } +} + +/* Function: RepositionWindow() + * + * in: HWND aHwndDlg : Window handle to reposition. + * DWORD aBannerImage: Integer indicating which dialog needs to have + * it's dlg items moved. + * There are only 3 types: + * NO_BANNER_IMAGE + * BANNER_IMAGE_DOWNLOAD + * BANNER_IMAGE_INSTALLING + * + * purpose: To reposition a window given the screen position of the previous + * window. The previous window position is saved in: + * gSystemInfo.lastWindowPosCenterX + * gSystemInfo.lastWindowPosCenterY + * + * aHwndDlg is the window handle to the dialog to reposition. + * aBannerImage is a DWORD value that indicates which dialog + * the banner is displayed in. There are only two possible dialogs: + * Download dialog + * Install dialog + * + * This function also hides the banner image normally displayed in + * the Download and Install Process dialgs. Once hidden, it also + * moves all of their dialog items up by the height of the hidden + * banner image and resizes the dialogs so it'll look nice. + */ +void RepositionWindow(HWND aHwndDlg, DWORD aBannerImage) +{ + RECT rect; + int iLeft, iTop; + DWORD width = -1; + DWORD height = -1; + DWORD windowFlags = SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE; + + GetWindowRect(aHwndDlg, &rect); + if(aBannerImage && !gShowBannerImage) + { + RECT rLogo; + HWND hwndBanner; + + hwndBanner = GetDlgItem(aHwndDlg, IDB_BITMAP_BANNER); + GetWindowRect(hwndBanner, &rLogo); + ShowWindow(hwndBanner, SW_HIDE); + width = rect.right; + height = rect.bottom - rLogo.bottom + rLogo.top; + windowFlags = SWP_NOZORDER | SWP_NOACTIVATE; + + /* aBannerImage indicates which dialog we need to move it's dlg items + * up to fit the resized window. + */ + switch(aBannerImage) + { + case BANNER_IMAGE_DOWNLOAD: + MoveDlgItem(aHwndDlg, DownloadDlgItemList, 0, -rLogo.bottom); + break; + + case BANNER_IMAGE_INSTALLING: + MoveDlgItem(aHwndDlg, InstallProgressDlgItemList, 0, -rLogo.bottom); + break; + + default: + break; + } + } + + iLeft = (gSystemInfo.lastWindowPosCenterX - ((rect.right - rect.left) / 2)); + iTop = (gSystemInfo.lastWindowPosCenterY - ((rect.bottom - rect.top) / 2)); + SetWindowPos(aHwndDlg, NULL, iLeft, iTop, width, height, windowFlags); +} + +/* Function: SaveWindowPosition() + * + * in: HWND aDlg: Window handle to remember the position of. + * + * purpose: Saves the current window's position so that it can be + * used to position the next window created. + */ +void SaveWindowPosition(HWND aDlg) +{ + RECT rectDlg; + + if(GetWindowRect(aDlg, &rectDlg)) + { + gSystemInfo.lastWindowPosCenterX = ((rectDlg.right - rectDlg.left) / 2) + rectDlg.left; + gSystemInfo.lastWindowPosCenterY = ((rectDlg.bottom - rectDlg.top) / 2) + rectDlg.top; + } +} + +LRESULT CALLBACK DlgProcWelcome(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diWelcome.szTitle); + + wsprintf(szBuf, diWelcome.szMessage0, sgProduct.szProductName, sgProduct.szProductName); + SetDlgItemText(hDlg, IDC_STATIC0, szBuf); + SetDlgItemText(hDlg, IDC_STATIC1, diWelcome.szMessage1); + SetDlgItemText(hDlg, IDC_STATIC2, diWelcome.szMessage2); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcLicense(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + LPSTR szLicenseFilenameBuf = NULL; + WIN32_FIND_DATA wfdFindFileData; + DWORD dwFileSize; + DWORD dwBytesRead; + HANDLE hFLicense; + FILE *fLicense; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diLicense.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diLicense.szMessage0); + SetDlgItemText(hDlg, IDC_MESSAGE1, diLicense.szMessage1); + + lstrcpy(szBuf, szSetupDir); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, diLicense.szLicenseFilename); + + if((hFLicense = FindFirstFile(szBuf, &wfdFindFileData)) != INVALID_HANDLE_VALUE) + { + dwFileSize = (wfdFindFileData.nFileSizeHigh * MAXDWORD) + wfdFindFileData.nFileSizeLow + 1; + FindClose(hFLicense); + if((szLicenseFilenameBuf = NS_GlobalAlloc(dwFileSize)) != NULL) + { + if((fLicense = fopen(szBuf, "rb")) != NULL) + { + dwBytesRead = fread(szLicenseFilenameBuf, sizeof(char), dwFileSize, fLicense); + fclose(fLicense); + SetDlgItemText(hDlg, IDC_EDIT_LICENSE, szLicenseFilenameBuf); + } + + FreeMemory(&szLicenseFilenameBuf); + } + } + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szAccept_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szDecline_); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_LICENSE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK ListBoxBrowseWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case LB_SETCURSEL: + gdwIndexLastSelected = (DWORD)wParam; + break; + } + + return(CallWindowProc(OldListBoxWndProc, hWnd, uMsg, wParam, lParam)); +} + +LRESULT CALLBACK BrowseHookProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + DWORD dwIndex; + DWORD dwLoop; + char szBuf[MAX_BUF]; + char szBufIndex[MAX_BUF]; + char szPath[MAX_BUF]; + HWND hwndLBFolders; + + switch(message) + { + case WM_INITDIALOG: + hwndLBFolders = GetDlgItem(hDlg, 1121); + SetDlgItemText(hDlg, IDC_EDIT_DESTINATION, szTempSetupPath); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + OldListBoxWndProc = SubclassWindow(hwndLBFolders, (WNDPROC)ListBoxBrowseWndProc); + gdwIndexLastSelected = SendDlgItemMessage(hDlg, 1121, LB_GETCURSEL, 0, (LPARAM)0); + + SetWindowText(hDlg, sgInstallGui.szSelectDirectory); + SetDlgItemText(hDlg, 1092, sgInstallGui.szDirectories_); + SetDlgItemText(hDlg, 1091, sgInstallGui.szDrives_); + SetDlgItemText(hDlg, 1, sgInstallGui.szOk); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel); + SendDlgItemMessage (hDlg, DLG_BROWSE_DIR, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, 1092, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, 1091, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, 1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_DESTINATION, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, 1121, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, 1137, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case 1121: + if(HIWORD(wParam) == LBN_DBLCLK) + { + dwIndex = SendDlgItemMessage(hDlg, 1121, LB_GETCURSEL, 0, (LPARAM)0); + SendDlgItemMessage(hDlg, 1121, LB_GETTEXT, 0, (LPARAM)szPath); + + if(gdwIndexLastSelected < dwIndex) + { + for(dwLoop = 1; dwLoop <= gdwIndexLastSelected; dwLoop++) + { + SendDlgItemMessage(hDlg, 1121, LB_GETTEXT, dwLoop, (LPARAM)szBufIndex); + AppendBackSlash(szPath, sizeof(szPath)); + lstrcat(szPath, szBufIndex); + } + + SendDlgItemMessage(hDlg, 1121, LB_GETTEXT, dwIndex, (LPARAM)szBufIndex); + AppendBackSlash(szPath, sizeof(szPath)); + lstrcat(szPath, szBufIndex); + } + else + { + for(dwLoop = 1; dwLoop <= dwIndex; dwLoop++) + { + SendDlgItemMessage(hDlg, 1121, LB_GETTEXT, dwLoop, (LPARAM)szBufIndex); + AppendBackSlash(szPath, sizeof(szPath)); + lstrcat(szPath, szBufIndex); + } + } + SetDlgItemText(hDlg, IDC_EDIT_DESTINATION, szPath); + } + break; + + case IDOK: + SaveWindowPosition(hDlg); + GetDlgItemText(hDlg, IDC_EDIT_DESTINATION, szBuf, MAX_BUF); + if(*szBuf == '\0') + { + char szEDestinationPath[MAX_BUF]; + + GetPrivateProfileString("Messages", "ERROR_DESTINATION_PATH", "", szEDestinationPath, sizeof(szEDestinationPath), szFileIniInstall); + MessageBox(hDlg, szEDestinationPath, NULL, MB_OK | MB_ICONEXCLAMATION); + break; + } + + AppendBackSlash(szBuf, sizeof(szBuf)); + + /* Make sure that the path is not within the windows dir */ + if(IsPathWithinWindir(szBuf)) + { + char errorMsg[MAX_BUF]; + char errorMsgTitle[MAX_BUF]; + + GetPrivateProfileString("Messages", "ERROR_PATH_WITHIN_WINDIR", + "", errorMsg, sizeof(errorMsg), szFileIniInstall); + GetPrivateProfileString("Messages", "ERROR_MESSAGE_TITLE", "", + errorMsgTitle, sizeof(errorMsgTitle), szFileIniInstall); + MessageBox(hDlg, errorMsg, errorMsgTitle, MB_OK | MB_ICONERROR); + break; + } + + /* Create the path if it does not exist */ + if(FileExists(szBuf) == FALSE) + { + char szBufTemp[MAX_BUF]; + char szBuf2[MAX_PATH]; + + if(CreateDirectoriesAll(szBuf, ADD_TO_UNINSTALL_LOG) != WIZ_OK) + { + char szECreateDirectory[MAX_BUF]; + char szEMessageTitle[MAX_BUF]; + + lstrcpy(szBufTemp, "\n\n"); + lstrcat(szBufTemp, sgProduct.szPath); + RemoveBackSlash(szBufTemp); + lstrcat(szBufTemp, "\n\n"); + + if(GetPrivateProfileString("Messages", "ERROR_CREATE_DIRECTORY", "", szECreateDirectory, sizeof(szECreateDirectory), szFileIniInstall)) + wsprintf(szBuf, szECreateDirectory, szBufTemp); + + GetPrivateProfileString("Messages", "ERROR_MESSAGE_TITLE", "", szEMessageTitle, sizeof(szEMessageTitle), szFileIniInstall); + + MessageBox(hDlg, szBuf, szEMessageTitle, MB_OK | MB_ICONERROR); + break; + } + + if(*sgProduct.szSubPath != '\0') + { + /* log the subpath for uninstallation. This subpath does not normally get logged + * for uninstallation due to a chicken and egg problem with creating the log file + * and the directory its in */ + lstrcpy(szBuf2, szBuf); + AppendBackSlash(szBuf2, sizeof(szBuf2)); + lstrcat(szBuf2, sgProduct.szSubPath); + UpdateInstallLog(KEY_CREATE_FOLDER, szBuf2, FALSE); + } + + bCreateDestinationDir = TRUE; + } + + lstrcpy(szTempSetupPath, szBuf); + RemoveBackSlash(szTempSetupPath); + EndDialog(hDlg, 0); + break; + } + break; + } + return(0); +} + +BOOL BrowseForDirectory(HWND hDlg, char *szCurrDir) +{ + OPENFILENAME of; + char ftitle[MAX_PATH]; + char fname[MAX_PATH]; + char szCDir[MAX_BUF]; + char szBuf[MAX_BUF]; + char szSearchPathBuf[MAX_BUF]; + char szDlgBrowseTitle[MAX_BUF]; + BOOL bRet; + + /* save the current directory */ + GetCurrentDirectory(MAX_BUF, szCDir); + + ZeroMemory(szDlgBrowseTitle, sizeof(szDlgBrowseTitle)); + GetPrivateProfileString("Messages", "DLGBROWSETITLE", "", szDlgBrowseTitle, sizeof(szDlgBrowseTitle), szFileIniInstall); + + lstrcpy(szSearchPathBuf, szCurrDir); + if((*szSearchPathBuf != '\0') && ((lstrlen(szSearchPathBuf) != 1) || (*szSearchPathBuf != '\\'))) + { + RemoveBackSlash(szSearchPathBuf); + while(FileExists(szSearchPathBuf) == FALSE) + { + RemoveBackSlash(szSearchPathBuf); + ParsePath(szSearchPathBuf, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY); + lstrcpy(szSearchPathBuf, szBuf); + } + } + + ZeroMemory(ftitle, sizeof(ftitle)); + strcpy(fname, "*.*"); + of.lStructSize = sizeof(OPENFILENAME); + of.hwndOwner = hDlg; + of.hInstance = hSetupRscInst; + of.lpstrFilter = NULL; + of.lpstrCustomFilter = NULL; + of.nMaxCustFilter = 0; + of.nFilterIndex = 0; + of.lpstrFile = fname; + of.nMaxFile = MAX_PATH; + of.lpstrFileTitle = ftitle; + of.nMaxFileTitle = MAX_PATH; + of.lpstrInitialDir = szSearchPathBuf; + of.lpstrTitle = szDlgBrowseTitle; + of.Flags = OFN_NONETWORKBUTTON | + OFN_ENABLEHOOK | + OFN_NOCHANGEDIR | + OFN_ENABLETEMPLATE; + of.nFileOffset = 0; + of.nFileExtension = 0; + of.lpstrDefExt = NULL; + of.lCustData = 0; + of.lpfnHook = BrowseHookProc; + of.lpTemplateName = MAKEINTRESOURCE(DLG_BROWSE_DIR); + + if(GetOpenFileName(&of)) + bRet = TRUE; + else + bRet = FALSE; + + /* restore the current directory */ + SetCurrentDirectory(szCDir); + return(bRet); +} + +void TruncateString(HWND hWnd, LPSTR szInURL, LPSTR szOutString, DWORD dwOutStringBufSize) +{ + HDC hdcWnd; + LOGFONT logFont; + HFONT hfontNew; + HFONT hfontOld; + RECT rWndRect; + SIZE sizeString; + char *ptr = NULL; + int iHalfLen; + int iOutStringLen; + + if((DWORD)lstrlen(szInURL) > dwOutStringBufSize) + return; + + ZeroMemory(szOutString, dwOutStringBufSize); + lstrcpy(szOutString, szInURL); + iOutStringLen = lstrlen(szOutString); + hdcWnd = GetWindowDC(hWnd); + GetClientRect(hWnd, &rWndRect); + SystemParametersInfo(SPI_GETICONTITLELOGFONT, + sizeof(logFont), + (PVOID)&logFont, + 0); + + hfontNew = CreateFontIndirect(&logFont); + if(hfontNew) + { + hfontOld = (HFONT)SelectObject(hdcWnd, hfontNew); + + GetTextExtentPoint32(hdcWnd, szOutString, iOutStringLen, &sizeString); + while(sizeString.cx > rWndRect.right) + { + iHalfLen = iOutStringLen / 2; + if(iHalfLen == 2) + break; + + ptr = szOutString + iHalfLen; + memmove(ptr - 1, ptr, lstrlen(ptr) + 1); + szOutString[iHalfLen - 2] = '.'; + szOutString[iHalfLen - 1] = '.'; + szOutString[iHalfLen] = '.'; + iOutStringLen = lstrlen(szOutString); + GetTextExtentPoint32(hdcWnd, szOutString, iOutStringLen, &sizeString); + } + } + + SelectObject(hdcWnd, hfontOld); + DeleteObject(hfontNew); + ReleaseDC(hWnd, hdcWnd); +} +LRESULT CALLBACK DlgProcSetupType(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + HWND hRadioSt0; + HWND hStaticSt0; + HWND hRadioSt1; + HWND hStaticSt1; + HWND hRadioSt2; + HWND hStaticSt2; + HWND hRadioSt3; + HWND hStaticSt3; + HWND hReadme; + HWND hDestinationPath; + char szBuf[MAX_BUF]; + char szBufTemp[MAX_BUF]; + + hRadioSt0 = GetDlgItem(hDlg, IDC_RADIO_ST0); + hStaticSt0 = GetDlgItem(hDlg, IDC_STATIC_ST0_DESCRIPTION); + hRadioSt1 = GetDlgItem(hDlg, IDC_RADIO_ST1); + hStaticSt1 = GetDlgItem(hDlg, IDC_STATIC_ST1_DESCRIPTION); + hRadioSt2 = GetDlgItem(hDlg, IDC_RADIO_ST2); + hStaticSt2 = GetDlgItem(hDlg, IDC_STATIC_ST2_DESCRIPTION); + hRadioSt3 = GetDlgItem(hDlg, IDC_RADIO_ST3); + hStaticSt3 = GetDlgItem(hDlg, IDC_STATIC_ST3_DESCRIPTION); + hReadme = GetDlgItem(hDlg, IDC_README); + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diSetupType.szTitle); + + hDestinationPath = GetDlgItem(hDlg, IDC_EDIT_DESTINATION); /* handle to the static destination path text window */ + TruncateString(hDestinationPath, szTempSetupPath, szBuf, sizeof(szBuf)); + + SetDlgItemText(hDlg, IDC_EDIT_DESTINATION, szBuf); + SetDlgItemText(hDlg, IDC_STATIC_MSG0, diSetupType.szMessage0); + + if(diSetupType.stSetupType0.bVisible) + { + SetDlgItemText(hDlg, IDC_RADIO_ST0, diSetupType.stSetupType0.szDescriptionShort); + SetDlgItemText(hDlg, IDC_STATIC_ST0_DESCRIPTION, diSetupType.stSetupType0.szDescriptionLong); + ShowWindow(hRadioSt0, SW_SHOW); + ShowWindow(hStaticSt0, SW_SHOW); + } + else + { + ShowWindow(hRadioSt0, SW_HIDE); + ShowWindow(hStaticSt0, SW_HIDE); + } + + if(diSetupType.stSetupType1.bVisible) + { + SetDlgItemText(hDlg, IDC_RADIO_ST1, diSetupType.stSetupType1.szDescriptionShort); + SetDlgItemText(hDlg, IDC_STATIC_ST1_DESCRIPTION, diSetupType.stSetupType1.szDescriptionLong); + ShowWindow(hRadioSt1, SW_SHOW); + ShowWindow(hStaticSt1, SW_SHOW); + } + else + { + ShowWindow(hRadioSt1, SW_HIDE); + ShowWindow(hStaticSt1, SW_HIDE); + } + + if(diSetupType.stSetupType2.bVisible) + { + SetDlgItemText(hDlg, IDC_RADIO_ST2, diSetupType.stSetupType2.szDescriptionShort); + SetDlgItemText(hDlg, IDC_STATIC_ST2_DESCRIPTION, diSetupType.stSetupType2.szDescriptionLong); + ShowWindow(hRadioSt2, SW_SHOW); + ShowWindow(hStaticSt2, SW_SHOW); + } + else + { + ShowWindow(hRadioSt2, SW_HIDE); + ShowWindow(hStaticSt2, SW_HIDE); + } + + if(diSetupType.stSetupType3.bVisible) + { + SetDlgItemText(hDlg, IDC_RADIO_ST3, diSetupType.stSetupType3.szDescriptionShort); + SetDlgItemText(hDlg, IDC_STATIC_ST3_DESCRIPTION, diSetupType.stSetupType3.szDescriptionLong); + ShowWindow(hRadioSt3, SW_SHOW); + ShowWindow(hStaticSt3, SW_SHOW); + } + else + { + ShowWindow(hRadioSt3, SW_HIDE); + ShowWindow(hStaticSt3, SW_HIDE); + } + + /* enable the appropriate radio button */ + switch(dwTempSetupType) + { + case ST_RADIO0: + CheckDlgButton(hDlg, IDC_RADIO_ST0, BST_CHECKED); + SetFocus(hRadioSt0); + break; + + case ST_RADIO1: + CheckDlgButton(hDlg, IDC_RADIO_ST1, BST_CHECKED); + SetFocus(hRadioSt1); + break; + + case ST_RADIO2: + CheckDlgButton(hDlg, IDC_RADIO_ST2, BST_CHECKED); + SetFocus(hRadioSt2); + break; + + case ST_RADIO3: + CheckDlgButton(hDlg, IDC_RADIO_ST3, BST_CHECKED); + SetFocus(hRadioSt3); + break; + } + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + if((*diSetupType.szReadmeFilename == '\0') || (FileExists(diSetupType.szReadmeFilename) == FALSE)) + ShowWindow(hReadme, SW_HIDE); + else + ShowWindow(hReadme, SW_SHOW); + + SetDlgItemText(hDlg, IDC_DESTINATION, sgInstallGui.szDestinationDirectory); + SetDlgItemText(hDlg, IDC_BUTTON_BROWSE, sgInstallGui.szBrowse_); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SetDlgItemText(hDlg, IDC_README, sgInstallGui.szReadme_); + SendDlgItemMessage (hDlg, IDC_STATIC_MSG0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_RADIO_ST0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_RADIO_ST1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_RADIO_ST2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_RADIO_ST3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_ST0_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_ST1_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_ST2_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_ST3_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_DESTINATION, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_BUTTON_BROWSE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_README, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + + if(sgProduct.bLockPath) + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_BROWSE), FALSE); + else + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_BROWSE), TRUE); + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_BUTTON_BROWSE: + SaveWindowPosition(hDlg); + if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST0) == BST_CHECKED) + dwTempSetupType = ST_RADIO0; + else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST1) == BST_CHECKED) + dwTempSetupType = ST_RADIO1; + else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST2) == BST_CHECKED) + dwTempSetupType = ST_RADIO2; + else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST3) == BST_CHECKED) + dwTempSetupType = ST_RADIO3; + + BrowseForDirectory(hDlg, szTempSetupPath); + + hDestinationPath = GetDlgItem(hDlg, IDC_EDIT_DESTINATION); /* handle to the static destination path text window */ + TruncateString(hDestinationPath, szTempSetupPath, szBuf, sizeof(szBuf)); + SetDlgItemText(hDlg, IDC_EDIT_DESTINATION, szBuf); + break; + + case IDC_README: + if(*diSetupType.szReadmeApp == '\0') + WinSpawn(diSetupType.szReadmeFilename, NULL, szSetupDir, SW_SHOWNORMAL, FALSE); + else + WinSpawn(diSetupType.szReadmeApp, diSetupType.szReadmeFilename, szSetupDir, SW_SHOWNORMAL, FALSE); + break; + + case IDWIZNEXT: + SaveWindowPosition(hDlg); + lstrcpy(sgProduct.szPath, szTempSetupPath); + + /* append a backslash to the path because CreateDirectoriesAll() + uses a backslash to determine directories */ + lstrcpy(szBuf, sgProduct.szPath); + AppendBackSlash(szBuf, sizeof(szBuf)); + + /* Make sure that the path is not within the windows dir */ + if(IsPathWithinWindir(szBuf)) + { + char errorMsg[MAX_BUF]; + char errorMsgTitle[MAX_BUF]; + + GetPrivateProfileString("Messages", "ERROR_PATH_WITHIN_WINDIR", + "", errorMsg, sizeof(errorMsg), szFileIniInstall); + GetPrivateProfileString("Messages", "ERROR_MESSAGE_TITLE", "", + errorMsgTitle, sizeof(errorMsgTitle), szFileIniInstall); + MessageBox(hDlg, errorMsg, errorMsgTitle, MB_OK | MB_ICONERROR); + break; + } + + /* Create the path if it does not exist */ + if(FileExists(szBuf) == FALSE) + { + char szBuf2[MAX_PATH]; + + if(CreateDirectoriesAll(szBuf, ADD_TO_UNINSTALL_LOG) != WIZ_OK) + { + char szECreateDirectory[MAX_BUF]; + char szEMessageTitle[MAX_BUF]; + + lstrcpy(szBufTemp, "\n\n"); + lstrcat(szBufTemp, sgProduct.szPath); + RemoveBackSlash(szBufTemp); + lstrcat(szBufTemp, "\n\n"); + + if(GetPrivateProfileString("Messages", "ERROR_CREATE_DIRECTORY", "", szECreateDirectory, sizeof(szECreateDirectory), szFileIniInstall)) + wsprintf(szBuf, szECreateDirectory, szBufTemp); + + GetPrivateProfileString("Messages", "ERROR_MESSAGE_TITLE", "", szEMessageTitle, sizeof(szEMessageTitle), szFileIniInstall); + + MessageBox(hDlg, szBuf, szEMessageTitle, MB_OK | MB_ICONERROR); + break; + } + + if(*sgProduct.szSubPath != '\0') + { + /* log the subpath for uninstallation. This subpath does not normally get logged + * for uninstallation due to a chicken and egg problem with creating the log file + * and the directory its in */ + lstrcpy(szBuf2, szBuf); + AppendBackSlash(szBuf2, sizeof(szBuf2)); + lstrcat(szBuf2, sgProduct.szSubPath); + UpdateInstallLog(KEY_CREATE_FOLDER, szBuf2, FALSE); + } + + bCreateDestinationDir = TRUE; + } + + /* retrieve and save the state of the selected radio button */ + if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST0) == BST_CHECKED) + dwSetupType = ST_RADIO0; + else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST1) == BST_CHECKED) + dwSetupType = ST_RADIO1; + else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST2) == BST_CHECKED) + dwSetupType = ST_RADIO2; + else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST3) == BST_CHECKED) + dwSetupType = ST_RADIO3; + + dwTempSetupType = dwSetupType; + SiCNodeSetItemsSelected(dwSetupType); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + dwTempSetupType = dwSetupType; + lstrcpy(szTempSetupPath, sgProduct.szPath); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + lstrcpy(sgProduct.szPath, szTempSetupPath); + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcUpgrade(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char buf[MAX_BUF]; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + + GetPrivateProfileString("Messages", "MB_WARNING_STR", "", + buf, sizeof(buf), szFileIniInstall); + SetWindowText(hDlg, buf); + + GetPrivateProfileString("Strings", "Message Cleanup On Upgrade", "", + buf, sizeof(buf), szFileIniConfig); + ReplacePrivateProfileStrCR(buf); + SetDlgItemText(hDlg, IDC_MESSAGE0, buf); + + GetPrivateProfileString("Strings", "Cleanup On Upgrade Path Box String", "", + buf, sizeof(buf), szFileIniConfig); + SetDlgItemText(hDlg, IDC_STATIC, buf); + + MozCopyStr(sgProduct.szPath, buf, sizeof(buf)); + RemoveBackSlash(buf); + SetDlgItemText(hDlg, IDC_DELETE_PATH, buf); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetDlgItemText(hDlg, IDCONTINUE, sgInstallGui.szContinue_); + SetDlgItemText(hDlg, IDSKIP, sgInstallGui.szSkip_); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_DELETE_PATH, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCONTINUE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDSKIP, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDCONTINUE: + /* If the installation path happens to be within the %windir%, then + * show error message and continue without removing the previous + * installation path. */ + if(IsPathWithinWindir(sgProduct.szPath)) + { + GetPrivateProfileString("Strings", "Message Cleanup On Upgrade Windir", "", + buf, sizeof(buf), szFileIniConfig); + MessageBox(hWndMain, buf, NULL, MB_ICONEXCLAMATION); + } + else + /* set the var to delete target path here */ + sgProduct.doCleanupOnUpgrade = TRUE; + + SiCNodeSetItemsSelected(dwSetupType); + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDSKIP: + sgProduct.doCleanupOnUpgrade = FALSE; + SiCNodeSetItemsSelected(dwSetupType); + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + default: + break; + } + break; + } + return(0); +} + +void DrawLBText(LPDRAWITEMSTRUCT lpdis, DWORD dwACFlag) +{ + siC *siCTemp = NULL; + TCHAR tchBuffer[MAX_BUF]; + TEXTMETRIC tm; + DWORD y; + + siCTemp = SiCNodeGetObject(lpdis->itemID, FALSE, dwACFlag); + if(siCTemp != NULL) + { + SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)tchBuffer); + + if((lpdis->itemAction & ODA_FOCUS) && (lpdis->itemState & ODS_SELECTED)) + { + // remove the focus rect on the previous selected item + DrawFocusRect(lpdis->hDC, &(lpdis->rcItem)); + } + + siCTemp = SiCNodeGetObject(lpdis->itemID, FALSE, dwACFlag); + if(lpdis->itemAction & ODA_FOCUS) + { + if((lpdis->itemState & ODS_SELECTED) && + !(lpdis->itemState & ODS_FOCUS)) + { + if(siCTemp->dwAttributes & SIC_DISABLED) + SetTextColor(lpdis->hDC, GetSysColor(COLOR_GRAYTEXT)); + else + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW)); + } + } + else + { + if(siCTemp->dwAttributes & SIC_DISABLED) + SetTextColor(lpdis->hDC, GetSysColor(COLOR_GRAYTEXT)); + else + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); + } + } + } + else if(lpdis->itemAction & ODA_DRAWENTIRE) + { + if(siCTemp->dwAttributes & SIC_DISABLED) + SetTextColor(lpdis->hDC, GetSysColor(COLOR_GRAYTEXT)); + else + SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT)); + } + + // If a screen reader is being used we want to redraw the text whether + // it has focus or not because the text changes whenever the checkbox + // changes. + if( gSystemInfo.bScreenReader || (lpdis->itemAction & (ODA_DRAWENTIRE | ODA_FOCUS)) ) + { + // Display the text associated with the item. + GetTextMetrics(lpdis->hDC, &tm); + y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2; + + ExtTextOut(lpdis->hDC, + CX_CHECKBOX + 5, + y, + ETO_OPAQUE | ETO_CLIPPED, + &(lpdis->rcItem), + tchBuffer, + strlen(tchBuffer), + NULL); + } + } +} + +void DrawCheck(LPDRAWITEMSTRUCT lpdis, DWORD dwACFlag) +{ + siC *siCTemp = NULL; + HDC hdcMem; + HBITMAP hbmpCheckBox; + + siCTemp = SiCNodeGetObject(lpdis->itemID, FALSE, dwACFlag); + if(siCTemp != NULL) + { + if(!(siCTemp->dwAttributes & SIC_SELECTED)) + /* Component is not selected. Use the unchecked bitmap regardless if the + * component is disabled or not. The unchecked bitmap looks the same if + * it's disabled or enabled. */ + hbmpCheckBox = hbmpBoxUnChecked; + else if(siCTemp->dwAttributes & SIC_DISABLED) + /* Component is checked and disabled */ + hbmpCheckBox = hbmpBoxCheckedDisabled; + else + /* Component is checked and enabled */ + hbmpCheckBox = hbmpBoxChecked; + + SendMessage(lpdis->hwndItem, LB_SETITEMDATA, lpdis->itemID, (LPARAM)hbmpCheckBox); + if((hdcMem = CreateCompatibleDC(lpdis->hDC)) != NULL) + { + SelectObject(hdcMem, hbmpCheckBox); + + // BitBlt() is used to prepare the checkbox icon into the list box item's device context. + // The SendMessage() function using LB_SETITEMDATA performs the drawing. + BitBlt(lpdis->hDC, + lpdis->rcItem.left + 2, + lpdis->rcItem.top + 2, + lpdis->rcItem.right - lpdis->rcItem.left, + lpdis->rcItem.bottom - lpdis->rcItem.top, + hdcMem, + 0, + 0, + SRCCOPY); + + DeleteDC(hdcMem); + } + } +} + +void lbAddItem(HWND hList, siC *siCComponent) +{ + DWORD dwItem; + TCHAR tchBuffer[MAX_BUF]; + + lstrcpy(tchBuffer, siCComponent->szDescriptionShort); + if(gSystemInfo.bScreenReader) + { + lstrcat(tchBuffer, " - "); + if(!(siCComponent->dwAttributes & SIC_SELECTED)) + lstrcat(tchBuffer, sgInstallGui.szUnchecked); + else + lstrcat(tchBuffer, sgInstallGui.szChecked); + } + dwItem = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)tchBuffer); + + if(siCComponent->dwAttributes & SIC_DISABLED) + SendMessage(hList, LB_SETITEMDATA, dwItem, (LPARAM)hbmpBoxCheckedDisabled); + else if(siCComponent->dwAttributes & SIC_SELECTED) + SendMessage(hList, LB_SETITEMDATA, dwItem, (LPARAM)hbmpBoxChecked); + else + SendMessage(hList, LB_SETITEMDATA, dwItem, (LPARAM)hbmpBoxUnChecked); +} + +void InvalidateLBCheckbox(HWND hwndListBox) +{ + RECT rcCheckArea; + + // retrieve the rectangle of all list items to update. + GetClientRect(hwndListBox, &rcCheckArea); + + // Set the right coordinate of the rectangle to be the same + // as the right edge of the bitmap drawn. + // But if a screen reader is being used we want to redraw the text + // as well as the checkbox so we do not set the right coordinate. + if(!gSystemInfo.bScreenReader) + rcCheckArea.right = CX_CHECKBOX; + + // It then invalidates the checkbox region to be redrawn. + // Invalidating the region sends a WM_DRAWITEM message to + // the dialog, which redraws the region given the + // node attirbute, in this case it is a bitmap of a + // checked/unchecked checkbox. + InvalidateRect(hwndListBox, &rcCheckArea, TRUE); +} + +void ToggleCheck(HWND hwndListBox, DWORD dwIndex, DWORD dwACFlag) +{ + BOOL bMoreToResolve; + LPSTR szToggledReferenceName = NULL; + DWORD dwAttributes; + + // Checks to see if the checkbox is checked or not checked, and + // toggles the node attributes appropriately. + dwAttributes = SiCNodeGetAttributes(dwIndex, FALSE, dwACFlag); + if(!(dwAttributes & SIC_DISABLED)) + { + if(dwAttributes & SIC_SELECTED) + { + SiCNodeSetAttributes(dwIndex, SIC_SELECTED, FALSE, FALSE, dwACFlag, hwndListBox); + + szToggledReferenceName = SiCNodeGetReferenceName(dwIndex, FALSE, dwACFlag); + ResolveDependees(szToggledReferenceName, hwndListBox); + } + else + { + SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, FALSE, dwACFlag, hwndListBox); + bMoreToResolve = ResolveDependencies(dwIndex, hwndListBox); + + while(bMoreToResolve) + bMoreToResolve = ResolveDependencies(-1, hwndListBox); + + szToggledReferenceName = SiCNodeGetReferenceName(dwIndex, FALSE, dwACFlag); + ResolveDependees(szToggledReferenceName, hwndListBox); + } + + InvalidateLBCheckbox(hwndListBox); + } +} + +// ************************************************************************ +// FUNCTION : SubclassWindow( HWND, WNDPROC ) +// PURPOSE : Subclasses a window procedure +// COMMENTS : Returns the old window procedure +// ************************************************************************ +WNDPROC SubclassWindow( HWND hWnd, WNDPROC NewWndProc) +{ + WNDPROC OldWndProc; + + OldWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC); + SetWindowLong(hWnd, GWL_WNDPROC, (LONG) NewWndProc); + + return OldWndProc; +} + +// ************************************************************************ +// FUNCTION : NewListBoxWndProc( HWND, UINT, WPARAM, LPARAM ) +// PURPOSE : Processes messages for "LISTBOX" class. +// COMMENTS : Prevents the user from moving the window +// by dragging the titlebar. +// ************************************************************************ +LRESULT CALLBACK NewListBoxWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + DWORD dwPosX; + DWORD dwPosY; + DWORD dwIndex; + + switch(uMsg) + { + case WM_CHAR: + /* check for the space key */ + if((TCHAR)wParam == 32) + { + dwIndex = SendMessage(hWnd, + LB_GETCURSEL, + 0, + 0); + ToggleCheck(hWnd, dwIndex, gdwACFlag); + } + break; + + case WM_LBUTTONDOWN: + if(wParam == MK_LBUTTON) + { + dwPosX = LOWORD(lParam); // x pos + dwPosY = HIWORD(lParam); // y pos + + if((dwPosX > 1) && (dwPosX <= CX_CHECKBOX)) + { + dwIndex = LOWORD(SendMessage(hWnd, + LB_ITEMFROMPOINT, + 0, + (LPARAM)MAKELPARAM(dwPosX, dwPosY))); + ToggleCheck(hWnd, dwIndex, gdwACFlag); + } + } + break; + } + + return(CallWindowProc(OldListBoxWndProc, hWnd, uMsg, wParam, lParam)); +} + +LRESULT CALLBACK DlgProcSelectComponents(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + BOOL bReturn = FALSE; + siC *siCTemp; + DWORD dwIndex; + DWORD dwItems = MAX_BUF; + HWND hwndLBComponents; + TCHAR tchBuffer[MAX_BUF]; + LPDRAWITEMSTRUCT lpdis; + ULONGLONG ullDSBuf; + char szBuf[MAX_BUF]; + + hwndLBComponents = GetDlgItem(hDlg, IDC_LIST_COMPONENTS); + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diSelectComponents.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diSelectComponents.szMessage0); + + siCTemp = siComponents; + if(siCTemp != NULL) + { + if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) + lbAddItem(hwndLBComponents, siCTemp); + + siCTemp = siCTemp->Next; + while((siCTemp != siComponents) && (siCTemp != NULL)) + { + if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) + lbAddItem(hwndLBComponents, siCTemp); + + siCTemp = siCTemp->Next; + } + SetFocus(hwndLBComponents); + SendMessage(hwndLBComponents, LB_SETCURSEL, 0, 0); + SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, SiCNodeGetDescriptionLong(0, FALSE, AC_COMPONENTS)); + } + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + /* update the disk space available info in the dialog. GetDiskSpaceAvailable() + returns value in kbytes */ + ullDSBuf = GetDiskSpaceAvailable(sgProduct.szPath); + _ui64toa(ullDSBuf, tchBuffer, 10); + ParsePath(sgProduct.szPath, szBuf, sizeof(szBuf), FALSE, PP_ROOT_ONLY); + RemoveBackSlash(szBuf); + lstrcat(szBuf, " "); + lstrcat(szBuf, tchBuffer); + lstrcat(szBuf, " KB"); + SetDlgItemText(hDlg, IDC_SPACE_AVAILABLE, szBuf); + + SetDlgItemText(hDlg, IDC_STATIC1, sgInstallGui.szComponents_); + SetDlgItemText(hDlg, IDC_STATIC2, sgInstallGui.szDescription); + SetDlgItemText(hDlg, IDC_STATIC3, sgInstallGui.szTotalDownloadSize); + SetDlgItemText(hDlg, IDC_STATIC4, sgInstallGui.szSpaceAvailable); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC4, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_LIST_COMPONENTS, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_DOWNLOAD_SIZE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_SPACE_AVAILABLE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + + gdwACFlag = AC_COMPONENTS; + OldListBoxWndProc = SubclassWindow(hwndLBComponents, (WNDPROC)NewListBoxWndProc); + break; + + case WM_DRAWITEM: + lpdis = (LPDRAWITEMSTRUCT)lParam; + + // If there are no list box items, skip this message. + if(lpdis->itemID == -1) + break; + + DrawLBText(lpdis, AC_COMPONENTS); + DrawCheck(lpdis, AC_COMPONENTS); + + // draw the focus rect on the selected item + if((lpdis->itemAction & ODA_FOCUS) && + (lpdis->itemState & ODS_FOCUS)) + { + DrawFocusRect(lpdis->hDC, &(lpdis->rcItem)); + } + + bReturn = TRUE; + + /* update the disk space required info in the dialog. It is already + in Kilobytes */ + ullDSBuf = GetDiskSpaceRequired(DSR_DOWNLOAD_SIZE); + _ui64toa(ullDSBuf, tchBuffer, 10); + lstrcpy(szBuf, tchBuffer); + lstrcat(szBuf, " KB"); + + SetDlgItemText(hDlg, IDC_DOWNLOAD_SIZE, szBuf); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_LIST_COMPONENTS: + /* to update the long description for each component the user selected */ + if((dwIndex = SendMessage(hwndLBComponents, LB_GETCURSEL, 0, 0)) != LB_ERR) + SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, SiCNodeGetDescriptionLong(dwIndex, FALSE, AC_COMPONENTS)); + break; + + case IDWIZNEXT: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + + return(bReturn); +} + +LRESULT CALLBACK DlgProcSelectAdditionalComponents(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + BOOL bReturn = FALSE; + siC *siCTemp; + DWORD dwIndex; + DWORD dwItems = MAX_BUF; + HWND hwndLBComponents; + TCHAR tchBuffer[MAX_BUF]; + LPDRAWITEMSTRUCT lpdis; + ULONGLONG ullDSBuf; + char szBuf[MAX_BUF]; + + hwndLBComponents = GetDlgItem(hDlg, IDC_LIST_COMPONENTS); + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diSelectAdditionalComponents.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diSelectAdditionalComponents.szMessage0); + + siCTemp = siComponents; + if(siCTemp != NULL) + { + if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && (siCTemp->dwAttributes & SIC_ADDITIONAL)) + lbAddItem(hwndLBComponents, siCTemp); + + siCTemp = siCTemp->Next; + while((siCTemp != siComponents) && (siCTemp != NULL)) + { + if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && (siCTemp->dwAttributes & SIC_ADDITIONAL)) + lbAddItem(hwndLBComponents, siCTemp); + + siCTemp = siCTemp->Next; + } + SetFocus(hwndLBComponents); + SendMessage(hwndLBComponents, LB_SETCURSEL, 0, 0); + SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, SiCNodeGetDescriptionLong(0, FALSE, AC_ADDITIONAL_COMPONENTS)); + } + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + /* update the disk space available info in the dialog. GetDiskSpaceAvailable() + returns value in kbytes */ + ullDSBuf = GetDiskSpaceAvailable(sgProduct.szPath); + _ui64toa(ullDSBuf, tchBuffer, 10); + ParsePath(sgProduct.szPath, szBuf, sizeof(szBuf), FALSE, PP_ROOT_ONLY); + RemoveBackSlash(szBuf); + lstrcat(szBuf, " "); + lstrcat(szBuf, tchBuffer); + lstrcat(szBuf, " KB"); + SetDlgItemText(hDlg, IDC_SPACE_AVAILABLE, szBuf); + + SetDlgItemText(hDlg, IDC_STATIC1, sgInstallGui.szAdditionalComponents_); + SetDlgItemText(hDlg, IDC_STATIC2, sgInstallGui.szDescription); + SetDlgItemText(hDlg, IDC_STATIC3, sgInstallGui.szTotalDownloadSize); + SetDlgItemText(hDlg, IDC_STATIC4, sgInstallGui.szSpaceAvailable); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC4, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_LIST_COMPONENTS, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_DOWNLOAD_SIZE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_SPACE_AVAILABLE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + + gdwACFlag = AC_ADDITIONAL_COMPONENTS; + OldListBoxWndProc = SubclassWindow(hwndLBComponents, (WNDPROC)NewListBoxWndProc); + break; + + case WM_DRAWITEM: + lpdis = (LPDRAWITEMSTRUCT)lParam; + + // If there are no list box items, skip this message. + if(lpdis->itemID == -1) + break; + + DrawLBText(lpdis, AC_ADDITIONAL_COMPONENTS); + DrawCheck(lpdis, AC_ADDITIONAL_COMPONENTS); + + // draw the focus rect on the selected item + if((lpdis->itemAction & ODA_FOCUS) && + (lpdis->itemState & ODS_FOCUS)) + { + DrawFocusRect(lpdis->hDC, &(lpdis->rcItem)); + } + + bReturn = TRUE; + + /* update the disk space required info in the dialog. It is already + in Kilobytes */ + ullDSBuf = GetDiskSpaceRequired(DSR_DOWNLOAD_SIZE); + _ui64toa(ullDSBuf, tchBuffer, 10); + lstrcpy(szBuf, tchBuffer); + lstrcat(szBuf, " KB"); + + SetDlgItemText(hDlg, IDC_DOWNLOAD_SIZE, szBuf); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_LIST_COMPONENTS: + /* to update the long description for each component the user selected */ + if((dwIndex = SendMessage(hwndLBComponents, LB_GETCURSEL, 0, 0)) != LB_ERR) + SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, SiCNodeGetDescriptionLong(dwIndex, FALSE, AC_ADDITIONAL_COMPONENTS)); + break; + + case IDWIZNEXT: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + + return(bReturn); +} + +LRESULT CALLBACK DlgProcWindowsIntegration(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + HWND hcbCheck0; + HWND hcbCheck1; + HWND hcbCheck2; + HWND hcbCheck3; + + hcbCheck0 = GetDlgItem(hDlg, IDC_CHECK0); + hcbCheck1 = GetDlgItem(hDlg, IDC_CHECK1); + hcbCheck2 = GetDlgItem(hDlg, IDC_CHECK2); + hcbCheck3 = GetDlgItem(hDlg, IDC_CHECK3); + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diWindowsIntegration.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diWindowsIntegration.szMessage0); + SetDlgItemText(hDlg, IDC_MESSAGE1, diWindowsIntegration.szMessage1); + + if(diWindowsIntegration.wiCB0.bEnabled) + { + ShowWindow(hcbCheck0, SW_SHOW); + CheckDlgButton(hDlg, IDC_CHECK0, diWindowsIntegration.wiCB0.bCheckBoxState); + SetDlgItemText(hDlg, IDC_CHECK0, diWindowsIntegration.wiCB0.szDescription); + } + else + ShowWindow(hcbCheck0, SW_HIDE); + + if(diWindowsIntegration.wiCB1.bEnabled) + { + ShowWindow(hcbCheck1, SW_SHOW); + CheckDlgButton(hDlg, IDC_CHECK1, diWindowsIntegration.wiCB1.bCheckBoxState); + SetDlgItemText(hDlg, IDC_CHECK1, diWindowsIntegration.wiCB1.szDescription); + } + else + ShowWindow(hcbCheck1, SW_HIDE); + + if(diWindowsIntegration.wiCB2.bEnabled) + { + ShowWindow(hcbCheck2, SW_SHOW); + CheckDlgButton(hDlg, IDC_CHECK2, diWindowsIntegration.wiCB2.bCheckBoxState); + SetDlgItemText(hDlg, IDC_CHECK2, diWindowsIntegration.wiCB2.szDescription); + } + else + ShowWindow(hcbCheck2, SW_HIDE); + + if(diWindowsIntegration.wiCB3.bEnabled) + { + ShowWindow(hcbCheck3, SW_SHOW); + CheckDlgButton(hDlg, IDC_CHECK3, diWindowsIntegration.wiCB3.bCheckBoxState); + SetDlgItemText(hDlg, IDC_CHECK3, diWindowsIntegration.wiCB3.szDescription); + } + else + ShowWindow(hcbCheck3, SW_HIDE); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + if(IsDlgButtonChecked(hDlg, IDC_CHECK0) == BST_CHECKED) + { + } + + if(diWindowsIntegration.wiCB0.bEnabled) + { + if(IsDlgButtonChecked(hDlg, IDC_CHECK0) == BST_CHECKED) + diWindowsIntegration.wiCB0.bCheckBoxState = TRUE; + else + diWindowsIntegration.wiCB0.bCheckBoxState = FALSE; + } + + if(diWindowsIntegration.wiCB1.bEnabled) + { + if(IsDlgButtonChecked(hDlg, IDC_CHECK1) == BST_CHECKED) + diWindowsIntegration.wiCB1.bCheckBoxState = TRUE; + else + diWindowsIntegration.wiCB1.bCheckBoxState = FALSE; + } + + if(diWindowsIntegration.wiCB2.bEnabled) + { + if(IsDlgButtonChecked(hDlg, IDC_CHECK2) == BST_CHECKED) + diWindowsIntegration.wiCB2.bCheckBoxState = TRUE; + else + diWindowsIntegration.wiCB2.bCheckBoxState = FALSE; + } + + if(diWindowsIntegration.wiCB3.bEnabled) + { + if(IsDlgButtonChecked(hDlg, IDC_CHECK3) == BST_CHECKED) + diWindowsIntegration.wiCB3.bCheckBoxState = TRUE; + else + diWindowsIntegration.wiCB3.bCheckBoxState = FALSE; + } + + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcProgramFolder(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + HANDLE hDir; + DWORD dwIndex; + WIN32_FIND_DATA wfdFindFileData; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diProgramFolder.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diProgramFolder.szMessage0); + SetDlgItemText(hDlg, IDC_EDIT_PROGRAM_FOLDER, sgProduct.szProgramFolderName); + + lstrcpy(szBuf, sgProduct.szProgramFolderPath); + lstrcat(szBuf, "\\*.*"); + if((hDir = FindFirstFile(szBuf , &wfdFindFileData)) != INVALID_HANDLE_VALUE) + { + if((wfdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lstrcmpi(wfdFindFileData.cFileName, ".") != 0) && (lstrcmpi(wfdFindFileData.cFileName, "..") != 0)) + { + SendDlgItemMessage(hDlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)wfdFindFileData.cFileName); + } + + while(FindNextFile(hDir, &wfdFindFileData)) + { + if((wfdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lstrcmpi(wfdFindFileData.cFileName, ".") != 0) && (lstrcmpi(wfdFindFileData.cFileName, "..") != 0)) + SendDlgItemMessage(hDlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)wfdFindFileData.cFileName); + } + FindClose(hDir); + } + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetDlgItemText(hDlg, IDC_STATIC1, sgInstallGui.szProgramFolder_); + SetDlgItemText(hDlg, IDC_STATIC2, sgInstallGui.szExistingFolder_); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_PROGRAM_FOLDER, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_LIST, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + GetDlgItemText(hDlg, IDC_EDIT_PROGRAM_FOLDER, szBuf, MAX_BUF); + if(*szBuf == '\0') + { + char szEProgramFolderName[MAX_BUF]; + + GetPrivateProfileString("Messages", "ERROR_PROGRAM_FOLDER_NAME", "", szEProgramFolderName, sizeof(szEProgramFolderName), szFileIniInstall); + MessageBox(hDlg, szEProgramFolderName, NULL, MB_OK | MB_ICONEXCLAMATION); + break; + } + lstrcpy(sgProduct.szProgramFolderName, szBuf); + + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDC_LIST: + if((dwIndex = SendDlgItemMessage(hDlg, IDC_LIST, LB_GETCURSEL, 0, 0)) != LB_ERR) + { + SendDlgItemMessage(hDlg, IDC_LIST, LB_GETTEXT, dwIndex, (LPARAM)szBuf); + SetDlgItemText(hDlg, IDC_EDIT_PROGRAM_FOLDER, szBuf); + } + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +void SaveDownloadProtocolOption(HWND hDlg) +{ + if(IsDlgButtonChecked(hDlg, IDC_USE_FTP) == BST_CHECKED) + diAdditionalOptions.dwUseProtocol = UP_FTP; + else if(IsDlgButtonChecked(hDlg, IDC_USE_HTTP) == BST_CHECKED) + diAdditionalOptions.dwUseProtocol = UP_HTTP; +} + +LRESULT CALLBACK DlgProcAdvancedSettings(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diAdvancedSettings.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diAdvancedSettings.szMessage0); + SetDlgItemText(hDlg, IDC_EDIT_PROXY_SERVER, diAdvancedSettings.szProxyServer); + SetDlgItemText(hDlg, IDC_EDIT_PROXY_PORT, diAdvancedSettings.szProxyPort); + SetDlgItemText(hDlg, IDC_EDIT_PROXY_USER, diAdvancedSettings.szProxyUser); + SetDlgItemText(hDlg, IDC_EDIT_PROXY_PASSWD, diAdvancedSettings.szProxyPasswd); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + GetPrivateProfileString("Strings", "IDC Use Ftp", "", szBuf, sizeof(szBuf), szFileIniConfig); + SetDlgItemText(hDlg, IDC_USE_FTP, szBuf); + GetPrivateProfileString("Strings", "IDC Use Http", "", szBuf, sizeof(szBuf), szFileIniConfig); + SetDlgItemText(hDlg, IDC_USE_HTTP, szBuf); + + SetDlgItemText(hDlg, IDC_STATIC, sgInstallGui.szProxySettings); + SetDlgItemText(hDlg, IDC_STATIC1, sgInstallGui.szServer); + SetDlgItemText(hDlg, IDC_STATIC2, sgInstallGui.szPort); + SetDlgItemText(hDlg, IDC_STATIC3, sgInstallGui.szUserId); + SetDlgItemText(hDlg, IDC_STATIC4, sgInstallGui.szPassword); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szOk_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC4, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_SERVER, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_PORT, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_USER, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_PASSWD, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + SendDlgItemMessage (hDlg, IDC_USE_FTP, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_USE_HTTP, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + + switch(diAdditionalOptions.dwUseProtocol) + { + case UP_HTTP: + CheckDlgButton(hDlg, IDC_USE_FTP, BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_USE_HTTP, BST_CHECKED); + break; + + case UP_FTP: + default: + CheckDlgButton(hDlg, IDC_USE_FTP, BST_CHECKED); + CheckDlgButton(hDlg, IDC_USE_HTTP, BST_UNCHECKED); + break; + + } + + if((diAdditionalOptions.bShowProtocols) && (diAdditionalOptions.bUseProtocolSettings)) + { + ShowWindow(GetDlgItem(hDlg, IDC_USE_FTP), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDC_USE_HTTP), SW_SHOW); + } + else + { + ShowWindow(GetDlgItem(hDlg, IDC_USE_FTP), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_USE_HTTP), SW_HIDE); + } + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + /* get the proxy server and port information */ + GetDlgItemText(hDlg, IDC_EDIT_PROXY_SERVER, diAdvancedSettings.szProxyServer, MAX_BUF); + GetDlgItemText(hDlg, IDC_EDIT_PROXY_PORT, diAdvancedSettings.szProxyPort, MAX_BUF); + GetDlgItemText(hDlg, IDC_EDIT_PROXY_USER, diAdvancedSettings.szProxyUser, MAX_BUF); + GetDlgItemText(hDlg, IDC_EDIT_PROXY_PASSWD, diAdvancedSettings.szProxyPasswd, MAX_BUF); + + SaveDownloadProtocolOption(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + case IDCANCEL: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + default: + break; + } + break; + } + return(0); +} + +void SaveAdditionalOptions(HWND hDlg, HWND hwndCBSiteSelector) +{ + int iIndex; + + /* get selected item from the site selector's pull down list */ + iIndex = SendMessage(hwndCBSiteSelector, CB_GETCURSEL, 0, 0); + SendMessage(hwndCBSiteSelector, CB_GETLBTEXT, (WPARAM)iIndex, (LPARAM)szSiteSelectorDescription); + + /* get the state of the Save Installer Files checkbox */ + if(IsDlgButtonChecked(hDlg, IDC_CHECK_SAVE_INSTALLER_FILES) == BST_CHECKED) + diAdditionalOptions.bSaveInstaller = TRUE; + else + diAdditionalOptions.bSaveInstaller = FALSE; + + /* get the state of the Recapture Homepage checkbox */ + if(IsDlgButtonChecked(hDlg, IDC_CHECK_RECAPTURE_HOMEPAGE) == BST_CHECKED) + diAdditionalOptions.bRecaptureHomepage = TRUE; + else + diAdditionalOptions.bRecaptureHomepage = FALSE; +} + +LRESULT CALLBACK DlgProcAdditionalOptions(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + HWND hwndCBSiteSelector; + int iIndex; + ssi *ssiTemp; + char szCBDefault[MAX_BUF]; + + hwndCBSiteSelector = GetDlgItem(hDlg, IDC_LIST_SITE_SELECTOR); + + switch(msg) + { + case WM_INITDIALOG: +// if(gdwSiteSelectorStatus == SS_HIDE) +// { +// ShowWindow(GetDlgItem(hDlg, IDC_MESSAGE0), SW_HIDE); +// ShowWindow(GetDlgItem(hDlg, IDC_LIST_SITE_SELECTOR), SW_HIDE); +// } + + if(diAdditionalOptions.bShowHomepageOption == FALSE) + { + ShowWindow(GetDlgItem(hDlg, IDC_MESSAGE0), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_CHECK_RECAPTURE_HOMEPAGE), SW_HIDE); + } + + if(GetTotalArchivesToDownload() == 0) + { + ShowWindow(GetDlgItem(hDlg, IDC_MESSAGE1), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_CHECK_SAVE_INSTALLER_FILES), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_EDIT_LOCAL_INSTALLER_PATH), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_BUTTON_PROXY_SETTINGS), SW_HIDE); + } + + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diAdditionalOptions.szTitle); + SetDlgItemText(hDlg, IDC_MESSAGE0, diAdditionalOptions.szMessage0); + SetDlgItemText(hDlg, IDC_MESSAGE1, diAdditionalOptions.szMessage1); + + GetPrivateProfileString("Strings", "IDC Save Installer Files", "", szBuf, sizeof(szBuf), szFileIniConfig); + SetDlgItemText(hDlg, IDC_CHECK_SAVE_INSTALLER_FILES, szBuf); + GetPrivateProfileString("Strings", "IDC Recapture Homepage", "", szBuf, sizeof(szBuf), szFileIniConfig); + SetDlgItemText(hDlg, IDC_CHECK_RECAPTURE_HOMEPAGE, szBuf); + + GetSaveInstallerPath(szBuf, sizeof(szBuf)); + SetDlgItemText(hDlg, IDC_EDIT_LOCAL_INSTALLER_PATH, szBuf); + + SetDlgItemText(hDlg, IDC_BUTTON_PROXY_SETTINGS, sgInstallGui.szProxySettings_); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_BUTTON_PROXY_SETTINGS, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_LIST_SITE_SELECTOR, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK_SAVE_INSTALLER_FILES, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK_RECAPTURE_HOMEPAGE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_EDIT_LOCAL_INSTALLER_PATH, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + ssiTemp = ssiSiteSelector; + do + { + if(ssiTemp == NULL) + break; + + SendMessage(hwndCBSiteSelector, CB_ADDSTRING, 0, (LPARAM)(ssiTemp->szDescription)); + ssiTemp = ssiTemp->Next; + } while(ssiTemp != ssiSiteSelector); + + if((szSiteSelectorDescription == NULL) || (*szSiteSelectorDescription == '\0')) + { + if(GetPrivateProfileString("Messages", "CB_DEFAULT", "", szCBDefault, sizeof(szCBDefault), szFileIniInstall) && + ((iIndex = SendMessage(hwndCBSiteSelector, CB_SELECTSTRING, -1, (LPARAM)szCBDefault)) != CB_ERR)) + SendMessage(hwndCBSiteSelector, CB_SETCURSEL, (WPARAM)iIndex, 0); + else + SendMessage(hwndCBSiteSelector, CB_SETCURSEL, 0, 0); + } + else if((iIndex = SendMessage(hwndCBSiteSelector, CB_SELECTSTRING, -1, (LPARAM)szSiteSelectorDescription)) != CB_ERR) + SendMessage(hwndCBSiteSelector, CB_SETCURSEL, (WPARAM)iIndex, 0); + else + SendMessage(hwndCBSiteSelector, CB_SETCURSEL, 0, 0); + + if(diAdditionalOptions.bSaveInstaller) + CheckDlgButton(hDlg, IDC_CHECK_SAVE_INSTALLER_FILES, BST_CHECKED); + else + CheckDlgButton(hDlg, IDC_CHECK_SAVE_INSTALLER_FILES, BST_UNCHECKED); + + if(diAdditionalOptions.bRecaptureHomepage) + CheckDlgButton(hDlg, IDC_CHECK_RECAPTURE_HOMEPAGE, BST_CHECKED); + else + CheckDlgButton(hDlg, IDC_CHECK_RECAPTURE_HOMEPAGE, BST_UNCHECKED); + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + SaveAdditionalOptions(hDlg, hwndCBSiteSelector); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + SaveAdditionalOptions(hDlg, hwndCBSiteSelector); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDC_BUTTON_ADDITIONAL_SETTINGS: + SaveWindowPosition(hDlg); + SaveAdditionalOptions(hDlg, hwndCBSiteSelector); + DestroyWindow(hDlg); + DlgSequence(OTHER_DLG_1); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +void AppendStringWOAmpersand(LPSTR szInputString, DWORD dwInputStringSize, LPSTR szString) +{ + DWORD i; + DWORD iInputStringCounter; + DWORD iInputStringLen; + DWORD iStringLen; + + + iInputStringLen = lstrlen(szInputString); + iStringLen = lstrlen(szString); + + if((iInputStringLen + iStringLen) >= dwInputStringSize) + return; + + iInputStringCounter = iInputStringLen; + for(i = 0; i < iStringLen; i++) + { + if(szString[i] != '&') + szInputString[iInputStringCounter++] = szString[i]; + } +} + +LPSTR GetStartInstallMessage() +{ + char szBuf[MAX_BUF]; + char szSTRRequired[MAX_BUF_TINY]; + siC *siCObject = NULL; + LPSTR szMessageBuf = NULL; + DWORD dwBufSize; + DWORD dwIndex0; + + GetPrivateProfileString("Strings", "STR Force Upgrade Required", "", szSTRRequired, sizeof(szSTRRequired), szFileIniConfig); + + /* calculate the amount of memory to allocate for the buffer */ + dwBufSize = 0; + + /* setup type */ + if(GetPrivateProfileString("Messages", "STR_SETUP_TYPE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + dwBufSize += 4; // take into account 4 indentation spaces + + switch(dwSetupType) + { + case ST_RADIO3: + dwBufSize += lstrlen(diSetupType.stSetupType3.szDescriptionShort) + 2; // the extra 2 bytes is for the \r\n characters + break; + + case ST_RADIO2: + dwBufSize += lstrlen(diSetupType.stSetupType2.szDescriptionShort) + 2; // the extra 2 bytes is for the \r\n characters + break; + + case ST_RADIO1: + dwBufSize += lstrlen(diSetupType.stSetupType1.szDescriptionShort) + 2; // the extra 2 bytes is for the \r\n characters + break; + + default: + dwBufSize += lstrlen(diSetupType.stSetupType0.szDescriptionShort) + 2; // the extra 2 bytes is for the \r\n characters + break; + } + dwBufSize += 2; // the extra 2 bytes is for the \r\n characters + + /* selected components */ + if(GetPrivateProfileString("Messages", "STR_SELECTED_COMPONENTS", "", szBuf, sizeof(szBuf), szFileIniInstall)) + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + + dwIndex0 = 0; + siCObject = SiCNodeGetObject(dwIndex0, FALSE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + { + dwBufSize += 4; // take into account 4 indentation spaces + dwBufSize += lstrlen(siCObject->szDescriptionShort); + } + + if(siCObject->bForceUpgrade) + { + /* add the "(Required)" string (or something equivalent) after the component description */ + if(*szSTRRequired != '\0') + { + dwBufSize += 1; // space after the short description + dwBufSize += lstrlen(szSTRRequired); + } + } + + if(siCObject->dwAttributes & SIC_SELECTED) + dwBufSize += 2; // the extra 2 bytes is for the \r\n characters + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, FALSE, AC_ALL); + } + dwBufSize += 2; // the extra 2 bytes is for the \r\n characters + + /* destination path */ + if(GetPrivateProfileString("Messages", "STR_DESTINATION_DIRECTORY", "", szBuf, sizeof(szBuf), szFileIniInstall)) + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + + dwBufSize += 4; // take into account 4 indentation spaces + dwBufSize += lstrlen(sgProduct.szPath) + 2; // the extra 2 bytes is for the \r\n characters + dwBufSize += 2; // the extra 2 bytes is for the \r\n characters + + /* program folder */ + if(GetPrivateProfileString("Messages", "STR_PROGRAM_FOLDER", "", szBuf, sizeof(szBuf), szFileIniInstall)) + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + + dwBufSize += 4; // take into account 4 indentation spaces + dwBufSize += lstrlen(sgProduct.szProgramFolderName) + 2; // the extra 2 bytes is for the \r\n\r\n characters + + if(GetTotalArchivesToDownload() > 0) + { + dwBufSize += 2; // the extra 2 bytes is for the \r\n characters + + /* site selector info */ + if(GetPrivateProfileString("Messages", "STR_DOWNLOAD_SITE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + + dwBufSize += 4; // take into account 4 indentation spaces + dwBufSize += lstrlen(szSiteSelectorDescription) + 2; // the extra 2 bytes is for the \r\n characters + + if(diAdditionalOptions.bSaveInstaller) + { + dwBufSize += 2; // the extra 2 bytes is for the \r\n characters + + /* site selector info */ + if(GetPrivateProfileString("Messages", "STR_SAVE_INSTALLER_FILES", "", szBuf, sizeof(szBuf), szFileIniInstall)) + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + + GetSaveInstallerPath(szBuf, sizeof(szBuf)); + dwBufSize += 4; // take into account 4 indentation spaces + dwBufSize += lstrlen(szBuf) + 2; // the extra 2 bytes is for the \r\n characters + } + } + + dwBufSize += 1; // take into account the null character + + + /* From here down, the buffer is created given the above calculated buffer size. If the + * string concatenation (addition) is changed below, then the buffer size calculation above + * needs to be changed accordingly! */ + + /* allocate the memory */ + if((szMessageBuf = NS_GlobalAlloc(dwBufSize)) != NULL) + { + ZeroMemory(szMessageBuf, dwBufSize); + + /* Setup Type */ + if(GetPrivateProfileString("Messages", "STR_SETUP_TYPE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + { + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + lstrcat(szMessageBuf, " "); // add 4 indentation spaces + + switch(dwSetupType) + { + case ST_RADIO3: + AppendStringWOAmpersand(szMessageBuf, dwBufSize, diSetupType.stSetupType3.szDescriptionShort); + break; + + case ST_RADIO2: + AppendStringWOAmpersand(szMessageBuf, dwBufSize, diSetupType.stSetupType2.szDescriptionShort); + break; + + case ST_RADIO1: + AppendStringWOAmpersand(szMessageBuf, dwBufSize, diSetupType.stSetupType1.szDescriptionShort); + break; + + default: + AppendStringWOAmpersand(szMessageBuf, dwBufSize, diSetupType.stSetupType0.szDescriptionShort); + break; + } + lstrcat(szMessageBuf, "\r\n\r\n"); + + /* Selected Components */ + if(GetPrivateProfileString("Messages", "STR_SELECTED_COMPONENTS", "", szBuf, sizeof(szBuf), szFileIniInstall)) + { + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + + dwIndex0 = 0; + siCObject = SiCNodeGetObject(dwIndex0, FALSE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + { + lstrcat(szMessageBuf, " "); // add 4 indentation spaces + lstrcat(szMessageBuf, siCObject->szDescriptionShort); + } + + if(siCObject->bForceUpgrade) + { + /* add the "(Required)" string (or something equivalent) after the component description */ + if(*szSTRRequired != '\0') + { + lstrcat(szMessageBuf, " "); // add 1 space + lstrcat(szMessageBuf, szSTRRequired); + } + } + + if(siCObject->dwAttributes & SIC_SELECTED) + lstrcat(szMessageBuf, "\r\n"); + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, FALSE, AC_ALL); + } + lstrcat(szMessageBuf, "\r\n"); + + /* destination directory */ + if(GetPrivateProfileString("Messages", "STR_DESTINATION_DIRECTORY", "", szBuf, sizeof(szBuf), szFileIniInstall)) + { + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + lstrcat(szMessageBuf, " "); // add 4 indentation spaces + lstrcat(szMessageBuf, sgProduct.szPath); + lstrcat(szMessageBuf, "\r\n\r\n"); + + /* program folder */ + if(GetPrivateProfileString("Messages", "STR_PROGRAM_FOLDER", "", szBuf, sizeof(szBuf), szFileIniInstall)) + { + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + lstrcat(szMessageBuf, " "); // add 4 indentation spaces + lstrcat(szMessageBuf, sgProduct.szProgramFolderName); + lstrcat(szMessageBuf, "\r\n"); + + if(GetTotalArchivesToDownload() > 0) + { + lstrcat(szMessageBuf, "\r\n"); + + /* site selector info */ + if(GetPrivateProfileString("Messages", "STR_DOWNLOAD_SITE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + { + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + + lstrcat(szMessageBuf, " "); // add 4 indentation spaces + lstrcat(szMessageBuf, szSiteSelectorDescription); // site selector description + lstrcat(szMessageBuf, "\r\n"); + + if(diAdditionalOptions.bSaveInstaller) + { + lstrcat(szMessageBuf, "\r\n"); + + /* site selector info */ + if(GetPrivateProfileString("Messages", "STR_SAVE_INSTALLER_FILES", "", szBuf, sizeof(szBuf), szFileIniInstall)) + { + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + + GetSaveInstallerPath(szBuf, sizeof(szBuf)); + lstrcat(szMessageBuf, " "); // add 4 indentation spaces + lstrcat(szMessageBuf, szBuf); + lstrcat(szMessageBuf, "\r\n"); + } + } + } + + return(szMessageBuf); +} + +// XXX also defined in extra.c, need to factor out + +#define SETUP_STATE_REG_KEY "Software\\%s\\%s\\%s\\Setup" + +LRESULT CALLBACK DlgProcQuickLaunch(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + LPSTR szMessage = NULL; + char szBuf[MAX_BUF]; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diQuickLaunch.szTitle); + + GetPrivateProfileString("Strings", "IDC Turbo Mode", "", szBuf, sizeof(szBuf), szFileIniConfig); + SetDlgItemText(hDlg, IDC_CHECK_TURBO_MODE, szBuf); + SetDlgItemText(hDlg, IDC_STATIC, sgInstallGui.szCurrentSettings); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szNext_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CHECK_TURBO_MODE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetDlgItemText(hDlg, IDC_MESSAGE0, diQuickLaunch.szMessage0); + SetDlgItemText(hDlg, IDC_MESSAGE1, diQuickLaunch.szMessage1); + SetDlgItemText(hDlg, IDC_MESSAGE2, diQuickLaunch.szMessage2); + + if(diQuickLaunch.bTurboModeEnabled) + ShowWindow(GetDlgItem(hDlg, IDC_CHECK_TURBO_MODE), SW_SHOW); + else + { + ShowWindow(GetDlgItem(hDlg, IDC_CHECK_TURBO_MODE), SW_HIDE); + diQuickLaunch.bTurboMode = FALSE; + } + + if(diQuickLaunch.bTurboMode) + CheckDlgButton(hDlg, IDC_CHECK_TURBO_MODE, BST_CHECKED); + else + CheckDlgButton(hDlg, IDC_CHECK_TURBO_MODE, BST_UNCHECKED); + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + if(diQuickLaunch.bTurboModeEnabled) + { + if(IsDlgButtonChecked(hDlg, IDC_CHECK_TURBO_MODE) == BST_CHECKED) + diQuickLaunch.bTurboMode = TRUE; + else + diQuickLaunch.bTurboMode = FALSE; + } + + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + /* remember the last state of the TurboMode checkbox */ + if(IsDlgButtonChecked(hDlg, IDC_CHECK_TURBO_MODE) == BST_CHECKED) { + diQuickLaunch.bTurboMode = TRUE; + } + else { + diQuickLaunch.bTurboMode = FALSE; + } + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcStartInstall(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + LPSTR szMessage = NULL; + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + SetWindowText(hDlg, diStartInstall.szTitle); + + SetDlgItemText(hDlg, IDC_STATIC, sgInstallGui.szCurrentSettings); + SetDlgItemText(hDlg, IDWIZBACK, sgInstallGui.szBack_); + SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szInstall_); + SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_); + SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZBACK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_CURRENT_SETTINGS, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + if((diAdvancedSettings.bShowDialog == FALSE) || (GetTotalArchivesToDownload() == 0)) + { + ShowWindow(GetDlgItem(hDlg, IDC_BUTTON_SITE_SELECTOR), SW_HIDE); + SetDlgItemText(hDlg, IDC_MESSAGE0, diStartInstall.szMessageInstall); + } + else + { + ShowWindow(GetDlgItem(hDlg, IDC_BUTTON_SITE_SELECTOR), SW_SHOW); + SetDlgItemText(hDlg, IDC_MESSAGE0, diStartInstall.szMessageDownload); + } + + if((szMessage = GetStartInstallMessage()) != NULL) + { + SetDlgItemText(hDlg, IDC_CURRENT_SETTINGS, szMessage); + FreeMemory(&szMessage); + } + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(NEXT_DLG); + break; + + case IDWIZBACK: + SaveWindowPosition(hDlg); + DestroyWindow(hDlg); + DlgSequence(PREV_DLG); + break; + + case IDCANCEL: + AskCancelDlg(hDlg); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcReboot(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + HWND hRadioYes; + + hRadioYes = GetDlgItem(hDlg, IDC_RADIO_YES); + + switch(msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hDlg, FALSE); + CheckDlgButton(hDlg, IDC_RADIO_YES, BST_CHECKED); + SetFocus(hRadioYes); + + RepositionWindow(hDlg, NO_BANNER_IMAGE); + + SetWindowText(hDlg, sgInstallGui.szRestart); + SetDlgItemText(hDlg, 202, sgInstallGui.szSetupMessage); + SetDlgItemText(hDlg, IDC_RADIO_YES, sgInstallGui.szYesRestart); + SetDlgItemText(hDlg, IDC_RADIO_NO, sgInstallGui.szNoRestart); + SetDlgItemText(hDlg, IDOK, sgInstallGui.szOk); + SendDlgItemMessage (hDlg, 202, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_RADIO_YES, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_RADIO_NO, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hDlg, IDOK, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + break; + + case WM_COMMAND: + SaveWindowPosition(hDlg); + switch(LOWORD(wParam)) + { + case IDOK: + if(IsDlgButtonChecked(hDlg, IDC_RADIO_YES) == BST_CHECKED) + { + // Get a token for this process. + OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); + + // Get the LUID for the shutdown privilege. + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the shutdown privilege for this process. + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); + + DestroyWindow(hDlg); + PostQuitMessage(0); + DestroyWindow(hWndMain); + + // Reboot the system and force all applications to close. + ExitWindowsEx(EWX_REBOOT, 0); + } + else + { + DestroyWindow(hDlg); + PostQuitMessage(0); + } + break; + + case IDCANCEL: + DestroyWindow(hDlg); + PostQuitMessage(0); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcMessage(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + RECT rDlg; + HWND hSTMessage = GetDlgItem(hDlg, IDC_MESSAGE); /* handle to the Static Text message window */ + HDC hdcSTMessage; + SIZE sizeString; + LOGFONT logFont; + HFONT hfontTmp; + HFONT hfontOld; + char szBuf[MAX_BUF]; + char szBuf2[MAX_BUF]; + + ZeroMemory(szBuf, sizeof(szBuf)); + ZeroMemory(szBuf2, sizeof(szBuf2)); + + switch(msg) + { + case WM_INITDIALOG: + if(GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf2, sizeof(szBuf2), szFileIniInstall)) + { + if((sgProduct.szProductName != NULL) && (*sgProduct.szProductName != '\0')) + wsprintf(szBuf, szBuf2, sgProduct.szProductName); + else + wsprintf(szBuf, szBuf2, ""); + } + else if((sgProduct.szProductName != NULL) && (*sgProduct.szProductName != '\0')) + lstrcpy(szBuf, sgProduct.szProductName); + + SetWindowText(hDlg, szBuf); + RepositionWindow(hDlg, NO_BANNER_IMAGE); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_MESSAGE: + SaveWindowPosition(hDlg); + hdcSTMessage = GetWindowDC(hSTMessage); + + SystemParametersInfo(SPI_GETICONTITLELOGFONT, + sizeof(logFont), + (PVOID)&logFont, + 0); + hfontTmp = CreateFontIndirect(&logFont); + + if(hfontTmp) + hfontOld = SelectObject(hdcSTMessage, hfontTmp); + + GetTextExtentPoint32(hdcSTMessage, (LPSTR)lParam, lstrlen((LPSTR)lParam), &sizeString); + SelectObject(hdcSTMessage, hfontOld); + DeleteObject(hfontTmp); + ReleaseDC(hSTMessage, hdcSTMessage); + + SetWindowPos(hDlg, NULL, + (gSystemInfo.lastWindowPosCenterX)-((sizeString.cx + 55)/2), + (gSystemInfo.lastWindowPosCenterY)-((sizeString.cy + 50)/2), + sizeString.cx + 55, + sizeString.cy + 50, + SWP_SHOWWINDOW|SWP_NOZORDER); + + if(GetClientRect(hDlg, &rDlg)) + SetWindowPos(hSTMessage, + HWND_TOP, + rDlg.left, + rDlg.top, + rDlg.right, + rDlg.bottom, + SWP_SHOWWINDOW|SWP_NOZORDER); + + SetDlgItemText(hDlg, IDC_MESSAGE, (LPSTR)lParam); + break; + } + break; + } + return(0); +} + +void ProcessWindowsMessages() +{ + MSG msg; + + while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void ShowMessage(LPSTR szMessage, BOOL bShow) +{ + if(sgProduct.mode != SILENT) + { + if(bShow && szMessage) + { + char szBuf[MAX_BUF]; + + ZeroMemory(szBuf, sizeof(szBuf)); + GetPrivateProfileString("Messages", "MB_MESSAGE_STR", "", szBuf, sizeof(szBuf), szFileIniInstall); + hDlgMessage = InstantiateDialog(hWndMain, DLG_MESSAGE, szBuf, DlgProcMessage); + SendMessage(hDlgMessage, WM_COMMAND, IDC_MESSAGE, (LPARAM)szMessage); + SendDlgItemMessage (hDlgMessage, IDC_MESSAGE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + } + else + { + SaveWindowPosition(hDlgMessage); + DestroyWindow(hDlgMessage); + hDlgMessage = NULL; + } + } +} + +HWND InstantiateDialog(HWND hParent, DWORD dwDlgID, LPSTR szTitle, WNDPROC wpDlgProc) +{ + char szBuf[MAX_BUF]; + HWND hDlg = NULL; + + + if((hDlg = CreateDialog(hSetupRscInst, MAKEINTRESOURCE(dwDlgID), hParent, wpDlgProc)) == NULL) + { + char szEDialogCreate[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_DIALOG_CREATE", "", szEDialogCreate, sizeof(szEDialogCreate), szFileIniInstall)) + { + wsprintf(szBuf, szEDialogCreate, szTitle); + PrintError(szBuf, ERROR_CODE_SHOW); + } + PostQuitMessage(1); + } + + return(hDlg); +} + +/* + * Check to see if turbo is enabled. If so, do the following: + * * Log the turbo status that use had chosen. + * * Set the appropriate Windows registry keys/values. + */ +void SetTurboArgs(void) +{ + char szData[MAX_BUF]; + char szKey[MAX_BUF]; + + if(diQuickLaunch.bTurboModeEnabled) + { + /* log if the user selected the turbo mode or not */ + LogISTurboMode(diQuickLaunch.bTurboMode); + LogMSTurboMode(diQuickLaunch.bTurboMode); + + if(diQuickLaunch.bTurboMode) + strcpy( szData, "turbo=yes" ); + else + strcpy( szData, "turbo=no" ); + + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + AppendWinReg(HKEY_CURRENT_USER, + szKey, + "browserargs", + REG_SZ, + szData, + 0, + strlen( szData ) + 1, + FALSE, + FALSE ); + } +} + +void DlgSequence(int iDirection) +{ + HRESULT hrValue; + BOOL bDone = FALSE; + + do + { + gbProcessingXpnstallFiles = FALSE; + + if(iDirection == NEXT_DLG) + { + switch(dwWizardState) + { + case DLG_NONE: + dwWizardState = DLG_WELCOME; + break; + case DLG_WELCOME: + dwWizardState = DLG_LICENSE; + break; + case DLG_LICENSE: + dwWizardState = DLG_SETUP_TYPE; + break; + case DLG_SETUP_TYPE: + dwWizardState = DLG_UPGRADE; + break; + case DLG_UPGRADE: + dwWizardState = DLG_SELECT_COMPONENTS; + break; + case DLG_SELECT_COMPONENTS: + dwWizardState = DLG_SELECT_ADDITIONAL_COMPONENTS; + break; + case DLG_SELECT_ADDITIONAL_COMPONENTS: + dwWizardState = DLG_WINDOWS_INTEGRATION; + break; + case DLG_WINDOWS_INTEGRATION: + dwWizardState = DLG_PROGRAM_FOLDER; + break; + case DLG_PROGRAM_FOLDER: + dwWizardState = DLG_QUICK_LAUNCH; + break; + case DLG_QUICK_LAUNCH: + dwWizardState = DLG_ADDITIONAL_OPTIONS; + break; + case DLG_ADDITIONAL_OPTIONS: + dwWizardState = DLG_START_INSTALL; + break; + case DLG_START_INSTALL: + dwWizardState = DLG_COMMIT_INSTALL; + break; + + case DLG_ADVANCED_SETTINGS: + dwWizardState = DLG_ADDITIONAL_OPTIONS; + break; + + default: + dwWizardState = DLG_WELCOME; + break; } + } + else if(iDirection == PREV_DLG) + { + switch(dwWizardState) + { + case DLG_LICENSE: + dwWizardState = DLG_WELCOME; + break; + case DLG_SETUP_TYPE: + dwWizardState = DLG_LICENSE; + break; + case DLG_UPGRADE: + dwWizardState = DLG_SETUP_TYPE; + break; + case DLG_SELECT_COMPONENTS: + dwWizardState = DLG_SETUP_TYPE; + break; + case DLG_SELECT_ADDITIONAL_COMPONENTS: + dwWizardState = DLG_SELECT_COMPONENTS; + break; + case DLG_WINDOWS_INTEGRATION: + dwWizardState = DLG_SELECT_ADDITIONAL_COMPONENTS; + break; + case DLG_PROGRAM_FOLDER: + dwWizardState = DLG_WINDOWS_INTEGRATION; + break; + case DLG_QUICK_LAUNCH: + dwWizardState = DLG_PROGRAM_FOLDER; + break; + case DLG_ADDITIONAL_OPTIONS: + dwWizardState = DLG_QUICK_LAUNCH; + break; + case DLG_START_INSTALL: + dwWizardState = DLG_ADDITIONAL_OPTIONS; + break; + + case DLG_ADVANCED_SETTINGS: + dwWizardState = DLG_ADDITIONAL_OPTIONS; + break; + + default: + dwWizardState = DLG_WELCOME; + break; + } + } + else if(iDirection == OTHER_DLG_1) + { + switch(dwWizardState) + { + case DLG_ADDITIONAL_OPTIONS: + dwWizardState = DLG_ADVANCED_SETTINGS; + break; + + // You'll get here only if DLG_ADVANCED_SETTINGS is not displayed, which really should + // should never be the case unless DLG_ADDITIONAL_OPTIONS is also not displayed, since this + // is a button off that dialog. But if the user turns this off in error, handling the case + // will keep from dropping into an infinite loop. + case DLG_ADVANCED_SETTINGS: + dwWizardState = DLG_ADDITIONAL_OPTIONS; + break; + } + } + + switch(dwWizardState) + { + case DLG_WELCOME: + if(diWelcome.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diWelcome.szTitle, DlgProcWelcome); + bDone = TRUE; + } + break; + + case DLG_LICENSE: + if(diLicense.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diLicense.szTitle, DlgProcLicense); + bDone = TRUE; + } + break; + + case DLG_SETUP_TYPE: + if(diSetupType.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diSetupType.szTitle, DlgProcSetupType); + bDone = TRUE; + } + break; + + case DLG_UPGRADE: + if(sgProduct.checkCleanupOnUpgrade) + { + char buf[MAX_BUF]; + + // Found destination folder. check to see if we're upgrading ontop + // of a previous installation. If so, we need to prompt the user + // about removing the entire dir before installation happens. + MozCopyStr(sgProduct.szPath, buf, sizeof(buf)); + AppendBackSlash(buf, sizeof(buf)); + lstrcat(buf, sgProduct.szProgramName); + if(FileExists(buf)) + { + char warningTitleString[MAX_BUF]; + + GetPrivateProfileString("Messages", "MB_WARNING_STR", "", + warningTitleString, sizeof(warningTitleString), + szFileIniInstall); + + /* Prompt user if deleting target path is okay. Only show + * prompt if the setup is running in normal mode, else + * assume user wants deletion */ + if(sgProduct.mode == NORMAL) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, + warningTitleString, DlgProcUpgrade); + bDone = TRUE; + } + else + sgProduct.doCleanupOnUpgrade = TRUE; + } + } + + /* SiCNodeSetItemsSelected() is called from within DlgProcUpgrade(). + * If DlgProcUpgrade is not called (in the case of a !NORMAL install), + * then we need to call it here. */ + if(sgProduct.mode != NORMAL) + SiCNodeSetItemsSelected(dwSetupType); + + break; + + case DLG_SELECT_COMPONENTS: + if((diSelectComponents.bShowDialog) && (sgProduct.dwCustomType == dwSetupType)) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diSelectComponents.szTitle, DlgProcSelectComponents); + bDone = TRUE; + } + break; + + case DLG_SELECT_ADDITIONAL_COMPONENTS: + if((diSelectAdditionalComponents.bShowDialog) && (GetAdditionalComponentsCount() > 0)) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diSelectAdditionalComponents.szTitle, DlgProcSelectAdditionalComponents); + bDone = TRUE; + } + break; + + case DLG_WINDOWS_INTEGRATION: + if(diWindowsIntegration.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diWindowsIntegration.szTitle, DlgProcWindowsIntegration); + bDone = TRUE; + } + break; + + case DLG_PROGRAM_FOLDER: + if(diProgramFolder.bShowDialog && (sgProduct.dwCustomType == dwSetupType)) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diProgramFolder.szTitle, DlgProcProgramFolder); + bDone = TRUE; + } + break; + + case DLG_ADVANCED_SETTINGS: + if(diAdvancedSettings.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diAdvancedSettings.szTitle, DlgProcAdvancedSettings); + bDone = TRUE; + } + break; + + case DLG_QUICK_LAUNCH: + if(diQuickLaunch.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diQuickLaunch.szTitle, DlgProcQuickLaunch); + bDone = TRUE; + } + break; + + case DLG_ADDITIONAL_OPTIONS: + do + { + hrValue = VerifyDiskSpace(); + if(hrValue == IDOK) + { + /* show previous visible window */ + iDirection = PREV_DLG; + } + else if(hrValue == IDCANCEL) + { + AskCancelDlg(hWndMain); + hrValue = IDRETRY; + } + }while(hrValue == IDRETRY); + + if(hrValue != IDOK) + { + if(ShowAdditionalOptionsDialog() == TRUE) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diAdditionalOptions.szTitle, DlgProcAdditionalOptions); + bDone = TRUE; + } + } + break; + + case DLG_START_INSTALL: + if(diStartInstall.bShowDialog) + { + hDlgCurrent = InstantiateDialog(hWndMain, dwWizardState, diStartInstall.szTitle, DlgProcStartInstall); + bDone = TRUE; + } + break; + + case DLG_COMMIT_INSTALL: + gbProcessingXpnstallFiles = TRUE; + CommitInstall(); + bDone = TRUE; + break; + } + } while(!bDone); +} + +void CommitInstall(void) +{ + HRESULT hrErr; + char szDestPath[MAX_BUF]; + char szInstallLogFile[MAX_BUF]; + long RetrieveResults; + + LogISShared(); + LogISDestinationPath(); + LogISSetupType(); + LogISComponentsSelected(); + LogISComponentsToDownload(); + LogISDiskSpace(gdsnComponentDSRequirement); + + lstrcpy(szDestPath, sgProduct.szPath); + if(*sgProduct.szSubPath != '\0') + { + AppendBackSlash(szDestPath, sizeof(szDestPath)); + lstrcat(szDestPath, sgProduct.szSubPath); + } + AppendBackSlash(szDestPath, sizeof(szDestPath)); + + /* Create the destination path here in case it had not been created, + * as in the case of silent or auto mode installs */ + if(CreateDirectoriesAll(szDestPath, ADD_TO_UNINSTALL_LOG) != WIZ_OK) + { + char buf[MAX_BUF]; + char errorCreateDir[MAX_BUF]; + char pathToShow[MAX_PATH]; + + /* reformat the path to display so that it'll be readable in the + * error dialog shown */ + _snprintf(pathToShow, sizeof(pathToShow), "\"%s\" ", szDestPath); + pathToShow[sizeof(pathToShow) - 1] = '\0'; + if(GetPrivateProfileString("Messages", "ERROR_CREATE_DIRECTORY", "", errorCreateDir, sizeof(errorCreateDir), szFileIniInstall)) + wsprintf(buf, errorCreateDir, pathToShow); + assert(*buf != '\0'); + PrintError(buf, ERROR_CODE_HIDE); + PostQuitMessage(1); + return; + } + + /* Set global var, that determines where the log file is to update, to + * not use the TEMP dir *before* the FileCopy() calls because we want + * to log the FileCopy() calls to where the log files were copied to. + * This is possible because the logging, that is done within the + * FileCopy() function, is done after the actual copy + */ + gbILUseTemp = FALSE; + + /* copy the install_wizard.log file from the temp\ns_temp dir to + * the destination dir and use the new destination file to continue + * logging. + */ + lstrcpy(szInstallLogFile, szTempDir); + AppendBackSlash(szInstallLogFile, sizeof(szInstallLogFile)); + lstrcat(szInstallLogFile, FILE_INSTALL_LOG); + FileCopy(szInstallLogFile, szDestPath, FALSE, FALSE); + DeleteFile(szInstallLogFile); + + /* copy the install_status.log file from the temp\ns_temp dir to + * the destination dir and use the new destination file to continue + * logging. + */ + lstrcpy(szInstallLogFile, szTempDir); + AppendBackSlash(szInstallLogFile, sizeof(szInstallLogFile)); + lstrcat(szInstallLogFile, FILE_INSTALL_STATUS_LOG); + FileCopy(szInstallLogFile, szDestPath, FALSE, FALSE); + DeleteFile(szInstallLogFile); + + /* PRE_DOWNLOAD process file manipulation functions */ + RetrieveResults = WIZ_OK; + if(sgProduct.bInstallFiles) + { + ProcessFileOpsForAll(T_PRE_DOWNLOAD); + RetrieveResults = RetrieveArchives(); + } + + if(RetrieveResults == WIZ_OK) + { + // Clean up old versions of GRE previously installed. + // These GREs should only be fully uninstalled if they were only + // being used by the mozilla that we're installing over/ontop of + // (upgrade scenario). + // We should only do this type of cleanup if we're about to install' + // GRE in shared mode. + // + // This should only be called when the installer is installing GRE! + if(IsInstallerProductGRE()) + CleanupOrphanedGREs(); + + if(sgProduct.bInstallFiles) + { + /* Check to see if Turbo is required. If so, set the + * appropriate Windows registry keys */ + SetTurboArgs(); + + /* POST_DOWNLOAD process file manipulation functions */ + ProcessFileOpsForAll(T_POST_DOWNLOAD); + /* PRE_XPCOM process file manipulation functions */ + ProcessFileOpsForAll(T_PRE_XPCOM); + + /* save the installer files in the local machine */ + if(diAdditionalOptions.bSaveInstaller) + SaveInstallerFiles(); + + if(CheckInstances()) + { + bSDUserCanceled = TRUE; + CleanupXpcomFile(); + PostQuitMessage(0); + + return; + } + + /* Remove the previous installation of the product here. + * This should be done before processing the Xpinstall engine. */ + if(sgProduct.doCleanupOnUpgrade) + { + SetSetupState(SETUP_STATE_REMOVING_PREV_INST); + CleanupOnUpgrade(); + } + + if(gbDownloadTriggered || gbPreviousUnfinishedDownload) + SetSetupState(SETUP_STATE_UNPACK_XPCOM); + + if(ProcessXpinstallEngine() != WIZ_OK) + { + bSDUserCanceled = TRUE; + CleanupXpcomFile(); + PostQuitMessage(0); + + return; + } + + if(gbDownloadTriggered || gbPreviousUnfinishedDownload) + SetSetupState(SETUP_STATE_INSTALL_XPI); // clears and sets new setup state + + /* POST_XPCOM process file manipulation functions */ + ProcessFileOpsForAll(T_POST_XPCOM); + /* PRE_SMARTUPDATE process file manipulation functions */ + ProcessFileOpsForAll(T_PRE_SMARTUPDATE); + + lstrcat(szDestPath, "uninstall\\"); + CreateDirectoriesAll(szDestPath, ADD_TO_UNINSTALL_LOG); + hrErr = SmartUpdateJars(); + } + else + hrErr = WIZ_OK; + + if((hrErr == WIZ_OK) || (hrErr == 999)) + { + if(sgProduct.bInstallFiles) + UpdateJSProxyInfo(); + + /* POST_SMARTUPDATE process file manipulation functions */ + ProcessFileOpsForAll(T_POST_SMARTUPDATE); + + if(sgProduct.bInstallFiles) + { + /* PRE_LAUNCHAPP process file manipulation functions */ + ProcessFileOpsForAll(T_PRE_LAUNCHAPP); + + LaunchApps(); + + // Refresh system icons if necessary + if(gSystemInfo.bRefreshIcons) + RefreshIcons(); + + UnsetSetupState(); // clear setup state + ClearWinRegUninstallFileDeletion(); + if(!gbIgnoreProgramFolderX) + ProcessProgramFolderShowCmd(); + + CleanupArgsRegistry(); + CleanupPreviousVersionRegKeys(); + + /* POST_LAUNCHAPP process file manipulation functions */ + ProcessFileOpsForAll(T_POST_LAUNCHAPP); + /* DEPEND_REBOOT process file manipulation functions */ + ProcessFileOpsForAll(T_DEPEND_REBOOT); + } + + CleanupXpcomFile(); + if(NeedReboot()) + { + LogExitStatus("Reboot"); + if(sgProduct.mode == NORMAL) + hDlgCurrent = InstantiateDialog(hWndMain, DLG_RESTART, diReboot.szTitle, DlgProcReboot); + else + PostQuitMessage(0); + } + else + PostQuitMessage(0); + } + else + { + CleanupXpcomFile(); + PostQuitMessage(0); + } + } + else + { + bSDUserCanceled = TRUE; + CleanupXpcomFile(); + CleanupArgsRegistry(); + PostQuitMessage(0); + } + gbProcessingXpnstallFiles = FALSE; +} diff --git a/toolkit/mozapps/installer/windows/wizard/setup/dialogs.h b/toolkit/mozapps/installer/windows/wizard/setup/dialogs.h new file mode 100644 index 00000000000..3331bfb613d --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/dialogs.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _DIALOGS_H_ +#define _DIALOGS_H_ + +LRESULT CALLBACK DlgProcMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK DlgProcWelcome(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcLicense(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcSetupType(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcSelectComponents(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcSelectAdditionalComponents(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcWindowsIntegration(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcProgramFolder(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcAdditionalOptions(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcAdvancedSettings(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcQuickLaunch(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcSiteSelector(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcStartInstall(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcReboot(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcMessage(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK NewListBoxWndProc( HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK DlgProcUpgrade(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); + +void ToggleCheck(HWND hwndListBox, DWORD dwIndex, DWORD dwACFlag); +BOOL AskCancelDlg(HWND hDlg); +void lbAddItem(HWND hList, siC *siCComponent); +HWND InstantiateDialog(HWND hParent, DWORD dwDlgID, LPSTR szTitle, WNDPROC wpDlgProc); +void DlgSequence(int iDirection); +void PaintGradientShade(HWND hWnd, HDC hdc); +BOOL BrowseForDirectory(HWND hDlg, char *szCurrDir); +LRESULT CALLBACK BrowseHookProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +void ShowMessage(LPSTR szMessage, BOOL bShow); +void DrawLBText(LPDRAWITEMSTRUCT lpdis, DWORD dwACFlag); +void DrawCheck(LPDRAWITEMSTRUCT lpdis, DWORD dwACFlag); +void InvalidateLBCheckbox(HWND hwndListBox); +void ProcessWindowsMessages(void); +LPSTR GetStartInstallMessage(void); +void AppendStringWOAmpersand(LPSTR szInputString, DWORD dwInputStringSize, LPSTR szString); +void TruncateString(HWND hWnd, LPSTR szInPath, LPSTR szOutPath, DWORD dwOutPathBufSize); +void SaveAdditionalOptions(HWND hDlg, HWND hwndCBSiteSelector); +WNDPROC SubclassWindow( HWND hWnd, WNDPROC NewWndProc); +LRESULT CALLBACK ListBoxBrowseWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void DisableSystemMenuItems(HWND hWnd, BOOL bDisableClose); +void CommitInstall(void); +void RepositionWindow(HWND aHwndDlg, DWORD aBannerImage); +void SaveWindowPosition(HWND aDlg); + +#endif /* _DIALOGS_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/extern.h b/toolkit/mozapps/installer/windows/wizard/setup/extern.h new file mode 100644 index 00000000000..a6a4a1f1e92 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/extern.h @@ -0,0 +1,109 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _EXTERN_H_ +#define _EXTERN_H_ + +#include "setup.h" + +/* external global variables */ +extern HINSTANCE hInst; +extern HINSTANCE hSetupRscInst; +extern HINSTANCE hSDInst; +extern HINSTANCE hXPIStubInst; + +extern HBITMAP hbmpBoxChecked; +extern HBITMAP hbmpBoxCheckedDisabled; +extern HBITMAP hbmpBoxUnChecked; + +extern HANDLE hAccelTable; + +extern HWND hDlgCurrent; +extern HWND hDlgMessage; +extern HWND hWndMain; + +extern LPSTR szEGlobalAlloc; +extern LPSTR szEStringLoad; +extern LPSTR szEDllLoad; +extern LPSTR szEStringNull; +extern LPSTR szEOutOfMemory; +extern LPSTR szTempSetupPath; + +extern LPSTR szSetupDir; +extern LPSTR szTempDir; +extern LPSTR szOSTempDir; +extern LPSTR szFileIniConfig; +extern LPSTR szFileIniInstall; + +extern LPSTR szSiteSelectorDescription; + +extern DWORD dwWizardState; +extern DWORD dwSetupType; + +extern DWORD dwTempSetupType; +extern DWORD gdwUpgradeValue; +extern DWORD gdwSiteSelectorStatus; + +extern BOOL bSDUserCanceled; +extern BOOL bIdiArchivesExists; +extern BOOL bCreateDestinationDir; +extern BOOL bReboot; +extern BOOL gbILUseTemp; +extern BOOL gbPreviousUnfinishedDownload; +extern BOOL gbIgnoreRunAppX; +extern BOOL gbIgnoreProgramFolderX; +extern BOOL gbRestrictedAccess; +extern BOOL gbDownloadTriggered; +extern BOOL gbAllowMultipleInstalls; +extern BOOL gbForceInstall; +extern BOOL gbForceInstallGre; +extern BOOL gShowBannerImage; + +extern setupGen sgProduct; +extern diS diSetup; +extern diW diWelcome; +extern diQL diQuickLaunch; +extern diL diLicense; +extern diST diSetupType; +extern diSC diSelectComponents; +extern diSC diSelectAdditionalComponents; +extern diWI diWindowsIntegration; +extern diPF diProgramFolder; +extern diDO diAdditionalOptions; +extern diAS diAdvancedSettings; +extern diSI diStartInstall; +extern diD diDownload; +extern diR diReboot; +extern siSD siSDObject; +extern siCF siCFXpcomFile; +extern siC *siComponents; +extern ssi *ssiSiteSelector; +extern char *SetupFileList[]; +extern installGui sgInstallGui; +extern sems gErrorMessageStream; +extern sysinfo gSystemInfo; +extern dsN *gdsnComponentDSRequirement; + +#endif /* _EXTERN_H */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/extra.c b/toolkit/mozapps/installer/windows/wizard/setup/extra.c new file mode 100644 index 00000000000..1b910c04afb --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/extra.c @@ -0,0 +1,9101 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + * Curt Patrick + */ + +#include "extern.h" +#include "extra.h" +#include "process.h" +#include "dialogs.h" +#include "ifuncns.h" +#include "xpnetHook.h" +#include "time.h" +#include "xpi.h" +#include "logging.h" +#include "nsEscape.h" +#include +#include +#include + +// shellapi.h is needed to build with WIN32_LEAN_AND_MEAN +#include + +#define HIDWORD(l) ((DWORD) (((ULONG) (l) >> 32) & 0xFFFF)) +#define LODWORD(l) ((DWORD) (l)) + +#define DEFAULT_ICON_SIZE 32 + +#define FTPSTR_LEN (sizeof(szFtp) - 1) +#define HTTPSTR_LEN (sizeof(szHttp) - 1) + +ULONG (PASCAL *NS_GetDiskFreeSpace)(LPCTSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); +ULONG (PASCAL *NS_GetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); +HRESULT InitGre(greInfo *gre); +void DeInitGre(greInfo *gre); +void UpdateGreInstallerCmdLine(greInfo *aGre, char *aParameter, DWORD aParameterBufSize, BOOL forExistingGre); +void LaunchExistingGreInstaller(greInfo *gre); +HRESULT GetInstalledGreConfigIni(greInfo *aGre, char *aGreConfigIni, DWORD aGreConfigIniBufSize); +HRESULT GetInfoFromInstalledGreConfigIni(greInfo *aGre); +HRESULT DetermineGreComponentDestinationPath(char *aInPath, char *aOutPath, DWORD aOutPathBufSize); +BOOL IsOkToRemoveFileOrDirname(char *aFileOrDirname, char **aListToIgnore, +int aListToIgnoreLength, char **aListProfileObjects, int aListProfileLength); +int GetTotalNumKeys(char *aSectionName, char *aBaseKeyName); +void CleanupArrayList(char **aList, int aListLength); +char **BuildArrayList(char *aSectionName, char *aBaseKeyName, int *aArrayLength); +BOOL IsDirAProfileDir(char *aParentPath, char **aListProfileObjects, int aListLength); + +static greInfo gGre; + +char *ArchiveExtensions[] = {"zip", + "xpi", + "jar", + ""}; + +// Path and filename to the GRE's uninstaller. This is used to cleanup +// old versions of GRE that have been orphaned when upgrading mozilla. +#define GRE_UNINSTALLER_FILE "[WINDIR]\\GREUninstall.exe" + +#define GRE_REG_KEY "Software\\mozilla.org\\GRE" +#define SETUP_STATE_REG_KEY "Software\\%s\\%s\\%s\\Setup" +#define APP_PATHS_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s" + +//GRE app installer progress bar integration +typedef LONG (CALLBACK* LPFNDLLFUNC)(LPCTSTR,INT); + +#define GRE_APP_INSTALLER_PROXY_DLL "ProgUpd.dll" +#define GRE_PROXY_UPD_FUNC "StdUpdateProgress" +#define GRE_INSTALLER_ID "gre" + +#define FOR_EXISTING_GRE TRUE +#define FOR_NEW_GRE FALSE + +LPSTR szProxyDLLPath; +LPFNDLLFUNC lpfnProgressUpd; +HINSTANCE hGREAppInstallerProxyDLL; + +BOOL gGreInstallerHasRun = FALSE; + +BOOL InitDialogClass(HINSTANCE hInstance, HINSTANCE hSetupRscInst) +{ + WNDCLASS wc; + + wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW; + wc.lpfnWndProc = DefDlgProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = DLGWINDOWEXTRA; + wc.hInstance = hSetupRscInst; + wc.hIcon = LoadIcon(hSetupRscInst, MAKEINTRESOURCE(IDI_SETUP)); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = CLASS_NAME_SETUP_DLG; + + return(RegisterClass(&wc)); +} + +BOOL InitApplication(HINSTANCE hInstance, HINSTANCE hSetupRscInst) +{ + BOOL bRv; + WNDCLASS wc; + + wc.style = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC | CS_SAVEBITS; + wc.lpfnWndProc = DefWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hSetupRscInst, MAKEINTRESOURCE(IDI_SETUP)); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_ACTIVECAPTION + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = CLASS_NAME_SETUP; + + bRv = RegisterClass(&wc); + if(bRv == FALSE) + return(bRv); + + return(InitDialogClass(hInstance, hSetupRscInst)); +} + +BOOL InitInstance(HINSTANCE hInstance, DWORD dwCmdShow) +{ + HWND hWnd; + + gSystemInfo.dwScreenX = GetSystemMetrics(SM_CXSCREEN); + gSystemInfo.dwScreenY = GetSystemMetrics(SM_CYSCREEN); + + gSystemInfo.lastWindowPosCenterX = gSystemInfo.dwScreenX / 2; + gSystemInfo.lastWindowPosCenterY = gSystemInfo.dwScreenY / 2; + + hInst = hInstance; + + /* This window is only for the purpose of allowing the self-extracting .exe + * code to detect that a setup.exe is currenly running and do the appropriate + * action given certain conditions. This window is created and left in the + * invisible state. + * There's no other purpose for this window at this time. + */ + hWnd = CreateWindow(CLASS_NAME_SETUP, + DEFAULT_SETUP_WINDOW_NAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + -150, + -50, + 1, + 1, + NULL, + NULL, + hInstance, + NULL); + + if(!hWnd) + return(FALSE); + + hWndMain = NULL; + + return(TRUE); +} + +void PrintError(LPSTR szMsg, DWORD dwErrorCodeSH) +{ + DWORD dwErr; + char szErrorString[MAX_BUF]; + + if(dwErrorCodeSH == ERROR_CODE_SHOW) + { + dwErr = GetLastError(); + wsprintf(szErrorString, "%d : %s", dwErr, szMsg); + } + else + wsprintf(szErrorString, "%s", szMsg); + + if((sgProduct.mode != SILENT) && (sgProduct.mode != AUTO)) + { + MessageBox(hWndMain, szErrorString, NULL, MB_ICONEXCLAMATION); + } + else if(sgProduct.mode == AUTO) + { + ShowMessage(szErrorString, TRUE); + Delay(5); + ShowMessage(szErrorString, FALSE); + } +} + +/* Windows API does offer a GlobalReAlloc() routine, but it kept + * returning an out of memory error for subsequent calls to it + * after the first time, thus the reason for this routine. */ +void *NS_GlobalReAlloc(HGLOBAL *hgMemory, + DWORD dwMemoryBufSize, + DWORD dwNewSize) +{ + HGLOBAL hgPtr = NULL; + + if((hgPtr = NS_GlobalAlloc(dwNewSize)) == NULL) + return(NULL); + else + { + memcpy(hgPtr, *hgMemory, dwMemoryBufSize); + FreeMemory(hgMemory); + *hgMemory = hgPtr; + return(hgPtr); + } +} + +void *NS_GlobalAlloc(DWORD dwMaxBuf) +{ + void *vBuf = NULL; + + if((vBuf = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, dwMaxBuf)) == NULL) + { + if((szEGlobalAlloc == NULL) || (*szEGlobalAlloc == '\0')) + PrintError(TEXT("Memory allocation error."), ERROR_CODE_HIDE); + else + PrintError(szEGlobalAlloc, ERROR_CODE_SHOW); + + return(NULL); + } + else + return(vBuf); +} + +void FreeMemory(void **vPointer) +{ + if(*vPointer != NULL) + *vPointer = GlobalFree(*vPointer); +} + +HRESULT NS_LoadStringAlloc(HANDLE hInstance, DWORD dwID, LPSTR *szStringBuf, DWORD dwStringBuf) +{ + char szBuf[MAX_BUF]; + + if((*szStringBuf = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + + if(!LoadString(hInstance, dwID, *szStringBuf, dwStringBuf)) + { + if((szEStringLoad == NULL) ||(*szEStringLoad == '\0')) + wsprintf(szBuf, "Could not load string resource ID %d", dwID); + else + wsprintf(szBuf, szEStringLoad, dwID); + + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + return(0); +} + +HRESULT NS_LoadString(HANDLE hInstance, DWORD dwID, LPSTR szStringBuf, DWORD dwStringBuf) +{ + char szBuf[MAX_BUF]; + + if(!LoadString(hInstance, dwID, szStringBuf, dwStringBuf)) + { + if((szEStringLoad == NULL) ||(*szEStringLoad == '\0')) + wsprintf(szBuf, "Could not load string resource ID %d", dwID); + else + wsprintf(szBuf, szEStringLoad, dwID); + + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + return(WIZ_OK); +} + +void Delay(DWORD dwSeconds) +{ + SleepEx(dwSeconds * 1000, FALSE); +} + +BOOL VerifyRestrictedAccess(void) +{ + char szSubKey[MAX_BUF]; + char szSubKeyToTest[] = "Software\\%s - Test Key"; + BOOL bRv; + DWORD dwDisp = 0; + DWORD dwErr; + HKEY hkRv; + + wsprintf(szSubKey, szSubKeyToTest, sgProduct.szCompanyName); + dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, + szSubKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hkRv, + &dwDisp); + if(dwErr == ERROR_SUCCESS) + { + RegCloseKey(hkRv); + switch(dwDisp) + { + case REG_CREATED_NEW_KEY: + RegDeleteKey(HKEY_LOCAL_MACHINE, szSubKey); + break; + + case REG_OPENED_EXISTING_KEY: + break; + } + bRv = FALSE; + } + else + bRv = TRUE; + + return(bRv); +} + +void SetInstallFilesVar(LPSTR szProdDir) +{ + char szProgramPath[MAX_BUF]; + + if(szProdDir[lstrlen(szProdDir) - 1] == '\\') + wsprintf(szProgramPath, "%s%s", szProdDir, sgProduct.szProgramName); + else + wsprintf(szProgramPath, "%s\\%s", szProdDir, sgProduct.szProgramName); + + if((!gbForceInstall) && FileExists(szProgramPath)) + sgProduct.bInstallFiles = FALSE; +} + +void UnsetSetupState(void) +{ + char szKey[MAX_BUF_TINY]; + + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + DeleteWinRegValue(HKEY_CURRENT_USER, szKey, "Setup State"); +} + +void SetSetupState(char *szState) +{ + char szKey[MAX_BUF_TINY]; + + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + + SetWinReg(HKEY_CURRENT_USER, szKey, TRUE, "Setup State", TRUE, + REG_SZ, szState, lstrlen(szState), TRUE, FALSE); +} + +DWORD GetPreviousUnfinishedState(void) +{ + char szBuf[MAX_BUF_TINY]; + char szKey[MAX_BUF_TINY]; + DWORD dwRv = PUS_NONE; + + if(sgProduct.szCompanyName && + sgProduct.szProductNameInternal && + sgProduct.szUserAgent) + { + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + GetWinReg(HKEY_CURRENT_USER, szKey, "Setup State", szBuf, sizeof(szBuf)); + if(lstrcmpi(szBuf, SETUP_STATE_DOWNLOAD) == 0) + dwRv = PUS_DOWNLOAD; + else if(lstrcmpi(szBuf, SETUP_STATE_UNPACK_XPCOM) == 0) + dwRv = PUS_UNPACK_XPCOM; + else if(lstrcmpi(szBuf, SETUP_STATE_INSTALL_XPI) == 0) + dwRv = PUS_INSTALL_XPI; + } + + return(dwRv); +} + +void UnsetSetupCurrentDownloadFile(void) +{ + char szKey[MAX_BUF]; + + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + DeleteWinRegValue(HKEY_CURRENT_USER, + szKey, + "Setup Current Download"); +} + +void SetSetupCurrentDownloadFile(char *szCurrentFilename) +{ + char szKey[MAX_BUF]; + + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + SetWinReg(HKEY_CURRENT_USER, + szKey, + TRUE, + "Setup Current Download", + TRUE, + REG_SZ, + szCurrentFilename, + lstrlen(szCurrentFilename), + TRUE, + FALSE); +} + +char *GetSetupCurrentDownloadFile(char *szCurrentDownloadFile, + DWORD dwCurrentDownloadFileBufSize) +{ + char szKey[MAX_BUF]; + + if(!szCurrentDownloadFile) + return(NULL); + + ZeroMemory(szCurrentDownloadFile, dwCurrentDownloadFileBufSize); + if(sgProduct.szCompanyName && + sgProduct.szProductNameInternal && + sgProduct.szUserAgent) + { + wsprintf(szKey, + SETUP_STATE_REG_KEY, + sgProduct.szCompanyName, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + GetWinReg(HKEY_CURRENT_USER, + szKey, + "Setup Current Download", + szCurrentDownloadFile, + dwCurrentDownloadFileBufSize); + } + + return(szCurrentDownloadFile); +} + +void UpdateGREAppInstallerProgress(int percent) +{ + if (lpfnProgressUpd) + lpfnProgressUpd(GRE_INSTALLER_ID, percent); +} + +BOOL UpdateFile(char *szInFilename, char *szOutFilename, char *szIgnoreStr) +{ + FILE *ifp; + FILE *ofp; + char szLineRead[MAX_BUF]; + char szLCIgnoreLongStr[MAX_BUF]; + char szLCIgnoreShortStr[MAX_BUF]; + char szLCLineRead[MAX_BUF]; + BOOL bFoundIgnoreStr = FALSE; + + if((ifp = fopen(szInFilename, "rt")) == NULL) + return(bFoundIgnoreStr); + if((ofp = fopen(szOutFilename, "w+t")) == NULL) + { + fclose(ifp); + return(bFoundIgnoreStr); + } + + if(lstrlen(szIgnoreStr) < sizeof(szLCIgnoreLongStr)) + { + lstrcpy(szLCIgnoreLongStr, szIgnoreStr); + CharLower(szLCIgnoreLongStr); + } + if(lstrlen(szIgnoreStr) < sizeof(szLCIgnoreShortStr)) + { + GetShortPathName(szIgnoreStr, szLCIgnoreShortStr, sizeof(szLCIgnoreShortStr)); + CharLower(szLCIgnoreShortStr); + } + + while(fgets(szLineRead, sizeof(szLineRead), ifp) != NULL) + { + lstrcpy(szLCLineRead, szLineRead); + CharLower(szLCLineRead); + if(!strstr(szLCLineRead, szLCIgnoreLongStr) && !strstr(szLCLineRead, szLCIgnoreShortStr)) + fputs(szLineRead, ofp); + else + bFoundIgnoreStr = TRUE; + } + fclose(ifp); + fclose(ofp); + + return(bFoundIgnoreStr); +} + +/* Looks for and removes the uninstaller from the Windows Registry + * that is set to delete the uninstaller at the next restart of + * Windows. This key is set/created when the user does the following: + * + * 1) Runs the uninstaller from the previous version of the product. + * 2) User does not reboot the OS and starts the installation of + * the next version of the product. + * + * This functions prevents the uninstaller from being deleted on a + * system reboot after the user performs 2). + */ +void ClearWinRegUninstallFileDeletion(void) +{ + char *szPtrIn = NULL; + char *szPtrOut = NULL; + char szInMultiStr[MAX_BUF]; + char szOutMultiStr[MAX_BUF]; + char szLCKeyBuf[MAX_BUF]; + char szLCUninstallFilenameLongBuf[MAX_BUF]; + char szLCUninstallFilenameShortBuf[MAX_BUF]; + char szWinInitFile[MAX_BUF]; + char szTempInitFile[MAX_BUF]; + char szWinDir[MAX_BUF]; + DWORD dwOutMultiStrLen; + DWORD dwType; + BOOL bFoundUninstaller = FALSE; + + if(!GetWindowsDirectory(szWinDir, sizeof(szWinDir))) + return; + + wsprintf(szLCUninstallFilenameLongBuf, "%s\\%s", szWinDir, sgProduct.szUninstallFilename); + GetShortPathName(szLCUninstallFilenameLongBuf, szLCUninstallFilenameShortBuf, sizeof(szLCUninstallFilenameShortBuf)); + CharLower(szLCUninstallFilenameLongBuf); + CharLower(szLCUninstallFilenameShortBuf); + + if(gSystemInfo.dwOSType & OS_NT) + { + ZeroMemory(szInMultiStr, sizeof(szInMultiStr)); + ZeroMemory(szOutMultiStr, sizeof(szOutMultiStr)); + + dwType = GetWinReg(HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\Session Manager", + "PendingFileRenameOperations", + szInMultiStr, + sizeof(szInMultiStr)); + if((dwType == REG_MULTI_SZ) && (szInMultiStr != '\0')) + { + szPtrIn = szInMultiStr; + szPtrOut = szOutMultiStr; + dwOutMultiStrLen = 0; + do + { + lstrcpy(szLCKeyBuf, szPtrIn); + CharLower(szLCKeyBuf); + if(!strstr(szLCKeyBuf, szLCUninstallFilenameLongBuf) && !strstr(szLCKeyBuf, szLCUninstallFilenameShortBuf)) + { + if((dwOutMultiStrLen + lstrlen(szPtrIn) + 3) <= sizeof(szOutMultiStr)) + { + /* uninstaller not found, so copy the szPtrIn string to szPtrOut buffer */ + lstrcpy(szPtrOut, szPtrIn); + dwOutMultiStrLen += lstrlen(szPtrIn) + 2; /* there are actually 2 NULL bytes between the strings */ + szPtrOut = &szPtrOut[lstrlen(szPtrIn) + 2]; /* there are actually 2 NULL bytes between the strings */ + } + else + { + bFoundUninstaller = FALSE; + /* not enough memory; break out of while loop. */ + break; + } + } + else + bFoundUninstaller = TRUE; + + szPtrIn = &szPtrIn[lstrlen(szPtrIn) + 2]; /* there are actually 2 NULL bytes between the strings */ + }while(*szPtrIn != '\0'); + } + + if(bFoundUninstaller) + { + if(dwOutMultiStrLen > 0) + { + /* take into account the 3rd NULL byte that signifies the end of the MULTI string */ + ++dwOutMultiStrLen; + SetWinReg(HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\Session Manager", + TRUE, + "PendingFileRenameOperations", + TRUE, + REG_MULTI_SZ, + szOutMultiStr, + dwOutMultiStrLen, + FALSE, + FALSE); + } + else + DeleteWinRegValue(HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\Session Manager", + "PendingFilerenameOperations"); + } + } + else + { + /* OS type is win9x */ + wsprintf(szWinInitFile, "%s\\wininit.ini", szWinDir); + wsprintf(szTempInitFile, "%s\\wininit.moz", szWinDir); + if(FileExists(szWinInitFile)) + { + if(UpdateFile(szWinInitFile, szTempInitFile, szLCUninstallFilenameLongBuf)) + CopyFile(szTempInitFile, szWinInitFile, FALSE); + + DeleteFile(szTempInitFile); + } + } +} + +HRESULT Initialize(HINSTANCE hInstance) +{ + char szBuf[MAX_BUF]; + char szCurrentProcessDir[MAX_BUF]; + + bSDUserCanceled = FALSE; + hDlgMessage = NULL; + + /* load strings from setup.exe */ + if(NS_LoadStringAlloc(hInstance, IDS_ERROR_GLOBALALLOC, &szEGlobalAlloc, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInstance, IDS_ERROR_STRING_LOAD, &szEStringLoad, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInstance, IDS_ERROR_DLL_LOAD, &szEDllLoad, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInstance, IDS_ERROR_STRING_NULL, &szEStringNull, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInstance, IDS_ERROR_OUTOFMEMORY, &szEOutOfMemory, MAX_BUF)) + return(1); + + GetModuleFileName(NULL, szBuf, sizeof(szBuf)); + ParsePath(szBuf, szCurrentProcessDir, + sizeof(szCurrentProcessDir), + FALSE, + PP_PATH_ONLY); + hAccelTable = LoadAccelerators(hInstance, CLASS_NAME_SETUP_DLG); + + if((hSetupRscInst = LoadLibraryEx("Setuprsc.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) + { + char szFullFilename[MAX_BUF]; + + lstrcpy(szFullFilename, szCurrentProcessDir); + AppendBackSlash(szFullFilename, sizeof(szFullFilename)); + lstrcat(szFullFilename, "Setuprsc.dll"); + if((hSetupRscInst = LoadLibraryEx(szFullFilename, NULL, 0)) == NULL) + { + wsprintf(szBuf, szEDllLoad, szFullFilename); + PrintError(szBuf, ERROR_CODE_HIDE); + return(WIZ_ERROR_LOADING_RESOURCE_LIB); + } + } + + dwWizardState = DLG_NONE; + dwTempSetupType = dwWizardState; + siComponents = NULL; + bCreateDestinationDir = FALSE; + bReboot = FALSE; + gdwUpgradeValue = UG_NONE; + gdwSiteSelectorStatus = SS_SHOW; + gbILUseTemp = TRUE; + gbIgnoreRunAppX = FALSE; + gbIgnoreProgramFolderX = FALSE; + + if((szSetupDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + lstrcpy(szSetupDir, szCurrentProcessDir); + + if((szTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szOSTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szProxyDLLPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szFileIniConfig = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szFileIniInstall = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + // determine the system's TEMP path + if(GetTempPath(MAX_BUF, szTempDir) == 0) + { + if(GetWindowsDirectory(szTempDir, MAX_BUF) == 0) + { + char szEGetWinDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", szEGetWinDirFailed, sizeof(szEGetWinDirFailed), szFileIniInstall)) + PrintError(szEGetWinDirFailed, ERROR_CODE_SHOW); + + return(1); + } + + AppendBackSlash(szTempDir, MAX_BUF); + lstrcat(szTempDir, "TEMP"); + } + lstrcpy(szOSTempDir, szTempDir); + AppendBackSlash(szTempDir, MAX_BUF); + lstrcat(szTempDir, WIZ_TEMP_DIR); + + /* if multiple installer instances are allowed; + each instance requires a unique temp directory + */ + if(gbAllowMultipleInstalls) + { + DWORD dwLen = lstrlen(szTempDir); + + if (strncmp(szSetupDir, szTempDir, dwLen) == 0) + { + lstrcpy(szTempDir, szSetupDir); + } + else + { + int i; + for(i = 1; i <= 100 && (FileExists(szTempDir) != FALSE); i++) + { + itoa(i, (szTempDir + dwLen), 10); + } + + if (FileExists(szTempDir) != FALSE) + { + MessageBox(hWndMain, "Cannot create temp directory", NULL, MB_OK | MB_ICONEXCLAMATION); + exit(1); + } + } + } + else + { + // we're not running in mmi mode (allow multiple instances of installer + // to run at the same time), we should look for and remove the dirs + // that are created in the mmi mode. + DWORD dwLen; + char tempDirToCleanup[MAX_BUF]; + int i = 1; + + lstrcpy(tempDirToCleanup, szTempDir); + dwLen = lstrlen(tempDirToCleanup); + itoa(i, (tempDirToCleanup + dwLen), 10); + for(i = 2; i <= 100 && (FileExists(tempDirToCleanup)); i++) + { + DirectoryRemove(tempDirToCleanup, TRUE); + itoa(i, (tempDirToCleanup + dwLen), 10); + } + } + + if(!FileExists(szTempDir)) + { + AppendBackSlash(szTempDir, MAX_BUF); + CreateDirectoriesAll(szTempDir, DO_NOT_ADD_TO_UNINSTALL_LOG); + if(!FileExists(szTempDir)) + { + char szECreateTempDir[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_CREATE_TEMP_DIR", "", szECreateTempDir, sizeof(szECreateTempDir), szFileIniInstall)) + { + wsprintf(szBuf, szECreateTempDir, szTempDir); + PrintError(szBuf, ERROR_CODE_HIDE); + } + return(1); + } + RemoveBackSlash(szTempDir); + } + + /* Check if we need to load GRE App installer proxy DLL; + this DLL lives in the Windows temp directory when the + external GRE app installer is running. If found, it + will be loaded and fed with incremental progress updates. + */ + + GetTempPath(MAX_BUF, szProxyDLLPath); + AppendBackSlash(szProxyDLLPath, MAX_BUF); + strcat(szProxyDLLPath, GRE_APP_INSTALLER_PROXY_DLL); + + if (FileExists(szProxyDLLPath) != FALSE) + hGREAppInstallerProxyDLL = LoadLibrary(szProxyDLLPath); + + if (hGREAppInstallerProxyDLL != NULL) + lpfnProgressUpd = (LPFNDLLFUNC) GetProcAddress(hGREAppInstallerProxyDLL, GRE_PROXY_UPD_FUNC); + + + hbmpBoxChecked = LoadBitmap(hSetupRscInst, MAKEINTRESOURCE(IDB_BOX_CHECKED)); + hbmpBoxCheckedDisabled = LoadBitmap(hSetupRscInst, MAKEINTRESOURCE(IDB_BOX_CHECKED_DISABLED)); + hbmpBoxUnChecked = LoadBitmap(hSetupRscInst, MAKEINTRESOURCE(IDB_BOX_UNCHECKED)); + + DeleteIdiGetConfigIni(); + bIdiArchivesExists = DeleteIdiGetArchives(); + DeleteIdiGetRedirect(); + DeleteInstallLogFile(FILE_INSTALL_LOG); + DeleteInstallLogFile(FILE_INSTALL_STATUS_LOG); + LogISTime(W_START); + DetermineOSVersionEx(); + + SystemParametersInfo(SPI_GETSCREENREADER, 0, &(gSystemInfo.bScreenReader), 0); + + return(0); +} + +/* Function to remove quotes from a string */ +void RemoveQuotes(LPSTR lpszSrc, LPSTR lpszDest, int iDestSize) +{ + char *lpszBegin; + + if(lstrlen(lpszSrc) > iDestSize) + return; + + if(*lpszSrc == '\"') + lpszBegin = &lpszSrc[1]; + else + lpszBegin = lpszSrc; + + lstrcpy(lpszDest, lpszBegin); + + if(lpszDest[lstrlen(lpszDest) - 1] == '\"') + lpszDest[lstrlen(lpszDest) - 1] = '\0'; +} + +/* Function to copy strings safely. + * returns the amount of memory required (including NULL byte) if there's not enough + * else, it returns 0 for success. + */ +int MozCopyStr(LPSTR szSrc, LPSTR szDest, DWORD dwDestBufSize) +{ + DWORD length; + + assert(szSrc); + assert(szDest); + + length = lstrlen(szSrc) + 1; + strncpy(szDest, szSrc, dwDestBufSize); + if(length > dwDestBufSize) + { + szDest[dwDestBufSize - 1] = '\0'; + return(length); + } + return(0); +} + +/* Function to locate the first non space character in a string, + * and return a pointer to it. */ +LPSTR GetFirstNonSpace(LPSTR lpszString) +{ + int i; + int iStrLength; + + iStrLength = lstrlen(lpszString); + + for(i = 0; i < iStrLength; i++) + { + if(!isspace(lpszString[i])) + return(&lpszString[i]); + } + + return(NULL); +} + +/* Function to locate the first character c in lpszString, + * and return a pointer to it. */ +LPSTR MozStrChar(LPSTR lpszString, char c) +{ + char* p = lpszString; + + if(!p) + return NULL; + + while (*p && (*p != c)) + p = CharNext(p); + + if (*p == '\0') // null means end of string + return NULL; + + return p; +} + +/* Function to return the argument count given a command line input + * format string */ +int GetArgC(LPSTR lpszCommandLine) +{ + int i; + int iArgCount; + int iStrLength; + LPSTR lpszBeginStr; + BOOL bFoundQuote; + BOOL bFoundSpace; + + iArgCount = 0; + lpszBeginStr = GetFirstNonSpace(lpszCommandLine); + + if(lpszBeginStr == NULL) + return(iArgCount); + + iStrLength = lstrlen(lpszBeginStr); + bFoundQuote = FALSE; + bFoundSpace = TRUE; + + for(i = 0; i < iStrLength; i++) + { + if(lpszCommandLine[i] == '\"') + { + if(bFoundQuote == FALSE) + { + ++iArgCount; + bFoundQuote = TRUE; + } + else + { + bFoundQuote = FALSE; + } + } + else if(bFoundQuote == FALSE) + { + if(!isspace(lpszCommandLine[i]) && (bFoundSpace == TRUE)) + { + ++iArgCount; + bFoundSpace = FALSE; + } + else if(isspace(lpszCommandLine[i])) + { + bFoundSpace = TRUE; + } + } + } + + return(iArgCount); +} + +/* Function to return a specific argument parameter from a given command line input + * format string. */ +LPSTR GetArgV(LPSTR lpszCommandLine, int iIndex, LPSTR lpszDest, int iDestSize) +{ + int i; + int j; + int iArgCount; + int iStrLength; + LPSTR lpszBeginStr; + LPSTR lpszDestTemp; + BOOL bFoundQuote; + BOOL bFoundSpace; + + iArgCount = 0; + lpszBeginStr = GetFirstNonSpace(lpszCommandLine); + + if(lpszBeginStr == NULL) + return(NULL); + + lpszDestTemp = (char *)calloc(iDestSize, sizeof(char)); + if(lpszDestTemp == NULL) + { + PrintError("Out of memory", ERROR_CODE_HIDE); + exit(1); + } + + ZeroMemory(lpszDest, iDestSize); + iStrLength = lstrlen(lpszBeginStr); + bFoundQuote = FALSE; + bFoundSpace = TRUE; + j = 0; + + for(i = 0; i < iStrLength; i++) + { + if(lpszCommandLine[i] == '\"') + { + if(bFoundQuote == FALSE) + { + ++iArgCount; + bFoundQuote = TRUE; + } + else + { + bFoundQuote = FALSE; + } + } + else if(bFoundQuote == FALSE) + { + if(!isspace(lpszCommandLine[i]) && (bFoundSpace == TRUE)) + { + ++iArgCount; + bFoundSpace = FALSE; + } + else if(isspace(lpszCommandLine[i])) + { + bFoundSpace = TRUE; + } + } + + if((iIndex == (iArgCount - 1)) && + ((bFoundQuote == TRUE) || (bFoundSpace == FALSE) || + ((bFoundQuote == FALSE) && (lpszCommandLine[i] == '\"')))) + { + if(j < iDestSize) + { + lpszDestTemp[j] = lpszCommandLine[i]; + ++j; + } + else + { + lpszDestTemp[j] = '\0'; + } + } + } + + RemoveQuotes(lpszDestTemp, lpszDest, iDestSize); + free(lpszDestTemp); + return(lpszDest); +} + +BOOL IsInArchivesLst(siC *siCObject, BOOL bModify) +{ + char *szBufPtr; + char szBuf[MAX_BUF]; + char szArchiveLstFile[MAX_BUF_MEDIUM]; + BOOL bRet = FALSE; + + lstrcpy(szArchiveLstFile, szTempDir); + AppendBackSlash(szArchiveLstFile, sizeof(szArchiveLstFile)); + lstrcat(szArchiveLstFile, "Archive.lst"); + GetPrivateProfileString("Archives", NULL, "", szBuf, sizeof(szBuf), szArchiveLstFile); + if(*szBuf != '\0') + { + szBufPtr = szBuf; + while(*szBufPtr != '\0') + { + if(lstrcmpi(siCObject->szArchiveName, szBufPtr) == 0) + { + if(bModify) + { + /* jar file found. Unset attribute to download from the net */ + siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED; + /* save the path of where jar was found at */ + lstrcpy(siCObject->szArchivePath, szTempDir); + AppendBackSlash(siCObject->szArchivePath, MAX_BUF); + } + bRet = TRUE; + + /* found what we're looking for. No need to continue */ + break; + } + szBufPtr += lstrlen(szBufPtr) + 1; + } + } + return(bRet); +} + +HRESULT ParseSetupIni() +{ + char szBuf[MAX_BUF]; + char szFileIniSetup[MAX_BUF]; + char szFileIdiGetConfigIni[MAX_BUF]; + + lstrcpy(szFileIdiGetConfigIni, szTempDir); + AppendBackSlash(szFileIdiGetConfigIni, sizeof(szFileIdiGetConfigIni)); + lstrcat(szFileIdiGetConfigIni, FILE_IDI_GETCONFIGINI); + + lstrcpy(szFileIniSetup, szSetupDir); + AppendBackSlash(szFileIniSetup, sizeof(szFileIniSetup)); + lstrcat(szFileIniSetup, FILE_INI_SETUP); + + CopyFile(szFileIniSetup, szFileIdiGetConfigIni, FALSE); + + if(!FileExists(szFileIdiGetConfigIni)) + { + char szEFileNotFound[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall)) + { + wsprintf(szBuf, szEFileNotFound, szFileIdiGetConfigIni); + PrintError(szBuf, ERROR_CODE_HIDE); + } + return(1); + } + + return(0); +} + +HRESULT GetConfigIni() +{ + char szFileIniTempDir[MAX_BUF]; + char szFileIniSetupDir[MAX_BUF]; + char szMsgRetrieveConfigIni[MAX_BUF]; + char szBuf[MAX_BUF]; + HRESULT hResult = 0; + + if(!GetPrivateProfileString("Messages", "MSG_RETRIEVE_CONFIGINI", "", szMsgRetrieveConfigIni, sizeof(szMsgRetrieveConfigIni), szFileIniInstall)) + return(1); + + lstrcpy(szFileIniTempDir, szTempDir); + AppendBackSlash(szFileIniTempDir, sizeof(szFileIniTempDir)); + lstrcat(szFileIniTempDir, FILE_INI_CONFIG); + + /* set default value for szFileIniConfig here */ + lstrcpy(szFileIniConfig, szFileIniTempDir); + + lstrcpy(szFileIniSetupDir, szSetupDir); + AppendBackSlash(szFileIniSetupDir, sizeof(szFileIniSetupDir)); + lstrcat(szFileIniSetupDir, FILE_INI_CONFIG); + + /* if config.ini exists, then use it, else download config.ini from the net */ + if(!FileExists(szFileIniTempDir)) + { + if(FileExists(szFileIniSetupDir)) + { + lstrcpy(szFileIniConfig, szFileIniSetupDir); + hResult = 0; + } + else + { + char szEFileNotFound[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall)) + { + wsprintf(szBuf, szEFileNotFound, FILE_INI_CONFIG); + PrintError(szBuf, ERROR_CODE_HIDE); + } + hResult = 1; + } + } + else + hResult = 0; + + return(hResult); +} + +HRESULT GetInstallIni() +{ + char szFileIniTempDir[MAX_BUF]; + char szFileIniSetupDir[MAX_BUF]; + char szMsgRetrieveInstallIni[MAX_BUF]; + char szBuf[MAX_BUF]; + HRESULT hResult = 0; + + if(NS_LoadString(hSetupRscInst, IDS_MSG_RETRIEVE_INSTALLINI, szMsgRetrieveInstallIni, MAX_BUF) != WIZ_OK) + return(1); + + lstrcpy(szFileIniTempDir, szTempDir); + AppendBackSlash(szFileIniTempDir, sizeof(szFileIniTempDir)); + lstrcat(szFileIniTempDir, FILE_INI_INSTALL); + + /* set default value for szFileIniInstall here */ + lstrcpy(szFileIniInstall, szFileIniTempDir); + + lstrcpy(szFileIniSetupDir, szSetupDir); + AppendBackSlash(szFileIniSetupDir, sizeof(szFileIniSetupDir)); + lstrcat(szFileIniSetupDir, FILE_INI_INSTALL); + + /* if install.ini exists, then use it, else download install.ini from the net */ + if(!FileExists(szFileIniTempDir)) + { + if(FileExists(szFileIniSetupDir)) + { + lstrcpy(szFileIniInstall, szFileIniSetupDir); + hResult = 0; + } + else + { + char szEFileNotFound[MAX_BUF]; + + if(NS_LoadString(hSetupRscInst, IDS_ERROR_FILE_NOT_FOUND, szEFileNotFound, MAX_BUF) == WIZ_OK) + { + wsprintf(szBuf, szEFileNotFound, FILE_INI_INSTALL); + PrintError(szBuf, ERROR_CODE_HIDE); + } + hResult = 1; + } + } + else + hResult = 0; + + return(hResult); +} + +int LocateJar(siC *siCObject, LPSTR szPath, int dwPathSize, BOOL bIncludeTempDir) +{ + BOOL bRet; + char szBuf[MAX_BUF * 2]; + char szSEADirTemp[MAX_BUF]; + char szSetupDirTemp[MAX_BUF]; + char szTempDirTemp[MAX_BUF]; + + /* initialize default behavior */ + bRet = AP_NOT_FOUND; + if(szPath != NULL) + ZeroMemory(szPath, dwPathSize); + siCObject->dwAttributes |= SIC_DOWNLOAD_REQUIRED; + + lstrcpy(szSEADirTemp, sgProduct.szAlternateArchiveSearchPath); + AppendBackSlash(szSEADirTemp, sizeof(szSEADirTemp)); + lstrcat(szSEADirTemp, siCObject->szArchiveName); + + /* XXX_QUICK_FIX + * checking sgProduct.szAlternateArchiveSearchPath for empty string + * should be done prior to AppendBackSlash() above. + * This is a quick fix for the time frame that we are currently in. */ + if((*sgProduct.szAlternateArchiveSearchPath != '\0') && (FileExists(szSEADirTemp))) + { + /* jar file found. Unset attribute to download from the net */ + siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED; + /* save the path of where jar was found at */ + lstrcpy(siCObject->szArchivePath, sgProduct.szAlternateArchiveSearchPath); + AppendBackSlash(siCObject->szArchivePath, MAX_BUF); + bRet = AP_ALTERNATE_PATH; + + /* save path where archive is located */ + if((szPath != NULL) && (lstrlen(sgProduct.szAlternateArchiveSearchPath) < dwPathSize)) + lstrcpy(szPath, sgProduct.szAlternateArchiveSearchPath); + } + else + { + lstrcpy(szSetupDirTemp, szSetupDir); + AppendBackSlash(szSetupDirTemp, sizeof(szSetupDirTemp)); + + lstrcpy(szTempDirTemp, szTempDir); + AppendBackSlash(szTempDirTemp, sizeof(szTempDirTemp)); + + if(lstrcmpi(szTempDirTemp, szSetupDirTemp) == 0) + { + /* check the temp dir for the .xpi file */ + lstrcpy(szBuf, szTempDirTemp); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, siCObject->szArchiveName); + + if(FileExists(szBuf)) + { + if(bIncludeTempDir == TRUE) + { + /* jar file found. Unset attribute to download from the net */ + siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED; + /* save the path of where jar was found at */ + lstrcpy(siCObject->szArchivePath, szTempDirTemp); + AppendBackSlash(siCObject->szArchivePath, MAX_BUF); + bRet = AP_TEMP_PATH; + } + + /* if the archive name is in the archive.lst file, then it was uncompressed + * by the self extracting .exe file. Assume that the .xpi file exists. + * This is a safe assumption because the self extracting.exe creates the + * archive.lst with what it uncompresses everytime it is run. */ + if(IsInArchivesLst(siCObject, TRUE)) + bRet = AP_SETUP_PATH; + + /* save path where archive is located */ + if((szPath != NULL) && (lstrlen(szTempDirTemp) < dwPathSize)) + lstrcpy(szPath, szTempDirTemp); + } + } + else + { + /* check the setup dir for the .xpi file */ + lstrcpy(szBuf, szSetupDirTemp); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, siCObject->szArchiveName); + + if(FileExists(szBuf)) + { + /* jar file found. Unset attribute to download from the net */ + siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED; + /* save the path of where jar was found at */ + lstrcpy(siCObject->szArchivePath, szSetupDirTemp); + AppendBackSlash(siCObject->szArchivePath, MAX_BUF); + bRet = AP_SETUP_PATH; + + /* save path where archive is located */ + if((szPath != NULL) && (lstrlen(sgProduct.szAlternateArchiveSearchPath) < dwPathSize)) + lstrcpy(szPath, szSetupDirTemp); + } + else + { + /* check the ns_temp dir for the .xpi file */ + lstrcpy(szBuf, szTempDirTemp); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, siCObject->szArchiveName); + + if(FileExists(szBuf)) + { + if(bIncludeTempDir == TRUE) + { + /* jar file found. Unset attribute to download from the net */ + siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED; + /* save the path of where jar was found at */ + lstrcpy(siCObject->szArchivePath, szTempDirTemp); + AppendBackSlash(siCObject->szArchivePath, MAX_BUF); + bRet = AP_TEMP_PATH; + } + + /* save path where archive is located */ + if((szPath != NULL) && (lstrlen(sgProduct.szAlternateArchiveSearchPath) < dwPathSize)) + lstrcpy(szPath, szTempDirTemp); + } + } + } + } + return(bRet); +} + +void SwapFTPAndHTTP(char *szInUrl, DWORD dwInUrlSize) +{ + char szTmpBuf[MAX_BUF]; + char *ptr = NULL; + char szFtp[] = "ftp://"; + char szHttp[] = "http://"; + + if((!szInUrl) || !diAdditionalOptions.bUseProtocolSettings) + return; + + ZeroMemory(szTmpBuf, sizeof(szTmpBuf)); + switch(diAdditionalOptions.dwUseProtocol) + { + case UP_HTTP: + if((strncmp(szInUrl, szFtp, FTPSTR_LEN) == 0) && + ((int)dwInUrlSize > lstrlen(szInUrl) + 1)) + { + ptr = szInUrl + FTPSTR_LEN; + memmove(ptr + 1, ptr, lstrlen(ptr) + 1); + memcpy(szInUrl, szHttp, HTTPSTR_LEN); + } + break; + + case UP_FTP: + default: + if((strncmp(szInUrl, szHttp, HTTPSTR_LEN) == 0) && + ((int)dwInUrlSize > lstrlen(szInUrl) + 1)) + { + ptr = szInUrl + HTTPSTR_LEN; + memmove(ptr - 1, ptr, lstrlen(ptr) + 1); + memcpy(szInUrl, szFtp, FTPSTR_LEN); + } + break; + } +} + +int UpdateIdiFile(char *szPartialUrl, + DWORD dwPartialUrlBufSize, + siC *siCObject, + char *szSection, + char *szKey, + char *szFileIdiGetArchives) +{ + char szUrl[MAX_BUF]; + char szBuf[MAX_BUF]; + char szBufTemp[MAX_BUF]; + + SwapFTPAndHTTP(szPartialUrl, dwPartialUrlBufSize); + RemoveSlash(szPartialUrl); + wsprintf(szUrl, "%s/%s", szPartialUrl, siCObject->szArchiveName); + if(WritePrivateProfileString(szSection, + szKey, + szUrl, + szFileIdiGetArchives) == 0) + { + char szEWPPS[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall)) + { + wsprintf(szBufTemp, + "%s\n [%s]\n url=%s", + szFileIdiGetArchives, + szSection, + szUrl); + wsprintf(szBuf, szEWPPS, szBufTemp); + PrintError(szBuf, ERROR_CODE_SHOW); + } + return(1); + } + return(0); +} + +HRESULT AddArchiveToIdiFile(siC *siCObject, + char *szSection, + char *szFileIdiGetArchives) +{ + char szFile[MAX_BUF]; + char szBuf[MAX_BUF]; + char szUrl[MAX_BUF]; + char szIdentifier[MAX_BUF]; + char szArchiveSize[MAX_ITOA]; + char szKey[MAX_BUF_TINY]; + int iIndex = 0; + ssi *ssiSiteSelectorTemp; + + WritePrivateProfileString(szSection, + "desc", + siCObject->szDescriptionShort, + szFileIdiGetArchives); + _ui64toa(siCObject->ullInstallSizeArchive, szArchiveSize, 10); + WritePrivateProfileString(szSection, + "size", + szArchiveSize, + szFileIdiGetArchives); + itoa(siCObject->dwAttributes & SIC_IGNORE_DOWNLOAD_ERROR, szBuf, 10); + WritePrivateProfileString(szSection, + "Ignore File Network Error", + szBuf, + szFileIdiGetArchives); + + lstrcpy(szFile, szTempDir); + AppendBackSlash(szFile, sizeof(szFile)); + lstrcat(szFile, FILE_INI_REDIRECT); + + ZeroMemory(szIdentifier, sizeof(szIdentifier)); + ssiSiteSelectorTemp = SsiGetNode(szSiteSelectorDescription); + + GetPrivateProfileString("Redirect", + "Status", + "", + szBuf, + sizeof(szBuf), + szFileIniConfig); + if(lstrcmpi(szBuf, "ENABLED") != 0) + { + /* redirect.ini is *not* enabled, so use the url from the + * config.ini's [Site Selector] section */ + if(*ssiSiteSelectorTemp->szDomain != '\0') + { + wsprintf(szKey, "url%d", iIndex); + lstrcpy(szUrl, ssiSiteSelectorTemp->szDomain); + UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives); + ++iIndex; + } + + /* use the url from the config.ini's [General] section as well */ + GetPrivateProfileString("General", + "url", + "", + szUrl, + sizeof(szUrl), + szFileIniConfig); + if(*szUrl != 0) + { + wsprintf(szKey, "url%d", iIndex); + UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives); + } + } + else if(FileExists(szFile)) + { + /* redirect.ini is enabled *and* it exists */ + GetPrivateProfileString("Site Selector", + ssiSiteSelectorTemp->szIdentifier, + "", + szUrl, + sizeof(szUrl), + szFile); + if(*szUrl != '\0') + { + wsprintf(szKey, "url%d", iIndex); + UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives); + ++iIndex; + } + + /* use the url from the config.ini's [General] section as well */ + GetPrivateProfileString("General", + "url", + "", + szUrl, + sizeof(szUrl), + szFileIniConfig); + if(*szUrl != 0) + { + wsprintf(szKey, "url%d", iIndex); + UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives); + } + } + else + { + /* redirect.ini is enabled, but the file does not exist, + * so fail over to the url from the config.ini's [General] section */ + GetPrivateProfileString("General", + "url", + "", + szUrl, + sizeof(szUrl), + szFileIniConfig); + if(*szUrl != 0) + { + wsprintf(szKey, "url%d", iIndex); + UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives); + } + } + + return(0); +} + +void SetSetupRunMode(LPSTR szMode) +{ + /* Check to see if mode has already been set. If so, + * then do not override it. + * We don't want to override this value because it could have been + * set via the command line argument as opposed to the config.ini + * having been parse. Command line arguments take precedence. + */ + if(sgProduct.mode != NOT_SET) + return; + + if(lstrcmpi(szMode, "NORMAL") == 0) + sgProduct.mode = NORMAL; + if(lstrcmpi(szMode, "AUTO") == 0) + sgProduct.mode = AUTO; + if(lstrcmpi(szMode, "SILENT") == 0) + sgProduct.mode = SILENT; +} + +BOOL CheckForArchiveExtension(LPSTR szFile) +{ + int i; + BOOL bRv = FALSE; + char szExtension[MAX_BUF_TINY]; + + /* if there is no extension in szFile, szExtension will be zero'ed out */ + ParsePath(szFile, szExtension, sizeof(szExtension), FALSE, PP_EXTENSION_ONLY); + i = 0; + while(*ArchiveExtensions[i] != '\0') + { + if(lstrcmpi(szExtension, ArchiveExtensions[i]) == 0) + { + bRv = TRUE; + break; + } + + ++i; + } + return(bRv); +} + +long RetrieveRedirectFile() +{ + long lResult; + char szBuf[MAX_BUF]; + char szBufUrl[MAX_BUF]; + char szBufTemp[MAX_BUF]; + char szIndex0[MAX_BUF]; + char szFileIdiGetRedirect[MAX_BUF]; + char szFileIniRedirect[MAX_BUF]; + ssi *ssiSiteSelectorTemp; + + if(GetTotalArchivesToDownload() == 0) + return(0); + + lstrcpy(szFileIniRedirect, szTempDir); + AppendBackSlash(szFileIniRedirect, sizeof(szFileIniRedirect)); + lstrcat(szFileIniRedirect, FILE_INI_REDIRECT); + + if(FileExists(szFileIniRedirect)) + DeleteFile(szFileIniRedirect); + + GetPrivateProfileString("Redirect", "Status", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "ENABLED") != 0) + return(0); + + ssiSiteSelectorTemp = SsiGetNode(szSiteSelectorDescription); + if(ssiSiteSelectorTemp != NULL) + { + if(ssiSiteSelectorTemp->szDomain != NULL) + lstrcpy(szBufUrl, ssiSiteSelectorTemp->szDomain); + } + else + /* No domain to download the redirect.ini file from. + * Assume that it does not exist. + * This should trigger the backup/alternate url. */ + return(0); + + lstrcpy(szFileIdiGetRedirect, szTempDir); + AppendBackSlash(szFileIdiGetRedirect, sizeof(szFileIdiGetRedirect)); + lstrcat(szFileIdiGetRedirect, FILE_IDI_GETREDIRECT); + + GetPrivateProfileString("Redirect", "Description", "", szBuf, sizeof(szBuf), szFileIniConfig); + WritePrivateProfileString("File0", "desc", szBuf, szFileIdiGetRedirect); + GetPrivateProfileString("Redirect", "Server Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + AppendSlash(szBufUrl, sizeof(szBufUrl)); + lstrcat(szBufUrl, szBuf); + SwapFTPAndHTTP(szBufUrl, sizeof(szBufUrl)); + if(WritePrivateProfileString("File0", "url", szBufUrl, szFileIdiGetRedirect) == 0) + { + char szEWPPS[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall)) + { + wsprintf(szBufTemp, "%s\n [%s]\n %s=%s", szFileIdiGetRedirect, "File0", szIndex0, szBufUrl); + wsprintf(szBuf, szEWPPS, szBufTemp); + PrintError(szBuf, ERROR_CODE_SHOW); + } + return(1); + } + + lResult = DownloadFiles(szFileIdiGetRedirect, /* input idi file to parse */ + szTempDir, /* download directory */ + diAdvancedSettings.szProxyServer, /* proxy server name */ + diAdvancedSettings.szProxyPort, /* proxy server port */ + diAdvancedSettings.szProxyUser, /* proxy server user (optional) */ + diAdvancedSettings.szProxyPasswd, /* proxy password (optional) */ + FALSE, /* show retry message */ + TRUE, /* ignore network error */ + NULL, /* buffer to store the name of failed file */ + 0); /* size of failed file name buffer */ + return(lResult); +} + +int CRCCheckDownloadedArchives(char *szCorruptedArchiveList, + DWORD dwCorruptedArchiveListSize, + char *szFileIdiGetArchives) +{ + DWORD dwIndex0; + DWORD dwFileCounter; + siC *siCObject = NULL; + char szArchivePathWithFilename[MAX_BUF]; + char szArchivePath[MAX_BUF]; + char szMsgCRCCheck[MAX_BUF]; + char szSection[MAX_INI_SK]; + int iRv; + int iResult; + + /* delete the getarchives.idi file because it needs to be recreated + * if there are any files that fails the CRC check */ + if(szFileIdiGetArchives) + DeleteFile(szFileIdiGetArchives); + + if(szCorruptedArchiveList != NULL) + ZeroMemory(szCorruptedArchiveList, dwCorruptedArchiveListSize); + + GetPrivateProfileString("Strings", "Message Verifying Archives", "", szMsgCRCCheck, sizeof(szMsgCRCCheck), szFileIniConfig); + ShowMessage(szMsgCRCCheck, TRUE); + + iResult = WIZ_CRC_PASS; + dwIndex0 = 0; + dwFileCounter = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if((siCObject->dwAttributes & SIC_SELECTED) && + !(siCObject->dwAttributes & SIC_IGNORE_DOWNLOAD_ERROR)) + { + if((iRv = LocateJar(siCObject, szArchivePath, sizeof(szArchivePath), TRUE)) == AP_NOT_FOUND) + { + char szBuf[MAX_BUF]; + char szEFileNotFound[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall)) + { + wsprintf(szBuf, szEFileNotFound, siCObject->szArchiveName); + PrintError(szBuf, ERROR_CODE_HIDE); + } + iResult = WIZ_ARCHIVES_MISSING; // not all .xpi files were downloaded + break; + } + + if(lstrlen(szArchivePath) < sizeof(szArchivePathWithFilename)) + lstrcpy(szArchivePathWithFilename, szArchivePath); + + AppendBackSlash(szArchivePathWithFilename, sizeof(szArchivePathWithFilename)); + if((lstrlen(szArchivePathWithFilename) + lstrlen(siCObject->szArchiveName)) < sizeof(szArchivePathWithFilename)) + lstrcat(szArchivePathWithFilename, siCObject->szArchiveName); + + if(CheckForArchiveExtension(szArchivePathWithFilename)) + { + /* Make sure that the Archive that failed is located in the TEMP + * folder. This means that it was downloaded at one point and not + * simply uncompressed from the self-extracting exe file. */ + if(VerifyArchive(szArchivePathWithFilename) != ZIP_OK) + { + if(iRv == AP_TEMP_PATH) + { + /* Delete the archive even though the download lib will automatically + * overwrite the file. This is in case that Setup is canceled, at the + * next restart, the file will be downloaded during the first attempt, + * not after a VerifyArchive() call. */ + DeleteFile(szArchivePathWithFilename); + wsprintf(szSection, "File%d", dwFileCounter); + ++dwFileCounter; + if(szFileIdiGetArchives) + if((AddArchiveToIdiFile(siCObject, + szSection, + szFileIdiGetArchives)) != 0) + return(WIZ_ERROR_UNDEFINED); + + ++siCObject->iCRCRetries; + if(szCorruptedArchiveList != NULL) + { + if((DWORD)(lstrlen(szCorruptedArchiveList) + lstrlen(siCObject->szArchiveName + 1)) < dwCorruptedArchiveListSize) + { + lstrcat(szCorruptedArchiveList, " "); + lstrcat(szCorruptedArchiveList, siCObject->szArchiveName); + lstrcat(szCorruptedArchiveList, "\n"); + } + } + } + iResult = WIZ_CRC_FAIL; + } + } + } + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + ShowMessage(szMsgCRCCheck, FALSE); + return(iResult); +} + +long RetrieveArchives() +{ + DWORD dwIndex0; + DWORD dwFileCounter; + BOOL bDone; + siC *siCObject = NULL; + long lResult; + char szFileIdiGetArchives[MAX_BUF]; + char szSection[MAX_BUF]; + char szCorruptedArchiveList[MAX_BUF]; + char szFailedFile[MAX_BUF]; + char szBuf[MAX_BUF]; + char szPartiallyDownloadedFilename[MAX_BUF]; + int iCRCRetries; + int iRv; + + /* retrieve the redirect.ini file */ + RetrieveRedirectFile(); + + ZeroMemory(szCorruptedArchiveList, sizeof(szCorruptedArchiveList)); + lstrcpy(szFileIdiGetArchives, szTempDir); + AppendBackSlash(szFileIdiGetArchives, sizeof(szFileIdiGetArchives)); + lstrcat(szFileIdiGetArchives, FILE_IDI_GETARCHIVES); + GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename, + sizeof(szPartiallyDownloadedFilename)); + + gbDownloadTriggered= FALSE; + lResult = WIZ_OK; + dwIndex0 = 0; + dwFileCounter = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + { + /* If a previous unfinished setup was detected, then + * include the TEMP dir when searching for archives. + * Only download jars if not already in the local machine. + * Also if the last file being downloaded should be resumed. + * The resume detection is done automatically. */ + if((LocateJar(siCObject, + NULL, + 0, + gbPreviousUnfinishedDownload) == AP_NOT_FOUND) || + (lstrcmpi(szPartiallyDownloadedFilename, + siCObject->szArchiveName) == 0)) + { + wsprintf(szSection, "File%d", dwFileCounter); + if((lResult = AddArchiveToIdiFile(siCObject, + szSection, + szFileIdiGetArchives)) != 0) + return(lResult); + + ++dwFileCounter; + } + } + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + + SetSetupState(SETUP_STATE_DOWNLOAD); + + /* iCRCRetries is initially set to 0 because the first attemp at downloading + * the archives is not considered a "retry". Subsequent downloads are + * considered retries. */ + iCRCRetries = 0; + bDone = FALSE; + do + { + /* the existence of the getarchives.idi file determines if there are + any archives needed to be downloaded */ + if(FileExists(szFileIdiGetArchives)) + { + gbDownloadTriggered = TRUE; + lResult = DownloadFiles(szFileIdiGetArchives, /* input idi file to parse */ + szTempDir, /* download directory */ + diAdvancedSettings.szProxyServer, /* proxy server name */ + diAdvancedSettings.szProxyPort, /* proxy server port */ + diAdvancedSettings.szProxyUser, /* proxy server user (optional) */ + diAdvancedSettings.szProxyPasswd, /* proxy password (optional) */ + iCRCRetries, /* show retry message */ + FALSE, /* ignore network error */ + szFailedFile, /* buffer to store the name of failed file */ + sizeof(szFailedFile)); /* size of failed file name buffer */ + if(lResult == WIZ_OK) + { + /* CRC check only the archives that were downloaded. + * It will regenerate the idi file with the list of files + * that have not passed the CRC check. */ + iRv = CRCCheckDownloadedArchives(szCorruptedArchiveList, + sizeof(szCorruptedArchiveList), + szFileIdiGetArchives); + switch(iRv) + { + case WIZ_CRC_PASS: + bDone = TRUE; + break; + + default: + bDone = FALSE; + break; + } + } + else + { + /* Download failed. Error message was already shown by DownloadFiles(). + * Simple exit loop here */ + bDone = TRUE; + } + } + else + /* no idi file, so exit loop */ + bDone = TRUE; + + if(!bDone) + { + ++iCRCRetries; + if(iCRCRetries > MAX_CRC_FAILED_DOWNLOAD_RETRIES) + bDone = TRUE; + } + + } while(!bDone); + + if(iCRCRetries > MAX_CRC_FAILED_DOWNLOAD_RETRIES) + { + /* too many retries from failed CRC checks */ + char szMsg[MAX_BUF]; + + LogISComponentsFailedCRC(szCorruptedArchiveList, W_DOWNLOAD); + GetPrivateProfileString("Strings", "Error Too Many CRC Failures", "", szMsg, sizeof(szMsg), szFileIniConfig); + if(*szMsg != '\0') + PrintError(szMsg, ERROR_CODE_HIDE); + + lResult = WIZ_CRC_FAIL; + } + else + { + if(gbDownloadTriggered) + LogISComponentsFailedCRC(NULL, W_DOWNLOAD); + } + + LogISDownloadProtocol(diAdditionalOptions.dwUseProtocol); + LogMSDownloadProtocol(diAdditionalOptions.dwUseProtocol); + + if(lResult == WIZ_OK) + { + LogISDownloadStatus("ok", NULL); + } + else if(gbDownloadTriggered) + { + wsprintf(szBuf, "failed: %d", lResult); + LogISDownloadStatus(szBuf, szFailedFile); + } + + /* We want to log the download status regardless if we downloaded or not. */ + LogMSDownloadStatus(lResult); + + if(lResult == WIZ_OK) + { + UnsetSetupCurrentDownloadFile(); + UnsetSetupState(); + } + + return(lResult); +} + +void RemoveBackSlash(LPSTR szInput) +{ + DWORD dwInputLen; + BOOL bDone; + char *ptrChar = NULL; + + if(szInput) + { + dwInputLen = lstrlen(szInput); + bDone = FALSE; + ptrChar = &szInput[dwInputLen]; + while(!bDone) + { + ptrChar = CharPrev(szInput, ptrChar); + if(*ptrChar == '\\') + *ptrChar = '\0'; + else + bDone = TRUE; + } + } +} + +void AppendBackSlash(LPSTR szInput, DWORD dwInputSize) +{ + DWORD dwInputLen = lstrlen(szInput); + + if(szInput) + { + if(*szInput == '\0') + { + if((dwInputLen + 1) < dwInputSize) + { + lstrcat(szInput, "\\"); + } + } + else if(*CharPrev(szInput, &szInput[dwInputLen]) != '\\') + { + if((dwInputLen + 1) < dwInputSize) + { + lstrcat(szInput, "\\"); + } + } + } +} + +void RemoveSlash(LPSTR szInput) +{ + DWORD dwInputLen; + BOOL bDone; + char *ptrChar = NULL; + + if(szInput) + { + dwInputLen = lstrlen(szInput); + bDone = FALSE; + ptrChar = &szInput[dwInputLen]; + while(!bDone) + { + ptrChar = CharPrev(szInput, ptrChar); + if(*ptrChar == '/') + *ptrChar = '\0'; + else + bDone = TRUE; + } + } +} + +void AppendSlash(LPSTR szInput, DWORD dwInputSize) +{ + DWORD dwInputLen = lstrlen(szInput); + + if(szInput) + { + if(*szInput == '\0') + { + if((dwInputLen + 1) < dwInputSize) + { + lstrcat(szInput, "/"); + } + } + else if(*CharPrev(szInput, &szInput[dwInputLen]) != '/') + { + if((dwInputLen + 1) < dwInputSize) + { + lstrcat(szInput, "/"); + } + } + } +} + +void ParsePath(LPSTR szInput, LPSTR szOutput, DWORD dwOutputSize, BOOL bURLPath, DWORD dwType) +{ + int iFoundDelimiter; + DWORD dwInputLen; + DWORD dwOutputLen; + BOOL bFound; + BOOL bDone = FALSE; + char cDelimiter; + char *ptrChar = NULL; + char *ptrLastChar = NULL; + + if(bURLPath) + cDelimiter = '/'; + else + cDelimiter = '\\'; + + if(szInput && szOutput) + { + bFound = TRUE; + dwInputLen = lstrlen(szInput); + ZeroMemory(szOutput, dwOutputSize); + + if(dwInputLen < dwOutputSize) + { + switch(dwType) + { + case PP_FILENAME_ONLY: + ptrChar = &szInput[dwInputLen]; + bDone = FALSE; + while(!bDone) + { + ptrChar = CharPrev(szInput, ptrChar); + if(*ptrChar == cDelimiter) + { + lstrcpy(szOutput, CharNext(ptrChar)); + bDone = TRUE; + } + else if(ptrChar == szInput) + { + /* we're at the beginning of the string and still + * nothing found. So just return the input string. */ + lstrcpy(szOutput, szInput); + bDone = TRUE; + } + } + break; + + case PP_PATH_ONLY: + lstrcpy(szOutput, szInput); + dwOutputLen = lstrlen(szOutput); + ptrChar = &szOutput[dwOutputLen]; + bDone = FALSE; + while(!bDone) + { + ptrChar = CharPrev(szOutput, ptrChar); + if(*ptrChar == cDelimiter) + { + *CharNext(ptrChar) = '\0'; + bDone = TRUE; + } + else if(ptrChar == szOutput) + { + /* we're at the beginning of the string and still + * nothing found. So just return the input string. */ + bDone = TRUE; + } + } + break; + + case PP_EXTENSION_ONLY: + /* check the last character first */ + ptrChar = CharPrev(szInput, &szInput[dwInputLen]); + if(*ptrChar == '.') + break; + + bDone = FALSE; + while(!bDone) + { + ptrChar = CharPrev(szInput, ptrChar); + if(*ptrChar == cDelimiter) + /* found path delimiter before '.' */ + bDone = TRUE; + else if(*ptrChar == '.') + { + lstrcpy(szOutput, CharNext(ptrChar)); + bDone = TRUE; + } + else if(ptrChar == szInput) + bDone = TRUE; + } + break; + + case PP_ROOT_ONLY: + lstrcpy(szOutput, szInput); + dwOutputLen = lstrlen(szOutput); + ptrLastChar = CharPrev(szOutput, &szOutput[dwOutputLen]); + ptrChar = CharNext(szOutput); + if(*ptrChar == ':') + { + ptrChar = CharNext(ptrChar); + *ptrChar = cDelimiter; + *CharNext(ptrChar) = '\0'; + } + else + { + iFoundDelimiter = 0; + ptrChar = szOutput; + while(!bDone) + { + if(*ptrChar == cDelimiter) + ++iFoundDelimiter; + + if(iFoundDelimiter == 4) + { + *CharNext(ptrChar) = '\0'; + bDone = TRUE; + } + else if(ptrChar == ptrLastChar) + bDone = TRUE; + else + ptrChar = CharNext(ptrChar); + } + } + break; + } + } + } +} + +/* Function: UpdateGreInstallerCmdLine() + * in: greInfo *aGre - contains infor needed by this function + * BOOL forExistingGre - to determine if the caller is needing the + * aParameter to be used by an existing GRE installer or by + * a new GRE installer. + * in/out: char *aParameter. + * purpose: To update the default GRE installer's command line parameters + * with new defaults depending on config.ini or cmdline arguments + * to this app's installer. + * It will also check to make sure GRE's default destination path + * is writable. If not, it will change the GRE's destination path + * to [product path]\GRE\[gre ver]. + */ +void UpdateGreInstallerCmdLine(greInfo *aGre, char *aParameter, DWORD aParameterBufSize, BOOL forExistingGre) +{ + char productPath[MAX_BUF]; + + MozCopyStr(sgProduct.szPath, productPath, sizeof(productPath)); + RemoveBackSlash(productPath); + + /* Decide GRE installer's run mode. Default should be -ma (AUTO). + * The only other possibility is -ms (SILENT). We don't want to allow + * the GRE installer to run in NORMAL mode because we don't want to + * let the user see more dialogs than they need to. */ + if(sgProduct.mode == SILENT) + lstrcat(aParameter, " -ms"); + else + lstrcat(aParameter, " -ma"); + + /* Force the install of GRE if '-greForce' is passed or if GRE + * is to be local. + * + * Passing '-f' to GRE's installer will force it to install + * regardless of version found on system. If '-f' is already + * present in the parameter, it will do no harm to pass it again. */ + if(gbForceInstallGre || (sgProduct.greType == GRE_LOCAL)) + lstrcat(aParameter, " -f"); + + /* If GRE is to be local, then instruct the GRE's installer to + * install to this application's destination path stored in + * sgProduct.szPath. + * + * We need to also instruct the GRE's installer to create a + * private windows registry GRE key instead of the default one, so + * that other apps attempting to use the global GRE will not find + * this private, local copy. They should not find this copy! */ + if(sgProduct.greType == GRE_LOCAL) + { + char buf[MAX_BUF]; + + wsprintf(buf, " -dd \"%s\" -reg_path %s", productPath, sgProduct.grePrivateKey); + lstrcat(aParameter, buf); + } + else if(!forExistingGre) + { + char buf[MAX_BUF]; + + assert(aGre); + assert(*aGre->homePath); + assert(*aGre->userAgent); + + /* Append a backslash to the path so CreateDirectoriesAll() will see the + * the last directory name as a directory instead of a file. */ + AppendBackSlash(aGre->homePath, sizeof(aGre->homePath)); + + /* Attempt to create the GRE destination directory. If it fails, we don't + * have sufficient access to the default path. We then need to install + * GRE to: + * [product path]\GRE\[gre id] + * + * This path should be guaranteed to be writable because the user had + * already created the parent path ([product path]). */ + if(DirHasWriteAccess(aGre->homePath) != WIZ_OK) + { + int rv = WIZ_OK; + + /* Update the homePath to the new destination path of where GRE will be + * installed to. homePath is used elsewhere and it needs to be + * referencing the new path, else things will break. */ + _snprintf(aGre->homePath, sizeof(aGre->homePath), "%s\\GRE\\%s\\", productPath, aGre->userAgent); + aGre->homePath[sizeof(aGre->homePath) - 1] = '\0'; + + /* CreateDirectoriesAll() is guaranteed to succeed using the new GRE + * destination path because it is a subdir of this product's destination + * path that has already been created successfully. */ + rv = CreateDirectoriesAll(aGre->homePath, ADD_TO_UNINSTALL_LOG); + assert(rv == WIZ_OK); + + /* When using the -dd option to override the GRE's destination path, the + * path must be a path which includes the GRE ID, ie: + * C:\Program Files\mozilla.org\Mozilla\GRE\1.4_0000000000 + */ + _snprintf(buf, sizeof(buf), " -dd \"%s\"", aGre->homePath); + buf[sizeof(buf) - 1] = '\0'; + lstrcat(aParameter, buf); + } + } +} + +/* Function: GetInstalledGreConfigIni() + * in: greInfo *aGre: gre class containing the location of GRE + * already installed. + * out: char *aGreConfigIni, DWORD aGreConfigIniBufSize: contains + * the full path to the installed GRE installer's config.ini + * file. + * purpose: To get the full path to the installed GRE installer's + * config.ini file. + */ +HRESULT GetInstalledGreConfigIni(greInfo *aGre, char *aGreConfigIni, DWORD aGreConfigIniBufSize) +{ + char buf[MAX_BUF]; + + if(!aGre || !aGreConfigIni || (*aGre->homePath == '\0')) + return(WIZ_ERROR_UNDEFINED); + + *aGreConfigIni = '\0'; + MozCopyStr(aGre->homePath, buf, sizeof(buf)); + AppendBackSlash(buf, sizeof(buf)); + wsprintf(aGreConfigIni, "%s%s\\%s", buf, GRE_SETUP_DIR_NAME, FILE_INI_CONFIG); + return(WIZ_OK); +} + +/* Function: GetInfoFromInstalledGreConfigIni() + * in: greInfo *aGre: gre class to fill the info for. + * out: returns info in aGre. + * purpose: To retrieve the GRE uninstaller file (full path) from + * the installed GRE's config.ini file. + * GetInfoFromGreInstaller() retrieves information from + * the (to be run) GRE installer's config.ini, not from the + * installed GRE installer's config.ini file. + */ +HRESULT GetInfoFromInstalledGreConfigIni(greInfo *aGre) +{ + HRESULT rv = WIZ_ERROR_UNDEFINED; + char greConfigIni[MAX_BUF]; + char buf[MAX_BUF]; + char greUninstallerFilename[MAX_BUF]; + + if(!aGre) + return(rv); + + *aGre->uninstallerAppPath = '\0'; + rv = GetInstalledGreConfigIni(aGre, greConfigIni, sizeof(greConfigIni)); + if(WIZ_OK == rv) + { + GetPrivateProfileString("General", "Uninstall Filename", "", greUninstallerFilename, sizeof(greUninstallerFilename), greConfigIni); + wsprintf(buf, "[WINDIR]\\%s", greUninstallerFilename); + DecryptString(aGre->uninstallerAppPath, buf); + GetPrivateProfileString("General", "User Agent", "", aGre->userAgent, sizeof(aGre->userAgent), greConfigIni); + } + return(rv); +} + +/* Function: GetInfoFromGreInstaller() + * in: char *aGreInstallerFile: full path to the GRE installer. + * greInfo *aGre: gre class to fill the homePath for. + * out: returns homePath in aGre. + * purpose: To retrieve the GRE home path from the GRE installer. + */ +void GetInfoFromGreInstaller(char *aGreInstallerFile, greInfo *aGre) +{ + char szBuf[MAX_BUF]; + char extractedConfigFile[MAX_BUF]; + int size = 0; + + if(!aGre) + return; + + /* If GRE is to be installed locally, then set it to the + * application's destination path. */ + if(sgProduct.greType == GRE_LOCAL) + { + MozCopyStr(sgProduct.szPath, aGre->homePath, sizeof(aGre->homePath)); + return; + } + + *aGre->homePath = '\0'; + + /* uncompress GRE installer's config.ini file in order to parse for: + * [General] + * Path= + * User Agent= + */ + wsprintf(szBuf, "-mmi -ms -u %s", FILE_INI_CONFIG); + WinSpawn(aGreInstallerFile, szBuf, szOSTempDir, SW_SHOWNORMAL, WS_WAIT); + MozCopyStr(szOSTempDir, extractedConfigFile, sizeof(extractedConfigFile)); + AppendBackSlash(extractedConfigFile, sizeof(extractedConfigFile)); + lstrcat(extractedConfigFile, FILE_INI_CONFIG); + GetPrivateProfileString("General", "Path", "", szBuf, sizeof(szBuf), extractedConfigFile); + DecryptString(aGre->homePath, szBuf); + GetPrivateProfileString("General", "User Agent", "", aGre->userAgent, sizeof(aGre->userAgent), extractedConfigFile); + DeleteFile(extractedConfigFile); +} + +/* Function: CleanupOrphanedGREs() + * in: none. + * out: none. + * purpose: To clean up GREs that were left on the system by previous + * installations of this product only (not by any other product). + */ +HRESULT CleanupOrphanedGREs() +{ + HKEY greIDKeyHandle; + HKEY greAppListKeyHandle; + DWORD totalGreIDSubKeys; + DWORD totalGREAppListSubKeys; + char **greIDListToClean = NULL; + char **greAppListToClean = NULL; + char greKeyID[MAX_BUF_MEDIUM]; + char greRegKey[MAX_BUF]; + char greKeyAppList[MAX_BUF_MEDIUM]; + char greAppListKeyPath[MAX_BUF]; + char greUninstaller[MAX_BUF]; + DWORD idKeySize; + DWORD appListKeySize; + DWORD indexOfGREID; + DWORD indexOfGREAppList; + int rv = WIZ_OK; + int regRv = WIZ_OK; + char buf[MAX_BUF]; + + DecryptString(greUninstaller, GRE_UNINSTALLER_FILE); + + _snprintf(buf, sizeof(buf), " GRE Cleanup Orphans: %s\n", sgProduct.greCleanupOrphans ? "true" : "false"); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + + _snprintf(buf, sizeof(buf), " GRE Uninstaller Path: %s\n", greUninstaller); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + + _snprintf(buf, sizeof(buf), " GRE Uninstaller found: %s\n", FileExists(greUninstaller) ? "true" : "false"); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + + // If greCleanupOrphans is false (set either in config.ini or passed in + // thru the cmdline) or GRE's uninstaller file does not exist, then + // simply do nothing and return. + if(!sgProduct.greCleanupOrphans || !FileExists(greUninstaller)) + { + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return: %d\n", WIZ_OK); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + return(WIZ_OK); + } + + // If GRE is installed locally, then use the private GRE key, else + // use the default global GRE key in the windows registry. + if(sgProduct.greType == GRE_LOCAL) + DecryptString(greRegKey, sgProduct.grePrivateKey); + else + MozCopyStr(GRE_REG_KEY, greRegKey, sizeof(greRegKey)); + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, greRegKey, 0, KEY_READ, &greIDKeyHandle) != ERROR_SUCCESS) + { + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return (RegOpenKeyEx: %s): %d\n", greRegKey, WIZ_ERROR_UNDEFINED); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + return(WIZ_ERROR_UNDEFINED); + } + + // Build the list of GRE's given greRegKey. For example, if greRegKey is: + // + // HKLM\Software\mozilla.org\GRE + // + // then build a list of the GRE IDs inside this key. + totalGreIDSubKeys = 0; + regRv = RegQueryInfoKey(greIDKeyHandle, NULL, NULL, NULL, &totalGreIDSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if((regRv != ERROR_SUCCESS) || (totalGreIDSubKeys == 0)) + { + rv = WIZ_ERROR_UNDEFINED; + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return (RegQueryInfoKey: all keys): %d\n", rv); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + return(rv); + } + + if((rv == WIZ_OK) && (greIDListToClean = NS_GlobalAlloc(sizeof(char *) * totalGreIDSubKeys)) == NULL) + { + RegCloseKey(greIDKeyHandle); + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return. Failed to allocate memory for greIDListToClean: %d\n", WIZ_OUT_OF_MEMORY); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + return(WIZ_OUT_OF_MEMORY); + } + + // Show message that orphaned GREs are being cleaned up + if(*sgProduct.greCleanupOrphansMessage != '\0'); + ShowMessage(sgProduct.greCleanupOrphansMessage, TRUE); + + if(rv == WIZ_OK) + { + // Initialize the array of pointers (of GRE ID keys) to NULL + for(indexOfGREID = 0; indexOfGREID < totalGreIDSubKeys; indexOfGREID++) + greIDListToClean[indexOfGREID] = NULL; + + // Enumerate the GRE ID list and save the GRE ID to each of its array element + for(indexOfGREID = 0; indexOfGREID < totalGreIDSubKeys; indexOfGREID++) + { + idKeySize = sizeof(greKeyID); + if(RegEnumKeyEx(greIDKeyHandle, indexOfGREID, greKeyID, &idKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + if((greIDListToClean[indexOfGREID] = NS_GlobalAlloc(sizeof(char) * (idKeySize + 1))) == NULL) + { + RegCloseKey(greIDKeyHandle); + rv = WIZ_OUT_OF_MEMORY; + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return. Failed to add %s to greIDListToClean[]: %d\n", greKeyID, rv); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + break; + } + MozCopyStr(greKeyID, greIDListToClean[indexOfGREID], idKeySize + 1); + } + } + RegCloseKey(greIDKeyHandle); + + if(rv == WIZ_OK) + { + // Enumerate the GRE ID list built from above to get to each of it's AppList key. + // The list that we need to build now is from the following key: + // + // HKLM\Software\mozilla.org\GRE\[GRE ID]\AppList + for(indexOfGREID = 0; indexOfGREID < totalGreIDSubKeys; indexOfGREID++) + { + // If we find the same GRE version as what we're trying to install, + // then we don't want to process it because if we do, it will + // uninstall it. Which means that it'll reinstall it again. We don't + // want to have reinstall when we don't need to. + // + // szUserAgent is the GRE unique id if this instance of the installer is + // installing GRE. + if(strcmpi(sgProduct.szUserAgent, greIDListToClean[indexOfGREID]) == 0) + continue; + + _snprintf(greAppListKeyPath, sizeof(greAppListKeyPath), "%s\\%s\\AppList", + GRE_REG_KEY, greIDListToClean[indexOfGREID]); + greAppListKeyPath[sizeof(greAppListKeyPath) - 1] = '\0'; + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, greAppListKeyPath, 0, KEY_READ, &greAppListKeyHandle) != ERROR_SUCCESS) + { + rv = WIZ_ERROR_UNDEFINED; + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return. Failed to open key %s: %d\n", greAppListKeyPath, rv); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + break; + } + + totalGREAppListSubKeys = 0; + if(RegQueryInfoKey(greAppListKeyHandle, NULL, NULL, NULL, &totalGREAppListSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + RegCloseKey(greAppListKeyHandle); + rv = WIZ_ERROR_UNDEFINED; + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return. Failed to regquery for all keys in %s: %d\n", greAppListKeyPath, rv); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + break; + } + + if((rv == WIZ_OK) && (greAppListToClean = NS_GlobalAlloc(sizeof(char *) * totalGREAppListSubKeys)) == NULL) + { + RegCloseKey(greAppListKeyHandle); + rv = WIZ_OUT_OF_MEMORY; + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return. Failed to allocate memory for greAppListToClean: %d\n", rv); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + break; + } + + // Initialize the GREAppList elements to NULL. + for(indexOfGREAppList = 0; indexOfGREAppList < totalGREAppListSubKeys; indexOfGREAppList++) + greAppListToClean[indexOfGREAppList] = NULL; + + // enumerate the GRE AppList key and build a list. + for(indexOfGREAppList = 0; indexOfGREAppList < totalGREAppListSubKeys; indexOfGREAppList++) + { + appListKeySize = sizeof(greKeyAppList); + if(RegEnumKeyEx(greAppListKeyHandle, indexOfGREAppList, greKeyAppList, &appListKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + if((greAppListToClean[indexOfGREAppList] = NS_GlobalAlloc(sizeof(char) * (appListKeySize + 1))) == NULL) + { + RegCloseKey(greAppListKeyHandle); + rv = WIZ_OUT_OF_MEMORY; + _snprintf(buf, sizeof(buf), " Cleanup Orphaned GRE premature return. Failed to add %s to greAppListToClean[]: %d\n", greKeyAppList, rv); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + break; + } + MozCopyStr(greKeyAppList, greAppListToClean[indexOfGREAppList], appListKeySize + 1); + } + } + RegCloseKey(greAppListKeyHandle); + + if(rv != WIZ_OK) + break; + + UpdateInstallStatusLog("\n Cleanup Orphaned GRE's uninstall commandline:\n"); + // Enumerate the saved GREAppList and start calling GREUninstall.exe + // to remove them if appropriate. + // GREUninstall.exe will take care of determining if the particular + // GRE should be fully removed or not. + // We need to enumerate the list again instead of doing this in the + // save loop as above because deleting keys while at the same time + // enumerating thru its parent key is a Bad Thing(TM). + for(indexOfGREAppList = 0; indexOfGREAppList < totalGREAppListSubKeys; indexOfGREAppList++) + { + char programNamePath[MAX_BUF]; + char greUninstallParam[MAX_BUF]; + + DecryptString(programNamePath, sgProduct.szAppPath); + _snprintf(greUninstallParam, sizeof(greUninstallParam), "-mmi -ms -ua \"%s\" -app \"%s\" -app_path \"%s\"", + greIDListToClean[indexOfGREID], greAppListToClean[indexOfGREAppList], programNamePath); + greUninstallParam[sizeof(greUninstallParam) - 1] = '\0'; + UpdateInstallStatusLog(" "); + UpdateInstallStatusLog(greUninstallParam); + UpdateInstallStatusLog("\n"); + WinSpawn(greUninstaller, greUninstallParam, szTempDir, SW_SHOWNORMAL, WS_WAIT); + } + + // Cleanup allocated memory + for(indexOfGREAppList = 0; indexOfGREAppList < totalGREAppListSubKeys; indexOfGREAppList++) + FreeMemory(&greAppListToClean[indexOfGREAppList]); + if(greAppListToClean) + GlobalFree(greAppListToClean); + } + } + } + + // + // Cleanup allocated memory + CleanupArrayList(greIDListToClean, totalGreIDSubKeys); + if(greIDListToClean) + GlobalFree(greIDListToClean); + + // Hide message that orphaned GREs are being cleaned up + if(*sgProduct.greCleanupOrphansMessage != '\0'); + ShowMessage(sgProduct.greCleanupOrphansMessage, FALSE); + + return(rv); +} + +void LaunchOneComponent(siC *siCObject, greInfo *aGre) +{ + BOOL bArchiveFound; + char szArchive[MAX_BUF]; + char szMsg[MAX_BUF]; + + if(!siCObject) + /* nothing to do return */ + return; + + GetPrivateProfileString("Messages", "MSG_CONFIGURING", "", szMsg, sizeof(szMsg), szFileIniInstall); + + /* launch 3rd party executable */ + if((siCObject->dwAttributes & SIC_SELECTED) && (siCObject->dwAttributes & SIC_LAUNCHAPP)) + { + bArchiveFound = TRUE; + lstrcpy(szArchive, sgProduct.szAlternateArchiveSearchPath); + AppendBackSlash(szArchive, sizeof(szArchive)); + lstrcat(szArchive, siCObject->szArchiveName); + if((*sgProduct.szAlternateArchiveSearchPath == '\0') || !FileExists(szArchive)) + { + lstrcpy(szArchive, szSetupDir); + AppendBackSlash(szArchive, sizeof(szArchive)); + lstrcat(szArchive, siCObject->szArchiveName); + if(!FileExists(szArchive)) + { + lstrcpy(szArchive, szTempDir); + AppendBackSlash(szArchive, sizeof(szArchive)); + lstrcat(szArchive, siCObject->szArchiveName); + if(!FileExists(szArchive)) + { + bArchiveFound = FALSE; + } + } + } + + if(bArchiveFound) + { + char szParameterBuf[MAX_BUF]; + char szSpawnFile[MAX_BUF]; + char szMessageString[MAX_BUF]; + DWORD dwErr = FO_SUCCESS; + + *szMessageString = '\0'; + if(*szMsg != '\0') + { + wsprintf(szMessageString, szMsg, siCObject->szDescriptionShort); + ShowMessage(szMessageString, TRUE); + } + + DecryptString(szParameterBuf, siCObject->szParameter); + lstrcpy(szSpawnFile, szArchive); + if(siCObject->dwAttributes & SIC_UNCOMPRESS) + { + if((dwErr = FileUncompress(szArchive, szTempDir)) == FO_SUCCESS) + { + lstrcpy(szSpawnFile, szTempDir); + AppendBackSlash(szSpawnFile, sizeof(szSpawnFile)); + lstrcat(szSpawnFile, siCObject->szArchiveNameUncompressed); + } + + LogISLaunchAppsComponentUncompress(siCObject->szDescriptionShort, dwErr); + if(dwErr != FO_SUCCESS) + { + if(*szMessageString != '\0') + ShowMessage(szMessageString, FALSE); + return; + } + } + + if(aGre) + { + GetInfoFromGreInstaller(szSpawnFile, aGre); + UpdateGreInstallerCmdLine(aGre, szParameterBuf, sizeof(szParameterBuf), FOR_NEW_GRE); + } + + LogISLaunchAppsComponent(siCObject->szDescriptionShort); + WinSpawn(szSpawnFile, szParameterBuf, szTempDir, SW_SHOWNORMAL, WS_WAIT); + + if(siCObject->dwAttributes & SIC_UNCOMPRESS) + FileDelete(szSpawnFile); + + if(*szMessageString != '\0') + ShowMessage(szMessageString, FALSE); + } + } +} + +void LaunchExistingGreInstaller(greInfo *aGre) +{ + char szMsg[MAX_BUF]; + char szParameterBuf[MAX_BUF]; + char szMessageString[MAX_BUF]; + siC *siCObject = aGre->siCGreComponent; + + if((!siCObject) || !FileExists(aGre->installerAppPath)) + /* nothing to do return */ + return; + + GetPrivateProfileString("Messages", "MSG_CONFIGURING", "", szMsg, sizeof(szMsg), szFileIniInstall); + + *szMessageString = '\0'; + if(*szMsg != '\0') + { + wsprintf(szMessageString, szMsg, siCObject->szDescriptionShort); + ShowMessage(szMessageString, TRUE); + } + + DecryptString(szParameterBuf, siCObject->szParameter); + UpdateGreInstallerCmdLine(NULL, szParameterBuf, sizeof(szParameterBuf), FOR_EXISTING_GRE); + LogISLaunchAppsComponent(siCObject->szDescriptionShort); + WinSpawn(aGre->installerAppPath, szParameterBuf, szTempDir, SW_SHOWNORMAL, WS_WAIT); + if(*szMessageString != '\0') + ShowMessage(szMessageString, FALSE); +} + +HRESULT LaunchApps() +{ + DWORD dwIndex0; + siC *siCObject = NULL; + + LogISLaunchApps(W_START); + dwIndex0 = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + /* launch 3rd party executable */ + LaunchOneComponent(siCObject, NULL); + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + + LogISLaunchApps(W_END); + return(0); +} + +/* Function: IsPathWithinWindir() + * in: char *aTargetPath + * out: returns a BOOL type indicating whether the install path chosen + * by the user is within the %windir% or not. + * purpose: To see if aTargetPath is within the %windir% path. + */ +BOOL IsPathWithinWindir(char *aTargetPath) +{ + char windir[MAX_PATH]; + char targetPath[MAX_PATH]; + + assert(aTargetPath); + + if(GetWindowsDirectory(windir, sizeof(windir))) + { + MozCopyStr(aTargetPath, targetPath, sizeof(targetPath)); + AppendBackSlash(targetPath, sizeof targetPath); + CharUpperBuff(targetPath, sizeof(targetPath)); + AppendBackSlash(windir, sizeof(windir)); + CharUpperBuff(windir, sizeof(windir)); + if(strstr(targetPath, windir) == targetPath) + return(TRUE); + } + else + { + /* If we can't get the windows path, just show error message and assume + * the install path is not within the windows dir. */ + char szEGetWindirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", szEGetWindirFailed, sizeof(szEGetWindirFailed), szFileIniInstall)) + PrintError(szEGetWindirFailed, ERROR_CODE_SHOW); + } + return(FALSE); +} + +/* Function: CleanupArrayList() + * in: char **aList - array to cleanup + * int aListLength - length of array + * out: none. + * purpose: Cleans up memory. + */ +void CleanupArrayList(char **aList, int aListLength) +{ + int index = 0; + + // Free allocated memory + for(index = 0; index < aListLength; index++) + FreeMemory(&aList[index]); +} + +/* Function: GetTotalNumKeys() + * in: char *aSectionName - name of section to get info on + * char *aBaseKeyName - base name of key to count + * out: none. + * purpose: To get the total number of 'aBaseKeyName's in aSection. + * A base key name is just the name of the key without the + * numbers, ie: + * base key name : Object + * actual key in .ini file: Object0, Object1, etc... + */ +int GetTotalNumKeys(char *aSectionName, char *aBaseKeyName) +{ + int index = 0; + char keyName[MAX_BUF_TINY]; + char buf[MAX_BUF]; + + assert(aSectionName); + assert(aBaseKeyName); + + _snprintf(keyName, sizeof(keyName), "%s%d", aBaseKeyName, index); + keyName[sizeof(keyName) - 1] = '\0'; + GetPrivateProfileString(aSectionName, keyName, "", buf, sizeof(buf), szFileIniConfig); + while(*buf != '\0') + { + ++index; + _snprintf(keyName, sizeof(keyName), "%s%d", aBaseKeyName, index); + keyName[sizeof(keyName) - 1] = '\0'; + GetPrivateProfileString(aSectionName, keyName, "", buf, sizeof(buf), szFileIniConfig); + } + + return(index); +} + +/* Function: BuildArrayList() + * in: char *aSectionName - section name to look for info to build array + * char *aBaseKeyName - base key name to use to build array from + * out: returns char ** - array list built + * int *aArrayLength - length of array built + * purpose: To build an Array list given the aSectionName and aBaseKeyName. + * Caller is responsible for cleaning up of allocated memory done + * in this function! + */ +char **BuildArrayList(char *aSectionName, char *aBaseKeyName, int *aArrayLength) +{ + int index = 0; + int totalKeys = 0; + char **list; + char keyName[MAX_BUF_TINY]; + char buf[MAX_BUF]; + + *aArrayLength = 0; + totalKeys = GetTotalNumKeys(aSectionName, aBaseKeyName); + + // if totalKeys is <= 0, then there's nothing to do. + if(totalKeys <= 0) + return(NULL); + + if((list = NS_GlobalAlloc(sizeof(char *) * totalKeys)) == NULL) + return(NULL); + + // Create and initialize the array of pointers + for(index = 0; index < totalKeys; index++) + { + // build the actual key name to use. + _snprintf(keyName, sizeof(keyName), "%s%d", aBaseKeyName, index); + keyName[sizeof(keyName) - 1] = '\0'; + GetPrivateProfileString(aSectionName, keyName, "", buf, sizeof(buf), szFileIniConfig); + if(*buf != '\0') + { + if((list[index] = NS_GlobalAlloc(sizeof(char) * (lstrlen(buf) + 1))) == NULL) + { + // couldn't allocate memory for an array, cleanup the array list that + // has been currently built, and return NULL. + CleanupArrayList(list, index); + if(list) + GlobalFree(list); + + return(NULL); + } + MozCopyStr(buf, list[index], lstrlen(buf) + 1); + } + else + list[index] = NULL; + } + *aArrayLength = index; + + // caller is responsible for garbage cleanup of list. + return(list); +} + +/* Function: IsDirAProfileDir() + * in: char *aParentPath - path to start the check. + * char **aListProfileObjects - array list of profile files/dirs to + * use to determine if a dir is a profile dir or not. + * int aListLength + * out: BOOL + * purpose: To check to see if a dir is a profile dir or not. If any of it's + * subdirectories is a profile dir, then the initial aParentPath is + * considered to be a profile dir. + */ +BOOL IsDirAProfileDir(char *aParentPath, char **aListProfileObjects, int aListLength) +{ + HANDLE fileHandle; + WIN32_FIND_DATA fdFile; + char destPathTemp[MAX_BUF]; + BOOL found; + BOOL isProfileDir; + int index; + + if((aListLength <= 0) || !aListProfileObjects || !*aListProfileObjects) + return(FALSE); + + /* check the initial aParentPath to see if the dir contains the + * files/dirs that contitute a profile dir */ + isProfileDir = TRUE; + for(index = 0; index < aListLength; index++) + { + /* create full path */ + _snprintf(destPathTemp, sizeof(destPathTemp), "%s\\%s", aParentPath, aListProfileObjects[index]); + destPathTemp[sizeof(destPathTemp) - 1] = '\0'; + + /* if any of the files/dirs that make up a profile dir is missing, + * then it's not a profile dir */ + if(!FileExists(destPathTemp)) + { + isProfileDir = FALSE; + break; + } + } + + /* If it's determined to be a profile dir, then return immediately. If it's + * not, then continue searching the other dirs to see if any constitute a + * profile dir. */ + if(isProfileDir) + return(TRUE); + + _snprintf(destPathTemp, sizeof(destPathTemp), "%s\\*", aParentPath); + destPathTemp[sizeof(destPathTemp) - 1] = '\0'; + + found = TRUE; + fileHandle = FindFirstFile(destPathTemp, &fdFile); + while((fileHandle != INVALID_HANDLE_VALUE) && found) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + // if it's a directory, there we need to traverse it to see if there are + // dirs that are profile dirs. + if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + _snprintf(destPathTemp, sizeof(destPathTemp), "%s\\%s", aParentPath, fdFile.cFileName); + destPathTemp[sizeof(destPathTemp) - 1] = '\0'; + isProfileDir = IsDirAProfileDir(destPathTemp, aListProfileObjects, aListLength); + if(isProfileDir) + break; + + } + } + found = FindNextFile(fileHandle, &fdFile); + } + + FindClose(fileHandle); + return(isProfileDir); +} + +/* Function: IsOkToRemoveFileOrDir() + * in: char *aFileOrDirname + * out: bool return type + * purpose: To check if the file or dirname is not in the aListToIgnore. + */ +BOOL IsOkToRemoveFileOrDirname(char *aFileOrDirname, char **aListToIgnore, + int aListToIgnoreLength, char **aListProfileObjects, int aListProfileLength) +{ + int i; + char filename[MAX_BUF]; + + if(!aListToIgnore || !*aListToIgnore) + return(TRUE); + + ParsePath(aFileOrDirname, filename, sizeof(filename), FALSE, PP_FILENAME_ONLY); + + // check to see if this is a profile folder + if(FileExists(aFileOrDirname) & FILE_ATTRIBUTE_DIRECTORY) + if(IsDirAProfileDir(aFileOrDirname, aListProfileObjects, aListProfileLength)) + return(FALSE); + + for(i = 0; i < aListToIgnoreLength; i++) + { + if(lstrcmpi(filename, aListToIgnore[i]) == 0) + return(FALSE); + } + return(TRUE); +} + +/* Function: CleanupOnUpgrade() + * in: none. + * out: none. + * purpose: To cleanup/remove files and dirs within the user chosen + * installation path, excluding the list in + * aListToIgnore. + */ +void CleanupOnUpgrade() +{ + HANDLE fileHandle; + WIN32_FIND_DATA fdFile; + char destPathTemp[MAX_BUF]; + char targetPath[MAX_BUF]; + char buf[MAX_BUF]; + BOOL found; + char **listObjectsToIgnore; + int listTotalObjectsToIgnore; + char **listProfileObjects; + int listTotalProfileObjects; + int index; + + MozCopyStr(sgProduct.szPath, targetPath, sizeof(targetPath)); + RemoveBackSlash(targetPath); + + if(!FileExists(targetPath)) + return; + + UpdateInstallStatusLog("\n Files/Dirs deleted on upgrade:\n"); + + /* Check to see if the installation path is within the %windir%. If so, + * warn the user and do not delete any file! */ + if(IsPathWithinWindir(targetPath)) + { + if(sgProduct.mode == NORMAL) + { + GetPrivateProfileString("Strings", "Message Cleanup On Upgrade Windir", "", + buf, sizeof(buf), szFileIniConfig); + MessageBox(hWndMain, buf, NULL, MB_ICONEXCLAMATION); + } + + _snprintf(buf, sizeof(buf), " None. Installation path is within %windir%:\n %s\n", targetPath); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + return; + } + + // param1: section name + // param2: base key name within section name + // ie: ObjectToIgnore0= + // ObjectToIgnore1= + // ObjectToIgnore2= + listObjectsToIgnore = BuildArrayList("Cleanup On Upgrade", "ObjectToIgnore", &listTotalObjectsToIgnore); + listProfileObjects = BuildArrayList("Profile Dir Object List", "Object", &listTotalProfileObjects); + + _snprintf(destPathTemp, sizeof(destPathTemp), "%s\\*", targetPath); + destPathTemp[sizeof(destPathTemp) - 1] = '\0'; + + found = TRUE; + fileHandle = FindFirstFile(destPathTemp, &fdFile); + while((fileHandle != INVALID_HANDLE_VALUE) && found) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path */ + _snprintf(destPathTemp, sizeof(destPathTemp), "%s\\%s", targetPath, fdFile.cFileName); + destPathTemp[sizeof(destPathTemp) - 1] = '\0'; + + if(IsOkToRemoveFileOrDirname(destPathTemp, listObjectsToIgnore, + listTotalObjectsToIgnore, listProfileObjects, listTotalProfileObjects)) + { + if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + AppendBackSlash(destPathTemp, sizeof(destPathTemp)); + DirectoryRemove(destPathTemp, TRUE); + } + else + DeleteFile(destPathTemp); + + /* Check to see if the file/dir was deleted successfully */ + if(!FileExists(destPathTemp)) + _snprintf(buf, sizeof(buf), " ok: %s\n", destPathTemp); + else + _snprintf(buf, sizeof(buf), " failed: %s\n", destPathTemp); + } + else + _snprintf(buf, sizeof(buf), " skipped: %s\n", destPathTemp); + + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + } + + found = FindNextFile(fileHandle, &fdFile); + } + + FindClose(fileHandle); + + // Log the array lists to make sure it matches the list of files/dirs that + // were processed. + UpdateInstallStatusLog("\n Files/Dirs list to ignore:\n"); + for(index = 0; index < listTotalObjectsToIgnore; index++) + { + _snprintf(buf, sizeof(buf), " ObjectToIgnore%d: %s\n", index + 1, listObjectsToIgnore[index]); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + } + + CleanupArrayList(listObjectsToIgnore, listTotalObjectsToIgnore); + if(listObjectsToIgnore) + GlobalFree(listObjectsToIgnore); + + UpdateInstallStatusLog("\n Files/Dirs list to verify dir is a Profile dir:\n"); + for(index = 0; index < listTotalProfileObjects; index++) + { + _snprintf(buf, sizeof(buf), " Object%d: %s\n", index + 1, listProfileObjects[index]); + buf[sizeof(buf) - 1] = '\0'; + UpdateInstallStatusLog(buf); + } + + CleanupArrayList(listProfileObjects, listTotalProfileObjects); + if(listProfileObjects) + GlobalFree(listProfileObjects); + +} + +/* Function: ProcessGre() + * in: none. + * out: path to where GRE is installed at. + * purpose: To install GRE on the system, so this installer can use it's + * xpinstall engine. It uses gre->homePath to see if GRE is already + * installed on the system. If GRE is already present on the system, + * gre->homePath is guaranteed to contain it's destination path. + */ +HRESULT ProcessGre(greInfo *aGre) +{ + char greUninstallCommand[MAX_BUF]; + + if(!aGre) + return(WIZ_OK); + + /* If aGre->homePath does not exist, it means that a compatible version of GRE was + * not found on the system, so we need to install one. We also need to get the + * path to where it's going to install the GRE for in case we need to use it + * as the xpinstall engine. + * + * If gbForceInstallGre is true, then force an installation of GRE regardless + * if it's already on the system. Also save the GRE's destination path to + * aGre->homePath. + * + * If aGre->homePath does exist, then we simply call LaunchExistingGreInstaller() + * to run the existing GRE's installer app to register mozilla. + */ + UpdateInstallStatusLog("\n"); + if((*aGre->homePath == '\0') || (gbForceInstallGre)) + LaunchOneComponent(aGre->siCGreComponent, aGre); + else + LaunchExistingGreInstaller(aGre); + + /* XXX instead of unsetting the SELECTED attribute, set the DOWNLOAD_ONLY attribute + * in the config.ini file. + */ + /* Unset "Component GRE"'s SELECTED attribute so it doesn't get spawned again later from LaunchApps() */ + gGreInstallerHasRun = TRUE; + if(aGre->siCGreComponent) + aGre->siCGreComponent->dwAttributes &= ~SIC_SELECTED; + + /* Log the GRE uninstall command to call in order for this app's uninstaller to + * uninstall GRE. + */ + if(GetInfoFromInstalledGreConfigIni(aGre) == WIZ_OK) + { + /* If were installing GRE locally, then update the app's uninstall command + * to pass the local/private windows GRE key path to GRE's uninstaller + * during uninstall. */ + if(sgProduct.greType == GRE_LOCAL) + wsprintf(greUninstallCommand, + "\"%s\" -mmi -ms -app \"%s %s\" -ua \"%s\" -reg_path %s", + aGre->uninstallerAppPath, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent, + aGre->userAgent, + sgProduct.grePrivateKey); + else + wsprintf(greUninstallCommand, + "\"%s\" -mmi -ms -app \"%s %s\" -ua \"%s\"", + aGre->uninstallerAppPath, + sgProduct.szProductNameInternal, + sgProduct.szUserAgent, + aGre->userAgent); + UpdateInstallLog(KEY_UNINSTALL_COMMAND, greUninstallCommand, DNU_UNINSTALL); + } + return(WIZ_OK); +} + +/* Function: GetXpinstallPath() + * in: none. + * out: path to where xpinstall engine is at. + * purpose: To retrieve the full path of where a valid xpinstall engine is + * installed at. + * * If we're using xpcom.xpi, then append 'bin' to the returned + * path because when xpcom.xpi is uncompressed, xpinstall will be + * within a 'bin' subdir. + * * If we're using GRE, then simply just return the GRE + * destination path. + */ +void GetXpinstallPath(char *aPath, int aPathBufSize) +{ + if(siCFXpcomFile.bStatus == STATUS_ENABLED) + { + MozCopyStr(siCFXpcomFile.szDestination, aPath, aPathBufSize); + AppendBackSlash(aPath, aPathBufSize); + lstrcat(aPath, "bin"); + } + else + MozCopyStr(gGre.homePath, aPath, aPathBufSize); +} + +/* Function: ProcessXpinstallEngine() + * in: none. + * out: none. + * purpose: To setup the xpinstall engine either by: + * 1) uncompressing xpcom.xpi into the temp dir. + * 2) locating existing compatible version of GRE. + * 3) installing GRE that was downloaded with this product. + * + * Since GRE installer uses the same native installer as the Mozilla + * installer, xpcom.xpi should be used only by the GRE installer. + * All other installers should be using GRE (either finding one on + * the local system, or installer its own copy). + */ +HRESULT ProcessXpinstallEngine() +{ + HRESULT rv = WIZ_OK; + + /* If product to be installed is _not_ GRE, then call ProcessGRE. + * ProcessGre() will either install GRE or simply run the existing + * GRE's installer that's already on the system. This will setup + * GRE so it can be used as the xpinstall engine (if it's needed). + */ + if(!IsInstallerProductGRE()) + rv = ProcessGre(&gGre); + + if(*siCFXpcomFile.szMessage != '\0') + ShowMessage(siCFXpcomFile.szMessage, TRUE); + + if((WIZ_OK == rv) && (siCFXpcomFile.bStatus == STATUS_ENABLED)) + rv = ProcessXpcomFile(); + + if(*siCFXpcomFile.szMessage != '\0') + ShowMessage(siCFXpcomFile.szMessage, FALSE); + + return(rv); +} + +char *GetOSTypeString(char *szOSType, DWORD dwOSTypeBufSize) +{ + ZeroMemory(szOSType, dwOSTypeBufSize); + + if(gSystemInfo.dwOSType & OS_WIN95_DEBUTE) + lstrcpy(szOSType, "Win95 debute"); + else if(gSystemInfo.dwOSType & OS_WIN95) + lstrcpy(szOSType, "Win95"); + else if(gSystemInfo.dwOSType & OS_WIN98) + lstrcpy(szOSType, "Win98"); + else if(gSystemInfo.dwOSType & OS_NT3) + lstrcpy(szOSType, "NT3"); + else if(gSystemInfo.dwOSType & OS_NT4) + lstrcpy(szOSType, "NT4"); + else if(gSystemInfo.dwOSType & OS_NT50) + lstrcpy(szOSType, "NT50"); + else if(gSystemInfo.dwOSType & OS_NT51) + lstrcpy(szOSType, "NT51"); + else + lstrcpy(szOSType, "NT5"); + + return(szOSType); +} + +void DetermineOSVersionEx() +{ + BOOL bIsWin95Debute; + char szBuf[MAX_BUF]; + char szOSType[MAX_BUF]; + char szESetupRequirement[MAX_BUF]; + DWORD dwStrLen; + OSVERSIONINFO osVersionInfo; + MEMORYSTATUS msMemoryInfo; + + gSystemInfo.dwOSType = 0; + osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if(!GetVersionEx(&osVersionInfo)) + { + /* GetVersionEx() failed for some reason. It's not fatal, but could cause + * some complications during installation */ + char szEMsg[MAX_BUF_TINY]; + + if(GetPrivateProfileString("Messages", "ERROR_GETVERSION", "", szEMsg, sizeof(szEMsg), szFileIniInstall)) + PrintError(szEMsg, ERROR_CODE_SHOW); + } + + bIsWin95Debute = IsWin95Debute(); + switch(osVersionInfo.dwPlatformId) + { + case VER_PLATFORM_WIN32_WINDOWS: + gSystemInfo.dwOSType |= OS_WIN9x; + if(osVersionInfo.dwMinorVersion == 0) + { + gSystemInfo.dwOSType |= OS_WIN95; + if(bIsWin95Debute) + gSystemInfo.dwOSType |= OS_WIN95_DEBUTE; + } + else + gSystemInfo.dwOSType |= OS_WIN98; + break; + + case VER_PLATFORM_WIN32_NT: + gSystemInfo.dwOSType |= OS_NT; + switch(osVersionInfo.dwMajorVersion) + { + case 3: + gSystemInfo.dwOSType |= OS_NT3; + break; + + case 4: + gSystemInfo.dwOSType |= OS_NT4; + break; + + default: + gSystemInfo.dwOSType |= OS_NT5; + switch(osVersionInfo.dwMinorVersion) + { + case 0: + /* a minor version of 0 (major.minor.build) indicates Win2000 */ + gSystemInfo.dwOSType |= OS_NT50; + break; + + case 1: + /* a minor version of 1 (major.minor.build) indicates WinXP */ + gSystemInfo.dwOSType |= OS_NT51; + break; + } + break; + } + break; + + default: + if(GetPrivateProfileString("Messages", "ERROR_SETUP_REQUIREMENT", "", szESetupRequirement, sizeof(szESetupRequirement), szFileIniInstall)) + PrintError(szESetupRequirement, ERROR_CODE_HIDE); + break; + } + + gSystemInfo.dwMajorVersion = osVersionInfo.dwMajorVersion; + gSystemInfo.dwMinorVersion = osVersionInfo.dwMinorVersion; + gSystemInfo.dwBuildNumber = (DWORD)(LOWORD(osVersionInfo.dwBuildNumber)); + + dwStrLen = sizeof(gSystemInfo.szExtraString) > + lstrlen(osVersionInfo.szCSDVersion) ? + lstrlen(osVersionInfo.szCSDVersion) : + sizeof(gSystemInfo.szExtraString) - 1; + ZeroMemory(gSystemInfo.szExtraString, sizeof(gSystemInfo.szExtraString)); + strncpy(gSystemInfo.szExtraString, osVersionInfo.szCSDVersion, dwStrLen); + + msMemoryInfo.dwLength = sizeof(MEMORYSTATUS); + GlobalMemoryStatus(&msMemoryInfo); + gSystemInfo.dwMemoryTotalPhysical = msMemoryInfo.dwTotalPhys/1024; + gSystemInfo.dwMemoryAvailablePhysical = msMemoryInfo.dwAvailPhys/1024; + + GetOSTypeString(szOSType, sizeof(szOSType)); + wsprintf(szBuf, +" System Info:\n\ + OS Type: %s\n\ + Major Version: %d\n\ + Minor Version: %d\n\ + Build Number: %d\n\ + Extra String: %s\n\ + Total Physical Memory: %dKB\n\ + Total Available Physical Memory: %dKB\n", + szOSType, + gSystemInfo.dwMajorVersion, + gSystemInfo.dwMinorVersion, + gSystemInfo.dwBuildNumber, + gSystemInfo.szExtraString, + gSystemInfo.dwMemoryTotalPhysical, + gSystemInfo.dwMemoryAvailablePhysical); + + UpdateInstallStatusLog(szBuf); +} + +HRESULT WinSpawn(LPSTR szClientName, LPSTR szParameters, LPSTR szCurrentDir, int iShowCmd, BOOL bWait) +{ + SHELLEXECUTEINFO seInfo; + + seInfo.cbSize = sizeof(SHELLEXECUTEINFO); + seInfo.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS; + seInfo.hwnd = hWndMain; + seInfo.lpVerb = NULL; + seInfo.lpFile = szClientName; + seInfo.lpParameters = szParameters; + seInfo.lpDirectory = szCurrentDir; + seInfo.nShow = SW_SHOWNORMAL; + seInfo.hInstApp = 0; + seInfo.lpIDList = NULL; + seInfo.lpClass = NULL; + seInfo.hkeyClass = 0; + seInfo.dwHotKey = 0; + seInfo.hIcon = 0; + seInfo.hProcess = 0; + + if((ShellExecuteEx(&seInfo) != 0) && (seInfo.hProcess != NULL)) + { + if(bWait) + { + for(;;) + { + if(WaitForSingleObject(seInfo.hProcess, 200) == WAIT_OBJECT_0) + break; + + ProcessWindowsMessages(); + } + } + return(TRUE); + } + return(FALSE); +} + +HRESULT InitDlgWelcome(diW *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage2 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgWelcome(diW *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); + FreeMemory(&(diDialog->szMessage1)); + FreeMemory(&(diDialog->szMessage2)); +} + +HRESULT InitDlgLicense(diL *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szLicenseFilename = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgLicense(diL *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szLicenseFilename)); + FreeMemory(&(diDialog->szMessage0)); + FreeMemory(&(diDialog->szMessage1)); +} + +HRESULT InitDlgQuickLaunch(diQL *diDialog) +{ + diDialog->bTurboMode = FALSE; + diDialog->bTurboModeEnabled = FALSE; + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage2 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgQuickLaunch(diQL *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); + FreeMemory(&(diDialog->szMessage1)); + FreeMemory(&(diDialog->szMessage2)); +} + +HRESULT InitDlgSetupType(diST *diDialog) +{ + diDialog->bShowDialog = FALSE; + + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szReadmeFilename = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szReadmeApp = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + diDialog->stSetupType0.dwCItems = 0; + diDialog->stSetupType1.dwCItems = 0; + diDialog->stSetupType2.dwCItems = 0; + diDialog->stSetupType3.dwCItems = 0; + if((diDialog->stSetupType0.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->stSetupType0.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((diDialog->stSetupType1.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->stSetupType1.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((diDialog->stSetupType2.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->stSetupType2.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((diDialog->stSetupType3.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->stSetupType3.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgSetupType(diST *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); + + FreeMemory(&(diDialog->szReadmeFilename)); + FreeMemory(&(diDialog->szReadmeApp)); + FreeMemory(&(diDialog->stSetupType0.szDescriptionShort)); + FreeMemory(&(diDialog->stSetupType0.szDescriptionLong)); + FreeMemory(&(diDialog->stSetupType1.szDescriptionShort)); + FreeMemory(&(diDialog->stSetupType1.szDescriptionLong)); + FreeMemory(&(diDialog->stSetupType2.szDescriptionShort)); + FreeMemory(&(diDialog->stSetupType2.szDescriptionLong)); + FreeMemory(&(diDialog->stSetupType3.szDescriptionShort)); + FreeMemory(&(diDialog->stSetupType3.szDescriptionLong)); +} + +HRESULT InitDlgSelectComponents(diSC *diDialog, DWORD dwSM) +{ + diDialog->bShowDialog = FALSE; + + /* set to show the Single dialog or the Multi dialog for the SelectComponents dialog */ + diDialog->bShowDialogSM = dwSM; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgSelectComponents(diSC *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); +} + +HRESULT InitDlgWindowsIntegration(diWI *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + + diDialog->wiCB0.bEnabled = FALSE; + diDialog->wiCB1.bEnabled = FALSE; + diDialog->wiCB2.bEnabled = FALSE; + diDialog->wiCB3.bEnabled = FALSE; + + diDialog->wiCB0.bCheckBoxState = FALSE; + diDialog->wiCB1.bCheckBoxState = FALSE; + diDialog->wiCB2.bCheckBoxState = FALSE; + diDialog->wiCB3.bCheckBoxState = FALSE; + + if((diDialog->wiCB0.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->wiCB1.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->wiCB2.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->wiCB3.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((diDialog->wiCB0.szArchive = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->wiCB1.szArchive = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->wiCB2.szArchive = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->wiCB3.szArchive = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgWindowsIntegration(diWI *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); + FreeMemory(&(diDialog->szMessage1)); + + FreeMemory(&(diDialog->wiCB0.szDescription)); + FreeMemory(&(diDialog->wiCB1.szDescription)); + FreeMemory(&(diDialog->wiCB2.szDescription)); + FreeMemory(&(diDialog->wiCB3.szDescription)); + FreeMemory(&(diDialog->wiCB0.szArchive)); + FreeMemory(&(diDialog->wiCB1.szArchive)); + FreeMemory(&(diDialog->wiCB2.szArchive)); + FreeMemory(&(diDialog->wiCB3.szArchive)); +} + +HRESULT InitDlgProgramFolder(diPF *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgProgramFolder(diPF *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); +} + +HRESULT InitDlgAdditionalOptions(diDO *diDialog) +{ + diDialog->bShowDialog = FALSE; + diDialog->bSaveInstaller = FALSE; + diDialog->bRecaptureHomepage = FALSE; + diDialog->bShowHomepageOption = FALSE; + diDialog->dwUseProtocol = UP_FTP; + diDialog->bUseProtocolSettings = TRUE; + diDialog->bShowProtocols = TRUE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgAdditionalOptions(diDO *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); + FreeMemory(&(diDialog->szMessage1)); +} + +HRESULT InitDlgAdvancedSettings(diAS *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szProxyServer = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szProxyPort = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szProxyUser = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szProxyPasswd = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgAdvancedSettings(diAS *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); + FreeMemory(&(diDialog->szProxyServer)); + FreeMemory(&(diDialog->szProxyPort)); + FreeMemory(&(diDialog->szProxyUser)); + FreeMemory(&(diDialog->szProxyPasswd)); +} + +HRESULT InitDlgStartInstall(diSI *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessageInstall = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessageDownload = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgStartInstall(diSI *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessageInstall)); + FreeMemory(&(diDialog->szMessageDownload)); +} + +HRESULT InitDlgDownload(diD *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF_TINY)) == NULL) + return(1); + if((diDialog->szMessageDownload0 = NS_GlobalAlloc(MAX_BUF_MEDIUM)) == NULL) + return(1); + if((diDialog->szMessageRetry0 = NS_GlobalAlloc(MAX_BUF_MEDIUM)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgDownload(diD *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessageDownload0)); + FreeMemory(&(diDialog->szMessageRetry0)); +} + +DWORD InitDlgReboot(diR *diDialog) +{ + diDialog->dwShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF_MEDIUM)) == NULL) + return(1); + GetPrivateProfileString("Messages", "DLG_REBOOT_TITLE", "", diDialog->szTitle, MAX_BUF_MEDIUM, szFileIniInstall); + + return(0); +} + +void DeInitDlgReboot(diR *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); +} + +HRESULT InitSetupGeneral() +{ + gSystemInfo.bRefreshIcons = FALSE; + sgProduct.mode = NOT_SET; + sgProduct.bSharedInst = FALSE; + sgProduct.bInstallFiles = TRUE; + sgProduct.checkCleanupOnUpgrade = FALSE; + sgProduct.doCleanupOnUpgrade = FALSE; + sgProduct.greType = GRE_TYPE_NOT_SET; + sgProduct.dwCustomType = ST_RADIO0; + sgProduct.dwNumberOfComponents = 0; + sgProduct.bLockPath = FALSE; + + if((sgProduct.szPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szSubPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szProgramName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szCompanyName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szProductName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szProductNameInternal = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szProductNamePrevious = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szUninstallFilename = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szUserAgent = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szProgramFolderName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szProgramFolderPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szAlternateArchiveSearchPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szParentProcessFilename = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((szTempSetupPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szSiteSelectorDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szAppID = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szAppPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((sgProduct.szRegPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + sgProduct.greCleanupOrphans = FALSE; + *sgProduct.greCleanupOrphansMessage = '\0'; + *sgProduct.greID = '\0'; + *sgProduct.grePrivateKey = '\0'; + return(0); +} + +void DeInitSetupGeneral() +{ + FreeMemory(&(sgProduct.szPath)); + FreeMemory(&(sgProduct.szSubPath)); + FreeMemory(&(sgProduct.szProgramName)); + FreeMemory(&(sgProduct.szCompanyName)); + FreeMemory(&(sgProduct.szProductName)); + FreeMemory(&(sgProduct.szProductNameInternal)); + FreeMemory(&(sgProduct.szProductNamePrevious)); + FreeMemory(&(sgProduct.szUninstallFilename)); + FreeMemory(&(sgProduct.szUserAgent)); + FreeMemory(&(sgProduct.szProgramFolderName)); + FreeMemory(&(sgProduct.szProgramFolderPath)); + FreeMemory(&(sgProduct.szAlternateArchiveSearchPath)); + FreeMemory(&(sgProduct.szParentProcessFilename)); + FreeMemory(&(sgProduct.szAppID)); + FreeMemory(&(sgProduct.szAppPath)); + FreeMemory(&(sgProduct.szRegPath)); + FreeMemory(&(szTempSetupPath)); + FreeMemory(&(szSiteSelectorDescription)); +} + +HRESULT InitSDObject() +{ + if((siSDObject.szXpcomFile = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szXpcomDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szNoAds = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szSilent = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szExecution = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szConfirmInstall = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szExtractMsg = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szExe = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szExeParam = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siSDObject.szXpcomFilePath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitSDObject() +{ + FreeMemory(&(siSDObject.szXpcomFile)); + FreeMemory(&(siSDObject.szXpcomDir)); + FreeMemory(&(siSDObject.szNoAds)); + FreeMemory(&(siSDObject.szSilent)); + FreeMemory(&(siSDObject.szExecution)); + FreeMemory(&(siSDObject.szConfirmInstall)); + FreeMemory(&(siSDObject.szExtractMsg)); + FreeMemory(&(siSDObject.szExe)); + FreeMemory(&(siSDObject.szExeParam)); + FreeMemory(&(siSDObject.szXpcomFilePath)); +} + +HRESULT InitSXpcomFile() +{ + if((siCFXpcomFile.szSource = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siCFXpcomFile.szDestination = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((siCFXpcomFile.szMessage = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + siCFXpcomFile.bCleanup = TRUE; + siCFXpcomFile.bStatus = STATUS_ENABLED; + siCFXpcomFile.ullInstallSize = 0; + return(0); +} + +void DeInitSXpcomFile() +{ + FreeMemory(&(siCFXpcomFile.szSource)); + FreeMemory(&(siCFXpcomFile.szDestination)); + FreeMemory(&(siCFXpcomFile.szMessage)); +} + +/* Function: InitGre() + * in: gre structure. + * out: gre structure. + * purpose: To initialize a newly created greInfo structure. + */ +HRESULT InitGre(greInfo *gre) +{ + gre->homePath[0] = '\0'; + gre->installerAppPath[0] = '\0'; + gre->uninstallerAppPath[0] = '\0'; + gre->userAgent[0] = '\0'; + gre->minVersion.ullMajor = 0; + gre->minVersion.ullMinor = 0; + gre->minVersion.ullRelease = 0; + gre->minVersion.ullBuild = 0; + gre->maxVersion.ullMajor = 0; + gre->maxVersion.ullMinor = 0; + gre->maxVersion.ullRelease = 0; + gre->maxVersion.ullBuild = 0; + gre->greSupersedeList = NULL; + gre->greInstalledList = NULL; + gre->siCGreComponent = NULL; + return(WIZ_OK); +} + +/* Function: DeInitGre() + * in: gre structure. + * out: gre structure. + * purpose: To cleanup allocated memory to a greInfo structure. + */ +void DeInitGre(greInfo *gre) +{ + DeleteGverList(gre->greSupersedeList); + DeleteGverList(gre->greInstalledList); +} + +siC *CreateSiCNode() +{ + siC *siCNode; + + if((siCNode = NS_GlobalAlloc(sizeof(struct sinfoComponent))) == NULL) + exit(1); + + siCNode->dwAttributes = 0; + siCNode->ullInstallSize = 0; + siCNode->ullInstallSizeSystem = 0; + siCNode->ullInstallSizeArchive = 0; + siCNode->lRandomInstallPercentage = 0; + siCNode->lRandomInstallValue = 0; + siCNode->bForceUpgrade = FALSE; + + if((siCNode->szArchiveName = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szArchiveNameUncompressed = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szArchivePath = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szDestinationPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szParameter = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCNode->szReferenceName = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + + siCNode->iNetRetries = 0; + siCNode->iCRCRetries = 0; + siCNode->iNetTimeOuts = 0; + siCNode->siCDDependencies = NULL; + siCNode->siCDDependees = NULL; + siCNode->Next = NULL; + siCNode->Prev = NULL; + + return(siCNode); +} + +void SiCNodeInsert(siC **siCHead, siC *siCTemp) +{ + if(*siCHead == NULL) + { + *siCHead = siCTemp; + (*siCHead)->Next = *siCHead; + (*siCHead)->Prev = *siCHead; + } + else + { + siCTemp->Next = *siCHead; + siCTemp->Prev = (*siCHead)->Prev; + (*siCHead)->Prev->Next = siCTemp; + (*siCHead)->Prev = siCTemp; + } +} + +void SiCNodeDelete(siC *siCTemp) +{ + if(siCTemp != NULL) + { + DeInitSiCDependencies(siCTemp->siCDDependencies); + DeInitSiCDependencies(siCTemp->siCDDependees); + + siCTemp->Next->Prev = siCTemp->Prev; + siCTemp->Prev->Next = siCTemp->Next; + siCTemp->Next = NULL; + siCTemp->Prev = NULL; + + FreeMemory(&(siCTemp->szDestinationPath)); + FreeMemory(&(siCTemp->szArchivePath)); + FreeMemory(&(siCTemp->szArchiveName)); + FreeMemory(&(siCTemp->szArchiveNameUncompressed)); + FreeMemory(&(siCTemp->szParameter)); + FreeMemory(&(siCTemp->szReferenceName)); + FreeMemory(&(siCTemp->szDescriptionLong)); + FreeMemory(&(siCTemp->szDescriptionShort)); + FreeMemory(&siCTemp); + } +} + +siCD *CreateSiCDepNode() +{ + siCD *siCDepNode; + + if((siCDepNode = NS_GlobalAlloc(sizeof(struct sinfoComponentDep))) == NULL) + exit(1); + + if((siCDepNode->szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((siCDepNode->szReferenceName = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + siCDepNode->Next = NULL; + siCDepNode->Prev = NULL; + + return(siCDepNode); +} + +void SiCDepNodeInsert(siCD **siCDepHead, siCD *siCDepTemp) +{ + if(*siCDepHead == NULL) + { + *siCDepHead = siCDepTemp; + (*siCDepHead)->Next = *siCDepHead; + (*siCDepHead)->Prev = *siCDepHead; + } + else + { + siCDepTemp->Next = *siCDepHead; + siCDepTemp->Prev = (*siCDepHead)->Prev; + (*siCDepHead)->Prev->Next = siCDepTemp; + (*siCDepHead)->Prev = siCDepTemp; + } +} + +void SiCDepNodeDelete(siCD *siCDepTemp) +{ + if(siCDepTemp != NULL) + { + siCDepTemp->Next->Prev = siCDepTemp->Prev; + siCDepTemp->Prev->Next = siCDepTemp->Next; + siCDepTemp->Next = NULL; + siCDepTemp->Prev = NULL; + + FreeMemory(&(siCDepTemp->szDescriptionShort)); + FreeMemory(&(siCDepTemp->szReferenceName)); + FreeMemory(&siCDepTemp); + } +} + +ssi *CreateSsiSiteSelectorNode() +{ + ssi *ssiNode; + + if((ssiNode = NS_GlobalAlloc(sizeof(struct ssInfo))) == NULL) + exit(1); + if((ssiNode->szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((ssiNode->szDomain = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((ssiNode->szIdentifier = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + + ssiNode->Next = NULL; + ssiNode->Prev = NULL; + + return(ssiNode); +} + +void SsiSiteSelectorNodeInsert(ssi **ssiHead, ssi *ssiTemp) +{ + if(*ssiHead == NULL) + { + *ssiHead = ssiTemp; + (*ssiHead)->Next = *ssiHead; + (*ssiHead)->Prev = *ssiHead; + } + else + { + ssiTemp->Next = *ssiHead; + ssiTemp->Prev = (*ssiHead)->Prev; + (*ssiHead)->Prev->Next = ssiTemp; + (*ssiHead)->Prev = ssiTemp; + } +} + +void SsiSiteSelectorNodeDelete(ssi *ssiTemp) +{ + if(ssiTemp != NULL) + { + ssiTemp->Next->Prev = ssiTemp->Prev; + ssiTemp->Prev->Next = ssiTemp->Next; + ssiTemp->Next = NULL; + ssiTemp->Prev = NULL; + + FreeMemory(&(ssiTemp->szDescription)); + FreeMemory(&(ssiTemp->szDomain)); + FreeMemory(&(ssiTemp->szIdentifier)); + FreeMemory(&ssiTemp); + } +} + +HRESULT SiCNodeGetAttributes(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->dwAttributes); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->dwAttributes); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(-1); +} + +void SiCNodeSetAttributes(DWORD dwIndex, DWORD dwAttributes, BOOL bSet, BOOL bIncludeInvisible, DWORD dwACFlag, HWND hwndListBox) +{ + DWORD dwCount = 0; + DWORD dwVisibleIndex = 0; + siC *siCTemp = siComponents; + + LPSTR szTmpString; + TCHAR tchBuffer[MAX_BUF]; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + { + if(bSet) + siCTemp->dwAttributes |= dwAttributes; + else + siCTemp->dwAttributes &= ~dwAttributes; + + if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) + && (dwAttributes == SIC_SELECTED) + && gSystemInfo.bScreenReader + && hwndListBox) + { + szTmpString = SiCNodeGetDescriptionShort(dwVisibleIndex, FALSE, dwACFlag); + lstrcpy(tchBuffer, szTmpString); + lstrcat(tchBuffer, " - "); + if(bSet) + lstrcat(tchBuffer, sgInstallGui.szChecked); + else + lstrcat(tchBuffer, sgInstallGui.szUnchecked); + + //We've got to actually change the text in the listbox for the screen reader to see it. + SendMessage(hwndListBox, LB_INSERTSTRING, 0, (LPARAM)tchBuffer); + SendMessage(hwndListBox, LB_DELETESTRING, 1, 0); + } + } + + ++dwCount; + if(!(siCTemp->dwAttributes & SIC_INVISIBLE)) + ++dwVisibleIndex; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + { + if(bSet) + siCTemp->dwAttributes |= dwAttributes; + else + siCTemp->dwAttributes &= ~dwAttributes; + + if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) + && (dwAttributes == SIC_SELECTED) + && gSystemInfo.bScreenReader + && hwndListBox) + { + szTmpString = SiCNodeGetDescriptionShort(dwVisibleIndex, FALSE, dwACFlag); + lstrcpy(tchBuffer, szTmpString); + lstrcat(tchBuffer, " - "); + if(bSet) + lstrcat(tchBuffer, sgInstallGui.szChecked); + else + lstrcat(tchBuffer, sgInstallGui.szUnchecked); + + //We've got to actually change the text in the listbox for the screen reader to see it. + SendMessage(hwndListBox, LB_INSERTSTRING, dwVisibleIndex, (LPARAM)tchBuffer); + SendMessage(hwndListBox, LB_DELETESTRING, dwVisibleIndex+1, 0); + } + } + + ++dwCount; + if(!(siCTemp->dwAttributes & SIC_INVISIBLE)) + ++dwVisibleIndex; + } + + siCTemp = siCTemp->Next; + } + } +} + +BOOL IsInList(DWORD dwCurrentItem, DWORD dwItems, DWORD *dwItemsSelected) +{ + DWORD i; + + for(i = 0; i < dwItems; i++) + { + if(dwItemsSelected[i] == dwCurrentItem) + return(TRUE); + } + + return(FALSE); +} + +void RestoreInvisibleFlag(siC *siCNode) +{ + char szBuf[MAX_BUF_TINY]; + char szAttribute[MAX_BUF_TINY]; + + GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig); + lstrcpy(szAttribute, szBuf); + CharUpperBuff(szAttribute, sizeof(szAttribute)); + + if(strstr(szAttribute, "INVISIBLE") || siCNode->bSupersede) + siCNode->dwAttributes |= SIC_INVISIBLE; + else + siCNode->dwAttributes &= ~SIC_INVISIBLE; +} + +void RestoreAdditionalFlag(siC *siCNode) +{ + char szBuf[MAX_BUF_TINY]; + char szAttribute[MAX_BUF_TINY]; + + GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig); + lstrcpy(szAttribute, szBuf); + CharUpperBuff(szAttribute, sizeof(szAttribute)); + + if(strstr(szAttribute, "ADDITIONAL") && !strstr(szAttribute, "NOTADDITIONAL")) + siCNode->dwAttributes |= SIC_ADDITIONAL; + else + siCNode->dwAttributes &= ~SIC_ADDITIONAL; +} + +void RestoreEnabledFlag(siC *siCNode) +{ + char szBuf[MAX_BUF_TINY]; + char szAttribute[MAX_BUF_TINY]; + + GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig); + lstrcpy(szAttribute, szBuf); + CharUpperBuff(szAttribute, sizeof(szAttribute)); + + if(strstr(szAttribute, "ENABLED") && !strstr(szAttribute, "DISABLED")) + siCNode->dwAttributes |= SIC_DISABLED; + else + siCNode->dwAttributes &= ~SIC_DISABLED; +} + +// This function: +// - Zeros the SELECTED and ADDITIONAL attributes of all components. +// - Set all attributes as specified for the specific Setup Type +// - Overrides attributes designated in any [Component XXX-Overwrite-Setup TypeX] +// sections for the specific Setup Type. +void SiCNodeSetItemsSelected(DWORD dwSetupType) +{ + siC *siCNode; + char szBuf[MAX_BUF]; + char szSTSection[MAX_BUF]; + char szComponentKey[MAX_BUF]; + char szComponentSection[MAX_BUF]; + char szOverrideSection[MAX_BUF]; + char szOverrideAttributes[MAX_BUF]; + DWORD dwIndex0; + + lstrcpy(szSTSection, "Setup Type"); + itoa(dwSetupType, szBuf, 10); + lstrcat(szSTSection, szBuf); + + // For each component in the global list unset its SELECTED and ADDITIONAL attributes + siCNode = siComponents; + do + { + if(siCNode == NULL) + break; + + /* clear these flags for all components so they can be + * reset later if they belong to the setup type the user + * selected */ + siCNode->dwAttributes &= ~SIC_SELECTED; + siCNode->dwAttributes &= ~SIC_ADDITIONAL; + siCNode->dwAttributes |= SIC_INVISIBLE; + + /* Force Upgrade needs to be performed here because the user has just + * selected the destination path for the product. The destination path is + * critical to the checking of the Force Upgrade. */ + ResolveForceUpgrade(siCNode); + ResolveSupersede(siCNode, &gGre); + siCNode = siCNode->Next; + } while((siCNode != NULL) && (siCNode != siComponents)); + + /* for each component in a setup type, set its ATTRIBUTES to the right values */ + dwIndex0 = 0; + wsprintf(szComponentKey, "C%d", dwIndex0); + GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIniConfig); + while(*szComponentSection != '\0') + { + if((siCNode = SiCNodeFind(siComponents, szComponentSection)) != NULL) + { + /* Component is in the Setup Type the user selected, so we now need to + * reset the INVISIBLE and ADDITIONAL flags because they were unset + * above and also are not reset anywhere else. */ + RestoreInvisibleFlag(siCNode); + RestoreAdditionalFlag(siCNode); + + wsprintf(szOverrideSection, "%s-Override-%s", siCNode->szReferenceName, szSTSection); + GetPrivateProfileString(szOverrideSection, "Attributes", "", szOverrideAttributes, sizeof(szOverrideAttributes), szFileIniConfig); + + if((siCNode->lRandomInstallPercentage != 0) && + (siCNode->lRandomInstallPercentage <= siCNode->lRandomInstallValue) && + !(siCNode->dwAttributes & SIC_DISABLED)) + { + /* Random Install Percentage check passed *and* the component + * is not DISABLED */ + if(*szOverrideAttributes != '\0') + siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE); + siCNode->dwAttributes &= ~SIC_SELECTED; + } + else if(sgProduct.dwCustomType != dwSetupType) + { + /* Setup Type other than custom detected, so + * make sure all components from this Setup Type + * is selected (regardless if it's DISABLED or not). + * Don't select components that are Superseded */ + if(!siCNode->bSupersede) + siCNode->dwAttributes |= SIC_SELECTED; + + /* We need to restore the ENBLED/DISABLED flag for this component + * from config.ini because it could have been altered in + * ResolveForceUpgrade(). We need to restore it here so the override + * attribute can override it here. */ + RestoreEnabledFlag(siCNode); + if(*szOverrideAttributes != '\0') + siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE); + } + else if(!(siCNode->dwAttributes & SIC_DISABLED) && !siCNode->bForceUpgrade && !siCNode->bSupersede) + { + /* Custom setup type detected and the component is + * not DISABLED and FORCE_UPGRADE. Reset the component's + * attribute to default. If the component is DISABLED and + * happens not be SELECTED in the config.ini file, we leave + * it as is. The user will see the component in the Options + * Dialogs as not selected and DISABLED. Not sure why we + * want this, but marketing might find it useful someday. */ + + GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig); + siCNode->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE); + if(*szOverrideAttributes != '\0') + siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE); + } + } + + ++dwIndex0; + wsprintf(szComponentKey, "C%d", dwIndex0); + GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIniConfig); + } +} + +char *SiCNodeGetReferenceName(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->szReferenceName); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->szReferenceName); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(NULL); +} + +char *SiCNodeGetDescriptionShort(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->szDescriptionShort); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->szDescriptionShort); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(NULL); +} + +char *SiCNodeGetDescriptionLong(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->szDescriptionLong); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->szDescriptionLong); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(NULL); +} + +ULONGLONG SiCNodeGetInstallSize(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->ullInstallSize); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->ullInstallSize); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(0L); +} + +ULONGLONG SiCNodeGetInstallSizeSystem(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->ullInstallSizeSystem); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->ullInstallSizeSystem); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(0L); +} + +ULONGLONG SiCNodeGetInstallSizeArchive(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == 0) + return(siCTemp->ullInstallSizeArchive); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + if(dwIndex == dwCount) + return(siCTemp->ullInstallSizeArchive); + + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(0L); +} + +/* retrieve Index of node containing short description */ +int SiCNodeGetIndexDS(char *szInDescriptionShort) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(lstrcmpi(szInDescriptionShort, siCTemp->szDescriptionShort) == 0) + return(dwCount); + + ++dwCount; + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(lstrcmpi(szInDescriptionShort, siCTemp->szDescriptionShort) == 0) + return(dwCount); + + ++dwCount; + siCTemp = siCTemp->Next; + } + } + return(-1); +} + +/* retrieve Index of node containing Reference Name */ +int SiCNodeGetIndexRN(char *szInReferenceName) +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(lstrcmpi(szInReferenceName, siCTemp->szReferenceName) == 0) + return(dwCount); + + ++dwCount; + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(lstrcmpi(szInReferenceName, siCTemp->szReferenceName) == 0) + return(dwCount); + + ++dwCount; + siCTemp = siCTemp->Next; + } + } + return(-1); +} + +siC *SiCNodeGetObject(DWORD dwIndex, BOOL bIncludeInvisibleObjs, DWORD dwACFlag) +{ + DWORD dwCount = -1; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if((bIncludeInvisibleObjs) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + ++dwCount; + } + else if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + ++dwCount; + } + + if(dwIndex == dwCount) + return(siCTemp); + + siCTemp = siCTemp->Next; + while((siCTemp != siComponents) && (siCTemp != NULL)) + { + if(bIncludeInvisibleObjs) + { + ++dwCount; + } + else if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && + ((dwACFlag == AC_ALL) || + ((dwACFlag == AC_COMPONENTS) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) || + ((dwACFlag == AC_ADDITIONAL_COMPONENTS) && (siCTemp->dwAttributes & SIC_ADDITIONAL)))) + { + ++dwCount; + } + + if(dwIndex == dwCount) + return(siCTemp); + + siCTemp = siCTemp->Next; + } + } + return(NULL); +} + +DWORD GetAdditionalComponentsCount() +{ + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(siCTemp->dwAttributes & SIC_ADDITIONAL) + { + ++dwCount; + } + + siCTemp = siCTemp->Next; + while((siCTemp != siComponents) && (siCTemp != NULL)) + { + if(siCTemp->dwAttributes & SIC_ADDITIONAL) + { + ++dwCount; + } + + siCTemp = siCTemp->Next; + } + } + return(dwCount); +} + +dsN *CreateDSNode() +{ + dsN *dsNode; + + if((dsNode = NS_GlobalAlloc(sizeof(struct diskSpaceNode))) == NULL) + exit(1); + + dsNode->ullSpaceRequired = 0; + + if((dsNode->szVDSPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + if((dsNode->szPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + dsNode->Next = dsNode; + dsNode->Prev = dsNode; + + return(dsNode); +} + +void DsNodeInsert(dsN **dsNHead, dsN *dsNTemp) +{ + if(*dsNHead == NULL) + { + *dsNHead = dsNTemp; + (*dsNHead)->Next = *dsNHead; + (*dsNHead)->Prev = *dsNHead; + } + else + { + dsNTemp->Next = *dsNHead; + dsNTemp->Prev = (*dsNHead)->Prev; + (*dsNHead)->Prev->Next = dsNTemp; + (*dsNHead)->Prev = dsNTemp; + } +} + +void DsNodeDelete(dsN **dsNTemp) +{ + if(*dsNTemp != NULL) + { + (*dsNTemp)->Next->Prev = (*dsNTemp)->Prev; + (*dsNTemp)->Prev->Next = (*dsNTemp)->Next; + (*dsNTemp)->Next = NULL; + (*dsNTemp)->Prev = NULL; + + FreeMemory(&((*dsNTemp)->szVDSPath)); + FreeMemory(&((*dsNTemp)->szPath)); + FreeMemory(dsNTemp); + } +} + +BOOL IsWin95Debute() +{ + HINSTANCE hLib; + BOOL bIsWin95Debute; + + bIsWin95Debute = FALSE; + if((hLib = LoadLibraryEx("kernel32.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) != NULL) + { + if(((FARPROC)NS_GetDiskFreeSpaceEx = GetProcAddress(hLib, "GetDiskFreeSpaceExA")) == NULL) + { + (FARPROC)NS_GetDiskFreeSpace = GetProcAddress(hLib, "GetDiskFreeSpaceA"); + bIsWin95Debute = TRUE; + } + + FreeLibrary(hLib); + } + return(bIsWin95Debute); +} + +/* returns the value in kilobytes */ +ULONGLONG GetDiskSpaceRequired(DWORD dwType) +{ + ULONGLONG ullTotalSize = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + if(siCTemp->dwAttributes & SIC_SELECTED) + { + switch(dwType) + { + case DSR_DESTINATION: + ullTotalSize += siCTemp->ullInstallSize; + break; + + case DSR_SYSTEM: + ullTotalSize += siCTemp->ullInstallSizeSystem; + break; + + case DSR_TEMP: + case DSR_DOWNLOAD_SIZE: + if((LocateJar(siCTemp, NULL, 0, gbPreviousUnfinishedDownload) == AP_NOT_FOUND) || + (dwType == DSR_DOWNLOAD_SIZE)) + ullTotalSize += siCTemp->ullInstallSizeArchive; + break; + } + } + + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + if(siCTemp->dwAttributes & SIC_SELECTED) + { + switch(dwType) + { + case DSR_DESTINATION: + ullTotalSize += siCTemp->ullInstallSize; + break; + + case DSR_SYSTEM: + ullTotalSize += siCTemp->ullInstallSizeSystem; + break; + + case DSR_TEMP: + case DSR_DOWNLOAD_SIZE: + if((LocateJar(siCTemp, NULL, 0, gbPreviousUnfinishedDownload) == AP_NOT_FOUND) || + (dwType == DSR_DOWNLOAD_SIZE)) + ullTotalSize += siCTemp->ullInstallSizeArchive; + break; + } + } + + siCTemp = siCTemp->Next; + } + } + + /* add the amount of disk space it will take for the + xpinstall engine in the TEMP area */ + if(dwType == DSR_TEMP) + if(siCFXpcomFile.bStatus == STATUS_ENABLED) + ullTotalSize += siCFXpcomFile.ullInstallSize; + + return(ullTotalSize); +} + +int LocateExistingPath(char *szPath, char *szExistingPath, DWORD dwExistingPathSize) +{ + char szBuf[MAX_BUF]; + + lstrcpy(szExistingPath, szPath); + AppendBackSlash(szExistingPath, dwExistingPathSize); + while((FileExists(szExistingPath) == FALSE)) + { + RemoveBackSlash(szExistingPath); + ParsePath(szExistingPath, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY); + lstrcpy(szExistingPath, szBuf); + AppendBackSlash(szExistingPath, dwExistingPathSize); + } + return(WIZ_OK); +} + +/* returns the value in bytes */ +ULONGLONG GetDiskSpaceAvailable(LPSTR szPath) +{ + char szTempPath[MAX_BUF]; + char szBuf[MAX_BUF]; + char szExistingPath[MAX_BUF]; + char szBuf2[MAX_BUF]; + ULARGE_INTEGER uliFreeBytesAvailableToCaller; + ULARGE_INTEGER uliTotalNumberOfBytesToCaller; + ULARGE_INTEGER uliTotalNumberOfFreeBytes; + ULONGLONG ullReturn = 0; + DWORD dwSectorsPerCluster; + DWORD dwBytesPerSector; + DWORD dwNumberOfFreeClusters; + DWORD dwTotalNumberOfClusters; + + if((gSystemInfo.dwOSType & OS_WIN95_DEBUTE) && (NS_GetDiskFreeSpace != NULL)) + { + ParsePath(szPath, szTempPath, MAX_BUF, FALSE, PP_ROOT_ONLY); + NS_GetDiskFreeSpace(szTempPath, + &dwSectorsPerCluster, + &dwBytesPerSector, + &dwNumberOfFreeClusters, + &dwTotalNumberOfClusters); + ullReturn = ((ULONGLONG)dwBytesPerSector * (ULONGLONG)dwSectorsPerCluster * (ULONGLONG)dwNumberOfFreeClusters); + } + else if(NS_GetDiskFreeSpaceEx != NULL) + { + LocateExistingPath(szPath, szExistingPath, sizeof(szExistingPath)); + AppendBackSlash(szExistingPath, sizeof(szExistingPath)); + + /* Appearently under Win9x, the path still needs to be in 8.3 format + * or GetDiskFreeSpaceEx() will fail. */ + if(gSystemInfo.dwOSType & OS_WIN9x) + { + lstrcpy(szBuf, szExistingPath); + GetShortPathName(szBuf, szExistingPath, sizeof(szExistingPath)); + } + + if(NS_GetDiskFreeSpaceEx(szExistingPath, + &uliFreeBytesAvailableToCaller, + &uliTotalNumberOfBytesToCaller, + &uliTotalNumberOfFreeBytes) == FALSE) + { + char szEDeterminingDiskSpace[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_DETERMINING_DISK_SPACE", "", szEDeterminingDiskSpace, sizeof(szEDeterminingDiskSpace), szFileIniInstall)) + { + lstrcpy(szBuf2, "\n "); + lstrcat(szBuf2, szPath); + wsprintf(szBuf, szEDeterminingDiskSpace, szBuf2); + PrintError(szBuf, ERROR_CODE_SHOW); + } + } + ullReturn = uliFreeBytesAvailableToCaller.QuadPart; + } + + if(ullReturn > 1024) + ullReturn /= 1024; + else + ullReturn = 0; + + return(ullReturn); +} + +HRESULT ErrorMsgDiskSpace(ULONGLONG ullDSAvailable, ULONGLONG ullDSRequired, LPSTR szPath, BOOL bCrutialMsg) +{ + char szBuf0[MAX_BUF]; + char szBuf1[MAX_BUF]; + char szBuf2[MAX_BUF]; + char szBuf3[MAX_BUF]; + char szBufRootPath[MAX_BUF]; + char szBufMsg[MAX_BUF]; + char szDSAvailable[MAX_BUF]; + char szDSRequired[MAX_BUF]; + char szDlgDiskSpaceCheckTitle[MAX_BUF]; + char szDlgDiskSpaceCheckMsg[MAX_BUF]; + DWORD dwDlgType; + + if(!GetPrivateProfileString("Messages", "DLG_DISK_SPACE_CHECK_TITLE", "", szDlgDiskSpaceCheckTitle, sizeof(szDlgDiskSpaceCheckTitle), szFileIniInstall)) + exit(1); + + if(bCrutialMsg) + { + dwDlgType = MB_RETRYCANCEL; + if(!GetPrivateProfileString("Messages", "DLG_DISK_SPACE_CHECK_CRUTIAL_MSG", "", szDlgDiskSpaceCheckMsg, sizeof(szDlgDiskSpaceCheckMsg), szFileIniInstall)) + exit(1); + } + else + { + dwDlgType = MB_OK; + if(!GetPrivateProfileString("Messages", "DLG_DISK_SPACE_CHECK_MSG", "", szDlgDiskSpaceCheckMsg, sizeof(szDlgDiskSpaceCheckMsg), szFileIniInstall)) + exit(1); + } + + ParsePath(szPath, szBufRootPath, sizeof(szBufRootPath), FALSE, PP_ROOT_ONLY); + RemoveBackSlash(szBufRootPath); + lstrcpy(szBuf0, szPath); + RemoveBackSlash(szBuf0); + + _ui64toa(ullDSAvailable, szDSAvailable, 10); + _ui64toa(ullDSRequired, szDSRequired, 10); + + wsprintf(szBuf1, "\n\n %s\n\n ", szBuf0); + wsprintf(szBuf2, "%s KB\n ", szDSRequired); + wsprintf(szBuf3, "%s KB\n\n", szDSAvailable); + wsprintf(szBufMsg, szDlgDiskSpaceCheckMsg, szBufRootPath, szBuf1, szBuf2, szBuf3); + + if((sgProduct.mode != SILENT) && (sgProduct.mode != AUTO)) + { + return(MessageBox(hWndMain, szBufMsg, szDlgDiskSpaceCheckTitle, dwDlgType | MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_APPLMODAL | MB_SETFOREGROUND)); + } + else if(sgProduct.mode == AUTO) + { + ShowMessage(szBufMsg, TRUE); + Delay(5); + ShowMessage(szBufMsg, FALSE); + exit(1); + } + + return(IDCANCEL); +} + +BOOL ContainsReparseTag(char *szPath, char *szReparsePath, DWORD dwReparsePathSize) +{ + BOOL bFoundReparseTag = FALSE; + DWORD dwOriginalLen = lstrlen(szPath); + DWORD dwLen = dwOriginalLen; + char *szPathTmp = NULL; + char *szBuf = NULL; + + if((szPathTmp = NS_GlobalAlloc(dwLen + 1)) == NULL) + exit(1); + if((szBuf = NS_GlobalAlloc(dwLen + 1)) == NULL) + exit(1); + + lstrcpy(szPathTmp, szPath); + while((szPathTmp[dwLen - 2] != ':') && (szPathTmp[dwLen - 2] != '\\')) + { + if(FileExists(szPathTmp) & FILE_ATTRIBUTE_REPARSE_POINT) + { + if((DWORD)lstrlen(szPathTmp) <= dwReparsePathSize) + lstrcpy(szReparsePath, szPathTmp); + else + ZeroMemory(szReparsePath, dwReparsePathSize); + + bFoundReparseTag = TRUE; + break; + } + + lstrcpy(szBuf, szPathTmp); + RemoveBackSlash(szBuf); + ParsePath(szBuf, szPathTmp, dwOriginalLen + 1, FALSE, PP_PATH_ONLY); + dwLen = lstrlen(szPathTmp); + } + + FreeMemory(&szBuf); + FreeMemory(&szPathTmp); + return(bFoundReparseTag); +} + +void UpdatePathDiskSpaceRequired(LPSTR szPath, ULONGLONG ullSize, dsN **dsnComponentDSRequirement) +{ + BOOL bFound = FALSE; + dsN *dsnTemp = *dsnComponentDSRequirement; + char szReparsePath[MAX_BUF]; + char szVDSPath[MAX_BUF]; + char szRootPath[MAX_BUF]; + + if(ullSize > 0) + { + ParsePath(szPath, szRootPath, sizeof(szRootPath), FALSE, PP_ROOT_ONLY); + + if(gSystemInfo.dwOSType & OS_WIN95_DEBUTE) + // check for Win95 debute version + lstrcpy(szVDSPath, szRootPath); + else if((gSystemInfo.dwOSType & OS_NT5) && + ContainsReparseTag(szPath, szReparsePath, sizeof(szReparsePath))) + { + // check for Reparse Tag (mount points under NT5 only) + if(*szReparsePath == '\0') + { + // szReparsePath is not big enough to hold the Reparse path. This is a + // non fatal error. Keep going using szPath instead. + lstrcpy(szVDSPath, szPath); + } + else if(GetDiskSpaceAvailable(szReparsePath) == GetDiskSpaceAvailable(szPath)) + // Check for user quota on path. It is very unlikely that the user quota + // for the path will be the same as the quota for its root path when user + // quota is enabled. + // + // If it happens to be the same, then I'm assuming that the disk space on + // the path's root path will decrease at the same rate as the path with + // user quota enabled. + // + // If user quota is not enabled on the folder, then use the root path. + lstrcpy(szVDSPath, szReparsePath); + else + lstrcpy(szVDSPath, szPath); + } + else if(GetDiskSpaceAvailable(szRootPath) == GetDiskSpaceAvailable(szPath)) + // Check for user quota on path. It is very unlikely that the user quota + // for the path will be the same as the quota for its root path when user + // quota is enabled. + // + // If it happens to be the same, then I'm assuming that the disk space on + // the path's root path will decrease at the same rate as the path with + // user quota enabled. + // + // If user quota is not enabled on the folder, then use the root path. + lstrcpy(szVDSPath, szRootPath); + else + lstrcpy(szVDSPath, szPath); + + do + { + if(*dsnComponentDSRequirement == NULL) + { + *dsnComponentDSRequirement = CreateDSNode(); + dsnTemp = *dsnComponentDSRequirement; + strcpy(dsnTemp->szVDSPath, szVDSPath); + strcpy(dsnTemp->szPath, szPath); + dsnTemp->ullSpaceRequired = ullSize; + bFound = TRUE; + } + else if(lstrcmpi(dsnTemp->szVDSPath, szVDSPath) == 0) + { + dsnTemp->ullSpaceRequired += ullSize; + bFound = TRUE; + } + else + dsnTemp = dsnTemp->Next; + + } while((dsnTemp != *dsnComponentDSRequirement) && (dsnTemp != NULL) && (bFound == FALSE)); + + if(bFound == FALSE) + { + dsnTemp = CreateDSNode(); + strcpy(dsnTemp->szVDSPath, szVDSPath); + strcpy(dsnTemp->szPath, szPath); + dsnTemp->ullSpaceRequired = ullSize; + DsNodeInsert(dsnComponentDSRequirement, dsnTemp); + } + } +} + +/* Function: DetermineGreComponentDestinationPath() + * + * in: char *aInPath - original path to where the 'Component GRE' is to + * be installed to. + * char *aOutPath - out buffer of what the new destinaton path will + * be for 'Component GRE'. This can be the same as aInPath. + * + * purpose: To figure determine if the original path is writable or not. If + * not, then use following as the new destination path: + * + * [product path]\GRE\[gre id] + * + * This path is guaranteed to work because the user chose it. There + * is logic to make sure we have write access to this new path thru + * the Setup Type dialog. + * This path is also the same path that will be passed on to the GRE + * installer in it's -dd command line parameter. + */ +HRESULT DetermineGreComponentDestinationPath(char *aInPath, char *aOutPath, DWORD aOutPathBufSize) +{ + int rv = WIZ_OK; + char inPath[MAX_BUF]; + + MozCopyStr(aInPath, inPath, sizeof(inPath)); + AppendBackSlash(inPath, sizeof(inPath)); + if(DirHasWriteAccess(inPath) != WIZ_OK) + { + char productPath[MAX_BUF]; + + MozCopyStr(sgProduct.szPath, productPath, sizeof(productPath)); + RemoveBackSlash(productPath); + + assert(*sgProduct.greID); + _snprintf(aOutPath, aOutPathBufSize, "%s\\GRE\\%s", productPath, sgProduct.greID); + aOutPath[aOutPathBufSize - 1] = '\0'; + } + else + MozCopyStr(aInPath, aOutPath, aOutPathBufSize); + + return(rv); +} + +HRESULT InitComponentDiskSpaceInfo(dsN **dsnComponentDSRequirement) +{ + DWORD dwIndex0; + siC *siCObject = NULL; + HRESULT hResult = 0; + char szBuf[MAX_BUF]; + char szIndex0[MAX_BUF]; + char szSysPath[MAX_BUF]; + char szBufSysPath[MAX_BUF]; + char szBufTempPath[MAX_BUF]; + + if(GetSystemDirectory(szSysPath, MAX_BUF) == 0) + { + ZeroMemory(szSysPath, MAX_BUF); + ZeroMemory(szBufSysPath, MAX_BUF); + } + else + { + ParsePath(szSysPath, szBufSysPath, sizeof(szBufSysPath), FALSE, PP_ROOT_ONLY); + AppendBackSlash(szBufSysPath, sizeof(szBufSysPath)); + } + + ParsePath(szTempDir, szBufTempPath, sizeof(szBufTempPath), FALSE, PP_ROOT_ONLY); + AppendBackSlash(szBufTempPath, sizeof(szBufTempPath)); + + dwIndex0 = 0; + itoa(dwIndex0, szIndex0, 10); + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + { + if(*(siCObject->szDestinationPath) == '\0') + lstrcpy(szBuf, sgProduct.szPath); + else if((lstrcmpi(siCObject->szReferenceName, "Component GRE") == 0) && + !IsInstallerProductGRE()) + /* We found 'Component GRE' and this product is not 'GRE'. The GRE + * product happens to also have a 'Component GRE', but we don't + * care about that one. */ + DetermineGreComponentDestinationPath(siCObject->szDestinationPath, szBuf, sizeof(szBuf)); + else + lstrcpy(szBuf, siCObject->szDestinationPath); + + AppendBackSlash(szBuf, sizeof(szBuf)); + UpdatePathDiskSpaceRequired(szBuf, siCObject->ullInstallSize, dsnComponentDSRequirement); + + if(*szTempDir != '\0') + UpdatePathDiskSpaceRequired(szTempDir, siCObject->ullInstallSizeArchive, dsnComponentDSRequirement); + + if(*szSysPath != '\0') + UpdatePathDiskSpaceRequired(szSysPath, siCObject->ullInstallSizeSystem, dsnComponentDSRequirement); + } + + ++dwIndex0; + itoa(dwIndex0, szIndex0, 10); + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + + /* take the uncompressed size of Xpcom into account */ + if(*szTempDir != '\0') + if(siCFXpcomFile.bStatus == STATUS_ENABLED) + UpdatePathDiskSpaceRequired(szTempDir, siCFXpcomFile.ullInstallSize, dsnComponentDSRequirement); + + return(hResult); +} + +HRESULT VerifyDiskSpace() +{ + ULONGLONG ullDSAvailable; + HRESULT hRetValue = FALSE; + dsN *dsnTemp = NULL; + + DeInitDSNode(&gdsnComponentDSRequirement); + InitComponentDiskSpaceInfo(&gdsnComponentDSRequirement); + if(gdsnComponentDSRequirement != NULL) + { + dsnTemp = gdsnComponentDSRequirement; + + do + { + if(dsnTemp != NULL) + { + ullDSAvailable = GetDiskSpaceAvailable(dsnTemp->szVDSPath); + if(ullDSAvailable < dsnTemp->ullSpaceRequired) + { + hRetValue = ErrorMsgDiskSpace(ullDSAvailable, dsnTemp->ullSpaceRequired, dsnTemp->szPath, FALSE); + break; + } + + dsnTemp = dsnTemp->Next; + } + } while((dsnTemp != NULL) && (dsnTemp != gdsnComponentDSRequirement)); + } + return(hRetValue); +} + +/* Function: ParseOSType + * + * Input: char * + * + * Return: DWORD + * + * Description: This function parses an input string (szOSType) for specific + * string keys: + * WIN95_DEBUTE, WIN95, WIN98, NT3, NT4, NT5, NT50, NT51 + * + * It then stores the information in a DWORD, each bit corresponding to a + * particular OS type. + */ +DWORD ParseOSType(char *szOSType) +{ + char szBuf[MAX_BUF]; + DWORD dwOSType = 0; + + lstrcpy(szBuf, szOSType); + CharUpperBuff(szBuf, sizeof(szBuf)); + + if(strstr(szBuf, "WIN95 DEBUTE")) + dwOSType |= OS_WIN95_DEBUTE; + if(strstr(szBuf, "WIN95") && + !strstr(szBuf, "WIN95 DEBUTE")) + dwOSType |= OS_WIN95; + if(strstr(szBuf, "WIN98")) + dwOSType |= OS_WIN98; + if(strstr(szBuf, "NT3")) + dwOSType |= OS_NT3; + if(strstr(szBuf, "NT4")) + dwOSType |= OS_NT4; + if(strstr(szBuf, "NT50")) + dwOSType |= OS_NT50; + if(strstr(szBuf, "NT51")) + dwOSType |= OS_NT51; + if(strstr(szBuf, "NT5") && + !strstr(szBuf, "NT50") && + !strstr(szBuf, "NT51")) + dwOSType |= OS_NT5; + + return(dwOSType); +} + +HRESULT ParseComponentAttributes(char *szAttribute, DWORD dwAttributes, BOOL bOverride) +{ + char szBuf[MAX_BUF]; + + lstrcpy(szBuf, szAttribute); + CharUpperBuff(szBuf, sizeof(szBuf)); + + if(bOverride != TRUE) + { + if(strstr(szBuf, "LAUNCHAPP")) + dwAttributes |= SIC_LAUNCHAPP; + if(strstr(szBuf, "DOWNLOAD_ONLY")) + dwAttributes |= SIC_DOWNLOAD_ONLY; + if(strstr(szBuf, "FORCE_UPGRADE")) + dwAttributes |= SIC_FORCE_UPGRADE; + if(strstr(szBuf, "IGNORE_DOWNLOAD_ERROR")) + dwAttributes |= SIC_IGNORE_DOWNLOAD_ERROR; + if(strstr(szBuf, "IGNORE_XPINSTALL_ERROR")) + dwAttributes |= SIC_IGNORE_XPINSTALL_ERROR; + if(strstr(szBuf, "UNCOMPRESS")) + dwAttributes |= SIC_UNCOMPRESS; + } + + if(strstr(szBuf, "UNSELECTED")) + dwAttributes &= ~SIC_SELECTED; + else if(strstr(szBuf, "SELECTED")) + dwAttributes |= SIC_SELECTED; + + if(strstr(szBuf, "INVISIBLE")) + dwAttributes |= SIC_INVISIBLE; + else if(strstr(szBuf, "VISIBLE")) + dwAttributes &= ~SIC_INVISIBLE; + + if(strstr(szBuf, "DISABLED")) + dwAttributes |= SIC_DISABLED; + if(strstr(szBuf, "ENABLED")) + dwAttributes &= ~SIC_DISABLED; + + if(strstr(szBuf, "NOTADDITIONAL")) + dwAttributes &= ~SIC_ADDITIONAL; + else if(strstr(szBuf, "ADDITIONAL")) + dwAttributes |= SIC_ADDITIONAL; + + if(strstr(szBuf, "NOTSUPERSEDE")) + dwAttributes &= ~SIC_SUPERSEDE; + else if(strstr(szBuf, "SUPERSEDE")) + dwAttributes |= SIC_SUPERSEDE; + + + return(dwAttributes); +} + +long RandomSelect() +{ + long lArbitrary = 0; + + srand((unsigned)time(NULL)); + lArbitrary = rand() % 100; + return(lArbitrary); +} + +siC *SiCNodeFind(siC *siCHeadNode, char *szInReferenceName) +{ + siC *siCNode = siCHeadNode; + + do + { + if(siCNode == NULL) + break; + + if(lstrcmpi(siCNode->szReferenceName, szInReferenceName) == 0) + return(siCNode); + + siCNode = siCNode->Next; + } while((siCNode != NULL) && (siCNode != siCHeadNode)); + + return(NULL); +} + +BOOL ResolveForceUpgrade(siC *siCObject) +{ + DWORD dwIndex; + char szFilePath[MAX_BUF]; + char szKey[MAX_BUF_TINY]; + char szForceUpgradeFile[MAX_BUF]; + + siCObject->bForceUpgrade = FALSE; + if(siCObject->dwAttributes & SIC_FORCE_UPGRADE) + { + if(!sgProduct.doCleanupOnUpgrade) + { + dwIndex = 0; + BuildNumberedString(dwIndex, NULL, "Force Upgrade File", szKey, sizeof(szKey)); + GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szForceUpgradeFile, sizeof(szForceUpgradeFile), szFileIniConfig); + while(*szForceUpgradeFile != '\0') + { + DecryptString(szFilePath, szForceUpgradeFile); + if(FileExists(szFilePath)) + { + siCObject->bForceUpgrade = TRUE; + + /* Found at least one file, so break out of while loop */ + break; + } + + BuildNumberedString(++dwIndex, NULL, "Force Upgrade File", szKey, sizeof(szKey)); + GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szForceUpgradeFile, sizeof(szForceUpgradeFile), szFileIniConfig); + } + } + + if(siCObject->bForceUpgrade) + { + siCObject->dwAttributes |= SIC_SELECTED; + siCObject->dwAttributes |= SIC_DISABLED; + } + else + /* Make sure to unset the DISABLED bit. If the Setup Type is other than + * Custom, then we don't care if it's DISABLED or not because this flag + * is only used in the Custom dialogs. + * + * If the Setup Type is Custom and this component is DISABLED by default + * via the config.ini, it's default value will be restored in the + * SiCNodeSetItemsSelected() function that called ResolveForceUpgrade(). */ + siCObject->dwAttributes &= ~SIC_DISABLED; + } + return(siCObject->bForceUpgrade); +} + +void InitSiComponents(char *szFileIni) +{ + DWORD dwIndex0; + DWORD dwIndex1; + int iCurrentLoop; + char szIndex0[MAX_BUF]; + char szIndex1[MAX_BUF]; + char szBuf[MAX_BUF]; + char szComponentKey[MAX_BUF]; + char szComponentSection[MAX_BUF]; + char szDependency[MAX_BUF]; + char szDependee[MAX_BUF]; + char szSTSection[MAX_BUF]; + char szDPSection[MAX_BUF]; + siC *siCTemp = NULL; + siCD *siCDepTemp = NULL; + siCD *siCDDependeeTemp = NULL; + + /* clean up the list before reading new components given the Setup Type */ + DeInitSiComponents(&siComponents); + + /* Parse the Setup Type sections in reverse order because + * the Custom Setup Type is always last. It needs to be parsed + * first because the component list it has will be shown in its + * other custom dialogs. Order matters! */ + for(iCurrentLoop = 3; iCurrentLoop >= 0; iCurrentLoop--) + { + lstrcpy(szSTSection, "Setup Type"); + itoa(iCurrentLoop, szBuf, 10); + lstrcat(szSTSection, szBuf); + + /* read in each component given a setup type */ + dwIndex0 = 0; + itoa(dwIndex0, szIndex0, 10); + lstrcpy(szComponentKey, "C"); + lstrcat(szComponentKey, szIndex0); + GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIni); + while(*szComponentSection != '\0') + { + GetPrivateProfileString(szComponentSection, "Archive", "", szBuf, sizeof(szBuf), szFileIni); + if((*szBuf != '\0') && (SiCNodeFind(siComponents, szComponentSection) == NULL)) + { + /* create and initialize empty node */ + siCTemp = CreateSiCNode(); + + /* store name of archive for component */ + lstrcpy(siCTemp->szArchiveName, szBuf); + + /* store name of the uncompressed archive for the component */ + GetPrivateProfileString(szComponentSection, + "Archive Uncompressed", + "", + siCTemp->szArchiveNameUncompressed, + sizeof(szBuf), + szFileIni); + + /* get short description of component */ + GetPrivateProfileString(szComponentSection, "Description Short", "", szBuf, sizeof(szBuf), szFileIni); + lstrcpy(siCTemp->szDescriptionShort, szBuf); + + /* get long description of component */ + GetPrivateProfileString(szComponentSection, "Description Long", "", szBuf, sizeof(szBuf), szFileIni); + lstrcpy(siCTemp->szDescriptionLong, szBuf); + + /* get commandline parameter for component */ + GetPrivateProfileString(szComponentSection, "Parameter", "", siCTemp->szParameter, MAX_BUF, szFileIni); + + /* set reference name for component */ + lstrcpy(siCTemp->szReferenceName, szComponentSection); + + /* get install size required in destination for component. Sould be in Kilobytes */ + GetPrivateProfileString(szComponentSection, "Install Size", "", szBuf, sizeof(szBuf), szFileIni); + if(*szBuf != '\0') + siCTemp->ullInstallSize = _atoi64(szBuf); + else + siCTemp->ullInstallSize = 0; + + /* get install size required in system for component. Sould be in Kilobytes */ + GetPrivateProfileString(szComponentSection, "Install Size System", "", szBuf, sizeof(szBuf), szFileIni); + if(*szBuf != '\0') + siCTemp->ullInstallSizeSystem = _atoi64(szBuf); + else + siCTemp->ullInstallSizeSystem = 0; + + /* get install size required in temp for component. Sould be in Kilobytes */ + GetPrivateProfileString(szComponentSection, "Install Size Archive", "", szBuf, sizeof(szBuf), szFileIni); + if(*szBuf != '\0') + siCTemp->ullInstallSizeArchive = _atoi64(szBuf); + else + siCTemp->ullInstallSizeArchive = 0; + + /* get attributes of component */ + GetPrivateProfileString(szComponentSection, "Attributes", "", szBuf, sizeof(szBuf), szFileIni); + siCTemp->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE); + + /* get the random percentage value and select or deselect the component (by default) for + * installation */ + GetPrivateProfileString(szComponentSection, "Random Install Percentage", "", szBuf, sizeof(szBuf), szFileIni); + if(*szBuf != '\0') + { + siCTemp->lRandomInstallPercentage = atol(szBuf); + if(siCTemp->lRandomInstallPercentage != 0) + siCTemp->lRandomInstallValue = RandomSelect(); + } + + /* get all dependencies for this component */ + dwIndex1 = 0; + itoa(dwIndex1, szIndex1, 10); + lstrcpy(szDependency, "Dependency"); + lstrcat(szDependency, szIndex1); + GetPrivateProfileString(szComponentSection, szDependency, "", szBuf, sizeof(szBuf), szFileIni); + while(*szBuf != '\0') + { + /* create and initialize empty node */ + siCDepTemp = CreateSiCDepNode(); + + /* store name of archive for component */ + lstrcpy(siCDepTemp->szReferenceName, szBuf); + + /* inserts the newly created component into the global component list */ + SiCDepNodeInsert(&(siCTemp->siCDDependencies), siCDepTemp); + + ProcessWindowsMessages(); + ++dwIndex1; + itoa(dwIndex1, szIndex1, 10); + lstrcpy(szDependency, "Dependency"); + lstrcat(szDependency, szIndex1); + GetPrivateProfileString(szComponentSection, szDependency, "", szBuf, sizeof(szBuf), szFileIni); + } + + /* get all dependees for this component */ + dwIndex1 = 0; + itoa(dwIndex1, szIndex1, 10); + lstrcpy(szDependee, "Dependee"); + lstrcat(szDependee, szIndex1); + GetPrivateProfileString(szComponentSection, szDependee, "", szBuf, sizeof(szBuf), szFileIni); + while(*szBuf != '\0') + { + /* create and initialize empty node */ + siCDDependeeTemp = CreateSiCDepNode(); + + /* store name of archive for component */ + lstrcpy(siCDDependeeTemp->szReferenceName, szBuf); + + /* inserts the newly created component into the global component list */ + SiCDepNodeInsert(&(siCTemp->siCDDependees), siCDDependeeTemp); + + ProcessWindowsMessages(); + ++dwIndex1; + itoa(dwIndex1, szIndex1, 10); + lstrcpy(szDependee, "Dependee"); + lstrcat(szDependee, szIndex1); + GetPrivateProfileString(szComponentSection, szDependee, "", szBuf, sizeof(szBuf), szFileIni); + } + + // locate previous path if necessary + lstrcpy(szDPSection, szComponentSection); + lstrcat(szDPSection, "-Destination Path"); + if(LocatePreviousPath(szDPSection, siCTemp->szDestinationPath, MAX_PATH) == FALSE) + ZeroMemory(siCTemp->szDestinationPath, MAX_PATH); + + /* inserts the newly created component into the global component list */ + SiCNodeInsert(&siComponents, siCTemp); + } + + ProcessWindowsMessages(); + ++dwIndex0; + itoa(dwIndex0, szIndex0, 10); + lstrcpy(szComponentKey, "C"); + lstrcat(szComponentKey, szIndex0); + GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIni); + } + } + + sgProduct.dwNumberOfComponents = dwIndex0; +} + +void ResetComponentAttributes(char *szFileIni) +{ + char szIndex[MAX_BUF]; + char szBuf[MAX_BUF]; + char szComponentItem[MAX_BUF]; + siC *siCTemp; + DWORD dwCounter; + + for(dwCounter = 0; dwCounter < sgProduct.dwNumberOfComponents; dwCounter++) + { + itoa(dwCounter, szIndex, 10); + lstrcpy(szComponentItem, "Component"); + lstrcat(szComponentItem, szIndex); + + siCTemp = SiCNodeGetObject(dwCounter, TRUE, AC_ALL); + GetPrivateProfileString(szComponentItem, "Attributes", "", szBuf, sizeof(szBuf), szFileIni); + siCTemp->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE); + } +} + +void UpdateSiteSelector() +{ + DWORD dwIndex; + char szIndex[MAX_BUF]; + char szKDescription[MAX_BUF]; + char szDescription[MAX_BUF]; + char szKDomain[MAX_BUF]; + char szDomain[MAX_BUF]; + char szFileIniRedirect[MAX_BUF]; + ssi *ssiSiteSelectorTemp; + + lstrcpy(szFileIniRedirect, szTempDir); + AppendBackSlash(szFileIniRedirect, sizeof(szFileIniRedirect)); + lstrcat(szFileIniRedirect, FILE_INI_REDIRECT); + + if(FileExists(szFileIniRedirect) == FALSE) + return; + + /* get all dependees for this component */ + dwIndex = 0; + itoa(dwIndex, szIndex, 10); + lstrcpy(szKDescription, "Description"); + lstrcpy(szKDomain, "Domain"); + lstrcat(szKDescription, szIndex); + lstrcat(szKDomain, szIndex); + GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIniRedirect); + while(*szDescription != '\0') + { + if(lstrcmpi(szDescription, szSiteSelectorDescription) == 0) + { + GetPrivateProfileString("Site Selector", szKDomain, "", szDomain, sizeof(szDomain), szFileIniRedirect); + if(*szDomain != '\0') + { + ssiSiteSelectorTemp = SsiGetNode(szDescription); + if(ssiSiteSelectorTemp != NULL) + { + lstrcpy(ssiSiteSelectorTemp->szDomain, szDomain); + } + else + { + /* no match found for the given domain description, so assume there's nothing + * to change. just return. */ + return; + } + } + else + { + /* found matched description, but domain was not set, so assume there's no + * redirect required, just return. */ + return; + } + } + + ++dwIndex; + itoa(dwIndex, szIndex, 10); + lstrcpy(szKDescription, "Description"); + lstrcpy(szKDomain, "Domain"); + lstrcat(szKDescription, szIndex); + lstrcat(szKDomain, szIndex); + ZeroMemory(szDescription, sizeof(szDescription)); + ZeroMemory(szDomain, sizeof(szDomain)); + GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIniRedirect); + } +} + +void InitSiteSelector(char *szFileIni) +{ + DWORD dwIndex; + char szIndex[MAX_BUF]; + char szKDescription[MAX_BUF]; + char szDescription[MAX_BUF]; + char szKDomain[MAX_BUF]; + char szDomain[MAX_BUF]; + char szKIdentifier[MAX_BUF]; + char szIdentifier[MAX_BUF]; + ssi *ssiSiteSelectorNewNode; + + ssiSiteSelector = NULL; + + /* get all dependees for this component */ + dwIndex = 0; + itoa(dwIndex, szIndex, 10); + lstrcpy(szKDescription, "Description"); + lstrcpy(szKDomain, "Domain"); + lstrcpy(szKIdentifier, "Identifier"); + lstrcat(szKDescription, szIndex); + lstrcat(szKDomain, szIndex); + lstrcat(szKIdentifier, szIndex); + GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIni); + while(*szDescription != '\0') + { + /* if the Domain and Identifier are not set, then skip */ + GetPrivateProfileString("Site Selector", szKDomain, "", szDomain, sizeof(szDomain), szFileIni); + GetPrivateProfileString("Site Selector", szKIdentifier, "", szIdentifier, sizeof(szIdentifier), szFileIni); + if((*szDomain != '\0') && (*szIdentifier != '\0')) + { + /* create and initialize empty node */ + ssiSiteSelectorNewNode = CreateSsiSiteSelectorNode(); + + lstrcpy(ssiSiteSelectorNewNode->szDescription, szDescription); + lstrcpy(ssiSiteSelectorNewNode->szDomain, szDomain); + lstrcpy(ssiSiteSelectorNewNode->szIdentifier, szIdentifier); + + /* inserts the newly created node into the global node list */ + SsiSiteSelectorNodeInsert(&(ssiSiteSelector), ssiSiteSelectorNewNode); + } + + ProcessWindowsMessages(); + ++dwIndex; + itoa(dwIndex, szIndex, 10); + lstrcpy(szKDescription, "Description"); + lstrcpy(szKDomain, "Domain"); + lstrcpy(szKIdentifier, "Identifier"); + lstrcat(szKDescription, szIndex); + lstrcat(szKDomain, szIndex); + lstrcat(szKIdentifier, szIndex); + ZeroMemory(szDescription, sizeof(szDescription)); + ZeroMemory(szDomain, sizeof(szDomain)); + ZeroMemory(szIdentifier, sizeof(szIdentifier)); + GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIni); + } +} + +void InitErrorMessageStream(char *szFileIni) +{ + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Message Stream", + "Status", + "", + szBuf, + sizeof(szBuf), + szFileIni); + + if(lstrcmpi(szBuf, "disabled") == 0) + gErrorMessageStream.bEnabled = FALSE; + else + gErrorMessageStream.bEnabled = TRUE; + + GetPrivateProfileString("Message Stream", + "url", + "", + gErrorMessageStream.szURL, + sizeof(gErrorMessageStream.szURL), + szFileIni); + + GetPrivateProfileString("Message Stream", + "Show Confirmation", + "", + szBuf, + sizeof(szBuf), + szFileIni); + if(strcmpi(szBuf, "FALSE") == 0) + gErrorMessageStream.bShowConfirmation = FALSE; + else + gErrorMessageStream.bShowConfirmation = TRUE; + + GetPrivateProfileString("Message Stream", + "Confirmation Message", + "", + gErrorMessageStream.szConfirmationMessage, + sizeof(szBuf), + szFileIni); + + gErrorMessageStream.bSendMessage = FALSE; + gErrorMessageStream.dwMessageBufSize = MAX_BUF; + gErrorMessageStream.szMessage = NS_GlobalAlloc(gErrorMessageStream.dwMessageBufSize); +} + +void DeInitErrorMessageStream() +{ + FreeMemory(&gErrorMessageStream.szMessage); +} + +#ifdef SSU_DEBUG +void ViewSiComponentsDependency(char *szBuffer, char *szIndentation, siC *siCNode) +{ + siC *siCNodeTemp; + siCD *siCDependencyTemp; + + siCDependencyTemp = siCNode->siCDDependencies; + if(siCDependencyTemp != NULL) + { + char szIndentationPadding[MAX_BUF]; + DWORD dwIndex; + + lstrcpy(szIndentationPadding, szIndentation); + lstrcat(szIndentationPadding, " "); + + do + { + lstrcat(szBuffer, szIndentationPadding); + lstrcat(szBuffer, siCDependencyTemp->szReferenceName); + lstrcat(szBuffer, "::"); + + if((dwIndex = SiCNodeGetIndexRN(siCDependencyTemp->szReferenceName)) != -1) + lstrcat(szBuffer, SiCNodeGetDescriptionShort(dwIndex, TRUE, AC_ALL)); + else + lstrcat(szBuffer, "Component does not exist"); + + lstrcat(szBuffer, ":"); + lstrcat(szBuffer, "\n"); + + if(dwIndex != -1) + { + if((siCNodeTemp = SiCNodeGetObject(dwIndex, TRUE, AC_ALL)) != NULL) + ViewSiComponentsDependency(szBuffer, szIndentationPadding, siCNodeTemp); + else + lstrcat(szBuffer, "Node not found"); + } + + siCDependencyTemp = siCDependencyTemp->Next; + }while((siCDependencyTemp != NULL) && (siCDependencyTemp != siCNode->siCDDependencies)); + } +} + +void ViewSiComponentsDependee(char *szBuffer, char *szIndentation, siC *siCNode) +{ + siC *siCNodeTemp; + siCD *siCDependeeTemp; + + siCDependeeTemp = siCNode->siCDDependees; + if(siCDependeeTemp != NULL) + { + char szIndentationPadding[MAX_BUF]; + DWORD dwIndex; + + lstrcpy(szIndentationPadding, szIndentation); + lstrcat(szIndentationPadding, " "); + + do + { + lstrcat(szBuffer, szIndentationPadding); + lstrcat(szBuffer, siCDependeeTemp->szReferenceName); + lstrcat(szBuffer, "::"); + + if((dwIndex = SiCNodeGetIndexRN(siCDependeeTemp->szReferenceName)) != -1) + lstrcat(szBuffer, SiCNodeGetDescriptionShort(dwIndex, TRUE, AC_ALL)); + else + lstrcat(szBuffer, "Component does not exist"); + + lstrcat(szBuffer, ":"); + lstrcat(szBuffer, "\n"); + + if(dwIndex != -1) + { + if((siCNodeTemp = SiCNodeGetObject(dwIndex, TRUE, AC_ALL)) != NULL) + ViewSiComponentsDependency(szBuffer, szIndentationPadding, siCNodeTemp); + else + lstrcat(szBuffer, "Node not found"); + } + + siCDependeeTemp = siCDependeeTemp->Next; + }while((siCDependeeTemp != NULL) && (siCDependeeTemp != siCNode->siCDDependees)); + } +} + +void ViewSiComponents() +{ + char szBuf[MAX_BUF]; + siC *siCTemp = siComponents; + + // build dependency list + ZeroMemory(szBuf, sizeof(szBuf)); + lstrcpy(szBuf, "Dependency:\n"); + + do + { + if(siCTemp == NULL) + break; + + lstrcat(szBuf, " "); + lstrcat(szBuf, siCTemp->szReferenceName); + lstrcat(szBuf, "::"); + lstrcat(szBuf, siCTemp->szDescriptionShort); + lstrcat(szBuf, ":\n"); + + ViewSiComponentsDependency(szBuf, " ", siCTemp); + + siCTemp = siCTemp->Next; + } while((siCTemp != NULL) && (siCTemp != siComponents)); + + MessageBox(hWndMain, szBuf, NULL, MB_ICONEXCLAMATION); + + // build dependee list + ZeroMemory(szBuf, sizeof(szBuf)); + lstrcpy(szBuf, "Dependee:\n"); + + do + { + if(siCTemp == NULL) + break; + + lstrcat(szBuf, " "); + lstrcat(szBuf, siCTemp->szReferenceName); + lstrcat(szBuf, "::"); + lstrcat(szBuf, siCTemp->szDescriptionShort); + lstrcat(szBuf, ":\n"); + + ViewSiComponentsDependee(szBuf, " ", siCTemp); + + siCTemp = siCTemp->Next; + } while((siCTemp != NULL) && (siCTemp != siComponents)); + + MessageBox(hWndMain, szBuf, NULL, MB_ICONEXCLAMATION); +} +#endif /* SSU_DEBUG */ + +void DeInitSiCDependencies(siCD *siCDDependencies) +{ + siCD *siCDepTemp; + + if(siCDDependencies == NULL) + { + return; + } + else if((siCDDependencies->Prev == NULL) || (siCDDependencies->Prev == siCDDependencies)) + { + SiCDepNodeDelete(siCDDependencies); + return; + } + else + { + siCDepTemp = siCDDependencies->Prev; + } + + while(siCDepTemp != siCDDependencies) + { + SiCDepNodeDelete(siCDepTemp); + siCDepTemp = siCDDependencies->Prev; + } + SiCDepNodeDelete(siCDepTemp); +} + +void DeInitSiComponents(siC **siCHeadNode) +{ + siC *siCTemp; + + if((*siCHeadNode) == NULL) + { + return; + } + else if(((*siCHeadNode)->Prev == NULL) || ((*siCHeadNode)->Prev == (*siCHeadNode))) + { + SiCNodeDelete((*siCHeadNode)); + return; + } + else + { + siCTemp = (*siCHeadNode)->Prev; + } + + while(siCTemp != (*siCHeadNode)) + { + SiCNodeDelete(siCTemp); + siCTemp = (*siCHeadNode)->Prev; + } + SiCNodeDelete(siCTemp); +} + +void DeInitDSNode(dsN **dsnComponentDSRequirement) +{ + dsN *dsNTemp; + + if(*dsnComponentDSRequirement == NULL) + { + return; + } + else if(((*dsnComponentDSRequirement)->Prev == NULL) || ((*dsnComponentDSRequirement)->Prev == *dsnComponentDSRequirement)) + { + DsNodeDelete(dsnComponentDSRequirement); + return; + } + else + { + dsNTemp = (*dsnComponentDSRequirement)->Prev; + } + + while(dsNTemp != *dsnComponentDSRequirement) + { + DsNodeDelete(&dsNTemp); + dsNTemp = (*dsnComponentDSRequirement)->Prev; + } + DsNodeDelete(dsnComponentDSRequirement); +} + +BOOL ResolveComponentDependency(siCD *siCDInDependency, HWND hwndListBox) +{ + int dwIndex; + siCD *siCDepTemp = siCDInDependency; + BOOL bMoreToResolve = FALSE; + DWORD dwAttrib; + + if(siCDepTemp != NULL) + { + if((dwIndex = SiCNodeGetIndexRN(siCDepTemp->szReferenceName)) != -1) + { + dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL); + if(!(dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED)) + { + bMoreToResolve = TRUE; + SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, TRUE, AC_ALL, hwndListBox); + } + } + + siCDepTemp = siCDepTemp->Next; + while((siCDepTemp != NULL) && (siCDepTemp != siCDInDependency)) + { + if((dwIndex = SiCNodeGetIndexRN(siCDepTemp->szReferenceName)) != -1) + { + dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL); + if(!(dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED)) + { + bMoreToResolve = TRUE; + SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, TRUE, AC_ALL, hwndListBox); + } + } + + siCDepTemp = siCDepTemp->Next; + } + } + return(bMoreToResolve); +} + +BOOL ResolveDependencies(DWORD dwIndex, HWND hwndListBox) +{ + BOOL bMoreToResolve = FALSE; + DWORD dwCount = 0; + siC *siCTemp = siComponents; + + if(siCTemp != NULL) + { + /* can resolve specific component or all components (-1) */ + if((dwIndex == dwCount) || (dwIndex == -1)) + { + if(SiCNodeGetAttributes(dwCount, TRUE, AC_ALL) & SIC_SELECTED) + { + bMoreToResolve = ResolveComponentDependency(siCTemp->siCDDependencies, hwndListBox); + if(dwIndex == dwCount) + { + return(bMoreToResolve); + } + } + } + + ++dwCount; + siCTemp = siCTemp->Next; + while((siCTemp != NULL) && (siCTemp != siComponents)) + { + /* can resolve specific component or all components (-1) */ + if((dwIndex == dwCount) || (dwIndex == -1)) + { + if(SiCNodeGetAttributes(dwCount, TRUE, AC_ALL) & SIC_SELECTED) + { + bMoreToResolve = ResolveComponentDependency(siCTemp->siCDDependencies, hwndListBox); + if(dwIndex == dwCount) + { + return(bMoreToResolve); + } + } + } + + ++dwCount; + siCTemp = siCTemp->Next; + } + } + return(bMoreToResolve); +} + +BOOL ResolveComponentDependee(siCD *siCDInDependee) +{ + int dwIndex; + siCD *siCDDependeeTemp = siCDInDependee; + BOOL bAtLeastOneSelected = FALSE; + + if(siCDDependeeTemp != NULL) + { + if((dwIndex = SiCNodeGetIndexRN(siCDDependeeTemp->szReferenceName)) != -1) + { + if((SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL) & SIC_SELECTED) == TRUE) + { + bAtLeastOneSelected = TRUE; + } + } + + siCDDependeeTemp = siCDDependeeTemp->Next; + while((siCDDependeeTemp != NULL) && (siCDDependeeTemp != siCDInDependee)) + { + if((dwIndex = SiCNodeGetIndexRN(siCDDependeeTemp->szReferenceName)) != -1) + { + if((SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL) & SIC_SELECTED) == TRUE) + { + bAtLeastOneSelected = TRUE; + } + } + + siCDDependeeTemp = siCDDependeeTemp->Next; + } + } + return(bAtLeastOneSelected); +} + +ssi* SsiGetNode(LPSTR szDescription) +{ + ssi *ssiSiteSelectorTemp = ssiSiteSelector; + + do + { + if(ssiSiteSelectorTemp == NULL) + break; + + if(lstrcmpi(ssiSiteSelectorTemp->szDescription, szDescription) == 0) + return(ssiSiteSelectorTemp); + + ssiSiteSelectorTemp = ssiSiteSelectorTemp->Next; + } while((ssiSiteSelectorTemp != NULL) && (ssiSiteSelectorTemp != ssiSiteSelector)); + + return(NULL); +} + +void ResolveDependees(LPSTR szToggledReferenceName, HWND hwndListBox) +{ + BOOL bAtLeastOneSelected; + BOOL bMoreToResolve = FALSE; + siC *siCTemp = siComponents; + DWORD dwIndex; + DWORD dwAttrib; + + do + { + if(siCTemp == NULL) + break; + + if((siCTemp->siCDDependees != NULL) && + (lstrcmpi(siCTemp->szReferenceName, szToggledReferenceName) != 0)) + { + bAtLeastOneSelected = ResolveComponentDependee(siCTemp->siCDDependees); + if(bAtLeastOneSelected == FALSE) + { + if((dwIndex = SiCNodeGetIndexRN(siCTemp->szReferenceName)) != -1) + { + dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL); + if((dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED)) + { + SiCNodeSetAttributes(dwIndex, SIC_SELECTED, FALSE, TRUE, AC_ALL, hwndListBox); + bMoreToResolve = TRUE; + } + } + } + else + { + if((dwIndex = SiCNodeGetIndexRN(siCTemp->szReferenceName)) != -1) + { + dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL); + if(!(dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED)) + { + SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, TRUE, AC_ALL, hwndListBox); + bMoreToResolve = TRUE; + } + } + } + } + + siCTemp = siCTemp->Next; + } while((siCTemp != NULL) && (siCTemp != siComponents)); + + if(bMoreToResolve == TRUE) + ResolveDependees(szToggledReferenceName, hwndListBox); +} + +/* Function: ReplacePrivateProfileStrCR() + * + * in: LPSTR aInputOutputStr: In/out string to containing "\\n" to replace. + * + * purpose: To parse for and replace "\\n" string with "\n". Strings stored + * in .ini files cannot contain "\n" because it's a key delimiter. + * To work around this limination, "\\n" chars can be used to + * represent '\n'. This function will look for "\\n" and replace + * them with a true "\n". + * If it encounters a string of "\\\\n" (which looks like '\\n'), + * then this function will strip out the extra '\\' and just show + * "\\n"; + */ +void ReplacePrivateProfileStrCR(LPSTR aInputOutputStr) +{ + LPSTR pSearch = aInputOutputStr; + LPSTR pSearchEnd = aInputOutputStr + lstrlen(aInputOutputStr); + LPSTR pPreviousSearch = NULL; + + while (pSearch < pSearchEnd) + { + if (('\\' == *pSearch) || ('n' == *pSearch)) + { + // found a '\\' or 'n'. check to see if the prefivous char is also a '\\'. + if (pPreviousSearch && ('\\' == *pPreviousSearch)) + { + if ('n' == *pSearch) + *pSearch = '\n'; + + memmove(pPreviousSearch, pSearch, pSearchEnd-pSearch+1); + + // our string is shorter now ... + pSearchEnd -= pSearch - pPreviousSearch; + } + } + + pPreviousSearch = pSearch; + pSearch = CharNext(pSearch); + } +} + +void PrintUsage(void) +{ + char szBuf[MAX_BUF]; + char szUsageMsg[MAX_BUF]; + char szProcessFilename[MAX_BUF]; + + /* -h: this help + * -a [path]: Alternate archive search path + * -app: ID of application which is launching the installer (Shared installs) + * -app_path: Points to representative file of app (Shared installs) + * -dd [path]: Suggested install destination directory. (Shared installs) + * -greLocal: Forces GRE to be installed into the application dir. + * -greShared: Forces GRE to be installed into a global, shared dir (normally + * c:\program files\common files\mozilla.org\GRE + * -reg_path [path]: Where to make entries in the Windows registry. (Shared installs) + * -f: Force install of GRE installer (Shared installs), though it'll work + * for non GRE installers too. + * -greForce: Force 'Component GRE' to be downloaded, run, and installed. This + * bypasses GRE's logic of determining when to install by running its + * installer with a '-f' flag. + * -n [filename]: setup's parent's process filename + * -ma: run setup in Auto mode + * -mmi: Allow multiple installer instances. (Shared installs) + * -showBanner: Show the banner in the download and install process dialogs. + * This will override config.ini + * -hideBanner: Hides the banner in the download and install process dialogs. + * This will override config.ini + * -ms: run setup in Silent mode + * -ira: ignore the [RunAppX] sections + * -ispf: ignore the [Program FolderX] sections that show + * the Start Menu shortcut folder at the end of installation. + */ + + if(sgProduct.szParentProcessFilename && *sgProduct.szParentProcessFilename != '\0') + ParsePath(sgProduct.szParentProcessFilename, szProcessFilename, sizeof(szProcessFilename), FALSE, PP_FILENAME_ONLY); + else + { + GetModuleFileName(NULL, szBuf, sizeof(szBuf)); + ParsePath(szBuf, szProcessFilename, sizeof(szProcessFilename), FALSE, PP_FILENAME_ONLY); + } + + GetPrivateProfileString("Strings", "UsageMsg Usage", "", szBuf, sizeof(szBuf), szFileIniConfig); + if (lstrlen(szBuf) > 0) + { + char strUsage[MAX_BUF]; + + ReplacePrivateProfileStrCR(szBuf); + _snprintf(szUsageMsg, sizeof(szUsageMsg), szBuf, szProcessFilename); + szUsageMsg[sizeof(szUsageMsg) - 1] = '\0'; + GetPrivateProfileString("Messages", "DLG_USAGE_TITLE", "", strUsage, sizeof(strUsage), szFileIniInstall); + MessageBox(hWndMain, szUsageMsg, strUsage, MB_ICONEXCLAMATION); + } +} + +/* Function: ParseForStartupOptions() + * in: aCmdLine + * purpose: Parses for options that affect the initialization of setup.exe, + * such as -ms, -ma, -mmi. + * This is required to be parsed this early because setup needs to + * know if dialogs need to be shown (-ms, -ma) and also where to + * create the temp directory for temporary items to be placed at + * (-mmi). + */ +DWORD ParseForStartupOptions(LPSTR aCmdLine) +{ + char szArgVBuf[MAX_BUF]; + int i; + int iArgC; + +#ifdef XXX_DEBUG + char szBuf[MAX_BUF]; + char szOutputStr[MAX_BUF]; +#endif + + iArgC = GetArgC(aCmdLine); + +#ifdef XXX_DEBUG + wsprintf(szOutputStr, "ArgC: %d\n", iArgC); +#endif + + i = 0; + while(i < iArgC) + { + GetArgV(aCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + + if(!lstrcmpi(szArgVBuf, "-mmi") || !lstrcmpi(szArgVBuf, "/mmi")) + { + gbAllowMultipleInstalls = TRUE; + } + else if(!lstrcmpi(szArgVBuf, "-ma") || !lstrcmpi(szArgVBuf, "/ma")) + SetSetupRunMode("AUTO"); + else if(!lstrcmpi(szArgVBuf, "-ms") || !lstrcmpi(szArgVBuf, "/ms")) + SetSetupRunMode("SILENT"); + +#ifdef XXX_DEBUG + itoa(i, szBuf, 10); + lstrcat(szOutputStr, " "); + lstrcat(szOutputStr, szBuf); + lstrcat(szOutputStr, ": "); + lstrcat(szOutputStr, szArgVBuf); + lstrcat(szOutputStr, "\n"); +#endif + + ++i; + } + +#ifdef XXX_DEBUG + MessageBox(NULL, szOutputStr, "Output", MB_OK); +#endif + return(WIZ_OK); +} + +DWORD ParseCommandLine(LPSTR aMessageToClose, LPSTR lpszCmdLine) +{ + char szArgVBuf[MAX_BUF]; + int i; + int iArgC; + +#ifdef XXX_DEBUG + char szBuf[MAX_BUF]; + char szOutputStr[MAX_BUF]; +#endif + + iArgC = GetArgC(lpszCmdLine); + +#ifdef XXX_DEBUG + wsprintf(szOutputStr, "ArgC: %d\n", iArgC); +#endif + + i = 0; + while(i < iArgC) + { + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + + if(!lstrcmpi(szArgVBuf, "-h") || !lstrcmpi(szArgVBuf, "/h")) + { + ShowMessage(aMessageToClose, FALSE); + PrintUsage(); + return(WIZ_ERROR_UNDEFINED); + } + else if(!lstrcmpi(szArgVBuf, "-a") || !lstrcmpi(szArgVBuf, "/a")) + { + ++i; + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + lstrcpy(sgProduct.szAlternateArchiveSearchPath, szArgVBuf); + } + else if(!lstrcmpi(szArgVBuf, "-greForce") || !lstrcmpi(szArgVBuf, "/greForce")) + { + gbForceInstallGre = TRUE; + } + else if(!lstrcmpi(szArgVBuf, "-greLocal") || !lstrcmpi(szArgVBuf, "/greLocal")) + { + sgProduct.greType = GRE_LOCAL; + } + else if(!lstrcmpi(szArgVBuf, "-greShared") || !lstrcmpi(szArgVBuf, "/greShared")) + { + sgProduct.greType = GRE_SHARED; + } + else if(!lstrcmpi(szArgVBuf, "-f") || !lstrcmpi(szArgVBuf, "/f")) + { + gbForceInstall = TRUE; + } + else if(!lstrcmpi(szArgVBuf, "-n") || !lstrcmpi(szArgVBuf, "/n")) + { + ++i; + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + lstrcpy(sgProduct.szParentProcessFilename, szArgVBuf); + } + else if(!lstrcmpi(szArgVBuf, "-ira") || !lstrcmpi(szArgVBuf, "/ira")) + /* ignore [RunAppX] sections */ + gbIgnoreRunAppX = TRUE; + else if(!lstrcmpi(szArgVBuf, "-ispf") || !lstrcmpi(szArgVBuf, "/ispf")) + /* ignore [Program FolderX] sections */ + gbIgnoreProgramFolderX = TRUE; + else if(!lstrcmpi(szArgVBuf, "-dd") || !lstrcmpi(szArgVBuf, "/dd")) + { + ++i; + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + lstrcpy(sgProduct.szPath, szArgVBuf); + } + // identifies the app which is installing for shared installs + else if(!lstrcmpi(szArgVBuf, "-app") || !lstrcmpi(szArgVBuf, "/app")) + { + ++i; + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + lstrcpy(sgProduct.szAppID, szArgVBuf); + } + // points to a file belonging to the app which can be searched to determine + // if the app is installed + else if(!lstrcmpi(szArgVBuf, "-app_path") || !lstrcmpi(szArgVBuf, "/app_path")) + { + ++i; + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + lstrcpy(sgProduct.szAppPath, szArgVBuf); + } + // alternative path in Windows registry, for private sharable installations + else if(!lstrcmpi(szArgVBuf, "-reg_path") || !lstrcmpi(szArgVBuf, "/reg_path")) + { + ++i; + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + lstrcpy(sgProduct.szRegPath, szArgVBuf); + } + else if(!lstrcmpi(szArgVBuf, "-showBanner") || !lstrcmpi(szArgVBuf, "/showBanner")) + gShowBannerImage = TRUE; + else if(!lstrcmpi(szArgVBuf, "-hideBanner") || !lstrcmpi(szArgVBuf, "/hideBanner")) + gShowBannerImage = FALSE; + else if(!lstrcmpi(szArgVBuf, "-cleanupOnUpgrade") || !lstrcmpi(szArgVBuf, "/cleanupOnUpgrade")) + sgProduct.checkCleanupOnUpgrade = TRUE; + else if(!lstrcmpi(szArgVBuf, "-noCleanupOnUpgrade") || !lstrcmpi(szArgVBuf, "/noCleanupOnUpgrade")) + sgProduct.checkCleanupOnUpgrade = FALSE; + else if(!lstrcmpi(szArgVBuf, "-greCleanupOrphans") || !lstrcmpi(szArgVBuf, "/greCleanupOrphans")) + sgProduct.greCleanupOrphans = TRUE; + else if(!lstrcmpi(szArgVBuf, "-greNoCleanupOrphans") || !lstrcmpi(szArgVBuf, "/greNoCleanupOrphans")) + sgProduct.greCleanupOrphans = FALSE; + +#ifdef XXX_DEBUG + itoa(i, szBuf, 10); + lstrcat(szOutputStr, " "); + lstrcat(szOutputStr, szBuf); + lstrcat(szOutputStr, ": "); + lstrcat(szOutputStr, szArgVBuf); + lstrcat(szOutputStr, "\n"); +#endif + + ++i; + } + +#ifdef XXX_DEBUG + MessageBox(NULL, szOutputStr, "Output", MB_OK); +#endif + return(WIZ_OK); +} + +void GetAlternateArchiveSearchPath(LPSTR lpszCmdLine) +{ + char szBuf[MAX_PATH]; + LPSTR lpszAASPath; + LPSTR lpszEndPath; + LPSTR lpszEndQuote; + + if(lstrcpy(szBuf, lpszCmdLine)) + { + if((lpszAASPath = strstr(szBuf, "-a")) == NULL) + return; + else + lpszAASPath += 2; + + if(*lpszAASPath == '\"') + { + lpszAASPath = lpszAASPath + 1; + if((lpszEndQuote = strstr(lpszAASPath, "\"")) != NULL) + { + *lpszEndQuote = '\0'; + } + } + else if((lpszEndPath = strstr(lpszAASPath, " ")) != NULL) + { + *lpszEndPath = '\0'; + } + + lstrcpy(sgProduct.szAlternateArchiveSearchPath, lpszAASPath); + } +} + +int PreCheckInstance(char *szSection, char *szIniFile) +{ + char szBuf[MAX_BUF]; + char szKey[MAX_BUF]; + char szName[MAX_BUF]; + char szParameter[MAX_BUF]; + char szPath[MAX_BUF]; + char szFile[MAX_BUF]; + char *ptrName = NULL; + HKEY hkeyRoot; + int iRv = WIZ_OK; + DWORD dwCounter = 0; + BOOL bContinue = TRUE; + char szExtraCmd[] = "Extra Cmd"; + char szExtraCmdKey[MAX_BUF]; + + do + { + /* Read the win reg key path */ + wsprintf(szExtraCmdKey, "%s%d Reg Key", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szKey, + sizeof(szKey), + szIniFile); + if(*szKey == '\0') + { + bContinue = FALSE; + continue; + } + + /* Read the win reg root key */ + wsprintf(szExtraCmdKey, "%s%d Reg Key Root", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szBuf, + sizeof(szBuf), + szIniFile); + if(*szBuf == '\0') + { + bContinue = FALSE; + continue; + } + hkeyRoot = ParseRootKey(szBuf); + + /* Read the win reg name value */ + wsprintf(szExtraCmdKey, "%s%d Reg Name", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szName, + sizeof(szName), + szIniFile); + if(*szName == '\0') + ptrName = NULL; + else + ptrName = szName; + + /* Read the parameter to use for quitting the browser's turbo mode */ + wsprintf(szExtraCmdKey, "%s%d Parameter", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szParameter, + sizeof(szParameter), + szIniFile); + + /* Read the win reg key that contains the path to the browser */ + GetWinReg(hkeyRoot, szKey, ptrName, szFile, sizeof(szFile)); + ParsePath(szFile, szPath, sizeof(szPath), FALSE, PP_PATH_ONLY); + + /* Make sure the file exists */ + if(FileExists(szFile)) + { + // we've found a file, so let's execute it and stop. No need to look + // for other keys to parse. We only want to do that if the file is + // _not_ found. This is for when we change the name of the browser + // app file and still need to deal with locating it and calling + // -kill on it. ie. + // previous name: netscp6.exe + // new name: netscp.exe + // We only need to call one of them, not both. + bContinue = FALSE; + + /* Run the file */ + WinSpawn(szFile, szParameter, szPath, SW_HIDE, WS_WAIT); + + /* Even though WinSpawn is suppose to wait for the app to finish, this + * does not really work that way for trying to quit the browser when + * it's in turbo mode, so we wait 2 secs for it to complete. */ + Delay(2); + } + + ++dwCounter; + } while(bContinue); + + return(iRv); +} + +HRESULT GetCheckInstanceQuitMessage(char *aSection, char *aMessage, DWORD aMessageBufSize) +{ + char messageFullInstaller[MAX_BUF]; + + *aMessage = '\0'; + *messageFullInstaller = '\0'; + + GetPrivateProfileString(aSection, "Message", "", aMessage, aMessageBufSize, szFileIniConfig); + GetPrivateProfileString(aSection, "Message Full Installer", "", messageFullInstaller, sizeof(messageFullInstaller), szFileIniConfig); + if(!gbDownloadTriggered && !gbPreviousUnfinishedDownload && (*messageFullInstaller != '\0')) + MozCopyStr(messageFullInstaller, aMessage, aMessageBufSize); + + return(WIZ_OK); +} + +HRESULT ShowMessageAndQuitProcess(HWND aHwndFW, char *aMsgQuitProcess, char *aMsgWait, BOOL aCloseAllWindows, char *aProcessName, BOOL aForceQuit) +{ + switch(sgProduct.mode) + { + case NORMAL: + { + char msgTitleStr[MAX_BUF]; + GetPrivateProfileString("Messages", "MB_ATTENTION_STR", "", msgTitleStr, sizeof(msgTitleStr), szFileIniInstall); + MessageBox(hWndMain, aMsgQuitProcess, msgTitleStr, MB_ICONEXCLAMATION | MB_SETFOREGROUND); + break; + } + + case AUTO: + { + /* Setup mode is AUTO. Show message, timeout, then auto close + * all the windows associated with the process */ + ShowMessage(aMsgQuitProcess, TRUE); + Delay(5); + ShowMessage(aMsgQuitProcess, FALSE); + break; + } + + case SILENT: + break; + } + + if(aForceQuit) + { + assert(aProcessName); + FindAndKillProcess(aProcessName, KP_KILL_PROCESS); + } + else + { + assert(aHwndFW); + /* First try sending a WM_QUIT message to the window because this is the + * preferred way to quit a process. If it works, then we're good and + * CloseAllWindowsOfWindowHandle() will have nothing to do. + * If it doesn't work, then CloseAllWindowsOfWindowHandle will try to + * quit the process. */ + SendMessageTimeout(aHwndFW, WM_QUIT, (WPARAM)1, (LPARAM)0, SMTO_NORMAL, WM_CLOSE_TIMEOUT_VALUE, NULL); + if(aCloseAllWindows) + CloseAllWindowsOfWindowHandle(aHwndFW, aMsgWait); + } + Delay(2); + return(WIZ_OK); +} + +HRESULT CheckInstances() +{ + char section[MAX_BUF]; + char processName[MAX_BUF]; + char className[MAX_BUF]; + char windowName[MAX_BUF]; + char closeAllWindows[MAX_BUF]; + char message[MAX_BUF]; + char msgTitleStr[MAX_BUF]; + char prettyName[MAX_BUF]; + char buf[MAX_BUF]; + char msgWait[MAX_BUF]; + int index; + int killProcessTries = 0; + int instanceOfFoundProcess = 0; + BOOL bContinue; + BOOL bCloseAllWindows; + HWND hwndFW; + LPSTR szWN; + LPSTR szCN; + DWORD dwRv0; + DWORD dwRv1; + + GetPrivateProfileString("Messages", "MB_ATTENTION_STR", "", msgTitleStr, sizeof(msgTitleStr), szFileIniInstall); + bContinue = TRUE; + index = -1; + while(bContinue) + { + *className = '\0'; + *windowName = '\0'; + *message = '\0'; + + wsprintf(section, "Check Instance%d", ++index); + GetPrivateProfileString(section, "Process Name", "", processName, sizeof(processName), szFileIniConfig); + GetPrivateProfileString(section, "Pretty Name", "", prettyName, sizeof(prettyName), szFileIniConfig); + GetPrivateProfileString(section, "Message Wait", "", msgWait, sizeof(msgWait), szFileIniConfig); + GetPrivateProfileString(section, "Close All Process Windows", "", closeAllWindows, sizeof(closeAllWindows), szFileIniConfig); + if(lstrcmpi(closeAllWindows, "TRUE") == 0) + bCloseAllWindows = TRUE; + else + bCloseAllWindows = FALSE; + + if(instanceOfFoundProcess != index) + { + killProcessTries = 0; + instanceOfFoundProcess = index; + } + + if((killProcessTries == 1) && (*processName != '\0')) + { + if(FindAndKillProcess(processName, KP_DO_NOT_KILL_PROCESS)) + { + /* found process, display warning message, then kill process */ + GetPrivateProfileString("Messages", "MSG_FORCE_QUIT_PROCESS", "", message, sizeof(message), szFileIniInstall); + if(*message != '\0') + { + wsprintf(buf, message, prettyName, processName, prettyName, prettyName); + ShowMessageAndQuitProcess(NULL, buf, msgWait, bCloseAllWindows, processName, CI_FORCE_QUIT_PROCESS); + ++killProcessTries; + instanceOfFoundProcess = index--; + } + } + continue; + } + else if(killProcessTries == MAX_KILL_PROCESS_RETRIES) + { + GetPrivateProfileString("Messages", "MSG_FORCE_QUIT_PROCESS_FAILED", "", message, sizeof(message), szFileIniInstall); + if(*message != '\0') + { + wsprintf(buf, message, prettyName, processName, prettyName); + switch(sgProduct.mode) + { + case NORMAL: + MessageBox(hWndMain, buf, msgTitleStr, MB_ICONEXCLAMATION | MB_SETFOREGROUND); + break; + + case AUTO: + /* Setup mode is AUTO. Show message, timeout, then auto close + * all the windows associated with the process */ + ShowMessage(buf, TRUE); + Delay(5); + ShowMessage(buf, FALSE); + break; + + default: + break; + } + } + + /* can't kill the process for some unknown reason. Stop the installation. */ + return(TRUE); + } + else if((killProcessTries > 1) && + (killProcessTries < MAX_KILL_PROCESS_RETRIES) && + (*processName != '\0')) + { + if(FindAndKillProcess(processName, KP_KILL_PROCESS)) + { + ++killProcessTries; + instanceOfFoundProcess = index--; + } + continue; + } + + dwRv0 = GetPrivateProfileString(section, "Class Name", "", className, sizeof(className), szFileIniConfig); + dwRv1 = GetPrivateProfileString(section, "Window Name", "", windowName, sizeof(windowName), szFileIniConfig); + if((dwRv0 == 0L) && (dwRv1 == 0L) && (*processName == '\0')) + { + bContinue = FALSE; + } + else if((*className != '\0') || (*windowName != '\0')) + { + if(*className == '\0') + szCN = NULL; + else + szCN = className; + + if(*windowName == '\0') + szWN = NULL; + else + szWN = windowName; + + /* If an instance is found, call PreCheckInstance first. + * PreCheckInstance will try to disable the browser's + * QuickLaunch feature. If the browser was in QuickLaunch + * mode without any windows open, PreCheckInstance would + * shutdown the browser, thus a second call to FindAndKillProcess + * is required to see if the process is still around. */ + if((hwndFW = FindWindow(szCN, szWN)) != NULL) + PreCheckInstance(section, szFileIniConfig); + + if((hwndFW = FindWindow(szCN, szWN)) != NULL) + { + GetCheckInstanceQuitMessage(section, message, sizeof(message)); + if(*message != '\0') + { + ShowMessageAndQuitProcess(hwndFW, message, msgWait, bCloseAllWindows, processName, CI_CLOSE_PROCESS); + ++killProcessTries; + instanceOfFoundProcess = index--; + } + else + { + /* No message to display. Assume cancel because we can't allow user to continue */ + return(TRUE); + } + } + } + + if((killProcessTries == 0) && (*processName != '\0')) + { + /* The first attempt used FindWindow(), but sometimes the browser can be + * in a state where there's no window open and still not fully shutdown. + * In this case, we need to check for the process itself and kill it. */ + if(FindAndKillProcess(processName, KP_DO_NOT_KILL_PROCESS)) + { + GetCheckInstanceQuitMessage(section, message, sizeof(message)); + if(*message != '\0') + { + ShowMessageAndQuitProcess(hwndFW, message, msgWait, bCloseAllWindows, processName, CI_FORCE_QUIT_PROCESS); + ++killProcessTries; + instanceOfFoundProcess = index--; + } + else + { + /* No message to display. Assume cancel because we can't allow user to continue */ + return(TRUE); + } + } + } + } + + return(FALSE); +} + +void RefreshIcons() +{ + char subKey[MAX_BUF]; + char iconConstraint[MAX_BUF]; + BYTE iconConstraintNew[MAX_BUF]; + HKEY hkResult; + DWORD dwValueType; + long iconConstraintSize; + long rv; + + // Get the size of the icon from the windows registry. + // When this registry value is changed, the OS can flush the + // icon cache and thus update the icons. + iconConstraintSize = sizeof(iconConstraint); + strcpy(subKey, "Control Panel\\Desktop\\WindowMetrics"); + RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_ALL_ACCESS, &hkResult); + rv = RegQueryValueEx(hkResult, "Shell Icon Size", 0, &dwValueType, iconConstraint, &iconConstraintSize); + if(rv != ERROR_SUCCESS || iconConstraintSize == 0) + { + // Key not found or value not found, so use default OS value. + int iIconSize = GetSystemMetrics(SM_CXICON); + if(iIconSize == 0) + // Getting default OS value failed, use hard coded value + iIconSize = DEFAULT_ICON_SIZE; + + sprintf(iconConstraint, "%d", iIconSize); + } + + // decrease the size of the icon by 1 + // and tell the system to refresh the icons + sprintf(iconConstraintNew, "%d", atoi(iconConstraint) - 1); + iconConstraintSize = lstrlen(iconConstraintNew); + RegSetValueEx(hkResult, "Shell Icon Size", 0, dwValueType, iconConstraintNew, iconConstraintSize); + SendMessageTimeout(HWND_BROADCAST, + WM_SETTINGCHANGE, + SPI_SETNONCLIENTMETRICS, + (LPARAM)"WindowMetrics", + SMTO_NORMAL|SMTO_ABORTIFHUNG, + 10000, NULL); + + // reset the original size of the icon + // and tell the system to refresh the icons + iconConstraintSize = lstrlen(iconConstraint); + RegSetValueEx(hkResult, "Shell Icon Size", 0, dwValueType, iconConstraint, iconConstraintSize); + SendMessageTimeout(HWND_BROADCAST, + WM_SETTINGCHANGE, + SPI_SETNONCLIENTMETRICS, + (LPARAM)"WindowMetrics", + SMTO_NORMAL|SMTO_ABORTIFHUNG, + 10000, NULL); +} + +int CRCCheckArchivesStartup(char *szCorruptedArchiveList, DWORD dwCorruptedArchiveListSize, BOOL bIncludeTempPath) +{ + DWORD dwIndex0; + DWORD dwFileCounter; + siC *siCObject = NULL; + char szArchivePathWithFilename[MAX_BUF]; + char szArchivePath[MAX_BUF]; + char szMsgCRCCheck[MAX_BUF]; + char szPartiallyDownloadedFilename[MAX_BUF]; + int iRv; + int iResult; + + if(szCorruptedArchiveList != NULL) + ZeroMemory(szCorruptedArchiveList, dwCorruptedArchiveListSize); + + GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename, + sizeof(szPartiallyDownloadedFilename)); + GetPrivateProfileString("Strings", "Message Verifying Archives", "", szMsgCRCCheck, sizeof(szMsgCRCCheck), szFileIniConfig); + ShowMessage(szMsgCRCCheck, TRUE); + + iResult = WIZ_CRC_PASS; + dwIndex0 = 0; + dwFileCounter = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + /* only download jars if not already in the local machine */ + iRv = LocateJar(siCObject, szArchivePath, sizeof(szArchivePath), bIncludeTempPath); + if((iRv != AP_NOT_FOUND) && + (lstrcmpi(szPartiallyDownloadedFilename, + siCObject->szArchiveName) != 0)) + { + if(lstrlen(szArchivePath) < sizeof(szArchivePathWithFilename)) + lstrcpy(szArchivePathWithFilename, szArchivePath); + + AppendBackSlash(szArchivePathWithFilename, sizeof(szArchivePathWithFilename)); + if((lstrlen(szArchivePathWithFilename) + lstrlen(siCObject->szArchiveName)) < sizeof(szArchivePathWithFilename)) + lstrcat(szArchivePathWithFilename, siCObject->szArchiveName); + + if(CheckForArchiveExtension(szArchivePathWithFilename)) + { + /* Make sure that the Archive that failed is located in the TEMP + * folder. This means that it was downloaded at one point and not + * simply uncompressed from the self-extracting exe file. */ + if(VerifyArchive(szArchivePathWithFilename) != ZIP_OK) + { + if(iRv == AP_TEMP_PATH) + DeleteFile(szArchivePathWithFilename); + else if(szCorruptedArchiveList != NULL) + { + iResult = WIZ_CRC_FAIL; + if((DWORD)(lstrlen(szCorruptedArchiveList) + lstrlen(siCObject->szArchiveName + 1)) < dwCorruptedArchiveListSize) + { + lstrcat(szCorruptedArchiveList, " "); + lstrcat(szCorruptedArchiveList, siCObject->szArchiveName); + lstrcat(szCorruptedArchiveList, "\n"); + } + else + { + iResult = WIZ_OUT_OF_MEMORY; + break; + } + } + } + } + } + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + ShowMessage(szMsgCRCCheck, FALSE); + return(iResult); +} + +int StartupCheckArchives(void) +{ + int iRv; + char szBuf[MAX_BUF_SMALL]; + char szCorruptedArchiveList[MAX_BUF]; + + iRv = CRCCheckArchivesStartup(szCorruptedArchiveList, sizeof(szCorruptedArchiveList), gbPreviousUnfinishedDownload); + switch(iRv) + { + char szMsg[MAX_BUF]; + char szBuf2[MAX_BUF]; + char szTitle[MAX_BUF_TINY]; + + case WIZ_CRC_FAIL: + switch(sgProduct.mode) + { + case NORMAL: + if(GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + lstrcpy(szTitle, "Setup"); + else + wsprintf(szTitle, szBuf, sgProduct.szProductName); + + GetPrivateProfileString("Strings", "Error Corrupted Archives Detected", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(*szBuf != '\0') + { + lstrcpy(szBuf2, "\n\n"); + lstrcat(szBuf2, szCorruptedArchiveList); + lstrcat(szBuf2, "\n"); + wsprintf(szMsg, szBuf, szBuf2); + } + MessageBox(hWndMain, szMsg, szTitle, MB_OK | MB_ICONSTOP); + break; + + case AUTO: + GetPrivateProfileString("Strings", "Error Corrupted Archives Detected AUTO mode", "", szBuf, sizeof(szBuf), szFileIniConfig); + ShowMessage(szBuf, TRUE); + Delay(5); + ShowMessage(szBuf, FALSE); + break; + } + + LogISComponentsFailedCRC(szCorruptedArchiveList, W_STARTUP); + return(WIZ_CRC_FAIL); + + case WIZ_CRC_PASS: + break; + + default: + break; + } + LogISComponentsFailedCRC(NULL, W_STARTUP); + return(iRv); +} + +HRESULT ParseConfigIni(LPSTR lpszCmdLine) +{ + int iRv; + char szBuf[MAX_BUF]; + char szMsgInitSetup[MAX_BUF]; + char szPreviousPath[MAX_BUF]; + char szShowDialog[MAX_BUF]; + DWORD dwPreviousUnfinishedState; + + if(InitDlgWelcome(&diWelcome)) + return(1); + if(InitDlgLicense(&diLicense)) + return(1); + if(InitDlgSetupType(&diSetupType)) + return(1); + if(InitDlgSelectComponents(&diSelectComponents, SM_SINGLE)) + return(1); + if(InitDlgSelectComponents(&diSelectAdditionalComponents, SM_SINGLE)) + return(1); + if(InitDlgWindowsIntegration(&diWindowsIntegration)) + return(1); + if(InitDlgProgramFolder(&diProgramFolder)) + return(1); + if(InitDlgAdditionalOptions(&diAdditionalOptions)) + return(1); + if(InitDlgAdvancedSettings(&diAdvancedSettings)) + return(1); + if(InitDlgQuickLaunch(&diQuickLaunch)) + return(1); + if(InitDlgStartInstall(&diStartInstall)) + return(1); + if(InitDlgDownload(&diDownload)) + return(1); + if(InitDlgReboot(&diReboot)) + return(1); + if(InitSDObject()) + return(1); + if(InitSXpcomFile()) + return(1); + if(InitGre(&gGre)) + return(WIZ_ERROR_INIT); + + /* get install Mode information */ + GetPrivateProfileString("General", "Run Mode", "", szBuf, sizeof(szBuf), szFileIniConfig); + SetSetupRunMode(szBuf); + + /* find out if we are doing a shared install */ + GetPrivateProfileString("General", "Shared Install", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + sgProduct.bSharedInst = TRUE; + + /* find out if we need to cleanup previous installation on upgrade + * (installing ontop of - not related to cleaning up olde GRE's + * installed elsewhere) */ + GetPrivateProfileString("Cleanup On Upgrade", "Cleanup", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + sgProduct.checkCleanupOnUpgrade = TRUE; + + /* this is a default value so don't change it if it has already been set */ + if(*sgProduct.szAppID == '\0') + GetPrivateProfileString("General", "Default AppID", "", sgProduct.szAppID, MAX_BUF, szFileIniConfig); + + if(GetPrivateProfileString("Messages", "MSG_INIT_SETUP", "", szMsgInitSetup, sizeof(szMsgInitSetup), szFileIniInstall)) + ShowMessage(szMsgInitSetup, TRUE); + + /* get product name description */ + GetPrivateProfileString("General", "Company Name", "", sgProduct.szCompanyName, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "Product Name", "", sgProduct.szProductName, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "Product Name Internal", "", sgProduct.szProductNameInternal, MAX_BUF, szFileIniConfig); + if (sgProduct.szProductNameInternal[0] == 0) + lstrcpy(sgProduct.szProductNameInternal, sgProduct.szProductName); + + GetPrivateProfileString("General", "Product Name Previous", "", sgProduct.szProductNamePrevious, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "Uninstall Filename", "", sgProduct.szUninstallFilename, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "User Agent", "", sgProduct.szUserAgent, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "Sub Path", "", sgProduct.szSubPath, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "Program Name", "", sgProduct.szProgramName, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("General", "Lock Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + sgProduct.bLockPath = TRUE; + + /* this is a default value so don't change it if it has already been set */ + if (sgProduct.szRegPath[0] == 0) + wsprintf(sgProduct.szRegPath, "Software\\%s\\%s\\%s", sgProduct.szCompanyName, sgProduct.szProductNameInternal, sgProduct.szUserAgent); + + gbRestrictedAccess = VerifyRestrictedAccess(); + if(gbRestrictedAccess) + { + /* Detected user does not have the appropriate + * privileges on this system */ + char szTitle[MAX_BUF_TINY]; + int iRvMB; + + switch(sgProduct.mode) + { + case NORMAL: + if(!GetPrivateProfileString("Messages", "MB_WARNING_STR", "", szBuf, sizeof(szBuf), szFileIniInstall)) + lstrcpy(szTitle, "Setup"); + else + wsprintf(szTitle, szBuf, sgProduct.szProductName); + + GetPrivateProfileString("Strings", "Message NORMAL Restricted Access", "", szBuf, sizeof(szBuf), szFileIniConfig); + iRvMB = MessageBox(hWndMain, szBuf, szTitle, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2); + break; + + case AUTO: + ShowMessage(szMsgInitSetup, FALSE); + GetPrivateProfileString("Strings", "Message AUTO Restricted Access", "", szBuf, sizeof(szBuf), szFileIniConfig); + ShowMessage(szBuf, TRUE); + Delay(5); + ShowMessage(szBuf, FALSE); + iRvMB = IDNO; + break; + + default: + iRvMB = IDNO; + break; + } + + if(iRvMB == IDNO) + { + /* User chose not to continue with the lack of + * appropriate access privileges */ + PostQuitMessage(1); + return(1); + } + } + + /* get main install path */ + if(LocatePreviousPath("Locate Previous Product Path", szPreviousPath, sizeof(szPreviousPath)) == FALSE) + { + GetPrivateProfileString("General", "Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(sgProduct.szPath, szBuf); + } + else + { + /* If the previous path is located in the registry, then we need to check to see if the path from + * the registry plus the Sub Path contains the Program Name file. If it does, then we have the + * correct path, so just use it. + * + * If it does not contain the Program Name file, then check the parent path (from the registry) + + * SubPath. If this path contains the Program Name file, then we found an older path format. We + * then need to use the parent path as the default path. + * + * Only do the older path format checking if the Sub Path= and Program Name= keys exist. If + * either are not set, then assume that the path from the registry is what we want. + */ + if((*sgProduct.szSubPath != '\0') && (*sgProduct.szProgramName != '\0')) + { + /* If the Sub Path= and Program Name= keys exist, do extra parsing for the correct path */ + lstrcpy(szBuf, szPreviousPath); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, sgProduct.szSubPath); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, sgProduct.szProgramName); + + /* Check to see if PreviousPath + SubPath + ProgramName exists. If it does, then we have the + * correct path. + */ + if(FileExists(szBuf)) + { + lstrcpy(sgProduct.szPath, szPreviousPath); + } + else + { + /* If not, try parent of PreviousPath + SubPath + ProgramName. + * If this exists, then we need to use the parent path of PreviousPath. + */ + RemoveBackSlash(szPreviousPath); + ParsePath(szPreviousPath, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, sgProduct.szSubPath); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, sgProduct.szProgramName); + + if(FileExists(szBuf)) + { + RemoveBackSlash(szPreviousPath); + ParsePath(szPreviousPath, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY); + lstrcpy(sgProduct.szPath, szBuf); + } + else + { + /* If we still can't locate ProgramName file, then use the default in the config.ini */ + GetPrivateProfileString("General", "Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(sgProduct.szPath, szBuf); + } + } + } + else + { + lstrcpy(sgProduct.szPath, szPreviousPath); + } + } + RemoveBackSlash(sgProduct.szPath); + + /* get main program folder path */ + GetPrivateProfileString("General", "Program Folder Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(sgProduct.szProgramFolderPath, szBuf); + + /* get main program folder name */ + GetPrivateProfileString("General", "Program Folder Name", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(sgProduct.szProgramFolderName, szBuf); + + GetPrivateProfileString("General", "Refresh Icons", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + gSystemInfo.bRefreshIcons = TRUE; + + /* Set default value for greType if not already set. If already set, + * it was set via cmdline argumen. Do not override the setting. */ + if(sgProduct.greType == GRE_TYPE_NOT_SET) + { + sgProduct.greType = GRE_SHARED; /* Always default to installing GRE to global area. */ + GetPrivateProfileString("General", "GRE Type", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "Local") == 0) + sgProduct.greType = GRE_LOCAL; + else + sgProduct.greType = GRE_SHARED; + } + + GetPrivateProfileString("General", "GRE Cleanup Orphans", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + sgProduct.greCleanupOrphans = TRUE; + + GetPrivateProfileString("General", "GRE Cleanup Orphans Message", "", sgProduct.greCleanupOrphansMessage, sizeof(sgProduct.greCleanupOrphansMessage), szFileIniConfig); + GetPrivateProfileString("General", "GRE ID", "", sgProduct.greID, sizeof(sgProduct.greID), szFileIniConfig); + GetPrivateProfileString("General", "GRE Private Key", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(*szBuf != '\0') + DecryptString(sgProduct.grePrivateKey, szBuf); + + GetPrivateProfileString("General", "Show Banner Image", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "FALSE") == 0) + gShowBannerImage = FALSE; + + iRv = ParseCommandLine(szMsgInitSetup, lpszCmdLine); + if(iRv) + return(iRv); + + /* make a copy of sgProduct.szPath to be used in the Setup Type dialog */ + lstrcpy(szTempSetupPath, sgProduct.szPath); + + // check to see if files need to be installed for share installations + if(sgProduct.bSharedInst == TRUE) + SetInstallFilesVar(sgProduct.szPath); + + /* Welcome dialog */ + GetPrivateProfileString("Dialog Welcome", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Welcome", "Title", "", diWelcome.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Welcome", "Message0", "", diWelcome.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Welcome", "Message1", "", diWelcome.szMessage1, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Welcome", "Message2", "", diWelcome.szMessage2, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diWelcome.bShowDialog = TRUE; + + /* License dialog */ + GetPrivateProfileString("Dialog License", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog License", "Title", "", diLicense.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog License", "License File", "", diLicense.szLicenseFilename, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog License", "Message0", "", diLicense.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog License", "Message1", "", diLicense.szMessage1, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diLicense.bShowDialog = TRUE; + + /* Setup Type dialog */ + GetPrivateProfileString("Dialog Setup Type", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Setup Type", "Title", "", diSetupType.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Setup Type", "Message0", "", diSetupType.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Setup Type", "Readme Filename", "", diSetupType.szReadmeFilename, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Setup Type", "Readme App", "", diSetupType.szReadmeApp, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diSetupType.bShowDialog = TRUE; + + /* Get Setup Types info */ + GetPrivateProfileString("Setup Type0", "Description Short", "", diSetupType.stSetupType0.szDescriptionShort, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Setup Type0", "Description Long", "", diSetupType.stSetupType0.szDescriptionLong, MAX_BUF, szFileIniConfig); + STSetVisibility(&diSetupType.stSetupType0); + + GetPrivateProfileString("Setup Type1", "Description Short", "", diSetupType.stSetupType1.szDescriptionShort, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Setup Type1", "Description Long", "", diSetupType.stSetupType1.szDescriptionLong, MAX_BUF, szFileIniConfig); + STSetVisibility(&diSetupType.stSetupType1); + + GetPrivateProfileString("Setup Type2", "Description Short", "", diSetupType.stSetupType2.szDescriptionShort, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Setup Type2", "Description Long", "", diSetupType.stSetupType2.szDescriptionLong, MAX_BUF, szFileIniConfig); + STSetVisibility(&diSetupType.stSetupType2); + + GetPrivateProfileString("Setup Type3", "Description Short", "", diSetupType.stSetupType3.szDescriptionShort, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Setup Type3", "Description Long", "", diSetupType.stSetupType3.szDescriptionLong, MAX_BUF, szFileIniConfig); + STSetVisibility(&diSetupType.stSetupType3); + + /* remember the radio button that is considered the Custom type (the last radio button) */ + SetCustomType(); + + /* Select Components dialog */ + GetPrivateProfileString("Dialog Select Components", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Select Components", "Title", "", diSelectComponents.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Select Components", "Message0", "", diSelectComponents.szMessage0, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diSelectComponents.bShowDialog = TRUE; + + /* Select Additional Components dialog */ + GetPrivateProfileString("Dialog Select Additional Components", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Select Additional Components", "Title", "", diSelectAdditionalComponents.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Select Additional Components", "Message0", "", diSelectAdditionalComponents.szMessage0, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diSelectAdditionalComponents.bShowDialog = TRUE; + + /* Windows Integration dialog */ + GetPrivateProfileString("Dialog Windows Integration", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Windows Integration", "Title", "", diWindowsIntegration.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Windows Integration", "Message0", "", diWindowsIntegration.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Windows Integration", "Message1", "", diWindowsIntegration.szMessage1, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diWindowsIntegration.bShowDialog = TRUE; + + /* Program Folder dialog */ + GetPrivateProfileString("Dialog Program Folder", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Program Folder", "Title", "", diProgramFolder.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Program Folder", "Message0", "", diProgramFolder.szMessage0, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diProgramFolder.bShowDialog = TRUE; + + /* Additional Options dialog */ + GetPrivateProfileString("Dialog Additional Options", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Additional Options", "Title", "", diAdditionalOptions.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Additional Options", "Message0", "", diAdditionalOptions.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Additional Options", "Message1", "", diAdditionalOptions.szMessage1, MAX_BUF, szFileIniConfig); + + GetPrivateProfileString("Dialog Additional Options", "Save Installer", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + diAdditionalOptions.bSaveInstaller = TRUE; + + GetPrivateProfileString("Dialog Additional Options", "Recapture Homepage", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + diAdditionalOptions.bRecaptureHomepage = TRUE; + + GetPrivateProfileString("Dialog Additional Options", "Show Homepage Option", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + diAdditionalOptions.bShowHomepageOption = TRUE; + + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diAdditionalOptions.bShowDialog = TRUE; + + /* Advanced Settings dialog */ + GetPrivateProfileString("Dialog Advanced Settings", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Advanced Settings", "Title", "", diAdvancedSettings.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Advanced Settings", "Message0", "", diAdvancedSettings.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Advanced Settings", "Proxy Server", "", diAdvancedSettings.szProxyServer, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Advanced Settings", "Proxy Port", "", diAdvancedSettings.szProxyPort, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Advanced Settings", "Proxy User", "", diAdvancedSettings.szProxyUser, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Advanced Settings", "Proxy Password", "", diAdvancedSettings.szProxyPasswd, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diAdvancedSettings.bShowDialog = TRUE; + + GetPrivateProfileString("Dialog Advanced Settings", "Use Protocol", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "HTTP") == 0) + diAdditionalOptions.dwUseProtocol = UP_HTTP; + else + diAdditionalOptions.dwUseProtocol = UP_FTP; + + GetPrivateProfileString("Dialog Advanced Settings", "Use Protocol Settings", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "DISABLED") == 0) + diAdditionalOptions.bUseProtocolSettings = FALSE; + else + diAdditionalOptions.bUseProtocolSettings = TRUE; + + GetPrivateProfileString("Dialog Advanced Settings", + "Show Protocols", + "", + szBuf, + sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "FALSE") == 0) + diAdditionalOptions.bShowProtocols = FALSE; + else + diAdditionalOptions.bShowProtocols = TRUE; + + /* Program Folder dialog */ + GetPrivateProfileString("Dialog Quick Launch", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Quick Launch", "Title", "", diQuickLaunch.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Quick Launch", "Message0", "", diQuickLaunch.szMessage0, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Quick Launch", "Message1", "", diQuickLaunch.szMessage1, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Quick Launch", "Message2", "", diQuickLaunch.szMessage2, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diQuickLaunch.bShowDialog = TRUE; + GetPrivateProfileString("Dialog Quick Launch", "Turbo Mode", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + diQuickLaunch.bTurboMode = TRUE; + GetPrivateProfileString("Dialog Quick Launch", "Turbo Mode Enabled","", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + diQuickLaunch.bTurboModeEnabled = TRUE; + else + /* since turbo mode is disabled, make sure bTurboMode is FALSE */ + diQuickLaunch.bTurboMode = FALSE; + + /* Start Install dialog */ + GetPrivateProfileString("Dialog Start Install", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Start Install", "Title", "", diStartInstall.szTitle, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Start Install", "Message Install", "", diStartInstall.szMessageInstall, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Dialog Start Install", "Message Download", "", diStartInstall.szMessageDownload, MAX_BUF, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diStartInstall.bShowDialog = TRUE; + + /* Download dialog */ + GetPrivateProfileString("Dialog Download", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + GetPrivateProfileString("Dialog Download", "Title", "", diDownload.szTitle, MAX_BUF_TINY, szFileIniConfig); + GetPrivateProfileString("Dialog Download", "Message Download0", "", diDownload.szMessageDownload0, MAX_BUF_MEDIUM, szFileIniConfig); + GetPrivateProfileString("Dialog Download", "Message Retry0", "", diDownload.szMessageRetry0, MAX_BUF_MEDIUM, szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diDownload.bShowDialog = TRUE; + + /* Reboot dialog */ + GetPrivateProfileString("Dialog Reboot", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diReboot.dwShowDialog = TRUE; + else if(lstrcmpi(szShowDialog, "AUTO") == 0) + diReboot.dwShowDialog = AUTO; + + GetPrivateProfileString("Windows Integration-Item0", "CheckBoxState", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item0", "Description", "", diWindowsIntegration.wiCB0.szDescription, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item0", "Archive", "", diWindowsIntegration.wiCB0.szArchive, MAX_BUF, szFileIniConfig); + /* Check to see if the checkbox need to be shown at all or not */ + if(*diWindowsIntegration.wiCB0.szDescription != '\0') + diWindowsIntegration.wiCB0.bEnabled = TRUE; + /* check to see if the checkbox needs to be checked by default or not */ + if(lstrcmpi(szBuf, "TRUE") == 0) + diWindowsIntegration.wiCB0.bCheckBoxState = TRUE; + + GetPrivateProfileString("Windows Integration-Item1", "CheckBoxState", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item1", "Description", "", diWindowsIntegration.wiCB1.szDescription, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item1", "Archive", "", diWindowsIntegration.wiCB1.szArchive, MAX_BUF, szFileIniConfig); + /* Check to see if the checkbox need to be shown at all or not */ + if(*diWindowsIntegration.wiCB1.szDescription != '\0') + diWindowsIntegration.wiCB1.bEnabled = TRUE; + /* check to see if the checkbox needs to be checked by default or not */ + if(lstrcmpi(szBuf, "TRUE") == 0) + diWindowsIntegration.wiCB1.bCheckBoxState = TRUE; + + GetPrivateProfileString("Windows Integration-Item2", "CheckBoxState", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item2", "Description", "", diWindowsIntegration.wiCB2.szDescription, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item2", "Archive", "", diWindowsIntegration.wiCB2.szArchive, MAX_BUF, szFileIniConfig); + /* Check to see if the checkbox need to be shown at all or not */ + if(*diWindowsIntegration.wiCB2.szDescription != '\0') + diWindowsIntegration.wiCB2.bEnabled = TRUE; + /* check to see if the checkbox needs to be checked by default or not */ + if(lstrcmpi(szBuf, "TRUE") == 0) + diWindowsIntegration.wiCB2.bCheckBoxState = TRUE; + + GetPrivateProfileString("Windows Integration-Item3", "CheckBoxState", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item3", "Description", "", diWindowsIntegration.wiCB3.szDescription, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Windows Integration-Item3", "Archive", "", diWindowsIntegration.wiCB3.szArchive, MAX_BUF, szFileIniConfig); + /* Check to see if the checkbox need to be shown at all or not */ + if(*diWindowsIntegration.wiCB3.szDescription != '\0') + diWindowsIntegration.wiCB3.bEnabled = TRUE; + /* check to see if the checkbox needs to be checked by default or not */ + if(lstrcmpi(szBuf, "TRUE") == 0) + diWindowsIntegration.wiCB3.bCheckBoxState = TRUE; + + /* Read in the Site Selector Status */ + GetPrivateProfileString("Site Selector", "Status", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "HIDE") == 0) + gdwSiteSelectorStatus = SS_HIDE; + + switch(sgProduct.mode) + { + case AUTO: + case SILENT: + diWelcome.bShowDialog = FALSE; + diLicense.bShowDialog = FALSE; + diSetupType.bShowDialog = FALSE; + diSelectComponents.bShowDialog = FALSE; + diSelectAdditionalComponents.bShowDialog = FALSE; + diWindowsIntegration.bShowDialog = FALSE; + diProgramFolder.bShowDialog = FALSE; + diQuickLaunch.bShowDialog = FALSE; + diAdditionalOptions.bShowDialog = FALSE; + diAdvancedSettings.bShowDialog = FALSE; + diStartInstall.bShowDialog = FALSE; + diDownload.bShowDialog = FALSE; + break; + } + + InitSiComponents(szFileIniConfig); + InitSiteSelector(szFileIniConfig); + InitErrorMessageStream(szFileIniConfig); + + /* get Default Setup Type */ + GetPrivateProfileString("General", "Default Setup Type", "", szBuf, sizeof(szBuf), szFileIniConfig); + if((lstrcmpi(szBuf, "Setup Type 0") == 0) && diSetupType.stSetupType0.bVisible) + { + dwSetupType = ST_RADIO0; + dwTempSetupType = dwSetupType; + } + else if((lstrcmpi(szBuf, "Setup Type 1") == 0) && diSetupType.stSetupType1.bVisible) + { + dwSetupType = ST_RADIO1; + dwTempSetupType = dwSetupType; + } + else if((lstrcmpi(szBuf, "Setup Type 2") == 0) && diSetupType.stSetupType2.bVisible) + { + dwSetupType = ST_RADIO2; + dwTempSetupType = dwSetupType; + } + else if((lstrcmpi(szBuf, "Setup Type 3") == 0) && diSetupType.stSetupType3.bVisible) + { + dwSetupType = ST_RADIO3; + dwTempSetupType = dwSetupType; + } + else + { + if(diSetupType.stSetupType0.bVisible) + { + dwSetupType = ST_RADIO0; + dwTempSetupType = dwSetupType; + } + else if(diSetupType.stSetupType1.bVisible) + { + dwSetupType = ST_RADIO1; + dwTempSetupType = dwSetupType; + } + else if(diSetupType.stSetupType2.bVisible) + { + dwSetupType = ST_RADIO2; + dwTempSetupType = dwSetupType; + } + else if(diSetupType.stSetupType3.bVisible) + { + dwSetupType = ST_RADIO3; + dwTempSetupType = dwSetupType; + } + } + SiCNodeSetItemsSelected(dwSetupType); + + /* get install size required in temp for component Xpcom. Sould be in Kilobytes */ + GetPrivateProfileString("Core", "Install Size", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(*szBuf != '\0') + siCFXpcomFile.ullInstallSize = _atoi64(szBuf); + else + siCFXpcomFile.ullInstallSize = 0; + + GetPrivateProfileString("SmartDownload-Netscape Install", "core_file", "", siSDObject.szXpcomFile, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "core_file_path", "", siSDObject.szXpcomFilePath, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "xpcom_dir", "", siSDObject.szXpcomDir, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "no_ads", "", siSDObject.szNoAds, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "silent", "", siSDObject.szSilent, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "execution", "", siSDObject.szExecution, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "confirm_install", "", siSDObject.szConfirmInstall, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Netscape Install", "extract_msg", "", siSDObject.szExtractMsg, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Execution", "exe", "", siSDObject.szExe, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("SmartDownload-Execution", "exe_param", "", siSDObject.szExeParam, MAX_BUF, szFileIniConfig); + + GetPrivateProfileString("Core", "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(siCFXpcomFile.szSource, szBuf); + GetPrivateProfileString("Core", "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(siCFXpcomFile.szDestination, szBuf); + GetPrivateProfileString("Core", "Message", "", siCFXpcomFile.szMessage, MAX_BUF, szFileIniConfig); + GetPrivateProfileString("Core", "Cleanup", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "FALSE") == 0) + siCFXpcomFile.bCleanup = FALSE; + else + siCFXpcomFile.bCleanup = TRUE; + GetPrivateProfileString("Core", "Status", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "DISABLED") == 0) + siCFXpcomFile.bStatus = STATUS_DISABLED; + else + siCFXpcomFile.bStatus = STATUS_ENABLED; + + LogISProductInfo(); + LogMSProductInfo(); + CleanupXpcomFile(); + ShowMessage(szMsgInitSetup, FALSE); + + /* check the windows registry to see if a previous instance of setup finished downloading + * all the required archives. */ + dwPreviousUnfinishedState = GetPreviousUnfinishedState(); + + // Delete archives from the previous state *if* the user did not cancel + // out of the download state. + if(dwPreviousUnfinishedState == PUS_NONE) + DeleteArchives(DA_ONLY_IF_NOT_IN_ARCHIVES_LST); + + gbPreviousUnfinishedDownload = dwPreviousUnfinishedState == PUS_DOWNLOAD; + if(gbPreviousUnfinishedDownload) + { + char szTitle[MAX_BUF_TINY]; + + switch(sgProduct.mode) + { + case NORMAL: + if(!GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + lstrcpy(szTitle, "Setup"); + else + wsprintf(szTitle, szBuf, sgProduct.szProductName); + + GetPrivateProfileString("Strings", "Message Unfinished Download Restart", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(MessageBox(hWndMain, szBuf, szTitle, MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND) == IDNO) + { + UnsetSetupCurrentDownloadFile(); + UnsetSetupState(); /* unset the download state so that the archives can be deleted */ + DeleteArchives(DA_ONLY_IF_NOT_IN_ARCHIVES_LST); + } + break; + } + } + else if((dwPreviousUnfinishedState == PUS_UNPACK_XPCOM) || (dwPreviousUnfinishedState == PUS_INSTALL_XPI)) + { + char szTitle[MAX_BUF_TINY]; + + // need to set this var to true even though the previous state was not the + // download state. This is because it is used for disk space calculation + // wrt saved downloaded files and making sure CRC checks are performed on + // them. + gbPreviousUnfinishedDownload = TRUE; + switch(sgProduct.mode) + { + case NORMAL: + if(!GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf, sizeof(szBuf), szFileIniInstall)) + lstrcpy(szTitle, "Setup"); + else + wsprintf(szTitle, szBuf, sgProduct.szProductName); + + GetPrivateProfileString("Strings", "Message Unfinished Install Xpi Restart", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(MessageBox(hWndMain, szBuf, szTitle, MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND) == IDNO) + { + UnsetSetupCurrentDownloadFile(); + UnsetSetupState(); /* unset the installing xpis state so that the archives can be deleted */ + DeleteArchives(DA_ONLY_IF_NOT_IN_ARCHIVES_LST); + } + break; + } + } + + /* clean up previous exit status log file */ + DeleteExitStatusFile(); + + iRv = StartupCheckArchives(); + return(iRv); +} + +HRESULT ParseInstallIni() +{ + LOGFONT lf; + NONCLIENTMETRICS ncm; + + /* get system font */ + memset(&ncm, 0, sizeof(ncm)); + ncm.cbSize = sizeof(ncm); + SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); + sgInstallGui.systemFont = CreateFontIndirect( &ncm.lfMessageFont ); + + /* get defined font */ + GetPrivateProfileString("General", "FONTNAME", "", sgInstallGui.szFontName, sizeof(sgInstallGui.szFontName), szFileIniInstall); + GetPrivateProfileString("General", "FONTSIZE", "", sgInstallGui.szFontSize, sizeof(sgInstallGui.szFontSize), szFileIniInstall); + GetPrivateProfileString("General", "CHARSET", "", sgInstallGui.szCharSet, sizeof(sgInstallGui.szCharSet), szFileIniInstall); + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, sgInstallGui.szFontName); + lf.lfHeight = -MulDiv(atoi(sgInstallGui.szFontSize), GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72); + lf.lfCharSet = atoi(sgInstallGui.szCharSet); + sgInstallGui.definedFont = CreateFontIndirect( &lf ); + + GetPrivateProfileString("General", "OK_", "", sgInstallGui.szOk_, sizeof(sgInstallGui.szOk_), szFileIniInstall); + GetPrivateProfileString("General", "OK", "", sgInstallGui.szOk, sizeof(sgInstallGui.szOk), szFileIniInstall); + GetPrivateProfileString("General", "CANCEL_", "", sgInstallGui.szCancel_, sizeof(sgInstallGui.szCancel_), szFileIniInstall); + GetPrivateProfileString("General", "CANCEL", "", sgInstallGui.szCancel, sizeof(sgInstallGui.szCancel), szFileIniInstall); + GetPrivateProfileString("General", "NEXT_", "", sgInstallGui.szNext_, sizeof(sgInstallGui.szNext_), szFileIniInstall); + GetPrivateProfileString("General", "BACK_", "", sgInstallGui.szBack_, sizeof(sgInstallGui.szBack_), szFileIniInstall); + GetPrivateProfileString("General", "IGNORE_", "", sgInstallGui.szIgnore_, sizeof(sgInstallGui.szIgnore_), szFileIniInstall); + GetPrivateProfileString("General", "PROXYSETTINGS_", "", sgInstallGui.szProxySettings_, sizeof(sgInstallGui.szProxySettings_), szFileIniInstall); + GetPrivateProfileString("General", "PROXYSETTINGS", "", sgInstallGui.szProxySettings, sizeof(sgInstallGui.szProxySettings), szFileIniInstall); + GetPrivateProfileString("General", "SERVER", "", sgInstallGui.szServer, sizeof(sgInstallGui.szServer), szFileIniInstall); + GetPrivateProfileString("General", "PORT", "", sgInstallGui.szPort, sizeof(sgInstallGui.szPort), szFileIniInstall); + GetPrivateProfileString("General", "USERID", "", sgInstallGui.szUserId, sizeof(sgInstallGui.szUserId), szFileIniInstall); + GetPrivateProfileString("General", "PASSWORD", "", sgInstallGui.szPassword, sizeof(sgInstallGui.szPassword), szFileIniInstall); + GetPrivateProfileString("General", "SELECTDIRECTORY", "", sgInstallGui.szSelectDirectory, sizeof(sgInstallGui.szSelectDirectory), szFileIniInstall); + GetPrivateProfileString("General", "DIRECTORIES_", "", sgInstallGui.szDirectories_, sizeof(sgInstallGui.szDirectories_), szFileIniInstall); + GetPrivateProfileString("General", "DRIVES_", "", sgInstallGui.szDrives_, sizeof(sgInstallGui.szDrives_), szFileIniInstall); + GetPrivateProfileString("General", "STATUS", "", sgInstallGui.szStatus, sizeof(sgInstallGui.szStatus), szFileIniInstall); + GetPrivateProfileString("General", "FILE", "", sgInstallGui.szFile, sizeof(sgInstallGui.szFile), szFileIniInstall); + GetPrivateProfileString("General", "URL", "", sgInstallGui.szUrl, sizeof(sgInstallGui.szUrl), szFileIniInstall); + GetPrivateProfileString("General", "TO", "", sgInstallGui.szTo, sizeof(sgInstallGui.szTo), szFileIniInstall); + GetPrivateProfileString("General", "ACCEPT_", "", sgInstallGui.szAccept_, sizeof(sgInstallGui.szAccept_), szFileIniInstall); + GetPrivateProfileString("General", "DECLINE_", "", sgInstallGui.szDecline_, sizeof(sgInstallGui.szDecline_), szFileIniInstall); + GetPrivateProfileString("General", "PROGRAMFOLDER_", "", sgInstallGui.szProgramFolder_, sizeof(sgInstallGui.szProgramFolder_), szFileIniInstall); + GetPrivateProfileString("General", "EXISTINGFOLDERS_", "", sgInstallGui.szExistingFolder_, sizeof(sgInstallGui.szExistingFolder_), szFileIniInstall); + GetPrivateProfileString("General", "SETUPMESSAGE", "", sgInstallGui.szSetupMessage, sizeof(sgInstallGui.szSetupMessage), szFileIniInstall); + GetPrivateProfileString("General", "RESTART", "", sgInstallGui.szRestart, sizeof(sgInstallGui.szRestart), szFileIniInstall); + GetPrivateProfileString("General", "YESRESTART", "", sgInstallGui.szYesRestart, sizeof(sgInstallGui.szYesRestart), szFileIniInstall); + GetPrivateProfileString("General", "NORESTART", "", sgInstallGui.szNoRestart, sizeof(sgInstallGui.szNoRestart), szFileIniInstall); + GetPrivateProfileString("General", "ADDITIONALCOMPONENTS_", "", sgInstallGui.szAdditionalComponents_, sizeof(sgInstallGui.szAdditionalComponents_), szFileIniInstall); + GetPrivateProfileString("General", "DESCRIPTION", "", sgInstallGui.szDescription, sizeof(sgInstallGui.szDescription), szFileIniInstall); + GetPrivateProfileString("General", "TOTALDOWNLOADSIZE", "", sgInstallGui.szTotalDownloadSize, sizeof(sgInstallGui.szTotalDownloadSize), szFileIniInstall); + GetPrivateProfileString("General", "SPACEAVAILABLE", "", sgInstallGui.szSpaceAvailable, sizeof(sgInstallGui.szSpaceAvailable), szFileIniInstall); + GetPrivateProfileString("General", "COMPONENTS_", "", sgInstallGui.szComponents_, sizeof(sgInstallGui.szComponents_), szFileIniInstall); + GetPrivateProfileString("General", "DESTINATIONDIRECTORY", "", sgInstallGui.szDestinationDirectory, sizeof(sgInstallGui.szDestinationDirectory), szFileIniInstall); + GetPrivateProfileString("General", "BROWSE_", "", sgInstallGui.szBrowse_, sizeof(sgInstallGui.szBrowse_), szFileIniInstall); + GetPrivateProfileString("General", "CURRENTSETTINGS", "", sgInstallGui.szCurrentSettings, sizeof(sgInstallGui.szCurrentSettings), szFileIniInstall); + GetPrivateProfileString("General", "INSTALL_", "", sgInstallGui.szInstall_, sizeof(sgInstallGui.szInstall_), szFileIniInstall); + GetPrivateProfileString("General", "DELETE_", "", sgInstallGui.szDelete_, sizeof(sgInstallGui.szDelete_), szFileIniInstall); + GetPrivateProfileString("General", "CONTINUE_", "", sgInstallGui.szContinue_, sizeof(sgInstallGui.szContinue_), szFileIniInstall); + GetPrivateProfileString("General", "SKIP_", "", sgInstallGui.szSkip_, sizeof(sgInstallGui.szSkip_), szFileIniInstall); + GetPrivateProfileString("General", "EXTRACTING", "", sgInstallGui.szExtracting, sizeof(sgInstallGui.szExtracting), szFileIniInstall); + GetPrivateProfileString("General", "README", "", sgInstallGui.szReadme_, sizeof(sgInstallGui.szReadme_), szFileIniInstall); + GetPrivateProfileString("General", "PAUSE_", "", sgInstallGui.szPause_, sizeof(sgInstallGui.szPause_), szFileIniInstall); + GetPrivateProfileString("General", "RESUME_", "", sgInstallGui.szResume_, sizeof(sgInstallGui.szResume_), szFileIniInstall); + GetPrivateProfileString("General", "CHECKED", "", sgInstallGui.szChecked, sizeof(sgInstallGui.szChecked), szFileIniInstall); + GetPrivateProfileString("General", "UNCHECKED", "", sgInstallGui.szUnchecked, sizeof(sgInstallGui.szUnchecked), szFileIniInstall); + GetPrivateProfileString("Messages", "CB_DEFAULT", "", szSiteSelectorDescription, MAX_BUF, szFileIniInstall); + + return(0); +} + + +BOOL LocatePreviousPath(LPSTR szMainSectionName, LPSTR szPath, DWORD dwPathSize) +{ + DWORD dwIndex; + char szIndex[MAX_BUF]; + char szSection[MAX_BUF]; + char szValue[MAX_BUF]; + BOOL bFound; + + bFound = FALSE; + dwIndex = -1; + while(!bFound) + { + ++dwIndex; + itoa(dwIndex, szIndex, 10); + lstrcpy(szSection, szMainSectionName); + lstrcat(szSection, szIndex); + + GetPrivateProfileString(szSection, "Key", "", szValue, sizeof(szValue), szFileIniConfig); + if(*szValue != '\0') + bFound = LocatePathNscpReg(szSection, szPath, dwPathSize); + else + { + GetPrivateProfileString(szSection, "HKey", "", szValue, sizeof(szValue), szFileIniConfig); + if(*szValue != '\0') + bFound = LocatePathWinReg(szSection, szPath, dwPathSize); + else + { + GetPrivateProfileString(szSection, "Path", "", szValue, sizeof(szValue), szFileIniConfig); + if(*szValue != '\0') + bFound = LocatePath(szSection, szPath, dwPathSize); + else + break; + } + } + } + + return(bFound); +} + +BOOL LocatePathNscpReg(LPSTR szSection, LPSTR szPath, DWORD dwPathSize) +{ + char szKey[MAX_BUF]; + char szContainsFilename[MAX_BUF]; + char szBuf[MAX_BUF]; + BOOL bReturn; + + bReturn = FALSE; + GetPrivateProfileString(szSection, "Key", "", szKey, sizeof(szKey), szFileIniConfig); + if(*szKey != '\0') + { + bReturn = FALSE; + ZeroMemory(szPath, dwPathSize); + + VR_GetPath(szKey, MAX_BUF, szBuf); + if(*szBuf != '\0') + { + GetPrivateProfileString(szSection, "Contains Filename", "", szContainsFilename, sizeof(szContainsFilename), szFileIniConfig); + if(lstrcmpi(szContainsFilename, "TRUE") == 0) + ParsePath(szBuf, szPath, dwPathSize, FALSE, PP_PATH_ONLY); + else + lstrcpy(szPath, szBuf); + + bReturn = TRUE; + } + } + + return(bReturn); +} + +DWORD GetTotalArchivesToDownload() +{ + DWORD dwIndex0; + DWORD dwTotalArchivesToDownload; + siC *siCObject = NULL; + char szIndex0[MAX_BUF]; + + dwTotalArchivesToDownload = 0; + dwIndex0 = 0; + itoa(dwIndex0, szIndex0, 10); + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + { + if(LocateJar(siCObject, NULL, 0, gbPreviousUnfinishedDownload) == AP_NOT_FOUND) + { + ++dwTotalArchivesToDownload; + } + } + + ++dwIndex0; + itoa(dwIndex0, szIndex0, 10); + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + + return(dwTotalArchivesToDownload); +} + +BOOL LocatePathWinReg(LPSTR szSection, LPSTR szPath, DWORD dwPathSize) +{ + char szHKey[MAX_BUF]; + char szHRoot[MAX_BUF]; + char szName[MAX_BUF]; + char szVerifyExistence[MAX_BUF]; + char szBuf[MAX_BUF]; + BOOL bDecryptKey; + BOOL bContainsFilename; + BOOL bReturn; + HKEY hkeyRoot; + + bReturn = FALSE; + GetPrivateProfileString(szSection, "HKey", "", szHKey, sizeof(szHKey), szFileIniConfig); + if(*szHKey != '\0') + { + bReturn = FALSE; + ZeroMemory(szPath, dwPathSize); + + GetPrivateProfileString(szSection, "HRoot", "", szHRoot, sizeof(szHRoot), szFileIniConfig); + GetPrivateProfileString(szSection, "Name", "", szName, sizeof(szName), szFileIniConfig); + GetPrivateProfileString(szSection, "Decrypt HKey", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "FALSE") == 0) + bDecryptKey = FALSE; + else + bDecryptKey = TRUE; + + /* check for both 'Verify Existance' and 'Verify Existence' */ + GetPrivateProfileString(szSection, "Verify Existence", "", szVerifyExistence, sizeof(szVerifyExistence), szFileIniConfig); + if(*szVerifyExistence == '\0') + GetPrivateProfileString(szSection, "Verify Existance", "", szVerifyExistence, sizeof(szVerifyExistence), szFileIniConfig); + + GetPrivateProfileString(szSection, "Contains Filename", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + bContainsFilename = TRUE; + else + bContainsFilename = FALSE; + + hkeyRoot = ParseRootKey(szHRoot); + if(bDecryptKey == TRUE) + { + DecryptString(szBuf, szHKey); + lstrcpy(szHKey, szBuf); + } + + GetWinReg(hkeyRoot, szHKey, szName, szBuf, sizeof(szBuf)); + if(*szBuf != '\0') + { + if(lstrcmpi(szVerifyExistence, "FILE") == 0) + { + if(FileExists(szBuf)) + { + if(bContainsFilename == TRUE) + ParsePath(szBuf, szPath, dwPathSize, FALSE, PP_PATH_ONLY); + else + lstrcpy(szPath, szBuf); + + bReturn = TRUE; + } + else + bReturn = FALSE; + } + else if(lstrcmpi(szVerifyExistence, "PATH") == 0) + { + if(bContainsFilename == TRUE) + ParsePath(szBuf, szPath, dwPathSize, FALSE, PP_PATH_ONLY); + else + lstrcpy(szPath, szBuf); + + if(FileExists(szPath)) + bReturn = TRUE; + else + bReturn = FALSE; + } + else + { + if(bContainsFilename == TRUE) + ParsePath(szBuf, szPath, dwPathSize, FALSE, PP_PATH_ONLY); + else + lstrcpy(szPath, szBuf); + + bReturn = TRUE; + } + } + } + + return(bReturn); +} + +BOOL LocatePath(LPSTR szSection, LPSTR szPath, DWORD dwPathSize) +{ + char szPathKey[MAX_BUF]; + BOOL bReturn; + + bReturn = FALSE; + GetPrivateProfileString(szSection, "Path", "", szPathKey, sizeof(szPathKey), szFileIniConfig); + if(*szPathKey != '\0') + { + bReturn = FALSE; + ZeroMemory(szPath, dwPathSize); + + DecryptString(szPath, szPathKey); + bReturn = TRUE; + } + + return(bReturn); +} + +void SetCustomType() +{ + if(diSetupType.stSetupType3.bVisible == TRUE) + sgProduct.dwCustomType = ST_RADIO3; + else if(diSetupType.stSetupType2.bVisible == TRUE) + sgProduct.dwCustomType = ST_RADIO2; + else if(diSetupType.stSetupType1.bVisible == TRUE) + sgProduct.dwCustomType = ST_RADIO1; + else if(diSetupType.stSetupType0.bVisible == TRUE) + sgProduct.dwCustomType = ST_RADIO0; +} + +void STSetVisibility(st *stSetupType) +{ + if(*(stSetupType->szDescriptionShort) == '\0') + stSetupType->bVisible = FALSE; + else + stSetupType->bVisible = TRUE; +} + +HRESULT DecryptVariable(LPSTR szVariable, DWORD dwVariableSize) +{ + char szBuf[MAX_BUF]; + char szBuf2[MAX_BUF]; + char szKey[MAX_BUF]; + char szName[MAX_BUF]; + char szValue[MAX_BUF]; + char szLookupSection[MAX_BUF]; + char szWRMSCurrentVersion[] = "Software\\Microsoft\\Windows\\CurrentVersion"; + char szWRMSShellFolders[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; + char szWRMSMapGroup[] = "Software\\Microsoft\\Windows\\CurrentVersion\\GrpConv\\MapGroup"; + HKEY hkeyRoot; + + /* zero out the memory allocations */ + ZeroMemory(szBuf, sizeof(szBuf)); + ZeroMemory(szKey, sizeof(szKey)); + ZeroMemory(szName, sizeof(szName)); + ZeroMemory(szValue, sizeof(szValue)); + ZeroMemory(szBuf2, sizeof(szBuf2)); + ZeroMemory(szLookupSection, sizeof(szLookupSection)); + + if(lstrcmpi(szVariable, "PROGRAMFILESDIR") == 0) + { + /* parse for the "c:\Program Files" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSCurrentVersion, "ProgramFilesDir", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PROGRAMFILESPATH") == 0) + { + /* parse for the "\Program Files" directory -- NOTE does not include the drive letter */ + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSCurrentVersion, "ProgramFilesDir", szBuf, sizeof(szBuf)); + lstrcpy(szVariable, szBuf+2); + } + else if(lstrcmpi(szVariable, "INSTALLDRIVE") == 0) + { + /* parse for "C:" */ + szVariable[0] = sgProduct.szPath[0]; + szVariable[1] = sgProduct.szPath[1]; + szVariable[2] = '\0'; + } + else if(lstrcmpi(szVariable, "COMMONFILESDIR") == 0) + { + /* parse for the "c:\Program Files\Common Files" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSCurrentVersion, "CommonFilesDir", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "MEDIAPATH") == 0) + { + /* parse for the "c:\Winnt40\Media" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSCurrentVersion, "MediaPath", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "CONFIGPATH") == 0) + { + /* parse for the "c:\Windows\Config" directory */ + if(gSystemInfo.dwOSType & OS_WIN9x) + { + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSCurrentVersion, "ConfigPath", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "DEVICEPATH") == 0) + { + /* parse for the "c:\Winnt40\INF" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSCurrentVersion, "DevicePath", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "COMMON_STARTUP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu\\Programs\\Startup" directory */ + if(gSystemInfo.dwOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Startup", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSShellFolders, "Common Startup", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "PROGRAMS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu\\Programs" directory */ + if((gSystemInfo.dwOSType & OS_WIN9x) || gbRestrictedAccess) + { + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Programs", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSShellFolders, "Common Programs", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "COMMON_PROGRAMS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu\\Programs" directory */ + if(gSystemInfo.dwOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Programs", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSShellFolders, "Common Programs", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "COMMON_STARTMENU") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu" directory */ + if(gSystemInfo.dwOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Start Menu", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSShellFolders, "Common Start Menu", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "COMMON_DESKTOP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Desktop" directory */ + if(gSystemInfo.dwOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Desktop", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, szWRMSShellFolders, "Common Desktop", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "QUICK_LAUNCH") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Application Data\Microsoft\Internet Explorer\Quick Launch" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "AppData", szBuf, sizeof(szBuf)); + wsprintf(szVariable, "%s\\Microsoft\\Internet Explorer\\Quick Launch", szBuf); + if(!FileExists(szVariable)) + GetWinReg(HKEY_CURRENT_USER, szWRMSMapGroup, "Quick Launch", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_STARTUP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Start Menu\Programs\Startup" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Startup", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_PROGRAMS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Start Menu\Programs" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Programs", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_STARTMENU") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Start Menu" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Start Menu", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_DESKTOP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Desktop" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Desktop", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_APPDATA") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Application Data" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "AppData", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_CACHE") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Temporary Internet Files" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Cache", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_COOKIES") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Cookies" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Cookies", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_FAVORITES") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Favorites" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Favorites", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_FONTS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Fonts" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Fonts", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_HISTORY") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\History" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "History", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_NETHOOD") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\NetHood" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "NetHood", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_PERSONAL") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Personal" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Personal", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_PRINTHOOD") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\PrintHood" directory */ + if(gSystemInfo.dwOSType & OS_NT) + { + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "PrintHood", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "PERSONAL_RECENT") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Recent" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Recent", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_SENDTO") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\SendTo" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "SendTo", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_TEMPLATES") == 0) + { + /* parse for the "C:\WINNT40\ShellNew" directory */ + GetWinReg(HKEY_CURRENT_USER, szWRMSShellFolders, "Templates", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PROGRAMFOLDERNAME") == 0) + { + /* parse for the "Netscape Communicator" folder name */ + lstrcpy(szVariable, sgProduct.szProgramFolderName); + } + else if(lstrcmpi(szVariable, "PROGRAMFOLDERPATH") == 0) + { + /* parse for the "c:\Windows\profiles\All Users\Start Menu\Programs" path */ + lstrcpy(szVariable, sgProduct.szProgramFolderPath); + } + else if(lstrcmpi(szVariable, "PROGRAMFOLDERPATHNAME") == 0) + { + /* parse for the "c:\Windows\profiles\All Users\Start Menu\Programs\Netscape Communicator" path */ + lstrcpy(szVariable, sgProduct.szProgramFolderPath); + lstrcat(szVariable, "\\"); + lstrcat(szVariable, sgProduct.szProgramFolderName); + } + else if(lstrcmpi(szVariable, "PROGRAMFOLDERPATH") == 0) + { + /* parse for the "c:\Windows\profiles\All Users\Start Menu\Programs" path */ + lstrcpy(szVariable, sgProduct.szProgramFolderPath); + } + else if(lstrcmpi(szVariable, "WIZTEMP") == 0) + { + /* parse for the "c:\Temp\ns_temp" path */ + lstrcpy(szVariable, szTempDir); + if(szVariable[strlen(szVariable) - 1] == '\\') + szVariable[strlen(szVariable) - 1] = '\0'; + } + else if(lstrcmpi(szVariable, "TEMP") == 0) + { + /* parse for the "c:\Temp" path */ + lstrcpy(szVariable, szOSTempDir); + if(szVariable[strlen(szVariable) - 1] == '\\') + szVariable[strlen(szVariable) - 1] = '\0'; + } + else if(lstrcmpi(szVariable, "WINDISK") == 0) + { + /* Locate the drive that Windows is installed on, and only use the drive letter and the ':' character (C:). */ + if(GetWindowsDirectory(szBuf, MAX_BUF) == 0) + { + char szEGetWinDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", szEGetWinDirFailed, sizeof(szEGetWinDirFailed), szFileIniInstall)) + PrintError(szEGetWinDirFailed, ERROR_CODE_SHOW); + + exit(1); + } + else + { + /* Copy the first 2 characters from the path.. */ + /* This is the drive letter and the ':' character for */ + /* where Windows is installed at. */ + memset(szVariable, '\0', MAX_BUF); + szVariable[0] = szBuf[0]; + szVariable[1] = szBuf[1]; + } + } + else if(lstrcmpi(szVariable, "WINDIR") == 0) + { + /* Locate the "c:\Windows" directory */ + if(GetWindowsDirectory(szVariable, dwVariableSize) == 0) + { + char szEGetWinDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", szEGetWinDirFailed, sizeof(szEGetWinDirFailed), szFileIniInstall)) + PrintError(szEGetWinDirFailed, ERROR_CODE_SHOW); + exit(1); + } + } + else if(lstrcmpi(szVariable, "WINSYSDIR") == 0) + { + /* Locate the "c:\Windows\System" (for Win95/Win98) or "c:\Windows\System32" (for NT) directory */ + if(GetSystemDirectory(szVariable, dwVariableSize) == 0) + { + char szEGetSysDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_SYSTEM_DIRECTORY_FAILED", "", szEGetSysDirFailed, sizeof(szEGetSysDirFailed), szFileIniInstall)) + PrintError(szEGetSysDirFailed, ERROR_CODE_SHOW); + + exit(1); + } + } + else if( (lstrcmpi(szVariable, "JRE LIB PATH") == 0) + || (lstrcmpi(szVariable, "JRE BIN PATH") == 0) ) + { + /* Locate the "c:\Program Files\JavaSoft\JRE\1.3\Bin" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\javaw.Exe", NULL, szBuf, dwVariableSize); + if(*szBuf == '\0') + { + *szVariable = '\0'; + return(FALSE); + } + + ParsePath(szBuf, szBuf2, sizeof(szBuf2), FALSE, PP_PATH_ONLY); + if(lstrcmpi(szVariable, "JRE LIB PATH") == 0) + { + /* The path to javaw.exe is "...\jre\1.3.1\bin\javaw.exe", so we need to get it's + * path only. This should return: + * + * ...\jre\1.3.1\bin\ + * + * We remove the trailing backslash to get the following: + * + * ...\jre\1.3.1\bin + * + * Then get the path again (the trailing backslash indicates that it's a + * path, thus the lack of it indicates a file): + * + * ...\jre\1.3.1\ + * + * Now append 'lib' to it. We are assuming that ...\jre\1.3.1\lib is at the + * same dir level as ...\jre\1.3.1\bin: + * + * ...\jre\1.3.1\lib + */ + RemoveBackSlash(szBuf2); + ParsePath(szBuf2, szVariable, dwVariableSize, FALSE, PP_PATH_ONLY); + AppendBackSlash(szVariable, dwVariableSize); + lstrcat(szVariable, "lib"); + } + else + lstrcpy(szVariable, szBuf2); + } + else if(lstrcmpi(szVariable, "JRE PATH") == 0) + { + /* Locate the "c:\Program Files\JavaSoft\JRE\1.3" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\JavaSoft\\Java Plug-in\\1.3", "JavaHome", szVariable, dwVariableSize); + if(*szVariable == '\0') + return(FALSE); + } + else if(lstrcmpi(szVariable, "SETUP PATH") == 0) + { + lstrcpy(szVariable, sgProduct.szPath); + if(*sgProduct.szSubPath != '\0') + { + AppendBackSlash(szVariable, dwVariableSize); + lstrcat(szVariable, sgProduct.szSubPath); + } + } + else if(lstrcmpi(szVariable, "Default Path") == 0) + { + lstrcpy(szVariable, sgProduct.szPath); + if(*sgProduct.szSubPath != '\0') + { + AppendBackSlash(szVariable, dwVariableSize); + lstrcat(szVariable, sgProduct.szSubPath); + } + } + else if(lstrcmpi(szVariable, "SETUP STARTUP PATH") == 0) + { + lstrcpy(szVariable, szSetupDir); + } + else if(lstrcmpi(szVariable, "Default Folder") == 0) + { + lstrcpy(szVariable, sgProduct.szProgramFolderPath); + AppendBackSlash(szVariable, dwVariableSize); + lstrcat(szVariable, sgProduct.szProgramFolderName); + } + else if(lstrcmpi(szVariable, "Product CurrentVersion") == 0) + { + char szKey[MAX_BUF]; + + wsprintf(szKey, "Software\\%s\\%s", sgProduct.szCompanyName, sgProduct.szProductNameInternal); + + /* parse for the current Netscape WinReg key */ + GetWinReg(HKEY_LOCAL_MACHINE, szKey, "CurrentVersion", szBuf, sizeof(szBuf)); + + if(*szBuf == '\0') + return(FALSE); + + wsprintf(szVariable, "Software\\%s\\%s\\%s", sgProduct.szCompanyName, sgProduct.szProductNameInternal, szBuf); + } + else if(lstrcmpi(szVariable, "Product PreviousVersion") == 0) + { + char szKey[MAX_BUF]; + + wsprintf(szKey, "Software\\%s\\%s", sgProduct.szCompanyName, sgProduct.szProductNamePrevious); + + /* parse for the current Netscape WinReg key */ + GetWinReg(HKEY_LOCAL_MACHINE, szKey, "CurrentVersion", szBuf, sizeof(szBuf)); + + if(*szBuf == '\0') + return(FALSE); + + wsprintf(szVariable, "Software\\%s\\%s\\%s", sgProduct.szCompanyName, sgProduct.szProductNamePrevious, szBuf); + } + else if(lstrcmpi(szVariable, "APP_ID") == 0) + { + lstrcpy(szVariable, sgProduct.szAppID); + } + else if(lstrcmpi(szVariable, "PATH_TO_APP") == 0) + { + lstrcpy(szVariable, sgProduct.szAppPath); + } + else if(lstrcmpi(szVariable, "REGPATH") == 0) + { + lstrcpy(szVariable, sgProduct.szRegPath); + } + else if(szVariable[0] == '$') + { + // the $ indicates that there's another section that defines a lookup for this string. + // find that section to get the registry information, lookup the proper value and + // stick it into szVariable + wsprintf(szLookupSection,"Path Lookup %s",szVariable); + + GetPrivateProfileString(szLookupSection, "Path Reg Key Root", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(*szBuf == '\0') + return(FALSE); + hkeyRoot = ParseRootKey(szBuf); + + GetPrivateProfileString(szLookupSection, "Path Reg Key", "", szKey, sizeof(szKey), szFileIniConfig); + + GetPrivateProfileString(szLookupSection, "Path Reg Name", "", szName, sizeof(szName), szFileIniConfig); + + GetWinReg(hkeyRoot, szKey, szName, szBuf, sizeof(szBuf)); + if(*szBuf == '\0') + return(FALSE); + + GetPrivateProfileString(szLookupSection, "Strip Filename", "", szBuf2, sizeof(szBuf2), szFileIniConfig); + if(lstrcmpi(szBuf2, "TRUE") == 0) + { + ParsePath(szBuf, szVariable, dwVariableSize, FALSE, PP_PATH_ONLY); + RemoveBackSlash(szVariable); + } + else + { + lstrcpy(szVariable,szBuf); + } + } + else if(lstrcmpi(szVariable, "GRE PATH") == 0) + { + if(*gGre.homePath != '\0') + lstrcpy(szVariable, gGre.homePath); + } + else + return(FALSE); + + return(TRUE); +} + +void CollateBackslashes(LPSTR szInputOutputStr) +{ + // search for "\\" in the output string, and replace it with "\" + LPSTR pSearch = szInputOutputStr; + LPSTR pSearchEnd = szInputOutputStr + lstrlen(szInputOutputStr); + LPSTR pPreviousSearch = NULL; + + while (pSearch < pSearchEnd) + { + if ('\\' == *pSearch) + { + if (pPreviousSearch && ('\\' == *pPreviousSearch)) + { // found a second one -> remove it + memmove(pPreviousSearch, pSearch, pSearchEnd-pSearch+1); + + // our string is shorter now ... + pSearchEnd -= pSearch - pPreviousSearch; + + // no increment of pSearch here - we want to continue with the same character, + // again (just for the weird case of yet another backslash...) + continue; + } + } + + pPreviousSearch = pSearch; + pSearch = CharNext(pSearch); + } +} + +HRESULT DecryptString(LPSTR szOutputStr, LPSTR szInputStr) +{ + DWORD dwLenInputStr; + DWORD dwCounter; + DWORD dwVar; + DWORD dwPrepend; + char szBuf[MAX_BUF]; + char szOutuptStrTemp[MAX_BUF]; + char szVariable[MAX_BUF]; + char szPrepend[MAX_BUF]; + char szAppend[MAX_BUF]; + char szResultStr[MAX_BUF]; + BOOL bFoundVar; + BOOL bBeginParse; + BOOL bDecrypted; + + /* zero out the memory addresses */ + memset(szBuf, '\0', MAX_BUF); + memset(szVariable, '\0', MAX_BUF); + memset(szPrepend, '\0', MAX_BUF); + memset(szAppend, '\0', MAX_BUF); + memset(szResultStr, '\0', MAX_BUF); + + lstrcpy(szPrepend, szInputStr); + dwLenInputStr = lstrlen(szInputStr); + bBeginParse = FALSE; + bFoundVar = FALSE; + + for(dwCounter = 0; dwCounter < dwLenInputStr; dwCounter++) + { + if((szInputStr[dwCounter] == ']') && bBeginParse) + break; + + if(bBeginParse) + szVariable[dwVar++] = szInputStr[dwCounter]; + + if((szInputStr[dwCounter] == '[') && !bBeginParse) + { + dwVar = 0; + dwPrepend = dwCounter; + bBeginParse = TRUE; + } + } + + if(dwCounter == dwLenInputStr) + /* did not find anything to expand. */ + dwCounter = 0; + else + { + bFoundVar = TRUE; + ++dwCounter; + } + + if(bFoundVar) + { + lstrcpy(szAppend, &szInputStr[dwCounter]); + + szPrepend[dwPrepend] = '\0'; + + /* if Variable is "XPI PATH", do special processing */ + if(lstrcmpi(szVariable, "XPI PATH") == 0) + { + lstrcpy(szBuf, sgProduct.szAlternateArchiveSearchPath); + RemoveBackSlash(szBuf); + lstrcpy(szOutuptStrTemp, szPrepend); + lstrcat(szOutuptStrTemp, szBuf); + lstrcat(szOutuptStrTemp, szAppend); + + if((*sgProduct.szAlternateArchiveSearchPath != '\0') && FileExists(szOutuptStrTemp)) + { + lstrcpy(szVariable, sgProduct.szAlternateArchiveSearchPath); + } + else + { + lstrcpy(szBuf, szSetupDir); + RemoveBackSlash(szBuf); + lstrcpy(szOutuptStrTemp, szPrepend); + lstrcat(szOutuptStrTemp, szBuf); + lstrcat(szOutuptStrTemp, szAppend); + + if(!FileExists(szOutuptStrTemp)) + lstrcpy(szVariable, szTempDir); + else + lstrcpy(szVariable, szSetupDir); + } + + RemoveBackSlash(szVariable); + bDecrypted = TRUE; + } + else + { + bDecrypted = DecryptVariable(szVariable, sizeof(szVariable)); + } + + if(!bDecrypted) + { + /* Variable was not able to be dcripted. */ + /* Leave the variable as it was read in by adding the '[' and ']' */ + /* characters back to the variable. */ + lstrcpy(szBuf, "["); + lstrcat(szBuf, szVariable); + lstrcat(szBuf, "]"); + lstrcpy(szVariable, szBuf); + } + + lstrcpy(szOutputStr, szPrepend); + lstrcat(szOutputStr, szVariable); + lstrcat(szOutputStr, szAppend); + + if(bDecrypted) + { + DecryptString(szResultStr, szOutputStr); + lstrcpy(szOutputStr, szResultStr); + CollateBackslashes(szOutputStr); + } + } + else + lstrcpy(szOutputStr, szInputStr); + + return(TRUE); +} + +int ExtractDirEntries(char* directory, void* vZip) +{ + int err; + int result; + char buf[512]; // XXX: need an XP "max path" + + int paths = 1; + if(paths) + { + void* find = ZIP_FindInit(vZip, directory); + + if(find) + { + int prefix_length = 0; + + if(directory) + prefix_length = lstrlen(directory) - 1; + + if(prefix_length >= sizeof(buf)-1) + return ZIP_ERR_GENERAL; + + err = ZIP_FindNext( find, buf, sizeof(buf) ); + while ( err == ZIP_OK ) + { + CreateDirectoriesAll(buf, DO_NOT_ADD_TO_UNINSTALL_LOG); + if(buf[lstrlen(buf) - 1] != '/') + // only extract if it's a file + result = ZIP_ExtractFile(vZip, buf, buf); + err = ZIP_FindNext( find, buf, sizeof(buf) ); + } + ZIP_FindFree( find ); + } + else + err = ZIP_ERR_GENERAL; + + if ( err == ZIP_ERR_FNF ) + return ZIP_OK; // found them all + } + + return ZIP_ERR_GENERAL; +} + +HRESULT FileExists(LPSTR szFile) +{ + DWORD rv; + + if((rv = GetFileAttributes(szFile)) == -1) + { + return(FALSE); + } + else + { + return(rv); + } +} + +BOOL NeedReboot() +{ + if(GreInstallerNeedsReboot()) + return(TRUE); + if(diReboot.dwShowDialog == AUTO) + return(bReboot); + else + return(diReboot.dwShowDialog); +} + +/* Function: IsInstallerProductGRE() + * in: none. + * out: Boolean value on whether or not the installer will be installing + * the GRE. + * purpose: The check to see if the product the installer will be installing + * is GRE or not. + */ +BOOL IsInstallerProductGRE() +{ + return(lstrcmpi(sgProduct.szProductNameInternal, "GRE") == 0 ? TRUE : FALSE); +} + +/* Function: GreInstallerNeedsReboot() + * in: none. + * out: Boolean value on whether or not GRE installer needed a + * when it ran last. + * purpose: To check if this is not the GRE installer and that the GRE installer + * has been run needed a reboot. + */ +BOOL GreInstallerNeedsReboot() +{ + BOOL greReboot = FALSE; + + /* if this setup is not installing GRE *and* the GRE Setup has been run, then + * check for GRE setup's exit value, if one exists */ + if(!IsInstallerProductGRE() && gGreInstallerHasRun) + { + char status[MAX_BUF]; + + GetGreSetupExitStatus(status, sizeof(status)); + /* if a reboot is detected from the GRE setup run, then + * simply return TRUE for reboot is needed. */ + if(lstrcmpi(status, "Reboot") == 0) + greReboot = TRUE; + } + return(greReboot); +} + +BOOL DeleteWGetLog(void) +{ + char szFile[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFile, sizeof(szFile)); + + lstrcpy(szFile, szTempDir); + AppendBackSlash(szFile, sizeof(szFile)); + lstrcat(szFile, FILE_WGET_LOG); + + if(FileExists(szFile)) + bFileExists = TRUE; + + DeleteFile(szFile); + return(bFileExists); +} + +BOOL DeleteIdiGetConfigIni() +{ + char szFileIdiGetConfigIni[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFileIdiGetConfigIni, sizeof(szFileIdiGetConfigIni)); + + lstrcpy(szFileIdiGetConfigIni, szTempDir); + AppendBackSlash(szFileIdiGetConfigIni, sizeof(szFileIdiGetConfigIni)); + lstrcat(szFileIdiGetConfigIni, FILE_IDI_GETCONFIGINI); + if(FileExists(szFileIdiGetConfigIni)) + { + bFileExists = TRUE; + } + DeleteFile(szFileIdiGetConfigIni); + return(bFileExists); +} + +BOOL DeleteInstallLogFile(char *szFile) +{ + char szInstallLogFile[MAX_BUF]; + BOOL bFileExists = FALSE; + + lstrcpy(szInstallLogFile, szTempDir); + AppendBackSlash(szInstallLogFile, sizeof(szInstallLogFile)); + lstrcat(szInstallLogFile, szFile); + + if(FileExists(szInstallLogFile)) + { + bFileExists = TRUE; + DeleteFile(szInstallLogFile); + } + + return(bFileExists); +} + +BOOL DeleteIniRedirect() +{ + char szFileIniRedirect[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFileIniRedirect, sizeof(szFileIniRedirect)); + + lstrcpy(szFileIniRedirect, szTempDir); + AppendBackSlash(szFileIniRedirect, sizeof(szFileIniRedirect)); + lstrcat(szFileIniRedirect, FILE_INI_REDIRECT); + if(FileExists(szFileIniRedirect)) + { + bFileExists = TRUE; + } + DeleteFile(szFileIniRedirect); + return(bFileExists); +} + +BOOL DeleteIdiGetRedirect() +{ + char szFileIdiGetRedirect[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFileIdiGetRedirect, sizeof(szFileIdiGetRedirect)); + + lstrcpy(szFileIdiGetRedirect, szTempDir); + AppendBackSlash(szFileIdiGetRedirect, sizeof(szFileIdiGetRedirect)); + lstrcat(szFileIdiGetRedirect, FILE_IDI_GETREDIRECT); + if(FileExists(szFileIdiGetRedirect)) + { + bFileExists = TRUE; + } + DeleteFile(szFileIdiGetRedirect); + return(bFileExists); +} + +BOOL DeleteIdiGetArchives() +{ + char szFileIdiGetArchives[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFileIdiGetArchives, sizeof(szFileIdiGetArchives)); + + lstrcpy(szFileIdiGetArchives, szTempDir); + AppendBackSlash(szFileIdiGetArchives, sizeof(szFileIdiGetArchives)); + lstrcat(szFileIdiGetArchives, FILE_IDI_GETARCHIVES); + if(FileExists(szFileIdiGetArchives)) + { + bFileExists = TRUE; + } + DeleteFile(szFileIdiGetArchives); + return(bFileExists); +} + +BOOL DeleteIdiFileIniConfig() +{ + char szFileIniConfig[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFileIniConfig, sizeof(szFileIniConfig)); + + lstrcpy(szFileIniConfig, szTempDir); + AppendBackSlash(szFileIniConfig, sizeof(szFileIniConfig)); + lstrcat(szFileIniConfig, FILE_INI_CONFIG); + if(FileExists(szFileIniConfig)) + { + bFileExists = TRUE; + } + DeleteFile(szFileIniConfig); + return(bFileExists); +} + +BOOL DeleteIdiFileIniInstall() +{ + char szFileIniInstall[MAX_BUF]; + BOOL bFileExists = FALSE; + + ZeroMemory(szFileIniInstall, sizeof(szFileIniInstall)); + + lstrcpy(szFileIniInstall, szTempDir); + AppendBackSlash(szFileIniInstall, sizeof(szFileIniInstall)); + lstrcat(szFileIniInstall, FILE_INI_INSTALL); + if(FileExists(szFileIniInstall)) + { + bFileExists = TRUE; + } + DeleteFile(szFileIniInstall); + return(bFileExists); +} + +void DeleteArchives(DWORD dwDeleteCheck) +{ + DWORD dwIndex0; + char szArchiveName[MAX_BUF]; + siC *siCObject = NULL; + + ZeroMemory(szArchiveName, sizeof(szArchiveName)); + + if((!bSDUserCanceled) && (GetPreviousUnfinishedState() == PUS_NONE)) + { + dwIndex0 = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + lstrcpy(szArchiveName, szTempDir); + AppendBackSlash(szArchiveName, sizeof(szArchiveName)); + lstrcat(szArchiveName, siCObject->szArchiveName); + + switch(dwDeleteCheck) + { + case DA_ONLY_IF_IN_ARCHIVES_LST: + if(IsInArchivesLst(siCObject, FALSE)) + DeleteFile(szArchiveName); + break; + + case DA_ONLY_IF_NOT_IN_ARCHIVES_LST: + if(!IsInArchivesLst(siCObject, FALSE)) + DeleteFile(szArchiveName); + break; + + case DA_IGNORE_ARCHIVES_LST: + default: + DeleteFile(szArchiveName); + break; + } + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } + + DeleteIniRedirect(); + } +} + +void CleanTempFiles() +{ + DeleteIdiGetConfigIni(); + DeleteIdiGetArchives(); + DeleteIdiGetRedirect(); + + /* do not delete config.ini file. + if it was uncompressed from the self-extracting .exe file, + then it will be deleted automatically. + Right now the config.ini does not get downloaded, so we + don't have to worry about that case + */ + DeleteIdiFileIniConfig(); + DeleteIdiFileIniInstall(); + DeleteArchives(DA_IGNORE_ARCHIVES_LST); + DeleteInstallLogFile(FILE_INSTALL_LOG); + DeleteInstallLogFile(FILE_INSTALL_STATUS_LOG); +} + +void SendErrorMessage(void) +{ + char szBuf[MAX_BUF]; + char *szPartialEscapedURL = NULL; + + /* append to the message stream the list of components that either had + * network retries or crc retries */ + LogMSDownloadFileStatus(); + + /* replace this function call with a call to xpnet */ + if((szPartialEscapedURL = nsEscape(gErrorMessageStream.szMessage, + url_Path)) != NULL) + { + char szWGetLog[MAX_BUF]; + char szMsg[MAX_BUF]; + char *szFullURL = NULL; + DWORD dwSize; + + lstrcpy(szWGetLog, szTempDir); + AppendBackSlash(szWGetLog, sizeof(szWGetLog)); + lstrcat(szWGetLog, FILE_WGET_LOG); + + /* take into account '?' and '\0' chars */ + dwSize = lstrlen(gErrorMessageStream.szURL) + + lstrlen(szPartialEscapedURL) + 2; + if((szFullURL = NS_GlobalAlloc(dwSize)) != NULL) + { + wsprintf(szFullURL, + "%s?%s", + gErrorMessageStream.szURL, + szPartialEscapedURL); + + wsprintf(szMsg, + "UnEscapedURL: %s?%s\nEscapedURL: %s", + gErrorMessageStream.szURL, + gErrorMessageStream.szMessage, + szFullURL); + + if(gErrorMessageStream.bShowConfirmation && + (*gErrorMessageStream.szConfirmationMessage != '\0')) + { + char szConfirmationMessage[MAX_BUF]; + + wsprintf(szBuf, + "\n\n %s", + gErrorMessageStream.szMessage); + wsprintf(szConfirmationMessage, + gErrorMessageStream.szConfirmationMessage, + szBuf); + if(MessageBox(hWndMain, + szConfirmationMessage, + sgProduct.szProductName, + MB_OKCANCEL | MB_ICONQUESTION) == IDOK) + { + //PrintError(szMsg, ERROR_CODE_HIDE); + WGet(szFullURL, + szWGetLog, + diAdvancedSettings.szProxyServer, + diAdvancedSettings.szProxyPort, + diAdvancedSettings.szProxyUser, + diAdvancedSettings.szProxyPasswd); + } + } + else if(!gErrorMessageStream.bShowConfirmation) + { + //PrintError(szMsg, ERROR_CODE_HIDE); + WGet(szFullURL, + szWGetLog, + diAdvancedSettings.szProxyServer, + diAdvancedSettings.szProxyPort, + diAdvancedSettings.szProxyUser, + diAdvancedSettings.szProxyPasswd); + } + + FreeMemory(&szFullURL); + } + + FreeMemory(&szPartialEscapedURL); + } +} + +void DeInitialize() +{ + char szBuf[MAX_BUF]; + + LogISTime(W_END); + if(bCreateDestinationDir) + { + lstrcpy(szBuf, sgProduct.szPath); + AppendBackSlash(szBuf, sizeof(szBuf)); + DirectoryRemove(szBuf, FALSE); + } + + if(hbmpBoxChecked) + DeleteObject(hbmpBoxChecked); + if(hbmpBoxCheckedDisabled) + DeleteObject(hbmpBoxCheckedDisabled); + if(hbmpBoxUnChecked) + DeleteObject(hbmpBoxUnChecked); + + DeleteWGetLog(); + CleanTempFiles(); + DirectoryRemove(szTempDir, FALSE); + + if(gErrorMessageStream.bEnabled && gErrorMessageStream.bSendMessage) + SendErrorMessage(); + + DeInitSiComponents(&siComponents); + DeInitGre(&gGre); + DeInitSXpcomFile(); + DeInitSDObject(); + DeInitDlgReboot(&diReboot); + DeInitDlgDownload(&diDownload); + DeInitDlgStartInstall(&diStartInstall); + DeInitDlgAdditionalOptions(&diAdditionalOptions); + DeInitDlgAdvancedSettings(&diAdvancedSettings); + DeInitDlgProgramFolder(&diProgramFolder); + DeInitDlgWindowsIntegration(&diWindowsIntegration); + DeInitDlgSelectComponents(&diSelectAdditionalComponents); + DeInitDlgSelectComponents(&diSelectComponents); + DeInitDlgSetupType(&diSetupType); + DeInitDlgWelcome(&diWelcome); + DeInitDlgLicense(&diLicense); + DeInitDlgQuickLaunch(&diQuickLaunch); + DeInitDSNode(&gdsnComponentDSRequirement); + DeInitErrorMessageStream(); + + FreeMemory(&szTempDir); + FreeMemory(&szOSTempDir); + FreeMemory(&szProxyDLLPath); + FreeMemory(&szSetupDir); + FreeMemory(&szFileIniConfig); + FreeMemory(&szFileIniInstall); + FreeMemory(&szEGlobalAlloc); + FreeMemory(&szEOutOfMemory); + FreeMemory(&szEDllLoad); + FreeMemory(&szEStringLoad); + FreeMemory(&szEStringNull); + DeleteObject(sgInstallGui.systemFont); + DeleteObject(sgInstallGui.definedFont); + + FreeLibrary(hSetupRscInst); + if (hGREAppInstallerProxyDLL != NULL) + FreeLibrary(hGREAppInstallerProxyDLL); +} + +char *GetSaveInstallerPath(char *szBuf, DWORD dwBufSize) +{ +#ifdef XXX_INTL_HACK_WORKAROUND_FOR_NOW + char szBuf2[MAX_BUF]; +#endif + + /* determine the path to where the setup and downloaded files will be saved to */ + lstrcpy(szBuf, sgProduct.szPath); + AppendBackSlash(szBuf, dwBufSize); + if(*sgProduct.szSubPath != '\0') + { + lstrcat(szBuf, sgProduct.szSubPath); + lstrcat(szBuf, " "); + } + +#ifdef XXX_INTL_HACK_WORKAROUND_FOR_NOW +/* Installer can't create the Save Installer Path if the word "Setup" is localized. */ + if(GetPrivateProfileString("Messages", "STR_SETUP", "", szBuf2, sizeof(szBuf2), szFileIniInstall)) + lstrcat(szBuf, szBuf2); + else +#endif + lstrcat(szBuf, "Setup"); + + /* We need to have the product name be part of the Setup directory name. + * This is because if GRE is installed ontop of this app, GRE's saved files + * will overwrite files of the same name for this app. */ + if(*sgProduct.szProductNameInternal != '\0') + { + lstrcat(szBuf, " "); + lstrcat(szBuf, sgProduct.szProductNameInternal); + } + + return(szBuf); +} + +void SaveInstallerFiles() +{ + int i; + char szBuf[MAX_BUF]; + char destInstallDir[MAX_BUF]; + char destInstallXpiDir[MAX_BUF]; + char szMFN[MAX_BUF]; + char szArchivePath[MAX_BUF]; + DWORD dwIndex0; + siC *siCObject = NULL; + + GetSaveInstallerPath(destInstallDir, sizeof(destInstallDir)); + AppendBackSlash(destInstallDir, sizeof(destInstallDir)); + CreateDirectoriesAll(destInstallDir, ADD_TO_UNINSTALL_LOG); + + /* copy the self extracting file that spawned setup.exe, if one exists */ + if((*sgProduct.szAlternateArchiveSearchPath != '\0') && (*sgProduct.szParentProcessFilename != '\0')) + { + FileCopy(sgProduct.szParentProcessFilename, destInstallDir, FALSE, FALSE); + + /* The dir for xpi files is .\xpi because the self-extracting + * .exe file will automatically look for the .xpi files in a xpi subdir + * off of the current working dir. */ + _snprintf(destInstallXpiDir, sizeof(destInstallXpiDir), "%sxpi\\", destInstallDir); + destInstallXpiDir[sizeof(destInstallXpiDir) - 1] = '\0'; + CreateDirectoriesAll(destInstallXpiDir, ADD_TO_UNINSTALL_LOG); + } + else + { + /* Else if self extracting file does not exist, copy the setup files */ + /* First get the current process' filename (in case it's not really named setup.exe */ + /* Then copy it to the install folder */ + GetModuleFileName(NULL, szBuf, sizeof(szBuf)); + ParsePath(szBuf, szMFN, sizeof(szMFN), FALSE, PP_FILENAME_ONLY); + + lstrcpy(szBuf, szSetupDir); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, szMFN); + FileCopy(szBuf, destInstallDir, FALSE, FALSE); + + /* now copy the rest of the setup files */ + i = 0; + while(TRUE) + { + if(*SetupFileList[i] == '\0') + break; + + lstrcpy(szBuf, szSetupDir); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, SetupFileList[i]); + FileCopy(szBuf, destInstallDir, FALSE, FALSE); + + ++i; + } + /* copy the license file */ + if(*diLicense.szLicenseFilename != '\0') + FileCopy(diLicense.szLicenseFilename, destInstallDir, FALSE, FALSE); + /* copy the readme file */ + if(*diSetupType.szReadmeFilename != '\0') + FileCopy(diLicense.szLicenseFilename, destInstallDir, FALSE, FALSE); + + /* The dir for xpi files is just "." as opposed to ".\xpi" + * because the setup.exe (not the self-extracting .exe) will look for the + * .xpi files in the cwd. */ + MozCopyStr(destInstallDir, destInstallXpiDir, sizeof(destInstallXpiDir)); + } + + dwIndex0 = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + LocateJar(siCObject, szArchivePath, sizeof(szArchivePath), TRUE); + if(*szArchivePath != '\0') + { + lstrcpy(szBuf, szArchivePath); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, siCObject->szArchiveName); + FileCopy(szBuf, destInstallXpiDir, FALSE, FALSE); + } + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } +} + +BOOL ShowAdditionalOptionsDialog(void) +{ + if(diAdditionalOptions.bShowDialog == FALSE) + return(FALSE); + + if( (diAdditionalOptions.bShowHomepageOption == FALSE) && (GetTotalArchivesToDownload() < 1) ) + return(FALSE); + + return(TRUE); +} diff --git a/toolkit/mozapps/installer/windows/wizard/setup/extra.h b/toolkit/mozapps/installer/windows/wizard/setup/extra.h new file mode 100644 index 00000000000..90821502fbb --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/extra.h @@ -0,0 +1,236 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _EXTRA_H_ +#define _EXTRA_H_ + +#include "supersede.h" + +BOOL InitDialogClass(HINSTANCE hInstance, HINSTANCE hSetupRscInst); +BOOL InitApplication(HINSTANCE hInstance, HINSTANCE hSetupRscInst); +BOOL InitInstance(HINSTANCE hInstance, DWORD dwCmdShow); +void PrintError(LPSTR szMsg, DWORD dwErrorCodeSH); +void FreeMemory(void **vPointer); +void *NS_GlobalReAlloc(HGLOBAL *hgMemory, + DWORD dwMemoryBufSize, + DWORD dwNewSize); +void *NS_GlobalAlloc(DWORD dwMaxBuf); +HRESULT Initialize(HINSTANCE hInstance); +HRESULT NS_LoadStringAlloc(HANDLE hInstance, DWORD dwID, LPSTR *szStringBuf, DWORD dwStringBuf); +HRESULT NS_LoadString(HANDLE hInstance, DWORD dwID, LPSTR szStringBuf, DWORD dwStringBuf); +HRESULT WinSpawn(LPSTR szClientName, LPSTR szParameters, LPSTR szCurrentDir, int iShowCmd, BOOL bWait); +HRESULT ParseConfigIni(LPSTR lpszCmdLine); +HRESULT ParseInstallIni(); +HRESULT DecryptString(LPSTR szOutputStr, LPSTR szInputStr); +HRESULT DecryptVariable(LPSTR szVariable, DWORD dwVariableSize); +void CollateBackslashes(LPSTR szInputOutputStr); +HRESULT InitSetupGeneral(void); +HRESULT InitDlgWelcome(diW *diDialog); +HRESULT InitDlgLicense(diL *diDialog); +HRESULT InitDlgQuickLaunch(diQL *diDialog); +HRESULT InitDlgSetupType(diST *diDialog); +HRESULT InitDlgSelectComponents(diSC *diDialog, DWORD dwSM); +HRESULT InitDlgWindowsIntegration(diWI *diDialog); +HRESULT InitDlgProgramFolder(diPF *diDialog); +HRESULT InitDlgStartInstall(diSI *diDialog); +HRESULT InitDlgSiteSelector(diAS *diDialog); +HRESULT InitSDObject(void); +void DeInitSDObject(void); +siC *CreateSiCNode(void); +void SiCNodeInsert(siC **siCHead, siC *siCTemp); +void SiCNodeDelete(siC *siCTemp); +siCD *CreateSiCDepNode(void); +void SiCDepNodeDelete(siCD *siCDepTemp); +void SiCDepNodeInsert(siCD **siCDepHead, siCD *siCDepTemp); +HRESULT SiCNodeGetAttributes(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +void SiCNodeSetAttributes(DWORD dwIndex, DWORD dwAttributes, BOOL bSet, BOOL bIncludeInvisible, DWORD dwACFlag, HWND hwndListBox); +void SiCNodeSetItemsSelected(DWORD dwSetupType); +char *SiCNodeGetReferenceName(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +char *SiCNodeGetDescriptionShort(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +char *SiCNodeGetDescriptionLong(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +char *SiCNodeGetReferenceName(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +siC *SiCNodeGetObject(DWORD dwIndex, BOOL bIncludeInvisibleObjs, DWORD dwACFlag); +ULONGLONG SiCNodeGetInstallSize(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +ULONGLONG SiCNodeGetInstallSizeSystem(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +ULONGLONG SiCNodeGetInstallSizeArchive(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag); +siC *SiCNodeFind(siC *siComponents, char *szInReferenceName); +void InitSiComponents(char *szFileIni); +HRESULT ParseComponentAttributes(char *szBuf, DWORD dwAttributes, BOOL bOverride); +void InitSiteSelector(char *szFileIni); +void DeInitSiCDependencies(siCD *siCDDependencies); +BOOL ResolveDependencies(DWORD dwIndex, HWND hwndListBox); +BOOL ResolveComponentDependency(siCD *siCDInDependency, HWND hwndListBox); +void ResolveDependees(LPSTR szToggledDescriptionShort, HWND hwndListBox); +BOOL ResolveComponentDependee(siCD *siCDInDependee); +void STSetVisibility(st *stSetupType); +HRESULT InitSXpcomFile(void); +void DeInitSXpcomFile(void); +void DeInitialize(void); +void DeInitDlgWelcome(diW *diDialog); +void DeInitDlgLicense(diL *diDialog); +void DeInitDlgQuickLaunch(diQL *diDialog); +void DeInitDlgSetupType(diST *diDialog); +void DeInitDlgSelectComponents(diSC *diDialog); +void DeInitDlgWindowsIntegration(diWI *diDialog); +void DeInitDlgProgramFolder(diPF *diDialog); +void DeInitDlgStartInstall(diSI *diDialog); +void DeInitDlgSiteSelector(diAS *diDialog); +void DetermineOSVersionEx(void); +void DeInitSiComponents(siC **siComponents); +void DeInitSetupGeneral(void); +HRESULT ParseSetupIni(void); +HRESULT GetConfigIni(void); +HRESULT GetInstallIni(void); +void CleanTempFiles(void); +void OutputSetupTitle(HDC hDC); +long RetrieveArchives(void); +long RetrieveRedirectFile(void); +void ParsePath(LPSTR szInput, LPSTR szOutput, DWORD dwOutputSize, BOOL bUseSlash, DWORD dwType); +void RemoveBackSlash(LPSTR szInput); +void AppendBackSlash(LPSTR szInput, DWORD dwInputSize); +void RemoveSlash(LPSTR szInput); +void AppendSlash(LPSTR szInput, DWORD dwInputSize); +BOOL DeleteIdiGetConfigIni(void); +BOOL DeleteIdiGetArchives(void); +BOOL DeleteIdiGetRedirect(void); +BOOL DeleteIdiFileIniConfig(void); +BOOL DeleteIdiFileIniInstall(void); +void DeleteArchives(DWORD dwDeleteCheck); +BOOL DeleteIniRedirect(void); +HRESULT LaunchApps(void); +HRESULT FileExists(LPSTR szFile); +int ExtractDirEntries(char* directory,void* vZip); +int LocateJar(siC *siCObject, LPSTR szPath, int dwPathSize, BOOL bIncludeTempDir); +HRESULT AddArchiveToIdiFile(siC *siCObject, + char *szSFile, + char *szFileIdiGetArchives); +int SiCNodeGetIndexDS(char *szInDescriptionShort); +int SiCNodeGetIndexRN(char *szInReferenceName); +void ViewSiComponentsDependency(char *szBuffer, char *szIndentation, siC *siCNode); +void ViewSiComponentsDependee(char *szBuffer, char *szIndentation, siC *siCNode); +void ViewSiComponents(void); +BOOL IsWin95Debute(void); +ULONGLONG GetDiskSpaceRequired(DWORD dwType); +ULONGLONG GetDiskSpaceAvailable(LPSTR szPath); +HRESULT VerifyDiskSpace(void); +HRESULT ErrorMsgDiskSpace(ULONGLONG ullDSAvailable, ULONGLONG ullDSRequired, LPSTR szPath, BOOL bCrutialMsg); +void SetCustomType(void); +void GetAlternateArchiveSearchPath(LPSTR lpszCmdLine); +BOOL NeedReboot(void); +BOOL LocatePreviousPath(LPSTR szMainSectionName, LPSTR szPath, DWORD dwPathSize); +BOOL LocatePathNscpReg(LPSTR szSection, LPSTR szPath, DWORD dwPathSize); +BOOL LocatePathWinReg(LPSTR szSection, LPSTR szPath, DWORD dwPathSize); +BOOL LocatePath(LPSTR szSection, LPSTR szPath, DWORD dwPathSize); +int VR_GetPath(char *component_path, unsigned long sizebuf, char *buf); +dsN *CreateDSNode(); +void DsNodeInsert(dsN **dsNHead, dsN *dsNTemp); +void DsNodeDelete(dsN **dsNTemp); +void DeInitDSNode(dsN **dsnComponentDSRequirement); +void UpdatePathDiskSpaceRequired(LPSTR szPath, ULONGLONG ullInstallSize, dsN **dsnComponentDSRequirement); +HRESULT InitComponentDiskSpaceInfo(dsN **dsnComponentDSRequirement); +HRESULT CheckInstances(); +long RandomSelect(void); +BOOL CheckLegacy(HWND hDlg); +COLORREF DecryptFontColor(LPSTR szColor); +ssi *CreateSsiSiteSelectorNode(); +void SsiSiteSelectorNodeInsert(ssi **ssiHead, ssi *ssiTemp); +void SsiSiteSelectorNodeDelete(ssi *ssiTemp); +ssi* SsiGetNode(LPSTR szDescription); +void UpdateSiteSelector(void); +DWORD GetAdditionalComponentsCount(void); +DWORD GetTotalArchivesToDownload(); +void RemoveQuotes(LPSTR lpszSrc, LPSTR lpszDest, int iDestSize); +int MozCopyStr(LPSTR szSrc, LPSTR szDest, DWORD dwDestBufSize); +LPSTR GetFirstNonSpace(LPSTR lpszString); +LPSTR MozStrChar(LPSTR lpszString, char c); +int GetArgC(LPSTR lpszCommandLine); +LPSTR GetArgV(LPSTR lpszCommandLine, + int iIndex, + LPSTR lpszDest, + int iDestSize); +DWORD ParseCommandLine(LPSTR aMessageToClose, LPSTR lpszCmdLine); +DWORD ParseForStartupOptions(LPSTR aCmdLine); +void SetSetupRunMode(LPSTR szMode); +void Delay(DWORD dwSeconds); +void UnsetSetupState(void); +void SetSetupState(char *szState); +siCD *InitWinInitNodes(char *szInFile); +void UpdateWininit(LPSTR szUninstallFilename); +char *GetSaveInstallerPath(char *szBuf, DWORD dwBufSize); +void SaveInstallerFiles(void); +void ResetComponentAttributes(char *szFileIni); +BOOL IsInList(DWORD dwCurrentItem, + DWORD dwItems, + DWORD *dwItemsSelected); +int LocateExistingPath(char *szPath, + char *szExistingPath, + DWORD dwExistingPathSize); +BOOL ContainsReparseTag(char *szPath, + char *szReparsePath, + DWORD dwReparsePathSize); +BOOL DeleteInstallLogFile(char *szFile); +int CRCCheckDownloadedArchives(char *szCorruptedArchiveList, + DWORD dwCorruptedArchivelistSize, + char *szFileIdiGetArchives); +int CRCCheckArchivesStartup(char *szCorruptedArchiveList, + DWORD dwCorruptedArchiveListSize, + BOOL bIncludeTempPath); +BOOL ResolveForceUpgrade(siC *siCObject); +void RestoreInvisibleFlag(siC *siCNode); +void RestoreAdditionalFlag(siC *siCNode); +void RestoreEnabledFlag(siC *siCNode); +void SwapFTPAndHTTP(char *szInUrl, DWORD dwInUrlSize); +void ClearWinRegUninstallFileDeletion(void); +int AppendToGlobalMessageStream(char *szInfo); +char *GetOSTypeString(char *szOSType, DWORD dwOSTypeBufSize); +int UpdateIdiFile(char *szPartialUrl, + DWORD dwPartialUrlBufSize, + siC *siCObject, + char *szSection, + char *szKey, + char *szFileIdiGetArchives); +void SetDownloadFile(void); +void UnsetSetupCurrentDownloadFile(void); +void SetSetupCurrentDownloadFile(char *szCurrentFilename); +char *GetSetupCurrentDownloadFile(char *szCurrentDownloadFile, + DWORD dwCurrentDownloadFileBufSize); +BOOL DeleteWGetLog(void); +DWORD ParseOSType(char *szOSType); +BOOL ShowAdditionalOptionsDialog(void); +DWORD GetPreviousUnfinishedState(void); +void RefreshIcons(); +void NeedToInstallFiles(LPSTR szProdDir); +void LaunchOneComponent(siC *siCObject, greInfo *aGre); +HRESULT ProcessXpinstallEngine(void); +void GetXpinstallPath(char *aPath, int aPathBufSize); +BOOL GreInstallerNeedsReboot(void); +void ReplacePrivateProfileStrCR(LPSTR aInputOutputStr); +void UpdateGREAppInstallerProgress(int percent); +BOOL IsPathWithinWindir(); +void CleanupOnUpgrade(); +BOOL IsInstallerProductGRE(void); +HRESULT CleanupOrphanedGREs(void); + +#endif /* _EXTRA_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/ifuncns.c b/toolkit/mozapps/installer/windows/wizard/setup/ifuncns.c new file mode 100644 index 00000000000..bda76c7f1e1 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/ifuncns.c @@ -0,0 +1,2383 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + * Curt Patrick + */ + +#include "extern.h" +#include "extra.h" +#include "dialogs.h" +#include "shortcut.h" +#include "ifuncns.h" +#include "wizverreg.h" +#include "logging.h" +#include + +#define SIZEOFNOTSTRING 4 + +HRESULT TimingCheck(DWORD dwTiming, LPSTR szSection, LPSTR szFile) +{ + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString(szSection, "Timing", "", szBuf, sizeof(szBuf), szFile); + if(*szBuf != '\0') + { + switch(dwTiming) + { + case T_PRE_DOWNLOAD: + if(lstrcmpi(szBuf, "pre download") == 0) + return(TRUE); + break; + + case T_POST_DOWNLOAD: + if(lstrcmpi(szBuf, "post download") == 0) + return(TRUE); + break; + + case T_PRE_XPCOM: + if(lstrcmpi(szBuf, "pre xpcom") == 0) + return(TRUE); + break; + + case T_POST_XPCOM: + if(lstrcmpi(szBuf, "post xpcom") == 0) + return(TRUE); + break; + + case T_PRE_SMARTUPDATE: + if(lstrcmpi(szBuf, "pre smartupdate") == 0) + return(TRUE); + break; + + case T_POST_SMARTUPDATE: + if(lstrcmpi(szBuf, "post smartupdate") == 0) + return(TRUE); + break; + + case T_PRE_LAUNCHAPP: + if(lstrcmpi(szBuf, "pre launchapp") == 0) + return(TRUE); + break; + + case T_POST_LAUNCHAPP: + if(lstrcmpi(szBuf, "post launchapp") == 0) + return(TRUE); + break; + + case T_PRE_ARCHIVE: + if(lstrcmpi(szBuf, "pre archive") == 0) + return(TRUE); + break; + + case T_POST_ARCHIVE: + if(lstrcmpi(szBuf, "post archive") == 0) + return(TRUE); + break; + + case T_DEPEND_REBOOT: + if(lstrcmpi(szBuf, "depend reboot") == 0) + return(TRUE); + break; + } + } + return(FALSE); +} + +HRESULT MeetCondition(LPSTR szSection) +{ + char szBuf[MAX_BUF_TINY]; + BOOL bResult = FALSE; // An undefined result is never met + BOOL bNegateTheResult = FALSE; + + char *pszCondition = szBuf; + + GetPrivateProfileString(szSection, "Condition", "", szBuf, sizeof(szBuf), szFileIniConfig); + + // If there is no condition then the "condition" is met, so we return TRUE. + if(pszCondition[0] == '\0') + return TRUE; + + // See if "not " is prepended to the condition. + if(strncmp(pszCondition, "not ", SIZEOFNOTSTRING) == 0) + { + bNegateTheResult = TRUE; + pszCondition = pszCondition + SIZEOFNOTSTRING; + } + + // The condition "DefaultApp" is met if the app which is running the install is the same as the + // the app identified by the Default AppID key in config.ini. + if(strcmp(pszCondition, "DefaultApp") == 0) + { + GetPrivateProfileString("General", "Default AppID", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(strcmp(szBuf, sgProduct.szAppID) == 0) + bResult = TRUE; + } + // The condition "RecaptureHPChecked" is met if the RecaptureHome checkbox in "Additional Options" dialog. + // has been checked by the user. + else if(strcmp(pszCondition, "RecaptureHPChecked") == 0) + { + bResult = diAdditionalOptions.bRecaptureHomepage; + } + + if(bNegateTheResult) + return !bResult; + + return bResult; +} + +char *BuildNumberedString(DWORD dwIndex, char *szInputStringPrefix, char *szInputString, char *szOutBuf, DWORD dwOutBufSize) +{ + if((szInputStringPrefix) && (*szInputStringPrefix != '\0')) + wsprintf(szOutBuf, "%s-%s%d", szInputStringPrefix, szInputString, dwIndex); + else + wsprintf(szOutBuf, "%s%d", szInputString, dwIndex); + + return(szOutBuf); +} + +void GetUserAgentShort(char *szUserAgent, char *szOutUAShort, DWORD dwOutUAShortSize) +{ + char *ptrFirstSpace = NULL; + + ZeroMemory(szOutUAShort, dwOutUAShortSize); + if((szUserAgent == NULL) || (*szUserAgent == '\0')) + return; + + ptrFirstSpace = strstr(szUserAgent, " "); + if(ptrFirstSpace != NULL) + { + *ptrFirstSpace = '\0'; + lstrcpy(szOutUAShort, szUserAgent); + *ptrFirstSpace = ' '; + } +} + +DWORD GetWinRegSubKeyProductPath(HKEY hkRootKey, char *szInKey, char *szReturnSubKey, DWORD dwReturnSubKeySize, char *szInSubSubKey, char *szInName, char *szCompare, char *szInCurrentVersion) +{ + char *szRv = NULL; + char szKey[MAX_BUF]; + char szBuf[MAX_BUF]; + HKEY hkHandle; + DWORD dwIndex; + DWORD dwBufSize; + DWORD dwTotalSubKeys; + DWORD dwTotalValues; + FILETIME ftLastWriteFileTime; + BOOL bFoundSubKey; + + bFoundSubKey = FALSE; + + if(RegOpenKeyEx(hkRootKey, szInKey, 0, KEY_READ, &hkHandle) != ERROR_SUCCESS) + { + *szReturnSubKey = '\0'; + return(0); + } + + dwTotalSubKeys = 0; + dwTotalValues = 0; + RegQueryInfoKey(hkHandle, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL); + for(dwIndex = 0; dwIndex < dwTotalSubKeys; dwIndex++) + { + dwBufSize = dwReturnSubKeySize; + if(RegEnumKeyEx(hkHandle, dwIndex, szReturnSubKey, &dwBufSize, NULL, NULL, NULL, &ftLastWriteFileTime) == ERROR_SUCCESS) + { + if( (*szInCurrentVersion != '\0') && (lstrcmpi(szInCurrentVersion, szReturnSubKey) != 0) ) + { + /* The key found is not the CurrentVersion (current UserAgent), so we can return it to be deleted. + * We don't want to return the SubKey that is the same as the CurrentVersion because it might + * have just been created by the current installation process. So deleting it would be a + * "Bad Thing" (TM). + * + * If it was not created by the current installation process, then it'll be left + * around which is better than deleting something we will need later. To make sure this case is + * not encountered, CleanupPreviousVersionRegKeys() should be called at the *end* of the + * installation process (at least after all the .xpi files have been processed). */ + if(szInSubSubKey && (*szInSubSubKey != '\0')) + wsprintf(szKey, "%s\\%s\\%s", szInKey, szReturnSubKey, szInSubSubKey); + else + wsprintf(szKey, "%s\\%s", szInKey, szReturnSubKey); + + GetWinReg(hkRootKey, szKey, szInName, szBuf, sizeof(szBuf)); + AppendBackSlash(szBuf, sizeof(szBuf)); + if(lstrcmpi(szBuf, szCompare) == 0) + { + bFoundSubKey = TRUE; + /* found one subkey. break out of the for() loop */ + break; + } + } + } + } + + RegCloseKey(hkHandle); + if(!bFoundSubKey) + *szReturnSubKey = '\0'; + return(dwTotalSubKeys); +} + +void CleanupPreviousVersionRegKeys(void) +{ + DWORD dwIndex = 0; + DWORD dwSubKeyCount; + char szBufTiny[MAX_BUF_TINY]; + char szKeyRoot[MAX_BUF_TINY]; + char szCurrentVersion[MAX_BUF_TINY]; + char szUAShort[MAX_BUF_TINY]; + char szRvSubKey[MAX_PATH + 1]; + char szPath[MAX_BUF]; + char szKey[MAX_BUF]; + char szCleanupProduct[MAX_BUF]; + HKEY hkeyRoot; + char szSubSubKey[] = "Main"; + char szName[] = "Install Directory"; + char szWRMSUninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + char szSection[] = "Cleanup Previous Product RegKeys"; + + lstrcpy(szPath, sgProduct.szPath); + if(*sgProduct.szSubPath != '\0') + { + AppendBackSlash(szPath, sizeof(szPath)); + lstrcat(szPath, sgProduct.szSubPath); + } + AppendBackSlash(szPath, sizeof(szPath)); + + wsprintf(szBufTiny, "Product Reg Key%d", dwIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey), szFileIniConfig); + + while(*szKey != '\0') + { + wsprintf(szBufTiny, "Reg Key Root%d",dwIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szKeyRoot, sizeof(szKeyRoot), szFileIniConfig); + hkeyRoot = ParseRootKey(szKeyRoot); + + wsprintf(szBufTiny, "Product Name%d", dwIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szCleanupProduct, sizeof(szCleanupProduct), szFileIniConfig); + // something is wrong, they didn't give a product name. + if(*szCleanupProduct == '\0') + return; + + wsprintf(szBufTiny, "Current Version%d", dwIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szCurrentVersion, sizeof(szCurrentVersion), szFileIniConfig); + + do + { + // if the current version is not found, we'll get null in szCurrentVersion and GetWinRegSubKeyProductPath() will do the right thing + dwSubKeyCount = GetWinRegSubKeyProductPath(hkeyRoot, szKey, szRvSubKey, sizeof(szRvSubKey), szSubSubKey, szName, szPath, szCurrentVersion); + + if(*szRvSubKey != '\0') + { + if(dwSubKeyCount > 1) + { + AppendBackSlash(szKey, sizeof(szKey)); + lstrcat(szKey, szRvSubKey); + } + DeleteWinRegKey(hkeyRoot, szKey, TRUE); + + GetUserAgentShort(szRvSubKey, szUAShort, sizeof(szUAShort)); + if(*szUAShort != '\0') + { + /* delete uninstall key that contains product name and its user agent in parenthesis, for + * example: + * Mozilla (0.8) + */ + wsprintf(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s (%s)", szCleanupProduct, szUAShort); + DeleteWinRegKey(hkeyRoot, szKey, TRUE); + + /* delete uninstall key that contains product name and its user agent not in parenthesis, + * for example: + * Mozilla 0.8 + */ + wsprintf(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s %s", szCleanupProduct, szUAShort); + DeleteWinRegKey(hkeyRoot, szKey, TRUE); + + /* We are not looking to delete just the product name key, for example: + * Mozilla + * + * because it might have just been created by the current installation process, so + * deleting this would be a "Bad Thing" (TM). Besides, we shouldn't be deleting the + * CurrentVersion key that might have just gotten created because GetWinRegSubKeyProductPath() + * will not return the CurrentVersion key. + */ + } + // the szKey was stepped on. Reget it. + wsprintf(szBufTiny, "Product Reg Key%d", dwIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey), szFileIniConfig); + } + } while (*szRvSubKey != '\0'); + wsprintf(szBufTiny, "Product Reg Key%d", ++dwIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey), szFileIniConfig); + } + +} + +void ProcessFileOps(DWORD dwTiming, char *szSectionPrefix) +{ + if(sgProduct.bInstallFiles) + { + ProcessUncompressFile(dwTiming, szSectionPrefix); + ProcessCreateDirectory(dwTiming, szSectionPrefix); + ProcessMoveFile(dwTiming, szSectionPrefix); + ProcessCopyFile(dwTiming, szSectionPrefix); + ProcessCopyFileSequential(dwTiming, szSectionPrefix); + ProcessSelfRegisterFile(dwTiming, szSectionPrefix); + ProcessDeleteFile(dwTiming, szSectionPrefix); + ProcessRemoveDirectory(dwTiming, szSectionPrefix); + if(!gbIgnoreRunAppX) + ProcessRunApp(dwTiming, szSectionPrefix); + } + + // This is the only operation we do if we are not installing files + ProcessWinReg(dwTiming, szSectionPrefix); + + if(sgProduct.bInstallFiles) + { + ProcessProgramFolder(dwTiming, szSectionPrefix); + ProcessSetVersionRegistry(dwTiming, szSectionPrefix); + } +} + +void ProcessFileOpsForSelectedComponents(DWORD dwTiming) +{ + DWORD dwIndex0; + siC *siCObject = NULL; + + dwIndex0 = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + /* Since the archive is selected, we need to process the file ops here */ + ProcessFileOps(dwTiming, siCObject->szReferenceName); + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } /* while(siCObject) */ +} + +void ProcessFileOpsForAll(DWORD dwTiming) +{ + ProcessFileOps(dwTiming, NULL); + if(sgProduct.bInstallFiles) + { + ProcessFileOpsForSelectedComponents(dwTiming); + ProcessCreateCustomFiles(dwTiming); + } +} + +int VerifyArchive(LPSTR szArchive) +{ + void *vZip; + int iTestRv; + + /* Check for the existance of the from (source) file */ + if(!FileExists(szArchive)) + return(FO_ERROR_FILE_NOT_FOUND); + + if((iTestRv = ZIP_OpenArchive(szArchive, &vZip)) == ZIP_OK) + { + /* 1st parameter should be NULL or it will fail */ + /* It indicates extract the entire archive */ + iTestRv = ZIP_TestArchive(vZip); + ZIP_CloseArchive(&vZip); + } + return(iTestRv); +} + +HRESULT ProcessSetVersionRegistry(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + BOOL bIsDirectory; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF_TINY]; + char szRegistryKey[MAX_BUF]; + char szPath[MAX_BUF]; + char szVersion[MAX_BUF_TINY]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Version Registry", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Registry Key", "", szRegistryKey, sizeof(szRegistryKey), szFileIniConfig); + while(*szRegistryKey != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + GetPrivateProfileString(szSection, "Version", "", szVersion, sizeof(szVersion), szFileIniConfig); + GetPrivateProfileString(szSection, "Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szPath, szBuf); + if(FileExists(szPath) & FILE_ATTRIBUTE_DIRECTORY) + bIsDirectory = TRUE; + else + bIsDirectory = FALSE; + + lstrcpy(szBuf, sgProduct.szPath); + if(sgProduct.szSubPath != '\0') + { + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, sgProduct.szSubPath); + } + + VR_CreateRegistry(VR_DEFAULT_PRODUCT_NAME, szBuf, NULL); + VR_Install(szRegistryKey, szPath, szVersion, bIsDirectory); + VR_Close(); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Version Registry", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Registry Key", "", szRegistryKey, sizeof(szRegistryKey), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT FileUncompress(LPSTR szFrom, LPSTR szTo) +{ + char szBuf[MAX_BUF]; + DWORD dwReturn; + void *vZip; + + dwReturn = FO_SUCCESS; + /* Check for the existance of the from (source) file */ + if(!FileExists(szFrom)) + return(FO_ERROR_FILE_NOT_FOUND); + + /* Check for the existance of the to (destination) path */ + dwReturn = FileExists(szTo); + if(dwReturn && !(dwReturn & FILE_ATTRIBUTE_DIRECTORY)) + { + /* found a file with the same name as the destination path */ + return(FO_ERROR_DESTINATION_CONFLICT); + } + else if(!dwReturn) + { + lstrcpy(szBuf, szTo); + AppendBackSlash(szBuf, sizeof(szBuf)); + CreateDirectoriesAll(szBuf, DO_NOT_ADD_TO_UNINSTALL_LOG); + } + + GetCurrentDirectory(MAX_BUF, szBuf); + if(SetCurrentDirectory(szTo) == FALSE) + return(FO_ERROR_CHANGE_DIR); + + if((dwReturn = ZIP_OpenArchive(szFrom, &vZip)) != ZIP_OK) + return(dwReturn); + + /* 1st parameter should be NULL or it will fail */ + /* It indicates extract the entire archive */ + dwReturn = ExtractDirEntries(NULL, vZip); + ZIP_CloseArchive(&vZip); + + if(SetCurrentDirectory(szBuf) == FALSE) + return(FO_ERROR_CHANGE_DIR); + + return(dwReturn); +} + +HRESULT ProcessXpcomFile() +{ + char szSource[MAX_BUF]; + char szDestination[MAX_BUF]; + DWORD dwErr; + + if((dwErr = FileUncompress(siCFXpcomFile.szSource, siCFXpcomFile.szDestination)) != FO_SUCCESS) + { + char szMsg[MAX_BUF]; + char szErrorString[MAX_BUF]; + + if(*siCFXpcomFile.szMessage != '\0') + ShowMessage(siCFXpcomFile.szMessage, FALSE); + + LogISProcessXpcomFile(LIS_FAILURE, dwErr); + GetPrivateProfileString("Strings", "Error File Uncompress", "", szErrorString, sizeof(szErrorString), szFileIniConfig); + wsprintf(szMsg, szErrorString, siCFXpcomFile.szSource, dwErr); + PrintError(szMsg, ERROR_CODE_HIDE); + return(dwErr); + } + LogISProcessXpcomFile(LIS_SUCCESS, dwErr); + + /* copy msvcrt.dll and msvcirt.dll to the bin of the Xpcom temp dir: + * (c:\temp\Xpcom.ns\bin) + * This is incase these files do not exist on the system */ + lstrcpy(szSource, siCFXpcomFile.szDestination); + AppendBackSlash(szSource, sizeof(szSource)); + lstrcat(szSource, "ms*.dll"); + + lstrcpy(szDestination, siCFXpcomFile.szDestination); + AppendBackSlash(szDestination, sizeof(szDestination)); + lstrcat(szDestination, "bin"); + + FileCopy(szSource, szDestination, TRUE, FALSE); + + return(FO_SUCCESS); +} + +void CleanupXpcomFile() +{ + /* If xpcom file is not used (gre is used instead), then + * just return */ + if(siCFXpcomFile.bStatus != STATUS_ENABLED) + return; + + if(siCFXpcomFile.bCleanup == TRUE) + DirectoryRemove(siCFXpcomFile.szDestination, TRUE); + + return; +} + +#define SETUP_STATE_REG_KEY "Software\\%s\\%s\\%s\\Setup" + +HRESULT CleanupArgsRegistry() +{ + char szKey[MAX_BUF]; + + wsprintf(szKey, SETUP_STATE_REG_KEY, sgProduct.szCompanyName, sgProduct.szProductNameInternal, + sgProduct.szUserAgent); + DeleteWinRegValue(HKEY_CURRENT_USER, szKey, "browserargs"); + return(FO_SUCCESS); +} + +HRESULT ProcessUncompressFile(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + BOOL bOnlyIfExists; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szSource[MAX_BUF]; + char szDestination[MAX_BUF]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Uncompress File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szSource, szBuf); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szDestination, szBuf); + GetPrivateProfileString(szSection, "Only If Exists", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + bOnlyIfExists = TRUE; + else + bOnlyIfExists = FALSE; + + if((!bOnlyIfExists) || (bOnlyIfExists && FileExists(szDestination))) + { + DWORD dwErr; + + GetPrivateProfileString(szSection, "Message", "", szBuf, sizeof(szBuf), szFileIniConfig); + ShowMessage(szBuf, TRUE); + if((dwErr = FileUncompress(szSource, szDestination)) != FO_SUCCESS) + { + char szMsg[MAX_BUF]; + char szErrorString[MAX_BUF]; + + ShowMessage(szBuf, FALSE); + GetPrivateProfileString("Strings", "Error File Uncompress", "", szErrorString, sizeof(szErrorString), szFileIniConfig); + wsprintf(szMsg, szErrorString, szSource, dwErr); + PrintError(szMsg, ERROR_CODE_HIDE); + return(dwErr); + } + + ShowMessage(szBuf, FALSE); + } + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Uncompress File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT FileMove(LPSTR szFrom, LPSTR szTo) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szFromDir[MAX_BUF]; + char szFromTemp[MAX_BUF]; + char szToTemp[MAX_BUF]; + char szBuf[MAX_BUF]; + BOOL bFound; + + /* From file path exists and To file path does not exist */ + if((FileExists(szFrom)) && (!FileExists(szTo))) + { + MoveFile(szFrom, szTo); + + /* log the file move command */ + wsprintf(szBuf, "%s to %s", szFrom, szTo); + UpdateInstallLog(KEY_MOVE_FILE, szBuf, FALSE); + + return(FO_SUCCESS); + } + /* From file path exists and To file path exists */ + if(FileExists(szFrom) && FileExists(szTo)) + { + /* Since the To file path exists, assume it to be a directory and proceed. */ + /* We don't care if it's a file. If it is a file, then config.ini needs to be */ + /* corrected to remove the file before attempting a MoveFile(). */ + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + ParsePath(szFrom, szBuf, sizeof(szBuf), FALSE, PP_FILENAME_ONLY); + lstrcat(szToTemp, szBuf); + MoveFile(szFrom, szToTemp); + + /* log the file move command */ + wsprintf(szBuf, "%s to %s", szFrom, szToTemp); + UpdateInstallLog(KEY_MOVE_FILE, szBuf, FALSE); + + return(FO_SUCCESS); + } + + ParsePath(szFrom, szFromDir, sizeof(szFromDir), FALSE, PP_PATH_ONLY); + + if((hFile = FindFirstFile(szFrom, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path string including filename for source */ + lstrcpy(szFromTemp, szFromDir); + AppendBackSlash(szFromTemp, sizeof(szFromTemp)); + lstrcat(szFromTemp, fdFile.cFileName); + + /* create full path string including filename for destination */ + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + lstrcat(szToTemp, fdFile.cFileName); + + MoveFile(szFromTemp, szToTemp); + + /* log the file move command */ + wsprintf(szBuf, "%s to %s", szFromTemp, szToTemp); + UpdateInstallLog(KEY_MOVE_FILE, szBuf, FALSE); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT ProcessMoveFile(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szSource[MAX_BUF]; + char szDestination[MAX_BUF]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Move File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szSource, szBuf); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szDestination, szBuf); + FileMove(szSource, szDestination); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Move File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT FileCopy(LPSTR szFrom, LPSTR szTo, BOOL bFailIfExists, BOOL bDnu) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szFromDir[MAX_BUF]; + char szFromTemp[MAX_BUF]; + char szToTemp[MAX_BUF]; + char szBuf[MAX_BUF]; + BOOL bFound; + + if(FileExists(szFrom)) + { + /* The file in the From file path exists */ + CreateDirectoriesAll(szTo, !bDnu); + ParsePath(szFrom, szBuf, sizeof(szBuf), FALSE, PP_FILENAME_ONLY); + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + lstrcat(szToTemp, szBuf); + CopyFile(szFrom, szToTemp, bFailIfExists); + wsprintf(szBuf, "%s to %s", szFrom, szToTemp); + UpdateInstallLog(KEY_COPY_FILE, szBuf, bDnu); + + return(FO_SUCCESS); + } + + /* The file in the From file path does not exist. Assume to contain wild args and */ + /* proceed acordingly. */ + ParsePath(szFrom, szFromDir, sizeof(szFromDir), FALSE, PP_PATH_ONLY); + + if((hFile = FindFirstFile(szFrom, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path string including filename for source */ + lstrcpy(szFromTemp, szFromDir); + AppendBackSlash(szFromTemp, sizeof(szFromTemp)); + lstrcat(szFromTemp, fdFile.cFileName); + + /* create full path string including filename for destination */ + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + lstrcat(szToTemp, fdFile.cFileName); + + CopyFile(szFromTemp, szToTemp, bFailIfExists); + + /* log the file copy command */ + wsprintf(szBuf, "%s to %s", szFromTemp, szToTemp); + UpdateInstallLog(KEY_COPY_FILE, szBuf, bDnu); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT FileCopySequential(LPSTR szSourcePath, LPSTR szDestPath, LPSTR szFilename) +{ + int iFilenameOnlyLen; + char szDestFullFilename[MAX_BUF]; + char szSourceFullFilename[MAX_BUF]; + char szSearchFilename[MAX_BUF]; + char szSearchDestFullFilename[MAX_BUF]; + char szFilenameOnly[MAX_BUF]; + char szFilenameExtensionOnly[MAX_BUF]; + char szNumber[MAX_BUF]; + long dwNumber; + long dwMaxNumber; + LPSTR szDotPtr; + HANDLE hFile; + WIN32_FIND_DATA fdFile; + BOOL bFound; + + lstrcpy(szSourceFullFilename, szSourcePath); + AppendBackSlash(szSourceFullFilename, sizeof(szSourceFullFilename)); + lstrcat(szSourceFullFilename, szFilename); + + if(FileExists(szSourceFullFilename)) + { + /* zero out the memory */ + ZeroMemory(szSearchFilename, sizeof(szSearchFilename)); + ZeroMemory(szFilenameOnly, sizeof(szFilenameOnly)); + ZeroMemory(szFilenameExtensionOnly, sizeof(szFilenameExtensionOnly)); + + /* parse for the filename w/o extention and also only the extension */ + if((szDotPtr = strstr(szFilename, ".")) != NULL) + { + *szDotPtr = '\0'; + lstrcpy(szSearchFilename, szFilename); + lstrcpy(szFilenameOnly, szFilename); + lstrcpy(szFilenameExtensionOnly, &szDotPtr[1]); + *szDotPtr = '.'; + } + else + { + lstrcpy(szFilenameOnly, szFilename); + lstrcpy(szSearchFilename, szFilename); + } + + /* create the wild arg filename to search for in the szDestPath */ + lstrcat(szSearchFilename, "*.*"); + lstrcpy(szSearchDestFullFilename, szDestPath); + AppendBackSlash(szSearchDestFullFilename, sizeof(szSearchDestFullFilename)); + lstrcat(szSearchDestFullFilename, szSearchFilename); + + iFilenameOnlyLen = lstrlen(szFilenameOnly); + dwNumber = 0; + dwMaxNumber = 0; + + /* find the largest numbered filename in the szDestPath */ + if((hFile = FindFirstFile(szSearchDestFullFilename, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + ZeroMemory(szNumber, sizeof(szNumber)); + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + lstrcpy(szNumber, &fdFile.cFileName[iFilenameOnlyLen]); + dwNumber = atoi(szNumber); + if(dwNumber > dwMaxNumber) + dwMaxNumber = dwNumber; + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + + lstrcpy(szDestFullFilename, szDestPath); + AppendBackSlash(szDestFullFilename, sizeof(szDestFullFilename)); + lstrcat(szDestFullFilename, szFilenameOnly); + itoa(dwMaxNumber + 1, szNumber, 10); + lstrcat(szDestFullFilename, szNumber); + + if(*szFilenameExtensionOnly != '\0') + { + lstrcat(szDestFullFilename, "."); + lstrcat(szDestFullFilename, szFilenameExtensionOnly); + } + + CopyFile(szSourceFullFilename, szDestFullFilename, TRUE); + } + + return(FO_SUCCESS); +} + +HRESULT ProcessCopyFile(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szSource[MAX_BUF]; + char szDestination[MAX_BUF]; + BOOL bFailIfExists; + BOOL bDnu; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Copy File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szSource, szBuf); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szDestination, szBuf); + + GetPrivateProfileString(szSection, "Do Not Uninstall", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + bDnu = TRUE; + else + bDnu = FALSE; + + GetPrivateProfileString(szSection, "Fail If Exists", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "TRUE") == 0) + bFailIfExists = TRUE; + else + bFailIfExists = FALSE; + + FileCopy(szSource, szDestination, bFailIfExists, bDnu); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Copy File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT ProcessCopyFileSequential(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szSource[MAX_BUF]; + char szDestination[MAX_BUF]; + char szFilename[MAX_BUF]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Copy File Sequential", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename), szFileIniConfig); + while(*szFilename != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szSource, szBuf); + + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szDestination, szBuf); + + FileCopySequential(szSource, szDestination, szFilename); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Copy File Sequential", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename), szFileIniConfig); + } + return(FO_SUCCESS); +} + +int RegisterDll32(char *File) +{ + FARPROC DllReg; + HINSTANCE hLib; + + if((hLib = LoadLibraryEx(File, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) != NULL) + { + if((DllReg = GetProcAddress(hLib, "DllRegisterServer")) != NULL) + DllReg(); + + FreeLibrary(hLib); + return(0); + } + + return(1); +} + + +HRESULT FileSelfRegister(LPSTR szFilename, LPSTR szDestination) +{ + char szFullFilenamePath[MAX_BUF]; + DWORD dwRv; + HANDLE hFile; + WIN32_FIND_DATA fdFile; + BOOL bFound; + + lstrcpy(szFullFilenamePath, szDestination); + AppendBackSlash(szFullFilenamePath, sizeof(szFullFilenamePath)); + lstrcat(szFullFilenamePath, szFilename); + + /* From file path exists and To file path does not exist */ + if(FileExists(szFullFilenamePath)) + { + RegisterDll32(szFullFilenamePath); + return(FO_SUCCESS); + } + + lstrcpy(szFullFilenamePath, szDestination); + AppendBackSlash(szFullFilenamePath, sizeof(szFullFilenamePath)); + lstrcat(szFullFilenamePath, szFilename); + + if((hFile = FindFirstFile(szFullFilenamePath, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path string including filename for destination */ + lstrcpy(szFullFilenamePath, szDestination); + AppendBackSlash(szFullFilenamePath, sizeof(szFullFilenamePath)); + lstrcat(szFullFilenamePath, fdFile.cFileName); + + if((dwRv = FileExists(szFullFilenamePath)) && (dwRv != FILE_ATTRIBUTE_DIRECTORY)) + RegisterDll32(szFullFilenamePath); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT ProcessSelfRegisterFile(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szFilename[MAX_BUF]; + char szDestination[MAX_BUF]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Self Register File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szDestination, szBuf); + GetPrivateProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename), szFileIniConfig); + FileSelfRegister(szFilename, szDestination); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Self Register File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +void UpdateInstallLog(LPSTR szKey, LPSTR szString, BOOL bDnu) +{ + FILE *fInstallLog; + char szBuf[MAX_BUF]; + char szFileInstallLog[MAX_BUF]; + + if(gbILUseTemp) + { + lstrcpy(szFileInstallLog, szTempDir); + AppendBackSlash(szFileInstallLog, sizeof(szFileInstallLog)); + } + else + { + lstrcpy(szFileInstallLog, sgProduct.szPath); + AppendBackSlash(szFileInstallLog, sizeof(szFileInstallLog)); + lstrcat(szFileInstallLog, sgProduct.szSubPath); + AppendBackSlash(szFileInstallLog, sizeof(szFileInstallLog)); + } + + CreateDirectoriesAll(szFileInstallLog, !bDnu); + lstrcat(szFileInstallLog, FILE_INSTALL_LOG); + + if((fInstallLog = fopen(szFileInstallLog, "a+t")) != NULL) + { + if(bDnu) + wsprintf(szBuf, " ** (*dnu*) %s%s\n", szKey, szString); + else + wsprintf(szBuf, " ** %s%s\n", szKey, szString); + + fwrite(szBuf, sizeof(char), lstrlen(szBuf), fInstallLog); + fclose(fInstallLog); + } +} + +void UpdateInstallStatusLog(LPSTR szString) +{ + FILE *fInstallLog; + char szFileInstallStatusLog[MAX_BUF]; + + if(gbILUseTemp) + { + lstrcpy(szFileInstallStatusLog, szTempDir); + AppendBackSlash(szFileInstallStatusLog, sizeof(szFileInstallStatusLog)); + } + else + { + lstrcpy(szFileInstallStatusLog, sgProduct.szPath); + AppendBackSlash(szFileInstallStatusLog, sizeof(szFileInstallStatusLog)); + lstrcat(szFileInstallStatusLog, sgProduct.szSubPath); + AppendBackSlash(szFileInstallStatusLog, sizeof(szFileInstallStatusLog)); + } + + CreateDirectoriesAll(szFileInstallStatusLog, DO_NOT_ADD_TO_UNINSTALL_LOG); + lstrcat(szFileInstallStatusLog, FILE_INSTALL_STATUS_LOG); + + if((fInstallLog = fopen(szFileInstallStatusLog, "a+t")) != NULL) + { + fwrite(szString, sizeof(char), lstrlen(szString), fInstallLog); + fclose(fInstallLog); + } +} + +void UpdateJSProxyInfo() +{ + FILE *fJSFile; + char szBuf[MAX_BUF]; + char szJSFile[MAX_BUF]; + + if((*diAdvancedSettings.szProxyServer != '\0') || (*diAdvancedSettings.szProxyPort != '\0')) + { + lstrcpy(szJSFile, sgProduct.szPath); + if(*sgProduct.szSubPath != '\0') + { + AppendBackSlash(szJSFile, sizeof(szJSFile)); + lstrcat(szJSFile, sgProduct.szSubPath); + } + AppendBackSlash(szJSFile, sizeof(szJSFile)); + lstrcat(szJSFile, "defaults\\pref\\"); + CreateDirectoriesAll(szJSFile, ADD_TO_UNINSTALL_LOG); + lstrcat(szJSFile, FILE_ALL_JS); + + if((fJSFile = fopen(szJSFile, "a+t")) != NULL) + { + ZeroMemory(szBuf, sizeof(szBuf)); + if(*diAdvancedSettings.szProxyServer != '\0') + { + if(diAdditionalOptions.dwUseProtocol == UP_FTP) + wsprintf(szBuf, + "pref(\"network.proxy.ftp\", \"%s\");\n", + diAdvancedSettings.szProxyServer); + else + wsprintf(szBuf, + "pref(\"network.proxy.http\", \"%s\");\n", + diAdvancedSettings.szProxyServer); + } + + if(*diAdvancedSettings.szProxyPort != '\0') + { + if(diAdditionalOptions.dwUseProtocol == UP_FTP) + wsprintf(szBuf, + "pref(\"network.proxy.ftp_port\", %s);\n", + diAdvancedSettings.szProxyPort); + else + wsprintf(szBuf, + "pref(\"network.proxy.http_port\", %s);\n", + diAdvancedSettings.szProxyPort); + } + + lstrcat(szBuf, "pref(\"network.proxy.type\", 1);\n"); + + fwrite(szBuf, sizeof(char), lstrlen(szBuf), fJSFile); + fclose(fJSFile); + } + } +} + +/* Function: DirHasWriteAccess() + * + * in: char *aPath - path to check for write access + * + * purpose: To determine if aPath has write access. It does this by + * simply creating the directory. If the path already exists + * then it will attempt to create a directory within the path. + * This function will cleanup all the directories it created. + */ +HRESULT DirHasWriteAccess(char *aPath) +{ + int i; + int iLen = lstrlen(aPath); + char szCreatePath[MAX_BUF]; + + ZeroMemory(szCreatePath, sizeof(szCreatePath)); + memcpy(szCreatePath, aPath, iLen); + for(i = 0; i < iLen; i++) + { + if((iLen > 1) && + ((i != 0) && ((aPath[i] == '\\') || (aPath[i] == '/'))) && + (!((aPath[0] == '\\') && (i == 1)) && !((aPath[1] == ':') && (i == 2)))) + { + szCreatePath[i] = '\0'; + if(FileExists(szCreatePath) == FALSE) + { + if(!CreateDirectory(szCreatePath, NULL)) + return(WIZ_ERROR_CREATE_DIRECTORY); + + RemoveDirectory(szCreatePath); + return(WIZ_OK); + } + szCreatePath[i] = aPath[i]; + } + } + + /* All the dirs exist, so no test has been done. Create a test dir within + * aPath to verify if we have write access or not */ + AppendBackSlash(szCreatePath, sizeof(szCreatePath)); + lstrcat(szCreatePath, "testdir"); + if(!CreateDirectory(szCreatePath, NULL)) + return(WIZ_ERROR_CREATE_DIRECTORY); + + RemoveDirectory(szCreatePath); + return(WIZ_OK); +} + +HRESULT CreateDirectoriesAll(char* szPath, BOOL bLogForUninstall) +{ + int i; + int iLen = lstrlen(szPath); + char szCreatePath[MAX_BUF]; + HRESULT hrResult = WIZ_OK; + + ZeroMemory(szCreatePath, MAX_BUF); + memcpy(szCreatePath, szPath, iLen); + for(i = 0; i < iLen; i++) + { + if((iLen > 1) && + ((i != 0) && ((szPath[i] == '\\') || (szPath[i] == '/'))) && + (!((szPath[0] == '\\') && (i == 1)) && !((szPath[1] == ':') && (i == 2)))) + { + szCreatePath[i] = '\0'; + if(FileExists(szCreatePath) == FALSE) + { + if(!CreateDirectory(szCreatePath, NULL)) + return(WIZ_ERROR_CREATE_DIRECTORY); + + if(bLogForUninstall) + UpdateInstallLog(KEY_CREATE_FOLDER, szCreatePath, FALSE); + } + szCreatePath[i] = szPath[i]; + } + } + return(hrResult); +} + +HRESULT ProcessCreateDirectory(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szDestination[MAX_BUF]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Create Directory", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szDestination, szBuf); + AppendBackSlash(szDestination, sizeof(szDestination)); + CreateDirectoriesAll(szDestination, ADD_TO_UNINSTALL_LOG); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Create Directory", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT FileDelete(LPSTR szDestination) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szBuf[MAX_BUF]; + char szPathOnly[MAX_BUF]; + BOOL bFound; + + if(FileExists(szDestination)) + { + /* The file in the From file path exists */ + DeleteFile(szDestination); + return(FO_SUCCESS); + } + + /* The file in the From file path does not exist. Assume to contain wild args and */ + /* proceed acordingly. */ + ParsePath(szDestination, szPathOnly, sizeof(szPathOnly), FALSE, PP_PATH_ONLY); + + if((hFile = FindFirstFile(szDestination, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if(!(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + lstrcpy(szBuf, szPathOnly); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, fdFile.cFileName); + + DeleteFile(szBuf); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT ProcessDeleteFile(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szDestination[MAX_BUF]; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Delete File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szDestination, szBuf); + FileDelete(szDestination); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Delete File", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT DirectoryRemove(LPSTR szDestination, BOOL bRemoveSubdirs) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szDestTemp[MAX_BUF]; + BOOL bFound; + + if(!FileExists(szDestination)) + return(FO_SUCCESS); + + if(bRemoveSubdirs == TRUE) + { + lstrcpy(szDestTemp, szDestination); + AppendBackSlash(szDestTemp, sizeof(szDestTemp)); + lstrcat(szDestTemp, "*"); + + bFound = TRUE; + hFile = FindFirstFile(szDestTemp, &fdFile); + while((hFile != INVALID_HANDLE_VALUE) && (bFound == TRUE)) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path */ + lstrcpy(szDestTemp, szDestination); + AppendBackSlash(szDestTemp, sizeof(szDestTemp)); + lstrcat(szDestTemp, fdFile.cFileName); + + if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + DirectoryRemove(szDestTemp, bRemoveSubdirs); + } + else + { + DeleteFile(szDestTemp); + } + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + } + + RemoveDirectory(szDestination); + return(FO_SUCCESS); +} + +HRESULT ProcessRemoveDirectory(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szDestination[MAX_BUF]; + BOOL bRemoveSubdirs; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Remove Directory", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szDestination, szBuf); + GetPrivateProfileString(szSection, "Remove subdirs", "", szBuf, sizeof(szBuf), szFileIniConfig); + bRemoveSubdirs = FALSE; + if(lstrcmpi(szBuf, "TRUE") == 0) + bRemoveSubdirs = TRUE; + + DirectoryRemove(szDestination, bRemoveSubdirs); + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Remove Directory", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT ProcessRunApp(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex; + char szBuf[MAX_BUF]; + char szSection[MAX_BUF]; + char szTarget[MAX_BUF]; + char szParameters[MAX_BUF]; + char szWorkingDir[MAX_BUF]; + BOOL bRunApp; + BOOL bWait; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "RunApp", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Target", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig)) + { + DecryptString(szTarget, szBuf); + GetPrivateProfileString(szSection, "Parameters", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szParameters, szBuf); + + bRunApp = MeetCondition(szSection); + + GetPrivateProfileString(szSection, "WorkingDir", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szWorkingDir, szBuf); + + GetPrivateProfileString(szSection, "Wait", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(lstrcmpi(szBuf, "FALSE") == 0) + bWait = FALSE; + else + bWait = TRUE; + + if ((bRunApp == TRUE) && FileExists(szTarget)) + { + if((dwTiming == T_DEPEND_REBOOT) && (NeedReboot() == TRUE)) + { + lstrcat(szTarget, " "); + lstrcat(szTarget, szParameters); + SetWinReg(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", + TRUE, + "Netscape", + TRUE, + REG_SZ, + szTarget, + lstrlen(szTarget), + FALSE, + FALSE); + } + else + { + GetPrivateProfileString(szSection, "Message", "", szBuf, sizeof(szBuf), szFileIniConfig); + if ( szBuf[0] != '\0' ) + ShowMessage(szBuf, TRUE); + WinSpawn(szTarget, szParameters, szWorkingDir, SW_SHOWNORMAL, bWait); + if ( szBuf[0] != '\0' ) + ShowMessage(szBuf, FALSE); + } + } + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "RunApp", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Target", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +DWORD ParseRestrictedAccessKey(LPSTR szKey) +{ + DWORD dwKey; + + if(lstrcmpi(szKey, "ONLY_RESTRICTED") == 0) + dwKey = RA_ONLY_RESTRICTED; + else if(lstrcmpi(szKey, "ONLY_NONRESTRICTED") == 0) + dwKey = RA_ONLY_NONRESTRICTED; + else + dwKey = RA_IGNORE; + + return(dwKey); +} + +/* Function: GetKeyInfo() + * in: LPSTR aKey, DWORD aOutBufSize, DWORD aInfoType. + * out: LPSTR aOut. + * purpose: To parse a full windows registry key path format: + * [root key]\[subkey] + * It can return either the root key or the subkey depending on + * what's being requested. + */ +LPSTR GetKeyInfo(LPSTR aKey, LPSTR aOut, DWORD aOutBufSize, DWORD aInfoType) +{ + LPSTR keyCopy = NULL; + LPSTR key = NULL; + + *aOut = '\0'; + if((keyCopy = strdup(aKey)) == NULL) + return NULL; + + switch(aInfoType) + { + case KEY_INFO_ROOT: + key = MozStrChar(keyCopy, '\\'); + if(key == keyCopy) + { + // root key not found, return NULL + free(keyCopy); + return NULL; + } + else if(key) + // found '\\' which indicates the end of the root key + // and beginning of the subkey. + *key = '\0'; + + if(MozCopyStr(keyCopy, aOut, aOutBufSize)) + { + free(keyCopy); + return NULL; + } + break; + + case KEY_INFO_SUBKEY: + key = MozStrChar(keyCopy, '\\'); + if(key != NULL) + ++key; + + if(!key) + // No subkey found. Assume the entire string is the subkey. + key = keyCopy; + + if(MozCopyStr(key, aOut, aOutBufSize)) + { + free(keyCopy); + return NULL; + } + break; + } + + free(keyCopy); + return(aOut); +} + +HKEY ParseRootKey(LPSTR szRootKey) +{ + HKEY hkRootKey; + + if(lstrcmpi(szRootKey, "HKEY_CURRENT_CONFIG") == 0) + hkRootKey = HKEY_CURRENT_CONFIG; + else if(lstrcmpi(szRootKey, "HKEY_CURRENT_USER") == 0) + hkRootKey = HKEY_CURRENT_USER; + else if(lstrcmpi(szRootKey, "HKEY_LOCAL_MACHINE") == 0) + hkRootKey = HKEY_LOCAL_MACHINE; + else if(lstrcmpi(szRootKey, "HKEY_USERS") == 0) + hkRootKey = HKEY_USERS; + else if(lstrcmpi(szRootKey, "HKEY_PERFORMANCE_DATA") == 0) + hkRootKey = HKEY_PERFORMANCE_DATA; + else if(lstrcmpi(szRootKey, "HKEY_DYN_DATA") == 0) + hkRootKey = HKEY_DYN_DATA; + else /* HKEY_CLASSES_ROOT */ + hkRootKey = HKEY_CLASSES_ROOT; + + return(hkRootKey); +} + +char *ParseRootKeyString(HKEY hkKey, LPSTR szRootKey, DWORD dwRootKeyBufSize) +{ + if(!szRootKey) + return(NULL); + + ZeroMemory(szRootKey, dwRootKeyBufSize); + if((hkKey == HKEY_CURRENT_CONFIG) && + ((long)dwRootKeyBufSize > lstrlen("HKEY_CURRENT_CONFIG"))) + lstrcpy(szRootKey, "HKEY_CURRENT_CONFIG"); + else if((hkKey == HKEY_CURRENT_USER) && + ((long)dwRootKeyBufSize > lstrlen("HKEY_CURRENT_USER"))) + lstrcpy(szRootKey, "HKEY_CURRENT_USER"); + else if((hkKey == HKEY_LOCAL_MACHINE) && + ((long)dwRootKeyBufSize > lstrlen("HKEY_LOCAL_MACHINE"))) + lstrcpy(szRootKey, "HKEY_LOCAL_MACHINE"); + else if((hkKey == HKEY_USERS) && + ((long)dwRootKeyBufSize > lstrlen("HKEY_USERS"))) + lstrcpy(szRootKey, "HKEY_USERS"); + else if((hkKey == HKEY_PERFORMANCE_DATA) && + ((long)dwRootKeyBufSize > lstrlen("HKEY_PERFORMANCE_DATA"))) + lstrcpy(szRootKey, "HKEY_PERFORMANCE_DATA"); + else if((hkKey == HKEY_DYN_DATA) && + ((long)dwRootKeyBufSize > lstrlen("HKEY_DYN_DATA"))) + lstrcpy(szRootKey, "HKEY_DYN_DATA"); + else if((long)dwRootKeyBufSize > lstrlen("HKEY_CLASSES_ROOT")) + lstrcpy(szRootKey, "HKEY_CLASSES_ROOT"); + + return(szRootKey); +} + +BOOL ParseRegType(LPSTR szType, DWORD *dwType) +{ + BOOL bSZ; + + if(lstrcmpi(szType, "REG_SZ") == 0) + { + /* Unicode NULL terminated string */ + *dwType = REG_SZ; + bSZ = TRUE; + } + else if(lstrcmpi(szType, "REG_EXPAND_SZ") == 0) + { + /* Unicode NULL terminated string + * (with environment variable references) */ + *dwType = REG_EXPAND_SZ; + bSZ = TRUE; + } + else if(lstrcmpi(szType, "REG_BINARY") == 0) + { + /* Free form binary */ + *dwType = REG_BINARY; + bSZ = FALSE; + } + else if(lstrcmpi(szType, "REG_DWORD") == 0) + { + /* 32bit number */ + *dwType = REG_DWORD; + bSZ = FALSE; + } + else if(lstrcmpi(szType, "REG_DWORD_LITTLE_ENDIAN") == 0) + { + /* 32bit number + * (same as REG_DWORD) */ + *dwType = REG_DWORD_LITTLE_ENDIAN; + bSZ = FALSE; + } + else if(lstrcmpi(szType, "REG_DWORD_BIG_ENDIAN") == 0) + { + /* 32bit number */ + *dwType = REG_DWORD_BIG_ENDIAN; + bSZ = FALSE; + } + else if(lstrcmpi(szType, "REG_LINK") == 0) + { + /* Symbolic link (unicode) */ + *dwType = REG_LINK; + bSZ = TRUE; + } + else if(lstrcmpi(szType, "REG_MULTI_SZ") == 0) + { + /* Multiple Unicode strings */ + *dwType = REG_MULTI_SZ; + bSZ = TRUE; + } + else /* Default is REG_NONE */ + { + /* no value type */ + *dwType = REG_NONE; + bSZ = TRUE; + } + + return(bSZ); +} + +BOOL WinRegKeyExists(HKEY hkRootKey, LPSTR szKey) +{ + HKEY hkResult; + DWORD dwErr; + BOOL bKeyExists = FALSE; + + if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS) + { + bKeyExists = TRUE; + RegCloseKey(hkResult); + } + + return(bKeyExists); +} + +BOOL WinRegNameExists(HKEY hkRootKey, LPSTR szKey, LPSTR szName) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwSize; + char szBuf[MAX_BUF]; + BOOL bNameExists = FALSE; + + ZeroMemory(szBuf, sizeof(szBuf)); + if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS) + { + dwSize = sizeof(szBuf); + dwErr = RegQueryValueEx(hkResult, szName, 0, NULL, szBuf, &dwSize); + + if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS)) + bNameExists = TRUE; + + RegCloseKey(hkResult); + } + + return(bNameExists); +} + +void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwTotalSubKeys; + DWORD dwTotalValues; + DWORD dwSubKeySize; + FILETIME ftLastWriteFileTime; + char szSubKey[MAX_BUF_TINY]; + char szNewKey[MAX_BUF]; + long lRv; + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_QUERY_VALUE, &hkResult); + if(dwErr == ERROR_SUCCESS) + { + dwTotalSubKeys = 0; + dwTotalValues = 0; + RegQueryInfoKey(hkResult, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL); + RegCloseKey(hkResult); + + if(((dwTotalSubKeys == 0) && (dwTotalValues == 0)) || bAbsoluteDelete) + { + if(dwTotalSubKeys && bAbsoluteDelete) + { + do + { + dwSubKeySize = sizeof(szSubKey); + lRv = 0; + if(RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS) + { + if((lRv = RegEnumKeyEx(hkResult, 0, szSubKey, &dwSubKeySize, NULL, NULL, NULL, &ftLastWriteFileTime)) == ERROR_SUCCESS) + { + RegCloseKey(hkResult); + lstrcpy(szNewKey, szKey); + AppendBackSlash(szNewKey, sizeof(szNewKey)); + lstrcat(szNewKey, szSubKey); + DeleteWinRegKey(hkRootKey, szNewKey, bAbsoluteDelete); + } + else + RegCloseKey(hkResult); + } + } while(lRv != ERROR_NO_MORE_ITEMS); + } + + dwErr = RegDeleteKey(hkRootKey, szKey); + } + } +} + +void DeleteWinRegValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName) +{ + HKEY hkResult; + DWORD dwErr; + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult); + if(dwErr == ERROR_SUCCESS) + { + if(*szName == '\0') + dwErr = RegDeleteValue(hkResult, NULL); + else + dwErr = RegDeleteValue(hkResult, szName); + + RegCloseKey(hkResult); + } +} + +DWORD GetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, LPSTR szReturnValue, DWORD dwReturnValueSize) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwSize; + DWORD dwType; + char szBuf[MAX_BUF]; + + ZeroMemory(szBuf, sizeof(szBuf)); + ZeroMemory(szReturnValue, dwReturnValueSize); + + if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS) + { + dwSize = sizeof(szBuf); + dwErr = RegQueryValueEx(hkResult, szName, 0, &dwType, szBuf, &dwSize); + + if((dwType == REG_MULTI_SZ) && (*szBuf != '\0')) + { + DWORD dwCpSize; + + dwCpSize = dwReturnValueSize < dwSize ? (dwReturnValueSize - 1) : dwSize; + memcpy(szReturnValue, szBuf, dwCpSize); + } + else if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS)) + ExpandEnvironmentStrings(szBuf, szReturnValue, dwReturnValueSize); + else + *szReturnValue = '\0'; + + RegCloseKey(hkResult); + } + + return(dwType); +} + +LONG _CreateWinRegKey(HKEY hkRootKey, + LPSTR szKey, + BOOL bLogForUninstall, + BOOL bDnu, + BOOL bForceCreate) +{ + HKEY hkResult; + LONG err = ERROR_SUCCESS; + DWORD dwDisp; + char szBuf[MAX_BUF]; + char szRootKey[MAX_BUF_TINY]; + + if(!WinRegKeyExists(hkRootKey, szKey) || bForceCreate) + { + err = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp); + /* log the win reg command */ + if(((err == ERROR_SUCCESS) && + bLogForUninstall && + ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey))) || bForceCreate) + { + wsprintf(szBuf, "%s\\%s []", szRootKey, szKey); + UpdateInstallLog(KEY_CREATE_REG_KEY, szBuf, bDnu); + } + RegCloseKey(hkResult); + } + + return(err); +} + +LONG CreateWinRegKey(HKEY hkRootKey, + LPSTR szKey, + BOOL bLogForUninstall, + BOOL bDnu) +{ + char szTempKeyPath[MAX_BUF]; + char saveChar; + LPSTR pointerToBackslashChar = NULL; + LPSTR pointerToStrWalker = NULL; + + if(MozCopyStr(szKey, szTempKeyPath, sizeof(szTempKeyPath))) + return(ERROR_BUFFER_OVERFLOW); + + // Make sure that we create all the keys (starting from the root) that + // do not exist. We need to do this in order to log it for uninstall. + // If this was not done, then only the last key in the key path would be + // uninstalled. + RemoveBackSlash(szTempKeyPath); + pointerToStrWalker = szTempKeyPath; + while((pointerToBackslashChar = strstr(pointerToStrWalker, "\\")) != NULL) + { + saveChar = *pointerToBackslashChar; + *pointerToBackslashChar = '\0'; + // Log the registry only if it was created here + _CreateWinRegKey(hkRootKey, szTempKeyPath, bLogForUninstall, bDnu, DO_NOT_FORCE_ADD_TO_UNINSTALL_LOG); + *pointerToBackslashChar = saveChar; + pointerToStrWalker = &pointerToBackslashChar[1]; + } + + // Log the registry regardless if it was created here or not. If it was + // explicitly listed to be created, we should log for uninstall. This + // covers the case where the user deletes the uninstall log file from a + // previous build where a new install would not log the creation because + // it already exists. + return(_CreateWinRegKey(hkRootKey, szKey, bLogForUninstall, bDnu, FORCE_ADD_TO_UNINSTALL_LOG)); +} + +void SetWinReg(HKEY hkRootKey, + LPSTR szKey, + BOOL bOverwriteKey, + LPSTR szName, + BOOL bOverwriteName, + DWORD dwType, + LPBYTE lpbData, + DWORD dwSize, + BOOL bLogForUninstall, + BOOL bDnu) +{ + HKEY hkResult; + DWORD dwErr; + BOOL bNameExists; + char szBuf[MAX_BUF]; + char szRootKey[MAX_BUF_TINY]; + + /* We don't care if it failed or not because it could already exist. */ + CreateWinRegKey(hkRootKey, szKey, bLogForUninstall, bDnu); + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult); + if(dwErr == ERROR_SUCCESS) + { + bNameExists = WinRegNameExists(hkRootKey, szKey, szName); + if((bNameExists == FALSE) || + ((bNameExists == TRUE) && (bOverwriteName == TRUE))) + { + dwErr = RegSetValueEx(hkResult, szName, 0, dwType, lpbData, dwSize); + /* log the win reg command */ + if(bLogForUninstall && + ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey))) + { + if(ParseRegType(szBuf, &dwType)) + { + wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName); + UpdateInstallLog(KEY_STORE_REG_STRING, szBuf, bDnu); + } + else + { + wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName); + UpdateInstallLog(KEY_STORE_REG_NUMBER, szBuf, bDnu); + } + } + } + + RegCloseKey(hkResult); + } +} + +/* Name: AppendWinRegString + * + * Arguments: + * + * HKEY hkRootKey -- root key, e.g., HKEY_LOCAL_MACHINE + * LPSTR szKey -- subkey + * LPSTR szName -- value name + * DWORD dwType -- value type, should be REG_SZ + * LPBYTE lpbData -- value data + * BYTE delimiter -- e.g., ':'. If 0, then don't apply delimiter + * DWORD dwSize -- size of the value data + * BOOL bLogForUninstall -- if true, update install log + * BOOL bDnu -- what to update the install log with + * + * Description: + * + * This function should be called to append a string (REG_SZ) to the + * string already stored in the specified key. If the key does not + * exist, then simply store the key (ignoring the delimiter). If the + * key does exist, read the current value, append the delimiter (if + * not zero), and append the data passed in. + * + * Return Value: void + * + * Original Code: Clone of SetWinReg(), syd@netscape.com 6/11/2001 + * + */ + +void AppendWinReg(HKEY hkRootKey, + LPSTR szKey, + LPSTR szName, + DWORD dwType, + LPBYTE lpbData, + BYTE delimiter, + DWORD dwSize, + BOOL bLogForUninstall, + BOOL bDnu) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwDisp; + BOOL bKeyExists; + BOOL bNameExists; + char szBuf[MAX_BUF]; + char szRootKey[MAX_BUF_TINY]; + + bKeyExists = WinRegKeyExists(hkRootKey, szKey); + bNameExists = WinRegNameExists(hkRootKey, szKey, szName); + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult); + + if (dwType != REG_SZ) // this function is void. How do we pass errors to caller? + return; + + if(dwErr != ERROR_SUCCESS) + { + dwErr = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp); + /* log the win reg command */ + if(bLogForUninstall && + ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey))) + { + wsprintf(szBuf, "%s\\%s []", szRootKey, szKey); + UpdateInstallLog(KEY_CREATE_REG_KEY, szBuf, bDnu); + } + } + + if(dwErr == ERROR_SUCCESS) + { + if((bNameExists == FALSE)) + { + /* first time, so just write it, ignoring the delimiter */ + + dwErr = RegSetValueEx(hkResult, szName, 0, dwType, lpbData, dwSize); + /* log the win reg command */ + if(bLogForUninstall && + ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey))) + { + if(ParseRegType(szBuf, &dwType)) + { + wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName); + UpdateInstallLog(KEY_STORE_REG_STRING, szBuf, bDnu); + } + else + { + wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName); + UpdateInstallLog(KEY_STORE_REG_NUMBER, szBuf, bDnu); + } + } + } else { + /* already exists, so read the prrevious value, append the delimiter if + specified, append the new value, and rewrite the key */ + + GetWinReg(hkRootKey, szKey, szName, szBuf, sizeof(szBuf)); // func is void, assume success + if ( delimiter != 0 ) { + char delim[ 2 ]; + delim[0] = delimiter; + delim[1] = '\0'; + strcat( szBuf, delim ); + } + strcat( szBuf, lpbData ); + RegCloseKey(hkResult); + SetWinReg(hkRootKey, szKey, TRUE, szName, TRUE, dwType, szBuf, strlen( szBuf ) + 1, bLogForUninstall, bDnu); + return; + } + + RegCloseKey(hkResult); + } +} + +HRESULT ProcessWinReg(DWORD dwTiming, char *szSectionPrefix) +{ + char szBuf[MAX_BUF]; + char szKey[MAX_BUF]; + char szName[MAX_BUF]; + char szShortName[MAX_BUF]; + char szValue[MAX_BUF]; + char szDecrypt[MAX_BUF]; + char szOverwriteKey[MAX_BUF]; + char szOverwriteName[MAX_BUF]; + char szSection[MAX_BUF]; + HKEY hRootKey; + BOOL bDone; + BOOL bDnu; + BOOL bOverwriteKey; + BOOL bOverwriteName; + BOOL bOSDetected; + DWORD dwIndex; + DWORD dwNameIndex = 1; + DWORD dwType; + DWORD dwSize; + const DWORD dwUpperLimit = 100; + __int64 iiNum; + + dwIndex = 0; + BuildNumberedString(dwIndex, szSectionPrefix, "Windows Registry", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Root Key", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection, szFileIniConfig) && MeetCondition(szSection)) + { + hRootKey = ParseRootKey(szBuf); + + GetPrivateProfileString(szSection, "Key", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString(szSection, "Decrypt Key", "", szDecrypt, sizeof(szDecrypt), szFileIniConfig); + GetPrivateProfileString(szSection, "Overwrite Key", "", szOverwriteKey, sizeof(szOverwriteKey), szFileIniConfig); + ZeroMemory(szKey, sizeof(szKey)); + if(lstrcmpi(szDecrypt, "TRUE") == 0) + DecryptString(szKey, szBuf); + else + lstrcpy(szKey, szBuf); + + if(lstrcmpi(szOverwriteKey, "FALSE") == 0) + bOverwriteKey = FALSE; + else + bOverwriteKey = TRUE; + + GetPrivateProfileString(szSection, "Name", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString(szSection, "Decrypt Name", "", szDecrypt, sizeof(szDecrypt), szFileIniConfig); + GetPrivateProfileString(szSection, "Overwrite Name", "", szOverwriteName, sizeof(szOverwriteName), szFileIniConfig); + ZeroMemory(szName, sizeof(szName)); + if(lstrcmpi(szDecrypt, "TRUE") == 0) + DecryptString(szName, szBuf); + else + lstrcpy(szName, szBuf); + + if(lstrcmpi(szOverwriteName, "ENUMERATE") == 0) + { + bOverwriteName = FALSE; + lstrcpy(szShortName, szName); + wsprintf(szName, "%s%02d", szShortName, dwNameIndex++); + + bDone = FALSE; + while(!bDone && (dwNameIndex < dwUpperLimit)) + { + if(WinRegNameExists(hRootKey, szKey, szName)) + { + GetWinReg(hRootKey, szKey, szName, szBuf, sizeof(szBuf)); + if(lstrcmpi(szBuf, sgProduct.szAppPath) == 0) + bDone = TRUE; + else + wsprintf(szName, "%s%02d", szShortName, dwNameIndex++); + } + else + bDone = TRUE; + } + if(dwNameIndex >= dwUpperLimit) + return FO_ERROR_INCR_EXCEEDS_LIMIT; + } + else if(lstrcmpi(szOverwriteName, "FALSE") == 0) + bOverwriteName = FALSE; + else + bOverwriteName = TRUE; + + GetPrivateProfileString(szSection, "Name Value", "", szBuf, sizeof(szBuf), szFileIniConfig); + GetPrivateProfileString(szSection, "Decrypt Name Value", "", szDecrypt, sizeof(szDecrypt), szFileIniConfig); + ZeroMemory(szValue, sizeof(szValue)); + if(lstrcmpi(szDecrypt, "TRUE") == 0) + DecryptString(szValue, szBuf); + else + lstrcpy(szValue, szBuf); + + GetPrivateProfileString(szSection, "Size", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(*szBuf != '\0') + dwSize = atoi(szBuf); + else + dwSize = 0; + + GetPrivateProfileString(szSection, + "Do Not Uninstall", + "", + szBuf, + sizeof(szBuf), + szFileIniConfig); + + if(lstrcmpi(szBuf, "TRUE") == 0) + bDnu = TRUE; + else + bDnu = FALSE; + + /* Read the OS key to see if there are restrictions on which OS to + * the Windows registry key for */ + GetPrivateProfileString(szSection, + "OS", + "", + szBuf, + sizeof(szBuf), + szFileIniConfig); + /* If there is no OS key value set, then assume all OS is valid. + * If there are any, then compare against the global OS value to + * make sure there's a match. */ + bOSDetected = TRUE; + if( (*szBuf != '\0') && ((gSystemInfo.dwOSType & ParseOSType(szBuf)) == 0) ) + bOSDetected = FALSE; + + if(bOSDetected) + { + ZeroMemory(szBuf, sizeof(szBuf)); + GetPrivateProfileString(szSection, + "Type", + "", + szBuf, + sizeof(szBuf), + szFileIniConfig); + + if(ParseRegType(szBuf, &dwType)) + { + /* create/set windows registry key here (string value)! */ + SetWinReg(hRootKey, szKey, bOverwriteKey, szName, bOverwriteName, + dwType, (CONST LPBYTE)szValue, lstrlen(szValue), TRUE, bDnu); + } + else + { + iiNum = _atoi64(szValue); + /* create/set windows registry key here (binary/dword value)! */ + SetWinReg(hRootKey, szKey, bOverwriteKey, szName, bOverwriteName, + dwType, (CONST LPBYTE)&iiNum, dwSize, TRUE, bDnu); + } + } + } + + ++dwIndex; + BuildNumberedString(dwIndex, szSectionPrefix, "Windows Registry", szSection, sizeof(szSection)); + GetPrivateProfileString(szSection, "Root Key", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT ProcessProgramFolder(DWORD dwTiming, char *szSectionPrefix) +{ + DWORD dwIndex0; + DWORD dwIndex1; + DWORD dwIconId; + DWORD dwRestrictedAccess; + char szIndex1[MAX_BUF]; + char szBuf[MAX_BUF]; + char szSection0[MAX_BUF]; + char szSection1[MAX_BUF]; + char szProgramFolder[MAX_BUF]; + char szFile[MAX_BUF]; + char szArguments[MAX_BUF]; + char szWorkingDir[MAX_BUF]; + char szDescription[MAX_BUF]; + char szIconPath[MAX_BUF]; + + dwIndex0 = 0; + BuildNumberedString(dwIndex0, szSectionPrefix, "Program Folder", szSection0, sizeof(szSection0)); + GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + if(TimingCheck(dwTiming, szSection0, szFileIniConfig)) + { + DecryptString(szProgramFolder, szBuf); + + dwIndex1 = 0; + itoa(dwIndex1, szIndex1, 10); + lstrcpy(szSection1, szSection0); + lstrcat(szSection1, "-Shortcut"); + lstrcat(szSection1, szIndex1); + GetPrivateProfileString(szSection1, "File", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + DecryptString(szFile, szBuf); + GetPrivateProfileString(szSection1, "Arguments", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szArguments, szBuf); + GetPrivateProfileString(szSection1, "Working Dir", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szWorkingDir, szBuf); + GetPrivateProfileString(szSection1, "Description", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szDescription, szBuf); + GetPrivateProfileString(szSection1, "Icon Path", "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szIconPath, szBuf); + GetPrivateProfileString(szSection1, "Icon Id", "", szBuf, sizeof(szBuf), szFileIniConfig); + if(*szBuf != '\0') + dwIconId = atol(szBuf); + else + dwIconId = 0; + + GetPrivateProfileString(szSection1, "Restricted Access", "", szBuf, sizeof(szBuf), szFileIniConfig); + dwRestrictedAccess = ParseRestrictedAccessKey(szBuf); + if((dwRestrictedAccess == RA_IGNORE) || + ((dwRestrictedAccess == RA_ONLY_RESTRICTED) && gbRestrictedAccess) || + ((dwRestrictedAccess == RA_ONLY_NONRESTRICTED) && !gbRestrictedAccess)) + { + CreateALink(szFile, szProgramFolder, szDescription, szWorkingDir, szArguments, szIconPath, dwIconId); + lstrcpy(szBuf, szProgramFolder); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, szDescription); + UpdateInstallLog(KEY_WINDOWS_SHORTCUT, szBuf, FALSE); + } + + ++dwIndex1; + itoa(dwIndex1, szIndex1, 10); + lstrcpy(szSection1, szSection0); + lstrcat(szSection1, "-Shortcut"); + lstrcat(szSection1, szIndex1); + GetPrivateProfileString(szSection1, "File", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + } + + ++dwIndex0; + BuildNumberedString(dwIndex0, szSectionPrefix, "Program Folder", szSection0, sizeof(szSection0)); + GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT ProcessProgramFolderShowCmd() +{ + DWORD dwIndex0; + int iShowFolder; + char szBuf[MAX_BUF]; + char szSection0[MAX_BUF]; + char szProgramFolder[MAX_BUF]; + + dwIndex0 = 0; + BuildNumberedString(dwIndex0, NULL, "Program Folder", szSection0, sizeof(szSection0)); + GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig); + while(*szBuf != '\0') + { + DecryptString(szProgramFolder, szBuf); + GetPrivateProfileString(szSection0, "Show Folder", "", szBuf, sizeof(szBuf), szFileIniConfig); + + if(strcmpi(szBuf, "HIDE") == 0) + iShowFolder = SW_HIDE; + else if(strcmpi(szBuf, "MAXIMIZE") == 0) + iShowFolder = SW_MAXIMIZE; + else if(strcmpi(szBuf, "MINIMIZE") == 0) + iShowFolder = SW_MINIMIZE; + else if(strcmpi(szBuf, "RESTORE") == 0) + iShowFolder = SW_RESTORE; + else if(strcmpi(szBuf, "SHOW") == 0) + iShowFolder = SW_SHOW; + else if(strcmpi(szBuf, "SHOWMAXIMIZED") == 0) + iShowFolder = SW_SHOWMAXIMIZED; + else if(strcmpi(szBuf, "SHOWMINIMIZED") == 0) + iShowFolder = SW_SHOWMINIMIZED; + else if(strcmpi(szBuf, "SHOWMINNOACTIVE") == 0) + iShowFolder = SW_SHOWMINNOACTIVE; + else if(strcmpi(szBuf, "SHOWNA") == 0) + iShowFolder = SW_SHOWNA; + else if(strcmpi(szBuf, "SHOWNOACTIVATE") == 0) + iShowFolder = SW_SHOWNOACTIVATE; + else if(strcmpi(szBuf, "SHOWNORMAL") == 0) + iShowFolder = SW_SHOWNORMAL; + + if(iShowFolder != SW_HIDE) + if(sgProduct.mode != SILENT) + WinSpawn(szProgramFolder, NULL, NULL, iShowFolder, WS_WAIT); + + ++dwIndex0; + BuildNumberedString(dwIndex0, NULL, "Program Folder", szSection0, sizeof(szSection0)); + GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig); + } + return(FO_SUCCESS); +} + +HRESULT ProcessCreateCustomFiles(DWORD dwTiming) +{ + DWORD dwCompIndex; + DWORD dwFileIndex; + DWORD dwSectIndex; + DWORD dwKVIndex; + siC *siCObject = NULL; + char szBufTiny[MAX_BUF_TINY]; + char szSection[MAX_BUF_TINY]; + char szBuf[MAX_BUF]; + char szFileName[MAX_BUF]; + char szDefinedSection[MAX_BUF]; + char szDefinedKey[MAX_BUF]; + char szDefinedValue[MAX_BUF]; + + dwCompIndex = 0; + siCObject = SiCNodeGetObject(dwCompIndex, TRUE, AC_ALL); + + while(siCObject) + { + dwFileIndex = 0; + wsprintf(szSection,"%s-Configuration File%d",siCObject->szReferenceName,dwFileIndex); + siCObject = SiCNodeGetObject(++dwCompIndex, TRUE, AC_ALL); + if(TimingCheck(dwTiming, szSection, szFileIniConfig) == FALSE) + { + continue; + } + + GetPrivateProfileString(szSection, "FileName", "", szBuf, sizeof(szBuf), szFileIniConfig); + while (*szBuf != '\0') + { + DecryptString(szFileName, szBuf); + if(FileExists(szFileName)) + { + DeleteFile(szFileName); + } + + /* TO DO - Support a File Type for something other than .ini */ + dwSectIndex = 0; + wsprintf(szBufTiny, "Section%d",dwSectIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szDefinedSection, sizeof(szDefinedSection), szFileIniConfig); + while(*szDefinedSection != '\0') + { + dwKVIndex =0; + wsprintf(szBufTiny,"Section%d-Key%d",dwSectIndex,dwKVIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szDefinedKey, sizeof(szDefinedKey), szFileIniConfig); + while(*szDefinedKey != '\0') + { + wsprintf(szBufTiny,"Section%d-Value%d",dwSectIndex,dwKVIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szBuf, sizeof(szBuf), szFileIniConfig); + DecryptString(szDefinedValue, szBuf); + if(WritePrivateProfileString(szDefinedSection, szDefinedKey, szDefinedValue, szFileName) == 0) + { + char szEWPPS[MAX_BUF]; + char szBuf[MAX_BUF]; + char szBuf2[MAX_BUF]; + if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall)) + { + wsprintf(szBuf, "%s\n [%s]\n %s=%s", szFileName, szDefinedSection, szDefinedKey, szDefinedValue); + wsprintf(szBuf2, szEWPPS, szBuf); + PrintError(szBuf2, ERROR_CODE_SHOW); + } + return(FO_ERROR_WRITE); + } + wsprintf(szBufTiny,"Section%d-Key%d",dwSectIndex,++dwKVIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szDefinedKey, sizeof(szDefinedKey), szFileIniConfig); + } /* while(*szDefinedKey != '\0') */ + + wsprintf(szBufTiny, "Section%d",++dwSectIndex); + GetPrivateProfileString(szSection, szBufTiny, "", szDefinedSection, sizeof(szDefinedSection), szFileIniConfig); + } /* while(*szDefinedSection != '\0') */ + + wsprintf(szSection,"%s-Configuration File%d",siCObject->szReferenceName,++dwFileIndex); + GetPrivateProfileString(szSection, "FileName", "", szBuf, sizeof(szBuf), szFileIniConfig); + } /* while(*szBuf != '\0') */ + } /* while(siCObject) */ + return (FO_SUCCESS); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/ifuncns.h b/toolkit/mozapps/installer/windows/wizard/setup/ifuncns.h new file mode 100644 index 00000000000..7debb0ca08b --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/ifuncns.h @@ -0,0 +1,110 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _IFUNCNS_H_ +#define _IFUNCNS_H_ + +HRESULT TimingCheck(DWORD dwTiming, LPSTR szSection, LPSTR szFile); +HRESULT MeetCondition(LPSTR dwSection); +HRESULT FileUncompress(LPSTR szFrom, LPSTR szTo); +HRESULT ProcessXpcomFile(void); +void CleanupXpcomFile(void); +HRESULT ProcessUncompressFile(DWORD dwTiming, char *szSectionPrefix); +HRESULT FileMove(LPSTR szFrom, LPSTR szTo); +HRESULT ProcessMoveFile(DWORD dwTiming, char *szSectionPrefix); +HRESULT FileCopy(LPSTR szFrom, LPSTR szTo, BOOL bFailIfExists, BOOL bDnu); +HRESULT ProcessCopyFile(DWORD dwTiming, char *szSectionPrefix); +HRESULT ProcessCreateDirectory(DWORD dwTiming, char *szSectionPrefix); +HRESULT ProcessCreateCustomFiles(DWORD dwTiming); +HRESULT FileDelete(LPSTR szDestination); +HRESULT ProcessDeleteFile(DWORD dwTiming, char *szSectionPrefix); +HRESULT DirectoryRemove(LPSTR szDestination, BOOL bRemoveSubdirs); +HRESULT ProcessRemoveDirectory(DWORD dwTiming, char *szSectionPrefix); +HRESULT ProcessRunApp(DWORD dwTiming, char *szSectionPrefix); +HRESULT ProcessWinReg(DWORD dwTiming, char *szSectionPrefix); +HRESULT CreateALink(LPSTR lpszPathObj, + LPSTR lpszPathLink, + LPSTR lpszDesc, + LPSTR lpszWorkingPath, + LPSTR lpszArgs, + LPSTR lpszIconFullPath, + int iIcon); +HRESULT ProcessProgramFolder(DWORD dwTiming, char *szSectionPrefix); +HRESULT ProcessProgramFolderShowCmd(void); +HRESULT CreateDirectoriesAll(char* szPath, BOOL bLogForUninstall); +void ProcessFileOps(DWORD dwTiming, char *szSectionPrefix); +void DeleteWinRegValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName); +void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete); +DWORD GetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, LPSTR szReturnValue, DWORD dwSize); +void SetWinReg(HKEY hkRootKey, + LPSTR szKey, + BOOL bOverwriteKey, + LPSTR szName, + BOOL bOverwriteName, + DWORD dwType, + LPBYTE lpbData, + DWORD dwSize, + BOOL bLogForUninstall, + BOOL bDnu); +HKEY ParseRootKey(LPSTR szRootKey); +char *ParseRootKeyString(HKEY hkKey, + LPSTR szRootKey, + DWORD dwRootKeyBufSize); +BOOL ParseRegType(LPSTR szType, DWORD *dwType); +BOOL WinRegKeyExists(HKEY hkRootKey, LPSTR szKey); +BOOL WinRegNameExists(HKEY hkRootKey, LPSTR szKey, LPSTR szName); +HRESULT FileCopySequential(LPSTR szSourcePath, LPSTR szDestPath, LPSTR szFilename); +HRESULT ProcessCopyFileSequential(DWORD dwTiming, char *szSectionPrefix); +void UpdateInstallLog(LPSTR szKey, LPSTR szString, BOOL bDnu); +void UpdateInstallStatusLog(LPSTR szString); +int RegisterDll32(char *File); +HRESULT FileSelfRegister(LPSTR szFilename, LPSTR szDestination); +HRESULT ProcessSelfRegisterFile(DWORD dwTiming, char *szSectionPrefix); +void UpdateJSProxyInfo(void); +int VerifyArchive(LPSTR szArchive); +HRESULT ProcessSetVersionRegistry(DWORD dwTiming, char *szSectionPrefix); +char *BuildNumberedString(DWORD dwIndex, char *szInputStringPrefix, char *szInputString, char *szOutBuf, DWORD dwOutBufSize); +void GetUserAgentShort(char *szUserAgent, char *szOutUAShort, DWORD dwOutUAShortSize); +void CleanupPreviousVersionRegKeys(void); +DWORD ParseRestrictedAccessKey(LPSTR szKey); +LPSTR GetKeyInfo(LPSTR aKey, LPSTR aOut, DWORD aOutBufSize, DWORD aInfoType); +void AppendWinReg(HKEY hkRootKey, + LPSTR szKey, + LPSTR szName, + DWORD dwType, + LPBYTE lpbData, + BYTE delimiter, + DWORD dwSize, + BOOL bLogForUninstall, + BOOL bDnu); +HRESULT CleanupArgsRegistry(); +void ProcessFileOpsForSelectedComponents(DWORD dwTiming); +void ProcessFileOpsForAll(DWORD dwTiming); +HRESULT DirHasWriteAccess(char *szPath); + +#define KEY_INFO_ROOT 0x00000001 +#define KEY_INFO_SUBKEY 0x00000002 + +#endif /* _IFUNCNS_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/logging.c b/toolkit/mozapps/installer/windows/wizard/setup/logging.c new file mode 100644 index 00000000000..13acdf7cb37 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/logging.c @@ -0,0 +1,655 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 2001 Netscape Communications Corp. All Rights + * Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "extern.h" +#include "logging.h" +#include "extra.h" +#include "ifuncns.h" +#include "xpi.h" + +#define E_USER_CANCEL -813 +#define SECTION_EXIT_STATUS "Exit Status" +#define KEY_STATUS "Status" + +int AppendToGlobalMessageStream(char *szInfo) +{ + DWORD dwInfoLen = lstrlen(szInfo); + DWORD dwMessageLen; + + if(gErrorMessageStream.bEnabled && gErrorMessageStream.szMessage) + { + dwMessageLen = lstrlen(gErrorMessageStream.szMessage); + if((dwInfoLen + dwMessageLen) >= gErrorMessageStream.dwMessageBufSize) + { + if(NS_GlobalReAlloc(&gErrorMessageStream.szMessage, + gErrorMessageStream.dwMessageBufSize, + dwInfoLen + dwMessageLen + MAX_BUF_TINY) == NULL) + return(WIZ_OUT_OF_MEMORY); + + gErrorMessageStream.dwMessageBufSize = dwInfoLen + + dwMessageLen + + MAX_BUF_TINY; + } + + lstrcat(gErrorMessageStream.szMessage, szInfo); + } + + return(WIZ_OK); +} + +void LogISTime(int iType) +{ + char szBuf[MAX_BUF]; + char szTime[MAX_BUF_TINY]; + char szDate[MAX_BUF_TINY]; + SYSTEMTIME stLocalTime; + + GetLocalTime(&stLocalTime); + GetTimeFormat(LOCALE_NEUTRAL, + LOCALE_NOUSEROVERRIDE, + &stLocalTime, + NULL, + szTime, + sizeof(szTime)); + GetDateFormat(LOCALE_NEUTRAL, + LOCALE_NOUSEROVERRIDE, + &stLocalTime, + NULL, + szDate, + sizeof(szDate)); + + if(iType == W_START) + wsprintf(szBuf, "Start Log: %s - %s\n", szDate, szTime); + else + wsprintf(szBuf, "End Log: %s - %s\n", szDate, szTime); + + UpdateInstallStatusLog(szBuf); +} + +void LogISProductInfo(void) +{ + char szBuf[MAX_BUF]; + + wsprintf(szBuf, "\n Product Info:\n"); + UpdateInstallStatusLog(szBuf); + + switch(sgProduct.mode) + { + case SILENT: + wsprintf(szBuf, " Install mode: Silent\n"); + break; + case AUTO: + wsprintf(szBuf, " Install mode: Auto\n"); + break; + default: + wsprintf(szBuf, " Install mode: Normal\n"); + break; + } + UpdateInstallStatusLog(szBuf); + + wsprintf(szBuf, " Company name: %s\n Product name (external): %s\n Product name (internal): %s\n Uninstall Filename: %s\n UserAgent: %s\n Alternate search path: %s\n", + sgProduct.szCompanyName, + sgProduct.szProductName, + sgProduct.szProductNameInternal, + sgProduct.szUninstallFilename, + sgProduct.szUserAgent, + sgProduct.szAlternateArchiveSearchPath); + UpdateInstallStatusLog(szBuf); +} + +void LogISDestinationPath(void) +{ + char szBuf[MAX_BUF]; + + wsprintf(szBuf, + "\n Destination Path:\n Main: %s\n SubPath: %s\n", + sgProduct.szPath, + sgProduct.szSubPath); + UpdateInstallStatusLog(szBuf); +} + +void LogISShared(void) +{ + char szBuf[MAX_BUF]; + + if(sgProduct.bSharedInst == TRUE) + wsprintf(szBuf,"\n Shared Installation: TRUE\n"); + UpdateInstallStatusLog(szBuf); +} + +void LogISSetupType(void) +{ + char szBuf[MAX_BUF_TINY]; + + switch(dwSetupType) + { + case ST_RADIO3: + wsprintf(szBuf, "\n Setup Type: %s\n", + diSetupType.stSetupType3.szDescriptionShort); + break; + + case ST_RADIO2: + wsprintf(szBuf, "\n Setup Type: %s\n", + diSetupType.stSetupType2.szDescriptionShort); + break; + + case ST_RADIO1: + wsprintf(szBuf, "\n Setup Type: %s\n", + diSetupType.stSetupType1.szDescriptionShort); + break; + + default: + wsprintf(szBuf, "\n Setup Type: %s\n", + diSetupType.stSetupType0.szDescriptionShort); + break; + } + + UpdateInstallStatusLog(szBuf); +} + +void LogISComponentsSelected(void) +{ + char szBuf[MAX_BUF_TINY]; + siC *siCNode; + BOOL bFoundComponentSelected; + + wsprintf(szBuf, "\n Components selected:\n"); + UpdateInstallStatusLog(szBuf); + + bFoundComponentSelected = FALSE; + siCNode = siComponents; + do + { + if(siCNode == NULL) + break; + + if(siCNode->dwAttributes & SIC_SELECTED) + { + if(!siCNode->bForceUpgrade) + wsprintf(szBuf, + " %s\n", + siCNode->szDescriptionShort); + else + wsprintf(szBuf, + " %s (Required)\n", + siCNode->szDescriptionShort); + + UpdateInstallStatusLog(szBuf); + bFoundComponentSelected = TRUE; + } + + siCNode = siCNode->Next; + } while((siCNode != NULL) && (siCNode != siComponents)); + + if(!bFoundComponentSelected) + { + wsprintf(szBuf, " none\n"); + UpdateInstallStatusLog(szBuf); + } +} + +void LogISComponentsToDownload(void) +{ + char szBuf[MAX_BUF_TINY]; + char szArchivePath[MAX_BUF_MEDIUM]; + siC *siCNode; + BOOL bFoundComponentSelected; + BOOL bFoundComponentsToDownload; + + wsprintf(szBuf, "\n Components to download:\n"); + UpdateInstallStatusLog(szBuf); + + bFoundComponentSelected = FALSE; + bFoundComponentsToDownload = FALSE; + siCNode = siComponents; + do + { + if(siCNode == NULL) + break; + + if(siCNode->dwAttributes & SIC_SELECTED) + { + + if(LocateJar(siCNode, + szArchivePath, + sizeof(szArchivePath), + gbPreviousUnfinishedDownload) == AP_NOT_FOUND) + { + wsprintf(szBuf, + " %s will be downloaded\n", + siCNode->szDescriptionShort); + bFoundComponentsToDownload = TRUE; + } + else + wsprintf(szBuf, + " %s found: %s\n", + siCNode->szDescriptionShort, + szArchivePath); + + UpdateInstallStatusLog(szBuf); + bFoundComponentSelected = TRUE; + } + + siCNode = siCNode->Next; + } while((siCNode != NULL) && (siCNode != siComponents)); + + if(!bFoundComponentSelected) + { + wsprintf(szBuf, " none\n"); + UpdateInstallStatusLog(szBuf); + } + if(!bFoundComponentsToDownload) + { + wsprintf(szBuf, " **\n ** All components have been found locally. No components will be downloaded.\n **\n"); + UpdateInstallStatusLog(szBuf); + } +} + +void LogISDownloadProtocol(DWORD dwProtocolType) +{ + char szBuf[MAX_BUF]; + char szProtocolType[MAX_BUF]; + + switch(dwProtocolType) + { + case UP_HTTP: + lstrcpy(szProtocolType, "HTTP"); + break; + + default: + lstrcpy(szProtocolType, "FTP"); + break; + } + + wsprintf(szBuf, "\n Download protocol: %s\n", szProtocolType); + UpdateInstallStatusLog(szBuf); +} + +void LogISDownloadStatus(char *szStatus, char *szFailedFile) +{ + char szBuf[MAX_BUF]; + siC *siCObject = NULL; + DWORD dwIndex; + + if(szFailedFile) + wsprintf(szBuf, + "\n Download status: %s\n file: %s\n\n", + szStatus, + szFailedFile); + else + wsprintf(szBuf, + "\n Download status: %s\n", + szStatus); + UpdateInstallStatusLog(szBuf); + + dwIndex = 0; + siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + { + wsprintf(szBuf, " %s: NetRetries:%d, CRCRetries:%d, NetTimeOuts:%d\n", + siCObject->szDescriptionShort, + siCObject->iNetRetries, + siCObject->iCRCRetries, + siCObject->iNetTimeOuts); + UpdateInstallStatusLog(szBuf); + } + + ++dwIndex; + siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL); + } +} + +void LogISComponentsFailedCRC(char *szList, int iWhen) +{ + char szBuf[MAX_BUF]; + + if(iWhen == W_STARTUP) + { + if(szList && (*szList != '\0')) + wsprintf(szBuf, + "\n Components corrupted (startup):\n%s", + szList); + else + wsprintf(szBuf, + "\n Components corrupted (startup):\n none\n"); + } + else + { + if(szList && (*szList != '\0')) + wsprintf(szBuf, + "\n Components corrupted (download):\n%s", + szList); + else + wsprintf(szBuf, + "\n Components corrupted (download):\n none\n"); + } + + UpdateInstallStatusLog(szBuf); +} + +void LogISXPInstall(int iWhen) +{ + char szBuf[MAX_BUF]; + + if(iWhen == W_START) + wsprintf(szBuf, "\n XPInstall Start\n"); + else + wsprintf(szBuf, " XPInstall End\n"); + + UpdateInstallStatusLog(szBuf); +} + +void LogISXPInstallComponent(char *szComponentName) +{ + char szBuf[MAX_BUF]; + + wsprintf(szBuf, " %s", szComponentName); + UpdateInstallStatusLog(szBuf); +} + +void LogISXPInstallComponentResult(DWORD dwErrorNumber) +{ + char szBuf[MAX_BUF]; + char szErrorString[MAX_BUF]; + + GetErrorString(dwErrorNumber, szErrorString, sizeof(szErrorString)); + wsprintf(szBuf, ": %d %s\n", dwErrorNumber, szErrorString); + UpdateInstallStatusLog(szBuf); +} + +void LogISLaunchApps(int iWhen) +{ + char szBuf[MAX_BUF]; + + if(iWhen == W_START) + wsprintf(szBuf, "\n Launch Apps Start\n"); + else + wsprintf(szBuf, " Launch Apps End\n"); + + UpdateInstallStatusLog(szBuf); +} + +void LogISLaunchAppsComponent(char *szComponentName) +{ + char szBuf[MAX_BUF]; + + wsprintf(szBuf, " launching %s\n", szComponentName); + UpdateInstallStatusLog(szBuf); +} + +void LogISLaunchAppsComponentUncompress(char *szComponentName, DWORD dwErr) +{ + char szBuf[MAX_BUF]; + + wsprintf(szBuf, " uncompressing %s: %d\n", szComponentName, dwErr); + UpdateInstallStatusLog(szBuf); +} + +void LogISProcessXpcomFile(int iStatus, int iResult) +{ + char szBuf[MAX_BUF]; + + if(iStatus == LIS_SUCCESS) + wsprintf(szBuf, "\n Uncompressing Xpcom Succeeded: %d\n", iResult); + else + wsprintf(szBuf, "\n Uncompressing Xpcom Failed: %d\n", iResult); + + UpdateInstallStatusLog(szBuf); +} + +void LogISDiskSpace(dsN *dsnComponentDSRequirement) +{ + ULONGLONG ullDSAvailable; + dsN *dsnTemp = NULL; + char szBuf[MAX_BUF]; + char szDSRequired[MAX_BUF_TINY]; + char szDSAvailable[MAX_BUF_TINY]; + + if(dsnComponentDSRequirement != NULL) + { + wsprintf(szBuf, "\n Disk Space Info:\n"); + UpdateInstallStatusLog(szBuf); + dsnTemp = dsnComponentDSRequirement; + do + { + if(!dsnTemp) + break; + + ullDSAvailable = GetDiskSpaceAvailable(dsnTemp->szVDSPath); + _ui64toa(ullDSAvailable, szDSAvailable, 10); + _ui64toa(dsnTemp->ullSpaceRequired, szDSRequired, 10); + wsprintf(szBuf, + " Path: %s\n Required: %sKB\n Available: %sKB\n", + dsnTemp->szVDSPath, + szDSRequired, + szDSAvailable); + UpdateInstallStatusLog(szBuf); + + dsnTemp = dsnTemp->Next; + } while((dsnTemp != NULL) && (dsnTemp != dsnComponentDSRequirement)); + } +} + +void LogISTurboMode(BOOL bTurboMode) +{ + char szBuf[MAX_BUF]; + + if(bTurboMode) + wsprintf(szBuf, "\n Turbo Mode: true\n"); + else + wsprintf(szBuf, "\n Turbo Mode: false\n"); + + UpdateInstallStatusLog(szBuf); +} + +void LogMSProductInfo(void) +{ + char szBuf[MAX_BUF]; + char szOSType[MAX_BUF_TINY]; + + GetOSTypeString(szOSType, sizeof(szOSType)); + if(*gSystemInfo.szExtraString != '\0') + wsprintf(szBuf, "UserAgent=%s/%s (%s,%d.%d.%d,%s)", + sgProduct.szProductName, + sgProduct.szUserAgent, + szOSType, + gSystemInfo.dwMajorVersion, + gSystemInfo.dwMinorVersion, + gSystemInfo.dwBuildNumber, + gSystemInfo.szExtraString); + else + wsprintf(szBuf, "UserAgent=%s/%s (%s,%d.%d.%d)", + sgProduct.szProductName, + sgProduct.szUserAgent, + szOSType, + gSystemInfo.dwMajorVersion, + gSystemInfo.dwMinorVersion, + gSystemInfo.dwBuildNumber); + + AppendToGlobalMessageStream(szBuf); +} + +void LogMSDownloadProtocol(DWORD dwProtocolType) +{ + char szMessageStream[MAX_BUF_TINY]; + char szProtocolType[MAX_BUF]; + + switch(dwProtocolType) + { + case UP_HTTP: + lstrcpy(szProtocolType, "HTTP"); + break; + + default: + lstrcpy(szProtocolType, "FTP"); + break; + } + + wsprintf(szMessageStream, "&DownloadProtocol=%s", szProtocolType); + AppendToGlobalMessageStream(szMessageStream); +} + +void LogMSDownloadStatus(int iDownloadStatus) +{ + char szMessageStream[MAX_BUF_TINY]; + + wsprintf(szMessageStream, "&DownloadStatus=%d", iDownloadStatus); + AppendToGlobalMessageStream(szMessageStream); + gErrorMessageStream.bSendMessage = TRUE; +} + +void LogMSDownloadFileStatus(void) +{ + siC *siCObject = NULL; + DWORD dwIndex; + char szMessageStream[MAX_BUF]; + + ZeroMemory(szMessageStream, sizeof(szMessageStream)); + dwIndex = 0; + siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->iNetRetries || + siCObject->iCRCRetries || + siCObject->iNetTimeOuts) + { + char szFileInfo[MAX_BUF_SMALL]; + + wsprintf(szFileInfo, + "&%s=%d,%d,%d", + siCObject->szArchiveName, + siCObject->iNetRetries, + siCObject->iCRCRetries, + siCObject->iNetTimeOuts); + + lstrcat(szMessageStream, szFileInfo); + } + ++dwIndex; + siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL); + } + + if(*szMessageStream != '\0') + AppendToGlobalMessageStream(szMessageStream); +} + +void LogMSXPInstallStatus(char *szFile, int iErr) +{ + char szMessageStream[MAX_BUF]; + static BOOL bAlreadyLogged = FALSE; + + if(bAlreadyLogged) + return; + + if(szFile) + wsprintf(szMessageStream, "&XPInstallStatus=%d&XPInstallFile=%s", iErr, szFile); + else + wsprintf(szMessageStream, "&XPInstallStatus=%d", iErr); + + AppendToGlobalMessageStream(szMessageStream); + bAlreadyLogged = TRUE; + if((iErr != E_REBOOT) && + (((iErr == E_USER_CANCEL) && + !gErrorMessageStream.bShowConfirmation) || + ((iErr != E_USER_CANCEL) && + (iErr != WIZ_OK)))) + gErrorMessageStream.bSendMessage = TRUE; +} + +void LogMSTurboMode(BOOL bTurboMode) +{ + char szMessageStream[MAX_BUF]; + + wsprintf(szMessageStream, "&TM=%d", bTurboMode); + AppendToGlobalMessageStream(szMessageStream); +} + +/* Function: GetExitStatusLogFile() + * in: aProductName, aLogFileBufSize + * in/out: aLogFile + * purpose: To build the full filename of the exit log file + * located in the TEMP dir given aProductName. + */ +void GetExitStatusLogFile(LPSTR aProductName, LPSTR aLogFile, DWORD aLogFileBufSize) +{ + char buf[MAX_BUF]; + char logFilename[MAX_BUF]; + + if(!aProductName || !aLogFile) + return; + + *aLogFile = '\0'; + lstrcpy(buf, szOSTempDir); + MozCopyStr(szOSTempDir, buf, sizeof(buf)); + AppendBackSlash(buf, sizeof(buf)); + _snprintf(logFilename, sizeof(logFilename), SETUP_EXIT_STATUS_LOG, aProductName); + logFilename[sizeof(logFilename) - 1] = '\0'; + _snprintf(aLogFile, aLogFileBufSize, "%s%s", buf, logFilename); + aLogFile[aLogFileBufSize - 1] = '\0'; +} + +/* Function: DeleteExitStatusFile() + * in: none. + * out: none + * purpose: To delete the setup's exit status file located in + * the TEMP dir. + */ +void DeleteExitStatusFile() +{ + char logFile[MAX_BUF]; + + GetExitStatusLogFile(sgProduct.szProductNameInternal, logFile, sizeof(logFile)); + if(FileExists(logFile)) + DeleteFile(logFile); +} + +/* Function: LogExitStatus() + * in: status to log. + * out: none + * purpose: To log the exit status of this setup. We're normally + * trying to log the need for a reboot. + */ +void LogExitStatus(LPSTR status) +{ + char logFile[MAX_BUF]; + + GetExitStatusLogFile(sgProduct.szProductNameInternal, logFile, sizeof(logFile)); + WritePrivateProfileString(SECTION_EXIT_STATUS, KEY_STATUS, status, logFile); +} + +/* Function: GetGreSetupExitStatus() + * in: none + * out: aStatus - status read in from the exit status log file + * purpose: To read the exis status from the GRE setup that was run + * from within this setup. + */ +void GetGreSetupExitStatus(LPSTR aStatus, DWORD aStatusBufSize) +{ + char logFile[MAX_BUF]; + + *aStatus = '\0'; + GetExitStatusLogFile("GRE", logFile, sizeof(logFile)); + if(FileExists(logFile)) + GetPrivateProfileString(SECTION_EXIT_STATUS, KEY_STATUS, "", aStatus, aStatusBufSize, logFile); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/logging.h b/toolkit/mozapps/installer/windows/wizard/setup/logging.h new file mode 100644 index 00000000000..b986db39cce --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/logging.h @@ -0,0 +1,58 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 2001 Netscape Communications Corp. All Rights + * Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _LOGGING_H_ +#define _LOGGING_H_ + +int AppendToGlobalMessageStream(char *szInfo); +void LogISTime(int iType); +void LogISProductInfo(void); +void LogISDestinationPath(void); +void LogISSetupType(void); +void LogISComponentsSelected(void); +void LogISComponentsToDownload(void); +void LogISComponentsFailedCRC(char *szList, int iWhen); +void LogISDownloadStatus(char *szStatus, char *szFailedFile); +void LogISDownloadProtocol(DWORD dwProtocolType); +void LogISXPInstall(int iWhen); +void LogISXPInstallComponent(char *szComponentName); +void LogISXPInstallComponentResult(DWORD dwErrorNumber); +void LogISLaunchApps(int iWhen); +void LogISLaunchAppsComponent(char *szComponentName); +void LogISLaunchAppsComponentUncompress(char *szComponentName, + DWORD dwErr); +void LogISProcessXpcomFile(int iStatus, int iResult); +void LogISShared(void); +void LogISDiskSpace(dsN *dsnComponentDSRequirement); +void LogISTurboMode(BOOL bTurboMode); +void LogMSProductInfo(void); +void LogMSDownloadFileStatus(void); +void LogMSDownloadStatus(int iDownloadStatus); +void LogMSDownloadProtocol(DWORD dwProtocolType); +void LogMSXPInstallStatus(char *szFile, int iErr); +void LogMSTurboMode(BOOL bTurboMode); +void DeleteExitStatusFile(void); +void LogExitStatus(LPSTR status); +void GetGreSetupExitStatus(LPSTR aStatus, DWORD aStatusBufSize); + +#endif /* _LOGGING_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/nsEscape.cpp b/toolkit/mozapps/installer/windows/wizard/setup/nsEscape.cpp new file mode 100644 index 00000000000..b81c1027cd5 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/nsEscape.cpp @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Sean Su + * Revision checked in on 01/03/30 by ssu@netscape.com, derived from: + * mozilla/xpcom/io/nsEscape.h + * mozilla/xpcom/io/nsEscape.cpp + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "extern.h" +#include "extra.h" + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include "nsEscape.h" + +typedef int PRInt32; + +const int netCharType[256] = +/* Bit 0 xalpha -- the alphas +** Bit 1 xpalpha -- as xalpha but +** converts spaces to plus and plus to %20 +** Bit 3 ... path -- as xalphas but doesn't escape '/' +*/ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */ + 0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */ + 7,7,7,7,7,7,7,7,7,7,0,0,0,7,0,0, /* 3x 0123456789:;<=>? */ + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ + /* bits for '@' changed from 7 to 0 so '@' can be escaped */ + /* in usernames and passwords in publishing. */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */ + 0, }; + +/* decode % escaped hex codes into character values + */ +#define UNHEX(C) \ + ((C >= '0' && C <= '9') ? C - '0' : \ + ((C >= 'A' && C <= 'F') ? C - 'A' + 10 : \ + ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0))) + + +#define IS_OK(C) (netCharType[((unsigned int) (C))] & (mask)) +#define HEX_ESCAPE '%' + +//---------------------------------------------------------------------------------------- +NS_COM char* nsEscape(const char * str, nsEscapeMask mask) +//---------------------------------------------------------------------------------------- +{ + if(!str) + return NULL; + return nsEscapeCount(str, lstrlen(str), mask, NULL); +} + +//---------------------------------------------------------------------------------------- +NS_COM char* nsEscapeCount( + const char * str, + PRInt32 len, + nsEscapeMask mask, + PRInt32* out_len) +//---------------------------------------------------------------------------------------- +{ + if (!str) + return 0; + + int i, extra = 0; + char* hexChars = "0123456789ABCDEF"; + + register const unsigned char* src = (const unsigned char *) str; + for (i = 0; i < len; i++) + { + if (!IS_OK(*src++)) + extra += 2; /* the escape, plus an extra byte for each nibble */ + } + + char* result = (char *)NS_GlobalAlloc(len + extra + 1); + if (!result) + return 0; + + register unsigned char* dst = (unsigned char *) result; + src = (const unsigned char *) str; + if (mask == url_XPAlphas) + { + for (i = 0; i < len; i++) + { + unsigned char c = *src++; + if (IS_OK(c)) + *dst++ = c; + else if (c == ' ') + *dst++ = '+'; /* convert spaces to pluses */ + else + { + *dst++ = HEX_ESCAPE; + *dst++ = hexChars[c >> 4]; /* high nibble */ + *dst++ = hexChars[c & 0x0f]; /* low nibble */ + } + } + } + else + { + for (i = 0; i < len; i++) + { + unsigned char c = *src++; + if (IS_OK(c)) + *dst++ = c; + else + { + *dst++ = HEX_ESCAPE; + *dst++ = hexChars[c >> 4]; /* high nibble */ + *dst++ = hexChars[c & 0x0f]; /* low nibble */ + } + } + } + + *dst = '\0'; /* tack on eos */ + if(out_len) + *out_len = dst - (unsigned char *) result; + return result; +} + +//---------------------------------------------------------------------------------------- +NS_COM char* nsUnescape(char * str) +//---------------------------------------------------------------------------------------- +{ + nsUnescapeCount(str); + return str; +} + +//---------------------------------------------------------------------------------------- +NS_COM PRInt32 nsUnescapeCount(char * str) +//---------------------------------------------------------------------------------------- +{ + register char *src = str; + register char *dst = str; + + while (*src) + if (*src != HEX_ESCAPE) + *dst++ = *src++; + else + { + src++; /* walk over escape */ + if (*src) + { + *dst = UNHEX(*src) << 4; + src++; + } + if (*src) + { + *dst = (*dst + UNHEX(*src)); + src++; + } + dst++; + } + + *dst = 0; + return (int)(dst - str); + +} /* NET_UnEscapeCnt */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/nsEscape.h b/toolkit/mozapps/installer/windows/wizard/setup/nsEscape.h new file mode 100644 index 00000000000..c1ec38b5f40 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/nsEscape.h @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Sean Su + * Revision checked in on 01/03/22 by ssu@netscape.com, derived from: + * mozilla/xpcom/io/nsEscape.h + * mozilla/xpcom/io/nsEscape.cpp + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _ESCAPE_H_ +#define _ESCAPE_H_ + +#define NS_COM +#define PRUnichar char + +/* valid mask values for NET_Escape() and NET_EscapedSize(). */ +typedef enum { + url_XAlphas = (1<<0) +, url_XPAlphas = (1<<1) +, url_Path = (1<<2) +} nsEscapeMask; + +#ifdef __cplusplus +extern "C" { +#endif +NS_COM char * nsEscape(const char * str, nsEscapeMask mask); + /* Caller must use nsCRT::free() on the result */ + +NS_COM char * nsUnescape(char * str); + /* decode % escaped hex codes into character values, + * modifies the parameter, returns the same buffer + */ + +NS_COM char * nsEscapeCount(const char * str, PRInt32 len, nsEscapeMask mask, PRInt32* out_len); + /* Like nsEscape, but if out_len is non-null, return result string length + * in *out_len, and uses len instead of NUL termination. + * Caller must use nsCRT::free() on the result. + */ +NS_COM PRInt32 nsUnescapeCount (char * str); + /* decode % escaped hex codes into character values, + * modifies the parameter buffer, returns the length of the result + * (result may contain \0's). + */ + +#ifdef __cplusplus +} +#endif + +#endif // _ESCAPE_H_ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/process.c b/toolkit/mozapps/installer/windows/wizard/setup/process.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setup/process.h b/toolkit/mozapps/installer/windows/wizard/setup/process.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setup/resource.h b/toolkit/mozapps/installer/windows/wizard/setup/resource.h new file mode 100644 index 00000000000..0f089e0f26e --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/resource.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by setup.rc +// + +#include "winresrc.h" + +#define IDS_ERROR_DLL_LOAD 1 +#define IDS_ERROR_STRING_LOAD 2 +#define IDS_ERROR_STRING_NULL 4 +#define IDS_ERROR_GLOBALALLOC 5 +#define IDS_ERROR_OUTOFMEMORY 6 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/toolkit/mozapps/installer/windows/wizard/setup/setup.c b/toolkit/mozapps/installer/windows/wizard/setup/setup.c new file mode 100644 index 00000000000..a79dc3762f8 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/setup.c @@ -0,0 +1,215 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "setup.h" +#include "extra.h" +#include "dialogs.h" +#include "ifuncns.h" + +/* global variables */ +HINSTANCE hInst; +HINSTANCE hSetupRscInst; +HINSTANCE hSDInst; +HINSTANCE hXPIStubInst; + +HBITMAP hbmpBoxChecked; +HBITMAP hbmpBoxCheckedDisabled; +HBITMAP hbmpBoxUnChecked; + +HANDLE hAccelTable; + +HWND hDlgCurrent; +HWND hDlgMessage; +HWND hWndMain; + +LPSTR szEGlobalAlloc; +LPSTR szEStringLoad; +LPSTR szEDllLoad; +LPSTR szEStringNull; +LPSTR szTempSetupPath; +LPSTR szEOutOfMemory; + +LPSTR szSetupDir; +LPSTR szTempDir; +LPSTR szOSTempDir; +LPSTR szFileIniConfig; +LPSTR szFileIniInstall; + +LPSTR szSiteSelectorDescription; + +DWORD dwWizardState; +DWORD dwSetupType; + +DWORD dwTempSetupType; +DWORD gdwUpgradeValue; +DWORD gdwSiteSelectorStatus; + +BOOL bSDUserCanceled; +BOOL bIdiArchivesExists; +BOOL bCreateDestinationDir; +BOOL bReboot; +BOOL gbILUseTemp; +BOOL gbPreviousUnfinishedDownload; +BOOL gbPreviousUnfinishedInstallXpi; +BOOL gbIgnoreRunAppX; +BOOL gbIgnoreProgramFolderX; +BOOL gbRestrictedAccess; +BOOL gbDownloadTriggered; +BOOL gbAllowMultipleInstalls = FALSE; +BOOL gbForceInstall = FALSE; +BOOL gbForceInstallGre = FALSE; +BOOL gShowBannerImage = TRUE; + +setupGen sgProduct; +diS diSetup; +diW diWelcome; +diL diLicense; +diQL diQuickLaunch; +diST diSetupType; +diSC diSelectComponents; +diSC diSelectAdditionalComponents; +diWI diWindowsIntegration; +diPF diProgramFolder; +diDO diAdditionalOptions; +diAS diAdvancedSettings; +diSI diStartInstall; +diD diDownload; +diR diReboot; +siSD siSDObject; +siCF siCFXpcomFile; +siC *siComponents; +ssi *ssiSiteSelector; +installGui sgInstallGui; +sems gErrorMessageStream; +sysinfo gSystemInfo; +dsN *gdsnComponentDSRequirement = NULL; + + +/* do not add setup.exe to the list because we figure out the filename + * by calling GetModuleFileName() */ +char *SetupFileList[] = {"setuprsc.dll", + "config.ini", + "setup.ini", + "install.ini", + "license.txt", + ""}; + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) +{ + /***********************************************************************/ + /* HANDLE hInstance; handle for this instance */ + /* HANDLE hPrevInstance; handle for possible previous instances */ + /* LPSTR lpszCmdLine; long pointer to exec command line */ + /* int nCmdShow; Show code for main window display */ + /***********************************************************************/ + + MSG msg; + char szBuf[MAX_BUF]; + int iRv = WIZ_OK; + HWND hwndFW; + + if(!hPrevInstance) + { + if(InitSetupGeneral()) + PostQuitMessage(1); + else if(ParseForStartupOptions(lpszCmdLine)) + PostQuitMessage(1); + else if(((hwndFW = FindWindow(CLASS_NAME_SETUP_DLG, NULL)) != NULL || + ((hwndFW = FindWindow(CLASS_NAME_SETUP, NULL)) != NULL)) && + !gbAllowMultipleInstalls) + { + /* Allow only one instance of setup to run. + * Detect a previous instance of setup, bring it to the + * foreground, and quit current instance */ + + ShowWindow(hwndFW, SW_RESTORE); + SetForegroundWindow(hwndFW); + iRv = WIZ_SETUP_ALREADY_RUNNING; + PostQuitMessage(1); + } + else if(Initialize(hInstance)) + PostQuitMessage(1); + else if(!InitApplication(hInstance, hSetupRscInst)) + { + char szEFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_FAILED", "", szEFailed, sizeof(szEFailed), szFileIniInstall)) + { + wsprintf(szBuf, szEFailed, "InitApplication()."); + PrintError(szBuf, ERROR_CODE_SHOW); + } + PostQuitMessage(1); + } + else if(!InitInstance(hInstance, nCmdShow)) + { + char szEFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_FAILED", "", szEFailed, sizeof(szEFailed), szFileIniInstall)) + { + wsprintf(szBuf, szEFailed, "InitInstance()."); + PrintError(szBuf, ERROR_CODE_SHOW); + } + PostQuitMessage(1); + } + else if(GetInstallIni()) + { + PostQuitMessage(1); + } + else if(ParseInstallIni()) + { + PostQuitMessage(1); + } + else if(GetConfigIni()) + { + PostQuitMessage(1); + } + else if(ParseConfigIni(lpszCmdLine)) + { + PostQuitMessage(1); + } + else + { + DlgSequence(NEXT_DLG); + } + } + + while(GetMessage(&msg, NULL, 0, 0)) + { + if((!IsDialogMessage(hDlgCurrent, &msg)) && (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + if(iRv != WIZ_SETUP_ALREADY_RUNNING) + /* Do clean up before exiting from the application */ + DeInitialize(); + + /* garbage collection */ + DeInitSetupGeneral(); + + return(msg.wParam); +} /* End of WinMain */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/setup.h b/toolkit/mozapps/installer/windows/wizard/setup/setup.h new file mode 100644 index 00000000000..cc3d5f52e88 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/setup.h @@ -0,0 +1,655 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _SETUP_H_ +#define _SETUP_H_ + +#ifdef __cplusplus +#define PR_BEGIN_EXTERN_C extern "C" { +#define PR_END_EXTERN_C } +#else /* __cplusplus */ +#define PR_BEGIN_EXTERN_C +#define PR_END_EXTERN_C +#endif /* __cplusplus */ + +#define PR_EXTERN(type) type + +typedef unsigned int PRUint32; +typedef int PRInt32; + +#include +#include +#include +#include +#include +#include +#include +#include +#include "setuprsc.h" +#include "resource.h" +#include "zipfile.h" + +#define DEFAULT_SETUP_WINDOW_NAME "Setup" +/* Class name for the invisible window to be created */ +#define CLASS_NAME_SETUP "MozillaSetup" +#define CLASS_NAME_SETUP_DLG "MozillaSetupDlg" +#define FILE_INI_SETUP "setup.ini" +#define FILE_INI_CONFIG "config.ini" +#define FILE_INI_INSTALL "install.ini" +#define FILE_IDI_GETCONFIGINI "getconfigini.idi" +#define FILE_IDI_GETARCHIVES "getarchives.idi" +#define FILE_IDI_GETREDIRECT "getredirect.idi" +#define FILE_INI_REDIRECT "redirect.ini" +#define FILE_WGET_LOG "wget.log" +#define WIZ_TEMP_DIR "ns_temp" +#define FILE_INSTALL_LOG "install_wizard.log" +#define FILE_INSTALL_STATUS_LOG "install_status.log" +#define FILE_ALL_JS "all-proxy.js" +#define VR_DEFAULT_PRODUCT_NAME "Mozilla" + +#define FORCE_ADD_TO_UNINSTALL_LOG TRUE +#define DO_NOT_FORCE_ADD_TO_UNINSTALL_LOG FALSE + +/* defines that indicate whether something should + * be logged to the install_wizardX.log or not + * for uninstallation purposes. + */ +#define ADD_TO_UNINSTALL_LOG TRUE +#define DO_NOT_ADD_TO_UNINSTALL_LOG FALSE + +/* defines that indeicate whether an install command + * should have '*dnu*' prepended. '*dnu*' is parsed + * by the uninstaller and signals that the specific + * install command should _not_ be undone. + */ +#define DNU_UNINSTALL FALSE +#define DNU_DO_NOT_UNINSTALL TRUE + +#define WINREG_OVERWRITE_KEY TRUE +#define WINREG_DO_NOT_OVERWRITE_KEY FALSE +#define WINREG_OVERWRITE_NAME TRUE +#define WINREG_DO_NOT_OVERWRITE_NAME FALSE + +#define INCLUDE_INVISIBLE_OBJS TRUE +#define SKIP_INVISIBLE_OBJS FALSE + +#define NO_BANNER_IMAGE 0x00000000 +#define BANNER_IMAGE_DOWNLOAD 0x00000001 +#define BANNER_IMAGE_INSTALLING 0x00000002 + +#define APPPATH_GRE_PATH_SET 0x00000000 +#define APPPATH_GRE_PATH_NOT_SET 0x00000001 +#define APPPATH_GRE_PATH_ALREADY_SET 0x00000002 + +#define NEXT_DLG 1 +#define PREV_DLG 2 +#define OTHER_DLG_1 3 + +#define MAX_CRC_FAILED_DOWNLOAD_RETRIES 5 +#define MAX_FILE_DOWNLOAD_RETRIES 10 + +#define STATUS_DISABLED 0 +#define STATUS_ENABLED 1 + +#define GRE_SETUP_DIR_NAME "Setup GRE" + +/* filename which contains this product setup's exit status */ +#define SETUP_EXIT_STATUS_LOG "%s Setup Exit Status.log" + +/* LOCAL GRE defines */ +#define GRE_TYPE_NOT_SET -1 +#define GRE_SHARED 0 +#define GRE_LOCAL 1 + +/* WS: WinSpawn wait values */ +#define WS_DO_NOT_WAIT FALSE +#define WS_WAIT TRUE + +#define MAX_KILL_PROCESS_RETRIES 10 + +/* CI: Check Instance */ +#define CI_FORCE_QUIT_PROCESS TRUE +#define CI_CLOSE_PROCESS FALSE + +#define BAR_MARGIN 1 +#define BAR_SPACING 0 +#define BAR_WIDTH 6 +#define BAR_LIBXPNET_MARGIN 1 +#define BAR_LIBXPNET_SPACING 0 +#define BAR_LIBXPNET_WIDTH 1 + +/* W: When for install status logging */ +#define W_START 0 +#define W_END 1 + +/* W: When for crc check failed logging */ +#define W_STARTUP 0 +#define W_DOWNLOAD 1 + +/* UP: Use Protocol */ +#define UP_FTP 0 +#define UP_HTTP 1 + +/* RA: Restricted Access */ +#define RA_IGNORE 0 +#define RA_ONLY_RESTRICTED 1 +#define RA_ONLY_NONRESTRICTED 2 + +/* LIS: Log Install Status */ +#define LIS_SUCCESS 0 +#define LIS_FAILURE 1 + +/* UG: Upgrade */ +#define UG_NONE 0 +#define UG_DELETE 1 +#define UG_IGNORE 2 +#define UG_GOBACK 3 + +/* AP: Archive Path */ +#define AP_NOT_FOUND 0 +#define AP_TEMP_PATH 1 +#define AP_SETUP_PATH 2 +#define AP_ALTERNATE_PATH 3 + +/* PP: Parse Path */ +#define PP_FILENAME_ONLY 1 +#define PP_PATH_ONLY 2 +#define PP_ROOT_ONLY 3 +#define PP_EXTENSION_ONLY 4 + +/* DA: Delete Archive */ +#define DA_ONLY_IF_IN_ARCHIVES_LST 1 +#define DA_ONLY_IF_NOT_IN_ARCHIVES_LST 2 +#define DA_IGNORE_ARCHIVES_LST 3 + +/* T: Timing */ +#define T_PRE_DOWNLOAD 1 +#define T_POST_DOWNLOAD 2 +#define T_PRE_XPCOM 3 +#define T_POST_XPCOM 4 +#define T_PRE_SMARTUPDATE 5 +#define T_POST_SMARTUPDATE 6 +#define T_PRE_LAUNCHAPP 7 +#define T_POST_LAUNCHAPP 8 +#define T_DEPEND_REBOOT 9 +#define T_PRE_ARCHIVE 10 +#define T_POST_ARCHIVE 11 + +#define MAX_BUF 2048 +#define MAX_BUF_TINY 256 +#define MAX_BUF_SMALL 512 +#define MAX_BUF_MEDIUM 1024 +#define MAX_BUF_LARGE MAX_BUF +#define MAX_BUF_XLARGE 4096 +#define MAX_ITOA 46 +#define MAX_INI_SK 128 + +#define ERROR_CODE_HIDE 0 +#define ERROR_CODE_SHOW 1 +#define DLG_NONE 0 +#define DLG_COMMIT_INSTALL 1 +#define CX_CHECKBOX 13 +#define CY_CHECKBOX 13 + +/* WIZ: WIZARD defines */ +#define WIZ_OK 0 +#define WIZ_ERROR_UNDEFINED 1024 +#define WIZ_MEMORY_ALLOC_FAILED 1025 +#define WIZ_OUT_OF_MEMORY WIZ_MEMORY_ALLOC_FAILED +#define WIZ_ARCHIVES_MISSING 1026 +#define WIZ_CRC_PASS WIZ_OK +#define WIZ_CRC_FAIL 1028 +#define WIZ_SETUP_ALREADY_RUNNING 1029 +#define WIZ_TOO_MANY_NETWORK_ERRORS 1030 +#define WIZ_ERROR_PARSING_INTERNAL_STR 1031 +#define WIZ_ERROR_REGKEY 1032 +#define WIZ_ERROR_INIT 1033 +#define WIZ_ERROR_LOADING_RESOURCE_LIB 1034 +#define WIZ_ERROR_CREATE_DIRECTORY 1035 + +/* E: Errors */ +#define E_REBOOT 999 + +/* FO: File Operation */ +#define FO_OK 0 +#define FO_SUCCESS 0 +#define FO_ERROR_FILE_NOT_FOUND 1 +#define FO_ERROR_DESTINATION_CONFLICT 2 +#define FO_ERROR_CHANGE_DIR 3 +#define FO_ERROR_WRITE 4 +#define FO_ERROR_INCR_EXCEEDS_LIMIT 5 + +/* Mode of Setup to run in */ +#define NOT_SET -1 +#define NORMAL 0 +#define SILENT 1 +#define AUTO 2 + +/* ST: Setup Type */ +#define ST_RADIO0 0 +#define ST_RADIO1 1 +#define ST_RADIO2 2 +#define ST_RADIO3 3 + +/* SM: Setup Type Mode */ +#define SM_SINGLE 0 +#define SM_MULTI 1 + +/* SIC: Setup Info Component*/ +#define SIC_SELECTED 0x00000001 +#define SIC_INVISIBLE 0x00000002 +#define SIC_LAUNCHAPP 0x00000004 +#define SIC_DOWNLOAD_REQUIRED 0x00000008 +#define SIC_DOWNLOAD_ONLY 0x00000010 +#define SIC_ADDITIONAL 0x00000020 +#define SIC_DISABLED 0x00000040 +#define SIC_FORCE_UPGRADE 0x00000080 +#define SIC_IGNORE_DOWNLOAD_ERROR 0x00000100 +#define SIC_IGNORE_XPINSTALL_ERROR 0x00000200 +#define SIC_UNCOMPRESS 0x00000400 +#define SIC_SUPERSEDE 0x00000800 + +/* AC: Additional Components */ +#define AC_NONE 0 +#define AC_COMPONENTS 1 +#define AC_ADDITIONAL_COMPONENTS 2 +#define AC_ALL 3 + +/* OS: Operating System */ +#define OS_WIN9x 0x00000001 +#define OS_WIN95_DEBUTE 0x00000002 +#define OS_WIN95 0x00000004 +#define OS_WIN98 0x00000008 +#define OS_NT 0x00000010 +#define OS_NT3 0x00000020 +#define OS_NT4 0x00000040 +#define OS_NT5 0x00000080 +#define OS_NT50 0x00000100 +#define OS_NT51 0x00000200 + +/* DSR: Disk Space Required */ +#define DSR_DESTINATION 0 +#define DSR_SYSTEM 1 +#define DSR_TEMP 2 +#define DSR_DOWNLOAD_SIZE 3 + +/* SS: Site Selector */ +#define SS_HIDE 0 +#define SS_SHOW 1 + +/* PUS: Previous Unfinished State */ +#define PUS_NONE 0 +#define PUS_DOWNLOAD 1 +#define PUS_UNPACK_XPCOM 2 +#define PUS_INSTALL_XPI 3 +#define SETUP_STATE_DOWNLOAD "downloading" +#define SETUP_STATE_UNPACK_XPCOM "unpacking xpcom" +#define SETUP_STATE_INSTALL_XPI "installing xpi" +#define SETUP_STATE_REMOVING_PREV_INST "removing previous installation" + + +typedef struct dlgSetup +{ + DWORD dwDlgID; + WNDPROC fDlgProc; + LPSTR szTitle; +} diS; + +typedef struct dlgWelcome +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; + LPSTR szMessage1; + LPSTR szMessage2; +} diW; + +typedef struct dlgLicense +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szLicenseFilename; + LPSTR szMessage0; + LPSTR szMessage1; +} diL; + +typedef struct dlgQuickLaunch +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; + LPSTR szMessage1; + LPSTR szMessage2; + BOOL bTurboMode; + BOOL bTurboModeEnabled; +} diQL; + + +typedef struct stStruct +{ + BOOL bVisible; + DWORD dwCItems; + DWORD dwCItemsSelected[MAX_BUF]; /* components */ + LPSTR szDescriptionShort; + LPSTR szDescriptionLong; +} st; + +typedef struct dlgSetupType +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; + LPSTR szReadmeFilename; + LPSTR szReadmeApp; + st stSetupType0; + st stSetupType1; + st stSetupType2; + st stSetupType3; +} diST; + +typedef struct dlgSelectComponents +{ + BOOL bShowDialog; + DWORD bShowDialogSM; + LPSTR szTitle; + LPSTR szMessage0; +} diSC; + +typedef struct wiCBstruct +{ + BOOL bEnabled; + BOOL bCheckBoxState; + LPSTR szDescription; + LPSTR szArchive; +} wiCBs; + +typedef struct dlgWindowsIntegration +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; + LPSTR szMessage1; + wiCBs wiCB0; + wiCBs wiCB1; + wiCBs wiCB2; + wiCBs wiCB3; +} diWI; + +typedef struct dlgProgramFolder +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; +} diPF; + +typedef struct dlgAdditionalOptions +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; + LPSTR szMessage1; + BOOL bSaveInstaller; + BOOL bRecaptureHomepage; + BOOL bShowHomepageOption; + DWORD dwUseProtocol; + BOOL bUseProtocolSettings; + BOOL bShowProtocols; +} diDO; + +typedef struct dlgAdvancedSettings +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; + LPSTR szProxyServer; + LPSTR szProxyPort; + LPSTR szProxyUser; + LPSTR szProxyPasswd; +} diAS; + +typedef struct dlgStartInstall +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessageInstall; + LPSTR szMessageDownload; +} diSI; + +typedef struct dlgDownload +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessageDownload0; + LPSTR szMessageRetry0; +} diD; + +typedef struct dlgReboot +{ + DWORD dwShowDialog; + LPSTR szTitle; +} diR; + +typedef struct setupStruct +{ + int mode; + int greType; + DWORD dwCustomType; + DWORD dwNumberOfComponents; + LPSTR szPath; + LPSTR szSubPath; + LPSTR szProgramName; + LPSTR szCompanyName; + LPSTR szProductName; + LPSTR szProductNameInternal; + LPSTR szProductNamePrevious; + LPSTR szUninstallFilename; + LPSTR szUserAgent; + LPSTR szProgramFolderName; + LPSTR szProgramFolderPath; + LPSTR szAlternateArchiveSearchPath; + LPSTR szParentProcessFilename; + BOOL bLockPath; + BOOL bSharedInst; + BOOL bInstallFiles; + BOOL checkCleanupOnUpgrade; + BOOL doCleanupOnUpgrade; + LPSTR szAppID; + LPSTR szAppPath; + LPSTR szRegPath; + BOOL greCleanupOrphans; + char greCleanupOrphansMessage[MAX_BUF]; + char greID[MAX_BUF]; + char grePrivateKey[MAX_BUF]; +} setupGen; + +typedef struct sinfoSmartDownload +{ + LPSTR szXpcomFile; + LPSTR szXpcomDir; + LPSTR szNoAds; + LPSTR szSilent; + LPSTR szExecution; + LPSTR szConfirmInstall; + LPSTR szExtractMsg; + LPSTR szExe; + LPSTR szExeParam; + LPSTR szXpcomFilePath; +} siSD; + +typedef struct sinfoXpcomFile +{ + LPSTR szSource; + LPSTR szDestination; + LPSTR szMessage; + BOOL bCleanup; + BOOL bStatus; + ULONGLONG ullInstallSize; +} siCF; + +typedef struct sinfoComponentDep siCD; +struct sinfoComponentDep +{ + LPSTR szDescriptionShort; + LPSTR szReferenceName; + siCD *Next; + siCD *Prev; +}; + +typedef struct sinfoComponent siC; +struct sinfoComponent +{ + ULONGLONG ullInstallSize; + ULONGLONG ullInstallSizeSystem; + ULONGLONG ullInstallSizeArchive; + long lRandomInstallPercentage; + long lRandomInstallValue; + DWORD dwAttributes; + LPSTR szArchiveName; + LPSTR szArchiveNameUncompressed; + LPSTR szArchivePath; + LPSTR szDestinationPath; + LPSTR szDescriptionShort; + LPSTR szDescriptionLong; + LPSTR szParameter; + LPSTR szReferenceName; + BOOL bForceUpgrade; + BOOL bSupersede; + int iNetRetries; + int iCRCRetries; + int iNetTimeOuts; + siCD *siCDDependencies; + siCD *siCDDependees; + siC *Next; + siC *Prev; +}; + +typedef struct ssInfo ssi; +struct ssInfo +{ + LPSTR szDescription; + LPSTR szDomain; + LPSTR szIdentifier; + ssi *Next; + ssi *Prev; +}; + +typedef struct dlgInstall +{ + HFONT systemFont; + HFONT definedFont; + char szFontName[MAX_BUF]; + char szFontSize[MAX_BUF]; + char szCharSet[MAX_BUF]; + char szOk_[MAX_BUF]; + char szOk[MAX_BUF]; + char szCancel_[MAX_BUF]; + char szCancel[MAX_BUF]; + char szNext_[MAX_BUF]; + char szBack_[MAX_BUF]; + char szIgnore_[MAX_BUF]; + char szProxySettings_[MAX_BUF]; + char szProxySettings[MAX_BUF]; + char szServer[MAX_BUF]; + char szPort[MAX_BUF]; + char szUserId[MAX_BUF]; + char szPassword[MAX_BUF]; + char szSelectDirectory[MAX_BUF]; + char szDirectories_[MAX_BUF]; + char szDrives_[MAX_BUF]; + char szStatus[MAX_BUF]; + char szFile[MAX_BUF]; + char szUrl[MAX_BUF]; + char szTo[MAX_BUF]; + char szAccept_[MAX_BUF]; + char szDecline_[MAX_BUF]; + char szProgramFolder_[MAX_BUF]; + char szExistingFolder_[MAX_BUF]; + char szSetupMessage[MAX_BUF]; + char szRestart[MAX_BUF]; + char szYesRestart[MAX_BUF]; + char szNoRestart[MAX_BUF]; + char szAdditionalComponents_[MAX_BUF]; + char szDescription[MAX_BUF]; + char szTotalDownloadSize[MAX_BUF]; + char szSpaceAvailable[MAX_BUF]; + char szComponents_[MAX_BUF]; + char szDestinationDirectory[MAX_BUF]; + char szBrowse_[MAX_BUF]; + char szCurrentSettings[MAX_BUF]; + char szInstall_[MAX_BUF]; + char szDelete_[MAX_BUF]; + char szContinue_[MAX_BUF]; + char szSkip_[MAX_BUF]; + char szExtracting[MAX_BUF]; + char szReadme_[MAX_BUF]; + char szPause_[MAX_BUF]; + char szResume_[MAX_BUF]; + char szChecked[MAX_BUF]; + char szUnchecked[MAX_BUF]; +} installGui; + +/* structure message stream */ +typedef struct sEMsgStream sems; +struct sEMsgStream +{ + char szURL[MAX_BUF]; + char szConfirmationMessage[MAX_BUF]; + char *szMessage; + DWORD dwMessageBufSize; + BOOL bEnabled; + BOOL bSendMessage; + BOOL bShowConfirmation; +}; + +/* structure system info*/ +typedef struct sSysInfo sysinfo; +struct sSysInfo +{ + DWORD dwOSType; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + char szExtraString[MAX_BUF]; + DWORD dwMemoryTotalPhysical; + DWORD dwMemoryAvailablePhysical; + DWORD dwScreenX; + DWORD dwScreenY; + DWORD lastWindowPosCenterX; + DWORD lastWindowPosCenterY; + BOOL bScreenReader; + BOOL bRefreshIcons; +}; + +typedef struct diskSpaceNode dsN; +struct diskSpaceNode +{ + ULONGLONG ullSpaceRequired; + LPSTR szPath; + LPSTR szVDSPath; + dsN *Next; + dsN *Prev; +}; + +#endif /* _SETUP_H */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/setup.ico b/toolkit/mozapps/installer/windows/wizard/setup/setup.ico new file mode 100644 index 0000000000000000000000000000000000000000..f8acc71c2506733106ec3a9f48c16fbb7e52b064 GIT binary patch literal 1078 zcmb7@v5wm?42J1T0BbnZd4pss@)qYIK$bp?hXT?T7B^T!0rzpbMR&8&zQO@rI&?75 zAptt5AC+@aq*oMW@{9UKQX~~dq>>xiY*u3O^+x11dbPUnZ6)$*A+qIc16okYl2t_U zeOVME7S)SlWh*Hqv>9^wO3t*+1$b5sYfm#q~SW6zx-MnAPy86^kp>FbcC#0S^w5PV185+9WKQ}1%_9MMBiVusE* zS;q@^6P>?@K6BoFP@^*^b^ z^_EL)@;6|f^ThsTQDz(qGhGxb+y9#LCact;BRNCMz%|)(p~&s%g?T~mUCkWbjyq>B zI^?&!R`)2zQeb2_*46EAMMMo%)-{0#RZ_YWfPcpT+Ft`)%J NmvHt0OjkI=e*(b)OYQ&w literal 0 HcmV?d00001 diff --git a/toolkit/mozapps/installer/windows/wizard/setup/setup.ini b/toolkit/mozapps/installer/windows/wizard/setup/setup.ini new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setup/setup.rc b/toolkit/mozapps/installer/windows/wizard/setup/setup.rc new file mode 100644 index 00000000000..702957fc455 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/setup.rc @@ -0,0 +1,157 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,2 + PRODUCTVERSION 1,0,0,2 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "mozilla.org\0" + VALUE "FileDescription", "setup\0" + VALUE "FileVersion", "1, 0, 0, 2\0" + VALUE "InternalName", "setup\0" + VALUE "LegalCopyright", "Copyright © 2001\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "setup.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Mozilla Setup\0" + VALUE "ProductVersion", "1, 0, 0, 2\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +1 ICON DISCARDABLE "setup.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ERROR_DLL_LOAD "Could not load %s" + IDS_ERROR_STRING_LOAD "Could not load string resource ID %d" + IDS_ERROR_STRING_NULL "Null pointer encountered." + IDS_ERROR_GLOBALALLOC "Memory allocation error." + IDS_ERROR_OUTOFMEMORY "Out of memory" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/shortcut.cpp b/toolkit/mozapps/installer/windows/wizard/setup/shortcut.cpp new file mode 100644 index 00000000000..729423c2db5 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/shortcut.cpp @@ -0,0 +1,93 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +/* This is a hack for vc5.0. It needs to be set *before* any shell + * include files. The INITGUID definition turns off the inclusion + * of shlguid.h in shlobj.h so it has to be done explicitly. + */ +#if (_MSC_VER == 1100) +#define INITGUID +#include "objbase.h" +DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0); +#endif + +#include +#include +#include "shortcut.h" + +HRESULT CreateALink(LPSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc, LPSTR lpszWorkingPath, LPSTR lpszArgs, LPSTR lpszIconFullPath, int iIcon) +{ + HRESULT hres; + IShellLink *psl; + char lpszFullPath[MAX_BUF]; + + lstrcpy(lpszFullPath, lpszPathLink); + lstrcat(lpszFullPath, "\\"); + lstrcat(lpszFullPath, lpszDesc); + lstrcat(lpszFullPath, ".lnk"); + + CreateDirectory(lpszPathLink, NULL); + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl); + if(SUCCEEDED(hres)) + { + IPersistFile* ppf; + + // Set the path to the shortcut target, and add the + // description. + psl->SetPath(lpszPathObj); + + // Do not set the description at this time. We need to fix this + // parameter so it can be passed in independent of the shortcut name + // itself. Comment this code out for now until a real fix can be done. + // psl->SetDescription(lpszDesc); + + if(lpszWorkingPath) + psl->SetWorkingDirectory(lpszWorkingPath); + if(lpszArgs) + psl->SetArguments(lpszArgs); + psl->SetIconLocation(lpszIconFullPath, iIcon); + + // Query IShellLink for the IPersistFile interface for saving the + // shortcut in persistent storage. + hres = psl->QueryInterface(IID_IPersistFile, (LPVOID FAR *)&ppf); + if(SUCCEEDED(hres)) + { + WORD wsz[MAX_BUF]; + + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, lpszFullPath, -1, (wchar_t *)wsz, MAX_BUF); + + // Save the link by calling IPersistFile::Save. + hres = ppf->Save((wchar_t *)wsz, TRUE); + ppf->Release(); + } + psl->Release(); + } + CoUninitialize(); + + return hres; +} diff --git a/toolkit/mozapps/installer/windows/wizard/setup/shortcut.h b/toolkit/mozapps/installer/windows/wizard/setup/shortcut.h new file mode 100644 index 00000000000..c626fcc99c3 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/shortcut.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _SHORTCUT_H_ +#define _SHORTCUT_H_ + +#ifndef MAX_BUF +#define MAX_BUF 4096 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +HRESULT CreateALink(LPSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc, LPSTR lpszWorkingPath, LPSTR lpszArgs, LPSTR lpszIconFullPath, int iIcon); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/toolkit/mozapps/installer/windows/wizard/setup/supersede.c b/toolkit/mozapps/installer/windows/wizard/setup/supersede.c new file mode 100644 index 00000000000..0c8a08d8924 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/supersede.c @@ -0,0 +1,467 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Sean Su + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "setup.h" +#include "extern.h" +#include "extra.h" +#include "ifuncns.h" +#include "supersede.h" + +void SaveGreInfo(grever *aGreInstalledListTmp, greInfo* aGre); +void ResolveSupersedeGre(siC *siCObject, greInfo *aGre); +HRESULT GetGreSupersedeVersionList(siC *siCObject, grever **aGreSupersedeList); +HRESULT GetGreInstalledVersionList(siC *siCObject, grever **aGreInstalledList); + +grever *CreateGVerNode() +{ + grever *gverNode; + + if((gverNode = NS_GlobalAlloc(sizeof(struct structGreVer))) == NULL) + return(NULL); + + gverNode->greHomePath[0] = '\0'; + gverNode->greInstaller[0] = '\0'; + gverNode->greUserAgent[0] = '\0'; + gverNode->version.ullMajor = 0; + gverNode->version.ullMinor = 0; + gverNode->version.ullRelease = 0; + gverNode->version.ullBuild = 0; + gverNode->next = NULL; + return(gverNode); +} + +void DeleteGverList(grever *gverHead) +{ + grever *tmp; + + while(gverHead != NULL) + { + tmp = gverHead; + gverHead = gverHead->next; + FreeMemory(&tmp); + } +} + +/* function to build a linked list of GRE supersede versions */ +HRESULT GetGreSupersedeVersionList(siC *siCObject, grever **aGreSupersedeList) +{ + grever *gverTmp = NULL; + grever *gverTail = NULL; + char key[MAX_BUF_TINY]; + char versionString[MAX_BUF_TINY]; + DWORD index; + + if(*aGreSupersedeList) + /* list already built, just return */ + return(WIZ_OK); + + index = 0; + wsprintf(key, "SupersedeVersion%d", index); + GetPrivateProfileString(siCObject->szReferenceName, key, "", versionString, + sizeof(versionString), szFileIniConfig); + while(*versionString != '\0') + { + gverTmp = CreateGVerNode(); + if(!gverTmp) + // error has already been displayed. + exit(WIZ_OUT_OF_MEMORY); + + TranslateVersionStr(versionString, &gverTmp->version); + if(*aGreSupersedeList == NULL) + { + /* brand new list */ + *aGreSupersedeList = gverTmp; + gverTail = *aGreSupersedeList; + } + else if(gverTail) + { + /* append the new node to the end of the list */ + gverTail->next = gverTmp; + gverTail = gverTail->next; + } + + wsprintf(key, "SupersedeVersion%d", ++index); + GetPrivateProfileString(siCObject->szReferenceName, key, "", versionString, + sizeof(versionString), szFileIniConfig); + } + return(WIZ_OK); +} + +/* function to build a list of GRE's installed on the local system */ +HRESULT GetGreInstalledVersionList(siC *siCObject, grever **aGreInstalledList) +{ + DWORD index; + DWORD enumIndex; + DWORD greVersionKeyLen; + grever *gverTmp = NULL; + grever *gverTail = NULL; + char szSupersedeWinRegPath[MAX_BUF]; + char key[MAX_BUF_TINY]; + char greVersionKey[MAX_BUF_TINY]; + char subKey[MAX_BUF]; + char subKeyInstaller[MAX_BUF]; + char szBuf[MAX_BUF]; + char greXpcomPath[MAX_BUF]; + char greXpcomFile[MAX_BUF]; + int greXpcomPathLen; + char xpcomFilename[] = "xpcom.dll"; + char greKeyPath[MAX_BUF]; + verBlock vbInstalledVersion; + HKEY hkeyRoot = NULL; + HKEY hkGreKeyParentPath = NULL; + HKEY hkGreKeyPath = NULL; + LONG rv; + + if(*aGreInstalledList) + /* list already built, just return */ + return(WIZ_OK); + + index = 0; + wsprintf(key, "SupersedeWinReg%d", index); + GetPrivateProfileString(siCObject->szReferenceName, key, "", szSupersedeWinRegPath, + sizeof(szSupersedeWinRegPath), szFileIniConfig); + while(*szSupersedeWinRegPath != '\0') + { + BOOL skip = FALSE; + if(!GetKeyInfo(szSupersedeWinRegPath, szBuf, sizeof(szBuf), KEY_INFO_ROOT)) + // Malformed windows registry key, continue to reading the next key. + skip = TRUE; + + hkeyRoot = ParseRootKey(szBuf); + if(!GetKeyInfo(szSupersedeWinRegPath, subKey, sizeof(subKey), KEY_INFO_SUBKEY)) + // Malformed windows registry key, continue to reading the next key. + skip = TRUE; + + if(RegOpenKeyEx(hkeyRoot, subKey, 0, KEY_READ, &hkGreKeyParentPath) != ERROR_SUCCESS) + // Problems opening the registry key. Ignore and continue reading the next key. + skip = TRUE; + + greVersionKeyLen = sizeof(greVersionKey); + enumIndex = 0; + while(!skip && + (RegEnumKeyEx(hkGreKeyParentPath, enumIndex++, greVersionKey, &greVersionKeyLen, + NULL, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)) + { + sprintf(greKeyPath, "%s\\%s", subKey, greVersionKey); + if(RegOpenKeyEx(hkeyRoot, greKeyPath, 0, KEY_READ, &hkGreKeyPath) != ERROR_SUCCESS) + // Encoutered problems trying to open key. Just continue. + // We don't care about any errors. If we can't open the key, + // we just go on to other keys. These errors are nonfatal. + continue; + + greXpcomPathLen = sizeof(greXpcomPath); + rv = RegQueryValueEx(hkGreKeyPath, "GreHome", 0, NULL, (BYTE *)greXpcomPath, &greXpcomPathLen); + RegCloseKey(hkGreKeyPath); + + if(rv != ERROR_SUCCESS) + // Encoutered problems trying to read a var name. Just continue. + // We don't care about any errors. If we can't open the key, + // we just go on to other keys. These errors are nonfatal. + continue; + + if(MozCopyStr(greXpcomPath, greXpcomFile, sizeof(greXpcomFile))) + { + RegCloseKey(hkGreKeyParentPath); + PrintError(szEOutOfMemory, ERROR_CODE_HIDE); + exit(WIZ_OUT_OF_MEMORY); + } + + if(sizeof(greXpcomFile) <= lstrlen(greXpcomFile) + sizeof(xpcomFilename) + 1) + { + RegCloseKey(hkGreKeyParentPath); + PrintError(szEOutOfMemory, ERROR_CODE_HIDE); + exit(WIZ_OUT_OF_MEMORY); + } + + AppendBackSlash(greXpcomFile, sizeof(greXpcomFile)); + lstrcat(greXpcomFile, xpcomFilename); + + if(GetFileVersion(greXpcomFile, &vbInstalledVersion)) + { + // Don't create a node list unless xpcom.dll file actually exists. + gverTmp = CreateGVerNode(); + if(!gverTmp) + { + RegCloseKey(hkGreKeyParentPath); + // error has already been displayed. + exit(WIZ_OUT_OF_MEMORY); + } + + if(MozCopyStr(greXpcomPath, gverTmp->greHomePath, sizeof(gverTmp->greHomePath))) + { + RegCloseKey(hkGreKeyParentPath); + PrintError(szEOutOfMemory, ERROR_CODE_HIDE); + exit(WIZ_OUT_OF_MEMORY); + } + + gverTmp->version.ullMajor = vbInstalledVersion.ullMajor; + gverTmp->version.ullMinor = vbInstalledVersion.ullMinor; + gverTmp->version.ullRelease = vbInstalledVersion.ullRelease; + gverTmp->version.ullBuild = vbInstalledVersion.ullBuild; + if(*aGreInstalledList == NULL) + { + /* brand new list */ + *aGreInstalledList = gverTmp; + gverTail = *aGreInstalledList; + } + else if(gverTail) + { + /* append the new node to the end of the list */ + gverTail->next = gverTmp; + gverTail = gverTail->next; + } + + /* get the GRE's installer app path */ + sprintf(subKeyInstaller, "%s\\%s\\Installer", subKey, greVersionKey); + GetWinReg(hkeyRoot, subKeyInstaller, "PathToExe", gverTmp->greInstaller, sizeof(gverTmp->greInstaller)); + MozCopyStr(greVersionKey, gverTmp->greUserAgent, sizeof(gverTmp->greUserAgent)); + } + + greVersionKeyLen = sizeof(greVersionKey); + } + + if(hkGreKeyParentPath) + { + RegCloseKey(hkGreKeyParentPath); + hkGreKeyParentPath = NULL; + } + + ++index; + wsprintf(key, "SupersedeWinReg%d", index); + GetPrivateProfileString(siCObject->szReferenceName, key, "", szSupersedeWinRegPath, sizeof(szSupersedeWinRegPath), szFileIniConfig); + } + return(WIZ_OK); +} + +void SaveGreInfo(grever *aGreInstalledListTmp, greInfo* aGre) +{ + MozCopyStr(aGreInstalledListTmp->greInstaller, aGre->installerAppPath, sizeof(aGre->installerAppPath)); + MozCopyStr(aGreInstalledListTmp->greUserAgent, aGre->userAgent, sizeof(aGre->userAgent)); + MozCopyStr(aGreInstalledListTmp->greHomePath, aGre->homePath, sizeof(aGre->homePath)); +} + +void ResolveSupersedeGre(siC *siCObject, greInfo *aGre) +{ + grever *greSupersedeListTmp = NULL; + grever *greInstalledListTmp = NULL; + char versionStr[MAX_BUF_TINY]; + siC *siCTmp = NULL; + BOOL foundVersionWithinRange = FALSE; + BOOL minVerRead = FALSE; + BOOL maxVerRead = FALSE; + BOOL stillInRange = FALSE; + + if(GetGreSupersedeVersionList(siCObject, &aGre->greSupersedeList)) + return; + if(GetGreInstalledVersionList(siCObject, &aGre->greInstalledList)) + return; + if(!aGre->greSupersedeList || !aGre->greInstalledList) + // nothing to compare, return + return; + + GetPrivateProfileString(siCObject->szReferenceName, "SupersedeMinVersion", "", + versionStr, sizeof(versionStr), szFileIniConfig); + if(*versionStr != '\0') + { + TranslateVersionStr(versionStr, &aGre->minVersion); + minVerRead = TRUE; + } + + GetPrivateProfileString(siCObject->szReferenceName, "SupersedeMaxVersion", "", + versionStr, sizeof(versionStr), szFileIniConfig); + if(*versionStr != '\0') + { + TranslateVersionStr(versionStr, &aGre->maxVersion); + maxVerRead = TRUE; + } + + + // do the version comparison here. + greInstalledListTmp = aGre->greInstalledList; + while(greInstalledListTmp) + { + greSupersedeListTmp = aGre->greSupersedeList; + while(greSupersedeListTmp) + { + if(CompareVersion(greInstalledListTmp->version, greSupersedeListTmp->version) == 0) + { + SaveGreInfo(greInstalledListTmp, aGre); + siCObject->bSupersede = TRUE; + aGre->siCGreComponent = siCObject; + break; + } + else if(!foundVersionWithinRange && (minVerRead || maxVerRead)) + { + stillInRange = TRUE; + + if(minVerRead) + stillInRange = CompareVersion(greInstalledListTmp->version, aGre->minVersion) >= 0; + + if(stillInRange && maxVerRead) + stillInRange = CompareVersion(greInstalledListTmp->version, aGre->maxVersion) <= 0; + + if(stillInRange) + { + // Find the first version within the range. + SaveGreInfo(greInstalledListTmp, aGre); + foundVersionWithinRange = TRUE; + } + } + greSupersedeListTmp = greSupersedeListTmp->next; + } + + if(siCObject->bSupersede) + break; + + greInstalledListTmp = greInstalledListTmp->next; + } + + if(!siCObject->bSupersede && foundVersionWithinRange) + siCObject->bSupersede = TRUE; + + if(siCObject->bSupersede) + { + siCObject->dwAttributes &= ~SIC_SELECTED; + siCObject->dwAttributes |= SIC_DISABLED; + siCObject->dwAttributes |= SIC_INVISIBLE; + } + else + /* Make sure to unset the DISABLED bit. If the Setup Type is other than + * Custom, then we don't care if it's DISABLED or not because this flag + * is only used in the Custom dialogs. + * + * If the Setup Type is Custom and this component is DISABLED by default + * via the config.ini, it's default value will be restored in the + * SiCNodeSetItemsSelected() function that called ResolveSupersede(). */ + siCObject->dwAttributes &= ~SIC_DISABLED; +} + +BOOL ResolveSupersede(siC *siCObject, greInfo *aGre) +{ + DWORD dwIndex; + char szFilePath[MAX_BUF]; + char szSupersedeFile[MAX_BUF]; + char szSupersedeVersion[MAX_BUF]; + char szType[MAX_BUF_TINY]; + char szKey[MAX_BUF_TINY]; + verBlock vbVersionNew; + verBlock vbFileVersion; + + siCObject->bSupersede = FALSE; + if(siCObject->dwAttributes & SIC_SUPERSEDE) + { + dwIndex = 0; + GetPrivateProfileString(siCObject->szReferenceName, "SupersedeType", "", szType, sizeof(szType), szFileIniConfig); + if(*szType !='\0') + { + if(lstrcmpi(szType, "File Exists") == 0) + { + wsprintf(szKey, "SupersedeFile%d", dwIndex); + GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szSupersedeFile, sizeof(szSupersedeFile), szFileIniConfig); + while(*szSupersedeFile != '\0') + { + DecryptString(szFilePath, szSupersedeFile); + if(FileExists(szFilePath)) + { + wsprintf(szKey, "SupersedeMinVersion%d",dwIndex); + GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szSupersedeVersion, sizeof(szSupersedeVersion), szFileIniConfig); + if(*szSupersedeVersion != '\0') + { + if(GetFileVersion(szFilePath,&vbFileVersion)) + { + /* If we can get the version, and it is greater than or equal to the SupersedeVersion + * set supersede. If we cannot get the version, do not supersede the file. */ + TranslateVersionStr(szSupersedeVersion, &vbVersionNew); + if(CompareVersion(vbFileVersion,vbVersionNew) >= 0) + { + siCObject->bSupersede = TRUE; + break; /* Found at least one file, so break out of while loop */ + } + } + } + else + { /* The file exists, and there's no version to check. set Supersede */ + siCObject->bSupersede = TRUE; + break; /* Found at least one file, so break out of while loop */ + } + } + wsprintf(szKey, "SupersedeFile%d", ++dwIndex); + GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szSupersedeFile, sizeof(szSupersedeFile), szFileIniConfig); + } + } + else if(lstrcmpi(szType, "GRE") == 0) + { + /* save the GRE component */ + aGre->siCGreComponent = siCObject; + + /* If -fgre is passed in, and the current product to install is !GRE, + * and the current component is 'Component GRE' then select and + * disable it to force it to be installed regardless of supersede + * rules. + * + * If the product is GRE, then it won't have a 'Component GRE', but + * rather a 'Component XPCOM', in which case it will always get + * installed */ + if((gbForceInstallGre) && (lstrcmpi(sgProduct.szProductNameInternal, "GRE") != 0)) + { + siCObject->dwAttributes |= SIC_SELECTED; + siCObject->dwAttributes |= SIC_DISABLED; + } + else + ResolveSupersedeGre(siCObject, aGre); + } + } + + if(siCObject->bSupersede) + { + siCObject->dwAttributes &= ~SIC_SELECTED; + siCObject->dwAttributes |= SIC_DISABLED; + siCObject->dwAttributes |= SIC_INVISIBLE; + } + else + /* Make sure to unset the DISABLED bit. If the Setup Type is other than + * Custom, then we don't care if it's DISABLED or not because this flag + * is only used in the Custom dialogs. + * + * If the Setup Type is Custom and this component is DISABLED by default + * via the config.ini, it's default value will be restored in the + * SiCNodeSetItemsSelected() function that called ResolveSupersede(). */ + siCObject->dwAttributes &= ~SIC_DISABLED; + } + return(siCObject->bSupersede); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/supersede.h b/toolkit/mozapps/installer/windows/wizard/setup/supersede.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setup/version.c b/toolkit/mozapps/installer/windows/wizard/setup/version.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setup/version.h b/toolkit/mozapps/installer/windows/wizard/setup/version.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setup/wizverreg.h b/toolkit/mozapps/installer/windows/wizard/setup/wizverreg.h new file mode 100644 index 00000000000..4f38faf04d0 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/wizverreg.h @@ -0,0 +1,31 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 1998, 1999, 2000, 2001 Netscape Communications Corp. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _WIZVERREG_H_ +#define _WIZVERREG_H_ + +int VR_CreateRegistry(char *installation, char *programPath, char *versionStr); +int VR_Install(char *component_path, char *filepath, char *version, int bDirectory); +int VR_Close(void); + +#endif /* _WIZVERREG_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/xperr.h b/toolkit/mozapps/installer/windows/wizard/setup/xperr.h new file mode 100644 index 00000000000..d3ff2b8e67c --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/xperr.h @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _XPERR_H_ +#define _XPERR_H_ + +char *XpErrorList[] = {"0" , "OK", + "-200", "BAD_PACKAGE_NAME", + "-201", "UNEXPECTED_ERROR", + "-202", "ACCESS_DENIED", + "-203", "TOO_MANY_CERTIFICATES", + "-204", "NO_INSTALL_SCRIPT", + "-205", "NO_CERTIFICATE", + "-206", "NO_MATCHING_CERTIFICATE", + "-207", "CANT_READ_ARCHIVE", + "-208", "INVALID_ARGUMENTS", + "-209", "ILLEGAL_RELATIVE_PATH", + "-210", "USER_CANCELLED", + "-211", "INSTALL_NOT_STARTED", + "-212", "SILENT_MODE_DENIED", + "-213", "NO_SUCH_COMPONENT", + "-214", "DOES_NOT_EXIST", + "-215", "READ_ONLY", + "-216", "IS_DIRECTORY", + "-217", "NETWORK_FILE_IS_IN_USE", + "-218", "APPLE_SINGLE_ERR", + "-219", "INVALID_PATH_ERR", + "-220", "PATCH_BAD_DIFF", + "-221", "PATCH_BAD_CHECKSUM_TARGET", + "-222", "PATCH_BAD_CHECKSUM_RESULT", + "-223", "UNINSTALL_FAILED", + "-224", "PACKAGE_FOLDER_NOT_SET", + "-225", "EXTRACTION_FAILED", + "-226", "FILENAME_ALREADY_USED", + "-227", "ABORT_INSTALL", + "-228", "DOWNLOAD_ERROR", + "-229", "SCRIPT_ERROR", + "-230", "ALREADY_EXISTS", + "-231", "IS_FILE", + "-232", "SOURCE_DOES_NOT_EXIST", + "-233", "SOURCE_IS_DIRECTORY", + "-234", "SOURCE_IS_FILE", + "-235", "INSUFFICIENT_DISK_SPACE", + "-236", "FILENAME_TOO_LONG", + "-237", "UNABLE_TO_LOCATE_LIB_FUNCTION", + "-238", "UNABLE_TO_LOAD_LIBRARY", + "-239", "CHROME_REGISTRY_ERROR", + "-240", "MALFORMED_INSTALL", + "-241", "KEY_ACCESS_DENIED", + "-242", "KEY_DOES_NOT_EXIST", + "-243", "VALUE_DOES_NOT_EXIST", + "-299", "OUT_OF_MEMORY", + "-322", "INIT_STUB_ERROR", + "-5550", "GESTALT_UNKNOWN_ERR", + "-5551", "GESTALT_INVALID_ARGUMENT", + ""}; + +#endif /* _XPERR_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/xpi.c b/toolkit/mozapps/installer/windows/wizard/setup/xpi.c new file mode 100644 index 00000000000..53c3d585a93 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/xpi.c @@ -0,0 +1,832 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "extern.h" +#include "dialogs.h" +#include "extra.h" +#include "xpistub.h" +#include "xpi.h" +#include "xperr.h" +#include "logging.h" +#include "ifuncns.h" + +#define BDIR_RIGHT 1 +#define BDIR_LEFT 2 + +typedef HRESULT (_cdecl *XpiInit)(const char *, const char *aLogName, pfnXPIProgress); +typedef HRESULT (_cdecl *XpiInstall)(const char *, const char *, long); +typedef void (_cdecl *XpiExit)(void); +typedef BOOL (WINAPI *SetDllPathProc)(const char*); + +static XpiInit pfnXpiInit; +static XpiInstall pfnXpiInstall; +static XpiExit pfnXpiExit; +static SetDllPathProc pfnSetDllPath = NULL; + +static long lFileCounter; +static long lBarberCounter; +static BOOL bBarberBar; +static DWORD dwBarberDirection; +static DWORD dwCurrentArchive; +static DWORD dwTotalArchives; +char szStrProcessingFile[MAX_BUF]; +char szStrCopyingFile[MAX_BUF]; +char szStrInstalling[MAX_BUF]; +static char gSavedCwd[MAX_BUF]; + +static void UpdateGaugeFileProgressBar(unsigned value); +static void UpdateGaugeArchiveProgressBar(unsigned value); +static void UpdateGaugeFileBarber(void); + +struct ExtractFilesDlgInfo +{ + HWND hWndDlg; + int nMaxFileBars; // maximum number of bars that can be displayed + int nMaxArchiveBars; // maximum number of bars that can be displayed + int nFileBars; // current number of bars to display + int nArchiveBars; // current number of bars to display +} dlgInfo; + +HRESULT InitializeXPIStub(char *xpinstallPath) +{ + char szBuf[MAX_BUF]; + char szXPIStubFile[MAX_BUF]; + char szEGetProcAddress[MAX_BUF]; + HANDLE hKernel; + + hXPIStubInst = NULL; + GetCurrentDirectory(sizeof(gSavedCwd), gSavedCwd); + + if(!GetPrivateProfileString("Messages", "ERROR_GETPROCADDRESS", "", szEGetProcAddress, sizeof(szEGetProcAddress), szFileIniInstall)) + return(1); + + /* change current directory to where xpistub.dll */ + SetCurrentDirectory(xpinstallPath); + + /* Windows XP SP1 changed DLL search path strategy, setting current dir */ + /* is no longer sufficient. Use SetDLLDirectory() if available */ + if ((hKernel = LoadLibrary("kernel32.dll")) != NULL) + { + pfnSetDllPath = (SetDllPathProc)GetProcAddress(hKernel, "SetDllDirectoryA"); + if (pfnSetDllPath) + pfnSetDllPath(xpinstallPath); + } + + /* build full path to xpistub.dll */ + lstrcpy(szXPIStubFile, xpinstallPath); + AppendBackSlash(szXPIStubFile, sizeof(szXPIStubFile)); + lstrcat(szXPIStubFile, "xpistub.dll"); + + if(FileExists(szXPIStubFile) == FALSE) + return(2); + + /* load xpistub.dll */ + if((hXPIStubInst = LoadLibraryEx(szXPIStubFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) + { + wsprintf(szBuf, szEDllLoad, szXPIStubFile); + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + if(((FARPROC)pfnXpiInit = GetProcAddress(hXPIStubInst, "XPI_Init")) == NULL) + { + wsprintf(szBuf, szEGetProcAddress, "XPI_Init"); + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + if(((FARPROC)pfnXpiInstall = GetProcAddress(hXPIStubInst, "XPI_Install")) == NULL) + { + wsprintf(szBuf, szEGetProcAddress, "XPI_Install"); + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + if(((FARPROC)pfnXpiExit = GetProcAddress(hXPIStubInst, "XPI_Exit")) == NULL) + { + wsprintf(szBuf, szEGetProcAddress, "XPI_Exit"); + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + + return(0); +} + +HRESULT DeInitializeXPIStub() +{ + pfnXpiInit = NULL; + pfnXpiInstall = NULL; + pfnXpiExit = NULL; + + if(hXPIStubInst) + FreeLibrary(hXPIStubInst); + + chdir(szSetupDir); + if (pfnSetDllPath) + pfnSetDllPath(NULL); + + SetCurrentDirectory(gSavedCwd); + return(0); +} + +void GetTotalArchivesToInstall(void) +{ + DWORD dwIndex0; + siC *siCObject = NULL; + + dwIndex0 = 0; + dwTotalArchives = 0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if((siCObject->dwAttributes & SIC_SELECTED) && !(siCObject->dwAttributes & SIC_LAUNCHAPP)) + ++dwTotalArchives; + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } +} + +char *GetErrorString(DWORD dwError, char *szErrorString, DWORD dwErrorStringSize) +{ + int i = 0; + char szErrorNumber[MAX_BUF]; + + ZeroMemory(szErrorString, dwErrorStringSize); + itoa(dwError, szErrorNumber, 10); + + /* map the error value to a string */ + while(TRUE) + { + if(*XpErrorList[i] == '\0') + break; + + if(lstrcmpi(szErrorNumber, XpErrorList[i]) == 0) + { + if(*XpErrorList[i + 1] != '\0') + lstrcpy(szErrorString, XpErrorList[i + 1]); + + break; + } + + ++i; + } + + return(szErrorString); +} + +/* function that clears the file progress bar of the xpinstall progress + * dialog. + */ +void InvalidateBarberBarArea() +{ + HWND hWndGauge; + RECT rect; + + /* get the file progress bar gauge */ + hWndGauge = GetDlgItem(dlgInfo.hWndDlg, IDC_GAUGE_FILE); + /* get the dimensions of the gauge */ + GetClientRect(hWndGauge, &rect); + /* invalidate the rect area of the gauge */ + InvalidateRect(hWndGauge, &rect, FALSE); + /* update the dialog */ + UpdateWindow(dlgInfo.hWndDlg); +} + +HRESULT SmartUpdateJars() +{ + DWORD dwIndex0; + siC *siCObject = NULL; + HRESULT hrResult; + char szBuf[MAX_BUF]; + char szEXpiInstall[MAX_BUF]; + char szArchive[MAX_BUF]; + char szMsgSmartUpdateStart[MAX_BUF]; + char szDlgExtractingTitle[MAX_BUF]; + char xpinstallPath[MAX_BUF]; + char xpiArgs[MAX_BUF]; + + if(!GetPrivateProfileString("Messages", "MSG_SMARTUPDATE_START", "", szMsgSmartUpdateStart, sizeof(szMsgSmartUpdateStart), szFileIniInstall)) + return(1); + if(!GetPrivateProfileString("Messages", "DLG_EXTRACTING_TITLE", "", szDlgExtractingTitle, sizeof(szDlgExtractingTitle), szFileIniInstall)) + return(1); + if(!GetPrivateProfileString("Messages", "STR_PROCESSINGFILE", "", szStrProcessingFile, sizeof(szStrProcessingFile), szFileIniInstall)) + exit(1); + if(!GetPrivateProfileString("Messages", "STR_INSTALLING", "", szStrInstalling, sizeof(szStrInstalling), szFileIniInstall)) + exit(1); + if(!GetPrivateProfileString("Messages", "STR_COPYINGFILE", "", szStrCopyingFile, sizeof(szStrCopyingFile), szFileIniInstall)) + exit(1); + + ShowMessage(szMsgSmartUpdateStart, TRUE); + GetXpinstallPath(xpinstallPath, sizeof(xpinstallPath)); + if(InitializeXPIStub(xpinstallPath) == WIZ_OK) + { + LogISXPInstall(W_START); + lstrcpy(szBuf, sgProduct.szPath); + if(*sgProduct.szSubPath != '\0') + { + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, sgProduct.szSubPath); + } + hrResult = pfnXpiInit(szBuf, FILE_INSTALL_LOG, cbXPIProgress); + + ShowMessage(szMsgSmartUpdateStart, FALSE); + InitProgressDlg(); + GetTotalArchivesToInstall(); + SetWindowText(dlgInfo.hWndDlg, szDlgExtractingTitle); + + dwIndex0 = 0; + dwCurrentArchive = 0; + dwTotalArchives = (dwTotalArchives * 2) + 1; + bBarberBar = FALSE; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + while(siCObject) + { + if(siCObject->dwAttributes & SIC_SELECTED) + /* Since the archive is selected, we need to process the file ops here */ + ProcessFileOps(T_PRE_ARCHIVE, siCObject->szReferenceName); + + /* launch smartupdate engine for earch jar to be installed */ + if((siCObject->dwAttributes & SIC_SELECTED) && + !(siCObject->dwAttributes & SIC_LAUNCHAPP) && + !(siCObject->dwAttributes & SIC_DOWNLOAD_ONLY)) + { + lFileCounter = 0; + lBarberCounter = 0; + dwBarberDirection = BDIR_RIGHT; + dlgInfo.nFileBars = 0; + UpdateGaugeFileProgressBar(0); + + lstrcpy(szArchive, sgProduct.szAlternateArchiveSearchPath); + AppendBackSlash(szArchive, sizeof(szArchive)); + lstrcat(szArchive, siCObject->szArchiveName); + if((*sgProduct.szAlternateArchiveSearchPath == '\0') || (!FileExists(szArchive))) + { + lstrcpy(szArchive, szSetupDir); + AppendBackSlash(szArchive, sizeof(szArchive)); + lstrcat(szArchive, siCObject->szArchiveName); + if(!FileExists(szArchive)) + { + lstrcpy(szArchive, szTempDir); + AppendBackSlash(szArchive, sizeof(szArchive)); + lstrcat(szArchive, siCObject->szArchiveName); + if(!FileExists(szArchive)) + { + char szEFileNotFound[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall)) + { + wsprintf(szBuf, szEFileNotFound, szArchive); + PrintError(szBuf, ERROR_CODE_HIDE); + } + return(1); + } + } + } + + if(dwCurrentArchive == 0) + { + ++dwCurrentArchive; + UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); + UpdateGREAppInstallerProgress((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); + } + + wsprintf(szBuf, szStrInstalling, siCObject->szDescriptionShort); + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS0, szBuf); + LogISXPInstallComponent(siCObject->szDescriptionShort); + + /* XXX fix: we need to better support passing arguments to .xpi files. + * This is a temporary hack to get greType passed to browser.xpi so that + * it won't delete GRE files if GRE is installed in the mozilla dir. + * + * What should be done is have the arguments be described in each + * component's section in config.ini and have it passed thru here. */ + *xpiArgs = '\0'; + if(lstrcmpi(siCObject->szArchiveName, "gre.xpi") == 0) + MozCopyStr(sgProduct.szRegPath, xpiArgs, sizeof(xpiArgs)); + else if((lstrcmpi(siCObject->szArchiveName, "browser.xpi") == 0) && + (sgProduct.greType == GRE_LOCAL)) + /* passing -greShared to browser.xpi will tell it to cleanup GRE files + * from it's directory if they exist. */ + MozCopyStr("-greLocal", xpiArgs, sizeof(xpiArgs)); + + hrResult = pfnXpiInstall(szArchive, xpiArgs, 0xFFFF); + if(hrResult == E_REBOOT) + bReboot = TRUE; + else if((hrResult != WIZ_OK) && + !(siCObject->dwAttributes & SIC_IGNORE_XPINSTALL_ERROR)) + { + LogMSXPInstallStatus(siCObject->szArchiveName, hrResult); + LogISXPInstallComponentResult(hrResult); + if(GetPrivateProfileString("Messages", "ERROR_XPI_INSTALL", "", szEXpiInstall, sizeof(szEXpiInstall), szFileIniInstall)) + { + char szErrorString[MAX_BUF]; + + GetErrorString(hrResult, szErrorString, sizeof(szErrorString)); + wsprintf(szBuf, "%s - %s: %d %s", szEXpiInstall, siCObject->szDescriptionShort, hrResult, szErrorString); + PrintError(szBuf, ERROR_CODE_HIDE); + } + + /* break out of the siCObject while loop */ + break; + } + + ++dwCurrentArchive; + UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); + UpdateGREAppInstallerProgress((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); + + ProcessWindowsMessages(); + LogISXPInstallComponentResult(hrResult); + + if((hrResult != WIZ_OK) && + (siCObject->dwAttributes & SIC_IGNORE_XPINSTALL_ERROR)) + /* reset the result to WIZ_OK if there was an error and the + * component's attributes contains SIC_IGNORE_XPINSTALL_ERROR. + * This should be done after LogISXPInstallComponentResult() + * because we still should log the error value. */ + hrResult = WIZ_OK; + } + + if(siCObject->dwAttributes & SIC_SELECTED) + /* Since the archive is selected, we need to do the file ops here */ + ProcessFileOps(T_POST_ARCHIVE, siCObject->szReferenceName); + + ++dwIndex0; + siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); + } /* while(siCObject) */ + + //report 100% progress status for successful installs + UpdateGREAppInstallerProgress(100); + LogMSXPInstallStatus(NULL, hrResult); + pfnXpiExit(); + DeInitProgressDlg(); + } + else + { + ShowMessage(szMsgSmartUpdateStart, FALSE); + } + + DeInitializeXPIStub(); + LogISXPInstall(W_END); + + return(hrResult); +} + +void cbXPIStart(const char *URL, const char *UIName) +{ +} + +void cbXPIProgress(const char* msg, PRInt32 val, PRInt32 max) +{ + char szFilename[MAX_BUF]; + char szStrProcessingFileBuf[MAX_BUF]; + char szStrCopyingFileBuf[MAX_BUF]; + + if(sgProduct.mode != SILENT) + { + ParsePath((char *)msg, szFilename, sizeof(szFilename), FALSE, PP_FILENAME_ONLY); + + if(max == 0) + { + wsprintf(szStrProcessingFileBuf, szStrProcessingFile, szFilename); + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS3, szStrProcessingFileBuf); + bBarberBar = TRUE; + UpdateGaugeFileBarber(); + } + else + { + if(bBarberBar == TRUE) + { + dlgInfo.nFileBars = 0; + ++dwCurrentArchive; + UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); + UpdateGREAppInstallerProgress((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); + + InvalidateBarberBarArea(); + bBarberBar = FALSE; + } + + wsprintf(szStrCopyingFileBuf, szStrCopyingFile, szFilename); + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS3, szStrCopyingFileBuf); + UpdateGaugeFileProgressBar((unsigned)(((double)(val+1)/(double)max)*(double)100)); + } + } + + ProcessWindowsMessages(); +} + +void cbXPIFinal(const char *URL, PRInt32 finalStatus) +{ +} + + + +///////////////////////////////////////////////////////////////////////////// +// Progress bar + +// Window proc for dialog +LRESULT CALLBACK +ProgressDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + DisableSystemMenuItems(hWndDlg, TRUE); + RepositionWindow(hWndDlg, BANNER_IMAGE_INSTALLING); + SendDlgItemMessage (hWndDlg, IDC_STATUS0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_GAUGE_ARCHIVE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATUS3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_GAUGE_FILE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + return FALSE; + + case WM_COMMAND: + return TRUE; + } + + return FALSE; // didn't handle the message +} + +// This routine will update the File Gauge progress bar to the specified percentage +// (value between 0 and 100) +static void +UpdateGaugeFileBarber() +{ + int nBars; + HWND hWndGauge; + RECT rect; + + if(sgProduct.mode != SILENT) + { + hWndGauge = GetDlgItem(dlgInfo.hWndDlg, IDC_GAUGE_FILE); + if(dwBarberDirection == BDIR_RIGHT) + { + // 121 is the (number of bars) + (number bars in barber bar). + // this number determines how far to the right to draw the barber bat + // so as to make it look like it disappears off the progress meter area. + if(lBarberCounter < 121) + ++lBarberCounter; + else + dwBarberDirection = BDIR_LEFT; + } + else if(dwBarberDirection == BDIR_LEFT) + { + if(lBarberCounter > 0) + --lBarberCounter; + else + dwBarberDirection = BDIR_RIGHT; + } + + // Figure out how many bars should be displayed + nBars = (dlgInfo.nMaxFileBars * lBarberCounter / 100); + + // Update the gauge state before painting + dlgInfo.nFileBars = nBars; + + // Only invalidate the part that needs updating + GetClientRect(hWndGauge, &rect); + InvalidateRect(hWndGauge, &rect, FALSE); + + // Update the whole extracting dialog. We do this because we don't + // have a message loop to process WM_PAINT messages in case the + // extracting dialog was exposed + UpdateWindow(dlgInfo.hWndDlg); + } +} + +// This routine will update the File Gauge progress bar to the specified percentage +// (value between 0 and 100) +static void +UpdateGaugeFileProgressBar(unsigned value) +{ + int nBars; + + if(sgProduct.mode != SILENT) + { + // Figure out how many bars should be displayed + nBars = dlgInfo.nMaxFileBars * value / 100; + + // Only paint if we need to display more bars + if((nBars > dlgInfo.nFileBars) || (dlgInfo.nFileBars == 0)) + { + HWND hWndGauge = GetDlgItem(dlgInfo.hWndDlg, IDC_GAUGE_FILE); + RECT rect; + + // Update the gauge state before painting + dlgInfo.nFileBars = nBars; + + // Only invalidate the part that needs updating + GetClientRect(hWndGauge, &rect); + InvalidateRect(hWndGauge, &rect, FALSE); + + // Update the whole extracting dialog. We do this because we don't + // have a message loop to process WM_PAINT messages in case the + // extracting dialog was exposed + UpdateWindow(dlgInfo.hWndDlg); + } + } +} + +// This routine will update the Archive Gauge progress bar to the specified percentage +// (value between 0 and 100) +static void +UpdateGaugeArchiveProgressBar(unsigned value) +{ + int nBars; + + if(sgProduct.mode != SILENT) + { + // Figure out how many bars should be displayed + nBars = dlgInfo.nMaxArchiveBars * value / 100; + + // Only paint if we need to display more bars + if (nBars > dlgInfo.nArchiveBars) + { + HWND hWndGauge = GetDlgItem(dlgInfo.hWndDlg, IDC_GAUGE_ARCHIVE); + RECT rect; + + // Update the gauge state before painting + dlgInfo.nArchiveBars = nBars; + + // Only invalidate the part that needs updating + GetClientRect(hWndGauge, &rect); + InvalidateRect(hWndGauge, &rect, FALSE); + + // Update the whole extracting dialog. We do this because we don't + // have a message loop to process WM_PAINT messages in case the + // extracting dialog was exposed + UpdateWindow(dlgInfo.hWndDlg); + } + } +} + +// Draws a recessed border around the gauge +static void +DrawGaugeBorder(HWND hWnd) +{ + HDC hDC = GetWindowDC(hWnd); + RECT rect; + int cx, cy; + HPEN hShadowPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); + HGDIOBJ hOldPen; + + GetWindowRect(hWnd, &rect); + cx = rect.right - rect.left; + cy = rect.bottom - rect.top; + + // Draw a dark gray line segment + hOldPen = SelectObject(hDC, (HGDIOBJ)hShadowPen); + MoveToEx(hDC, 0, cy - 1, NULL); + LineTo(hDC, 0, 0); + LineTo(hDC, cx - 1, 0); + + // Draw a white line segment + SelectObject(hDC, GetStockObject(WHITE_PEN)); + MoveToEx(hDC, 0, cy - 1, NULL); + LineTo(hDC, cx - 1, cy - 1); + LineTo(hDC, cx - 1, 0); + + SelectObject(hDC, hOldPen); + DeleteObject(hShadowPen); + ReleaseDC(hWnd, hDC); +} + +// Draws the blue progress bar +static void +DrawProgressBar(HWND hWnd, int nBars) +{ + int i; + PAINTSTRUCT ps; + HDC hDC; + RECT rect; + HBRUSH hBrush; + + hDC = BeginPaint(hWnd, &ps); + GetClientRect(hWnd, &rect); + if(nBars <= 0) + { + /* clear the bars */ + hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU)); + FillRect(hDC, &rect, hBrush); + } + else + { + // Draw the bars + hBrush = CreateSolidBrush(RGB(0, 0, 128)); + rect.left = rect.top = BAR_MARGIN; + rect.bottom -= BAR_MARGIN; + rect.right = rect.left + BAR_WIDTH; + + for(i = 0; i < nBars; i++) + { + RECT dest; + + if(IntersectRect(&dest, &ps.rcPaint, &rect)) + FillRect(hDC, &rect, hBrush); + + OffsetRect(&rect, BAR_WIDTH + BAR_SPACING, 0); + } + } + + DeleteObject(hBrush); + EndPaint(hWnd, &ps); +} + +// Draws the blue progress bar +static void +DrawBarberBar(HWND hWnd, int nBars) +{ + int i; + PAINTSTRUCT ps; + HDC hDC; + RECT rect; + HBRUSH hBrush = NULL; + HBRUSH hBrushClear = NULL; + + hDC = BeginPaint(hWnd, &ps); + GetClientRect(hWnd, &rect); + if(nBars <= 0) + { + /* clear the bars */ + hBrushClear = CreateSolidBrush(GetSysColor(COLOR_MENU)); + FillRect(hDC, &rect, hBrushClear); + } + else + { + // Draw the bars + hBrushClear = CreateSolidBrush(GetSysColor(COLOR_MENU)); + hBrush = CreateSolidBrush(RGB(0, 0, 128)); + rect.left = rect.top = BAR_MARGIN; + rect.bottom -= BAR_MARGIN; + rect.right = rect.left + BAR_WIDTH; + + for(i = 0; i < (nBars + 1); i++) + { + RECT dest; + + if(IntersectRect(&dest, &ps.rcPaint, &rect)) + { + if((i >= (nBars - 15)) && (i < nBars)) + FillRect(hDC, &rect, hBrush); + else + FillRect(hDC, &rect, hBrushClear); + } + + OffsetRect(&rect, BAR_WIDTH + BAR_SPACING, 0); + } + } + + if(hBrushClear) + DeleteObject(hBrushClear); + + if(hBrush) + DeleteObject(hBrush); + + EndPaint(hWnd, &ps); +} + +// Adjusts the width of the gauge based on the maximum number of bars +static void +SizeToFitGauge(HWND hWnd, int nMaxBars) +{ + RECT rect; + int cx; + + // Get the window size in pixels + GetWindowRect(hWnd, &rect); + + // Size the width to fit + cx = 2 * GetSystemMetrics(SM_CXBORDER) + 2 * BAR_MARGIN + + nMaxBars * BAR_WIDTH + (nMaxBars - 1) * BAR_SPACING; + + SetWindowPos(hWnd, NULL, -1, -1, cx, rect.bottom - rect.top, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); +} + +// Window proc for file gauge +LRESULT CALLBACK +GaugeFileWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DWORD dwStyle; + RECT rect; + + switch(msg) + { + case WM_NCCREATE: + dwStyle = GetWindowLong(hWnd, GWL_STYLE); + SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_BORDER); + return(TRUE); + + case WM_CREATE: + // Figure out the maximum number of bars that can be displayed + GetClientRect(hWnd, &rect); + dlgInfo.nFileBars = 0; + dlgInfo.nMaxFileBars = (rect.right - rect.left - 2 * BAR_MARGIN + BAR_SPACING) / (BAR_WIDTH + BAR_SPACING); + + // Size the gauge to exactly fit the maximum number of bars + SizeToFitGauge(hWnd, dlgInfo.nMaxFileBars); + return(FALSE); + + case WM_NCPAINT: + DrawGaugeBorder(hWnd); + return(FALSE); + + case WM_PAINT: + if(bBarberBar == TRUE) + DrawBarberBar(hWnd, dlgInfo.nFileBars); + else + DrawProgressBar(hWnd, dlgInfo.nFileBars); + + return(FALSE); + } + + return(DefWindowProc(hWnd, msg, wParam, lParam)); +} + +// Window proc for file gauge +LRESULT CALLBACK +GaugeArchiveWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DWORD dwStyle; + RECT rect; + + switch(msg) + { + case WM_NCCREATE: + dwStyle = GetWindowLong(hWnd, GWL_STYLE); + SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_BORDER); + return(TRUE); + + case WM_CREATE: + // Figure out the maximum number of bars that can be displayed + GetClientRect(hWnd, &rect); + dlgInfo.nArchiveBars = 0; + dlgInfo.nMaxArchiveBars = (rect.right - rect.left - 2 * BAR_MARGIN + BAR_SPACING) / (BAR_WIDTH + BAR_SPACING); + + // Size the gauge to exactly fit the maximum number of bars + SizeToFitGauge(hWnd, dlgInfo.nMaxArchiveBars); + return(FALSE); + + case WM_NCPAINT: + DrawGaugeBorder(hWnd); + return(FALSE); + + case WM_PAINT: + DrawProgressBar(hWnd, dlgInfo.nArchiveBars); + return(FALSE); + } + + return(DefWindowProc(hWnd, msg, wParam, lParam)); +} + +void InitProgressDlg() +{ + WNDCLASS wc; + + if(sgProduct.mode != SILENT) + { + memset(&wc, 0, sizeof(wc)); + wc.style = CS_GLOBALCLASS; + wc.hInstance = hInst; + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpfnWndProc = (WNDPROC)GaugeFileWndProc; + wc.lpszClassName = "GaugeFile"; + RegisterClass(&wc); + + wc.lpfnWndProc = (WNDPROC)GaugeArchiveWndProc; + wc.lpszClassName = "GaugeArchive"; + RegisterClass(&wc); + + // Display the dialog box + dlgInfo.hWndDlg = CreateDialog(hSetupRscInst, MAKEINTRESOURCE(DLG_EXTRACTING), hWndMain, (WNDPROC)ProgressDlgProc); + UpdateWindow(dlgInfo.hWndDlg); + } +} + +void DeInitProgressDlg() +{ + if(sgProduct.mode != SILENT) + { + SaveWindowPosition(dlgInfo.hWndDlg); + DestroyWindow(dlgInfo.hWndDlg); + UnregisterClass("GaugeFile", hInst); + UnregisterClass("GaugeArchive", hInst); + } +} diff --git a/toolkit/mozapps/installer/windows/wizard/setup/xpi.h b/toolkit/mozapps/installer/windows/wizard/setup/xpi.h new file mode 100644 index 00000000000..bc96f80062f --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/xpi.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _XPI_H_ +#define _XPI_H_ + +HRESULT InitializeXPIStub(char *xpinstallPath); +HRESULT DeInitializeXPIStub(void); +HRESULT SmartUpdateJars(void); +void cbXPIStart(const char *, const char *UIName); +void cbXPIProgress(const char* msg, PRInt32 val, PRInt32 max); +void cbXPIFinal(const char *, PRInt32 finalStatus); +void InitProgressDlg(void); +void DeInitProgressDlg(void); +void GetTotalArchivesToInstall(void); +char *GetErrorString(DWORD dwError, char *szErrorString, DWORD dwErrorStringSize); + +#endif /* _XPI_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/xpistub.h b/toolkit/mozapps/installer/windows/wizard/setup/xpistub.h new file mode 100644 index 00000000000..c1f4f248619 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/xpistub.h @@ -0,0 +1,119 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Daniel Veditz + */ + + +//#include "nsError.h" +//#include "prtypes.h" + +#ifdef XP_MAC +#include +#endif + +#define nsresult long + +PR_BEGIN_EXTERN_C + +/** pfnXPIStart -- script start callback + * + * When an install script gets to StartInstall() this function + * will be called to tell the observer the pretty-name of the + * install package. You are not guaranteed this will be called + * for all scripts--there might be a fatal error before it gets + * to StartInstall(), either in the script itself or in the + * engine trying to set up for it. + */ +typedef void (*pfnXPIStart) (const char* URL, const char* UIName); + +/** pfnXPIProgress -- individual install item callback + * + * This callback will be called twice for each installed item, + * First when it is scheduled (val and max will both be 0) and + * then during the finalize step. + */ +typedef void (*pfnXPIProgress)(const char* msg, PRInt32 val, PRInt32 max); + +/** pfnXPIFinal -- script end callback + * + * This function will be called when the script calls either + * AbortInstall() or FinalizeInstall() and will return the + * last error code. + */ +typedef void (*pfnXPIFinal) (const char* URL, PRInt32 finalStatus); + + + +/** XPI_Init + * + * call XPI_Init() to initialize XPCOM and the XPInstall + * engine, and to pass in your callback functions. + * + * @param aXPIStubDir [MAC only] directory of the xpistub shlb off of which + * the component manager derives the components directory. + * @param aProgramDir directory to use as "program" directory. If NULL default + * will be used -- the location of the calling executable. + * Must be native filename format. + * @param startCB Called when script started + * @param progressCB Called for each installed file + * @param finalCB Called with status code at end + * + * @returns XPCOM status code indicating success or failure + */ +PR_EXTERN(nsresult) XPI_Init( +#ifdef XP_MAC + const FSSpec& aXPIStubDir, + const FSSpec& aProgramDir, +#else + const char* aProgramDir, +#endif + const char* aLogName, + pfnXPIProgress progressCB); + +/** XPI_Install + * + * Install an XPI package from a local file + * + * @param file Native filename of XPI archive + * @param args Install.arguments, if any + * @param flags the old SmartUpdate trigger flags. This may go away + * + * @returns status Status from the installed archive + */ +PR_EXTERN(PRInt32) XPI_Install( +#ifdef XP_MAC + const FSSpec& file, +#else + const char* file, +#endif + const char* args, + long flags ); + +/** XPI_Exit + * + * call when done to shut down the XPInstall and XPCOM engines + * and free allocated memory + */ +PR_EXTERN(void) XPI_Exit(); + +PR_END_EXTERN_C + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.cpp b/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.cpp new file mode 100644 index 00000000000..1e0e8e79826 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.cpp @@ -0,0 +1,1523 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 1998, 1999, 2000, 2001 Netscape Communications Corp. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "extern.h" +#include "extra.h" +#include "dialogs.h" +#include "xpnetHook.h" + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include "nsFTPConn.h" +#include "nsHTTPConn.h" +#include "nsSocket.h" + +#define UPDATE_INTERVAL_STATUS 1 +#define UPDATE_INTERVAL_PROGRESS_BAR 1 + +/* Cancel Status */ +#define CS_NONE 0x00000000 +#define CS_CANCEL 0x00000001 +#define CS_PAUSE 0x00000002 +#define CS_RESUME 0x00000003 + +const int kProxySrvrLen = 1024; +const char kHTTP[8] = "http://"; +const char kFTP[7] = "ftp://"; +const char kLoclFile[7] = "zzzFTP"; +const int kModTimeOutValue = 3; + +static nsHTTPConn *connHTTP = NULL; +static nsFTPConn *connFTP = NULL; +static long glLastBytesSoFar; +static long glAbsoluteBytesSoFar; +static long glBytesResumedFrom; +static long glTotalKb; +char gszStrCopyingFile[MAX_BUF_MEDIUM]; +char gszCurrentDownloadPath[MAX_BUF]; +char gszCurrentDownloadFilename[MAX_BUF_TINY]; +char gszCurrentDownloadFileDescription[MAX_BUF_TINY]; +char gszUrl[MAX_BUF]; +char gszTo[MAX_BUF]; +char gszFileInfo[MAX_BUF]; +char *gszConfigIniFile; +BOOL gbDlgDownloadMinimized; +BOOL gbDlgDownloadJustMinimized; +BOOL gbUrlChanged; +BOOL gbShowDownloadRetryMsg; +DWORD gdwDownloadDialogStatus; +int giIndex; +int giTotalArchivesToDownload; +DWORD gdwTickStart; +BOOL gbStartTickCounter; + +double GetPercentSoFar(void); + +static void UpdateGaugeFileProgressBar(double value); + int ProgressCB(int aBytesSoFar, int aTotalFinalSize); + void InitDownloadDlg(void); + void DeInitDownloadDlg(); + +/* local prototypes */ +siC *GetObjectFromArchiveName(char *szArchiveName); + +struct DownloadFileInfo +{ + char szUrl[MAX_BUF]; + char szFile[MAX_BUF_TINY]; +} dlFileInfo; + +struct ExtractFilesDlgInfo +{ + HWND hWndDlg; + int nMaxFileBars; // maximum number of bars that can be displayed + int nMaxArchiveBars; // maximum number of bars that can be displayed + int nFileBars; // current number of bars to display + int nArchiveBars; // current number of bars to display +} dlgInfo; + +struct TickInfo +{ + DWORD dwTickBegin; + DWORD dwTickEnd; + DWORD dwTickDif; + BOOL bTickStarted; + BOOL bTickDownloadResumed; +} gtiPaused; + +BOOL CheckInterval(long *lModLastValue, int iInterval) +{ + BOOL bRv = FALSE; + long lModCurrentValue; + + if(iInterval == 1) + { + lModCurrentValue = time(NULL); + if(lModCurrentValue != *lModLastValue) + bRv = TRUE; + } + else + { + lModCurrentValue = time(NULL) % iInterval; + if((lModCurrentValue == 0) && (*lModLastValue != 0)) + bRv = TRUE; + } + + *lModLastValue = lModCurrentValue; + return(bRv); +} + +char *GetTimeLeft(DWORD dwTimeLeft, + char *szTimeString, + DWORD dwTimeStringBufSize) +{ + DWORD dwTimeLeftPP; + SYSTEMTIME stTime; + + ZeroMemory(&stTime, sizeof(stTime)); + dwTimeLeftPP = dwTimeLeft + 1; + stTime.wHour = (unsigned)(dwTimeLeftPP / 60 / 60); + stTime.wMinute = (unsigned)((dwTimeLeftPP / 60) % 60); + stTime.wSecond = (unsigned)(dwTimeLeftPP % 60); + + ZeroMemory(szTimeString, dwTimeStringBufSize); + /* format time string using user's local time format information */ + GetTimeFormat(LOCALE_USER_DEFAULT, + TIME_NOTIMEMARKER|TIME_FORCE24HOURFORMAT, + &stTime, + NULL, + szTimeString, + dwTimeStringBufSize); + + return(szTimeString); +} + +DWORD AddToTick(DWORD dwTick, DWORD dwTickMoreToAdd) +{ + DWORD dwTickLeftTillWrap = 0; + + /* Since GetTickCount() is the number of milliseconds since the system + * has been on and the return value is a DWORD, this value will wrap + * every 49.71 days or 0xFFFFFFFF milliseconds. */ + dwTickLeftTillWrap = 0xFFFFFFFF - dwTick; + if(dwTickMoreToAdd > dwTickLeftTillWrap) + dwTick = dwTickMoreToAdd - dwTickLeftTillWrap; + else + dwTick = dwTick + dwTickMoreToAdd; + + return(dwTick); +} + +DWORD GetTickDif(DWORD dwTickEnd, DWORD dwTickStart) +{ + DWORD dwTickDif; + + /* Since GetTickCount() is the number of milliseconds since the system + * has been on and the return value is a DWORD, this value will wrap + * every 49.71 days or 0xFFFFFFFF milliseconds. + * + * Assumption: dwTickEnd has not wrapped _and_ passed dwTickStart */ + if(dwTickEnd < dwTickStart) + dwTickDif = 0xFFFFFFFF - dwTickStart + dwTickEnd; + else + dwTickDif = dwTickEnd - dwTickStart; + + return(dwTickDif); +} + +void InitTickInfo(void) +{ + gtiPaused.dwTickBegin = 0; + gtiPaused.dwTickEnd = 0; + gtiPaused.dwTickDif = 0; + gtiPaused.bTickStarted = FALSE; + gtiPaused.bTickDownloadResumed = FALSE; +} + +DWORD RoundDouble(double dValue) +{ + if(0.5 <= (dValue - (DWORD)dValue)) + return((DWORD)dValue + 1); + else + return((DWORD)dValue); +} + +void SetStatusStatus(void) +{ + char szStatusStatusLine[MAX_BUF_MEDIUM]; + char szCurrentStatusInfo[MAX_BUF_MEDIUM]; + char szPercentString[MAX_BUF_MEDIUM]; + char szPercentageCompleted[MAX_BUF_MEDIUM]; + static long lModLastValue = 0; + double dRate; + static double dRateCounter; + DWORD dwTickNow; + DWORD dwTickDif; + DWORD dwKBytesSoFar; + DWORD dwRoundedRate; + char szTimeLeft[MAX_BUF_TINY]; + + /* If the user just clicked on the Resume button, then the time lapsed + * between gdwTickStart and when the Resume button was clicked needs to + * be subtracted taken into account when calculating dwTickDif. So + * "this" lapsed time needs to be added to gdwTickStart. */ + if(gtiPaused.bTickDownloadResumed) + { + gdwTickStart = AddToTick(gdwTickStart, gtiPaused.dwTickDif); + InitTickInfo(); + } + + /* GetTickCount() returns time in milliseconds. This is more accurate, + * which will allow us to get at a 2 decimal precision value for the + * download rate. */ + dwTickNow = GetTickCount(); + if((gdwTickStart == 0) && gbStartTickCounter) + dwTickNow = gdwTickStart = GetTickCount(); + + dwTickDif = GetTickDif(dwTickNow, gdwTickStart); + + /* Only update the UI every UPDATE_INTERVAL_STATUS interval, + * which is currently set to 1 sec. */ + if(!CheckInterval(&lModLastValue, UPDATE_INTERVAL_STATUS)) + return; + + if(glAbsoluteBytesSoFar == 0) + dRateCounter = 0.0; + else + dRateCounter = dwTickDif / 1000; + + if(dRateCounter == 0.0) + dRate = 0.0; + else + dRate = (glAbsoluteBytesSoFar - glBytesResumedFrom) / dRateCounter / 1024; + + dwKBytesSoFar = glAbsoluteBytesSoFar / 1024; + + /* Use a rate that is rounded to the nearest integer. If dRate used directly, + * the "Time Left" will jump around quite a bit due to the rate usually + * varying up and down by quite a bit. The rounded rate give a "more linear" + * count down of the "Time Left". */ + dwRoundedRate = RoundDouble(dRate); + if(dwRoundedRate > 0) + GetTimeLeft((glTotalKb - dwKBytesSoFar) / dwRoundedRate, + szTimeLeft, + sizeof(szTimeLeft)); + else + lstrcpy(szTimeLeft, "00:00:00"); + + if(!gbShowDownloadRetryMsg) + { + GetPrivateProfileString("Strings", + "Status Download", + "", + szStatusStatusLine, + sizeof(szStatusStatusLine), + szFileIniConfig); + if(*szStatusStatusLine != '\0') + sprintf(szCurrentStatusInfo, + szStatusStatusLine, + szTimeLeft, + dRate, + dwKBytesSoFar, + glTotalKb); + else + sprintf(szCurrentStatusInfo, + "%s at %.2fKB/sec (%uKB of %uKB downloaded)", + szTimeLeft, + dRate, + dwKBytesSoFar, + glTotalKb); + } + else + { + GetPrivateProfileString("Strings", + "Status Retry", + "", + szStatusStatusLine, + sizeof(szStatusStatusLine), + szFileIniConfig); + if(*szStatusStatusLine != '\0') + sprintf(szCurrentStatusInfo, + szStatusStatusLine, + szTimeLeft, + dRate, + dwKBytesSoFar, + glTotalKb); + else + sprintf(szCurrentStatusInfo, + "%s at %.2KB/sec (%uKB of %uKB downloaded)", + szTimeLeft, + dRate, + dwKBytesSoFar, + glTotalKb); + } + + GetPrivateProfileString("Strings", + "Status Percentage Completed", + "", + szPercentageCompleted, + sizeof(szPercentageCompleted), + szFileIniConfig); + wsprintf(szPercentString, szPercentageCompleted, (int)GetPercentSoFar()); + + /* Set the download dialog title */ + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_STATUS, szCurrentStatusInfo); + SetDlgItemText(dlgInfo.hWndDlg, IDC_PERCENTAGE, szPercentString); +} + +void SetStatusFile(void) +{ + char szString[MAX_BUF]; + + /* Set the download dialog status*/ + wsprintf(szString, gszFileInfo, gszCurrentDownloadFileDescription); + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_FILE, szString); + SetStatusStatus(); +} + +void SetStatusUrl(void) +{ + /* display the current url being processed */ + if(gbUrlChanged) + { + char szUrlPathBuf[MAX_BUF]; + char szToPathBuf[MAX_BUF]; + HWND hStatusUrl = NULL; + HWND hStatusTo = NULL; + + hStatusUrl = GetDlgItem(dlgInfo.hWndDlg, IDC_STATUS_URL); + if(hStatusUrl) + TruncateString(hStatusUrl, gszUrl, szUrlPathBuf, sizeof(szUrlPathBuf)); + else + lstrcpy(szUrlPathBuf, gszUrl); + + hStatusTo = GetDlgItem(dlgInfo.hWndDlg, IDC_STATUS_TO); + if(hStatusTo) + TruncateString(hStatusTo, gszTo, szToPathBuf, sizeof(szToPathBuf)); + else + lstrcpy(szToPathBuf, gszTo); + + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_URL, szUrlPathBuf); + SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_TO, szToPathBuf); + SetStatusFile(); + gbUrlChanged = FALSE; + } +} + +double GetPercentSoFar(void) +{ + return((double)(((double)(glAbsoluteBytesSoFar / 1024) / (double)glTotalKb) * (double)100)); +} + +void SetMinimizedDownloadTitle(DWORD dwPercentSoFar) +{ + static DWORD dwLastPercentSoFar = 0; + char szDownloadTitle[MAX_BUF_MEDIUM]; + char gszCurrentDownloadInfo[MAX_BUF_MEDIUM]; + + GetPrivateProfileString("Strings", "Dialog Download Title Minimized", "", szDownloadTitle, sizeof(szDownloadTitle), szFileIniConfig); + + if(*szDownloadTitle != '\0') + wsprintf(gszCurrentDownloadInfo, szDownloadTitle, dwPercentSoFar, gszCurrentDownloadFilename); + else + wsprintf(gszCurrentDownloadInfo, "%d%% for all files", dwPercentSoFar); + + /* check and save the current percent so far to minimize flickering */ + if((dwLastPercentSoFar != dwPercentSoFar) || gbDlgDownloadJustMinimized) + { + /* When the dialog is has just been minimized, the title is not set + * until the percentage changes, which when downloading via modem, + * could take several seconds. This variable allows us to tell when + * the dialog had *just* been minimized regardless if the percentage + * had changed or not. */ + gbDlgDownloadJustMinimized = FALSE; + + /* Set the download dialog title */ + SetWindowText(dlgInfo.hWndDlg, gszCurrentDownloadInfo); + dwLastPercentSoFar = dwPercentSoFar; + } +} + +void SetRestoredDownloadTitle(void) +{ + /* Set the download dialog title */ + SetWindowText(dlgInfo.hWndDlg, diDownload.szTitle); +} + +void GetTotalArchivesToDownload(int *iTotalArchivesToDownload, DWORD *dwTotalEstDownloadSize) +{ + int iIndex = 0; + char szUrl[MAX_BUF]; + char szSection[MAX_INI_SK]; + char szDownloadSize[MAX_ITOA]; + + *dwTotalEstDownloadSize = 0; + iIndex = 0; + wsprintf(szSection, "File%d", iIndex); + GetPrivateProfileString(szSection, + "url0", + "", + szUrl, + sizeof(szUrl), + gszConfigIniFile); + while(*szUrl != '\0') + { + GetPrivateProfileString(szSection, "size", "", szDownloadSize, sizeof(szDownloadSize), gszConfigIniFile); + if((lstrlen(szDownloadSize) < 32) && (*szDownloadSize != '\0')) + /* size will be in kb. 31 bits (int minus the signed bit) of precision should sufice */ + *dwTotalEstDownloadSize += atoi(szDownloadSize); + + ++iIndex; + wsprintf(szSection, "File%d", iIndex); + GetPrivateProfileString(szSection, + "url0", + "", + szUrl, + sizeof(szUrl), + gszConfigIniFile); + } + *iTotalArchivesToDownload = iIndex; +} + +/* + * Name: ProcessWndMsgCB + * + * Arguments: None + * + * Description: Callback function invoked by socket code and by FTP and HTTP layers + * to give the UI a chance to breath while we are in a look processing + * incoming data, or looping in select() + * + * Author: syd@netscape.com 5/11/2001 + * +*/ + +int +ProcessWndMsgCB() +{ + int iRv = nsFTPConn::OK; + + ProcessWindowsMessages(); + if((gdwDownloadDialogStatus == CS_CANCEL) || + (gdwDownloadDialogStatus == CS_PAUSE)) + iRv = nsFTPConn::E_USER_CANCEL; + + return(iRv); +} + +/* Function used only to send the message stream error */ +int WGet(char *szUrl, + char *szFile, + char *szProxyServer, + char *szProxyPort, + char *szProxyUser, + char *szProxyPasswd) +{ + int rv; + char proxyURL[MAX_BUF]; + nsHTTPConn *conn = NULL; + + if((szProxyServer != NULL) && (szProxyPort != NULL) && + (*szProxyServer != '\0') && (*szProxyPort != '\0')) + { + /* detected proxy information, let's use it */ + memset(proxyURL, 0, sizeof(proxyURL)); + wsprintf(proxyURL, "http://%s:%s", szProxyServer, szProxyPort); + + conn = new nsHTTPConn(proxyURL); + if(conn == NULL) + return(WIZ_OUT_OF_MEMORY); + + if((szProxyUser != NULL) && (*szProxyUser != '\0') && + (szProxyPasswd != NULL) && (*szProxyPasswd != '\0')) + /* detected user and password info */ + conn->SetProxyInfo(szUrl, szProxyUser, szProxyPasswd); + else + conn->SetProxyInfo(szUrl, NULL, NULL); + } + else + { + /* no proxy information supplied. set up normal http object */ + conn = new nsHTTPConn(szUrl, ProcessWndMsgCB); + if(conn == NULL) + return(WIZ_OUT_OF_MEMORY); + } + + rv = conn->Open(); + if(rv == WIZ_OK) + { + rv = conn->Get(NULL, szFile); + conn->Close(); + } + + if(conn) + delete(conn); + + return(rv); +} + +int DownloadViaProxyOpen(char *szUrl, char *szProxyServer, char *szProxyPort, char *szProxyUser, char *szProxyPasswd) +{ + int rv; + char proxyURL[kProxySrvrLen]; + + if((!szUrl) || (*szUrl == '\0')) + return nsHTTPConn::E_PARAM; + + rv = nsHTTPConn::OK; + memset(proxyURL, 0, kProxySrvrLen); + wsprintf(proxyURL, "http://%s:%s", szProxyServer, szProxyPort); + + connHTTP = new nsHTTPConn(proxyURL, ProcessWndMsgCB); + if(connHTTP == NULL) + { + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig); + PrintError(szBuf, ERROR_CODE_HIDE); + + return(WIZ_OUT_OF_MEMORY); + } + + if((szProxyUser != NULL) && (*szProxyUser != '\0') && + (szProxyPasswd != NULL) && (*szProxyPasswd != '\0')) + connHTTP->SetProxyInfo(szUrl, szProxyUser, szProxyPasswd); + else + connHTTP->SetProxyInfo(szUrl, NULL, NULL); + + rv = connHTTP->Open(); + return(rv); +} + +void DownloadViaProxyClose(void) +{ + gbStartTickCounter = FALSE; + if(connHTTP) + { + connHTTP->Close(); + delete(connHTTP); + connHTTP = NULL; + } +} + +int DownloadViaProxy(char *szUrl, char *szProxyServer, char *szProxyPort, char *szProxyUser, char *szProxyPasswd) +{ + int rv; + char *file = NULL; + + rv = nsHTTPConn::OK; + if((!szUrl) || (*szUrl == '\0')) + return nsHTTPConn::E_PARAM; + + if(connHTTP == NULL) + { + rv = DownloadViaProxyOpen(szUrl, + szProxyServer, + szProxyPort, + szProxyUser, + szProxyPasswd); + + if(rv != nsHTTPConn::OK) + { + DownloadViaProxyClose(); + return(rv); + } + } + + if(connHTTP == NULL) + { + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig); + PrintError(szBuf, ERROR_CODE_HIDE); + + return(WIZ_OUT_OF_MEMORY); + } + + if(strrchr(szUrl, '/') != (szUrl + strlen(szUrl))) + file = strrchr(szUrl, '/') + 1; // set to leaf name + + gbStartTickCounter = TRUE; + rv = connHTTP->Get(ProgressCB, file); // use leaf from URL + DownloadViaProxyClose(); + return(rv); +} + +int DownloadViaHTTPOpen(char *szUrl) +{ + int rv; + + if((!szUrl) || (*szUrl == '\0')) + return nsHTTPConn::E_PARAM; + + rv = nsHTTPConn::OK; + connHTTP = new nsHTTPConn(szUrl, ProcessWndMsgCB); + if(connHTTP == NULL) + { + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), gszConfigIniFile); + PrintError(szBuf, ERROR_CODE_HIDE); + + return(WIZ_OUT_OF_MEMORY); + } + + rv = connHTTP->Open(); + return(rv); +} + +void DownloadViaHTTPClose(void) +{ + gbStartTickCounter = FALSE; + if(connHTTP) + { + connHTTP->Close(); + delete(connHTTP); + connHTTP = NULL; + } +} + +int DownloadViaHTTP(char *szUrl) +{ + int rv; + char *file = NULL; + + if((!szUrl) || (*szUrl == '\0')) + return nsHTTPConn::E_PARAM; + + if(connHTTP == NULL) + { + rv = DownloadViaHTTPOpen(szUrl); + if(rv != nsHTTPConn::OK) + { + DownloadViaHTTPClose(); + return(rv); + } + } + + if(connHTTP == NULL) + { + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), gszConfigIniFile); + PrintError(szBuf, ERROR_CODE_HIDE); + + return(WIZ_OUT_OF_MEMORY); + } + + rv = nsHTTPConn::OK; + if(strrchr(szUrl, '/') != (szUrl + strlen(szUrl))) + file = strrchr(szUrl, '/') + 1; // set to leaf name + + gbStartTickCounter = TRUE; + rv = connHTTP->Get(ProgressCB, file); + DownloadViaHTTPClose(); + return(rv); +} + +int DownloadViaFTPOpen(char *szUrl) +{ + char *host = 0, *path = 0, *file = (char*) kLoclFile; + int port = 21; + int rv; + + if((!szUrl) || (*szUrl == '\0')) + return nsFTPConn::E_PARAM; + + rv = nsHTTPConn::ParseURL(kFTP, szUrl, &host, &port, &path); + + connFTP = new nsFTPConn(host, ProcessWndMsgCB); + if(connFTP == NULL) + { + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig); + PrintError(szBuf, ERROR_CODE_HIDE); + + return(WIZ_OUT_OF_MEMORY); + } + + rv = connFTP->Open(); + if(host) + free(host); + if(path) + free(path); + + return(rv); +} + +void DownloadViaFTPClose(void) +{ + gbStartTickCounter = FALSE; + if(connFTP) + { + connFTP->Close(); + delete(connFTP); + connFTP = NULL; + } +} + +int DownloadViaFTP(char *szUrl) +{ + char *host = 0, *path = 0, *file = (char*) kLoclFile; + int port = 21; + int rv; + + if((!szUrl) || (*szUrl == '\0')) + return nsFTPConn::E_PARAM; + + if(connFTP == NULL) + { + rv = DownloadViaFTPOpen(szUrl); + if(rv != nsFTPConn::OK) + { + DownloadViaFTPClose(); + return(rv); + } + } + + if(connFTP == NULL) + { + char szBuf[MAX_BUF_TINY]; + + GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig); + PrintError(szBuf, ERROR_CODE_HIDE); + + return(WIZ_OUT_OF_MEMORY); + } + + rv = nsHTTPConn::ParseURL(kFTP, szUrl, &host, &port, &path); + + if(strrchr(path, '/') != (path + strlen(path))) + file = strrchr(path, '/') + 1; // set to leaf name + + gbStartTickCounter = TRUE; + rv = connFTP->Get(path, file, nsFTPConn::BINARY, TRUE, ProgressCB); + + if(host) + free(host); + if(path) + free(path); + + return(rv); +} + +void PauseTheDownload(int rv, int *iFileDownloadRetries) +{ + if(rv != nsFTPConn::E_USER_CANCEL) + { + SendMessage(dlgInfo.hWndDlg, WM_COMMAND, IDPAUSE, 0); + --*iFileDownloadRetries; + } + + while(gdwDownloadDialogStatus == CS_PAUSE) + { + SleepEx(200, FALSE); + ProcessWindowsMessages(); + } +} + +void CloseSocket(char *szProxyServer, char *szProxyPort) +{ + /* Close the socket connection from the first attempt. */ + if((szProxyServer != NULL) && (szProxyPort != NULL) && + (*szProxyServer != '\0') && (*szProxyPort != '\0')) + DownloadViaProxyClose(); + else + { + /* is this an HTTP URL? */ + if(strncmp(gszUrl, kHTTP, lstrlen(kHTTP)) == 0) + DownloadViaHTTPClose(); + /* or is this an FTP URL? */ + else if(strncmp(gszUrl, kFTP, lstrlen(kFTP)) == 0) + DownloadViaFTPClose(); + } +} + +siC *GetObjectFromArchiveName(char *szArchiveName) +{ + DWORD dwIndex; + siC *siCObject = NULL; + siC *siCNode = NULL; + + dwIndex = 0; + siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL); + while(siCObject) + { + if(lstrcmpi(szArchiveName, siCObject->szArchiveName) == 0) + { + siCNode = siCObject; + break; + } + + ++dwIndex; + siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL); + } + + return(siCNode); +} + +int DownloadFiles(char *szInputIniFile, + char *szDownloadDir, + char *szProxyServer, + char *szProxyPort, + char *szProxyUser, + char *szProxyPasswd, + BOOL bShowRetryMsg, + BOOL bIgnoreAllNetworkErrors, + char *szFailedFile, + DWORD dwFailedFileSize) +{ + char szBuf[MAX_BUF]; + char szCurrentFile[MAX_BUF]; + char szSection[MAX_INI_SK]; + char szKey[MAX_INI_SK]; + char szSavedCwd[MAX_BUF_MEDIUM]; + int iCounter; + int rv; + int iFileDownloadRetries; + int iIgnoreFileNetworkError; + int iLocalTimeOutCounter; + DWORD dwTotalEstDownloadSize; + char szPartiallyDownloadedFilename[MAX_BUF]; + BOOL bDownloadInitiated; + char szTempURL[MAX_BUF]; + char szWorkingURLPathOnly[MAX_BUF]; + siC *siCCurrentFileObj = NULL; + + ZeroMemory(szTempURL, sizeof(szTempURL)); + ZeroMemory(szWorkingURLPathOnly, sizeof(szWorkingURLPathOnly)); + if(szInputIniFile == NULL) + return(WIZ_ERROR_UNDEFINED); + + if(szFailedFile) + ZeroMemory(szFailedFile, dwFailedFileSize); + + InitTickInfo(); + GetCurrentDirectory(sizeof(szSavedCwd), szSavedCwd); + SetCurrentDirectory(szDownloadDir); + + rv = WIZ_OK; + dwTotalEstDownloadSize = 0; + giTotalArchivesToDownload = 0; + glLastBytesSoFar = 0; + glAbsoluteBytesSoFar = 0; + glBytesResumedFrom = 0; + gdwTickStart = 0; /* Initialize the counter used to + * calculate download rate */ + gbStartTickCounter = FALSE; /* used to determine when to start + * the tick counter used to calculate + * the download rate */ + gbUrlChanged = TRUE; + gbDlgDownloadMinimized = FALSE; + gbDlgDownloadJustMinimized = FALSE; + gdwDownloadDialogStatus = CS_NONE; + gbShowDownloadRetryMsg = bShowRetryMsg; + gszConfigIniFile = szInputIniFile; + bDownloadInitiated = FALSE; + + GetTotalArchivesToDownload(&giTotalArchivesToDownload, + &dwTotalEstDownloadSize); + glTotalKb = dwTotalEstDownloadSize; + GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename, + sizeof(szPartiallyDownloadedFilename)); + + InitDownloadDlg(); + + for(giIndex = 0; giIndex < giTotalArchivesToDownload; giIndex++) + { + /* set (or reset) the counter to 0 in order to read the + * next files's 0'th url from the .idi file */ + iCounter = 0; + gbUrlChanged = TRUE; /* Update the download dialog with new URL */ + wsprintf(szSection, "File%d", giIndex); + wsprintf(szKey, "url%d", iCounter); + GetPrivateProfileString(szSection, + szKey, + "", + szTempURL, + sizeof(szTempURL), + gszConfigIniFile); + + if(*szTempURL == '\0') + continue; + + if(!bDownloadInitiated) + { + ParsePath(szTempURL, + szWorkingURLPathOnly, + sizeof(szWorkingURLPathOnly), + TRUE, //use '/' as the path delimiter + PP_PATH_ONLY); + } + + GetPrivateProfileString(szSection, + "desc", + "", + gszCurrentDownloadFileDescription, + sizeof(gszCurrentDownloadFileDescription), + gszConfigIniFile); + iIgnoreFileNetworkError = GetPrivateProfileInt(szSection, + "Ignore File Network Error", + 0, + gszConfigIniFile); + + /* save the file name to be downloaded */ + ParsePath(szTempURL, + szCurrentFile, + sizeof(szCurrentFile), + TRUE, //use '/' as the path delimiter + PP_FILENAME_ONLY); + + RemoveSlash(szWorkingURLPathOnly); + wsprintf(gszUrl, "%s/%s", szWorkingURLPathOnly, szCurrentFile); + + /* retrieve the file's data structure */ + siCCurrentFileObj = GetObjectFromArchiveName(szCurrentFile); + + if((*szPartiallyDownloadedFilename != 0) && + (lstrcmpi(szPartiallyDownloadedFilename, szCurrentFile) == 0)) + { + struct stat statBuf; + + if(stat(szPartiallyDownloadedFilename, &statBuf) != -1) + { + glAbsoluteBytesSoFar += statBuf.st_size; + glBytesResumedFrom = statBuf.st_size; + } + } + + lstrcpy(gszTo, szDownloadDir); + AppendBackSlash(gszTo, sizeof(gszTo)); + lstrcat(gszTo, szCurrentFile); + + if(gbDlgDownloadMinimized) + SetMinimizedDownloadTitle((int)GetPercentSoFar()); + else + { + SetStatusUrl(); + SetRestoredDownloadTitle(); + } + + SetSetupCurrentDownloadFile(szCurrentFile); + iFileDownloadRetries = 0; + iLocalTimeOutCounter = 0; + do + { + ProcessWindowsMessages(); + /* Download starts here */ + if((szProxyServer != NULL) && (szProxyPort != NULL) && + (*szProxyServer != '\0') && (*szProxyPort != '\0')) + /* If proxy info is provided, use HTTP proxy */ + rv = DownloadViaProxy(gszUrl, + szProxyServer, + szProxyPort, + szProxyUser, + szProxyPasswd); + else + { + /* is this an HTTP URL? */ + if(strncmp(gszUrl, kHTTP, lstrlen(kHTTP)) == 0) + rv = DownloadViaHTTP(gszUrl); + /* or is this an FTP URL? */ + else if(strncmp(gszUrl, kFTP, lstrlen(kFTP)) == 0) + rv = DownloadViaFTP(gszUrl); + } + + bDownloadInitiated = TRUE; + if((rv == nsFTPConn::E_USER_CANCEL) || + (gdwDownloadDialogStatus == CS_PAUSE)) + { + if(gdwDownloadDialogStatus == CS_PAUSE) + { + CloseSocket(szProxyServer, szProxyPort); + + /* rv needs to be set to something + * other than E_USER_CANCEL or E_OK */ + rv = nsFTPConn::E_CMD_UNEXPECTED; + + PauseTheDownload(rv, &iFileDownloadRetries); + bDownloadInitiated = FALSE; /* restart the download using + * new socket connection */ + } + else + { + /* user canceled; break out of the do loop */ + break; + } + } + else if((rv != nsFTPConn::OK) && + (rv != nsFTPConn::E_CMD_FAIL) && + (rv != nsSocket::E_BIND) && + (rv != nsHTTPConn::E_HTTP_RESPONSE) && + (gdwDownloadDialogStatus != CS_CANCEL)) + { + /* We timed out. No response from the server, or + * we somehow lost connection. */ + + char szTitle[MAX_BUF_SMALL]; + char szMsgDownloadPaused[MAX_BUF]; + + /* Incrememt the time out counter on E_TIMEOUT */ + if(rv == nsSocket::E_TIMEOUT) + { + ++siCCurrentFileObj->iNetTimeOuts; + ++iLocalTimeOutCounter; + } + + CloseSocket(szProxyServer, szProxyPort); + + /* If the number of timeouts is %3 == 0, then let's pause + * the download process. Otherwise, just close the + * connection and open a new one to see if the download + * can be restarted automatically. */ + if((rv != nsSocket::E_TIMEOUT) || + (rv == nsSocket::E_TIMEOUT) && ((iLocalTimeOutCounter % kModTimeOutValue) == 0)) + { + /* Start the pause tick counter here because we don't know how + * long before the user will dismiss the MessageBox() */ + if(!gtiPaused.bTickStarted) + { + gtiPaused.dwTickBegin = GetTickCount(); + gtiPaused.bTickStarted = TRUE; + gtiPaused.bTickDownloadResumed = FALSE; + } + + /* The connection unexepectedly dropped for some reason, so inform + * the user that the download will be Paused, and then update the + * Download dialog to show the Paused state. */ + GetPrivateProfileString("Messages", + "MB_WARNING_STR", + "", + szTitle, + sizeof(szTitle), + szFileIniInstall); + GetPrivateProfileString("Strings", + "Message Download Paused", + "", + szMsgDownloadPaused, + sizeof(szMsgDownloadPaused), + szFileIniConfig); + MessageBox(dlgInfo.hWndDlg, + szMsgDownloadPaused, + szTitle, + MB_ICONEXCLAMATION); + + /* Let's make sure we're in a paused state */ + gdwDownloadDialogStatus = CS_PAUSE; + PauseTheDownload(rv, &iFileDownloadRetries); + } + else + /* Let's make sure we're _not_ in a paused state */ + gdwDownloadDialogStatus = CS_NONE; + } + + /* We don't count time outs as normal failures. We're + * keeping track of time outs differently. */ + if(rv != nsSocket::E_TIMEOUT) + ++iFileDownloadRetries; + + if((iFileDownloadRetries > MAX_FILE_DOWNLOAD_RETRIES) && + (rv != nsFTPConn::E_USER_CANCEL) && + (gdwDownloadDialogStatus != CS_CANCEL)) + { + /* since the download retries maxed out, increment the counter + * to read the next url for the current file */ + ++iCounter; + wsprintf(szKey, "url%d", iCounter); + GetPrivateProfileString(szSection, + szKey, + "", + szTempURL, + sizeof(szTempURL), + gszConfigIniFile); + if(*szTempURL != '\0') + { + /* Found more urls to download from for the current file. + * Update the dialog to show the new url and reset the + * file download retries to 0 since it's a new url. */ + gbUrlChanged = TRUE; + iFileDownloadRetries = 0; + bDownloadInitiated = FALSE; // restart the download using new socket connection + CloseSocket(szProxyServer, szProxyPort); + ParsePath(szTempURL, + szWorkingURLPathOnly, + sizeof(szWorkingURLPathOnly), + TRUE, //use '/' as the path delimiter + PP_PATH_ONLY); + RemoveSlash(szWorkingURLPathOnly); + wsprintf(gszUrl, "%s/%s", szWorkingURLPathOnly, szCurrentFile); + SetStatusUrl(); + } + } + } while((rv != nsFTPConn::E_USER_CANCEL) && + (rv != nsFTPConn::OK) && + (gdwDownloadDialogStatus != CS_CANCEL) && + (iFileDownloadRetries <= MAX_FILE_DOWNLOAD_RETRIES)); + + /* Save the number of retries for each file */ + siCCurrentFileObj->iNetRetries = iFileDownloadRetries < 1 ? 0:iFileDownloadRetries - 1; + + if((rv == nsFTPConn::E_USER_CANCEL) || + (gdwDownloadDialogStatus == CS_CANCEL)) + { + /* make sure rv is E_USER_CANCEL when gdwDownloadDialogStatus + * is CS_CANCEL */ + rv = nsFTPConn::E_USER_CANCEL; + + if(szFailedFile && ((DWORD)lstrlen(szCurrentFile) <= dwFailedFileSize)) + lstrcpy(szFailedFile, gszCurrentDownloadFileDescription); + + /* break out of for() loop */ + break; + } + + if((rv != nsFTPConn::OK) && + (iFileDownloadRetries > MAX_FILE_DOWNLOAD_RETRIES) && + !bIgnoreAllNetworkErrors && + !iIgnoreFileNetworkError) + { + /* too many retries from failed downloads */ + char szMsg[MAX_BUF]; + + if(szFailedFile && ((DWORD)lstrlen(szCurrentFile) <= dwFailedFileSize)) + lstrcpy(szFailedFile, gszCurrentDownloadFileDescription); + + GetPrivateProfileString("Strings", + "Error Too Many Network Errors", + "", + szMsg, + sizeof(szMsg), + szFileIniConfig); + if(*szMsg != '\0') + { + wsprintf(szBuf, szMsg, szCurrentFile); + PrintError(szBuf, ERROR_CODE_HIDE); + } + + iFileDownloadRetries = 0; // reset the file download retries counter since + // we'll be restarting the download again. + bDownloadInitiated = FALSE; // restart the download using new socket connection + CloseSocket(szProxyServer, szProxyPort); + --giIndex; // Decrement the file index counter because we'll be trying to + // download the same file again. We don't want to go to the next + // file just yet. + + /* Let's make sure we're in a paused state. */ + /* The pause state will be unset by DownloadDlgProc(). */ + gdwDownloadDialogStatus = CS_PAUSE; + PauseTheDownload(rv, &iFileDownloadRetries); + } + else if(bIgnoreAllNetworkErrors || iIgnoreFileNetworkError) + rv = nsFTPConn::OK; + + UnsetSetupCurrentDownloadFile(); + } + + CloseSocket(szProxyServer, szProxyPort); + DeInitDownloadDlg(); + SetCurrentDirectory(szSavedCwd); + return(rv); +} + +int ProgressCB(int aBytesSoFar, int aTotalFinalSize) +{ + long lBytesDiffSoFar; + double dPercentSoFar; + int iRv = nsFTPConn::OK; + + if(sgProduct.mode != SILENT) + { + SetStatusUrl(); + + if(glTotalKb == 0) + glTotalKb = aTotalFinalSize; + + /* Calculate the difference between the last set of bytes read against + * the current set of bytes read. If the value is negative, that means + * that it started a new file, so reset lBytesDiffSoFar to aBytesSoFar */ + lBytesDiffSoFar = ((aBytesSoFar - glLastBytesSoFar) < 1) ? aBytesSoFar : (aBytesSoFar - glLastBytesSoFar); + + /* Save the current bytes read as the last set of bytes read */ + glLastBytesSoFar = aBytesSoFar; + glAbsoluteBytesSoFar += lBytesDiffSoFar; + + dPercentSoFar = GetPercentSoFar(); + if(gbDlgDownloadMinimized) + SetMinimizedDownloadTitle((int)dPercentSoFar); + + UpdateGaugeFileProgressBar(dPercentSoFar); + SetStatusStatus(); + + if((gdwDownloadDialogStatus == CS_CANCEL) || + (gdwDownloadDialogStatus == CS_PAUSE)) + iRv = nsFTPConn::E_USER_CANCEL; + } + + ProcessWindowsMessages(); + return(iRv); +} + +// Window proc for dialog +LRESULT CALLBACK +DownloadDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + GetPrivateProfileString("Strings", + "Status File Info", + "", + gszFileInfo, + sizeof(gszFileInfo), + szFileIniConfig); + DisableSystemMenuItems(hWndDlg, FALSE); + RepositionWindow(hWndDlg, BANNER_IMAGE_DOWNLOAD); + if(gbShowDownloadRetryMsg) + SetDlgItemText(hWndDlg, IDC_MESSAGE0, diDownload.szMessageRetry0); + else + SetDlgItemText(hWndDlg, IDC_MESSAGE0, diDownload.szMessageDownload0); + + EnableWindow(GetDlgItem(hWndDlg, IDRESUME), FALSE); + SetDlgItemText(hWndDlg, IDC_STATIC1, sgInstallGui.szStatus); + SetDlgItemText(hWndDlg, IDC_STATIC2, sgInstallGui.szFile); + SetDlgItemText(hWndDlg, IDC_STATIC4, sgInstallGui.szTo); + SetDlgItemText(hWndDlg, IDC_STATIC3, sgInstallGui.szUrl); + SetDlgItemText(hWndDlg, IDCANCEL, sgInstallGui.szCancel_); + SetDlgItemText(hWndDlg, IDPAUSE, sgInstallGui.szPause_); + SetDlgItemText(hWndDlg, IDRESUME, sgInstallGui.szResume_); + SendDlgItemMessage (hWndDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDPAUSE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDRESUME, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATUS_STATUS, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATUS_FILE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATUS_URL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + SendDlgItemMessage (hWndDlg, IDC_STATUS_TO, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L); + return FALSE; + + case WM_SIZE: + switch(wParam) + { + case SIZE_MINIMIZED: + SetMinimizedDownloadTitle((int)GetPercentSoFar()); + gbDlgDownloadMinimized = TRUE; + gbDlgDownloadJustMinimized = TRUE; + break; + + case SIZE_RESTORED: + SetStatusUrl(); + SetRestoredDownloadTitle(); + gbDlgDownloadMinimized = FALSE; + break; + } + return(FALSE); + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDCANCEL: + if(AskCancelDlg(hWndDlg)) + gdwDownloadDialogStatus = CS_CANCEL; + break; + + case IDPAUSE: + if(!gtiPaused.bTickStarted) + { + gtiPaused.dwTickBegin = GetTickCount(); + gtiPaused.bTickStarted = TRUE; + gtiPaused.bTickDownloadResumed = FALSE; + } + + EnableWindow(GetDlgItem(hWndDlg, IDPAUSE), FALSE); + EnableWindow(GetDlgItem(hWndDlg, IDRESUME), TRUE); + gdwDownloadDialogStatus = CS_PAUSE; + break; + + case IDRESUME: + gtiPaused.dwTickEnd = GetTickCount(); + gtiPaused.dwTickDif = GetTickDif(gtiPaused.dwTickEnd, + gtiPaused.dwTickBegin); + gtiPaused.bTickDownloadResumed = TRUE; + + EnableWindow(GetDlgItem(hWndDlg, IDRESUME), FALSE); + EnableWindow(GetDlgItem(hWndDlg, IDPAUSE), TRUE); + gdwDownloadDialogStatus = CS_NONE; + break; + + default: + break; + } + return(TRUE); + } + + return(FALSE); // didn't handle the message +} + +// This routine will update the File Gauge progress bar to the specified percentage +// (value between 0 and 100) +static void +UpdateGaugeFileProgressBar(double value) +{ + int nBars; + static long lModLastValue = 0; + + if(sgProduct.mode != SILENT) + { + if(!CheckInterval(&lModLastValue, UPDATE_INTERVAL_PROGRESS_BAR)) + return; + + // Figure out how many bars should be displayed + nBars = (int)(dlgInfo.nMaxFileBars * value / 100); + + // Only paint if we need to display more bars + if((nBars > dlgInfo.nFileBars) || (dlgInfo.nFileBars == 0)) + { + HWND hWndGauge = GetDlgItem(dlgInfo.hWndDlg, IDC_GAUGE_FILE); + RECT rect; + + // Update the gauge state before painting + dlgInfo.nFileBars = nBars; + + // Only invalidate the part that needs updating + GetClientRect(hWndGauge, &rect); + InvalidateRect(hWndGauge, &rect, FALSE); + + // Update the whole extracting dialog. We do this because we don't + // have a message loop to process WM_PAINT messages in case the + // extracting dialog was exposed + UpdateWindow(dlgInfo.hWndDlg); + } + } +} + +// Draws a recessed border around the gauge +static void +DrawGaugeBorder(HWND hWnd) +{ + HDC hDC = GetWindowDC(hWnd); + RECT rect; + int cx, cy; + HPEN hShadowPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); + HGDIOBJ hOldPen; + + GetWindowRect(hWnd, &rect); + cx = rect.right - rect.left; + cy = rect.bottom - rect.top; + + // Draw a dark gray line segment + hOldPen = SelectObject(hDC, (HGDIOBJ)hShadowPen); + MoveToEx(hDC, 0, cy - 1, NULL); + LineTo(hDC, 0, 0); + LineTo(hDC, cx - 1, 0); + + // Draw a white line segment + SelectObject(hDC, GetStockObject(WHITE_PEN)); + MoveToEx(hDC, 0, cy - 1, NULL); + LineTo(hDC, cx - 1, cy - 1); + LineTo(hDC, cx - 1, 0); + + SelectObject(hDC, hOldPen); + DeleteObject(hShadowPen); + ReleaseDC(hWnd, hDC); +} + +// Draws the blue progress bar +static void +DrawProgressBar(HWND hWnd, int nBars) +{ + int i; + PAINTSTRUCT ps; + HDC hDC; + RECT rect; + HBRUSH hBrush; + + hDC = BeginPaint(hWnd, &ps); + GetClientRect(hWnd, &rect); + if(nBars <= 0) + { + /* clear the bars */ + hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU)); + FillRect(hDC, &rect, hBrush); + } + else + { + // Draw the bars + hBrush = CreateSolidBrush(RGB(0, 0, 128)); + rect.left = rect.top = BAR_LIBXPNET_MARGIN; + rect.bottom -= BAR_LIBXPNET_MARGIN; + rect.right = rect.left + BAR_LIBXPNET_WIDTH; + + for(i = 0; i < nBars; i++) + { + RECT dest; + + if(IntersectRect(&dest, &ps.rcPaint, &rect)) + FillRect(hDC, &rect, hBrush); + + OffsetRect(&rect, BAR_LIBXPNET_WIDTH + BAR_LIBXPNET_SPACING, 0); + } + } + + DeleteObject(hBrush); + EndPaint(hWnd, &ps); +} + +// Adjusts the width of the gauge based on the maximum number of bars +static void +SizeToFitGauge(HWND hWnd, int nMaxBars) +{ + RECT rect; + int cx; + + // Get the window size in pixels + GetWindowRect(hWnd, &rect); + + // Size the width to fit + cx = 2 * GetSystemMetrics(SM_CXBORDER) + 2 * BAR_LIBXPNET_MARGIN + + nMaxBars * BAR_LIBXPNET_WIDTH + (nMaxBars - 1) * BAR_LIBXPNET_SPACING; + + SetWindowPos(hWnd, NULL, -1, -1, cx, rect.bottom - rect.top, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); +} + +// Window proc for Download gauge +BOOL CALLBACK +GaugeDownloadWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DWORD dwStyle; + RECT rect; + + switch(msg) + { + case WM_NCCREATE: + dwStyle = GetWindowLong(hWnd, GWL_STYLE); + SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_BORDER); + return(TRUE); + + case WM_CREATE: + // Figure out the maximum number of bars that can be displayed + GetClientRect(hWnd, &rect); + dlgInfo.nFileBars = 0; + dlgInfo.nMaxFileBars = (rect.right - rect.left - 2 * BAR_LIBXPNET_MARGIN + BAR_LIBXPNET_SPACING) / (BAR_LIBXPNET_WIDTH + BAR_LIBXPNET_SPACING); + + // Size the gauge to exactly fit the maximum number of bars + SizeToFitGauge(hWnd, dlgInfo.nMaxFileBars); + return(FALSE); + + case WM_NCPAINT: + DrawGaugeBorder(hWnd); + return(FALSE); + + case WM_PAINT: + DrawProgressBar(hWnd, dlgInfo.nFileBars); + return(FALSE); + } + + return(DefWindowProc(hWnd, msg, wParam, lParam)); +} + +void InitDownloadDlg(void) +{ + WNDCLASS wc; + + if(sgProduct.mode != SILENT) + { + memset(&wc, 0, sizeof(wc)); + wc.style = CS_GLOBALCLASS; + wc.hInstance = hInst; + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpfnWndProc = (WNDPROC)GaugeDownloadWndProc; + wc.lpszClassName = "GaugeFile"; + RegisterClass(&wc); + + // Display the dialog box + dlgInfo.hWndDlg = CreateDialog(hSetupRscInst, MAKEINTRESOURCE(DLG_DOWNLOADING), hWndMain, (DLGPROC)DownloadDlgProc); + UpdateWindow(dlgInfo.hWndDlg); + UpdateGaugeFileProgressBar(0); + } +} + +void DeInitDownloadDlg() +{ + if(sgProduct.mode != SILENT) + { + SaveWindowPosition(dlgInfo.hWndDlg); + DestroyWindow(dlgInfo.hWndDlg); + UnregisterClass("GaugeFile", hInst); + } +} diff --git a/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.h b/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.h new file mode 100644 index 00000000000..fb222a0b3eb --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.h @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 1998, 1999, 2000, 2001 Netscape Communications Corp. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _XPNETHOOK_H_ +#define _XPNETHOOK_H_ + +int WGet(char *szUrl, + char *szFile, + char *szProxyServer, + char *szProxyPort, + char *szProxyUser, + char *szProxyPasswd); +int DownloadFiles(char *szInputIniFile, + char *szDownloadDir, + char *szProxyServer, + char *szProxyPort, + char *szProxyUser, + char *szProxyPasswd, + BOOL bShowRetryMsg, + BOOL bIgnoreNetworkError, + char *szFailedFile, + DWORD dwFailedFileSize); + +#endif /* _XPNETHOOK_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/setup/zipfile.h b/toolkit/mozapps/installer/windows/wizard/setup/zipfile.h new file mode 100644 index 00000000000..f0477212608 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setup/zipfile.h @@ -0,0 +1,92 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Daniel Veditz + */ + +#ifndef _zipfile_h +#define _zipfile_h +/* + * This module implements a simple archive extractor for the PKZIP format. + * + * All functions return a status/error code, and have an opaque hZip argument + * that represents an open archive. + * + * Currently only compression mode 8 (or none) is supported. + */ + + +#define ZIP_OK 0 +#define ZIP_ERR_GENERAL -1 +#define ZIP_ERR_MEMORY -2 +#define ZIP_ERR_DISK -3 +#define ZIP_ERR_CORRUPT -4 +#define ZIP_ERR_PARAM -5 +#define ZIP_ERR_FNF -6 +#define ZIP_ERR_UNSUPPORTED -7 +#define ZIP_ERR_SMALLBUF -8 + +PR_BEGIN_EXTERN_C + +/* Open and close the archive + * + * If successful OpenArchive returns a handle in the hZip parameter + * that must be passed to all subsequent operations on the archive + */ +extern __declspec(dllexport)int ZIP_OpenArchive( const char * zipname, void** hZip ); +extern __declspec(dllexport)int ZIP_CloseArchive( void** hZip ); + + +/* Test the integrity of every item in this open archive + * by verifying each item's checksum against the stored + * CRC32 value. + */ +extern __declspec(dllexport)int ZIP_TestArchive( void* hZip ); + +/* Extract the named file in the archive to disk. + * This function will happily overwrite an existing Outfile if it can. + * It's up to the caller to detect or move it out of the way if it's important. + */ +extern __declspec(dllexport)int ZIP_ExtractFile( void* hZip, const char * filename, const char * outname ); + + +/* Functions to list the files contained in the archive + * + * FindInit() initializes the search with the pattern and returns a find token, + * or NULL on an error. Then FindNext() is called with the token to get the + * matching filenames if any. When done you must call FindFree() with the + * token to release memory. + * + * a NULL pattern will find all the files in the archive, otherwise the + * pattern must be a shell regexp type pattern. + * + * if a matching filename is too small for the passed buffer FindNext() + * will return ZIP_ERR_SMALLBUF. When no more matches can be found in + * the archive it will return ZIP_ERR_FNF + */ +extern __declspec(dllexport)void* ZIP_FindInit( void* hZip, const char * pattern ); +extern __declspec(dllexport)int ZIP_FindNext( void* hFind, char * outbuf, int bufsize ); +extern __declspec(dllexport)int ZIP_FindFree( void* hFind ); + + +PR_END_EXTERN_C + +#endif /* _zipfile_h */ diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/Makefile.in b/toolkit/mozapps/installer/windows/wizard/setuprsc/Makefile.in new file mode 100644 index 00000000000..6660b75bb66 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setuprsc/Makefile.in @@ -0,0 +1,62 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = setuprsc +LIBRARY_NAME = setuprsc +RESFILE = setuprsc.res + +USE_NON_MT_LIBS = 1 + +NO_DIST_INSTALL = 1 + +EXPORTS = setuprsc.h + +CPPSRCS = setuprsc.cpp + +GARBAGE += $(DIST)/install/$(SHARED_LIBRARY) +GARBAGE_DIRS += $(DIST)/include/$(MODULE) + +FORCE_SHARED_LIB=1 + +LOCAL_INCLUDES = -I$(srcdir) + +include $(topsrcdir)/config/rules.mk + +# Hack to get around the default rules insisting that .lib should exist +$(IMPORT_LIBRARY): + touch $@ + +export:: $(EXPORTS) + $(INSTALL) $< $(DIST)/include/$(MODULE)/ + +libs:: $(SHARED_LIBRARY) + $(INSTALL) $< $(DIST)/install + +install:: $(SHARED_LIBRARY) + $(INSTALL) $< $(DESTDIR)$(mozappdir)/install + diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/bitmap1.bmp b/toolkit/mozapps/installer/windows/wizard/setuprsc/bitmap1.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/box_ch_d.bmp b/toolkit/mozapps/installer/windows/wizard/setuprsc/box_ch_d.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/box_chec.bmp b/toolkit/mozapps/installer/windows/wizard/setuprsc/box_chec.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/box_unch.bmp b/toolkit/mozapps/installer/windows/wizard/setuprsc/box_unch.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/downloadLogo.bmp b/toolkit/mozapps/installer/windows/wizard/setuprsc/downloadLogo.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/setup.ico b/toolkit/mozapps/installer/windows/wizard/setuprsc/setup.ico new file mode 100644 index 0000000000000000000000000000000000000000..f8acc71c2506733106ec3a9f48c16fbb7e52b064 GIT binary patch literal 1078 zcmb7@v5wm?42J1T0BbnZd4pss@)qYIK$bp?hXT?T7B^T!0rzpbMR&8&zQO@rI&?75 zAptt5AC+@aq*oMW@{9UKQX~~dq>>xiY*u3O^+x11dbPUnZ6)$*A+qIc16okYl2t_U zeOVME7S)SlWh*Hqv>9^wO3t*+1$b5sYfm#q~SW6zx-MnAPy86^kp>FbcC#0S^w5PV185+9WKQ}1%_9MMBiVusE* zS;q@^6P>?@K6BoFP@^*^b^ z^_EL)@;6|f^ThsTQDz(qGhGxb+y9#LCact;BRNCMz%|)(p~&s%g?T~mUCkWbjyq>B zI^?&!R`)2zQeb2_*46EAMMMo%)-{0#RZ_YWfPcpT+Ft`)%J NmvHt0OjkI=e*(b)OYQ&w literal 0 HcmV?d00001 diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.cpp b/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.cpp new file mode 100644 index 00000000000..9800efd9b9d --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include + +int FAR PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg, WORD cbHeapSize, LPSTR lpCmdLine) +{ + return(1); +} diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.h b/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.h new file mode 100644 index 00000000000..35d24d70825 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.h @@ -0,0 +1,149 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by setuprsc.rc +// + +#ifndef WINVER +#define WINVER 0x0400 +#endif +#include "winresrc.h" + +#define IDS_ERROR_FILE_NOT_FOUND 3 +#define IDRESUME 3 +#define IDPAUSE 4 +#define IDS_MSG_RETRIEVE_INSTALLINI 11 +#define IDI_ICON1 105 +#define IDI_SETUP 105 +#define IDB_BITMAP_WELCOME 108 +#define DLG_MESSAGE 110 +#define IDB_BITMAP_BANNER 114 +#define IDB_QUICK_LAUNCH 115 +#define DLG_BROWSE_DIR 503 +#define IDC_STATUS 1001 +#define IDC_STATUS1 1001 +#define ID_DELETE 1001 +#define IDC_STATUS_URL 1001 +#define IDCONTINUE 1001 +#define IDC_GAUGE 1002 +#define IDC_GAUGE_FILE 1002 +#define ID_IGNORE 1002 +#define IDSKIP 1002 +#define IDC_STATUS2 1003 +#define IDC_STATUS_URL2 1003 +#define IDC_STATUS_TO 1003 +#define IDC_STATUS0 1004 +#define IDC_STATUS3 1005 +#define ID_YES_TO_ALL 1005 +#define IDC_STATUS_URL3 1005 +#define IDC_GAUGE_ARCHIVE 1006 +#define IDC_EDIT_DESTINATION 1009 +#define IDC_BUTTON_BROWSE 1010 +#define IDC_EDIT_COMPONENT1 1013 +#define IDC_EDIT_SUBCOMPONENT 1014 +#define IDC_STATIC_SUBCOMPONENT 1016 +#define IDC_CHECK1 1017 +#define IDC_STATIC_DESCRIPTION 1018 +#define IDC_EDIT_PROGRAM_FOLDER 1019 +#define IDC_CHECK2 1023 +#define IDC_LIST2 1023 +#define IDC_LIST 1023 +#define IDC_CHECK3 1024 +#define IDC_EDIT_LICENSE 1024 +#define IDC_CHECK0 1025 +#define IDC_CURRENT_SETTINGS 1026 +#define IDC_LIST_COMPONENTS 1027 +#define IDC_LIST_SUBCOMPONENTS 1029 +#define IDC_STATIC_DRIVE_SPACE_REQUIRED 1030 +#define IDC_SPACE_AVAILABLE 1030 +#define IDC_STATIC_DRIVE_SPACE_AVAILABLE 1031 +#define IDC_STATIC_DESTINATION 1032 +#define IDC_STATIC0 1033 +#define IDC_STATIC1 1034 +#define IDC_STATIC2 1035 +#define IDC_STATIC3 1036 +#define IDC_STATIC4 1037 +#define IDC_PERCENTAGE 1038 +#define IDC_MESSAGE1 1040 +#define IDC_PICT0 1041 +#define IDC_MESSAGE0 1042 +#define IDC_STATIC_ST0_DESCRIPTION 1042 +#define IDC_STATIC_ST1_DESCRIPTION 1043 +#define IDC_MESSAGE2 1043 +#define IDC_STATIC_ST2_DESCRIPTION 1044 +#define IDC_STATIC_ST3_DESCRIPTION 1045 +#define IDC_STATIC_MSG0 1046 +#define IDC_MESSAGE 1049 +#define IDC_LIST1 1053 +#define IDC_BUTTON1 1055 +#define IDC_README 1055 +#define IDC_BUTTON_SITE_SELECTOR 1055 +#define IDC_DOWNLOAD_SIZE 1058 +#define IDC_SITE_SELECTOR 1059 +#define IDC_LIST_SITE_SELECTOR 1059 +#define IDC_CHECK_SAVE_INSTALLER 1061 +#define IDC_CHECK_SAVE_INSTALLER_FILES 1061 +#define IDC_EDIT_PROXY_SERVER 1062 +#define IDC_EDIT_PROXY_PORT 1063 +#define IDC_TAB1 1064 +#define IDC_EDIT_PROXY_USER 1064 +#define IDC_DELETE_PATH 1065 +#define IDC_EDIT_PROXY_PASSWD 1065 +#define IDC_LOCAL_INSTALLER_PATH 1066 +#define IDC_EDIT_LOCAL_INSTALLER_PATH 1066 +#define IDC_BUTTON_ADDITIONAL_SETTINGS 1067 +#define IDC_BUTTON_PROXY_SETTINGS 1067 +#define IDC_STATUS_FILE 1070 +#define IDC_STATUS_STATUS 1071 +#define IDC_USE_HTTP 1073 +#define IDC_USE_FTP 1074 +#define IDC_DESTINATION 1074 +#define IDC_CHECK_TURBO_MODE 1075 +#define IDC_CHECK_RECAPTURE_HOMEPAGE 1076 +#define DLG_WELCOME 2001 +#define DLG_LICENSE 2002 +#define DLG_SETUP_TYPE 2003 +#define DLG_SELECT_COMPONENTS_SINGLE 2004 +#define DLG_SELECT_COMPONENTS 2004 +#define DLG_SELECT_COMPONENTS_MULTI 2005 +#define DLG_WINDOWS_INTEGRATION 2006 +#define DLG_PROGRAM_FOLDER 2007 +#define DLG_START_INSTALL 2008 +#define DLG_EXTRACTING 2009 +#define DLG_QUICK_LAUNCH 2010 +#define DLG_RESTART 10206 +#define DLG_SITE_SELECTOR 10207 +#define DLG_ADVANCED_SETTINGS 10207 +#define DLG_SELECT_ADDITIONAL_COMPONENTS 10208 +#define DLG_UPGRADE 10209 +#define DLG_ADDITIONAL_OPTIONS 10210 +#define DLG_DOWNLOADING 10211 +#define DLG_START_INSTALL1 10212 +#define IDB_BOX_CHECKED 10304 +#define IDB_BOX_UNCHECKED 10306 +#define IDB_BOX_CHECKED_DISABLED 10307 +#define IDC_RADIO_TYPICAL 11007 +#define IDC_RADIO_ST0 11007 +#define IDC_RADIO_CUSTOM 11008 +#define IDC_RADIO_ST2 11008 +#define IDC_RADIO_COMPACT 11009 +#define IDC_RADIO_ST1 11009 +#define IDC_RADIO_ST3 11010 +#define IDC_RADIO_YES 11011 +#define IDC_RADIO_NO 11012 +#define IDWIZBACK 11013 +#define IDWIZNEXT 11014 +#define IDS_MSG_CREATE_DIRECTORY 11015 +#define IDWIZNEXT2 11015 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 116 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1079 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.rc b/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.rc new file mode 100644 index 00000000000..79bb70f82bb --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/setuprsc/setuprsc.rc @@ -0,0 +1,480 @@ +//Microsoft Developer Studio generated resource script. +// +#include "setuprsc.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "setuprsc.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +DLG_WELCOME DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_STATIC0,101,11,202,37,NOT WS_GROUP + LTEXT "",IDC_STATIC1,102,53,201,37,NOT WS_GROUP + LTEXT "",IDC_STATIC2,102,96,201,37,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + +DLG_SETUP_TYPE DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_RADIO_ST0,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,102,29,65,12 + CONTROL "",IDC_RADIO_ST1,"Button",BS_AUTORADIOBUTTON,102,57,65, + 12 + CONTROL "",IDC_RADIO_ST2,"Button",BS_AUTORADIOBUTTON,102,84,64, + 12 + CONTROL "",IDC_RADIO_ST3,"Button",BS_AUTORADIOBUTTON,102,112,64, + 12 + LTEXT "",IDC_STATIC_ST0_DESCRIPTION,175,31,126,24 + LTEXT "",IDC_STATIC_ST1_DESCRIPTION,175,59,126,24 + LTEXT "",IDC_STATIC_ST2_DESCRIPTION,175,86,126,24 + LTEXT "",IDC_STATIC_ST3_DESCRIPTION,175,114,126,25 + GROUPBOX "",IDC_DESTINATION,101,147,204,27 + CONTROL "",IDC_EDIT_DESTINATION,"Static",SS_LEFTNOWORDWRAP | + WS_GROUP,107,160,143,9 + PUSHBUTTON "",IDC_BUTTON_BROWSE,255,156,46,14 + PUSHBUTTON "",IDC_README,11,186,83,14 + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_STATIC_MSG0,101,11,204,17,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + +DLG_SELECT_COMPONENTS DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "",IDC_STATIC1,101,32,103,8 + LISTBOX IDC_LIST_COMPONENTS,101,42,204,67,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_HSCROLL | WS_GROUP | WS_TABSTOP + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_MESSAGE0,101,10,204,19,NOT WS_GROUP + GROUPBOX "",IDC_STATIC2,101,115,204,22 + LTEXT "",IDC_STATIC_DESCRIPTION,106,124,195,8,SS_NOPREFIX + GROUPBOX "",IDC_STATIC,101,140,204,33 + LTEXT "",IDC_DOWNLOAD_SIZE,105,160,92,8,NOT WS_GROUP + LTEXT "",IDC_SPACE_AVAILABLE,206,160,94,8,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE + LTEXT "",IDC_STATIC,201,32,103,8,0,WS_EX_RIGHT + LTEXT "",IDC_STATIC3,105,148,92,9 + LTEXT "",IDC_STATIC4,206,148,94,9 +END + +DLG_WINDOWS_INTEGRATION DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_CHECK0,"Button",BS_AUTOCHECKBOX | BS_TOP | + BS_MULTILINE | WS_TABSTOP,101,32,205,17 + CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | BS_TOP | + BS_MULTILINE | WS_TABSTOP,101,53,205,17 + CONTROL "",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | BS_TOP | + BS_MULTILINE | WS_TABSTOP,101,73,205,17 + CONTROL "",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | BS_TOP | + BS_MULTILINE | WS_TABSTOP,101,94,205,17 + LTEXT "",IDC_MESSAGE1,101,117,205,54,NOT WS_GROUP + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_MESSAGE0,101,11,204,17,NOT WS_GROUP + CONTROL 108,IDC_PICT0,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC0,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + +DLG_PROGRAM_FOLDER DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "",IDC_STATIC1,101,54,105,8 + EDITTEXT IDC_EDIT_PROGRAM_FOLDER,101,64,204,12,ES_AUTOHSCROLL + LTEXT "",IDC_STATIC2,101,84,163,8 + LISTBOX IDC_LIST,101,94,204,79,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_MESSAGE0,101,11,204,33,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + +DLG_LICENSE DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + EDITTEXT IDC_EDIT_LICENSE,11,29,295,119,ES_MULTILINE | + ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_GROUP + LTEXT "",IDC_MESSAGE0,11,8,295,17,NOT WS_GROUP + LTEXT "",IDC_MESSAGE1,11,152,295,19,NOT WS_GROUP + CONTROL "",-1,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + +DLG_QUICK_LAUNCH DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_CHECK_TURBO_MODE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,101,157,204,9 + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_MESSAGE0,101,14,204,18,NOT WS_GROUP + LTEXT "",IDC_MESSAGE1,101,50,204,20,NOT WS_GROUP + LTEXT "",IDC_MESSAGE2,101,127,204,18,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE + CONTROL 115,IDC_STATIC,"Static",SS_BITMAP,102,76,20,20 +END + +DLG_BROWSE_DIR DIALOG DISCARDABLE 147, 23, 190, 143 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "",1092,8,6,92,9 + EDITTEXT IDC_EDIT_DESTINATION,8,16,177,12,ES_AUTOHSCROLL | + ES_OEMCONVERT | NOT WS_BORDER,WS_EX_CLIENTEDGE + LISTBOX 1121,8,37,120,68,LBS_SORT | LBS_NOREDRAW | + LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | + LBS_DISABLENOSCROLL | WS_VSCROLL | WS_HSCROLL | + WS_TABSTOP + LTEXT "",1091,8,108,92,9 + COMBOBOX 1137,8,118,121,68,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | + CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "",1,135,43,50,14,WS_GROUP + PUSHBUTTON "",IDCANCEL,135,63,50,14,WS_GROUP +END + +DLG_RESTART DIALOG FIXED IMPURE 133, 69, 255, 111 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "",202,10,10,236,36,SS_NOPREFIX + CONTROL "",IDC_RADIO_YES,"Button",BS_AUTORADIOBUTTON,26,52,220, + 12 + CONTROL "",IDC_RADIO_NO,"Button",BS_AUTORADIOBUTTON,26,68,223,12 + DEFPUSHBUTTON "",IDOK,189,88,50,14,WS_GROUP +END + +DLG_MESSAGE DIALOG DISCARDABLE 0, 0, 236, 34 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + CTEXT "",IDC_MESSAGE,0,0,236,34,SS_CENTERIMAGE +END + +DLG_EXTRACTING DIALOG DISCARDABLE 0, 0, 312, 154 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_STATUS0,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | + WS_GROUP,12,64,286,8 + CONTROL "",IDC_GAUGE_ARCHIVE,"GaugeArchive",0x0,12,77,286,11 + CONTROL "",IDC_STATUS3,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | + WS_GROUP,12,98,286,8 + CONTROL "",IDC_GAUGE_FILE,"GaugeFile",0x0,12,110,286,11 + CONTROL 114,IDB_BITMAP_BANNER,"Static",SS_BITMAP,0,0,312,34 +END + +DLG_ADVANCED_SETTINGS DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_EDIT_PROXY_SERVER,165,57,134,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PROXY_PORT,165,74,134,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PROXY_USER,165,101,134,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PROXY_PASSWD,165,118,134,12,ES_PASSWORD | + ES_AUTOHSCROLL + CONTROL "",IDC_USE_FTP,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, + 101,148,205,9 + CONTROL "",IDC_USE_HTTP,"Button",BS_AUTORADIOBUTTON,101,161,205, + 9 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE + RTEXT "",IDC_STATIC1,108,59,52,9 + RTEXT "",IDC_STATIC2,108,75,52,9 + GROUPBOX "",IDC_STATIC,101,44,206,94 + LTEXT "",IDC_MESSAGE0,101,11,204,29,NOT WS_GROUP + RTEXT "",IDC_STATIC3,108,102,52,9 + RTEXT "",IDC_STATIC4,108,120,52,9 +END + +DLG_SELECT_ADDITIONAL_COMPONENTS DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "",IDC_STATIC1,101,32,125,8 + LISTBOX IDC_LIST_COMPONENTS,101,42,204,67,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_HSCROLL | WS_GROUP | WS_TABSTOP + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_MESSAGE0,101,10,204,19,NOT WS_GROUP + GROUPBOX "",IDC_STATIC2,101,115,204,22 + LTEXT "",IDC_STATIC_DESCRIPTION,106,124,195,8,SS_NOPREFIX + GROUPBOX "",IDC_STATIC,101,140,204,33 + LTEXT "",IDC_DOWNLOAD_SIZE,105,160,92,8,NOT WS_GROUP + LTEXT "",IDC_SPACE_AVAILABLE,206,160,94,8,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE + LTEXT "",IDC_STATIC,241,32,63,8,0,WS_EX_RIGHT + LTEXT "",IDC_STATIC3,105,148,92,9 + LTEXT "",IDC_STATIC4,206,148,94,9 +END + +DLG_UPGRADE DIALOG DISCARDABLE 51, 56, 310, 166 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",IDCONTINUE,65,147,53,14 + PUSHBUTTON "",IDSKIP,128,147,53,14 + PUSHBUTTON "",IDWIZBACK,191,147,53,14 + LTEXT "",IDC_MESSAGE0,9,9,291,93,NOT WS_GROUP + GROUPBOX "",IDC_STATIC,9,109,291,25 + LTEXT "",IDC_DELETE_PATH,13,118,282,12,SS_CENTERIMAGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,9,140,292,1, + WS_EX_STATICEDGE +END + +DLG_ADDITIONAL_OPTIONS DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_CHECK_RECAPTURE_HOMEPAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,100,56,202,8 + LTEXT "",IDC_MESSAGE1,100,76,204,33,NOT WS_GROUP + CONTROL "",IDC_CHECK_SAVE_INSTALLER_FILES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,100,112,204,9 + EDITTEXT IDC_EDIT_LOCAL_INSTALLER_PATH,100,124,204,12, + ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "",IDC_BUTTON_PROXY_SETTINGS,221,159,84,14 + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + LTEXT "",IDC_MESSAGE0,100,20,204,33,NOT WS_GROUP + CONTROL 108,-1,"Static",SS_BITMAP,11,11,83,162,WS_EX_CLIENTEDGE + CONTROL "",-1,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + +DLG_DOWNLOADING DIALOG DISCARDABLE 0, 0, 312, 154 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",IDPAUSE,136,134,50,14,WS_GROUP + PUSHBUTTON "",IDRESUME,187,134,50,14,WS_GROUP + PUSHBUTTON "",IDCANCEL,252,134,50,14,WS_GROUP + LTEXT "",IDC_MESSAGE0,9,39,293,23 + LTEXT "",IDC_STATIC3,9,81,37,8,SS_NOPREFIX + CONTROL "",IDC_STATUS_URL,"Static",SS_LEFTNOWORDWRAP | + SS_NOPREFIX | WS_GROUP,49,81,253,8 + LTEXT "",IDC_STATIC1,9,101,37,8,SS_NOPREFIX + CONTROL "",IDC_STATUS_STATUS,"Static",SS_LEFTNOWORDWRAP | + SS_NOPREFIX | WS_GROUP,49,101,253,8 + LTEXT "",IDC_STATIC2,9,72,37,8,SS_NOPREFIX + CONTROL "",IDC_STATUS_FILE,"Static",SS_LEFTNOWORDWRAP | + SS_NOPREFIX | WS_GROUP,49,72,253,8 + CONTROL "",IDC_GAUGE_FILE,"GaugeFile",0x0,9,114,271,11 + LTEXT "",IDC_PERCENTAGE,283,115,20,8,SS_NOPREFIX + CONTROL 114,IDB_BITMAP_BANNER,"Static",SS_BITMAP,0,0,312,34 + LTEXT "",IDC_STATIC4,9,91,37,8,SS_NOPREFIX + CONTROL "",IDC_STATUS_TO,"Static",SS_LEFTNOWORDWRAP | + SS_NOPREFIX | WS_GROUP,49,91,253,8 +END + +DLG_START_INSTALL DIALOG DISCARDABLE 51, 56, 315, 205 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",IDWIZNEXT,188,186,53,14 + PUSHBUTTON "",IDWIZBACK,134,186,53,14 + PUSHBUTTON "",IDCANCEL,252,186,53,14 + EDITTEXT IDC_CURRENT_SETTINGS,101,67,204,102,ES_MULTILINE | + ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL + LTEXT "",IDC_MESSAGE0,101,11,204,52,NOT WS_GROUP + CONTROL 108,IDC_STATIC,"Static",SS_BITMAP,11,11,83,162, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,11,179,295,1, + WS_EX_STATICEDGE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SETUP ICON DISCARDABLE "setup.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_BOX_UNCHECKED BITMAP FIXED IMPURE "box_unch.bmp" +IDB_BOX_CHECKED BITMAP FIXED IMPURE "box_chec.bmp" +IDB_BITMAP_WELCOME BITMAP DISCARDABLE "bitmap1.bmp" +IDB_BOX_CHECKED_DISABLED BITMAP FIXED IMPURE "box_ch_d.bmp" +IDB_BITMAP_BANNER BITMAP DISCARDABLE "downloadLogo.bmp" +IDB_QUICK_LAUNCH BITMAP DISCARDABLE "turbo-systray.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + DLG_EXTRACTING, DIALOG + BEGIN + BOTTOMMARGIN, 153 + END + + DLG_UPGRADE, DIALOG + BEGIN + BOTTOMMARGIN, 165 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ERROR_FILE_NOT_FOUND "File not found: %s" + IDS_MSG_RETRIEVE_INSTALLINI + "Please wait while Setup is attempting to retrieve install.ini, required by Setup, from the Web..." +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/toolkit/mozapps/installer/windows/wizard/setuprsc/turbo-systray.bmp b/toolkit/mozapps/installer/windows/wizard/setuprsc/turbo-systray.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/Makefile.in b/toolkit/mozapps/installer/windows/wizard/uninstall/Makefile.in new file mode 100644 index 00000000000..9b5b641c3c6 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/Makefile.in @@ -0,0 +1,70 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = uninstall +PROGRAM = uninstall$(BIN_SUFFIX) +RESFILE = uninstall.res +REQUIRES = $(ZLIB_REQUIRES) +EXTRA_DSO_LIBS = mozz_s +USE_NON_MT_LIBS = 1 + +EXPORTS = logkeys.h + +CSRCS = \ + uninstall.c \ + extra.c \ + dialogs.c \ + parser.c \ + ifuncns.c \ + rdi.c \ + process.c \ + $(NULL) + +MOZ_WINCONSOLE = 0 + +LOCAL_INCLUDES = -I$(srcdir) + +ifdef GNU_CC +OS_LIBS += -lshell32 -lversion -lgdi32 +else +OS_LIBS += shell32.lib version.lib +endif + +NO_DIST_INSTALL = 1 + +include $(topsrcdir)/config/rules.mk + +libs:: $(PROGRAM) + $(INSTALL) $(PROGRAM) $(DIST)/install + +install:: $(PROGRAM) + $(INSTALL) $(PROGRAM) $(DESTDIR)$(mozappdir)/install + +clean clobber realclean clobber_all:: + $(RM) $(DIST)/install/$(PROGRAM) + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.c b/toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.c new file mode 100644 index 00000000000..1f26fc26771 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.c @@ -0,0 +1,526 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "extern.h" +#include "extra.h" +#include "dialogs.h" +#include "ifuncns.h" +#include "parser.h" +#include "rdi.h" +#include "shlobj.h" + +#define MOZ_HWND_BROADCAST_MSG_TIMEOUT 5000 +#define MOZ_CLIENT_BROWSER_KEY "Software\\Clients\\StartMenuInternet" +#define MOZ_CLIENT_MAIL_KEY "Software\\Clients\\Mail" + +void SetDefault() +{ + char szBuf[MAX_BUF]; + char szRegKey[MAX_BUF]; + + GetPrivateProfileString(ugUninstall.szDefaultComponent, "ClientTypeName", "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + wsprintf(szRegKey, "SOFTWARE\\Clients\\%s", szBuf); + GetPrivateProfileString(ugUninstall.szDefaultComponent, "ClientProductKey", "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + + SetWinReg(HKEY_LOCAL_MACHINE, szRegKey, "", REG_SZ, szBuf, lstrlen(szBuf)); +} + +void ParseDefaultsInfo() +{ + char szBuf[MAX_BUF]; + char szIniKey[MAX_BUF]; + char szStorageDir[MAX_BUF]; + char szShortcutPath[MAX_BUF]; + char szStoredShortcutPath[MAX_BUF]; + char szRegKey[MAX_BUF]; + char szClientTypeName[MAX_BUF]; + char szClientProductKey[MAX_BUF]; + int iIndex; + DWORD dwIconsVisible; + + // If szAppPath is a null sting, i.e. we cannot find where the app has been installed: + // - HIDEICONS will still remove the shortcuts but + // - SHOWICONS will do nothing because we won't be able to find the shortcuts to display. + ParsePath(ugUninstall.szAppPath, szStorageDir, MAX_BUF, PP_PATH_ONLY); + lstrcat(szStorageDir, "defaults\\shortcuts\\"); + + // CLEANUP ISSUE: For all of the SHOWICON and HIDEICONS blocks below, there is a lot of + // redundancy: + // - Right now I'm just trying to create icons and, if I can't, trying under the PERSONAL + // key instead. I would be cleaner to check for restricted access once, and then just + // create the appropriate key each time. + // - Creating a ShowIcon() and a HideIcon() function would rid us much of the redundency. + + + // Deal with Desktop Icons + iIndex = 0; + wsprintf(szIniKey, "DesktopShortcut%d", iIndex); + GetPrivateProfileString(ugUninstall.szDefaultComponent, szIniKey, "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + while(szBuf[0] != '\0') + { + strcpy(szShortcutPath, "COMMON_DESKTOP"); + DecryptVariable(szShortcutPath, MAX_BUF); + + if((ugUninstall.mode == SHOWICONS) && (szStorageDir[0] != '\0')) + { + wsprintf(szStoredShortcutPath, "%s%s", szStorageDir, szBuf); + FileCopy(szStoredShortcutPath, szShortcutPath, 0); + if( (!FileExists(szShortcutPath)) && (!(ulOSType & OS_WIN9x)) ) + { + strcpy(szShortcutPath, "PERSONAL_DESKTOP"); + DecryptVariable(szShortcutPath, MAX_BUF); + FileCopy(szStoredShortcutPath, szShortcutPath, 0); + } + } + + if (ugUninstall.mode == HIDEICONS) + { + AppendBackSlash(szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, szBuf); + if( (!FileExists(szShortcutPath)) && (!(ulOSType & OS_WIN9x)) ) + { + strcpy(szShortcutPath, "PERSONAL_DESKTOP"); + DecryptVariable(szShortcutPath, MAX_BUF); + AppendBackSlash(szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, szBuf); + } + + FileDelete(szShortcutPath); + } + + iIndex++; + wsprintf(szIniKey, "DesktopShortcut%d", iIndex); + GetPrivateProfileString(ugUninstall.szDefaultComponent, szIniKey, "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + } + + // Deal with StartMenu Icons + iIndex = 0; + wsprintf(szIniKey, "StartMenuShortcut%d", iIndex); + GetPrivateProfileString(ugUninstall.szDefaultComponent, szIniKey, "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + while(szBuf[0] != '\0') + { + strcpy(szShortcutPath, "COMMON_STARTMENU"); + DecryptVariable(szShortcutPath, MAX_BUF); + + if((ugUninstall.mode == SHOWICONS) && (szStorageDir[0] != '\0')) + { + lstrcpy(szStoredShortcutPath, szStorageDir); + lstrcat(szStoredShortcutPath, szBuf); + FileCopy(szStoredShortcutPath, szShortcutPath, 0); + if( (!FileExists(szShortcutPath)) && (!(ulOSType & OS_WIN9x)) ) + { + strcpy(szShortcutPath, "PERSONAL_STARTMENU"); + DecryptVariable(szShortcutPath, MAX_BUF); + FileCopy(szStoredShortcutPath, szShortcutPath, 0); + } + } + + if (ugUninstall.mode == HIDEICONS) + { + AppendBackSlash(szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, szBuf); + if( (!FileExists(szShortcutPath)) && (!(ulOSType & OS_WIN9x)) ) + { + strcpy(szShortcutPath, "PERSONAL_STARTMENU"); + DecryptVariable(szShortcutPath, MAX_BUF); + AppendBackSlash(szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, szBuf); + } + + FileDelete(szShortcutPath); + } + + iIndex++; + wsprintf(szIniKey, "StartMenuShortcut%d", iIndex); + GetPrivateProfileString(ugUninstall.szDefaultComponent, szIniKey, "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + } + + // Deal with QuickLaunch Bar Icons + iIndex = 0; + wsprintf(szIniKey, "QuickLaunchBarShortcut%d", iIndex); + GetPrivateProfileString(ugUninstall.szDefaultComponent, szIniKey, "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + while(szBuf[0] != '\0') + { + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "AppData", szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, "\\Microsoft\\Internet Explorer\\Quick Launch"); + + if((ugUninstall.mode == SHOWICONS) && (szStorageDir[0] != '\0')) + { + wsprintf(szStoredShortcutPath, "%s%s", szStorageDir, szBuf); + FileCopy(szStoredShortcutPath, szShortcutPath, 0); + if( (!FileExists(szShortcutPath)) && (!(ulOSType & OS_WIN9x)) ) + { + GetWinReg(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\GrpConv\\MapGroups", "Quick Launch", szShortcutPath, MAX_BUF); + FileCopy(szStoredShortcutPath, szShortcutPath, 0); + } + } + + if (ugUninstall.mode == HIDEICONS) + { + AppendBackSlash(szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, szBuf); + if( (!FileExists(szShortcutPath)) && (!(ulOSType & OS_WIN9x)) ) + { + GetWinReg(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\GrpConv\\MapGroups", "Quick Launch", szShortcutPath, MAX_BUF); + AppendBackSlash(szShortcutPath, MAX_BUF); + lstrcat(szShortcutPath, szBuf); + } + + FileDelete(szShortcutPath); + } + + ++iIndex; + wsprintf(szIniKey, "QuickLaunchBarShortcut%d", iIndex); + GetPrivateProfileString(ugUninstall.szDefaultComponent, szIniKey, "", szBuf, MAX_BUF, szFileIniDefaultsInfo); + } + + GetPrivateProfileString(ugUninstall.szDefaultComponent, "ClientTypeName", "", szClientTypeName, MAX_BUF, szFileIniDefaultsInfo); + GetPrivateProfileString(ugUninstall.szDefaultComponent, "ClientProductKey", "", szClientProductKey, MAX_BUF, szFileIniDefaultsInfo); + wsprintf(szRegKey, "SOFTWARE\\Clients\\%s\\%s\\InstallInfo", szClientTypeName, szClientProductKey); + + if (ugUninstall.mode == SHOWICONS) + dwIconsVisible = 1; + else + dwIconsVisible = 0; + + SetWinRegNumValue(HKEY_LOCAL_MACHINE, szRegKey, "IconsVisible", dwIconsVisible); +} + +void ParseAllUninstallLogs() +{ + char szFileInstallLog[MAX_BUF]; + char szKey[MAX_BUF]; + sil *silFile; + DWORD dwFileFound; + DWORD dwRv = 0; + + UndoDesktopIntegration(); + CleanupMailIntegration(); + dwFileFound = GetLogFile(ugUninstall.szLogPath, ugUninstall.szLogFilename, szFileInstallLog, sizeof(szFileInstallLog)); + while(dwFileFound) + { + if((silFile = InitSilNodes(szFileInstallLog)) != NULL) + { + FileDelete(szFileInstallLog); + dwRv = Uninstall(silFile); + DeInitSilNodes(&silFile); + if(dwRv == WTD_CANCEL) + break; + } + + dwFileFound = GetLogFile(ugUninstall.szLogPath, ugUninstall.szLogFilename, szFileInstallLog, sizeof(szFileInstallLog)); + } + + if(dwRv != WTD_CANCEL) + { + lstrcpy(szFileInstallLog, ugUninstall.szLogPath); + AppendBackSlash(szFileInstallLog, MAX_BUF); + lstrcat(szFileInstallLog, ugUninstall.szLogFilename); + if(FileExists(szFileInstallLog)) + { + if((silFile = InitSilNodes(szFileInstallLog)) != NULL) + { + FileDelete(szFileInstallLog); + Uninstall(silFile); + DeInitSilNodes(&silFile); + } + } + + /* clean up the uninstall windows registry key */ + lstrcpy(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\uninstall\\"); + lstrcat(szKey, ugUninstall.szUninstallKeyDescription); + RegDeleteKey(HKEY_LOCAL_MACHINE, szKey); + + /* update Wininit.ini to remove itself at reboot */ + RemoveUninstaller(ugUninstall.szUninstallFilename); + + // Calling SHChangeNotify() will update the file association icons + // in case they had been reset. + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + /* Broadcast message only if the windows registry keys exist + * in case they were changed during uninstallation. If they + * were, then the broadcast will alert the OS to update the appropriate UIs. + * This needs to be done regardless if the user canceled the uninstall + * process or not. + */ + if(WinRegKeyExists(HKEY_LOCAL_MACHINE, MOZ_CLIENT_BROWSER_KEY)) + { + SendMessageTimeout(HWND_BROADCAST, + WM_SETTINGCHANGE, + 0, + (LPARAM)MOZ_CLIENT_BROWSER_KEY, + SMTO_NORMAL|SMTO_ABORTIFHUNG, + MOZ_HWND_BROADCAST_MSG_TIMEOUT, + NULL); + } + if(WinRegKeyExists(HKEY_LOCAL_MACHINE, MOZ_CLIENT_MAIL_KEY)) + { + SendMessageTimeout(HWND_BROADCAST, + WM_SETTINGCHANGE, + 0, + (LPARAM)MOZ_CLIENT_MAIL_KEY, + SMTO_NORMAL|SMTO_ABORTIFHUNG, + MOZ_HWND_BROADCAST_MSG_TIMEOUT, + NULL); + } +} + +LRESULT CALLBACK DlgProcUninstall(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + RECT rDlg; + + switch(msg) + { + case WM_INITDIALOG: + SetWindowText(hDlg, diUninstall.szTitle); + wsprintf(szBuf, diUninstall.szMessage0, ugUninstall.szDescription); + SetDlgItemText(hDlg, IDC_MESSAGE0, szBuf); + GetPrivateProfileString("Dialog Uninstall", "Yes", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, IDWIZNEXT, szBuf); + GetPrivateProfileString("Dialog Uninstall", "No", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, IDCANCEL, szBuf); + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + + if(GetClientRect(hDlg, &rDlg)) + SetWindowPos(hDlg, HWND_TOP, (dwScreenX/2)-(rDlg.right/2), (dwScreenY/2)-(rDlg.bottom/2), 0, 0, SWP_NOSIZE); + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDWIZNEXT: + EnableWindow(GetDlgItem(hDlg, IDWIZNEXT), FALSE); + EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE); + ParseAllUninstallLogs(); + VerifyAndDeleteInstallationFolder(); + DestroyWindow(hDlg); + PostQuitMessage(0); + break; + + case IDCANCEL: + DestroyWindow(hDlg); + PostQuitMessage(0); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcWhatToDo(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + char szBuf[MAX_BUF]; + RECT rDlg; + + switch(msg) + { + case WM_INITDIALOG: + GetPrivateProfileString("Messages", "DLG_REMOVE_FILE_TITLE", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetWindowText(hDlg, szBuf); + + if((LPSTR)lParam != NULL) + SetDlgItemText(hDlg, IDC_STATIC_SHARED_FILENAME, (LPSTR)lParam); + + GetPrivateProfileString("Dialog Uninstall", "Message1", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, IDC_MESSAGE0, szBuf); + GetPrivateProfileString("Dialog Uninstall", "Message2", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, IDC_MESSAGE1, szBuf); + GetPrivateProfileString("Dialog Uninstall", "FileName", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, IDC_STATIC, szBuf); + GetPrivateProfileString("Dialog Uninstall", "No", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, ID_NO, szBuf); + GetPrivateProfileString("Dialog Uninstall", "NoToAll", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, ID_NO_TO_ALL, szBuf); + GetPrivateProfileString("Dialog Uninstall", "Yes", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, ID_YES, szBuf); + GetPrivateProfileString("Dialog Uninstall", "YesToAll", "", szBuf, sizeof(szBuf), szFileIniUninstall); + SetDlgItemText(hDlg, ID_YES_TO_ALL, szBuf); + + SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_MESSAGE1, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, IDC_STATIC_SHARED_FILENAME, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, ID_NO, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, ID_NO_TO_ALL, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, ID_YES, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + SendDlgItemMessage (hDlg, ID_YES_TO_ALL, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + + if(GetClientRect(hDlg, &rDlg)) + SetWindowPos(hDlg, HWND_TOP, (dwScreenX/2)-(rDlg.right/2), (dwScreenY/2)-(rDlg.bottom/2), 0, 0, SWP_NOSIZE); + + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case ID_NO: + EndDialog(hDlg, WTD_NO); + break; + + case ID_NO_TO_ALL: + EndDialog(hDlg, WTD_NO_TO_ALL); + break; + + case ID_YES: + EndDialog(hDlg, WTD_YES); + break; + + case ID_YES_TO_ALL: + EndDialog(hDlg, WTD_YES_TO_ALL); + break; + + default: + break; + } + break; + } + return(0); +} + +LRESULT CALLBACK DlgProcMessage(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam) +{ + RECT rDlg; + HWND hSTMessage = GetDlgItem(hDlg, IDC_MESSAGE); /* handle to the Static Text message window */ + HDC hdcSTMessage; + SIZE sizeString; + LOGFONT logFont; + HFONT hfontTmp; + HFONT hfontOld; + int i; + + switch(msg) + { + case WM_INITDIALOG: + SendDlgItemMessage (hDlg, IDC_MESSAGE, WM_SETFONT, (WPARAM)ugUninstall.definedFont, 0L); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_MESSAGE: + hdcSTMessage = GetWindowDC(hSTMessage); + + SystemParametersInfo(SPI_GETICONTITLELOGFONT, + sizeof(logFont), + (PVOID)&logFont, + 0); + hfontTmp = CreateFontIndirect(&logFont); + + if(hfontTmp) + hfontOld = SelectObject(hdcSTMessage, hfontTmp); + + GetTextExtentPoint32(hdcSTMessage, (LPSTR)lParam, lstrlen((LPSTR)lParam), &sizeString); + SelectObject(hdcSTMessage, hfontOld); + DeleteObject(hfontTmp); + ReleaseDC(hSTMessage, hdcSTMessage); + + SetWindowPos(hDlg, HWND_TOP, + (dwScreenX/2)-((sizeString.cx + 40)/2), (dwScreenY/2)-((sizeString.cy + 40)/2), + sizeString.cx + 40, sizeString.cy + 40, + SWP_SHOWWINDOW); + + if(GetClientRect(hDlg, &rDlg)) + SetWindowPos(hSTMessage, + HWND_TOP, + rDlg.left, + rDlg.top, + rDlg.right, + rDlg.bottom, + SWP_SHOWWINDOW); + + for(i = 0; i < lstrlen((LPSTR)lParam); i++) + { + if((((LPSTR)lParam)[i] == '\r') || (((LPSTR)lParam)[i] == '\n')) + ((LPSTR)lParam)[i] = ' '; + } + + SetDlgItemText(hDlg, IDC_MESSAGE, (LPSTR)lParam); + break; + } + break; + } + return(0); +} + +void ProcessWindowsMessages() +{ + MSG msg; + + while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void ShowMessage(LPSTR szMessage, BOOL bShow) +{ + char szBuf[MAX_BUF]; + + if(ugUninstall.mode != SILENT) + { + if((bShow) && (hDlgMessage == NULL)) + { + ZeroMemory(szBuf, sizeof(szBuf)); + GetPrivateProfileString("Messages", "MB_MESSAGE_STR", "", szBuf, sizeof(szBuf), szFileIniUninstall); + hDlgMessage = InstantiateDialog(hWndMain, DLG_MESSAGE, szBuf, DlgProcMessage); + SendMessage(hDlgMessage, WM_COMMAND, IDC_MESSAGE, (LPARAM)szMessage); + } + else if(!bShow && hDlgMessage) + { + DestroyWindow(hDlgMessage); + hDlgMessage = NULL; + } + } +} + +HWND InstantiateDialog(HWND hParent, DWORD dwDlgID, LPSTR szTitle, WNDPROC wpDlgProc) +{ + char szBuf[MAX_BUF]; + HWND hDlg = NULL; + + if((hDlg = CreateDialog(hInst, MAKEINTRESOURCE(dwDlgID), hParent, wpDlgProc)) == NULL) + { + char szEDialogCreate[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_DIALOG_CREATE", "", szEDialogCreate, sizeof(szEDialogCreate), szFileIniUninstall)) + { + wsprintf(szBuf, szEDialogCreate, szTitle); + PrintError(szBuf, ERROR_CODE_SHOW); + } + + PostQuitMessage(1); + } + + return(hDlg); +} diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.h b/toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.h new file mode 100644 index 00000000000..aeae91e4ba5 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/dialogs.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _DIALOGS_H_ +#define _DIALOGS_H_ + +LRESULT CALLBACK DlgProcUninstall(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcWhatToDo(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); +LRESULT CALLBACK DlgProcMessage(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam); + +void ParseAllUninstallLogs(); +void ParseDefaultsInfo(); +void SetDefault(); +HWND InstantiateDialog(HWND hParent, DWORD dwDlgID, LPSTR szTitle, WNDPROC wpDlgProc); +void ShowMessage(LPSTR szMessage, BOOL bShow); +void ProcessWindowsMessages(void); + +#endif + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/extern.h b/toolkit/mozapps/installer/windows/wizard/uninstall/extern.h new file mode 100644 index 00000000000..68e0a0ed5c9 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/extern.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _EXTERN_H_ +#define _EXTERN_H_ + +#include "uninstall.h" + +/* external global variables */ +extern HINSTANCE hInst; +extern HANDLE hAccelTable; + +extern HWND hDlgUninstall; +extern HWND hDlgMessage; +extern HWND hWndMain; + +extern LPSTR szEGlobalAlloc; +extern LPSTR szEStringLoad; +extern LPSTR szEDllLoad; +extern LPSTR szEStringNull; +extern LPSTR szTempSetupPath; + +extern LPSTR szClassName; +extern LPSTR szUninstallDir; +extern LPSTR szTempDir; +extern LPSTR szOSTempDir; +extern LPSTR szFileIniUninstall; +extern LPSTR szFileIniDefaultsInfo; +extern LPSTR gszSharedFilename; + +extern ULONG ulOSType; +extern DWORD dwScreenX; +extern DWORD dwScreenY; + +extern DWORD gdwWhatToDo; + +extern BOOL gbAllowMultipleInstalls; + +extern uninstallGen ugUninstall; +extern diU diUninstall; + +#endif diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/extra.c b/toolkit/mozapps/installer/windows/wizard/uninstall/extra.c new file mode 100644 index 00000000000..81d78fcdac9 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/extra.c @@ -0,0 +1,2623 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "extern.h" +#include "extra.h" +#include "parser.h" +#include "dialogs.h" +#include "ifuncns.h" +#include "process.h" +#include + +// shellapi.h is needed to build with WIN32_LEAN_AND_MEAN +#include + +#define HIDWORD(l) ((DWORD) (((ULONG) (l) >> 32) & 0xFFFF)) +#define LODWORD(l) ((DWORD) (l)) + +#define INDEX_STR_LEN 10 +#define PN_PROCESS TEXT("Process") +#define PN_THREAD TEXT("Thread") + +ULONG (PASCAL *NS_GetDiskFreeSpace)(LPCTSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); +ULONG (PASCAL *NS_GetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); + +BOOL InitApplication(HINSTANCE hInstance) +{ + WNDCLASS wc; + + wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW; + wc.lpfnWndProc = DefDlgProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = DLGWINDOWEXTRA; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_UNINSTALL)); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = szClassName; + + dwScreenX = GetSystemMetrics(SM_CXSCREEN); + dwScreenY = GetSystemMetrics(SM_CYSCREEN); + + return(RegisterClass(&wc)); +} + +void PrintError(LPSTR szMsg, DWORD dwErrorCodeSH) +{ + DWORD dwErr; + char szErrorString[MAX_BUF]; + + if(dwErrorCodeSH == ERROR_CODE_SHOW) + { + dwErr = GetLastError(); + wsprintf(szErrorString, "%d : %s", dwErr, szMsg); + } + else + wsprintf(szErrorString, "%s", szMsg); + + if((ugUninstall.mode != SILENT) && (ugUninstall.mode != AUTO)) + { + MessageBox(hWndMain, szErrorString, NULL, MB_ICONEXCLAMATION); + } + else if(ugUninstall.mode == AUTO) + { + ShowMessage(szErrorString, TRUE); + Delay(5); + ShowMessage(szErrorString, FALSE); + } +} + +void *NS_GlobalAlloc(DWORD dwMaxBuf) +{ + LPSTR szBuf = NULL; + + if((szBuf = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, dwMaxBuf)) == NULL) + { + if((szEGlobalAlloc == NULL) || (*szEGlobalAlloc == '\0')) + PrintError(TEXT("Memory allocation error."), ERROR_CODE_HIDE); + else + PrintError(szEGlobalAlloc, ERROR_CODE_SHOW); + + return(NULL); + } + else + return(szBuf); +} + +void FreeMemory(void **vPointer) +{ + if(*vPointer != NULL) + *vPointer = GlobalFree(*vPointer); +} + +HRESULT NS_LoadStringAlloc(HANDLE hInstance, DWORD dwID, LPSTR *szStringBuf, DWORD dwStringBuf) +{ + char szBuf[MAX_BUF]; + + if((*szStringBuf = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + + if(!LoadString(hInstance, dwID, *szStringBuf, dwStringBuf)) + { + if((szEStringLoad == NULL) ||(*szEStringLoad == '\0')) + wsprintf(szBuf, "Could not load string resource ID %d", dwID); + else + wsprintf(szBuf, szEStringLoad, dwID); + + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + return(0); +} + +HRESULT NS_LoadString(HANDLE hInstance, DWORD dwID, LPSTR szStringBuf, DWORD dwStringBuf) +{ + char szBuf[MAX_BUF]; + + if(!LoadString(hInstance, dwID, szStringBuf, dwStringBuf)) + { + if((szEStringLoad == NULL) ||(*szEStringLoad == '\0')) + wsprintf(szBuf, "Could not load string resource ID %d", dwID); + else + wsprintf(szBuf, szEStringLoad, dwID); + + PrintError(szBuf, ERROR_CODE_SHOW); + return(1); + } + return(WIZ_OK); +} + +void Delay(DWORD dwSeconds) +{ + SleepEx(dwSeconds * 1000, FALSE); +} + +HRESULT Initialize(HINSTANCE hInstance) +{ + char szBuf[MAX_BUF]; + + hDlgMessage = NULL; + DetermineOSVersion(); + gdwWhatToDo = WTD_ASK; + + /* load strings from setup.exe */ + if(NS_LoadStringAlloc(hInst, IDS_ERROR_GLOBALALLOC, &szEGlobalAlloc, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInst, IDS_ERROR_STRING_LOAD, &szEStringLoad, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInst, IDS_ERROR_DLL_LOAD, &szEDllLoad, MAX_BUF)) + return(1); + if(NS_LoadStringAlloc(hInst, IDS_ERROR_STRING_NULL, &szEStringNull, MAX_BUF)) + return(1); + + ZeroMemory(szBuf, sizeof(MAX_BUF)); + if((szClassName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + lstrcpy(szClassName, CLASS_NAME_UNINSTALL_DLG); + hAccelTable = LoadAccelerators(hInst, szClassName); + if((szUninstallDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + GetModuleFileName(NULL, szBuf, sizeof(szBuf)); + ParsePath(szBuf, szUninstallDir, MAX_BUF, PP_PATH_ONLY); + + if((szTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szOSTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + if((szFileIniUninstall = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + lstrcpy(szFileIniUninstall, szUninstallDir); + AppendBackSlash(szFileIniUninstall, MAX_BUF); + lstrcat(szFileIniUninstall, FILE_INI_UNINSTALL); + + if((szFileIniDefaultsInfo = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + lstrcpy(szFileIniDefaultsInfo, szUninstallDir); + AppendBackSlash(szFileIniDefaultsInfo, MAX_BUF); + GetPrivateProfileString("General", "Defaults Info Filename", "", szBuf, MAX_BUF, szFileIniUninstall); + lstrcat(szFileIniDefaultsInfo, szBuf); + + // determine the system's TEMP path + if(GetTempPath(MAX_BUF, szTempDir) == 0) + { + if(GetWindowsDirectory(szTempDir, MAX_BUF) == 0) + { + char szEGetWinDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", + szEGetWinDirFailed, sizeof(szEGetWinDirFailed), + szFileIniUninstall)) + PrintError(szEGetWinDirFailed, ERROR_CODE_SHOW); + + return(1); + } + + AppendBackSlash(szTempDir, MAX_BUF); + lstrcat(szTempDir, "TEMP"); + } + lstrcpy(szOSTempDir, szTempDir); + AppendBackSlash(szTempDir, MAX_BUF); + lstrcat(szTempDir, WIZ_TEMP_DIR); + + /* if multiple installer instances are allowed; + each instance requires a unique temp directory + */ + if(gbAllowMultipleInstalls) + { + DWORD dwLen = lstrlen(szTempDir); + + if (strncmp(szUninstallDir, szTempDir, dwLen) == 0) + { + lstrcpy(szTempDir, szUninstallDir); + } + else + { + int i; + for(i = 1; i <= 100 && (FileExists(szTempDir) != FALSE); i++) + { + itoa(i, (szTempDir + dwLen), 10); + } + + if (FileExists(szTempDir) != FALSE) + { + MessageBox(hWndMain, "Cannot create temp directory", NULL, MB_OK | MB_ICONEXCLAMATION); + exit(1); + } + } + } + else + { + // we're not running in mmi mode (allow multiple instances of installer + // to run at the same time), we should look for and remove the dirs + // that are created in the mmi mode. + DWORD dwLen; + char tempDirToCleanup[MAX_BUF]; + int i = 1; + + lstrcpy(tempDirToCleanup, szTempDir); + dwLen = lstrlen(tempDirToCleanup); + itoa(i, (tempDirToCleanup + dwLen), 10); + for(i = 2; i <= 100 && (FileExists(tempDirToCleanup)); i++) + { + DirectoryRemove(tempDirToCleanup, TRUE); + itoa(i, (tempDirToCleanup + dwLen), 10); + } + } + + if(!FileExists(szTempDir)) + { + AppendBackSlash(szTempDir, MAX_BUF); + CreateDirectoriesAll(szTempDir); + if(!FileExists(szTempDir)) + { + char szECreateTempDir[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_CREATE_TEMP_DIR", "", + szECreateTempDir, sizeof(szECreateTempDir), + szFileIniUninstall)) + { + wsprintf(szBuf, szECreateTempDir, szTempDir); + PrintError(szBuf, ERROR_CODE_HIDE); + } + return(1); + } + RemoveBackSlash(szTempDir); + } + + ugUninstall.bVerbose = FALSE; + ugUninstall.bUninstallFiles = TRUE; + ugUninstall.bSharedInst = FALSE; + + return(0); +} + +/* Function to remove quotes from a string */ +void RemoveQuotes(LPSTR lpszSrc, LPSTR lpszDest, int iDestSize) +{ + char *lpszBegin; + + if(lstrlen(lpszSrc) > iDestSize) + return; + + if(*lpszSrc == '\"') + lpszBegin = &lpszSrc[1]; + else + lpszBegin = lpszSrc; + + lstrcpy(lpszDest, lpszBegin); + + if(lpszDest[lstrlen(lpszDest) - 1] == '\"') + lpszDest[lstrlen(lpszDest) - 1] = '\0'; +} + +/* Function to copy strings safely. + * returns the amount of memory required (including NULL byte) if there's not enough + * else, it returns 0 for success. + */ +int MozCopyStr(LPSTR szSrc, LPSTR szDest, DWORD dwDestBufSize) +{ + DWORD length = lstrlen(szSrc) + 1; + strncpy(szDest, szSrc, dwDestBufSize); + if(length > dwDestBufSize) + { + szDest[dwDestBufSize - 1] = '\0'; + return(length); + } + return(0); +} + +/* Function to locate the first non space character in a string, + * and return a pointer to it. */ +LPSTR GetFirstNonSpace(LPSTR lpszString) +{ + char* p = lpszString; + while (*p && isspace(*p)) + p = CharNext(p); + + if(*p == '\0') // null means end of string + return NULL; + + return p; +} + +/* Function to locate the first space character in a string, + * and return a pointer to it. */ +LPSTR GetFirstSpace(LPSTR lpszString) +{ + char* p = lpszString; + while (*p && !isspace(*p)) + p = CharNext(p); + + if (*p == '\0') // null means end of string + return NULL; + + return p; +} + +/* Function to locate the first character c in lpszString, + * and return a pointer to it. */ +LPSTR MozStrChar(LPSTR lpszString, char c) +{ + char* p = lpszString; + while (*p && (*p != c)) + p = CharNext(p); + + if (*p == '\0') // null means end of string + return NULL; + + return p; +} + +/* Function to return the argument count given a command line input + * format string */ +int GetArgC(LPSTR lpszCommandLine) +{ + int i; + int iArgCount; + int iStrLength; + LPSTR lpszBeginStr; + BOOL bFoundQuote; + BOOL bFoundSpace; + + iArgCount = 0; + lpszBeginStr = GetFirstNonSpace(lpszCommandLine); + + if(lpszBeginStr == NULL) + return(iArgCount); + + iStrLength = lstrlen(lpszBeginStr); + bFoundQuote = FALSE; + bFoundSpace = TRUE; + + for(i = 0; i < iStrLength; i++) + { + if(lpszCommandLine[i] == '\"') + { + if(bFoundQuote == FALSE) + { + ++iArgCount; + bFoundQuote = TRUE; + } + else + { + bFoundQuote = FALSE; + } + } + else if(bFoundQuote == FALSE) + { + if(!isspace(lpszCommandLine[i]) && (bFoundSpace == TRUE)) + { + ++iArgCount; + bFoundSpace = FALSE; + } + else if(isspace(lpszCommandLine[i])) + { + bFoundSpace = TRUE; + } + } + } + + return(iArgCount); +} + +/* Function to return a specific argument parameter from a given command line input + * format string. */ +LPSTR GetArgV(LPSTR lpszCommandLine, int iIndex, LPSTR lpszDest, int iDestSize) +{ + int i; + int j; + int iArgCount; + int iStrLength; + LPSTR lpszBeginStr; + LPSTR lpszDestTemp; + BOOL bFoundQuote; + BOOL bFoundSpace; + + iArgCount = 0; + lpszBeginStr = GetFirstNonSpace(lpszCommandLine); + + if(lpszBeginStr == NULL) + return(NULL); + + lpszDestTemp = (char *)calloc(iDestSize, sizeof(char)); + if(lpszDestTemp == NULL) + { + PrintError("Out of memory", ERROR_CODE_HIDE); + exit(1); + } + + ZeroMemory(lpszDest, iDestSize); + iStrLength = lstrlen(lpszBeginStr); + bFoundQuote = FALSE; + bFoundSpace = TRUE; + j = 0; + + for(i = 0; i < iStrLength; i++) + { + if(lpszCommandLine[i] == '\"') + { + if(bFoundQuote == FALSE) + { + ++iArgCount; + bFoundQuote = TRUE; + } + else + { + bFoundQuote = FALSE; + } + } + else if(bFoundQuote == FALSE) + { + if(!isspace(lpszCommandLine[i]) && (bFoundSpace == TRUE)) + { + ++iArgCount; + bFoundSpace = FALSE; + } + else if(isspace(lpszCommandLine[i])) + { + bFoundSpace = TRUE; + } + } + + if((iIndex == (iArgCount - 1)) && + ((bFoundQuote == TRUE) || (bFoundSpace == FALSE) || + ((bFoundQuote == FALSE) && (lpszCommandLine[i] == '\"')))) + { + if(j < iDestSize) + { + lpszDestTemp[j] = lpszCommandLine[i]; + ++j; + } + else + { + lpszDestTemp[j] = '\0'; + } + } + } + + RemoveQuotes(lpszDestTemp, lpszDest, iDestSize); + free(lpszDestTemp); + return(lpszDest); +} + +void SetUninstallRunMode(LPSTR szMode) +{ + /* Check to see if mode has already been set. If so, + * then do not override it. + */ + if(ugUninstall.mode != NOT_SET) + return; + + if(lstrcmpi(szMode, "NORMAL") == 0) + ugUninstall.mode = NORMAL; + if(lstrcmpi(szMode, "AUTO") == 0) + ugUninstall.mode = AUTO; + if(lstrcmpi(szMode, "SILENT") == 0) + ugUninstall.mode = SILENT; + if(lstrcmpi(szMode, "SHOWICONS") == 0) + ugUninstall.mode = SHOWICONS; + if(lstrcmpi(szMode, "HIDEICONS") == 0) + ugUninstall.mode = HIDEICONS; + if(lstrcmpi(szMode, "SETDEFAULT") == 0) + ugUninstall.mode = SETDEFAULT; +} + +void RemoveBackSlash(LPSTR szInput) +{ + int iCounter; + DWORD dwInputLen; + + if(szInput != NULL) + { + dwInputLen = lstrlen(szInput); + + for(iCounter = dwInputLen -1; iCounter >= 0 ; iCounter--) + { + if(szInput[iCounter] == '\\') + szInput[iCounter] = '\0'; + else + break; + } + } +} + +void AppendBackSlash(LPSTR szInput, DWORD dwInputSize) +{ + if(szInput != NULL) + { + if(*szInput == '\0') + { + if(((DWORD)lstrlen(szInput) + 1) < dwInputSize) + { + lstrcat(szInput, "\\"); + } + } + else if(szInput[strlen(szInput) - 1] != '\\') + { + if(((DWORD)lstrlen(szInput) + 1) < dwInputSize) + { + lstrcat(szInput, "\\"); + } + } + } +} + +void RemoveSlash(LPSTR szInput) +{ + int iCounter; + DWORD dwInputLen; + + if(szInput != NULL) + { + dwInputLen = lstrlen(szInput); + + for(iCounter = dwInputLen -1; iCounter >= 0 ; iCounter--) + { + if(szInput[iCounter] == '/') + szInput[iCounter] = '\0'; + else + break; + } + } +} + +void AppendSlash(LPSTR szInput, DWORD dwInputSize) +{ + if(szInput != NULL) + { + if(*szInput == '\0') + { + if(((DWORD)lstrlen(szInput) + 1) < dwInputSize) + { + lstrcat(szInput, "/"); + } + } + else if(szInput[strlen(szInput) - 1] != '/') + { + if(((DWORD)lstrlen(szInput) + 1) < dwInputSize) + { + lstrcat(szInput, "/"); + } + } + } +} + +void ParsePath(LPSTR szInput, LPSTR szOutput, DWORD dwOutputSize, DWORD dwType) +{ + int iCounter; + DWORD dwCounter; + DWORD dwInputLen; + BOOL bFound; + + if((szInput != NULL) && (szOutput != NULL)) + { + bFound = FALSE; + dwInputLen = lstrlen(szInput); + ZeroMemory(szOutput, dwOutputSize); + + if(dwInputLen < dwOutputSize) + { + switch(dwType) + { + case PP_FILENAME_ONLY: + for(iCounter = dwInputLen - 1; iCounter >= 0; iCounter--) + { + if(szInput[iCounter] == '\\') + { + lstrcpy(szOutput, &szInput[iCounter + 1]); + bFound = TRUE; + break; + } + } + if(bFound == FALSE) + lstrcpy(szOutput, szInput); + + break; + + case PP_PATH_ONLY: + for(iCounter = dwInputLen - 1; iCounter >= 0; iCounter--) + { + if(szInput[iCounter] == '\\') + { + lstrcpy(szOutput, szInput); + szOutput[iCounter + 1] = '\0'; + bFound = TRUE; + break; + } + } + if(bFound == FALSE) + lstrcpy(szOutput, szInput); + + break; + + case PP_ROOT_ONLY: + if(szInput[1] == ':') + { + szOutput[0] = szInput[0]; + szOutput[1] = szInput[1]; + AppendBackSlash(szOutput, dwOutputSize); + } + else if(szInput[1] == '\\') + { + int iFoundBackSlash = 0; + for(dwCounter = 0; dwCounter < dwInputLen; dwCounter++) + { + if(szInput[dwCounter] == '\\') + { + szOutput[dwCounter] = szInput[dwCounter]; + ++iFoundBackSlash; + } + + if(iFoundBackSlash == 3) + break; + } + + if(iFoundBackSlash != 0) + AppendBackSlash(szOutput, dwOutputSize); + } + break; + } + } + } +} + +void DetermineOSVersion() +{ + BOOL bIsWin95Debute; + char szEMsg[MAX_BUF]; + OSVERSIONINFO osVersionInfo; + + ulOSType = 0; + osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if(!GetVersionEx(&osVersionInfo)) + { + /* GetVersionEx() failed for some reason. It's not fatal, but could cause + * some complications during installation */ + if(GetPrivateProfileString("Messages", "ERROR_GETVERSION", "", szEMsg, sizeof(szEMsg), szFileIniUninstall)) + PrintError(szEMsg, ERROR_CODE_SHOW); + } + + bIsWin95Debute = IsWin95Debute(); + switch(osVersionInfo.dwPlatformId) + { + case VER_PLATFORM_WIN32_WINDOWS: + ulOSType |= OS_WIN9x; + if(osVersionInfo.dwMinorVersion == 0) + { + ulOSType |= OS_WIN95; + if(bIsWin95Debute) + ulOSType |= OS_WIN95_DEBUTE; + } + else + ulOSType |= OS_WIN98; + break; + + case VER_PLATFORM_WIN32_NT: + ulOSType |= OS_NT; + switch(osVersionInfo.dwMajorVersion) + { + case 3: + ulOSType |= OS_NT3; + break; + + case 4: + ulOSType |= OS_NT4; + break; + + default: + ulOSType |= OS_NT5; + switch(osVersionInfo.dwMinorVersion) + { + case 0: + /* a minor version of 0 (major.minor.build) indicates Win2000 */ + ulOSType |= OS_NT50; + break; + + case 1: + /* a minor version of 1 (major.minor.build) indicates WinXP */ + ulOSType |= OS_NT51; + break; + } + break; + } + break; + + default: + if(GetPrivateProfileString("Messages", "ERROR_SETUP_REQUIREMENT", "", szEMsg, sizeof(szEMsg), szFileIniUninstall)) + PrintError(szEMsg, ERROR_CODE_HIDE); + + exit(1); + break; + } +} + +HRESULT WinSpawn(LPSTR szClientName, LPSTR szParameters, LPSTR szCurrentDir, int iShowCmd, BOOL bWait) +{ + SHELLEXECUTEINFO seInfo; + + seInfo.cbSize = sizeof(SHELLEXECUTEINFO); + seInfo.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS; + seInfo.hwnd = hWndMain; + seInfo.lpVerb = NULL; + seInfo.lpFile = szClientName; + seInfo.lpParameters = szParameters; + seInfo.lpDirectory = szCurrentDir; + seInfo.nShow = SW_SHOWNORMAL; + seInfo.hInstApp = 0; + seInfo.lpIDList = NULL; + seInfo.lpClass = NULL; + seInfo.hkeyClass = 0; + seInfo.dwHotKey = 0; + seInfo.hIcon = 0; + seInfo.hProcess = 0; + + if((ShellExecuteEx(&seInfo) != 0) && (seInfo.hProcess != NULL)) + { + if(bWait) + { + for(;;) + { + if(WaitForSingleObject(seInfo.hProcess, 200) == WAIT_OBJECT_0) + break; + + ProcessWindowsMessages(); + } + } + return(TRUE); + } + return(FALSE); +} + +HRESULT InitDlgUninstall(diU *diDialog) +{ + diDialog->bShowDialog = FALSE; + if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitDlgUninstall(diU *diDialog) +{ + FreeMemory(&(diDialog->szTitle)); + FreeMemory(&(diDialog->szMessage0)); +} + +HRESULT InitUninstallGeneral() +{ + ugUninstall.mode = NOT_SET; + + if((ugUninstall.szAppPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szLogPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szLogFilename = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szCompanyName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szProductName = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szWrKey = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szUserAgent = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szDefaultComponent = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szWrMainKey = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szUninstallKeyDescription = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szUninstallFilename = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szClientAppID = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + if((ugUninstall.szClientAppPath = NS_GlobalAlloc(MAX_BUF)) == NULL) + return(1); + + return(0); +} + +void DeInitUninstallGeneral() +{ + FreeMemory(&(ugUninstall.szAppPath)); + FreeMemory(&(ugUninstall.szLogPath)); + FreeMemory(&(ugUninstall.szLogFilename)); + FreeMemory(&(ugUninstall.szDescription)); + FreeMemory(&(ugUninstall.szUninstallKeyDescription)); + FreeMemory(&(ugUninstall.szUninstallFilename)); + FreeMemory(&(ugUninstall.szUserAgent)); + FreeMemory(&(ugUninstall.szDefaultComponent)); + FreeMemory(&(ugUninstall.szWrKey)); + FreeMemory(&(ugUninstall.szCompanyName)); + FreeMemory(&(ugUninstall.szProductName)); + FreeMemory(&(ugUninstall.szWrMainKey)); + FreeMemory(&(ugUninstall.szClientAppID)); + FreeMemory(&(ugUninstall.szClientAppPath)); + DeleteObject(ugUninstall.definedFont); +} + +sil *CreateSilNode() +{ + sil *silNode; + + if((silNode = NS_GlobalAlloc(sizeof(struct sInfoLine))) == NULL) + exit(1); + + if((silNode->szLine = NS_GlobalAlloc(MAX_BUF)) == NULL) + exit(1); + + silNode->ullLineNumber = 0; + silNode->Next = silNode; + silNode->Prev = silNode; + + return(silNode); +} + +void SilNodeInsert(sil *silHead, sil *silTemp) +{ + if(silHead == NULL) + { + silHead = silTemp; + silHead->Next = silHead; + silHead->Prev = silHead; + } + else + { + silTemp->Next = silHead; + silTemp->Prev = silHead->Prev; + silHead->Prev->Next = silTemp; + silHead->Prev = silTemp; + } +} + +void SilNodeDelete(sil *silTemp) +{ + if(silTemp != NULL) + { + silTemp->Next->Prev = silTemp->Prev; + silTemp->Prev->Next = silTemp->Next; + silTemp->Next = NULL; + silTemp->Prev = NULL; + + FreeMemory(&(silTemp->szLine)); + FreeMemory(&silTemp); + } +} + +BOOL IsWin95Debute() +{ + HINSTANCE hLib; + BOOL bIsWin95Debute; + + bIsWin95Debute = FALSE; + if((hLib = LoadLibraryEx("kernel32.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) != NULL) + { + if(((FARPROC)NS_GetDiskFreeSpaceEx = GetProcAddress(hLib, "GetDiskFreeSpaceExA")) == NULL) + { + (FARPROC)NS_GetDiskFreeSpace = GetProcAddress(hLib, "GetDiskFreeSpaceA"); + bIsWin95Debute = TRUE; + } + + FreeLibrary(hLib); + } + return(bIsWin95Debute); +} + +DWORD ParseCommandLine(LPSTR lpszCmdLine) +{ + char szArgVBuf[MAX_BUF]; + int i; + int iArgC; + + i = 0; + iArgC = GetArgC(lpszCmdLine); + while(i < iArgC) + { + GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); + + if((lstrcmpi(szArgVBuf, "-ma") == 0) || (lstrcmpi(szArgVBuf, "/ma") == 0)) + { + SetUninstallRunMode("AUTO"); + } + else if((lstrcmpi(szArgVBuf, "-ms") == 0) || (lstrcmpi(szArgVBuf, "/ms") == 0)) + { + SetUninstallRunMode("SILENT"); + } + else if((lstrcmpi(szArgVBuf, "-ua") == 0) || (lstrcmpi(szArgVBuf, "/ua") == 0)) + { + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szUserAgent, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-ss") == 0) || (lstrcmpi(szArgVBuf, "/ss") == 0)) + // Show Shortcuts + { + SetUninstallRunMode("SHOWICONS"); + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szDefaultComponent, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-hs") == 0) || (lstrcmpi(szArgVBuf, "/hs") == 0)) + // Hide Shortcuts + { + SetUninstallRunMode("HIDEICONS"); + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szDefaultComponent, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-sd") == 0) || (lstrcmpi(szArgVBuf, "/sd") == 0)) + // SetDefault + { + SetUninstallRunMode("SETDEFAULT"); + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szDefaultComponent, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-app") == 0) || (lstrcmpi(szArgVBuf, "/app") == 0)) + // Set the App ID + { + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szClientAppID, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-app_path") == 0) || (lstrcmpi(szArgVBuf, "/app_path") == 0)) + // Set the App Path + { + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szClientAppPath, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-reg_path") == 0) || (lstrcmpi(szArgVBuf, "/reg_path") == 0)) + // Set the alternative Windows registry path + { + if((i + 1) < iArgC) + GetArgV(lpszCmdLine, ++i, ugUninstall.szWrMainKey, MAX_BUF); + } + else if((lstrcmpi(szArgVBuf, "-v") == 0) || (lstrcmpi(szArgVBuf, "/v") == 0)) + // Set Verbose + { + ugUninstall.bVerbose = TRUE; + } + else if(!lstrcmpi(szArgVBuf, "-mmi") || !lstrcmpi(szArgVBuf, "/mmi")) + { + gbAllowMultipleInstalls = TRUE; + } + + ++i; + } + return(WIZ_OK); +} + +int PreCheckInstance(char *szSection, char *szIniFile) +{ + char szBuf[MAX_BUF]; + char szKey[MAX_BUF]; + char szName[MAX_BUF]; + char szParameter[MAX_BUF]; + char szPath[MAX_BUF]; + char szFile[MAX_BUF]; + char *ptrName = NULL; + HKEY hkeyRoot; + int iRv = WIZ_OK; + DWORD dwCounter = 0; + BOOL bContinue = TRUE; + char szExtraCmd[] = "Extra Cmd"; + char szExtraCmdKey[MAX_BUF]; + + do + { + /* Read the win reg key path */ + wsprintf(szExtraCmdKey, "%s%d Reg Key", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szKey, + sizeof(szKey), + szIniFile); + if(*szKey == '\0') + { + bContinue = FALSE; + continue; + } + + /* Read the win reg root key */ + wsprintf(szExtraCmdKey, "%s%d Reg Key Root", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szBuf, + sizeof(szBuf), + szIniFile); + if(*szBuf == '\0') + { + bContinue = FALSE; + continue; + } + hkeyRoot = ParseRootKey(szBuf); + + /* Read the win reg name value */ + wsprintf(szExtraCmdKey, "%s%d Reg Name", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szName, + sizeof(szName), + szIniFile); + if(*szName == '\0') + ptrName = NULL; + else + ptrName = szName; + + /* Read the parameter to use for quitting the browser's turbo mode */ + wsprintf(szExtraCmdKey, "%s%d Parameter", szExtraCmd, dwCounter); + GetPrivateProfileString(szSection, + szExtraCmdKey, + "", + szParameter, + sizeof(szParameter), + szIniFile); + + /* Read the win reg key that contains the path to the browser */ + GetWinReg(hkeyRoot, szKey, ptrName, szFile, sizeof(szFile)); + ParsePath(szFile, szPath, sizeof(szPath), PP_PATH_ONLY); + + /* Make sure the file exists */ + if(FileExists(szFile)) + { + // we've found a file, so let's execute it and stop. No need to look + // for other keys to parse. We only want to do that if the file is + // _not_ found. This is for when we change the name of the browser + // app file and still need to deal with locating it and calling + // -kill on it. ie. + // previous name: netscp6.exe + // new name: netscp.exe + // We only need to call one of them, not both. + bContinue = FALSE; + + /* Run the file */ + WinSpawn(szFile, szParameter, szPath, SW_HIDE, WS_WAIT); + + /* Even though WinSpawn is suppose to wait for the app to finish, this + * does not really work that way for trying to quit the browser when + * it's in turbo mode, so we wait 2 secs for it to complete. */ + Delay(2); + } + + ++dwCounter; + } while(bContinue); + + return(iRv); +} + +HRESULT GetCheckInstanceQuitMessage(char *aSection, char *aMessage, DWORD aMessageBufSize) +{ + *aMessage = '\0'; + GetPrivateProfileString(aSection, "Message", "", aMessage, aMessageBufSize, szFileIniUninstall); + return(WIZ_OK); +} + +HRESULT ShowMessageAndQuitProcess(HWND aHwndFW, char *aMsgQuitProcess, char *aMsgWait, BOOL aCloseAllWindows, char *aProcessName, BOOL aForceQuit) +{ + switch(ugUninstall.mode) + { + case NORMAL: + { + char msgTitleStr[MAX_BUF]; + GetPrivateProfileString("Messages", "MB_ATTENTION_STR", "", msgTitleStr, sizeof(msgTitleStr), szFileIniUninstall); + MessageBox(hWndMain, aMsgQuitProcess, msgTitleStr, MB_ICONEXCLAMATION | MB_SETFOREGROUND); + break; + } + + case AUTO: + { + /* Setup mode is AUTO. Show message, timeout, then auto close + * all the windows associated with the process */ + ShowMessage(aMsgQuitProcess, TRUE); + Delay(5); + ShowMessage(aMsgQuitProcess, FALSE); + break; + } + + case SILENT: + break; + } + + if(aForceQuit) + { + assert(aProcessName); + FindAndKillProcess(aProcessName, KP_KILL_PROCESS); + } + else + { + assert(aHwndFW); + /* First try sending a WM_QUIT message to the window because this is the + * preferred way to quit a process. If it works, then we're good and + * CloseAllWindowsOfWindowHandle() will have nothing to do. + * If it doesn't work, then CloseAllWindowsOfWindowHandle will try to + * quit the process. */ + SendMessageTimeout(aHwndFW, WM_QUIT, (WPARAM)1, (LPARAM)0, SMTO_NORMAL, WM_CLOSE_TIMEOUT_VALUE, NULL); + if(aCloseAllWindows) + CloseAllWindowsOfWindowHandle(aHwndFW, aMsgWait); + } + Delay(2); + return(WIZ_OK); +} + +HRESULT CheckInstances() +{ + char section[MAX_BUF]; + char processName[MAX_BUF]; + char className[MAX_BUF]; + char windowName[MAX_BUF]; + char closeAllWindows[MAX_BUF]; + char message[MAX_BUF]; + char msgTitleStr[MAX_BUF]; + char prettyName[MAX_BUF]; + char buf[MAX_BUF]; + char msgWait[MAX_BUF]; + int index; + int killProcessTries = 0; + int instanceOfFoundProcess = 0; + BOOL bContinue; + BOOL bCloseAllWindows; + HWND hwndFW; + LPSTR szWN; + LPSTR szCN; + DWORD dwRv0; + DWORD dwRv1; + + GetPrivateProfileString("Messages", "MB_ATTENTION_STR", "", msgTitleStr, sizeof(msgTitleStr), szFileIniUninstall); + bContinue = TRUE; + index = -1; + while(bContinue) + { + *className = '\0'; + *windowName = '\0'; + *message = '\0'; + + wsprintf(section, "Check Instance%d", ++index); + GetPrivateProfileString(section, "Process Name", "", processName, sizeof(processName), szFileIniUninstall); + GetPrivateProfileString(section, "Pretty Name", "", prettyName, sizeof(prettyName), szFileIniUninstall); + GetPrivateProfileString(section, "Message Wait", "", msgWait, sizeof(msgWait), szFileIniUninstall); + GetPrivateProfileString(section, "Close All Process Windows", "", closeAllWindows, sizeof(closeAllWindows), szFileIniUninstall); + if(lstrcmpi(closeAllWindows, "TRUE") == 0) + bCloseAllWindows = TRUE; + else + bCloseAllWindows = FALSE; + + if(instanceOfFoundProcess != index) + { + killProcessTries = 0; + instanceOfFoundProcess = index; + } + + if((killProcessTries == 1) && (*processName != '\0')) + { + if(FindAndKillProcess(processName, KP_DO_NOT_KILL_PROCESS)) + { + /* found process, display warning message, then kill process */ + GetPrivateProfileString("Messages", "MSG_FORCE_QUIT_PROCESS", "", message, sizeof(message), szFileIniUninstall); + if(*message != '\0') + { + wsprintf(buf, message, prettyName, processName, prettyName, prettyName); + ShowMessageAndQuitProcess(NULL, buf, msgWait, bCloseAllWindows, processName, CI_FORCE_QUIT_PROCESS); + ++killProcessTries; + instanceOfFoundProcess = index--; + } + } + continue; + } + else if(killProcessTries == MAX_KILL_PROCESS_RETRIES) + { + GetPrivateProfileString("Messages", "MSG_FORCE_QUIT_PROCESS_FAILED", "", message, sizeof(message), szFileIniUninstall); + if(*message != '\0') + { + wsprintf(buf, message, prettyName, processName, prettyName); + switch(ugUninstall.mode) + { + case NORMAL: + MessageBox(hWndMain, buf, msgTitleStr, MB_ICONEXCLAMATION | MB_SETFOREGROUND); + break; + + case AUTO: + /* Setup mode is AUTO. Show message, timeout, then auto close + * all the windows associated with the process */ + ShowMessage(buf, TRUE); + Delay(5); + ShowMessage(buf, FALSE); + break; + + default: + break; + } + } + + /* can't kill the process for some unknown reason. Stop the installation. */ + return(TRUE); + } + else if((killProcessTries > 1) && + (killProcessTries < MAX_KILL_PROCESS_RETRIES) && + (*processName != '\0')) + { + if(FindAndKillProcess(processName, KP_KILL_PROCESS)) + { + ++killProcessTries; + instanceOfFoundProcess = index--; + } + continue; + } + + dwRv0 = GetPrivateProfileString(section, "Class Name", "", className, sizeof(className), szFileIniUninstall); + dwRv1 = GetPrivateProfileString(section, "Window Name", "", windowName, sizeof(windowName), szFileIniUninstall); + if((dwRv0 == 0L) && (dwRv1 == 0L) && (*processName == '\0')) + { + bContinue = FALSE; + } + else if((*className != '\0') || (*windowName != '\0')) + { + if(*className == '\0') + szCN = NULL; + else + szCN = className; + + if(*windowName == '\0') + szWN = NULL; + else + szWN = windowName; + + /* If an instance is found, call PreCheckInstance first. + * PreCheckInstance will try to disable the browser's + * QuickLaunch feature. If the browser was in QuickLaunch + * mode without any windows open, PreCheckInstance would + * shutdown the browser, thus a second call to FindAndKillProcess + * is required to see if the process is still around. */ + if((hwndFW = FindWindow(szCN, szWN)) != NULL) + PreCheckInstance(section, szFileIniUninstall); + + if((hwndFW = FindWindow(szCN, szWN)) != NULL) + { + GetCheckInstanceQuitMessage(section, message, sizeof(message)); + if(*message != '\0') + { + ShowMessageAndQuitProcess(hwndFW, message, msgWait, bCloseAllWindows, processName, CI_CLOSE_PROCESS); + ++killProcessTries; + instanceOfFoundProcess = index--; + } + else + { + /* No message to display. Assume cancel because we can't allow user to continue */ + return(TRUE); + } + } + } + + if((killProcessTries == 0) && (*processName != '\0')) + { + /* The first attempt used FindWindow(), but sometimes the browser can be + * in a state where there's no window open and still not fully shutdown. + * In this case, we need to check for the process itself and kill it. */ + if(FindAndKillProcess(processName, KP_DO_NOT_KILL_PROCESS)) + { + GetCheckInstanceQuitMessage(section, message, sizeof(message)); + if(*message != '\0') + { + ShowMessageAndQuitProcess(hwndFW, message, msgWait, bCloseAllWindows, processName, CI_FORCE_QUIT_PROCESS); + ++killProcessTries; + instanceOfFoundProcess = index--; + } + else + { + /* No message to display. Assume cancel because we can't allow user to continue */ + return(TRUE); + } + } + } + } + + return(FALSE); +} + +BOOL GetFileVersion(LPSTR szFile, verBlock *vbVersion) +{ + UINT uLen; + UINT dwLen; + BOOL bRv; + DWORD dwHandle; + LPVOID lpData; + LPVOID lpBuffer; + VS_FIXEDFILEINFO *lpBuffer2; + + vbVersion->ullMajor = 0; + vbVersion->ullMinor = 0; + vbVersion->ullRelease = 0; + vbVersion->ullBuild = 0; + if(FileExists(szFile)) + { + bRv = TRUE; + dwLen = GetFileVersionInfoSize(szFile, &dwHandle); + lpData = (LPVOID)malloc(sizeof(long)*dwLen); + uLen = 0; + + if(GetFileVersionInfo(szFile, dwHandle, dwLen, lpData) != 0) + { + if(VerQueryValue(lpData, "\\", &lpBuffer, &uLen) != 0) + { + lpBuffer2 = (VS_FIXEDFILEINFO *)lpBuffer; + vbVersion->ullMajor = HIWORD(lpBuffer2->dwFileVersionMS); + vbVersion->ullMinor = LOWORD(lpBuffer2->dwFileVersionMS); + vbVersion->ullRelease = HIWORD(lpBuffer2->dwFileVersionLS); + vbVersion->ullBuild = LOWORD(lpBuffer2->dwFileVersionLS); + } + } + free(lpData); + } + else + /* File does not exist */ + bRv = FALSE; + + return(bRv); +} + +void TranslateVersionStr(LPSTR szVersion, verBlock *vbVersion) +{ + LPSTR szNum1 = NULL; + LPSTR szNum2 = NULL; + LPSTR szNum3 = NULL; + LPSTR szNum4 = NULL; + + szNum1 = strtok(szVersion, "."); + szNum2 = strtok(NULL, "."); + szNum3 = strtok(NULL, "."); + szNum4 = strtok(NULL, "."); + + vbVersion->ullMajor = _atoi64(szNum1); + vbVersion->ullMinor = _atoi64(szNum2); + vbVersion->ullRelease = _atoi64(szNum3); + vbVersion->ullBuild = _atoi64(szNum4); +} + +int CompareVersion(verBlock vbVersionOld, verBlock vbVersionNew) +{ + if(vbVersionOld.ullMajor > vbVersionNew.ullMajor) + return(4); + else if(vbVersionOld.ullMajor < vbVersionNew.ullMajor) + return(-4); + + if(vbVersionOld.ullMinor > vbVersionNew.ullMinor) + return(3); + else if(vbVersionOld.ullMinor < vbVersionNew.ullMinor) + return(-3); + + if(vbVersionOld.ullRelease > vbVersionNew.ullRelease) + return(2); + else if(vbVersionOld.ullRelease < vbVersionNew.ullRelease) + return(-2); + + if(vbVersionOld.ullBuild > vbVersionNew.ullBuild) + return(1); + else if(vbVersionOld.ullBuild < vbVersionNew.ullBuild) + return(-1); + + /* the versions are all the same */ + return(0); +} + +BOOL VerifyRestrictedAccess(void) +{ + char szSubKey[MAX_BUF]; + char szSubKeyToTest[] = "Software\\%s - Test Key"; + BOOL bRv; + DWORD dwDisp = 0; + DWORD dwErr; + HKEY hkRv; + + wsprintf(szSubKey, szSubKeyToTest, ugUninstall.szCompanyName); + dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, + szSubKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hkRv, + &dwDisp); + if(dwErr == ERROR_SUCCESS) + { + RegCloseKey(hkRv); + switch(dwDisp) + { + case REG_CREATED_NEW_KEY: + RegDeleteKey(HKEY_LOCAL_MACHINE, szSubKey); + break; + + case REG_OPENED_EXISTING_KEY: + break; + } + bRv = FALSE; + } + else + bRv = TRUE; + + return(bRv); +} + +BOOL CheckLegacy(HWND hDlg) +{ + char szSection[MAX_BUF]; + char szFilename[MAX_BUF]; + char szMessage[MAX_BUF]; + char szIndex[MAX_BUF]; + char szVersionNew[MAX_BUF]; + char szDecryptedFilePath[MAX_BUF]; + int iIndex; + BOOL bContinue; + DWORD dwRv0; + DWORD dwRv1; + verBlock vbVersionNew; + verBlock vbVersionOld; + + bContinue = TRUE; + iIndex = -1; + while(bContinue) + { + ZeroMemory(szFilename, sizeof(szFilename)); + ZeroMemory(szVersionNew, sizeof(szVersionNew)); + ZeroMemory(szMessage, sizeof(szMessage)); + + ++iIndex; + itoa(iIndex, szIndex, 10); + lstrcpy(szSection, "Legacy Check"); + lstrcat(szSection, szIndex); + + dwRv0 = GetPrivateProfileString(szSection, "Filename", "", szFilename, MAX_BUF, szFileIniUninstall); + dwRv1 = GetPrivateProfileString(szSection, "Version", "", szVersionNew, MAX_BUF, szFileIniUninstall); + if(dwRv0 == 0L) + { + bContinue = FALSE; + } + else if(*szFilename != '\0') + { + GetPrivateProfileString(szSection, "Message", "", szMessage, MAX_BUF, szFileIniUninstall); + if(*szMessage == '\0') + /* no message string input. so just continue with the next check */ + continue; + + DecryptString(szDecryptedFilePath, szFilename); + if((dwRv1 == 0L) || (*szVersionNew == '\0')) + { + if(FileExists(szDecryptedFilePath)) + { + char szMBWarningStr[MAX_BUF]; + + if(!GetPrivateProfileString("Messages", "MB_WARNING_STR", "", + szMBWarningStr, sizeof(szMBWarningStr), + szFileIniUninstall)) + lstrcpy(szMBWarningStr, "Warning"); + + if(MessageBox(hDlg, szMessage, szMBWarningStr, MB_ICONWARNING | MB_YESNO) == IDYES) + return(TRUE); + } + /* file does not exist, so it's okay. Continue with the next check */ + continue; + } + + if(GetFileVersion(szDecryptedFilePath, &vbVersionOld)) + { + TranslateVersionStr(szVersionNew, &vbVersionNew); + if(CompareVersion(vbVersionOld, vbVersionNew) < 0) + { + char szMBWarningStr[MAX_BUF]; + + if(!GetPrivateProfileString("Messages", "MB_WARNING_STR", "", + szMBWarningStr, sizeof(szMBWarningStr), + szFileIniUninstall)) + lstrcpy(szMBWarningStr, "Warning"); + + if(MessageBox(hDlg, szMessage, szMBWarningStr, MB_ICONWARNING | MB_YESNO) == IDYES) + return(TRUE); + } + } + } + } + /* returning TRUE means the user wants to go back and choose a different destination path + * returning FALSE means the user is ignoring the warning + */ + return(FALSE); +} + +// This function looks up the path for the application being uninstalled, NOT the client +// app in a shared install environment. +HRESULT GetAppPath() +{ + char szTmpAppPath[MAX_BUF]; + char szKey[MAX_BUF]; + BOOL bRestrictedAccess; + HKEY hkRoot; + + if(*ugUninstall.szUserAgent != '\0') + { + hkRoot = ugUninstall.hWrMainRoot; + wsprintf(szKey, "%s\\%s\\Main", ugUninstall.szWrMainKey, ugUninstall.szUserAgent); + } + else + { + hkRoot = ugUninstall.hWrRoot; + strcpy(szKey, ugUninstall.szWrKey); + } + + bRestrictedAccess = VerifyRestrictedAccess(); + if(bRestrictedAccess) + hkRoot = HKEY_CURRENT_USER; + + GetWinReg(hkRoot, szKey, "PathToExe", szTmpAppPath, sizeof(szTmpAppPath)); + if(FileExists(szTmpAppPath)) + lstrcpy(ugUninstall.szAppPath, szTmpAppPath); + + GetWinReg(hkRoot, szKey, "Install Directory", ugUninstall.szInstallPath, sizeof(ugUninstall.szInstallPath)); + + return(0); +} + +// For shared installs we maintain an app list, which is a glorified +// refcount of the apps which are using this version of the +// shared app. Processing the app list does two things: +// +// 1) Cleans up any registry entries for apps which are no longer +// installed. The app list includes a representative file for +// each app. If that file is not installed than the app is +// assumed to have been removed from the system. +// 2) Returns a count of the installed apps which depend upon this +// shared app. If this app is not shared, there will be no app +// list so this will always return 0. +DWORD CleanupAppList() +{ + typedef struct siAppListStruct siAppList; + struct siAppListStruct + { + char szAppID[MAX_BUF]; + siAppList *Next; + }; + + siAppList *siALHead; + siAppList *siALPrev; + siAppList *siALTmp; + + char *szRv = NULL; + char szKey[MAX_BUF]; + char szBuf[MAX_BUF]; + char szDefaultApp[MAX_BUF_TINY]; + BOOL bFoundDefaultApp; + HKEY hkResult; + DWORD dwIndex; + DWORD dwBufSize; + DWORD dwTotalSubKeys; + DWORD dwTotalValues; + DWORD dwAppCount; + FILETIME ftLastWriteFileTime; + + GetPrivateProfileString("General", "Default AppID", "", szDefaultApp, MAX_BUF_TINY, szFileIniUninstall); + wsprintf(szKey, "%s\\%s\\AppList", ugUninstall.szWrMainKey, ugUninstall.szUserAgent); + if(RegOpenKeyEx(ugUninstall.hWrMainRoot, szKey, 0, KEY_READ, &hkResult) != ERROR_SUCCESS) + { + return(0); + } + + siALHead = NULL; + dwAppCount = 0; + dwTotalSubKeys = 0; + dwTotalValues = 0; + RegQueryInfoKey(hkResult, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL); + + for(dwIndex = 0; dwIndex < dwTotalSubKeys; dwIndex++) + { + dwBufSize = sizeof(szBuf); + if(RegEnumKeyEx(hkResult, dwIndex, szBuf, &dwBufSize, NULL, NULL, NULL, &ftLastWriteFileTime) == ERROR_SUCCESS) + { + if((siALTmp = NS_GlobalAlloc(sizeof(struct siAppListStruct))) == NULL) + exit(1); + lstrcpy(siALTmp->szAppID, szBuf); + siALTmp->Next = NULL; + + if(siALHead == NULL) + siALHead = siALTmp; //New list, point the head at it. + else + siALPrev->Next = siALTmp; + + siALPrev = siALTmp; + } + } + RegCloseKey(hkResult); + + siALTmp = siALHead; + while(siALTmp != NULL) + { + if(lstrcmpi(siALTmp->szAppID, szDefaultApp) == 0) + bFoundDefaultApp = TRUE; + + // ProcessAppItem returns the # of installations of the App + dwAppCount = dwAppCount + ProcessAppItem(ugUninstall.hWrMainRoot, szKey, siALTmp->szAppID); + + siALPrev = siALTmp; + siALTmp = siALTmp->Next; + FreeMemory(&siALPrev); + } + + if(dwAppCount == 0) + RegDeleteKey(ugUninstall.hWrMainRoot, szKey); + + // If the Default App is not listed in AppList, then the shared app should not be in the + // Windows Add/Remove Programs list either. + if(!bFoundDefaultApp) + { + wsprintf(szKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s (%s)",ugUninstall.szProductName, ugUninstall.szUserAgent); + RegDeleteKey(ugUninstall.hWrMainRoot, szKey); + } + + return(dwAppCount); +} + + +// Removes the app item if it is the app identified with the /app command-line option +// If an app item is not installed this removes it from the app list. +// Returns the # of installations of the app item found in the AppList. +DWORD ProcessAppItem(HKEY hkRootKey, LPSTR szKeyAppList, LPSTR szAppID) +{ + DWORD dwIndex = 1; + const DWORD dwUpperLimit = 100; + BOOL bDefaultApp; + char szBuf[MAX_BUF]; + char szKey[MAX_BUF]; + char szName[MAX_BUF]; + char szUninstKey[MAX_BUF]; + + GetPrivateProfileString("General", "Default AppID", "", szBuf, sizeof(szBuf), szFileIniUninstall); + bDefaultApp = (lstrcmpi(szAppID, szBuf) == 0); + + wsprintf(szKey, "%s\\%s", szKeyAppList, szAppID); + + if(lstrcmpi(szAppID, ugUninstall.szClientAppID) == 0) // This is the app that the user said + { // on the command-line to uninstall. + if((ugUninstall.szClientAppPath[0] == '\0') || (bDefaultApp)) // If we didn't get an /app_path or this + { // is the default app, just remove it. + RegDeleteKey(hkRootKey, szKey); + if(bDefaultApp) + { + wsprintf(szKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GRE (%s)", ugUninstall.szUserAgent); + RegDeleteKey(hkRootKey, szKey); + } + + return 0; + } + + wsprintf(szName, "PathToExe%02d", dwIndex); + while(WinRegNameExists(hkRootKey, szKey, szName) && // Since we got an /app_path we need to cycle + (dwIndex < dwUpperLimit)) // through the list looking for that instance. + { + GetWinReg(hkRootKey, szKey, szName, szBuf, sizeof(szBuf)); + if((lstrcmpi(szBuf, ugUninstall.szClientAppPath) == 0) || (!FileExists(szBuf))) + { + // RemovePathToExeXX() will delete the dwIndex Name and reorder + // PathToExeXX so there are no gaps. + RemovePathToExeXX(hkRootKey, szKey, dwIndex, dwUpperLimit); + } + else + wsprintf(szName, "PathToExe%02d", ++dwIndex); + } + + if(--dwIndex == 0) + RegDeleteKey(hkRootKey, szKey); + + return dwIndex; + } + + if(bDefaultApp) // The Default App does not have an installed file registered. However, an entry in + { // the Windows Add/Remove products list indicates that the Default App is installed + // and needs to be counted. + wsprintf(szUninstKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s (%s)",ugUninstall.szProductName, ugUninstall.szUserAgent); + GetWinReg(hkRootKey, szUninstKey, "UninstallString", szBuf, sizeof(szBuf)); + + if(szBuf[0] != '\0') + return 1; + } + + dwIndex = 1; + wsprintf(szName, "PathToExe%02d", dwIndex); + while(WinRegNameExists(hkRootKey, szKey, szName) && // Count the entries which can be verified by the + (dwIndex < dwUpperLimit)) // existence of the file pointed to by PathToExeXX + { + GetWinReg(hkRootKey, szKey, szName, szBuf, sizeof(szBuf)); + if(!FileExists(szBuf)) + { + // RemovePathToExeXX() will delete the dwIndex Name and reorder + // PathToExeXX so there are no gaps. + RemovePathToExeXX(hkRootKey, szKey, dwIndex, dwUpperLimit); + } + else + wsprintf(szName, "PathToExe%02d", ++dwIndex); + } + + if(--dwIndex == 0) + RegDeleteKey(hkRootKey, szKey); + + return dwIndex; +} + +void RemovePathToExeXX(HKEY hkRootKey, LPSTR szKey, DWORD dwIndex, const DWORD dwUpperLimit) +{ + char szBuf[MAX_BUF_TINY]; + char szName[MAX_BUF_TINY]; + char szNextName[MAX_BUF_TINY]; + + wsprintf(szName, "PathToExe%02d", dwIndex++); + wsprintf(szNextName, "PathToExe%02d", dwIndex); + while(WinRegNameExists(hkRootKey, szKey, szNextName) && (dwIndex < dwUpperLimit)) + { + GetWinReg(hkRootKey, szKey, szNextName, szBuf, sizeof(szBuf)); + SetWinReg(hkRootKey, szKey, szName, REG_SZ, szBuf, lstrlen(szBuf)); + lstrcpy(szName, szNextName); + wsprintf(szNextName, "PathToExe%02d", ++dwIndex); + } + + DeleteWinRegValue(hkRootKey, szKey, szName); +} + +/* Function: ReplacePrivateProfileStrCR() + * + * in: LPSTR aInputOutputStr: In/out string to containing "\\n" to replace. + * + * purpose: To parse for and replace "\\n" string with "\n". Strings stored + * in .ini files cannot contain "\n" because it's a key delimiter. + * To work around this limination, "\\n" chars can be used to + * represent '\n'. This function will look for "\\n" and replace + * them with a true "\n". + * If it encounters a string of "\\\\n" (which looks like '\\n'), + * then this function will strip out the extra '\\' and just show + * "\\n"; + */ +void ReplacePrivateProfileStrCR(LPSTR aInputOutputStr) +{ + LPSTR pSearch = aInputOutputStr; + LPSTR pSearchEnd = aInputOutputStr + lstrlen(aInputOutputStr); + LPSTR pPreviousSearch = NULL; + + while (pSearch < pSearchEnd) + { + if (('\\' == *pSearch) || ('n' == *pSearch)) + { + // found a '\\' or 'n'. check to see if the prefivous char is also a '\\'. + if (pPreviousSearch && ('\\' == *pPreviousSearch)) + { + if ('n' == *pSearch) + *pSearch = '\n'; + + memmove(pPreviousSearch, pSearch, pSearchEnd-pSearch+1); + + // our string is shorter now ... + pSearchEnd -= pSearch - pPreviousSearch; + } + } + + pPreviousSearch = pSearch; + pSearch = CharNext(pSearch); + } +} + +/* Function: IsPathWithinWindir() + * in: char *aTargetPath + * out: returns a BOOL type indicating whether the install path chosen + * by the user is within the %windir% or not. + * purpose: To see if aTargetPath is within the %windir% path. + */ +BOOL IsPathWithinWindir(char *aTargetPath) +{ + char windir[MAX_PATH]; + char targetPath[MAX_PATH]; + HRESULT rv; + + assert(aTargetPath); + + rv = GetWindowsDirectory(windir, sizeof(windir)); + assert(rv); + MozCopyStr(aTargetPath, targetPath, sizeof(targetPath)); + RemoveBackSlash(targetPath); + CharUpperBuff(targetPath, sizeof(targetPath)); + RemoveBackSlash(windir); + CharUpperBuff(windir, sizeof(windir)); + + if(strstr(targetPath, windir)) + return(TRUE); + + return(FALSE); +} + +/* Function: VerifyAndDeleteInstallationFolder() + * in: none + * out: none + * purpose: To verify that the installation folder has been completely + * deleted, else prompt the user if they would like to delete + * the folder and it's left over contents. + * It will also check to make sure that the installation + * folder is not within the %windir% folder. If it is, + * it will warn the user and not perform the deletion of the + * installation folder. + */ +void VerifyAndDeleteInstallationFolder() +{ + if(FileExists(ugUninstall.szInstallPath)) + { + char buf[MAX_BUF]; + char msg[MAX_BUF]; + char msgBoxTitle[MAX_BUF]; + char installationPath[MAX_BUF]; + + MozCopyStr(ugUninstall.szInstallPath, installationPath, sizeof(installationPath)); + RemoveBackSlash(installationPath); + + if(ugUninstall.mode == NORMAL) + { + GetPrivateProfileString("Messages", "MB_ATTENTION_STR", "", msgBoxTitle, sizeof(msgBoxTitle), szFileIniUninstall); + GetPrivateProfileString("Messages", "MSG_DELETE_INSTALLATION_PATH", "", buf, sizeof(buf), szFileIniUninstall); + _snprintf(msg, sizeof(msg), buf, installationPath); + msg[sizeof(msg) - 1] = '\0'; + ReplacePrivateProfileStrCR(msg); + + /* Prompt user on if they want the completely remove the + * installation folder */ + if(MessageBox(hWndMain, msg, msgBoxTitle, MB_ICONQUESTION | MB_YESNO) == IDYES) + { + if(IsPathWithinWindir(installationPath)) + { + GetPrivateProfileString("Messages", "MSG_INSTALLATION_PATH_WITHIN_WINDIR", + "", msg, sizeof(msg), szFileIniUninstall); + MessageBox(hWndMain, msg, NULL, MB_ICONEXCLAMATION); + return; + } + + /* Remove the installation folder here */ + AppendBackSlash(installationPath, sizeof(installationPath)); + DirectoryRemove(installationPath, TRUE); + } + } + else + { + /* If uninstall is running in !NORMAL mode, assume user wants to + * completely delete the installation folder */ + AppendBackSlash(installationPath, sizeof(installationPath)); + DirectoryRemove(installationPath, TRUE); + } + } +} + +HRESULT GetUninstallLogPath() +{ + char szBuf[MAX_BUF]; + char szLogFolder[MAX_BUF]; + char szKey[MAX_BUF]; + char szWindowsUninstallKey[MAX_BUF]; + char szErrorMsg[MAX_BUF]; + char szEUninstallLogFolder[MAX_BUF]; + char szRootKey[MAX_BUF]; + BOOL bRestrictedAccess; + HKEY hkRoot; + + if(*ugUninstall.szUserAgent != '\0') + { + hkRoot = ugUninstall.hWrMainRoot; + lstrcpy(szKey, ugUninstall.szWrMainKey); + AppendBackSlash(szKey, sizeof(szKey)); + lstrcat(szKey, ugUninstall.szUserAgent); + AppendBackSlash(szKey, sizeof(szKey)); + lstrcat(szKey, "Uninstall"); + } + else + { + hkRoot = ugUninstall.hWrRoot; + strcpy(szKey, ugUninstall.szWrKey); + } + + bRestrictedAccess = VerifyRestrictedAccess(); + if(bRestrictedAccess) + hkRoot = HKEY_CURRENT_USER; + + GetWinReg(hkRoot, szKey, "Uninstall Log Folder", szLogFolder, sizeof(szLogFolder)); + GetWinReg(hkRoot, szKey, "Description", ugUninstall.szUninstallKeyDescription, MAX_BUF); + + if(!bRestrictedAccess) + { + lstrcpy(szWindowsUninstallKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"); + lstrcat(szWindowsUninstallKey, ugUninstall.szUninstallKeyDescription); + GetWinReg(HKEY_LOCAL_MACHINE, szWindowsUninstallKey, "DisplayName", ugUninstall.szDescription, MAX_BUF); + } + + /* if the DisplayName was not found in the windows registry, + * use the description read in from config.ini file */ + if(*ugUninstall.szDescription == '\0') + lstrcpy(ugUninstall.szDescription, ugUninstall.szUninstallKeyDescription); + + if(FileExists(szLogFolder) == FALSE) + { + if(GetPrivateProfileString("Messages", "ERROR_UNINSTALL_LOG_FOLDER", "", + szEUninstallLogFolder, sizeof(szEUninstallLogFolder), + szFileIniUninstall)) + { + lstrcpy(szBuf, "\n\n "); + + if(*szLogFolder == '\0') + { + GetStringRootKey(hkRoot, szRootKey, sizeof(szRootKey)); + lstrcat(szBuf, szRootKey); + lstrcat(szBuf, "\\"); + lstrcat(szBuf, szKey); + lstrcat(szBuf, "\\Uninstall Log Folder"); + } + else + lstrcat(szBuf, szLogFolder); + + lstrcat(szBuf, "\n"); + wsprintf(szErrorMsg, szEUninstallLogFolder, szBuf); + PrintError(szErrorMsg, ERROR_CODE_SHOW); + } + + return(1); + } + lstrcpy(ugUninstall.szLogPath, szLogFolder); + + return(0); +} + +HRESULT ParseUninstallIni() +{ + char szBuf[MAX_BUF]; + char szKeyCrypted[MAX_BUF]; + char szShowDialog[MAX_BUF]; + LOGFONT lf; + char fontName[MAX_BUF]; + char fontSize[MAX_BUF]; + char charSet[MAX_BUF]; + + lstrcpy(ugUninstall.szLogFilename, FILE_LOG_INSTALL); + + GetPrivateProfileString("General", "Shared Install", "", szBuf, MAX_BUF, szFileIniUninstall); + ugUninstall.bSharedInst = (lstrcmpi(szBuf, "TRUE") == 0); + + /* get install Mode information */ + GetPrivateProfileString("General", "Run Mode", "", szBuf, MAX_BUF, szFileIniUninstall); + SetUninstallRunMode(szBuf); + + if((ugUninstall.mode != SHOWICONS) && (ugUninstall.mode != HIDEICONS) && (ugUninstall.mode != SETDEFAULT)) + if(CheckInstances()) + return(1); + if(InitDlgUninstall(&diUninstall)) + return(1); + + /* get product name description */ + GetPrivateProfileString("General", "Company Name", "", ugUninstall.szCompanyName, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("General", "Product Name", "", ugUninstall.szProductName, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("General", "Root Key", "", szBuf, MAX_BUF, szFileIniUninstall); + ugUninstall.hWrRoot = ParseRootKey(szBuf); + + GetPrivateProfileString("General", "Key", "", szKeyCrypted, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("General", "Decrypt Key", "", szBuf, MAX_BUF, szFileIniUninstall); + if(lstrcmpi(szBuf, "TRUE") == 0) + { + DecryptString(ugUninstall.szWrKey, szKeyCrypted); + } + else + strcpy(ugUninstall.szWrKey, szKeyCrypted); + + RemoveBackSlash(ugUninstall.szWrKey); + + GetPrivateProfileString("General", "Main Root Key", "", szBuf, MAX_BUF, szFileIniUninstall); + ugUninstall.hWrMainRoot = ParseRootKey(szBuf); + + GetPrivateProfileString("General", "Main Key", "", szKeyCrypted, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("General", "Decrypt Main Key", "", szBuf, MAX_BUF, szFileIniUninstall); + + // If szWrMainKey is not null then it was set on the command-line and that is + // what we want to use. + if(*ugUninstall.szWrMainKey == '\0') + { + if(lstrcmpi(szBuf, "TRUE") == 0) + { + DecryptString(ugUninstall.szWrMainKey, szKeyCrypted); + } + else + strcpy(ugUninstall.szWrMainKey, szKeyCrypted); + } + + RemoveBackSlash(ugUninstall.szWrMainKey); + + GetPrivateProfileString("General", "Uninstall Filename", "", ugUninstall.szUninstallFilename, MAX_BUF, szFileIniUninstall); + + + /* Uninstall dialog */ + GetPrivateProfileString("Dialog Uninstall", "Show Dialog", "", szShowDialog, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("Dialog Uninstall", "Title", "", diUninstall.szTitle, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("Dialog Uninstall", "Message0", "", diUninstall.szMessage0, MAX_BUF, szFileIniUninstall); + if(lstrcmpi(szShowDialog, "TRUE") == 0) + diUninstall.bShowDialog = TRUE; + + switch(ugUninstall.mode) + { + case AUTO: + case SILENT: + case SHOWICONS: + case HIDEICONS: + case SETDEFAULT: + gdwWhatToDo = WTD_NO_TO_ALL; + diUninstall.bShowDialog = FALSE; + break; + } + + /* get defined font */ + GetPrivateProfileString("Dialog Uninstall", "FONTNAME", "", fontName, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("Dialog Uninstall", "FONTSIZE", "", fontSize, MAX_BUF, szFileIniUninstall); + GetPrivateProfileString("Dialog Uninstall", "CHARSET", "", charSet, MAX_BUF, szFileIniUninstall); + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, fontName); + lf.lfHeight = -MulDiv(atoi(fontSize), GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72); + lf.lfCharSet = atoi(charSet); + ugUninstall.definedFont = CreateFontIndirect( &lf ); + + GetAppPath(); + + + if(ugUninstall.bSharedInst) + { + // Shared installations require a user agent. Without one there is no way to know + // what version of GRE to clean up so we can't do anything--including CleanupAppList() + // so don't change the order of the if statement. + // (We should add UI warning the user when a required UserAgent is not supplied.) + // CleanupAppList() returns the number of installations of apps dependant on this shared app. + if((ugUninstall.szUserAgent[0] == '\0') || (CleanupAppList() != 0)) + ugUninstall.bUninstallFiles = FALSE; + } + + return(GetUninstallLogPath()); +} + +void GetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, LPSTR szReturnValue, DWORD dwReturnValueSize) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwSize; + char szBuf[MAX_BUF]; + + ZeroMemory(szBuf, sizeof(szBuf)); + ZeroMemory(szReturnValue, dwReturnValueSize); + + if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS) + { + dwSize = sizeof(szBuf); + dwErr = RegQueryValueEx(hkResult, szName, 0, NULL, szBuf, &dwSize); + + if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS)) + ExpandEnvironmentStrings(szBuf, szReturnValue, dwReturnValueSize); + else + *szReturnValue = '\0'; + + RegCloseKey(hkResult); + } +} + +void SetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, DWORD dwType, LPSTR szData, DWORD dwSize) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwDisp; + char szBuf[MAX_BUF]; + + memset(szBuf, '\0', MAX_BUF); + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult); + if(dwErr != ERROR_SUCCESS) + dwErr = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp); + + if(dwErr == ERROR_SUCCESS) + { + dwErr = RegSetValueEx(hkResult, szName, 0, dwType, szData, dwSize); + + RegCloseKey(hkResult); + } +} + +void SetWinRegNumValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName, DWORD dwData) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwDisp; + DWORD dwVal; + DWORD dwValSize; + + dwVal = dwData; + dwValSize = sizeof(DWORD); + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult); + if(dwErr != ERROR_SUCCESS) + dwErr = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp); + + if(dwErr == ERROR_SUCCESS) + { + dwErr = RegSetValueEx(hkResult, szName, 0, REG_DWORD, (LPBYTE)&dwVal, dwValSize); + + RegCloseKey(hkResult); + } +} + +HRESULT DecryptVariable(LPSTR szVariable, DWORD dwVariableSize) +{ + char szBuf[MAX_BUF]; + char szKey[MAX_BUF]; + char szName[MAX_BUF]; + char szValue[MAX_BUF]; + + /* zero out the memory allocations */ + ZeroMemory(szBuf, sizeof(szBuf)); + ZeroMemory(szKey, sizeof(szKey)); + ZeroMemory(szName, sizeof(szName)); + ZeroMemory(szValue, sizeof(szValue)); + + if(lstrcmpi(szVariable, "PROGRAMFILESDIR") == 0) + { + /* parse for the "c:\Program Files" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", "ProgramFilesDir", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "COMMONFILESDIR") == 0) + { + /* parse for the "c:\Program Files\Common Files" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", "CommonFilesDir", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "MEDIAPATH") == 0) + { + /* parse for the "c:\Winnt40\Media" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", "MediaPath", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "CONFIGPATH") == 0) + { + /* parse for the "c:\Windows\Config" directory */ + if(ulOSType & OS_WIN9x) + { + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", "ConfigPath", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "DEVICEPATH") == 0) + { + /* parse for the "c:\Winnt40\INF" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", "DevicePath", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "COMMON_STARTUP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu\\Programs\\Startup" directory */ + if(ulOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Startup", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Common Startup", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "COMMON_PROGRAMS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu\\Programs" directory */ + if(ulOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Programs", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Common Programs", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "COMMON_STARTMENU") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Start Menu" directory */ + if(ulOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Start Menu", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Common Start Menu", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "COMMON_DESKTOP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\All Users\Desktop" directory */ + if(ulOSType & OS_WIN9x) + { + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Desktop", szVariable, dwVariableSize); + } + else + { + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Common Desktop", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "PERSONAL_STARTUP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Start Menu\Programs\Startup" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Startup", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_PROGRAMS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Start Menu\Programs" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Programs", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_STARTMENU") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Start Menu" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Start Menu", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_DESKTOP") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Desktop" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Desktop", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_APPDATA") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Application Data" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "AppData", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_CACHE") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Temporary Internet Files" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Cache", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_COOKIES") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Cookies" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Cookies", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_FAVORITES") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Favorites" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Favorites", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_FONTS") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Fonts" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Fonts", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_HISTORY") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\History" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "History", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_NETHOOD") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\NetHood" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "NetHood", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_PERSONAL") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Personal" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Personal", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_PRINTHOOD") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\PrintHood" directory */ + if(ulOSType & OS_NT) + { + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "PrintHood", szVariable, dwVariableSize); + } + } + else if(lstrcmpi(szVariable, "PERSONAL_RECENT") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\Recent" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Recent", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_SENDTO") == 0) + { + /* parse for the "C:\WINNT40\Profiles\%USERNAME%\SendTo" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "SendTo", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "PERSONAL_TEMPLATES") == 0) + { + /* parse for the "C:\WINNT40\ShellNew" directory */ + GetWinReg(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Templates", szVariable, dwVariableSize); + } + else if(lstrcmpi(szVariable, "WIZTEMP") == 0) + { + /* parse for the "c:\Temp" path */ + lstrcpy(szVariable, szTempDir); + if(szVariable[strlen(szVariable) - 1] == '\\') + szVariable[strlen(szVariable) - 1] = '\0'; + } + else if(lstrcmpi(szVariable, "TEMP") == 0) + { + /* parse for the "c:\Temp" path */ + lstrcpy(szVariable, szOSTempDir); + if(szVariable[strlen(szVariable) - 1] == '\\') + szVariable[strlen(szVariable) - 1] = '\0'; + } + else if(lstrcmpi(szVariable, "WINDISK") == 0) + { + /* Locate the drive that Windows is installed on, and only use the drive letter and the ':' character (C:). */ + if(GetWindowsDirectory(szBuf, MAX_BUF) == 0) + { + char szEGetWinDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", + szEGetWinDirFailed, sizeof(szEGetWinDirFailed), + szFileIniUninstall)) + PrintError(szEGetWinDirFailed, ERROR_CODE_SHOW); + + exit(1); + } + else + { + /* Copy the first 2 characters from the path.. */ + /* This is the drive letter and the ':' character for */ + /* where Windows is installed at. */ + memset(szVariable, '\0', MAX_BUF); + szVariable[0] = szBuf[0]; + szVariable[1] = szBuf[1]; + } + } + else if(lstrcmpi(szVariable, "WINDIR") == 0) + { + /* Locate the "c:\Windows" directory */ + if(GetWindowsDirectory(szVariable, dwVariableSize) == 0) + { + char szEGetWinDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_WINDOWS_DIRECTORY_FAILED", "", + szEGetWinDirFailed, sizeof(szEGetWinDirFailed), + szFileIniUninstall)) + PrintError(szEGetWinDirFailed, ERROR_CODE_SHOW); + exit(1); + } + } + else if(lstrcmpi(szVariable, "WINSYSDIR") == 0) + { + /* Locate the "c:\Windows\System" (for Win95/Win98) or "c:\Windows\System32" (for NT) directory */ + if(GetSystemDirectory(szVariable, dwVariableSize) == 0) + { + char szEGetSysDirFailed[MAX_BUF]; + + if(GetPrivateProfileString("Messages", "ERROR_GET_SYSTEM_DIRECTORY_FAILED", "", + szEGetSysDirFailed, sizeof(szEGetSysDirFailed), + szFileIniUninstall)) + PrintError(szEGetSysDirFailed, ERROR_CODE_SHOW); + + exit(1); + } + } + else if(lstrcmpi(szVariable, "JRE BIN PATH") == 0) + { + /* Locate the "c:\Program Files\JavaSoft\JRE\1.3\Bin" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\javaw.Exe", NULL, szVariable, dwVariableSize); + if(*szVariable == '\0') + return(FALSE); + else + { + ParsePath(szVariable, szBuf, MAX_BUF, PP_PATH_ONLY); + lstrcpy(szVariable, szBuf); + } + } + else if(lstrcmpi(szVariable, "JRE PATH") == 0) + { + /* Locate the "c:\Program Files\JavaSoft\JRE\1.3" directory */ + GetWinReg(HKEY_LOCAL_MACHINE, "Software\\JavaSoft\\Java Plug-in\\1.3", "JavaHome", szVariable, dwVariableSize); + if(*szVariable == '\0') + return(FALSE); + } + else if(lstrcmpi(szVariable, "UNINSTALL STARTUP PATH") == 0) + { + lstrcpy(szVariable, szUninstallDir); + } + else if(lstrcmpi(szVariable, "Product CurrentVersion") == 0) + { + char szKey[MAX_BUF]; + + lstrcpy(szKey, "Software\\"); + lstrcat(szKey, ugUninstall.szCompanyName); + lstrcat(szKey, "\\"); + lstrcat(szKey, ugUninstall.szProductName); + + /* parse for the current Netscape WinReg key */ + GetWinReg(HKEY_LOCAL_MACHINE, szKey, "CurrentVersion", szBuf, sizeof(szBuf)); + + if(*szBuf == '\0') + return(FALSE); + + wsprintf(szVariable, "Software\\%s\\%s\\%s", ugUninstall.szCompanyName, ugUninstall.szProductName, szBuf); + } + else if(lstrcmpi(szVariable, "Product WinRegKey") == 0) + { + char szKey[MAX_BUF]; + + lstrcpy(szKey, "Software\\"); + lstrcat(szKey, ugUninstall.szCompanyName); + lstrcat(szKey, "\\"); + lstrcat(szKey, ugUninstall.szProductName); + + wsprintf(szVariable, "Software\\%s\\%s", ugUninstall.szCompanyName, ugUninstall.szProductName); + } + else + return(FALSE); + + return(TRUE); +} + +HRESULT DecryptString(LPSTR szOutputStr, LPSTR szInputStr) +{ + DWORD dwLenInputStr; + DWORD dwCounter; + DWORD dwVar; + DWORD dwPrepend; + char szBuf[MAX_BUF]; + char szVariable[MAX_BUF]; + char szPrepend[MAX_BUF]; + char szAppend[MAX_BUF]; + char szResultStr[MAX_BUF]; + BOOL bFoundVar; + BOOL bBeginParse; + BOOL bDecrypted; + + /* zero out the memory addresses */ + memset(szBuf, '\0', MAX_BUF); + memset(szVariable, '\0', MAX_BUF); + memset(szPrepend, '\0', MAX_BUF); + memset(szAppend, '\0', MAX_BUF); + memset(szResultStr, '\0', MAX_BUF); + + lstrcpy(szPrepend, szInputStr); + dwLenInputStr = lstrlen(szInputStr); + bBeginParse = FALSE; + bFoundVar = FALSE; + + for(dwCounter = 0; dwCounter < dwLenInputStr; dwCounter++) + { + if((szInputStr[dwCounter] == ']') && bBeginParse) + break; + + if(bBeginParse) + szVariable[dwVar++] = szInputStr[dwCounter]; + + if((szInputStr[dwCounter] == '[') && !bBeginParse) + { + dwVar = 0; + dwPrepend = dwCounter; + bBeginParse = TRUE; + } + } + + if(dwCounter == dwLenInputStr) + /* did not find anything to expand. */ + dwCounter = 0; + else + { + bFoundVar = TRUE; + ++dwCounter; + } + + if(bFoundVar) + { + lstrcpy(szAppend, &szInputStr[dwCounter]); + + szPrepend[dwPrepend] = '\0'; + + bDecrypted = DecryptVariable(szVariable, MAX_BUF); + if(!bDecrypted) + { + /* Variable was not able to be decrypted. */ + /* Leave the variable as it was read in by adding the '[' and ']' */ + /* characters back to the variable. */ + lstrcpy(szBuf, "["); + lstrcat(szBuf, szVariable); + lstrcat(szBuf, "]"); + lstrcpy(szVariable, szBuf); + } + + lstrcpy(szOutputStr, szPrepend); + lstrcat(szOutputStr, szVariable); + lstrcat(szOutputStr, szAppend); + + if(bDecrypted) + { + DecryptString(szResultStr, szOutputStr); + lstrcpy(szOutputStr, szResultStr); + } + } + else + lstrcpy(szOutputStr, szInputStr); + + return(TRUE); +} + +HRESULT FileExists(LPSTR szFile) +{ + DWORD rv; + + if((rv = GetFileAttributes(szFile)) == -1) + { + return(FALSE); + } + else + { + return(rv); + } +} + +BOOL WinRegNameExists(HKEY hkRootKey, LPSTR szKey, LPSTR szName) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwSize; + char szBuf[MAX_BUF]; + BOOL bNameExists = FALSE; + + szBuf[0] = '\0'; + if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS) + { + dwSize = sizeof(szBuf); + dwErr = RegQueryValueEx(hkResult, szName, 0, NULL, szBuf, &dwSize); + + if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS)) + bNameExists = TRUE; + + RegCloseKey(hkResult); + } + + return(bNameExists); +} + +void DeleteWinRegValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName) +{ + HKEY hkResult; + DWORD dwErr; + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult); + if(dwErr == ERROR_SUCCESS) + { + if(*szName == '\0') + dwErr = RegDeleteValue(hkResult, NULL); + else + dwErr = RegDeleteValue(hkResult, szName); + + RegCloseKey(hkResult); + } +} + +void DeInitialize() +{ + DeInitDlgUninstall(&diUninstall); + + FreeMemory(&szTempDir); + FreeMemory(&szOSTempDir); + FreeMemory(&szUninstallDir); + FreeMemory(&szEGlobalAlloc); + FreeMemory(&szEDllLoad); + FreeMemory(&szEStringLoad); + FreeMemory(&szEStringNull); + FreeMemory(&szFileIniUninstall); + FreeMemory(&szFileIniDefaultsInfo); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/extra.h b/toolkit/mozapps/installer/windows/wizard/uninstall/extra.h new file mode 100644 index 00000000000..953581a9ae1 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/extra.h @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _EXTRA_H_ +#define _EXTRA_H_ + +#include + +typedef struct diskSpaceNode dsN; +struct diskSpaceNode +{ + ULONGLONG ullSpaceRequired; + LPSTR szPath; + dsN *Next; + dsN *Prev; +}; + +typedef struct structVer +{ + ULONGLONG ullMajor; + ULONGLONG ullMinor; + ULONGLONG ullRelease; + ULONGLONG ullBuild; +} verBlock; + +BOOL InitApplication(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE hInstance, DWORD dwCmdShow); +void PrintError(LPSTR szMsg, DWORD dwErrorCodeSH); +void FreeMemory(void **vPointer); +void *NS_GlobalAlloc(DWORD dwMaxBuf); +HRESULT Initialize(HINSTANCE hInstance); +HRESULT NS_LoadStringAlloc(HANDLE hInstance, DWORD dwID, LPSTR *szStringBuf, DWORD dwStringBuf); +HRESULT NS_LoadString(HANDLE hInstance, DWORD dwID, LPSTR szStringBuf, DWORD dwStringBuf); +HRESULT WinSpawn(LPSTR szClientName, LPSTR szParameters, LPSTR szCurrentDir, int iShowCmd, BOOL bWait); +HRESULT ParseConfigIni(LPSTR lpszCmdLine); +HRESULT DecryptString(LPSTR szOutputStr, LPSTR szInputStr); +HRESULT DecryptVariable(LPSTR szVariable, DWORD dwVariableSize); +void GetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, LPSTR szReturnValue, DWORD dwSize); +void SetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, DWORD dwType, LPSTR szData, DWORD dwSize); +void SetWinRegNumValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName, DWORD dwData); +HRESULT InitUninstallGeneral(void); +HRESULT InitDlgUninstall(diU *diDialog); +sil *CreateSilNode(); +void SilNodeInsert(sil *silHead, sil *silTemp); +void SilNodeDelete(sil *silTemp); +void DeInitialize(void); +void DeInitDlgUninstall(diU *diDialog); +void DetermineOSVersion(void); +void DeInitILomponents(void); +void DeInitUninstallGeneral(void); +HRESULT ParseUninstallIni(); +void ParsePath(LPSTR szInput, LPSTR szOutput, DWORD dwLength, DWORD dwType); +void RemoveBackSlash(LPSTR szInput); +void AppendBackSlash(LPSTR szInput, DWORD dwInputSize); +void RemoveSlash(LPSTR szInput); +void AppendSlash(LPSTR szInput, DWORD dwInputSize); +HRESULT FileExists(LPSTR szFile); +BOOL IsWin95Debute(void); +HRESULT CheckInstances(); +BOOL GetFileVersion(LPSTR szFile, verBlock *vbVersion); +BOOL CheckLegacy(HWND hDlg); +int CompareVersion(verBlock vbVersionOld, verBlock vbVersionNew); +void RemoveQuotes(LPSTR lpszSrc, LPSTR lpszDest, int iDestSize); +int MozCopyStr(LPSTR szSrc, LPSTR szDest, DWORD dwDestBufSize); +LPSTR GetFirstSpace(LPSTR lpszString); +LPSTR GetFirstNonSpace(LPSTR lpszString); +LPSTR MozStrChar(LPSTR lpszString, char c); +int GetArgC(LPSTR lpszCommandLine); +LPSTR GetArgV(LPSTR lpszCommandLine, int iIndex, LPSTR lpszDest, int iDestSize); +DWORD ParseCommandLine(LPSTR lpszCmdLine); +void SetUninstallRunMode(LPSTR szMode); +void Delay(DWORD dwSeconds); +HRESULT GetAppPath(); +DWORD CleanupAppList(); +DWORD ProcessAppItem(HKEY hkRoot, LPSTR szKeyAppList, LPSTR szAppID); +void RemovePathToExeXX(HKEY hkRootKey, LPSTR szKey, DWORD dwIndex, const DWORD dwUpperLimit); +HRESULT GetUninstallLogPath(); +BOOL WinRegNameExists(HKEY hkRootKey, LPSTR szKey, LPSTR szName); +void DeleteWinRegValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName); +void ReplacePrivateProfileStrCR(LPSTR aInputOutputStr); +BOOL IsPathWithinWindir(char *aTargetPath); +void VerifyAndDeleteInstallationFolder(void); + +#endif /* _EXTRA_H_ */ + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.c b/toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.c new file mode 100644 index 00000000000..2743b03f81a --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.c @@ -0,0 +1,393 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "ifuncns.h" +#include "extra.h" + +BOOL SearchForUninstallKeys(char *szStringToMatch) +{ + char szBuf[MAX_BUF]; + char szStringToMatchLowerCase[MAX_BUF]; + char szBufKey[MAX_BUF]; + char szSubKey[MAX_BUF]; + HKEY hkHandle; + BOOL bFound; + DWORD dwIndex; + DWORD dwSubKeySize; + DWORD dwTotalSubKeys; + DWORD dwTotalValues; + FILETIME ftLastWriteFileTime; + char szWRMSUninstallKeyPath[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + char szWRMSUninstallName[] = "UninstallString"; + + lstrcpyn(szStringToMatchLowerCase, szStringToMatch, sizeof(szStringToMatchLowerCase)); + CharLower(szStringToMatchLowerCase); + + bFound = FALSE; + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, szWRMSUninstallKeyPath, 0, KEY_READ, &hkHandle) != ERROR_SUCCESS) + return(bFound); + + dwTotalSubKeys = 0; + dwTotalValues = 0; + RegQueryInfoKey(hkHandle, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL); + for(dwIndex = 0; dwIndex < dwTotalSubKeys; dwIndex++) + { + dwSubKeySize = sizeof(szSubKey); + if(RegEnumKeyEx(hkHandle, dwIndex, szSubKey, &dwSubKeySize, NULL, NULL, NULL, &ftLastWriteFileTime) == ERROR_SUCCESS) + { + wsprintf(szBufKey, "%s\\%s", szWRMSUninstallKeyPath, szSubKey); + GetWinReg(HKEY_LOCAL_MACHINE, szBufKey, szWRMSUninstallName, szBuf, sizeof(szBuf)); + CharLower(szBuf); + if(strstr(szBuf, szStringToMatchLowerCase) != NULL) + { + bFound = TRUE; + + /* found one subkey. break out of the for() loop */ + break; + } + } + } + + RegCloseKey(hkHandle); + return(bFound); +} + +HRESULT FileMove(LPSTR szFrom, LPSTR szTo) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szFromDir[MAX_BUF]; + char szFromTemp[MAX_BUF]; + char szToTemp[MAX_BUF]; + char szBuf[MAX_BUF]; + BOOL bFound; + + /* From file path exists and To file path does not exist */ + if((FileExists(szFrom)) && (!FileExists(szTo))) + { + MoveFile(szFrom, szTo); + return(FO_SUCCESS); + } + /* From file path exists and To file path exists */ + if(FileExists(szFrom) && FileExists(szTo)) + { + /* Since the To file path exists, assume it to be a directory and proceed. */ + /* We don't care if it's a file. If it is a file, then config.ini needs to be */ + /* corrected to remove the file before attempting a MoveFile(). */ + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + ParsePath(szFrom, szBuf, MAX_BUF, PP_FILENAME_ONLY); + lstrcat(szToTemp, szBuf); + MoveFile(szFrom, szToTemp); + return(FO_SUCCESS); + } + + ParsePath(szFrom, szFromDir, MAX_BUF, PP_PATH_ONLY); + + if((hFile = FindFirstFile(szFrom, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path string including filename for source */ + lstrcpy(szFromTemp, szFromDir); + AppendBackSlash(szFromTemp, sizeof(szFromTemp)); + lstrcat(szFromTemp, fdFile.cFileName); + + /* create full path string including filename for destination */ + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + lstrcat(szToTemp, fdFile.cFileName); + + MoveFile(szFromTemp, szToTemp); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT FileCopy(LPSTR szFrom, LPSTR szTo, BOOL bFailIfExists) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szFromDir[MAX_BUF]; + char szFromTemp[MAX_BUF]; + char szToTemp[MAX_BUF]; + char szBuf[MAX_BUF]; + BOOL bFound; + + if(FileExists(szFrom)) + { + /* The file in the From file path exists */ + ParsePath(szFrom, szBuf, MAX_BUF, PP_FILENAME_ONLY); + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + lstrcat(szToTemp, szBuf); + CopyFile(szFrom, szToTemp, bFailIfExists); + return(FO_SUCCESS); + } + + /* The file in the From file path does not exist. Assume to contain wild args and */ + /* proceed acordingly. */ + ParsePath(szFrom, szFromDir, MAX_BUF, PP_PATH_ONLY); + + if((hFile = FindFirstFile(szFrom, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path string including filename for source */ + lstrcpy(szFromTemp, szFromDir); + AppendBackSlash(szFromTemp, sizeof(szFromTemp)); + lstrcat(szFromTemp, fdFile.cFileName); + + /* create full path string including filename for destination */ + lstrcpy(szToTemp, szTo); + AppendBackSlash(szToTemp, sizeof(szToTemp)); + lstrcat(szToTemp, fdFile.cFileName); + + CopyFile(szFromTemp, szToTemp, bFailIfExists); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT CreateDirectoriesAll(char* szPath) +{ + int i; + int iLen = lstrlen(szPath); + char szCreatePath[MAX_BUF]; + HRESULT hrResult; + + ZeroMemory(szCreatePath, MAX_BUF); + memcpy(szCreatePath, szPath, iLen); + for(i = 0; i < iLen; i++) + { + if((iLen > 1) && + ((i != 0) && ((szPath[i] == '\\') || (szPath[i] == '/'))) && + (!((szPath[0] == '\\') && (i == 1)) && !((szPath[1] == ':') && (i == 2)))) + { + szCreatePath[i] = '\0'; + hrResult = CreateDirectory(szCreatePath, NULL); + szCreatePath[i] = szPath[i]; + } + } + return(hrResult); +} + +HRESULT FileDelete(LPSTR szDestination) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szBuf[MAX_BUF]; + char szPathOnly[MAX_BUF]; + BOOL bFound; + + if(FileExists(szDestination)) + { + /* The file in the From file path exists */ + DeleteFile(szDestination); + return(FO_SUCCESS); + } + + /* The file in the From file path does not exist. Assume to contain wild args and */ + /* proceed acordingly. */ + ParsePath(szDestination, szPathOnly, MAX_BUF, PP_PATH_ONLY); + + if((hFile = FindFirstFile(szDestination, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + if(!(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + lstrcpy(szBuf, szPathOnly); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, fdFile.cFileName); + + DeleteFile(szBuf); + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + return(FO_SUCCESS); +} + +HRESULT DirectoryRemove(LPSTR szDestination, BOOL bRemoveSubdirs) +{ + HANDLE hFile; + WIN32_FIND_DATA fdFile; + char szDestTemp[MAX_BUF]; + BOOL bFound; + + if(!FileExists(szDestination)) + return(FO_SUCCESS); + + if(bRemoveSubdirs == TRUE) + { + lstrcpy(szDestTemp, szDestination); + AppendBackSlash(szDestTemp, sizeof(szDestTemp)); + lstrcat(szDestTemp, "*"); + + bFound = TRUE; + hFile = FindFirstFile(szDestTemp, &fdFile); + while((hFile != INVALID_HANDLE_VALUE) && (bFound == TRUE)) + { + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + /* create full path */ + lstrcpy(szDestTemp, szDestination); + AppendBackSlash(szDestTemp, sizeof(szDestTemp)); + lstrcat(szDestTemp, fdFile.cFileName); + + if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + DirectoryRemove(szDestTemp, bRemoveSubdirs); + } + else + { + DeleteFile(szDestTemp); + } + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + } + + RemoveDirectory(szDestination); + return(FO_SUCCESS); +} + +HKEY ParseRootKey(LPSTR szRootKey) +{ + HKEY hkRootKey; + + if(lstrcmpi(szRootKey, "HKEY_CURRENT_CONFIG") == 0) + hkRootKey = HKEY_CURRENT_CONFIG; + else if(lstrcmpi(szRootKey, "HKEY_CURRENT_USER") == 0) + hkRootKey = HKEY_CURRENT_USER; + else if(lstrcmpi(szRootKey, "HKEY_LOCAL_MACHINE") == 0) + hkRootKey = HKEY_LOCAL_MACHINE; + else if(lstrcmpi(szRootKey, "HKEY_USERS") == 0) + hkRootKey = HKEY_USERS; + else if(lstrcmpi(szRootKey, "HKEY_PERFORMANCE_DATA") == 0) + hkRootKey = HKEY_PERFORMANCE_DATA; + else if(lstrcmpi(szRootKey, "HKEY_DYN_DATA") == 0) + hkRootKey = HKEY_DYN_DATA; + else /* HKEY_CLASSES_ROOT */ + hkRootKey = HKEY_CLASSES_ROOT; + + return(hkRootKey); +} + +LPSTR GetStringRootKey(HKEY hkRootKey, LPSTR szString, DWORD dwStringSize) +{ + if(hkRootKey == HKEY_CURRENT_CONFIG) + { + if(sizeof("HKEY_CURRENT_CONFIG") <= dwStringSize) + lstrcpy(szString, "HKEY_CURRENT_CONFIG"); + else + return(NULL); + } + else if(hkRootKey == HKEY_CURRENT_USER) + { + if(sizeof("HKEY_CURRENT_USER") <= dwStringSize) + lstrcpy(szString, "HKEY_CURRENT_USER"); + else + return(NULL); + } + else if(hkRootKey == HKEY_LOCAL_MACHINE) + { + if(sizeof("HKEY_LOCAL_MACHINE") <= dwStringSize) + lstrcpy(szString, "HKEY_LOCAL_MACHINE"); + else + return(NULL); + } + else if(hkRootKey == HKEY_USERS) + { + if(sizeof("HKEY_USERS") <= dwStringSize) + lstrcpy(szString, "HKEY_USERS"); + else + return(NULL); + } + else if(hkRootKey == HKEY_PERFORMANCE_DATA) + { + if(sizeof("HKEY_PERFORMANCE_DATA") <= dwStringSize) + lstrcpy(szString, "HKEY_PERFORMANCE_DATA"); + else + return(NULL); + } + else if(hkRootKey == HKEY_DYN_DATA) + { + if(sizeof("HKEY_DYN_DATA") <= dwStringSize) + lstrcpy(szString, "HKEY_DYN_DATA"); + else + return(NULL); + } + else + { + if(sizeof("HKEY_CLASSES_ROOT") <= dwStringSize) + lstrcpy(szString, "HKEY_CLASSES_ROOT"); + else + return(NULL); + } + + return(szString); +} + +BOOL WinRegKeyExists(HKEY hkRootKey, LPSTR szKey) +{ + HKEY hkResult; + BOOL bKeyExists = FALSE; + + if(RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS) + { + bKeyExists = TRUE; + RegCloseKey(hkResult); + } + + return(bKeyExists); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.h b/toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.h new file mode 100644 index 00000000000..547b0138707 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/ifuncns.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _IFUNCNS_H_ +#define _IFUNCNS_H_ + +#include "uninstall.h" + +HRESULT FileUncompress(LPSTR szFrom, LPSTR szTo); +HRESULT FileMove(LPSTR szFrom, LPSTR szTo); +HRESULT FileCopy(LPSTR szFrom, LPSTR szTo, BOOL bFailIfExists); +HRESULT FileDelete(LPSTR szDestination); +HRESULT DirectoryRemove(LPSTR szDestination, BOOL bRemoveSubdirs); +HRESULT CreateDirectoriesAll(char* szPath); +HKEY ParseRootKey(LPSTR szRootKey); +LPSTR GetStringRootKey(HKEY hkRootKey, LPSTR szString, DWORD dwStringSize); +BOOL SearchForUninstallKeys(char *szStringToMatch); +BOOL WinRegKeyExists(HKEY hkRootKey, LPSTR szKey); + +#endif diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/logkeys.h b/toolkit/mozapps/installer/windows/wizard/uninstall/logkeys.h new file mode 100644 index 00000000000..dbbf813fee2 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/logkeys.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _LOGKEYS_H_ +#define _LOGKEYS_H_ + +#define KEY_DO_NOT_UNINSTALL "(*dnu*) " +#define KEY_INSTALLING "installing: " +#define KEY_INSTALLING_SHARED_FILE "installing shared file: " +#define KEY_REPLACING "replacing: " +#define KEY_REPLACING_SHARED_FILE "replacing shared file: " +#define KEY_STORE_REG_STRING "store registry value string: " +#define KEY_STORE_REG_NUMBER "store registry value number: " +#define KEY_CREATE_REG_KEY "create registry key: " +#define KEY_COPY_FILE "copy file: " +#define KEY_MOVE_FILE "move file: " +#define KEY_RENAME_FILE "rename file: " +#define KEY_CREATE_FOLDER "create folder: " +#define KEY_RENAME_DIR "rename dir: " +#define KEY_WINDOWS_SHORTCUT "windows shortcut: " +#define KEY_WINDOWS_REGISTER_SERVER "windows register server: " +#define KEY_UNINSTALL_COMMAND "uninstall command: " + +#endif diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/parser.c b/toolkit/mozapps/installer/windows/wizard/uninstall/parser.c new file mode 100644 index 00000000000..12088d5b92d --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/parser.c @@ -0,0 +1,791 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "extern.h" +#include "logkeys.h" +#include "parser.h" +#include "extra.h" +#include "ifuncns.h" +#include "dialogs.h" + +#define KEY_SHARED_DLLS "Software\\Microsoft\\Windows\\CurrentVersion\\SharedDlls" + +BOOL DeleteOrDelayUntilReboot(LPSTR szFile) +{ + FILE *ofp; + char szWinDir[MAX_BUF]; + char szWininitFile[MAX_BUF]; + BOOL bDelayDelete = FALSE; + BOOL bWriteRenameSection; + + FileDelete(szFile); + if(FileExists(szFile)) + { + bDelayDelete = TRUE; + if(ulOSType & OS_NT) + MoveFileEx(szFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + else + { + if(GetWindowsDirectory(szWinDir, sizeof(szWinDir)) == 0) + return(FALSE); + + lstrcpy(szWininitFile, szWinDir); + AppendBackSlash(szWininitFile, sizeof(szWininitFile)); + lstrcat(szWininitFile, "wininit.ini"); + + if(FileExists(szWininitFile) == FALSE) + bWriteRenameSection = TRUE; + else + bWriteRenameSection = FALSE; + + if((ofp = fopen(szWininitFile, "a+")) == NULL) + return(FALSE); + + if(bWriteRenameSection == TRUE) + fprintf(ofp, "[RENAME]\n"); + + fprintf(ofp, "NUL=%s\n", szFile); + fclose(ofp); + } + } + else + bDelayDelete = FALSE; + + return(bDelayDelete); +} + +void RemoveUninstaller(LPSTR szUninstallFilename) +{ + char szBuf[MAX_BUF]; + char szWinDir[MAX_BUF]; + char szUninstallFile[MAX_BUF]; + + if(SearchForUninstallKeys(szUninstallFilename)) + /* Found the uninstall file name in the windows registry uninstall + * key sections. We should not try to delete ourselves. */ + return; + + if(GetWindowsDirectory(szWinDir, sizeof(szWinDir)) == 0) + return; + + lstrcpy(szBuf, szWinDir); + AppendBackSlash(szBuf, sizeof(szBuf)); + lstrcat(szBuf, szUninstallFilename); + GetShortPathName(szBuf, szUninstallFile, sizeof(szUninstallFile)); + DeleteOrDelayUntilReboot(szUninstallFile); +} + +sil *InitSilNodes(char *szInFile) +{ + FILE *ifp; + char szLineRead[MAX_BUF]; + sil *silTemp; + sil *silHead; + ULONGLONG ullLineCount; + + if(FileExists(szInFile) == FALSE) + return(NULL); + + ullLineCount = 0; + silHead = NULL; + if((ifp = fopen(szInFile, "r")) == NULL) + exit(1); + + while(fgets(szLineRead, MAX_BUF, ifp) != NULL) + { + silTemp = CreateSilNode(); + + silTemp->ullLineNumber = ++ullLineCount; + lstrcpy(silTemp->szLine, szLineRead); + if(silHead == NULL) + { + silHead = silTemp; + } + else + { + SilNodeInsert(silHead, silTemp); + } + + ProcessWindowsMessages(); + } + fclose(ifp); + return(silHead); +} + +void DeInitSilNodes(sil **silHead) +{ + sil *silTemp; + + if(*silHead == NULL) + { + return; + } + else if(((*silHead)->Prev == NULL) || ((*silHead)->Prev == *silHead)) + { + SilNodeDelete(*silHead); + return; + } + else + { + silTemp = (*silHead)->Prev; + } + + while(silTemp != *silHead) + { + SilNodeDelete(silTemp); + silTemp = (*silHead)->Prev; + + ProcessWindowsMessages(); + } + SilNodeDelete(silTemp); +} + +void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete) +{ + HKEY hkResult; + DWORD dwErr; + DWORD dwTotalSubKeys; + DWORD dwTotalValues; + DWORD dwSubKeySize; + FILETIME ftLastWriteFileTime; + char szSubKey[MAX_BUF]; + char szNewKey[MAX_BUF]; + long lRv; + + dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_QUERY_VALUE, &hkResult); + if(dwErr == ERROR_SUCCESS) + { + dwTotalSubKeys = 0; + dwTotalValues = 0; + RegQueryInfoKey(hkResult, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL); + RegCloseKey(hkResult); + + if(((dwTotalSubKeys == 0) && (dwTotalValues == 0)) || bAbsoluteDelete) + { + if(dwTotalSubKeys && bAbsoluteDelete) + { + do + { + dwSubKeySize = sizeof(szSubKey); + lRv = 0; + if(RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS) + { + if((lRv = RegEnumKeyEx(hkResult, 0, szSubKey, &dwSubKeySize, NULL, NULL, NULL, &ftLastWriteFileTime)) == ERROR_SUCCESS) + { + RegCloseKey(hkResult); + lstrcpy(szNewKey, szKey); + AppendBackSlash(szNewKey, sizeof(szNewKey)); + lstrcat(szNewKey, szSubKey); + DeleteWinRegKey(hkRootKey, szNewKey, bAbsoluteDelete); + } + else + RegCloseKey(hkResult); + } + } while(lRv != ERROR_NO_MORE_ITEMS); + } + + dwErr = RegDeleteKey(hkRootKey, szKey); + } + } +} + +void ParseForUninstallCommand(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwFileBufSize, LPSTR szParam, DWORD dwParamBufSize) +{ + LPSTR szFirstNonSpace; + LPSTR szBeginParamStr; + LPSTR szEndOfFilePath; + LPSTR szEndQuote; + char *cmdStart; + int length; + + ZeroMemory(szFile, dwFileBufSize); + ZeroMemory(szParam, dwParamBufSize); + + length = lstrlen(szString); + if(szString[length - 1] == '\n') + szString[length - 1] = '\0'; + + // get to the beginning of the command given an install log string + cmdStart = szString + lstrlen(szKeyStr); + if((szFirstNonSpace = GetFirstNonSpace(cmdStart)) != NULL) + { + if(*szFirstNonSpace == '\"') + { + ++szFirstNonSpace; + // found a beginning quote, look for the ending quote now + if((szEndQuote = MozStrChar(szFirstNonSpace, '\"')) != NULL) + { + // found ending quote. copy file path string *not* including the quotes + *szEndQuote = '\0'; + MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize); + + // get the params substring now + if((szBeginParamStr = GetFirstNonSpace(++szEndQuote)) != NULL) + { + // the params string should be the first non space char after the + // quoted file path string to the end of the string. + MozCopyStr(szBeginParamStr, szParam, dwParamBufSize); + } + } + else + { + // could not find the ending quote. assume the _entire_ string is the file path + MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize); + } + } + else + { + // no beginning quote found. file path is up to the first space character found + if((szEndOfFilePath = GetFirstSpace(szFirstNonSpace)) != NULL) + { + // found the first space char + *szEndOfFilePath = '\0'; + MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize); + + // get the params substring now + if((szBeginParamStr = GetFirstNonSpace(++szEndOfFilePath)) != NULL) + { + // the params string should be the first non space char after the + // quoted file path string to the end of the string. + MozCopyStr(szBeginParamStr, szParam, dwParamBufSize); + } + } + else + { + // no space char found. assume the _entire_ string is the file path + MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize); + } + } + } +} + +void ParseForFile(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwShortFilenameBufSize) +{ + int iLen; + LPSTR szFirstNonSpace; + char szBuf[MAX_BUF]; + + if((szFirstNonSpace = GetFirstNonSpace(&(szString[lstrlen(szKeyStr)]))) != NULL) + { + iLen = lstrlen(szFirstNonSpace); + if(szFirstNonSpace[iLen - 1] == '\n') + szFirstNonSpace[iLen -1] = '\0'; + + if(lstrcmpi(szKeyStr, KEY_WINDOWS_SHORTCUT) == 0) + { + lstrcpy(szBuf, szFirstNonSpace); + lstrcat(szBuf, ".lnk"); + szFirstNonSpace = szBuf; + } + + lstrcpy(szFile, szFirstNonSpace); + } +} + +void ParseForCopyFile(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwShortFilenameBufSize) +{ + int iLen; + LPSTR szFirstNonSpace; + LPSTR szSubStr = NULL; + char szBuf[MAX_BUF]; + + if((szSubStr = strstr(szString, " to ")) != NULL) + { + if((szFirstNonSpace = GetFirstNonSpace(&(szSubStr[lstrlen(" to ")]))) != NULL) + { + iLen = lstrlen(szFirstNonSpace); + if(szFirstNonSpace[iLen - 1] == '\n') + szFirstNonSpace[iLen -1] = '\0'; + + if(lstrcmpi(szKeyStr, KEY_WINDOWS_SHORTCUT) == 0) + { + lstrcpy(szBuf, szFirstNonSpace); + lstrcat(szBuf, ".lnk"); + szFirstNonSpace = szBuf; + } + + lstrcpy(szFile, szFirstNonSpace); + } + } +} + +HRESULT ParseForWinRegInfo(LPSTR szString, LPSTR szKeyStr, LPSTR szRootKey, DWORD dwRootKeyBufSize, LPSTR szKey, DWORD dwKeyBufSize, LPSTR szName, DWORD dwNameBufSize) +{ + int i; + int iLen; + int iBrackets; + char szStrCopy[MAX_BUF]; + LPSTR szFirstNonSpace; + LPSTR szFirstBackSlash; + BOOL bFoundOpenBracket; + BOOL bFoundName; + + *szRootKey = '\0'; + *szKey = '\0'; + *szName = '\0'; + + lstrcpy(szStrCopy, szString); + if((szFirstNonSpace = GetFirstNonSpace(&(szStrCopy[lstrlen(szKeyStr)]))) != NULL) + { + iLen = lstrlen(szFirstNonSpace); + if(szFirstNonSpace[iLen - 1] == '\n') + { + szFirstNonSpace[--iLen] = '\0'; + } + + szFirstBackSlash = strstr(szFirstNonSpace, "\\"); + if(!szFirstBackSlash) + return(WIZ_ERROR_PARSING_UNINST_STRS); + + szFirstBackSlash[0] = '\0'; + lstrcpy(szRootKey, szFirstNonSpace); + szFirstNonSpace = &(szFirstBackSlash[1]); + iLen = lstrlen(szFirstNonSpace); + + iBrackets = 0; + bFoundName = FALSE; + bFoundOpenBracket = FALSE; + for(i = iLen - 1; i >= 0; i--) + { + if(bFoundName == FALSE) + { + /* Find the Name created in the Windows registry key. + * Since the Name can contain '[' and ']', we have to + * parse for the brackets that denote the Name string in + * szFirstNonSpace. It parses from right to left. + */ + if(szFirstNonSpace[i] == ']') + { + if(iBrackets == 0) + szFirstNonSpace[i] = '\0'; + + ++iBrackets; + } + else if(szFirstNonSpace[i] == '[') + { + bFoundOpenBracket = TRUE; + --iBrackets; + } + + if((bFoundOpenBracket) && (iBrackets == 0)) + { + lstrcpy(szName, &(szFirstNonSpace[i + 1])); + bFoundName = TRUE; + } + } + else + { + /* locate the first non space to the left of the last '[' */ + if(!isspace(szFirstNonSpace[i])) + { + szFirstNonSpace[i + 1] = '\0'; + lstrcpy(szKey, szFirstNonSpace); + break; + } + } + } + } + return(WIZ_OK); +} + +DWORD DecrementSharedFileCounter(char *file) +{ + HKEY keyHandle = 0; + LONG result; + DWORD type = REG_DWORD; + DWORD valbuf = 0; + DWORD valbufsize; + DWORD rv = 0; + + valbufsize = sizeof(DWORD); + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, 0, KEY_READ | KEY_WRITE, &keyHandle); + if(ERROR_SUCCESS == result) + { + result = RegQueryValueEx(keyHandle, file, NULL, &type, (LPBYTE)&valbuf, (LPDWORD)&valbufsize); + if((ERROR_SUCCESS == result) && (type == REG_DWORD)) + { + rv = --valbuf; + } + + RegSetValueEx(keyHandle, file, 0, REG_DWORD, (LPBYTE)&valbuf, valbufsize); + RegCloseKey(keyHandle); + } + + return(rv); +} + +int GetSharedFileCount(char *file) +{ + HKEY keyHandle = 0; + LONG result; + DWORD type = REG_DWORD; + DWORD valbuf = 0; + DWORD valbufsize; + int rv = -999; + + valbufsize = sizeof(DWORD); + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, 0, KEY_READ, &keyHandle); + if(ERROR_SUCCESS == result) + { + result = RegQueryValueEx(keyHandle, file, NULL, &type, (LPBYTE)&valbuf, (LPDWORD)&valbufsize); + if((ERROR_SUCCESS == result) && (type == REG_DWORD)) + rv = valbuf; + + RegCloseKey(keyHandle); + } + + return(rv); +} + +BOOL UnregisterServer(char *file) +{ + FARPROC DllUnReg; + HINSTANCE hLib; + BOOL bFailed = FALSE; + + if(file != NULL) + { + if((hLib = LoadLibraryEx(file, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) != NULL) + { + if((DllUnReg = GetProcAddress(hLib, "DllUnregisterServer")) != NULL) + DllUnReg(); + else + bFailed = TRUE; + + FreeLibrary(hLib); + } + else + bFailed = TRUE; + } + else + bFailed = TRUE; + + return(bFailed); +} + +BOOL DetermineUnRegisterServer(sil *silInstallLogHead, LPSTR szFile) +{ + sil *silInstallLogTemp; + int iSharedFileCount; + char szLCLine[MAX_BUF]; + char szLCFile[MAX_BUF]; + BOOL bRv; + + bRv = FALSE; + if(silInstallLogHead != NULL) + { + silInstallLogTemp = silInstallLogHead; + iSharedFileCount = GetSharedFileCount(szFile); + lstrcpy(szLCFile, szFile); + CharLowerBuff(szLCFile, sizeof(szLCLine)); + + do + { + silInstallLogTemp = silInstallLogTemp->Prev; + lstrcpy(szLCLine, silInstallLogTemp->szLine); + CharLowerBuff(szLCLine, sizeof(szLCLine)); + + if((strstr(szLCLine, szLCFile) != NULL) && + (strstr(szLCLine, KEY_INSTALLING_SHARED_FILE) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + --iSharedFileCount; + } + else if((strstr(szLCLine, szLCFile) != NULL) && + (strstr(szLCLine, KEY_INSTALLING) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + bRv = TRUE; + break; + } + else if((strstr(szLCLine, szLCFile) != NULL) && + (strstr(szLCLine, KEY_REPLACING_SHARED_FILE) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + --iSharedFileCount; + } + else if((strstr(szLCLine, szLCFile) != NULL) && + (strstr(szLCLine, KEY_REPLACING) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + bRv = TRUE; + break; + } + else if((strstr(szLCLine, szLCFile) != NULL) && + (strstr(szLCLine, KEY_COPY_FILE) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + bRv = TRUE; + break; + } + + ProcessWindowsMessages(); + } while(silInstallLogTemp != silInstallLogHead); + } + + if((iSharedFileCount <= 0) && (iSharedFileCount != -999)) + bRv = TRUE; + + return(bRv); +} + +DWORD Uninstall(sil* silInstallLogHead) +{ + sil *silInstallLogTemp; + LPSTR szSubStr; + char szLCLine[MAX_BUF]; + char szKey[MAX_BUF]; + char szRootKey[MAX_BUF]; + char szName[MAX_BUF]; + char szFile[MAX_BUF]; + char szParams[MAX_BUF]; + HKEY hkRootKey; + int rv; + + if(silInstallLogHead != NULL) + { + silInstallLogTemp = silInstallLogHead; + do + { + silInstallLogTemp = silInstallLogTemp->Prev; + lstrcpy(szLCLine, silInstallLogTemp->szLine); + CharLowerBuff(szLCLine, sizeof(szLCLine)); + + if(((szSubStr = strstr(szLCLine, KEY_WINDOWS_REGISTER_SERVER)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + ParseForFile(szSubStr, KEY_WINDOWS_REGISTER_SERVER, szFile, sizeof(szFile)); + if(DetermineUnRegisterServer(silInstallLogHead, szFile) == TRUE) + UnregisterServer(szFile); + } + else if(((szSubStr = strstr(szLCLine, KEY_INSTALLING_SHARED_FILE)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "Installing Shared File: " string and delete the file */ + ParseForFile(szSubStr, KEY_INSTALLING_SHARED_FILE, szFile, sizeof(szFile)); + if(DecrementSharedFileCounter(szFile) == 0) + { + if((gdwWhatToDo != WTD_NO_TO_ALL) && (gdwWhatToDo != WTD_YES_TO_ALL)) + { + MessageBeep(MB_ICONEXCLAMATION); + gdwWhatToDo = DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_WHAT_TO_DO), hDlgUninstall, DlgProcWhatToDo, (LPARAM)szFile); + } + + if((gdwWhatToDo == WTD_YES) || (gdwWhatToDo == WTD_YES_TO_ALL)) + { + DeleteWinRegValue(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, szFile); + DeleteOrDelayUntilReboot(szFile); + } + else if(gdwWhatToDo == WTD_CANCEL) + return(WTD_CANCEL); + } + } + else if(((szSubStr = strstr(szLCLine, KEY_INSTALLING)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "Installing: " string and delete the file */ + ParseForFile(szSubStr, KEY_INSTALLING, szFile, sizeof(szFile)); + DeleteOrDelayUntilReboot(szFile); + } + else if(((szSubStr = strstr(szLCLine, KEY_REPLACING_SHARED_FILE)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "Replacing Shared File: " string and delete the file */ + ParseForFile(szSubStr, KEY_REPLACING_SHARED_FILE, szFile, sizeof(szFile)); + if(DecrementSharedFileCounter(szFile) == 0) + { + if((gdwWhatToDo != WTD_NO_TO_ALL) && (gdwWhatToDo != WTD_YES_TO_ALL)) + gdwWhatToDo = DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_WHAT_TO_DO), hDlgUninstall, DlgProcWhatToDo, (LPARAM)szFile); + + if((gdwWhatToDo == WTD_YES) || (gdwWhatToDo == WTD_YES_TO_ALL)) + { + DeleteWinRegValue(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, szFile); + DeleteOrDelayUntilReboot(szFile); + } + else if(gdwWhatToDo == WTD_CANCEL) + return(WTD_CANCEL); + } + } + else if(((szSubStr = strstr(szLCLine, KEY_REPLACING)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "Replacing: " string and delete the file */ + ParseForFile(szSubStr, KEY_REPLACING, szFile, sizeof(szFile)); + DeleteOrDelayUntilReboot(szFile); + } + else if(((szSubStr = strstr(szLCLine, KEY_STORE_REG_STRING)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "Store Registry Value String: " string and remove the key */ + rv = ParseForWinRegInfo(szSubStr, KEY_STORE_REG_STRING, szRootKey, sizeof(szRootKey), szKey, sizeof(szKey), szName, sizeof(szName)); + if(WIZ_OK == rv) + { + hkRootKey = ParseRootKey(szRootKey); + DeleteWinRegValue(hkRootKey, szKey, szName); + } + } + else if(((szSubStr = strstr(szLCLine, KEY_STORE_REG_NUMBER)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "Store Registry Value Number: " string and remove the key */ + rv = ParseForWinRegInfo(szSubStr, KEY_STORE_REG_NUMBER, szRootKey, sizeof(szRootKey), szKey, sizeof(szKey), szName, sizeof(szName)); + if(WIZ_OK == rv) + { + hkRootKey = ParseRootKey(szRootKey); + DeleteWinRegValue(hkRootKey, szKey, szName); + } + } + else if(((szSubStr = strstr(szLCLine, KEY_CREATE_REG_KEY)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + rv = ParseForWinRegInfo(szSubStr, KEY_CREATE_REG_KEY, szRootKey, sizeof(szRootKey), szKey, sizeof(szKey), szName, sizeof(szName)); + if(WIZ_OK == rv) + { + hkRootKey = ParseRootKey(szRootKey); + DeleteWinRegKey(hkRootKey, szKey, FALSE); + } + } + else if(((szSubStr = strstr(szLCLine, KEY_CREATE_FOLDER)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + ParseForFile(szSubStr, KEY_CREATE_FOLDER, szFile, sizeof(szFile)); + DirectoryRemove(szFile, FALSE); + } + else if(((szSubStr = strstr(szLCLine, KEY_WINDOWS_SHORTCUT)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + ParseForFile(szSubStr, KEY_WINDOWS_SHORTCUT, szFile, sizeof(szFile)); + DeleteOrDelayUntilReboot(szFile); + } + else if(((szSubStr = strstr(szLCLine, KEY_COPY_FILE)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + /* check for "copy file: " string and delete the file */ + ParseForCopyFile(szSubStr, KEY_COPY_FILE, szFile, sizeof(szFile)); + DeleteOrDelayUntilReboot(szFile); + } + else if(((szSubStr = strstr(szLCLine, KEY_UNINSTALL_COMMAND)) != NULL) && + (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL)) + { + ParseForUninstallCommand(szSubStr, KEY_UNINSTALL_COMMAND, szFile, sizeof(szFile), szParams, sizeof(szParams)); + //execute szFile with szParams here! + if(FileExists(szFile)) + WinSpawn(szFile, szParams, NULL, SW_HIDE, TRUE); + } + + ProcessWindowsMessages(); + } while(silInstallLogTemp != silInstallLogHead); + } + + return(0); +} + +DWORD GetLogFile(LPSTR szTargetPath, LPSTR szInFilename, LPSTR szOutBuf, DWORD dwOutBufSize) +{ + int iFilenameOnlyLen; + char szSearchFilename[MAX_BUF]; + char szSearchTargetFullFilename[MAX_BUF]; + char szFilenameOnly[MAX_BUF]; + char szFilenameExtensionOnly[MAX_BUF]; + char szNumber[MAX_BUF]; + long dwNumber; + long dwMaxNumber; + LPSTR szDotPtr; + HANDLE hFile; + WIN32_FIND_DATA fdFile; + BOOL bFound; + + if(FileExists(szTargetPath)) + { + /* zero out the memory */ + ZeroMemory(szOutBuf, dwOutBufSize); + ZeroMemory(szSearchFilename, sizeof(szSearchFilename)); + ZeroMemory(szFilenameOnly, sizeof(szFilenameOnly)); + ZeroMemory(szFilenameExtensionOnly, sizeof(szFilenameExtensionOnly)); + + /* parse for the filename w/o extention and also only the extension */ + if((szDotPtr = strstr(szInFilename, ".")) != NULL) + { + *szDotPtr = '\0'; + lstrcpy(szSearchFilename, szInFilename); + lstrcpy(szFilenameOnly, szInFilename); + lstrcpy(szFilenameExtensionOnly, &szDotPtr[1]); + *szDotPtr = '.'; + } + else + { + lstrcpy(szFilenameOnly, szInFilename); + lstrcpy(szSearchFilename, szInFilename); + } + + /* create the wild arg filename to search for in the szTargetPath */ + lstrcat(szSearchFilename, "*.*"); + lstrcpy(szSearchTargetFullFilename, szTargetPath); + AppendBackSlash(szSearchTargetFullFilename, sizeof(szSearchTargetFullFilename)); + lstrcat(szSearchTargetFullFilename, szSearchFilename); + + iFilenameOnlyLen = lstrlen(szFilenameOnly); + dwNumber = 0; + dwMaxNumber = -1; + + /* find the largest numbered filename in the szTargetPath */ + if((hFile = FindFirstFile(szSearchTargetFullFilename, &fdFile)) == INVALID_HANDLE_VALUE) + bFound = FALSE; + else + bFound = TRUE; + + while(bFound) + { + ZeroMemory(szNumber, sizeof(szNumber)); + if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0)) + { + lstrcpy(szNumber, &fdFile.cFileName[iFilenameOnlyLen]); + dwNumber = atoi(szNumber); + if(dwNumber > dwMaxNumber) + dwMaxNumber = dwNumber; + } + + bFound = FindNextFile(hFile, &fdFile); + } + + FindClose(hFile); + + lstrcpy(szOutBuf, szTargetPath); + AppendBackSlash(szOutBuf, dwOutBufSize); + lstrcat(szOutBuf, szFilenameOnly); + itoa(dwMaxNumber, szNumber, 10); + lstrcat(szOutBuf, szNumber); + + if(*szFilenameExtensionOnly != '\0') + { + lstrcat(szOutBuf, "."); + lstrcat(szOutBuf, szFilenameExtensionOnly); + } + } + else + return(0); + + return(FileExists(szOutBuf)); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/parser.h b/toolkit/mozapps/installer/windows/wizard/uninstall/parser.h new file mode 100644 index 00000000000..2825e737c27 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/parser.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _PARSER_H_ +#define _PARSER_H_ + +sil *InitSilNodes(char *szFileIni); +void DeInitSilNodes(sil **silHead); +HRESULT FileExists(LPSTR szFile); +DWORD Uninstall(sil* silFile); +void ParseForFile(LPSTR szString, LPSTR szKey, LPSTR szFile, DWORD dwShortFilenameBufSize); +void ParseForCopyFile(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwShortFilenameBufSize); +HRESULT ParseForWinRegInfo(LPSTR szString, LPSTR szKeyStr, LPSTR szRootKey, DWORD dwRootKeyBufSize, LPSTR szKey, DWORD dwKeyBufSize, LPSTR szName, DWORD dwNameBufSize); +void ParseForUninstallCommand(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwFileBufSize, LPSTR szParam, DWORD dwParamBufSize); +void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete); +DWORD GetLogFile(LPSTR szTargetPath, LPSTR szInFilename, LPSTR szOutBuf, DWORD dwOutBufSize); +void RemoveUninstaller(LPSTR szUninstallFilename); +DWORD DecrementSharedFileCounter(char *file); +BOOL DeleteOrDelayUntilReboot(LPSTR szFile); +BOOL UnregisterServer(char *file); +int GetSharedFileCount(char *file); +BOOL DetermineUnRegisterServer(sil *silInstallLogHead, LPSTR szFile); + +#endif + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/process.c b/toolkit/mozapps/installer/windows/wizard/uninstall/process.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/process.h b/toolkit/mozapps/installer/windows/wizard/uninstall/process.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/rdi.c b/toolkit/mozapps/installer/windows/wizard/uninstall/rdi.c new file mode 100644 index 00000000000..0fc35315742 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/rdi.c @@ -0,0 +1,587 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 1998, 1999, 2000, 2001 Netscape Communications Corp. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "extern.h" +#include "parser.h" +#include "extra.h" +#include "ifuncns.h" + +HKEY hkUnreadMailRootKey = HKEY_CURRENT_USER; +char szUnreadMailKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail"; +char szMozillaDesktopKey[] = "Software\\Mozilla\\Desktop"; +char szRDISection[] = "Restore Desktop Integration"; + +/* structure for use with UnreadMail registry keys */ +typedef struct sKeyNode skn; +struct sKeyNode +{ + char szKey[MAX_BUF]; + skn *Next; + skn *Prev; +}; + +/* Function that creates an instance of skn */ +skn *CreateSknNode() +{ + skn *sknNode; + + if((sknNode = NS_GlobalAlloc(sizeof(struct sKeyNode))) == NULL) + exit(1); + + sknNode->Next = sknNode; + sknNode->Prev = sknNode; + + return(sknNode); +} + +/* Function that inserts a skn structure into a linked list */ +void SknNodeInsert(skn **sknHead, skn *sknTemp) +{ + if(*sknHead == NULL) + { + *sknHead = sknTemp; + (*sknHead)->Next = *sknHead; + (*sknHead)->Prev = *sknHead; + } + else + { + sknTemp->Next = *sknHead; + sknTemp->Prev = (*sknHead)->Prev; + (*sknHead)->Prev->Next = sknTemp; + (*sknHead)->Prev = sknTemp; + } +} + +/* Function that removes a skn structure from a skn linked list. + * and frees memory. */ +void SknNodeDelete(skn *sknTemp) +{ + if(sknTemp != NULL) + { + sknTemp->Next->Prev = sknTemp->Prev; + sknTemp->Prev->Next = sknTemp->Next; + sknTemp->Next = NULL; + sknTemp->Prev = NULL; + + FreeMemory(&sknTemp); + } +} + +/* Function that traverses a skn linked list and deletes each node. */ +void DeInitSknList(skn **sknHeadNode) +{ + skn *sknTemp; + + if(*sknHeadNode == NULL) + return; + + sknTemp = (*sknHeadNode)->Prev; + + while(sknTemp != *sknHeadNode) + { + SknNodeDelete(sknTemp); + sknTemp = (*sknHeadNode)->Prev; + } + + SknNodeDelete(sknTemp); + *sknHeadNode = NULL; +} + +/* Function to check if [windir]\mapi32.dll belongs to mozilla or not */ +int IsMapiMozMapi(BOOL *bIsMozMapi) +{ + HINSTANCE hLib; + char szMapiFilePath[MAX_BUF]; + int iRv = WIZ_ERROR_UNDEFINED; + int (PASCAL *GetMapiDllVersion)(void); + char szMapiVersionKey[] = "MAPI version installed"; + char szBuf[MAX_BUF]; + int iMapiVersionInstalled; + + /* Get the Mapi version that we installed from uninstall.ini. + * If there is none set, then return WIZ_ERROR_UNDEFINED. */ + GetPrivateProfileString(szRDISection, szMapiVersionKey, "", szBuf, sizeof(szBuf), szFileIniUninstall); + if(*szBuf == '\0') + return(iRv); + + iMapiVersionInstalled = atoi(szBuf); + if(GetSystemDirectory(szMapiFilePath, sizeof(szMapiFilePath)) == 0) + return(iRv); + + AppendBackSlash(szMapiFilePath, sizeof(szMapiFilePath)); + lstrcat(szMapiFilePath, "Mapi32.dll"); + if(!FileExists(szMapiFilePath)) + iRv = WIZ_FILE_NOT_FOUND; + else if((hLib = LoadLibrary(szMapiFilePath)) != NULL) + { + iRv = WIZ_OK; + *bIsMozMapi = FALSE; + if(((FARPROC)GetMapiDllVersion = GetProcAddress(hLib, "GetMapiDllVersion")) != NULL) + { + if(iMapiVersionInstalled == GetMapiDllVersion()) + *bIsMozMapi = TRUE; + } + FreeLibrary(hLib); + } + return(iRv); +} + +/* This function parses takes as input a registry key path string beginning + * with HKEY_XXXX (root key) and parses out the sub key path and the root + * key. + * + * It returns the root key as HKEY and the sub key path as char* */ +HKEY GetRootKeyAndSubKeyPath(char *szInKeyPath, char *szOutSubKeyPath, DWORD dwOutSubKeyPathSize) +{ + char *ptr = szInKeyPath; + HKEY hkRootKey = HKEY_CLASSES_ROOT; + + ZeroMemory(szOutSubKeyPath, dwOutSubKeyPathSize); + if(ptr == NULL) + return(hkRootKey); + + /* search for the first '\' char */ + while(*ptr && (*ptr != '\\')) + ++ptr; + + if((*ptr == '\0') || + (*ptr == '\\')) + { + BOOL bPtrModified = FALSE; + + if(*ptr == '\\') + { + *ptr = '\0'; + bPtrModified = TRUE; + } + hkRootKey = ParseRootKey(szInKeyPath); + + if(bPtrModified) + *ptr = '\\'; + + if((*ptr != '\0') && + ((unsigned)lstrlen(ptr + 1) + 1 <= dwOutSubKeyPathSize)) + /* copy only the sub key path after the root key string */ + lstrcpy(szOutSubKeyPath, ptr + 1); + } + return(hkRootKey); +} + + +/* This function checks for nonprintable characters. + * If at least one is found in the input string, it will return TRUE, + * else FALSE */ +BOOL CheckForNonPrintableChars(char *szInString) +{ + int i; + int iLen; + BOOL bFoundNonPrintableChar = FALSE; + + if(!szInString) + return(TRUE); + + iLen = lstrlen(szInString); + + for(i = 0; i < iLen; i++) + { + if(!isprint(szInString[i])) + { + bFoundNonPrintableChar = TRUE; + break; + } + } + + return(bFoundNonPrintableChar); +} + +/* This function checks to see if the key path is a ddeexec path. If so, + * it then checks for non printable chars */ +BOOL DdeexecCheck(char *szKey, char *szValue) +{ + char szKddeexec[] = "shell\\open\\ddeexec"; + char szKeyLower[MAX_BUF]; + BOOL bPass = TRUE; + + lstrcpy(szKeyLower, szKey); + CharLowerBuff(szKeyLower, sizeof(szKeyLower)); + if(strstr(szKeyLower, szKddeexec) && CheckForNonPrintableChars(szValue)) + bPass = FALSE; + + return(bPass); +} + +/* This function enumerates HKEY_LOCAL_MACHINE\Sofware\Mozilla\Desktop for + * variable information on what desktop integration was done by the + * browser/mail client. + * + * These variables found cannot be deleted or modified until the enumeration + * is complete, or else this function will fail! */ +void RestoreDesktopIntegration() +{ + char szVarName[MAX_BUF]; + char szValue[MAX_BUF]; + char szSubKey[MAX_BUF]; + HKEY hkHandle; + DWORD dwIndex; + DWORD dwSubKeySize; + DWORD dwTotalValues; + char szKHKEY[] = "HKEY"; + char szKisHandling[] = "isHandling"; + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, szMozillaDesktopKey, 0, KEY_READ|KEY_WRITE, &hkHandle) != ERROR_SUCCESS) + return; + + dwTotalValues = 0; + RegQueryInfoKey(hkHandle, NULL, NULL, NULL, NULL, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL); + for(dwIndex = 0; dwIndex < dwTotalValues; dwIndex++) + { + /* Enumerate thru all the vars found within the Mozilla Desktop key */ + dwSubKeySize = sizeof(szVarName); + if(RegEnumValue(hkHandle, dwIndex, szVarName, &dwSubKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + if(strnicmp(szVarName, szKHKEY, lstrlen(szKHKEY)) == 0) + { + HKEY hkRootKey; + + hkRootKey = GetRootKeyAndSubKeyPath(szVarName, szSubKey, sizeof(szSubKey)); + if(*szSubKey != '\0') + { + GetWinReg(HKEY_LOCAL_MACHINE, szMozillaDesktopKey, szVarName, szValue, sizeof(szValue)); + if(*szValue != '\0') + { + /* Due to a bug in the browser code that saves the previous HKEY + * value it's trying to replace as garbage chars, we need to try + * to detect it. If found, do not restore it. This bug only + * happens for the saved ddeexec keys. */ + if(DdeexecCheck(szSubKey, szValue)) + { + /* Restore the previous saved setting here */ + SetWinReg(hkRootKey, + szSubKey, + NULL, + REG_SZ, + szValue, + lstrlen(szValue)); + } + } + else + /* if the saved value is an empty string, then + * delete the default var for this key */ + DeleteWinRegValue(hkRootKey, + szSubKey, + szValue); + } + } + } + } + RegCloseKey(hkHandle); + return; +} + +void RestoreMozMapi() +{ + char szMozMapiBackupFile[MAX_BUF]; + BOOL bFileIsMozMapi = FALSE; + + GetWinReg(HKEY_LOCAL_MACHINE, + szMozillaDesktopKey, + "Mapi_backup_dll", + szMozMapiBackupFile, + sizeof(szMozMapiBackupFile)); + + /* If the windows registry Mapi_backup_dll var name does not exist, + * then we're not the default mail handler for the system. + * + * If the backup mapi file does not exist for some reason, then + * there's no way to restore the previous saved mapi32.dll file. */ + if((*szMozMapiBackupFile == '\0') || !FileExists(szMozMapiBackupFile)) + return; + + /* A TRUE for bFileIsMozMapi indicates that we need to restore + * the backed up mapi32.dll (if one was backed up). + * + * bFileIsMozMapi is TRUE in the following conditions: + * * mapi32.dll is not found + * * mapi32.dll loads and GetMapiDllVersion() exists + * _and_ returns the same version indicated in the uninstall.ini file: + * + * [Restore Desktop Integration] + * Mapi version installed=94 + * + * 94 indicates version 0.9.4 */ + if(IsMapiMozMapi(&bFileIsMozMapi) == WIZ_FILE_NOT_FOUND) + bFileIsMozMapi = TRUE; + + if(bFileIsMozMapi) + { + char szDestinationFilename[MAX_BUF]; + + /* Get the Windows System (or System32 under NT) directory */ + if(GetSystemDirectory(szDestinationFilename, sizeof(szDestinationFilename))) + { + /* Copy the backup filename into the normal Mapi32.dll filename */ + AppendBackSlash(szDestinationFilename, sizeof(szDestinationFilename)); + lstrcat(szDestinationFilename, "Mapi32.dll"); + CopyFile(szMozMapiBackupFile, szDestinationFilename, FALSE); + } + } + /* Delete the backup Mapi filename */ + FileDelete(szMozMapiBackupFile); +} + +BOOL UndoDesktopIntegration(void) +{ + char szMozillaKey[] = "Software\\Mozilla"; + char szBuf[MAX_BUF]; + + /* Check to see if uninstall.ini has indicated to restore + * the destktop integration performed by the browser/mail */ + GetPrivateProfileString(szRDISection, "Enabled", "", szBuf, sizeof(szBuf), szFileIniUninstall); + if(lstrcmpi(szBuf, "TRUE") == 0) + { + RestoreDesktopIntegration(); + RestoreMozMapi(); + + DeleteWinRegKey(HKEY_LOCAL_MACHINE, szMozillaDesktopKey, TRUE); + DeleteWinRegKey(HKEY_LOCAL_MACHINE, szMozillaKey, FALSE); + } + + return(0); +} + + +/* Function that retrieves the app name (including path) that is going to be + * uninstalled. The return string is in upper case. */ +int GetUninstallAppPathName(char *szAppPathName, DWORD dwAppPathNameSize) +{ + char szKey[MAX_BUF]; + HKEY hkRoot; + + if(*ugUninstall.szUserAgent != '\0') + { + hkRoot = ugUninstall.hWrMainRoot; + lstrcpy(szKey, ugUninstall.szWrMainKey); + AppendBackSlash(szKey, sizeof(szKey)); + lstrcat(szKey, ugUninstall.szUserAgent); + AppendBackSlash(szKey, sizeof(szKey)); + lstrcat(szKey, "Main"); + } + else + { + return(CMI_APP_PATHNAME_NOT_FOUND); + } + + GetWinReg(hkRoot, szKey, "PathToExe", szAppPathName, dwAppPathNameSize); + CharUpperBuff(szAppPathName, dwAppPathNameSize); + return(CMI_OK); +} + +/* Function to delete the UnreadMail keys that belong to the app that is being + * uninstalled. The skn list that is passed in should only contain UnreadMail + * subkeys to be deleted. */ +void DeleteUnreadMailKeys(skn *sknHeadNode) +{ + skn *sknTempNode; + char szUnreadMailDeleteKey[MAX_BUF]; + DWORD dwLength; + + if(sknHeadNode == NULL) + return; + + sknTempNode = sknHeadNode; + + do + { + /* build the full UnreadMail key to be deleted */ + dwLength = sizeof(szUnreadMailDeleteKey) > lstrlen(szUnreadMailKey) ? + lstrlen(szUnreadMailKey) + 1: sizeof(szUnreadMailDeleteKey); + lstrcpyn(szUnreadMailDeleteKey, szUnreadMailKey, dwLength); + AppendBackSlash(szUnreadMailDeleteKey, sizeof(szUnreadMailDeleteKey)); + if((unsigned)(lstrlen(sknTempNode->szKey) + 1) < + (sizeof(szUnreadMailDeleteKey) - lstrlen(szUnreadMailKey) + 1)) + { + lstrcat(szUnreadMailDeleteKey, sknTempNode->szKey); + + /* delete the UnreadMail key (even if it has subkeys) */ + DeleteWinRegKey(hkUnreadMailRootKey, szUnreadMailDeleteKey, TRUE); + } + + /* get the next key to delete */ + sknTempNode = sknTempNode->Next; + + }while(sknTempNode != sknHeadNode); +} + +/* Function that builds a list of UnreadMail subkey names that only belong to + * the app that is being uninstalled. The list is a linked list of skn + * structures. */ +BOOL GetUnreadMailKeyList(char *szUninstallAppPathName, skn **sknWinRegKeyList) +{ + HKEY hkSubKeyHandle; + HKEY hkHandle; + DWORD dwErr = ERROR_SUCCESS; + DWORD dwTotalSubKeys; + DWORD dwSubKeySize; + DWORD dwIndex; + DWORD dwBufSize; + BOOL bFoundAtLeastOne = FALSE; + char szSubKey[MAX_BUF]; + char szBuf[MAX_BUF]; + char szNewKey[MAX_BUF]; + skn *sknTempNode; + + /* open the UnreadMail key so we can enumerate its subkeys */ + dwErr = RegOpenKeyEx(hkUnreadMailRootKey, + szUnreadMailKey, + 0, + KEY_READ|KEY_QUERY_VALUE, + &hkHandle); + if(dwErr == ERROR_SUCCESS) + { + dwTotalSubKeys = 0; + RegQueryInfoKey(hkHandle, + NULL, + NULL, + NULL, + &dwTotalSubKeys, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + + if(dwTotalSubKeys != 0) + { + dwIndex = 0; + do + { + /* For each UnreadMail subkey, parse it's 'Application' var name for + * the app we're uninstalling (full path). Compare against both long + * path name and short path name. If match found, add to linked list + * of skn structures. + * + * No key deletion is performed at this time! */ + + sknTempNode = NULL; /* reset temporaty node pointer */ + dwSubKeySize = sizeof(szSubKey); + if((dwErr = RegEnumKeyEx(hkHandle, + dwIndex, + szSubKey, + &dwSubKeySize, + NULL, + NULL, + NULL, + NULL)) == ERROR_SUCCESS) + { + lstrcpy(szNewKey, szUnreadMailKey); + AppendBackSlash(szNewKey, sizeof(szNewKey)); + lstrcat(szNewKey, szSubKey); + + if(RegOpenKeyEx(hkUnreadMailRootKey, + szNewKey, + 0, + KEY_READ, + &hkSubKeyHandle) == ERROR_SUCCESS) + { + dwBufSize = sizeof(szBuf); + if(RegQueryValueEx(hkSubKeyHandle, + "Application", + NULL, + NULL, + szBuf, + &dwBufSize) == ERROR_SUCCESS) + { + CharUpperBuff(szBuf, sizeof(szBuf)); + if(strstr(szBuf, szUninstallAppPathName) != NULL) + { + bFoundAtLeastOne = TRUE; + sknTempNode = CreateSknNode(); + lstrcpyn(sknTempNode->szKey, szSubKey, dwSubKeySize + 1); + } + else + { + char szUninstallAppPathNameShort[MAX_BUF]; + + GetShortPathName(szUninstallAppPathName, + szUninstallAppPathNameShort, + sizeof(szUninstallAppPathNameShort)); + if(strstr(szBuf, szUninstallAppPathNameShort) != NULL) + { + bFoundAtLeastOne = TRUE; + sknTempNode = CreateSknNode(); + lstrcpyn(sknTempNode->szKey, szSubKey, dwSubKeySize + 1); + } + } + } + RegCloseKey(hkSubKeyHandle); + } + } + + if(sknTempNode) + SknNodeInsert(sknWinRegKeyList, sknTempNode); + + ++dwIndex; + } while(dwErr != ERROR_NO_MORE_ITEMS); + } + RegCloseKey(hkHandle); + } + return(bFoundAtLeastOne); +} + +/* Main function that deals with cleaning up the UnreadMail subkeys belonging + * to the app were currently uninstalling. */ +int CleanupMailIntegration(void) +{ + char szCMISection[] = "Cleanup Mail Integration"; + char szUninstallApp[MAX_BUF]; + char szBuf[MAX_BUF]; + skn *sknWinRegKeyList = NULL; + + /* Check to see if uninstall.ini has indicated to cleanup + * the mail integration performed by mail */ + GetPrivateProfileString(szCMISection, + "Enabled", + "", + szBuf, + sizeof(szBuf), + szFileIniUninstall); + if(lstrcmpi(szBuf, "TRUE") != 0) + return(CMI_OK); + + /* Get the full app name we're going to uninstall */ + if(GetUninstallAppPathName(szUninstallApp, sizeof(szUninstallApp)) != CMI_OK) + return(CMI_APP_PATHNAME_NOT_FOUND); + + /* Build a list of UnreadMail subkeys that needs to be deleted */ + if(GetUnreadMailKeyList(szUninstallApp, &sknWinRegKeyList)) + /* Delete the UnreadMail subkeys using the list built by + * GetUnreadMailKeyList() */ + DeleteUnreadMailKeys(sknWinRegKeyList); + + /* Clean up the linked list */ + DeInitSknList(&sknWinRegKeyList); + return(CMI_OK); +} + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/rdi.h b/toolkit/mozapps/installer/windows/wizard/uninstall/rdi.h new file mode 100644 index 00000000000..b725338116d --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/rdi.h @@ -0,0 +1,31 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Navigator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape Communications Corp. are + * Copyright (C) 1998, 1999, 2000, 2001 Netscape Communications Corp. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _RDI_H_ +#define _RDI_H_ + +BOOL UndoDesktopIntegration(void); +int CleanupMailIntegration(void); + +#endif + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/resource.h b/toolkit/mozapps/installer/windows/wizard/uninstall/resource.h new file mode 100644 index 00000000000..230b5ed013b --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/resource.h @@ -0,0 +1,50 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by uninstall.rc +// +#ifndef WINVER +#define WINVER 0x0400 +#endif +#include "winresrc.h" + +#define IDS_ERROR_DLL_LOAD 1 +#define IDS_ERROR_STRING_LOAD 2 +#define IDS_ERROR_STRING_NULL 4 +#define IDS_ERROR_GLOBALALLOC 5 +#define IDS_ERROR_FAILED 6 +#define IDI_SETUP 105 +#define IDI_UNINSTALL 105 +#define DLG_MESSAGE 110 +#define IDC_LIST_PRODUCTS 1000 +#define ID_NO 1001 +#define IDC_GAUGE_FILE 1002 +#define ID_NO_TO_ALL 1002 +#define IDC_STATUS0 1004 +#define ID_YES 1004 +#define IDC_STATUS3 1005 +#define ID_YES_TO_ALL 1005 +#define IDC_GAUGE_ARCHIVE 1006 +#define IDC_STATIC_SHARED_FILENAME 1006 +#define IDC_EDIT_CURRENT_SETTINGS 1026 +#define IDC_MESSAGE0 1042 +#define IDC_MESSAGE1 1043 +#define IDC_MESSAGE 1049 +#define DLG_UNINSTALL 2008 +#define DLG_EXTRACTING 2009 +#define DLG_PRODUCT_LIST 2009 +#define DLG_WHAT_TO_DO 2009 +#define IDWIZBACK 11013 +#define IDWIZNEXT 11014 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1007 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.c b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.c new file mode 100644 index 00000000000..1119758eb17 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.c @@ -0,0 +1,149 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#include "uninstall.h" +#include "extra.h" +#include "dialogs.h" +#include "ifuncns.h" + +/* global variables */ +HINSTANCE hInst; + +HANDLE hAccelTable; + +HWND hDlgUninstall; +HWND hDlgMessage; +HWND hWndMain; + +LPSTR szEGlobalAlloc; +LPSTR szEStringLoad; +LPSTR szEDllLoad; +LPSTR szEStringNull; +LPSTR szTempSetupPath; + +LPSTR szClassName; +LPSTR szUninstallDir; +LPSTR szTempDir; +LPSTR szOSTempDir; +LPSTR szFileIniUninstall; +LPSTR szFileIniDefaultsInfo; +LPSTR gszSharedFilename; + +ULONG ulOSType; +DWORD dwScreenX; +DWORD dwScreenY; + +DWORD gdwWhatToDo; + +BOOL gbAllowMultipleInstalls = FALSE; + +uninstallGen ugUninstall; +diU diUninstall; + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) +{ + /***********************************************************************/ + /* HANDLE hInstance; handle for this instance */ + /* HANDLE hPrevInstance; handle for possible previous instances */ + /* LPSTR lpszCmdLine; long pointer to exec command line */ + /* int nCmdShow; Show code for main window display */ + /***********************************************************************/ + + MSG msg; + char szBuf[MAX_BUF]; + int iRv = WIZ_OK; + HWND hwndFW; + + if(!hPrevInstance) + { + hInst = GetModuleHandle(NULL); + if(InitUninstallGeneral()) + PostQuitMessage(1); + else if(ParseCommandLine(lpszCmdLine)) + PostQuitMessage(1); + else if((hwndFW = FindWindow(CLASS_NAME_UNINSTALL_DLG, NULL)) != NULL && !gbAllowMultipleInstalls) + { + /* Allow only one instance of setup to run. + * Detect a previous instance of setup, bring it to the + * foreground, and quit current instance */ + + ShowWindow(hwndFW, SW_RESTORE); + SetForegroundWindow(hwndFW); + iRv = WIZ_SETUP_ALREADY_RUNNING; + PostQuitMessage(1); + } + else if(Initialize(hInst)) + { + PostQuitMessage(1); + } + else if(!InitApplication(hInst)) + { + char szEFailed[MAX_BUF]; + + if(NS_LoadString(hInst, IDS_ERROR_FAILED, szEFailed, MAX_BUF) == WIZ_OK) + { + wsprintf(szBuf, szEFailed, "InitApplication()."); + PrintError(szBuf, ERROR_CODE_SHOW); + } + PostQuitMessage(1); + } + else if(ParseUninstallIni()) + { + PostQuitMessage(1); + } + else if(ugUninstall.bUninstallFiles == TRUE) + { + if(diUninstall.bShowDialog == TRUE) + hDlgUninstall = InstantiateDialog(hWndMain, DLG_UNINSTALL, diUninstall.szTitle, DlgProcUninstall); + // Assumes that SHOWICONS, HIDEICONS, and SETDEFAULT never show dialogs + else if((ugUninstall.mode == SHOWICONS) || (ugUninstall.mode == HIDEICONS)) + ParseDefaultsInfo(); + else if(ugUninstall.mode == SETDEFAULT) + SetDefault(); + else + ParseAllUninstallLogs(); + } + } + + if((ugUninstall.bUninstallFiles == TRUE) && (diUninstall.bShowDialog == TRUE)) + { + while(GetMessage(&msg, NULL, 0, 0)) + { + if((!IsDialogMessage(hDlgUninstall, &msg)) && (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + /* garbage collection */ + DeInitUninstallGeneral(); + if(iRv != WIZ_SETUP_ALREADY_RUNNING) + /* Do clean up before exiting from the application */ + DeInitialize(); + + return(msg.wParam); +} /* End of WinMain */ + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.h b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.h new file mode 100644 index 00000000000..5cecddce638 --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.h @@ -0,0 +1,179 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Sean Su + */ + +#ifndef _SETUP_H_ +#define _SETUP_H_ + +#ifdef __cplusplus +#define PR_BEGIN_EXTERN_C extern "C" { +#define PR_END_EXTERN_C } +#else +#define PR_BEGIN_EXTERN_C +#define PR_END_EXTERN_C +#endif + +#define PR_EXTERN(type) type + +typedef unsigned int PRUint32; +typedef int PRInt32; + +#include +#include +#include +#include +#include +#include +#include +#include +#include "resource.h" + +#define CLASS_NAME "Uninstall" +#define CLASS_NAME_UNINSTALL_DLG "MozillaSetupDlg" +#define FILE_INI_UNINSTALL "uninstall.ini" +#define FILE_LOG_INSTALL "install_wizard.log" +#define WIZ_TEMP_DIR "ns_temp" + +#define MAX_KILL_PROCESS_RETRIES 10 + +/* WTD: What To Do */ +#define WTD_ASK 0 +#define WTD_CANCEL 1 +#define WTD_NO 2 +#define WTD_NO_TO_ALL 3 +#define WTD_YES 4 +#define WTD_YES_TO_ALL 5 + +/* WS: WinSpawn wait values */ +#define WS_DO_NOT_WAIT FALSE +#define WS_WAIT TRUE + +/* CI: Check Instance */ +#define CI_FORCE_QUIT_PROCESS TRUE +#define CI_CLOSE_PROCESS FALSE + +/* PP: Parse Path */ +#define PP_FILENAME_ONLY 1 +#define PP_PATH_ONLY 2 +#define PP_ROOT_ONLY 3 + +#define MAX_BUF 4096 +#define MAX_BUF_TINY 256 +#define ERROR_CODE_HIDE 0 +#define ERROR_CODE_SHOW 1 +#define CX_CHECKBOX 13 +#define CY_CHECKBOX 13 + +/* WIZ: WIZARD defines */ +#define WIZ_OK 0 +#define WIZ_ERROR_UNDEFINED 1024 +#define WIZ_MEMORY_ALLOC_FAILED 1025 +#define WIZ_OUT_OF_MEMORY WIZ_MEMORY_ALLOC_FAILED +#define WIZ_ARCHIVES_MISSING 1026 +#define WIZ_CRC_PASS WIZ_OK +#define WIZ_CRC_FAIL 1028 +#define WIZ_SETUP_ALREADY_RUNNING 1029 +#define WIZ_TOO_MANY_NETWORK_ERRORS 1030 +#define WIZ_ERROR_PARSING_INTERNAL_STR 1031 +#define WIZ_ERROR_REGKEY 1032 +#define WIZ_ERROR_INIT 1033 +#define WIZ_ERROR_LOADING_RESOURCE_LIB 1034 +#define WIZ_FILE_NOT_FOUND 1035 +#define WIZ_ERROR_PARSING_UNINST_STRS 1036 + +/* CMI: Cleanup Mail Integration */ +#define CMI_OK 0 +#define CMI_APP_PATHNAME_NOT_FOUND 1 + +/* FO: File Operation */ +#define FO_OK 0 +#define FO_SUCCESS 0 +#define FO_ERROR_FILE_NOT_FOUND 1 +#define FO_ERROR_DESTINATION_CONFLICT 2 +#define FO_ERROR_CHANGE_DIR 3 + +/* Mode of Setup to run in */ +#define NOT_SET -1 +#define NORMAL 0 +#define SILENT 1 +#define AUTO 2 +#define SHOWICONS 3 +#define HIDEICONS 4 +#define SETDEFAULT 5 + +/* OS: Operating System */ +#define OS_WIN9x 0x00000001 +#define OS_WIN95_DEBUTE 0x00000002 +#define OS_WIN95 0x00000004 +#define OS_WIN98 0x00000008 +#define OS_NT 0x00000010 +#define OS_NT3 0x00000020 +#define OS_NT4 0x00000040 +#define OS_NT5 0x00000080 +#define OS_NT50 0x00000100 +#define OS_NT51 0x00000200 + +typedef struct dlgUninstall +{ + BOOL bShowDialog; + LPSTR szTitle; + LPSTR szMessage0; +} diU; + +typedef struct uninstallStruct +{ + int mode; + LPSTR szAppPath; + LPSTR szLogPath; + LPSTR szLogFilename; + LPSTR szCompanyName; + LPSTR szProductName; + LPSTR szDescription; + LPSTR szUninstallKeyDescription; + LPSTR szUninstallFilename; + HKEY hWrMainRoot; + LPSTR szWrMainKey; + HKEY hWrRoot; + LPSTR szWrKey; + LPSTR szUserAgent; + LPSTR szDefaultComponent; + LPSTR szClientAppID; + LPSTR szClientAppPath; + BOOL bVerbose; + BOOL bUninstallFiles; + BOOL bSharedInst; + HFONT definedFont; + char szInstallPath[MAX_BUF]; +} uninstallGen; + +typedef struct sInfoLine sil; +struct sInfoLine +{ + ULONGLONG ullLineNumber; + LPSTR szLine; + sil *Next; + sil *Prev; +}; + +#endif + diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.ico b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.ico new file mode 100644 index 0000000000000000000000000000000000000000..f8acc71c2506733106ec3a9f48c16fbb7e52b064 GIT binary patch literal 1078 zcmb7@v5wm?42J1T0BbnZd4pss@)qYIK$bp?hXT?T7B^T!0rzpbMR&8&zQO@rI&?75 zAptt5AC+@aq*oMW@{9UKQX~~dq>>xiY*u3O^+x11dbPUnZ6)$*A+qIc16okYl2t_U zeOVME7S)SlWh*Hqv>9^wO3t*+1$b5sYfm#q~SW6zx-MnAPy86^kp>FbcC#0S^w5PV185+9WKQ}1%_9MMBiVusE* zS;q@^6P>?@K6BoFP@^*^b^ z^_EL)@;6|f^ThsTQDz(qGhGxb+y9#LCact;BRNCMz%|)(p~&s%g?T~mUCkWbjyq>B zI^?&!R`)2zQeb2_*46EAMMMo%)-{0#RZ_YWfPcpT+Ft`)%J NmvHt0OjkI=e*(b)OYQ&w literal 0 HcmV?d00001 diff --git a/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.rc b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.rc new file mode 100644 index 00000000000..2f52d4f3d3f --- /dev/null +++ b/toolkit/mozapps/installer/windows/wizard/uninstall/uninstall.rc @@ -0,0 +1,171 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,2 + PRODUCTVERSION 1,0,0,2 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "mozilla.org\0" + VALUE "FileDescription", "uninstall\0" + VALUE "FileVersion", "1, 0, 0, 2\0" + VALUE "InternalName", "uninstall\0" + VALUE "LegalCopyright", "Copyright © 2001\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "uninstall.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Mozilla uninstaller\0" + VALUE "ProductVersion", "1, 0, 0, 2\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_UNINSTALL ICON DISCARDABLE "uninstall.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +DLG_UNINSTALL DIALOG DISCARDABLE 51, 56, 225, 79 +STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CLASS "MozillaSetupDlg" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",IDWIZNEXT,54,55,53,14 + PUSHBUTTON "",IDCANCEL,118,55,53,14 + LTEXT "",IDC_MESSAGE0,17,11,191,32,NOT WS_GROUP +END + +DLG_MESSAGE DIALOG DISCARDABLE 0, 0, 236, 34 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE +FONT 8, "MS Sans Serif" +BEGIN + CTEXT "",IDC_MESSAGE,0,0,236,34,SS_CENTERIMAGE +END + +DLG_WHAT_TO_DO DIALOG DISCARDABLE 51, 56, 333, 140 +STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "",ID_NO,40,108,53,14 + PUSHBUTTON "",ID_NO_TO_ALL,107,108,53,14 + PUSHBUTTON "",ID_YES,174,108,53,14 + PUSHBUTTON "",ID_YES_TO_ALL,241,108,53,14 + LTEXT "",IDC_MESSAGE0,16,13,301,33,NOT WS_GROUP + LTEXT "",IDC_MESSAGE1,16,50,301,19,NOT WS_GROUP + RTEXT "",IDC_STATIC,18,81,41,8 + LTEXT "Static",IDC_STATIC_SHARED_FILENAME,66,79,251,14, + SS_CENTERIMAGE | SS_SUNKEN +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ERROR_DLL_LOAD "Could not load %s" + IDS_ERROR_STRING_LOAD "Could not load string resource ID %d" + IDS_ERROR_STRING_NULL "Null pointer encountered." + IDS_ERROR_GLOBALALLOC "Memory allocation error." +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED +