Back to index

lightning-sunbird  0.9+nobinonly
parser.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  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "extern.h"
00041 #include "logkeys.h"
00042 #include "parser.h"
00043 #include "extra.h"
00044 #include "ifuncns.h"
00045 #include "dialogs.h"
00046 
00047 #define KEY_SHARED_DLLS "Software\\Microsoft\\Windows\\CurrentVersion\\SharedDlls"
00048 
00049 BOOL DeleteOrDelayUntilReboot(LPSTR szFile)
00050 {
00051   FILE      *ofp;
00052   char      szWinDir[MAX_BUF];
00053   char      szWininitFile[MAX_BUF];
00054   BOOL      bDelayDelete = FALSE;
00055   BOOL      bWriteRenameSection;
00056 
00057   FileDelete(szFile);
00058   if(FileExists(szFile))
00059   {
00060     bDelayDelete = TRUE;
00061     if(ulOSType & OS_NT)
00062       MoveFileEx(szFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
00063     else
00064     {
00065       if(GetWindowsDirectory(szWinDir, sizeof(szWinDir)) == 0)
00066         return(FALSE);
00067 
00068       lstrcpy(szWininitFile, szWinDir);
00069       AppendBackSlash(szWininitFile, sizeof(szWininitFile));
00070       lstrcat(szWininitFile, "wininit.ini");
00071 
00072       if(FileExists(szWininitFile) == FALSE)
00073         bWriteRenameSection = TRUE;
00074       else
00075         bWriteRenameSection = FALSE;
00076 
00077       if((ofp = fopen(szWininitFile, "a+")) == NULL)
00078         return(FALSE);
00079 
00080       if(bWriteRenameSection == TRUE)
00081         fprintf(ofp, "[RENAME]\n");
00082 
00083       fprintf(ofp, "NUL=%s\n", szFile);
00084       fclose(ofp);
00085     }
00086   }
00087   else
00088     bDelayDelete = FALSE;
00089 
00090   return(bDelayDelete);
00091 }
00092 
00093 void RemoveUninstaller(LPSTR szUninstallFilename)
00094 {
00095   char      szBuf[MAX_BUF];
00096   char      szWinDir[MAX_BUF];
00097   char      szUninstallFile[MAX_BUF];
00098 
00099   if(SearchForUninstallKeys(szUninstallFilename))
00100     /* Found the uninstall file name in the windows registry uninstall
00101      * key sections.  We should not try to delete ourselves. */
00102     return;
00103 
00104   if(GetWindowsDirectory(szWinDir, sizeof(szWinDir)) == 0)
00105     return;
00106 
00107   lstrcpy(szBuf, szWinDir);
00108   AppendBackSlash(szBuf, sizeof(szBuf));
00109   lstrcat(szBuf, szUninstallFilename);
00110   GetShortPathName(szBuf, szUninstallFile, sizeof(szUninstallFile));
00111   DeleteOrDelayUntilReboot(szUninstallFile);
00112 }
00113 
00114 sil *InitSilNodes(char *szInFile)
00115 {
00116   FILE      *ifp;
00117   char      szLineRead[MAX_BUF];
00118   sil       *silTemp;
00119   sil       *silHead;
00120   ULONGLONG ullLineCount;
00121 
00122   if(FileExists(szInFile) == FALSE)
00123     return(NULL);
00124 
00125   ullLineCount = 0;
00126   silHead      = NULL;
00127   if((ifp = fopen(szInFile, "r")) == NULL)
00128     exit(1);
00129 
00130   while(fgets(szLineRead, MAX_BUF, ifp) != NULL)
00131   {
00132     silTemp = CreateSilNode();
00133 
00134     silTemp->ullLineNumber = ++ullLineCount;
00135     lstrcpy(silTemp->szLine, szLineRead);
00136     if(silHead == NULL)
00137     {
00138       silHead = silTemp;
00139     }
00140     else
00141     {
00142       SilNodeInsert(silHead, silTemp);
00143     }
00144 
00145     ProcessWindowsMessages();
00146   }
00147   fclose(ifp);
00148   return(silHead);
00149 }
00150 
00151 void DeInitSilNodes(sil **silHead)
00152 {
00153   sil   *silTemp;
00154   
00155   if(*silHead == NULL)
00156   {
00157     return;
00158   }
00159   else if(((*silHead)->Prev == NULL) || ((*silHead)->Prev == *silHead))
00160   {
00161     SilNodeDelete(*silHead);
00162     return;
00163   }
00164   else
00165   {
00166     silTemp = (*silHead)->Prev;
00167   }
00168 
00169   while(silTemp != *silHead)
00170   {
00171     SilNodeDelete(silTemp);
00172     silTemp = (*silHead)->Prev;
00173 
00174     ProcessWindowsMessages();
00175   }
00176   SilNodeDelete(silTemp);
00177 }
00178 
00179 void DeleteWinRegKey(HKEY hkRootKey, LPSTR szKey, BOOL bAbsoluteDelete)
00180 {
00181   HKEY      hkResult;
00182   DWORD     dwErr;
00183   DWORD     dwTotalSubKeys;
00184   DWORD     dwTotalValues;
00185   DWORD     dwSubKeySize;
00186   FILETIME  ftLastWriteFileTime;
00187   char      szSubKey[MAX_BUF];
00188   char      szNewKey[MAX_BUF];
00189   long      lRv;
00190 
00191   dwErr = RegOpenKeyEx(hkRootKey, szKey, 0, KEY_QUERY_VALUE, &hkResult);
00192   if(dwErr == ERROR_SUCCESS)
00193   {
00194     dwTotalSubKeys = 0;
00195     dwTotalValues  = 0;
00196     RegQueryInfoKey(hkResult, NULL, NULL, NULL, &dwTotalSubKeys, NULL, NULL, &dwTotalValues, NULL, NULL, NULL, NULL);
00197     RegCloseKey(hkResult);
00198 
00199     if(((dwTotalSubKeys == 0) && (dwTotalValues == 0)) || bAbsoluteDelete)
00200     {
00201       if(dwTotalSubKeys && bAbsoluteDelete)
00202       {
00203         do
00204         {
00205           dwSubKeySize = sizeof(szSubKey);
00206           lRv = 0;
00207           if(RegOpenKeyEx(hkRootKey, szKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS)
00208           {
00209             if((lRv = RegEnumKeyEx(hkResult, 0, szSubKey, &dwSubKeySize, NULL, NULL, NULL, &ftLastWriteFileTime)) == ERROR_SUCCESS)
00210             {
00211               RegCloseKey(hkResult);
00212               lstrcpy(szNewKey, szKey);
00213               AppendBackSlash(szNewKey, sizeof(szNewKey));
00214               lstrcat(szNewKey, szSubKey);
00215               DeleteWinRegKey(hkRootKey, szNewKey, bAbsoluteDelete);
00216             }
00217             else
00218               RegCloseKey(hkResult);
00219           }
00220         } while(lRv != ERROR_NO_MORE_ITEMS);
00221       }
00222 
00223       dwErr = RegDeleteKey(hkRootKey, szKey);
00224     }
00225   }
00226 }
00227 
00228 void ParseForUninstallCommand(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwFileBufSize, LPSTR szParam, DWORD dwParamBufSize)
00229 {
00230   LPSTR   szFirstNonSpace;
00231   LPSTR   szBeginParamStr;
00232   LPSTR   szEndOfFilePath;
00233   LPSTR   szEndQuote;
00234   char    *cmdStart;
00235   int     length;
00236 
00237   ZeroMemory(szFile, dwFileBufSize);
00238   ZeroMemory(szParam, dwParamBufSize);
00239 
00240   length = lstrlen(szString);
00241   if(szString[length - 1] == '\n')
00242     szString[length - 1] = '\0';
00243 
00244   // get to the beginning of the command given an install log string
00245   cmdStart = szString + lstrlen(szKeyStr);
00246   if((szFirstNonSpace = GetFirstNonSpace(cmdStart)) != NULL)
00247   {
00248     if(*szFirstNonSpace == '\"')
00249     {
00250       ++szFirstNonSpace;
00251       // found a beginning quote, look for the ending quote now
00252       if((szEndQuote = MozStrChar(szFirstNonSpace, '\"')) != NULL)
00253       {
00254         // found ending quote. copy file path string *not* including the quotes
00255         *szEndQuote = '\0';
00256         MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize);
00257 
00258         // get the params substring now
00259         if((szBeginParamStr = GetFirstNonSpace(++szEndQuote)) != NULL)
00260         {
00261           // the params string should be the first non space char after the
00262           // quoted file path string to the end of the string.
00263           MozCopyStr(szBeginParamStr, szParam, dwParamBufSize);
00264         }
00265       }
00266       else
00267       {
00268         // could not find the ending quote.  assume the _entire_ string is the file path
00269         MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize);
00270       }
00271     }
00272     else
00273     {
00274       // no beginning quote found.  file path is up to the first space character found
00275       if((szEndOfFilePath = GetFirstSpace(szFirstNonSpace)) != NULL)
00276       {
00277         // found the first space char
00278         *szEndOfFilePath = '\0';
00279         MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize);
00280 
00281         // get the params substring now
00282         if((szBeginParamStr = GetFirstNonSpace(++szEndOfFilePath)) != NULL)
00283         {
00284           // the params string should be the first non space char after the
00285           // quoted file path string to the end of the string.
00286           MozCopyStr(szBeginParamStr, szParam, dwParamBufSize);
00287         }
00288       }
00289       else
00290       {
00291         // no space char found. assume the _entire_ string is the file path
00292         MozCopyStr(szFirstNonSpace, szFile, dwFileBufSize);
00293       }
00294     }
00295   }
00296 }
00297 
00298 void ParseForFile(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwShortFilenameBufSize)
00299 {
00300   int     iLen;
00301   LPSTR   szFirstNonSpace;
00302   char    szBuf[MAX_BUF];
00303 
00304   if((szFirstNonSpace = GetFirstNonSpace(&(szString[lstrlen(szKeyStr)]))) != NULL)
00305   {
00306     iLen = lstrlen(szFirstNonSpace);
00307     if(szFirstNonSpace[iLen - 1] == '\n')
00308       szFirstNonSpace[iLen -1] = '\0';
00309 
00310     if(lstrcmpi(szKeyStr, KEY_WINDOWS_SHORTCUT) == 0)
00311     {
00312       lstrcpy(szBuf, szFirstNonSpace);
00313       lstrcat(szBuf, ".lnk");
00314       szFirstNonSpace = szBuf;
00315     }
00316 
00317     lstrcpy(szFile, szFirstNonSpace);
00318   }
00319 }
00320 
00321 void ParseForCopyFile(LPSTR szString, LPSTR szKeyStr, LPSTR szFile, DWORD dwShortFilenameBufSize)
00322 {
00323   int     iLen;
00324   LPSTR   szFirstNonSpace;
00325   LPSTR   szSubStr = NULL;
00326   char    szBuf[MAX_BUF];
00327 
00328   if((szSubStr = strstr(szString, " to ")) != NULL)
00329   {
00330     if((szFirstNonSpace = GetFirstNonSpace(&(szSubStr[lstrlen(" to ")]))) != NULL)
00331     {
00332       iLen = lstrlen(szFirstNonSpace);
00333       if(szFirstNonSpace[iLen - 1] == '\n')
00334         szFirstNonSpace[iLen -1] = '\0';
00335 
00336       if(lstrcmpi(szKeyStr, KEY_WINDOWS_SHORTCUT) == 0)
00337       {
00338         lstrcpy(szBuf, szFirstNonSpace);
00339         lstrcat(szBuf, ".lnk");
00340         szFirstNonSpace = szBuf;
00341       }
00342 
00343     lstrcpy(szFile, szFirstNonSpace);
00344     }
00345   }
00346 }
00347 
00348 HRESULT ParseForWinRegInfo(LPSTR szString, LPSTR szKeyStr, LPSTR szRootKey, DWORD dwRootKeyBufSize, LPSTR szKey, DWORD dwKeyBufSize, LPSTR szName, DWORD dwNameBufSize)
00349 {
00350   int     i;
00351   int     iLen;
00352   int     iBrackets;
00353   char    szStrCopy[MAX_BUF];
00354   LPSTR   szFirstNonSpace;
00355   LPSTR   szFirstBackSlash;
00356   BOOL    bFoundOpenBracket;
00357   BOOL    bFoundName;
00358 
00359   *szRootKey = '\0';
00360   *szKey = '\0';
00361   *szName = '\0';
00362 
00363   lstrcpy(szStrCopy, szString);
00364   if((szFirstNonSpace = GetFirstNonSpace(&(szStrCopy[lstrlen(szKeyStr)]))) != NULL)
00365   {
00366     iLen = lstrlen(szFirstNonSpace);
00367     if(szFirstNonSpace[iLen - 1] == '\n')
00368     {
00369       szFirstNonSpace[--iLen] = '\0';
00370     }
00371 
00372     szFirstBackSlash = strstr(szFirstNonSpace, "\\");
00373     if(!szFirstBackSlash)
00374       return(WIZ_ERROR_PARSING_UNINST_STRS);
00375 
00376     szFirstBackSlash[0] = '\0';
00377     lstrcpy(szRootKey, szFirstNonSpace);
00378     szFirstNonSpace = &(szFirstBackSlash[1]);
00379     iLen = lstrlen(szFirstNonSpace);
00380 
00381     iBrackets         = 0;
00382     bFoundName        = FALSE;
00383     bFoundOpenBracket = FALSE;
00384     for(i = iLen - 1; i >= 0; i--)
00385     {
00386       if(bFoundName == FALSE)
00387       {
00388         /* Find the Name created in the Windows registry key.
00389          * Since the Name can contain '[' and ']', we have to
00390          * parse for the brackets that denote the Name string in
00391          * szFirstNonSpace.  It parses from right to left.
00392          */
00393         if(szFirstNonSpace[i] == ']')
00394         {
00395           if(iBrackets == 0)
00396             szFirstNonSpace[i] = '\0';
00397 
00398           ++iBrackets;
00399         }
00400         else if(szFirstNonSpace[i] == '[')
00401         {
00402           bFoundOpenBracket = TRUE;
00403           --iBrackets;
00404         }
00405 
00406         if((bFoundOpenBracket) && (iBrackets == 0))
00407         {
00408           lstrcpy(szName, &(szFirstNonSpace[i + 1]));
00409           bFoundName = TRUE;
00410         }
00411       }
00412       else
00413       {
00414         /* locate the first non space to the left of the last '[' */
00415         if(!isspace(szFirstNonSpace[i]))
00416         {
00417           szFirstNonSpace[i + 1] = '\0';
00418           lstrcpy(szKey, szFirstNonSpace);
00419           break;
00420         }
00421       }
00422     }
00423   }
00424   return(WIZ_OK);
00425 }
00426 
00427 DWORD DecrementSharedFileCounter(char *file)
00428 {
00429   HKEY     keyHandle = 0;
00430   LONG     result;
00431   DWORD    type      = REG_DWORD;
00432   DWORD    valbuf    = 0;
00433   DWORD    valbufsize;
00434   DWORD    rv        = 0;
00435 
00436   valbufsize = sizeof(DWORD);
00437   result     = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, 0, KEY_READ | KEY_WRITE, &keyHandle);
00438   if(ERROR_SUCCESS == result)
00439   {
00440     result = RegQueryValueEx(keyHandle, file, NULL, &type, (LPBYTE)&valbuf, (LPDWORD)&valbufsize);
00441     if((ERROR_SUCCESS == result) && (type == REG_DWORD))
00442       rv = valbuf = ((long)valbuf - 1) < 0 ? 0 : (valbuf - 1);
00443 
00444     RegSetValueEx(keyHandle, file, 0, REG_DWORD, (LPBYTE)&valbuf, valbufsize);
00445     RegCloseKey(keyHandle);
00446   }
00447 
00448   return(rv);
00449 }
00450 
00451 int GetSharedFileCount(char *file)
00452 {
00453   HKEY     keyHandle = 0;
00454   LONG     result;
00455   DWORD    type      = REG_DWORD;
00456   DWORD    valbuf    = 0;
00457   DWORD    valbufsize;
00458   int      rv        = -999;
00459 
00460   valbufsize = sizeof(DWORD);
00461   result     = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, 0, KEY_READ, &keyHandle);
00462   if(ERROR_SUCCESS == result)
00463   {
00464     result = RegQueryValueEx(keyHandle, file, NULL, &type, (LPBYTE)&valbuf, (LPDWORD)&valbufsize);
00465     if((ERROR_SUCCESS == result) && (type == REG_DWORD))
00466       rv = valbuf;
00467 
00468     RegCloseKey(keyHandle);
00469   }
00470 
00471   return(rv);
00472 }
00473 
00474 BOOL UnregisterServer(char *file)
00475 {
00476   FARPROC   DllUnReg;
00477   HINSTANCE hLib;
00478   BOOL      bFailed = FALSE;
00479 
00480   if(file != NULL)
00481   {
00482     if((hLib = LoadLibraryEx(file, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) != NULL)
00483     {
00484       if((DllUnReg = GetProcAddress(hLib, "DllUnregisterServer")) != NULL)
00485         DllUnReg();
00486       else
00487         bFailed = TRUE;
00488 
00489       FreeLibrary(hLib);
00490     }
00491     else
00492       bFailed = TRUE;
00493   }
00494   else
00495     bFailed = TRUE;
00496 
00497   return(bFailed);
00498 }
00499 
00500 BOOL DetermineUnRegisterServer(sil *silInstallLogHead, LPSTR szFile)
00501 {
00502   sil   *silInstallLogTemp;
00503   int   iSharedFileCount;
00504   char  szLCLine[MAX_BUF];
00505   char  szLCFile[MAX_BUF];
00506   BOOL  bRv;
00507 
00508   bRv = FALSE;
00509   if(silInstallLogHead != NULL)
00510   {
00511     silInstallLogTemp = silInstallLogHead;
00512     iSharedFileCount  = GetSharedFileCount(szFile);
00513     lstrcpy(szLCFile, szFile);
00514     CharLowerBuff(szLCFile, sizeof(szLCLine));
00515 
00516     do
00517     {
00518       silInstallLogTemp = silInstallLogTemp->Prev;
00519       lstrcpy(szLCLine, silInstallLogTemp->szLine);
00520       CharLowerBuff(szLCLine, sizeof(szLCLine));
00521 
00522       if((strstr(szLCLine, szLCFile) != NULL) &&
00523          (strstr(szLCLine, KEY_INSTALLING_SHARED_FILE) != NULL) &&
00524          (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00525       {
00526         --iSharedFileCount;
00527       }
00528       else if((strstr(szLCLine, szLCFile) != NULL) &&
00529               (strstr(szLCLine, KEY_INSTALLING) != NULL) &&
00530               (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00531       {
00532         bRv = TRUE;
00533         break;
00534       }
00535       else if((strstr(szLCLine, szLCFile) != NULL) &&
00536               (strstr(szLCLine, KEY_REPLACING_SHARED_FILE) != NULL) &&
00537               (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00538       {
00539         --iSharedFileCount;
00540       }
00541       else if((strstr(szLCLine, szLCFile) != NULL) &&
00542               (strstr(szLCLine, KEY_REPLACING) != NULL) &&
00543               (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00544       {
00545         bRv = TRUE;
00546         break;
00547       }
00548       else if((strstr(szLCLine, szLCFile) != NULL) &&
00549               (strstr(szLCLine, KEY_COPY_FILE) != NULL) &&
00550               (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00551       {
00552         bRv = TRUE;
00553         break;
00554       }
00555 
00556       ProcessWindowsMessages();
00557     } while(silInstallLogTemp != silInstallLogHead);
00558   }
00559 
00560   if((iSharedFileCount <= 0) && (iSharedFileCount != -999))
00561     bRv = TRUE;
00562 
00563   return(bRv);
00564 }
00565 
00566 DWORD Uninstall(sil* silInstallLogHead)
00567 {
00568   sil   *silInstallLogTemp;
00569   LPSTR szSubStr;
00570   char  szLCLine[MAX_BUF];
00571   char  szKey[MAX_BUF];
00572   char  szRootKey[MAX_BUF];
00573   char  szName[MAX_BUF];
00574   char  szFile[MAX_BUF];
00575   char  szParams[MAX_BUF];
00576   HKEY  hkRootKey;
00577   int   rv;
00578 
00579   if(silInstallLogHead != NULL)
00580   {
00581     silInstallLogTemp = silInstallLogHead;
00582     do
00583     {
00584       silInstallLogTemp = silInstallLogTemp->Prev;
00585       lstrcpy(szLCLine, silInstallLogTemp->szLine);
00586       CharLowerBuff(szLCLine, sizeof(szLCLine));
00587 
00588       if(((szSubStr = strstr(szLCLine, KEY_WINDOWS_REGISTER_SERVER)) != NULL) &&
00589           (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00590       {
00591         ParseForFile(szSubStr, KEY_WINDOWS_REGISTER_SERVER, szFile, sizeof(szFile));
00592         if(DetermineUnRegisterServer(silInstallLogHead, szFile) == TRUE)
00593           UnregisterServer(szFile);
00594       }
00595       else if((((szSubStr = strstr(szLCLine, KEY_INSTALLING_SHARED_FILE)) != NULL) ||
00596                ((szSubStr = strstr(szLCLine, KEY_REPLACING_SHARED_FILE)) != NULL)) &&
00597                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00598       {
00599         /* check for "Installing Shared File: " string and delete the file */
00600         ParseForFile(szSubStr, KEY_INSTALLING_SHARED_FILE, szFile, sizeof(szFile));
00601         if(DecrementSharedFileCounter(szFile) == 0)
00602         {
00603           if((gdwWhatToDo != WTD_NO_TO_ALL) && (gdwWhatToDo != WTD_YES_TO_ALL) && FileExists(szFile))
00604           {
00605             MessageBeep(MB_ICONEXCLAMATION);
00606             gdwWhatToDo = DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_WHAT_TO_DO), hDlgUninstall, DlgProcWhatToDo, (LPARAM)szFile);
00607           }
00608 
00609           if((gdwWhatToDo == WTD_YES) || (gdwWhatToDo == WTD_YES_TO_ALL) || !FileExists(szFile))
00610           {
00611             DeleteWinRegValue(HKEY_LOCAL_MACHINE, KEY_SHARED_DLLS, szFile);
00612             DeleteOrDelayUntilReboot(szFile);
00613           }
00614           else if(gdwWhatToDo == WTD_CANCEL)
00615             return(WTD_CANCEL);
00616         }
00617       }
00618       else if(((szSubStr = strstr(szLCLine, KEY_INSTALLING)) != NULL) &&
00619                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00620       {
00621         /* check for "Installing: " string and delete the file */
00622         ParseForFile(szSubStr, KEY_INSTALLING, szFile, sizeof(szFile));
00623         DeleteOrDelayUntilReboot(szFile);
00624       }
00625       else if(((szSubStr = strstr(szLCLine, KEY_REPLACING)) != NULL) &&
00626                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00627       {
00628         /* check for "Replacing: " string and delete the file */
00629         ParseForFile(szSubStr, KEY_REPLACING, szFile, sizeof(szFile));
00630         DeleteOrDelayUntilReboot(szFile);
00631       }
00632       else if(((szSubStr = strstr(szLCLine, KEY_STORE_REG_STRING)) != NULL) &&
00633                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00634       {
00635         /* check for "Store Registry Value String: " string and remove the key */
00636         rv = ParseForWinRegInfo(szSubStr, KEY_STORE_REG_STRING, szRootKey, sizeof(szRootKey), szKey, sizeof(szKey), szName, sizeof(szName));
00637         if(WIZ_OK == rv)
00638         {
00639           hkRootKey = ParseRootKey(szRootKey);
00640           DeleteWinRegValue(hkRootKey, szKey, szName);
00641         }
00642       }
00643       else if(((szSubStr = strstr(szLCLine, KEY_STORE_REG_NUMBER)) != NULL) &&
00644                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00645       {
00646         /* check for "Store Registry Value Number: " string and remove the key */
00647         rv = ParseForWinRegInfo(szSubStr, KEY_STORE_REG_NUMBER, szRootKey, sizeof(szRootKey), szKey, sizeof(szKey), szName, sizeof(szName));
00648         if(WIZ_OK == rv)
00649         {
00650           hkRootKey = ParseRootKey(szRootKey);
00651           DeleteWinRegValue(hkRootKey, szKey, szName);
00652         }
00653       }
00654       else if(((szSubStr = strstr(szLCLine, KEY_CREATE_REG_KEY)) != NULL) &&
00655                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00656       {
00657         rv = ParseForWinRegInfo(szSubStr, KEY_CREATE_REG_KEY, szRootKey, sizeof(szRootKey), szKey, sizeof(szKey), szName, sizeof(szName));
00658         if(WIZ_OK == rv)
00659         {
00660           hkRootKey = ParseRootKey(szRootKey);
00661           DeleteWinRegKey(hkRootKey, szKey, FALSE);
00662         }
00663       }
00664       else if(((szSubStr = strstr(szLCLine, KEY_CREATE_FOLDER)) != NULL) &&
00665                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00666       {
00667         ParseForFile(szSubStr, KEY_CREATE_FOLDER, szFile, sizeof(szFile));
00668         DirectoryRemove(szFile, FALSE);
00669       }
00670       else if(((szSubStr = strstr(szLCLine, KEY_WINDOWS_SHORTCUT)) != NULL) &&
00671                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00672       {
00673         ParseForFile(szSubStr, KEY_WINDOWS_SHORTCUT, szFile, sizeof(szFile));
00674         DeleteOrDelayUntilReboot(szFile);
00675       }
00676       else if(((szSubStr = strstr(szLCLine, KEY_COPY_FILE)) != NULL) &&
00677                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00678       {
00679         /* check for "copy file: " string and delete the file */
00680         ParseForCopyFile(szSubStr, KEY_COPY_FILE, szFile, sizeof(szFile));
00681         DeleteOrDelayUntilReboot(szFile);
00682       }
00683       else if(((szSubStr = strstr(szLCLine, KEY_UNINSTALL_COMMAND)) != NULL) &&
00684                (strstr(szLCLine, KEY_DO_NOT_UNINSTALL) == NULL))
00685       {
00686         ParseForUninstallCommand(szSubStr, KEY_UNINSTALL_COMMAND, szFile, sizeof(szFile), szParams, sizeof(szParams));
00687         //execute szFile with szParams here!
00688         if(FileExists(szFile))
00689             WinSpawn(szFile, szParams, NULL, SW_HIDE, TRUE);
00690       }
00691 
00692       ProcessWindowsMessages();
00693     } while(silInstallLogTemp != silInstallLogHead);
00694   }
00695 
00696   return(0);
00697 }
00698 
00699 DWORD GetLogFile(LPSTR szTargetPath, LPSTR szInFilename, LPSTR szOutBuf, DWORD dwOutBufSize)
00700 {
00701   int             iFilenameOnlyLen;
00702   char            szSearchFilename[MAX_BUF];
00703   char            szSearchTargetFullFilename[MAX_BUF];
00704   char            szFilenameOnly[MAX_BUF];
00705   char            szFilenameExtensionOnly[MAX_BUF];
00706   char            szNumber[MAX_BUF];
00707   long            dwNumber;
00708   long            dwMaxNumber;
00709   LPSTR           szDotPtr;
00710   HANDLE          hFile;
00711   WIN32_FIND_DATA fdFile;
00712   BOOL            bFound;
00713 
00714   if(FileExists(szTargetPath))
00715   {
00716     /* zero out the memory */
00717     ZeroMemory(szOutBuf,                dwOutBufSize);
00718     ZeroMemory(szSearchFilename,        sizeof(szSearchFilename));
00719     ZeroMemory(szFilenameOnly,          sizeof(szFilenameOnly));
00720     ZeroMemory(szFilenameExtensionOnly, sizeof(szFilenameExtensionOnly));
00721 
00722     /* parse for the filename w/o extention and also only the extension */
00723     if((szDotPtr = strstr(szInFilename, ".")) != NULL)
00724     {
00725       *szDotPtr = '\0';
00726       lstrcpy(szSearchFilename, szInFilename);
00727       lstrcpy(szFilenameOnly, szInFilename);
00728       lstrcpy(szFilenameExtensionOnly, &szDotPtr[1]);
00729       *szDotPtr = '.';
00730     }
00731     else
00732     {
00733       lstrcpy(szFilenameOnly, szInFilename);
00734       lstrcpy(szSearchFilename, szInFilename);
00735     }
00736 
00737     /* create the wild arg filename to search for in the szTargetPath */
00738     lstrcat(szSearchFilename, "*.*");
00739     lstrcpy(szSearchTargetFullFilename, szTargetPath);
00740     AppendBackSlash(szSearchTargetFullFilename, sizeof(szSearchTargetFullFilename));
00741     lstrcat(szSearchTargetFullFilename, szSearchFilename);
00742 
00743     iFilenameOnlyLen = lstrlen(szFilenameOnly);
00744     dwNumber         = 0;
00745     dwMaxNumber      = -1;
00746 
00747     /* find the largest numbered filename in the szTargetPath */
00748     if((hFile = FindFirstFile(szSearchTargetFullFilename, &fdFile)) == INVALID_HANDLE_VALUE)
00749       bFound = FALSE;
00750     else
00751       bFound = TRUE;
00752 
00753     while(bFound)
00754     {
00755        ZeroMemory(szNumber, sizeof(szNumber));
00756       if((lstrcmpi(fdFile.cFileName, ".") != 0) && (lstrcmpi(fdFile.cFileName, "..") != 0))
00757       {
00758         lstrcpy(szNumber, &fdFile.cFileName[iFilenameOnlyLen]);
00759         dwNumber = atoi(szNumber);
00760         if(dwNumber > dwMaxNumber)
00761           dwMaxNumber = dwNumber;
00762       }
00763 
00764       bFound = FindNextFile(hFile, &fdFile);
00765     }
00766 
00767     FindClose(hFile);
00768 
00769     lstrcpy(szOutBuf, szTargetPath);
00770     AppendBackSlash(szOutBuf, dwOutBufSize);
00771     lstrcat(szOutBuf, szFilenameOnly);
00772     itoa(dwMaxNumber, szNumber, 10);
00773     lstrcat(szOutBuf, szNumber);
00774 
00775     if(*szFilenameExtensionOnly != '\0')
00776     {
00777       lstrcat(szOutBuf, ".");
00778       lstrcat(szOutBuf, szFilenameExtensionOnly);
00779     }
00780   }
00781   else
00782     return(0);
00783 
00784   return(FileExists(szOutBuf));
00785 }
00786