Back to index

lightning-sunbird  0.9+nobinonly
ifuncns.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 "shortcut.h"
00045 #include "ifuncns.h"
00046 #include "wizverreg.h"
00047 #include "logging.h"
00048 #include <logkeys.h>
00049 
00050 #define  SIZEOFNOTSTRING 4
00051 
00052 HRESULT TimingCheck(DWORD dwTiming, LPSTR szSection, LPSTR szFile)
00053 {
00054   char szBuf[MAX_BUF_TINY];
00055 
00056   GetPrivateProfileString(szSection, "Timing", "", szBuf, sizeof(szBuf), szFile);
00057   if(*szBuf != '\0')
00058   {
00059     switch(dwTiming)
00060     {
00061       case T_PRE_DOWNLOAD:
00062         if(lstrcmpi(szBuf, "pre download") == 0)
00063           return(TRUE);
00064         break;
00065 
00066       case T_POST_DOWNLOAD:
00067         if(lstrcmpi(szBuf, "post download") == 0)
00068           return(TRUE);
00069         break;
00070 
00071       case T_PRE_XPCOM:
00072         if(lstrcmpi(szBuf, "pre xpcom") == 0)
00073           return(TRUE);
00074         break;
00075 
00076       case T_POST_XPCOM:
00077         if(lstrcmpi(szBuf, "post xpcom") == 0)
00078           return(TRUE);
00079         break;
00080 
00081       case T_PRE_SMARTUPDATE:
00082         if(lstrcmpi(szBuf, "pre smartupdate") == 0)
00083           return(TRUE);
00084         break;
00085 
00086       case T_POST_SMARTUPDATE:
00087         if(lstrcmpi(szBuf, "post smartupdate") == 0)
00088           return(TRUE);
00089         break;
00090 
00091       case T_PRE_LAUNCHAPP:
00092         if(lstrcmpi(szBuf, "pre launchapp") == 0)
00093           return(TRUE);
00094         break;
00095 
00096       case T_POST_LAUNCHAPP:
00097         if(lstrcmpi(szBuf, "post launchapp") == 0)
00098           return(TRUE);
00099         break;
00100 
00101       case T_PRE_ARCHIVE:
00102         if(lstrcmpi(szBuf, "pre archive") == 0)
00103           return(TRUE);
00104         break;
00105 
00106       case T_POST_ARCHIVE:
00107         if(lstrcmpi(szBuf, "post archive") == 0)
00108           return(TRUE);
00109         break;
00110 
00111       case T_DEPEND_REBOOT:
00112         if(lstrcmpi(szBuf, "depend reboot") == 0)
00113           return(TRUE);
00114         break;
00115     }
00116   }
00117   return(FALSE);
00118 }
00119 
00120 HRESULT MeetCondition(LPSTR szSection)
00121 {
00122   char szBuf[MAX_BUF_TINY];
00123   BOOL bResult = FALSE; // An undefined result is never met
00124   BOOL bNegateTheResult = FALSE;
00125 
00126   char *pszCondition = szBuf;
00127 
00128   GetPrivateProfileString(szSection, "Condition", "", szBuf, sizeof(szBuf), szFileIniConfig);
00129 
00130   // If there is no condition then the "condition" is met, so we return TRUE.
00131   if(pszCondition[0] == '\0')
00132     return TRUE;
00133 
00134   // See if "not " is prepended to the condition.
00135   if(strncmp(pszCondition, "not ", SIZEOFNOTSTRING) == 0)
00136   {
00137     bNegateTheResult = TRUE;
00138     pszCondition = pszCondition + SIZEOFNOTSTRING;
00139   }
00140 
00141   // The condition "DefaultApp" is met if the app which is running the install is the same as the
00142   //   the app identified by the Default AppID key in config.ini.
00143   if(strcmp(pszCondition, "DefaultApp") == 0)
00144   {
00145     GetPrivateProfileString("General", "Default AppID", "", szBuf, sizeof(szBuf), szFileIniConfig);
00146     if(strcmp(szBuf, sgProduct.szAppID) == 0)
00147       bResult = TRUE;
00148   }
00149   // The condition "RecaptureHPChecked" is met if the RecaptureHome checkbox in "Additional Options" dialog.
00150   //   has been checked by the user.
00151   else if(strcmp(pszCondition, "RecaptureHPChecked") == 0)
00152   {
00153     bResult = diAdditionalOptions.bRecaptureHomepage;
00154   }
00155 
00156   if(bNegateTheResult)
00157     return !bResult;
00158 
00159   return bResult;
00160 }
00161 
00162 char *BuildNumberedString(DWORD dwIndex, char *szInputStringPrefix, char *szInputString, char *szOutBuf, DWORD dwOutBufSize)
00163 {
00164   if((szInputStringPrefix) && (*szInputStringPrefix != '\0'))
00165     wsprintf(szOutBuf, "%s-%s%d", szInputStringPrefix, szInputString, dwIndex);
00166   else
00167     wsprintf(szOutBuf, "%s%d", szInputString, dwIndex);
00168 
00169   return(szOutBuf);
00170 }
00171 
00172 void GetUserAgentShort(char *szUserAgent, char *szOutUAShort, DWORD dwOutUAShortSize)
00173 {
00174   char *ptrFirstSpace = NULL;
00175 
00176   ZeroMemory(szOutUAShort, dwOutUAShortSize);
00177   if((szUserAgent == NULL) || (*szUserAgent == '\0'))
00178     return;
00179 
00180   ptrFirstSpace = strstr(szUserAgent, " ");
00181   if(ptrFirstSpace != NULL)
00182   {
00183     *ptrFirstSpace = '\0';
00184     lstrcpy(szOutUAShort, szUserAgent);
00185     *ptrFirstSpace = ' ';
00186   }
00187 }
00188 
00189 DWORD GetWinRegSubKeyProductPath(HKEY hkRootKey, char *szInKey, char *szReturnSubKey, DWORD dwReturnSubKeySize, char *szInSubSubKey, char *szInName, char *szCompare, char *szInCurrentVersion)
00190 {
00191   char      *szRv = NULL;
00192   char      szKey[MAX_BUF];
00193   char      szBuf[MAX_BUF];
00194   HKEY      hkHandle;
00195   DWORD     dwIndex;
00196   DWORD     dwBufSize;
00197   DWORD     dwTotalSubKeys;
00198   DWORD     dwTotalValues;
00199   FILETIME  ftLastWriteFileTime;
00200   BOOL      bFoundSubKey;
00201 
00202   bFoundSubKey = FALSE;
00203 
00204   if(RegOpenKeyEx(hkRootKey, szInKey, 0, KEY_READ, &hkHandle) != ERROR_SUCCESS)
00205   {
00206     *szReturnSubKey = '\0';
00207     return(0);
00208   }
00209 
00210   dwTotalSubKeys = 0;
00211   dwTotalValues  = 0;
00212   RegQueryInfoKey(hkHandle, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL);
00213   for(dwIndex = 0; dwIndex < dwTotalSubKeys; dwIndex++)
00214   {
00215     dwBufSize = dwReturnSubKeySize;
00216     if(RegEnumKeyEx(hkHandle, dwIndex, szReturnSubKey, &dwBufSize, NULL, NULL, NULL, &ftLastWriteFileTime) == ERROR_SUCCESS)
00217     {
00218       if(  (*szInCurrentVersion != '\0') && (lstrcmpi(szInCurrentVersion, szReturnSubKey) != 0)  )
00219       {
00220         /* The key found is not the CurrentVersion (current UserAgent), so we can return it to be deleted.
00221          * We don't want to return the SubKey that is the same as the CurrentVersion because it might
00222          * have just been created by the current installation process.  So deleting it would be a
00223          * "Bad Thing" (TM).
00224          *
00225          * If it was not created by the current installation process, then it'll be left
00226          * around which is better than deleting something we will need later. To make sure this case is
00227          * not encountered, CleanupPreviousVersionRegKeys() should be called at the *end* of the
00228          * installation process (at least after all the .xpi files have been processed). */
00229         if(szInSubSubKey && (*szInSubSubKey != '\0'))
00230           wsprintf(szKey, "%s\\%s\\%s", szInKey, szReturnSubKey, szInSubSubKey);
00231         else
00232           wsprintf(szKey, "%s\\%s", szInKey, szReturnSubKey);
00233 
00234         GetWinReg(hkRootKey, szKey, szInName, szBuf, sizeof(szBuf));
00235         AppendBackSlash(szBuf, sizeof(szBuf));
00236         if(lstrcmpi(szBuf, szCompare) == 0)
00237         {
00238           bFoundSubKey = TRUE;
00239           /* found one subkey. break out of the for() loop */
00240           break;
00241         }
00242       }
00243     }
00244   }
00245 
00246   RegCloseKey(hkHandle);
00247   if(!bFoundSubKey)
00248     *szReturnSubKey = '\0';
00249   return(dwTotalSubKeys);
00250 }
00251 
00252 void CleanupPreviousVersionRegKeys(void)
00253 {
00254   DWORD dwIndex = 0;
00255   DWORD dwSubKeyCount;
00256   char  szBufTiny[MAX_BUF_TINY];
00257   char  szKeyRoot[MAX_BUF_TINY];
00258   char  szCurrentVersion[MAX_BUF_TINY];
00259   char  szUAShort[MAX_BUF_TINY];
00260   char  szRvSubKey[MAX_PATH + 1];
00261   char  szPath[MAX_BUF];
00262   char  szKey[MAX_BUF];
00263   char  szCleanupProduct[MAX_BUF];
00264   HKEY  hkeyRoot;
00265   char  szSubSubKey[] = "Main";
00266   char  szName[] = "Install Directory";
00267   char  szWRMSUninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
00268   char  szSection[] = "Cleanup Previous Product RegKeys";
00269 
00270   lstrcpy(szPath, sgProduct.szPath);
00271   if(*sgProduct.szSubPath != '\0')
00272   {
00273     AppendBackSlash(szPath, sizeof(szPath));
00274     lstrcat(szPath, sgProduct.szSubPath);
00275   }
00276   AppendBackSlash(szPath, sizeof(szPath));
00277 
00278   wsprintf(szBufTiny, "Product Reg Key%d", dwIndex);        
00279   GetPrivateProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey), szFileIniConfig);
00280 
00281   while(*szKey != '\0')
00282   {
00283     wsprintf(szBufTiny, "Reg Key Root%d",dwIndex);
00284     GetPrivateProfileString(szSection, szBufTiny, "", szKeyRoot, sizeof(szKeyRoot), szFileIniConfig);
00285     hkeyRoot = ParseRootKey(szKeyRoot);
00286 
00287     wsprintf(szBufTiny, "Product Name%d", dwIndex);        
00288     GetPrivateProfileString(szSection, szBufTiny, "", szCleanupProduct, sizeof(szCleanupProduct), szFileIniConfig);
00289     // something is wrong, they didn't give a product name.
00290     if(*szCleanupProduct == '\0')
00291       return;
00292 
00293     wsprintf(szBufTiny, "Current Version%d", dwIndex);        
00294     GetPrivateProfileString(szSection, szBufTiny, "", szCurrentVersion, sizeof(szCurrentVersion), szFileIniConfig);
00295 
00296     do
00297     {
00298       // if the current version is not found, we'll get null in szCurrentVersion and GetWinRegSubKeyProductPath() will do the right thing
00299       dwSubKeyCount = GetWinRegSubKeyProductPath(hkeyRoot, szKey, szRvSubKey, sizeof(szRvSubKey), szSubSubKey, szName, szPath, szCurrentVersion);
00300          
00301       if(*szRvSubKey != '\0')
00302       {
00303         if(dwSubKeyCount > 1)
00304         {
00305           AppendBackSlash(szKey, sizeof(szKey));
00306           lstrcat(szKey, szRvSubKey);
00307         }
00308         DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00309 
00310         GetUserAgentShort(szRvSubKey, szUAShort, sizeof(szUAShort));
00311         if(*szUAShort != '\0')
00312         {
00313           /* delete uninstall key that contains product name and its user agent in parenthesis, for
00314            * example:
00315            *     Mozilla (0.8)
00316            */
00317           wsprintf(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s (%s)", szCleanupProduct, szUAShort);
00318           DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00319 
00320           /* delete uninstall key that contains product name and its user agent not in parenthesis,
00321            * for example:
00322            *     Mozilla 0.8
00323            */
00324           wsprintf(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s %s", szCleanupProduct, szUAShort);
00325           DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00326 
00327           /* delete installed product that contains product name and its user agent not in parenthesis,
00328            * for example:
00329            *     Mozilla 0.8
00330            */
00331           wsprintf(szKey, "Software\\Mozilla\\%s %s", szCleanupProduct, szUAShort);
00332           DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00333 
00334           /* We are not looking to delete just the product name key, for example:
00335            *     Mozilla
00336            *
00337            * because it might have just been created by the current installation process, so
00338            * deleting this would be a "Bad Thing" (TM).  Besides, we shouldn't be deleting the
00339            * CurrentVersion key that might have just gotten created because GetWinRegSubKeyProductPath()
00340            * will not return the CurrentVersion key.
00341            */
00342         }
00343         // the szKey was stepped on.  Reget it.
00344         wsprintf(szBufTiny, "Product Reg Key%d", dwIndex);        
00345         GetPrivateProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey), szFileIniConfig);
00346       }
00347     }  while (*szRvSubKey != '\0');
00348     wsprintf(szBufTiny, "Product Reg Key%d", ++dwIndex);        
00349     GetPrivateProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey), szFileIniConfig);
00350   } 
00351 
00352 }
00353 
00354 void ProcessFileOps(DWORD dwTiming, char *szSectionPrefix)
00355 {
00356   if(sgProduct.bInstallFiles)
00357   {
00358     ProcessUncompressFile(dwTiming, szSectionPrefix);
00359     ProcessCreateDirectory(dwTiming, szSectionPrefix);
00360     ProcessMoveFile(dwTiming, szSectionPrefix);
00361     ProcessCopyFile(dwTiming, szSectionPrefix);
00362     ProcessCopyFileSequential(dwTiming, szSectionPrefix);
00363     ProcessSelfRegisterFile(dwTiming, szSectionPrefix);
00364     ProcessDeleteFile(dwTiming, szSectionPrefix);
00365     ProcessRemoveDirectory(dwTiming, szSectionPrefix);
00366     if(!gbIgnoreRunAppX)
00367       ProcessRunApp(dwTiming, szSectionPrefix);
00368   }
00369 
00370   // This is the only operation we do if we are not installing files
00371   ProcessWinReg(dwTiming, szSectionPrefix);
00372 
00373   if(sgProduct.bInstallFiles)
00374   {
00375     ProcessProgramFolder(dwTiming, szSectionPrefix);
00376     ProcessSetVersionRegistry(dwTiming, szSectionPrefix);
00377   }
00378 }
00379 
00380 void ProcessFileOpsForSelectedComponents(DWORD dwTiming)
00381 {
00382   DWORD dwIndex0;
00383   siC   *siCObject = NULL;
00384 
00385   dwIndex0  = 0;
00386   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00387   while(siCObject)
00388   {
00389     if(siCObject->dwAttributes & SIC_SELECTED)
00390       /* Since the archive is selected, we need to process the file ops here */
00391       ProcessFileOps(dwTiming, siCObject->szReferenceName);
00392 
00393     ++dwIndex0;
00394     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00395   } /* while(siCObject) */
00396 }
00397 
00398 void ProcessFileOpsForAll(DWORD dwTiming)
00399 {
00400   ProcessFileOps(dwTiming, NULL);
00401   if(sgProduct.bInstallFiles)
00402   {
00403     ProcessFileOpsForSelectedComponents(dwTiming);
00404     ProcessCreateCustomFiles(dwTiming);
00405   }
00406 }
00407 
00408 int VerifyArchive(LPSTR szArchive)
00409 {
00410   void *vZip;
00411   int  iTestRv;
00412 
00413   /* Check for the existance of the from (source) file */
00414   if(!FileExists(szArchive))
00415     return(FO_ERROR_FILE_NOT_FOUND);
00416 
00417   if((iTestRv = ZIP_OpenArchive(szArchive, &vZip)) == ZIP_OK)
00418   {
00419     /* 1st parameter should be NULL or it will fail */
00420     /* It indicates extract the entire archive */
00421     iTestRv = ZIP_TestArchive(vZip);
00422     ZIP_CloseArchive(&vZip);
00423   }
00424   return(iTestRv);
00425 }
00426 
00427 HRESULT ProcessSetVersionRegistry(DWORD dwTiming, char *szSectionPrefix)
00428 {
00429   DWORD   dwIndex;
00430   BOOL    bIsDirectory;
00431   char    szBuf[MAX_BUF];
00432   char    szSection[MAX_BUF_TINY];
00433   char    szRegistryKey[MAX_BUF];
00434   char    szPath[MAX_BUF];
00435   char    szVersion[MAX_BUF_TINY];
00436 
00437   dwIndex = 0;
00438   BuildNumberedString(dwIndex, szSectionPrefix, "Version Registry", szSection, sizeof(szSection));
00439   GetPrivateProfileString(szSection, "Registry Key", "", szRegistryKey, sizeof(szRegistryKey), szFileIniConfig);
00440   while(*szRegistryKey != '\0')
00441   {
00442     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
00443     {
00444       GetPrivateProfileString(szSection, "Version", "", szVersion, sizeof(szVersion), szFileIniConfig);
00445       GetPrivateProfileString(szSection, "Path",    "", szBuf,     sizeof(szBuf),     szFileIniConfig);
00446       DecryptString(szPath, szBuf);
00447       if(FileExists(szPath) & FILE_ATTRIBUTE_DIRECTORY)
00448         bIsDirectory = TRUE;
00449       else
00450         bIsDirectory = FALSE;
00451 
00452       lstrcpy(szBuf, sgProduct.szPath);
00453       if(sgProduct.szSubPath != '\0')
00454       {
00455         AppendBackSlash(szBuf, sizeof(szBuf));
00456         lstrcat(szBuf, sgProduct.szSubPath);
00457       }
00458 
00459       VR_CreateRegistry(VR_DEFAULT_PRODUCT_NAME, szBuf, NULL);
00460       VR_Install(szRegistryKey, szPath, szVersion, bIsDirectory);
00461       VR_Close();
00462     }
00463 
00464     ++dwIndex;
00465     BuildNumberedString(dwIndex, szSectionPrefix, "Version Registry", szSection, sizeof(szSection));
00466     GetPrivateProfileString(szSection, "Registry Key", "", szRegistryKey, sizeof(szRegistryKey), szFileIniConfig);
00467   }
00468   return(FO_SUCCESS);
00469 }
00470 
00471 HRESULT FileUncompress(LPSTR szFrom, LPSTR szTo)
00472 {
00473   char  szBuf[MAX_BUF];
00474   DWORD dwReturn;
00475   void  *vZip;
00476 
00477   dwReturn = FO_SUCCESS;
00478   /* Check for the existance of the from (source) file */
00479   if(!FileExists(szFrom))
00480     return(FO_ERROR_FILE_NOT_FOUND);
00481 
00482   /* Check for the existance of the to (destination) path */
00483   dwReturn = FileExists(szTo);
00484   if(dwReturn && !(dwReturn & FILE_ATTRIBUTE_DIRECTORY))
00485   {
00486     /* found a file with the same name as the destination path */
00487     return(FO_ERROR_DESTINATION_CONFLICT);
00488   }
00489   else if(!dwReturn)
00490   {
00491     lstrcpy(szBuf, szTo);
00492     AppendBackSlash(szBuf, sizeof(szBuf));
00493     CreateDirectoriesAll(szBuf, DO_NOT_ADD_TO_UNINSTALL_LOG);
00494   }
00495 
00496   GetCurrentDirectory(MAX_BUF, szBuf);
00497   if(SetCurrentDirectory(szTo) == FALSE)
00498     return(FO_ERROR_CHANGE_DIR);
00499 
00500   if((dwReturn = ZIP_OpenArchive(szFrom, &vZip)) != ZIP_OK)
00501     return(dwReturn);
00502 
00503   /* 1st parameter should be NULL or it will fail */
00504   /* It indicates extract the entire archive */
00505   dwReturn = ExtractDirEntries(NULL, vZip);
00506   ZIP_CloseArchive(&vZip);
00507 
00508   if(SetCurrentDirectory(szBuf) == FALSE)
00509     return(FO_ERROR_CHANGE_DIR);
00510 
00511   return(dwReturn);
00512 }
00513 
00514 HRESULT ProcessXpcomFile()
00515 {
00516   char szSource[MAX_BUF];
00517   char szDestination[MAX_BUF];
00518   DWORD dwErr;
00519 
00520   if((dwErr = FileUncompress(siCFXpcomFile.szSource, siCFXpcomFile.szDestination)) != FO_SUCCESS)
00521   {
00522     char szMsg[MAX_BUF];
00523     char szErrorString[MAX_BUF];
00524 
00525     LogISProcessXpcomFile(LIS_FAILURE, dwErr);
00526     GetPrivateProfileString("Strings", "Error File Uncompress", "", szErrorString, sizeof(szErrorString), szFileIniConfig);
00527     wsprintf(szMsg, szErrorString, siCFXpcomFile.szSource, dwErr);
00528     PrintError(szMsg, ERROR_CODE_HIDE);
00529     return(dwErr);
00530   }
00531   LogISProcessXpcomFile(LIS_SUCCESS, dwErr);
00532 
00533   /* copy msvcrt.dll and msvcirt.dll to the bin of the Xpcom temp dir:
00534    *   (c:\temp\Xpcom.ns\bin)
00535    * This is incase these files do not exist on the system */
00536   lstrcpy(szSource, siCFXpcomFile.szDestination);
00537   AppendBackSlash(szSource, sizeof(szSource));
00538   lstrcat(szSource, "ms*.dll");
00539 
00540   lstrcpy(szDestination, siCFXpcomFile.szDestination);
00541   AppendBackSlash(szDestination, sizeof(szDestination));
00542   lstrcat(szDestination, "bin");
00543 
00544   FileCopy(szSource, szDestination, TRUE, FALSE);
00545 
00546   return(FO_SUCCESS);
00547 }
00548 
00549 void CleanupXpcomFile()
00550 {
00551   /* If xpcom file is not used (gre is used instead), then
00552    * just return */
00553   if(siCFXpcomFile.bStatus != STATUS_ENABLED)
00554     return;
00555 
00556   if(siCFXpcomFile.bCleanup == TRUE)
00557     DirectoryRemove(siCFXpcomFile.szDestination, TRUE);
00558 
00559   return;
00560 }
00561 
00562 #define SETUP_STATE_REG_KEY "Software\\%s\\%s\\%s\\Setup"
00563 
00564 HRESULT CleanupArgsRegistry()
00565 {
00566   char  szKey[MAX_BUF];
00567 
00568   wsprintf(szKey, SETUP_STATE_REG_KEY, sgProduct.szCompanyName, sgProduct.szProductNameInternal,
00569     sgProduct.szUserAgent);
00570   DeleteWinRegValue(HKEY_CURRENT_USER, szKey, "browserargs");
00571   return(FO_SUCCESS);
00572 }
00573 
00574 HRESULT ProcessUncompressFile(DWORD dwTiming, char *szSectionPrefix)
00575 {
00576   DWORD   dwIndex;
00577   BOOL    bOnlyIfExists;
00578   char    szBuf[MAX_BUF];
00579   char    szSection[MAX_BUF];
00580   char    szSource[MAX_BUF];
00581   char    szDestination[MAX_BUF];
00582 
00583   dwIndex = 0;
00584   BuildNumberedString(dwIndex, szSectionPrefix, "Uncompress File", szSection, sizeof(szSection));
00585   GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00586   while(*szBuf != '\0')
00587   {
00588     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
00589     {
00590       DecryptString(szSource, szBuf);
00591       GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
00592       DecryptString(szDestination, szBuf);
00593       GetPrivateProfileString(szSection, "Only If Exists", "", szBuf, sizeof(szBuf), szFileIniConfig);
00594       if(lstrcmpi(szBuf, "TRUE") == 0)
00595         bOnlyIfExists = TRUE;
00596       else
00597         bOnlyIfExists = FALSE;
00598 
00599       if((!bOnlyIfExists) || (bOnlyIfExists && FileExists(szDestination)))
00600       {
00601         DWORD dwErr;
00602 
00603         GetPrivateProfileString(szSection, "Message",     "", szBuf, sizeof(szBuf), szFileIniConfig);
00604         ShowMessage(szBuf, TRUE);
00605         if((dwErr = FileUncompress(szSource, szDestination)) != FO_SUCCESS)
00606         {
00607           char szMsg[MAX_BUF];
00608           char szErrorString[MAX_BUF];
00609 
00610           GetPrivateProfileString("Strings", "Error File Uncompress", "", szErrorString, sizeof(szErrorString), szFileIniConfig);
00611           wsprintf(szMsg, szErrorString, szSource, dwErr);
00612           PrintError(szMsg, ERROR_CODE_HIDE);
00613           return(dwErr);
00614         }
00615       }
00616     }
00617 
00618     ++dwIndex;
00619     BuildNumberedString(dwIndex, szSectionPrefix, "Uncompress File", szSection, sizeof(szSection));
00620     GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00621   }
00622   return(FO_SUCCESS);
00623 }
00624 
00625 HRESULT FileMove(LPSTR szFrom, LPSTR szTo)
00626 {
00627   HANDLE          hFile;
00628   WIN32_FIND_DATA fdFile;
00629   char            szFromDir[MAX_BUF];
00630   char            szFromTemp[MAX_BUF];
00631   char            szToTemp[MAX_BUF];
00632   char            szBuf[MAX_BUF];
00633   BOOL            bFound;
00634 
00635   /* From file path exists and To file path does not exist */
00636   if((FileExists(szFrom)) && (!FileExists(szTo)))
00637   {
00638     MoveFile(szFrom, szTo);
00639 
00640     /* log the file move command */
00641     wsprintf(szBuf, "%s to %s", szFrom, szTo);
00642     UpdateInstallLog(KEY_MOVE_FILE, szBuf, FALSE);
00643 
00644     return(FO_SUCCESS);
00645   }
00646   /* From file path exists and To file path exists */
00647   if(FileExists(szFrom) && FileExists(szTo))
00648   {
00649     /* Since the To file path exists, assume it to be a directory and proceed.      */
00650     /* We don't care if it's a file.  If it is a file, then config.ini needs to be  */
00651     /* corrected to remove the file before attempting a MoveFile().                 */
00652     lstrcpy(szToTemp, szTo);
00653     AppendBackSlash(szToTemp, sizeof(szToTemp));
00654     ParsePath(szFrom, szBuf, sizeof(szBuf), FALSE, PP_FILENAME_ONLY);
00655     lstrcat(szToTemp, szBuf);
00656     MoveFile(szFrom, szToTemp);
00657 
00658     /* log the file move command */
00659     wsprintf(szBuf, "%s to %s", szFrom, szToTemp);
00660     UpdateInstallLog(KEY_MOVE_FILE, szBuf, FALSE);
00661 
00662     return(FO_SUCCESS);
00663   }
00664 
00665   ParsePath(szFrom, szFromDir, sizeof(szFromDir), FALSE, PP_PATH_ONLY);
00666 
00667   if((hFile = FindFirstFile(szFrom, &fdFile)) == INVALID_HANDLE_VALUE)
00668     bFound = FALSE;
00669   else
00670     bFound = TRUE;
00671 
00672   while(bFound)
00673   {
00674     if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0))
00675     {
00676       /* create full path string including filename for source */
00677       lstrcpy(szFromTemp, szFromDir);
00678       AppendBackSlash(szFromTemp, sizeof(szFromTemp));
00679       lstrcat(szFromTemp, fdFile.cFileName);
00680 
00681       /* create full path string including filename for destination */
00682       lstrcpy(szToTemp, szTo);
00683       AppendBackSlash(szToTemp, sizeof(szToTemp));
00684       lstrcat(szToTemp, fdFile.cFileName);
00685 
00686       MoveFile(szFromTemp, szToTemp);
00687 
00688       /* log the file move command */
00689       wsprintf(szBuf, "%s to %s", szFromTemp, szToTemp);
00690       UpdateInstallLog(KEY_MOVE_FILE, szBuf, FALSE);
00691     }
00692 
00693     bFound = FindNextFile(hFile, &fdFile);
00694   }
00695 
00696   FindClose(hFile);
00697   return(FO_SUCCESS);
00698 }
00699 
00700 HRESULT ProcessMoveFile(DWORD dwTiming, char *szSectionPrefix)
00701 {
00702   DWORD dwIndex;
00703   char  szBuf[MAX_BUF];
00704   char  szSection[MAX_BUF];
00705   char  szSource[MAX_BUF];
00706   char  szDestination[MAX_BUF];
00707 
00708   dwIndex = 0;
00709   BuildNumberedString(dwIndex, szSectionPrefix, "Move File", szSection, sizeof(szSection));
00710   GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00711   while(*szBuf != '\0')
00712   {
00713     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
00714     {
00715       DecryptString(szSource, szBuf);
00716       GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
00717       DecryptString(szDestination, szBuf);
00718       FileMove(szSource, szDestination);
00719     }
00720 
00721     ++dwIndex;
00722     BuildNumberedString(dwIndex, szSectionPrefix, "Move File", szSection, sizeof(szSection));
00723     GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00724   }
00725   return(FO_SUCCESS);
00726 }
00727 
00728 HRESULT FileCopy(LPSTR szFrom, LPSTR szTo, BOOL bFailIfExists, BOOL bDnu)
00729 {
00730   HANDLE          hFile;
00731   WIN32_FIND_DATA fdFile;
00732   char            szFromDir[MAX_BUF];
00733   char            szFromTemp[MAX_BUF];
00734   char            szToTemp[MAX_BUF];
00735   char            szBuf[MAX_BUF];
00736   BOOL            bFound;
00737 
00738   if(FileExists(szFrom))
00739   {
00740     /* The file in the From file path exists */
00741     CreateDirectoriesAll(szTo, !bDnu);
00742     ParsePath(szFrom, szBuf, sizeof(szBuf), FALSE, PP_FILENAME_ONLY);
00743     lstrcpy(szToTemp, szTo);
00744     AppendBackSlash(szToTemp, sizeof(szToTemp));
00745     lstrcat(szToTemp, szBuf);
00746     CopyFile(szFrom, szToTemp, bFailIfExists);
00747     wsprintf(szBuf, "%s to %s", szFrom, szToTemp);
00748     UpdateInstallLog(KEY_COPY_FILE, szBuf, bDnu);
00749 
00750     return(FO_SUCCESS);
00751   }
00752 
00753   /* The file in the From file path does not exist.  Assume to contain wild args and */
00754   /* proceed acordingly.                                                             */
00755   ParsePath(szFrom, szFromDir, sizeof(szFromDir), FALSE, PP_PATH_ONLY);
00756 
00757   if((hFile = FindFirstFile(szFrom, &fdFile)) == INVALID_HANDLE_VALUE)
00758     bFound = FALSE;
00759   else
00760     bFound = TRUE;
00761 
00762   while(bFound)
00763   {
00764     if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0))
00765     {
00766       /* create full path string including filename for source */
00767       lstrcpy(szFromTemp, szFromDir);
00768       AppendBackSlash(szFromTemp, sizeof(szFromTemp));
00769       lstrcat(szFromTemp, fdFile.cFileName);
00770 
00771       /* create full path string including filename for destination */
00772       lstrcpy(szToTemp, szTo);
00773       AppendBackSlash(szToTemp, sizeof(szToTemp));
00774       lstrcat(szToTemp, fdFile.cFileName);
00775 
00776       CopyFile(szFromTemp, szToTemp, bFailIfExists);
00777 
00778       /* log the file copy command */
00779       wsprintf(szBuf, "%s to %s", szFromTemp, szToTemp);
00780       UpdateInstallLog(KEY_COPY_FILE, szBuf, bDnu);
00781     }
00782 
00783     bFound = FindNextFile(hFile, &fdFile);
00784   }
00785 
00786   FindClose(hFile);
00787   return(FO_SUCCESS);
00788 }
00789 
00790 HRESULT FileCopySequential(LPSTR szSourcePath, LPSTR szDestPath, LPSTR szFilename)
00791 {
00792   int             iFilenameOnlyLen;
00793   char            szDestFullFilename[MAX_BUF];
00794   char            szSourceFullFilename[MAX_BUF];
00795   char            szSearchFilename[MAX_BUF];
00796   char            szSearchDestFullFilename[MAX_BUF];
00797   char            szFilenameOnly[MAX_BUF];
00798   char            szFilenameExtensionOnly[MAX_BUF];
00799   char            szNumber[MAX_BUF];
00800   long            dwNumber;
00801   long            dwMaxNumber;
00802   LPSTR           szDotPtr;
00803   HANDLE          hFile;
00804   WIN32_FIND_DATA fdFile;
00805   BOOL            bFound;
00806 
00807   lstrcpy(szSourceFullFilename, szSourcePath);
00808   AppendBackSlash(szSourceFullFilename, sizeof(szSourceFullFilename));
00809   lstrcat(szSourceFullFilename, szFilename);
00810 
00811   if(FileExists(szSourceFullFilename))
00812   {
00813     /* zero out the memory */
00814     ZeroMemory(szSearchFilename,        sizeof(szSearchFilename));
00815     ZeroMemory(szFilenameOnly,          sizeof(szFilenameOnly));
00816     ZeroMemory(szFilenameExtensionOnly, sizeof(szFilenameExtensionOnly));
00817 
00818     /* parse for the filename w/o extention and also only the extension */
00819     if((szDotPtr = strstr(szFilename, ".")) != NULL)
00820     {
00821       *szDotPtr = '\0';
00822       lstrcpy(szSearchFilename, szFilename);
00823       lstrcpy(szFilenameOnly, szFilename);
00824       lstrcpy(szFilenameExtensionOnly, &szDotPtr[1]);
00825       *szDotPtr = '.';
00826     }
00827     else
00828     {
00829       lstrcpy(szFilenameOnly, szFilename);
00830       lstrcpy(szSearchFilename, szFilename);
00831     }
00832 
00833     /* create the wild arg filename to search for in the szDestPath */
00834     lstrcat(szSearchFilename, "*.*");
00835     lstrcpy(szSearchDestFullFilename, szDestPath);
00836     AppendBackSlash(szSearchDestFullFilename, sizeof(szSearchDestFullFilename));
00837     lstrcat(szSearchDestFullFilename, szSearchFilename);
00838 
00839     iFilenameOnlyLen = lstrlen(szFilenameOnly);
00840     dwNumber         = 0;
00841     dwMaxNumber      = 0;
00842 
00843     /* find the largest numbered filename in the szDestPath */
00844     if((hFile = FindFirstFile(szSearchDestFullFilename, &fdFile)) == INVALID_HANDLE_VALUE)
00845       bFound = FALSE;
00846     else
00847       bFound = TRUE;
00848 
00849     while(bFound)
00850     {
00851        ZeroMemory(szNumber, sizeof(szNumber));
00852       if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0))
00853       {
00854         lstrcpy(szNumber, &fdFile.cFileName[iFilenameOnlyLen]);
00855         dwNumber = atoi(szNumber);
00856         if(dwNumber > dwMaxNumber)
00857           dwMaxNumber = dwNumber;
00858       }
00859 
00860       bFound = FindNextFile(hFile, &fdFile);
00861     }
00862 
00863     FindClose(hFile);
00864 
00865     lstrcpy(szDestFullFilename, szDestPath);
00866     AppendBackSlash(szDestFullFilename, sizeof(szDestFullFilename));
00867     lstrcat(szDestFullFilename, szFilenameOnly);
00868     itoa(dwMaxNumber + 1, szNumber, 10);
00869     lstrcat(szDestFullFilename, szNumber);
00870 
00871     if(*szFilenameExtensionOnly != '\0')
00872     {
00873       lstrcat(szDestFullFilename, ".");
00874       lstrcat(szDestFullFilename, szFilenameExtensionOnly);
00875     }
00876 
00877     CopyFile(szSourceFullFilename, szDestFullFilename, TRUE);
00878   }
00879 
00880   return(FO_SUCCESS);
00881 }
00882 
00883 HRESULT ProcessCopyFile(DWORD dwTiming, char *szSectionPrefix)
00884 {
00885   DWORD dwIndex;
00886   char  szBuf[MAX_BUF];
00887   char  szSection[MAX_BUF];
00888   char  szSource[MAX_BUF];
00889   char  szDestination[MAX_BUF];
00890   BOOL  bFailIfExists;
00891   BOOL  bDnu;
00892 
00893   dwIndex = 0;
00894   BuildNumberedString(dwIndex, szSectionPrefix, "Copy File", szSection, sizeof(szSection));
00895   GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00896   while(*szBuf != '\0')
00897   {
00898     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
00899     {
00900       DecryptString(szSource, szBuf);
00901       GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
00902       DecryptString(szDestination, szBuf);
00903 
00904       GetPrivateProfileString(szSection, "Do Not Uninstall", "", szBuf, sizeof(szBuf), szFileIniConfig);
00905       if(lstrcmpi(szBuf, "TRUE") == 0)
00906         bDnu = TRUE;
00907       else
00908         bDnu = FALSE;
00909 
00910       GetPrivateProfileString(szSection, "Fail If Exists", "", szBuf, sizeof(szBuf), szFileIniConfig);
00911       if(lstrcmpi(szBuf, "TRUE") == 0)
00912         bFailIfExists = TRUE;
00913       else
00914         bFailIfExists = FALSE;
00915 
00916       FileCopy(szSource, szDestination, bFailIfExists, bDnu);
00917     }
00918 
00919     ++dwIndex;
00920     BuildNumberedString(dwIndex, szSectionPrefix, "Copy File", szSection, sizeof(szSection));
00921     GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00922   }
00923   return(FO_SUCCESS);
00924 }
00925 
00926 HRESULT ProcessCopyFileSequential(DWORD dwTiming, char *szSectionPrefix)
00927 {
00928   DWORD dwIndex;
00929   char  szBuf[MAX_BUF];
00930   char  szSection[MAX_BUF];
00931   char  szSource[MAX_BUF];
00932   char  szDestination[MAX_BUF];
00933   char  szFilename[MAX_BUF];
00934 
00935   dwIndex = 0;
00936   BuildNumberedString(dwIndex, szSectionPrefix, "Copy File Sequential", szSection, sizeof(szSection));
00937   GetPrivateProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename), szFileIniConfig);
00938   while(*szFilename != '\0')
00939   {
00940     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
00941     {
00942       GetPrivateProfileString(szSection, "Source", "", szBuf, sizeof(szBuf), szFileIniConfig);
00943       DecryptString(szSource, szBuf);
00944 
00945       GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
00946       DecryptString(szDestination, szBuf);
00947 
00948       FileCopySequential(szSource, szDestination, szFilename);
00949     }
00950 
00951     ++dwIndex;
00952     BuildNumberedString(dwIndex, szSectionPrefix, "Copy File Sequential", szSection, sizeof(szSection));
00953     GetPrivateProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename), szFileIniConfig);
00954   }
00955   return(FO_SUCCESS);
00956 }
00957 
00958 int RegisterDll32(char *File)
00959 {
00960   FARPROC   DllReg;
00961   HINSTANCE hLib;
00962 
00963   if((hLib = LoadLibraryEx(File, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) != NULL)
00964   {
00965     if((DllReg = GetProcAddress(hLib, "DllRegisterServer")) != NULL)
00966       DllReg();
00967 
00968     FreeLibrary(hLib);
00969     return(0);
00970   }
00971 
00972   return(1);
00973 }
00974 
00975 
00976 HRESULT FileSelfRegister(LPSTR szFilename, LPSTR szDestination)
00977 {
00978   char            szFullFilenamePath[MAX_BUF];
00979   DWORD           dwRv;
00980   HANDLE          hFile;
00981   WIN32_FIND_DATA fdFile;
00982   BOOL            bFound;
00983 
00984   lstrcpy(szFullFilenamePath, szDestination);
00985   AppendBackSlash(szFullFilenamePath, sizeof(szFullFilenamePath));
00986   lstrcat(szFullFilenamePath, szFilename);
00987 
00988   /* From file path exists and To file path does not exist */
00989   if(FileExists(szFullFilenamePath))
00990   {
00991     RegisterDll32(szFullFilenamePath);
00992     return(FO_SUCCESS);
00993   }
00994 
00995   lstrcpy(szFullFilenamePath, szDestination);
00996   AppendBackSlash(szFullFilenamePath, sizeof(szFullFilenamePath));
00997   lstrcat(szFullFilenamePath, szFilename);
00998 
00999   if((hFile = FindFirstFile(szFullFilenamePath, &fdFile)) == INVALID_HANDLE_VALUE)
01000     bFound = FALSE;
01001   else
01002     bFound = TRUE;
01003 
01004   while(bFound)
01005   {
01006     if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0))
01007     {
01008       /* create full path string including filename for destination */
01009       lstrcpy(szFullFilenamePath, szDestination);
01010       AppendBackSlash(szFullFilenamePath, sizeof(szFullFilenamePath));
01011       lstrcat(szFullFilenamePath, fdFile.cFileName);
01012 
01013       if((dwRv = FileExists(szFullFilenamePath)) && (dwRv != FILE_ATTRIBUTE_DIRECTORY))
01014         RegisterDll32(szFullFilenamePath);
01015     }
01016 
01017     bFound = FindNextFile(hFile, &fdFile);
01018   }
01019 
01020   FindClose(hFile);
01021   return(FO_SUCCESS);
01022 }
01023 
01024 HRESULT ProcessSelfRegisterFile(DWORD dwTiming, char *szSectionPrefix)
01025 {
01026   DWORD dwIndex;
01027   char  szBuf[MAX_BUF];
01028   char  szSection[MAX_BUF];
01029   char  szFilename[MAX_BUF];
01030   char  szDestination[MAX_BUF];
01031 
01032   dwIndex = 0;
01033   BuildNumberedString(dwIndex, szSectionPrefix, "Self Register File", szSection, sizeof(szSection));
01034   GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01035   while(*szBuf != '\0')
01036   {
01037     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
01038     {
01039       DecryptString(szDestination, szBuf);
01040       GetPrivateProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename), szFileIniConfig);
01041       FileSelfRegister(szFilename, szDestination);
01042     }
01043 
01044     ++dwIndex;
01045     BuildNumberedString(dwIndex, szSectionPrefix, "Self Register File", szSection, sizeof(szSection));
01046     GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01047   }
01048   return(FO_SUCCESS);
01049 }
01050 
01051 void UpdateInstallLog(LPSTR szKey, LPSTR szString, BOOL bDnu)
01052 {
01053   FILE *fInstallLog;
01054   char szBuf[MAX_BUF];
01055   char szFileInstallLog[MAX_BUF];
01056 
01057   if(gbILUseTemp)
01058   {
01059     lstrcpy(szFileInstallLog, szTempDir);
01060     AppendBackSlash(szFileInstallLog, sizeof(szFileInstallLog));
01061   }
01062   else
01063   {
01064     lstrcpy(szFileInstallLog, sgProduct.szPath);
01065     AppendBackSlash(szFileInstallLog, sizeof(szFileInstallLog));
01066     lstrcat(szFileInstallLog, sgProduct.szSubPath);
01067     AppendBackSlash(szFileInstallLog, sizeof(szFileInstallLog));
01068   }
01069 
01070   CreateDirectoriesAll(szFileInstallLog, !bDnu);
01071   lstrcat(szFileInstallLog, FILE_INSTALL_LOG);
01072 
01073   if((fInstallLog = fopen(szFileInstallLog, "a+t")) != NULL)
01074   {
01075     if(bDnu)
01076       wsprintf(szBuf, "     ** (*dnu*) %s%s\n", szKey, szString);
01077     else
01078       wsprintf(szBuf, "     ** %s%s\n", szKey, szString);
01079 
01080     fwrite(szBuf, sizeof(char), lstrlen(szBuf), fInstallLog);
01081     fclose(fInstallLog);
01082   }
01083 }
01084 
01085 void UpdateInstallStatusLog(LPSTR szString)
01086 {
01087   FILE *fInstallLog;
01088   char szFileInstallStatusLog[MAX_BUF];
01089 
01090   if(gbILUseTemp)
01091   {
01092     lstrcpy(szFileInstallStatusLog, szTempDir);
01093     AppendBackSlash(szFileInstallStatusLog, sizeof(szFileInstallStatusLog));
01094   }
01095   else
01096   {
01097     lstrcpy(szFileInstallStatusLog, sgProduct.szPath);
01098     AppendBackSlash(szFileInstallStatusLog, sizeof(szFileInstallStatusLog));
01099     lstrcat(szFileInstallStatusLog, sgProduct.szSubPath);
01100     AppendBackSlash(szFileInstallStatusLog, sizeof(szFileInstallStatusLog));
01101   }
01102 
01103   CreateDirectoriesAll(szFileInstallStatusLog, DO_NOT_ADD_TO_UNINSTALL_LOG);
01104   lstrcat(szFileInstallStatusLog, FILE_INSTALL_STATUS_LOG);
01105 
01106   if((fInstallLog = fopen(szFileInstallStatusLog, "a+t")) != NULL)
01107   {
01108     fwrite(szString, sizeof(char), lstrlen(szString), fInstallLog);
01109     fclose(fInstallLog);
01110   }
01111 }
01112 
01113 void UpdateJSProxyInfo()
01114 {
01115   FILE *fJSFile;
01116   char szBuf[MAX_BUF];
01117   char szJSFile[MAX_BUF];
01118 
01119   if((*diAdvancedSettings.szProxyServer != '\0') || (*diAdvancedSettings.szProxyPort != '\0'))
01120   {
01121     lstrcpy(szJSFile, sgProduct.szPath);
01122     if(*sgProduct.szSubPath != '\0')
01123     {
01124       AppendBackSlash(szJSFile, sizeof(szJSFile));
01125       lstrcat(szJSFile, sgProduct.szSubPath);
01126     }
01127     AppendBackSlash(szJSFile, sizeof(szJSFile));
01128     lstrcat(szJSFile, "defaults\\pref\\");
01129     CreateDirectoriesAll(szJSFile, ADD_TO_UNINSTALL_LOG);
01130     lstrcat(szJSFile, FILE_ALL_JS);
01131 
01132     if((fJSFile = fopen(szJSFile, "a+t")) != NULL)
01133     {
01134       ZeroMemory(szBuf, sizeof(szBuf));
01135       if(*diAdvancedSettings.szProxyServer != '\0')
01136       {
01137         if(diAdditionalOptions.dwUseProtocol == UP_FTP)
01138           wsprintf(szBuf,
01139                    "pref(\"network.proxy.ftp\", \"%s\");\n",
01140                    diAdvancedSettings.szProxyServer);
01141         else
01142           wsprintf(szBuf,
01143                    "pref(\"network.proxy.http\", \"%s\");\n",
01144                    diAdvancedSettings.szProxyServer);
01145       }
01146 
01147       if(*diAdvancedSettings.szProxyPort != '\0')
01148       {
01149         if(diAdditionalOptions.dwUseProtocol == UP_FTP)
01150           wsprintf(szBuf,
01151                    "pref(\"network.proxy.ftp_port\", %s);\n",
01152                    diAdvancedSettings.szProxyPort);
01153         else
01154           wsprintf(szBuf,
01155                    "pref(\"network.proxy.http_port\", %s);\n",
01156                    diAdvancedSettings.szProxyPort);
01157       }
01158 
01159       lstrcat(szBuf, "pref(\"network.proxy.type\", 1);\n");
01160 
01161       fwrite(szBuf, sizeof(char), lstrlen(szBuf), fJSFile);
01162       fclose(fJSFile);
01163     }
01164   }
01165 }
01166 
01167 /* Function: DirHasWriteAccess()
01168  *
01169  *       in: char *aPath - path to check for write access
01170  *
01171  *  purpose: To determine if aPath has write access.  It does this by
01172  *           simply creating the directory.  If the path already exists
01173  *           then it will attempt to create a directory within the path.
01174  *           This function will cleanup all the directories it created.
01175  */
01176 HRESULT DirHasWriteAccess(char *aPath)
01177 {
01178   int     i;
01179   int     iLen = lstrlen(aPath);
01180   char    szCreatePath[MAX_BUF];
01181 
01182   ZeroMemory(szCreatePath, sizeof(szCreatePath));
01183   memcpy(szCreatePath, aPath, iLen);
01184   for(i = 0; i < iLen; i++)
01185   {
01186     if((iLen > 1) &&
01187       ((i != 0) && ((aPath[i] == '\\') || (aPath[i] == '/'))) &&
01188       (!((aPath[0] == '\\') && (i == 1)) && !((aPath[1] == ':') && (i == 2))))
01189     {
01190       szCreatePath[i] = '\0';
01191       if(FileExists(szCreatePath) == FALSE)
01192       {
01193         if(!CreateDirectory(szCreatePath, NULL))
01194           return(WIZ_ERROR_CREATE_DIRECTORY);
01195 
01196         RemoveDirectory(szCreatePath);
01197         return(WIZ_OK);
01198       }
01199       szCreatePath[i] = aPath[i];
01200     }
01201   }
01202 
01203   /* All the dirs exist, so no test has been done.  Create a test dir within
01204    * aPath to verify if we have write access or not */
01205   AppendBackSlash(szCreatePath, sizeof(szCreatePath));
01206   lstrcat(szCreatePath, "testdir");
01207   if(!CreateDirectory(szCreatePath, NULL))
01208     return(WIZ_ERROR_CREATE_DIRECTORY);
01209 
01210   RemoveDirectory(szCreatePath);
01211   return(WIZ_OK);
01212 }
01213 
01214 HRESULT CreateDirectoriesAll(char* szPath, BOOL bLogForUninstall)
01215 {
01216   int     i;
01217   int     iLen = lstrlen(szPath);
01218   char    szCreatePath[MAX_BUF];
01219   HRESULT hrResult = WIZ_OK;
01220 
01221   ZeroMemory(szCreatePath, MAX_BUF);
01222   memcpy(szCreatePath, szPath, iLen);
01223   for(i = 0; i < iLen; i++)
01224   {
01225     if((iLen > 1) &&
01226       ((i != 0) && ((szPath[i] == '\\') || (szPath[i] == '/'))) &&
01227       (!((szPath[0] == '\\') && (i == 1)) && !((szPath[1] == ':') && (i == 2))))
01228     {
01229       szCreatePath[i] = '\0';
01230       if(FileExists(szCreatePath) == FALSE)
01231       {
01232         if(!CreateDirectory(szCreatePath, NULL))
01233           return(WIZ_ERROR_CREATE_DIRECTORY);
01234 
01235         if(bLogForUninstall)
01236           UpdateInstallLog(KEY_CREATE_FOLDER, szCreatePath, FALSE);
01237       }
01238       szCreatePath[i] = szPath[i];
01239     }
01240   }
01241   return(hrResult);
01242 }
01243 
01244 HRESULT ProcessCreateDirectory(DWORD dwTiming, char *szSectionPrefix)
01245 {
01246   DWORD dwIndex;
01247   char  szBuf[MAX_BUF];
01248   char  szSection[MAX_BUF];
01249   char  szDestination[MAX_BUF];
01250 
01251   dwIndex = 0;
01252   BuildNumberedString(dwIndex, szSectionPrefix, "Create Directory", szSection, sizeof(szSection));
01253   GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01254   while(*szBuf != '\0')
01255   {
01256     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
01257     {
01258       DecryptString(szDestination, szBuf);
01259       AppendBackSlash(szDestination, sizeof(szDestination));
01260       CreateDirectoriesAll(szDestination, ADD_TO_UNINSTALL_LOG);
01261     }
01262 
01263     ++dwIndex;
01264     BuildNumberedString(dwIndex, szSectionPrefix, "Create Directory", szSection, sizeof(szSection));
01265     GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01266   }
01267   return(FO_SUCCESS);
01268 }
01269 
01270 HRESULT FileDelete(LPSTR szDestination)
01271 {
01272   HANDLE          hFile;
01273   WIN32_FIND_DATA fdFile;
01274   char            szBuf[MAX_BUF];
01275   char            szPathOnly[MAX_BUF];
01276   BOOL            bFound;
01277 
01278   if(FileExists(szDestination))
01279   {
01280     /* The file in the From file path exists */
01281     DeleteFile(szDestination);
01282     return(FO_SUCCESS);
01283   }
01284 
01285   /* The file in the From file path does not exist.  Assume to contain wild args and */
01286   /* proceed acordingly.                                                             */
01287   ParsePath(szDestination, szPathOnly, sizeof(szPathOnly), FALSE, PP_PATH_ONLY);
01288 
01289   if((hFile = FindFirstFile(szDestination, &fdFile)) == INVALID_HANDLE_VALUE)
01290     bFound = FALSE;
01291   else
01292     bFound = TRUE;
01293 
01294   while(bFound)
01295   {
01296     if(!(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
01297     {
01298       lstrcpy(szBuf, szPathOnly);
01299       AppendBackSlash(szBuf, sizeof(szBuf));
01300       lstrcat(szBuf, fdFile.cFileName);
01301 
01302       DeleteFile(szBuf);
01303     }
01304 
01305     bFound = FindNextFile(hFile, &fdFile);
01306   }
01307 
01308   FindClose(hFile);
01309   return(FO_SUCCESS);
01310 }
01311 
01312 HRESULT ProcessDeleteFile(DWORD dwTiming, char *szSectionPrefix)
01313 {
01314   DWORD dwIndex;
01315   char  szBuf[MAX_BUF];
01316   char  szSection[MAX_BUF];
01317   char  szDestination[MAX_BUF];
01318 
01319   dwIndex = 0;
01320   BuildNumberedString(dwIndex, szSectionPrefix, "Delete File", szSection, sizeof(szSection));
01321   GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01322   while(*szBuf != '\0')
01323   {
01324     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
01325     {
01326       DecryptString(szDestination, szBuf);
01327       FileDelete(szDestination);
01328     }
01329 
01330     ++dwIndex;
01331     BuildNumberedString(dwIndex, szSectionPrefix, "Delete File", szSection, sizeof(szSection));
01332     GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01333   }
01334   return(FO_SUCCESS);
01335 }
01336 
01337 HRESULT DirectoryRemove(LPSTR szDestination, BOOL bRemoveSubdirs)
01338 {
01339   HANDLE          hFile;
01340   WIN32_FIND_DATA fdFile;
01341   char            szDestTemp[MAX_BUF];
01342   BOOL            bFound;
01343 
01344   if(!FileExists(szDestination))
01345     return(FO_SUCCESS);
01346 
01347   if(bRemoveSubdirs == TRUE)
01348   {
01349     lstrcpy(szDestTemp, szDestination);
01350     AppendBackSlash(szDestTemp, sizeof(szDestTemp));
01351     lstrcat(szDestTemp, "*");
01352 
01353     bFound = TRUE;
01354     hFile = FindFirstFile(szDestTemp, &fdFile);
01355     while((hFile != INVALID_HANDLE_VALUE) && (bFound == TRUE))
01356     {
01357       if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0))
01358       {
01359         /* create full path */
01360         lstrcpy(szDestTemp, szDestination);
01361         AppendBackSlash(szDestTemp, sizeof(szDestTemp));
01362         lstrcat(szDestTemp, fdFile.cFileName);
01363 
01364         if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
01365         {
01366           DirectoryRemove(szDestTemp, bRemoveSubdirs);
01367         }
01368         else
01369         {
01370           DeleteFile(szDestTemp);
01371         }
01372       }
01373 
01374       bFound = FindNextFile(hFile, &fdFile);
01375     }
01376 
01377     FindClose(hFile);
01378   }
01379   
01380   RemoveDirectory(szDestination);
01381   return(FO_SUCCESS);
01382 }
01383 
01384 HRESULT ProcessRemoveDirectory(DWORD dwTiming, char *szSectionPrefix)
01385 {
01386   DWORD dwIndex;
01387   char  szBuf[MAX_BUF];
01388   char  szSection[MAX_BUF];
01389   char  szDestination[MAX_BUF];
01390   BOOL  bRemoveSubdirs;
01391 
01392   dwIndex = 0;
01393   BuildNumberedString(dwIndex, szSectionPrefix, "Remove Directory", szSection, sizeof(szSection));
01394   GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01395   while(*szBuf != '\0')
01396   {
01397     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
01398     {
01399       DecryptString(szDestination, szBuf);
01400       GetPrivateProfileString(szSection, "Remove subdirs", "", szBuf, sizeof(szBuf), szFileIniConfig);
01401       bRemoveSubdirs = FALSE;
01402       if(lstrcmpi(szBuf, "TRUE") == 0)
01403         bRemoveSubdirs = TRUE;
01404 
01405       DirectoryRemove(szDestination, bRemoveSubdirs);
01406     }
01407 
01408     ++dwIndex;
01409     BuildNumberedString(dwIndex, szSectionPrefix, "Remove Directory", szSection, sizeof(szSection));
01410     GetPrivateProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf), szFileIniConfig);
01411   }
01412   return(FO_SUCCESS);
01413 }
01414 
01415 HRESULT ProcessRunApp(DWORD dwTiming, char *szSectionPrefix)
01416 {
01417   DWORD dwIndex;
01418   char  szBuf[MAX_BUF];
01419   char  szSection[MAX_BUF];
01420   char  szTarget[MAX_BUF];
01421   char  szParameters[MAX_BUF];
01422   char  szWorkingDir[MAX_BUF];
01423   BOOL  bRunApp;
01424   BOOL  bWait;
01425 
01426   dwIndex = 0;
01427   BuildNumberedString(dwIndex, szSectionPrefix, "RunApp", szSection, sizeof(szSection));
01428   GetPrivateProfileString(szSection, "Target", "", szBuf, sizeof(szBuf), szFileIniConfig);
01429   while(*szBuf != '\0')
01430   {
01431     if(TimingCheck(dwTiming, szSection, szFileIniConfig))
01432     {
01433       DecryptString(szTarget, szBuf);
01434       GetPrivateProfileString(szSection, "Parameters", "", szBuf, sizeof(szBuf), szFileIniConfig);
01435       DecryptString(szParameters, szBuf);
01436 
01437       bRunApp = MeetCondition(szSection);
01438 
01439       GetPrivateProfileString(szSection, "WorkingDir", "", szBuf, sizeof(szBuf), szFileIniConfig);
01440       DecryptString(szWorkingDir, szBuf);
01441 
01442       GetPrivateProfileString(szSection, "Wait", "", szBuf, sizeof(szBuf), szFileIniConfig);
01443       if(lstrcmpi(szBuf, "FALSE") == 0)
01444         bWait = FALSE;
01445       else
01446         bWait = TRUE;
01447 
01448       if ((bRunApp == TRUE) && FileExists(szTarget))
01449       {
01450         if((dwTiming == T_DEPEND_REBOOT) && (NeedReboot() == TRUE))
01451         {
01452           lstrcat(szTarget, " ");
01453           lstrcat(szTarget, szParameters);
01454           SetWinReg(HKEY_CURRENT_USER,
01455                     "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
01456                     TRUE,
01457                     "Netscape",
01458                     TRUE,
01459                     REG_SZ,
01460                     szTarget,
01461                     lstrlen(szTarget),
01462                     FALSE,
01463                     FALSE);
01464         }
01465         else
01466         {
01467           GetPrivateProfileString(szSection, "Message", "", szBuf, sizeof(szBuf), szFileIniConfig);
01468           ShowMessage(szBuf, TRUE);  
01469           WinSpawn(szTarget, szParameters, szWorkingDir, SW_SHOWNORMAL, bWait);
01470         }
01471       }
01472     }
01473 
01474     ++dwIndex;
01475     BuildNumberedString(dwIndex, szSectionPrefix, "RunApp", szSection, sizeof(szSection));
01476     GetPrivateProfileString(szSection, "Target", "", szBuf, sizeof(szBuf), szFileIniConfig);
01477   }
01478   return(FO_SUCCESS);
01479 }
01480 
01481 DWORD ParseRestrictedAccessKey(LPSTR szKey)
01482 {
01483   DWORD dwKey;
01484 
01485   if(lstrcmpi(szKey, "ONLY_RESTRICTED") == 0)
01486     dwKey = RA_ONLY_RESTRICTED;
01487   else if(lstrcmpi(szKey, "ONLY_NONRESTRICTED") == 0)
01488     dwKey = RA_ONLY_NONRESTRICTED;
01489   else
01490     dwKey = RA_IGNORE;
01491 
01492   return(dwKey);
01493 }
01494 
01495 /* Function: GetKeyInfo()
01496  *       in: LPSTR aKey, DWORD aOutBufSize, DWORD aInfoType.
01497  *      out: LPSTR aOut.
01498  *  purpose: To parse a full windows registry key path format:
01499  *             [root key]\[subkey]
01500  *           It can return either the root key or the subkey depending on
01501  *           what's being requested.
01502  */
01503 LPSTR GetKeyInfo(LPSTR aKey, LPSTR aOut, DWORD aOutBufSize, DWORD aInfoType)
01504 {
01505   LPSTR keyCopy = NULL;
01506   LPSTR key = NULL;
01507 
01508   *aOut = '\0';
01509   if((keyCopy = strdup(aKey)) == NULL)
01510     return NULL;
01511 
01512   switch(aInfoType)
01513   {
01514     case KEY_INFO_ROOT:
01515       key = MozStrChar(keyCopy, '\\');
01516       if(key == keyCopy)
01517       {
01518         // root key not found, return NULL
01519         free(keyCopy);
01520         return NULL;
01521       }
01522       else if(key)
01523         // found '\\' which indicates the end of the root key
01524         // and beginning of the subkey.
01525         *key = '\0';
01526 
01527       if(MozCopyStr(keyCopy, aOut, aOutBufSize))
01528       {
01529         free(keyCopy);
01530         return NULL;
01531       }
01532       break;
01533 
01534     case KEY_INFO_SUBKEY:
01535       key = MozStrChar(keyCopy, '\\');
01536       if(key != NULL)
01537         ++key;
01538 
01539       if(!key)
01540         // No subkey found.  Assume the entire string is the subkey.
01541         key = keyCopy;
01542 
01543       if(MozCopyStr(key, aOut, aOutBufSize))
01544       {
01545         free(keyCopy);
01546         return NULL;
01547       }
01548       break;
01549   }
01550 
01551   free(keyCopy);
01552   return(aOut);
01553 }
01554 
01555 HKEY ParseRootKey(LPSTR szRootKey)
01556 {
01557   HKEY hkRootKey;
01558 
01559   if(lstrcmpi(szRootKey, "HKEY_CURRENT_CONFIG") == 0)
01560     hkRootKey = HKEY_CURRENT_CONFIG;
01561   else if(lstrcmpi(szRootKey, "HKEY_CURRENT_USER") == 0)
01562     hkRootKey = HKEY_CURRENT_USER;
01563   else if(lstrcmpi(szRootKey, "HKEY_LOCAL_MACHINE") == 0)
01564     hkRootKey = HKEY_LOCAL_MACHINE;
01565   else if(lstrcmpi(szRootKey, "HKEY_USERS") == 0)
01566     hkRootKey = HKEY_USERS;
01567   else if(lstrcmpi(szRootKey, "HKEY_PERFORMANCE_DATA") == 0)
01568     hkRootKey = HKEY_PERFORMANCE_DATA;
01569   else if(lstrcmpi(szRootKey, "HKEY_DYN_DATA") == 0)
01570     hkRootKey = HKEY_DYN_DATA;
01571   else /* HKEY_CLASSES_ROOT */
01572     hkRootKey = HKEY_CLASSES_ROOT;
01573 
01574   return(hkRootKey);
01575 }
01576 
01577 char *ParseRootKeyString(HKEY hkKey, LPSTR szRootKey, DWORD dwRootKeyBufSize)
01578 {
01579   if(!szRootKey)
01580     return(NULL);
01581 
01582   ZeroMemory(szRootKey, dwRootKeyBufSize);
01583   if((hkKey == HKEY_CURRENT_CONFIG) &&
01584     ((long)dwRootKeyBufSize > lstrlen("HKEY_CURRENT_CONFIG")))
01585     lstrcpy(szRootKey, "HKEY_CURRENT_CONFIG");
01586   else if((hkKey == HKEY_CURRENT_USER) &&
01587          ((long)dwRootKeyBufSize > lstrlen("HKEY_CURRENT_USER")))
01588     lstrcpy(szRootKey, "HKEY_CURRENT_USER");
01589   else if((hkKey == HKEY_LOCAL_MACHINE) &&
01590          ((long)dwRootKeyBufSize > lstrlen("HKEY_LOCAL_MACHINE")))
01591     lstrcpy(szRootKey, "HKEY_LOCAL_MACHINE");
01592   else if((hkKey == HKEY_USERS) &&
01593          ((long)dwRootKeyBufSize > lstrlen("HKEY_USERS")))
01594     lstrcpy(szRootKey, "HKEY_USERS");
01595   else if((hkKey == HKEY_PERFORMANCE_DATA) &&
01596          ((long)dwRootKeyBufSize > lstrlen("HKEY_PERFORMANCE_DATA")))
01597     lstrcpy(szRootKey, "HKEY_PERFORMANCE_DATA");
01598   else if((hkKey == HKEY_DYN_DATA) &&
01599          ((long)dwRootKeyBufSize > lstrlen("HKEY_DYN_DATA")))
01600     lstrcpy(szRootKey, "HKEY_DYN_DATA");
01601   else if((long)dwRootKeyBufSize > lstrlen("HKEY_CLASSES_ROOT"))
01602     lstrcpy(szRootKey, "HKEY_CLASSES_ROOT");
01603 
01604   return(szRootKey);
01605 }
01606 
01607 BOOL ParseRegType(LPSTR szType, DWORD *dwType)
01608 {
01609   BOOL bSZ;
01610 
01611   if(lstrcmpi(szType, "REG_SZ") == 0)
01612   {
01613     /* Unicode NULL terminated string */
01614     *dwType = REG_SZ;
01615     bSZ     = TRUE;
01616   }
01617   else if(lstrcmpi(szType, "REG_EXPAND_SZ") == 0)
01618   {
01619     /* Unicode NULL terminated string
01620      * (with environment variable references) */
01621     *dwType = REG_EXPAND_SZ;
01622     bSZ     = TRUE;
01623   }
01624   else if(lstrcmpi(szType, "REG_BINARY") == 0)
01625   {
01626     /* Free form binary */
01627     *dwType = REG_BINARY;
01628     bSZ     = FALSE;
01629   }
01630   else if(lstrcmpi(szType, "REG_DWORD") == 0)
01631   {
01632     /* 32bit number */
01633     *dwType = REG_DWORD;
01634     bSZ     = FALSE;
01635   }
01636   else if(lstrcmpi(szType, "REG_DWORD_LITTLE_ENDIAN") == 0)
01637   {
01638     /* 32bit number
01639      * (same as REG_DWORD) */
01640     *dwType = REG_DWORD_LITTLE_ENDIAN;
01641     bSZ     = FALSE;
01642   }
01643   else if(lstrcmpi(szType, "REG_DWORD_BIG_ENDIAN") == 0)
01644   {
01645     /* 32bit number */
01646     *dwType = REG_DWORD_BIG_ENDIAN;
01647     bSZ     = FALSE;
01648   }
01649   else if(lstrcmpi(szType, "REG_LINK") == 0)
01650   {
01651     /* Symbolic link (unicode) */
01652     *dwType = REG_LINK;
01653     bSZ     = TRUE;
01654   }
01655   else if(lstrcmpi(szType, "REG_MULTI_SZ") == 0)
01656   {
01657     /* Multiple Unicode strings */
01658     *dwType = REG_MULTI_SZ;
01659     bSZ     = TRUE;
01660   }
01661   else /* Default is REG_NONE */
01662   {
01663     /* no value type */
01664     *dwType = REG_NONE;
01665     bSZ     = TRUE;
01666   }
01667 
01668   return(bSZ);
01669 }
01670 
01671 BOOL WinRegKeyExists(HKEY hkRootKey, LPSTR szKey)
01672 {
01673   HKEY  hkResult;
01674   DWORD dwErr;
01675   BOOL  bKeyExists = FALSE;
01676 
01677   if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS)
01678   {
01679     bKeyExists = TRUE;
01680     RegCloseKey(hkResult);
01681   }
01682 
01683   return(bKeyExists);
01684 }
01685 
01686 BOOL WinRegNameExists(HKEY hkRootKey, LPSTR szKey, LPSTR szName)
01687 {
01688   HKEY  hkResult;
01689   DWORD dwErr;
01690   DWORD dwSize;
01691   char  szBuf[MAX_BUF];
01692   BOOL  bNameExists = FALSE;
01693 
01694   ZeroMemory(szBuf, sizeof(szBuf));
01695   if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS)
01696   {
01697     dwSize = sizeof(szBuf);
01698     dwErr  = RegQueryValueEx(hkResult, szName, 0, NULL, szBuf, &dwSize);
01699 
01700     if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS))
01701       bNameExists = TRUE;
01702 
01703     RegCloseKey(hkResult);
01704   }
01705 
01706   return(bNameExists);
01707 }
01708 
01709 void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete)
01710 {
01711   HKEY      hkResult;
01712   DWORD     dwErr;
01713   DWORD     dwTotalSubKeys;
01714   DWORD     dwTotalValues;
01715   DWORD     dwSubKeySize;
01716   FILETIME  ftLastWriteFileTime;
01717   char      szSubKey[MAX_BUF_TINY];
01718   char      szNewKey[MAX_BUF];
01719   long      lRv;
01720 
01721   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_QUERY_VALUE, &hkResult);
01722   if(dwErr == ERROR_SUCCESS)
01723   {
01724     dwTotalSubKeys = 0;
01725     dwTotalValues  = 0;
01726     RegQueryInfoKey(hkResult, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL);
01727     RegCloseKey(hkResult);
01728 
01729     if(((dwTotalSubKeys == 0) && (dwTotalValues == 0)) || bAbsoluteDelete)
01730     {
01731       if(dwTotalSubKeys && bAbsoluteDelete)
01732       {
01733         do
01734         {
01735           dwSubKeySize = sizeof(szSubKey);
01736           lRv = 0;
01737           if(RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS)
01738           {
01739             if((lRv = RegEnumKeyEx(hkResult, 0, szSubKey, &dwSubKeySize, NULL, NULL, NULL, &ftLastWriteFileTime)) == ERROR_SUCCESS)
01740             {
01741               RegCloseKey(hkResult);
01742               lstrcpy(szNewKey, szKey);
01743               AppendBackSlash(szNewKey, sizeof(szNewKey));
01744               lstrcat(szNewKey, szSubKey);
01745               DeleteWinRegKey(hkRootKey, szNewKey, bAbsoluteDelete);
01746             }
01747             else
01748               RegCloseKey(hkResult);
01749           }
01750         } while(lRv != ERROR_NO_MORE_ITEMS);
01751       }
01752 
01753       dwErr = RegDeleteKey(hkRootKey, szKey);
01754     }
01755   }
01756 }
01757 
01758 void DeleteWinRegValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName)
01759 {
01760   HKEY    hkResult;
01761   DWORD   dwErr;
01762 
01763   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult);
01764   if(dwErr == ERROR_SUCCESS)
01765   {
01766     if(*szName == '\0')
01767       dwErr = RegDeleteValue(hkResult, NULL);
01768     else
01769       dwErr = RegDeleteValue(hkResult, szName);
01770 
01771     RegCloseKey(hkResult);
01772   }
01773 }
01774 
01775 DWORD GetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, LPSTR szReturnValue, DWORD dwReturnValueSize)
01776 {
01777   HKEY  hkResult;
01778   DWORD dwErr;
01779   DWORD dwSize;
01780   DWORD dwType;
01781   char  szBuf[MAX_BUF];
01782 
01783   ZeroMemory(szBuf, sizeof(szBuf));
01784   ZeroMemory(szReturnValue, dwReturnValueSize);
01785 
01786   if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS)
01787   {
01788     dwSize = sizeof(szBuf);
01789     dwErr  = RegQueryValueEx(hkResult, szName, 0, &dwType, szBuf, &dwSize);
01790 
01791     if((dwType == REG_MULTI_SZ) && (*szBuf != '\0'))
01792     {
01793       DWORD dwCpSize;
01794 
01795       dwCpSize = dwReturnValueSize < dwSize ? (dwReturnValueSize - 1) : dwSize;
01796       memcpy(szReturnValue, szBuf, dwCpSize);
01797     }
01798     else if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS))
01799       ExpandEnvironmentStrings(szBuf, szReturnValue, dwReturnValueSize);
01800     else
01801       *szReturnValue = '\0';
01802 
01803     RegCloseKey(hkResult);
01804   }
01805 
01806   return(dwType);
01807 }
01808 
01809 LONG _CreateWinRegKey(HKEY hkRootKey,
01810                        LPSTR szKey,
01811                        BOOL bLogForUninstall,
01812                        BOOL bDnu,
01813                        BOOL bForceCreate)
01814 {
01815   HKEY    hkResult;
01816   LONG    err = ERROR_SUCCESS;
01817   DWORD   dwDisp;
01818   char    szBuf[MAX_BUF];
01819   char    szRootKey[MAX_BUF_TINY];
01820 
01821   if(!WinRegKeyExists(hkRootKey, szKey) || bForceCreate)
01822   {
01823     err = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp);
01824     /* log the win reg command */
01825     if(((err == ERROR_SUCCESS) &&
01826        bLogForUninstall &&
01827        ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey))) || bForceCreate)
01828     {
01829       wsprintf(szBuf, "%s\\%s []", szRootKey, szKey);
01830       UpdateInstallLog(KEY_CREATE_REG_KEY, szBuf, bDnu);
01831     }
01832     RegCloseKey(hkResult);
01833   }
01834 
01835   return(err);
01836 }
01837 
01838 LONG CreateWinRegKey(HKEY hkRootKey,
01839                       LPSTR szKey,
01840                       BOOL bLogForUninstall,
01841                       BOOL bDnu)
01842 {
01843   char    szTempKeyPath[MAX_BUF];
01844   char    saveChar;
01845   LPSTR   pointerToBackslashChar = NULL;
01846   LPSTR   pointerToStrWalker = NULL;
01847 
01848   if(MozCopyStr(szKey, szTempKeyPath, sizeof(szTempKeyPath)))
01849     return(ERROR_BUFFER_OVERFLOW);
01850 
01851   // Make sure that we create all the keys (starting from the root) that
01852   // do not exist.  We need to do this in order to log it for uninstall.
01853   // If this was not done, then only the last key in the key path would be
01854   // uninstalled.
01855   RemoveBackSlash(szTempKeyPath);
01856   pointerToStrWalker = szTempKeyPath;
01857   while((pointerToBackslashChar = strstr(pointerToStrWalker, "\\")) != NULL)
01858   {
01859     saveChar = *pointerToBackslashChar;
01860     *pointerToBackslashChar = '\0';
01861     // Log the registry only if it was created here
01862     _CreateWinRegKey(hkRootKey, szTempKeyPath, bLogForUninstall, bDnu, DO_NOT_FORCE_ADD_TO_UNINSTALL_LOG);
01863     *pointerToBackslashChar = saveChar;
01864     pointerToStrWalker = &pointerToBackslashChar[1];
01865   }
01866 
01867   // Log the registry regardless if it was created here or not.  If it was
01868   // explicitly listed to be created, we should log for uninstall.  This 
01869   // covers the case where the user deletes the uninstall log file from a
01870   // previous build where a new install would not log the creation because
01871   // it already exists.
01872   return(_CreateWinRegKey(hkRootKey, szKey, bLogForUninstall, bDnu, FORCE_ADD_TO_UNINSTALL_LOG));
01873 }
01874 
01875 void SetWinReg(HKEY hkRootKey,
01876                LPSTR szKey,
01877                BOOL bOverwriteKey,
01878                LPSTR szName,
01879                BOOL bOverwriteName,
01880                DWORD dwType,
01881                LPBYTE lpbData,
01882                DWORD dwSize,
01883                BOOL bLogForUninstall,
01884                BOOL bDnu)
01885 {
01886   HKEY    hkResult;
01887   DWORD   dwErr;
01888   BOOL    bNameExists;
01889   char    szBuf[MAX_BUF];
01890   char    szRootKey[MAX_BUF_TINY];
01891 
01892   /* We don't care if it failed or not because it could already exist. */
01893   CreateWinRegKey(hkRootKey, szKey, bLogForUninstall, bDnu);
01894 
01895   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult);
01896   if(dwErr == ERROR_SUCCESS)
01897   {
01898     bNameExists = WinRegNameExists(hkRootKey, szKey, szName);
01899     if((bNameExists == FALSE) ||
01900       ((bNameExists == TRUE) && (bOverwriteName == TRUE)))
01901     {
01902       dwErr = RegSetValueEx(hkResult, szName, 0, dwType, lpbData, dwSize);
01903       /* log the win reg command */
01904       if(bLogForUninstall &&
01905          ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey)))
01906       {
01907         if(ParseRegType(szBuf, &dwType))
01908         {
01909           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
01910           UpdateInstallLog(KEY_STORE_REG_STRING, szBuf, bDnu);
01911         }
01912         else
01913         {
01914           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
01915           UpdateInstallLog(KEY_STORE_REG_NUMBER, szBuf, bDnu);
01916         }
01917       }
01918     }
01919 
01920     RegCloseKey(hkResult);
01921   }
01922 }
01923 
01924 /* Name: AppendWinRegString
01925  *
01926  * Arguments:
01927  *
01928  * HKEY hkRootKey -- root key, e.g., HKEY_LOCAL_MACHINE
01929  * LPSTR szKey -- subkey
01930  * LPSTR szName -- value name
01931  * DWORD dwType -- value type, should be REG_SZ
01932  * LPBYTE lpbData -- value data
01933  * BYTE delimiter -- e.g., ':'. If 0, then don't apply delimiter
01934  * DWORD dwSize -- size of the value data
01935  * BOOL bLogForUninstall -- if true, update install log
01936  * BOOL bDnu -- what to update the install log with
01937  *
01938  * Description:
01939  *
01940  * This function should be called to append a string (REG_SZ) to the
01941  * string already stored in the specified key. If the key does not
01942  * exist, then simply store the key (ignoring the delimiter). If the
01943  * key does exist, read the current value, append the delimiter (if
01944  * not zero), and append the data passed in.
01945  *
01946  * Return Value: void
01947  *
01948  * Original Code: Clone of SetWinReg(), syd@netscape.com 6/11/2001
01949  *
01950  */
01951 
01952 void AppendWinReg(HKEY hkRootKey,
01953                LPSTR szKey,
01954                LPSTR szName,
01955                DWORD dwType,
01956                LPBYTE lpbData,
01957                BYTE delimiter,
01958                DWORD dwSize,
01959                BOOL bLogForUninstall,
01960                BOOL bDnu)
01961 {
01962   HKEY    hkResult;
01963   DWORD   dwErr;
01964   DWORD   dwDisp;
01965   BOOL    bKeyExists;
01966   BOOL    bNameExists;
01967   char    szBuf[MAX_BUF];
01968   char    szRootKey[MAX_BUF_TINY]; 
01969 
01970   bKeyExists  = WinRegKeyExists(hkRootKey, szKey);
01971   bNameExists = WinRegNameExists(hkRootKey, szKey, szName);
01972   dwErr       = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult);
01973 
01974   if (dwType != REG_SZ) // this function is void. How do we pass errors to caller?
01975       return;
01976 
01977   if(dwErr != ERROR_SUCCESS)
01978   {
01979     dwErr = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp);
01980     /* log the win reg command */
01981     if(bLogForUninstall &&
01982        ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey)))
01983     {
01984       wsprintf(szBuf, "%s\\%s []", szRootKey, szKey);
01985       UpdateInstallLog(KEY_CREATE_REG_KEY, szBuf, bDnu);
01986     }
01987   }
01988 
01989   if(dwErr == ERROR_SUCCESS)
01990   {
01991     if((bNameExists == FALSE))
01992     {
01993       /* first time, so just write it, ignoring the delimiter */
01994 
01995       dwErr = RegSetValueEx(hkResult, szName, 0, dwType, lpbData, dwSize);
01996       /* log the win reg command */
01997       if(bLogForUninstall &&
01998          ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey)))
01999       {
02000         if(ParseRegType(szBuf, &dwType))
02001         {
02002           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
02003           UpdateInstallLog(KEY_STORE_REG_STRING, szBuf, bDnu);
02004         }
02005         else
02006         {
02007           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
02008           UpdateInstallLog(KEY_STORE_REG_NUMBER, szBuf, bDnu);
02009         }
02010       }
02011     } else {
02012       /* already exists, so read the prrevious value, append the delimiter if 
02013          specified, append the new value, and rewrite the key */
02014       
02015       GetWinReg(hkRootKey, szKey, szName, szBuf, sizeof(szBuf));  // func is void, assume success
02016       if ( delimiter != 0 ) {
02017           char delim[ 2 ];
02018           delim[0] = delimiter;
02019           delim[1] = '\0';
02020           strcat( szBuf, delim );
02021       }
02022       strcat( szBuf, lpbData );
02023       RegCloseKey(hkResult);
02024       SetWinReg(hkRootKey, szKey, TRUE, szName, TRUE, dwType, szBuf, strlen( szBuf ) + 1, bLogForUninstall, bDnu);
02025       return;
02026     }
02027 
02028     RegCloseKey(hkResult);
02029   }
02030 }
02031 
02032 HRESULT ProcessWinReg(DWORD dwTiming, char *szSectionPrefix)
02033 {
02034   char    szBuf[MAX_BUF];
02035   char    szKey[MAX_BUF];
02036   char    szName[MAX_BUF];
02037   char    szShortName[MAX_BUF];
02038   char    szValue[MAX_BUF];
02039   char    szDecrypt[MAX_BUF];
02040   char    szOverwriteKey[MAX_BUF];
02041   char    szOverwriteName[MAX_BUF];
02042   char    szSection[MAX_BUF];
02043   HKEY    hRootKey;
02044   BOOL    bDone;
02045   BOOL    bDnu;
02046   BOOL    bOverwriteKey;
02047   BOOL    bOverwriteName;
02048   BOOL    bOSDetected;
02049   DWORD   dwIndex;
02050   DWORD   dwNameIndex = 1;
02051   DWORD   dwType;
02052   DWORD   dwSize;
02053   const DWORD   dwUpperLimit = 100;
02054   __int64 iiNum;
02055 
02056   dwIndex = 0;
02057   BuildNumberedString(dwIndex, szSectionPrefix, "Windows Registry", szSection, sizeof(szSection));
02058   GetPrivateProfileString(szSection, "Root Key", "", szBuf, sizeof(szBuf), szFileIniConfig);
02059   while(*szBuf != '\0')
02060   {
02061     if(TimingCheck(dwTiming, szSection, szFileIniConfig) && MeetCondition(szSection))
02062     {
02063       hRootKey = ParseRootKey(szBuf);
02064 
02065       GetPrivateProfileString(szSection, "Key",                 "", szBuf,           sizeof(szBuf),          szFileIniConfig);
02066       GetPrivateProfileString(szSection, "Decrypt Key",         "", szDecrypt,       sizeof(szDecrypt),      szFileIniConfig);
02067       GetPrivateProfileString(szSection, "Overwrite Key",       "", szOverwriteKey,  sizeof(szOverwriteKey), szFileIniConfig);
02068       ZeroMemory(szKey, sizeof(szKey));
02069       if(lstrcmpi(szDecrypt, "TRUE") == 0)
02070         DecryptString(szKey, szBuf);
02071       else
02072         lstrcpy(szKey, szBuf);
02073 
02074       if(lstrcmpi(szOverwriteKey, "FALSE") == 0)
02075         bOverwriteKey = FALSE;
02076       else
02077         bOverwriteKey = TRUE;
02078 
02079       GetPrivateProfileString(szSection, "Name",                "", szBuf,           sizeof(szBuf),           szFileIniConfig);
02080       GetPrivateProfileString(szSection, "Decrypt Name",        "", szDecrypt,       sizeof(szDecrypt),       szFileIniConfig);
02081       GetPrivateProfileString(szSection, "Overwrite Name",      "", szOverwriteName, sizeof(szOverwriteName), szFileIniConfig);
02082       ZeroMemory(szName, sizeof(szName));
02083       if(lstrcmpi(szDecrypt, "TRUE") == 0)
02084         DecryptString(szName, szBuf);
02085       else
02086         lstrcpy(szName, szBuf);
02087 
02088       if(lstrcmpi(szOverwriteName, "ENUMERATE") == 0)
02089       {
02090         bOverwriteName = FALSE;
02091         lstrcpy(szShortName, szName);
02092         wsprintf(szName, "%s%02d", szShortName, dwNameIndex++);
02093 
02094         bDone = FALSE;
02095         while(!bDone && (dwNameIndex < dwUpperLimit))
02096         {
02097           if(WinRegNameExists(hRootKey, szKey, szName))
02098           {
02099             GetWinReg(hRootKey, szKey, szName, szBuf, sizeof(szBuf));
02100             if(lstrcmpi(szBuf, sgProduct.szAppPath) == 0)
02101               bDone = TRUE;
02102             else
02103               wsprintf(szName, "%s%02d", szShortName, dwNameIndex++);
02104           }
02105           else
02106             bDone = TRUE;
02107         }
02108         if(dwNameIndex >= dwUpperLimit)
02109           return FO_ERROR_INCR_EXCEEDS_LIMIT;
02110       }
02111       else if(lstrcmpi(szOverwriteName, "FALSE") == 0)
02112         bOverwriteName = FALSE;
02113       else
02114         bOverwriteName = TRUE;
02115 
02116       GetPrivateProfileString(szSection, "Name Value",          "", szBuf,           sizeof(szBuf), szFileIniConfig);
02117       GetPrivateProfileString(szSection, "Decrypt Name Value",  "", szDecrypt,       sizeof(szDecrypt), szFileIniConfig);
02118       ZeroMemory(szValue, sizeof(szValue));
02119       if(lstrcmpi(szDecrypt, "TRUE") == 0)
02120         DecryptString(szValue, szBuf);
02121       else
02122         lstrcpy(szValue, szBuf);
02123 
02124       GetPrivateProfileString(szSection, "Size",                "", szBuf,           sizeof(szBuf), szFileIniConfig);
02125       if(*szBuf != '\0')
02126         dwSize = atoi(szBuf);
02127       else
02128         dwSize = 0;
02129 
02130       GetPrivateProfileString(szSection,
02131                               "Do Not Uninstall",
02132                               "",
02133                               szBuf,
02134                               sizeof(szBuf),
02135                               szFileIniConfig);
02136 
02137       if(lstrcmpi(szBuf, "TRUE") == 0)
02138         bDnu = TRUE;
02139       else
02140         bDnu = FALSE;
02141 
02142       /* Read the OS key to see if there are restrictions on which OS to
02143        * the Windows registry key for */
02144       GetPrivateProfileString(szSection,
02145                               "OS",
02146                               "",
02147                               szBuf,
02148                               sizeof(szBuf),
02149                               szFileIniConfig);
02150       /* If there is no OS key value set, then assume all OS is valid.
02151        * If there are any, then compare against the global OS value to
02152        * make sure there's a match. */
02153       bOSDetected = TRUE;
02154       if( (*szBuf != '\0') && ((gSystemInfo.dwOSType & ParseOSType(szBuf)) == 0) )
02155         bOSDetected = FALSE;
02156 
02157       if(bOSDetected)
02158       {
02159         ZeroMemory(szBuf, sizeof(szBuf));
02160         GetPrivateProfileString(szSection,
02161                                 "Type",
02162                                 "",
02163                                 szBuf,
02164                                 sizeof(szBuf),
02165                                 szFileIniConfig);
02166 
02167         if(ParseRegType(szBuf, &dwType))
02168         {
02169           /* create/set windows registry key here (string value)! */
02170           SetWinReg(hRootKey, szKey, bOverwriteKey, szName, bOverwriteName,
02171                   dwType, (CONST LPBYTE)szValue, lstrlen(szValue), TRUE, bDnu);
02172         }
02173         else
02174         {
02175           iiNum = _atoi64(szValue);
02176           /* create/set windows registry key here (binary/dword value)! */
02177           SetWinReg(hRootKey, szKey, bOverwriteKey, szName, bOverwriteName,
02178                   dwType, (CONST LPBYTE)&iiNum, dwSize, TRUE, bDnu);
02179         }
02180       }
02181     }
02182 
02183     ++dwIndex;
02184     BuildNumberedString(dwIndex, szSectionPrefix, "Windows Registry", szSection, sizeof(szSection));
02185     GetPrivateProfileString(szSection, "Root Key", "", szBuf, sizeof(szBuf), szFileIniConfig);
02186   }
02187   return(FO_SUCCESS);
02188 }
02189 
02190 HRESULT ProcessProgramFolder(DWORD dwTiming, char *szSectionPrefix)
02191 {
02192   DWORD dwIndex0;
02193   DWORD dwIndex1;
02194   DWORD dwIconId;
02195   DWORD dwRestrictedAccess;
02196   char  szIndex1[MAX_BUF];
02197   char  szBuf[MAX_BUF];
02198   char  szSection0[MAX_BUF];
02199   char  szSection1[MAX_BUF];
02200   char  szProgramFolder[MAX_BUF];
02201   char  szFile[MAX_BUF];
02202   char  szArguments[MAX_BUF];
02203   char  szWorkingDir[MAX_BUF];
02204   char  szDescription[MAX_BUF];
02205   char  szIconPath[MAX_BUF];
02206 
02207   dwIndex0 = 0;
02208   BuildNumberedString(dwIndex0, szSectionPrefix, "Program Folder", szSection0, sizeof(szSection0));
02209   GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig);
02210   while(*szBuf != '\0')
02211   {
02212     if(TimingCheck(dwTiming, szSection0, szFileIniConfig))
02213     {
02214       DecryptString(szProgramFolder, szBuf);
02215 
02216       dwIndex1 = 0;
02217       itoa(dwIndex1, szIndex1, 10);
02218       lstrcpy(szSection1, szSection0);
02219       lstrcat(szSection1, "-Shortcut");
02220       lstrcat(szSection1, szIndex1);
02221       GetPrivateProfileString(szSection1, "File", "", szBuf, sizeof(szBuf), szFileIniConfig);
02222       while(*szBuf != '\0')
02223       {
02224         DecryptString(szFile, szBuf);
02225         GetPrivateProfileString(szSection1, "Arguments",    "", szBuf, sizeof(szBuf), szFileIniConfig);
02226         DecryptString(szArguments, szBuf);
02227         GetPrivateProfileString(szSection1, "Working Dir",  "", szBuf, sizeof(szBuf), szFileIniConfig);
02228         DecryptString(szWorkingDir, szBuf);
02229         GetPrivateProfileString(szSection1, "Description",  "", szBuf, sizeof(szBuf), szFileIniConfig);
02230         DecryptString(szDescription, szBuf);
02231         GetPrivateProfileString(szSection1, "Icon Path",    "", szBuf, sizeof(szBuf), szFileIniConfig);
02232         DecryptString(szIconPath, szBuf);
02233         GetPrivateProfileString(szSection1, "Icon Id",      "", szBuf, sizeof(szBuf), szFileIniConfig);
02234         if(*szBuf != '\0')
02235           dwIconId = atol(szBuf);
02236         else
02237           dwIconId = 0;
02238 
02239         GetPrivateProfileString(szSection1, "Restricted Access",    "", szBuf, sizeof(szBuf), szFileIniConfig);
02240         dwRestrictedAccess = ParseRestrictedAccessKey(szBuf);
02241         if((dwRestrictedAccess == RA_IGNORE) ||
02242           ((dwRestrictedAccess == RA_ONLY_RESTRICTED) && gbRestrictedAccess) ||
02243           ((dwRestrictedAccess == RA_ONLY_NONRESTRICTED) && !gbRestrictedAccess))
02244         {
02245           CreateALink(szFile, szProgramFolder, szDescription, szWorkingDir, szArguments, szIconPath, dwIconId);
02246           lstrcpy(szBuf, szProgramFolder);
02247           AppendBackSlash(szBuf, sizeof(szBuf));
02248           lstrcat(szBuf, szDescription);
02249           UpdateInstallLog(KEY_WINDOWS_SHORTCUT, szBuf, FALSE);
02250         }
02251 
02252         ++dwIndex1;
02253         itoa(dwIndex1, szIndex1, 10);
02254         lstrcpy(szSection1, szSection0);
02255         lstrcat(szSection1, "-Shortcut");
02256         lstrcat(szSection1, szIndex1);
02257         GetPrivateProfileString(szSection1, "File", "", szBuf, sizeof(szBuf), szFileIniConfig);
02258       }
02259     }
02260 
02261     ++dwIndex0;
02262     BuildNumberedString(dwIndex0, szSectionPrefix, "Program Folder", szSection0, sizeof(szSection0));
02263     GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig);
02264   }
02265   return(FO_SUCCESS);
02266 }
02267 
02268 HRESULT ProcessProgramFolderShowCmd()
02269 {
02270   DWORD dwIndex0;
02271   int   iShowFolder;
02272   char  szBuf[MAX_BUF];
02273   char  szSection0[MAX_BUF];
02274   char  szProgramFolder[MAX_BUF];
02275 
02276   dwIndex0 = 0;
02277   BuildNumberedString(dwIndex0, NULL, "Program Folder", szSection0, sizeof(szSection0));
02278   GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig);
02279   while(*szBuf != '\0')
02280   {
02281     DecryptString(szProgramFolder, szBuf);
02282     GetPrivateProfileString(szSection0, "Show Folder", "", szBuf, sizeof(szBuf), szFileIniConfig);
02283 
02284     if(strcmpi(szBuf, "HIDE") == 0)
02285       iShowFolder = SW_HIDE;
02286     else if(strcmpi(szBuf, "MAXIMIZE") == 0)
02287       iShowFolder = SW_MAXIMIZE;
02288     else if(strcmpi(szBuf, "MINIMIZE") == 0)
02289       iShowFolder = SW_MINIMIZE;
02290     else if(strcmpi(szBuf, "RESTORE") == 0)
02291       iShowFolder = SW_RESTORE;
02292     else if(strcmpi(szBuf, "SHOW") == 0)
02293       iShowFolder = SW_SHOW;
02294     else if(strcmpi(szBuf, "SHOWMAXIMIZED") == 0)
02295       iShowFolder = SW_SHOWMAXIMIZED;
02296     else if(strcmpi(szBuf, "SHOWMINIMIZED") == 0)
02297       iShowFolder = SW_SHOWMINIMIZED;
02298     else if(strcmpi(szBuf, "SHOWMINNOACTIVE") == 0)
02299       iShowFolder = SW_SHOWMINNOACTIVE;
02300     else if(strcmpi(szBuf, "SHOWNA") == 0)
02301       iShowFolder = SW_SHOWNA;
02302     else if(strcmpi(szBuf, "SHOWNOACTIVATE") == 0)
02303       iShowFolder = SW_SHOWNOACTIVATE;
02304     else if(strcmpi(szBuf, "SHOWNORMAL") == 0)
02305       iShowFolder = SW_SHOWNORMAL;
02306 
02307     if(iShowFolder != SW_HIDE)
02308       if(sgProduct.mode != SILENT)
02309         WinSpawn(szProgramFolder, NULL, NULL, iShowFolder, WS_WAIT);
02310 
02311     ++dwIndex0;
02312     BuildNumberedString(dwIndex0, NULL, "Program Folder", szSection0, sizeof(szSection0));
02313     GetPrivateProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf), szFileIniConfig);
02314   }
02315   return(FO_SUCCESS);
02316 }
02317 
02318 HRESULT ProcessCreateCustomFiles(DWORD dwTiming)
02319 {
02320   DWORD dwCompIndex;
02321   DWORD dwFileIndex;
02322   DWORD dwSectIndex;
02323   DWORD dwKVIndex;
02324   siC   *siCObject = NULL;
02325   char  szBufTiny[MAX_BUF_TINY];
02326   char  szSection[MAX_BUF_TINY];
02327   char  szBuf[MAX_BUF];
02328   char  szFileName[MAX_BUF];
02329   char  szDefinedSection[MAX_BUF]; 
02330   char  szDefinedKey[MAX_BUF]; 
02331   char  szDefinedValue[MAX_BUF];
02332 
02333   dwCompIndex   = 0;
02334   siCObject = SiCNodeGetObject(dwCompIndex, TRUE, AC_ALL);
02335 
02336   while(siCObject)
02337   {
02338     dwFileIndex   = 0;
02339     wsprintf(szSection,"%s-Configuration File%d",siCObject->szReferenceName,dwFileIndex);
02340     siCObject = SiCNodeGetObject(++dwCompIndex, TRUE, AC_ALL);
02341     if(TimingCheck(dwTiming, szSection, szFileIniConfig) == FALSE)
02342     {
02343       continue;
02344     }
02345 
02346     GetPrivateProfileString(szSection, "FileName", "", szBuf, sizeof(szBuf), szFileIniConfig);
02347     while (*szBuf != '\0')
02348     {
02349       DecryptString(szFileName, szBuf);
02350       if(FileExists(szFileName))
02351       {
02352         DeleteFile(szFileName);
02353       }
02354 
02355       /* TO DO - Support a File Type for something other than .ini */
02356       dwSectIndex = 0;
02357       wsprintf(szBufTiny, "Section%d",dwSectIndex);
02358       GetPrivateProfileString(szSection, szBufTiny, "", szDefinedSection, sizeof(szDefinedSection), szFileIniConfig);
02359       while(*szDefinedSection != '\0')
02360       {  
02361         dwKVIndex =0;
02362         wsprintf(szBufTiny,"Section%d-Key%d",dwSectIndex,dwKVIndex);
02363         GetPrivateProfileString(szSection, szBufTiny, "", szDefinedKey, sizeof(szDefinedKey), szFileIniConfig);
02364         while(*szDefinedKey != '\0')
02365         {
02366           wsprintf(szBufTiny,"Section%d-Value%d",dwSectIndex,dwKVIndex);
02367           GetPrivateProfileString(szSection, szBufTiny, "", szBuf, sizeof(szBuf), szFileIniConfig);
02368           DecryptString(szDefinedValue, szBuf);
02369           if(WritePrivateProfileString(szDefinedSection, szDefinedKey, szDefinedValue, szFileName) == 0)
02370           {
02371             char szEWPPS[MAX_BUF];
02372             char szBuf[MAX_BUF];
02373             char szBuf2[MAX_BUF];
02374             if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall))
02375             {
02376               wsprintf(szBuf, "%s\n    [%s]\n    %s=%s", szFileName, szDefinedSection, szDefinedKey, szDefinedValue);
02377               wsprintf(szBuf2, szEWPPS, szBuf);
02378               PrintError(szBuf2, ERROR_CODE_SHOW);
02379             }
02380             return(FO_ERROR_WRITE);
02381           }
02382           wsprintf(szBufTiny,"Section%d-Key%d",dwSectIndex,++dwKVIndex);
02383           GetPrivateProfileString(szSection, szBufTiny, "", szDefinedKey, sizeof(szDefinedKey), szFileIniConfig);
02384         } /* while(*szDefinedKey != '\0')  */
02385 
02386         wsprintf(szBufTiny, "Section%d",++dwSectIndex);
02387         GetPrivateProfileString(szSection, szBufTiny, "", szDefinedSection, sizeof(szDefinedSection), szFileIniConfig);
02388       } /*       while(*szDefinedSection != '\0') */
02389 
02390       wsprintf(szSection,"%s-Configuration File%d",siCObject->szReferenceName,++dwFileIndex);
02391       GetPrivateProfileString(szSection, "FileName", "", szBuf, sizeof(szBuf), szFileIniConfig);
02392     } /* while(*szBuf != '\0') */
02393   } /* while(siCObject) */
02394   return (FO_SUCCESS);
02395 }
02396