Back to index

lightning-sunbird  0.9+nobinonly
nsInstallUninstall.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  *   Douglas Turner <dougt@netscape.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 "nsInstall.h"
00042 #include "nsInstallUninstall.h"
00043 #include "nsInstallResources.h"
00044 #include "VerReg.h"
00045 #include "nsCRT.h"
00046 #include "prmem.h"
00047 #include "ScheduledTasks.h"
00048 #include "nsReadableUtils.h"
00049 #include "nsILocalFile.h"
00050 
00051 extern "C" NS_EXPORT PRInt32 SU_Uninstall(char *regPackageName);
00052 REGERR su_UninstallProcessItem(char *component_path);
00053 
00054 MOZ_DECL_CTOR_COUNTER(nsInstallUninstall)
00055 
00056 nsInstallUninstall::nsInstallUninstall( nsInstall* inInstall,
00057                                         const nsString& regName,
00058                                         PRInt32 *error)
00059 
00060 : nsInstallObject(inInstall)
00061 {
00062     MOZ_COUNT_CTOR(nsInstallUninstall);
00063 
00064     if (regName.IsEmpty()) 
00065     {
00066         *error = nsInstall::INVALID_ARGUMENTS;
00067         return;
00068     }
00069     
00070     mRegName.Assign(regName);
00071 
00072     char* userName = (char*)PR_Malloc(MAXREGPATHLEN);
00073     PRInt32 err = VR_GetUninstallUserName( NS_CONST_CAST(char*, NS_ConvertUCS2toUTF8(regName).get()),
00074                                            userName, 
00075                                            MAXREGPATHLEN );
00076     
00077     mUIName.AssignWithConversion(userName);
00078     
00079     if (err != REGERR_OK)
00080     {
00081         *error = nsInstall::NO_SUCH_COMPONENT;
00082     }
00083     
00084     PR_FREEIF(userName);
00085     
00086 }
00087 
00088 nsInstallUninstall::~nsInstallUninstall()
00089 {
00090     MOZ_COUNT_DTOR(nsInstallUninstall);
00091 }
00092 
00093 
00094 PRInt32 nsInstallUninstall::Prepare()
00095 {
00096     // no set-up necessary
00097     return nsInstall::SUCCESS;
00098 }
00099 
00100 PRInt32 nsInstallUninstall::Complete()
00101 {
00102     PRInt32 err = nsInstall::SUCCESS;
00103 
00104     if (mInstall == NULL) 
00105        return nsInstall::INVALID_ARGUMENTS;
00106 
00107     err = SU_Uninstall( NS_CONST_CAST(char*, NS_ConvertUCS2toUTF8(mRegName).get()) );
00108     
00109     return err;
00110 }
00111 
00112 void nsInstallUninstall::Abort()
00113 {
00114 }
00115 
00116 char* nsInstallUninstall::toString()
00117 {
00118     char* buffer = new char[1024];
00119     char* rsrcVal = nsnull;
00120 
00121     if (buffer == nsnull || !mInstall)
00122         return buffer;
00123     
00124     char* temp = ToNewCString(mUIName);
00125     
00126     if (temp)
00127     {
00128         rsrcVal = mInstall->GetResourcedString(NS_LITERAL_STRING("Uninstall"));
00129 
00130         if (rsrcVal)
00131         {
00132             sprintf( buffer, rsrcVal, temp);
00133             nsCRT::free(rsrcVal);
00134         }
00135     }
00136 
00137     if (temp)
00138          Recycle(temp);
00139 
00140     return buffer;
00141 }
00142 
00143 
00144 PRBool
00145 nsInstallUninstall::CanUninstall()
00146 {
00147     return PR_FALSE;
00148 }
00149 
00150 PRBool
00151 nsInstallUninstall::RegisterPackageNode()
00152 {
00153     return PR_FALSE;
00154 }
00155 
00156 extern "C" NS_EXPORT PRInt32 SU_Uninstall(char *regPackageName)
00157 {
00158     REGERR status = REGERR_FAIL;
00159     char pathbuf[MAXREGPATHLEN+1] = {0};
00160     char sharedfilebuf[MAXREGPATHLEN+1] = {0};
00161     REGENUM state = 0;
00162     int32 length;
00163     int32 err;
00164 
00165     if (regPackageName == NULL)
00166         return REGERR_PARAM;
00167 
00168     if (pathbuf == NULL)
00169         return REGERR_PARAM;
00170 
00171     /* Get next path from Registry */
00172     status = VR_Enum( regPackageName, &state, pathbuf, MAXREGPATHLEN );
00173 
00174     /* if we got a good path */
00175     while (status == REGERR_OK)
00176     {
00177         char component_path[2*MAXREGPATHLEN+1] = {0};
00178         strcat(component_path, regPackageName);
00179         length = strlen(regPackageName);
00180         if (component_path[length - 1] != '/')
00181             strcat(component_path, "/");
00182         strcat(component_path, pathbuf);
00183         err = su_UninstallProcessItem(component_path);
00184         status = VR_Enum( regPackageName, &state, pathbuf, MAXREGPATHLEN );  
00185     }
00186     
00187     err = VR_Remove(regPackageName);
00188     // there is a problem here.  It looks like if the file is refcounted, we still blow away the reg key
00189     // FIX!
00190     state = 0;
00191     status = VR_UninstallEnumSharedFiles( regPackageName, &state, sharedfilebuf, MAXREGPATHLEN );
00192     while (status == REGERR_OK)
00193     {
00194         err = su_UninstallProcessItem(sharedfilebuf);
00195         err = VR_UninstallDeleteFileFromList(regPackageName, sharedfilebuf);
00196         status = VR_UninstallEnumSharedFiles( regPackageName, &state, sharedfilebuf, MAXREGPATHLEN );
00197     }
00198 
00199     err = VR_UninstallDeleteSharedFilesKey(regPackageName);
00200     err = VR_UninstallDestroy(regPackageName);
00201     return err;
00202 }
00203 
00204 REGERR su_UninstallProcessItem(char *component_path)
00205 {
00206     int refcount;
00207     int err;
00208     char filepath[MAXREGPATHLEN];
00209     nsCOMPtr<nsILocalFile> nsLFPath;
00210     nsCOMPtr<nsIFile> nsFPath;
00211 
00212     err = VR_GetPath(component_path, sizeof(filepath), filepath);
00213     if ( err == REGERR_OK )
00214     {
00215         NS_NewNativeLocalFile(nsDependentCString(filepath), PR_TRUE, getter_AddRefs(nsLFPath));
00216         nsFPath = nsLFPath;
00217         err = VR_GetRefCount(component_path, &refcount);  
00218         if ( err == REGERR_OK )
00219         {
00220             --refcount;
00221             if (refcount > 0)
00222                 err = VR_SetRefCount(component_path, refcount);  
00223             else 
00224             {
00225                 err = VR_Remove(component_path);
00226                 DeleteFileNowOrSchedule(nsFPath);
00227             }
00228         }
00229         else
00230         {
00231             /* delete node and file */
00232             err = VR_Remove(component_path);
00233             DeleteFileNowOrSchedule(nsFPath);
00234         }
00235     }
00236     return err;
00237 }
00238