Back to index

lightning-sunbird  0.9+nobinonly
extra.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Sean Su <ssu@netscape.com>
00025  *
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 "extra.h"
00042 #include "parser.h"
00043 #include "dialogs.h"
00044 #include "ifuncns.h"
00045 
00046 #define INDEX_STR_LEN       10
00047 #define PN_PROCESS          TEXT("Process")
00048 #define PN_THREAD           TEXT("Thread")
00049 
00050 BOOL InitApplication(HMODULE hInstance)
00051 {
00052   CLASSINFO classinfo;
00053 
00054   ulScreenX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
00055   ulScreenY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
00056   ulDlgFrameX = WinQuerySysValue(HWND_DESKTOP, SV_CXDLGFRAME);
00057   ulDlgFrameY = WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME);
00058   ulTitleBarY = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
00059 
00060   WinQueryClassInfo((HAB)0, WC_FRAME, &classinfo);
00061   return (WinRegisterClass((HAB)0, szClassName, WinDefDlgProc,
00062                            CS_SAVEBITS, classinfo.cbWindowData));
00063 }
00064 
00065 void PrintError(PSZ szMsg, ULONG ulErrorCodeSH)
00066 {
00067   ERRORID erridErrorCode;
00068   char  szErrorString[MAX_BUF];
00069 
00070   if(ulErrorCodeSH == ERROR_CODE_SHOW)
00071   {
00072     erridErrorCode = WinGetLastError((HAB)0);
00073     sprintf(szErrorString, "%d : %s", erridErrorCode, szMsg);
00074   }
00075   else
00076     sprintf(szErrorString, "%s", szMsg);
00077 
00078   if((ugUninstall.ulMode != SILENT) && (ugUninstall.ulMode != AUTO))
00079   {
00080     WinMessageBox(HWND_DESKTOP, hWndMain, szErrorString, NULL, 0, MB_ICONEXCLAMATION);
00081   }
00082   else if(ugUninstall.ulMode == AUTO)
00083   {
00084     ShowMessage(szErrorString, TRUE);
00085     DosSleep(5000);
00086     ShowMessage(szErrorString, FALSE);
00087   }
00088 }
00089 
00090 void *NS_GlobalAlloc(ULONG ulMaxBuf)
00091 {
00092   PSZ szBuf = NULL;
00093 
00094   if((szBuf = calloc(1, ulMaxBuf)) == NULL)
00095   {     
00096     if((szEGlobalAlloc == NULL) || (*szEGlobalAlloc == '\0'))
00097       PrintError("Memory allocation error.", ERROR_CODE_HIDE);
00098     else
00099       PrintError(szEGlobalAlloc, ERROR_CODE_SHOW);
00100 
00101     return(NULL);
00102   }
00103   else
00104     return(szBuf);
00105 }
00106 
00107 void FreeMemory(void **vPointer)
00108 {
00109   if(*vPointer != NULL)
00110     free(*vPointer);
00111   *vPointer = NULL;
00112 }
00113 
00114 HRESULT NS_LoadStringAlloc(HMODULE hInstance, ULONG ulID, PSZ *szStringBuf, ULONG ulStringBuf)
00115 {
00116   char szBuf[MAX_BUF];
00117 
00118   if((*szStringBuf = NS_GlobalAlloc(MAX_BUF)) == NULL)
00119     exit(1);
00120   
00121   if(!WinLoadString((HAB)0, hInstance, ulID, ulStringBuf, *szStringBuf))
00122   {
00123     if((szEStringLoad == NULL) ||(*szEStringLoad == '\0'))
00124       sprintf(szBuf, "Could not load string resource ID %d", ulID);
00125     else
00126       sprintf(szBuf, szEStringLoad, ulID);
00127 
00128     PrintError(szBuf, ERROR_CODE_SHOW);
00129     return(1);
00130   }
00131   return(0);
00132 }
00133 
00134 HRESULT NS_LoadString(HMODULE hInstance, ULONG ulID, PSZ szStringBuf, ULONG ulStringBuf)
00135 {
00136   char szBuf[MAX_BUF];
00137 
00138   if(!WinLoadString((HAB)0, hInstance, ulID, ulStringBuf, szStringBuf))
00139   {
00140     if((szEStringLoad == NULL) ||(*szEStringLoad == '\0'))
00141       sprintf(szBuf, "Could not load string resource ID %d", ulID);
00142     else
00143       sprintf(szBuf, szEStringLoad, ulID);
00144 
00145     PrintError(szBuf, ERROR_CODE_SHOW);
00146     return(1);
00147   }
00148   return(WIZ_OK);
00149 }
00150 
00151 HRESULT Initialize(HMODULE hInstance, PSZ szAppName)
00152 {
00153   char szBuf[MAX_BUF];
00154   HWND hwndFW;
00155 
00156   char *tempEnvVar = NULL;
00157 
00158   hDlgMessage = NULL;
00159   gulWhatToDo = WTD_ASK;
00160 
00161 
00162   /* load strings from setup.exe */
00163   if(NS_LoadStringAlloc(0, IDS_ERROR_GLOBALALLOC, &szEGlobalAlloc, MAX_BUF))
00164     return(1);
00165   if(NS_LoadStringAlloc(0, IDS_ERROR_STRING_LOAD, &szEStringLoad,  MAX_BUF))
00166     return(1);
00167   if(NS_LoadStringAlloc(0, IDS_ERROR_DLL_LOAD,    &szEDllLoad,     MAX_BUF))
00168     return(1);
00169   if(NS_LoadStringAlloc(0, IDS_ERROR_STRING_NULL, &szEStringNull,  MAX_BUF))
00170     return(1);
00171 
00172   memset(szBuf, 0, sizeof(MAX_BUF));
00173   if((szClassName = NS_GlobalAlloc(MAX_BUF)) == NULL)
00174     return(1);
00175 
00176   strcpy(szClassName, CLASS_NAME);
00177 
00178 #ifdef OLDCODE
00179   /* Allow only one instance of setup to run.
00180    * Detect a previous instance of setup, bring it to the 
00181    * foreground, and quit current instance */
00182   if((hwndFW = FindWindow(szClassName, szClassName)) != NULL)
00183   {
00184     ShowWindow(hwndFW, SW_RESTORE);
00185     SetForegroundWindow(hwndFW);
00186     return(1);
00187   }
00188 #endif
00189 
00190   if((szUninstallDir = NS_GlobalAlloc(MAX_BUF)) == NULL)
00191     return(1);
00192 
00193   ParsePath(szAppName, szUninstallDir, MAX_BUF, PP_PATH_ONLY);
00194 
00195   if((szTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL)
00196     return(1);
00197 
00198   if((szOSTempDir = NS_GlobalAlloc(MAX_BUF)) == NULL)
00199     return(1);
00200 
00201   if((szFileIniUninstall = NS_GlobalAlloc(MAX_BUF)) == NULL)
00202     return(1);
00203 
00204   strcpy(szFileIniUninstall, szUninstallDir);
00205   AppendBackSlash(szFileIniUninstall, MAX_BUF);
00206   strcat(szFileIniUninstall, FILE_INI_UNINSTALL);
00207 
00208   if((szFileIniDefaultsInfo = NS_GlobalAlloc(MAX_BUF)) == NULL)
00209     return(1);
00210 
00211   strcpy(szFileIniDefaultsInfo, szUninstallDir);
00212   AppendBackSlash(szFileIniDefaultsInfo, MAX_BUF);
00213   GetPrivateProfileString("General", "Defaults Info Filename", "", szBuf, MAX_BUF, szFileIniUninstall);
00214   strcat(szFileIniDefaultsInfo, szBuf);
00215 
00216   // determine the system's TEMP path
00217   tempEnvVar = getenv("TMP");
00218   if ((tempEnvVar) && (!(isFAT(tempEnvVar)))) {
00219     strcpy(szTempDir, tempEnvVar);
00220   }
00221   else
00222   {
00223     tempEnvVar = getenv("TEMP");
00224     if (tempEnvVar)
00225       strcpy(szTempDir, tempEnvVar);
00226   }
00227   if ((!tempEnvVar) || (isFAT(tempEnvVar)))
00228   {
00229     ULONG ulBootDrive = 0;
00230     APIRET rc;
00231     char  buffer[] = " :\\OS2\\";
00232     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00233                     &ulBootDrive, sizeof(ulBootDrive));
00234     buffer[0] = 'A' - 1 + ulBootDrive;
00235     if (isFAT(buffer)) {
00236        /* Try current disk if boot drive is FAT */
00237        ULONG ulDriveNum;
00238        ULONG ulDriveMap;
00239        strcpy(buffer, " :\\");
00240        DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
00241        buffer[0] = 'A' - 1 + ulDriveNum;
00242        if (isFAT(buffer)) {
00243          int i;
00244          for (i = 2; i < 26; i++) {
00245            if ((ulDriveMap<<(31-i)) >> 31) {
00246              buffer[0] = 'A' + i;
00247              if (!(isFAT(buffer))) {
00248                 break;
00249              }
00250            }
00251          }
00252          if (i == 26) {
00253             char szBuf[MAX_BUF];
00254             WinLoadString(0, NULLHANDLE, IDS_ERROR_NO_LONG_FILENAMES, sizeof(szBuf), szBuf);
00255             WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szBuf, NULL, 0, MB_ICONEXCLAMATION);
00256             return(1);
00257          }
00258        }
00259     }
00260     strcpy(szTempDir, buffer);
00261     strcat(szTempDir, "TEMP");
00262   }
00263   strcpy(szOSTempDir, szTempDir);
00264   AppendBackSlash(szTempDir, MAX_BUF);
00265   strcat(szTempDir, WIZ_TEMP_DIR);
00266 
00267   if(!FileExists(szTempDir))
00268   {
00269     AppendBackSlash(szTempDir, MAX_BUF);
00270     CreateDirectoriesAll(szTempDir);
00271     RemoveBackSlash(szTempDir);
00272     if(!FileExists(szTempDir))
00273     {
00274       char szECreateTempDir[MAX_BUF];
00275 
00276       if(GetPrivateProfileString("Messages", "ERROR_CREATE_TEMP_DIR", "",
00277                                  szECreateTempDir, sizeof(szECreateTempDir), 
00278                                  szFileIniUninstall))
00279       {
00280         sprintf(szBuf, szECreateTempDir, szTempDir);
00281         PrintError(szBuf, ERROR_CODE_HIDE);
00282       }
00283       return(1);
00284     }
00285   }
00286 
00287   ugUninstall.bVerbose = FALSE;
00288   ugUninstall.bUninstallFiles = TRUE;
00289 
00290   return(0);
00291 }
00292 
00293 /* Function to remove quotes from a string */
00294 void RemoveQuotes(PSZ szSrc, PSZ szDest, int iDestSize)
00295 {
00296   char *szBegin;
00297 
00298   if(strlen(szSrc) > iDestSize)
00299     return;
00300 
00301   if(*szSrc == '\"')
00302     szBegin = &szSrc[1];
00303   else
00304     szBegin = szSrc;
00305 
00306   strcpy(szDest, szBegin);
00307 
00308   if(szDest[strlen(szDest) - 1] == '\"')
00309     szDest[strlen(szDest) - 1] = '\0';
00310 }
00311 
00312 /* Function to locate the first non space character in a string,
00313  * and return a pointer to it. */
00314 PSZ GetFirstNonSpace(PSZ szString)
00315 {
00316   int   i;
00317   int   iStrLength;
00318 
00319   iStrLength = strlen(szString);
00320 
00321   for(i = 0; i < iStrLength; i++)
00322   {
00323     if(!isspace(szString[i]))
00324       return(&szString[i]);
00325   }
00326 
00327   return(NULL);
00328 }
00329 
00330 void SetUninstallRunMode(PSZ szMode)
00331 {
00332   if(stricmp(szMode, "NORMAL") == 0)
00333     ugUninstall.ulMode = NORMAL;
00334   if(stricmp(szMode, "AUTO") == 0)
00335     ugUninstall.ulMode = AUTO;
00336   if(stricmp(szMode, "SILENT") == 0)
00337     ugUninstall.ulMode = SILENT;
00338 }
00339 
00340 void RemoveBackSlash(PSZ szInput)
00341 {
00342   char  *ptrChar = NULL;
00343 
00344   if(!szInput)
00345     return;
00346 
00347   ptrChar = WinPrevChar(0, 0, 0, szInput, szInput + strlen(szInput));
00348   if (*ptrChar == '\\') {
00349     *ptrChar = '\0';
00350   }
00351 }
00352 
00353 void AppendBackSlash(PSZ szInput, ULONG ulInputSize)
00354 {
00355   if(szInput != NULL)
00356   {
00357     if(*szInput == '\0')
00358     {
00359       if(((ULONG)strlen(szInput) + 1) < ulInputSize)
00360       {
00361         strcat(szInput, "\\");
00362       }
00363     }
00364     else if(szInput[strlen(szInput) - 1] != '\\')
00365     {
00366       if(((ULONG)strlen(szInput) + 1) < ulInputSize)
00367       {
00368         strcat(szInput, "\\");
00369       }
00370     }
00371   }
00372 }
00373 
00374 void RemoveSlash(PSZ szInput)
00375 {
00376   int   iCounter;
00377   ULONG ulInputLen;
00378 
00379   if(szInput != NULL)
00380   {
00381     ulInputLen = strlen(szInput);
00382 
00383     for(iCounter = ulInputLen -1; iCounter >= 0 ; iCounter--)
00384     {
00385       if(szInput[iCounter] == '/')
00386         szInput[iCounter] = '\0';
00387       else
00388         break;
00389     }
00390   }
00391 }
00392 
00393 void AppendSlash(PSZ szInput, ULONG ulInputSize)
00394 {
00395   if(szInput != NULL)
00396   {
00397     if(*szInput == '\0')
00398     {
00399       if(((ULONG)strlen(szInput) + 1) < ulInputSize)
00400       {
00401         strcat(szInput, "/");
00402       }
00403     }
00404     else if(szInput[strlen(szInput) - 1] != '/')
00405     {
00406       if(((ULONG)strlen(szInput) + 1) < ulInputSize)
00407       {
00408         strcat(szInput, "/");
00409       }
00410     }
00411   }
00412 }
00413 
00414 void ParsePath(PSZ szInput, PSZ szOutput, ULONG ulOutputSize, ULONG ulType)
00415 {
00416   int   iCounter;
00417   ULONG ulCounter;
00418   ULONG ulInputLen;
00419   BOOL  bFound;
00420 
00421   if((szInput != NULL) && (szOutput != NULL))
00422   {
00423     bFound        = TRUE;
00424     ulInputLen    = strlen(szInput);
00425     memset(szOutput, 0, ulOutputSize);
00426 
00427     if(ulInputLen < ulOutputSize)
00428     {
00429       switch(ulType)
00430       {
00431         case PP_FILENAME_ONLY:
00432           for(iCounter = ulInputLen - 1; iCounter >= 0; iCounter--)
00433           {
00434             if(szInput[iCounter] == '\\')
00435             {
00436               strcpy(szOutput, &szInput[iCounter + 1]);
00437               bFound = TRUE;
00438               break;
00439             }
00440           }
00441           if(bFound == FALSE)
00442             strcpy(szOutput, szInput);
00443 
00444           break;
00445 
00446         case PP_PATH_ONLY:
00447           for(iCounter = ulInputLen - 1; iCounter >= 0; iCounter--)
00448           {
00449             if(szInput[iCounter] == '\\')
00450             {
00451               strcpy(szOutput, szInput);
00452               szOutput[iCounter + 1] = '\0';
00453               bFound = TRUE;
00454               break;
00455             }
00456           }
00457           if(bFound == FALSE)
00458             strcpy(szOutput, szInput);
00459 
00460           break;
00461 
00462         case PP_ROOT_ONLY:
00463           if(szInput[1] == ':')
00464           {
00465             szOutput[0] = szInput[0];
00466             szOutput[1] = szInput[1];
00467             AppendBackSlash(szOutput, ulOutputSize);
00468           }
00469           else if(szInput[1] == '\\')
00470           {
00471             int iFoundBackSlash = 0;
00472             for(ulCounter = 0; ulCounter < ulInputLen; ulCounter++)
00473             {
00474               if(szInput[ulCounter] == '\\')
00475               {
00476                 szOutput[ulCounter] = szInput[ulCounter];
00477                 ++iFoundBackSlash;
00478               }
00479 
00480               if(iFoundBackSlash == 3)
00481                 break;
00482             }
00483 
00484             if(iFoundBackSlash != 0)
00485               AppendBackSlash(szOutput, ulOutputSize);
00486           }
00487           break;
00488       }
00489     }
00490   }
00491 }
00492 
00493 HRESULT WinSpawn(PSZ szClientName, PSZ szParameters, PSZ szCurrentDir, BOOL bWait)
00494 {
00495   STARTDATA startdata;
00496   PID       pid, endpid;
00497   ULONG     ulSessID;
00498   APIRET rc;
00499   RESULTCODES resultcodes;
00500   ULONG     ulFlags;
00501   
00502   rc = DosQueryAppType(szClientName, &ulFlags);
00503   if (rc == NO_ERROR) {
00504     memset(&startdata, 0, sizeof(STARTDATA));
00505     startdata.Length  = sizeof(STARTDATA);
00506     startdata.PgmName = szClientName;
00507     startdata.PgmInputs = szParameters;
00508     rc = DosStartSession(&startdata, &ulSessID, &pid);
00509     if (rc == NO_ERROR) {
00510       if (bWait) {
00511         DosWaitChild(DCWA_PROCESS, DCWW_NOWAIT, &resultcodes, &endpid, pid);
00512       }
00513       return (TRUE);
00514     }
00515   } else {
00516     CHAR szBuf[CCHMAXPATH];
00517     HOBJECT hobject;
00518     strcpy(szBuf, szCurrentDir);
00519     strcat(szBuf, szClientName);
00520     hobject = WinQueryObject(szBuf);
00521     WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
00522     WinOpenObject(hobject, 0, TRUE); // 0 = OPEN_DEFAULT
00523   }
00524 
00525   return(FALSE);
00526 }
00527 
00528 HRESULT InitDlgUninstall(diU *diDialog)
00529 {
00530   diDialog->bShowDialog = FALSE;
00531   if((diDialog->szTitle = NS_GlobalAlloc(MAX_BUF)) == NULL)
00532     return(1);
00533   if((diDialog->szMessage0 = NS_GlobalAlloc(MAX_BUF)) == NULL)
00534     return(1);
00535 
00536   return(0);
00537 }
00538 
00539 void DeInitDlgUninstall(diU *diDialog)
00540 {
00541   FreeMemory(&(diDialog->szTitle));
00542   FreeMemory(&(diDialog->szMessage0));
00543 }
00544 
00545 HRESULT InitUninstallGeneral()
00546 {
00547   ugUninstall.ulMode = NORMAL;
00548 
00549   if((ugUninstall.szAppPath                 = NS_GlobalAlloc(MAX_BUF)) == NULL)
00550     return(1);
00551   if((ugUninstall.szLogPath                 = NS_GlobalAlloc(MAX_BUF)) == NULL)
00552     return(1);
00553   if((ugUninstall.szLogFilename             = NS_GlobalAlloc(MAX_BUF)) == NULL)
00554     return(1);
00555   if((ugUninstall.szCompanyName             = NS_GlobalAlloc(MAX_BUF)) == NULL)
00556     return(1);
00557   if((ugUninstall.szProductName             = NS_GlobalAlloc(MAX_BUF)) == NULL)
00558     return(1);
00559   if((ugUninstall.szOIKey                   = NS_GlobalAlloc(MAX_BUF)) == NULL)
00560     return(1);
00561   if((ugUninstall.szUserAgent               = NS_GlobalAlloc(MAX_BUF)) == NULL)
00562     return(1);
00563   if((ugUninstall.szDefaultComponent        = NS_GlobalAlloc(MAX_BUF)) == NULL)
00564     return(1);
00565   if((ugUninstall.szOIMainApp               = NS_GlobalAlloc(MAX_BUF)) == NULL)
00566     return(1);
00567   if((ugUninstall.szDescription             = NS_GlobalAlloc(MAX_BUF)) == NULL)
00568     return(1);
00569   if((ugUninstall.szUninstallKeyDescription = NS_GlobalAlloc(MAX_BUF)) == NULL)
00570     return(1);
00571   if((ugUninstall.szUninstallFilename       = NS_GlobalAlloc(MAX_BUF)) == NULL)
00572     return(1);
00573   if((ugUninstall.szAppID                   = NS_GlobalAlloc(MAX_BUF)) == NULL)
00574     return(1);
00575 
00576   return(0);
00577 }
00578 
00579 void DeInitUninstallGeneral()
00580 {
00581   FreeMemory(&(ugUninstall.szAppPath));
00582   FreeMemory(&(ugUninstall.szLogPath));
00583   FreeMemory(&(ugUninstall.szLogFilename));
00584   FreeMemory(&(ugUninstall.szDescription));
00585   FreeMemory(&(ugUninstall.szUninstallKeyDescription));
00586   FreeMemory(&(ugUninstall.szUninstallFilename));
00587   FreeMemory(&(ugUninstall.szUserAgent));
00588   FreeMemory(&(ugUninstall.szDefaultComponent));
00589   FreeMemory(&(ugUninstall.szOIKey));
00590   FreeMemory(&(ugUninstall.szCompanyName));
00591   FreeMemory(&(ugUninstall.szProductName));
00592   FreeMemory(&(ugUninstall.szOIMainApp));
00593   FreeMemory(&(ugUninstall.szAppID));
00594 }
00595 
00596 sil *CreateSilNode()
00597 {
00598   sil *silNode;
00599 
00600   if((silNode = NS_GlobalAlloc(sizeof(struct sInfoLine))) == NULL)
00601     exit(1);
00602 
00603   if((silNode->szLine = NS_GlobalAlloc(MAX_BUF)) == NULL)
00604     exit(1);
00605 
00606   silNode->ullLineNumber = 0;
00607   silNode->Next          = silNode;
00608   silNode->Prev          = silNode;
00609 
00610   return(silNode);
00611 }
00612 
00613 void SilNodeInsert(sil *silHead, sil *silTemp)
00614 {
00615   if(silHead == NULL)
00616   {
00617     silHead          = silTemp;
00618     silHead->Next    = silHead;
00619     silHead->Prev    = silHead;
00620   }
00621   else
00622   {
00623     silTemp->Next           = silHead;
00624     silTemp->Prev           = silHead->Prev;
00625     silHead->Prev->Next     = silTemp;
00626     silHead->Prev           = silTemp;
00627   }
00628 }
00629 
00630 void SilNodeDelete(sil *silTemp)
00631 {
00632   if(silTemp != NULL)
00633   {
00634     silTemp->Next->Prev = silTemp->Prev;
00635     silTemp->Prev->Next = silTemp->Next;
00636     silTemp->Next       = NULL;
00637     silTemp->Prev       = NULL;
00638 
00639     FreeMemory(&(silTemp->szLine));
00640     FreeMemory(&silTemp);
00641   }
00642 }
00643 
00644 ULONG ParseCommandLine(int argc, char *argv[])
00645 {
00646   int   i;
00647 
00648   i     = 0;
00649   while(i < argc)
00650   {
00651     if((stricmp(argv[i], "-ma") == 0) || (stricmp(argv[i], "/ma") == 0))
00652     {
00653       SetUninstallRunMode("AUTO");
00654     }
00655     else if((stricmp(argv[i], "-ms") == 0) || (stricmp(argv[i], "/ms") == 0))
00656     {
00657       SetUninstallRunMode("SILENT");
00658     }
00659     else if((stricmp(argv[i], "-ua") == 0) || (stricmp(argv[i], "/ua") == 0))
00660     {
00661       if((i + 1) < argc) {
00662         i++;
00663         strcpy(ugUninstall.szUserAgent, argv[i]);
00664       }
00665     }
00666     else if((stricmp(argv[i], "-app") == 0) || (stricmp(argv[i], "/app") == 0))
00667     // Set the App ID
00668     {
00669       if((i + 1) < argc) {
00670         i++;
00671         strcpy(ugUninstall.szAppID, argv[i]);
00672       }
00673     }
00674     else if((stricmp(argv[i], "-reg_path") == 0) || (stricmp(argv[i], "/reg_path") == 0))
00675     // Set the alternative Windows registry path
00676     {
00677       if((i + 1) < argc) {
00678         i++;
00679         strcpy(ugUninstall.szOIMainApp, argv[i]);
00680       }
00681     }
00682     else if((stricmp(argv[i], "-v") == 0) || (stricmp(argv[i], "/v") == 0))
00683     // Set Verbose
00684     {
00685       ugUninstall.bVerbose = TRUE;
00686     }
00687 
00688     ++i;
00689   }
00690 }
00691 
00692 #define BUFMIN       8*1024
00693 #define BUFMAX       256*1024
00694 #define BUFDEFAULT 32*1024
00695 
00696 BOOL CheckForProcess(PID pid, PSZ szProcessName, ULONG ulProcessName, PSZ szFQProcessName, ULONG ulFQProcessName)
00697 {
00698 /* Only compile this code if we have the new toolkit */
00699 #ifdef QS_PROCESS
00700   ULONG bufsize = BUFDEFAULT;
00701   QSPTRREC* pbh;
00702   APIRET rc = 0;
00703   CHAR szUpperAppName[CCHMAXPATH] = {0};
00704 
00705   /* Can't call with both - only one or the other */
00706   if (pid && szProcessName) {
00707     return FALSE;
00708   }
00709   if (szProcessName) {
00710     strcpy(szUpperAppName, szProcessName);
00711     strupr(szUpperAppName);
00712   }
00713   do {
00714     pbh = (QSPTRREC*) malloc(bufsize);
00715     if(!pbh) {
00716       if(bufsize <= BUFMIN)
00717         rc = ERROR_NOT_ENOUGH_MEMORY;
00718       else if(rc != ERROR_BUFFER_OVERFLOW)
00719         bufsize /= 2;
00720     } else {
00721       rc = DosQuerySysState(QS_PROCESS | QS_MTE, 0, 0, 0, pbh, bufsize);
00722       if(rc == ERROR_BUFFER_OVERFLOW) {
00723         if(bufsize < BUFMAX) {
00724           free(pbh);
00725           bufsize *= 2;
00726         } else {
00727           rc = ERROR_TOO_MANY_NAMES;    // give up.
00728         }
00729       }
00730     }
00731   } while(rc == ERROR_BUFFER_OVERFLOW);
00732 
00733   if(rc == NO_ERROR) {
00734     QSPREC* ppiLocal = pbh->pProcRec;
00735     while(ppiLocal->RecType == QS_PROCESS) {
00736       QSLREC* pmi = pbh->pLibRec;
00737       while (pmi && pmi->hmte != ppiLocal->hMte)
00738         pmi = (QSLREC*)pmi->pNextRec;
00739       if(pmi) {
00740         if ((szUpperAppName[0] && strstr((char*)pmi->pName, szUpperAppName)) ||
00741            (ppiLocal->pid == pid)) {
00742             if (szFQProcessName)
00743               strcpy(szFQProcessName, (char*)pmi->pName);
00744             if (pbh)
00745               free(pbh);
00746             return TRUE;
00747         }
00748       }
00749       ppiLocal=(QSPREC*)(ppiLocal->pThrdRec+ppiLocal->cTCB);
00750     }
00751   }
00752   if(pbh)
00753     free(pbh);
00754 #endif
00755   return FALSE;
00756 }
00757 
00758 int PreCheckInstance(char *szSection, char *szIniFile, char *szFQProcessName)
00759 {
00760   char  szParameter[MAX_BUF];
00761   char  szPath[MAX_BUF];
00762   ULONG ulCounter = 0;
00763   BOOL  bContinue = TRUE;
00764   char  szExtraCmd[] = "Extra Cmd";
00765   char  szExtraCmdParameter[MAX_BUF];
00766 
00767   do
00768   {
00769     /* Read the win reg key path */
00770     sprintf(szExtraCmdParameter, "%s%d Parameter", szExtraCmd, ulCounter);
00771     GetPrivateProfileString(szSection,
00772                             szExtraCmdParameter,
00773                             "",
00774                             szParameter,
00775                             sizeof(szParameter),
00776                             szIniFile);
00777     if(*szParameter == '\0')
00778     {
00779       bContinue = FALSE;
00780       continue;
00781     }
00782 
00783     ParsePath(szFQProcessName, szPath, sizeof(szPath), PP_PATH_ONLY);
00784 
00785     // we've found a file, so let's execute it and stop.  No need to look
00786     // for other keys to parse.  We only want to do that if the file is
00787     // _not_ found.  This is for when we change the name of the browser
00788     // app file and still need to deal with locating it and calling
00789     // -kill on it. ie.
00790     //   previous name: netscp6.exe
00791     //   new name: netscp.exe
00792     // We only need to call one of them, not both.
00793     bContinue = FALSE;
00794 
00795     /* Run the file */
00796     WinSpawn(szFQProcessName, szParameter, szPath, TRUE);
00797 
00798     /* Even though WinSpawn is suppose to wait for the app to finish, this
00799      * does not really work that way for trying to quit the browser when
00800      * it's in turbo mode, so we wait 2 secs for it to complete. */
00801     DosSleep(2000);
00802     
00803     ++ulCounter;
00804   } while(bContinue);
00805 
00806   return(WIZ_OK);
00807 }
00808 
00809 HRESULT CheckInstances()
00810 {
00811   char  szFQProcessName[CCHMAXPATH];
00812   char  szProcessName[CCHMAXPATH];
00813   char  szSection[MAX_BUF];
00814   char  szClassName[MAX_BUF];
00815   char  szWindowName[MAX_BUF];
00816   char  szMessage[MAX_BUF];
00817   char  szIndex[MAX_BUF];
00818   int   iIndex;
00819   BOOL  bContinue;
00820   HWND  hwndFW;
00821   PSZ   szWN;
00822   PSZ   szCN;
00823   ULONG ulRv0;
00824   ULONG ulRv1;
00825 
00826   bContinue = TRUE;
00827   iIndex    = -1;
00828   while(bContinue)
00829   {
00830     memset(szClassName,  0, sizeof(szClassName));
00831     memset(szWindowName, 0, sizeof(szWindowName));
00832     memset(szMessage,    0, sizeof(szMessage));
00833 
00834     ++iIndex;
00835     _itoa(iIndex, szIndex, 10);
00836     strcpy(szSection, "Check Instance");
00837     strcat(szSection, szIndex);
00838 
00839     GetPrivateProfileString(szSection, "Message", "", szMessage, MAX_BUF, szFileIniUninstall);
00840 
00841     if(GetPrivateProfileString(szSection, "Process Name", "", szProcessName, sizeof(szProcessName), szFileIniUninstall) != 0L)
00842     {
00843       if(*szProcessName != '\0')
00844       {
00845         /* If an instance is found, call PreCheckInstance first */
00846         if(CheckForProcess(0, szProcessName, sizeof(szProcessName), szFQProcessName, sizeof(szFQProcessName)) == TRUE)
00847           PreCheckInstance(szSection, szFileIniUninstall, szFQProcessName);
00848 
00849         if(CheckForProcess(0, szProcessName, sizeof(szProcessName), NULL, 0) == TRUE)
00850         {
00851           if(*szMessage != '\0')
00852           {
00853             switch(ugUninstall.ulMode)
00854             {
00855               case NORMAL:
00856                 switch(WinMessageBox(HWND_DESKTOP, hWndMain, szMessage, NULL, 0, MB_ICONEXCLAMATION | MB_OKCANCEL))
00857                 {
00858                   case MBID_CANCEL:
00859                     /* User selected to cancel Setup */
00860                     return(TRUE);
00861 
00862                   case MBID_RETRY:
00863                   case MBID_OK:
00864                     /* User selected to retry.  Reset counter */
00865                     iIndex = -1;
00866                     break;
00867                 }
00868                 break;
00869 
00870               case AUTO:
00871                 ShowMessage(szMessage, TRUE);
00872                 DosSleep(5000);
00873                 ShowMessage(szMessage, FALSE);
00874 
00875                 /* Setup mode is AUTO.  Show message, timeout, then cancel because we can't allow user to continue */
00876                 return(TRUE);
00877 
00878               case SILENT:
00879                 return(TRUE);
00880             }
00881           }
00882           else
00883           {
00884             /* No message to display.  Assume cancel because we can't allow user to continue */
00885             return(TRUE);
00886           }
00887         }
00888       }
00889 
00890       /* Process Name= key existed, and has been processed, so continue looking for more */
00891       continue;
00892     }
00893 
00894     /* Process Name= key did not exist, so look for other keys */
00895     ulRv0 = GetPrivateProfileString(szSection, "Class Name", "", szClassName, MAX_BUF, szFileIniUninstall);
00896     ulRv1 = GetPrivateProfileString(szSection, "Window Name", "", szWindowName, MAX_BUF, szFileIniUninstall);
00897     if((ulRv0 == 0L) &&
00898        (ulRv1 == 0L))
00899     {
00900       bContinue = FALSE;
00901     }
00902     else if((*szClassName != '\0') || (*szWindowName != '\0'))
00903     {
00904       if(*szClassName == '\0')
00905         szCN = NULL;
00906       else
00907         szCN = szClassName;
00908 
00909       if(*szWindowName == '\0')
00910         szWN = NULL;
00911       else
00912         szWN = szWindowName;
00913 
00914       /* If an instance is found, call PreCheckInstance first. */
00915       if((hwndFW = FindWindow(szCN)) != NULL) {
00916         PID pid;
00917         TID tid;
00918         WinQueryWindowProcess(hwndFW, &pid, &tid);
00919         CheckForProcess(pid, NULL, 0, szFQProcessName, sizeof(szFQProcessName));
00920         PreCheckInstance(szSection, szFileIniUninstall, szFQProcessName);
00921       }
00922 
00923       if((hwndFW = FindWindow(szCN)) != NULL)
00924       {
00925         if(*szMessage != '\0')
00926         {
00927           switch(ugUninstall.ulMode)
00928           {
00929             case NORMAL:
00930               switch(WinMessageBox(HWND_DESKTOP, hWndMain, szMessage, NULL, 0, MB_ICONEXCLAMATION | MB_RETRYCANCEL))
00931               {
00932                 case MBID_CANCEL:
00933                   /* User selected to cancel Setup */
00934                   return(TRUE);
00935 
00936                 case MBID_RETRY:
00937                   /* User selected to retry.  Reset counter */
00938                   iIndex = -1;
00939                   break;
00940               }
00941               break;
00942 
00943             case AUTO:
00944               ShowMessage(szMessage, TRUE);
00945               DosSleep(5000);
00946               ShowMessage(szMessage, FALSE);
00947 
00948               /* Setup mode is AUTO.  Show message, timeout, then cancel because we can't allow user to continue */
00949               return(TRUE);
00950 
00951             case SILENT:
00952               return(TRUE);
00953           }
00954         }
00955         else
00956         {
00957           /* No message to display.  Assume cancel because we can't allow user to continue */
00958           return(TRUE);
00959         }
00960       }
00961     }
00962   }
00963 
00964   return(FALSE);
00965 }
00966 
00967 HRESULT GetAppPath()
00968 {
00969   char szTmpAppPath[MAX_BUF];
00970   char szApp[MAX_BUF];
00971 
00972   if(*ugUninstall.szUserAgent != '\0')
00973   {
00974     sprintf(szApp, "%s %s", ugUninstall.szOIMainApp, ugUninstall.szUserAgent);
00975   }
00976   else
00977   {
00978     strcpy(szApp, ugUninstall.szOIKey);
00979   }
00980 
00981   PrfQueryProfileString(HINI_USERPROFILE, szApp, "PathToExe", "", szTmpAppPath, sizeof(szTmpAppPath));
00982 
00983   if(FileExists(szTmpAppPath))
00984   {
00985     strcpy(ugUninstall.szAppPath, szTmpAppPath);
00986   }
00987 
00988   return(0);
00989 }
00990 
00991 HRESULT GetUninstallLogPath()
00992 {
00993   char szBuf[MAX_BUF];
00994   char szLogFolder[MAX_BUF];
00995   char szApp[MAX_BUF];
00996   char szWindowsUninstallKey[MAX_BUF];
00997   char szErrorMsg[MAX_BUF];
00998   char szEUninstallLogFolder[MAX_BUF];
00999   BOOL bRestrictedAccess;
01000 
01001   if(*ugUninstall.szUserAgent != '\0')
01002   {
01003     sprintf(szApp, "%s %s", ugUninstall.szOIMainApp, ugUninstall.szUserAgent);
01004   }
01005   else
01006   {
01007     strcpy(szApp, ugUninstall.szOIKey);
01008   }
01009 
01010   PrfQueryProfileString(HINI_USERPROFILE, szApp, "Uninstall Log Folder", "", szLogFolder, sizeof(szLogFolder));
01011 
01012   strcpy(ugUninstall.szDescription, ugUninstall.szOIMainApp);
01013 
01014   if(FileExists(szLogFolder) == FALSE)
01015   {
01016     if(GetPrivateProfileString("Messages", "ERROR_UNINSTALL_LOG_FOLDER", "",
01017                                szEUninstallLogFolder, sizeof(szEUninstallLogFolder), 
01018                                szFileIniUninstall))
01019     {
01020       strcpy(szBuf, "\n\n    ");
01021 
01022       strcat(szBuf, szLogFolder);
01023 
01024       strcat(szBuf, "\n");
01025       sprintf(szErrorMsg, szEUninstallLogFolder, szBuf);
01026       PrintError(szErrorMsg, ERROR_CODE_SHOW);
01027     }
01028 
01029     return(1);
01030   }
01031   strcpy(ugUninstall.szLogPath, szLogFolder);
01032 
01033   return(0);
01034 }
01035 
01036 HRESULT ParseUninstallIni(int argc, char *argv[])
01037 {
01038   char szBuf[MAX_BUF];
01039   char szAppCrypted[MAX_BUF];
01040   char szKeyCrypted[MAX_BUF];
01041   char szShowDialog[MAX_BUF];
01042   char fontName[MAX_BUF];
01043   char fontSize[MAX_BUF];
01044   char charSet[MAX_BUF];
01045 
01046   if(InitUninstallGeneral())
01047     return(1);
01048 
01049   strcpy(ugUninstall.szLogFilename, FILE_LOG_INSTALL);
01050 
01051   /* get install Mode information */
01052   GetPrivateProfileString("General", "Run Mode", "", szBuf, MAX_BUF, szFileIniUninstall);
01053   SetUninstallRunMode(szBuf);
01054   ParseCommandLine(argc, argv);
01055 
01056   if(CheckInstances())
01057     return(1);
01058   if(InitDlgUninstall(&diUninstall))
01059     return(1);
01060  
01061   /* get product name description */
01062   GetPrivateProfileString("General", "Company Name", "", ugUninstall.szCompanyName, MAX_BUF, szFileIniUninstall);
01063   GetPrivateProfileString("General", "Product Name", "", ugUninstall.szProductName, MAX_BUF, szFileIniUninstall);
01064 
01065   GetPrivateProfileString("General", "App",          "", szKeyCrypted, MAX_BUF, szFileIniUninstall);
01066   GetPrivateProfileString("General", "Decrypt App",  "", szBuf, MAX_BUF, szFileIniUninstall);
01067   if(stricmp(szBuf, "TRUE") == 0)
01068   {
01069     DecryptString(ugUninstall.szOIKey, szKeyCrypted);
01070   }
01071   else
01072     strcpy(ugUninstall.szOIKey, szKeyCrypted);
01073 
01074   GetPrivateProfileString("General", "Main App",         "", szAppCrypted, MAX_BUF, szFileIniUninstall);
01075   GetPrivateProfileString("General", "Decrypt Main App", "", szBuf, MAX_BUF, szFileIniUninstall);
01076 
01077   // If szOIMainApp is not null then it was set on the command-line and that is
01078   //    what we want to use.
01079   if(*ugUninstall.szOIMainApp == '\0') 
01080   {
01081     if(stricmp(szBuf, "TRUE") == 0)
01082     {
01083       DecryptString(ugUninstall.szOIMainApp, szAppCrypted);
01084     }
01085     else
01086       strcpy(ugUninstall.szOIMainApp, szAppCrypted);
01087   }
01088 
01089   GetPrivateProfileString("General", "Uninstall Filename", "", ugUninstall.szUninstallFilename, MAX_BUF, szFileIniUninstall);
01090 
01091 
01092   /* Uninstall dialog */
01093   GetPrivateProfileString("Dialog Uninstall",       "Show Dialog",  "", szShowDialog,                 MAX_BUF, szFileIniUninstall);
01094   GetPrivateProfileString("Dialog Uninstall",       "Title",        "", diUninstall.szTitle,          MAX_BUF, szFileIniUninstall);
01095   GetPrivateProfileString("Dialog Uninstall",       "Message0",     "", diUninstall.szMessage0,       MAX_BUF, szFileIniUninstall);
01096   if(stricmp(szShowDialog, "TRUE") == 0)
01097     diUninstall.bShowDialog = TRUE;
01098 
01099   switch(ugUninstall.ulMode)
01100   {
01101     case AUTO:
01102     case SILENT:
01103       gulWhatToDo             = WTD_NO_TO_ALL;
01104       diUninstall.bShowDialog = FALSE;
01105       break;
01106   }
01107 
01108   /* get defined font */
01109   GetPrivateProfileString("Dialog Uninstall", "FONTNAME", "", fontName, MAX_BUF, szFileIniUninstall);
01110   GetPrivateProfileString("Dialog Uninstall", "FONTSIZE", "", fontSize, MAX_BUF, szFileIniUninstall);
01111   GetPrivateProfileString("Dialog Uninstall", "CHARSET", "", charSet, MAX_BUF, szFileIniUninstall);
01112   strcpy(ugUninstall.szDefinedFont, fontSize);
01113   strcat(ugUninstall.szDefinedFont, ".");
01114   strcat(ugUninstall.szDefinedFont, fontName);
01115 
01116   GetAppPath();
01117 
01118   ugUninstall.bUninstallFiles = TRUE;
01119 
01120   return(GetUninstallLogPath());
01121 }
01122 
01123 HRESULT DecryptVariable(PSZ szVariable, ULONG ulVariableSize)
01124 {
01125   char szBuf[MAX_BUF];
01126   char szKey[MAX_BUF];
01127   char szName[MAX_BUF];
01128   char szValue[MAX_BUF];
01129 
01130   /* zero out the memory allocations */
01131   memset(szBuf,           0, sizeof(szBuf));
01132   memset(szKey,           0, sizeof(szKey));
01133   memset(szName,          0, sizeof(szName));
01134   memset(szValue,         0, sizeof(szValue));
01135 
01136   if(stricmp(szVariable, "PROGRAMFILESDIR") == 0)
01137   {
01138     /* @MAK Needed for install */
01139   }
01140   else if(stricmp(szVariable, "STARTUP") == 0)
01141   {
01142     HOBJECT hobj;
01143     hobj = WinQueryObject("<WP_STARTUP>");
01144     WinQueryObjectPath(hobj, szVariable, ulVariableSize);
01145   }
01146   else if(stricmp(szVariable, "DESKTOP") == 0)
01147   {
01148     HOBJECT hobj;
01149     hobj = WinQueryObject("<WP_DESKTOP>");
01150     WinQueryObjectPath(hobj, szVariable, ulVariableSize);
01151   }
01152   else if(stricmp(szVariable, "WARPCENTER") == 0)
01153   {
01154     HOBJECT hobj;
01155     hobj = WinQueryObject("<WP_WARPCENTER????>");
01156     WinQueryObjectPath(hobj, szVariable, ulVariableSize);
01157   }
01158   else if(stricmp(szVariable, "WIZTEMP") == 0)
01159   {
01160     /* parse for the "c:\Temp" path */
01161     strcpy(szVariable, szTempDir);
01162     if(szVariable[strlen(szVariable) - 1] == '\\')
01163       szVariable[strlen(szVariable) - 1] = '\0';
01164   }
01165   else if(stricmp(szVariable, "TEMP") == 0)
01166   {
01167     /* parse for the "c:\Temp" path */
01168     strcpy(szVariable, szOSTempDir);
01169     if(szVariable[strlen(szVariable) - 1] == '\\')
01170       szVariable[strlen(szVariable) - 1] = '\0';
01171   }
01172   else if(stricmp(szVariable, "OS2DISK") == 0)
01173   {
01174     /* Locate the drive that OS/2 is installed on, and only use the drive letter and the ':' character (C:). */
01175     ULONG ulBootDrive = 0;
01176     memset(szVariable, '\0', MAX_BUF);
01177     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
01178                     &ulBootDrive, sizeof(ulBootDrive));
01179     szVariable[0] = 'A' - 1 + ulBootDrive;
01180     szVariable[1] = ':';
01181   }
01182   else if(stricmp(szVariable, "OS2DIR") == 0)
01183   {
01184     /* Locate the "OS2" directory */
01185     ULONG ulBootDrive = 0;
01186     APIRET rc;
01187     char  buffer[] = " :\\OS2\\";
01188     DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
01189                     &ulBootDrive, sizeof(ulBootDrive));
01190     buffer[0] = 'A' - 1 + ulBootDrive;
01191     strcpy(szVariable, buffer);
01192   }
01193   else if(stricmp(szVariable, "JRE BIN PATH") == 0)
01194   {
01195   }
01196   else if(stricmp(szVariable, "JRE PATH") == 0)
01197   {
01198   }
01199   else if(stricmp(szVariable, "UNINSTALL STARTUP PATH") == 0)
01200   {
01201     strcpy(szVariable, szUninstallDir);
01202   }
01203   else if(stricmp(szVariable, "Product CurrentVersion") == 0)
01204   {
01205     char szApp[MAX_BUF];
01206 
01207     sprintf(szApp, "%s", ugUninstall.szProductName);
01208 
01209     /* parse for the current Netscape INI entry */
01210     PrfQueryProfileString(HINI_USERPROFILE, szApp, "CurrentVersion", "",
01211                           szBuf, sizeof(szBuf));
01212 
01213     if(*szBuf == '\0')
01214       return(FALSE);
01215 
01216     strcpy(szVariable, szBuf);
01217   }
01218   else if(stricmp(szVariable, "Product OS2INIApp") == 0)
01219   {
01220     sprintf(szVariable, "%s", ugUninstall.szProductName);
01221   }
01222   else
01223     return(FALSE);
01224 
01225   return(TRUE);
01226 }
01227 
01228 HRESULT DecryptString(PSZ szOutputStr, PSZ szInputStr)
01229 {
01230   ULONG ulLenInputStr;
01231   ULONG ulCounter;
01232   ULONG ulVar;
01233   ULONG ulPrepend;
01234   char  szBuf[MAX_BUF];
01235   char  szVariable[MAX_BUF];
01236   char  szPrepend[MAX_BUF];
01237   char  szAppend[MAX_BUF];
01238   char  szResultStr[MAX_BUF];
01239   BOOL  bFoundVar;
01240   BOOL  bBeginParse;
01241   BOOL  bDecrypted;
01242 
01243   /* zero out the memory addresses */
01244   memset(szBuf,       '\0', MAX_BUF);
01245   memset(szVariable,  '\0', MAX_BUF);
01246   memset(szPrepend,   '\0', MAX_BUF);
01247   memset(szAppend,    '\0', MAX_BUF);
01248   memset(szResultStr, '\0', MAX_BUF);
01249 
01250   strcpy(szPrepend, szInputStr);
01251   ulLenInputStr = strlen(szInputStr);
01252   bBeginParse   = FALSE;
01253   bFoundVar     = FALSE;
01254 
01255   for(ulCounter = 0; ulCounter < ulLenInputStr; ulCounter++)
01256   {
01257     if((szInputStr[ulCounter] == ']') && bBeginParse)
01258       break;
01259 
01260     if(bBeginParse)
01261       szVariable[ulVar++] = szInputStr[ulCounter];
01262 
01263     if((szInputStr[ulCounter] == '[') && !bBeginParse)
01264     {
01265       ulVar        = 0;
01266       ulPrepend    = ulCounter;
01267       bBeginParse  = TRUE;
01268     }
01269   }
01270 
01271   if(ulCounter == ulLenInputStr)
01272     /* did not find anything to expand. */
01273     ulCounter = 0;
01274   else
01275   {
01276     bFoundVar = TRUE;
01277     ++ulCounter;
01278   }
01279 
01280   if(bFoundVar)
01281   {
01282     strcpy(szAppend, &szInputStr[ulCounter]);
01283 
01284     szPrepend[ulPrepend] = '\0';
01285 
01286     bDecrypted = DecryptVariable(szVariable, MAX_BUF);
01287     if(!bDecrypted)
01288     {
01289       /* Variable was not able to be decrypted. */
01290       /* Leave the variable as it was read in by adding the '[' and ']' */
01291       /* characters back to the variable. */
01292       strcpy(szBuf, "[");
01293       strcat(szBuf, szVariable);
01294       strcat(szBuf, "]");
01295       strcpy(szVariable, szBuf);
01296     }
01297 
01298     strcpy(szOutputStr, szPrepend);
01299     strcat(szOutputStr, szVariable);
01300     strcat(szOutputStr, szAppend);
01301 
01302     if(bDecrypted)
01303     {
01304       DecryptString(szResultStr, szOutputStr);
01305       strcpy(szOutputStr, szResultStr);
01306     }
01307   }
01308   else
01309     strcpy(szOutputStr, szInputStr);
01310 
01311   return(TRUE);
01312 }
01313 
01314 #define S_IFMT (S_IFDIR | S_IFREG)
01315 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
01316 
01317 HRESULT FileExists(PSZ szFile)
01318 {
01319   struct stat st;
01320   int statrv;
01321 
01322   statrv = stat(szFile, &st);
01323   if (statrv == 0)
01324      if (S_ISDIR(st.st_mode))
01325         return FILE_DIRECTORY;
01326      else
01327         return(TRUE);
01328   else if ((strlen(szFile) == 2) && (szFile[1] == ':'))
01329   {
01330      char temp[4] = {0};
01331      strcpy(temp, szFile);
01332      strcat(temp, "\\");
01333      statrv = stat(temp, &st);
01334      if (statrv == 0)
01335         return FILE_DIRECTORY;
01336   }
01337   return (FALSE);
01338 }
01339 
01340 BOOL isFAT(char* szPath)
01341 {
01342   APIRET rc;
01343   ULONG ulSize;
01344   PFSQBUFFER2 pfsqbuf2;
01345   CHAR szDrive[3];
01346 
01347   ulSize = sizeof(FSQBUFFER2) + 3 * CCHMAXPATH;
01348   pfsqbuf2 = (PFSQBUFFER2)malloc(ulSize);
01349   strncpy(szDrive, szPath, 2);
01350   szDrive[2] = '\0';
01351 
01352   DosError(FERR_DISABLEHARDERR);
01353   rc = DosQueryFSAttach(szDrive, 0, FSAIL_QUERYNAME,
01354                         pfsqbuf2, &ulSize);
01355   DosError(FERR_ENABLEHARDERR);
01356 
01357   if (rc == NO_ERROR) {
01358     if (strcmp(pfsqbuf2->szFSDName + pfsqbuf2->cbName, "FAT") != 0)
01359       return FALSE;
01360   }
01361 
01362   return TRUE;
01363 }
01364 
01365 void DeInitialize()
01366 {
01367   DeInitDlgUninstall(&diUninstall);
01368   DeInitUninstallGeneral();
01369 
01370   FreeMemory(&szTempDir);
01371   FreeMemory(&szOSTempDir);
01372   FreeMemory(&szUninstallDir);
01373   FreeMemory(&szEGlobalAlloc);
01374   FreeMemory(&szEDllLoad);
01375   FreeMemory(&szEStringLoad);
01376   FreeMemory(&szEStringNull);
01377   FreeMemory(&szFileIniUninstall);
01378   FreeMemory(&szFileIniDefaultsInfo);
01379 }
01380 
01381 HWND FindWindow(PCSZ pszAtomString)
01382 {
01383   ATOM atom;
01384   HENUM henum;
01385   HWND hwndClient, hwnd = NULLHANDLE;
01386 
01387 
01388   atom = WinFindAtom(WinQuerySystemAtomTable(), pszAtomString);
01389   if (atom) {
01390     henum = WinBeginEnumWindows(HWND_DESKTOP);
01391     while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
01392     {
01393       ULONG ulWindowWord;
01394       ulWindowWord = WinQueryWindowULong(hwnd, QWL_USER);
01395       if (ulWindowWord == atom) {
01396         break;
01397       } else {
01398         /* Try the class name method to support older browsers */
01399         HWND hwndClient;
01400         CHAR szClassName[MAX_BUF];
01401         hwndClient = WinWindowFromID(hwnd, FID_CLIENT);
01402         WinQueryClassName(hwndClient ? hwndClient : hwnd, MAX_BUF, szClassName);
01403         if (strcmp(szClassName, pszAtomString) == 0) {
01404            break;
01405         }
01406       }
01407     }
01408     WinEndEnumWindows(henum);
01409   }
01410   if (!hwnd) {
01411      /* Try the object windows just in case, but only for the classname */
01412     henum = WinBeginEnumWindows(HWND_OBJECT);
01413     while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
01414     {
01415       /* Try the class name method to support older browsers */
01416       HWND hwndClient;
01417       CHAR szClassName[MAX_BUF];
01418       hwndClient = WinWindowFromID(hwnd, FID_CLIENT);
01419       WinQueryClassName(hwndClient ? hwndClient : hwnd, MAX_BUF, szClassName);
01420       if (strcmp(szClassName, pszAtomString) == 0) {
01421          break;
01422       }
01423     }
01424   }
01425   return  hwnd;
01426 }
01427