mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-15 04:00:12 +01:00
9330 lines
306 KiB
C
9330 lines
306 KiB
C
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** 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 client code, released
|
|
* March 31, 1998.
|
|
*
|
|
* 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 <ssu@netscape.com>
|
|
* Curt Patrick <curt@netscape.com>
|
|
* Ben Goodger <ben@mozilla.org>
|
|
*
|
|
* 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 "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 <logkeys.h>
|
|
#include <winnls.h>
|
|
#include <winver.h>
|
|
|
|
// shellapi.h is needed to build with WIN32_LEAN_AND_MEAN
|
|
#include <shellapi.h>
|
|
|
|
#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 UpdateGREInstallProgress(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);
|
|
}
|
|
|
|
/* Function: RemoveDelayedDeleteFileEntries()
|
|
*
|
|
* in: const char *aPathToMatch - path to match against
|
|
*
|
|
* purpose: To remove windows registry entries (normally set by the uninstaller)
|
|
* that dictates what files to remove at system remove.
|
|
* The windows registry key that will be parsed is:
|
|
*
|
|
* key : HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager
|
|
* name: PendingFileRenameOperations
|
|
*
|
|
* This will not remove any entries that are set to be 'renamed'
|
|
* at system remove, only to be 'deleted'.
|
|
*
|
|
* This function is multibyte safe.
|
|
*
|
|
* To see what format the value of the var is in, look up the win32 API:
|
|
* MoveFileEx()
|
|
*/
|
|
void RemoveDelayedDeleteFileEntries(const char *aPathToMatch)
|
|
{
|
|
HKEY hkResult;
|
|
DWORD dwErr;
|
|
DWORD dwType = REG_NONE;
|
|
DWORD oldMaxValueLen = 0;
|
|
DWORD newMaxValueLen = 0;
|
|
DWORD lenToEnd = 0;
|
|
char *multiStr = NULL;
|
|
const char key[] = "SYSTEM\\CurrentControlSet\\Control\\Session Manager";
|
|
const char name[] = "PendingFileRenameOperations";
|
|
char *pathToMatch;
|
|
char *lcName;
|
|
char *pName;
|
|
char *pRename;
|
|
int nameLen, renameLen;
|
|
|
|
assert(aPathToMatch);
|
|
|
|
/* if not NT systems (win2k, winXP) return */
|
|
if (!(gSystemInfo.dwOSType & OS_NT))
|
|
return;
|
|
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ|KEY_WRITE, &hkResult) != ERROR_SUCCESS)
|
|
return;
|
|
|
|
dwErr = RegQueryValueEx(hkResult, name, 0, &dwType, NULL, &oldMaxValueLen);
|
|
if (dwErr != ERROR_SUCCESS || oldMaxValueLen == 0 || dwType != REG_MULTI_SZ)
|
|
{
|
|
/* no value, no data, or wrong type */
|
|
return;
|
|
}
|
|
|
|
multiStr = calloc(oldMaxValueLen, sizeof(BYTE));
|
|
if (!multiStr)
|
|
return;
|
|
|
|
pathToMatch = strdup(aPathToMatch);
|
|
if (!pathToMatch)
|
|
{
|
|
free(multiStr);
|
|
return;
|
|
}
|
|
|
|
if (RegQueryValueEx(hkResult, name, 0, NULL, multiStr, &oldMaxValueLen) == ERROR_SUCCESS)
|
|
{
|
|
// The registry value consists of name/newname pairs of null-terminated
|
|
// strings, with a final extra null termination. We're only interested
|
|
// in files to be deleted, which are indicated by a null newname.
|
|
CharLower(pathToMatch);
|
|
lenToEnd = newMaxValueLen = oldMaxValueLen;
|
|
pName = multiStr;
|
|
while(*pName && lenToEnd > 0)
|
|
{
|
|
// find the locations and lengths of the current pair. Count the
|
|
// nulls, we need to know how much data to skip or move
|
|
nameLen = strlen(pName) + 1;
|
|
pRename = pName + nameLen;
|
|
renameLen = strlen(pRename) + 1;
|
|
|
|
// How much remains beyond the current pair
|
|
lenToEnd -= (nameLen + renameLen);
|
|
|
|
if (*pRename == '\0')
|
|
{
|
|
// No new name, it's a delete. Is it the one we want?
|
|
lcName = strdup(pName);
|
|
if (lcName)
|
|
{
|
|
CharLower(lcName);
|
|
if (strstr(lcName, pathToMatch))
|
|
{
|
|
// It's a match--
|
|
// delete this pair by moving the remainder on top
|
|
memmove(pName, pRename + renameLen, lenToEnd);
|
|
|
|
// update the total length to reflect the missing pair
|
|
newMaxValueLen -= (nameLen + renameLen);
|
|
|
|
// next pair is in place, continue w/out moving pName
|
|
free(lcName);
|
|
continue;
|
|
}
|
|
free(lcName);
|
|
}
|
|
}
|
|
// on to the next pair
|
|
pName = pRename + renameLen;
|
|
}
|
|
|
|
if (newMaxValueLen != oldMaxValueLen)
|
|
{
|
|
// We've deleted something, save the changed data
|
|
RegSetValueEx(hkResult, name, 0, REG_MULTI_SZ, multiStr, newMaxValueLen);
|
|
RegFlushKey(hkResult);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkResult);
|
|
free(multiStr);
|
|
free(pathToMatch);
|
|
}
|
|
|
|
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((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);
|
|
}
|
|
|
|
static char szFileIniConfig[MAX_BUF];
|
|
|
|
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);
|
|
}
|
|
|
|
DWORD
|
|
GetConfigIniProfileString(const char *aSection, const char *aKey,
|
|
const char *aDefault, char *aResult, DWORD aMaxLen)
|
|
{
|
|
DWORD length;
|
|
|
|
char *c;
|
|
|
|
char *varend;
|
|
DWORD varlen;
|
|
char* replacevalue = (char*) _alloca(aMaxLen);
|
|
DWORD replacelen;
|
|
|
|
length = GetPrivateProfileString(aSection, aKey, aDefault,
|
|
aResult, aMaxLen, szFileIniConfig);
|
|
|
|
// loop through the string looking for {VAR}, to replace with [Messages]
|
|
// from install.ini
|
|
c = aResult;
|
|
|
|
while (*c) {
|
|
if (*c == '{') {
|
|
varend = ++c;
|
|
// c is now the beginning of VAR
|
|
|
|
while (*varend != '}') {
|
|
if (*varend == '\0') {
|
|
// This is malformed, as we found a { without a }
|
|
// but we don't have a way to assert, so we just return.
|
|
return length;
|
|
}
|
|
|
|
++varend;
|
|
}
|
|
|
|
// varlen is the length of {VAR} with the braces.
|
|
varlen = varend - c + 2;
|
|
|
|
if (varlen > 2) {
|
|
*varend = '\0';
|
|
|
|
// In order to honor aMaxLen, cap the length of the replacement value.
|
|
replacelen =
|
|
GetPrivateProfileString("Messages", c, c,
|
|
replacevalue, aMaxLen - length + varlen,
|
|
szFileIniInstall);
|
|
|
|
if (replacelen != varlen) {
|
|
// Move the end of the buffer forward/back to compensate for
|
|
// the difference in length.
|
|
memmove(c + replacelen - 1, varend + 1, (aResult + length) - varend);
|
|
length += replacelen - varlen;
|
|
}
|
|
|
|
// copy the replacevalue over the {VAR}
|
|
memcpy(c - 1, replacevalue, replacelen);
|
|
|
|
c += replacelen - 1;
|
|
}
|
|
else {
|
|
// If we encountered a plain {}, just advance the outer loop.
|
|
// This should really be an assertion.
|
|
c = varend + 1;
|
|
}
|
|
}
|
|
else {
|
|
++c;
|
|
}
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
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);
|
|
|
|
GetConfigIniProfileString("Redirect", "Status", "",
|
|
szBuf, sizeof(szBuf));
|
|
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 */
|
|
GetConfigIniProfileString("General", "url", "",
|
|
szUrl, sizeof(szUrl));
|
|
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 */
|
|
GetConfigIniProfileString("General", "url", "",
|
|
szUrl, sizeof(szUrl));
|
|
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 */
|
|
GetConfigIniProfileString("General", "url", "",
|
|
szUrl, sizeof(szUrl));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Redirect", "Status", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Redirect", "Description", "", szBuf, sizeof(szBuf));
|
|
WritePrivateProfileString("File0", "desc", szBuf, szFileIdiGetRedirect);
|
|
GetConfigIniProfileString("Redirect", "Server Path", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Strings", "Message Verifying Archives", "", szMsgCRCCheck, sizeof(szMsgCRCCheck));
|
|
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);
|
|
GetConfigIniProfileString("Strings", "Error Too Many CRC Failures", "", szMsg, sizeof(szMsg));
|
|
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';
|
|
GetConfigIniProfileString(aSectionName, keyName, "", buf, sizeof(buf));
|
|
while(*buf != '\0')
|
|
{
|
|
++index;
|
|
_snprintf(keyName, sizeof(keyName), "%s%d", aBaseKeyName, index);
|
|
keyName[sizeof(keyName) - 1] = '\0';
|
|
GetConfigIniProfileString(aSectionName, keyName, "", buf, sizeof(buf));
|
|
}
|
|
|
|
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';
|
|
GetConfigIniProfileString(aSectionName, keyName, "", buf, sizeof(buf));
|
|
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)
|
|
{
|
|
GetConfigIniProfileString("Strings", "Message Cleanup On Upgrade Windir", "",
|
|
buf, sizeof(buf));
|
|
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((WIZ_OK == rv) && (siCFXpcomFile.bStatus == STATUS_ENABLED))
|
|
rv = ProcessXpcomFile();
|
|
|
|
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->szMessageWelcome = 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);
|
|
if((diDialog->szMessage3 = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgWelcome(diW *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szMessageWelcome));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
FreeMemory(&(diDialog->szMessage1));
|
|
FreeMemory(&(diDialog->szMessage2));
|
|
FreeMemory(&(diDialog->szMessage3));
|
|
}
|
|
|
|
HRESULT InitDlgLicense(diL *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szSubTitle = 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->szRadioAccept = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szRadioDecline = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgLicense(diL *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szLicenseFilename));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
FreeMemory(&(diDialog->szRadioAccept));
|
|
FreeMemory(&(diDialog->szRadioDecline));
|
|
}
|
|
|
|
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->szSubTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
diDialog->stSetupType0.dwCItems = 0;
|
|
diDialog->stSetupType1.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);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgSetupType(diST *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
|
|
FreeMemory(&(diDialog->stSetupType0.szDescriptionShort));
|
|
FreeMemory(&(diDialog->stSetupType0.szDescriptionLong));
|
|
FreeMemory(&(diDialog->stSetupType1.szDescriptionShort));
|
|
FreeMemory(&(diDialog->stSetupType1.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->szSubTitle = 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->szSubTitle));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
}
|
|
|
|
HRESULT InitDlgSelectInstallPath(diSIP *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
|
|
/* set to show the Single dialog or the Multi dialog for the SelectComponents dialog */
|
|
if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szSubTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgSelectInstallPath(diSIP *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
}
|
|
|
|
HRESULT InitDlgUpgrade(diU *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
diDialog->bShowInEasyInstall = FALSE;
|
|
|
|
/* set to show the Single dialog or the Multi dialog for the SelectComponents dialog */
|
|
if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szSubTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szMessageCleanup = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szCheckboxSafeInstall = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szSafeInstallInfo = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szUnsafeInstallInfo = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szNoSafeUpgradeWindir = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgUpgrade(diU *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szMessageCleanup));
|
|
FreeMemory(&(diDialog->szCheckboxSafeInstall));
|
|
FreeMemory(&(diDialog->szSafeInstallInfo));
|
|
FreeMemory(&(diDialog->szUnsafeInstallInfo));
|
|
FreeMemory(&(diDialog->szNoSafeUpgradeWindir));
|
|
}
|
|
|
|
HRESULT InitDlgWindowsIntegration(diWI *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
exit(1);
|
|
if((diDialog->szSubTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
exit(1);
|
|
if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
exit(1);
|
|
if((diDialog->szRegistryKey = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
exit(1);
|
|
|
|
diDialog->wiCB0.bEnabled = FALSE;
|
|
diDialog->wiCB1.bEnabled = FALSE;
|
|
diDialog->wiCB2.bEnabled = FALSE;
|
|
|
|
diDialog->wiCB0.bCheckBoxState = FALSE;
|
|
diDialog->wiCB1.bCheckBoxState = FALSE;
|
|
diDialog->wiCB2.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->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);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgWindowsIntegration(diWI *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
FreeMemory(&(diDialog->szRegistryKey));
|
|
|
|
FreeMemory(&(diDialog->wiCB0.szDescription));
|
|
FreeMemory(&(diDialog->wiCB1.szDescription));
|
|
FreeMemory(&(diDialog->wiCB2.szDescription));
|
|
FreeMemory(&(diDialog->wiCB0.szArchive));
|
|
FreeMemory(&(diDialog->wiCB1.szArchive));
|
|
FreeMemory(&(diDialog->wiCB2.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->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->szSubTitle = 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);
|
|
if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgStartInstall(diSI *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szMessageInstall));
|
|
FreeMemory(&(diDialog->szMessageDownload));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
}
|
|
|
|
HRESULT InitDlgDownloading(diDL *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szSubTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szBlurb = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szFileNameKey = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szTimeRemainingKey = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgDownloading(diDL *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szBlurb));
|
|
FreeMemory(&(diDialog->szFileNameKey));
|
|
FreeMemory(&(diDialog->szTimeRemainingKey));
|
|
}
|
|
|
|
HRESULT InitDlgInstalling(diI *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szSubTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szBlurb = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szStatusFile = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szStatusComponent = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void DeInitDlgInstalling(diI *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szSubTitle));
|
|
FreeMemory(&(diDialog->szBlurb));
|
|
FreeMemory(&(diDialog->szStatusFile));
|
|
FreeMemory(&(diDialog->szStatusComponent));
|
|
}
|
|
|
|
HRESULT InitDlgInstallSuccessful(diIS *diDialog)
|
|
{
|
|
diDialog->bShowDialog = FALSE;
|
|
diDialog->bLaunchAppChecked = 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);
|
|
if((diDialog->szLaunchApp = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szRegistryKey = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
if((diDialog->szMessageHeader = NS_GlobalAlloc(MAX_BUF)) == NULL)
|
|
return(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void DeInitDlgInstallSuccessful(diIS *diDialog)
|
|
{
|
|
FreeMemory(&(diDialog->szTitle));
|
|
FreeMemory(&(diDialog->szMessage0));
|
|
FreeMemory(&(diDialog->szMessage1));
|
|
FreeMemory(&(diDialog->szLaunchApp));
|
|
FreeMemory(&(diDialog->szRegistryKey));
|
|
FreeMemory(&(diDialog->szMessageHeader));
|
|
}
|
|
|
|
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 = TRUE;
|
|
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.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.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];
|
|
|
|
GetConfigIniProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf));
|
|
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];
|
|
|
|
GetConfigIniProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf));
|
|
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];
|
|
|
|
GetConfigIniProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
GetConfigIniProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection));
|
|
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);
|
|
GetConfigIniProfileString(szOverrideSection, "Attributes", "", szOverrideAttributes, sizeof(szOverrideAttributes));
|
|
|
|
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. */
|
|
|
|
GetConfigIniProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf));
|
|
siCNode->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE);
|
|
if(*szOverrideAttributes != '\0')
|
|
siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE);
|
|
}
|
|
}
|
|
|
|
++dwIndex0;
|
|
wsprintf(szComponentKey, "C%d", dwIndex0);
|
|
GetConfigIniProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection));
|
|
}
|
|
}
|
|
|
|
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, "MAIN_COMPONENT"))
|
|
dwAttributes |= SIC_MAIN_COMPONENT;
|
|
}
|
|
|
|
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));
|
|
GetConfigIniProfileString(siCObject->szReferenceName, szKey, "", szForceUpgradeFile, sizeof(szForceUpgradeFile));
|
|
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));
|
|
GetConfigIniProfileString(siCObject->szReferenceName, szKey, "", szForceUpgradeFile, sizeof(szForceUpgradeFile));
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
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);
|
|
GetConfigIniProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection));
|
|
while(*szComponentSection != '\0')
|
|
{
|
|
GetConfigIniProfileString(szComponentSection, "Archive", "", szBuf, sizeof(szBuf));
|
|
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 */
|
|
GetConfigIniProfileString(szComponentSection, "Archive Uncompressed", "",
|
|
siCTemp->szArchiveNameUncompressed, sizeof(szBuf));
|
|
|
|
/* get short description of component */
|
|
GetConfigIniProfileString(szComponentSection, "Description Short", "", szBuf, sizeof(szBuf));
|
|
lstrcpy(siCTemp->szDescriptionShort, szBuf);
|
|
|
|
/* get long description of component */
|
|
GetConfigIniProfileString(szComponentSection, "Description Long", "", szBuf, sizeof(szBuf));
|
|
lstrcpy(siCTemp->szDescriptionLong, szBuf);
|
|
|
|
/* get commandline parameter for component */
|
|
GetConfigIniProfileString(szComponentSection, "Parameter", "", siCTemp->szParameter, MAX_BUF);
|
|
|
|
/* set reference name for component */
|
|
lstrcpy(siCTemp->szReferenceName, szComponentSection);
|
|
|
|
/* get install size required in destination for component. Sould be in Kilobytes */
|
|
GetConfigIniProfileString(szComponentSection, "Install Size", "", szBuf, sizeof(szBuf));
|
|
if(*szBuf != '\0')
|
|
siCTemp->ullInstallSize = _atoi64(szBuf);
|
|
else
|
|
siCTemp->ullInstallSize = 0;
|
|
|
|
/* get install size required in system for component. Sould be in Kilobytes */
|
|
GetConfigIniProfileString(szComponentSection, "Install Size System", "", szBuf, sizeof(szBuf));
|
|
if(*szBuf != '\0')
|
|
siCTemp->ullInstallSizeSystem = _atoi64(szBuf);
|
|
else
|
|
siCTemp->ullInstallSizeSystem = 0;
|
|
|
|
/* get install size required in temp for component. Sould be in Kilobytes */
|
|
GetConfigIniProfileString(szComponentSection, "Install Size Archive", "", szBuf, sizeof(szBuf));
|
|
if(*szBuf != '\0')
|
|
siCTemp->ullInstallSizeArchive = _atoi64(szBuf);
|
|
else
|
|
siCTemp->ullInstallSizeArchive = 0;
|
|
|
|
/* get attributes of component */
|
|
GetConfigIniProfileString(szComponentSection, "Attributes", "", szBuf, sizeof(szBuf));
|
|
siCTemp->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE);
|
|
|
|
/* get the component's file count */
|
|
GetConfigIniProfileString(szComponentSection, "FileCount", "", szBuf, sizeof(szBuf));
|
|
siCTemp->iFileCount = atoi(szBuf);
|
|
|
|
/* get the random percentage value and select or deselect the component (by default) for
|
|
* installation */
|
|
GetConfigIniProfileString(szComponentSection, "Random Install Percentage", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
GetConfigIniProfileString(szComponentSection, szDependency, "", szBuf, sizeof(szBuf));
|
|
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);
|
|
GetConfigIniProfileString(szComponentSection, szDependency, "", szBuf, sizeof(szBuf));
|
|
}
|
|
|
|
/* get all dependees for this component */
|
|
dwIndex1 = 0;
|
|
itoa(dwIndex1, szIndex1, 10);
|
|
lstrcpy(szDependee, "Dependee");
|
|
lstrcat(szDependee, szIndex1);
|
|
GetConfigIniProfileString(szComponentSection, szDependee, "", szBuf, sizeof(szBuf));
|
|
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);
|
|
GetConfigIniProfileString(szComponentSection, szDependee, "", szBuf, sizeof(szBuf));
|
|
}
|
|
|
|
// 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);
|
|
GetConfigIniProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection));
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
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);
|
|
GetConfigIniProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription));
|
|
while(*szDescription != '\0')
|
|
{
|
|
/* if the Domain and Identifier are not set, then skip */
|
|
GetConfigIniProfileString("Site Selector", szKDomain, "", szDomain, sizeof(szDomain));
|
|
GetConfigIniProfileString("Site Selector", szKIdentifier, "", szIdentifier, sizeof(szIdentifier));
|
|
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));
|
|
GetConfigIniProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription));
|
|
}
|
|
}
|
|
|
|
void InitErrorMessageStream()
|
|
{
|
|
char szBuf[MAX_BUF_TINY];
|
|
|
|
GetConfigIniProfileString("Message Stream", "Status", "",
|
|
szBuf, sizeof(szBuf));
|
|
|
|
if(lstrcmpi(szBuf, "disabled") == 0)
|
|
gErrorMessageStream.bEnabled = FALSE;
|
|
else
|
|
gErrorMessageStream.bEnabled = TRUE;
|
|
|
|
GetConfigIniProfileString("Message Stream", "url", "",
|
|
gErrorMessageStream.szURL, sizeof(gErrorMessageStream.szURL));
|
|
|
|
GetConfigIniProfileString("Message Stream", "Show Confirmation", "",
|
|
szBuf, sizeof(szBuf));
|
|
if(strcmpi(szBuf, "FALSE") == 0)
|
|
gErrorMessageStream.bShowConfirmation = FALSE;
|
|
else
|
|
gErrorMessageStream.bShowConfirmation = TRUE;
|
|
|
|
GetConfigIniProfileString("Message Stream", "Confirmation Message", "",
|
|
gErrorMessageStream.szConfirmationMessage, sizeof(szBuf));
|
|
|
|
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);
|
|
}
|
|
|
|
GetConfigIniProfileString("Strings", "UsageMsg Usage", "", szBuf, sizeof(szBuf));
|
|
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 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);
|
|
GetConfigIniProfileString(szSection, szExtraCmdKey, "",
|
|
szKey, sizeof(szKey));
|
|
if(*szKey == '\0')
|
|
{
|
|
bContinue = FALSE;
|
|
continue;
|
|
}
|
|
|
|
/* Read the win reg root key */
|
|
wsprintf(szExtraCmdKey, "%s%d Reg Key Root", szExtraCmd, dwCounter);
|
|
GetConfigIniProfileString(szSection, szExtraCmdKey, "",
|
|
szBuf, sizeof(szBuf));
|
|
if(*szBuf == '\0')
|
|
{
|
|
bContinue = FALSE;
|
|
continue;
|
|
}
|
|
hkeyRoot = ParseRootKey(szBuf);
|
|
|
|
/* Read the win reg name value */
|
|
wsprintf(szExtraCmdKey, "%s%d Reg Name", szExtraCmd, dwCounter);
|
|
GetConfigIniProfileString(szSection, szExtraCmdKey, "",
|
|
szName, sizeof(szName));
|
|
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);
|
|
GetConfigIniProfileString(szSection, szExtraCmdKey, "",
|
|
szParameter, sizeof(szParameter));
|
|
|
|
/* 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';
|
|
|
|
GetConfigIniProfileString(aSection, "Message", "", aMessage, aMessageBufSize);
|
|
GetConfigIniProfileString(aSection, "Message Full Installer", "", messageFullInstaller, sizeof(messageFullInstaller));
|
|
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);
|
|
GetConfigIniProfileString(section, "Process Name", "", processName, sizeof(processName));
|
|
GetConfigIniProfileString(section, "Pretty Name", "", prettyName, sizeof(prettyName));
|
|
GetConfigIniProfileString(section, "Message Wait", "", msgWait, sizeof(msgWait));
|
|
GetConfigIniProfileString(section, "Close All Process Windows", "", closeAllWindows, sizeof(closeAllWindows));
|
|
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 = GetConfigIniProfileString(section, "Class Name", "", className, sizeof(className));
|
|
dwRv1 = GetConfigIniProfileString(section, "Window Name", "", windowName, sizeof(windowName));
|
|
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);
|
|
|
|
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));
|
|
GetConfigIniProfileString("Strings", "Message Verifying Archives", "", szMsgCRCCheck, sizeof(szMsgCRCCheck));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Strings", "Error Corrupted Archives Detected", "", szBuf, sizeof(szBuf));
|
|
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:
|
|
GetConfigIniProfileString("Strings", "Error Corrupted Archives Detected AUTO mode", "", szBuf, sizeof(szBuf));
|
|
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(InitDlgSelectInstallPath(&diSelectInstallPath))
|
|
return(1);
|
|
if(InitDlgUpgrade(&diUpgrade))
|
|
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(InitDlgDownloading(&diDownloading))
|
|
return(1);
|
|
if(InitDlgInstalling(&diInstalling))
|
|
return(1);
|
|
if(InitDlgInstallSuccessful(&diInstallSuccessful))
|
|
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 */
|
|
GetConfigIniProfileString("General", "Run Mode", "", szBuf, sizeof(szBuf));
|
|
SetSetupRunMode(szBuf);
|
|
|
|
/* find out if we are doing a shared install */
|
|
GetConfigIniProfileString("General", "Shared Install", "", szBuf, sizeof(szBuf));
|
|
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) */
|
|
GetConfigIniProfileString("Cleanup On Upgrade", "Cleanup", "", szBuf, sizeof(szBuf));
|
|
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')
|
|
GetConfigIniProfileString("General", "Default AppID", "", sgProduct.szAppID, MAX_BUF);
|
|
|
|
if(GetPrivateProfileString("Messages", "MSG_INIT_SETUP", "", szMsgInitSetup, sizeof(szMsgInitSetup), szFileIniInstall))
|
|
ShowMessage(szMsgInitSetup, TRUE);
|
|
|
|
/* get product name description */
|
|
GetConfigIniProfileString("General", "Company Name", "", sgProduct.szCompanyName, MAX_BUF);
|
|
GetConfigIniProfileString("General", "Product Name", "", sgProduct.szProductName, MAX_BUF);
|
|
GetConfigIniProfileString("General", "Product Name Internal", "", sgProduct.szProductNameInternal, MAX_BUF);
|
|
if (sgProduct.szProductNameInternal[0] == 0)
|
|
lstrcpy(sgProduct.szProductNameInternal, sgProduct.szProductName);
|
|
|
|
GetConfigIniProfileString("General", "Product Name Previous", "", sgProduct.szProductNamePrevious, MAX_BUF);
|
|
GetConfigIniProfileString("General", "User Agent", "", sgProduct.szUserAgent, MAX_BUF);
|
|
GetConfigIniProfileString("General", "Sub Path", "", sgProduct.szSubPath, MAX_BUF);
|
|
GetConfigIniProfileString("General", "Program Name", "", sgProduct.szProgramName, MAX_BUF);
|
|
GetConfigIniProfileString("General", "Lock Path", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Strings", "Message NORMAL Restricted Access", "", szBuf, sizeof(szBuf));
|
|
iRvMB = MessageBox(hWndMain, szBuf, szTitle, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2);
|
|
break;
|
|
|
|
case AUTO:
|
|
ShowMessage(szMsgInitSetup, FALSE);
|
|
GetConfigIniProfileString("Strings", "Message AUTO Restricted Access", "", szBuf, sizeof(szBuf));
|
|
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 */
|
|
|
|
// goats VerifyRestrictedAccess
|
|
if(LocatePreviousPath("Locate Previous Product Path", szPreviousPath, sizeof(szPreviousPath)) == FALSE)
|
|
{
|
|
GetConfigIniProfileString("General", "Path", "", szBuf, sizeof(szBuf));
|
|
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 */
|
|
GetConfigIniProfileString("General", "Path", "", szBuf, sizeof(szBuf));
|
|
DecryptString(sgProduct.szPath, szBuf);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(sgProduct.szPath, szPreviousPath);
|
|
}
|
|
}
|
|
RemoveBackSlash(sgProduct.szPath);
|
|
|
|
/* get main program folder path */
|
|
GetConfigIniProfileString("General", "Program Folder Path", "", szBuf, sizeof(szBuf));
|
|
DecryptString(sgProduct.szProgramFolderPath, szBuf);
|
|
|
|
/* get main program folder name */
|
|
GetConfigIniProfileString("General", "Program Folder Name", "", szBuf, sizeof(szBuf));
|
|
DecryptString(sgProduct.szProgramFolderName, szBuf);
|
|
|
|
GetConfigIniProfileString("General", "Refresh Icons", "", szBuf, sizeof(szBuf));
|
|
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. */
|
|
GetConfigIniProfileString("General", "GRE Type", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "Local") == 0)
|
|
sgProduct.greType = GRE_LOCAL;
|
|
else
|
|
sgProduct.greType = GRE_SHARED;
|
|
}
|
|
|
|
GetConfigIniProfileString("General", "GRE Cleanup Orphans", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "TRUE") == 0)
|
|
sgProduct.greCleanupOrphans = TRUE;
|
|
|
|
GetConfigIniProfileString("General", "GRE Cleanup Orphans Message", "", sgProduct.greCleanupOrphansMessage, sizeof(sgProduct.greCleanupOrphansMessage));
|
|
GetConfigIniProfileString("General", "GRE ID", "", sgProduct.greID, sizeof(sgProduct.greID));
|
|
GetConfigIniProfileString("General", "GRE Private Key", "", szBuf, sizeof(szBuf));
|
|
if(*szBuf != '\0')
|
|
DecryptString(sgProduct.grePrivateKey, szBuf);
|
|
|
|
GetConfigIniProfileString("General", "Show Banner Image", "", szBuf, sizeof(szBuf));
|
|
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 */
|
|
GetConfigIniProfileString("Dialog Welcome", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Welcome", "Title", "", diWelcome.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Welcome", "MessageWelcome", "", diWelcome.szMessageWelcome, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Welcome", "Message0", "", diWelcome.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Welcome", "Message1", "", diWelcome.szMessage1, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Welcome", "Message2", "", diWelcome.szMessage2, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Welcome", "Message3", "", diWelcome.szMessage3, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diWelcome.bShowDialog = TRUE;
|
|
|
|
/* License dialog */
|
|
GetConfigIniProfileString("Dialog License", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog License", "Title", "", diLicense.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog License", "Sub Title", "", diLicense.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog License", "License File", "", diLicense.szLicenseFilename, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog License", "Message0", "", diLicense.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog License", "RadioAccept", "", diLicense.szRadioAccept, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog License", "RadioDecline", "", diLicense.szRadioDecline, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diLicense.bShowDialog = TRUE;
|
|
|
|
/* Setup Type dialog */
|
|
GetConfigIniProfileString("Dialog Setup Type", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Setup Type", "Title", "", diSetupType.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Setup Type", "Sub Title", "", diSetupType.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Setup Type", "Message0", "", diSetupType.szMessage0, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diSetupType.bShowDialog = TRUE;
|
|
|
|
/* Get Setup Types info */
|
|
GetConfigIniProfileString("Setup Type0", "Description Short", "", diSetupType.stSetupType0.szDescriptionShort, MAX_BUF);
|
|
GetConfigIniProfileString("Setup Type0", "Description Long", "", diSetupType.stSetupType0.szDescriptionLong, MAX_BUF);
|
|
STSetVisibility(&diSetupType.stSetupType0);
|
|
|
|
GetConfigIniProfileString("Setup Type1", "Description Short", "", diSetupType.stSetupType1.szDescriptionShort, MAX_BUF);
|
|
GetConfigIniProfileString("Setup Type1", "Description Long", "", diSetupType.stSetupType1.szDescriptionLong, MAX_BUF);
|
|
STSetVisibility(&diSetupType.stSetupType1);
|
|
|
|
/* remember the radio button that is considered the Custom type (the last radio button) */
|
|
SetCustomType();
|
|
|
|
/* Select Components dialog */
|
|
GetConfigIniProfileString("Dialog Select Components", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Select Components", "Title", "", diSelectComponents.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Select Components", "Sub Title", "", diSelectComponents.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Select Components", "Message0", "", diSelectComponents.szMessage0, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diSelectComponents.bShowDialog = TRUE;
|
|
|
|
/* Select Install Folder dialog */
|
|
GetConfigIniProfileString("Dialog Select Install Path", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Select Install Path", "Title", "", diSelectInstallPath.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Select Install Path", "Sub Title", "", diSelectInstallPath.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Select Install Path", "Message0", "", diSelectInstallPath.szMessage0, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diSelectInstallPath.bShowDialog = TRUE;
|
|
|
|
/* Upgrade dialog */
|
|
GetConfigIniProfileString("Dialog Upgrade", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diUpgrade.bShowDialog = TRUE;
|
|
GetConfigIniProfileString("Dialog Upgrade", "Show In Easy Install", "", szShowDialog, sizeof(szShowDialog));
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diUpgrade.bShowInEasyInstall = TRUE;
|
|
GetConfigIniProfileString("Dialog Upgrade", "Title", "", diUpgrade.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Upgrade", "Sub Title", "", diUpgrade.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Upgrade", "Message Cleanup", "", diUpgrade.szMessageCleanup, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Upgrade", "Checkbox Clean Install", "", diUpgrade.szCheckboxSafeInstall, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Upgrade", "Message Clean Install", "", diUpgrade.szSafeInstallInfo, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Upgrade", "Message Install Over", "", diUpgrade.szUnsafeInstallInfo, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Upgrade", "Message Install Over Windir", "", diUpgrade.szNoSafeUpgradeWindir, MAX_BUF);
|
|
|
|
/* Select Additional Components dialog */
|
|
GetConfigIniProfileString("Dialog Select Additional Components", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Select Additional Components", "Title", "", diSelectAdditionalComponents.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Select Additional Components", "Message0", "", diSelectAdditionalComponents.szMessage0, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diSelectAdditionalComponents.bShowDialog = TRUE;
|
|
|
|
/* Windows Integration dialog */
|
|
GetConfigIniProfileString("Dialog Windows Integration", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Windows Integration", "Title", "", diWindowsIntegration.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Windows Integration", "Sub Title", "", diWindowsIntegration.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Windows Integration", "Message0", "", diWindowsIntegration.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Windows Integration", "Registry Key", "", diWindowsIntegration.szRegistryKey, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diWindowsIntegration.bShowDialog = TRUE;
|
|
|
|
GetConfigIniProfileString("Windows Integration-Item0", "CheckBoxState", "", szBuf, sizeof(szBuf));
|
|
GetConfigIniProfileString("Windows Integration-Item0", "Description", "", diWindowsIntegration.wiCB0.szDescription, MAX_BUF);
|
|
GetConfigIniProfileString("Windows Integration-Item0", "Archive", "", diWindowsIntegration.wiCB0.szArchive, MAX_BUF);
|
|
/* 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;
|
|
|
|
GetConfigIniProfileString("Windows Integration-Item1", "CheckBoxState", "", szBuf, sizeof(szBuf));
|
|
GetConfigIniProfileString("Windows Integration-Item1", "Description", "", diWindowsIntegration.wiCB1.szDescription, MAX_BUF);
|
|
GetConfigIniProfileString("Windows Integration-Item1", "Archive", "", diWindowsIntegration.wiCB1.szArchive, MAX_BUF);
|
|
/* 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;
|
|
|
|
GetConfigIniProfileString("Windows Integration-Item2", "CheckBoxState", "", szBuf, sizeof(szBuf));
|
|
GetConfigIniProfileString("Windows Integration-Item2", "Description", "", diWindowsIntegration.wiCB2.szDescription, MAX_BUF);
|
|
GetConfigIniProfileString("Windows Integration-Item2", "Archive", "", diWindowsIntegration.wiCB2.szArchive, MAX_BUF);
|
|
/* 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;
|
|
|
|
/* Program Folder dialog */
|
|
GetConfigIniProfileString("Dialog Program Folder", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Program Folder", "Title", "", diProgramFolder.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Program Folder", "Message0", "", diProgramFolder.szMessage0, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diProgramFolder.bShowDialog = TRUE;
|
|
|
|
/* Additional Options dialog */
|
|
GetConfigIniProfileString("Dialog Additional Options", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Additional Options", "Title", "", diAdditionalOptions.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Additional Options", "Message0", "", diAdditionalOptions.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Additional Options", "Message1", "", diAdditionalOptions.szMessage1, MAX_BUF);
|
|
|
|
GetConfigIniProfileString("Dialog Additional Options", "Save Installer", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "TRUE") == 0)
|
|
diAdditionalOptions.bSaveInstaller = TRUE;
|
|
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diAdditionalOptions.bShowDialog = TRUE;
|
|
|
|
/* Advanced Settings dialog */
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Title", "", diAdvancedSettings.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Message0", "", diAdvancedSettings.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Proxy Server", "", diAdvancedSettings.szProxyServer, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Proxy Port", "", diAdvancedSettings.szProxyPort, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Proxy User", "", diAdvancedSettings.szProxyUser, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Proxy Password", "", diAdvancedSettings.szProxyPasswd, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diAdvancedSettings.bShowDialog = TRUE;
|
|
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Use Protocol", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "HTTP") == 0)
|
|
diAdditionalOptions.dwUseProtocol = UP_HTTP;
|
|
else
|
|
diAdditionalOptions.dwUseProtocol = UP_FTP;
|
|
|
|
GetConfigIniProfileString("Dialog Advanced Settings", "Use Protocol Settings", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "DISABLED") == 0)
|
|
diAdditionalOptions.bUseProtocolSettings = FALSE;
|
|
else
|
|
diAdditionalOptions.bUseProtocolSettings = TRUE;
|
|
|
|
GetConfigIniProfileString("Dialog Advanced Settings",
|
|
"Show Protocols", "",
|
|
szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "FALSE") == 0)
|
|
diAdditionalOptions.bShowProtocols = FALSE;
|
|
else
|
|
diAdditionalOptions.bShowProtocols = TRUE;
|
|
|
|
/* Program Folder dialog */
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Title", "", diQuickLaunch.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Message0", "", diQuickLaunch.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Message1", "", diQuickLaunch.szMessage1, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Message2", "", diQuickLaunch.szMessage2, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diQuickLaunch.bShowDialog = TRUE;
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Turbo Mode", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "TRUE") == 0)
|
|
diQuickLaunch.bTurboMode = TRUE;
|
|
GetConfigIniProfileString("Dialog Quick Launch", "Turbo Mode Enabled","", szBuf, sizeof(szBuf));
|
|
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 */
|
|
GetConfigIniProfileString("Dialog Start Install", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Start Install", "Title", "", diStartInstall.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Start Install", "Sub Title", "", diStartInstall.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Start Install", "Message Install", "", diStartInstall.szMessageInstall, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Start Install", "Message Download", "", diStartInstall.szMessageDownload, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Start Install", "Message0", "", diStartInstall.szMessage0, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diStartInstall.bShowDialog = TRUE;
|
|
|
|
/* Downloading dialog */
|
|
GetConfigIniProfileString("Dialog Downloading", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Downloading", "Title", "", diDownloading.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Downloading", "Sub Title", "", diDownloading.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Downloading", "Message Install", "", diDownloading.szBlurb, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Downloading", "Message Download", "", diDownloading.szFileNameKey, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Downloading", "Message0", "", diDownloading.szTimeRemainingKey, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diDownloading.bShowDialog = TRUE;
|
|
|
|
/* Downloading dialog */
|
|
GetConfigIniProfileString("Dialog Installing", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Installing", "Title", "", diInstalling.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Installing", "Sub Title", "", diInstalling.szSubTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Installing", "Blurb", "", diInstalling.szBlurb, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Installing", "Status File", "", diInstalling.szStatusFile, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Installing", "Status Component", "", diInstalling.szStatusComponent, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diInstalling.bShowDialog = TRUE;
|
|
|
|
// Install Successful page.
|
|
GetConfigIniProfileString("Dialog Install Successful", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diInstallSuccessful.bShowDialog = TRUE;
|
|
GetConfigIniProfileString("Dialog Install Successful", "Title", "", diInstallSuccessful.szTitle, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Install Successful", "MessageHeader", "", diInstallSuccessful.szMessageHeader, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Install Successful", "Message0", "", diInstallSuccessful.szMessage0, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Install Successful", "Message1", "", diInstallSuccessful.szMessage1, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Install Successful", "Launch App", "", diInstallSuccessful.szLaunchApp, MAX_BUF);
|
|
GetConfigIniProfileString("Dialog Install Successful", "Launch App Checked", "", szShowDialog, MAX_BUF);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diInstallSuccessful.bLaunchAppChecked = TRUE;
|
|
GetConfigIniProfileString("Dialog Install Successful", "Registry Key", "", diInstallSuccessful.szRegistryKey, MAX_BUF);
|
|
|
|
/* Download dialog */
|
|
GetConfigIniProfileString("Dialog Download", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
GetConfigIniProfileString("Dialog Download", "Title", "", diDownload.szTitle, MAX_BUF_TINY);
|
|
GetConfigIniProfileString("Dialog Download", "Message Download0", "", diDownload.szMessageDownload0, MAX_BUF_MEDIUM);
|
|
GetConfigIniProfileString("Dialog Download", "Message Retry0", "", diDownload.szMessageRetry0, MAX_BUF_MEDIUM);
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diDownload.bShowDialog = TRUE;
|
|
|
|
/* Reboot dialog */
|
|
GetConfigIniProfileString("Dialog Reboot", "Show Dialog", "", szShowDialog, sizeof(szShowDialog));
|
|
if(lstrcmpi(szShowDialog, "TRUE") == 0)
|
|
diReboot.dwShowDialog = TRUE;
|
|
else if(lstrcmpi(szShowDialog, "AUTO") == 0)
|
|
diReboot.dwShowDialog = AUTO;
|
|
|
|
/* Read in the Site Selector Status */
|
|
GetConfigIniProfileString("Site Selector", "Status", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "HIDE") == 0)
|
|
gdwSiteSelectorStatus = SS_HIDE;
|
|
|
|
switch(sgProduct.mode)
|
|
{
|
|
case AUTO:
|
|
case SILENT:
|
|
diWelcome.bShowDialog = FALSE;
|
|
diLicense.bShowDialog = FALSE;
|
|
diSetupType.bShowDialog = FALSE;
|
|
diSelectInstallPath.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;
|
|
diDownloading.bShowDialog = FALSE;
|
|
diInstallSuccessful.bShowDialog = FALSE;
|
|
diInstallSuccessful.bLaunchAppChecked = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (sgProduct.mode == SILENT)
|
|
diInstalling.bShowDialog = FALSE;
|
|
|
|
|
|
InitSiComponents();
|
|
InitSiteSelector();
|
|
InitErrorMessageStream();
|
|
|
|
/* get Default Setup Type */
|
|
GetConfigIniProfileString("General", "Default Setup Type", "", szBuf, sizeof(szBuf));
|
|
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(diSetupType.stSetupType0.bVisible)
|
|
{
|
|
dwSetupType = ST_RADIO0;
|
|
dwTempSetupType = dwSetupType;
|
|
}
|
|
else if(diSetupType.stSetupType1.bVisible)
|
|
{
|
|
dwSetupType = ST_RADIO1;
|
|
dwTempSetupType = dwSetupType;
|
|
}
|
|
}
|
|
SiCNodeSetItemsSelected(dwSetupType);
|
|
|
|
/* get install size required in temp for component Xpcom. Sould be in Kilobytes */
|
|
GetConfigIniProfileString("Core", "Install Size", "", szBuf, sizeof(szBuf));
|
|
if(*szBuf != '\0')
|
|
siCFXpcomFile.ullInstallSize = _atoi64(szBuf);
|
|
else
|
|
siCFXpcomFile.ullInstallSize = 0;
|
|
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "core_file", "", siSDObject.szXpcomFile, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "core_file_path", "", siSDObject.szXpcomFilePath, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "xpcom_dir", "", siSDObject.szXpcomDir, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "no_ads", "", siSDObject.szNoAds, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "silent", "", siSDObject.szSilent, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "execution", "", siSDObject.szExecution, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "confirm_install", "", siSDObject.szConfirmInstall, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Netscape Install", "extract_msg", "", siSDObject.szExtractMsg, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Execution", "exe", "", siSDObject.szExe, MAX_BUF);
|
|
GetConfigIniProfileString("SmartDownload-Execution", "exe_param", "", siSDObject.szExeParam, MAX_BUF);
|
|
|
|
GetConfigIniProfileString("Core", "Source", "", szBuf, sizeof(szBuf));
|
|
DecryptString(siCFXpcomFile.szSource, szBuf);
|
|
GetConfigIniProfileString("Core", "Destination", "", szBuf, sizeof(szBuf));
|
|
DecryptString(siCFXpcomFile.szDestination, szBuf);
|
|
GetConfigIniProfileString("Core", "Message", "", siCFXpcomFile.szMessage, MAX_BUF);
|
|
GetConfigIniProfileString("Core", "Cleanup", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "FALSE") == 0)
|
|
siCFXpcomFile.bCleanup = FALSE;
|
|
else
|
|
siCFXpcomFile.bCleanup = TRUE;
|
|
GetConfigIniProfileString("Core", "Status", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Strings", "Message Unfinished Download Restart", "", szBuf, sizeof(szBuf));
|
|
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);
|
|
|
|
GetConfigIniProfileString("Strings", "Message Unfinished Install Xpi Restart", "", szBuf, sizeof(szBuf));
|
|
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;
|
|
char fontName[MAX_BUF];
|
|
char fontSize[MAX_BUF];
|
|
|
|
/* 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 );
|
|
|
|
/* get welcome title font */
|
|
GetPrivateProfileString("General", "WELCOMETITLEFONTNAME", "", fontName, sizeof(fontName), szFileIniInstall);
|
|
#ifdef MOZ_THUNDERBIRD
|
|
GetPrivateProfileString("General", "WELCOMETITLEFONTSIZE_THUNDERBIRD", "", fontSize, sizeof(fontSize), szFileIniInstall);
|
|
#else
|
|
GetPrivateProfileString("General", "WELCOMETITLEFONTSIZE", "", fontSize, sizeof(fontSize), szFileIniInstall);
|
|
#endif
|
|
memset(&lf, 0, sizeof(lf));
|
|
strcpy(lf.lfFaceName, fontName);
|
|
lf.lfHeight = -MulDiv(atoi(fontSize), GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
|
|
lf.lfWeight = GetPrivateProfileInt("General", "WELCOMETITLEFONTWEIGHT", 0, szFileIniInstall);
|
|
lf.lfCharSet = atoi(sgInstallGui.szCharSet);
|
|
sgInstallGui.welcomeTitleFont = 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", "PROXY_MESSAGE", "", sgInstallGui.szProxyMessage, sizeof(sgInstallGui.szProxyMessage), szFileIniInstall);
|
|
GetPrivateProfileString("General", "PROXY_BUTTON", "", sgInstallGui.szProxyButton, sizeof(sgInstallGui.szProxyButton), 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", "BROWSEINFO", "", sgInstallGui.szBrowseInfo, sizeof(sgInstallGui.szBrowseInfo), szFileIniInstall);
|
|
GetPrivateProfileString("General", "DESTINATIONDIRECTORY", "", sgInstallGui.szDestinationDirectory, sizeof(sgInstallGui.szDestinationDirectory), szFileIniInstall);
|
|
GetPrivateProfileString("General", "BROWSE_", "", sgInstallGui.szBrowse_, sizeof(sgInstallGui.szBrowse_), szFileIniInstall);
|
|
GetPrivateProfileString("General", "DOWNLOADSIZE", "", sgInstallGui.szDownloadSize, sizeof(sgInstallGui.szDownloadSize), szFileIniInstall);
|
|
GetPrivateProfileString("General", "CURRENTSETTINGS", "", sgInstallGui.szCurrentSettings, sizeof(sgInstallGui.szCurrentSettings), szFileIniInstall);
|
|
GetPrivateProfileString("General", "INSTALLFOLDER", "", sgInstallGui.szInstallFolder, sizeof(sgInstallGui.szInstallFolder), szFileIniInstall);
|
|
GetPrivateProfileString("General", "ADDTLCOMPWRAPPER", "", sgInstallGui.szAddtlCompWrapper, sizeof(sgInstallGui.szAddtlCompWrapper), szFileIniInstall);
|
|
GetPrivateProfileString("General", "PRIMCOMPNOOTHERS", "", sgInstallGui.szPrimCompNoOthers, sizeof(sgInstallGui.szPrimCompNoOthers), szFileIniInstall);
|
|
GetPrivateProfileString("General", "PRIMCOMPOTHERS", "", sgInstallGui.szPrimCompOthers, sizeof(sgInstallGui.szPrimCompOthers), 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);
|
|
|
|
GetConfigIniProfileString(szSection, "Key", "", szValue, sizeof(szValue));
|
|
if(*szValue != '\0')
|
|
bFound = LocatePathNscpReg(szSection, szPath, dwPathSize);
|
|
else
|
|
{
|
|
GetConfigIniProfileString(szSection, "HKey", "", szValue, sizeof(szValue));
|
|
if(*szValue != '\0')
|
|
bFound = LocatePathWinReg(szSection, szPath, dwPathSize);
|
|
else
|
|
{
|
|
GetConfigIniProfileString(szSection, "Path", "", szValue, sizeof(szValue));
|
|
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;
|
|
GetConfigIniProfileString(szSection, "Key", "", szKey, sizeof(szKey));
|
|
if(*szKey != '\0')
|
|
{
|
|
bReturn = FALSE;
|
|
ZeroMemory(szPath, dwPathSize);
|
|
|
|
VR_GetPath(szKey, MAX_BUF, szBuf);
|
|
if(*szBuf != '\0')
|
|
{
|
|
GetConfigIniProfileString(szSection, "Contains Filename", "", szContainsFilename, sizeof(szContainsFilename));
|
|
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;
|
|
GetConfigIniProfileString(szSection, "HKey", "", szHKey, sizeof(szHKey));
|
|
if(*szHKey != '\0')
|
|
{
|
|
bReturn = FALSE;
|
|
ZeroMemory(szPath, dwPathSize);
|
|
|
|
GetConfigIniProfileString(szSection, "HRoot", "", szHRoot, sizeof(szHRoot));
|
|
GetConfigIniProfileString(szSection, "Name", "", szName, sizeof(szName));
|
|
GetConfigIniProfileString(szSection, "Decrypt HKey", "", szBuf, sizeof(szBuf));
|
|
if(lstrcmpi(szBuf, "FALSE") == 0)
|
|
bDecryptKey = FALSE;
|
|
else
|
|
bDecryptKey = TRUE;
|
|
|
|
/* check for both 'Verify Existance' and 'Verify Existence' */
|
|
GetConfigIniProfileString(szSection, "Verify Existence", "", szVerifyExistence, sizeof(szVerifyExistence));
|
|
if(*szVerifyExistence == '\0')
|
|
GetConfigIniProfileString(szSection, "Verify Existance", "", szVerifyExistence, sizeof(szVerifyExistence));
|
|
|
|
GetConfigIniProfileString(szSection, "Contains Filename", "", szBuf, sizeof(szBuf));
|
|
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;
|
|
GetConfigIniProfileString(szSection, "Path", "", szPathKey, sizeof(szPathKey));
|
|
if(*szPathKey != '\0')
|
|
{
|
|
bReturn = FALSE;
|
|
ZeroMemory(szPath, dwPathSize);
|
|
|
|
DecryptString(szPath, szPathKey);
|
|
bReturn = TRUE;
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
void SetCustomType()
|
|
{
|
|
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);
|
|
|
|
GetConfigIniProfileString(szLookupSection, "Path Reg Key Root", "", szBuf, sizeof(szBuf));
|
|
if(*szBuf == '\0')
|
|
return(FALSE);
|
|
hkeyRoot = ParseRootKey(szBuf);
|
|
|
|
GetConfigIniProfileString(szLookupSection, "Path Reg Key", "", szKey, sizeof(szKey));
|
|
|
|
GetConfigIniProfileString(szLookupSection, "Path Reg Name", "", szName, sizeof(szName));
|
|
|
|
GetWinReg(hkeyRoot, szKey, szName, szBuf, sizeof(szBuf));
|
|
if(*szBuf == '\0')
|
|
return(FALSE);
|
|
|
|
GetConfigIniProfileString(szLookupSection, "Strip Filename", "", szBuf2, sizeof(szBuf2));
|
|
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);
|
|
DeInitDlgDownloading(&diDownloading);
|
|
DeInitDlgInstalling(&diInstalling);
|
|
DeInitDlgInstallSuccessful(&diInstallSuccessful);
|
|
DeInitDlgAdditionalOptions(&diAdditionalOptions);
|
|
DeInitDlgAdvancedSettings(&diAdvancedSettings);
|
|
DeInitDlgProgramFolder(&diProgramFolder);
|
|
DeInitDlgWindowsIntegration(&diWindowsIntegration);
|
|
DeInitDlgSelectComponents(&diSelectAdditionalComponents);
|
|
DeInitDlgUpgrade(&diUpgrade);
|
|
DeInitDlgSelectInstallPath(&diSelectInstallPath);
|
|
DeInitDlgSelectComponents(&diSelectComponents);
|
|
DeInitDlgSetupType(&diSetupType);
|
|
DeInitDlgWelcome(&diWelcome);
|
|
DeInitDlgLicense(&diLicense);
|
|
DeInitDlgQuickLaunch(&diQuickLaunch);
|
|
DeInitDSNode(&gdsnComponentDSRequirement);
|
|
DeInitErrorMessageStream();
|
|
|
|
FreeMemory(&szTempDir);
|
|
FreeMemory(&szOSTempDir);
|
|
FreeMemory(&szProxyDLLPath);
|
|
FreeMemory(&szSetupDir);
|
|
FreeMemory(&szFileIniInstall);
|
|
FreeMemory(&szEGlobalAlloc);
|
|
FreeMemory(&szEOutOfMemory);
|
|
FreeMemory(&szEDllLoad);
|
|
FreeMemory(&szEStringLoad);
|
|
FreeMemory(&szEStringNull);
|
|
DeleteObject(sgInstallGui.systemFont);
|
|
DeleteObject(sgInstallGui.definedFont);
|
|
DeleteObject(sgInstallGui.welcomeTitleFont);
|
|
|
|
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);
|
|
|
|
/* 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);
|
|
|
|
return(TRUE);
|
|
}
|