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 the GNU General Public License Version 2 or later (the "GPL"), or
00029  * 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)
00053 {
00054   char szBuf[MAX_BUF_TINY];
00055 
00056   GetConfigIniProfileString(szSection, "Timing", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Condition", "", szBuf, sizeof(szBuf));
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     GetConfigIniProfileString("General", "Default AppID", "", szBuf, sizeof(szBuf));
00146     if(strcmp(szBuf, sgProduct.szAppID) == 0)
00147       bResult = TRUE;
00148   }
00149 
00150   if(bNegateTheResult)
00151     return !bResult;
00152 
00153   return bResult;
00154 }
00155 
00156 char *BuildNumberedString(DWORD dwIndex, char *szInputStringPrefix, char *szInputString, char *szOutBuf, DWORD dwOutBufSize)
00157 {
00158   if((szInputStringPrefix) && (*szInputStringPrefix != '\0'))
00159     wsprintf(szOutBuf, "%s-%s%d", szInputStringPrefix, szInputString, dwIndex);
00160   else
00161     wsprintf(szOutBuf, "%s%d", szInputString, dwIndex);
00162 
00163   return(szOutBuf);
00164 }
00165 
00166 void GetUserAgentShort(char *szUserAgent, char *szOutUAShort, DWORD dwOutUAShortSize)
00167 {
00168   char *ptrFirstSpace = NULL;
00169 
00170   ZeroMemory(szOutUAShort, dwOutUAShortSize);
00171   if((szUserAgent == NULL) || (*szUserAgent == '\0'))
00172     return;
00173 
00174   ptrFirstSpace = strstr(szUserAgent, " ");
00175   if(ptrFirstSpace != NULL)
00176   {
00177     *ptrFirstSpace = '\0';
00178     lstrcpy(szOutUAShort, szUserAgent);
00179     *ptrFirstSpace = ' ';
00180   }
00181 }
00182 
00183 DWORD GetWinRegSubKeyProductPath(HKEY hkRootKey, char *szInKey, char *szReturnSubKey, DWORD dwReturnSubKeySize, char *szInSubSubKey, char *szInName, char *szCompare, char *szInCurrentVersion)
00184 {
00185   char      *szRv = NULL;
00186   char      szKey[MAX_BUF];
00187   char      szBuf[MAX_BUF];
00188   HKEY      hkHandle;
00189   DWORD     dwIndex;
00190   DWORD     dwBufSize;
00191   DWORD     dwTotalSubKeys;
00192   DWORD     dwTotalValues;
00193   FILETIME  ftLastWriteFileTime;
00194   BOOL      bFoundSubKey;
00195 
00196   bFoundSubKey = FALSE;
00197 
00198   if(RegOpenKeyEx(hkRootKey, szInKey, 0, KEY_READ, &hkHandle) != ERROR_SUCCESS)
00199   {
00200     *szReturnSubKey = '\0';
00201     return(0);
00202   }
00203 
00204   dwTotalSubKeys = 0;
00205   dwTotalValues  = 0;
00206   RegQueryInfoKey(hkHandle, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL);
00207   for(dwIndex = 0; dwIndex < dwTotalSubKeys; dwIndex++)
00208   {
00209     dwBufSize = dwReturnSubKeySize;
00210     if(RegEnumKeyEx(hkHandle, dwIndex, szReturnSubKey, &dwBufSize, NULL, NULL, NULL, &ftLastWriteFileTime) == ERROR_SUCCESS)
00211     {
00212       if(  (*szInCurrentVersion != '\0') && (lstrcmpi(szInCurrentVersion, szReturnSubKey) != 0)  )
00213       {
00214         /* The key found is not the CurrentVersion (current UserAgent), so we can return it to be deleted.
00215          * We don't want to return the SubKey that is the same as the CurrentVersion because it might
00216          * have just been created by the current installation process.  So deleting it would be a
00217          * "Bad Thing" (TM).
00218          *
00219          * If it was not created by the current installation process, then it'll be left
00220          * around which is better than deleting something we will need later. To make sure this case is
00221          * not encountered, CleanupPreviousVersionRegKeys() should be called at the *end* of the
00222          * installation process (at least after all the .xpi files have been processed). */
00223         if(szInSubSubKey && (*szInSubSubKey != '\0'))
00224           wsprintf(szKey, "%s\\%s\\%s", szInKey, szReturnSubKey, szInSubSubKey);
00225         else
00226           wsprintf(szKey, "%s\\%s", szInKey, szReturnSubKey);
00227 
00228         GetWinReg(hkRootKey, szKey, szInName, szBuf, sizeof(szBuf));
00229         AppendBackSlash(szBuf, sizeof(szBuf));
00230         if(lstrcmpi(szBuf, szCompare) == 0)
00231         {
00232           bFoundSubKey = TRUE;
00233           /* found one subkey. break out of the for() loop */
00234           break;
00235         }
00236       }
00237     }
00238   }
00239 
00240   RegCloseKey(hkHandle);
00241   if(!bFoundSubKey)
00242     *szReturnSubKey = '\0';
00243   return(dwTotalSubKeys);
00244 }
00245 
00246 void CleanupPreviousVersionRegKeys(void)
00247 {
00248   DWORD dwIndex = 0;
00249   DWORD dwSubKeyCount;
00250   char  szBufTiny[MAX_BUF_TINY];
00251   char  szKeyRoot[MAX_BUF_TINY];
00252   char  szCurrentVersion[MAX_BUF_TINY];
00253   char  szUAShort[MAX_BUF_TINY];
00254   char  szRvSubKey[MAX_PATH + 1];
00255   char  szPath[MAX_BUF];
00256   char  szKey[MAX_BUF];
00257   char  szCleanupProduct[MAX_BUF];
00258   HKEY  hkeyRoot;
00259   char  szSubSubKey[] = "Main";
00260   char  szName[] = "Install Directory";
00261   char  szWRMSUninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
00262   char  szSection[] = "Cleanup Previous Product RegKeys";
00263 
00264   lstrcpy(szPath, sgProduct.szPath);
00265   if(*sgProduct.szSubPath != '\0')
00266   {
00267     AppendBackSlash(szPath, sizeof(szPath));
00268     lstrcat(szPath, sgProduct.szSubPath);
00269   }
00270   AppendBackSlash(szPath, sizeof(szPath));
00271 
00272   wsprintf(szBufTiny, "Product Reg Key%d", dwIndex);        
00273   GetConfigIniProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey));
00274 
00275   while(*szKey != '\0')
00276   {
00277     wsprintf(szBufTiny, "Reg Key Root%d",dwIndex);
00278     GetConfigIniProfileString(szSection, szBufTiny, "", szKeyRoot, sizeof(szKeyRoot));
00279     hkeyRoot = ParseRootKey(szKeyRoot);
00280 
00281     wsprintf(szBufTiny, "Product Name%d", dwIndex);        
00282     GetConfigIniProfileString(szSection, szBufTiny, "", szCleanupProduct, sizeof(szCleanupProduct));
00283     // something is wrong, they didn't give a product name.
00284     if(*szCleanupProduct == '\0')
00285       return;
00286 
00287     wsprintf(szBufTiny, "Current Version%d", dwIndex);        
00288     GetConfigIniProfileString(szSection, szBufTiny, "", szCurrentVersion, sizeof(szCurrentVersion));
00289 
00290     do
00291     {
00292       // if the current version is not found, we'll get null in szCurrentVersion and GetWinRegSubKeyProductPath() will do the right thing
00293       dwSubKeyCount = GetWinRegSubKeyProductPath(hkeyRoot, szKey, szRvSubKey, sizeof(szRvSubKey), szSubSubKey, szName, szPath, szCurrentVersion);
00294          
00295       if(*szRvSubKey != '\0')
00296       {
00297         if(dwSubKeyCount > 1)
00298         {
00299           AppendBackSlash(szKey, sizeof(szKey));
00300           lstrcat(szKey, szRvSubKey);
00301         }
00302         DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00303 
00304         GetUserAgentShort(szRvSubKey, szUAShort, sizeof(szUAShort));
00305         if(*szUAShort != '\0')
00306         {
00307           /* delete uninstall key that contains product name and its user agent in parenthesis, for
00308            * example:
00309            *     Mozilla (0.8)
00310            */
00311           wsprintf(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s (%s)", szCleanupProduct, szUAShort);
00312           DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00313 
00314           /* delete uninstall key that contains product name and its user agent not in parenthesis,
00315            * for example:
00316            *     Mozilla 0.8
00317            */
00318           wsprintf(szKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s %s", szCleanupProduct, szUAShort);
00319           DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00320 
00321           /* delete installed product that contains product name and its user agent not in parenthesis,
00322            * for example:
00323            *     Mozilla 0.8
00324            */
00325           wsprintf(szKey, "Software\\Mozilla\\%s %s", szCleanupProduct, szUAShort);
00326           DeleteWinRegKey(hkeyRoot, szKey, TRUE);
00327 
00328           /* We are not looking to delete just the product name key, for example:
00329            *     Mozilla
00330            *
00331            * because it might have just been created by the current installation process, so
00332            * deleting this would be a "Bad Thing" (TM).  Besides, we shouldn't be deleting the
00333            * CurrentVersion key that might have just gotten created because GetWinRegSubKeyProductPath()
00334            * will not return the CurrentVersion key.
00335            */
00336         }
00337         // the szKey was stepped on.  Reget it.
00338         wsprintf(szBufTiny, "Product Reg Key%d", dwIndex);        
00339         GetConfigIniProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey));
00340       }
00341     }  while (*szRvSubKey != '\0');
00342     wsprintf(szBufTiny, "Product Reg Key%d", ++dwIndex);        
00343     GetConfigIniProfileString(szSection, szBufTiny, "", szKey, sizeof(szKey));
00344   } 
00345 
00346 }
00347 
00348 void ProcessFileOps(DWORD dwTiming, char *szSectionPrefix)
00349 {
00350   if(sgProduct.bInstallFiles)
00351   {
00352     ProcessUncompressFile(dwTiming, szSectionPrefix);
00353     ProcessCreateDirectory(dwTiming, szSectionPrefix);
00354     ProcessMoveFile(dwTiming, szSectionPrefix);
00355     ProcessCopyFile(dwTiming, szSectionPrefix);
00356     ProcessCopyFileSequential(dwTiming, szSectionPrefix);
00357     ProcessSelfRegisterFile(dwTiming, szSectionPrefix);
00358     ProcessDeleteFile(dwTiming, szSectionPrefix);
00359     ProcessRemoveDirectory(dwTiming, szSectionPrefix);
00360     if(!gbIgnoreRunAppX)
00361       ProcessRunApp(dwTiming, szSectionPrefix);
00362   }
00363 
00364   // This is the only operation we do if we are not installing files
00365   ProcessWinReg(dwTiming, szSectionPrefix);
00366 
00367   if(sgProduct.bInstallFiles)
00368   {
00369     ProcessProgramFolder(dwTiming, szSectionPrefix);
00370     ProcessSetVersionRegistry(dwTiming, szSectionPrefix);
00371   }
00372 }
00373 
00374 void ProcessFileOpsForSelectedComponents(DWORD dwTiming)
00375 {
00376   DWORD dwIndex0;
00377   siC   *siCObject = NULL;
00378 
00379   dwIndex0  = 0;
00380   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00381   while(siCObject)
00382   {
00383     if(siCObject->dwAttributes & SIC_SELECTED)
00384       /* Since the archive is selected, we need to process the file ops here */
00385       ProcessFileOps(dwTiming, siCObject->szReferenceName);
00386 
00387     ++dwIndex0;
00388     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00389   } /* while(siCObject) */
00390 }
00391 
00392 void ProcessFileOpsForAll(DWORD dwTiming)
00393 {
00394   ProcessFileOps(dwTiming, NULL);
00395   if(sgProduct.bInstallFiles)
00396   {
00397     ProcessFileOpsForSelectedComponents(dwTiming);
00398     ProcessCreateCustomFiles(dwTiming);
00399   }
00400 }
00401 
00402 int VerifyArchive(LPSTR szArchive)
00403 {
00404   void *vZip;
00405   int  iTestRv;
00406 
00407   /* Check for the existance of the from (source) file */
00408   if(!FileExists(szArchive))
00409     return(FO_ERROR_FILE_NOT_FOUND);
00410 
00411   if((iTestRv = ZIP_OpenArchive(szArchive, &vZip)) == ZIP_OK)
00412   {
00413     /* 1st parameter should be NULL or it will fail */
00414     /* It indicates extract the entire archive */
00415     iTestRv = ZIP_TestArchive(vZip);
00416     ZIP_CloseArchive(&vZip);
00417   }
00418   return(iTestRv);
00419 }
00420 
00421 HRESULT ProcessSetVersionRegistry(DWORD dwTiming, char *szSectionPrefix)
00422 {
00423   DWORD   dwIndex;
00424   BOOL    bIsDirectory;
00425   char    szBuf[MAX_BUF];
00426   char    szSection[MAX_BUF_TINY];
00427   char    szRegistryKey[MAX_BUF];
00428   char    szPath[MAX_BUF];
00429   char    szVersion[MAX_BUF_TINY];
00430 
00431   dwIndex = 0;
00432   BuildNumberedString(dwIndex, szSectionPrefix, "Version Registry", szSection, sizeof(szSection));
00433   GetConfigIniProfileString(szSection, "Registry Key", "", szRegistryKey, sizeof(szRegistryKey));
00434   while(*szRegistryKey != '\0')
00435   {
00436     if(TimingCheck(dwTiming, szSection))
00437     {
00438       GetConfigIniProfileString(szSection, "Version", "", szVersion, sizeof(szVersion));
00439       GetConfigIniProfileString(szSection, "Path",    "", szBuf,     sizeof(szBuf));
00440       DecryptString(szPath, szBuf);
00441       if(FileExists(szPath) & FILE_ATTRIBUTE_DIRECTORY)
00442         bIsDirectory = TRUE;
00443       else
00444         bIsDirectory = FALSE;
00445 
00446       lstrcpy(szBuf, sgProduct.szPath);
00447       if(sgProduct.szSubPath != '\0')
00448       {
00449         AppendBackSlash(szBuf, sizeof(szBuf));
00450         lstrcat(szBuf, sgProduct.szSubPath);
00451       }
00452 
00453       VR_CreateRegistry(VR_DEFAULT_PRODUCT_NAME, szBuf, NULL);
00454       VR_Install(szRegistryKey, szPath, szVersion, bIsDirectory);
00455       VR_Close();
00456     }
00457 
00458     ++dwIndex;
00459     BuildNumberedString(dwIndex, szSectionPrefix, "Version Registry", szSection, sizeof(szSection));
00460     GetConfigIniProfileString(szSection, "Registry Key", "", szRegistryKey, sizeof(szRegistryKey));
00461   }
00462   return(FO_SUCCESS);
00463 }
00464 
00465 HRESULT FileUncompress(LPSTR szFrom, LPSTR szTo)
00466 {
00467   char  szBuf[MAX_BUF];
00468   DWORD dwReturn;
00469   void  *vZip;
00470 
00471   dwReturn = FO_SUCCESS;
00472   /* Check for the existance of the from (source) file */
00473   if(!FileExists(szFrom))
00474     return(FO_ERROR_FILE_NOT_FOUND);
00475 
00476   /* Check for the existance of the to (destination) path */
00477   dwReturn = FileExists(szTo);
00478   if(dwReturn && !(dwReturn & FILE_ATTRIBUTE_DIRECTORY))
00479   {
00480     /* found a file with the same name as the destination path */
00481     return(FO_ERROR_DESTINATION_CONFLICT);
00482   }
00483   else if(!dwReturn)
00484   {
00485     lstrcpy(szBuf, szTo);
00486     AppendBackSlash(szBuf, sizeof(szBuf));
00487     CreateDirectoriesAll(szBuf, DO_NOT_ADD_TO_UNINSTALL_LOG);
00488   }
00489 
00490   GetCurrentDirectory(MAX_BUF, szBuf);
00491   if(SetCurrentDirectory(szTo) == FALSE)
00492     return(FO_ERROR_CHANGE_DIR);
00493 
00494   if((dwReturn = ZIP_OpenArchive(szFrom, &vZip)) != ZIP_OK)
00495     return(dwReturn);
00496 
00497   /* 1st parameter should be NULL or it will fail */
00498   /* It indicates extract the entire archive */
00499   dwReturn = ExtractDirEntries(NULL, vZip);
00500   ZIP_CloseArchive(&vZip);
00501 
00502   if(SetCurrentDirectory(szBuf) == FALSE)
00503     return(FO_ERROR_CHANGE_DIR);
00504 
00505   return(dwReturn);
00506 }
00507 
00508 HRESULT ProcessXpcomFile()
00509 {
00510   char szSource[MAX_BUF];
00511   char szDestination[MAX_BUF];
00512   DWORD dwErr;
00513 
00514   if((dwErr = FileUncompress(siCFXpcomFile.szSource, siCFXpcomFile.szDestination)) != FO_SUCCESS)
00515   {
00516     char szMsg[MAX_BUF];
00517     char szErrorString[MAX_BUF];
00518 
00519     if(*siCFXpcomFile.szMessage != '\0')
00520       ShowMessage(siCFXpcomFile.szMessage, FALSE);
00521 
00522     LogISProcessXpcomFile(LIS_FAILURE, dwErr);
00523     GetConfigIniProfileString("Strings", "Error File Uncompress", "", szErrorString, sizeof(szErrorString));
00524     wsprintf(szMsg, szErrorString, siCFXpcomFile.szSource, dwErr);
00525     PrintError(szMsg, ERROR_CODE_HIDE);
00526     return(dwErr);
00527   }
00528   LogISProcessXpcomFile(LIS_SUCCESS, dwErr);
00529 
00530   /* copy msvcrt.dll and msvcirt.dll to the bin of the Xpcom temp dir:
00531    *   (c:\temp\Xpcom.ns\bin)
00532    * This is incase these files do not exist on the system */
00533   lstrcpy(szSource, siCFXpcomFile.szDestination);
00534   AppendBackSlash(szSource, sizeof(szSource));
00535   lstrcat(szSource, "ms*.dll");
00536 
00537   lstrcpy(szDestination, siCFXpcomFile.szDestination);
00538   AppendBackSlash(szDestination, sizeof(szDestination));
00539 
00540   lstrcat(szDestination, "bin");
00541 
00542   FileCopy(szSource, szDestination, TRUE, FALSE);
00543   return(FO_SUCCESS);
00544 }
00545 
00546 void CleanupXpcomFile()
00547 {
00548   /* If xpcom file is not used (gre is used instead), then
00549    * just return */
00550   if(siCFXpcomFile.bStatus != STATUS_ENABLED)
00551     return;
00552 
00553   if(siCFXpcomFile.bCleanup == TRUE)
00554     DirectoryRemove(siCFXpcomFile.szDestination, TRUE);
00555 
00556   return;
00557 }
00558 
00559 #define SETUP_STATE_REG_KEY "Software\\%s\\%s\\%s\\Setup"
00560 
00561 HRESULT CleanupArgsRegistry()
00562 {
00563   char  szKey[MAX_BUF];
00564 
00565   wsprintf(szKey, SETUP_STATE_REG_KEY, sgProduct.szCompanyName, sgProduct.szProductNameInternal,
00566     sgProduct.szUserAgent);
00567   DeleteWinRegValue(HKEY_CURRENT_USER, szKey, "browserargs");
00568   return(FO_SUCCESS);
00569 }
00570 
00571 HRESULT ProcessUncompressFile(DWORD dwTiming, char *szSectionPrefix)
00572 {
00573   DWORD   dwIndex;
00574   BOOL    bOnlyIfExists;
00575   char    szBuf[MAX_BUF];
00576   char    szSection[MAX_BUF];
00577   char    szSource[MAX_BUF];
00578   char    szDestination[MAX_BUF];
00579 
00580   dwIndex = 0;
00581   BuildNumberedString(dwIndex, szSectionPrefix, "Uncompress File", szSection, sizeof(szSection));
00582   GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
00583   while(*szBuf != '\0')
00584   {
00585     if(TimingCheck(dwTiming, szSection))
00586     {
00587       DecryptString(szSource, szBuf);
00588       GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
00589       DecryptString(szDestination, szBuf);
00590       GetConfigIniProfileString(szSection, "Only If Exists", "", szBuf, sizeof(szBuf));
00591       if(lstrcmpi(szBuf, "TRUE") == 0)
00592         bOnlyIfExists = TRUE;
00593       else
00594         bOnlyIfExists = FALSE;
00595 
00596       if((!bOnlyIfExists) || (bOnlyIfExists && FileExists(szDestination)))
00597       {
00598         DWORD dwErr;
00599 
00600         GetConfigIniProfileString(szSection, "Message", "", szBuf, sizeof(szBuf));
00601         ShowMessage(szBuf, TRUE);
00602         if((dwErr = FileUncompress(szSource, szDestination)) != FO_SUCCESS)
00603         {
00604           char szMsg[MAX_BUF];
00605           char szErrorString[MAX_BUF];
00606 
00607           ShowMessage(szBuf, FALSE);
00608           GetConfigIniProfileString("Strings", "Error File Uncompress", "", szErrorString, sizeof(szErrorString));
00609           wsprintf(szMsg, szErrorString, szSource, dwErr);
00610           PrintError(szMsg, ERROR_CODE_HIDE);
00611           return(dwErr);
00612         }
00613 
00614         ShowMessage(szBuf, FALSE);
00615       }
00616     }
00617 
00618     ++dwIndex;
00619     BuildNumberedString(dwIndex, szSectionPrefix, "Uncompress File", szSection, sizeof(szSection));
00620     GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
00711   while(*szBuf != '\0')
00712   {
00713     if(TimingCheck(dwTiming, szSection))
00714     {
00715       DecryptString(szSource, szBuf);
00716       GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
00717       DecryptString(szDestination, szBuf);
00718       FileMove(szSource, szDestination);
00719     }
00720 
00721     ++dwIndex;
00722     BuildNumberedString(dwIndex, szSectionPrefix, "Move File", szSection, sizeof(szSection));
00723     GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
00896   while(*szBuf != '\0')
00897   {
00898     if(TimingCheck(dwTiming, szSection))
00899     {
00900       DecryptString(szSource, szBuf);
00901       GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
00902       DecryptString(szDestination, szBuf);
00903 
00904       GetConfigIniProfileString(szSection, "Do Not Uninstall", "", szBuf, sizeof(szBuf));
00905       if(lstrcmpi(szBuf, "TRUE") == 0)
00906         bDnu = TRUE;
00907       else
00908         bDnu = FALSE;
00909 
00910       GetConfigIniProfileString(szSection, "Fail If Exists", "", szBuf, sizeof(szBuf));
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     GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename));
00938   while(*szFilename != '\0')
00939   {
00940     if(TimingCheck(dwTiming, szSection))
00941     {
00942       GetConfigIniProfileString(szSection, "Source", "", szBuf, sizeof(szBuf));
00943       DecryptString(szSource, szBuf);
00944 
00945       GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
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     GetConfigIniProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename));
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   GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
01035   while(*szBuf != '\0')
01036   {
01037     if(TimingCheck(dwTiming, szSection))
01038     {
01039       DecryptString(szDestination, szBuf);
01040       GetConfigIniProfileString(szSection, "Filename", "", szFilename, sizeof(szFilename));
01041       FileSelfRegister(szFilename, szDestination);
01042     }
01043 
01044     ++dwIndex;
01045     BuildNumberedString(dwIndex, szSectionPrefix, "Self Register File", szSection, sizeof(szSection));
01046     GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
01254   while(*szBuf != '\0')
01255   {
01256     if(TimingCheck(dwTiming, szSection))
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     GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
01322   while(*szBuf != '\0')
01323   {
01324     if(TimingCheck(dwTiming, szSection))
01325     {
01326       DecryptString(szDestination, szBuf);
01327       FileDelete(szDestination);
01328     }
01329 
01330     ++dwIndex;
01331     BuildNumberedString(dwIndex, szSectionPrefix, "Delete File", szSection, sizeof(szSection));
01332     GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
01395   while(*szBuf != '\0')
01396   {
01397     if(TimingCheck(dwTiming, szSection))
01398     {
01399       DecryptString(szDestination, szBuf);
01400       GetConfigIniProfileString(szSection, "Remove subdirs", "", szBuf, sizeof(szBuf));
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     GetConfigIniProfileString(szSection, "Destination", "", szBuf, sizeof(szBuf));
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   GetConfigIniProfileString(szSection, "Target", "", szBuf, sizeof(szBuf));
01429   while(*szBuf != '\0')
01430   {
01431     if(TimingCheck(dwTiming, szSection))
01432     {
01433       DecryptString(szTarget, szBuf);
01434       GetConfigIniProfileString(szSection, "Parameters", "", szBuf, sizeof(szBuf));
01435       DecryptString(szParameters, szBuf);
01436 
01437       bRunApp = MeetCondition(szSection);
01438 
01439       GetConfigIniProfileString(szSection, "WorkingDir", "", szBuf, sizeof(szBuf));
01440       DecryptString(szWorkingDir, szBuf);
01441 
01442       GetConfigIniProfileString(szSection, "Wait", "", szBuf, sizeof(szBuf));
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           GetConfigIniProfileString(szSection, "Message", "", szBuf, sizeof(szBuf));
01468           if ( szBuf[0] != '\0' )
01469             ShowMessage(szBuf, TRUE);  
01470           WinSpawn(szTarget, szParameters, szWorkingDir, SW_SHOWNORMAL, bWait);
01471           if ( szBuf[0] != '\0' )
01472             ShowMessage(szBuf, FALSE);  
01473         }
01474       }
01475     }
01476 
01477     ++dwIndex;
01478     BuildNumberedString(dwIndex, szSectionPrefix, "RunApp", szSection, sizeof(szSection));
01479     GetConfigIniProfileString(szSection, "Target", "", szBuf, sizeof(szBuf));
01480   }
01481   return(FO_SUCCESS);
01482 }
01483 
01484 DWORD ParseRestrictedAccessKey(LPSTR szKey)
01485 {
01486   DWORD dwKey;
01487 
01488   if(lstrcmpi(szKey, "ONLY_RESTRICTED") == 0)
01489     dwKey = RA_ONLY_RESTRICTED;
01490   else if(lstrcmpi(szKey, "ONLY_NONRESTRICTED") == 0)
01491     dwKey = RA_ONLY_NONRESTRICTED;
01492   else
01493     dwKey = RA_IGNORE;
01494 
01495   return(dwKey);
01496 }
01497 
01498 /* Function: GetKeyInfo()
01499  *       in: LPSTR aKey, DWORD aOutBufSize, DWORD aInfoType.
01500  *      out: LPSTR aOut.
01501  *  purpose: To parse a full windows registry key path format:
01502  *             [root key]\[subkey]
01503  *           It can return either the root key or the subkey depending on
01504  *           what's being requested.
01505  */
01506 LPSTR GetKeyInfo(LPSTR aKey, LPSTR aOut, DWORD aOutBufSize, DWORD aInfoType)
01507 {
01508   LPSTR keyCopy = NULL;
01509   LPSTR key = NULL;
01510 
01511   *aOut = '\0';
01512   if((keyCopy = strdup(aKey)) == NULL)
01513     return NULL;
01514 
01515   switch(aInfoType)
01516   {
01517     case KEY_INFO_ROOT:
01518       key = MozStrChar(keyCopy, '\\');
01519       if(key == keyCopy)
01520       {
01521         // root key not found, return NULL
01522         free(keyCopy);
01523         return NULL;
01524       }
01525       else if(key)
01526         // found '\\' which indicates the end of the root key
01527         // and beginning of the subkey.
01528         *key = '\0';
01529 
01530       if(MozCopyStr(keyCopy, aOut, aOutBufSize))
01531       {
01532         free(keyCopy);
01533         return NULL;
01534       }
01535       break;
01536 
01537     case KEY_INFO_SUBKEY:
01538       key = MozStrChar(keyCopy, '\\');
01539       if(key != NULL)
01540         ++key;
01541 
01542       if(!key)
01543         // No subkey found.  Assume the entire string is the subkey.
01544         key = keyCopy;
01545 
01546       if(MozCopyStr(key, aOut, aOutBufSize))
01547       {
01548         free(keyCopy);
01549         return NULL;
01550       }
01551       break;
01552   }
01553 
01554   free(keyCopy);
01555   return(aOut);
01556 }
01557 
01558 HKEY ParseRootKey(LPSTR szRootKey)
01559 {
01560   HKEY hkRootKey;
01561 
01562   if(lstrcmpi(szRootKey, "HKEY_CURRENT_CONFIG") == 0)
01563     hkRootKey = HKEY_CURRENT_CONFIG;
01564   else if(lstrcmpi(szRootKey, "HKEY_CURRENT_USER") == 0)
01565     hkRootKey = HKEY_CURRENT_USER;
01566   else if(lstrcmpi(szRootKey, "HKEY_LOCAL_MACHINE") == 0)
01567     hkRootKey = HKEY_LOCAL_MACHINE;
01568   else if(lstrcmpi(szRootKey, "HKEY_USERS") == 0)
01569     hkRootKey = HKEY_USERS;
01570   else if(lstrcmpi(szRootKey, "HKEY_PERFORMANCE_DATA") == 0)
01571     hkRootKey = HKEY_PERFORMANCE_DATA;
01572   else if(lstrcmpi(szRootKey, "HKEY_DYN_DATA") == 0)
01573     hkRootKey = HKEY_DYN_DATA;
01574   else /* HKEY_CLASSES_ROOT */
01575     hkRootKey = HKEY_CLASSES_ROOT;
01576 
01577   return(hkRootKey);
01578 }
01579 
01580 char *ParseRootKeyString(HKEY hkKey, LPSTR szRootKey, DWORD dwRootKeyBufSize)
01581 {
01582   if(!szRootKey)
01583     return(NULL);
01584 
01585   ZeroMemory(szRootKey, dwRootKeyBufSize);
01586   if((hkKey == HKEY_CURRENT_CONFIG) &&
01587     ((long)dwRootKeyBufSize > lstrlen("HKEY_CURRENT_CONFIG")))
01588     lstrcpy(szRootKey, "HKEY_CURRENT_CONFIG");
01589   else if((hkKey == HKEY_CURRENT_USER) &&
01590          ((long)dwRootKeyBufSize > lstrlen("HKEY_CURRENT_USER")))
01591     lstrcpy(szRootKey, "HKEY_CURRENT_USER");
01592   else if((hkKey == HKEY_LOCAL_MACHINE) &&
01593          ((long)dwRootKeyBufSize > lstrlen("HKEY_LOCAL_MACHINE")))
01594     lstrcpy(szRootKey, "HKEY_LOCAL_MACHINE");
01595   else if((hkKey == HKEY_USERS) &&
01596          ((long)dwRootKeyBufSize > lstrlen("HKEY_USERS")))
01597     lstrcpy(szRootKey, "HKEY_USERS");
01598   else if((hkKey == HKEY_PERFORMANCE_DATA) &&
01599          ((long)dwRootKeyBufSize > lstrlen("HKEY_PERFORMANCE_DATA")))
01600     lstrcpy(szRootKey, "HKEY_PERFORMANCE_DATA");
01601   else if((hkKey == HKEY_DYN_DATA) &&
01602          ((long)dwRootKeyBufSize > lstrlen("HKEY_DYN_DATA")))
01603     lstrcpy(szRootKey, "HKEY_DYN_DATA");
01604   else if((long)dwRootKeyBufSize > lstrlen("HKEY_CLASSES_ROOT"))
01605     lstrcpy(szRootKey, "HKEY_CLASSES_ROOT");
01606 
01607   return(szRootKey);
01608 }
01609 
01610 BOOL ParseRegType(LPSTR szType, DWORD *dwType)
01611 {
01612   BOOL bSZ;
01613 
01614   if(lstrcmpi(szType, "REG_SZ") == 0)
01615   {
01616     /* Unicode NULL terminated string */
01617     *dwType = REG_SZ;
01618     bSZ     = TRUE;
01619   }
01620   else if(lstrcmpi(szType, "REG_EXPAND_SZ") == 0)
01621   {
01622     /* Unicode NULL terminated string
01623      * (with environment variable references) */
01624     *dwType = REG_EXPAND_SZ;
01625     bSZ     = TRUE;
01626   }
01627   else if(lstrcmpi(szType, "REG_BINARY") == 0)
01628   {
01629     /* Free form binary */
01630     *dwType = REG_BINARY;
01631     bSZ     = FALSE;
01632   }
01633   else if(lstrcmpi(szType, "REG_DWORD") == 0)
01634   {
01635     /* 32bit number */
01636     *dwType = REG_DWORD;
01637     bSZ     = FALSE;
01638   }
01639   else if(lstrcmpi(szType, "REG_DWORD_LITTLE_ENDIAN") == 0)
01640   {
01641     /* 32bit number
01642      * (same as REG_DWORD) */
01643     *dwType = REG_DWORD_LITTLE_ENDIAN;
01644     bSZ     = FALSE;
01645   }
01646   else if(lstrcmpi(szType, "REG_DWORD_BIG_ENDIAN") == 0)
01647   {
01648     /* 32bit number */
01649     *dwType = REG_DWORD_BIG_ENDIAN;
01650     bSZ     = FALSE;
01651   }
01652   else if(lstrcmpi(szType, "REG_LINK") == 0)
01653   {
01654     /* Symbolic link (unicode) */
01655     *dwType = REG_LINK;
01656     bSZ     = TRUE;
01657   }
01658   else if(lstrcmpi(szType, "REG_MULTI_SZ") == 0)
01659   {
01660     /* Multiple Unicode strings */
01661     *dwType = REG_MULTI_SZ;
01662     bSZ     = TRUE;
01663   }
01664   else /* Default is REG_NONE */
01665   {
01666     /* no value type */
01667     *dwType = REG_NONE;
01668     bSZ     = TRUE;
01669   }
01670 
01671   return(bSZ);
01672 }
01673 
01674 BOOL WinRegKeyExists(HKEY hkRootKey, LPSTR szKey)
01675 {
01676   HKEY  hkResult;
01677   DWORD dwErr;
01678   BOOL  bKeyExists = FALSE;
01679 
01680   if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS)
01681   {
01682     bKeyExists = TRUE;
01683     RegCloseKey(hkResult);
01684   }
01685 
01686   return(bKeyExists);
01687 }
01688 
01689 BOOL WinRegNameExists(HKEY hkRootKey, LPSTR szKey, LPSTR szName)
01690 {
01691   HKEY  hkResult;
01692   DWORD dwErr;
01693   DWORD dwSize;
01694   char  szBuf[MAX_BUF];
01695   BOOL  bNameExists = FALSE;
01696 
01697   ZeroMemory(szBuf, sizeof(szBuf));
01698   if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS)
01699   {
01700     dwSize = sizeof(szBuf);
01701     dwErr  = RegQueryValueEx(hkResult, szName, 0, NULL, szBuf, &dwSize);
01702 
01703     if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS))
01704       bNameExists = TRUE;
01705 
01706     RegCloseKey(hkResult);
01707   }
01708 
01709   return(bNameExists);
01710 }
01711 
01712 void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete)
01713 {
01714   HKEY      hkResult;
01715   DWORD     dwErr;
01716   DWORD     dwTotalSubKeys;
01717   DWORD     dwTotalValues;
01718   DWORD     dwSubKeySize;
01719   FILETIME  ftLastWriteFileTime;
01720   char      szSubKey[MAX_BUF_TINY];
01721   char      szNewKey[MAX_BUF];
01722   long      lRv;
01723 
01724   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_QUERY_VALUE, &hkResult);
01725   if(dwErr == ERROR_SUCCESS)
01726   {
01727     dwTotalSubKeys = 0;
01728     dwTotalValues  = 0;
01729     RegQueryInfoKey(hkResult, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL);
01730     RegCloseKey(hkResult);
01731 
01732     if(((dwTotalSubKeys == 0) && (dwTotalValues == 0)) || bAbsoluteDelete)
01733     {
01734       if(dwTotalSubKeys && bAbsoluteDelete)
01735       {
01736         do
01737         {
01738           dwSubKeySize = sizeof(szSubKey);
01739           lRv = 0;
01740           if(RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS)
01741           {
01742             if((lRv = RegEnumKeyEx(hkResult, 0, szSubKey, &dwSubKeySize, NULL, NULL, NULL, &ftLastWriteFileTime)) == ERROR_SUCCESS)
01743             {
01744               RegCloseKey(hkResult);
01745               lstrcpy(szNewKey, szKey);
01746               AppendBackSlash(szNewKey, sizeof(szNewKey));
01747               lstrcat(szNewKey, szSubKey);
01748               DeleteWinRegKey(hkRootKey, szNewKey, bAbsoluteDelete);
01749             }
01750             else
01751               RegCloseKey(hkResult);
01752           }
01753         } while(lRv != ERROR_NO_MORE_ITEMS);
01754       }
01755 
01756       dwErr = RegDeleteKey(hkRootKey, szKey);
01757     }
01758   }
01759 }
01760 
01761 void DeleteWinRegValue(HKEY hkRootKey, LPSTR szKey, LPSTR szName)
01762 {
01763   HKEY    hkResult;
01764   DWORD   dwErr;
01765 
01766   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult);
01767   if(dwErr == ERROR_SUCCESS)
01768   {
01769     if(*szName == '\0')
01770       dwErr = RegDeleteValue(hkResult, NULL);
01771     else
01772       dwErr = RegDeleteValue(hkResult, szName);
01773 
01774     RegCloseKey(hkResult);
01775   }
01776 }
01777 
01778 DWORD GetWinReg(HKEY hkRootKey, LPSTR szKey, LPSTR szName, LPSTR szReturnValue, DWORD dwReturnValueSize)
01779 {
01780   HKEY  hkResult;
01781   DWORD dwErr;
01782   DWORD dwSize;
01783   DWORD dwType;
01784   char  szBuf[MAX_BUF];
01785 
01786   ZeroMemory(szBuf, sizeof(szBuf));
01787   ZeroMemory(szReturnValue, dwReturnValueSize);
01788 
01789   if((dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult)) == ERROR_SUCCESS)
01790   {
01791     dwSize = sizeof(szBuf);
01792     dwErr  = RegQueryValueEx(hkResult, szName, 0, &dwType, szBuf, &dwSize);
01793 
01794     if((dwType == REG_MULTI_SZ) && (*szBuf != '\0'))
01795     {
01796       DWORD dwCpSize;
01797 
01798       dwCpSize = dwReturnValueSize < dwSize ? (dwReturnValueSize - 1) : dwSize;
01799       memcpy(szReturnValue, szBuf, dwCpSize);
01800     }
01801     else if((*szBuf != '\0') && (dwErr == ERROR_SUCCESS))
01802       ExpandEnvironmentStrings(szBuf, szReturnValue, dwReturnValueSize);
01803     else
01804       *szReturnValue = '\0';
01805 
01806     RegCloseKey(hkResult);
01807   }
01808 
01809   return(dwType);
01810 }
01811 
01812 LONG _CreateWinRegKey(HKEY hkRootKey,
01813                        LPSTR szKey,
01814                        BOOL bLogForUninstall,
01815                        BOOL bDnu,
01816                        BOOL bForceCreate)
01817 {
01818   HKEY    hkResult;
01819   LONG    err = ERROR_SUCCESS;
01820   DWORD   dwDisp;
01821   char    szBuf[MAX_BUF];
01822   char    szRootKey[MAX_BUF_TINY];
01823 
01824   if(!WinRegKeyExists(hkRootKey, szKey) || bForceCreate)
01825   {
01826     err = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp);
01827     /* log the win reg command */
01828     if(((err == ERROR_SUCCESS) &&
01829        bLogForUninstall &&
01830        ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey))) || bForceCreate)
01831     {
01832       wsprintf(szBuf, "%s\\%s []", szRootKey, szKey);
01833       UpdateInstallLog(KEY_CREATE_REG_KEY, szBuf, bDnu);
01834     }
01835     RegCloseKey(hkResult);
01836   }
01837 
01838   return(err);
01839 }
01840 
01841 LONG CreateWinRegKey(HKEY hkRootKey,
01842                       LPSTR szKey,
01843                       BOOL bLogForUninstall,
01844                       BOOL bDnu)
01845 {
01846   char    szTempKeyPath[MAX_BUF];
01847   char    saveChar;
01848   LPSTR   pointerToBackslashChar = NULL;
01849   LPSTR   pointerToStrWalker = NULL;
01850 
01851   if(MozCopyStr(szKey, szTempKeyPath, sizeof(szTempKeyPath)))
01852     return(ERROR_BUFFER_OVERFLOW);
01853 
01854   // Make sure that we create all the keys (starting from the root) that
01855   // do not exist.  We need to do this in order to log it for uninstall.
01856   // If this was not done, then only the last key in the key path would be
01857   // uninstalled.
01858   RemoveBackSlash(szTempKeyPath);
01859   pointerToStrWalker = szTempKeyPath;
01860   while((pointerToBackslashChar = strstr(pointerToStrWalker, "\\")) != NULL)
01861   {
01862     saveChar = *pointerToBackslashChar;
01863     *pointerToBackslashChar = '\0';
01864     // Log the registry only if it was created here
01865     _CreateWinRegKey(hkRootKey, szTempKeyPath, bLogForUninstall, bDnu, DO_NOT_FORCE_ADD_TO_UNINSTALL_LOG);
01866     *pointerToBackslashChar = saveChar;
01867     pointerToStrWalker = &pointerToBackslashChar[1];
01868   }
01869 
01870   // Log the registry regardless if it was created here or not.  If it was
01871   // explicitly listed to be created, we should log for uninstall.  This 
01872   // covers the case where the user deletes the uninstall log file from a
01873   // previous build where a new install would not log the creation because
01874   // it already exists.
01875   return(_CreateWinRegKey(hkRootKey, szKey, bLogForUninstall, bDnu, FORCE_ADD_TO_UNINSTALL_LOG));
01876 }
01877 
01878 void SetWinReg(HKEY hkRootKey,
01879                LPSTR szKey,
01880                BOOL bOverwriteKey,
01881                LPSTR szName,
01882                BOOL bOverwriteName,
01883                DWORD dwType,
01884                LPBYTE lpbData,
01885                DWORD dwSize,
01886                BOOL bLogForUninstall,
01887                BOOL bDnu)
01888 {
01889   HKEY    hkResult;
01890   DWORD   dwErr;
01891   BOOL    bNameExists;
01892   char    szBuf[MAX_BUF];
01893   char    szRootKey[MAX_BUF_TINY];
01894 
01895   /* We don't care if it failed or not because it could already exist. */
01896   CreateWinRegKey(hkRootKey, szKey, bLogForUninstall, bDnu);
01897 
01898   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult);
01899   if(dwErr == ERROR_SUCCESS)
01900   {
01901     bNameExists = WinRegNameExists(hkRootKey, szKey, szName);
01902     if((bNameExists == FALSE) ||
01903       ((bNameExists == TRUE) && (bOverwriteName == TRUE)))
01904     {
01905       dwErr = RegSetValueEx(hkResult, szName, 0, dwType, lpbData, dwSize);
01906       /* log the win reg command */
01907       if(bLogForUninstall &&
01908          ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey)))
01909       {
01910         if(ParseRegType(szBuf, &dwType))
01911         {
01912           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
01913           UpdateInstallLog(KEY_STORE_REG_STRING, szBuf, bDnu);
01914         }
01915         else
01916         {
01917           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
01918           UpdateInstallLog(KEY_STORE_REG_NUMBER, szBuf, bDnu);
01919         }
01920       }
01921     }
01922 
01923     RegCloseKey(hkResult);
01924   }
01925 }
01926 
01927 /* Name: AppendWinRegString
01928  *
01929  * Arguments:
01930  *
01931  * HKEY hkRootKey -- root key, e.g., HKEY_LOCAL_MACHINE
01932  * LPSTR szKey -- subkey
01933  * LPSTR szName -- value name
01934  * DWORD dwType -- value type, should be REG_SZ
01935  * LPBYTE lpbData -- value data
01936  * BYTE delimiter -- e.g., ':'. If 0, then don't apply delimiter
01937  * DWORD dwSize -- size of the value data
01938  * BOOL bLogForUninstall -- if true, update install log
01939  * BOOL bDnu -- what to update the install log with
01940  *
01941  * Description:
01942  *
01943  * This function should be called to append a string (REG_SZ) to the
01944  * string already stored in the specified key. If the key does not
01945  * exist, then simply store the key (ignoring the delimiter). If the
01946  * key does exist, read the current value, append the delimiter (if
01947  * not zero), and append the data passed in.
01948  *
01949  * Return Value: void
01950  *
01951  * Original Code: Clone of SetWinReg(), syd@netscape.com 6/11/2001
01952  *
01953  */
01954 
01955 void AppendWinReg(HKEY hkRootKey,
01956                LPSTR szKey,
01957                LPSTR szName,
01958                DWORD dwType,
01959                LPBYTE lpbData,
01960                BYTE delimiter,
01961                DWORD dwSize,
01962                BOOL bLogForUninstall,
01963                BOOL bDnu)
01964 {
01965   HKEY    hkResult;
01966   DWORD   dwErr;
01967   DWORD   dwDisp;
01968   BOOL    bKeyExists;
01969   BOOL    bNameExists;
01970   char    szBuf[MAX_BUF];
01971   char    szRootKey[MAX_BUF_TINY]; 
01972 
01973   bKeyExists  = WinRegKeyExists(hkRootKey, szKey);
01974   bNameExists = WinRegNameExists(hkRootKey, szKey, szName);
01975   dwErr       = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_WRITE, &hkResult);
01976 
01977   if (dwType != REG_SZ) // this function is void. How do we pass errors to caller?
01978       return;
01979 
01980   if(dwErr != ERROR_SUCCESS)
01981   {
01982     dwErr = RegCreateKeyEx(hkRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkResult, &dwDisp);
01983     /* log the win reg command */
01984     if(bLogForUninstall &&
01985        ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey)))
01986     {
01987       wsprintf(szBuf, "%s\\%s []", szRootKey, szKey);
01988       UpdateInstallLog(KEY_CREATE_REG_KEY, szBuf, bDnu);
01989     }
01990   }
01991 
01992   if(dwErr == ERROR_SUCCESS)
01993   {
01994     if((bNameExists == FALSE))
01995     {
01996       /* first time, so just write it, ignoring the delimiter */
01997 
01998       dwErr = RegSetValueEx(hkResult, szName, 0, dwType, lpbData, dwSize);
01999       /* log the win reg command */
02000       if(bLogForUninstall &&
02001          ParseRootKeyString(hkRootKey, szRootKey, sizeof(szRootKey)))
02002       {
02003         if(ParseRegType(szBuf, &dwType))
02004         {
02005           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
02006           UpdateInstallLog(KEY_STORE_REG_STRING, szBuf, bDnu);
02007         }
02008         else
02009         {
02010           wsprintf(szBuf, "%s\\%s [%s]", szRootKey, szKey, szName);
02011           UpdateInstallLog(KEY_STORE_REG_NUMBER, szBuf, bDnu);
02012         }
02013       }
02014     } else {
02015       /* already exists, so read the prrevious value, append the delimiter if 
02016          specified, append the new value, and rewrite the key */
02017       
02018       GetWinReg(hkRootKey, szKey, szName, szBuf, sizeof(szBuf));  // func is void, assume success
02019       if ( delimiter != 0 ) {
02020           char delim[ 2 ];
02021           delim[0] = delimiter;
02022           delim[1] = '\0';
02023           strcat( szBuf, delim );
02024       }
02025       strcat( szBuf, lpbData );
02026       RegCloseKey(hkResult);
02027       SetWinReg(hkRootKey, szKey, TRUE, szName, TRUE, dwType, szBuf, strlen( szBuf ) + 1, bLogForUninstall, bDnu);
02028       return;
02029     }
02030 
02031     RegCloseKey(hkResult);
02032   }
02033 }
02034 
02035 HRESULT ProcessWinReg(DWORD dwTiming, char *szSectionPrefix)
02036 {
02037   char    szBuf[MAX_BUF];
02038   char    szKey[MAX_BUF];
02039   char    szName[MAX_BUF];
02040   char    szShortName[MAX_BUF];
02041   char    szValue[MAX_BUF];
02042   char    szDecrypt[MAX_BUF];
02043   char    szOverwriteKey[MAX_BUF];
02044   char    szOverwriteName[MAX_BUF];
02045   char    szSection[MAX_BUF];
02046   HKEY    hRootKey;
02047   BOOL    bDone;
02048   BOOL    bDnu;
02049   BOOL    bOverwriteKey;
02050   BOOL    bOverwriteName;
02051   BOOL    bOSDetected;
02052   DWORD   dwIndex;
02053   DWORD   dwNameIndex = 1;
02054   DWORD   dwType;
02055   DWORD   dwSize;
02056   const DWORD   dwUpperLimit = 100;
02057   __int64 iiNum;
02058 
02059   dwIndex = 0;
02060   BuildNumberedString(dwIndex, szSectionPrefix, "Windows Registry", szSection, sizeof(szSection));
02061   GetConfigIniProfileString(szSection, "Root Key", "", szBuf, sizeof(szBuf));
02062   while(*szBuf != '\0')
02063   {
02064     if(TimingCheck(dwTiming, szSection) && MeetCondition(szSection))
02065     {
02066       hRootKey = ParseRootKey(szBuf);
02067 
02068       GetConfigIniProfileString(szSection, "Key",                 "", szBuf,           sizeof(szBuf));
02069       GetConfigIniProfileString(szSection, "Decrypt Key",         "", szDecrypt,       sizeof(szDecrypt));
02070       GetConfigIniProfileString(szSection, "Overwrite Key",       "", szOverwriteKey,  sizeof(szOverwriteKey));
02071       ZeroMemory(szKey, sizeof(szKey));
02072       if(lstrcmpi(szDecrypt, "TRUE") == 0)
02073         DecryptString(szKey, szBuf);
02074       else
02075         lstrcpy(szKey, szBuf);
02076 
02077       if(lstrcmpi(szOverwriteKey, "FALSE") == 0)
02078         bOverwriteKey = FALSE;
02079       else
02080         bOverwriteKey = TRUE;
02081 
02082       GetConfigIniProfileString(szSection, "Name",                "", szBuf,           sizeof(szBuf));
02083       GetConfigIniProfileString(szSection, "Decrypt Name",        "", szDecrypt,       sizeof(szDecrypt));
02084       GetConfigIniProfileString(szSection, "Overwrite Name",      "", szOverwriteName, sizeof(szOverwriteName));
02085       ZeroMemory(szName, sizeof(szName));
02086       if(lstrcmpi(szDecrypt, "TRUE") == 0)
02087         DecryptString(szName, szBuf);
02088       else
02089         lstrcpy(szName, szBuf);
02090 
02091       if(lstrcmpi(szOverwriteName, "ENUMERATE") == 0)
02092       {
02093         bOverwriteName = FALSE;
02094         lstrcpy(szShortName, szName);
02095         wsprintf(szName, "%s%02d", szShortName, dwNameIndex++);
02096 
02097         bDone = FALSE;
02098         while(!bDone && (dwNameIndex < dwUpperLimit))
02099         {
02100           if(WinRegNameExists(hRootKey, szKey, szName))
02101           {
02102             GetWinReg(hRootKey, szKey, szName, szBuf, sizeof(szBuf));
02103             if(lstrcmpi(szBuf, sgProduct.szAppPath) == 0)
02104               bDone = TRUE;
02105             else
02106               wsprintf(szName, "%s%02d", szShortName, dwNameIndex++);
02107           }
02108           else
02109             bDone = TRUE;
02110         }
02111         if(dwNameIndex >= dwUpperLimit)
02112           return FO_ERROR_INCR_EXCEEDS_LIMIT;
02113       }
02114       else if(lstrcmpi(szOverwriteName, "FALSE") == 0)
02115         bOverwriteName = FALSE;
02116       else
02117         bOverwriteName = TRUE;
02118 
02119       GetConfigIniProfileString(szSection, "Name Value",          "", szBuf,           sizeof(szBuf));
02120       GetConfigIniProfileString(szSection, "Decrypt Name Value",  "", szDecrypt,       sizeof(szDecrypt));
02121       ZeroMemory(szValue, sizeof(szValue));
02122       if(lstrcmpi(szDecrypt, "TRUE") == 0)
02123         DecryptString(szValue, szBuf);
02124       else
02125         lstrcpy(szValue, szBuf);
02126 
02127       GetConfigIniProfileString(szSection, "Size",                "", szBuf,           sizeof(szBuf));
02128       if(*szBuf != '\0')
02129         dwSize = atoi(szBuf);
02130       else
02131         dwSize = 0;
02132 
02133       GetConfigIniProfileString(szSection, "Do Not Uninstall", "",
02134                                 szBuf, sizeof(szBuf));
02135 
02136       if(lstrcmpi(szBuf, "TRUE") == 0)
02137         bDnu = TRUE;
02138       else
02139         bDnu = FALSE;
02140 
02141       /* Read the OS key to see if there are restrictions on which OS to
02142        * the Windows registry key for */
02143       GetConfigIniProfileString(szSection, "OS", "", szBuf, sizeof(szBuf));
02144       /* If there is no OS key value set, then assume all OS is valid.
02145        * If there are any, then compare against the global OS value to
02146        * make sure there's a match. */
02147       bOSDetected = TRUE;
02148       if( (*szBuf != '\0') && ((gSystemInfo.dwOSType & ParseOSType(szBuf)) == 0) )
02149         bOSDetected = FALSE;
02150 
02151       if(bOSDetected)
02152       {
02153         ZeroMemory(szBuf, sizeof(szBuf));
02154         GetConfigIniProfileString(szSection, "Type", "", szBuf, sizeof(szBuf));
02155 
02156         if(ParseRegType(szBuf, &dwType))
02157         {
02158           /* create/set windows registry key here (string value)! */
02159           SetWinReg(hRootKey, szKey, bOverwriteKey, szName, bOverwriteName,
02160                   dwType, (CONST LPBYTE)szValue, lstrlen(szValue), TRUE, bDnu);
02161         }
02162         else
02163         {
02164           iiNum = _atoi64(szValue);
02165           /* create/set windows registry key here (binary/dword value)! */
02166           SetWinReg(hRootKey, szKey, bOverwriteKey, szName, bOverwriteName,
02167                   dwType, (CONST LPBYTE)&iiNum, dwSize, TRUE, bDnu);
02168         }
02169       }
02170     }
02171 
02172     ++dwIndex;
02173     BuildNumberedString(dwIndex, szSectionPrefix, "Windows Registry", szSection, sizeof(szSection));
02174     GetConfigIniProfileString(szSection, "Root Key", "", szBuf, sizeof(szBuf));
02175   }
02176   return(FO_SUCCESS);
02177 }
02178 
02179 HRESULT ProcessProgramFolder(DWORD dwTiming, char *szSectionPrefix)
02180 {
02181   DWORD dwIndex0;
02182   DWORD dwIndex1;
02183   DWORD dwIconId;
02184   DWORD dwRestrictedAccess;
02185   char  szIndex1[MAX_BUF];
02186   char  szBuf[MAX_BUF];
02187   char  szSection0[MAX_BUF];
02188   char  szSection1[MAX_BUF];
02189   char  szProgramFolder[MAX_BUF];
02190   char  szFile[MAX_BUF];
02191   char  szArguments[MAX_BUF];
02192   char  szWorkingDir[MAX_BUF];
02193   char  szDescription[MAX_BUF];
02194   char  szIconPath[MAX_BUF];
02195 
02196   dwIndex0 = 0;
02197   BuildNumberedString(dwIndex0, szSectionPrefix, "Program Folder", szSection0, sizeof(szSection0));
02198   GetConfigIniProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf));
02199   while(*szBuf != '\0')
02200   {
02201     if(TimingCheck(dwTiming, szSection0))
02202     {
02203       DecryptString(szProgramFolder, szBuf);
02204 
02205       dwIndex1 = 0;
02206       itoa(dwIndex1, szIndex1, 10);
02207       lstrcpy(szSection1, szSection0);
02208       lstrcat(szSection1, "-Shortcut");
02209       lstrcat(szSection1, szIndex1);
02210       GetConfigIniProfileString(szSection1, "File", "", szBuf, sizeof(szBuf));
02211       while(*szBuf != '\0')
02212       {
02213         DecryptString(szFile, szBuf);
02214         GetConfigIniProfileString(szSection1, "Arguments",    "", szBuf, sizeof(szBuf));
02215         DecryptString(szArguments, szBuf);
02216         GetConfigIniProfileString(szSection1, "Working Dir",  "", szBuf, sizeof(szBuf));
02217         DecryptString(szWorkingDir, szBuf);
02218         GetConfigIniProfileString(szSection1, "Description",  "", szBuf, sizeof(szBuf));
02219         DecryptString(szDescription, szBuf);
02220         GetConfigIniProfileString(szSection1, "Icon Path",    "", szBuf, sizeof(szBuf));
02221         DecryptString(szIconPath, szBuf);
02222         GetConfigIniProfileString(szSection1, "Icon Id",      "", szBuf, sizeof(szBuf));
02223         if(*szBuf != '\0')
02224           dwIconId = atol(szBuf);
02225         else
02226           dwIconId = 0;
02227 
02228         GetConfigIniProfileString(szSection1, "Restricted Access",    "", szBuf, sizeof(szBuf));
02229         dwRestrictedAccess = ParseRestrictedAccessKey(szBuf);
02230         if((dwRestrictedAccess == RA_IGNORE) ||
02231           ((dwRestrictedAccess == RA_ONLY_RESTRICTED) && gbRestrictedAccess) ||
02232           ((dwRestrictedAccess == RA_ONLY_NONRESTRICTED) && !gbRestrictedAccess))
02233         {
02234           CreateALink(szFile, szProgramFolder, szDescription, szWorkingDir, szArguments, szIconPath, dwIconId);
02235           lstrcpy(szBuf, szProgramFolder);
02236           AppendBackSlash(szBuf, sizeof(szBuf));
02237           lstrcat(szBuf, szDescription);
02238           UpdateInstallLog(KEY_WINDOWS_SHORTCUT, szBuf, FALSE);
02239         }
02240 
02241         ++dwIndex1;
02242         itoa(dwIndex1, szIndex1, 10);
02243         lstrcpy(szSection1, szSection0);
02244         lstrcat(szSection1, "-Shortcut");
02245         lstrcat(szSection1, szIndex1);
02246         GetConfigIniProfileString(szSection1, "File", "", szBuf, sizeof(szBuf));
02247       }
02248     }
02249 
02250     ++dwIndex0;
02251     BuildNumberedString(dwIndex0, szSectionPrefix, "Program Folder", szSection0, sizeof(szSection0));
02252     GetConfigIniProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf));
02253   }
02254   return(FO_SUCCESS);
02255 }
02256 
02257 HRESULT ProcessProgramFolderShowCmd()
02258 {
02259   DWORD dwIndex0;
02260   int   iShowFolder;
02261   char  szBuf[MAX_BUF];
02262   char  szSection0[MAX_BUF];
02263   char  szProgramFolder[MAX_BUF];
02264 
02265   dwIndex0 = 0;
02266   BuildNumberedString(dwIndex0, NULL, "Program Folder", szSection0, sizeof(szSection0));
02267   GetConfigIniProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf));
02268   while(*szBuf != '\0')
02269   {
02270     DecryptString(szProgramFolder, szBuf);
02271     GetConfigIniProfileString(szSection0, "Show Folder", "", szBuf, sizeof(szBuf));
02272 
02273     if(strcmpi(szBuf, "HIDE") == 0)
02274       iShowFolder = SW_HIDE;
02275     else if(strcmpi(szBuf, "MAXIMIZE") == 0)
02276       iShowFolder = SW_MAXIMIZE;
02277     else if(strcmpi(szBuf, "MINIMIZE") == 0)
02278       iShowFolder = SW_MINIMIZE;
02279     else if(strcmpi(szBuf, "RESTORE") == 0)
02280       iShowFolder = SW_RESTORE;
02281     else if(strcmpi(szBuf, "SHOW") == 0)
02282       iShowFolder = SW_SHOW;
02283     else if(strcmpi(szBuf, "SHOWMAXIMIZED") == 0)
02284       iShowFolder = SW_SHOWMAXIMIZED;
02285     else if(strcmpi(szBuf, "SHOWMINIMIZED") == 0)
02286       iShowFolder = SW_SHOWMINIMIZED;
02287     else if(strcmpi(szBuf, "SHOWMINNOACTIVE") == 0)
02288       iShowFolder = SW_SHOWMINNOACTIVE;
02289     else if(strcmpi(szBuf, "SHOWNA") == 0)
02290       iShowFolder = SW_SHOWNA;
02291     else if(strcmpi(szBuf, "SHOWNOACTIVATE") == 0)
02292       iShowFolder = SW_SHOWNOACTIVATE;
02293     else if(strcmpi(szBuf, "SHOWNORMAL") == 0)
02294       iShowFolder = SW_SHOWNORMAL;
02295 
02296     if(iShowFolder != SW_HIDE)
02297       if(sgProduct.mode != SILENT)
02298         WinSpawn(szProgramFolder, NULL, NULL, iShowFolder, WS_WAIT);
02299 
02300     ++dwIndex0;
02301     BuildNumberedString(dwIndex0, NULL, "Program Folder", szSection0, sizeof(szSection0));
02302     GetConfigIniProfileString(szSection0, "Program Folder", "", szBuf, sizeof(szBuf));
02303   }
02304   return(FO_SUCCESS);
02305 }
02306 
02307 HRESULT ProcessCreateCustomFiles(DWORD dwTiming)
02308 {
02309   DWORD dwCompIndex;
02310   DWORD dwFileIndex;
02311   DWORD dwSectIndex;
02312   DWORD dwKVIndex;
02313   siC   *siCObject = NULL;
02314   char  szBufTiny[MAX_BUF_TINY];
02315   char  szSection[MAX_BUF_TINY];
02316   char  szBuf[MAX_BUF];
02317   char  szFileName[MAX_BUF];
02318   char  szDefinedSection[MAX_BUF]; 
02319   char  szDefinedKey[MAX_BUF]; 
02320   char  szDefinedValue[MAX_BUF];
02321 
02322   dwCompIndex   = 0;
02323   siCObject = SiCNodeGetObject(dwCompIndex, TRUE, AC_ALL);
02324 
02325   while(siCObject)
02326   {
02327     dwFileIndex   = 0;
02328     wsprintf(szSection,"%s-Configuration File%d",siCObject->szReferenceName,dwFileIndex);
02329     siCObject = SiCNodeGetObject(++dwCompIndex, TRUE, AC_ALL);
02330     if(TimingCheck(dwTiming, szSection) == FALSE)
02331     {
02332       continue;
02333     }
02334 
02335     GetConfigIniProfileString(szSection, "FileName", "", szBuf, sizeof(szBuf));
02336     while (*szBuf != '\0')
02337     {
02338       DecryptString(szFileName, szBuf);
02339       if(FileExists(szFileName))
02340       {
02341         DeleteFile(szFileName);
02342       }
02343 
02344       /* TO DO - Support a File Type for something other than .ini */
02345       dwSectIndex = 0;
02346       wsprintf(szBufTiny, "Section%d",dwSectIndex);
02347       GetConfigIniProfileString(szSection, szBufTiny, "", szDefinedSection, sizeof(szDefinedSection));
02348       while(*szDefinedSection != '\0')
02349       {  
02350         dwKVIndex =0;
02351         wsprintf(szBufTiny,"Section%d-Key%d",dwSectIndex,dwKVIndex);
02352         GetConfigIniProfileString(szSection, szBufTiny, "", szDefinedKey, sizeof(szDefinedKey));
02353         while(*szDefinedKey != '\0')
02354         {
02355           wsprintf(szBufTiny,"Section%d-Value%d",dwSectIndex,dwKVIndex);
02356           GetConfigIniProfileString(szSection, szBufTiny, "", szBuf, sizeof(szBuf));
02357           DecryptString(szDefinedValue, szBuf);
02358           if(WritePrivateProfileString(szDefinedSection, szDefinedKey, szDefinedValue, szFileName) == 0)
02359           {
02360             char szEWPPS[MAX_BUF];
02361             char szBuf[MAX_BUF];
02362             char szBuf2[MAX_BUF];
02363             if(GetPrivateProfileString("Messages", "ERROR_WRITEPRIVATEPROFILESTRING", "", szEWPPS, sizeof(szEWPPS), szFileIniInstall))
02364             {
02365               wsprintf(szBuf, "%s\n    [%s]\n    %s=%s", szFileName, szDefinedSection, szDefinedKey, szDefinedValue);
02366               wsprintf(szBuf2, szEWPPS, szBuf);
02367               PrintError(szBuf2, ERROR_CODE_SHOW);
02368             }
02369             return(FO_ERROR_WRITE);
02370           }
02371           wsprintf(szBufTiny,"Section%d-Key%d",dwSectIndex,++dwKVIndex);
02372           GetConfigIniProfileString(szSection, szBufTiny, "", szDefinedKey, sizeof(szDefinedKey));
02373         } /* while(*szDefinedKey != '\0')  */
02374 
02375         wsprintf(szBufTiny, "Section%d",++dwSectIndex);
02376         GetConfigIniProfileString(szSection, szBufTiny, "", szDefinedSection, sizeof(szDefinedSection));
02377       } /*       while(*szDefinedSection != '\0') */
02378 
02379       wsprintf(szSection,"%s-Configuration File%d",siCObject->szReferenceName,++dwFileIndex);
02380       GetConfigIniProfileString(szSection, "FileName", "", szBuf, sizeof(szBuf));
02381     } /* while(*szBuf != '\0') */
02382   } /* while(siCObject) */
02383   return (FO_SUCCESS);
02384 }