Back to index

lightning-sunbird  0.9+nobinonly
xpistub.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; 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  *   Daniel Veditz <dveditz@netscape.com>
00025  *   Pierre Phaneuf <pp@ludusdesign.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "xpistub.h"
00042 
00043 #include "nsIComponentManager.h"
00044 #include "nsIComponentRegistrar.h"
00045 #include "nsIServiceManager.h"
00046 #include "nsCOMPtr.h"
00047 #include "nsLocalFile.h"
00048 
00049 #include "nscore.h"
00050 #include "nspr.h"
00051 
00052 #include "nsStubNotifier.h"
00053 
00054 #include "nsISoftwareUpdate.h"
00055 #include "nsSoftwareUpdateIIDs.h"
00056 #include "nsPIXPIStubHook.h"
00057 
00058 #include "plstr.h"
00059 
00060 #if defined(XP_WIN) || defined(XP_OS2)
00061 #if defined(XP_OS2)
00062 #include <stdlib.h>
00063 #define MAX_PATH _MAX_PATH
00064 #else
00065 #include <windows.h>
00066 #endif
00067 #ifndef XP_OS2_EMX
00068 #include <direct.h>
00069 #endif /*emx*/
00070 #define COMPONENT_REG "component.reg"
00071 #endif
00072 
00073 #ifdef XP_UNIX
00074 #include <unistd.h>
00075 #define COMPONENT_REG "component.reg"
00076 #endif
00077 
00078 //------------------------------------------------------------------------
00079 //          globals
00080 //------------------------------------------------------------------------
00081 
00082 static nsIXPIListener      *gListener = 0;
00083 static nsISoftwareUpdate   *gXPI = 0;
00084 static nsIServiceManager   *gServiceMgr = 0;
00085 
00086 static NS_DEFINE_IID(kSoftwareUpdateCID, NS_SoftwareUpdate_CID);
00087 
00088 PRInt32 gInstallStatus;
00089 
00090 
00091 
00092 //------------------------------------------------------------------------
00093 //          XPI_Init()
00094 //------------------------------------------------------------------------
00095 PR_PUBLIC_API(nsresult) XPI_Init( const char*         aProgramDir,
00096                                   const char*         aLogName,
00097                                   pfnXPIProgress      progressCB )
00098 {
00099     nsresult              rv;
00100 
00101     //--------------------------------------------------------------------
00102     // Initialize XPCOM and AutoRegister() its components
00103     //--------------------------------------------------------------------
00104 #if defined(XP_WIN) || defined(XP_OS2)
00105 
00106  #ifdef XP_OS2_EMX
00107     char componentPath[MAX_PATH];
00108     _getcwd2(componentPath, MAX_PATH);
00109     int len = strlen(componentPath);
00110     for (int i = 0; i < len; i++) {
00111       if (componentPath[i] == '/') {
00112         componentPath[i] = '\\';
00113       }
00114     }
00115  #else
00116     char componentPath[MAX_PATH];
00117     getcwd(componentPath, MAX_PATH);
00118  #endif
00119 
00120     nsCOMPtr<nsILocalFile> file;
00121     rv = NS_NewNativeLocalFile(nsDependentCString(componentPath), PR_TRUE, getter_AddRefs(file));
00122     if (NS_FAILED(rv)) return rv;
00123     
00124     rv = NS_InitXPCOM2(&gServiceMgr, file, nsnull); 
00125 
00126 #elif defined(XP_UNIX)
00127 
00128     rv = NS_InitXPCOM2(&gServiceMgr, nsnull, nsnull); 
00129 
00130     char cwd[1024];
00131     char compDirPath[1024];
00132 
00133     memset(cwd, 0, 1024);
00134     memset(compDirPath, 0, 1024);
00135     getcwd(cwd, 1024);
00136     sprintf(compDirPath, "%s/components", cwd);
00137 
00138     nsCOMPtr<nsILocalFile> compDir;
00139     NS_NewNativeLocalFile(nsDependentCString(compDirPath), PR_TRUE, getter_AddRefs(compDir));
00140 
00141 #else
00142 
00143     rv = NS_InitXPCOM2(&gServiceMgr, NULL, NULL);
00144 
00145 #endif
00146 
00147     if (NS_FAILED(rv))
00148         return rv;
00149 
00150     nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(gServiceMgr);
00151     NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
00152 
00153 #if defined(XP_UNIX)
00154     rv = registrar->AutoRegister(compDir);
00155 #else
00156     rv = registrar->AutoRegister(nsnull);
00157 #endif
00158     if (NS_FAILED(rv))
00159         return rv;
00160 
00161 
00162     //--------------------------------------------------------------------
00163     // Get the SoftwareUpdate (XPInstall) service.
00164     //
00165     // Since AppShell is not started by XPIStub the XPI service is never 
00166     // registered with the service manager. We keep a local pointer to it 
00167     // so it stays alive througout.
00168     //--------------------------------------------------------------------
00169     rv = CallCreateInstance(kSoftwareUpdateCID, &gXPI);
00170     if (NS_FAILED(rv))
00171         return rv;
00172 
00173 
00174     //--------------------------------------------------------------------
00175     // Override XPInstall's natural assumption that the current executable
00176     // is Mozilla. Use the given directory as the "Program" folder.
00177     //--------------------------------------------------------------------
00178     nsCOMPtr<nsPIXPIStubHook>   hook = do_QueryInterface(gXPI);
00179     nsCOMPtr<nsILocalFile>      iDirSpec;
00180   
00181     if (aProgramDir)
00182     {
00183        NS_NewNativeLocalFile(nsDependentCString(aProgramDir), PR_TRUE, getter_AddRefs(iDirSpec));
00184     }
00185     else
00186     {
00187        nsCOMPtr<nsIProperties> directoryService = 
00188           do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
00189 
00190        directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), 
00191                              getter_AddRefs(iDirSpec));
00192     }
00193 
00194     if (hook && iDirSpec)
00195     {
00196         rv = hook->StubInitialize( iDirSpec, aLogName );
00197         if (NS_FAILED(rv)) return rv;
00198     }
00199     else
00200         return NS_ERROR_NULL_POINTER;
00201 
00202 
00203     //--------------------------------------------------------------------
00204     // Save the install wizard's callbacks as a nsIXPINotifer for later
00205     //--------------------------------------------------------------------
00206     nsStubListener* stub = new nsStubListener( progressCB );
00207     if (!stub)
00208     {
00209         gXPI->Release();
00210         rv = NS_ERROR_OUT_OF_MEMORY;
00211     }
00212     else
00213     {
00214         rv = stub->QueryInterface(NS_GET_IID(nsIXPIListener), (void**)&gListener);
00215     }
00216     return rv;
00217 }
00218 
00219 
00220 
00221 //------------------------------------------------------------------------
00222 //          XPI_Exit()
00223 //------------------------------------------------------------------------
00224 PR_PUBLIC_API(void) XPI_Exit()
00225 {
00226     if (gListener)
00227         gListener->Release();
00228 
00229     if (gXPI)
00230         gXPI->Release();
00231 
00232     NS_ShutdownXPCOM(gServiceMgr);
00233 
00234 }
00235 
00236 
00237 
00238 
00239 //------------------------------------------------------------------------
00240 //          XPI_Install()
00241 //------------------------------------------------------------------------
00242 PR_PUBLIC_API(PRInt32) XPI_Install(
00243                                     const char*   aFile,
00244                                     const char*   aArgs, 
00245                                     long          aFlags )
00246 {
00247     nsresult                rv = NS_ERROR_NULL_POINTER;
00248     nsString                args; args.AssignWithConversion(aArgs);
00249     nsCOMPtr<nsILocalFile>  iFile;
00250 
00251     gInstallStatus = -322; // unique stub error code
00252     
00253     NS_NewNativeLocalFile(nsDependentCString(aFile), PR_TRUE, getter_AddRefs(iFile));
00254 
00255     if (iFile && gXPI)
00256         rv = gXPI->InstallJar( iFile,
00257                                nsnull,
00258                                args.get(),
00259                                nsnull,
00260                                (aFlags | XPI_NO_NEW_THREAD),
00261                                gListener );
00262 
00263     return gInstallStatus;
00264 }