Back to index

lightning-sunbird  0.9+nobinonly
xpi.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 "dialogs.h"
00042 #include "extra.h"
00043 #include "xpistub.h"
00044 #include "xpi.h"
00045 #include "xperr.h"
00046 #include "logging.h"
00047 #include "ifuncns.h"
00048 
00049 #define BDIR_RIGHT 1
00050 #define BDIR_LEFT  2
00051 
00052 typedef HRESULT (_Optlink *XpiInit)(const char *, const char *aLogName, pfnXPIProgress);
00053 typedef HRESULT (_Optlink *XpiInstall)(const char *, const char *, long);
00054 typedef void    (_Optlink *XpiExit)(void);
00055 
00056 static XpiInit          pfnXpiInit;
00057 static XpiInstall       pfnXpiInstall;
00058 static XpiExit          pfnXpiExit;
00059 
00060 static DWORD            dwCurrentArchive;
00061 static DWORD            dwTotalArchives;
00062 char                    szStrProcessingFile[MAX_BUF];
00063 char                    szStrCopyingFile[MAX_BUF];
00064 char                    szStrInstalling[MAX_BUF];
00065 
00066 static void UpdateGaugeArchiveProgressBar(unsigned value);
00067 
00068 struct ExtractFilesDlgInfo
00069 {
00070        HWND   hWndDlg;
00071        int           nMaxFileBars;     // maximum number of bars that can be displayed
00072        int           nMaxArchiveBars;     // maximum number of bars that can be displayed
00073        int           nArchiveBars;          // current number of bars to display
00074 } dlgInfo;
00075 
00076 HRESULT InitializeXPIStub()
00077 {
00078   char szBuf[MAX_BUF];
00079   char szXPIStubFile[MAX_BUF];
00080   char szEDosQueryProcAddr[MAX_BUF];
00081   APIRET rc;
00082 
00083   hXPIStubInst = NULL;
00084 
00085   if(!GetPrivateProfileString("Messages", "ERROR_DOSQUERYPROCADDR", "", szEDosQueryProcAddr, sizeof(szEDosQueryProcAddr), szFileIniInstall))
00086     return(1);
00087 
00088   /* change current directory to where xpistub.dll */
00089   /* change current directory to where xpistub.dll */
00090   strcpy(szBuf, siCFXpcomFile.szDestination);
00091   AppendBackSlash(szBuf, sizeof(szBuf));
00092   strcat(szBuf, "bin");
00093   chdir(szBuf);
00094 
00095   /* Set LIBPATHSTRICT */
00096   DosSetExtLIBPATH("T", LIBPATHSTRICT);
00097 
00098   /* Add it to LIBPATH */
00099   DosSetExtLIBPATH(szBuf, BEGIN_LIBPATH);
00100 
00101   /* build full path to xpistub.dll */
00102   strcpy(szXPIStubFile, szBuf);
00103   AppendBackSlash(szXPIStubFile, sizeof(szXPIStubFile));
00104   strcat(szXPIStubFile, "xpistub.dll");
00105 
00106   if(FileExists(szXPIStubFile) == FALSE)
00107     return(2);
00108 
00109   /* load xpistub.dll */
00110   if (DosLoadModule(NULL, 0, szXPIStubFile, &hXPIStubInst) != NO_ERROR)
00111   {
00112     sprintf(szBuf, szEDllLoad, szXPIStubFile);
00113     PrintError(szBuf, ERROR_CODE_SHOW);
00114     return(1);
00115   }
00116   if(DosQueryProcAddr(hXPIStubInst, 0, "_XPI_Init", &pfnXpiInit) != NO_ERROR)
00117   {
00118     sprintf(szBuf, szEDosQueryProcAddr, "_XPI_Init");
00119     PrintError(szBuf, ERROR_CODE_SHOW);
00120     return(1);
00121   }
00122   if(DosQueryProcAddr(hXPIStubInst, 0, "_XPI_Install", &pfnXpiInstall) != NO_ERROR)
00123   {
00124     sprintf(szBuf, szEDosQueryProcAddr, "_XPI_Install");
00125     PrintError(szBuf, ERROR_CODE_SHOW);
00126     return(1);
00127   }
00128   if(DosQueryProcAddr(hXPIStubInst, 0, "_XPI_Exit", &pfnXpiExit) != NO_ERROR)
00129   {
00130     sprintf(szBuf, szEDosQueryProcAddr, "_XPI_Exit");
00131     PrintError(szBuf, ERROR_CODE_SHOW);
00132     return(1);
00133   }
00134 
00135   return(0);
00136 }
00137 
00138 HRESULT DeInitializeXPIStub()
00139 {
00140   pfnXpiInit    = NULL;
00141   pfnXpiInstall = NULL;
00142   pfnXpiExit    = NULL;
00143 
00144   if(hXPIStubInst)
00145     DosFreeModule(hXPIStubInst);
00146 
00147   chdir(szSetupDir);
00148   return(0);
00149 }
00150 
00151 void GetTotalArchivesToInstall(void)
00152 {
00153   DWORD     dwIndex0;
00154   siC       *siCObject = NULL;
00155 
00156   dwIndex0        = 0;
00157   dwTotalArchives = 0;
00158   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00159   while(siCObject)
00160   {
00161     if((siCObject->dwAttributes & SIC_SELECTED) && !(siCObject->dwAttributes & SIC_LAUNCHAPP))
00162       ++dwTotalArchives;
00163 
00164     ++dwIndex0;
00165     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00166   }
00167 }
00168 
00169 char *GetErrorString(DWORD dwError, char *szErrorString, DWORD dwErrorStringSize)
00170 {
00171   int  i = 0;
00172   char szErrorNumber[MAX_BUF];
00173 
00174   memset(szErrorString, 0, dwErrorStringSize);
00175   _itoa(dwError, szErrorNumber, 10);
00176 
00177   /* map the error value to a string */
00178   while(TRUE)
00179   {
00180     if(*XpErrorList[i] == '\0')
00181       break;
00182 
00183     if(stricmp(szErrorNumber, XpErrorList[i]) == 0)
00184     {
00185       if(*XpErrorList[i + 1] != '\0')
00186         strcpy(szErrorString, XpErrorList[i + 1]);
00187 
00188       break;
00189     }
00190 
00191     ++i;
00192   }
00193 
00194   return(szErrorString);
00195 }
00196 
00197 HRESULT SmartUpdateJars()
00198 {
00199   DWORD     dwIndex0;
00200   siC       *siCObject = NULL;
00201   HRESULT   hrResult;
00202   char      szBuf[MAX_BUF];
00203   char      szEXpiInstall[MAX_BUF];
00204   char      szArchive[MAX_BUF];
00205   char      szMsgSmartUpdateStart[MAX_BUF];
00206   char      szDlgExtractingTitle[MAX_BUF];
00207 
00208   if(!GetPrivateProfileString("Messages", "MSG_SMARTUPDATE_START", "", szMsgSmartUpdateStart, sizeof(szMsgSmartUpdateStart), szFileIniInstall))
00209     return(1);
00210   if(!GetPrivateProfileString("Messages", "DLG_EXTRACTING_TITLE", "", szDlgExtractingTitle, sizeof(szDlgExtractingTitle), szFileIniInstall))
00211     return(1);
00212   if(!GetPrivateProfileString("Messages", "STR_PROCESSINGFILE", "", szStrProcessingFile, sizeof(szStrProcessingFile), szFileIniInstall))
00213     exit(1);
00214   if(!GetPrivateProfileString("Messages", "STR_INSTALLING", "", szStrInstalling, sizeof(szStrInstalling), szFileIniInstall))
00215     exit(1);
00216   if(!GetPrivateProfileString("Messages", "STR_COPYINGFILE", "", szStrCopyingFile, sizeof(szStrCopyingFile), szFileIniInstall))
00217     exit(1);
00218 
00219   ShowMessage(szMsgSmartUpdateStart, TRUE);
00220   if(InitializeXPIStub() == WIZ_OK)
00221   {
00222     LogISXPInstall(W_START);
00223     strcpy(szBuf, sgProduct.szPath);
00224     if(*sgProduct.szSubPath != '\0')
00225     {
00226       AppendBackSlash(szBuf, sizeof(szBuf));
00227       strcat(szBuf, sgProduct.szSubPath);
00228     }
00229     hrResult = pfnXpiInit(szBuf, FILE_INSTALL_LOG, cbXPIProgress);
00230 
00231     /* Unset LIBPATHSTRICT */
00232     DosSetExtLIBPATH("F", LIBPATHSTRICT);
00233 
00234     ShowMessage(szMsgSmartUpdateStart, FALSE);
00235     InitProgressDlg();
00236     GetTotalArchivesToInstall();
00237     WinSetWindowText(dlgInfo.hWndDlg, szDlgExtractingTitle);
00238 
00239     dwIndex0          = 0;
00240     dwCurrentArchive  = 0;
00241     siCObject         = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00242     while(siCObject)
00243     {
00244       if(siCObject->dwAttributes & SIC_SELECTED)
00245         /* Since the archive is selected, we need to process the file ops here */
00246          ProcessFileOps(T_PRE_ARCHIVE, siCObject->szReferenceName);
00247 
00248       /* launch smartupdate engine for earch jar to be installed */
00249       if((siCObject->dwAttributes & SIC_SELECTED)   &&
00250         !(siCObject->dwAttributes & SIC_LAUNCHAPP) &&
00251         !(siCObject->dwAttributes & SIC_DOWNLOAD_ONLY))
00252       {
00253         strcpy(szArchive, sgProduct.szAlternateArchiveSearchPath);
00254         AppendBackSlash(szArchive, sizeof(szArchive));
00255         strcat(szArchive, siCObject->szArchiveName);
00256         if((*sgProduct.szAlternateArchiveSearchPath == '\0') || (!FileExists(szArchive)))
00257         {
00258           strcpy(szArchive, szSetupDir);
00259           AppendBackSlash(szArchive, sizeof(szArchive));
00260           strcat(szArchive, siCObject->szArchiveName);
00261           if(!FileExists(szArchive))
00262           {
00263             strcpy(szArchive, szTempDir);
00264             AppendBackSlash(szArchive, sizeof(szArchive));
00265             strcat(szArchive, siCObject->szArchiveName);
00266             if(!FileExists(szArchive))
00267             {
00268               char szEFileNotFound[MAX_BUF];
00269 
00270               if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall))
00271               {
00272                 sprintf(szBuf, szEFileNotFound, szArchive);
00273                 PrintError(szBuf, ERROR_CODE_HIDE);
00274               }
00275               return(1);
00276             }
00277           }
00278         }
00279 
00280         if(dwCurrentArchive == 0)
00281         {
00282           ++dwCurrentArchive;
00283           UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100));
00284         }
00285 
00286         sprintf(szBuf, szStrInstalling, siCObject->szDescriptionShort);
00287         WinSetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS0, szBuf);
00288         LogISXPInstallComponent(siCObject->szDescriptionShort);
00289 
00290         hrResult = pfnXpiInstall(szArchive, "", 0xFFFF);
00291         if(hrResult == E_REBOOT)
00292           bReboot = TRUE;
00293         else if((hrResult != WIZ_OK) &&
00294                !(siCObject->dwAttributes & SIC_IGNORE_XPINSTALL_ERROR))
00295         {
00296           LogMSXPInstallStatus(siCObject->szArchiveName, hrResult);
00297           LogISXPInstallComponentResult(hrResult);
00298           if(GetPrivateProfileString("Messages", "ERROR_XPI_INSTALL", "", szEXpiInstall, sizeof(szEXpiInstall), szFileIniInstall))
00299           {
00300             char szErrorString[MAX_BUF];
00301 
00302             GetErrorString(hrResult, szErrorString, sizeof(szErrorString));
00303             sprintf(szBuf, "%s - %s: %d %s", szEXpiInstall, siCObject->szDescriptionShort, hrResult, szErrorString);
00304             PrintError(szBuf, ERROR_CODE_HIDE);
00305           }
00306 
00307           /* break out of the siCObject while loop */
00308           break;
00309         }
00310 
00311         ++dwCurrentArchive;
00312         UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100));
00313         ProcessWindowsMessages();
00314         LogISXPInstallComponentResult(hrResult);
00315 
00316         if((hrResult != WIZ_OK) &&
00317           (siCObject->dwAttributes & SIC_IGNORE_XPINSTALL_ERROR))
00318           /* reset the result to WIZ_OK if there was an error and the
00319            * component's attributes contains SIC_IGNORE_XPINSTALL_ERROR.
00320            * This should be done after LogISXPInstallComponentResult()
00321            * because we still should log the error value. */
00322           hrResult = WIZ_OK;
00323       }
00324 
00325       if(siCObject->dwAttributes & SIC_SELECTED)
00326         /* Since the archive is selected, we need to do the file ops here */
00327          ProcessFileOps(T_POST_ARCHIVE, siCObject->szReferenceName);
00328 
00329       ++dwIndex0;
00330       siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
00331     } /* while(siCObject) */
00332 
00333     LogMSXPInstallStatus(NULL, hrResult);
00334     pfnXpiExit();
00335     if(sgProduct.ulMode != SILENT)
00336       WinDestroyWindow(dlgInfo.hWndDlg);
00337   }
00338   else
00339   {
00340     ShowMessage(szMsgSmartUpdateStart, FALSE);
00341   }
00342 
00343   DeInitializeXPIStub();
00344   LogISXPInstall(W_END);
00345 
00346   return(hrResult);
00347 }
00348 
00349 void cbXPIStart(const char *URL, const char *UIName)
00350 {
00351 }
00352 
00353 void cbXPIProgress(const char* msg, PRInt32 val, PRInt32 max)
00354 {
00355   char szBuf[MAX_BUF];
00356 
00357   if(sgProduct.ulMode != SILENT)
00358   {
00359     TruncateString(WinWindowFromID(dlgInfo.hWndDlg, IDC_STATUS3), msg, szBuf, sizeof(szBuf));
00360     WinSetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS3, szBuf);
00361   }
00362 
00363   ProcessWindowsMessages();
00364 }
00365 
00366 void cbXPIFinal(const char *URL, PRInt32 finalStatus)
00367 {
00368 }
00369 
00370 
00371 
00373 // Progress bar
00374 
00375 // Centers the specified window over the desktop. Assumes the window is
00376 // smaller both horizontally and vertically than the desktop
00377 static void
00378 CenterWindow(HWND hWndDlg)
00379 {
00380   SWP swpDlg;
00381 
00382   WinQueryWindowPos(hWndDlg, &swpDlg);
00383   WinSetWindowPos(hWndDlg,
00384                   0,
00385                   (WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN)/2)-(swpDlg.cx/2),
00386                   (WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)/2)-(swpDlg.cy/2),
00387                   0,
00388                   0,
00389                   SWP_MOVE);
00390 }
00391 
00392 // Window proc for dialog
00393 MRESULT APIENTRY
00394 ProgressDlgProc(HWND hWndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
00395 {
00396   switch (msg)
00397   {
00398     case WM_INITDLG:
00399       AdjustDialogSize(hWndDlg);
00400       WinSetPresParam(hWndDlg, PP_FONTNAMESIZE,
00401                       strlen(sgInstallGui.szDefinedFont)+1, sgInstallGui.szDefinedFont);
00402       WinSendMsg(WinWindowFromID(hWndDlg, IDC_GAUGE_ARCHIVE), SLM_SETSLIDERINFO,
00403                                MPFROM2SHORT(SMA_SHAFTDIMENSIONS, 0),
00404                                (MPARAM)20);
00405 //      DisableSystemMenuItems(hWndDlg, TRUE);
00406       CenterWindow(hWndDlg);
00407       break;
00408    case WM_CLOSE:
00409    case WM_COMMAND:
00410       return (MRESULT)TRUE;
00411   }
00412   return WinDefDlgProc(hWndDlg, msg, mp1, mp2);
00413 }
00414 
00415 // This routine will update the Archive Gauge progress bar to the specified percentage
00416 // (value between 0 and 100)
00417 static void
00418 UpdateGaugeArchiveProgressBar(unsigned value)
00419 {
00420   if(sgProduct.ulMode != SILENT) {
00421     WinSendMsg(WinWindowFromID(dlgInfo.hWndDlg, IDC_GAUGE_ARCHIVE), SLM_SETSLIDERINFO,
00422                                MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE),
00423                                (MPARAM)(value-1));
00424   }
00425 }
00426 
00427 void InitProgressDlg()
00428 {
00429   if(sgProduct.ulMode != SILENT)
00430   {
00431     dlgInfo.hWndDlg = WinLoadDlg(HWND_DESKTOP, hWndMain, ProgressDlgProc, hSetupRscInst, DLG_EXTRACTING, NULL);
00432     WinShowWindow(dlgInfo.hWndDlg, TRUE);
00433   }
00434 }
00435