/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, * released March 31, 1998. * * The Initial Developer of the Original Code is Netscape Communications * Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. * * Contributors: * Daniel Veditz * Douglas Turner */ #include "nsInstallFile.h" #include "nsFileSpec.h" #include "VerReg.h" #include "ScheduledTasks.h" #include "nsInstall.h" #include "nsIDOMInstallVersion.h" #include "nsInstallResources.h" /* Public Methods */ /* Constructor inInstall - softUpdate object we belong to inComponentName - full path of the registry component inVInfo - full version info inJarLocation - location inside the JAR file inFinalFileSpec - final location on disk */ nsInstallFile::nsInstallFile(nsInstall* inInstall, const nsString& inComponentName, const nsString& inVInfo, const nsString& inJarLocation, const nsString& folderSpec, const nsString& inPartialPath, PRBool forceInstall, PRInt32 *error) : nsInstallObject(inInstall) { mVersionRegistryName = nsnull; mJarLocation = nsnull; mExtracedFile = nsnull; mFinalFile = nsnull; mVersionInfo = nsnull; mUpgradeFile = PR_FALSE; if ((folderSpec == "null") || (inInstall == NULL)) { *error = nsInstall::INVALID_ARGUMENTS; return; } /* Check for existence of the newer version */ PRBool versionNewer = PR_FALSE; // Is this a newer version char* qualifiedRegNameString = inComponentName.ToNewCString(); if ( (forceInstall == PR_FALSE ) && (inVInfo != "") && ( VR_ValidateComponent( qualifiedRegNameString ) == 0 ) ) { nsInstallVersion *newVersion = new nsInstallVersion(); newVersion->Init(inVInfo); VERSION versionStruct; VR_GetVersion( qualifiedRegNameString, &versionStruct ); nsInstallVersion* oldVersion = new nsInstallVersion(); oldVersion->Init(versionStruct.major, versionStruct.minor, versionStruct.release, versionStruct.build); PRInt32 areTheyEqual; newVersion->CompareTo(oldVersion, &areTheyEqual); delete oldVersion; delete newVersion; if (areTheyEqual == nsIDOMInstallVersion::MAJOR_DIFF_MINUS || areTheyEqual == nsIDOMInstallVersion::MINOR_DIFF_MINUS || areTheyEqual == nsIDOMInstallVersion::REL_DIFF_MINUS || areTheyEqual == nsIDOMInstallVersion::BLD_DIFF_MINUS ) { // the file to be installed is OLDER than what is on disk. Return error delete qualifiedRegNameString; *error = areTheyEqual; return; } } delete qualifiedRegNameString; mFinalFile = new nsFileSpec(folderSpec); *mFinalFile += inPartialPath; mReplaceFile = mFinalFile->Exists(); if (mReplaceFile == PR_FALSE) { nsFileSpec parent; mFinalFile->GetParent(parent); nsFileSpec makeDirs(parent.GetCString(), PR_TRUE); } mForceInstall = forceInstall; mVersionRegistryName = new nsString(inComponentName); mJarLocation = new nsString(inJarLocation); mVersionInfo = new nsString(inVInfo); nsString regPackageName; mInstall->GetRegPackageName(regPackageName); // determine Child status if ( regPackageName == "" ) { // in the "current communicator package" absolute pathnames (start // with slash) indicate shared files -- all others are children mChildFile = ( mVersionRegistryName->CharAt(0) != '/' ); } else { // there is no "starts with" api in nsString. LAME! nsString startsWith; mVersionRegistryName->Left(startsWith, regPackageName.Length()); if (startsWith.Equals(regPackageName)) { mChildFile = true; } else { mChildFile = false; } } } nsInstallFile::~nsInstallFile() { if (mVersionRegistryName) delete mVersionRegistryName; if (mJarLocation) delete mJarLocation; if (mExtracedFile) delete mExtracedFile; if (mFinalFile) delete mFinalFile; if (mVersionInfo) delete mVersionInfo; } /* Prepare * Extracts file out of the JAR archive */ PRInt32 nsInstallFile::Prepare() { if (mInstall == nsnull || mFinalFile == nsnull || mJarLocation == nsnull ) return nsInstall::INVALID_ARGUMENTS; return mInstall->ExtractFileFromJar(*mJarLocation, mFinalFile, &mExtracedFile); } /* Complete * Completes the install: * - move the downloaded file to the final location * - updates the registry */ PRInt32 nsInstallFile::Complete() { PRInt32 err; if (mInstall == nsnull || mVersionRegistryName == nsnull || mFinalFile == nsnull ) { return nsInstall::INVALID_ARGUMENTS; } err = CompleteFileMove(); if ( 0 == err || nsInstall::REBOOT_NEEDED == err ) { err = RegisterInVersionRegistry(); } return err; } void nsInstallFile::Abort() { if (mExtracedFile != nsnull) mExtracedFile->Delete(PR_FALSE); } char* nsInstallFile::toString() { char* buffer = new char[1024]; if (mFinalFile == nsnull) { sprintf( buffer, nsInstallResources::GetInstallFileString(), nsnull); } else if (mReplaceFile) { // we are replacing this file. sprintf( buffer, nsInstallResources::GetReplaceFileString(), mFinalFile->GetCString()); } else { sprintf( buffer, nsInstallResources::GetInstallFileString(), mFinalFile->GetCString()); } return buffer; } PRInt32 nsInstallFile::CompleteFileMove() { int result = 0; if (mExtracedFile == nsnull) { return -1; } if ( *mExtracedFile == *mFinalFile ) { /* No need to rename, they are the same */ result = 0; } else { result = ReplaceFileNowOrSchedule(*mExtracedFile, *mFinalFile ); } return result; } PRInt32 nsInstallFile::RegisterInVersionRegistry() { int refCount; nsString regPackageName; mInstall->GetRegPackageName(regPackageName); // Register file and log for Uninstall if (!mChildFile) { int found; if (regPackageName != "") { found = VR_UninstallFileExistsInList( (char*)(const char*)nsAutoCString(regPackageName) , (char*)(const char*)nsAutoCString(*mVersionRegistryName)); } else { found = VR_UninstallFileExistsInList( "", (char*)(const char*)nsAutoCString(*mVersionRegistryName) ); } if (found != REGERR_OK) mUpgradeFile = PR_FALSE; else mUpgradeFile = PR_TRUE; } else if (REGERR_OK == VR_InRegistry( (char*)(const char*)nsAutoCString(*mVersionRegistryName))) { mUpgradeFile = PR_TRUE; } else { mUpgradeFile = PR_FALSE; } if ( REGERR_OK != VR_GetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), &refCount )) { refCount = 0; } VR_Install( (char*)(const char*)nsAutoCString(*mVersionRegistryName), (char*)(const char*)mFinalFile->GetNativePathCString(), // DO NOT CHANGE THIS. (char*)(const char*)nsAutoCString(*mVersionInfo), PR_FALSE ); if (mUpgradeFile) { if (refCount == 0) VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 1 ); else VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), refCount ); //FIX?? what should the ref count be/ } else { if (refCount != 0) { VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), refCount + 1 ); } else { if (mReplaceFile) VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 2 ); else VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 1 ); } } if ( !mChildFile && !mUpgradeFile ) { if (regPackageName != "") { VR_UninstallAddFileToList( (char*)(const char*)nsAutoCString(regPackageName), (char*)(const char*)nsAutoCString(*mVersionRegistryName)); } else { VR_UninstallAddFileToList( "", (char*)(const char*)nsAutoCString(*mVersionRegistryName) ); } } return nsInstall::SUCCESS; } /* CanUninstall * InstallFile() installs files which can be uninstalled, * hence this function returns true. */ PRBool nsInstallFile::CanUninstall() { return TRUE; } /* RegisterPackageNode * InstallFile() installs files which need to be registered, * hence this function returns true. */ PRBool nsInstallFile::RegisterPackageNode() { return TRUE; }