488 lines
13 KiB
C++
488 lines
13 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (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.
|
|
*
|
|
* 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.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
#include "nsSoftwareUpdate.h"
|
|
#include "nsXPInstallManager.h"
|
|
#include "nsInstallTrigger.h"
|
|
#include "nsInstallVersion.h"
|
|
#include "nsIDOMInstallTriggerGlobal.h"
|
|
|
|
#include "nscore.h"
|
|
#include "nsIFactory.h"
|
|
#include "nsISupports.h"
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "nsIPref.h"
|
|
|
|
#include "nsRepository.h"
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsSpecialSystemDirectory.h"
|
|
|
|
#include "VerReg.h"
|
|
|
|
#include "nsIContentHandler.h"
|
|
#include "nsIChannel.h"
|
|
#include "nsIURI.h"
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
|
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
|
|
static NS_DEFINE_IID(kIInstallTrigger_IID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
|
|
static NS_DEFINE_IID(kIInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
|
|
|
|
static NS_DEFINE_IID(kPrefsIID, NS_IPREF_IID);
|
|
static NS_DEFINE_IID(kPrefsCID, NS_PREF_CID);
|
|
|
|
nsInstallTrigger::nsInstallTrigger()
|
|
{
|
|
mScriptObject = nsnull;
|
|
NS_INIT_ISUPPORTS();
|
|
}
|
|
|
|
nsInstallTrigger::~nsInstallTrigger()
|
|
{
|
|
}
|
|
|
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS3 (nsInstallTrigger,
|
|
nsIScriptObjectOwner,
|
|
nsIDOMInstallTriggerGlobal,
|
|
nsIContentHandler);
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
|
{
|
|
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
|
|
nsresult res = NS_OK;
|
|
|
|
if (nsnull == mScriptObject)
|
|
{
|
|
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
|
|
|
res = NS_NewScriptInstallTriggerGlobal( aContext,
|
|
(nsISupports *)(nsIDOMInstallTriggerGlobal*)this,
|
|
(nsISupports *)global,
|
|
&mScriptObject);
|
|
NS_IF_RELEASE(global);
|
|
|
|
}
|
|
|
|
|
|
*aScriptObject = mScriptObject;
|
|
return res;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::SetScriptObject(void *aScriptObject)
|
|
{
|
|
mScriptObject = aScriptObject;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::HandleContent(const char * aContentType,
|
|
const char * aCommand,
|
|
const char * aWindowTarget,
|
|
nsISupports* aWindowContext,
|
|
nsIChannel * aChannel)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
if (!aChannel) return NS_ERROR_NULL_POINTER;
|
|
|
|
if (nsCRT::strcasecmp(aContentType, "application/x-xpinstall") == 0) {
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = aChannel->GetURI(getter_AddRefs(uri));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (uri) {
|
|
char* spec;
|
|
uri->GetSpec(&spec);
|
|
if (!spec)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
PRBool value;
|
|
rv = StartSoftwareUpdate(NS_ConvertASCIItoUCS2(spec), 0, &value);
|
|
|
|
nsMemory::Free(spec);
|
|
|
|
if (NS_SUCCEEDED(rv) && value)
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::UpdateEnabled(PRBool* aReturn)
|
|
{
|
|
nsIPref * prefs;
|
|
|
|
nsresult rv = nsServiceManager::GetService(kPrefsCID,
|
|
kPrefsIID,
|
|
(nsISupports**) &prefs);
|
|
|
|
|
|
if ( NS_SUCCEEDED(rv) )
|
|
{
|
|
rv = prefs->GetBoolPref( (const char*) XPINSTALL_ENABLE_PREF, aReturn);
|
|
|
|
if (NS_FAILED(rv))
|
|
{
|
|
*aReturn = PR_FALSE;
|
|
}
|
|
|
|
NS_RELEASE(prefs);
|
|
}
|
|
else
|
|
{
|
|
*aReturn = PR_FALSE; /* no prefs manager. set to false */
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::Install(nsXPITriggerInfo* aTrigger, PRBool* aReturn)
|
|
{
|
|
NS_ASSERTION(aReturn, "Invalid pointer arg");
|
|
*aReturn = PR_FALSE;
|
|
|
|
PRBool enabled;
|
|
nsresult rv = UpdateEnabled(&enabled);
|
|
if (NS_FAILED(rv) || !enabled)
|
|
{
|
|
delete aTrigger;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsXPInstallManager *mgr = new nsXPInstallManager();
|
|
if (mgr)
|
|
{
|
|
// The Install manager will delete itself when done
|
|
rv = mgr->InitManager( aTrigger, 0 );
|
|
if (NS_SUCCEEDED(rv))
|
|
*aReturn = PR_TRUE;
|
|
}
|
|
else
|
|
{
|
|
delete aTrigger;
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::InstallChrome(PRUint32 aType, nsXPITriggerItem *aItem, PRBool* aReturn)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
NS_ENSURE_ARG_POINTER(aItem);
|
|
*aReturn = PR_FALSE;
|
|
|
|
|
|
// make sure we're allowing installs
|
|
PRBool enabled;
|
|
nsresult rv = UpdateEnabled(&enabled);
|
|
if (NS_FAILED(rv) || !enabled)
|
|
return NS_OK;
|
|
|
|
|
|
// The Install manager will delete itself when done, once we've called
|
|
// InitManager. Before then **WE** must delete it
|
|
nsXPInstallManager *mgr = new nsXPInstallManager();
|
|
if (mgr)
|
|
{
|
|
nsXPITriggerInfo* trigger = new nsXPITriggerInfo();
|
|
if ( trigger )
|
|
{
|
|
trigger->Add( aItem );
|
|
|
|
// The Install manager will delete itself when done
|
|
rv = mgr->InitManager( trigger, aType );
|
|
*aReturn = PR_TRUE;
|
|
}
|
|
else
|
|
{
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
delete mgr;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRBool* aReturn)
|
|
{
|
|
PRBool enabled;
|
|
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
|
*aReturn = PR_FALSE;
|
|
|
|
UpdateEnabled(&enabled);
|
|
if (!enabled)
|
|
return NS_OK;
|
|
|
|
// The Install manager will delete itself when done, once we've called
|
|
// InitManager. Before then **WE** must delete it
|
|
nsXPInstallManager *mgr = new nsXPInstallManager();
|
|
if (mgr)
|
|
{
|
|
nsXPITriggerInfo* trigger = new nsXPITriggerInfo();
|
|
if ( trigger )
|
|
{
|
|
nsXPITriggerItem* item = new nsXPITriggerItem(0,aURL.GetUnicode());
|
|
if (item)
|
|
{
|
|
trigger->Add( item );
|
|
// The Install manager will delete itself when done
|
|
rv = mgr->InitManager( trigger, 0 );
|
|
*aReturn = PR_TRUE;
|
|
}
|
|
else
|
|
{
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
delete trigger;
|
|
delete mgr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
delete mgr;
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
{
|
|
nsInstallVersion inVersion;
|
|
inVersion.Init(aVersion);
|
|
return ConditionalSoftwareUpdate(aURL, aRegName, aDiffLevel, &inVersion, aMode, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
{
|
|
PRBool needJar = PR_FALSE;
|
|
|
|
PRBool enabled;
|
|
|
|
UpdateEnabled(&enabled);
|
|
if (!enabled)
|
|
return NS_OK;
|
|
|
|
if (aURL.IsEmpty() || aVersion == nsnull)
|
|
{
|
|
needJar = PR_TRUE;
|
|
}
|
|
else
|
|
{
|
|
char * regNameCString = aRegName.ToNewCString();
|
|
|
|
REGERR status = VR_ValidateComponent( regNameCString );
|
|
|
|
if ( status == REGERR_NOFIND || status == REGERR_NOFILE )
|
|
{
|
|
// either component is not in the registry or it's a file
|
|
// node and the physical file is missing
|
|
needJar = PR_TRUE;
|
|
}
|
|
else
|
|
{
|
|
VERSION oldVersion;
|
|
PRInt32 diffValue;
|
|
|
|
status = VR_GetVersion( regNameCString, &oldVersion );
|
|
nsInstallVersion oldInstallVersion;
|
|
|
|
oldInstallVersion.Init(oldVersion.major,
|
|
oldVersion.minor,
|
|
oldVersion.release,
|
|
oldVersion.build);
|
|
|
|
|
|
if ( status != REGERR_OK )
|
|
needJar = PR_TRUE;
|
|
else if ( aDiffLevel < 0 )
|
|
{
|
|
aVersion->CompareTo(&oldInstallVersion, &diffValue);
|
|
needJar = (diffValue <= aDiffLevel);
|
|
}
|
|
else
|
|
{
|
|
aVersion->CompareTo(&oldInstallVersion, &diffValue);
|
|
needJar = (diffValue >= aDiffLevel);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (needJar)
|
|
return StartSoftwareUpdate(aURL, aMode, aReturn);
|
|
else
|
|
*aReturn = 0;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
{
|
|
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, aVersion, aMode, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
{
|
|
nsInstallVersion inVersion;
|
|
inVersion.Init(aVersion);
|
|
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, &inVersion, aMode, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
|
|
{
|
|
nsInstallVersion inVersion;
|
|
inVersion.Init(aVersion);;
|
|
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, &inVersion, 0, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
|
|
{
|
|
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, aVersion, 0, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)
|
|
{
|
|
nsInstallVersion inVersion;
|
|
inVersion.Init(aMajor, aMinor, aRelease, aBuild);
|
|
|
|
return CompareVersion(aRegName, &inVersion, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
|
|
{
|
|
nsInstallVersion inVersion;
|
|
inVersion.Init(aVersion);
|
|
|
|
return CompareVersion(aRegName, &inVersion, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
|
|
{
|
|
*aReturn = EQUAL; // assume failure.
|
|
|
|
PRBool enabled;
|
|
|
|
UpdateEnabled(&enabled);
|
|
if (!enabled)
|
|
return NS_OK;
|
|
|
|
VERSION cVersion;
|
|
char* tempCString;
|
|
REGERR status;
|
|
nsInstallVersion regNameVersion;
|
|
|
|
tempCString = aRegName.ToNewCString();
|
|
|
|
status = VR_GetVersion( tempCString, &cVersion );
|
|
|
|
/* if we got the version */
|
|
if ( status == REGERR_OK )
|
|
{
|
|
if ( VR_ValidateComponent( tempCString ) == REGERR_NOFILE )
|
|
{
|
|
regNameVersion.Init(0,0,0,0);
|
|
}
|
|
else
|
|
{
|
|
regNameVersion.Init(cVersion.major,
|
|
cVersion.minor,
|
|
cVersion.release,
|
|
cVersion.build);
|
|
}
|
|
}
|
|
else
|
|
regNameVersion.Init(0,0,0,0);
|
|
|
|
regNameVersion.CompareTo( aVersion, aReturn );
|
|
|
|
if (tempCString)
|
|
Recycle(tempCString);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsInstallTrigger::GetVersion(const nsString& component, nsString& version)
|
|
{
|
|
PRBool enabled;
|
|
|
|
UpdateEnabled(&enabled);
|
|
if (!enabled)
|
|
return NS_OK;
|
|
|
|
VERSION cVersion;
|
|
char* tempCString;
|
|
REGERR status;
|
|
|
|
tempCString = component.ToNewCString();
|
|
|
|
status = VR_GetVersion( tempCString, &cVersion );
|
|
|
|
version.Truncate();
|
|
|
|
/* if we got the version */
|
|
if ( status == REGERR_OK && VR_ValidateComponent( tempCString ) == REGERR_OK)
|
|
{
|
|
nsInstallVersion regNameVersion;
|
|
|
|
regNameVersion.Init(cVersion.major,
|
|
cVersion.minor,
|
|
cVersion.release,
|
|
cVersion.build);
|
|
|
|
regNameVersion.ToString(version);
|
|
}
|
|
|
|
if (tempCString)
|
|
Recycle(tempCString);
|
|
|
|
return NS_OK;
|
|
}
|
|
|