Mozilla/mozilla/modules/softupdt/src/nsSoftwareUpdate.cpp
raman%netscape.com f2d3791cf7 C++ implementation of Java objects. These files are not part of the build system yet.
git-svn-id: svn://10.0.0.236/trunk@8088 18797224-902f-48f8-a5cc-f745e15eee43
1998-08-17 00:45:51 +00:00

1086 lines
29 KiB
C++

/* -*- 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 "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "prmem.h"
#include "prmon.h"
#include "prlog.h"
#include "fe_proto.h"
#include "xp.h"
#include "xp_str.h"
#include "prprf.h"
#include "nsString.h"
#include "nsSoftwareUpdate.h"
#include "nsSoftUpdateEnums.h"
#include "nsInstallObject.h"
#include "nsInstallFile.h"
#include "nsInstallDelete.h"
#include "nsInstallExecute.h"
#include "nsVersionRegistry.h"
#include "nsSUError.h"
#include "nsWinReg.h"
#include "nsPrivilegeManager.h"
#include "nsTarget.h"
#include "nsPrincipal.h"
PR_BEGIN_EXTERN_C
/* Public Methods */
/**
* @param env JavaScript environment (this inside the installer). Contains installer directives
* @param inUserPackageName Name of tha package installed. This name is displayed to the user
*/
nsSoftwareUpdate::nsSoftwareUpdate(void* env, char* inUserPackageName)
{
userPackageName = PR_sprintf_append(userPackageName, "%s", inUserPackageName);
installPrincipal = NULL;
packageName = NULL;
packageFolder = NULL;
installedFiles = NULL;
confdlg = NULL;
progwin = 0;
patchList = new nsHashtable();
zigPtr = NULL;
userChoice = -1;
lastError = 0;
silent = PR_FALSE;
force = PR_FALSE;
/* Need to verify that this is a SoftUpdate JavaScript object */
VerifyJSObject(env);
/* XXX: FIX IT. How do we get data from env
jarName = (String) env.getMember("src");
silent = ((PRBool) env.getMember("silent")).booleanValue();
force = ((PRBool) env.getMember("force")).booleanValue();
*/
#ifdef XP_PC
filesep = "\\";
#elif defined(XP_MAC)
filesep = ":";
#else
filesep = "/";
#endif
}
nsSoftwareUpdate::~nsSoftwareUpdate()
{
CleanUp();
}
nsPrincipal* nsSoftwareUpdate::GetPrincipal()
{
return installPrincipal;
}
char* nsSoftwareUpdate::GetUserPackageName()
{
return userPackageName;
}
char* nsSoftwareUpdate::GetRegPackageName()
{
return packageName;
}
PRBool nsSoftwareUpdate::GetSilent()
{
return silent;
}
/**
* @return a vector of InstallObjects
*/
nsVector* nsSoftwareUpdate::GetInstallQueue()
{
return installedFiles;
}
/**
* @return the most recent non-zero error code
* @see ResetError
*/
PRInt32 nsSoftwareUpdate::GetLastError()
{
return lastError;
}
/**
* resets remembered error code to zero
* @see GetLastError
*/
void nsSoftwareUpdate::ResetError()
{
lastError = 0;
}
/**
* @return the folder object suitable to be passed into AddSubcomponent
* @param folderID One of the predefined folder names
* @see AddSubcomponent
*/
nsFolderSpec* nsSoftwareUpdate::GetFolder(char* folderID, char* *errorMsg)
{
nsFolderSpec* spec = NULL;
errorMsg = NULL;
if ((XP_STRCMP(folderID, "Installed") != 0) &&
(XP_STRCMP(folderID, FOLDER_FILE_URL) != 0)) {
spec = new nsFolderSpec(folderID, packageName, userPackageName);
if (XP_STRCMP(folderID, "User Pick") == 0) {
// Force the prompt
char * ignore = spec->GetDirectoryPath(errorMsg);
if (*errorMsg != NULL)
return NULL;
}
}
return spec;
}
/**
* @return the full path to a component as it is known to the
* Version Registry
* @param component Version Registry component name
*/
nsFolderSpec* nsSoftwareUpdate::GetComponentFolder(char* component)
{
char* allocatedStr=NULL;
char* dir;
nsFolderSpec* spec = NULL;
dir = nsVersionRegistry::getDefaultDirectory( component );
if ( dir == NULL ) {
dir = nsVersionRegistry::componentPath( component );
if ( dir != NULL ) {
int i;
nsString dirStr(dir);
if ((i = dirStr.RFind(filesep)) > 0) {
allocatedStr = new char[i];
allocatedStr = dirStr.ToCString(allocatedStr, i);
dir = allocatedStr;
}
}
}
if ( dir != NULL ) {
/* We have a directory */
spec = new nsFolderSpec("Installed", dir, userPackageName);
}
if (allocatedStr != NULL)
delete allocatedStr;
return spec;
}
nsFolderSpec* nsSoftwareUpdate::GetComponentFolder(char* component, char* subdir, char* *errorMsg)
{
return GetFolder( GetComponentFolder( component ), subdir, errorMsg );
}
/**
* sets the default folder for the package
* @param folder a folder object obtained through GetFolder()
*/
void nsSoftwareUpdate::SetPackageFolder(nsFolderSpec* folder)
{
packageFolder = folder;
}
/**
* Returns a Windows Profile object if you're on windows,
* null if you're not or if there's a security error
*/
void* nsSoftwareUpdate::GetWinProfile(nsFolderSpec* folder, char* file, char* *errorMsg)
{
#ifdef XP_PC
nsWinProfile* profile = NULL;
*errorMsg = NULL;
if ( packageName == NULL ) {
#ifdef XXX /* FIX IT */
*errorMsg = SU_GetErrorMsg3(nsSUStrings::error_WinProfileMustCallStart(), nsSoftUpdateError_INSTALL_NOT_STARTED );
#endif
return NULL;
}
profile = new nsWinProfile(this, folder, file, errorMsg);
return profile;
#else
return NULL;
#endif
}
/**
* @return an object for manipulating the Windows Registry.
* Null if you're not on windows
*/
void* nsSoftwareUpdate::GetWinRegistry(char* *errorMsg)
{
#ifdef XP_PC
nsWinReg* registry = NULL;
if ( packageName == NULL ) {
#ifdef XXX /* FIX IT */
*errorMsg = SU_GetErrorMsg3(nsSUStrings::error_WinProfileMustCallStart(), nsSoftUpdateError_INSTALL_NOT_STARTED );
#endif
return NULL;
}
registry = new nsWinReg(this, errorMsg);
return registry;
#else
return NULL;
#endif /* XP_PC */
}
/**
* extract the file out of the JAR directory and places it into temporary
* directory.
* two security checks:
* - the certificate of the extracted file must match the installer certificate
* - must have privileges to extract the jar file
* @param inJarLocation file name inside the JAR file
*/
char* nsSoftwareUpdate::ExtractJARFile(char* inJarLocation, char* finalFile, char* *errorMsg)
{
if (zigPtr == NULL) {
*errorMsg = SU_GetErrorMsg3("JAR file has not been opened", nsSoftUpdateError_UNKNOWN_JAR_FILE );
return NULL;
}
/* Security checks */
nsTarget* target;
nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager();
target = nsTarget::findTarget( INSTALL_PRIV );
if (target != NULL) {
if (!privMgr->isPrivilegeEnabled(target, 1)) {
return NULL;
}
}
/* Make sure that the certificate of the extracted file matches
the installer certificate */
/* XXX this needs to be optimized, so that we do not create a principal
for every certificate */
{
PRUint32 i;
PRBool haveMatch = PR_FALSE;
nsPrincipalArray* prinArray = (nsPrincipalArray*)getCertificates( zigPtr, inJarLocation );
if ((prinArray == NULL) || (prinArray->GetSize() == 0)) {
char *msg = PR_sprintf_append("Missing certificate for %s", inJarLocation);
*errorMsg = SU_GetErrorMsg3(msg, nsSoftUpdateError_NO_CERTIFICATE);
PR_FREEIF(msg);
return NULL;
}
PRUint32 noOfPrins = prinArray->GetSize();
for (i=0; i < noOfPrins; i++) {
nsPrincipal* prin = (nsPrincipal*)prinArray->Get(i);
if (installPrincipal->equals( prin )) {
haveMatch = true;
break;
}
}
if (haveMatch == false) {
char *msg = NULL;
msg = PR_sprintf_append(msg, "Missing certificate for %s", inJarLocation);
*errorMsg = SU_GetErrorMsg3(msg, nsSoftUpdateError_NO_MATCHING_CERTIFICATE);
PR_FREEIF(msg);
}
/* Free all the objects */
for (i=0; i < noOfPrins; i++) {
nsPrincipal* prin = (nsPrincipal*)prinArray->Get(i);
delete prin;
prinArray->Set(i, NULL);
}
delete prinArray;
if (*errorMsg != NULL)
return NULL;
}
/* Extract the file */
char* outExtractLocation = NativeExtractJARFile(inJarLocation, finalFile, errorMsg);
return outExtractLocation;
}
/**
* Call this to initialize the update
* Opens the jar file and gets the certificate of the installer
* Opens up the gui, and asks for proper security privileges
* @param vrPackageName Full qualified version registry name of the package
* (ex: "/Plugins/Adobe/Acrobat")
* NULL or empty package names are errors
* @param inVInfo version of the package installed.
* Can be NULL, in which case package is installed
* without a version. Having a NULL version, this package is
* automatically updated in the future (ie. no version check is performed).
* @param securityLevel ignored (was LIMITED_INSTALL or FULL_INSTALL)
*/
PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, nsVersionInfo* inVInfo, PRInt32 securityLevel, char* *errorMsg)
{
// ignore securityLevel
return StartInstall( vrPackageName, inVInfo, errorMsg);
}
/**
* An new form that doesn't require the security level
*/
PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, nsVersionInfo* inVInfo, char* *errorMsg)
{
int errcode= nsSoftwareUpdate_SUCCESS;
ResetError();
if ( (vrPackageName == NULL) ) {
#ifdef XXX /* FIX IT */
*errorMsg = SU_GetErrorMsg3(nsSUStrings::error_BadPackageName(), nsSoftUpdateError_INVALID_ARGUMENTS );
#endif
return nsSoftUpdateError_INVALID_ARGUMENTS;
}
packageName = PR_sprintf_append(packageName, "%s", vrPackageName);
int len = XP_STRLEN(vrPackageName);
int last_pos = len-1;
char* packageName = new char[len+1];
XP_STRCPY(packageName, vrPackageName);
while ((last_pos >= 0) && (packageName[last_pos] == '/')) {
// Make sure that package name does not end with '/'
char* ptr = new char[last_pos+1];
memcpy(packageName, ptr, last_pos);
packageName[last_pos] = '\0';
delete packageName;
packageName = ptr;
last_pos = last_pos - 1;
}
versionInfo = inVInfo;
installedFiles = new nsVector();
/* JAR initalization */
/* open the file, create a principal out of installer file certificate */
OpenJARFile(errorMsg);
InitializeInstallerCertificate(errorMsg);
CheckSilentPrivileges(errorMsg);
RequestSecurityPrivileges(errorMsg);
OpenProgressDialog(errorMsg);
if (*errorMsg == NULL)
return nsSoftUpdateError_UNEXPECTED_ERROR;
// set up default package folder, if any
char* path = nsVersionRegistry::getDefaultDirectory( packageName );
if ( path != NULL ) {
packageFolder = new nsFolderSpec("Installed", path, userPackageName);
}
saveError( errcode );
return errcode;
}
/**
* another StartInstall() simplification -- version as char*
*/
PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, char* inVer, char* *errorMsg)
{
return StartInstall( vrPackageName, new nsVersionInfo( inVer ), errorMsg );
}
/*
* UI feedback
*/
void nsSoftwareUpdate::UserCancelled()
{
userChoice = 0;
AbortInstall();
}
void nsSoftwareUpdate::UserApproved()
{
userChoice = 1;
}
/**
* Proper completion of the install
* Copies all the files to the right place
* returns 0 on success, <0 error code on failure
*/
PRInt32 nsSoftwareUpdate::FinalizeInstall(char* *errorMsg)
{
PRBool rebootNeeded = false;
int result = nsSoftwareUpdate_SUCCESS;
SetProgressDialogItem(""); // blank the "current item" line
if (packageName == NULL) {
// probably didn't call StartInstall()
#ifdef XXX /* FIX IT */
*errorMsg = SU_GetErrorMsg3(nsSUStrings::error_WinProfileMustCallStart(), nsSoftUpdateError_INSTALL_NOT_STARTED);
#endif
return nsSoftUpdateError_UNEXPECTED_ERROR;
}
if ( installedFiles == NULL || installedFiles->GetSize() == 0 ) {
// no actions queued: don't register the package version
// and no need for user confirmation
CleanUp();
return result; // XXX: a different status code here?
}
// Wait for user approval
#ifdef XXX /* FIX IT */
if ( !silent && UserWantsConfirm() ) {
confdlg = new nsProgressDetails(this);
/* XXX What is this?
while ( userChoice == -1 )
Thread.sleep(10);
*/
confdlg = NULL;
if (userChoice != 1) {
AbortInstall();
return saveError(nsSoftUpdateError_USER_CANCELLED);
}
}
SetProgressDialogRange( installedFiles->GetSize() );
#endif /* XXX */
// Register default package folder if set
if ( packageFolder != NULL ) {
nsVersionRegistry::setDefaultDirectory( packageName, packageFolder->toString() );
}
/* call Complete() on all the elements */
/* If an error occurs in the middle, call Abort() on the rest */
nsVector* ve = GetInstallQueue();
nsInstallObject* ie = NULL;
// Main loop
int count = 0;
nsVersionRegistry::uninstallCreate(packageName, userPackageName);
PRUint32 i=0;
for (i=0; i < ve->GetSize(); i++) {
ie = (nsInstallObject*)ve->Get(i);
if (ie == NULL)
continue;
ie->Complete(errorMsg);
if (errorMsg != NULL) {
ie->Abort();
return nsSoftUpdateError_UNEXPECTED_ERROR;
}
SetProgressDialogThermo(++count);
}
// add overall version for package
if ( versionInfo != NULL) {
result = nsVersionRegistry::installComponent(packageName, NULL, versionInfo);
}
CleanUp();
if (result == nsSoftwareUpdate_SUCCESS && rebootNeeded)
result = nsSoftwareUpdate_REBOOT_NEEDED;
saveError( result );
return result;
}
/**
* Aborts the install :), cleans up all the installed files
* XXX: This is a synchronized method. FIX it.
*/
void nsSoftwareUpdate::AbortInstall()
{
nsInstallObject* ie;
if (installedFiles != NULL) {
nsVector* ve = GetInstallQueue();
PRUint32 i=0;
for (i=0; i < ve->GetSize(); i++) {
ie = (nsInstallObject *)ve->Get(i);
if (ie == NULL)
continue;
ie->Abort();
}
}
CloseJARFile();
CleanUp();
}
/**
* ScheduleForInstall
* call this to put an InstallObject on the install queue
* Do not call installedFiles.addElement directly, because this routine also handles
* progress messages
*/
char* nsSoftwareUpdate::ScheduleForInstall(nsInstallObject* ob)
{
char *errorMsg = NULL;
// flash current item
SetProgressDialogItem( ob->toString() );
// do any unpacking or other set-up
errorMsg = ob->Prepare();
if (errorMsg != NULL) {
return errorMsg;
}
// Add to installation list if we haven't thrown out
installedFiles->Add( ob );
// if (confdlg != NULL)
// confdlg.ScheduleForInstall( ob );
return NULL;
}
/**
* Extract a file from JAR archive to the disk, and update the
* version registry. Actually, keep a record of elements to be installed. FinalizeInstall()
* does the real installation. Install elements are accepted if they meet one of the
* following criteria:
* 1) There is no entry for this subcomponnet in the registry
* 2) The subcomponent version info is newer than the one installed
* 3) The subcomponent version info is NULL
*
* @param name path of the package in the registry. Can be:
* absolute: "/Plugins/Adobe/Acrobat/Drawer.exe"
* relative: "Drawer.exe". Relative paths are relative to main package name
* NULL: if NULL jarLocation is assumed to be the relative path
* @param version version of the subcomponent. Can be NULL
* @param jarSource location of the file to be installed inside JAR
* @param folderSpec one of the predefined folder locations
* @see GetFolder
* @param relativePath where the file should be copied to on the local disk.
* Relative to folder
* if NULL, use the path to the JAR source.
* @param forceInstall if true, file is always replaced
*/
PRInt32 nsSoftwareUpdate::AddSubcomponent(char* name,
nsVersionInfo* version,
char* jarSource,
nsFolderSpec* folderSpec,
char* relativePath,
PRBool forceInstall,
char* *errorMsg)
{
nsInstallFile* ie;
int result = nsSoftwareUpdate_SUCCESS;
*errorMsg = NULL;
if ( jarSource == NULL || (XP_STRLEN(jarSource) == 0) ) {
*errorMsg = SU_GetErrorMsg3("No Jar Source", nsSoftUpdateError_INVALID_ARGUMENTS );
return nsSoftUpdateError_INVALID_ARGUMENTS;
}
if ( folderSpec == NULL ) {
*errorMsg = SU_GetErrorMsg3("folderSpec is NULL ", nsSoftUpdateError_INVALID_ARGUMENTS );
return nsSoftUpdateError_INVALID_ARGUMENTS;
}
if (packageName == NULL) {
// probably didn't call StartInstall()
#ifdef XXX /* FIX IT */
*errorMsg = SU_GetErrorMsg3(nsSUStrings::error_BadPackageNameAS(), nsSoftUpdateError_BAD_PACKAGE_NAME );
#endif
return nsSoftUpdateError_BAD_PACKAGE_NAME;
}
if ((name == NULL) || (XP_STRLEN(name) == 0)) {
// Default subName = location in jar file
name = GetQualifiedRegName( jarSource );
} else {
name = GetQualifiedRegName( name );
}
if ( (relativePath == NULL) || (XP_STRLEN(relativePath) == 0) ) {
relativePath = jarSource;
}
/* Check for existence of the newer version */
PRBool versionNewer = PR_FALSE;
if ( (forceInstall == PR_FALSE ) &&
(version != NULL) &&
( nsVersionRegistry::validateComponent( name ) == 0 ) ) {
nsVersionInfo* oldVersion = nsVersionRegistry::componentVersion(name);
if ( version->compareTo( oldVersion ) != nsVersionEnum_EQUAL )
versionNewer = PR_TRUE;
} else {
versionNewer = PR_TRUE;
}
if (versionNewer) {
ie = new nsInstallFile( this, name, version, jarSource,
folderSpec, relativePath, forceInstall,
errorMsg );
if (errorMsg == NULL) {
*errorMsg = ScheduleForInstall( ie );
}
}
if (*errorMsg != NULL) {
result = nsSoftUpdateError_UNEXPECTED_ERROR;
}
saveError( result );
return result;
}
/**
* executes the file
* @param jarSource name of the file to execute inside JAR archive
* @param args command-line argument string (Win/Unix only)
*/
PRInt32 nsSoftwareUpdate::Execute(char* jarSource, char* *errorMsg, char* args)
{
int errcode = nsSoftwareUpdate_SUCCESS;
nsInstallExecute* ie = new nsInstallExecute(this, jarSource, errorMsg, args);
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_ACCESS_DENIED;
} else {
*errorMsg = ScheduleForInstall( ie );
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_UNEXPECTED_ERROR;
}
}
saveError( errcode );
return errcode;
}
#ifdef XP_MAC
#include <Gestalt.h>
#endif
/**
* Mac-only, simulates Mac toolbox Gestalt function
* OSErr Gestalt(char* selector, long * response)
* @param selector 4-character string,
* @param os_err corresponds to OSErr
* @param errorMsg Error message
* @return an integer corresponding to response from Gestalt
*/
PRInt32 nsSoftwareUpdate::Gestalt(char* selectorStr, int* os_err, char* *errorMsg)
{
*errorMsg = NULL;
#ifdef XP_MAC
*os_err = noErr;
long response = 0;
OSType selector;
if ((selectorStr == NULL) ||
(XP_STRLEN(selectorStr) != 4))
{
*os_err = nsSoftUpdateError_GESTALT_UNKNOWN_ERR; /* gestaltUnknownErr */
goto fail;
}
XP_MEMCPY(&selector, selectorStr, 4);
*os_err = (int)Gestalt(selector, response);
if (*os_err == noErr) {
return response;
}
goto fail; /* Drop through to failure */
#else
*os_err = nsSoftUpdateError_GESTALT_INVALID_ARGUMENT;
goto fail;
#endif
fail:
#ifdef XXX /* FIX IT */
*errorMsg = SU_GetErrorMsg3(nsSUStrings::error_ExtractFailed(), *os_err );
#endif
return 0;
}
/**
* Patch
*
*/
PRInt32 nsSoftwareUpdate::Patch(char* regName, nsVersionInfo* version, char* patchname, char* *errorMsg)
{
int errcode = nsSoftwareUpdate_SUCCESS;
if ( regName == NULL || patchname == NULL ) {
*errorMsg = SU_GetErrorMsg3("regName or patchName is NULL ", nsSoftUpdateError_INVALID_ARGUMENTS );
return saveError( nsSoftUpdateError_INVALID_ARGUMENTS );
}
char* rname = GetQualifiedRegName( regName );
#ifdef XXX /* FIX IT */
nsInstallPatch* ip = new nsInstallPatch(this, rname, version, patchname, errorMsg);
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_ACCESS_DENIED;
} else {
*errorMsg = ScheduleForInstall( ip );
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_UNEXPECTED_ERROR;
}
}
#endif /* XXX */
saveError( errcode );
return errcode;
}
PRInt32 nsSoftwareUpdate::Patch(char* regName, nsVersionInfo* version, char* patchname,
nsFolderSpec* folder, char* filename, char* *errorMsg)
{
if ( folder == NULL || regName == NULL || XP_STRLEN(regName) == 0 || patchname == NULL ) {
*errorMsg = SU_GetErrorMsg3("folder or regName or patchName is NULL ", nsSoftUpdateError_INVALID_ARGUMENTS );
return saveError( nsSoftUpdateError_INVALID_ARGUMENTS );
}
int errcode = nsSoftwareUpdate_SUCCESS;
char* rname = GetQualifiedRegName( regName );
#ifdef XXX /* FIX IT */
nsInstallPatch* ip = new nsInstallPatch( this, rname, version,
patchname, folder, filename, errorMsg );
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_ACCESS_DENIED;
} else {
*errorMsg = ScheduleForInstall( ip );
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_UNEXPECTED_ERROR;
}
}
#endif /* XXX */
saveError( errcode );
return errcode;
}
/**
* This method deletes the specified file from the disk. It does not look
* for the file in the registry and is guaranteed to muddle any uninstall
* reference counting. Its main purpose is to delete files installed or
* created outside of SmartUpdate.
*/
PRInt32 nsSoftwareUpdate::DeleteFile(nsFolderSpec* folder, char* relativeFileName, char* *errorMsg)
{
int errcode = nsSoftwareUpdate_SUCCESS;
nsInstallDelete* id = new nsInstallDelete(this, folder, relativeFileName, errorMsg);
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_ACCESS_DENIED;
} else {
*errorMsg = ScheduleForInstall( id );
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_UNEXPECTED_ERROR;
}
}
/* XXX: who set FILE_DOES_NOT_EXIST errcode ?? */
if (errcode == nsSoftUpdateError_FILE_DOES_NOT_EXIST) {
errcode = nsSoftwareUpdate_SUCCESS;
}
saveError( errcode );
return errcode;
}
/**
* This method finds named registry component and deletes both the file and the
* entry in the Client VR. registryName is the name of the component in the registry.
* Returns usual errors codes + code to indicate item doesn't exist in registry, registry
* item wasn't a file item, or the related file doesn't exist. If the file is in use we will
* store the name and to try to delete it on subsequent start-ups until we're successful.
*/
PRInt32 nsSoftwareUpdate::DeleteComponent(char* registryName, char* *errorMsg)
{
int errcode = nsSoftwareUpdate_SUCCESS;
nsInstallDelete* id = new nsInstallDelete(this, NULL, registryName, errorMsg);
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_ACCESS_DENIED;
} else {
*errorMsg = ScheduleForInstall( id );
if (*errorMsg != NULL) {
errcode = nsSoftUpdateError_UNEXPECTED_ERROR;
}
}
/* XXX: who set FILE_DOES_NOT_EXIST errcode ?? */
if (errcode == nsSoftUpdateError_FILE_DOES_NOT_EXIST) {
errcode = nsSoftwareUpdate_SUCCESS;
}
saveError( errcode );
return errcode;
}
nsFolderSpec* nsSoftwareUpdate::GetFolder(char* targetFolder, char* subdirectory, char* *errorMsg)
{
if (XP_STRCMP(targetFolder, FOLDER_FILE_URL) == 0) {
char* newPath = NULL;
char* path = NativeFileURLToNative("/", subdirectory );
if ( path != NULL ) {
PRInt32 filesep_len = XP_STRLEN(filesep);
PRInt32 path_len = XP_STRLEN(path);
PRBool ends_with_filesep = PR_FALSE;
if (path_len >= filesep_len) {
ends_with_filesep = (XP_STRSTR(&path[path_len - filesep_len], filesep) ? PR_TRUE : PR_FALSE);
}
if (ends_with_filesep) {
return new nsFolderSpec("Installed", path, userPackageName);
} else {
newPath = PR_sprintf_append(newPath, "%s%s", path, filesep);
return new nsFolderSpec("Installed", newPath, userPackageName);
}
} else {
return NULL;
}
} else {
return GetFolder( GetFolder(targetFolder, NULL, errorMsg), subdirectory, errorMsg );
}
}
nsFolderSpec* nsSoftwareUpdate::GetFolder(nsFolderSpec* folder, char* subdir, char* *errorMsg)
{
/* XXX: FIX IT */
return NULL;
}
/**
* This method returns true if there is enough free diskspace, false if there isn't.
* The drive containg the folder is checked for # of free bytes.
*/
long nsSoftwareUpdate::DiskSpaceAvailable(nsFolderSpec* folder)
{
/* XXX: Fix it */
return 0;
}
/**
* This method is used to install an entire subdirectory of the JAR.
* Any files so installed are individually entered into the registry so they
* can be uninstalled later. Like AddSubcomponent the directory is installed
* only if the version specified is greater than that already registered,
* or if the force parameter is true.The final version presented is the complete
* form, the others are for convenience and assume values for the missing
* arguments.
*/
PRInt32 nsSoftwareUpdate::AddDirectory(char* name,
nsVersionInfo* version,
char* jarSource,
nsFolderSpec* folderSpec,
char* subdir,
PRBool forceInstall)
{
/* XXX: Fix it */
return 0;
}
/* Uninstall */
PRInt32 nsSoftwareUpdate::Uninstall(char* packageName)
{
/* XXX: Fix it */
return 0;
}
/*******************************
*
* progress window
*
* functions for dealing with the progress window.
* normally I'd make this an object, but since we're implementing
* it with native routines and will soon be getting rid of Java
* altogether this makes more sense for now. Creating a new object
* would only lead to more JRI hell, especially on the Mac
*******************************/
void nsSoftwareUpdate::OpenProgressDialog()
{
}
void nsSoftwareUpdate::CloseProgressDialog()
{
}
void nsSoftwareUpdate::SetProgressDialogItem(char* message)
{
}
void nsSoftwareUpdate::SetProgressDialogRange(PRInt32 max)
{
}
void nsSoftwareUpdate::SetProgressDialogThermo(PRInt32 value)
{
}
/* Private Methods */
/*
* Reads in the installer certificate, and creates its principal
*/
char* nsSoftwareUpdate::InitializeInstallerCertificate()
{
/* XXX: Fix it */
return NULL;
}
/*
* checks if our principal has privileges for silent install
*/
PRBool nsSoftwareUpdate::CheckSilentPrivileges()
{
/* XXX: Fix it */
return PR_FALSE;
}
/* Request the security privileges, so that the security dialogs
* pop up
*/
void nsSoftwareUpdate::RequestSecurityPrivileges()
{
}
/**
* saves non-zero error codes so they can be seen by GetLastError()
*/
PRInt32 nsSoftwareUpdate::saveError(PRInt32 errcode)
{
/* XXX: Fix it */
return 0;
}
/*
* CleanUp
* call it when done with the install
*
* XXX: This is a synchronized method. FIX it.
*/
void nsSoftwareUpdate::CleanUp()
{
nsInstallObject* ie;
if ( installedFiles != NULL ) {
PRUint32 i=0;
for (; i < installedFiles->GetSize(); i++) {
ie = (nsInstallObject*)installedFiles->Get(i);
delete ie;
}
installedFiles->RemoveAll();
}
}
/**
* GetQualifiedRegName
*
* This routine converts a package-relative component registry name
* into a full name that can be used in calls to the version registry.
*/
char* nsSoftwareUpdate::GetQualifiedRegName(char* name)
{
/* XXX: Fix it */
return NULL;
}
/* Private Native methods */
/* VerifyJSObject
* Make sure that JSObject is of type SoftUpdate.
* Since SoftUpdate JSObject can only be created by C code
* we cannot be spoofed
*/
void nsSoftwareUpdate::VerifyJSObject(void* jsObj)
{
}
/* Open/close the jar file
*/
char* nsSoftwareUpdate::OpenJARFile()
{
/* XXX: Fix it */
return NULL;
}
void nsSoftwareUpdate::CloseJARFile()
{
}
/* getCertificates
* native encapsulation that calls AppletClassLoader.getCertificates
* we cannot call this method from Java because it is private.
* The method cannot be made public because it is a security risk
*/
void* nsSoftwareUpdate::getCertificates(void* zigPtr, char* pathname)
{
return nsPrincipal::getSigners(zigPtr, pathname);
}
char* nsSoftwareUpdate::NativeExtractJARFile(char* inJarLocation, char* finalFile, char* *errorMsg)
{
/* XXX: Fix it */
return NULL;
}
PRInt32 nsSoftwareUpdate::NativeMakeDirectory(char* path)
{
/* XXX: Fix it */
return 0;
}
long nsSoftwareUpdate::NativeDiskSpaceAvailable(char* path)
{
/* XXX: Fix it */
return 0;
}
char* nsSoftwareUpdate::NativeFileURLToNative(char* dir, char* path)
{
/* XXX: Fix it */
return NULL;
}
char** nsSoftwareUpdate::ExtractDirEntries(char* Dir)
{
/* XXX: Fix it */
return NULL;
}
PRInt32 nsSoftwareUpdate::NativeOpenProgDlg(char* packageName)
{
/* XXX: Fix it */
return 0;
}
void nsSoftwareUpdate::NativeCloseProgDlg(PRInt32 progptr)
{
}
void nsSoftwareUpdate::NativeSetProgDlgItem(PRInt32 progptr, char* message)
{
}
void nsSoftwareUpdate::NativeSetProgDlgRange(PRInt32 progptr, PRInt32 max)
{
}
void nsSoftwareUpdate::NativeSetProgDlgThermo(PRInt32 progptr, PRInt32 value)
{
}
PRBool nsSoftwareUpdate::UserWantsConfirm()
{
/* XXX: Fix it */
return PR_FALSE;
}
PR_END_EXTERN_C