Back to index

lightning-sunbird  0.9+nobinonly
extra.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Sean Su <ssu@netscape.com>
00025  *   Curt Patrick <curt@netscape.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "extern.h"
00042 #include "extra.h"
00043 #include "dialogs.h"
00044 #include "ifuncns.h"
00045 #include "xpnetHook.h"
00046 #include "time.h"
00047 #include "xpi.h"
00048 #include "logging.h"
00049 #include "nsEscape.h"
00050 
00051 char *ArchiveExtensions[] = {"zip",
00052                              "xpi",
00053                              "jar",
00054                              ""};
00055 
00056 BOOL InitApplication()
00057 {
00058   CLASSINFO classinfo;
00059   WinQueryClassInfo((HAB)0, WC_FRAME, &classinfo);
00060   return (WinRegisterClass((HAB)0, CLASS_NAME_SETUP_DLG, WinDefDlgProc,
00061                            CS_SAVEBITS, classinfo.cbWindowData));
00062 }
00063 
00064 BOOL InitInstance()
00065 {
00066   gSystemInfo.lScreenX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
00067   gSystemInfo.lScreenY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
00068   gSystemInfo.lDlgFrameX = WinQuerySysValue(HWND_DESKTOP, SV_CXDLGFRAME);
00069   gSystemInfo.lDlgFrameY = WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME);
00070   gSystemInfo.lTitleBarY = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
00071 
00072   hWndMain = NULL;
00073 
00074   return(TRUE);
00075 }
00076 
00077 void PrintError(PSZ szMsg, ULONG ulErrorCodeSH)
00078 {
00079   ERRORID erridErrorCode;
00080   char  szErrorString[MAX_BUF];
00081 
00082   if(ulErrorCodeSH == ERROR_CODE_SHOW)
00083   {
00084     erridErrorCode = WinGetLastError((HAB)0);
00085     sprintf(szErrorString, "%d : %s", erridErrorCode, szMsg);
00086   }
00087   else
00088     sprintf(szErrorString, "%s", szMsg);
00089 
00090   if((sgProduct.ulMode != SILENT) && (sgProduct.ulMode != AUTO))
00091   {
00092     WinMessageBox(HWND_DESKTOP, hWndMain, szErrorString, NULL, 0, MB_ICONEXCLAMATION);
00093   }
00094   else if(sgProduct.ulMode == AUTO)
00095   {
00096     ShowMessage(szErrorString, TRUE);
00097     DosSleep(5000);
00098     ShowMessage(szErrorString, FALSE);
00099   }
00100 }
00101 
00102 /* Windows API does offer a GlobalReAlloc() routine, but it kept
00103  * returning an out of memory error for subsequent calls to it
00104  * after the first time, thus the reason for this routine. */
00105 void *NS_GlobalReAlloc(void **hgMemory,
00106                        DWORD dwMemoryBufSize,
00107                        DWORD dwNewSize)
00108 {
00109   HGLOBAL hgPtr = NULL;
00110 
00111   if((hgPtr = NS_GlobalAlloc(dwNewSize)) == NULL)
00112     return(NULL);
00113   else
00114   {
00115     memcpy(hgPtr, *hgMemory, dwMemoryBufSize);
00116     FreeMemory(hgMemory);
00117     *hgMemory = hgPtr;
00118     return(hgPtr);
00119   }
00120 }
00121 
00122 void *NS_GlobalAlloc(ULONG ulMaxBuf)
00123 {
00124   void *vBuf = NULL;
00125 
00126   if ((vBuf = calloc(1, ulMaxBuf)) == NULL)
00127   {     
00128     if((szEGlobalAlloc == NULL) || (*szEGlobalAlloc == '\0'))
00129       PrintError("Memory allocation error.", ERROR_CODE_HIDE);
00130     else
00131       PrintError(szEGlobalAlloc, ERROR_CODE_SHOW);
00132 
00133     return(NULL);
00134   }
00135   else
00136   {
00137     return(vBuf);
00138   }
00139 }
00140 
00141 void FreeMemory(void **vPointer)
00142 {
00143   if(*vPointer != NULL)
00144     free(*vPointer);
00145   *vPointer = NULL;
00146 }
00147 
00148 HRESULT NS_LoadStringAlloc(HMODULE hInstance, ULONG ulID, PSZ *szStringBuf, ULONG ulStringBuf)
00149 {
00150   char szBuf[MAX_BUF];
00151 
00152   if((*szStringBuf = NS_GlobalAlloc(MAX_BUF)) == NULL)
00153     exit(1);
00154   
00155   if(!WinLoadString((HAB)0, hInstance, ulID, ulStringBuf, *szStringBuf))
00156   {
00157     if((szEStringLoad == NULL) ||(*szEStringLoad == '\0'))
00158       sprintf(szBuf, "Could not load string resource ID %d", ulID);
00159     else
00160       sprintf(szBuf, szEStringLoad, ulID);
00161 
00162     PrintError(szBuf, ERROR_CODE_SHOW);
00163     return(1);
00164   }
00165   return(0);
00166 }
00167 
00168 HRESULT NS_LoadString(HMODULE hInstance, ULONG ulID, PSZ szStringBuf, ULONG ulStringBuf)
00169 {
00170   char szBuf[MAX_BUF];
00171 
00172   if(!WinLoadString((HAB)0, hInstance, ulID, ulStringBuf, szStringBuf))
00173   {
00174     if((szEStringLoad == NULL) ||(*szEStringLoad == '\0'))
00175       sprintf(szBuf, "Could not load string resource ID %d", ulID);
00176     else
00177       sprintf(szBuf, szEStringLoad, ulID);
00178 
00179     PrintError(szBuf, ERROR_CODE_SHOW);
00180     return(1);
00181   }
00182   return(WIZ_OK);
00183 }
00184 
00185 void UnsetSetupState(void)
00186 {
00187   char szApp[MAX_BUF_TINY];
00188 
00189   sprintf(szApp,
00190            "%s %s",
00191            sgProduct.szProductNameInternal,
00192            sgProduct.szUserAgent);
00193   PrfWriteProfileString(HINI_USERPROFILE, szApp, "Setup State", NULL);
00194 }
00195 
00196 void SetSetupState(char *szState)
00197 {
00198   char szApp[MAX_BUF_TINY];
00199 
00200   sprintf(szApp,
00201            "%s %s",
00202            sgProduct.szProductNameInternal,
00203            sgProduct.szUserAgent);
00204 
00205   PrfWriteProfileString(HINI_USERPROFILE, szApp, "Setup State", szState);
00206 }
00207 
00208 DWORD GetPreviousUnfinishedState(void)
00209 {
00210   char szBuf[MAX_BUF_TINY];
00211   char szApp[MAX_BUF_TINY];
00212   DWORD dwRv = PUS_NONE;
00213 
00214   if(sgProduct.szProductNameInternal &&
00215      sgProduct.szUserAgent)
00216   {
00217     sprintf(szApp,
00218              "%s %s",
00219              sgProduct.szProductNameInternal,
00220              sgProduct.szUserAgent);
00221 
00222     PrfQueryProfileString(HINI_USERPROFILE, szApp, "Setup State", "", szBuf, sizeof(szBuf));
00223     if(stricmp(szBuf, SETUP_STATE_DOWNLOAD) == 0)
00224       dwRv = PUS_DOWNLOAD;
00225     else if(stricmp(szBuf, SETUP_STATE_UNPACK_XPCOM) == 0)
00226       dwRv = PUS_UNPACK_XPCOM;
00227     else if(stricmp(szBuf, SETUP_STATE_INSTALL_XPI) == 0)
00228       dwRv = PUS_INSTALL_XPI;
00229   }
00230 
00231   return(dwRv);
00232 }
00233 
00234 void UnsetSetupCurrentDownloadFile(void)
00235 {
00236   char szApp[MAX_BUF];
00237 
00238   sprintf(szApp,
00239            "%s %s",
00240            sgProduct.szProductNameInternal,
00241            sgProduct.szUserAgent);
00242   PrfWriteProfileString(HINI_USERPROFILE, szApp, "Setup Current Download", NULL);
00243 }
00244 
00245 void SetSetupCurrentDownloadFile(char *szCurrentFilename)
00246 {
00247   char szApp[MAX_BUF];
00248 
00249   sprintf(szApp,
00250            "%s %s",
00251            sgProduct.szProductNameInternal,
00252            sgProduct.szUserAgent);
00253   PrfWriteProfileString(HINI_USERPROFILE, szApp, "Setup State", szCurrentFilename);
00254 }
00255 
00256 char *GetSetupCurrentDownloadFile(char *szCurrentDownloadFile,
00257                                   ULONG ulCurrentDownloadFileBufSize)
00258 {
00259   char szApp[MAX_BUF];
00260 
00261   if(!szCurrentDownloadFile)
00262     return(NULL);
00263 
00264   memset(szCurrentDownloadFile, 0, ulCurrentDownloadFileBufSize);
00265   if(sgProduct.szProductNameInternal &&
00266      sgProduct.szUserAgent)
00267   {
00268     sprintf(szApp,
00269              "%s %s",
00270              sgProduct.szProductNameInternal,
00271              sgProduct.szUserAgent);
00272     PrfQueryProfileString(HINI_USERPROFILE, szApp, "Setup Current Download", "",
00273                           szCurrentDownloadFile, ulCurrentDownloadFileBufSize);
00274   }
00275 
00276   return(szCurrentDownloadFile);
00277 }
00278 
00279 BOOL UpdateFile(char *szInFilename, char *szOutFilename, char *szIgnoreStr)
00280 {
00281   FILE *ifp;
00282   FILE *ofp;
00283   char szLineRead[MAX_BUF];
00284   char szLCIgnoreLongStr[MAX_BUF];
00285   char szLCLineRead[MAX_BUF];
00286   BOOL bFoundIgnoreStr = FALSE;
00287 
00288   if((ifp = fopen(szInFilename, "rt")) == NULL)
00289     return(bFoundIgnoreStr);
00290   if((ofp = fopen(szOutFilename, "w+t")) == NULL)
00291   {
00292     fclose(ifp);
00293     return(bFoundIgnoreStr);
00294   }
00295 
00296   if(strlen(szIgnoreStr) < sizeof(szLCIgnoreLongStr))
00297   {
00298     strcpy(szLCIgnoreLongStr, szIgnoreStr);
00299     strlwr(szLCIgnoreLongStr);
00300   }
00301 
00302   while(fgets(szLineRead, sizeof(szLineRead), ifp) != NULL)
00303   {
00304     strcpy(szLCLineRead, szLineRead);
00305     strlwr(szLCLineRead);
00306     if(!strstr(szLCLineRead, szLCIgnoreLongStr))
00307       fputs(szLineRead, ofp);
00308     else
00309       bFoundIgnoreStr = TRUE;
00310   }
00311   fclose(ifp);
00312   fclose(ofp);
00313 
00314   return(bFoundIgnoreStr);
00315 }
00316 
00317 HRESULT Initialize(HMODULE hInstance, PSZ szAppName)
00318 {
00319   char szBuf[MAX_BUF];
00320   char szCurrentProcessDir[MAX_BUF];
00321   char *tempEnvVar = NULL;
00322 
00323   bSDUserCanceled     = FALSE;
00324   hDlgMessage         = NULL;
00325 
00326   /* load strings from setup.exe */
00327   if(NS_LoadStringAlloc(hInstance, IDS_ERROR_GLOBALALLOC, &szEGlobalAlloc, MAX_BUF))
00328     return(1);
00329   if(NS_LoadStringAlloc(hInstance, IDS_ERROR_STRING_LOAD, &szEStringLoad,  MAX_BUF))
00330     return(1);
00331   if(NS_LoadStringAlloc(hInstance, IDS_ERROR_DLL_LOAD,    &szEDllLoad,     MAX_BUF))
00332     return(1);
00333   if(NS_LoadStringAlloc(hInstance, IDS_ERROR_STRING_NULL, &szEStringNull,  MAX_BUF))
00334     return(1);
00335 
00336   ParsePath(szAppName, szCurrentProcessDir,
00337             sizeof(szCurrentProcessDir),
00338             FALSE,
00339             PP_PATH_ONLY);
00340 
00341   if(DosLoadModule(NULL, 0, "SETUPRSC", &hSetupRscInst) != NO_ERROR)
00342   {
00343     char szFullFilename[MAX_BUF];
00344 
00345     strcpy(szFullFilename, szCurrentProcessDir);
00346     AppendBackSlash(szFullFilename, sizeof(szFullFilename));
00347     strcat(szFullFilename, "Setuprsc.dll");
00348     if(DosLoadModule(NULL, 0, szFullFilename, &hSetupRscInst) != NO_ERROR)
00349     {
00350       sprintf(szBuf, szEDllLoad, szFullFilename);
00351       PrintError(szBuf, ERROR_CODE_HIDE);
00352       return(1);
00353     }
00354   }
00355 
00356   ulWizardState         = DLG_NONE;
00357   ulTempSetupType       = ulWizardState;
00358   siComponents          = NULL;
00359   bCreateDestinationDir = FALSE;
00360   bReboot               = FALSE;
00361   gulUpgradeValue       = UG_NONE;
00362   gulSiteSelectorStatus = SS_SHOW;
00363   gbILUseTemp           = TRUE;
00364   gbIgnoreRunAppX        = FALSE;
00365   gbIgnoreProgramFolderX = FALSE;
00366 
00367   if((szSetupDir = NS_GlobalAlloc(MAX_BUF)) == NULL)
00368     return(1);
00369   strcpy(szSetupDir, szCurrentProcessDir);
00370 
00371   if((szTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL)
00372     return(1);
00373 
00374   if((szOSTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL)
00375     return(1);
00376 
00377   if((szFileIniConfig = NS_GlobalAlloc(MAX_BUF)) == NULL)
00378     return(1);
00379 
00380   if((szFileIniInstall = NS_GlobalAlloc(MAX_BUF)) == NULL)
00381   return(1);
00382 
00383   // determine the system's TEMP path
00384   tempEnvVar = getenv("TMP");
00385   if ((tempEnvVar) && (!(isFAT(tempEnvVar)))) {
00386     strcpy(szTempDir, tempEnvVar);
00387   }
00388   else
00389   {
00390     tempEnvVar = getenv("TEMP");
00391     if (tempEnvVar)
00392       strcpy(szTempDir, tempEnvVar);
00393   }
00394   if ((!tempEnvVar) || (isFAT(tempEnvVar)))
00395   {
00396     ULONG ulBootDrive = 0;
00397     APIRET rc;
00398     char  buffer[] = " :\\OS2\\";
00399     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00400                     &ulBootDrive, sizeof(ulBootDrive));
00401     buffer[0] = 'A' - 1 + ulBootDrive;
00402     if (isFAT(buffer)) {
00403        /* Try current disk if boot drive is FAT */
00404        ULONG ulDriveNum;
00405        ULONG ulDriveMap;
00406        strcpy(buffer, " :\\");
00407        DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
00408        buffer[0] = 'A' - 1 + ulDriveNum;
00409        if (isFAT(buffer)) {
00410          int i;
00411          for (i = 2; i < 26; i++) {
00412            if ((ulDriveMap<<(31-i)) >> 31) {
00413              buffer[0] = 'A' + i;
00414              if (!(isFAT(buffer))) {
00415                 break;
00416              }
00417            }
00418          }
00419          if (i == 26) {
00420             char szBuf[MAX_BUF];
00421             if(NS_LoadString(hSetupRscInst, IDS_ERROR_NO_LONG_FILENAMES, szBuf, MAX_BUF) == WIZ_OK)
00422               WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szBuf, NULL, 0, MB_ICONEXCLAMATION);
00423             return(1);
00424          }
00425        }
00426     }
00427     strcpy(szTempDir, buffer);
00428     strcat(szTempDir, "TEMP");
00429   }
00430   strcpy(szOSTempDir, szTempDir);
00431   AppendBackSlash(szTempDir, MAX_BUF);
00432   strcat(szTempDir, WIZ_TEMP_DIR);
00433 
00434   if(!FileExists(szTempDir))
00435   {
00436     AppendBackSlash(szTempDir, MAX_BUF);
00437     CreateDirectoriesAll(szTempDir, FALSE);
00438     RemoveBackSlash(szTempDir);
00439     if(!FileExists(szTempDir))
00440     {
00441       char szECreateTempDir[MAX_BUF];
00442 
00443       if(GetPrivateProfileString("Messages", "ERROR_CREATE_TEMP_DIR", "",
00444                                  szECreateTempDir, sizeof(szECreateTempDir),
00445                                  szFileIniInstall))
00446       {
00447         sprintf(szBuf, szECreateTempDir, szTempDir);
00448         PrintError(szBuf, ERROR_CODE_HIDE);
00449       }
00450       return(1);
00451     }
00452   }
00453 
00454   DeleteIdiGetConfigIni();
00455   bIdiArchivesExists = DeleteIdiGetArchives();
00456   DeleteIdiGetRedirect();
00457   DeleteInstallLogFile(FILE_INSTALL_LOG);
00458   DeleteInstallLogFile(FILE_INSTALL_STATUS_LOG);
00459   LogISTime(W_START);
00460   DetermineOSVersionEx();
00461 
00462   gSystemInfo.bScreenReader = TRUE;
00463 
00464   return(0);
00465 }
00466 
00467 /* Function to remove quotes from a string */
00468 void RemoveQuotes(LPSTR lpszSrc, LPSTR lpszDest, int iDestSize)
00469 {
00470   char *lpszBegin;
00471 
00472   if(strlen(lpszSrc) > iDestSize)
00473     return;
00474 
00475   if(*lpszSrc == '\"')
00476     lpszBegin = &lpszSrc[1];
00477   else
00478     lpszBegin = lpszSrc;
00479 
00480   strcpy(lpszDest, lpszBegin);
00481 
00482   if(lpszDest[strlen(lpszDest) - 1] == '\"')
00483     lpszDest[strlen(lpszDest) - 1] = '\0';
00484 }
00485 
00486 /* Function to locate the first non space character in a string,
00487  * and return a pointer to it. */
00488 LPSTR GetFirstNonSpace(LPSTR lpszString)
00489 {
00490   int   i;
00491   int   iStrLength;
00492 
00493   iStrLength = strlen(lpszString);
00494 
00495   for(i = 0; i < iStrLength; i++)
00496   {
00497     if(!isspace(lpszString[i]))
00498       return(&lpszString[i]);
00499   }
00500 
00501   return(NULL);
00502 }
00503 
00504 BOOL IsInArchivesLst(siC *siCObject, BOOL bModify)
00505 {
00506   char *szBufPtr;
00507   char szBuf[MAX_BUF];
00508   char szArchiveLstFile[MAX_BUF_MEDIUM];
00509   BOOL bRet = FALSE;
00510 
00511   strcpy(szArchiveLstFile, szTempDir);
00512   AppendBackSlash(szArchiveLstFile, sizeof(szArchiveLstFile));
00513   strcat(szArchiveLstFile, "Archive.lst");
00514   GetPrivateProfileString("Archives", NULL, "", szBuf, sizeof(szBuf), szArchiveLstFile);
00515   if(*szBuf != '\0')
00516   {
00517     szBufPtr = szBuf;
00518     while(*szBufPtr != '\0')
00519     {
00520       if(stricmp(siCObject->szArchiveName, szBufPtr) == 0)
00521       {
00522         if(bModify)
00523         {
00524           /* jar file found.  Unset attribute to download from the net */
00525           siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED;
00526           /* save the path of where jar was found at */
00527           strcpy(siCObject->szArchivePath, szTempDir);
00528           AppendBackSlash(siCObject->szArchivePath, MAX_BUF);
00529         }
00530         bRet = TRUE;
00531 
00532         /* found what we're looking for.  No need to continue */
00533         break;
00534       }
00535       szBufPtr += strlen(szBufPtr) + 1;
00536     }
00537   }
00538   return(bRet);
00539 }
00540 
00541 HRESULT ParseSetupIni()
00542 {
00543   char szBuf[MAX_BUF];
00544   char szFileIniSetup[MAX_BUF];
00545   char szFileIdiGetConfigIni[MAX_BUF];
00546 
00547   strcpy(szFileIdiGetConfigIni, szTempDir);
00548   AppendBackSlash(szFileIdiGetConfigIni, sizeof(szFileIdiGetConfigIni));
00549   strcat(szFileIdiGetConfigIni, FILE_IDI_GETCONFIGINI);
00550 
00551   strcpy(szFileIniSetup, szSetupDir);
00552   AppendBackSlash(szFileIniSetup, sizeof(szFileIniSetup));
00553   strcat(szFileIniSetup, FILE_INI_SETUP);
00554 
00555   DosCopy(szFileIniSetup, szFileIdiGetConfigIni, DCPY_EXISTING);
00556 
00557   if(!FileExists(szFileIdiGetConfigIni))
00558   {
00559     char szEFileNotFound[MAX_BUF];
00560 
00561     if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall))
00562     {
00563       sprintf(szBuf, szEFileNotFound, szFileIdiGetConfigIni);
00564       PrintError(szBuf, ERROR_CODE_HIDE);
00565     }
00566     return(1);
00567   }
00568 
00569   return(0);
00570 }
00571 
00572 HRESULT GetConfigIni()
00573 {
00574   char    szFileIniTempDir[MAX_BUF];
00575   char    szFileIniSetupDir[MAX_BUF];
00576   char    szMsgRetrieveConfigIni[MAX_BUF];
00577   char    szBuf[MAX_BUF];
00578   HRESULT hResult = 0;
00579 
00580   if(!GetPrivateProfileString("Messages", "MSG_RETRIEVE_CONFIGINI", "", szMsgRetrieveConfigIni, sizeof(szMsgRetrieveConfigIni), szFileIniInstall))
00581     return(1);
00582     
00583   strcpy(szFileIniTempDir, szTempDir);
00584   AppendBackSlash(szFileIniTempDir, sizeof(szFileIniTempDir));
00585   strcat(szFileIniTempDir, FILE_INI_CONFIG);
00586 
00587   /* set default value for szFileIniConfig here */
00588   strcpy(szFileIniConfig, szFileIniTempDir);
00589 
00590   strcpy(szFileIniSetupDir, szSetupDir);
00591   AppendBackSlash(szFileIniSetupDir, sizeof(szFileIniSetupDir));
00592   strcat(szFileIniSetupDir, FILE_INI_CONFIG);
00593 
00594   /* if config.ini exists, then use it, else download config.ini from the net */
00595   if(!FileExists(szFileIniTempDir))
00596   {
00597     if(FileExists(szFileIniSetupDir))
00598     {
00599       strcpy(szFileIniConfig, szFileIniSetupDir);
00600       hResult = 0;
00601     }
00602     else
00603     {
00604       char szEFileNotFound[MAX_BUF];
00605 
00606     if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall))
00607       {
00608         sprintf(szBuf, szEFileNotFound, FILE_INI_CONFIG);
00609         PrintError(szBuf, ERROR_CODE_HIDE);
00610       }
00611       hResult = 1;
00612     }
00613   }
00614   else
00615     hResult = 0;
00616 
00617   return(hResult);
00618 }
00619 
00620 HRESULT GetInstallIni()
00621 {
00622   char    szFileIniTempDir[MAX_BUF];
00623   char    szFileIniSetupDir[MAX_BUF];
00624   char    szMsgRetrieveInstallIni[MAX_BUF];
00625   char    szBuf[MAX_BUF];
00626   HRESULT hResult = 0;
00627 
00628   if(NS_LoadString(hSetupRscInst, IDS_MSG_RETRIEVE_INSTALLINI, szMsgRetrieveInstallIni, MAX_BUF) != WIZ_OK)
00629     return(1);
00630     
00631   strcpy(szFileIniTempDir, szTempDir);
00632   AppendBackSlash(szFileIniTempDir, sizeof(szFileIniTempDir));
00633   strcat(szFileIniTempDir, FILE_INI_INSTALL);
00634 
00635   /* set default value for szFileIniInstall here */
00636   strcpy(szFileIniInstall, szFileIniTempDir);
00637 
00638   strcpy(szFileIniSetupDir, szSetupDir);
00639   AppendBackSlash(szFileIniSetupDir, sizeof(szFileIniSetupDir));
00640   strcat(szFileIniSetupDir, FILE_INI_INSTALL);
00641 
00642   /* if install.ini exists, then use it, else download install.ini from the net */
00643   if(!FileExists(szFileIniTempDir))
00644   {
00645     if(FileExists(szFileIniSetupDir))
00646     {
00647       strcpy(szFileIniInstall, szFileIniSetupDir);
00648       hResult = 0;
00649     }
00650     else
00651     {
00652       char szEFileNotFound[MAX_BUF];
00653 
00654       if(NS_LoadString(hSetupRscInst, IDS_ERROR_FILE_NOT_FOUND, szEFileNotFound, MAX_BUF) == WIZ_OK)
00655       {
00656         sprintf(szBuf, szEFileNotFound, FILE_INI_INSTALL);
00657         PrintError(szBuf, ERROR_CODE_HIDE);
00658       }
00659       hResult = 1;
00660     }
00661   }
00662   else
00663     hResult = 0;
00664 
00665   return(hResult);
00666 }
00667 
00668 int LocateJar(siC *siCObject, LPSTR szPath, int dwPathSize, BOOL bIncludeTempDir)
00669 {
00670   BOOL bRet;
00671   char szBuf[MAX_BUF * 2];
00672   char szSEADirTemp[MAX_BUF];
00673   char szSetupDirTemp[MAX_BUF];
00674   char szTempDirTemp[MAX_BUF];
00675 
00676   /* initialize default behavior */
00677   bRet = AP_NOT_FOUND;
00678   if(szPath != NULL)
00679     memset(szPath, 0, dwPathSize);
00680   siCObject->dwAttributes |= SIC_DOWNLOAD_REQUIRED;
00681 
00682   strcpy(szSEADirTemp, sgProduct.szAlternateArchiveSearchPath);
00683   AppendBackSlash(szSEADirTemp, sizeof(szSEADirTemp));
00684   strcat(szSEADirTemp, siCObject->szArchiveName);
00685 
00686   /* XXX_QUICK_FIX 
00687    * checking sgProduct.szAlternateArchiveSearchPath for empty string
00688    * should be done prior to AppendBackSlash() above.
00689    * This is a quick fix for the time frame that we are currently in. */
00690   if((*sgProduct.szAlternateArchiveSearchPath != '\0') && (FileExists(szSEADirTemp)))
00691   {
00692     /* jar file found.  Unset attribute to download from the net */
00693     siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED;
00694     /* save the path of where jar was found at */
00695     strcpy(siCObject->szArchivePath, sgProduct.szAlternateArchiveSearchPath);
00696     AppendBackSlash(siCObject->szArchivePath, MAX_BUF);
00697     bRet = AP_ALTERNATE_PATH;
00698 
00699     /* save path where archive is located */
00700     if((szPath != NULL) && (strlen(sgProduct.szAlternateArchiveSearchPath) < dwPathSize))
00701       strcpy(szPath, sgProduct.szAlternateArchiveSearchPath);
00702   }
00703   else
00704   {
00705     strcpy(szSetupDirTemp, szSetupDir);
00706     AppendBackSlash(szSetupDirTemp, sizeof(szSetupDirTemp));
00707 
00708     strcpy(szTempDirTemp,  szTempDir);
00709     AppendBackSlash(szTempDirTemp, sizeof(szTempDirTemp));
00710 
00711     if(stricmp(szTempDirTemp, szSetupDirTemp) == 0)
00712     {
00713       /* check the temp dir for the .xpi file */
00714       strcpy(szBuf, szTempDirTemp);
00715       AppendBackSlash(szBuf, sizeof(szBuf));
00716       strcat(szBuf, siCObject->szArchiveName);
00717 
00718       if(FileExists(szBuf))
00719       {
00720         if(bIncludeTempDir == TRUE)
00721         {
00722           /* jar file found.  Unset attribute to download from the net */
00723           siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED;
00724           /* save the path of where jar was found at */
00725           strcpy(siCObject->szArchivePath, szTempDirTemp);
00726           AppendBackSlash(siCObject->szArchivePath, MAX_BUF);
00727           bRet = AP_TEMP_PATH;
00728         }
00729 
00730         /* if the archive name is in the archive.lst file, then it was uncompressed
00731          * by the self extracting .exe file.  Assume that the .xpi file exists.
00732          * This is a safe assumption because the self extracting.exe creates the
00733          * archive.lst with what it uncompresses everytime it is run. */
00734         if(IsInArchivesLst(siCObject, TRUE))
00735           bRet = AP_SETUP_PATH;
00736 
00737         /* save path where archive is located */
00738         if((szPath != NULL) && (strlen(szTempDirTemp) < dwPathSize))
00739           strcpy(szPath, szTempDirTemp);
00740       }
00741     }
00742     else
00743     {
00744       /* check the setup dir for the .xpi file */
00745       strcpy(szBuf, szSetupDirTemp);
00746       AppendBackSlash(szBuf, sizeof(szBuf));
00747       strcat(szBuf, siCObject->szArchiveName);
00748 
00749       if(FileExists(szBuf))
00750       {
00751         /* jar file found.  Unset attribute to download from the net */
00752         siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED;
00753         /* save the path of where jar was found at */
00754         strcpy(siCObject->szArchivePath, szSetupDirTemp);
00755         AppendBackSlash(siCObject->szArchivePath, MAX_BUF);
00756         bRet = AP_SETUP_PATH;
00757 
00758         /* save path where archive is located */
00759         if((szPath != NULL) && (strlen(sgProduct.szAlternateArchiveSearchPath) < dwPathSize))
00760           strcpy(szPath, szSetupDirTemp);
00761       }
00762       else
00763       {
00764         /* check the ns_temp dir for the .xpi file */
00765         strcpy(szBuf, szTempDirTemp);
00766         AppendBackSlash(szBuf, sizeof(szBuf));
00767         strcat(szBuf, siCObject->szArchiveName);
00768 
00769         if(FileExists(szBuf))
00770         {
00771           if(bIncludeTempDir == TRUE)
00772           {
00773             /* jar file found.  Unset attribute to download from the net */
00774             siCObject->dwAttributes &= ~SIC_DOWNLOAD_REQUIRED;
00775             /* save the path of where jar was found at */
00776             strcpy(siCObject->szArchivePath, szTempDirTemp);
00777             AppendBackSlash(siCObject->szArchivePath, MAX_BUF);
00778             bRet = AP_TEMP_PATH;
00779           }
00780 
00781           /* save path where archive is located */
00782           if((szPath != NULL) && (strlen(sgProduct.szAlternateArchiveSearchPath) < dwPathSize))
00783             strcpy(szPath, szTempDirTemp);
00784         }
00785       }
00786     }
00787   }
00788   return(bRet);
00789 }
00790 
00791 void SwapFTPAndHTTP(char *szInUrl, DWORD dwInUrlSize)
00792 {
00793   char szTmpBuf[MAX_BUF];
00794   char *ptr       = NULL;
00795   char szFtp[]    = "ftp://";
00796   char szHttp[]   = "http://";
00797 
00798   if((!szInUrl) || !diAdditionalOptions.bUseProtocolSettings)
00799     return;
00800 
00801   memset(szTmpBuf, 0, sizeof(szTmpBuf));
00802   switch(diAdditionalOptions.dwUseProtocol)
00803   {
00804     case UP_HTTP:
00805       if((strncmp(szInUrl, szFtp, (sizeof(szFtp) - 1)) == 0) &&
00806          ((int)dwInUrlSize > strlen(szInUrl) + 1))
00807       {
00808         ptr = szInUrl + (sizeof(szFtp) - 1);
00809         memmove(ptr + 1, ptr, strlen(ptr) + 1);
00810         memcpy(szInUrl, szHttp, (sizeof(szHttp) - 1));
00811       }
00812       break;
00813 
00814     case UP_FTP:
00815     default:
00816       if((strncmp(szInUrl, szHttp, (sizeof(szHttp) - 1)) == 0) &&
00817          ((int)dwInUrlSize > strlen(szInUrl) + 1))
00818       {
00819         ptr = szInUrl + (sizeof(szHttp) - 1);
00820         memmove(ptr - 1, ptr, strlen(ptr) + 1);
00821         memcpy(szInUrl, szFtp, (sizeof(szFtp) - 1));
00822       }
00823       break;
00824   }
00825 }
00826 
00827 int UpdateIdiFile(char  *szPartialUrl,
00828                   DWORD dwPartialUrlBufSize,
00829                   siC   *siCObject,
00830                   char  *szSection,
00831                   char  *szKey,
00832                   char  *szFileIdiGetArchives)
00833 {
00834   char      szUrl[MAX_BUF];
00835   char      szBuf[MAX_BUF];
00836   char      szBufTemp[MAX_BUF];
00837 
00838   SwapFTPAndHTTP(szPartialUrl, dwPartialUrlBufSize);
00839   RemoveSlash(szPartialUrl);
00840   sprintf(szUrl, "%s/%s", szPartialUrl, siCObject->szArchiveName);
00841   if(WritePrivateProfileString(szSection,
00842                                szKey,
00843                                szUrl,
00844                                szFileIdiGetArchives) == 0)
00845   {
00846     char szEWPPS[MAX_BUF];
00847 
00848     if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall))
00849     {
00850       sprintf(szBufTemp,
00851                "%s\n    [%s]\n    url=%s",
00852                szFileIdiGetArchives,
00853                szSection,
00854                szUrl);
00855       sprintf(szBuf, szEWPPS, szBufTemp);
00856       PrintError(szBuf, ERROR_CODE_SHOW);
00857     }
00858     return(1);
00859   }
00860   return(0);
00861 }
00862 
00863 HRESULT AddArchiveToIdiFile(siC *siCObject,
00864                             char *szSection,
00865                             char *szFileIdiGetArchives)
00866 {
00867   char      szFile[MAX_BUF];
00868   char      szBuf[MAX_BUF];
00869   char      szUrl[MAX_BUF];
00870   char      szIdentifier[MAX_BUF];
00871   char      szArchiveSize[MAX_ITOA];
00872   char      szKey[MAX_BUF_TINY];
00873   int       iIndex = 0;
00874   ssi       *ssiSiteSelectorTemp;
00875 
00876   WritePrivateProfileString(szSection,
00877                             "desc",
00878                             siCObject->szDescriptionShort,
00879                             szFileIdiGetArchives);
00880   _itoa(siCObject->ulInstallSizeArchive, szArchiveSize, 10);
00881   WritePrivateProfileString(szSection,
00882                             "size",
00883                             szArchiveSize,
00884                             szFileIdiGetArchives);
00885   _itoa(siCObject->dwAttributes & SIC_IGNORE_DOWNLOAD_ERROR, szBuf, 10);
00886   WritePrivateProfileString(szSection,
00887                             "Ignore File Network Error",
00888                             szBuf,
00889                             szFileIdiGetArchives);
00890 
00891   strcpy(szFile, szTempDir);
00892   AppendBackSlash(szFile, sizeof(szFile));
00893   strcat(szFile, FILE_INI_REDIRECT);
00894 
00895   memset(szIdentifier, 0, sizeof(szIdentifier));
00896   ssiSiteSelectorTemp = SsiGetNode(szSiteSelectorDescription);
00897 
00898   GetPrivateProfileString("Redirect",
00899                           "Status",
00900                           "",
00901                           szBuf,
00902                           sizeof(szBuf),
00903                           szFileIniConfig);
00904   if(stricmp(szBuf, "ENABLED") != 0)
00905   {
00906     /* redirect.ini is *not* enabled, so use the url from the
00907      * config.ini's [Site Selector] section */
00908     if(*ssiSiteSelectorTemp->szDomain != '\0')
00909     {
00910       sprintf(szKey, "url%d", iIndex);
00911       strcpy(szUrl, ssiSiteSelectorTemp->szDomain);
00912       UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives);
00913       ++iIndex;
00914     }
00915 
00916     /* use the url from the config.ini's [General] section as well */
00917     GetPrivateProfileString("General",
00918                             "url",
00919                             "",
00920                             szUrl,
00921                             sizeof(szUrl),
00922                             szFileIniConfig);
00923     if(*szUrl != 0)
00924     {
00925       sprintf(szKey, "url%d", iIndex);
00926       UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives);
00927     }
00928   }
00929   else if(FileExists(szFile))
00930   {
00931     /* redirect.ini is enabled *and* it exists */
00932     GetPrivateProfileString("Site Selector",
00933                             ssiSiteSelectorTemp->szIdentifier,
00934                             "",
00935                             szUrl,
00936                             sizeof(szUrl),
00937                             szFile);
00938     if(*szUrl != '\0')
00939     {
00940       sprintf(szKey, "url%d", iIndex);
00941       UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives);
00942       ++iIndex;
00943     }
00944 
00945     /* use the url from the config.ini's [General] section as well */
00946     GetPrivateProfileString("General",
00947                             "url",
00948                             "",
00949                             szUrl,
00950                             sizeof(szUrl),
00951                             szFileIniConfig);
00952     if(*szUrl != 0)
00953     {
00954       sprintf(szKey, "url%d", iIndex);
00955       UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives);
00956     }
00957   }
00958   else
00959   {
00960     /* redirect.ini is enabled, but the file does not exist,
00961      * so fail over to the url from the config.ini's [General] section */
00962     GetPrivateProfileString("General",
00963                             "url",
00964                             "",
00965                             szUrl,
00966                             sizeof(szUrl),
00967                             szFileIniConfig);
00968     if(*szUrl != 0)
00969     {
00970       sprintf(szKey, "url%d", iIndex);
00971       UpdateIdiFile(szUrl, sizeof(szUrl), siCObject, szSection, szKey, szFileIdiGetArchives);
00972     }
00973   }
00974 
00975   return(0);
00976 }
00977 
00978 void SetSetupRunMode(LPSTR szMode)
00979 {
00980   if(stricmp(szMode, "NORMAL") == 0)
00981     sgProduct.ulMode = NORMAL;
00982   if(stricmp(szMode, "AUTO") == 0)
00983     sgProduct.ulMode = AUTO;
00984   if(stricmp(szMode, "SILENT") == 0)
00985     sgProduct.ulMode = SILENT;
00986 }
00987 
00988 BOOL CheckForArchiveExtension(LPSTR szFile)
00989 {
00990   int  i;
00991   BOOL bRv = FALSE;
00992   char szExtension[MAX_BUF_TINY];
00993 
00994   /* if there is no extension in szFile, szExtension will be zero'ed out */
00995   ParsePath(szFile, szExtension, sizeof(szExtension), FALSE, PP_EXTENSION_ONLY);
00996   i = 0;
00997   while(*ArchiveExtensions[i] != '\0')
00998   {
00999     if(stricmp(szExtension, ArchiveExtensions[i]) == 0)
01000     {
01001       bRv = TRUE;
01002       break;
01003     }
01004 
01005     ++i;
01006   }
01007   return(bRv);
01008 }
01009 
01010 long RetrieveRedirectFile()
01011 {
01012   long      lResult;
01013   char      szBuf[MAX_BUF];
01014   char      szBufUrl[MAX_BUF];
01015   char      szBufTemp[MAX_BUF];
01016   char      szIndex0[MAX_BUF];
01017   char      szFileIdiGetRedirect[MAX_BUF];
01018   char      szFileIniRedirect[MAX_BUF];
01019   ssi       *ssiSiteSelectorTemp;
01020 
01021   if(GetTotalArchivesToDownload() == 0)
01022     return(0);
01023 
01024   strcpy(szFileIniRedirect, szTempDir);
01025   AppendBackSlash(szFileIniRedirect, sizeof(szFileIniRedirect));
01026   strcat(szFileIniRedirect, FILE_INI_REDIRECT);
01027 
01028   if(FileExists(szFileIniRedirect))
01029     DosDelete(szFileIniRedirect);
01030 
01031   GetPrivateProfileString("Redirect", "Status", "", szBuf, sizeof(szBuf), szFileIniConfig);
01032   if(stricmp(szBuf, "ENABLED") != 0)
01033     return(0);
01034 
01035   ssiSiteSelectorTemp = SsiGetNode(szSiteSelectorDescription);
01036   if(ssiSiteSelectorTemp != NULL)
01037   {
01038     if(ssiSiteSelectorTemp->szDomain != NULL)
01039       strcpy(szBufUrl, ssiSiteSelectorTemp->szDomain);
01040   }
01041   else
01042     /* No domain to download the redirect.ini file from.
01043      * Assume that it does not exist.
01044      * This should trigger the backup/alternate url. */
01045     return(0);
01046 
01047   strcpy(szFileIdiGetRedirect, szTempDir);
01048   AppendBackSlash(szFileIdiGetRedirect, sizeof(szFileIdiGetRedirect));
01049   strcat(szFileIdiGetRedirect, FILE_IDI_GETREDIRECT);
01050 
01051   GetPrivateProfileString("Redirect", "Description", "", szBuf, sizeof(szBuf), szFileIniConfig);
01052   WritePrivateProfileString("File0", "desc", szBuf, szFileIdiGetRedirect);
01053   GetPrivateProfileString("Redirect", "Server Path", "", szBuf, sizeof(szBuf), szFileIniConfig);
01054   AppendSlash(szBufUrl, sizeof(szBufUrl));
01055   strcat(szBufUrl, szBuf);
01056   SwapFTPAndHTTP(szBufUrl, sizeof(szBufUrl));
01057   if(WritePrivateProfileString("File0", "url", szBufUrl, szFileIdiGetRedirect) == 0)
01058   {
01059     char szEWPPS[MAX_BUF];
01060 
01061     if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall))
01062     {
01063       sprintf(szBufTemp, "%s\n    [%s]\n    %s=%s", szFileIdiGetRedirect, "File0", szIndex0, szBufUrl);
01064       sprintf(szBuf, szEWPPS, szBufTemp);
01065       PrintError(szBuf, ERROR_CODE_SHOW);
01066     }
01067     return(1);
01068   }
01069 
01070   lResult = DownloadFiles(szFileIdiGetRedirect,               /* input idi file to parse                 */
01071                           szTempDir,                          /* download directory                      */
01072                           diAdvancedSettings.szProxyServer,   /* proxy server name                       */
01073                           diAdvancedSettings.szProxyPort,     /* proxy server port                       */
01074                           diAdvancedSettings.szProxyUser,     /* proxy server user (optional)            */
01075                           diAdvancedSettings.szProxyPasswd,   /* proxy password (optional)               */
01076                           FALSE,                              /* show retry message                      */
01077                           TRUE,                               /* ignore network error                    */
01078                           NULL,                               /* buffer to store the name of failed file */
01079                           0);                                 /* size of failed file name buffer         */
01080   return(lResult);
01081 }
01082 
01083 int CRCCheckDownloadedArchives(char *szCorruptedArchiveList,
01084                                DWORD dwCorruptedArchiveListSize,
01085                                char *szFileIdiGetArchives)
01086 {
01087   DWORD dwIndex0;
01088   DWORD dwFileCounter;
01089   siC   *siCObject = NULL;
01090   char  szArchivePathWithFilename[MAX_BUF];
01091   char  szArchivePath[MAX_BUF];
01092   char  szMsgCRCCheck[MAX_BUF];
01093   char  szSection[MAX_INI_SK];
01094   int   iRv;
01095   int   iResult;
01096 
01097   /* delete the getarchives.idi file because it needs to be recreated
01098    * if there are any files that fails the CRC check */
01099   if(szFileIdiGetArchives)
01100     DosDelete(szFileIdiGetArchives);
01101 
01102   if(szCorruptedArchiveList != NULL)
01103     memset(szCorruptedArchiveList, 0, dwCorruptedArchiveListSize);
01104 
01105   GetPrivateProfileString("Strings", "Message Verifying Archives", "", szMsgCRCCheck, sizeof(szMsgCRCCheck), szFileIniConfig);
01106   ShowMessage(szMsgCRCCheck, TRUE);
01107   
01108   iResult           = WIZ_CRC_PASS;
01109   dwIndex0          = 0;
01110   dwFileCounter     = 0;
01111   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01112   while(siCObject)
01113   {
01114     if((siCObject->dwAttributes & SIC_SELECTED) &&
01115       !(siCObject->dwAttributes & SIC_IGNORE_DOWNLOAD_ERROR))
01116     {
01117       if((iRv = LocateJar(siCObject, szArchivePath, sizeof(szArchivePath), TRUE)) == AP_NOT_FOUND)
01118       {
01119         char szBuf[MAX_BUF];
01120         char szEFileNotFound[MAX_BUF];
01121 
01122        if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall))
01123         {
01124           sprintf(szBuf, szEFileNotFound, siCObject->szArchiveName);
01125           PrintError(szBuf, ERROR_CODE_HIDE);
01126         }
01127         iResult = WIZ_ARCHIVES_MISSING; // not all .xpi files were downloaded
01128         break;
01129       }
01130 
01131       if(strlen(szArchivePath) < sizeof(szArchivePathWithFilename))
01132         strcpy(szArchivePathWithFilename, szArchivePath);
01133 
01134       AppendBackSlash(szArchivePathWithFilename, sizeof(szArchivePathWithFilename));
01135       if((strlen(szArchivePathWithFilename) + strlen(siCObject->szArchiveName)) < sizeof(szArchivePathWithFilename))
01136         strcat(szArchivePathWithFilename, siCObject->szArchiveName);
01137 
01138       if(CheckForArchiveExtension(szArchivePathWithFilename))
01139       {
01140         /* Make sure that the Archive that failed is located in the TEMP
01141          * folder.  This means that it was downloaded at one point and not
01142          * simply uncompressed from the self-extracting exe file. */
01143         if(VerifyArchive(szArchivePathWithFilename) != ZIP_OK)
01144         {
01145           if(iRv == AP_TEMP_PATH)
01146           {
01147             /* Delete the archive even though the download lib will automatically
01148              * overwrite the file.  This is in case that Setup is canceled, at the
01149              * next restart, the file will be downloaded during the first attempt,
01150              * not after a VerifyArchive() call. */
01151             DosDelete(szArchivePathWithFilename);
01152             sprintf(szSection, "File%d", dwFileCounter);
01153             ++dwFileCounter;
01154             if(szFileIdiGetArchives)
01155               if((AddArchiveToIdiFile(siCObject,
01156                                       szSection,
01157                                       szFileIdiGetArchives)) != 0)
01158                 return(WIZ_ERROR_UNDEFINED);
01159 
01160             ++siCObject->iCRCRetries;
01161             if(szCorruptedArchiveList != NULL)
01162             {
01163               if((DWORD)(strlen(szCorruptedArchiveList) + strlen(siCObject->szArchiveName + 1)) < dwCorruptedArchiveListSize)
01164               {
01165                 strcat(szCorruptedArchiveList, "        ");
01166                 strcat(szCorruptedArchiveList, siCObject->szArchiveName);
01167                 strcat(szCorruptedArchiveList, "\n");
01168               }
01169             }
01170           }
01171           iResult = WIZ_CRC_FAIL;
01172         }
01173       }
01174     }
01175 
01176     ++dwIndex0;
01177     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01178   }
01179   ShowMessage(szMsgCRCCheck, FALSE);
01180   return(iResult);
01181 }
01182 
01183 long RetrieveArchives()
01184 {
01185   DWORD     dwIndex0;
01186   DWORD     dwFileCounter;
01187   BOOL      bDone;
01188   siC       *siCObject = NULL;
01189   long      lResult;
01190   char      szFileIdiGetArchives[MAX_BUF];
01191   char      szSection[MAX_BUF];
01192   char      szCorruptedArchiveList[MAX_BUF];
01193   char      szFailedFile[MAX_BUF];
01194   char      szBuf[MAX_BUF];
01195   char      szPartiallyDownloadedFilename[MAX_BUF];
01196   int       iCRCRetries;
01197   int       iRv;
01198 
01199   /* retrieve the redirect.ini file */
01200   RetrieveRedirectFile();
01201 
01202   memset(szCorruptedArchiveList, 0, sizeof(szCorruptedArchiveList));
01203   strcpy(szFileIdiGetArchives, szTempDir);
01204   AppendBackSlash(szFileIdiGetArchives, sizeof(szFileIdiGetArchives));
01205   strcat(szFileIdiGetArchives, FILE_IDI_GETARCHIVES);
01206   GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename,
01207                               sizeof(szPartiallyDownloadedFilename));
01208 
01209   gbDownloadTriggered= FALSE;
01210   lResult            = WIZ_OK;
01211   dwIndex0           = 0;
01212   dwFileCounter      = 0;
01213   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01214   while(siCObject)
01215   {
01216     if(siCObject->dwAttributes & SIC_SELECTED)
01217     {
01218       /* If a previous unfinished setup was detected, then
01219        * include the TEMP dir when searching for archives.
01220        * Only download jars if not already in the local machine.
01221        * Also if the last file being downloaded should be resumed.
01222        * The resume detection is done automatically. */
01223       if((LocateJar(siCObject,
01224                     NULL,
01225                     0,
01226                     gbPreviousUnfinishedDownload) == AP_NOT_FOUND) ||
01227          (stricmp(szPartiallyDownloadedFilename,
01228                    siCObject->szArchiveName) == 0))
01229       {
01230         sprintf(szSection, "File%d", dwFileCounter);
01231         if((lResult = AddArchiveToIdiFile(siCObject,
01232                                           szSection,
01233                                           szFileIdiGetArchives)) != 0)
01234           return(lResult);
01235 
01236         ++dwFileCounter;
01237       }
01238     }
01239 
01240     ++dwIndex0;
01241     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01242   }
01243 
01244   SetSetupState(SETUP_STATE_DOWNLOAD);
01245 
01246   /* iCRCRetries is initially set to 0 because the first attemp at downloading
01247    * the archives is not considered a "retry".  Subsequent downloads are
01248    * considered retries. */
01249   iCRCRetries = 0;
01250   bDone = FALSE;
01251   do
01252   {
01253     /* the existence of the getarchives.idi file determines if there are
01254        any archives needed to be downloaded */
01255     if(FileExists(szFileIdiGetArchives))
01256     {
01257       gbDownloadTriggered = TRUE;
01258       lResult = DownloadFiles(szFileIdiGetArchives,               /* input idi file to parse                 */
01259                               szTempDir,                          /* download directory                      */
01260                               diAdvancedSettings.szProxyServer,   /* proxy server name                       */
01261                               diAdvancedSettings.szProxyPort,     /* proxy server port                       */
01262                               diAdvancedSettings.szProxyUser,     /* proxy server user (optional)            */
01263                               diAdvancedSettings.szProxyPasswd,   /* proxy password (optional)               */
01264                               iCRCRetries,                        /* show retry message                      */
01265                               FALSE,                              /* ignore network error                    */
01266                               szFailedFile,                       /* buffer to store the name of failed file */
01267                               sizeof(szFailedFile));              /* size of failed file name buffer         */
01268       if(lResult == WIZ_OK)
01269       {
01270         /* CRC check only the archives that were downloaded.
01271          * It will regenerate the idi file with the list of files
01272          * that have not passed the CRC check. */
01273         iRv = CRCCheckDownloadedArchives(szCorruptedArchiveList,
01274                                          sizeof(szCorruptedArchiveList),
01275                                          szFileIdiGetArchives);
01276         switch(iRv)
01277         {
01278           case WIZ_CRC_PASS:
01279             bDone = TRUE;
01280             break;
01281 
01282           default:
01283             bDone = FALSE;
01284             break;
01285         }
01286       }
01287       else
01288       {
01289         /* Download failed.  Error message was already shown by DownloadFiles().
01290          * Simple exit loop here  */
01291         bDone = TRUE;
01292       }
01293     }
01294     else
01295       /* no idi file, so exit loop */
01296       bDone = TRUE;
01297 
01298     if(!bDone)
01299     {
01300       ++iCRCRetries;
01301       if(iCRCRetries > MAX_CRC_FAILED_DOWNLOAD_RETRIES)
01302         bDone = TRUE;
01303     }
01304 
01305   } while(!bDone);
01306 
01307   if(iCRCRetries > MAX_CRC_FAILED_DOWNLOAD_RETRIES)
01308   {
01309     /* too many retries from failed CRC checks */
01310     char szMsg[MAX_BUF];
01311 
01312     LogISComponentsFailedCRC(szCorruptedArchiveList, W_DOWNLOAD);
01313     GetPrivateProfileString("Strings", "Error Too Many CRC Failures", "", szMsg, sizeof(szMsg), szFileIniConfig);
01314     if(*szMsg != '\0')
01315       PrintError(szMsg, ERROR_CODE_HIDE);
01316 
01317     lResult = WIZ_CRC_FAIL;
01318   }
01319   else
01320   {
01321     if(gbDownloadTriggered)
01322       LogISComponentsFailedCRC(NULL, W_DOWNLOAD);
01323   }
01324 
01325   LogISDownloadProtocol(diAdditionalOptions.dwUseProtocol);
01326   LogMSDownloadProtocol(diAdditionalOptions.dwUseProtocol);
01327 
01328   if(lResult == WIZ_OK)
01329   {
01330     LogISDownloadStatus("ok", NULL);
01331   }
01332   else if(gbDownloadTriggered)
01333   {
01334     sprintf(szBuf, "failed: %d", lResult);
01335     LogISDownloadStatus(szBuf, szFailedFile);
01336   }
01337 
01338   /* We want to log the download status regardless if we downloaded or not. */
01339   LogMSDownloadStatus(lResult);
01340 
01341   if(lResult == WIZ_OK)
01342   {
01343     UnsetSetupCurrentDownloadFile();
01344     UnsetSetupState();
01345   }
01346 
01347   return(lResult);
01348 }
01349 
01350 void RemoveBackSlash(PSZ szInput)
01351 {
01352   char  *ptrChar = NULL;
01353 
01354   if(!szInput)
01355     return;
01356 
01357   ptrChar = WinPrevChar(0, 0, 0, szInput, szInput + strlen(szInput));
01358   if (*ptrChar == '\\') {
01359     *ptrChar = '\0';
01360   }
01361 }
01362 
01363 void AppendBackSlash(PSZ szInput, ULONG ulInputSize)
01364 {
01365   ULONG ulInputLen = strlen(szInput);
01366 
01367   if(szInput)
01368   {
01369     if(*szInput == '\0')
01370     {
01371       if((ulInputLen + 1) < ulInputSize)
01372       {
01373         strcat(szInput, "\\");
01374       }
01375     }
01376     else if(*WinPrevChar(0, 0, 0, szInput, &szInput[ulInputLen]) != '\\')
01377     {
01378       if((ulInputLen + 1) < ulInputSize)
01379       {
01380         strcat(szInput, "\\");
01381       }
01382     }
01383   }
01384 }
01385 
01386 void RemoveSlash(LPSTR szInput)
01387 {
01388   DWORD dwInputLen;
01389   BOOL  bDone;
01390   char  *ptrChar = NULL;
01391 
01392   if(szInput)
01393   {
01394     dwInputLen = strlen(szInput);
01395     bDone = FALSE;
01396     ptrChar = &szInput[dwInputLen];
01397     while(!bDone)
01398     {
01399       ptrChar = WinPrevChar(0, 0, 0, szInput, ptrChar);
01400       if(*ptrChar == '/')
01401         *ptrChar = '\0';
01402       else
01403         bDone = TRUE;
01404     }
01405   }
01406 }
01407 
01408 void AppendSlash(LPSTR szInput, DWORD dwInputSize)
01409 {
01410   DWORD dwInputLen = strlen(szInput);
01411 
01412   if(szInput)
01413   {
01414     if(*szInput == '\0')
01415     {
01416       if((dwInputLen + 1) < dwInputSize)
01417       {
01418         strcat(szInput, "/");
01419       }
01420     }
01421     else if(*WinPrevChar(0, 0, 0, szInput, &szInput[dwInputLen]) != '/')
01422     {
01423       if((dwInputLen + 1) < dwInputSize)
01424       {
01425         strcat(szInput, "/");
01426       }
01427     }
01428   }
01429 }
01430 
01431 void ParsePath(PSZ szInput, PSZ szOutput, ULONG ulOutputSize, BOOL bURLPath, ULONG ulType)
01432 {
01433   int   iFoundDelimiter;
01434   ULONG ulInputLen;
01435   ULONG ulOutputLen;
01436   BOOL  bFound;
01437   BOOL  bDone = FALSE;
01438   char  cDelimiter;
01439   char  *ptrChar = NULL;
01440   char  *ptrLastChar = NULL;
01441 
01442   if(bURLPath)
01443     cDelimiter = '/';
01444   else
01445     cDelimiter = '\\';
01446 
01447   if(szInput && szOutput)
01448   {
01449     bFound        = TRUE;
01450     ulInputLen    = strlen(szInput);
01451     memset(szOutput, 0, ulOutputSize);
01452 
01453     if(ulInputLen < ulOutputSize)
01454     {
01455       switch(ulType)
01456       {
01457         case PP_FILENAME_ONLY:
01458           ptrChar = &szInput[ulInputLen];
01459           bDone = FALSE;
01460           while(!bDone)
01461           {
01462             ptrChar = WinPrevChar(0, 0, 0, szInput, ptrChar);
01463             if(*ptrChar == cDelimiter)
01464             {
01465               strcpy(szOutput, WinNextChar(0, 0, 0, ptrChar));
01466               bDone = TRUE;
01467             }
01468             else if(ptrChar == szInput)
01469             {
01470               /* we're at the beginning of the string and still
01471                * nothing found.  So just return the input string. */
01472               strcpy(szOutput, szInput);
01473               bDone = TRUE;
01474             }
01475           }
01476           break;
01477 
01478         case PP_PATH_ONLY:
01479           strcpy(szOutput, szInput);
01480           ulOutputLen = strlen(szOutput);
01481           ptrChar = &szOutput[ulOutputLen];
01482           bDone = FALSE;
01483           while(!bDone)
01484           {
01485             ptrChar = WinPrevChar(0, 0, 0, szOutput, ptrChar);
01486             if(*ptrChar == cDelimiter)
01487             {
01488               *WinNextChar(0, 0, 0, ptrChar) = '\0';
01489               bDone = TRUE;
01490             }
01491             else if(ptrChar == szOutput)
01492             {
01493               /* we're at the beginning of the string and still
01494                * nothing found.  So just return the input string. */
01495               bDone = TRUE;
01496             }
01497           }
01498           break;
01499 
01500         case PP_EXTENSION_ONLY:
01501           /* check the last character first */
01502           ptrChar = WinPrevChar(0, 0, 0, szInput, &szInput[ulInputLen]);
01503           if(*ptrChar == '.')
01504             break;
01505 
01506           bDone = FALSE;
01507           while(!bDone)
01508           {
01509             ptrChar = WinPrevChar(0, 0, 0, szInput, ptrChar);
01510             if(*ptrChar == cDelimiter)
01511               /* found path delimiter before '.' */
01512               bDone = TRUE;
01513             else if(*ptrChar == '.')
01514             {
01515               strcpy(szOutput, WinNextChar(0, 0, 0, ptrChar));
01516               bDone = TRUE;
01517             }
01518             else if(ptrChar == szInput)
01519               bDone = TRUE;
01520           }
01521           break;
01522 
01523         case PP_ROOT_ONLY:
01524           strcpy(szOutput, szInput);
01525           ulOutputLen = strlen(szOutput);
01526           ptrLastChar = WinPrevChar(0, 0, 0, szOutput, &szOutput[ulOutputLen]);
01527           ptrChar     = WinNextChar(0, 0, 0, szOutput);
01528           if(*ptrChar == ':')
01529           {
01530             ptrChar = WinNextChar(0, 0, 0, ptrChar);
01531             *ptrChar = cDelimiter;
01532             *WinNextChar(0, 0, 0, ptrChar) = '\0';
01533           }
01534           else
01535           {
01536             iFoundDelimiter = 0;
01537             ptrChar = szOutput;
01538             while(!bDone)
01539             {
01540               if(*ptrChar == cDelimiter)
01541                 ++iFoundDelimiter;
01542 
01543               if(iFoundDelimiter == 4)
01544               {
01545                 *WinNextChar(0, 0, 0, ptrChar) = '\0';
01546                 bDone = TRUE;
01547               }
01548               else if(ptrChar == ptrLastChar)
01549                 bDone = TRUE;
01550               else
01551                 ptrChar = WinNextChar(0, 0, 0, ptrChar);
01552             }
01553           }
01554           break;
01555       }
01556     }
01557   }
01558 }
01559 
01560 HRESULT LaunchApps()
01561 {
01562   DWORD     dwIndex0;
01563   BOOL      bArchiveFound;
01564   siC       *siCObject = NULL;
01565   char      szArchive[MAX_BUF];
01566   char      szMsg[MAX_BUF];
01567 
01568   LogISLaunchApps(W_START);
01569   if(!GetPrivateProfileString("Messages", "MSG_CONFIGURING", "", szMsg, sizeof(szMsg), szFileIniInstall))
01570     return(1);
01571 
01572   dwIndex0 = 0;
01573   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01574   while(siCObject)
01575   {
01576     /* launch 3rd party executable */
01577     if((siCObject->dwAttributes & SIC_SELECTED) && (siCObject->dwAttributes & SIC_LAUNCHAPP))
01578     {
01579       bArchiveFound = TRUE;
01580       strcpy(szArchive, sgProduct.szAlternateArchiveSearchPath);
01581       AppendBackSlash(szArchive, sizeof(szArchive));
01582       strcat(szArchive, siCObject->szArchiveName);
01583       if((*sgProduct.szAlternateArchiveSearchPath == '\0') || !FileExists(szArchive))
01584       {
01585         strcpy(szArchive, szSetupDir);
01586         AppendBackSlash(szArchive, sizeof(szArchive));
01587         strcat(szArchive, siCObject->szArchiveName);
01588         if(!FileExists(szArchive))
01589         {
01590           strcpy(szArchive, szTempDir);
01591           AppendBackSlash(szArchive, sizeof(szArchive));
01592           strcat(szArchive, siCObject->szArchiveName);
01593           if(!FileExists(szArchive))
01594           {
01595             bArchiveFound = FALSE;
01596           }
01597         }
01598       }
01599 
01600       if(bArchiveFound)
01601       {
01602         char szParameterBuf[MAX_BUF];
01603         char szSpawnFile[MAX_BUF];
01604         char szMessageString[MAX_BUF];
01605         DWORD dwErr = FO_SUCCESS;
01606 
01607         sprintf(szMessageString, szMsg, siCObject->szDescriptionShort);
01608         ShowMessage(szMessageString, TRUE);
01609         DecryptString(szParameterBuf, siCObject->szParameter);
01610 
01611         strcpy(szSpawnFile, szArchive);
01612         if(siCObject->dwAttributes & SIC_UNCOMPRESS)
01613         {
01614           if((dwErr = FileUncompress(szArchive, szTempDir)) == FO_SUCCESS)
01615           {
01616             strcpy(szSpawnFile, szTempDir);
01617             AppendBackSlash(szSpawnFile, sizeof(szSpawnFile));
01618             strcat(szSpawnFile, siCObject->szArchiveNameUncompressed);
01619           }
01620 
01621           LogISLaunchAppsComponentUncompress(siCObject->szDescriptionShort, dwErr);
01622           if(dwErr != FO_SUCCESS)
01623           {
01624             ShowMessage(szMessageString, FALSE);
01625             continue;
01626           }
01627         }
01628 
01629         LogISLaunchAppsComponent(siCObject->szDescriptionShort);
01630         WinSpawn(szSpawnFile, szParameterBuf, szTempDir, TRUE);
01631 
01632         if(siCObject->dwAttributes & SIC_UNCOMPRESS)
01633           FileDelete(szSpawnFile);
01634 
01635         ShowMessage(szMessageString, FALSE);
01636       }
01637     }
01638     ++dwIndex0;
01639     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01640   }
01641 
01642   LogISLaunchApps(W_END);
01643   return(0);
01644 }
01645 
01646 HRESULT ProcessOS2Integration()
01647 {
01648   if (diOS2Integration.oiCBMakeDefaultBrowser.bCheckBoxState == TRUE) {
01649     HOBJECT hObjURL = NULLHANDLE;
01650     CHAR    szSetupString[1000];
01651     CHAR    szTemp[CCHMAXPATH];
01652     strcpy(szSetupString, "OBJECTID=<MOZTEMPCONVERSIONURL>");
01653     sprintf(szTemp, "%s\\%s", sgProduct.szPath, sgProduct.szProgramName);
01654     strcat(szSetupString, ";DEFAULTBROWSER=");
01655     strcat(szSetupString, szTemp) ;
01656     PrfWriteProfileString(HINI_USER,
01657                           "WPURLDEFAULTSETTINGS",
01658                           "DefaultBrowserExe",
01659                           szTemp ) ;
01660 
01661     strcat(szSetupString, ";DEFAULTWORKINGDIR=");
01662     strcat(szSetupString, sgProduct.szPath);
01663     PrfWriteProfileString(HINI_USER,
01664                           "WPURLDEFAULTSETTINGS",
01665                           "DefaultWorkingDir",
01666                           sgProduct.szPath);
01667 
01668     if (hObjURL = WinCreateObject("WPUrl",
01669                                   "Temporary URL",
01670                                   szSetupString,
01671                                   "<WP_NOWHERE>",
01672                                   CO_REPLACEIFEXISTS))
01673     {
01674       WinDestroyObject(hObjURL);
01675     }
01676   }
01677   return(0);
01678 }
01679 
01680 char *GetOSTypeString(char *szOSType, ULONG ulOSTypeBufSize)
01681 {
01682   memset(szOSType, 0, ulOSTypeBufSize);
01683 
01684   if(gSystemInfo.ulOSType & OS_WARP3)
01685     strcpy(szOSType, "Warp 3");
01686   else
01687     strcpy(szOSType, "Warp 4");
01688 
01689   return(szOSType);
01690 }
01691 
01692 void DetermineOSVersionEx()
01693 {
01694   char          szBuf[MAX_BUF];
01695   char          szOSType[MAX_BUF];
01696   ULONG         aulSysInfo[QSV_MAX+1];
01697   APIRET        rc;
01698   ULONG TotPhysMem,TotResMem,TotAvailMem;
01699 
01700   rc = DosQuerySysInfo(1,
01701                        QSV_MAX,
01702                        (PVOID)&aulSysInfo[1],
01703                        sizeof(ULONG)*QSV_MAX);
01704 
01705   if(rc != NO_ERROR)
01706   {
01707     /* DosQuerySysInfo() failed for some reason.  It's not fatal, but could cause
01708      * some complications during installation */
01709     char szEMsg[MAX_BUF_TINY];
01710 
01711     if(GetPrivateProfileString("Messages", "ERROR_GETVERSION", "", szEMsg, sizeof(szEMsg), szFileIniInstall))
01712       PrintError(szEMsg, ERROR_CODE_SHOW);
01713   }
01714 
01715   gSystemInfo.ulOSType = OS_WARP4; /* @MAK - should detect more stuff here */
01716   gSystemInfo.ulMajorVersion = aulSysInfo[QSV_VERSION_MAJOR];
01717   gSystemInfo.ulMinorVersion = aulSysInfo[QSV_VERSION_MINOR];
01718   gSystemInfo.ulBuildNumber  = aulSysInfo[QSV_VERSION_REVISION];
01719   memset(gSystemInfo.szExtraString, 0, sizeof(gSystemInfo.szExtraString));
01720   strcpy(gSystemInfo.szExtraString, "Seriously should be something"); /* @MAK */
01721 
01722   gSystemInfo.ulMemoryTotalPhysical = aulSysInfo[QSV_TOTPHYSMEM]/1024;
01723   gSystemInfo.ulMemoryAvailablePhysical = aulSysInfo[QSV_TOTAVAILMEM]/1024;
01724 
01725   GetOSTypeString(szOSType, sizeof(szOSType));
01726   sprintf(szBuf,
01727 "    System Info:\n\
01728         OS Type: %s\n\
01729         Major Version: %d\n\
01730         Minor Version: %d\n\
01731         Build Number: %d\n\
01732         Extra String: %s\n\
01733         Total Physical Memory: %dKB\n\
01734         Total Available Physical Memory: %dKB\n",
01735            szOSType,
01736            gSystemInfo.ulMajorVersion,
01737            gSystemInfo.ulMinorVersion,
01738            gSystemInfo.ulBuildNumber,
01739            gSystemInfo.szExtraString,
01740            gSystemInfo.ulMemoryTotalPhysical,
01741            gSystemInfo.ulMemoryAvailablePhysical);
01742 
01743   UpdateInstallStatusLog(szBuf);
01744 }
01745 
01746 HRESULT WinSpawn(LPSTR szClientName, LPSTR szParameters, LPSTR szCurrentDir, BOOL bWait)
01747 {
01748   STARTDATA startdata;
01749   PID       pid, endpid;
01750   ULONG     ulSessID;
01751   APIRET rc;
01752   RESULTCODES resultcodes;
01753   ULONG     ulFlags;
01754   
01755   rc = DosQueryAppType(szClientName, &ulFlags);
01756   if (rc == NO_ERROR) {
01757     memset(&startdata, 0, sizeof(STARTDATA));
01758     startdata.Length  = sizeof(STARTDATA);
01759     startdata.PgmName = szClientName;
01760     startdata.PgmInputs = szParameters;
01761     rc = DosStartSession(&startdata, &ulSessID, &pid);
01762     if (rc == NO_ERROR) {
01763       if (bWait) {
01764         DosWaitChild(DCWA_PROCESS, DCWW_NOWAIT, &resultcodes, &endpid, pid);
01765       }
01766       return (TRUE);
01767     }
01768   } else {
01769     CHAR szBuf[CCHMAXPATH];
01770     HOBJECT hobject;
01771     strcpy(szBuf, szCurrentDir);
01772     strcat(szBuf, szClientName);
01773     hobject = WinQueryObject(szBuf);
01774     WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
01775     WinOpenObject(hobject, 0, TRUE); // 0 = OPEN_DEFAULT
01776   }
01777 
01778   return(FALSE);
01779 }
01780 
01781 HRESULT InitDlgWelcome(diW *diDialog)
01782 {
01783   diDialog->bShowDialog = FALSE;
01784   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01785     return(1);
01786   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01787     return(1);
01788   if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01789     return(1);
01790   if((diDialog->szMessage2 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01791     return(1);
01792 
01793   return(0);
01794 }
01795 
01796 void DeInitDlgWelcome(diW *diDialog)
01797 {
01798   FreeMemory(&(diDialog->szTitle));
01799   FreeMemory(&(diDialog->szMessage0));
01800   FreeMemory(&(diDialog->szMessage1));
01801   FreeMemory(&(diDialog->szMessage2));
01802 }
01803 
01804 HRESULT InitDlgLicense(diL *diDialog)
01805 {
01806   diDialog->bShowDialog = FALSE;
01807   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01808     return(1);
01809   if((diDialog->szLicenseFilename = NS_GlobalAlloc(MAX_BUF)) == NULL)
01810     return(1);
01811   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01812     return(1);
01813   if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01814     return(1);
01815 
01816   return(0);
01817 }
01818 
01819 void DeInitDlgLicense(diL *diDialog)
01820 {
01821   FreeMemory(&(diDialog->szTitle));
01822   FreeMemory(&(diDialog->szLicenseFilename));
01823   FreeMemory(&(diDialog->szMessage0));
01824   FreeMemory(&(diDialog->szMessage1));
01825 }
01826 
01827 HRESULT InitDlgQuickLaunch(diQL *diDialog)
01828 {
01829   diDialog->bTurboMode         = FALSE;
01830   diDialog->bTurboModeEnabled  = FALSE;
01831   diDialog->bShowDialog = FALSE;
01832   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01833     return(1);
01834   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01835     return(1);
01836   if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01837     return(1);
01838   if((diDialog->szMessage2 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01839     return(1);
01840 
01841   return(0);
01842 }
01843 
01844 void DeInitDlgQuickLaunch(diQL *diDialog)
01845 {
01846   FreeMemory(&(diDialog->szTitle));
01847   FreeMemory(&(diDialog->szMessage0));
01848   FreeMemory(&(diDialog->szMessage1));
01849   FreeMemory(&(diDialog->szMessage2));
01850 }
01851 
01852 HRESULT InitDlgSetupType(diST *diDialog)
01853 {
01854   diDialog->bShowDialog = FALSE;
01855 
01856   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01857     return(1);
01858   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01859     return(1);
01860   if((diDialog->szReadmeFilename = NS_GlobalAlloc(MAX_BUF)) == NULL)
01861     return(1);
01862   if((diDialog->szReadmeApp = NS_GlobalAlloc(MAX_BUF)) == NULL)
01863     return(1);
01864 
01865   diDialog->stSetupType0.dwCItems = 0;
01866   diDialog->stSetupType1.dwCItems = 0;
01867   diDialog->stSetupType2.dwCItems = 0;
01868   diDialog->stSetupType3.dwCItems = 0;
01869   if((diDialog->stSetupType0.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL)
01870     return(1);
01871   if((diDialog->stSetupType0.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL)
01872     return(1);
01873 
01874   if((diDialog->stSetupType1.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL)
01875     return(1);
01876   if((diDialog->stSetupType1.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL)
01877     return(1);
01878 
01879   if((diDialog->stSetupType2.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL)
01880     return(1);
01881   if((diDialog->stSetupType2.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL)
01882     return(1);
01883 
01884   if((diDialog->stSetupType3.szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL)
01885     return(1);
01886   if((diDialog->stSetupType3.szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL)
01887     return(1);
01888 
01889   return(0);
01890 }
01891 
01892 void DeInitDlgSetupType(diST *diDialog)
01893 {
01894   FreeMemory(&(diDialog->szTitle));
01895   FreeMemory(&(diDialog->szMessage0));
01896 
01897   FreeMemory(&(diDialog->szReadmeFilename));
01898   FreeMemory(&(diDialog->szReadmeApp));
01899   FreeMemory(&(diDialog->stSetupType0.szDescriptionShort));
01900   FreeMemory(&(diDialog->stSetupType0.szDescriptionLong));
01901   FreeMemory(&(diDialog->stSetupType1.szDescriptionShort));
01902   FreeMemory(&(diDialog->stSetupType1.szDescriptionLong));
01903   FreeMemory(&(diDialog->stSetupType2.szDescriptionShort));
01904   FreeMemory(&(diDialog->stSetupType2.szDescriptionLong));
01905   FreeMemory(&(diDialog->stSetupType3.szDescriptionShort));
01906   FreeMemory(&(diDialog->stSetupType3.szDescriptionLong));
01907 }
01908 
01909 HRESULT InitDlgSelectComponents(diSC *diDialog, DWORD dwSM)
01910 {
01911   diDialog->bShowDialog = FALSE;
01912 
01913   /* set to show the Single dialog or the Multi dialog for the SelectComponents dialog */
01914   diDialog->bShowDialogSM = dwSM;
01915   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01916     return(1);
01917   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01918     return(1);
01919 
01920   return(0);
01921 }
01922 
01923 void DeInitDlgSelectComponents(diSC *diDialog)
01924 {
01925   FreeMemory(&(diDialog->szTitle));
01926   FreeMemory(&(diDialog->szMessage0));
01927 }
01928 
01929 HRESULT InitDlgOS2Integration(diOI *diDialog)
01930 {
01931   diDialog->bShowDialog = FALSE;
01932   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01933     exit(1);
01934   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01935     exit(1);
01936   if((diDialog->szMessage1 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01937     exit(1);
01938   if((diDialog->szHomeDirectory = NS_GlobalAlloc(MAX_BUF)) == NULL)
01939     exit(1);
01940 
01941   diDialog->oiCBMakeDefaultBrowser.bEnabled = FALSE;
01942   diDialog->oiCBAssociateHTML.bEnabled = FALSE;
01943   diDialog->oiCBUpdateCONFIGSYS.bEnabled = FALSE;
01944 
01945   diDialog->oiCBMakeDefaultBrowser.bCheckBoxState = FALSE;
01946   diDialog->oiCBAssociateHTML.bCheckBoxState = FALSE;
01947   diDialog->oiCBUpdateCONFIGSYS.bCheckBoxState = FALSE;
01948 
01949   if((diDialog->oiCBMakeDefaultBrowser.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL)
01950     return(1);
01951   if((diDialog->oiCBAssociateHTML.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL)
01952     return(1);
01953   if((diDialog->oiCBUpdateCONFIGSYS.szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL)
01954     return(1);
01955 
01956   return(0);
01957 }
01958 
01959 void DeInitDlgOS2Integration(diOI *diDialog)
01960 {
01961   FreeMemory(&(diDialog->szTitle));
01962   FreeMemory(&(diDialog->szMessage0));
01963   FreeMemory(&(diDialog->szMessage1));
01964   FreeMemory(&(diDialog->szHomeDirectory));
01965 
01966   FreeMemory(&(diDialog->oiCBMakeDefaultBrowser.szDescription));
01967   FreeMemory(&(diDialog->oiCBAssociateHTML.szDescription));
01968   FreeMemory(&(diDialog->oiCBUpdateCONFIGSYS.szDescription));
01969 }
01970 
01971 HRESULT InitDlgProgramFolder(diPF *diDialog)
01972 {
01973   diDialog->bShowDialog = FALSE;
01974   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
01975     return(1);
01976   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
01977     return(1);
01978 
01979   return(0);
01980 }
01981 
01982 void DeInitDlgProgramFolder(diPF *diDialog)
01983 {
01984   FreeMemory(&(diDialog->szTitle));
01985   FreeMemory(&(diDialog->szMessage0));
01986 }
01987 
01988 HRESULT InitDlgAdditionalOptions(diDO *diDialog)
01989 {
01990   diDialog->bShowDialog           = FALSE;
01991   diDialog->bSaveInstaller        = FALSE;
01992   diDialog->bRecaptureHomepage    = FALSE;
01993   diDialog->bShowHomepageOption   = FALSE;
01994   diDialog->dwUseProtocol         = UP_FTP;
01995   diDialog->bUseProtocolSettings  = TRUE;
01996   diDialog->bShowProtocols        = TRUE;
01997   if((diDialog->szTitle           = NS_GlobalAlloc(MAX_BUF)) == NULL)
01998     return(1);
01999   if((diDialog->szMessage0        = NS_GlobalAlloc(MAX_BUF)) == NULL)
02000     return(1);
02001   if((diDialog->szMessage1        = NS_GlobalAlloc(MAX_BUF)) == NULL)
02002     return(1);
02003 
02004   return(0);
02005 }
02006 
02007 void DeInitDlgAdditionalOptions(diDO *diDialog)
02008 {
02009   FreeMemory(&(diDialog->szTitle));
02010   FreeMemory(&(diDialog->szMessage0));
02011   FreeMemory(&(diDialog->szMessage1));
02012 }
02013 
02014 HRESULT InitDlgAdvancedSettings(diAS *diDialog)
02015 {
02016   diDialog->bShowDialog       = FALSE;
02017   if((diDialog->szTitle       = NS_GlobalAlloc(MAX_BUF)) == NULL)
02018     return(1);
02019   if((diDialog->szMessage0    = NS_GlobalAlloc(MAX_BUF)) == NULL)
02020     return(1);
02021   if((diDialog->szProxyServer = NS_GlobalAlloc(MAX_BUF)) == NULL)
02022     return(1);
02023   if((diDialog->szProxyPort   = NS_GlobalAlloc(MAX_BUF)) == NULL)
02024     return(1);
02025   if((diDialog->szProxyUser   = NS_GlobalAlloc(MAX_BUF)) == NULL)
02026     return(1);
02027   if((diDialog->szProxyPasswd = NS_GlobalAlloc(MAX_BUF)) == NULL)
02028     return(1);
02029 
02030   return(0);
02031 }
02032 
02033 void DeInitDlgAdvancedSettings(diAS *diDialog)
02034 {
02035   FreeMemory(&(diDialog->szTitle));
02036   FreeMemory(&(diDialog->szMessage0));
02037   FreeMemory(&(diDialog->szProxyServer));
02038   FreeMemory(&(diDialog->szProxyPort));
02039   FreeMemory(&(diDialog->szProxyUser));
02040   FreeMemory(&(diDialog->szProxyPasswd));
02041 }
02042 
02043 HRESULT InitDlgStartInstall(diSI *diDialog)
02044 {
02045   diDialog->bShowDialog        = FALSE;
02046   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
02047     return(1);
02048   if((diDialog->szMessageInstall = NS_GlobalAlloc(MAX_BUF)) == NULL)
02049     return(1);
02050   if((diDialog->szMessageDownload = NS_GlobalAlloc(MAX_BUF)) == NULL)
02051     return(1);
02052 
02053   return(0);
02054 }
02055 
02056 void DeInitDlgStartInstall(diSI *diDialog)
02057 {
02058   FreeMemory(&(diDialog->szTitle));
02059   FreeMemory(&(diDialog->szMessageInstall));
02060   FreeMemory(&(diDialog->szMessageDownload));
02061 }
02062 
02063 HRESULT InitDlgDownload(diD *diDialog)
02064 {
02065   diDialog->bShowDialog = FALSE;
02066   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF_TINY)) == NULL)
02067     return(1);
02068   if((diDialog->szMessageDownload0 = NS_GlobalAlloc(MAX_BUF_MEDIUM)) == NULL)
02069     return(1);
02070   if((diDialog->szMessageRetry0 = NS_GlobalAlloc(MAX_BUF_MEDIUM)) == NULL)
02071     return(1);
02072 
02073   return(0);
02074 }
02075 
02076 void DeInitDlgDownload(diD *diDialog)
02077 {
02078   FreeMemory(&(diDialog->szTitle));
02079   FreeMemory(&(diDialog->szMessageDownload0));
02080   FreeMemory(&(diDialog->szMessageRetry0));
02081 }
02082 
02083 ULONG InitDlgReboot(diR *diDialog)
02084 {
02085   diDialog->dwShowDialog = FALSE;
02086   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF_MEDIUM)) == NULL)
02087     return(1);
02088   GetPrivateProfileString("Messages", "DLG_REBOOT_TITLE", "", diDialog->szTitle, MAX_BUF_MEDIUM, szFileIniInstall);
02089 
02090   return(0);
02091 }
02092 
02093 void DeInitDlgReboot(diR *diDialog)
02094 {
02095   FreeMemory(&(diDialog->szTitle));
02096 }
02097 
02098 HRESULT InitSetupGeneral()
02099 {
02100   char szBuf[MAX_BUF];
02101 
02102   sgProduct.ulMode               = NORMAL;
02103   sgProduct.ulCustomType         = ST_RADIO0;
02104   sgProduct.ulNumberOfComponents = 0;
02105   sgProduct.bLockPath            = FALSE;
02106 
02107   if((sgProduct.szPath                        = NS_GlobalAlloc(MAX_BUF)) == NULL)
02108     return(1);
02109   if((sgProduct.szSubPath                     = NS_GlobalAlloc(MAX_BUF)) == NULL)
02110     return(1);
02111   if((sgProduct.szProgramName                 = NS_GlobalAlloc(MAX_BUF)) == NULL)
02112     return(1);
02113   if((sgProduct.szCompanyName                 = NS_GlobalAlloc(MAX_BUF)) == NULL)
02114     return(1);
02115   if((sgProduct.szProductName                 = NS_GlobalAlloc(MAX_BUF)) == NULL)
02116     return(1);
02117   if((sgProduct.szProductNameInternal         = NS_GlobalAlloc(MAX_BUF)) == NULL)
02118     return(1);
02119   if((sgProduct.szProductNamePrevious         = NS_GlobalAlloc(MAX_BUF)) == NULL)
02120     return(1);
02121   if((sgProduct.szUninstallFilename           = NS_GlobalAlloc(MAX_BUF)) == NULL)
02122     return(1);
02123   if((sgProduct.szUserAgent                   = NS_GlobalAlloc(MAX_BUF)) == NULL)
02124     return(1);
02125   if((sgProduct.szProgramFolderName           = NS_GlobalAlloc(MAX_BUF)) == NULL)
02126     return(1);
02127   if((sgProduct.szProgramFolderPath           = NS_GlobalAlloc(MAX_BUF)) == NULL)
02128     return(1);
02129   if((sgProduct.szAlternateArchiveSearchPath  = NS_GlobalAlloc(MAX_BUF)) == NULL)
02130     return(1);
02131   if((sgProduct.szParentProcessFilename       = NS_GlobalAlloc(MAX_BUF)) == NULL)
02132     return(1);
02133   if((szTempSetupPath                         = NS_GlobalAlloc(MAX_BUF)) == NULL)
02134     return(1);
02135 
02136   if((szSiteSelectorDescription               = NS_GlobalAlloc(MAX_BUF)) == NULL)
02137     return(1);
02138 
02139   if(GetPrivateProfileString("Messages", "CB_DEFAULT", "", szBuf, sizeof(szBuf), szFileIniInstall))
02140     strcpy(szSiteSelectorDescription, szBuf);
02141 
02142   return(0);
02143 }
02144 
02145 void DeInitSetupGeneral()
02146 {
02147   FreeMemory(&(sgProduct.szPath));
02148   FreeMemory(&(sgProduct.szSubPath));
02149   FreeMemory(&(sgProduct.szProgramName));
02150   FreeMemory(&(sgProduct.szCompanyName));
02151   FreeMemory(&(sgProduct.szProductName));
02152   FreeMemory(&(sgProduct.szProductNameInternal));
02153   FreeMemory(&(sgProduct.szProductNamePrevious));
02154   FreeMemory(&(sgProduct.szUninstallFilename));
02155   FreeMemory(&(sgProduct.szUserAgent));
02156   FreeMemory(&(sgProduct.szProgramFolderName));
02157   FreeMemory(&(sgProduct.szProgramFolderPath));
02158   FreeMemory(&(sgProduct.szAlternateArchiveSearchPath));
02159   FreeMemory(&(sgProduct.szParentProcessFilename));
02160   FreeMemory(&(szTempSetupPath));
02161   FreeMemory(&(szSiteSelectorDescription));
02162 }
02163 
02164 HRESULT InitSXpcomFile()
02165 {
02166   if((siCFXpcomFile.szSource = NS_GlobalAlloc(MAX_BUF)) == NULL)
02167     return(1);
02168   if((siCFXpcomFile.szDestination = NS_GlobalAlloc(MAX_BUF)) == NULL)
02169     return(1);
02170   if((siCFXpcomFile.szMessage = NS_GlobalAlloc(MAX_BUF)) == NULL)
02171     return(1);
02172 
02173   siCFXpcomFile.bCleanup         = TRUE;
02174   siCFXpcomFile.ulInstallSize   = 0;
02175   return(0);
02176 }
02177 
02178 void DeInitSXpcomFile()
02179 {
02180   FreeMemory(&(siCFXpcomFile.szSource));
02181   FreeMemory(&(siCFXpcomFile.szDestination));
02182   FreeMemory(&(siCFXpcomFile.szMessage));
02183 }
02184 
02185 siC *CreateSiCNode()
02186 {
02187   siC *siCNode;
02188 
02189   if((siCNode = NS_GlobalAlloc(sizeof(struct sinfoComponent))) == NULL)
02190     exit(1);
02191 
02192   siCNode->dwAttributes             = 0;
02193   siCNode->ulInstallSize           = 0;
02194   siCNode->ulInstallSizeSystem     = 0;
02195   siCNode->ulInstallSizeArchive    = 0;
02196   siCNode->lRandomInstallPercentage = 0;
02197   siCNode->lRandomInstallValue      = 0;
02198   siCNode->bForceUpgrade            = FALSE;
02199 
02200   if((siCNode->szArchiveName = NS_GlobalAlloc(MAX_BUF)) == NULL)
02201     exit(1);
02202   if((siCNode->szArchiveNameUncompressed = NS_GlobalAlloc(MAX_BUF)) == NULL)
02203     exit(1);
02204   if((siCNode->szArchivePath = NS_GlobalAlloc(MAX_BUF)) == NULL)
02205     exit(1);
02206   if((siCNode->szDestinationPath = NS_GlobalAlloc(MAX_BUF)) == NULL)
02207     exit(1);
02208   if((siCNode->szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL)
02209     exit(1);
02210   if((siCNode->szDescriptionLong = NS_GlobalAlloc(MAX_BUF)) == NULL)
02211     exit(1);
02212   if((siCNode->szParameter = NS_GlobalAlloc(MAX_BUF)) == NULL)
02213     exit(1);
02214   if((siCNode->szReferenceName = NS_GlobalAlloc(MAX_BUF)) == NULL)
02215     exit(1);
02216 
02217   siCNode->iNetRetries      = 0;
02218   siCNode->iCRCRetries      = 0;
02219   siCNode->iNetTimeOuts     = 0;
02220   siCNode->siCDDependencies = NULL;
02221   siCNode->siCDDependees    = NULL;
02222   siCNode->Next             = NULL;
02223   siCNode->Prev             = NULL;
02224 
02225   return(siCNode);
02226 }
02227 
02228 void SiCNodeInsert(siC **siCHead, siC *siCTemp)
02229 {
02230   if(*siCHead == NULL)
02231   {
02232     *siCHead          = siCTemp;
02233     (*siCHead)->Next  = *siCHead;
02234     (*siCHead)->Prev  = *siCHead;
02235   }
02236   else
02237   {
02238     siCTemp->Next           = *siCHead;
02239     siCTemp->Prev           = (*siCHead)->Prev;
02240     (*siCHead)->Prev->Next  = siCTemp;
02241     (*siCHead)->Prev        = siCTemp;
02242   }
02243 }
02244 
02245 void SiCNodeDelete(siC *siCTemp)
02246 {
02247   if(siCTemp != NULL)
02248   {
02249     DeInitSiCDependencies(siCTemp->siCDDependencies);
02250     DeInitSiCDependencies(siCTemp->siCDDependees);
02251 
02252     siCTemp->Next->Prev = siCTemp->Prev;
02253     siCTemp->Prev->Next = siCTemp->Next;
02254     siCTemp->Next       = NULL;
02255     siCTemp->Prev       = NULL;
02256 
02257     FreeMemory(&(siCTemp->szDestinationPath));
02258     FreeMemory(&(siCTemp->szArchivePath));
02259     FreeMemory(&(siCTemp->szArchiveName));
02260     FreeMemory(&(siCTemp->szArchiveNameUncompressed));
02261     FreeMemory(&(siCTemp->szParameter));
02262     FreeMemory(&(siCTemp->szReferenceName));
02263     FreeMemory(&(siCTemp->szDescriptionLong));
02264     FreeMemory(&(siCTemp->szDescriptionShort));
02265     FreeMemory(&siCTemp);
02266   }
02267 }
02268 
02269 siCD *CreateSiCDepNode()
02270 {
02271   siCD *siCDepNode;
02272 
02273   if((siCDepNode = NS_GlobalAlloc(sizeof(struct sinfoComponentDep))) == NULL)
02274     exit(1);
02275 
02276   if((siCDepNode->szDescriptionShort = NS_GlobalAlloc(MAX_BUF)) == NULL)
02277     exit(1);
02278   if((siCDepNode->szReferenceName = NS_GlobalAlloc(MAX_BUF)) == NULL)
02279     exit(1);
02280   siCDepNode->Next = NULL;
02281   siCDepNode->Prev = NULL;
02282 
02283   return(siCDepNode);
02284 }
02285 
02286 void SiCDepNodeInsert(siCD **siCDepHead, siCD *siCDepTemp)
02287 {
02288   if(*siCDepHead == NULL)
02289   {
02290     *siCDepHead          = siCDepTemp;
02291     (*siCDepHead)->Next  = *siCDepHead;
02292     (*siCDepHead)->Prev  = *siCDepHead;
02293   }
02294   else
02295   {
02296     siCDepTemp->Next           = *siCDepHead;
02297     siCDepTemp->Prev           = (*siCDepHead)->Prev;
02298     (*siCDepHead)->Prev->Next  = siCDepTemp;
02299     (*siCDepHead)->Prev        = siCDepTemp;
02300   }
02301 }
02302 
02303 void SiCDepNodeDelete(siCD *siCDepTemp)
02304 {
02305   if(siCDepTemp != NULL)
02306   {
02307     siCDepTemp->Next->Prev = siCDepTemp->Prev;
02308     siCDepTemp->Prev->Next = siCDepTemp->Next;
02309     siCDepTemp->Next       = NULL;
02310     siCDepTemp->Prev       = NULL;
02311 
02312     FreeMemory(&(siCDepTemp->szDescriptionShort));
02313     FreeMemory(&(siCDepTemp->szReferenceName));
02314     FreeMemory(&siCDepTemp);
02315   }
02316 }
02317 
02318 ssi *CreateSsiSiteSelectorNode()
02319 {
02320   ssi *ssiNode;
02321 
02322   if((ssiNode = NS_GlobalAlloc(sizeof(struct ssInfo))) == NULL)
02323     exit(1);
02324   if((ssiNode->szDescription = NS_GlobalAlloc(MAX_BUF)) == NULL)
02325     exit(1);
02326   if((ssiNode->szDomain = NS_GlobalAlloc(MAX_BUF)) == NULL)
02327     exit(1);
02328   if((ssiNode->szIdentifier = NS_GlobalAlloc(MAX_BUF)) == NULL)
02329     exit(1);
02330 
02331   ssiNode->Next = NULL;
02332   ssiNode->Prev = NULL;
02333 
02334   return(ssiNode);
02335 }
02336 
02337 void SsiSiteSelectorNodeInsert(ssi **ssiHead, ssi *ssiTemp)
02338 {
02339   if(*ssiHead == NULL)
02340   {
02341     *ssiHead          = ssiTemp;
02342     (*ssiHead)->Next  = *ssiHead;
02343     (*ssiHead)->Prev  = *ssiHead;
02344   }
02345   else
02346   {
02347     ssiTemp->Next           = *ssiHead;
02348     ssiTemp->Prev           = (*ssiHead)->Prev;
02349     (*ssiHead)->Prev->Next  = ssiTemp;
02350     (*ssiHead)->Prev        = ssiTemp;
02351   }
02352 }
02353 
02354 void SsiSiteSelectorNodeDelete(ssi *ssiTemp)
02355 {
02356   if(ssiTemp != NULL)
02357   {
02358     ssiTemp->Next->Prev = ssiTemp->Prev;
02359     ssiTemp->Prev->Next = ssiTemp->Next;
02360     ssiTemp->Next       = NULL;
02361     ssiTemp->Prev       = NULL;
02362 
02363     FreeMemory(&(ssiTemp->szDescription));
02364     FreeMemory(&(ssiTemp->szDomain));
02365     FreeMemory(&(ssiTemp->szIdentifier));
02366     FreeMemory(&ssiTemp);
02367   }
02368 }
02369 
02370 HRESULT SiCNodeGetAttributes(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02371 {
02372   DWORD dwCount = 0;
02373   siC   *siCTemp = siComponents;
02374 
02375   if(siCTemp != NULL)
02376   {
02377     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02378        ((dwACFlag == AC_ALL) ||
02379        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02380        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02381     {
02382       if(dwIndex == 0)
02383         return(siCTemp->dwAttributes);
02384 
02385       ++dwCount;
02386     }
02387 
02388     siCTemp = siCTemp->Next;
02389     while((siCTemp != NULL) && (siCTemp != siComponents))
02390     {
02391       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02392          ((dwACFlag == AC_ALL) ||
02393          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02394          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02395       {
02396         if(dwIndex == dwCount)
02397           return(siCTemp->dwAttributes);
02398 
02399         ++dwCount;
02400       }
02401       
02402       siCTemp = siCTemp->Next;
02403     }
02404   }
02405   return(-1);
02406 }
02407 
02408 void SiCNodeSetAttributes(DWORD dwIndex, DWORD dwAttributes, BOOL bSet, BOOL bIncludeInvisible, DWORD dwACFlag, HWND hwndListBox)
02409 {
02410   DWORD dwCount        = 0;
02411   DWORD dwVisibleIndex = 0;
02412   siC   *siCTemp       = siComponents;
02413 
02414   LPSTR szTmpString;
02415   TCHAR tchBuffer[MAX_BUF];
02416 
02417   if(siCTemp != NULL)
02418   {
02419     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02420        ((dwACFlag == AC_ALL) ||
02421        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02422        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02423     {
02424       if(dwIndex == 0)
02425       {
02426         if(bSet)
02427           siCTemp->dwAttributes |= dwAttributes;
02428         else
02429           siCTemp->dwAttributes &= ~dwAttributes;
02430       }
02431 
02432       ++dwCount;
02433       if(!(siCTemp->dwAttributes & SIC_INVISIBLE))
02434         ++dwVisibleIndex;
02435     }
02436 
02437     siCTemp = siCTemp->Next;
02438     while((siCTemp != NULL) && (siCTemp != siComponents))
02439     {
02440       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02441          ((dwACFlag == AC_ALL) ||
02442          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02443          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02444       {
02445         if(dwIndex == dwCount)
02446         {
02447           if(bSet)
02448             siCTemp->dwAttributes |= dwAttributes;
02449           else
02450             siCTemp->dwAttributes &= ~dwAttributes;
02451         }
02452 
02453         ++dwCount;
02454         if(!(siCTemp->dwAttributes & SIC_INVISIBLE))
02455           ++dwVisibleIndex;
02456       }
02457 
02458       siCTemp = siCTemp->Next;
02459     }
02460   }
02461 }
02462 
02463 BOOL IsInList(DWORD dwCurrentItem, DWORD dwItems, DWORD *dwItemsSelected)
02464 {
02465   DWORD i;
02466 
02467   for(i = 0; i < dwItems; i++)
02468   {
02469     if(dwItemsSelected[i] == dwCurrentItem)
02470       return(TRUE);
02471   }
02472 
02473   return(FALSE);
02474 }
02475 
02476 void RestoreInvisibleFlag(siC *siCNode)
02477 {
02478   char szBuf[MAX_BUF_TINY];
02479   char szAttribute[MAX_BUF_TINY];
02480 
02481   GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig);
02482   strcpy(szAttribute, szBuf);
02483   strupr(szAttribute);
02484 
02485   if(strstr(szAttribute, "INVISIBLE") || siCNode->bSupersede)
02486     siCNode->dwAttributes |= SIC_INVISIBLE;
02487   else
02488     siCNode->dwAttributes &= ~SIC_INVISIBLE;
02489 }
02490 
02491 void RestoreAdditionalFlag(siC *siCNode)
02492 {
02493   char szBuf[MAX_BUF_TINY];
02494   char szAttribute[MAX_BUF_TINY];
02495 
02496   GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig);
02497   strcpy(szAttribute, szBuf);
02498   strupr(szAttribute);
02499 
02500   if(strstr(szAttribute, "ADDITIONAL") && !strstr(szAttribute, "NOTADDITIONAL"))
02501     siCNode->dwAttributes |= SIC_ADDITIONAL;
02502   else
02503     siCNode->dwAttributes &= ~SIC_ADDITIONAL;
02504 }
02505 
02506 
02507 //  This function:
02508 //  - Zeros the SELECTED and ADDITIONAL attributes of all components.
02509 //  - Set all attributes as specified for the specific Setup Type
02510 //  - Overrides attributes designated in any [Component XXX-Overwrite-Setup TypeX]
02511 //    sections for the specific Setup Type.
02512 void SiCNodeSetItemsSelected(DWORD dwSetupType)
02513 {
02514   siC  *siCNode;
02515   char szBuf[MAX_BUF];
02516   char szSTSection[MAX_BUF];
02517   char szComponentKey[MAX_BUF];
02518   char szComponentSection[MAX_BUF];
02519   char szOverrideSection[MAX_BUF];
02520   char szOverrideAttributes[MAX_BUF];
02521   DWORD dwIndex0;
02522 
02523   strcpy(szSTSection, "Setup Type");
02524   _itoa(dwSetupType, szBuf, 10);
02525   strcat(szSTSection, szBuf);
02526 
02527   // For each component in the global list unset its SELECTED and ADDITIONAL attributes
02528   siCNode = siComponents;
02529   do
02530   {
02531     if(siCNode == NULL)
02532       break;
02533 
02534     /* clear these flags for all components so they can be
02535      * reset later if they belong to the setup type the user
02536      * selected */
02537     siCNode->dwAttributes &= ~SIC_SELECTED;
02538     siCNode->dwAttributes &= ~SIC_ADDITIONAL;
02539     siCNode->dwAttributes |= SIC_INVISIBLE;
02540 
02541     /* Force Upgrade needs to be performed here because the user has just
02542      * selected the destination path for the product.  The destination path is
02543      * critical to the checking of the Force Upgrade. */
02544     ResolveForceUpgrade(siCNode);
02545     ResolveSupersede(siCNode);
02546     siCNode = siCNode->Next;
02547   } while((siCNode != NULL) && (siCNode != siComponents));
02548 
02549   /* for each component in a setup type, set its ATTRIBUTES to the right values */
02550   dwIndex0 = 0;
02551   sprintf(szComponentKey, "C%d", dwIndex0);
02552   GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIniConfig);
02553   while(*szComponentSection != '\0')
02554   {
02555     if((siCNode = SiCNodeFind(siComponents, szComponentSection)) != NULL)
02556     {
02557       /* Component is in the Setup Type the user selected, so we now need to
02558        * reset the INVISIBLE and ADDITIONAL flags because they were unset
02559        * above and also are not reset anywhere else. */
02560       RestoreInvisibleFlag(siCNode);
02561       RestoreAdditionalFlag(siCNode);
02562 
02563       sprintf(szOverrideSection, "%s-Override-%s", siCNode->szReferenceName, szSTSection);
02564       GetPrivateProfileString(szOverrideSection, "Attributes", "", szOverrideAttributes, sizeof(szOverrideAttributes), szFileIniConfig);
02565 
02566       if((siCNode->lRandomInstallPercentage != 0) &&
02567          (siCNode->lRandomInstallPercentage <= siCNode->lRandomInstallValue) &&
02568          !(siCNode->dwAttributes & SIC_DISABLED))
02569       {
02570         /* Random Install Percentage check passed *and* the component
02571          * is not DISABLED */
02572         if(*szOverrideAttributes != '\0')
02573           siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE);
02574         siCNode->dwAttributes &= ~SIC_SELECTED;
02575       }
02576       else if(sgProduct.ulCustomType != dwSetupType)
02577       {
02578         /* Setup Type other than custom detected, so
02579          * make sure all components from this Setup Type
02580          * is selected (regardless if it's DISABLED or not). 
02581          * Don't select components that are Superseded */
02582         if(!siCNode->bSupersede)
02583           siCNode->dwAttributes |= SIC_SELECTED;
02584 
02585         if(*szOverrideAttributes != '\0')
02586           siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE);
02587       }
02588       else if(!(siCNode->dwAttributes & SIC_DISABLED) && !siCNode->bForceUpgrade && !siCNode->bSupersede)
02589       {
02590         /* Custom setup type detected and the component is
02591          * not DISABLED and FORCE_UPGRADE.  Reset the component's 
02592          * attribute to default.  If the component is DISABLED and
02593          * happens not be SELECTED in the config.ini file, we leave
02594          * it as is.  The user will see the component in the Options
02595          * Dialogs as not selected and DISABLED.  Not sure why we
02596          * want this, but marketing might find it useful someday. */
02597 
02598         GetPrivateProfileString(siCNode->szReferenceName, "Attributes", "", szBuf, sizeof(szBuf), szFileIniConfig);
02599         siCNode->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE);
02600         if(*szOverrideAttributes != '\0')
02601           siCNode->dwAttributes = ParseComponentAttributes(szOverrideAttributes, siCNode->dwAttributes, TRUE);
02602       }
02603     }
02604 
02605     ++dwIndex0;
02606     sprintf(szComponentKey, "C%d", dwIndex0);
02607     GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIniConfig);
02608   }
02609 }
02610 
02611 char *SiCNodeGetReferenceName(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02612 {
02613   DWORD dwCount = 0;
02614   siC   *siCTemp = siComponents;
02615 
02616   if(siCTemp != NULL)
02617   {
02618     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02619        ((dwACFlag == AC_ALL) ||
02620        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02621        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02622     {
02623       if(dwIndex == 0)
02624         return(siCTemp->szReferenceName);
02625 
02626       ++dwCount;
02627     }
02628 
02629     siCTemp = siCTemp->Next;
02630     while((siCTemp != NULL) && (siCTemp != siComponents))
02631     {
02632       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02633          ((dwACFlag == AC_ALL) ||
02634          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02635          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02636       {
02637         if(dwIndex == dwCount)
02638           return(siCTemp->szReferenceName);
02639       
02640         ++dwCount;
02641       }
02642 
02643       siCTemp = siCTemp->Next;
02644     }
02645   }
02646   return(NULL);
02647 }
02648 
02649 char *SiCNodeGetDescriptionShort(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02650 {
02651   DWORD dwCount = 0;
02652   siC   *siCTemp = siComponents;
02653 
02654   if(siCTemp != NULL)
02655   {
02656     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02657        ((dwACFlag == AC_ALL) ||
02658        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02659        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02660     {
02661       if(dwIndex == 0)
02662         return(siCTemp->szDescriptionShort);
02663 
02664       ++dwCount;
02665     }
02666 
02667     siCTemp = siCTemp->Next;
02668     while((siCTemp != NULL) && (siCTemp != siComponents))
02669     {
02670       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02671          ((dwACFlag == AC_ALL) ||
02672          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02673          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02674       {
02675         if(dwIndex == dwCount)
02676           return(siCTemp->szDescriptionShort);
02677       
02678         ++dwCount;
02679       }
02680 
02681       siCTemp = siCTemp->Next;
02682     }
02683   }
02684   return(NULL);
02685 }
02686 
02687 char *SiCNodeGetDescriptionLong(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02688 {
02689   DWORD dwCount = 0;
02690   siC   *siCTemp = siComponents;
02691 
02692   if(siCTemp != NULL)
02693   {
02694     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02695        ((dwACFlag == AC_ALL) ||
02696        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02697        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02698     {
02699       if(dwIndex == 0)
02700         return(siCTemp->szDescriptionLong);
02701 
02702       ++dwCount;
02703     }
02704 
02705     siCTemp = siCTemp->Next;
02706     while((siCTemp != NULL) && (siCTemp != siComponents))
02707     {
02708       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02709          ((dwACFlag == AC_ALL) ||
02710          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02711          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02712       {
02713         if(dwIndex == dwCount)
02714           return(siCTemp->szDescriptionLong);
02715       
02716         ++dwCount;
02717       }
02718 
02719       siCTemp = siCTemp->Next;
02720     }
02721   }
02722   return(NULL);
02723 }
02724 
02725 unsigned long long SiCNodeGetInstallSize(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02726 {
02727   DWORD dwCount   = 0;
02728   siC   *siCTemp  = siComponents;
02729 
02730   if(siCTemp != NULL)
02731   {
02732     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02733        ((dwACFlag == AC_ALL) ||
02734        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02735        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02736     {
02737       if(dwIndex == 0)
02738         return(siCTemp->ulInstallSize);
02739 
02740       ++dwCount;
02741     }
02742     
02743     siCTemp = siCTemp->Next;
02744     while((siCTemp != NULL) && (siCTemp != siComponents))
02745     {
02746       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02747          ((dwACFlag == AC_ALL) ||
02748          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02749          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02750       {
02751         if(dwIndex == dwCount)
02752           return(siCTemp->ulInstallSize);
02753       
02754         ++dwCount;
02755       }
02756       
02757       siCTemp = siCTemp->Next;
02758     }
02759   }
02760   return(0L);
02761 }
02762 
02763 unsigned long long SiCNodeGetInstallSizeSystem(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02764 {
02765   DWORD dwCount   = 0;
02766   siC   *siCTemp  = siComponents;
02767 
02768   if(siCTemp != NULL)
02769   {
02770     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02771        ((dwACFlag == AC_ALL) ||
02772        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02773        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02774     {
02775       if(dwIndex == 0)
02776         return(siCTemp->ulInstallSizeSystem);
02777 
02778       ++dwCount;
02779     }
02780     
02781     siCTemp = siCTemp->Next;
02782     while((siCTemp != NULL) && (siCTemp != siComponents))
02783     {
02784       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02785          ((dwACFlag == AC_ALL) ||
02786          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02787          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02788       {
02789         if(dwIndex == dwCount)
02790           return(siCTemp->ulInstallSizeSystem);
02791       
02792         ++dwCount;
02793       }
02794       
02795       siCTemp = siCTemp->Next;
02796     }
02797   }
02798   return(0L);
02799 }
02800 
02801 unsigned long long SiCNodeGetInstallSizeArchive(DWORD dwIndex, BOOL bIncludeInvisible, DWORD dwACFlag)
02802 {
02803   DWORD dwCount   = 0;
02804   siC   *siCTemp  = siComponents;
02805 
02806   if(siCTemp != NULL)
02807   {
02808     if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02809        ((dwACFlag == AC_ALL) ||
02810        ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02811        ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02812     {
02813       if(dwIndex == 0)
02814         return(siCTemp->ulInstallSizeArchive);
02815 
02816       ++dwCount;
02817     }
02818     
02819     siCTemp = siCTemp->Next;
02820     while((siCTemp != NULL) && (siCTemp != siComponents))
02821     {
02822       if(((bIncludeInvisible == TRUE) || ((bIncludeInvisible == FALSE) && (!(siCTemp->dwAttributes & SIC_INVISIBLE)))) &&
02823          ((dwACFlag == AC_ALL) ||
02824          ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02825          ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02826       {
02827         if(dwIndex == dwCount)
02828           return(siCTemp->ulInstallSizeArchive);
02829       
02830         ++dwCount;
02831       }
02832       
02833       siCTemp = siCTemp->Next;
02834     }
02835   }
02836   return(0L);
02837 }
02838 
02839 /* retrieve Index of node containing short description */
02840 int SiCNodeGetIndexDS(char *szInDescriptionShort)
02841 {
02842   DWORD dwCount = 0;
02843   siC   *siCTemp = siComponents;
02844 
02845   if(siCTemp != NULL)
02846   {
02847     if(stricmp(szInDescriptionShort, siCTemp->szDescriptionShort) == 0)
02848       return(dwCount);
02849 
02850     ++dwCount;
02851     siCTemp = siCTemp->Next;
02852     while((siCTemp != NULL) && (siCTemp != siComponents))
02853     {
02854       if(stricmp(szInDescriptionShort, siCTemp->szDescriptionShort) == 0)
02855         return(dwCount);
02856       
02857       ++dwCount;
02858       siCTemp = siCTemp->Next;
02859     }
02860   }
02861   return(-1);
02862 }
02863 
02864 /* retrieve Index of node containing Reference Name */
02865 int SiCNodeGetIndexRN(char *szInReferenceName)
02866 {
02867   DWORD dwCount = 0;
02868   siC   *siCTemp = siComponents;
02869 
02870   if(siCTemp != NULL)
02871   {
02872     if(stricmp(szInReferenceName, siCTemp->szReferenceName) == 0)
02873       return(dwCount);
02874 
02875     ++dwCount;
02876     siCTemp = siCTemp->Next;
02877     while((siCTemp != NULL) && (siCTemp != siComponents))
02878     {
02879       if(stricmp(szInReferenceName, siCTemp->szReferenceName) == 0)
02880         return(dwCount);
02881       
02882       ++dwCount;
02883       siCTemp = siCTemp->Next;
02884     }
02885   }
02886   return(-1);
02887 }
02888 
02889 siC *SiCNodeGetObject(DWORD dwIndex, BOOL bIncludeInvisibleObjs, DWORD dwACFlag)
02890 {
02891   DWORD dwCount = -1;
02892   siC   *siCTemp = siComponents;
02893 
02894   if(siCTemp != NULL)
02895   {
02896     if((bIncludeInvisibleObjs) &&
02897       ((dwACFlag == AC_ALL) ||
02898       ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02899       ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02900     {
02901       ++dwCount;
02902     }
02903     else if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) &&
02904            ((dwACFlag == AC_ALL) ||
02905            ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02906            ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02907     {
02908       ++dwCount;
02909     }
02910 
02911     if(dwIndex == dwCount)
02912       return(siCTemp);
02913 
02914     siCTemp = siCTemp->Next;
02915     while((siCTemp != siComponents) && (siCTemp != NULL))
02916     {
02917       if(bIncludeInvisibleObjs)
02918       {
02919         ++dwCount;
02920       }
02921       else if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) &&
02922              ((dwACFlag == AC_ALL) ||
02923              ((dwACFlag == AC_COMPONENTS)            && (!(siCTemp->dwAttributes & SIC_ADDITIONAL))) ||
02924              ((dwACFlag == AC_ADDITIONAL_COMPONENTS) &&   (siCTemp->dwAttributes & SIC_ADDITIONAL))))
02925       {
02926         ++dwCount;
02927       }
02928 
02929       if(dwIndex == dwCount)
02930         return(siCTemp);
02931       
02932       siCTemp = siCTemp->Next;
02933     }
02934   }
02935   return(NULL);
02936 }
02937 
02938 DWORD GetAdditionalComponentsCount()
02939 {
02940   DWORD dwCount  = 0;
02941   siC   *siCTemp = siComponents;
02942 
02943   if(siCTemp != NULL)
02944   {
02945     if(siCTemp->dwAttributes & SIC_ADDITIONAL)
02946     {
02947       ++dwCount;
02948     }
02949 
02950     siCTemp = siCTemp->Next;
02951     while((siCTemp != siComponents) && (siCTemp != NULL))
02952     {
02953       if(siCTemp->dwAttributes & SIC_ADDITIONAL)
02954       {
02955         ++dwCount;
02956       }
02957       
02958       siCTemp = siCTemp->Next;
02959     }
02960   }
02961   return(dwCount);
02962 }
02963 
02964 dsN *CreateDSNode()
02965 {
02966   dsN *dsNode;
02967 
02968   if((dsNode = NS_GlobalAlloc(sizeof(struct diskSpaceNode))) == NULL)
02969     exit(1);
02970 
02971   dsNode->ulSpaceRequired = 0;
02972 
02973   if((dsNode->szVDSPath = NS_GlobalAlloc(MAX_BUF)) == NULL)
02974     exit(1);
02975   if((dsNode->szPath = NS_GlobalAlloc(MAX_BUF)) == NULL)
02976     exit(1);
02977   dsNode->Next             = dsNode;
02978   dsNode->Prev             = dsNode;
02979 
02980   return(dsNode);
02981 }
02982 
02983 void DsNodeInsert(dsN **dsNHead, dsN *dsNTemp)
02984 {
02985   if(*dsNHead == NULL)
02986   {
02987     *dsNHead          = dsNTemp;
02988     (*dsNHead)->Next  = *dsNHead;
02989     (*dsNHead)->Prev  = *dsNHead;
02990   }
02991   else
02992   {
02993     dsNTemp->Next           = *dsNHead;
02994     dsNTemp->Prev           = (*dsNHead)->Prev;
02995     (*dsNHead)->Prev->Next  = dsNTemp;
02996     (*dsNHead)->Prev        = dsNTemp;
02997   }
02998 }
02999 
03000 void DsNodeDelete(dsN **dsNTemp)
03001 {
03002   if(*dsNTemp != NULL)
03003   {
03004     (*dsNTemp)->Next->Prev = (*dsNTemp)->Prev;
03005     (*dsNTemp)->Prev->Next = (*dsNTemp)->Next;
03006     (*dsNTemp)->Next       = NULL;
03007     (*dsNTemp)->Prev       = NULL;
03008 
03009     FreeMemory(&((*dsNTemp)->szVDSPath));
03010     FreeMemory(&((*dsNTemp)->szPath));
03011     FreeMemory(dsNTemp);
03012   }
03013 }
03014 
03015 /* returns the value in kilobytes */
03016 unsigned long long GetDiskSpaceRequired(DWORD dwType)
03017 {
03018   unsigned long long ullTotalSize = 0;
03019   siC       *siCTemp     = siComponents;
03020 
03021   if(siCTemp != NULL)
03022   {
03023     if(siCTemp->dwAttributes & SIC_SELECTED)
03024     {
03025       switch(dwType)
03026       {
03027         case DSR_DESTINATION:
03028           ullTotalSize += siCTemp->ulInstallSize;
03029           break;
03030 
03031         case DSR_SYSTEM:
03032           ullTotalSize += siCTemp->ulInstallSizeSystem;
03033           break;
03034 
03035         case DSR_TEMP:
03036         case DSR_DOWNLOAD_SIZE:
03037           if((LocateJar(siCTemp, NULL, 0, gbPreviousUnfinishedDownload) == AP_NOT_FOUND) ||
03038              (dwType == DSR_DOWNLOAD_SIZE))
03039             ullTotalSize += siCTemp->ulInstallSizeArchive;
03040           break;
03041       }
03042     }
03043 
03044     siCTemp = siCTemp->Next;
03045     while((siCTemp != NULL) && (siCTemp != siComponents))
03046     {
03047       if(siCTemp->dwAttributes & SIC_SELECTED)
03048       {
03049         switch(dwType)
03050         {
03051           case DSR_DESTINATION:
03052             ullTotalSize += siCTemp->ulInstallSize;
03053             break;
03054 
03055           case DSR_SYSTEM:
03056             ullTotalSize += siCTemp->ulInstallSizeSystem;
03057             break;
03058 
03059           case DSR_TEMP:
03060           case DSR_DOWNLOAD_SIZE:
03061             if((LocateJar(siCTemp, NULL, 0, gbPreviousUnfinishedDownload) == AP_NOT_FOUND) ||
03062                (dwType == DSR_DOWNLOAD_SIZE))
03063               ullTotalSize += siCTemp->ulInstallSizeArchive;
03064             break;
03065         }
03066       }
03067 
03068       siCTemp = siCTemp->Next;
03069     }
03070   }
03071 
03072   /* add the amount of disk space it will take for the 
03073      xpinstall engine in the TEMP area */
03074   if(dwType == DSR_TEMP)
03075     ullTotalSize += siCFXpcomFile.ulInstallSize;
03076 
03077   return(ullTotalSize);
03078 }
03079 
03080 int LocateExistingPath(char *szPath, char *szExistingPath, DWORD dwExistingPathSize)
03081 {
03082   char szBuf[MAX_BUF];
03083 
03084   strcpy(szExistingPath, szPath);
03085   AppendBackSlash(szExistingPath, dwExistingPathSize);
03086   while((FileExists(szExistingPath) == FALSE))
03087   {
03088     RemoveBackSlash(szExistingPath);
03089     ParsePath(szExistingPath, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY);
03090     strcpy(szExistingPath, szBuf);
03091     AppendBackSlash(szExistingPath, dwExistingPathSize);
03092   }
03093   return(WIZ_OK);
03094 }
03095 
03096 /* returns the value in bytes */
03097 unsigned long long GetDiskSpaceAvailable(LPSTR szPath)
03098 {
03099   char szBuf[MAX_BUF];
03100   char szBuf2[MAX_BUF];
03101   FSALLOCATE fsAllocate;
03102   unsigned long long nBytes = 0;
03103   APIRET rc;
03104   ULONG ulDriveNo;
03105 
03106   ulDriveNo = toupper(szPath[0]) + 1 - 'A';
03107   rc = DosQueryFSInfo(ulDriveNo,
03108                       FSIL_ALLOC,
03109                       &fsAllocate,
03110                       sizeof(fsAllocate));
03111 
03112   if (rc != NO_ERROR) {
03113     char szEDeterminingDiskSpace[MAX_BUF];
03114 
03115     if(GetPrivateProfileString("Messages", "ERROR_DETERMINING_DISK_SPACE", "", szEDeterminingDiskSpace, sizeof(szEDeterminingDiskSpace), szFileIniInstall))
03116     {
03117       strcpy(szBuf2, "\n    ");
03118       strcat(szBuf2, szPath);
03119       sprintf(szBuf, szEDeterminingDiskSpace, szBuf2);
03120       PrintError(szBuf, ERROR_CODE_SHOW);
03121     }
03122   }
03123 
03124   nBytes = fsAllocate.cUnitAvail;
03125   nBytes *= fsAllocate.cSectorUnit;
03126   nBytes *= fsAllocate.cbSector;
03127   if (nBytes > 1024)
03128      nBytes /= 1024;
03129   else
03130      nBytes = 0;
03131 
03132   return nBytes;
03133 }
03134 
03135 HRESULT ErrorMsgDiskSpace(unsigned long long ullDSAvailable, unsigned long long ullDSRequired, LPSTR szPath, BOOL bCrutialMsg)
03136 {
03137   char      szBuf0[MAX_BUF];
03138   char      szBuf1[MAX_BUF];
03139   char      szBuf2[MAX_BUF];
03140   char      szBuf3[MAX_BUF];
03141   char      szBufRootPath[MAX_BUF];
03142   char      szBufMsg[MAX_BUF];
03143   char      szDSAvailable[MAX_BUF];
03144   char      szDSRequired[MAX_BUF];
03145   char      szDlgDiskSpaceCheckTitle[MAX_BUF];
03146   char      szDlgDiskSpaceCheckMsg[MAX_BUF];
03147   DWORD     dwDlgType;
03148 
03149   if(!GetPrivateProfileString("Messages", "DLG_DISK_SPACE_CHECK_TITLE", "", szDlgDiskSpaceCheckTitle, sizeof(szDlgDiskSpaceCheckTitle), szFileIniInstall))
03150     exit(1);
03151 
03152   if(bCrutialMsg)
03153   {
03154     dwDlgType = MB_RETRYCANCEL;
03155     if(!GetPrivateProfileString("Messages", "DLG_DISK_SPACE_CHECK_CRUCIAL_MSG", "", szDlgDiskSpaceCheckMsg, sizeof(szDlgDiskSpaceCheckMsg), szFileIniInstall))
03156       exit(1);
03157   }
03158   else
03159   {
03160     dwDlgType = MB_OK;
03161     if(!GetPrivateProfileString("Messages", "DLG_DISK_SPACE_CHECK_MSG", "", szDlgDiskSpaceCheckMsg, sizeof(szDlgDiskSpaceCheckMsg), szFileIniInstall))
03162       exit(1);
03163   }
03164 
03165   ParsePath(szPath, szBufRootPath, sizeof(szBufRootPath), FALSE, PP_ROOT_ONLY);
03166   RemoveBackSlash(szBufRootPath);
03167   strcpy(szBuf0, szPath);
03168   RemoveBackSlash(szBuf0);
03169 
03170   _itoa(ullDSAvailable, szDSAvailable, 10);
03171   _itoa(ullDSRequired, szDSRequired, 10);
03172 
03173   sprintf(szBuf1, "\n\n    %s\n\n    ", szBuf0);
03174   sprintf(szBuf2, "%s KB\n    ",        szDSRequired);
03175   sprintf(szBuf3, "%s KB\n\n",          szDSAvailable);
03176   sprintf(szBufMsg, szDlgDiskSpaceCheckMsg, szBufRootPath, szBuf1, szBuf2, szBuf3);
03177 
03178   if((sgProduct.ulMode != SILENT) && (sgProduct.ulMode != AUTO))
03179   {
03180     return(WinMessageBox(HWND_DESKTOP, hWndMain, szBufMsg, szDlgDiskSpaceCheckTitle, 0, dwDlgType | MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_APPLMODAL));
03181   }
03182   else if(sgProduct.ulMode == AUTO)
03183   {
03184     ShowMessage(szBufMsg, TRUE);
03185     DosSleep(5000);
03186     ShowMessage(szBufMsg, FALSE);
03187     exit(1);
03188   }
03189 
03190   return(MBID_CANCEL);
03191 }
03192 
03193 void UpdatePathDiskSpaceRequired(LPSTR szPath, unsigned long long ullSize, dsN **dsnComponentDSRequirement)
03194 {
03195   BOOL  bFound = FALSE;
03196   dsN   *dsnTemp = *dsnComponentDSRequirement;
03197   char  szReparsePath[MAX_BUF];
03198   char  szVDSPath[MAX_BUF];
03199   char  szRootPath[MAX_BUF];
03200 
03201   if(ullSize > 0)
03202   {
03203     ParsePath(szPath, szRootPath, sizeof(szRootPath), FALSE, PP_ROOT_ONLY);
03204 
03205     if(GetDiskSpaceAvailable(szRootPath) == GetDiskSpaceAvailable(szPath))
03206       // Check for user quota on path.  It is very unlikely that the user quota
03207       // for the path will be the same as the quota for its root path when user
03208       // quota is enabled.
03209       //
03210       // If it happens to be the same, then I'm assuming that the disk space on
03211       // the path's root path will decrease at the same rate as the path with
03212       // user quota enabled.
03213       //
03214       // If user quota is not enabled on the folder, then use the root path.
03215       strcpy(szVDSPath, szRootPath);
03216     else
03217       strcpy(szVDSPath, szPath);
03218 
03219     do
03220     {
03221       if(*dsnComponentDSRequirement == NULL)
03222       {
03223         *dsnComponentDSRequirement = CreateDSNode();
03224         dsnTemp = *dsnComponentDSRequirement;
03225         strcpy(dsnTemp->szVDSPath, szVDSPath);
03226         strcpy(dsnTemp->szPath, szPath);
03227         dsnTemp->ulSpaceRequired = ullSize;
03228         bFound = TRUE;
03229       }
03230       else if(stricmp(dsnTemp->szVDSPath, szVDSPath) == 0)
03231       {
03232         dsnTemp->ulSpaceRequired += ullSize;
03233         bFound = TRUE;
03234       }
03235       else
03236         dsnTemp = dsnTemp->Next;
03237 
03238     } while((dsnTemp != *dsnComponentDSRequirement) && (dsnTemp != NULL) && (bFound == FALSE));
03239 
03240     if(bFound == FALSE)
03241     {
03242       dsnTemp = CreateDSNode();
03243       strcpy(dsnTemp->szVDSPath, szVDSPath);
03244       strcpy(dsnTemp->szPath, szPath);
03245       dsnTemp->ulSpaceRequired = ullSize;
03246       DsNodeInsert(dsnComponentDSRequirement, dsnTemp);
03247     }
03248   }
03249 }
03250 
03251 HRESULT InitComponentDiskSpaceInfo(dsN **dsnComponentDSRequirement)
03252 {
03253   DWORD     dwIndex0;
03254   siC       *siCObject = NULL;
03255   HRESULT   hResult    = 0;
03256   char      szBuf[MAX_BUF];
03257   char      szIndex0[MAX_BUF];
03258   char      szBufTempPath[MAX_BUF];
03259 
03260   ParsePath(szTempDir, szBufTempPath, sizeof(szBufTempPath), FALSE, PP_ROOT_ONLY);
03261   AppendBackSlash(szBufTempPath, sizeof(szBufTempPath));
03262 
03263   dwIndex0 = 0;
03264   _itoa(dwIndex0, szIndex0, 10);
03265   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
03266   while(siCObject)
03267   {
03268     if(siCObject->dwAttributes & SIC_SELECTED)
03269     {
03270       if(*(siCObject->szDestinationPath) == '\0')
03271         strcpy(szBuf, sgProduct.szPath);
03272       else
03273         strcpy(szBuf, siCObject->szDestinationPath);
03274 
03275       AppendBackSlash(szBuf, sizeof(szBuf));
03276       UpdatePathDiskSpaceRequired(szBuf, siCObject->ulInstallSize, dsnComponentDSRequirement);
03277 
03278       if(*szTempDir != '\0')
03279         UpdatePathDiskSpaceRequired(szTempDir, siCObject->ulInstallSizeArchive, dsnComponentDSRequirement);
03280     }
03281 
03282     ++dwIndex0;
03283     _itoa(dwIndex0, szIndex0, 10);
03284     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
03285   }
03286 
03287   /* take the uncompressed size of Xpcom into account */
03288   if(*szTempDir != '\0')
03289     UpdatePathDiskSpaceRequired(szTempDir, siCFXpcomFile.ulInstallSize, dsnComponentDSRequirement);
03290 
03291   return(hResult);
03292 }
03293 
03294 HRESULT VerifyDiskSpace()
03295 {
03296   unsigned long long ullDSAvailable;
03297   HRESULT   hRetValue = FALSE;
03298   dsN       *dsnTemp = NULL;
03299 
03300   DeInitDSNode(&gdsnComponentDSRequirement);
03301   InitComponentDiskSpaceInfo(&gdsnComponentDSRequirement);
03302   if(gdsnComponentDSRequirement != NULL)
03303   {
03304     dsnTemp = gdsnComponentDSRequirement;
03305 
03306     do
03307     {
03308       if(dsnTemp != NULL)
03309       {
03310         ullDSAvailable = GetDiskSpaceAvailable(dsnTemp->szVDSPath);
03311         if(ullDSAvailable < dsnTemp->ulSpaceRequired)
03312         {
03313           hRetValue = ErrorMsgDiskSpace(ullDSAvailable, dsnTemp->ulSpaceRequired, dsnTemp->szPath, FALSE);
03314           break;
03315         }
03316 
03317         dsnTemp = dsnTemp->Next;
03318       }
03319     } while((dsnTemp != NULL) && (dsnTemp != gdsnComponentDSRequirement));
03320   }
03321   return(hRetValue);
03322 }
03323 
03324 /* Function: ParseOSType
03325  *
03326  * Input: char *
03327  *
03328  * Return: DWORD
03329  *
03330  * Description: This function parses an input string (szOSType) for specific
03331  * string keys:
03332  *     WIN95_DEBUTE, WIN95, WIN98, NT3, NT4, NT5, NT50, NT51
03333  *
03334  * It then stores the information in a DWORD, each bit corresponding to a
03335  * particular OS type.
03336  */ 
03337 ULONG ParseOSType(char *szOSType)
03338 {
03339   char  szBuf[MAX_BUF];
03340   ULONG ulOSType = 0;
03341 
03342   strcpy(szBuf, szOSType);
03343   strupr(szBuf);
03344 
03345   if(strstr(szBuf, "WARP4"))
03346     ulOSType |= OS_WARP4;
03347   if(strstr(szBuf, "WARP3"))
03348     ulOSType |= OS_WARP3;
03349 
03350   return(ulOSType);
03351 }
03352 
03353 HRESULT ParseComponentAttributes(char *szAttribute, DWORD dwAttributes, BOOL bOverride)
03354 {
03355   char  szBuf[MAX_BUF];
03356 
03357   strcpy(szBuf, szAttribute);
03358   strupr(szBuf);
03359 
03360   if(bOverride != TRUE)
03361   {
03362     if(strstr(szBuf, "LAUNCHAPP"))
03363       dwAttributes |= SIC_LAUNCHAPP;
03364     if(strstr(szBuf, "DOWNLOAD_ONLY"))
03365       dwAttributes |= SIC_DOWNLOAD_ONLY;
03366     if(strstr(szBuf, "FORCE_UPGRADE"))
03367       dwAttributes |= SIC_FORCE_UPGRADE;
03368     if(strstr(szBuf, "IGNORE_DOWNLOAD_ERROR"))
03369       dwAttributes |= SIC_IGNORE_DOWNLOAD_ERROR;
03370     if(strstr(szBuf, "IGNORE_XPINSTALL_ERROR"))
03371       dwAttributes |= SIC_IGNORE_XPINSTALL_ERROR;
03372     if(strstr(szBuf, "UNCOMPRESS"))
03373       dwAttributes |= SIC_UNCOMPRESS;
03374   }
03375 
03376   if(strstr(szBuf, "UNSELECTED"))
03377     dwAttributes &= ~SIC_SELECTED;
03378   else if(strstr(szBuf, "SELECTED"))
03379     dwAttributes |= SIC_SELECTED;
03380 
03381   if(strstr(szBuf, "INVISIBLE"))
03382     dwAttributes |= SIC_INVISIBLE;
03383   else if(strstr(szBuf, "VISIBLE"))
03384     dwAttributes &= ~SIC_INVISIBLE;
03385 
03386   if(strstr(szBuf, "DISABLED"))
03387     dwAttributes |= SIC_DISABLED;
03388   if(strstr(szBuf, "ENABLED"))
03389     dwAttributes &= ~SIC_DISABLED;
03390 
03391   if(strstr(szBuf, "NOTADDITIONAL"))
03392     dwAttributes &= ~SIC_ADDITIONAL;
03393   else if(strstr(szBuf, "ADDITIONAL"))
03394     dwAttributes |= SIC_ADDITIONAL;
03395 
03396   if(strstr(szBuf, "NOTSUPERSEDE"))
03397     dwAttributes &= ~SIC_SUPERSEDE;
03398   else if(strstr(szBuf, "SUPERSEDE"))
03399     dwAttributes |= SIC_SUPERSEDE;
03400    
03401 
03402   return(dwAttributes);
03403 }
03404 
03405 long RandomSelect()
03406 {
03407   long lArbitrary = 0;
03408 
03409   srand((unsigned)time(NULL));
03410   lArbitrary = rand() % 100;
03411   return(lArbitrary);
03412 }
03413 
03414 siC *SiCNodeFind(siC *siCHeadNode, char *szInReferenceName)
03415 {
03416   siC *siCNode = siCHeadNode;
03417 
03418   do
03419   {
03420     if(siCNode == NULL)
03421       break;
03422 
03423     if(stricmp(siCNode->szReferenceName, szInReferenceName) == 0)
03424       return(siCNode);
03425 
03426     siCNode = siCNode->Next;
03427   } while((siCNode != NULL) && (siCNode != siCHeadNode));
03428 
03429   return(NULL);
03430 }
03431 
03432 BOOL ResolveSupersede(siC *siCObject)
03433 {
03434   DWORD dwIndex;
03435   char  szFilePath[MAX_BUF];
03436   char  szSupersedeFile[MAX_BUF];
03437   char  szSupersedeVersion[MAX_BUF];
03438   char  szType[MAX_BUF_TINY];
03439   char  szKey[MAX_BUF_TINY];
03440 
03441   siCObject->bSupersede = FALSE;
03442   if(siCObject->dwAttributes & SIC_SUPERSEDE)
03443   {
03444     dwIndex = 0;
03445     GetPrivateProfileString(siCObject->szReferenceName, "SupersedeType", "", szType, sizeof(szType), szFileIniConfig);
03446     if(*szType !='\0')
03447     {
03448       if(stricmp(szType, "File Exists") == 0)
03449       {
03450         sprintf(szKey, "SupersedeFile%d", dwIndex);        
03451         GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szSupersedeFile, sizeof(szSupersedeFile), szFileIniConfig);
03452         while(*szSupersedeFile != '\0')
03453         {
03454           DecryptString(szFilePath, szSupersedeFile);
03455           if(FileExists(szFilePath))
03456           {
03457             /* The file exists.  set Supersede */
03458             siCObject->bSupersede = TRUE;
03459             break;  /* Found at least one file, so break out of while loop */
03460           }
03461           sprintf(szKey, "SupersedeFile%d", ++dwIndex);        
03462           GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szSupersedeFile, sizeof(szSupersedeFile), szFileIniConfig);
03463         }
03464       }
03465     }
03466 
03467     if(siCObject->bSupersede)
03468     {
03469       siCObject->dwAttributes &= ~SIC_SELECTED;
03470       siCObject->dwAttributes |= SIC_DISABLED;
03471       siCObject->dwAttributes |= SIC_INVISIBLE;
03472     }
03473     else
03474       /* Make sure to unset the DISABLED bit.  If the Setup Type is other than
03475        * Custom, then we don't care if it's DISABLED or not because this flag
03476        * is only used in the Custom dialogs.
03477        *
03478        * If the Setup Type is Custom and this component is DISABLED by default
03479        * via the config.ini, it's default value will be restored in the
03480        * SiCNodeSetItemsSelected() function that called ResolveSupersede(). */
03481       siCObject->dwAttributes &= ~SIC_DISABLED;
03482   }
03483   return(siCObject->bSupersede);
03484 }
03485 
03486 BOOL ResolveForceUpgrade(siC *siCObject)
03487 {
03488   DWORD dwIndex;
03489   char  szFilePath[MAX_BUF];
03490   char  szKey[MAX_BUF_TINY];
03491   char  szForceUpgradeFile[MAX_BUF];
03492 
03493   siCObject->bForceUpgrade = FALSE;
03494   if(siCObject->dwAttributes & SIC_FORCE_UPGRADE)
03495   {
03496     dwIndex = 0;
03497     BuildNumberedString(dwIndex, NULL, "Force Upgrade File", szKey, sizeof(szKey));
03498     GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szForceUpgradeFile, sizeof(szForceUpgradeFile), szFileIniConfig);
03499     while(*szForceUpgradeFile != '\0')
03500     {
03501       DecryptString(szFilePath, szForceUpgradeFile);
03502       if(FileExists(szFilePath))
03503       {
03504         siCObject->bForceUpgrade = TRUE;
03505 
03506         /* Found at least one file, so break out of while loop */
03507         break;
03508       }
03509 
03510       BuildNumberedString(++dwIndex, NULL, "Force Upgrade File", szKey, sizeof(szKey));
03511       GetPrivateProfileString(siCObject->szReferenceName, szKey, "", szForceUpgradeFile, sizeof(szForceUpgradeFile), szFileIniConfig);
03512     }
03513 
03514     if(siCObject->bForceUpgrade)
03515     {
03516       siCObject->dwAttributes |= SIC_SELECTED;
03517       siCObject->dwAttributes |= SIC_DISABLED;
03518     }
03519     else
03520       /* Make sure to unset the DISABLED bit.  If the Setup Type is other than
03521        * Custom, then we don't care if it's DISABLED or not because this flag
03522        * is only used in the Custom dialogs.
03523        *
03524        * If the Setup Type is Custom and this component is DISABLED by default
03525        * via the config.ini, it's default value will be restored in the
03526        * SiCNodeSetItemsSelected() function that called ResolveForceUpgrade(). */
03527       siCObject->dwAttributes &= ~SIC_DISABLED;
03528   }
03529   return(siCObject->bForceUpgrade);
03530 }
03531 
03532 void InitSiComponents(char *szFileIni)
03533 {
03534   DWORD dwIndex0;
03535   DWORD dwIndex1;
03536   int   iCurrentLoop;
03537   char  szIndex0[MAX_BUF];
03538   char  szIndex1[MAX_BUF];
03539   char  szBuf[MAX_BUF];
03540   char  szComponentKey[MAX_BUF];
03541   char  szComponentSection[MAX_BUF];
03542   char  szDependency[MAX_BUF];
03543   char  szDependee[MAX_BUF];
03544   char  szSTSection[MAX_BUF];
03545   char  szDPSection[MAX_BUF];
03546   siC   *siCTemp            = NULL;
03547   siCD  *siCDepTemp         = NULL;
03548   siCD  *siCDDependeeTemp   = NULL;
03549 
03550   /* clean up the list before reading new components given the Setup Type */
03551   DeInitSiComponents(&siComponents);
03552 
03553   /* Parse the Setup Type sections in reverse order because
03554    * the Custom Setup Type is always last.  It needs to be parsed
03555    * first because the component list it has will be shown in its
03556    * other custom dialogs.  Order matters! */
03557   for(iCurrentLoop = 3; iCurrentLoop >= 0; iCurrentLoop--)
03558   {
03559     strcpy(szSTSection, "Setup Type");
03560     _itoa(iCurrentLoop, szBuf, 10);
03561     strcat(szSTSection, szBuf);
03562 
03563     /* read in each component given a setup type */
03564     dwIndex0 = 0;
03565     _itoa(dwIndex0, szIndex0, 10);
03566     strcpy(szComponentKey, "C");
03567     strcat(szComponentKey, szIndex0);
03568     GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIni);
03569     while(*szComponentSection != '\0')
03570     {
03571       GetPrivateProfileString(szComponentSection, "Archive", "", szBuf, sizeof(szBuf), szFileIni);
03572       if((*szBuf != '\0') && (SiCNodeFind(siComponents, szComponentSection) == NULL))
03573       {
03574         /* create and initialize empty node */
03575         siCTemp = CreateSiCNode();
03576 
03577         /* store name of archive for component */
03578         strcpy(siCTemp->szArchiveName, szBuf);
03579 
03580         /* store name of the uncompressed archive for the component */
03581         GetPrivateProfileString(szComponentSection,
03582                                 "Archive Uncompressed",
03583                                 "",
03584                                 siCTemp->szArchiveNameUncompressed,
03585                                 sizeof(szBuf),
03586                                 szFileIni);
03587         
03588         /* get short description of component */
03589         GetPrivateProfileString(szComponentSection, "Description Short", "", szBuf, sizeof(szBuf), szFileIni);
03590         strcpy(siCTemp->szDescriptionShort, szBuf);
03591 
03592         /* get long description of component */
03593         GetPrivateProfileString(szComponentSection, "Description Long", "", szBuf, sizeof(szBuf), szFileIni);
03594         strcpy(siCTemp->szDescriptionLong, szBuf);
03595 
03596         /* get commandline parameter for component */
03597         GetPrivateProfileString(szComponentSection, "Parameter", "", siCTemp->szParameter, MAX_BUF, szFileIni);
03598 
03599         /* set reference name for component */
03600         strcpy(siCTemp->szReferenceName, szComponentSection);
03601 
03602         /* get install size required in destination for component.  Sould be in Kilobytes */
03603         GetPrivateProfileString(szComponentSection, "Install Size", "", szBuf, sizeof(szBuf), szFileIni);
03604         if(*szBuf != '\0')
03605           siCTemp->ulInstallSize = atoi(szBuf);
03606         else
03607           siCTemp->ulInstallSize = 0;
03608 
03609         /* get install size required in system for component.  Sould be in Kilobytes */
03610         GetPrivateProfileString(szComponentSection, "Install Size System", "", szBuf, sizeof(szBuf), szFileIni);
03611         if(*szBuf != '\0')
03612           siCTemp->ulInstallSizeSystem = atoi(szBuf);
03613         else
03614           siCTemp->ulInstallSizeSystem = 0;
03615 
03616         /* get install size required in temp for component.  Sould be in Kilobytes */
03617         GetPrivateProfileString(szComponentSection, "Install Size Archive", "", szBuf, sizeof(szBuf), szFileIni);
03618         if(*szBuf != '\0')
03619           siCTemp->ulInstallSizeArchive = atoi(szBuf);
03620         else
03621           siCTemp->ulInstallSizeArchive = 0;
03622 
03623         /* get attributes of component */
03624         GetPrivateProfileString(szComponentSection, "Attributes", "", szBuf, sizeof(szBuf), szFileIni);
03625         siCTemp->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE);
03626 
03627         /* get the random percentage value and select or deselect the component (by default) for
03628          * installation */
03629         GetPrivateProfileString(szComponentSection, "Random Install Percentage", "", szBuf, sizeof(szBuf), szFileIni);
03630         if(*szBuf != '\0')
03631         {
03632           siCTemp->lRandomInstallPercentage = atol(szBuf);
03633           if(siCTemp->lRandomInstallPercentage != 0)
03634             siCTemp->lRandomInstallValue = RandomSelect();
03635         }
03636 
03637         /* get all dependencies for this component */
03638         dwIndex1 = 0;
03639         _itoa(dwIndex1, szIndex1, 10);
03640         strcpy(szDependency, "Dependency");
03641         strcat(szDependency, szIndex1);
03642         GetPrivateProfileString(szComponentSection, szDependency, "", szBuf, sizeof(szBuf), szFileIni);
03643         while(*szBuf != '\0')
03644         {
03645           /* create and initialize empty node */
03646           siCDepTemp = CreateSiCDepNode();
03647 
03648           /* store name of archive for component */
03649           strcpy(siCDepTemp->szReferenceName, szBuf);
03650 
03651           /* inserts the newly created component into the global component list */
03652           SiCDepNodeInsert(&(siCTemp->siCDDependencies), siCDepTemp);
03653 
03654           ProcessWindowsMessages();
03655           ++dwIndex1;
03656           _itoa(dwIndex1, szIndex1, 10);
03657           strcpy(szDependency, "Dependency");
03658           strcat(szDependency, szIndex1);
03659           GetPrivateProfileString(szComponentSection, szDependency, "", szBuf, sizeof(szBuf), szFileIni);
03660         }
03661 
03662         /* get all dependees for this component */
03663         dwIndex1 = 0;
03664         _itoa(dwIndex1, szIndex1, 10);
03665         strcpy(szDependee, "Dependee");
03666         strcat(szDependee, szIndex1);
03667         GetPrivateProfileString(szComponentSection, szDependee, "", szBuf, sizeof(szBuf), szFileIni);
03668         while(*szBuf != '\0')
03669         {
03670           /* create and initialize empty node */
03671           siCDDependeeTemp = CreateSiCDepNode();
03672 
03673           /* store name of archive for component */
03674           strcpy(siCDDependeeTemp->szReferenceName, szBuf);
03675 
03676           /* inserts the newly created component into the global component list */
03677           SiCDepNodeInsert(&(siCTemp->siCDDependees), siCDDependeeTemp);
03678 
03679           ProcessWindowsMessages();
03680           ++dwIndex1;
03681           _itoa(dwIndex1, szIndex1, 10);
03682           strcpy(szDependee, "Dependee");
03683           strcat(szDependee, szIndex1);
03684           GetPrivateProfileString(szComponentSection, szDependee, "", szBuf, sizeof(szBuf), szFileIni);
03685         }
03686 
03687         // locate previous path if necessary
03688         strcpy(szDPSection, szComponentSection);
03689         strcat(szDPSection, "-Destination Path");
03690         if(LocatePreviousPath(szDPSection, siCTemp->szDestinationPath, MAX_PATH) == FALSE)
03691           memset(siCTemp->szDestinationPath, 0, MAX_PATH);
03692 
03693         /* inserts the newly created component into the global component list */
03694         SiCNodeInsert(&siComponents, siCTemp);
03695       }
03696 
03697       ProcessWindowsMessages();
03698       ++dwIndex0;
03699       _itoa(dwIndex0, szIndex0, 10);
03700       strcpy(szComponentKey, "C");
03701       strcat(szComponentKey, szIndex0);
03702       GetPrivateProfileString(szSTSection, szComponentKey, "", szComponentSection, sizeof(szComponentSection), szFileIni);
03703     }
03704   }
03705 
03706   sgProduct.ulNumberOfComponents = dwIndex0;
03707 }
03708 
03709 void ResetComponentAttributes(char *szFileIni)
03710 {
03711   char  szIndex[MAX_BUF];
03712   char  szBuf[MAX_BUF];
03713   char  szComponentItem[MAX_BUF];
03714   siC   *siCTemp;
03715   DWORD dwCounter;
03716 
03717   for(dwCounter = 0; dwCounter < sgProduct.ulNumberOfComponents; dwCounter++)
03718   {
03719     _itoa(dwCounter, szIndex, 10);
03720     strcpy(szComponentItem, "Component");
03721     strcat(szComponentItem, szIndex);
03722 
03723     siCTemp = SiCNodeGetObject(dwCounter, TRUE, AC_ALL);
03724     GetPrivateProfileString(szComponentItem, "Attributes", "", szBuf, sizeof(szBuf), szFileIni);
03725     siCTemp->dwAttributes = ParseComponentAttributes(szBuf, 0, FALSE);
03726   }
03727 }
03728 
03729 void UpdateSiteSelector()
03730 {
03731   DWORD dwIndex;
03732   char  szIndex[MAX_BUF];
03733   char  szKDescription[MAX_BUF];
03734   char  szDescription[MAX_BUF];
03735   char  szKDomain[MAX_BUF];
03736   char  szDomain[MAX_BUF];
03737   char  szFileIniRedirect[MAX_BUF];
03738   ssi   *ssiSiteSelectorTemp;
03739 
03740   strcpy(szFileIniRedirect, szTempDir);
03741   AppendBackSlash(szFileIniRedirect, sizeof(szFileIniRedirect));
03742   strcat(szFileIniRedirect, FILE_INI_REDIRECT);
03743 
03744   if(FileExists(szFileIniRedirect) == FALSE)
03745     return;
03746 
03747   /* get all dependees for this component */
03748   dwIndex = 0;
03749   _itoa(dwIndex, szIndex, 10);
03750   strcpy(szKDescription, "Description");
03751   strcpy(szKDomain,      "Domain");
03752   strcat(szKDescription, szIndex);
03753   strcat(szKDomain,      szIndex);
03754   GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIniRedirect);
03755   while(*szDescription != '\0')
03756   {
03757     if(stricmp(szDescription, szSiteSelectorDescription) == 0)
03758     {
03759       GetPrivateProfileString("Site Selector", szKDomain, "", szDomain, sizeof(szDomain), szFileIniRedirect);
03760       if(*szDomain != '\0')
03761       {
03762         ssiSiteSelectorTemp = SsiGetNode(szDescription);
03763         if(ssiSiteSelectorTemp != NULL)
03764         {
03765           strcpy(ssiSiteSelectorTemp->szDomain, szDomain);
03766         }
03767         else
03768         {
03769           /* no match found for the given domain description, so assume there's nothing
03770            * to change. just return. */
03771           return;
03772         }
03773       }
03774       else
03775       {
03776         /* found matched description, but domain was not set, so assume there's no
03777          * redirect required, just return. */
03778         return;
03779       }
03780     }
03781 
03782     ++dwIndex;
03783     _itoa(dwIndex, szIndex, 10);
03784     strcpy(szKDescription, "Description");
03785     strcpy(szKDomain,      "Domain");
03786     strcat(szKDescription, szIndex);
03787     strcat(szKDomain,      szIndex);
03788     memset(szDescription, 0, sizeof(szDescription));
03789     memset(szDomain, 0,      sizeof(szDomain));
03790     GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIniRedirect);
03791   }
03792 }
03793 
03794 void InitSiteSelector(char *szFileIni)
03795 {
03796   DWORD dwIndex;
03797   char  szIndex[MAX_BUF];
03798   char  szKDescription[MAX_BUF];
03799   char  szDescription[MAX_BUF];
03800   char  szKDomain[MAX_BUF];
03801   char  szDomain[MAX_BUF];
03802   char  szKIdentifier[MAX_BUF];
03803   char  szIdentifier[MAX_BUF];
03804   ssi   *ssiSiteSelectorNewNode;
03805 
03806   ssiSiteSelector = NULL;
03807 
03808   /* get all dependees for this component */
03809   dwIndex = 0;
03810   _itoa(dwIndex, szIndex, 10);
03811   strcpy(szKDescription, "Description");
03812   strcpy(szKDomain,      "Domain");
03813   strcpy(szKIdentifier,  "Identifier");
03814   strcat(szKDescription, szIndex);
03815   strcat(szKDomain,      szIndex);
03816   strcat(szKIdentifier,  szIndex);
03817   GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIni);
03818   while(*szDescription != '\0')
03819   {
03820     /* if the Domain and Identifier are not set, then skip */
03821     GetPrivateProfileString("Site Selector", szKDomain,     "", szDomain,     sizeof(szDomain), szFileIni);
03822     GetPrivateProfileString("Site Selector", szKIdentifier, "", szIdentifier, sizeof(szIdentifier), szFileIni);
03823     if((*szDomain != '\0') && (*szIdentifier != '\0'))
03824     {
03825       /* create and initialize empty node */
03826       ssiSiteSelectorNewNode = CreateSsiSiteSelectorNode();
03827 
03828       strcpy(ssiSiteSelectorNewNode->szDescription, szDescription);
03829       strcpy(ssiSiteSelectorNewNode->szDomain,      szDomain);
03830       strcpy(ssiSiteSelectorNewNode->szIdentifier,  szIdentifier);
03831 
03832       /* inserts the newly created node into the global node list */
03833       SsiSiteSelectorNodeInsert(&(ssiSiteSelector), ssiSiteSelectorNewNode);
03834     }
03835 
03836     ProcessWindowsMessages();
03837     ++dwIndex;
03838     _itoa(dwIndex, szIndex, 10);
03839     strcpy(szKDescription, "Description");
03840     strcpy(szKDomain,      "Domain");
03841     strcpy(szKIdentifier,  "Identifier");
03842     strcat(szKDescription, szIndex);
03843     strcat(szKDomain,      szIndex);
03844     strcat(szKIdentifier,  szIndex);
03845     memset(szDescription, 0, sizeof(szDescription));
03846     memset(szDomain, 0,      sizeof(szDomain));
03847     memset(szIdentifier, 0,  sizeof(szIdentifier));
03848     GetPrivateProfileString("Site Selector", szKDescription, "", szDescription, sizeof(szDescription), szFileIni);
03849   }
03850 }
03851 
03852 void InitErrorMessageStream(char *szFileIni)
03853 {
03854   char szBuf[MAX_BUF_TINY];
03855 
03856   GetPrivateProfileString("Message Stream",
03857                           "Status",
03858                           "",
03859                           szBuf,
03860                           sizeof(szBuf),
03861                           szFileIni);
03862 
03863   if(stricmp(szBuf, "disabled") == 0)
03864     gErrorMessageStream.bEnabled = FALSE;
03865   else
03866     gErrorMessageStream.bEnabled = TRUE;
03867 
03868   GetPrivateProfileString("Message Stream",
03869                           "url",
03870                           "",
03871                           gErrorMessageStream.szURL,
03872                           sizeof(gErrorMessageStream.szURL),
03873                           szFileIni);
03874 
03875   GetPrivateProfileString("Message Stream",
03876                           "Show Confirmation",
03877                           "",
03878                           szBuf,
03879                           sizeof(szBuf),
03880                           szFileIni);
03881   if(stricmp(szBuf, "FALSE") == 0)
03882     gErrorMessageStream.bShowConfirmation = FALSE;
03883   else
03884     gErrorMessageStream.bShowConfirmation = TRUE;
03885 
03886   GetPrivateProfileString("Message Stream",
03887                           "Confirmation Message",
03888                           "",
03889                           gErrorMessageStream.szConfirmationMessage,
03890                           sizeof(szBuf),
03891                           szFileIni);
03892 
03893   gErrorMessageStream.bSendMessage = FALSE;
03894   gErrorMessageStream.dwMessageBufSize = MAX_BUF;
03895   gErrorMessageStream.szMessage = NS_GlobalAlloc(gErrorMessageStream.dwMessageBufSize);
03896 }
03897 
03898 void DeInitErrorMessageStream()
03899 {
03900   FreeMemory(&gErrorMessageStream.szMessage);
03901 }
03902 
03903 #ifdef SSU_DEBUG
03904 void ViewSiComponentsDependency(char *szBuffer, char *szIndentation, siC *siCNode)
03905 {
03906   siC  *siCNodeTemp;
03907   siCD *siCDependencyTemp;
03908 
03909   siCDependencyTemp = siCNode->siCDDependencies;
03910   if(siCDependencyTemp != NULL)
03911   {
03912     char  szIndentationPadding[MAX_BUF];
03913     DWORD dwIndex;
03914 
03915     strcpy(szIndentationPadding, szIndentation);
03916     strcat(szIndentationPadding, "    ");
03917 
03918     do
03919     {
03920       strcat(szBuffer, szIndentationPadding);
03921       strcat(szBuffer, siCDependencyTemp->szReferenceName);
03922       strcat(szBuffer, "::");
03923 
03924       if((dwIndex = SiCNodeGetIndexRN(siCDependencyTemp->szReferenceName)) != -1)
03925         strcat(szBuffer, SiCNodeGetDescriptionShort(dwIndex, TRUE, AC_ALL));
03926       else
03927         strcat(szBuffer, "Component does not exist");
03928 
03929       strcat(szBuffer, ":");
03930       strcat(szBuffer, "\n");
03931 
03932       if(dwIndex != -1)
03933       {
03934         if((siCNodeTemp = SiCNodeGetObject(dwIndex, TRUE, AC_ALL)) != NULL)
03935           ViewSiComponentsDependency(szBuffer, szIndentationPadding, siCNodeTemp);
03936         else
03937           strcat(szBuffer, "Node not found");
03938       }
03939 
03940       siCDependencyTemp = siCDependencyTemp->Next;
03941     }while((siCDependencyTemp != NULL) && (siCDependencyTemp != siCNode->siCDDependencies));
03942   }
03943 }
03944 
03945 void ViewSiComponentsDependee(char *szBuffer, char *szIndentation, siC *siCNode)
03946 {
03947   siC  *siCNodeTemp;
03948   siCD *siCDependeeTemp;
03949 
03950   siCDependeeTemp = siCNode->siCDDependees;
03951   if(siCDependeeTemp != NULL)
03952   {
03953     char  szIndentationPadding[MAX_BUF];
03954     DWORD dwIndex;
03955 
03956     strcpy(szIndentationPadding, szIndentation);
03957     strcat(szIndentationPadding, "    ");
03958 
03959     do
03960     {
03961       strcat(szBuffer, szIndentationPadding);
03962       strcat(szBuffer, siCDependeeTemp->szReferenceName);
03963       strcat(szBuffer, "::");
03964 
03965       if((dwIndex = SiCNodeGetIndexRN(siCDependeeTemp->szReferenceName)) != -1)
03966         strcat(szBuffer, SiCNodeGetDescriptionShort(dwIndex, TRUE, AC_ALL));
03967       else
03968         strcat(szBuffer, "Component does not exist");
03969 
03970       strcat(szBuffer, ":");
03971       strcat(szBuffer, "\n");
03972 
03973       if(dwIndex != -1)
03974       {
03975         if((siCNodeTemp = SiCNodeGetObject(dwIndex, TRUE, AC_ALL)) != NULL)
03976           ViewSiComponentsDependency(szBuffer, szIndentationPadding, siCNodeTemp);
03977         else
03978           strcat(szBuffer, "Node not found");
03979       }
03980 
03981       siCDependeeTemp = siCDependeeTemp->Next;
03982     }while((siCDependeeTemp != NULL) && (siCDependeeTemp != siCNode->siCDDependees));
03983   }
03984 }
03985 
03986 void ViewSiComponents()
03987 {
03988   char  szBuf[MAX_BUF];
03989   siC   *siCTemp = siComponents;
03990 
03991   // build dependency list
03992   memset(szBuf, 0, sizeof(szBuf));
03993   strcpy(szBuf, "Dependency:\n");
03994 
03995   do
03996   {
03997     if(siCTemp == NULL)
03998       break;
03999 
04000     strcat(szBuf, "    ");
04001     strcat(szBuf, siCTemp->szReferenceName);
04002     strcat(szBuf, "::");
04003     strcat(szBuf, siCTemp->szDescriptionShort);
04004     strcat(szBuf, ":\n");
04005 
04006     ViewSiComponentsDependency(szBuf, "    ", siCTemp);
04007 
04008     siCTemp = siCTemp->Next;
04009   } while((siCTemp != NULL) && (siCTemp != siComponents));
04010 
04011   WinMessageBox(HWND_DESKTOP, hWndMain, szBuf, NULL, 0, MB_ICONEXCLAMATION);
04012 
04013   // build dependee list
04014   memset(szBuf, 0, sizeof(szBuf));
04015   strcpy(szBuf, "Dependee:\n");
04016 
04017   do
04018   {
04019     if(siCTemp == NULL)
04020       break;
04021 
04022     strcat(szBuf, "    ");
04023     strcat(szBuf, siCTemp->szReferenceName);
04024     strcat(szBuf, "::");
04025     strcat(szBuf, siCTemp->szDescriptionShort);
04026     strcat(szBuf, ":\n");
04027 
04028     ViewSiComponentsDependee(szBuf, "    ", siCTemp);
04029 
04030     siCTemp = siCTemp->Next;
04031   } while((siCTemp != NULL) && (siCTemp != siComponents));
04032 
04033   WinMessageBox(HWND_DESKTOP, hWndMain, szBuf, NULL, 0, MB_ICONEXCLAMATION);
04034 }
04035 #endif /* SSU_DEBUG */
04036 
04037 void DeInitSiCDependencies(siCD *siCDDependencies)
04038 {
04039   siCD   *siCDepTemp;
04040   
04041   if(siCDDependencies == NULL)
04042   {
04043     return;
04044   }
04045   else if((siCDDependencies->Prev == NULL) || (siCDDependencies->Prev == siCDDependencies))
04046   {
04047     SiCDepNodeDelete(siCDDependencies);
04048     return;
04049   }
04050   else
04051   {
04052     siCDepTemp = siCDDependencies->Prev;
04053   }
04054 
04055   while(siCDepTemp != siCDDependencies)
04056   {
04057     SiCDepNodeDelete(siCDepTemp);
04058     siCDepTemp = siCDDependencies->Prev;
04059   }
04060   SiCDepNodeDelete(siCDepTemp);
04061 }
04062 
04063 void DeInitSiComponents(siC **siCHeadNode)
04064 {
04065   siC   *siCTemp;
04066   
04067   if((*siCHeadNode) == NULL)
04068   {
04069     return;
04070   }
04071   else if(((*siCHeadNode)->Prev == NULL) || ((*siCHeadNode)->Prev == (*siCHeadNode)))
04072   {
04073     SiCNodeDelete((*siCHeadNode));
04074     return;
04075   }
04076   else
04077   {
04078     siCTemp = (*siCHeadNode)->Prev;
04079   }
04080 
04081   while(siCTemp != (*siCHeadNode))
04082   {
04083     SiCNodeDelete(siCTemp);
04084     siCTemp = (*siCHeadNode)->Prev;
04085   }
04086   SiCNodeDelete(siCTemp);
04087 }
04088 
04089 void DeInitDSNode(dsN **dsnComponentDSRequirement)
04090 {
04091   dsN *dsNTemp;
04092   
04093   if(*dsnComponentDSRequirement == NULL)
04094   {
04095     return;
04096   }
04097   else if(((*dsnComponentDSRequirement)->Prev == NULL) || ((*dsnComponentDSRequirement)->Prev == *dsnComponentDSRequirement))
04098   {
04099     DsNodeDelete(dsnComponentDSRequirement);
04100     return;
04101   }
04102   else
04103   {
04104     dsNTemp = (*dsnComponentDSRequirement)->Prev;
04105   }
04106 
04107   while(dsNTemp != *dsnComponentDSRequirement)
04108   {
04109     DsNodeDelete(&dsNTemp);
04110     dsNTemp = (*dsnComponentDSRequirement)->Prev;
04111   }
04112   DsNodeDelete(dsnComponentDSRequirement);
04113 }
04114 
04115 BOOL ResolveComponentDependency(siCD *siCDInDependency, HWND hwndListBox)
04116 {
04117   int     dwIndex;
04118   siCD    *siCDepTemp = siCDInDependency;
04119   BOOL    bMoreToResolve = FALSE;
04120   DWORD   dwAttrib;
04121 
04122   if(siCDepTemp != NULL)
04123   {
04124     if((dwIndex = SiCNodeGetIndexRN(siCDepTemp->szReferenceName)) != -1)
04125     {
04126       dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL);
04127       if(!(dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED))
04128       {
04129         bMoreToResolve = TRUE;
04130         SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, TRUE, AC_ALL, hwndListBox);
04131       }
04132     }
04133 
04134     siCDepTemp = siCDepTemp->Next;
04135     while((siCDepTemp != NULL) && (siCDepTemp != siCDInDependency))
04136     {
04137       if((dwIndex = SiCNodeGetIndexRN(siCDepTemp->szReferenceName)) != -1)
04138       {
04139         dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL);
04140         if(!(dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED))
04141         {
04142           bMoreToResolve = TRUE;
04143           SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, TRUE, AC_ALL, hwndListBox);
04144         }
04145       }
04146 
04147       siCDepTemp = siCDepTemp->Next;
04148     }
04149   }
04150   return(bMoreToResolve);
04151 }
04152 
04153 BOOL ResolveDependencies(DWORD dwIndex, HWND hwndListBox)
04154 {
04155   BOOL  bMoreToResolve  = FALSE;
04156   DWORD dwCount         = 0;
04157   siC   *siCTemp        = siComponents;
04158 
04159   if(siCTemp != NULL)
04160   {
04161     /* can resolve specific component or all components (-1) */
04162     if((dwIndex == dwCount) || (dwIndex == -1))
04163     {
04164       if(SiCNodeGetAttributes(dwCount, TRUE, AC_ALL) & SIC_SELECTED)
04165       {
04166          bMoreToResolve = ResolveComponentDependency(siCTemp->siCDDependencies, hwndListBox);
04167          if(dwIndex == dwCount)
04168          {
04169            return(bMoreToResolve);
04170          }
04171       }
04172     }
04173 
04174     ++dwCount;
04175     siCTemp = siCTemp->Next;
04176     while((siCTemp != NULL) && (siCTemp != siComponents))
04177     {
04178       /* can resolve specific component or all components (-1) */
04179       if((dwIndex == dwCount) || (dwIndex == -1))
04180       {
04181         if(SiCNodeGetAttributes(dwCount, TRUE, AC_ALL) & SIC_SELECTED)
04182         {
04183            bMoreToResolve = ResolveComponentDependency(siCTemp->siCDDependencies, hwndListBox);
04184            if(dwIndex == dwCount)
04185            {
04186              return(bMoreToResolve);
04187            }
04188         }
04189       }
04190 
04191       ++dwCount;
04192       siCTemp = siCTemp->Next;
04193     }
04194   }
04195   return(bMoreToResolve);
04196 }
04197 
04198 BOOL ResolveComponentDependee(siCD *siCDInDependee)
04199 {
04200   int     dwIndex;
04201   siCD    *siCDDependeeTemp   = siCDInDependee;
04202   BOOL    bAtLeastOneSelected = FALSE;
04203 
04204   if(siCDDependeeTemp != NULL)
04205   {
04206     if((dwIndex = SiCNodeGetIndexRN(siCDDependeeTemp->szReferenceName)) != -1)
04207     {
04208       if((SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL) & SIC_SELECTED) == TRUE)
04209       {
04210         bAtLeastOneSelected = TRUE;
04211       }
04212     }
04213 
04214     siCDDependeeTemp = siCDDependeeTemp->Next;
04215     while((siCDDependeeTemp != NULL) && (siCDDependeeTemp != siCDInDependee))
04216     {
04217       if((dwIndex = SiCNodeGetIndexRN(siCDDependeeTemp->szReferenceName)) != -1)
04218       {
04219         if((SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL) & SIC_SELECTED) == TRUE)
04220         {
04221           bAtLeastOneSelected = TRUE;
04222         }
04223       }
04224 
04225       siCDDependeeTemp = siCDDependeeTemp->Next;
04226     }
04227   }
04228   return(bAtLeastOneSelected);
04229 }
04230 
04231 ssi* SsiGetNode(LPSTR szDescription)
04232 {
04233   ssi *ssiSiteSelectorTemp = ssiSiteSelector;
04234 
04235   do
04236   {
04237     if(ssiSiteSelectorTemp == NULL)
04238       break;
04239 
04240     if(stricmp(ssiSiteSelectorTemp->szDescription, szDescription) == 0)
04241       return(ssiSiteSelectorTemp);
04242 
04243     ssiSiteSelectorTemp = ssiSiteSelectorTemp->Next;
04244   } while((ssiSiteSelectorTemp != NULL) && (ssiSiteSelectorTemp != ssiSiteSelector));
04245 
04246   return(NULL);
04247 }
04248 
04249 void ResolveDependees(LPSTR szToggledReferenceName, HWND hwndListBox)
04250 {
04251   BOOL  bAtLeastOneSelected;
04252   BOOL  bMoreToResolve  = FALSE;
04253   siC   *siCTemp        = siComponents;
04254   DWORD dwIndex;
04255   DWORD dwAttrib;
04256 
04257   do
04258   {
04259     if(siCTemp == NULL)
04260       break;
04261 
04262     if((siCTemp->siCDDependees != NULL) &&
04263        (stricmp(siCTemp->szReferenceName, szToggledReferenceName) != 0))
04264     {
04265       bAtLeastOneSelected = ResolveComponentDependee(siCTemp->siCDDependees);
04266       if(bAtLeastOneSelected == FALSE)
04267       {
04268         if((dwIndex = SiCNodeGetIndexRN(siCTemp->szReferenceName)) != -1)
04269         {
04270           dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL);
04271           if((dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED))
04272           {
04273             SiCNodeSetAttributes(dwIndex, SIC_SELECTED, FALSE, TRUE, AC_ALL, hwndListBox);
04274             bMoreToResolve = TRUE;
04275           }
04276         }
04277       }
04278       else
04279       {
04280         if((dwIndex = SiCNodeGetIndexRN(siCTemp->szReferenceName)) != -1)
04281         {
04282           dwAttrib = SiCNodeGetAttributes(dwIndex, TRUE, AC_ALL);
04283           if(!(dwAttrib & SIC_SELECTED) && !(dwAttrib & SIC_DISABLED))
04284           {
04285             SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, TRUE, AC_ALL, hwndListBox);
04286             bMoreToResolve = TRUE;
04287           }
04288         }
04289       }
04290     }
04291 
04292     siCTemp = siCTemp->Next;
04293   } while((siCTemp != NULL) && (siCTemp != siComponents));
04294 
04295   if(bMoreToResolve == TRUE)
04296     ResolveDependees(szToggledReferenceName, hwndListBox);
04297 }
04298 
04299 void PrintUsage(PSZ szAppName)
04300 {
04301   char szBuf[MAX_BUF];
04302   char szUsageMsg[MAX_BUF];
04303   char szProcessFilename[MAX_BUF];
04304 
04305   /* -h: this help
04306    * -a [path]: Alternate archive search path
04307    * -n [filename]: setup's parent's process filename
04308    * -ma: run setup in Auto mode
04309    * -ms: run setup in Silent mode
04310    * -ira: ignore the [RunAppX] sections
04311    * -ispf: ignore the [Program FolderX] sections that show
04312    *        the Start Menu shortcut folder at the end of installation.
04313    */
04314 
04315   if(*sgProduct.szParentProcessFilename != '\0')
04316     strcpy(szProcessFilename, sgProduct.szParentProcessFilename);
04317   else
04318   {
04319     strcpy(szBuf, szAppName);
04320     ParsePath(szBuf, szProcessFilename, sizeof(szProcessFilename), FALSE, PP_FILENAME_ONLY);
04321   }
04322 
04323   GetPrivateProfileString("Strings", "UsageMsg Usage", "", szBuf, sizeof(szBuf), szFileIniConfig);
04324   sprintf(szUsageMsg, szBuf, szProcessFilename, "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n");
04325 
04326   PrintError(szUsageMsg, ERROR_CODE_HIDE);
04327 }
04328 
04329 ULONG ParseCommandLine(int argc, char *argv[])
04330 {
04331   char  szArgVBuf[MAX_BUF];
04332   int   i;
04333   int   iArgC;
04334 
04335 #ifdef XXX_DEBUG
04336   char  szBuf[MAX_BUF];
04337   char  szOutputStr[MAX_BUF];
04338 #endif
04339 
04340 #ifdef XXX_DEBUG
04341   sprintf(szOutputStr, "ArgC: %d\n", iArgC);
04342 #endif
04343 
04344   i = 0;
04345   while(i < argc)
04346   {
04347     if(!stricmp(argv[i], "-h") || !stricmp(argv[i], "/h"))
04348     {
04349       PrintUsage(argv[0]);
04350       return(WIZ_ERROR_UNDEFINED);
04351     }
04352     else if(!stricmp(argv[i], "-a") || !stricmp(argv[i], "/a"))
04353     {
04354       ++i;
04355       strcpy(sgProduct.szAlternateArchiveSearchPath, argv[i]);
04356     }
04357     else if(!stricmp(argv[i], "-n") || !stricmp(argv[i], "/n"))
04358     {
04359       ++i;
04360       strcpy(sgProduct.szParentProcessFilename, argv[i]);
04361     }
04362     else if(!stricmp(argv[i], "-ma") || !stricmp(argv[i], "/ma"))
04363       SetSetupRunMode("AUTO");
04364     else if(!stricmp(argv[i], "-ms") || !stricmp(argv[i], "/ms"))
04365       SetSetupRunMode("SILENT");
04366     else if(!stricmp(argv[i], "-ira") || !stricmp(argv[i], "/ira"))
04367       /* ignore [RunAppX] sections */
04368       gbIgnoreRunAppX = TRUE;
04369     else if(!stricmp(argv[i], "-ispf") || !stricmp(argv[i], "/ispf"))
04370       /* ignore [Program FolderX] sections */
04371       gbIgnoreProgramFolderX = TRUE;
04372 
04373 #ifdef XXX_DEBUG
04374     _itoa(i, szBuf, 10);
04375     strcat(szOutputStr, "    ");
04376     strcat(szOutputStr, szBuf);
04377     strcat(szOutputStr, ": ");
04378     strcat(szOutputStr, argv[i]);
04379     strcat(szOutputStr, "\n");
04380 #endif
04381 
04382     ++i;
04383   }
04384 
04385 #ifdef XXX_DEBUG
04386   WinMessageBox(HWND_DESKTOP, NULL, szOutputStr, "Output", 0, MB_OK);
04387 #endif
04388   return(WIZ_OK);
04389 }
04390 
04391 void GetAlternateArchiveSearchPath(LPSTR lpszCmdLine)
04392 {
04393   char  szBuf[MAX_PATH];
04394   LPSTR lpszAASPath;
04395   LPSTR lpszEndPath;
04396   LPSTR lpszEndQuote;
04397 
04398   if(strcpy(szBuf, lpszCmdLine))
04399   {
04400     if((lpszAASPath = strstr(szBuf, "-a")) == NULL)
04401       return;
04402     else
04403       lpszAASPath += 2;
04404 
04405     if(*lpszAASPath == '\"')
04406     {
04407       lpszAASPath = lpszAASPath + 1;
04408       if((lpszEndQuote = strstr(lpszAASPath, "\"")) != NULL)
04409       {
04410         *lpszEndQuote = '\0';
04411       }
04412     }
04413     else if((lpszEndPath = strstr(lpszAASPath, " ")) != NULL)
04414     {
04415       *lpszEndPath = '\0';
04416     }
04417 
04418     strcpy(sgProduct.szAlternateArchiveSearchPath, lpszAASPath);
04419   }
04420 }
04421 
04422 #define BUFMIN       8*1024
04423 #define BUFMAX       256*1024
04424 #define BUFDEFAULT 32*1024
04425 
04426 BOOL CheckForProcess(PID pid, LPSTR szProcessName, DWORD dwProcessName, PSZ szFQProcessName, DWORD dwFQProcessName)
04427 {
04428 /* Only compile this code if we have the new toolkit */
04429 #ifdef QS_PROCESS
04430   ULONG bufsize = BUFDEFAULT;
04431   QSPTRREC* pbh;
04432   APIRET rc = 0;
04433   CHAR szUpperAppName[CCHMAXPATH] = {0};
04434 
04435   /* Can't call with both - only one or the other */
04436   if (pid && szProcessName) {
04437     return FALSE;
04438   }
04439   if (szProcessName) {
04440     strcpy(szUpperAppName, szProcessName);
04441     strupr(szUpperAppName);
04442   }
04443   do {
04444     pbh = (QSPTRREC*) malloc(bufsize);
04445     if(!pbh) {
04446       if(bufsize <= BUFMIN)
04447         rc = ERROR_NOT_ENOUGH_MEMORY;
04448       else if(rc != ERROR_BUFFER_OVERFLOW)
04449         bufsize /= 2;
04450     } else {
04451       rc = DosQuerySysState(QS_PROCESS | QS_MTE, 0, 0, 0, pbh, bufsize);
04452       if(rc == ERROR_BUFFER_OVERFLOW) {
04453         if(bufsize < BUFMAX) {
04454           free(pbh);
04455           bufsize *= 2;
04456         } else {
04457           rc = ERROR_TOO_MANY_NAMES;    // give up.
04458         }
04459       }
04460     }
04461   } while(rc == ERROR_BUFFER_OVERFLOW);
04462 
04463   if(rc == NO_ERROR) {
04464     QSPREC* ppiLocal = pbh->pProcRec;
04465     while(ppiLocal->RecType == QS_PROCESS) {
04466       QSLREC* pmi = pbh->pLibRec;
04467       while (pmi && pmi->hmte != ppiLocal->hMte)
04468         pmi = (QSLREC*)pmi->pNextRec;
04469       if(pmi) {
04470         if ((szUpperAppName[0] && strstr((char*)pmi->pName, szUpperAppName)) ||
04471            (ppiLocal->pid == pid)) {
04472             if (szFQProcessName)
04473               strcpy(szFQProcessName, (char*)pmi->pName);
04474             if (pbh)
04475               free(pbh);
04476             return TRUE;
04477         }
04478       }
04479       ppiLocal=(QSPREC*)(ppiLocal->pThrdRec+ppiLocal->cTCB);
04480     }
04481   }
04482   if(pbh)
04483     free(pbh);
04484 #endif
04485   return FALSE;
04486 }
04487 
04488 int PreCheckInstance(char *szSection, char *szIniFile, char *szFQProcessName)
04489 {
04490   char  szParameter[MAX_BUF];
04491   char  szPath[MAX_BUF];
04492   ULONG ulCounter = 0;
04493   BOOL  bContinue = TRUE;
04494   char  szExtraCmd[] = "Extra Cmd";
04495   char  szExtraCmdParameter[MAX_BUF];
04496 
04497   do
04498   {
04499     /* Read the win reg key path */
04500     sprintf(szExtraCmdParameter, "%s%d Parameter", szExtraCmd, ulCounter);
04501     GetPrivateProfileString(szSection,
04502                             szExtraCmdParameter,
04503                             "",
04504                             szParameter,
04505                             sizeof(szParameter),
04506                             szIniFile);
04507     if(*szParameter == '\0')
04508     {
04509       bContinue = FALSE;
04510       continue;
04511     }
04512 
04513     ParsePath(szFQProcessName, szPath, sizeof(szPath), FALSE, PP_PATH_ONLY);
04514 
04515     // we've found a file, so let's execute it and stop.  No need to look
04516     // for other keys to parse.  We only want to do that if the file is
04517     // _not_ found.  This is for when we change the name of the browser
04518     // app file and still need to deal with locating it and calling
04519     // -kill on it. ie.
04520     //   previous name: netscp6.exe
04521     //   new name: netscp.exe
04522     // We only need to call one of them, not both.
04523     bContinue = FALSE;
04524 
04525     /* Run the file */
04526     WinSpawn(szFQProcessName, szParameter, szPath, TRUE);
04527 
04528     /* Even though WinSpawn is suppose to wait for the app to finish, this
04529      * does not really work that way for trying to quit the browser when
04530      * it's in turbo mode, so we wait 2 secs for it to complete. */
04531     DosSleep(2000);
04532     
04533     ++ulCounter;
04534   } while(bContinue);
04535 
04536   return(WIZ_OK);
04537 }
04538 
04539 ULONG CloseAllWindowsOfWindowHandle(HWND hwndWindow)
04540 {
04541   HENUM henum;
04542   HWND hwnd;
04543   PID mainpid, pid;
04544   TID tid;
04545 
04546   WinQueryWindowProcess(hwndWindow, &mainpid, &tid);
04547 
04548   henum = WinBeginEnumWindows(HWND_DESKTOP);
04549   while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
04550   {
04551     WinQueryWindowProcess(hwnd, &pid, &tid);
04552     if (pid == mainpid) {
04553       if (WinIsWindowVisible(hwnd)) {
04554         MRESULT rc = WinSendMsg(hwnd, WM_CLOSE, 0, 0);
04555         printf("rc = %x\n", rc);
04556       }
04557     }
04558   }
04559   WinEndEnumWindows(henum);
04560   /* The windows don't close quick enough, so we need to wait a bit */
04561   DosSleep(2500);
04562 
04563   return(WIZ_OK);
04564 }
04565 
04566 HRESULT CheckInstances()
04567 {
04568   char  szSection[MAX_BUF];
04569   char  szProcessName[CCHMAXPATH];
04570   char  szFQProcessName[CCHMAXPATH];
04571   char  szClassName[MAX_BUF];
04572   char  szCloseAllWindows[MAX_BUF];
04573   char  szAttention[MAX_BUF];
04574   char  szMessage[MAX_BUF];
04575   char  szMessageFulInstaller[MAX_BUF];
04576   char  szIndex[MAX_BUF];
04577   int   iIndex;
04578   BOOL  bContinue;
04579   BOOL  bCloseAllWindows;
04580   HWND  hwndFW;
04581   LPSTR szCN;
04582   DWORD dwRv0;
04583   DWORD dwRv1;
04584 
04585   bContinue = TRUE;
04586   iIndex    = -1;
04587   while(bContinue)
04588   {
04589     memset(szClassName,            0, sizeof(szClassName));
04590     memset(szMessage,              0, sizeof(szMessage));
04591     memset(szMessageFulInstaller, 0, sizeof(szMessageFulInstaller));
04592 
04593     ++iIndex;
04594     _itoa(iIndex, szIndex, 10);
04595     strcpy(szSection, "Check Instance");
04596     strcat(szSection, szIndex);
04597 
04598     GetPrivateProfileString("Messages", "MB_ATTENTION_STR", "", szAttention, sizeof(szAttention), szFileIniInstall);
04599     GetPrivateProfileString(szSection, "Message", "", szMessage, sizeof(szMessage), szFileIniConfig);
04600     GetPrivateProfileString(szSection, "Message Full Installer", "", szMessageFulInstaller, sizeof(szMessageFulInstaller), szFileIniConfig);
04601     if(!gbDownloadTriggered && !gbPreviousUnfinishedDownload && (*szMessageFulInstaller != '\0'))
04602       strcpy(szMessage, szMessageFulInstaller);
04603 
04604     if(GetPrivateProfileString(szSection, "Process Name", "", szProcessName, sizeof(szProcessName), szFileIniConfig) != 0L)
04605     {
04606       if(*szProcessName != '\0')
04607       {
04608         /* If an instance is found, call PreCheckInstance first */
04609         if(CheckForProcess(0, szProcessName, sizeof(szProcessName), szFQProcessName, sizeof(szFQProcessName)) == TRUE)
04610           PreCheckInstance(szSection, szFileIniConfig, szFQProcessName);
04611 
04612         if(CheckForProcess(0, szProcessName, sizeof(szProcessName), NULL, 0) == TRUE)
04613         {
04614           if(*szMessage != '\0')
04615           {
04616             switch(sgProduct.ulMode)
04617             {
04618               case NORMAL:
04619                 switch(WinMessageBox(HWND_DESKTOP, hWndMain, szMessage, szAttention, 0, MB_ICONEXCLAMATION | MB_OKCANCEL))
04620                 {
04621                   case MBID_CANCEL:
04622                     /* User selected to cancel Setup */
04623                     return(TRUE);
04624 
04625                   case MBID_RETRY:
04626                   case MBID_OK:
04627                     /* User selected to retry.  Reset counter */
04628                     iIndex = -1;
04629                     break;
04630                 }
04631                 break;
04632 
04633               case AUTO:
04634                 ShowMessage(szMessage, TRUE);
04635                 DosSleep(5000);
04636                 ShowMessage(szMessage, FALSE);
04637 
04638                 /* Setup mode is AUTO.  Show message, timeout, then cancel because we can't allow user to continue */
04639                 return(TRUE);
04640 
04641               case SILENT:
04642                 return(TRUE);
04643             }
04644           }
04645           else
04646           {
04647             /* No message to display.  Assume cancel because we can't allow user to continue */
04648             return(TRUE);
04649           }
04650         }
04651       }
04652 
04653       /* Process Name= key existed, and has been processed, so continue looking for more */
04654       continue;
04655     }
04656 
04657     GetPrivateProfileString(szSection, "Close All Process Windows", "", szCloseAllWindows, sizeof(szCloseAllWindows), szFileIniConfig);
04658     if(stricmp(szCloseAllWindows, "TRUE") == 0)
04659       bCloseAllWindows = TRUE;
04660     else
04661       bCloseAllWindows = FALSE;
04662 
04663     /* Process Name= key did not exist, so look for other keys */
04664     dwRv0 = GetPrivateProfileString(szSection, "Class Name",  "", szClassName,  sizeof(szClassName), szFileIniConfig);
04665     if (dwRv0 == 0L)
04666     {
04667       bContinue = FALSE;
04668     }
04669     else if(*szClassName != '\0')
04670     {
04671       if(*szClassName == '\0')
04672         szCN = NULL;
04673       else
04674         szCN = szClassName;
04675 
04676       /* If an instance is found, call PreCheckInstance first */
04677       if((hwndFW = FindWindow(szCN)) != NULL) {
04678         PID pid;
04679         TID tid;
04680         WinQueryWindowProcess(hwndFW, &pid, &tid);
04681         CheckForProcess(pid, NULL, 0, szFQProcessName, sizeof(szFQProcessName));
04682         PreCheckInstance(szSection, szFileIniConfig, szFQProcessName);
04683       }
04684 
04685       if((hwndFW = FindWindow(szCN)) != NULL)
04686       {
04687         if(*szMessage != '\0')
04688         {
04689           switch(sgProduct.ulMode)
04690           {
04691             case NORMAL:
04692               switch(WinMessageBox(HWND_DESKTOP, hWndMain, szMessage, szAttention, 0, MB_ICONEXCLAMATION | MB_OKCANCEL))
04693               {
04694                 case MBID_CANCEL:
04695                   /* User selected to cancel Setup */
04696                   return(TRUE);
04697 
04698                 case MBID_RETRY:
04699                 case MBID_OK:
04700                   /* User selected to retry.  Reset counter */
04701                   if(bCloseAllWindows)
04702                       CloseAllWindowsOfWindowHandle(hwndFW);
04703 
04704                   iIndex = -1;
04705                   break;
04706               }
04707               break;
04708 
04709             case AUTO:
04710               /* Setup mode is AUTO.  Show message, timeout, then auto close
04711                * all the windows associated with the process */
04712 
04713               ShowMessage(szMessage, TRUE);
04714               DosSleep(5000);
04715               ShowMessage(szMessage, FALSE);
04716 
04717               if(bCloseAllWindows)
04718                 CloseAllWindowsOfWindowHandle(hwndFW);
04719 
04720               return(TRUE);
04721 
04722             case SILENT:
04723               /* Setup mode is SILENT.  Just auto close
04724                * all the windows associated with the process */
04725 
04726               if(bCloseAllWindows)
04727                 CloseAllWindowsOfWindowHandle(hwndFW);
04728 
04729               return(TRUE);
04730           }
04731         }
04732         else
04733         {
04734           /* No message to display.  Assume cancel because we can't allow user to continue */
04735           return(TRUE);
04736         }
04737       }
04738     }
04739   }
04740 
04741   return(FALSE);
04742 }
04743 
04744 int CRCCheckArchivesStartup(char *szCorruptedArchiveList, DWORD dwCorruptedArchiveListSize, BOOL bIncludeTempPath)
04745 {
04746   DWORD dwIndex0;
04747   DWORD dwFileCounter;
04748   siC   *siCObject = NULL;
04749   char  szArchivePathWithFilename[MAX_BUF];
04750   char  szArchivePath[MAX_BUF];
04751   char  szMsgCRCCheck[MAX_BUF];
04752   char  szPartiallyDownloadedFilename[MAX_BUF];
04753   int   iRv;
04754   int   iResult;
04755 
04756   if(szCorruptedArchiveList != NULL)
04757     memset(szCorruptedArchiveList, 0, dwCorruptedArchiveListSize);
04758 
04759   GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename,
04760                               sizeof(szPartiallyDownloadedFilename));
04761   GetPrivateProfileString("Strings", "Message Verifying Archives", "", szMsgCRCCheck, sizeof(szMsgCRCCheck), szFileIniConfig);
04762   ShowMessage(szMsgCRCCheck, TRUE);
04763   
04764   iResult           = WIZ_CRC_PASS;
04765   dwIndex0          = 0;
04766   dwFileCounter     = 0;
04767   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
04768   while(siCObject)
04769   {
04770     /* only download jars if not already in the local machine */
04771     iRv = LocateJar(siCObject, szArchivePath, sizeof(szArchivePath), bIncludeTempPath);
04772     if((iRv != AP_NOT_FOUND) &&
04773        (stricmp(szPartiallyDownloadedFilename,
04774                  siCObject->szArchiveName) != 0))
04775     {
04776       if(strlen(szArchivePath) < sizeof(szArchivePathWithFilename))
04777         strcpy(szArchivePathWithFilename, szArchivePath);
04778 
04779       AppendBackSlash(szArchivePathWithFilename, sizeof(szArchivePathWithFilename));
04780       if((strlen(szArchivePathWithFilename) + strlen(siCObject->szArchiveName)) < sizeof(szArchivePathWithFilename))
04781         strcat(szArchivePathWithFilename, siCObject->szArchiveName);
04782 
04783       if(CheckForArchiveExtension(szArchivePathWithFilename))
04784       {
04785         /* Make sure that the Archive that failed is located in the TEMP
04786          * folder.  This means that it was downloaded at one point and not
04787          * simply uncompressed from the self-extracting exe file. */
04788         if(VerifyArchive(szArchivePathWithFilename) != ZIP_OK)
04789         {
04790           if(iRv == AP_TEMP_PATH)
04791             DosDelete(szArchivePathWithFilename);
04792           else if(szCorruptedArchiveList != NULL)
04793           {
04794             iResult = WIZ_CRC_FAIL;
04795             if((DWORD)(strlen(szCorruptedArchiveList) + strlen(siCObject->szArchiveName + 1)) < dwCorruptedArchiveListSize)
04796             {
04797               strcat(szCorruptedArchiveList, "        ");
04798               strcat(szCorruptedArchiveList, siCObject->szArchiveName);
04799               strcat(szCorruptedArchiveList, "\n");
04800             }
04801             else
04802             {
04803               iResult = WIZ_OUT_OF_MEMORY;
04804               break;
04805             }
04806           }
04807         }
04808       }
04809     }
04810 
04811     ++dwIndex0;
04812     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
04813   }
04814   ShowMessage(szMsgCRCCheck, FALSE);
04815   return(iResult);
04816 }
04817 
04818 int StartupCheckArchives(void)
04819 {
04820   int  iRv;
04821   char szBuf[MAX_BUF_SMALL];
04822   char szCorruptedArchiveList[MAX_BUF];
04823 
04824   iRv = CRCCheckArchivesStartup(szCorruptedArchiveList, sizeof(szCorruptedArchiveList), gbPreviousUnfinishedDownload);
04825   switch(iRv)
04826   {
04827     char szMsg[MAX_BUF];
04828     char szBuf2[MAX_BUF];
04829     char szTitle[MAX_BUF_TINY];
04830 
04831     case WIZ_CRC_FAIL:
04832       switch(sgProduct.ulMode)
04833       {
04834         case NORMAL:
04835           if(GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf, sizeof(szBuf), szFileIniInstall))
04836             strcpy(szTitle, "Setup");
04837           else
04838             sprintf(szTitle, szBuf, sgProduct.szProductName);
04839 
04840           GetPrivateProfileString("Strings", "Error Corrupted Archives Detected", "", szBuf, sizeof(szBuf), szFileIniConfig);
04841           if(*szBuf != '\0')
04842           {
04843             strcpy(szBuf2, "\n\n");
04844             strcat(szBuf2, szCorruptedArchiveList);
04845             strcat(szBuf2, "\n");
04846             sprintf(szMsg, szBuf, szBuf2);
04847           }
04848           WinMessageBox(HWND_DESKTOP, hWndMain, szMsg, szTitle, 0, MB_OK | MB_ERROR);
04849           break;
04850 
04851         case AUTO:
04852           GetPrivateProfileString("Strings", "Error Corrupted Archives Detected AUTO mode", "", szBuf, sizeof(szBuf), szFileIniConfig);
04853           ShowMessage(szBuf, TRUE);
04854           DosSleep(5000);
04855           ShowMessage(szBuf, FALSE);
04856           break;
04857       }
04858 
04859       LogISComponentsFailedCRC(szCorruptedArchiveList, W_STARTUP);
04860       return(WIZ_CRC_FAIL);
04861 
04862     case WIZ_CRC_PASS:
04863       break;
04864 
04865     default:
04866       break;
04867   }
04868   LogISComponentsFailedCRC(NULL, W_STARTUP);
04869   return(iRv);
04870 }
04871 
04872 HRESULT ParseConfigIni(int argc, char *argv[])
04873 {
04874   int  iRv;
04875   char szBuf[MAX_BUF];
04876   char szMsgInitSetup[MAX_BUF];
04877   char szPreviousPath[MAX_BUF];
04878   char szShowDialog[MAX_BUF];
04879   DWORD dwPreviousUnfinishedState;
04880 
04881   if(InitSetupGeneral())
04882     return(1);
04883   if(InitDlgWelcome(&diWelcome))
04884     return(1);
04885   if(InitDlgLicense(&diLicense))
04886     return(1);
04887   if(InitDlgSetupType(&diSetupType))
04888     return(1);
04889   if(InitDlgSelectComponents(&diSelectComponents, SM_SINGLE))
04890     return(1);
04891   if(InitDlgSelectComponents(&diSelectAdditionalComponents, SM_SINGLE))
04892     return(1);
04893   if(InitDlgOS2Integration(&diOS2Integration))
04894     return(1);
04895   if(InitDlgProgramFolder(&diProgramFolder))
04896     return(1);
04897   if(InitDlgAdditionalOptions(&diAdditionalOptions))
04898     return(1);
04899   if(InitDlgAdvancedSettings(&diAdvancedSettings))
04900     return(1);
04901   if(InitDlgQuickLaunch(&diQuickLaunch))
04902     return(1);
04903   if(InitDlgStartInstall(&diStartInstall))
04904     return(1);
04905   if(InitDlgDownload(&diDownload))
04906     return(1);
04907   if(InitDlgReboot(&diReboot))
04908     return(1);
04909   if(InitSXpcomFile())
04910     return(1);
04911  
04912   /* get install Mode information */
04913   GetPrivateProfileString("General", "Run Mode", "", szBuf, sizeof(szBuf), szFileIniConfig);
04914   SetSetupRunMode(szBuf);
04915   if(ParseCommandLine(argc, argv))
04916     return(1);
04917 
04918   if(GetPrivateProfileString("Messages", "MSG_INIT_SETUP", "", szMsgInitSetup, sizeof(szMsgInitSetup), szFileIniInstall))
04919     ShowMessage(szMsgInitSetup, TRUE);
04920 
04921   /* get product name description */
04922   GetPrivateProfileString("General", "Company Name", "", sgProduct.szCompanyName, MAX_BUF, szFileIniConfig);
04923   GetPrivateProfileString("General", "Product Name", "", sgProduct.szProductName, MAX_BUF, szFileIniConfig);
04924   GetPrivateProfileString("General", "Product Name Internal", "", sgProduct.szProductNameInternal, MAX_BUF, szFileIniConfig);
04925   if (sgProduct.szProductNameInternal[0] == 0)
04926     strcpy(sgProduct.szProductNameInternal, sgProduct.szProductName);
04927   GetPrivateProfileString("General", "Product Name Previous", "", sgProduct.szProductNamePrevious, MAX_BUF, szFileIniConfig);
04928   GetPrivateProfileString("General", "Uninstall Filename", "", sgProduct.szUninstallFilename, MAX_BUF, szFileIniConfig);
04929   GetPrivateProfileString("General", "User Agent",   "", sgProduct.szUserAgent,   MAX_BUF, szFileIniConfig);
04930   GetPrivateProfileString("General", "Sub Path",     "", sgProduct.szSubPath,     MAX_BUF, szFileIniConfig);
04931   GetPrivateProfileString("General", "Program Name", "", sgProduct.szProgramName, MAX_BUF, szFileIniConfig);
04932   GetPrivateProfileString("General", "Lock Path",    "", szBuf,                   sizeof(szBuf), szFileIniConfig);
04933   if(stricmp(szBuf, "TRUE") == 0)
04934     sgProduct.bLockPath = TRUE;
04935 
04936   /* get main install path */
04937   if(LocatePreviousPath("Locate Previous Product Path", szPreviousPath, sizeof(szPreviousPath)) == FALSE)
04938   {
04939     GetPrivateProfileString("General", "Path", "", szBuf, sizeof(szBuf), szFileIniConfig);
04940     DecryptString(sgProduct.szPath, szBuf);
04941   }
04942   else
04943   {
04944     /* If the previous path is located in the regsitry, then we need to check to see if the path from
04945      * the regsitry plus the Sub Path contains the Program Name file.  If it does, then we have the
04946      * correct path, so just use it.
04947      *
04948      * If it does not contain the Program Name file, then check the parent path (from the registry) +
04949      * SubPath.  If this path contains the Program Name file, then we found an older path format.  We
04950      * then need to use the parent path as the default path.
04951      *
04952      * Only do the older path format checking if the Sub Path= and Program Name= keys exist.  If
04953      * either are not set, then assume that the path from the registry is what we want.
04954      */
04955     if((*sgProduct.szSubPath != '\0') && (*sgProduct.szProgramName != '\0'))
04956     {
04957       /* If the Sub Path= and Program Name= keys exist, do extra parsing for the correct path */
04958       strcpy(szBuf, szPreviousPath);
04959       AppendBackSlash(szBuf, sizeof(szBuf));
04960       strcat(szBuf, sgProduct.szSubPath);
04961       AppendBackSlash(szBuf, sizeof(szBuf));
04962       strcat(szBuf, sgProduct.szProgramName);
04963 
04964       /* Check to see if PreviousPath + SubPath + ProgramName exists.  If it does, then we have the
04965        * correct path.
04966        */
04967       if(FileExists(szBuf))
04968       {
04969         strcpy(sgProduct.szPath, szPreviousPath);
04970       }
04971       else
04972       {
04973         /* If not, try parent of PreviousPath + SubPath + ProgramName.
04974          * If this exists, then we need to use the parent path of PreviousPath.
04975          */
04976         RemoveBackSlash(szPreviousPath);
04977         ParsePath(szPreviousPath, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY);
04978         AppendBackSlash(szBuf, sizeof(szBuf));
04979         strcat(szBuf, sgProduct.szSubPath);
04980         AppendBackSlash(szBuf, sizeof(szBuf));
04981         strcat(szBuf, sgProduct.szProgramName);
04982 
04983         if(FileExists(szBuf))
04984         {
04985           RemoveBackSlash(szPreviousPath);
04986           ParsePath(szPreviousPath, szBuf, sizeof(szBuf), FALSE, PP_PATH_ONLY);
04987           strcpy(sgProduct.szPath, szBuf);
04988         }
04989         else
04990         {
04991           /* If we still can't locate ProgramName file, then use the default in the config.ini */
04992           GetPrivateProfileString("General", "Path", "", szBuf, sizeof(szBuf), szFileIniConfig);
04993           DecryptString(sgProduct.szPath, szBuf);
04994         }
04995       }
04996     }
04997     else
04998     {
04999       strcpy(sgProduct.szPath, szPreviousPath);
05000     }
05001   }
05002   RemoveBackSlash(sgProduct.szPath);
05003 
05004   /* make a copy of sgProduct.szPath to be used in the Setup Type dialog */
05005   strcpy(szTempSetupPath, sgProduct.szPath);
05006   
05007   /* get main program folder path */
05008   GetPrivateProfileString("General", "Program Folder Path", "", szBuf, sizeof(szBuf), szFileIniConfig);
05009   DecryptString(sgProduct.szProgramFolderPath, szBuf);
05010   
05011   /* get main program folder name */
05012   GetPrivateProfileString("General", "Program Folder Name", "", szBuf, sizeof(szBuf), szFileIniConfig);
05013   DecryptString(sgProduct.szProgramFolderName, szBuf);
05014 
05015   /* Welcome dialog */
05016   GetPrivateProfileString("Dialog Welcome",             "Show Dialog",     "", szShowDialog,                  sizeof(szShowDialog), szFileIniConfig);
05017   GetPrivateProfileString("Dialog Welcome",             "Title",           "", diWelcome.szTitle,             MAX_BUF, szFileIniConfig);
05018   GetPrivateProfileString("Dialog Welcome",             "Message0",        "", diWelcome.szMessage0,          MAX_BUF, szFileIniConfig);
05019   GetPrivateProfileString("Dialog Welcome",             "Message1",        "", diWelcome.szMessage1,          MAX_BUF, szFileIniConfig);
05020   GetPrivateProfileString("Dialog Welcome",             "Message2",        "", diWelcome.szMessage2,          MAX_BUF, szFileIniConfig);
05021   if(stricmp(szShowDialog, "TRUE") == 0)
05022     diWelcome.bShowDialog = TRUE;
05023 
05024   /* License dialog */
05025   GetPrivateProfileString("Dialog License",             "Show Dialog",     "", szShowDialog,                  sizeof(szShowDialog), szFileIniConfig);
05026   GetPrivateProfileString("Dialog License",             "Title",           "", diLicense.szTitle,             MAX_BUF, szFileIniConfig);
05027   GetPrivateProfileString("Dialog License",             "License File",    "", diLicense.szLicenseFilename,   MAX_BUF, szFileIniConfig);
05028   GetPrivateProfileString("Dialog License",             "Message0",        "", diLicense.szMessage0,          MAX_BUF, szFileIniConfig);
05029   GetPrivateProfileString("Dialog License",             "Message1",        "", diLicense.szMessage1,          MAX_BUF, szFileIniConfig);
05030   if(stricmp(szShowDialog, "TRUE") == 0)
05031     diLicense.bShowDialog = TRUE;
05032 
05033   /* Setup Type dialog */
05034   GetPrivateProfileString("Dialog Setup Type",          "Show Dialog",     "", szShowDialog,                  sizeof(szShowDialog), szFileIniConfig);
05035   GetPrivateProfileString("Dialog Setup Type",          "Title",           "", diSetupType.szTitle,           MAX_BUF, szFileIniConfig);
05036   GetPrivateProfileString("Dialog Setup Type",          "Message0",        "", diSetupType.szMessage0,        MAX_BUF, szFileIniConfig);
05037   GetPrivateProfileString("Dialog Setup Type",          "Readme Filename", "", diSetupType.szReadmeFilename,  MAX_BUF, szFileIniConfig);
05038   GetPrivateProfileString("Dialog Setup Type",          "Readme App",      "", diSetupType.szReadmeApp,       MAX_BUF, szFileIniConfig);
05039   if(stricmp(szShowDialog, "TRUE") == 0)
05040     diSetupType.bShowDialog = TRUE;
05041 
05042   /* Get Setup Types info */
05043   GetPrivateProfileString("Setup Type0", "Description Short", "", diSetupType.stSetupType0.szDescriptionShort, MAX_BUF, szFileIniConfig);
05044   GetPrivateProfileString("Setup Type0", "Description Long",  "", diSetupType.stSetupType0.szDescriptionLong,  MAX_BUF, szFileIniConfig);
05045   STSetVisibility(&diSetupType.stSetupType0);
05046 
05047   GetPrivateProfileString("Setup Type1", "Description Short", "", diSetupType.stSetupType1.szDescriptionShort, MAX_BUF, szFileIniConfig);
05048   GetPrivateProfileString("Setup Type1", "Description Long",  "", diSetupType.stSetupType1.szDescriptionLong,  MAX_BUF, szFileIniConfig);
05049   STSetVisibility(&diSetupType.stSetupType1);
05050 
05051   GetPrivateProfileString("Setup Type2", "Description Short", "", diSetupType.stSetupType2.szDescriptionShort, MAX_BUF, szFileIniConfig);
05052   GetPrivateProfileString("Setup Type2", "Description Long",  "", diSetupType.stSetupType2.szDescriptionLong,  MAX_BUF, szFileIniConfig);
05053   STSetVisibility(&diSetupType.stSetupType2);
05054 
05055   GetPrivateProfileString("Setup Type3", "Description Short", "", diSetupType.stSetupType3.szDescriptionShort, MAX_BUF, szFileIniConfig);
05056   GetPrivateProfileString("Setup Type3", "Description Long",  "", diSetupType.stSetupType3.szDescriptionLong,  MAX_BUF, szFileIniConfig);
05057   STSetVisibility(&diSetupType.stSetupType3);
05058 
05059   /* remember the radio button that is considered the Custom type (the last radio button) */
05060   SetCustomType();
05061 
05062   /* Select Components dialog */
05063   GetPrivateProfileString("Dialog Select Components",   "Show Dialog",  "", szShowDialog,                    sizeof(szShowDialog), szFileIniConfig);
05064   GetPrivateProfileString("Dialog Select Components",   "Title",        "", diSelectComponents.szTitle,      MAX_BUF, szFileIniConfig);
05065   GetPrivateProfileString("Dialog Select Components",   "Message0",     "", diSelectComponents.szMessage0,   MAX_BUF, szFileIniConfig);
05066   if(stricmp(szShowDialog, "TRUE") == 0)
05067     diSelectComponents.bShowDialog = TRUE;
05068 
05069   /* Select Additional Components dialog */
05070   GetPrivateProfileString("Dialog Select Additional Components",   "Show Dialog",  "", szShowDialog,                              sizeof(szShowDialog), szFileIniConfig);
05071   GetPrivateProfileString("Dialog Select Additional Components",   "Title",        "", diSelectAdditionalComponents.szTitle,      MAX_BUF, szFileIniConfig);
05072   GetPrivateProfileString("Dialog Select Additional Components",   "Message0",     "", diSelectAdditionalComponents.szMessage0,   MAX_BUF, szFileIniConfig);
05073   if(stricmp(szShowDialog, "TRUE") == 0)
05074     diSelectAdditionalComponents.bShowDialog = TRUE;
05075 
05076   /* OS/2 Integration dialog */
05077   GetPrivateProfileString("Dialog OS/2 Integration", "Show Dialog",  "", szShowDialog,                    sizeof(szShowDialog), szFileIniConfig);
05078   GetPrivateProfileString("Dialog OS/2 Integration", "Title",        "", diOS2Integration.szTitle,    MAX_BUF, szFileIniConfig);
05079   GetPrivateProfileString("Dialog OS/2 Integration", "Message0",     "", diOS2Integration.szMessage0, MAX_BUF, szFileIniConfig);
05080   GetPrivateProfileString("Dialog OS/2 Integration", "Message1",     "", diOS2Integration.szMessage1, MAX_BUF, szFileIniConfig);
05081   if(stricmp(szShowDialog, "TRUE") == 0)
05082     diOS2Integration.bShowDialog = TRUE;
05083 
05084   /* Additional Options dialog */
05085   GetPrivateProfileString("Dialog Additional Options",       "Show Dialog",    "", szShowDialog,                     sizeof(szShowDialog), szFileIniConfig);
05086   GetPrivateProfileString("Dialog Additional Options",       "Title",          "", diAdditionalOptions.szTitle,        MAX_BUF, szFileIniConfig);
05087   GetPrivateProfileString("Dialog Additional Options",       "Message0",       "", diAdditionalOptions.szMessage0,     MAX_BUF, szFileIniConfig);
05088   GetPrivateProfileString("Dialog Additional Options",       "Message1",       "", diAdditionalOptions.szMessage1,     MAX_BUF, szFileIniConfig);
05089 
05090   GetPrivateProfileString("Dialog Additional Options",       "Save Installer", "", szBuf,                            sizeof(szBuf), szFileIniConfig);
05091   if(stricmp(szBuf, "TRUE") == 0)
05092     diAdditionalOptions.bSaveInstaller = TRUE;
05093 
05094   GetPrivateProfileString("Dialog Additional Options",       "Recapture Homepage", "", szBuf,                            sizeof(szBuf), szFileIniConfig);
05095   if(stricmp(szBuf, "TRUE") == 0)
05096     diAdditionalOptions.bRecaptureHomepage = TRUE;
05097 
05098   GetPrivateProfileString("Dialog Additional Options",       "Show Homepage Option", "", szBuf,                            sizeof(szBuf), szFileIniConfig);
05099   if(stricmp(szBuf, "TRUE") == 0)
05100     diAdditionalOptions.bShowHomepageOption = TRUE;
05101 
05102   if(stricmp(szShowDialog, "TRUE") == 0)
05103     diAdditionalOptions.bShowDialog = TRUE;
05104 
05105   /* Advanced Settings dialog */
05106   GetPrivateProfileString("Dialog Advanced Settings",       "Show Dialog",    "", szShowDialog,                     sizeof(szShowDialog), szFileIniConfig);
05107   GetPrivateProfileString("Dialog Advanced Settings",       "Title",          "", diAdvancedSettings.szTitle,       MAX_BUF, szFileIniConfig);
05108   GetPrivateProfileString("Dialog Advanced Settings",       "Message0",       "", diAdvancedSettings.szMessage0,    MAX_BUF, szFileIniConfig);
05109   GetPrivateProfileString("Dialog Advanced Settings",       "Proxy Server",   "", diAdvancedSettings.szProxyServer, MAX_BUF, szFileIniConfig);
05110   GetPrivateProfileString("Dialog Advanced Settings",       "Proxy Port",     "", diAdvancedSettings.szProxyPort,   MAX_BUF, szFileIniConfig);
05111   GetPrivateProfileString("Dialog Advanced Settings",       "Proxy User",     "", diAdvancedSettings.szProxyUser,   MAX_BUF, szFileIniConfig);
05112   GetPrivateProfileString("Dialog Advanced Settings",       "Proxy Password", "", diAdvancedSettings.szProxyPasswd, MAX_BUF, szFileIniConfig);
05113   if(stricmp(szShowDialog, "TRUE") == 0)
05114     diAdvancedSettings.bShowDialog = TRUE;
05115 
05116   GetPrivateProfileString("Dialog Advanced Settings",       "Use Protocol",   "", szBuf,                            sizeof(szBuf), szFileIniConfig);
05117   if(stricmp(szBuf, "HTTP") == 0)
05118     diAdditionalOptions.dwUseProtocol = UP_HTTP;
05119   else
05120     diAdditionalOptions.dwUseProtocol = UP_FTP;
05121 
05122   GetPrivateProfileString("Dialog Advanced Settings",       "Use Protocol Settings", "", szBuf,                     sizeof(szBuf), szFileIniConfig);
05123   if(stricmp(szBuf, "DISABLED") == 0)
05124     diAdditionalOptions.bUseProtocolSettings = FALSE;
05125   else
05126     diAdditionalOptions.bUseProtocolSettings = TRUE;
05127 
05128   GetPrivateProfileString("Dialog Advanced Settings",
05129                           "Show Protocols",
05130                           "",
05131                           szBuf,
05132                           sizeof(szBuf), szFileIniConfig);
05133   if(stricmp(szBuf, "FALSE") == 0)
05134     diAdditionalOptions.bShowProtocols = FALSE;
05135   else
05136     diAdditionalOptions.bShowProtocols = TRUE;
05137 
05138    /* Quick Launch dialog */
05139   GetPrivateProfileString("Dialog Quick Launch",      "Show Dialog",  "", szShowDialog,                    sizeof(szShowDialog), szFileIniConfig);
05140   GetPrivateProfileString("Dialog Quick Launch",      "Title",        "", diQuickLaunch.szTitle,         MAX_BUF, szFileIniConfig);
05141   GetPrivateProfileString("Dialog Quick Launch",      "Message0",     "", diQuickLaunch.szMessage0,      MAX_BUF, szFileIniConfig);
05142   GetPrivateProfileString("Dialog Quick Launch",      "Message1",     "", diQuickLaunch.szMessage1,      MAX_BUF, szFileIniConfig);
05143   GetPrivateProfileString("Dialog Quick Launch",      "Message2",     "", diQuickLaunch.szMessage2,      MAX_BUF, szFileIniConfig);
05144   if(stricmp(szShowDialog, "TRUE") == 0)
05145     diQuickLaunch.bShowDialog = TRUE;
05146   GetPrivateProfileString("Dialog Quick Launch",       "Turbo Mode",         "", szBuf,                          sizeof(szBuf), szFileIniConfig);
05147   if(stricmp(szBuf, "TRUE") == 0)
05148     diQuickLaunch.bTurboMode = TRUE;   
05149   GetPrivateProfileString("Dialog Quick Launch",       "Turbo Mode Enabled","", szBuf,                          sizeof(szBuf), szFileIniConfig);
05150   if(stricmp(szBuf, "TRUE") == 0)
05151     diQuickLaunch.bTurboModeEnabled = TRUE;
05152   else
05153     /* since turbo mode is disabled, make sure bTurboMode is FALSE */
05154     diQuickLaunch.bTurboMode = FALSE;
05155 
05156   /* Start Install dialog */
05157   GetPrivateProfileString("Dialog Start Install",       "Show Dialog",      "", szShowDialog,                     sizeof(szShowDialog), szFileIniConfig);
05158   GetPrivateProfileString("Dialog Start Install",       "Title",            "", diStartInstall.szTitle,           MAX_BUF, szFileIniConfig);
05159   GetPrivateProfileString("Dialog Start Install",       "Message Install",  "", diStartInstall.szMessageInstall,  MAX_BUF, szFileIniConfig);
05160   GetPrivateProfileString("Dialog Start Install",       "Message Download", "", diStartInstall.szMessageDownload, MAX_BUF, szFileIniConfig);
05161   if(stricmp(szShowDialog, "TRUE") == 0)
05162     diStartInstall.bShowDialog = TRUE;
05163  
05164   /* Download dialog */
05165   GetPrivateProfileString("Dialog Download",       "Show Dialog",        "", szShowDialog,                   sizeof(szShowDialog),        szFileIniConfig);
05166   GetPrivateProfileString("Dialog Download",       "Title",              "", diDownload.szTitle,             MAX_BUF_TINY,   szFileIniConfig);
05167   GetPrivateProfileString("Dialog Download",       "Message Download0",  "", diDownload.szMessageDownload0,  MAX_BUF_MEDIUM, szFileIniConfig);
05168   GetPrivateProfileString("Dialog Download",       "Message Retry0",     "", diDownload.szMessageRetry0,     MAX_BUF_MEDIUM, szFileIniConfig);
05169   if(stricmp(szShowDialog, "TRUE") == 0)
05170     diDownload.bShowDialog = TRUE;
05171 
05172   /* Reboot dialog */
05173   GetPrivateProfileString("Dialog Reboot", "Show Dialog", "", szShowDialog, sizeof(szShowDialog), szFileIniConfig);
05174   if(stricmp(szShowDialog, "TRUE") == 0)
05175     diReboot.dwShowDialog = TRUE;
05176   else if(stricmp(szShowDialog, "AUTO") == 0)
05177     diReboot.dwShowDialog = AUTO;
05178 
05179   GetPrivateProfileString("OS/2 Integration-Item0", "CheckBoxState", "", szBuf,                                    sizeof(szBuf), szFileIniConfig);
05180   GetPrivateProfileString("OS/2 Integration-Item0", "Description",   "", diOS2Integration.oiCBMakeDefaultBrowser.szDescription, MAX_BUF, szFileIniConfig);
05181   /* Check to see if the checkbox need to be shown at all or not */
05182   if(*diOS2Integration.oiCBMakeDefaultBrowser.szDescription != '\0')
05183     diOS2Integration.oiCBMakeDefaultBrowser.bEnabled = TRUE;
05184   /* check to see if the checkbox needs to be checked by default or not */
05185   if(stricmp(szBuf, "TRUE") == 0)
05186     diOS2Integration.oiCBMakeDefaultBrowser.bCheckBoxState = TRUE;
05187 
05188   GetPrivateProfileString("OS/2 Integration-Item1", "CheckBoxState", "", szBuf,                           sizeof(szBuf), szFileIniConfig);
05189   GetPrivateProfileString("OS/2 Integration-Item1", "Description",   "", diOS2Integration.oiCBAssociateHTML.szDescription, MAX_BUF, szFileIniConfig);
05190   /* Check to see if the checkbox need to be shown at all or not */
05191   if(*diOS2Integration.oiCBAssociateHTML.szDescription != '\0')
05192     diOS2Integration.oiCBAssociateHTML.bEnabled = TRUE;
05193   /* check to see if the checkbox needs to be checked by default or not */
05194   if(stricmp(szBuf, "TRUE") == 0)
05195     diOS2Integration.oiCBAssociateHTML.bCheckBoxState = TRUE;
05196 
05197   GetPrivateProfileString("OS/2 Integration-Item2", "CheckBoxState", "", szBuf,                           sizeof(szBuf), szFileIniConfig);
05198   GetPrivateProfileString("OS/2 Integration-Item2", "Description",   "", diOS2Integration.oiCBUpdateCONFIGSYS.szDescription, MAX_BUF, szFileIniConfig);
05199   /* Check to see if the checkbox need to be shown at all or not */
05200   if(*diOS2Integration.oiCBUpdateCONFIGSYS.szDescription != '\0')
05201     diOS2Integration.oiCBUpdateCONFIGSYS.bEnabled = TRUE;
05202   /* check to see if the checkbox needs to be checked by default or not */
05203   if(stricmp(szBuf, "TRUE") == 0)
05204     diOS2Integration.oiCBUpdateCONFIGSYS.bCheckBoxState = TRUE;
05205 
05206   /* Read in the Site Selector Status */
05207   GetPrivateProfileString("Site Selector", "Status", "", szBuf, sizeof(szBuf), szFileIniConfig);
05208   if(stricmp(szBuf, "HIDE") == 0)
05209     gulSiteSelectorStatus = SS_HIDE;
05210 
05211   switch(sgProduct.ulMode)
05212   {
05213     case AUTO:
05214     case SILENT:
05215       diWelcome.bShowDialog                     = FALSE;
05216       diLicense.bShowDialog                     = FALSE;
05217       diSetupType.bShowDialog                   = FALSE;
05218       diSelectComponents.bShowDialog            = FALSE;
05219       diSelectAdditionalComponents.bShowDialog  = FALSE;
05220       diOS2Integration.bShowDialog          = FALSE;
05221       diProgramFolder.bShowDialog               = FALSE;
05222       diQuickLaunch.bShowDialog                 = FALSE;
05223       diAdditionalOptions.bShowDialog             = FALSE;
05224       diAdvancedSettings.bShowDialog            = FALSE;
05225       diStartInstall.bShowDialog                = FALSE;
05226       diDownload.bShowDialog                    = FALSE;
05227       break;
05228   }
05229 
05230   InitSiComponents(szFileIniConfig);
05231   InitSiteSelector(szFileIniConfig);
05232   InitErrorMessageStream(szFileIniConfig);
05233 
05234   /* get Default Setup Type */
05235   GetPrivateProfileString("General", "Default Setup Type", "", szBuf, sizeof(szBuf), szFileIniConfig);
05236   if((stricmp(szBuf, "Setup Type 0") == 0) && diSetupType.stSetupType0.bVisible)
05237   {
05238     ulSetupType     = ST_RADIO0;
05239     ulTempSetupType = ulSetupType;
05240   }
05241   else if((stricmp(szBuf, "Setup Type 1") == 0) && diSetupType.stSetupType1.bVisible)
05242   {
05243     ulSetupType     = ST_RADIO1;
05244     ulTempSetupType = ulSetupType;
05245   }
05246   else if((stricmp(szBuf, "Setup Type 2") == 0) && diSetupType.stSetupType2.bVisible)
05247   {
05248     ulSetupType     = ST_RADIO2;
05249     ulTempSetupType = ulSetupType;
05250   }
05251   else if((stricmp(szBuf, "Setup Type 3") == 0) && diSetupType.stSetupType3.bVisible)
05252   {
05253     ulSetupType     = ST_RADIO3;
05254     ulTempSetupType = ulSetupType;
05255   }
05256   else
05257   {
05258     if(diSetupType.stSetupType0.bVisible)
05259     {
05260       ulSetupType     = ST_RADIO0;
05261       ulTempSetupType = ulSetupType;
05262     }
05263     else if(diSetupType.stSetupType1.bVisible)
05264     {
05265       ulSetupType     = ST_RADIO1;
05266       ulTempSetupType = ulSetupType;
05267     }
05268     else if(diSetupType.stSetupType2.bVisible)
05269     {
05270       ulSetupType     = ST_RADIO2;
05271       ulTempSetupType = ulSetupType;
05272     }
05273     else if(diSetupType.stSetupType3.bVisible)
05274     {
05275       ulSetupType     = ST_RADIO3;
05276       ulTempSetupType = ulSetupType;
05277     }
05278   }
05279   SiCNodeSetItemsSelected(ulSetupType);
05280 
05281   /* get install size required in temp for component Xpcom.  Sould be in Kilobytes */
05282   GetPrivateProfileString("Core", "Install Size", "", szBuf, sizeof(szBuf), szFileIniConfig);
05283   if(*szBuf != '\0')
05284     siCFXpcomFile.ulInstallSize = atoi(szBuf);
05285   else
05286     siCFXpcomFile.ulInstallSize = 0;
05287 
05288   GetPrivateProfileString("Core",                           "Source",           "", szBuf,                        sizeof(szBuf), szFileIniConfig);
05289   DecryptString(siCFXpcomFile.szSource, szBuf);
05290   GetPrivateProfileString("Core",                           "Destination",      "", szBuf,                        sizeof(szBuf), szFileIniConfig);
05291   DecryptString(siCFXpcomFile.szDestination, szBuf);
05292   GetPrivateProfileString("Core",                           "Message",          "", siCFXpcomFile.szMessage,      MAX_BUF, szFileIniConfig);
05293   GetPrivateProfileString("Core",                           "Cleanup",          "", szBuf,                        sizeof(szBuf), szFileIniConfig);
05294   if(stricmp(szBuf, "FALSE") == 0)
05295     siCFXpcomFile.bCleanup = FALSE;
05296   else
05297     siCFXpcomFile.bCleanup = TRUE;
05298 
05299   LogISProductInfo();
05300   LogMSProductInfo();
05301   CleanupXpcomFile();
05302   ShowMessage(szMsgInitSetup, FALSE);
05303 
05304   /* check the windows registry to see if a previous instance of setup finished downloading
05305    * all the required archives. */
05306   dwPreviousUnfinishedState = GetPreviousUnfinishedState();
05307   gbPreviousUnfinishedDownload = dwPreviousUnfinishedState == PUS_DOWNLOAD;
05308   if(gbPreviousUnfinishedDownload)
05309   {
05310     char szTitle[MAX_BUF_TINY];
05311 
05312     switch(sgProduct.ulMode)
05313     {
05314       case NORMAL:
05315         if(!GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf, sizeof(szBuf), szFileIniInstall))
05316           strcpy(szTitle, "Setup");
05317         else
05318           sprintf(szTitle, szBuf, sgProduct.szProductName);
05319 
05320         GetPrivateProfileString("Strings", "Message Unfinished Download Restart", "", szBuf, sizeof(szBuf), szFileIniConfig);
05321         if(WinMessageBox(HWND_DESKTOP, hWndMain, szBuf, szTitle, 0, MB_YESNO | MB_ICONQUESTION) == MBID_NO)
05322         {
05323           UnsetSetupCurrentDownloadFile();
05324           UnsetSetupState(); /* unset the download state so that the archives can be deleted */
05325           DeleteArchives(DA_ONLY_IF_NOT_IN_ARCHIVES_LST);
05326         }
05327         break;
05328     }
05329   }
05330   else if((dwPreviousUnfinishedState == PUS_UNPACK_XPCOM) || (dwPreviousUnfinishedState == PUS_INSTALL_XPI))
05331   {
05332     char szTitle[MAX_BUF_TINY];
05333 
05334     // need to set this var to true even though the previous state was not the
05335     // download state.  This is because it is used for disk space calculation
05336     // wrt saved downloaded files and making sure CRC checks are performed on
05337     // them.
05338     gbPreviousUnfinishedDownload = TRUE;
05339     switch(sgProduct.ulMode)
05340     {
05341       case NORMAL:
05342         if(!GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf, sizeof(szBuf), szFileIniInstall))
05343           strcpy(szTitle, "Setup");
05344         else
05345           sprintf(szTitle, szBuf, sgProduct.szProductName);
05346 
05347         GetPrivateProfileString("Strings", "Message Unfinished Install Xpi Restart", "", szBuf, sizeof(szBuf), szFileIniConfig);
05348         if(WinMessageBox(HWND_DESKTOP, hWndMain, szBuf, szTitle, 0, MB_YESNO | MB_ICONQUESTION) == MBID_NO)
05349         {
05350           UnsetSetupCurrentDownloadFile();
05351           UnsetSetupState(); /* unset the installing xpis state so that the archives can be deleted */
05352           DeleteArchives(DA_ONLY_IF_NOT_IN_ARCHIVES_LST);
05353         }
05354         break;
05355     }
05356   }
05357 
05358   iRv = StartupCheckArchives();
05359   return(iRv);
05360 }
05361 
05362 HRESULT ParseInstallIni()
05363 {
05364   /* get system font */
05365   /* @MAK - we need to query this from somewhere */
05366   strcpy(sgInstallGui.szDefinedFont, "9");
05367   strcat(sgInstallGui.szDefinedFont, ".");
05368   strcat(sgInstallGui.szDefinedFont, "WarpSans");
05369 
05370   /* get defined font */
05371   GetPrivateProfileString("General", "FONTNAME", "", sgInstallGui.szFontName, sizeof(sgInstallGui.szFontName), szFileIniInstall);
05372   GetPrivateProfileString("General", "FONTSIZE", "", sgInstallGui.szFontSize, sizeof(sgInstallGui.szFontSize), szFileIniInstall);
05373   GetPrivateProfileString("General", "CHARSET", "", sgInstallGui.szCharSet, sizeof(sgInstallGui.szCharSet), szFileIniInstall);
05374   strcpy(sgInstallGui.szDefinedFont, sgInstallGui.szFontSize);
05375   strcat(sgInstallGui.szDefinedFont, ".");
05376   strcat(sgInstallGui.szDefinedFont, sgInstallGui.szFontName);
05377 
05378   GetPrivateProfileString("General", "OK_", "", sgInstallGui.szOk_, sizeof(sgInstallGui.szOk_), szFileIniInstall);
05379   GetPrivateProfileString("General", "OK", "", sgInstallGui.szOk, sizeof(sgInstallGui.szOk), szFileIniInstall);
05380   GetPrivateProfileString("General", "CANCEL_", "", sgInstallGui.szCancel_, sizeof(sgInstallGui.szCancel_), szFileIniInstall);
05381   GetPrivateProfileString("General", "CANCEL", "", sgInstallGui.szCancel, sizeof(sgInstallGui.szCancel), szFileIniInstall);
05382   GetPrivateProfileString("General", "NEXT_", "", sgInstallGui.szNext_, sizeof(sgInstallGui.szNext_), szFileIniInstall);
05383   GetPrivateProfileString("General", "BACK_", "", sgInstallGui.szBack_, sizeof(sgInstallGui.szBack_), szFileIniInstall);
05384   GetPrivateProfileString("General", "PROXYSETTINGS_", "", sgInstallGui.szProxySettings_, sizeof(sgInstallGui.szProxySettings_), szFileIniInstall);
05385   GetPrivateProfileString("General", "PROXYSETTINGS", "", sgInstallGui.szProxySettings, sizeof(sgInstallGui.szProxySettings), szFileIniInstall);
05386   GetPrivateProfileString("General", "SERVER", "", sgInstallGui.szServer, sizeof(sgInstallGui.szServer), szFileIniInstall);
05387   GetPrivateProfileString("General", "PORT", "", sgInstallGui.szPort, sizeof(sgInstallGui.szPort), szFileIniInstall);
05388   GetPrivateProfileString("General", "USERID", "", sgInstallGui.szUserId, sizeof(sgInstallGui.szUserId), szFileIniInstall);
05389   GetPrivateProfileString("General", "PASSWORD", "", sgInstallGui.szPassword, sizeof(sgInstallGui.szPassword), szFileIniInstall);
05390   GetPrivateProfileString("General", "SELECTDIRECTORY", "", sgInstallGui.szSelectDirectory, sizeof(sgInstallGui.szSelectDirectory), szFileIniInstall);
05391   GetPrivateProfileString("General", "DIRECTORIES_", "", sgInstallGui.szDirectories_, sizeof(sgInstallGui.szDirectories_), szFileIniInstall);
05392   GetPrivateProfileString("General", "DRIVES_", "", sgInstallGui.szDrives_, sizeof(sgInstallGui.szDrives_), szFileIniInstall);
05393   GetPrivateProfileString("General", "STATUS", "", sgInstallGui.szStatus, sizeof(sgInstallGui.szStatus), szFileIniInstall);
05394   GetPrivateProfileString("General", "FILE", "", sgInstallGui.szFile, sizeof(sgInstallGui.szFile), szFileIniInstall);
05395   GetPrivateProfileString("General", "URL", "", sgInstallGui.szUrl, sizeof(sgInstallGui.szUrl), szFileIniInstall);
05396   GetPrivateProfileString("General", "TO", "", sgInstallGui.szTo, sizeof(sgInstallGui.szTo), szFileIniInstall);
05397   GetPrivateProfileString("General", "ACCEPT_", "", sgInstallGui.szAccept_, sizeof(sgInstallGui.szAccept_), szFileIniInstall);
05398   GetPrivateProfileString("General", "DECLINE_", "", sgInstallGui.szDecline_, sizeof(sgInstallGui.szDecline_), szFileIniInstall);
05399   GetPrivateProfileString("General", "SETUPMESSAGE", "", sgInstallGui.szSetupMessage, sizeof(sgInstallGui.szSetupMessage), szFileIniInstall);
05400   GetPrivateProfileString("General", "YESRESTART", "", sgInstallGui.szYesRestart, sizeof(sgInstallGui.szYesRestart), szFileIniInstall);
05401   GetPrivateProfileString("General", "NORESTART", "", sgInstallGui.szNoRestart, sizeof(sgInstallGui.szNoRestart), szFileIniInstall);
05402   GetPrivateProfileString("General", "ADDITIONALCOMPONENTS_", "", sgInstallGui.szAdditionalComponents_, sizeof(sgInstallGui.szAdditionalComponents_), szFileIniInstall);
05403   GetPrivateProfileString("General", "DESCRIPTION", "", sgInstallGui.szDescription, sizeof(sgInstallGui.szDescription), szFileIniInstall);
05404   GetPrivateProfileString("General", "TOTALDOWNLOADSIZE", "", sgInstallGui.szTotalDownloadSize, sizeof(sgInstallGui.szTotalDownloadSize), szFileIniInstall);
05405   GetPrivateProfileString("General", "SPACEAVAILABLE", "", sgInstallGui.szSpaceAvailable, sizeof(sgInstallGui.szSpaceAvailable), szFileIniInstall);
05406   GetPrivateProfileString("General", "COMPONENTS_", "", sgInstallGui.szComponents_, sizeof(sgInstallGui.szComponents_), szFileIniInstall);
05407   GetPrivateProfileString("General", "DESTINATIONDIRECTORY", "", sgInstallGui.szDestinationDirectory, sizeof(sgInstallGui.szDestinationDirectory), szFileIniInstall);
05408   GetPrivateProfileString("General", "BROWSE_", "", sgInstallGui.szBrowse_, sizeof(sgInstallGui.szBrowse_), szFileIniInstall);
05409   GetPrivateProfileString("General", "CURRENTSETTINGS", "", sgInstallGui.szCurrentSettings, sizeof(sgInstallGui.szCurrentSettings), szFileIniInstall);
05410   GetPrivateProfileString("General", "INSTALL_", "", sgInstallGui.szInstall_, sizeof(sgInstallGui.szInstall_), szFileIniInstall);
05411   GetPrivateProfileString("General", "DELETE_", "", sgInstallGui.szDelete_, sizeof(sgInstallGui.szDelete_), szFileIniInstall);
05412   GetPrivateProfileString("General", "EXTRACTING", "", sgInstallGui.szExtracting, sizeof(sgInstallGui.szExtracting), szFileIniInstall);
05413   GetPrivateProfileString("General", "README", "", sgInstallGui.szReadme_, sizeof(sgInstallGui.szReadme_), szFileIniInstall);
05414   GetPrivateProfileString("General", "PAUSE_", "", sgInstallGui.szPause_, sizeof(sgInstallGui.szPause_), szFileIniInstall);
05415   GetPrivateProfileString("General", "RESUME_", "", sgInstallGui.szResume_, sizeof(sgInstallGui.szResume_), szFileIniInstall);
05416 
05417   return(0);
05418 }
05419 
05420 
05421 BOOL LocatePreviousPath(PSZ szMainSectionName, PSZ szPath, ULONG ulPathSize)
05422 {
05423   ULONG ulIndex;
05424   char  szIndex[MAX_BUF];
05425   char  szSection[MAX_BUF];
05426   char  szValue[MAX_BUF];
05427   BOOL  bFound;
05428 
05429   bFound  = FALSE;
05430   ulIndex = -1;
05431   while(!bFound)
05432   {
05433     ++ulIndex;
05434     _itoa(ulIndex, szIndex, 10);
05435     strcpy(szSection, szMainSectionName);
05436     strcat(szSection, szIndex);
05437 
05438     GetPrivateProfileString(szSection, "App", "", szValue, sizeof(szValue), szFileIniConfig);
05439     if(*szValue != '\0')
05440       bFound = LocatePathOS2INI(szSection, szPath, ulPathSize);
05441     else
05442       break;
05443   }
05444 
05445   return(bFound);
05446 }
05447 
05448 DWORD GetTotalArchivesToDownload()
05449 {
05450   DWORD     dwIndex0;
05451   DWORD     dwTotalArchivesToDownload;
05452   siC       *siCObject = NULL;
05453   char      szIndex0[MAX_BUF];
05454 
05455   dwTotalArchivesToDownload = 0;
05456   dwIndex0                  = 0;
05457   _itoa(dwIndex0,  szIndex0,  10);
05458   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
05459   while(siCObject)
05460   {
05461     if(siCObject->dwAttributes & SIC_SELECTED)
05462     {
05463       if(LocateJar(siCObject, NULL, 0, gbPreviousUnfinishedDownload) == AP_NOT_FOUND)
05464       {
05465         ++dwTotalArchivesToDownload;
05466       }
05467     }
05468 
05469     ++dwIndex0;
05470     _itoa(dwIndex0, szIndex0, 10);
05471     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
05472   }
05473 
05474   return(dwTotalArchivesToDownload);
05475 }
05476 
05477 BOOL LocatePathOS2INI(PSZ szSection, PSZ szPath, ULONG ulPathSize)
05478 {
05479   char  szApp[MAX_BUF];
05480   char  szHRoot[MAX_BUF];
05481   char  szName[MAX_BUF];
05482   char  szVerifyExistence[MAX_BUF];
05483   char  szBuf[MAX_BUF];
05484   char  szIni[MAX_BUF];
05485   BOOL  bDecryptKey;
05486   BOOL  bContainsFilename;
05487   BOOL  bReturn;
05488   HINI  hini = HINI_USERPROFILE;
05489 
05490   bReturn = FALSE;
05491   GetPrivateProfileString(szSection, "App", "", szApp, sizeof(szApp), szFileIniConfig);
05492   if(*szApp != '\0')
05493   {
05494     bReturn = FALSE;
05495     memset(szPath, 0, ulPathSize);
05496 
05497     GetPrivateProfileString(szSection, "Key",         "", szName,  sizeof(szName),  szFileIniConfig);
05498     GetPrivateProfileString(szSection, "Decrypt App", "", szBuf,   sizeof(szBuf),   szFileIniConfig);
05499     if(stricmp(szBuf, "FALSE") == 0)
05500       bDecryptKey = FALSE;
05501     else
05502       bDecryptKey = TRUE;
05503 
05504     /* check for both 'Verify Existance' and 'Verify Existence' */
05505     GetPrivateProfileString(szSection, "Verify Existence", "", szVerifyExistence, sizeof(szVerifyExistence), szFileIniConfig);
05506     if(*szVerifyExistence == '\0')
05507       GetPrivateProfileString(szSection, "Verify Existance", "", szVerifyExistence, sizeof(szVerifyExistence), szFileIniConfig);
05508 
05509     GetPrivateProfileString(szSection, "Contains Filename", "", szBuf, sizeof(szBuf), szFileIniConfig);
05510     if(stricmp(szBuf, "TRUE") == 0)
05511       bContainsFilename = TRUE;
05512     else
05513       bContainsFilename = FALSE;
05514 
05515     if(bDecryptKey == TRUE)
05516     {
05517       DecryptString(szBuf, szApp);
05518       strcpy(szApp, szBuf);
05519     }
05520 
05521     GetPrivateProfileString(szSection, "INI", "", szIni,  sizeof(szIni),  szFileIniConfig);
05522     if (szIni[0]) {
05523       BOOL bDecryptINI;
05524       GetPrivateProfileString(szSection, "Decrypt INI", "", szBuf,   sizeof(szBuf),   szFileIniConfig);
05525       if(stricmp(szBuf, "FALSE")) {
05526         DecryptString(szBuf, szIni);
05527         strcpy(szIni, szBuf);
05528       }
05529       hini = PrfOpenProfile((HAB)0, szIni);
05530     }
05531 
05532     PrfQueryProfileString(hini, szApp, szName, "", szBuf, sizeof(szBuf));
05533     if (szIni[0]) {
05534       PrfCloseProfile(hini);
05535     }
05536     if(*szBuf != '\0')
05537     {
05538       if(stricmp(szVerifyExistence, "FILE") == 0)
05539       {
05540         if(FileExists(szBuf))
05541         {
05542           if(bContainsFilename == TRUE)
05543             ParsePath(szBuf, szPath, ulPathSize, FALSE, PP_PATH_ONLY);
05544           else
05545             strcpy(szPath, szBuf);
05546 
05547           bReturn = TRUE;
05548         }
05549         else
05550           bReturn = FALSE;
05551       }
05552       else if(stricmp(szVerifyExistence, "PATH") == 0)
05553       {
05554         if(bContainsFilename == TRUE)
05555           ParsePath(szBuf, szPath, ulPathSize, FALSE, PP_PATH_ONLY);
05556         else
05557           strcpy(szPath, szBuf);
05558 
05559         if(FileExists(szPath))
05560           bReturn = TRUE;
05561         else
05562           bReturn = FALSE;
05563       }
05564       else
05565       {
05566         if(bContainsFilename == TRUE)
05567           ParsePath(szBuf, szPath, ulPathSize, FALSE, PP_PATH_ONLY);
05568         else
05569           strcpy(szPath, szBuf);
05570 
05571         bReturn = TRUE;
05572       }
05573     }
05574   }
05575 
05576   return(bReturn);
05577 }
05578 
05579 void SetCustomType()
05580 {
05581   if(diSetupType.stSetupType3.bVisible == TRUE)
05582     sgProduct.ulCustomType = ST_RADIO3;
05583   else if(diSetupType.stSetupType2.bVisible == TRUE)
05584     sgProduct.ulCustomType = ST_RADIO2;
05585   else if(diSetupType.stSetupType1.bVisible == TRUE)
05586     sgProduct.ulCustomType = ST_RADIO1;
05587   else if(diSetupType.stSetupType0.bVisible == TRUE)
05588     sgProduct.ulCustomType = ST_RADIO0;
05589 }
05590 
05591 void STSetVisibility(st *stSetupType)
05592 {
05593   if(*(stSetupType->szDescriptionShort) == '\0')
05594     stSetupType->bVisible = FALSE;
05595   else
05596     stSetupType->bVisible = TRUE;
05597 }
05598 
05599 HRESULT DecryptVariable(PSZ szVariable, ULONG ulVariableSize)
05600 {
05601   char szBuf[MAX_BUF];
05602   char szBuf2[MAX_BUF];
05603   char szKey[MAX_BUF];
05604   char szName[MAX_BUF];
05605   char szValue[MAX_BUF];
05606   char szLookupSection[MAX_BUF];
05607   HKEY hkeyRoot;
05608 
05609   /* zero out the memory allocations */
05610   memset(szBuf,           0, sizeof(szBuf));
05611   memset(szKey,           0, sizeof(szKey));
05612   memset(szName,          0, sizeof(szName));
05613   memset(szValue,         0, sizeof(szValue));
05614   memset(szBuf2,          0, sizeof(szBuf2));
05615   memset(szLookupSection, 0, sizeof(szLookupSection));
05616 
05617   if(stricmp(szVariable, "PROGRAMFILESDIR") == 0)
05618   {
05619     /* @MAK Needed for install */
05620   }
05621   else if(stricmp(szVariable, "INSTALLDRIVE") == 0)
05622   {
05623     /* parse for "C:" */
05624     szVariable[0] = sgProduct.szPath[0];
05625     szVariable[1] = sgProduct.szPath[1];
05626     szVariable[2] = '\0';
05627   }
05628   else if(stricmp(szVariable, "STARTUP") == 0)
05629   {
05630     HOBJECT hobj;
05631     hobj = WinQueryObject("<WP_STARTUP>");
05632     WinQueryObjectPath(hobj, szVariable, ulVariableSize);
05633   }
05634   else if(stricmp(szVariable, "DESKTOP") == 0)
05635   {
05636     HOBJECT hobj;
05637     hobj = WinQueryObject("<WP_DESKTOP>");
05638     WinQueryObjectPath(hobj, szVariable, ulVariableSize);
05639   }
05640   else if(stricmp(szVariable, "WARPCENTER") == 0)
05641   {
05642     HOBJECT hobj;
05643     hobj = WinQueryObject("<WP_WARPCENTER????>");
05644     WinQueryObjectPath(hobj, szVariable, ulVariableSize);
05645   }
05646   else if(stricmp(szVariable, "WIZTEMP") == 0)
05647   {
05648     /* parse for the "c:\Temp" path */
05649     strcpy(szVariable, szTempDir);
05650     if(szVariable[strlen(szVariable) - 1] == '\\')
05651       szVariable[strlen(szVariable) - 1] = '\0';
05652   }
05653   else if(stricmp(szVariable, "TEMP") == 0)
05654   {
05655     /* parse for the "c:\Temp" path */
05656     strcpy(szVariable, szOSTempDir);
05657     if(szVariable[strlen(szVariable) - 1] == '\\')
05658       szVariable[strlen(szVariable) - 1] = '\0';
05659   }
05660   else if(stricmp(szVariable, "OS2DISK") == 0)
05661   {
05662     /* Locate the drive that OS/2 is installed on, and only use the drive letter and the ':' character (C:). */
05663     ULONG ulBootDrive = 0;
05664     memset(szVariable, '\0', MAX_BUF);
05665     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
05666                     &ulBootDrive, sizeof(ulBootDrive));
05667     szVariable[0] = 'A' - 1 + ulBootDrive;
05668     szVariable[1] = ':';
05669   }
05670   else if(stricmp(szVariable, "OS2DIR") == 0)
05671   {
05672     /* Locate the "OS2" directory */
05673     ULONG ulBootDrive = 0;
05674     APIRET rc;
05675     char  buffer[] = " :\\OS2";
05676     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
05677                     &ulBootDrive, sizeof(ulBootDrive));
05678     buffer[0] = 'A' - 1 + ulBootDrive;
05679     strcpy(szVariable, buffer);
05680   }
05681   else if(stricmp(szVariable, "OS2SYSDIR") == 0)
05682   {
05683     /* Locate the "OS2\SYSTEM" directory */
05684     ULONG ulBootDrive = 0;
05685     APIRET rc;
05686     char  buffer[] = " :\\OS2\\SYSTEM";
05687     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
05688                     &ulBootDrive, sizeof(ulBootDrive));
05689     buffer[0] = 'A' - 1 + ulBootDrive;
05690     strcpy(szVariable, buffer);
05691   }
05692   else if(  (stricmp(szVariable, "JRE LIB PATH") == 0)
05693          || (stricmp(szVariable, "JRE BIN PATH") == 0) )
05694   {
05695     /* @MAK - we could do this */
05696   }
05697   else if(stricmp(szVariable, "JRE PATH") == 0)
05698   {
05699     /* @MAK - we could do this */
05700   }
05701   else if(stricmp(szVariable, "SETUP PATH") == 0)
05702   {
05703     strcpy(szVariable, sgProduct.szPath);
05704     if(*sgProduct.szSubPath != '\0')
05705     {
05706       AppendBackSlash(szVariable, ulVariableSize);
05707       strcat(szVariable, sgProduct.szSubPath);
05708     }
05709   }
05710   else if(stricmp(szVariable, "Default Path") == 0)
05711   {
05712     strcpy(szVariable, sgProduct.szPath);
05713     if(*sgProduct.szSubPath != '\0')
05714     {
05715       AppendBackSlash(szVariable, ulVariableSize);
05716       strcat(szVariable, sgProduct.szSubPath);
05717     }
05718   }
05719   else if(stricmp(szVariable, "SETUP STARTUP PATH") == 0)
05720   {
05721     strcpy(szVariable, szSetupDir);
05722   }
05723   else if(stricmp(szVariable, "Default Folder") == 0)
05724   {
05725     strcpy(szVariable, sgProduct.szProgramFolderPath);
05726     AppendBackSlash(szVariable, ulVariableSize);
05727     strcat(szVariable, sgProduct.szProgramFolderName);
05728   }
05729   else if(stricmp(szVariable, "Product CurrentVersion") == 0)
05730   {
05731     char szApp[MAX_BUF];
05732 
05733     sprintf(szApp, "%s", sgProduct.szProductNameInternal);
05734 
05735     /* parse for the current Netscape INI entry */
05736     PrfQueryProfileString(HINI_USERPROFILE, szApp, "CurrentVersion", "",
05737                           szBuf, sizeof(szBuf));
05738 
05739     if(*szBuf == '\0')
05740       return(FALSE);
05741 
05742     strcpy(szVariable, szBuf);
05743   }
05744   else if(stricmp(szVariable, "Product PreviousVersion") == 0)
05745   {
05746     char szApp[MAX_BUF];
05747 
05748     sprintf(szApp, "%s", sgProduct.szProductNamePrevious);
05749 
05750     /* parse for the current Netscape INI entry */
05751     PrfQueryProfileString(HINI_USERPROFILE, szApp, "CurrentVersion", "",
05752                           szBuf, sizeof(szBuf));
05753 
05754     if(*szBuf == '\0')
05755       return(FALSE);
05756 
05757     sprintf(szVariable, "%s %s", sgProduct.szProductNamePrevious, szBuf);
05758   }
05759   else
05760     return(FALSE);
05761 
05762   return(TRUE);
05763 }
05764 
05765 HRESULT DecryptString(PSZ szOutputStr, PSZ szInputStr)
05766 {
05767   ULONG ulLenInputStr;
05768   ULONG ulCounter;
05769   ULONG ulVar;
05770   ULONG ulPrepend;
05771   char  szBuf[MAX_BUF];
05772   char  szOutuptStrTemp[MAX_BUF];
05773   char  szVariable[MAX_BUF];
05774   char  szPrepend[MAX_BUF];
05775   char  szAppend[MAX_BUF];
05776   char  szResultStr[MAX_BUF];
05777   BOOL  bFoundVar;
05778   BOOL  bBeginParse;
05779   BOOL  bDecrypted;
05780 
05781   /* zero out the memory addresses */
05782   memset(szBuf,       '\0', MAX_BUF);
05783   memset(szVariable,  '\0', MAX_BUF);
05784   memset(szPrepend,   '\0', MAX_BUF);
05785   memset(szAppend,    '\0', MAX_BUF);
05786   memset(szResultStr, '\0', MAX_BUF);
05787 
05788   strcpy(szPrepend, szInputStr);
05789   ulLenInputStr = strlen(szInputStr);
05790   bBeginParse   = FALSE;
05791   bFoundVar     = FALSE;
05792 
05793   for(ulCounter = 0; ulCounter < ulLenInputStr; ulCounter++)
05794   {
05795     if((szInputStr[ulCounter] == ']') && bBeginParse)
05796       break;
05797 
05798     if(bBeginParse)
05799       szVariable[ulVar++] = szInputStr[ulCounter];
05800 
05801     if((szInputStr[ulCounter] == '[') && !bBeginParse)
05802     {
05803       ulVar        = 0;
05804       ulPrepend    = ulCounter;
05805       bBeginParse  = TRUE;
05806     }
05807   }
05808 
05809   if(ulCounter == ulLenInputStr)
05810     /* did not find anything to expand. */
05811     ulCounter = 0;
05812   else
05813   {
05814     bFoundVar = TRUE;
05815     ++ulCounter;
05816   }
05817 
05818   if(bFoundVar)
05819   {
05820     strcpy(szAppend, &szInputStr[ulCounter]);
05821 
05822     szPrepend[ulPrepend] = '\0';
05823 
05824     /* if Variable is "XPI PATH", do special processing */
05825     if(stricmp(szVariable, "XPI PATH") == 0)
05826     {
05827       strcpy(szBuf, sgProduct.szAlternateArchiveSearchPath);
05828       RemoveBackSlash(szBuf);
05829       strcpy(szOutuptStrTemp, szPrepend);
05830       strcat(szOutuptStrTemp, szBuf);
05831       strcat(szOutuptStrTemp, szAppend);
05832 
05833       if((*sgProduct.szAlternateArchiveSearchPath != '\0') && FileExists(szOutuptStrTemp))
05834       {
05835         strcpy(szVariable, sgProduct.szAlternateArchiveSearchPath);
05836       }
05837       else
05838       {
05839         strcpy(szBuf, szSetupDir);
05840         RemoveBackSlash(szBuf);
05841         strcpy(szOutuptStrTemp, szPrepend);
05842         strcat(szOutuptStrTemp, szBuf);
05843         strcat(szOutuptStrTemp, szAppend);
05844 
05845         if(!FileExists(szOutuptStrTemp))
05846           strcpy(szVariable, szTempDir);
05847         else
05848           strcpy(szVariable, szSetupDir);
05849       }
05850 
05851       RemoveBackSlash(szVariable);
05852       bDecrypted = TRUE;
05853     }
05854     else
05855     {
05856       bDecrypted = DecryptVariable(szVariable, sizeof(szVariable));
05857     }
05858 
05859     if(!bDecrypted)
05860     {
05861       /* Variable was not able to be dcripted. */
05862       /* Leave the variable as it was read in by adding the '[' and ']' */
05863       /* characters back to the variable. */
05864       strcpy(szBuf, "[");
05865       strcat(szBuf, szVariable);
05866       strcat(szBuf, "]");
05867       strcpy(szVariable, szBuf);
05868     }
05869 
05870     strcpy(szOutputStr, szPrepend);
05871     strcat(szOutputStr, szVariable);
05872     strcat(szOutputStr, szAppend);
05873 
05874     if(bDecrypted)
05875     {
05876       DecryptString(szResultStr, szOutputStr);
05877       strcpy(szOutputStr, szResultStr);
05878     }
05879   }
05880   else
05881     strcpy(szOutputStr, szInputStr);
05882 
05883   return(TRUE);
05884 }
05885 
05886 int ExtractDirEntries(char* directory, void* vZip)
05887 {
05888   int   err;
05889   int   result;
05890   char  buf[512];  // XXX: need an XP "max path"
05891 
05892   int paths = 1;
05893   if(paths)
05894   {
05895     void* find = ZIP_FindInit(vZip, directory);
05896 
05897     if(find)
05898     {
05899       int prefix_length = 0;
05900       
05901       if(directory)
05902         prefix_length = strlen(directory) - 1;
05903 
05904       if(prefix_length >= sizeof(buf)-1)
05905         return ZIP_ERR_GENERAL;
05906 
05907       err = ZIP_FindNext( find, buf, sizeof(buf) );
05908       while ( err == ZIP_OK ) 
05909       {
05910         CreateDirectoriesAll(buf, FALSE);
05911         if(buf[strlen(buf) - 1] != '/')
05912           // only extract if it's a file
05913           result = ZIP_ExtractFile(vZip, buf, buf);
05914         err = ZIP_FindNext( find, buf, sizeof(buf) );
05915       }
05916       ZIP_FindFree( find );
05917     }
05918     else
05919       err = ZIP_ERR_GENERAL;
05920 
05921     if ( err == ZIP_ERR_FNF )
05922       return ZIP_OK;   // found them all
05923   }
05924 
05925   return ZIP_ERR_GENERAL;
05926 }
05927 
05928 #define S_IFMT (S_IFDIR | S_IFREG)
05929 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
05930 
05931 HRESULT FileExists(PSZ szFile)
05932 {
05933   struct stat st;
05934   int statrv;
05935 
05936   statrv = stat(szFile, &st);
05937   if (statrv == 0)
05938      if (S_ISDIR(st.st_mode))
05939         return FILE_DIRECTORY;
05940      else
05941         return(TRUE);
05942   else if ((strlen(szFile) == 2) && (szFile[1] == ':'))
05943   {
05944      char temp[4] = {0};
05945      strcpy(temp, szFile);
05946      strcat(temp, "\\");
05947      statrv = stat(temp, &st);
05948      if (statrv == 0)
05949         return FILE_DIRECTORY;
05950   }
05951   return (FALSE);
05952 }
05953 
05954 BOOL isFAT(char* szPath)
05955 {
05956   APIRET rc;
05957   ULONG ulSize;
05958   PFSQBUFFER2 pfsqbuf2;
05959   CHAR szDrive[3];
05960 
05961   ulSize = sizeof(FSQBUFFER2) + 3 * CCHMAXPATH;
05962   pfsqbuf2 = (PFSQBUFFER2)malloc(ulSize);
05963   strncpy(szDrive, szPath, 2);
05964   szDrive[2] = '\0';
05965 
05966   DosError(FERR_DISABLEHARDERR);
05967   rc = DosQueryFSAttach(szDrive, 0, FSAIL_QUERYNAME,
05968                         pfsqbuf2, &ulSize);
05969   DosError(FERR_ENABLEHARDERR);
05970 
05971   if (rc == NO_ERROR) {
05972     if (strcmp(pfsqbuf2->szFSDName + pfsqbuf2->cbName, "FAT") != 0)
05973       return FALSE;
05974   }
05975 
05976   return TRUE;
05977 }
05978 
05979 BOOL NeedReboot()
05980 {
05981    if(diReboot.dwShowDialog == AUTO)
05982      return(bReboot);
05983    else
05984      return(diReboot.dwShowDialog);
05985 }
05986 
05987 BOOL DeleteWGetLog(void)
05988 {
05989   char  szFile[MAX_BUF];
05990   BOOL  bFileExists = FALSE;
05991 
05992   memset(szFile, 0, sizeof(szFile));
05993 
05994   strcpy(szFile, szTempDir);
05995   AppendBackSlash(szFile, sizeof(szFile));
05996   strcat(szFile, FILE_WGET_LOG);
05997 
05998   if(FileExists(szFile))
05999     bFileExists = TRUE;
06000 
06001   DosDelete(szFile);
06002   return(bFileExists);
06003 }
06004 
06005 BOOL DeleteIdiGetConfigIni()
06006 {
06007   char  szFileIdiGetConfigIni[MAX_BUF];
06008   BOOL  bFileExists = FALSE;
06009 
06010   memset(szFileIdiGetConfigIni, 0, sizeof(szFileIdiGetConfigIni));
06011 
06012   strcpy(szFileIdiGetConfigIni, szTempDir);
06013   AppendBackSlash(szFileIdiGetConfigIni, sizeof(szFileIdiGetConfigIni));
06014   strcat(szFileIdiGetConfigIni, FILE_IDI_GETCONFIGINI);
06015   if(FileExists(szFileIdiGetConfigIni))
06016   {
06017     bFileExists = TRUE;
06018   }
06019   DosDelete(szFileIdiGetConfigIni);
06020   return(bFileExists);
06021 }
06022 
06023 BOOL DeleteInstallLogFile(char *szFile)
06024 {
06025   char  szInstallLogFile[MAX_BUF];
06026   BOOL  bFileExists = FALSE;
06027 
06028   strcpy(szInstallLogFile, szTempDir);
06029   AppendBackSlash(szInstallLogFile, sizeof(szInstallLogFile));
06030   strcat(szInstallLogFile, szFile);
06031 
06032   if(FileExists(szInstallLogFile))
06033   {
06034     bFileExists = TRUE;
06035     DosDelete(szInstallLogFile);
06036   }
06037 
06038   return(bFileExists);
06039 }
06040 
06041 BOOL DeleteIniRedirect()
06042 {
06043   char  szFileIniRedirect[MAX_BUF];
06044   BOOL  bFileExists = FALSE;
06045 
06046   memset(szFileIniRedirect, 0, sizeof(szFileIniRedirect));
06047 
06048   strcpy(szFileIniRedirect, szTempDir);
06049   AppendBackSlash(szFileIniRedirect, sizeof(szFileIniRedirect));
06050   strcat(szFileIniRedirect, FILE_INI_REDIRECT);
06051   if(FileExists(szFileIniRedirect))
06052   {
06053     bFileExists = TRUE;
06054   }
06055   DosDelete(szFileIniRedirect);
06056   return(bFileExists);
06057 }
06058 
06059 BOOL DeleteIdiGetRedirect()
06060 {
06061   char  szFileIdiGetRedirect[MAX_BUF];
06062   BOOL  bFileExists = FALSE;
06063 
06064   memset(szFileIdiGetRedirect, 0, sizeof(szFileIdiGetRedirect));
06065 
06066   strcpy(szFileIdiGetRedirect, szTempDir);
06067   AppendBackSlash(szFileIdiGetRedirect, sizeof(szFileIdiGetRedirect));
06068   strcat(szFileIdiGetRedirect, FILE_IDI_GETREDIRECT);
06069   if(FileExists(szFileIdiGetRedirect))
06070   {
06071     bFileExists = TRUE;
06072   }
06073   DosDelete(szFileIdiGetRedirect);
06074   return(bFileExists);
06075 }
06076 
06077 BOOL DeleteIdiGetArchives()
06078 {
06079   char  szFileIdiGetArchives[MAX_BUF];
06080   BOOL  bFileExists = FALSE;
06081 
06082   memset(szFileIdiGetArchives, 0, sizeof(szFileIdiGetArchives));
06083 
06084   strcpy(szFileIdiGetArchives, szTempDir);
06085   AppendBackSlash(szFileIdiGetArchives, sizeof(szFileIdiGetArchives));
06086   strcat(szFileIdiGetArchives, FILE_IDI_GETARCHIVES);
06087   if(FileExists(szFileIdiGetArchives))
06088   {
06089     bFileExists = TRUE;
06090   }
06091   DosDelete(szFileIdiGetArchives);
06092   return(bFileExists);
06093 }
06094 
06095 BOOL DeleteIdiFileIniConfig()
06096 {
06097   char  szFileIniConfig[MAX_BUF];
06098   BOOL  bFileExists = FALSE;
06099 
06100   memset(szFileIniConfig, 0,sizeof(szFileIniConfig));
06101 
06102   strcpy(szFileIniConfig, szTempDir);
06103   AppendBackSlash(szFileIniConfig, sizeof(szFileIniConfig));
06104   strcat(szFileIniConfig, FILE_INI_CONFIG);
06105   if(FileExists(szFileIniConfig))
06106   {
06107     bFileExists = TRUE;
06108   }
06109   DosDelete(szFileIniConfig);
06110   return(bFileExists);
06111 }
06112 
06113 BOOL DeleteIdiFileIniInstall()
06114 {
06115   char  szFileIniInstall[MAX_BUF];
06116   BOOL  bFileExists = FALSE;
06117 
06118   memset(szFileIniInstall, 0, sizeof(szFileIniInstall));
06119 
06120   strcpy(szFileIniInstall, szTempDir);
06121   AppendBackSlash(szFileIniInstall, sizeof(szFileIniInstall));
06122   strcat(szFileIniInstall, FILE_INI_INSTALL);
06123   if(FileExists(szFileIniInstall))
06124   {
06125     bFileExists = TRUE;
06126   }
06127   DosDelete(szFileIniInstall);
06128   return(bFileExists);
06129 }
06130 
06131 void DeleteArchives(DWORD dwDeleteCheck)
06132 {
06133   DWORD dwIndex0;
06134   char  szArchiveName[MAX_BUF];
06135   siC   *siCObject = NULL;
06136 
06137   memset(szArchiveName, 0, sizeof(szArchiveName));
06138 
06139   if((!bSDUserCanceled) && (GetPreviousUnfinishedState() == PUS_NONE))
06140   {
06141     dwIndex0 = 0;
06142     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
06143     while(siCObject)
06144     {
06145       strcpy(szArchiveName, szTempDir);
06146       AppendBackSlash(szArchiveName, sizeof(szArchiveName));
06147       strcat(szArchiveName, siCObject->szArchiveName);
06148 
06149       switch(dwDeleteCheck)
06150       {
06151         case DA_ONLY_IF_IN_ARCHIVES_LST:
06152           if(IsInArchivesLst(siCObject, FALSE))
06153             DosDelete(szArchiveName);
06154           break;
06155 
06156         case DA_ONLY_IF_NOT_IN_ARCHIVES_LST:
06157           if(!IsInArchivesLst(siCObject, FALSE))
06158             DosDelete(szArchiveName);
06159           break;
06160 
06161         case DA_IGNORE_ARCHIVES_LST:
06162         default:
06163           DosDelete(szArchiveName);
06164           break;
06165       }
06166 
06167       ++dwIndex0;
06168       siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
06169     }
06170 
06171     DeleteIniRedirect();
06172   }
06173 }
06174 
06175 void CleanTempFiles()
06176 {
06177   DeleteIdiGetConfigIni();
06178   DeleteIdiGetArchives();
06179   DeleteIdiGetRedirect();
06180 
06181   /* do not delete config.ini file.
06182      if it was uncompressed from the self-extracting .exe file,
06183      then it will be deleted automatically.
06184      Right now the config.ini does not get downloaded, so we
06185      don't have to worry about that case
06186   */
06187   DeleteIdiFileIniConfig();
06188   DeleteIdiFileIniInstall();
06189   DeleteArchives(DA_IGNORE_ARCHIVES_LST);
06190   DeleteInstallLogFile(FILE_INSTALL_LOG);
06191   DeleteInstallLogFile(FILE_INSTALL_STATUS_LOG);
06192 }
06193 
06194 void SendErrorMessage(void)
06195 {
06196   char szBuf[MAX_BUF];
06197   char *szPartialEscapedURL = NULL;
06198 
06199   /* append to the message stream the list of components that either had
06200    * network retries or crc retries */
06201   LogMSDownloadFileStatus();
06202 
06203   /* replace this function call with a call to xpnet */
06204   if((szPartialEscapedURL = nsEscape(gErrorMessageStream.szMessage,
06205                                      url_Path)) != NULL)
06206   {
06207     char  szWGetLog[MAX_BUF];
06208     char  szMsg[MAX_BUF];
06209     char  *szFullURL = NULL;
06210     DWORD dwSize;
06211 
06212     strcpy(szWGetLog, szTempDir);
06213     AppendBackSlash(szWGetLog, sizeof(szWGetLog));
06214     strcat(szWGetLog, FILE_WGET_LOG);
06215 
06216     /* take into account '?' and '\0' chars */
06217     dwSize = strlen(gErrorMessageStream.szURL) +
06218              strlen(szPartialEscapedURL) + 2;
06219     if((szFullURL = NS_GlobalAlloc(dwSize)) != NULL)
06220     {
06221       sprintf(szFullURL,
06222                "%s?%s",
06223                gErrorMessageStream.szURL,
06224                szPartialEscapedURL);
06225 
06226       sprintf(szMsg,
06227                "UnEscapedURL: %s?%s\nEscapedURL: %s",
06228                gErrorMessageStream.szURL,
06229                gErrorMessageStream.szMessage,
06230                szFullURL);
06231 
06232       if(gErrorMessageStream.bShowConfirmation &&
06233         (*gErrorMessageStream.szConfirmationMessage != '\0'))
06234       {
06235         char szConfirmationMessage[MAX_BUF];
06236 
06237         sprintf(szBuf,
06238                  "\n\n  %s",
06239                  gErrorMessageStream.szMessage);
06240         sprintf(szConfirmationMessage,
06241                  gErrorMessageStream.szConfirmationMessage,
06242                  szBuf);
06243         if(WinMessageBox(HWND_DESKTOP, hWndMain,
06244                          szConfirmationMessage,
06245                          sgProduct.szProductName, 0,
06246                          MB_OKCANCEL | MB_ICONQUESTION) == MBID_OK)
06247         {
06248           //PrintError(szMsg, ERROR_CODE_HIDE);
06249           WGet(szFullURL,
06250                szWGetLog,
06251                diAdvancedSettings.szProxyServer,
06252                diAdvancedSettings.szProxyPort,
06253                diAdvancedSettings.szProxyUser,
06254                diAdvancedSettings.szProxyPasswd);
06255         }
06256       }
06257       else if(!gErrorMessageStream.bShowConfirmation)
06258       {
06259         //PrintError(szMsg, ERROR_CODE_HIDE);
06260         WGet(szFullURL,
06261              szWGetLog,
06262              diAdvancedSettings.szProxyServer,
06263              diAdvancedSettings.szProxyPort,
06264              diAdvancedSettings.szProxyUser,
06265              diAdvancedSettings.szProxyPasswd);
06266       }
06267 
06268       FreeMemory(&szFullURL);
06269     }
06270 
06271     FreeMemory(&szPartialEscapedURL);
06272   }
06273 }
06274 
06275 void DeInitialize()
06276 {
06277   char szBuf[MAX_BUF];
06278 
06279   LogISTime(W_END);
06280   if(bCreateDestinationDir)
06281   {
06282     strcpy(szBuf, sgProduct.szPath);
06283     AppendBackSlash(szBuf, sizeof(szBuf));
06284     DirectoryRemove(szBuf, FALSE);
06285   }
06286 
06287   DeleteWGetLog();
06288   CleanTempFiles();
06289   DirectoryRemove(szTempDir, FALSE);
06290 
06291   if(gErrorMessageStream.bEnabled && gErrorMessageStream.bSendMessage)
06292     SendErrorMessage();
06293 
06294   DeInitSiComponents(&siComponents);
06295   DeInitSXpcomFile();
06296   DeInitDlgReboot(&diReboot);
06297   DeInitDlgDownload(&diDownload);
06298   DeInitDlgStartInstall(&diStartInstall);
06299   DeInitDlgAdditionalOptions(&diAdditionalOptions);
06300   DeInitDlgAdvancedSettings(&diAdvancedSettings);
06301   DeInitDlgProgramFolder(&diProgramFolder);
06302   DeInitDlgOS2Integration(&diOS2Integration);
06303   DeInitDlgSelectComponents(&diSelectAdditionalComponents);
06304   DeInitDlgSelectComponents(&diSelectComponents);
06305   DeInitDlgSetupType(&diSetupType);
06306   DeInitDlgWelcome(&diWelcome);
06307   DeInitDlgLicense(&diLicense);
06308   DeInitDlgQuickLaunch(&diQuickLaunch);
06309   DeInitSetupGeneral();
06310   DeInitDSNode(&gdsnComponentDSRequirement);
06311   DeInitErrorMessageStream();
06312 
06313   FreeMemory(&szTempDir);
06314   FreeMemory(&szOSTempDir);
06315   FreeMemory(&szSetupDir);
06316   FreeMemory(&szFileIniConfig);
06317   FreeMemory(&szFileIniInstall);
06318   FreeMemory(&szEGlobalAlloc);
06319   FreeMemory(&szEDllLoad);
06320   FreeMemory(&szEStringLoad);
06321   FreeMemory(&szEStringNull);
06322 
06323   DosFreeModule(hSetupRscInst);
06324 }
06325 
06326 char *GetSaveInstallerPath(char *szBuf, DWORD dwBufSize)
06327 {
06328 #ifdef XXX_INTL_HACK_WORKAROUND_FOR_NOW
06329   char szBuf2[MAX_BUF];
06330 #endif
06331 
06332   /* determine the path to where the setup and downloaded files will be saved to */
06333   strcpy(szBuf, sgProduct.szPath);
06334   AppendBackSlash(szBuf, dwBufSize);
06335   if(*sgProduct.szSubPath != '\0')
06336   {
06337     strcat(szBuf, sgProduct.szSubPath);
06338     strcat(szBuf, " ");
06339   }
06340 
06341 #ifdef XXX_INTL_HACK_WORKAROUND_FOR_NOW
06342 /* Installer can't create the Save Installer Path if the word "Setup" is localized. */
06343   if(GetPrivateProfileString("Messages", "STR_SETUP", "", szBuf2, sizeof(szBuf2), szFileIniInstall))
06344     strcat(szBuf, szBuf2);
06345   else
06346 #endif
06347     strcat(szBuf, "Setup");
06348 
06349   return(szBuf);
06350 }
06351 
06352 void SaveInstallerFiles()
06353 {
06354   int       i;
06355   char      szBuf[MAX_BUF];
06356   char      szSource[MAX_BUF];
06357   char      szDestination[MAX_BUF];
06358   char      szMFN[MAX_BUF];
06359   char      szArchivePath[MAX_BUF];
06360   DWORD     dwIndex0;
06361   siC       *siCObject = NULL;
06362   PPIB      ppib;
06363   PTIB      ptib;
06364 
06365   GetSaveInstallerPath(szDestination, sizeof(szDestination));
06366   AppendBackSlash(szDestination, sizeof(szDestination));
06367 
06368   /* copy all files from the ns_temp dir to the install dir */
06369   CreateDirectoriesAll(szDestination, TRUE);
06370 
06371   /* copy the self extracting file that spawned setup.exe, if one exists */
06372   if((*sgProduct.szAlternateArchiveSearchPath != '\0') && (*sgProduct.szParentProcessFilename != '\0'))
06373   {
06374     strcpy(szSource, szSetupDir);
06375     AppendBackSlash(szSource, sizeof(szSource));
06376     strcat(szSource, "*.*");
06377 
06378     strcpy(szSource, sgProduct.szAlternateArchiveSearchPath);
06379     AppendBackSlash(szSource, sizeof(szSource));
06380     strcat(szSource, sgProduct.szParentProcessFilename);
06381     FileCopy(szSource, szDestination, FALSE, FALSE);
06382   }
06383   else
06384   {
06385     /* Else if self extracting file does not exist, copy the setup files */
06386     /* First get the current process' filename (in case it's not really named setup.exe */
06387     /* Then copy it to the install folder */
06388     char buffer[CCHMAXPATH];
06389     DosGetInfoBlocks( &ptib, &ppib);
06390     DosQueryModuleName( ppib->pib_hmte, sizeof(szBuf), szBuf);
06391     ParsePath(szBuf, szMFN, sizeof(szMFN), FALSE, PP_FILENAME_ONLY);
06392 
06393     strcpy(szBuf, szSetupDir);
06394     AppendBackSlash(szBuf, sizeof(szBuf));
06395     strcat(szBuf, szMFN);
06396     FileCopy(szBuf, szDestination, FALSE, FALSE);
06397 
06398     /* now copy the rest of the setup files */
06399     i = 0;
06400     while(TRUE)
06401     {
06402       if(*SetupFileList[i] == '\0')
06403         break;
06404 
06405       strcpy(szBuf, szSetupDir);
06406       AppendBackSlash(szBuf, sizeof(szBuf));
06407       strcat(szBuf, SetupFileList[i]);
06408       FileCopy(szBuf, szDestination, FALSE, FALSE);
06409 
06410       ++i;
06411     }
06412   }
06413 
06414   dwIndex0 = 0;
06415   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
06416   while(siCObject)
06417   {
06418     LocateJar(siCObject, szArchivePath, sizeof(szArchivePath), TRUE);
06419     if(*szArchivePath != '\0')
06420     {
06421       strcpy(szBuf, szArchivePath);
06422       AppendBackSlash(szBuf, sizeof(szBuf));
06423       strcat(szBuf, siCObject->szArchiveName);
06424       FileCopy(szBuf, szDestination, FALSE, FALSE);
06425     }
06426 
06427     ++dwIndex0;
06428     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
06429   }
06430 }
06431 
06432 BOOL ShowAdditionalOptionsDialog(void)
06433 {
06434   if(diAdditionalOptions.bShowDialog == FALSE)
06435     return(FALSE);
06436 
06437   if( (diAdditionalOptions.bShowHomepageOption == FALSE) && (GetTotalArchivesToDownload() < 1) )
06438     return(FALSE);
06439 
06440   return(TRUE);
06441 }
06442 
06443 HWND FindWindow(PCSZ pszAtomString)
06444 {
06445   ATOM atom;
06446   HENUM henum;
06447   HWND hwndClient, hwnd = NULLHANDLE;
06448 
06449 
06450   atom = WinFindAtom(WinQuerySystemAtomTable(), pszAtomString);
06451   if (atom) {
06452     henum = WinBeginEnumWindows(HWND_DESKTOP);
06453     while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
06454     {
06455       ULONG ulWindowWord;
06456       ulWindowWord = WinQueryWindowULong(hwnd, QWL_USER);
06457       if (ulWindowWord == atom) {
06458         break;
06459       } else {
06460         /* Try the class name method to support older browsers */
06461         HWND hwndClient;
06462         CHAR szClassName[MAX_BUF];
06463         hwndClient = WinWindowFromID(hwnd, FID_CLIENT);
06464         WinQueryClassName(hwndClient ? hwndClient : hwnd, MAX_BUF, szClassName);
06465         if (strcmp(szClassName, pszAtomString) == 0) {
06466            break;
06467         }
06468       }
06469     }
06470     WinEndEnumWindows(henum);
06471   }
06472   if (!hwnd) {
06473      /* Try the object windows just in case, but only for the classname */
06474     henum = WinBeginEnumWindows(HWND_OBJECT);
06475     while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
06476     {
06477       /* Try the class name method to support older browsers */
06478       HWND hwndClient;
06479       CHAR szClassName[MAX_BUF];
06480       hwndClient = WinWindowFromID(hwnd, FID_CLIENT);
06481       WinQueryClassName(hwndClient ? hwndClient : hwnd, MAX_BUF, szClassName);
06482       if (strcmp(szClassName, pszAtomString) == 0) {
06483          break;
06484       }
06485     }
06486   }
06487   return  hwnd;
06488 }
06489