diff --git a/mozilla/modules/softupdt/include/nsFolderSpec.h b/mozilla/modules/softupdt/include/nsFolderSpec.h index 5e2b6f6dc61..defc825ac3e 100644 --- a/mozilla/modules/softupdt/include/nsFolderSpec.h +++ b/mozilla/modules/softupdt/include/nsFolderSpec.h @@ -93,7 +93,7 @@ private: * NativePickDefaultDirectory * Platform-specific implementation of GetDirectoryPath */ - char* NativePickDefaultDirectory(char* *errorMsg); + char* NativePickDefaultDirectory(void); PRBool NativeIsJavaDir(); diff --git a/mozilla/modules/softupdt/include/nsInstallDelete.h b/mozilla/modules/softupdt/include/nsInstallDelete.h index 9946db2bf59..6b337d73c1c 100644 --- a/mozilla/modules/softupdt/include/nsInstallDelete.h +++ b/mozilla/modules/softupdt/include/nsInstallDelete.h @@ -21,6 +21,7 @@ #include "prtypes.h" #include "nsSoftwareUpdate.h" +#include "nsFolderSpec.h" PR_BEGIN_EXTERN_C @@ -62,7 +63,7 @@ private: char* registryName; // final file to be deleted /* Private Methods */ - void processInstallDelete(); + void processInstallDelete(char* *errorMsg); int NativeComplete(); int NativeCheckFileStatus(); diff --git a/mozilla/modules/softupdt/include/nsInstallExecute.h b/mozilla/modules/softupdt/include/nsInstallExecute.h index fd162a3e3d4..e85b4b39b56 100644 --- a/mozilla/modules/softupdt/include/nsInstallExecute.h +++ b/mozilla/modules/softupdt/include/nsInstallExecute.h @@ -43,15 +43,15 @@ public: /* Prepare * Extracts file out of the JAR archive into the temp directory */ - char* Prepare(); + char* Prepare(void); /* Complete * Completes the install by executing the file * Security hazard: make sure we request the right permissions */ - char* Complete(); + char* Complete(void); - void Abort(); + void Abort(void); char* toString(); @@ -64,8 +64,8 @@ private: char* cmdline; // constructed command-line /* Private Methods */ - void NativeComplete(); - void NativeAbort(); + char* NativeComplete(void); + void NativeAbort(void); }; diff --git a/mozilla/modules/softupdt/include/nsInstallPath.h b/mozilla/modules/softupdt/include/nsInstallPatch.h similarity index 66% rename from mozilla/modules/softupdt/include/nsInstallPath.h rename to mozilla/modules/softupdt/include/nsInstallPatch.h index 729088317f5..2137ded4e96 100644 --- a/mozilla/modules/softupdt/include/nsInstallPath.h +++ b/mozilla/modules/softupdt/include/nsInstallPatch.h @@ -16,8 +16,8 @@ * Reserved. */ -#ifndef nsInstallPath_h__ -#define nsInstallPath_h__ +#ifndef nsInstallPatch_h__ +#define nsInstallPatch_h__ #include "prtypes.h" #include "nsSoftwareUpdate.h" @@ -27,7 +27,7 @@ PR_BEGIN_EXTERN_C -struct nsInstallPath { +struct nsInstallPatch : public nsInstallObject { public: @@ -46,48 +46,51 @@ public: nsInstallPatch(nsSoftwareUpdate* inSoftUpdate, char* inVRName, nsVersionInfo* inVInfo, - char* inJarLocation); - + char* inJarLocation, + char* *errorMsg); + nsInstallPatch(nsSoftwareUpdate* inSoftUpdate, char* inVRName, nsVersionInfo* inVInfo, char* inJarLocation, nsFolderSpec* folderSpec, - char* inPartialPath); + char* inPartialPath, + char* *errorMsg); + - ~nsInstallPath(); + virtual ~nsInstallPatch(); - void Prepare(); + char* Prepare(void); /* Complete * Completes the install: * - move the patched file to the final location * - updates the registry */ - void Complete(); + char* Complete(void); - void Abort(); + void Abort(void); - char* toString(); + char* toString(void); private: /* Private Fields */ - char* vrName; // Registry name of the component - nsVersionInfo* versionInfo; // Version - char* jarLocation; // Location in the JAR - char* patchURL; // extracted location of diff (xpURL) - char* targetfile; // source and final file (native) - char* patchedfile; // temp name of patched file + char* vrName; // Registry name of the component + nsVersionInfo* versionInfo; // Version + char* jarLocation; // Location in the JAR + char* patchURL; // extracted location of diff (xpURL) + char* targetfile; // source and final file (native) + char* patchedfile; // temp name of patched file /* Private Methods */ - void checkPrivileges(); - char* NativePatch( char* srcfile, char* diffURL ); - PRInt32 NativeReplace( char* target, char* tmpfile ); - void NativeDeleteFile( char* file ); + char* checkPrivileges(void); + char* NativePatch( char* srcfile, char* diffURL, char* *errorMsg ); + int NativeReplace( char* target, char* tmpfile ); + void NativeDeleteFile( char* filename ); }; PR_END_EXTERN_C -#endif /* nsInstallPath_h__ */ +#endif /* nsInstallPatch_h__ */ diff --git a/mozilla/modules/softupdt/include/nsSoftUpdateEnums.h b/mozilla/modules/softupdt/include/nsSoftUpdateEnums.h index cd972e5af0b..0ff8c398b1c 100644 --- a/mozilla/modules/softupdt/include/nsSoftUpdateEnums.h +++ b/mozilla/modules/softupdt/include/nsSoftUpdateEnums.h @@ -58,10 +58,14 @@ typedef enum nsInstallType { } nsInstallType; typedef enum nsVersionEnum { - nsVersionEnum_MAJOR_DIFF = 4, - nsVersionEnum_MINOR_DIFF = 3, - nsVersionEnum_REL_DIFF = 2, - nsVersionEnum_BLD_DIFF = 1, + nsVersionEnum_MAJOR_DIFF = 4, + nsVersionEnum_MAJOR_DIFF_MINUS = -4, + nsVersionEnum_MINOR_DIFF = 3, + nsVersionEnum_MINOR_DIFF_MINUS = -3, + nsVersionEnum_REL_DIFF = 2, + nsVersionEnum_REL_DIFF_MINUS = -2, + nsVersionEnum_BLD_DIFF = 1, + nsVersionEnum_BLD_DIFF_MINUS = -1, nsVersionEnum_EQUAL = 0 } nsVersionEnum; @@ -112,25 +116,6 @@ typedef enum nsWinRegValueEnum { } nsWinRegValueEnum; typedef enum nsRegistryErrorsEnum { - REGERR_OK = 0, - REGERR_FAIL = 1, - REGERR_NOMORE = 2, - REGERR_NOFIND = 3, - REGERR_BADREAD = 4, - REGERR_BADLOCN = 5, - REGERR_PARAM = 6, - REGERR_BADMAGIC = 7, - REGERR_BADCHECK = 8, - REGERR_NOFILE = 9, - REGERR_MEMORY = 10, - REGERR_BUFTOOSMALL = 11, - REGERR_NAMETOOLONG = 12, - REGERR_REGVERSION = 13, - REGERR_DELETED = 14, - REGERR_BADTYPE = 15, - REGERR_NOPATH = 16, - REGERR_BADNAME = 17, - REGERR_READONLY = 18, REGERR_BADUTF8 = 19, REGERR_SECURITY = 99, diff --git a/mozilla/modules/softupdt/include/nsSoftwareUpdate.h b/mozilla/modules/softupdt/include/nsSoftwareUpdate.h index 7f5c1d0c4b9..e987c9daac6 100644 --- a/mozilla/modules/softupdt/include/nsSoftwareUpdate.h +++ b/mozilla/modules/softupdt/include/nsSoftwareUpdate.h @@ -291,11 +291,12 @@ public: char* jarSource, nsFolderSpec* folderSpec, char* subdir, - PRBool forceInstall); + PRBool forceInstall, + char* *errorMsg); /* Uninstall */ - PRInt32 Uninstall(char* packageName); + PRInt32 Uninstall(char* packageName, char* *errorMsg); /******************************* @@ -308,9 +309,9 @@ public: * altogether this makes more sense for now. Creating a new object * would only lead to more JRI hell, especially on the Mac *******************************/ - void OpenProgressDialog(); + void OpenProgressDialog(void); - void CloseProgressDialog(); + void CloseProgressDialog(void); void SetProgressDialogItem(char* message); @@ -327,13 +328,14 @@ private: nsProgressDetails* confdlg; /* Detail confirmation dialog */ PRInt32 userChoice; /* User feedback: -1 unknown, 0 is cancel, 1 is OK */ - PRInt32 progwin; /* pointer to native progress window */ + void* progwin; /* pointer to native progress window */ PRBool silent; /* Silent upgrade? */ PRBool force; /* Force install? */ PRInt32 lastError; /* the most recent non-zero error */ char* filesep; /* the platform-specific file separator */ char* installerJarName; /* Name of the installer file */ + unsigned long installerJarNameLength; /* Length of Name of the installer file */ char* jarName; /* Name of the JAR file */ char* jarCharset; /* Charset for filenames in JAR */ void* zigPtr; /* Stores the pointer to ZIG * */ @@ -347,7 +349,7 @@ private: /* * Reads in the installer certificate, and creates its principal */ - char* InitializeInstallerCertificate(); + PRInt32 InitializeInstallerCertificate(char* *errorMsg); /* * checks if our principal has privileges for silent install @@ -358,7 +360,7 @@ private: /* Request the security privileges, so that the security dialogs * pop up */ - void RequestSecurityPrivileges(); + PRInt32 RequestSecurityPrivileges(char* *errorMsg); /** @@ -393,11 +395,11 @@ private: * Since SoftUpdate JSObject can only be created by C code * we cannot be spoofed */ - void VerifyJSObject(void* jsObj); + char* VerifyJSObject(void* jsObj); /* Open/close the jar file */ - char* OpenJARFile(); + PRInt32 OpenJARFile(char* *errorMsg); void CloseJARFile(); /* getCertificates @@ -407,6 +409,8 @@ private: */ void* getCertificates(void* zigPtr, char* inJarLocation); + void freeCertificates(void* prins); + char* NativeExtractJARFile(char* inJarLocation, char* finalFile, char* *errorMsg); PRInt32 NativeMakeDirectory(char* path);; @@ -415,13 +419,13 @@ private: char* NativeFileURLToNative(char* Dir, char* path); - char** ExtractDirEntries(char* Dir); + char** ExtractDirEntries(char* Dir, int *length); - PRInt32 NativeOpenProgDlg(char* packageName); - void NativeCloseProgDlg(PRInt32 progptr); - void NativeSetProgDlgItem(PRInt32 progptr, char* message); - void NativeSetProgDlgRange(PRInt32 progptr, PRInt32 max); - void NativeSetProgDlgThermo(PRInt32 progptr, PRInt32 value); + void* NativeOpenProgDlg(char* packageName); + void NativeCloseProgDlg(void* progptr); + void NativeSetProgDlgItem(void* progptr, char* message); + void NativeSetProgDlgRange(void* progptr, PRInt32 max); + void NativeSetProgDlgThermo(void* progptr, PRInt32 value); PRBool UserWantsConfirm(); }; diff --git a/mozilla/modules/softupdt/include/nsTrigger.h b/mozilla/modules/softupdt/include/nsTrigger.h index 029c6bd07ae..b0595e7dce4 100644 --- a/mozilla/modules/softupdt/include/nsTrigger.h +++ b/mozilla/modules/softupdt/include/nsTrigger.h @@ -53,7 +53,7 @@ public: /** * @return true if SmartUpdate is enabled */ - static PRBool UpdateEnabled(); + static PRBool UpdateEnabled(void); /** * @param componentName version registry name of the component @@ -100,6 +100,10 @@ public: nsVersionInfo* version, PRInt32 flags); + + static PRBool ConditionalSoftwareUpdate(char* url, + char* componentName, + char* version); /** * Validates existence and compares versions diff --git a/mozilla/modules/softupdt/src/nsInstallPath.cpp b/mozilla/modules/softupdt/include/nsUninstallObject.h similarity index 52% rename from mozilla/modules/softupdt/src/nsInstallPath.cpp rename to mozilla/modules/softupdt/include/nsUninstallObject.h index 540e33eaaec..69ccb87894d 100644 --- a/mozilla/modules/softupdt/src/nsInstallPath.cpp +++ b/mozilla/modules/softupdt/include/nsUninstallObject.h @@ -16,9 +16,49 @@ * Reserved. */ -#include "nsInstallPath.h" +#ifndef nsUninstallObject_h__ +#define nsUninstallObject_h__ + +#include "prtypes.h" +#include "nsSoftwareUpdate.h" + PR_BEGIN_EXTERN_C +struct nsUninstallObject : public nsInstallObject { + +public: + + /* Public Fields */ + + /* Public Methods */ + + nsUninstallObject(nsSoftwareUpdate* inSoftUpdate, char* inRegName, char* *errorMsg); + + virtual ~nsUninstallObject(); + + /* Complete + * Uninstalls the package + */ + char* Complete(); + + char* Prepare(); + + void Abort(); + + char* toString(); + +private: + + /* Private Fields */ + char* regName; // Registry name of package + char* userName; // User name of package + + /* Private Methods */ + char* NativeComplete(char* regname); + +}; PR_END_EXTERN_C + +#endif /* nsUninstallObject_h__ */ diff --git a/mozilla/modules/softupdt/src/nsFolderSpec.cpp b/mozilla/modules/softupdt/src/nsFolderSpec.cpp index f30831b3ed6..2c4ed1c3290 100644 --- a/mozilla/modules/softupdt/src/nsFolderSpec.cpp +++ b/mozilla/modules/softupdt/src/nsFolderSpec.cpp @@ -19,15 +19,17 @@ #include "prmem.h" #include "prmon.h" #include "prlog.h" +#include "prthread.h" #include "fe_proto.h" +#include "xp.h" #include "xp_str.h" +#include "xpgetstr.h" #include "prefapi.h" #include "proto.h" #include "prprf.h" #include "prthread.h" #include "nsFolderSpec.h" #include "nsSUError.h" -#include "xp.h" #include "su_folderspec.h" #ifndef MAX_PATH @@ -69,21 +71,21 @@ PR_BEGIN_EXTERN_C nsFolderSpec::nsFolderSpec(char* inFolderID , char* inVRPath, char* inPackageName) { urlPath = folderID = versionRegistryPath = userPackageName = NULL; - folderID = PR_sprintf_append(folderID, "%s", inFolderID); - versionRegistryPath = PR_sprintf_append(versionRegistryPath, "%s", inVRPath); - userPackageName = PR_sprintf_append(userPackageName, "%s", inPackageName); + folderID = XP_STRDUP(inFolderID); + versionRegistryPath = XP_STRDUP(inVRPath); + userPackageName = XP_STRDUP(inPackageName); } nsFolderSpec::~nsFolderSpec(void) { if (folderID) - PR_Free(folderID); + XP_FREE(folderID); if (versionRegistryPath) - PR_Free(versionRegistryPath); + XP_FREE(versionRegistryPath); if (userPackageName) - PR_Free(userPackageName); + XP_FREE(userPackageName); if (urlPath) - PR_Free(urlPath); + XP_FREE(urlPath); } /* @@ -103,9 +105,10 @@ char* nsFolderSpec::GetDirectoryPath(char* *errorMsg) } else if (XP_STRCMP(folderID, "Installed") == 0) { // Then use the Version Registry path - urlPath = PR_sprintf_append(urlPath, "%s", versionRegistryPath); + urlPath = XP_STRDUP(versionRegistryPath); } else { // Built-in folder + /* NativeGetDirectoryPath updates urlPath */ int err = NativeGetDirectoryPath(); if (err != 0) *errorMsg = SU_GetErrorMsg3(folderID, err); @@ -116,7 +119,10 @@ char* nsFolderSpec::GetDirectoryPath(char* *errorMsg) /** * Returns full path to a file. Makes sure that the full path is bellow - * this directory (security measure + * this directory (security measure) + * + * Caller should free the returned string + * * @param relativePath relative path * @return full path to a file */ @@ -133,10 +139,13 @@ char* nsFolderSpec::MakeFullPath(char* relativePath, char* *errorMsg) if (errorMsg != NULL) { return NULL; } - fullPath = PR_sprintf_append(fullPath, "%s%s", dir_path, GetNativePath(relativePath)); + fullPath = XP_Cat(dir_path, GetNativePath(relativePath)); return fullPath; } +/* The caller is not supposed to free the memory. + * XXX: Should we give a copy of the string?? + */ char* nsFolderSpec::toString() { char *errorMsg = NULL; @@ -155,7 +164,7 @@ char* nsFolderSpec::toString() */ char* nsFolderSpec::PickDefaultDirectory(char* *errorMsg) { - urlPath = NativePickDefaultDirectory(errorMsg); + urlPath = NativePickDefaultDirectory(); if (urlPath == NULL) *errorMsg = SU_GetErrorMsg3(folderID, nsSoftUpdateError_INVALID_PATH_ERR); @@ -207,7 +216,7 @@ int nsFolderSpec::NativeGetDirectoryPath() /* Store it in the object */ if (folderPath != NULL) { urlPath = NULL; - urlPath = PR_sprintf_append(urlPath, "%s", folderPath); + urlPath = XP_STRDUP(folderPath); XP_FREE(folderPath); return 0; } @@ -260,7 +269,7 @@ char* nsFolderSpec::GetNativePath(char* path) * NativePickDefaultDirectory * Platform-specific implementation of GetDirectoryPath */ -char* nsFolderSpec::NativePickDefaultDirectory(char* *errorMsg) +char* nsFolderSpec::NativePickDefaultDirectory(void) { su_PickDirTimer callback; char * packageName; @@ -283,7 +292,7 @@ char* nsFolderSpec::NativePickDefaultDirectory(char* *errorMsg) callback.prompt = prompt; FE_SetTimeout( pickDirectoryCallback, &callback, 1 ); while (!callback.done) /* Busy loop for now */ - PR_Yield(); /* java_lang_Thread_yield(WHAT?); */ + PR_Sleep(PR_INTERVAL_NO_WAIT); /* java_lang_Thread_yield(WHAT?); */ } return callback.fileName; @@ -291,7 +300,6 @@ char* nsFolderSpec::NativePickDefaultDirectory(char* *errorMsg) PRBool nsFolderSpec::NativeIsJavaDir() { - int i; char* folderName; /* Get the name of the package to prompt for */ @@ -300,6 +308,7 @@ PRBool nsFolderSpec::NativeIsJavaDir() #ifdef XXX PR_ASSERT( folderName ); if ( folderName != NULL) { + int i; for (i=0; DirectoryTable[i].directoryName[0] != 0; i++ ) { if ( strcmp(folderName, DirectoryTable[i].directoryName) == 0 ) return DirectoryTable[i].bJavaDir; diff --git a/mozilla/modules/softupdt/src/nsInstallDelete.cpp b/mozilla/modules/softupdt/src/nsInstallDelete.cpp index c3c43d718c1..dff4ef7fd2b 100644 --- a/mozilla/modules/softupdt/src/nsInstallDelete.cpp +++ b/mozilla/modules/softupdt/src/nsInstallDelete.cpp @@ -16,9 +16,311 @@ * Reserved. */ +#include "prmem.h" +#include "prmon.h" +#include "prlog.h" +#include "prprf.h" +#include "xp.h" +#include "softupdt.h" #include "nsInstallDelete.h" +#include "nsVersionRegistry.h" +#include "nsSUError.h" +#include "NSReg.h" + +#include "nsPrivilegeManager.h" +#include "nsTarget.h" + +extern int SU_DETAILS_DELETE_FILE; +extern int SU_DETAILS_DELETE_COMPONENT; +extern int SU_ERROR_NOT_IN_REGISTRY; +extern int SU_ERROR_FILE_READ_ONLY; +extern int SU_ERROR_FILE_IS_DIRECTORY; +extern int SU_ERROR_UNEXPECTED; + PR_BEGIN_EXTERN_C +/* PUBLIC METHODS */ + +/* Constructor + * inFolder - a folder object representing the directory that contains the file + * inRelativeFileName - a relative path and file name + */ +nsInstallDelete::nsInstallDelete(nsSoftwareUpdate* inSoftUpdate, + nsFolderSpec* inFolder, + char* inRelativeFileName, + char* *errorMsg) : nsInstallObject(inSoftUpdate) +{ + registryName = NULL; + finalFile = NULL; + deleteStatus = DELETE_FILE; + FILE_DOES_NOT_EXIST = nsSoftUpdateError_FILE_DOES_NOT_EXIST; + FILE_READ_ONLY = nsSoftUpdateError_FILE_READ_ONLY; + FILE_IS_DIRECTORY = nsSoftUpdateError_FILE_IS_DIRECTORY; + + finalFile = inFolder->MakeFullPath(inRelativeFileName, errorMsg); + if (*errorMsg != NULL) { + return; + } + processInstallDelete(errorMsg); +} + +/* Constructor + * inRegistryName - name of the component in the registry + */ +nsInstallDelete::nsInstallDelete(nsSoftwareUpdate* inSoftUpdate, + char* inRegistryName, + char* *errorMsg) : nsInstallObject(inSoftUpdate) +{ + finalFile = NULL; + deleteStatus = DELETE_COMPONENT; + FILE_DOES_NOT_EXIST = nsSoftUpdateError_FILE_DOES_NOT_EXIST; + FILE_READ_ONLY = nsSoftUpdateError_FILE_READ_ONLY; + FILE_IS_DIRECTORY = nsSoftUpdateError_FILE_IS_DIRECTORY; + registryName = XP_STRDUP(inRegistryName); + processInstallDelete(errorMsg); +} + +nsInstallDelete::~nsInstallDelete() +{ + XP_FREEIF(finalFile); + XP_FREEIF(registryName); +} + +char* nsInstallDelete::Prepare() +{ + // no set-up necessary + return NULL; +} + +/* Complete + * Completes the install by deleting the file + * Security hazard: make sure we request the right permissions + */ +char* nsInstallDelete::Complete() +{ + char* errorMsg = NULL; + int err = -1; + nsTarget* execTarget = NULL; + + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + execTarget = nsTarget::findTarget(INSTALL_PRIV); + if (execTarget != NULL) { + if (!privMgr->enablePrivilege( execTarget, softUpdate->GetPrincipal(), 1 )) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } + } + } + + if (deleteStatus == DELETE_COMPONENT) { + err = nsVersionRegistry::deleteComponent(registryName); + } + char *msg = NULL; + if ((deleteStatus == DELETE_FILE) || (err == REGERR_OK)) { + if (finalFile != NULL) { + err = NativeComplete(); + if ((err != 0) && (err != nsSoftUpdateError_FILE_DOES_NOT_EXIST)) { + if (execTarget != NULL) { + privMgr->revertPrivilege( execTarget, 1 ); + } + msg = SU_GetString1(SU_ERROR_UNEXPECTED, finalFile); + } + } + } else { + msg = SU_GetString1(SU_ERROR_UNEXPECTED, finalFile); + } + if (msg != NULL) { + errorMsg = SU_GetErrorMsg3(msg, err); + PR_FREEIF(msg); + } + return errorMsg; +} + +void nsInstallDelete::Abort() +{ +} + +char* nsInstallDelete::toString() +{ + if (deleteStatus == DELETE_FILE) { + return SU_GetString1(SU_DETAILS_DELETE_FILE, finalFile); + } else { + return SU_GetString1(SU_DETAILS_DELETE_COMPONENT, registryName); + } +} + +/* PRIVATE METHODS */ +void nsInstallDelete::processInstallDelete(char* *errorMsg) +{ + int err; + + nsTarget* target = NULL; + + /* Request impersonation privileges */ + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + target = nsTarget::findTarget(INSTALL_PRIV); + if (target != NULL) { + /* XXX: we need a way to indicate that a dialog box should appear.*/ + if (!privMgr->enablePrivilege( target, softUpdate->GetPrincipal(), 1 )) { + *errorMsg = SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + return; + } + } + } + + if (deleteStatus == DELETE_COMPONENT) { + /* Check if the component is in the registry */ + err = nsVersionRegistry::inRegistry(registryName); + if (err != REGERR_OK) { + char *msg = NULL; + msg = SU_GetString1(SU_ERROR_NOT_IN_REGISTRY, registryName); + *errorMsg = SU_GetErrorMsg3(msg, nsSoftUpdateError_NO_SUCH_COMPONENT); + PR_FREEIF(msg); + return; + } else { + finalFile = nsVersionRegistry::componentPath(registryName); + } + } + + /* Check if the file exists and is not read only */ + if (finalFile != NULL) { + err = NativeCheckFileStatus(); + char *msg = NULL; + if (err == 0) { + /* System.out.println("File exists and is not read only" + finalFile);*/ + } else if (err == nsSoftUpdateError_FILE_DOES_NOT_EXIST) { + /*throw( new SoftUpdateException(Strings.error_FileDoesNotExist() + finalFile, err));*/ + } else if (err == nsSoftUpdateError_FILE_READ_ONLY) { + msg = SU_GetString1(SU_ERROR_FILE_READ_ONLY, finalFile); + } else if (err == nsSoftUpdateError_FILE_IS_DIRECTORY) { + msg = SU_GetString1(SU_ERROR_FILE_IS_DIRECTORY, finalFile); + } else { + msg = SU_GetString1(SU_ERROR_UNEXPECTED, finalFile); + } + if (msg != NULL) { + *errorMsg = SU_GetErrorMsg3(msg, err); + PR_FREEIF(msg); + } + } +} + +int nsInstallDelete::NativeComplete() +{ + char * fileName; + int32 err; + XP_StatStruct statinfo; + + fileName = XP_PlatformFileToURL(finalFile); + if (fileName != NULL) + { + char * temp = XP_STRDUP(&fileName[7]); + XP_FREEIF(fileName); + fileName = temp; + if (fileName) + { + err = XP_Stat(fileName, &statinfo, xpURL); + if (err != -1) + { + if ( XP_STAT_READONLY( statinfo ) ) + { + err = FILE_READ_ONLY; + } + else if (!S_ISDIR(statinfo.st_mode)) + { + err = XP_FileRemove ( fileName, xpURL ); + if (err != 0) + { +#ifdef XP_PC + /* REMIND need to move function to generic XP file */ + err = nsSoftwareUpdate_REBOOT_NEEDED; + su_DeleteOldFileLater( (char*)finalFile ); +#endif + } + + } + else + { + err = FILE_IS_DIRECTORY; + } + } + else + { + err = FILE_DOES_NOT_EXIST; + } + + } + else + { + err = -1; + } + } + + XP_FREEIF(fileName); + return err; +} + +int nsInstallDelete::NativeCheckFileStatus() +{ + char * fileName; + int32 err; + XP_StatStruct statinfo; + + fileName = XP_PlatformFileToURL(finalFile); + if (fileName != NULL) + { + char * temp = XP_STRDUP(&fileName[7]); + XP_FREEIF(fileName); + fileName = temp; + + if (fileName) + { + err = XP_Stat(fileName, &statinfo, xpURL); + if (err != -1) + { + if ( XP_STAT_READONLY( statinfo ) ) + { + err = FILE_READ_ONLY; + } + else if (!S_ISDIR(statinfo.st_mode)) + { + ; + } + else + { + err = FILE_IS_DIRECTORY; + } + } + else + { + err = FILE_DOES_NOT_EXIST; + } + } + else + { + err = -1; + } + + } + else + { + err = -1; + } + XP_FREEIF(fileName); + return err; +} PR_END_EXTERN_C diff --git a/mozilla/modules/softupdt/src/nsInstallExecute.cpp b/mozilla/modules/softupdt/src/nsInstallExecute.cpp index fdb624cbcb5..94a9cdb2456 100644 --- a/mozilla/modules/softupdt/src/nsInstallExecute.cpp +++ b/mozilla/modules/softupdt/src/nsInstallExecute.cpp @@ -16,9 +16,192 @@ * Reserved. */ +#include "prmem.h" +#include "prmon.h" +#include "prlog.h" +#include "prprf.h" +#include "xp.h" +#include "su_instl.h" + #include "nsInstallExecute.h" +#include "nsSUError.h" + +#include "nsPrivilegeManager.h" +#include "nsTarget.h" + +extern int SU_ERROR_UNEXPECTED; +extern int SU_DETAILS_EXECUTE_PROGRESS; +extern int SU_DETAILS_EXECUTE_PROGRESS2; PR_BEGIN_EXTERN_C +/* Public Methods */ + +/* Constructor + * inJarLocation - location inside the JAR file + * inZigPtr - pointer to the ZIG * + */ +nsInstallExecute::nsInstallExecute(nsSoftwareUpdate* inSoftUpdate, + char* inJarLocation, + char* *errorMsg, + char* inArgs) : nsInstallObject(inSoftUpdate) +{ + jarLocation = NULL; + tempFile = NULL; + args = NULL; + cmdline = NULL; + + /* Request impersonation privileges */ + nsTarget* target = NULL; + + /* Request impersonation privileges */ + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + + /* check the security permissions */ + target = nsTarget::findTarget(INSTALL_PRIV); + if (target != NULL) { + /* XXX: we need a way to indicate that a dialog box should appear.*/ + if (!privMgr->enablePrivilege( target, softUpdate->GetPrincipal(), 1 )) { + *errorMsg = SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + return; + } + } + } + jarLocation = XP_STRDUP(inJarLocation); + args = XP_STRDUP(inArgs); +} + + +nsInstallExecute::~nsInstallExecute() +{ + XP_FREEIF(jarLocation); + XP_FREEIF(args); + XP_FREEIF(cmdline); + XP_FREEIF(tempFile); +} + +/* Prepare + * Extracts file out of the JAR archive into the temp directory + */ +char* nsInstallExecute::Prepare(void) +{ + char *errorMsg = NULL; + nsTarget* execTarget = NULL; + + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + execTarget = nsTarget::findTarget(INSTALL_PRIV); + if (execTarget != NULL) { + if (!privMgr->enablePrivilege( execTarget, softUpdate->GetPrincipal(), 1 )) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } + } + } + + tempFile = softUpdate->ExtractJARFile( jarLocation, NULL, &errorMsg ); + if (errorMsg != NULL) + return errorMsg; + +#ifdef XP_MAC + cmdline = XP_STRDUP(tempFile); +#else + if ( args == NULL ) + cmdline = XP_STRDUP(tempFile); + else + cmdline = XP_Cat(tempFile, " ", args); +#endif /* XP_MAC */ + return NULL; +} + +/* Complete + * Completes the install by executing the file + * Security hazard: make sure we request the right permissions + */ +char* nsInstallExecute::Complete(void) +{ + char* errorMsg = NULL; + nsTarget* execTarget = NULL; + + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + execTarget = nsTarget::findTarget(INSTALL_PRIV); + if (execTarget != NULL) { + if (!privMgr->enablePrivilege( execTarget, softUpdate->GetPrincipal(), 1 )) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } + } + } + + errorMsg = NativeComplete(); + if (execTarget != NULL) { + privMgr->revertPrivilege( execTarget, 1 ); + } + // + // System.out.println("File executed: " + tempFile); + return errorMsg; +} + +void nsInstallExecute::Abort(void) +{ + NativeAbort(); +} + +char* nsInstallExecute::toString() +{ + char *ret_val; + char *msg = XP_Cat(jarLocation, tempFile); + if (tempFile == NULL) { + ret_val = SU_GetString1(SU_DETAILS_EXECUTE_PROGRESS, msg); + } else { + ret_val = SU_GetString1(SU_DETAILS_EXECUTE_PROGRESS2, msg); + } + XP_FREEIF(msg); + return ret_val; +} + +/* Private Methods */ +char* nsInstallExecute::NativeComplete(void) +{ + char* errorMsg = NULL; + int32 err; + + err = FE_ExecuteFile( tempFile, cmdline ); + XP_ASSERT( err == 0 ); + if ( err != 0 ) { + errorMsg = SU_GetErrorMsg4(SU_ERROR_UNEXPECTED, err); + } + return errorMsg; +} + +void nsInstallExecute::NativeAbort(void) +{ + char * currentName; + int result; + + /* Get the names */ + currentName = (char*)tempFile; + + result = XP_FileRemove(currentName, xpURL); + XP_ASSERT(result == 0); +} PR_END_EXTERN_C diff --git a/mozilla/modules/softupdt/src/nsInstallFile.cpp b/mozilla/modules/softupdt/src/nsInstallFile.cpp index 0f9fe512e0e..68b76763eb2 100644 --- a/mozilla/modules/softupdt/src/nsInstallFile.cpp +++ b/mozilla/modules/softupdt/src/nsInstallFile.cpp @@ -18,10 +18,15 @@ #include "nsCRT.h" #include "xp.h" +#include "su_folderspec.h" +#include "su_instl.h" + +#include "nsSoftUpdateEnums.h" +#include "NSReg.h" #include "nsInstallFile.h" #include "nsVersionRegistry.h" #include "nsSUError.h" -#include "nsSoftUpdateEnums.h" + #include "nsPrivilegeManager.h" #include "nsTarget.h" @@ -78,15 +83,19 @@ nsInstallFile::nsInstallFile(nsSoftwareUpdate* inSoftUpdate, nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); - /* XXX: We are using security to display the dialog. Thus depth may not matter */ if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ privMgr->enablePrivilege(impersonation, 1); /* check the security permissions */ target = nsTarget::findTarget(INSTALL_PRIV); if (target != NULL) { - /* XXX: we need a way to indicate that a dialog box should appear. */ - privMgr->enablePrivilege(target, softUpdate->GetPrincipal(), 1); + if (!privMgr->enablePrivilege(target, softUpdate->GetPrincipal(), 1)) { + *errorMsg = SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + return; + } } } @@ -143,8 +152,10 @@ char* nsInstallFile::Prepare() nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); - /* XXX: We are using security to display the dialog. Thus depth may not matter */ if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ PRBool allowed = privMgr->enablePrivilege(impersonation, 1); if (allowed == PR_FALSE) { errorMsg = SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); @@ -153,7 +164,6 @@ char* nsInstallFile::Prepare() /* check the security permissions */ if (target != NULL) { - /* XXX: we need a way to indicate that a dialog box should appear. */ PRBool allowed = privMgr->enablePrivilege(target, softUpdate->GetPrincipal(), 1); if (allowed == PR_FALSE) { errorMsg = SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); @@ -195,14 +205,17 @@ char* nsInstallFile::Complete() nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); - /* XXX: We are using security to display the dialog. Thus depth may not matter */ if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ privMgr->enablePrivilege(impersonation, 1); /* check the security permissions */ if (target != NULL) { - /* XXX: we need a way to indicate that a dialog box should appear. */ - privMgr->enablePrivilege(target, softUpdate->GetPrincipal(), 1); + if (!privMgr->enablePrivilege(target, softUpdate->GetPrincipal(), 1)) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } } } diff --git a/mozilla/modules/softupdt/src/nsInstallPatch.cpp b/mozilla/modules/softupdt/src/nsInstallPatch.cpp new file mode 100644 index 00000000000..5591b5b75ce --- /dev/null +++ b/mozilla/modules/softupdt/src/nsInstallPatch.cpp @@ -0,0 +1,395 @@ +/* -*- 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 "prprf.h" +#include "xp.h" +#include "xpgetstr.h" +#include "plhash.h" + +#include "softupdt.h" +#include "su_instl.h" +#include "su_folderspec.h" +#include "gdiff.h" + +#include "nsInstallPatch.h" +#include "nsSoftUpdateEnums.h" +#include "nsVersionRegistry.h" +#include "nsSUError.h" + +#include "nsTarget.h" +#include "nsPrivilegeManager.h" + +extern int SU_ERROR_NO_SUCH_COMPONENT; +extern int SU_ERROR_INSTALL_FILE_UNEXPECTED; +extern int SU_ERROR_UNEXPECTED; +extern int SU_DETAILS_PATCH; + +PR_BEGIN_EXTERN_C + +/* PUBLIC METHODS */ + +/* Constructor + * inSoftUpdate - softUpdate object we belong to + * inVRName - full path of the registry component + * inVInfo - full version info + * inJarLocation - location inside the JAR file + * folderspec - FolderSpec of target file + * inPartialPath - target file on disk relative to folderspec + */ +nsInstallPatch::nsInstallPatch(nsSoftwareUpdate* inSoftUpdate, + char* inVRName, + nsVersionInfo* inVInfo, + char* inJarLocation, + char* *errorMsg) : nsInstallObject(inSoftUpdate) +{ + vrName = NULL; + versionInfo = NULL; + jarLocation = NULL; + patchURL = NULL; + targetfile = NULL; + patchedfile = NULL; + *errorMsg = checkPrivileges(); + if (*errorMsg != NULL) + return; + targetfile = nsVersionRegistry::componentPath( vrName ); + if ( targetfile == NULL ) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_NO_SUCH_COMPONENT, nsSoftUpdateError_NO_SUCH_COMPONENT); + return; + } + vrName = XP_STRDUP(inVRName); + versionInfo = inVInfo; + jarLocation = XP_STRDUP(inJarLocation); +} + + +nsInstallPatch::nsInstallPatch(nsSoftwareUpdate* inSoftUpdate, + char* inVRName, + nsVersionInfo* inVInfo, + char* inJarLocation, + nsFolderSpec* folderSpec, + char* inPartialPath, + char* *errorMsg) : nsInstallObject(inSoftUpdate) +{ + vrName = NULL; + versionInfo = NULL; + jarLocation = NULL; + patchURL = NULL; + targetfile = NULL; + patchedfile = NULL; + *errorMsg = checkPrivileges(); + if (*errorMsg != NULL) + return; + targetfile = folderSpec->MakeFullPath( inPartialPath, errorMsg ); + if ( errorMsg != NULL ) { + return; + } + vrName = XP_STRDUP(inVRName); + versionInfo = inVInfo; + jarLocation = XP_STRDUP(inJarLocation); +} + + +nsInstallPatch::~nsInstallPatch() +{ + XP_FREEIF(vrName); + XP_FREEIF(jarLocation); + XP_FREEIF(patchURL); + XP_FREEIF(patchedfile); + XP_FREEIF(targetfile); + /* Raman: Fix it. How do we delete versionInfo. If we have copy on our side it is easy. */ + // ?? delete versionInfo; +} + +char* nsInstallPatch::Prepare(void) +{ + char* errorMsg = NULL; + char* srcname; + PRBool deleteOldSrc; + + nsTarget* priv = NULL; + + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* We should fix the DEPTH + */ + privMgr->enablePrivilege(impersonation, 1); + priv = nsTarget::findTarget(INSTALL_PRIV); + if (priv != NULL) { + if (!privMgr->enablePrivilege( priv, softUpdate->GetPrincipal(), 1)) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } + } + } + + patchURL = softUpdate->ExtractJARFile( jarLocation, targetfile, &errorMsg ); + + IntegerKey ikey(PL_HashString(targetfile)); + srcname = (char *)softUpdate->patchList->Get( &ikey ); + if (srcname != NULL) { + deleteOldSrc = true; + } else { + srcname = targetfile; + deleteOldSrc = false; + } + + patchedfile = NativePatch( srcname, patchURL, &errorMsg ); + if (errorMsg != NULL) { + return errorMsg; + } + + if ( patchedfile != NULL ) { + softUpdate->patchList->Put( &ikey, patchedfile ); + } else { + char *msg = XP_Cat(targetfile, " not patched"); + errorMsg = SU_GetErrorMsg3(msg, nsSoftUpdateError_UNEXPECTED_ERROR); + } + + if ( deleteOldSrc ) { + NativeDeleteFile( srcname ); + } + return errorMsg; +} + +/* Complete + * Completes the install: + * - move the patched file to the final location + * - updates the registry + */ +char* nsInstallPatch::Complete(void) +{ + int err; + char* errorMsg = NULL; + + if ((errorMsg = checkPrivileges()) != NULL) + return errorMsg; + + IntegerKey ikey(PL_HashString(targetfile)); + char* tmp = (char *)softUpdate->patchList->Get( &ikey ); + if ( XP_STRCMP(tmp, patchedfile ) == 0 ) { + + // the patch has not been superceded--do final replacement + + err = NativeReplace( targetfile, patchedfile ); + + if ( 0 == err || nsSoftwareUpdate_REBOOT_NEEDED == err ) { + err = nsVersionRegistry::installComponent( vrName, targetfile, versionInfo); + + if ( err != 0 ) { + char *msg = XP_Cat("Install component failed ", targetfile); + errorMsg = SU_GetErrorMsg3(msg, err); + XP_FREE(msg); + } + } else { + char *msg = SU_GetString1(SU_ERROR_INSTALL_FILE_UNEXPECTED, targetfile); + errorMsg = SU_GetErrorMsg3(msg, err); + XP_FREE(msg); + } + } else { + // nothing -- old intermediate patched file was + // deleted by a superceding patch + } + return errorMsg; +} + +void nsInstallPatch::Abort(void) +{ + // clean up patched file unless it has been already + // deleted by a superceding patch + + IntegerKey ikey(PL_HashString(targetfile)); + + char* tmp = (char *)softUpdate->patchList->Get( &ikey ); + if ( XP_STRCMP(tmp, patchedfile ) == 0 ) { + NativeDeleteFile( patchedfile ); + } +} + +char* nsInstallPatch::toString(void) +{ + return SU_GetString1(SU_DETAILS_PATCH, targetfile); +} + + +/* PRIVATE METHODS */ + +char* nsInstallPatch::checkPrivileges(void) +{ + // This won't actually give us these privileges because + // we lose them again as soon as the function returns. But we + // don't really need the privs, we're just checking security + + nsTarget* priv = NULL; + + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* We should fix the DEPTH + */ + privMgr->enablePrivilege(impersonation, 1); + priv = nsTarget::findTarget(INSTALL_PRIV); + if (priv != NULL) { + if (!privMgr->enablePrivilege( priv, softUpdate->GetPrincipal(), 1)) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } + } + } + return NULL; +} + +char* nsInstallPatch::NativePatch( char* srcfile, char* diffURL, char* *errorMsg ) +{ + char * fullSrcURL = NULL; + char * srcURL = NULL; + char * newfileURL = NULL; + char * newfile = NULL; + int32 err = GDIFF_OK; + + *errorMsg = NULL; + + /* get all the required filenames in the correct URL format */ + + if ( srcfile != NULL && diffURL != NULL ) { + fullSrcURL = XP_PlatformFileToURL( srcfile ); + if ( fullSrcURL != NULL ) { + char ch; + char *p; + + srcURL = fullSrcURL+7; /* skip "file://" part */ + p = XP_STRRCHR( srcURL, '/' ); + if ( p != NULL ) { + ch = p[1]; + p[1] = 0; + newfileURL = WH_TempName( xpURL, srcURL ); + p[1] = ch; + } + } + } + + + /* apply the patch if conversions worked */ + + if ( newfileURL != NULL ) { + err = SU_PatchFile( srcURL, xpURL, diffURL, xpURL, newfileURL, xpURL ); + } else { + /* String conversions failed -- probably out of memory */ + err = nsSoftUpdateError_UNEXPECTED_ERROR; + } + + + if ( err == GDIFF_OK ) { + /* everything's fine, convert to java string and return */ + newfile = WH_FileName( newfileURL, xpURL ); + } else { + /* convert GDIFF_ERR to SoftwareUpdate error and throw it */ + /* XXX: replace with correct error message! */ + *errorMsg = SU_GetErrorMsg4(SU_ERROR_UNEXPECTED, err); + } + + + /* cleanup */ + + if ( diffURL != NULL ) + XP_FileRemove( diffURL, xpURL ); + + XP_FREEIF( newfileURL ); + XP_FREEIF( fullSrcURL ); + + return (newfile); +} + +int nsInstallPatch::NativeReplace( char* target, char* newfile ) +{ + char * targetURL = NULL; + char * newURL = NULL; + char * pTarget; + char * pNew; + int err = SU_SUCCESS; + + if ( target != NULL && newfile != NULL ) { + targetURL = XP_PlatformFileToURL( target ); + newURL = XP_PlatformFileToURL( newfile ); + + if ( targetURL != NULL && newURL != NULL ) { + XP_StatStruct st; + + pTarget = targetURL+7; + pNew = newURL+7; + + if ( XP_Stat( pTarget, &st, xpURL ) == SU_SUCCESS ) { + /* file still exists */ + err = FE_ReplaceExistingFile( pNew, xpURL, pTarget, xpURL, 0 ); +#ifdef XP_WIN16 + if ( err == nsSoftwareUpdate_REBOOT_NEEDED && !utilityScheduled) { + utilityScheduled = TRUE; + FE_ScheduleRenameUtility(); + } +#endif + } else { + /* someone got rid of the target file? */ + /* can do simple rename, but assert */ + err = XP_FileRename( pNew, xpURL, pTarget, xpURL ); + XP_ASSERT( err == SU_SUCCESS ); + XP_ASSERT(0); + } + } else { + err = -1; + } + } else { + err = -1; + } + + XP_FREEIF( targetURL ); + XP_FREEIF( newURL ); + + return (err); +} + +void nsInstallPatch::NativeDeleteFile( char* filename ) +{ + char * fnameURL = NULL; + char * fname = NULL; + int result; + XP_StatStruct s; + + if ( filename != NULL ) { + fnameURL = XP_PlatformFileToURL( filename ); + XP_ASSERT( fnameURL ); + + if ( fnameURL != NULL ) { + fname = fnameURL+7; + + if ( XP_Stat( fname, &s, xpURL ) == 0 ) { + /* file is still here */ + result = XP_FileRemove( fname, xpURL ); + if ( result != SU_SUCCESS ) { + /* XXX: schedule for later */ + } + } + } + } + XP_FREEIF( fnameURL ); +} + +PR_END_EXTERN_C diff --git a/mozilla/modules/softupdt/src/nsSoftwareUpdate.cpp b/mozilla/modules/softupdt/src/nsSoftwareUpdate.cpp index 952cb85771a..f7caa332ede 100644 --- a/mozilla/modules/softupdt/src/nsSoftwareUpdate.cpp +++ b/mozilla/modules/softupdt/src/nsSoftwareUpdate.cpp @@ -23,6 +23,7 @@ #include "xp.h" #include "xp_str.h" #include "prprf.h" +#include "softupdt.h" #include "nsString.h" #include "nsSoftwareUpdate.h" #include "nsSoftUpdateEnums.h" @@ -30,20 +31,70 @@ #include "nsInstallFile.h" #include "nsInstallDelete.h" #include "nsInstallExecute.h" +#include "nsInstallPatch.h" #include "nsVersionRegistry.h" #include "nsSUError.h" #include "nsWinReg.h" #include "nsPrivilegeManager.h" #include "nsTarget.h" #include "nsPrincipal.h" +#include "zig.h" +#include "prefapi.h" +#include "proto.h" +#include "jsapi.h" +#include "xp_error.h" +#include "jsjava.h" +#include "xpgetstr.h" +#include "pw_public.h" + +#ifdef XP_MAC +#include "su_aplsn.h" +#endif + +#ifdef XP_MAC +#pragma export on +#endif + +extern int MK_OUT_OF_MEMORY; extern int SU_ERROR_BAD_PACKAGE_NAME; extern int SU_ERROR_WIN_PROFILE_MUST_CALL_START; extern int SU_ERROR_BAD_PACKAGE_NAME_AS; extern int SU_ERROR_EXTRACT_FAILED; +extern int SU_ERROR_NO_CERTIFICATE; +extern int SU_ERROR_TOO_MANY_CERTIFICATES; +extern int SU_ERROR_BAD_JS_ARGUMENT; +extern int SU_ERROR_SMART_UPDATE_DISABLED; +extern int SU_ERROR_UNEXPECTED; +extern int SU_ERROR_VERIFICATION_FAILED; +extern int SU_ERROR_MISSING_INSTALLER; +extern int SU_ERROR_OUT_OF_MEMORY; +extern int SU_ERROR_EXTRACT_FAILED; + +/***************************************** + * SoftwareUpdate progress dialog methods + *****************************************/ +#define TITLESIZE 256 +extern int SU_INSTALLWIN_TITLE; +extern int SU_INSTALLWIN_UNPACKING; +extern int SU_INSTALLWIN_INSTALLING; PR_BEGIN_EXTERN_C +static PRBool su_PathEndsWithSeparator(char* path, char* sep); + +#ifdef XP_PC +extern char * WH_TempFileName(int type, const char * prefix, const char * extension); +#endif + +extern void FolderSpecInitialize(JRIEnv * env); +extern void InstallFileInitialize(JRIEnv * env); +extern void SU_Reg_Initialize(JRIEnv *env ); +extern void SUWinSpecificInit( JRIEnv *env ); + +extern uint32 FE_DiskSpaceAvailable (MWContext *context, const char *lpszPath ); + + /* Public Methods */ /** @@ -52,22 +103,24 @@ PR_BEGIN_EXTERN_C */ nsSoftwareUpdate::nsSoftwareUpdate(void* env, char* inUserPackageName) { - userPackageName = PR_sprintf_append(userPackageName, "%s", inUserPackageName); + userPackageName = XP_STRDUP(inUserPackageName); installPrincipal = NULL; packageName = NULL; packageFolder = NULL; installedFiles = NULL; confdlg = NULL; - progwin = 0; + progwin = NULL; patchList = new nsHashtable(); zigPtr = NULL; userChoice = -1; lastError = 0; silent = PR_FALSE; force = PR_FALSE; + jarName = NULL; + char *errorMsg; /* Need to verify that this is a SoftUpdate JavaScript object */ - VerifyJSObject(env); + errorMsg = VerifyJSObject(env); /* XXX: FIX IT. How do we get data from env jarName = (String) env.getMember("src"); @@ -256,6 +309,9 @@ void* nsSoftwareUpdate::GetWinRegistry(char* *errorMsg) * two security checks: * - the certificate of the extracted file must match the installer certificate * - must have privileges to extract the jar file + * + * Caller should free the returned string + * * @param inJarLocation file name inside the JAR file */ char* nsSoftwareUpdate::ExtractJARFile(char* inJarLocation, char* finalFile, char* *errorMsg) @@ -284,7 +340,8 @@ char* nsSoftwareUpdate::ExtractJARFile(char* inJarLocation, char* finalFile, cha 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); + char *msg = NULL; + msg = PR_sprintf_append(msg, "Missing certificate for %s", inJarLocation); *errorMsg = SU_GetErrorMsg3(msg, nsSoftUpdateError_NO_CERTIFICATE); PR_FREEIF(msg); return NULL; @@ -305,13 +362,7 @@ char* nsSoftwareUpdate::ExtractJARFile(char* inJarLocation, char* finalFile, cha 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; + freeCertificates(prinArray); if (*errorMsg != NULL) return NULL; @@ -347,6 +398,7 @@ PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, nsVersionInfo* inVIn PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, nsVersionInfo* inVInfo, char* *errorMsg) { int errcode= nsSoftwareUpdate_SUCCESS; + *errorMsg = NULL; ResetError(); @@ -355,7 +407,7 @@ PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, nsVersionInfo* inVIn return nsSoftUpdateError_INVALID_ARGUMENTS; } - packageName = PR_sprintf_append(packageName, "%s", vrPackageName); + packageName = XP_STRDUP(vrPackageName); int len = XP_STRLEN(vrPackageName); int last_pos = len-1; @@ -375,14 +427,20 @@ PRInt32 nsSoftwareUpdate::StartInstall(char* vrPackageName, nsVersionInfo* inVIn /* 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; + errcode = OpenJARFile(errorMsg); + if (*errorMsg != NULL) + return errcode; + errcode = InitializeInstallerCertificate(errorMsg); + if (*errorMsg != NULL) + return errcode; + CheckSilentPrivileges(); + if (*errorMsg != NULL) + return errcode; + errcode = RequestSecurityPrivileges(errorMsg); + if (*errorMsg != NULL) + return errcode; + + OpenProgressDialog(); // set up default package folder, if any char* path = nsVersionRegistry::getDefaultDirectory( packageName ); @@ -443,14 +501,15 @@ PRInt32 nsSoftwareUpdate::FinalizeInstall(char* *errorMsg) } // Wait for user approval -#ifdef XXX /* FIX IT */ if ( !silent && UserWantsConfirm() ) { +#ifdef XXX /* FIX IT */ confdlg = new nsProgressDetails(this); /* XXX What is this? while ( userChoice == -1 ) Thread.sleep(10); */ +#endif /* XXX */ confdlg = NULL; if (userChoice != 1) { @@ -460,7 +519,6 @@ PRInt32 nsSoftwareUpdate::FinalizeInstall(char* *errorMsg) } SetProgressDialogRange( installedFiles->GetSize() ); -#endif /* XXX */ // Register default package folder if set @@ -718,7 +776,6 @@ PRInt32 nsSoftwareUpdate::Patch(char* regName, nsVersionInfo* version, char* pat char* rname = GetQualifiedRegName( regName ); -#ifdef XXX /* FIX IT */ nsInstallPatch* ip = new nsInstallPatch(this, rname, version, patchname, errorMsg); if (*errorMsg != NULL) { errcode = nsSoftUpdateError_ACCESS_DENIED; @@ -728,7 +785,6 @@ PRInt32 nsSoftwareUpdate::Patch(char* regName, nsVersionInfo* version, char* pat errcode = nsSoftUpdateError_UNEXPECTED_ERROR; } } -#endif /* XXX */ saveError( errcode ); return errcode; } @@ -745,7 +801,6 @@ PRInt32 nsSoftwareUpdate::Patch(char* regName, nsVersionInfo* version, char* pat char* rname = GetQualifiedRegName( regName ); -#ifdef XXX /* FIX IT */ nsInstallPatch* ip = new nsInstallPatch( this, rname, version, patchname, folder, filename, errorMsg ); if (*errorMsg != NULL) { @@ -756,7 +811,6 @@ PRInt32 nsSoftwareUpdate::Patch(char* regName, nsVersionInfo* version, char* pat errcode = nsSoftUpdateError_UNEXPECTED_ERROR; } } -#endif /* XXX */ saveError( errcode ); return errcode; } @@ -816,24 +870,35 @@ PRInt32 nsSoftwareUpdate::DeleteComponent(char* registryName, char* *errorMsg) return errcode; } +static PRBool su_PathEndsWithSeparator(char* path, char* sep) +{ + PRBool ends_with_filesep = PR_FALSE; + if (path != NULL) { + PRInt32 filesep_len = XP_STRLEN(sep); + PRInt32 path_len = XP_STRLEN(path); + if (path_len >= filesep_len) { + ends_with_filesep = (XP_STRSTR(&path[path_len - filesep_len], sep) ? PR_TRUE : PR_FALSE); + } + } + return ends_with_filesep; +} + + 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); + nsFolderSpec *spec; + if (su_PathEndsWithSeparator(path, filesep)) { + spec = new nsFolderSpec("Installed", path, userPackageName); } else { - newPath = PR_sprintf_append(newPath, "%s%s", path, filesep); - return new nsFolderSpec("Installed", newPath, userPackageName); + path = XP_AppendStr(path, filesep); + spec = new nsFolderSpec("Installed", path, userPackageName); } + XP_FREE(path); + return spec; } else { return NULL; } @@ -844,8 +909,26 @@ nsFolderSpec* nsSoftwareUpdate::GetFolder(char* targetFolder, char* subdirectory nsFolderSpec* nsSoftwareUpdate::GetFolder(nsFolderSpec* folder, char* subdir, char* *errorMsg) { - /* XXX: FIX IT */ - return NULL; + nsFolderSpec* spec = NULL; + char* path = NULL; + char* newPath = NULL; + + if ( subdir == NULL || (XP_STRLEN(subdir) == 0 )) { + // no subdir, return what we were passed + spec = folder; + } else if ( folder != NULL ) { + path = folder->MakeFullPath( subdir, errorMsg ); + if (path != NULL) { + if (su_PathEndsWithSeparator(path, filesep)) { + spec = new nsFolderSpec("Installed", path, userPackageName); + } else { + path = XP_AppendStr(path, filesep); + spec = new nsFolderSpec("Installed", path, userPackageName); + } + XP_FREE(path); + } + } + return spec; } /** @@ -854,8 +937,12 @@ nsFolderSpec* nsSoftwareUpdate::GetFolder(nsFolderSpec* folder, char* subdir, ch */ long nsSoftwareUpdate::DiskSpaceAvailable(nsFolderSpec* folder) { - /* XXX: Fix it */ - return 0; + char *errorMsg = NULL; + char* path = folder->GetDirectoryPath(&errorMsg); + if ((path == NULL) || (errorMsg == NULL)) + return 0; + + return NativeDiskSpaceAvailable(path); } /** @@ -868,21 +955,121 @@ long nsSoftwareUpdate::DiskSpaceAvailable(nsFolderSpec* folder) * arguments. */ PRInt32 nsSoftwareUpdate::AddDirectory(char* name, - nsVersionInfo* version, - char* jarSource, - nsFolderSpec* folderSpec, - char* subdir, - PRBool forceInstall) + nsVersionInfo* version, + char* jarSource, + nsFolderSpec* folderSpec, + char* subdir, + PRBool forceInstall, + char* *errorMsg) { - /* XXX: Fix it */ - return 0; + nsInstallFile* ie; + int result = nsSoftwareUpdate_SUCCESS; + char *qualified_name = NULL; + *errorMsg = NULL; + + if ( jarSource == NULL || XP_STRLEN(jarSource) == 0 || folderSpec == NULL ) { + *errorMsg = SU_GetErrorMsg3("folder or Jarsource is NULL ", nsSoftUpdateError_INVALID_ARGUMENTS ); + return saveError(nsSoftUpdateError_INVALID_ARGUMENTS); + } + + if (packageName == NULL) { + // probably didn't call StartInstall() + *errorMsg = SU_GetErrorMsg4(SU_ERROR_BAD_PACKAGE_NAME_AS, nsSoftUpdateError_BAD_PACKAGE_NAME ); + return saveError(nsSoftUpdateError_BAD_PACKAGE_NAME); + } + + if ((name == NULL) || (XP_STRLEN(name) == 0)) { + // Default subName = location in jar file + qualified_name = GetQualifiedRegName( jarSource ); + } else { + qualified_name = GetQualifiedRegName( name ); + } + + if ( subdir == NULL ) { + subdir = NULL; + } else if ( XP_STRLEN(subdir) != 0 ) { + subdir = XP_Cat(subdir, "/"); + } + + + /* XXX: May be we should print the following to JS console + System.out.println("AddDirectory " + qualified_name + + " from " + jarSource + " into " + + folderSpec.MakeFullPath(subdir)); + */ + + + int length; + char** matchingFiles = ExtractDirEntries( jarSource, &length ); + int i; + PRBool bInstall; + nsVersionInfo* oldVer; + + for (i=0; i < length; i++) { + char* fullRegName = XP_Cat(qualified_name, "/", matchingFiles[i]); + + if ( (forceInstall == PR_FALSE) && (version != NULL) && + (nsVersionRegistry::validateComponent(fullRegName) == 0) ) { + // Only install if newer + oldVer = nsVersionRegistry::componentVersion(fullRegName); + bInstall = ( version->compareTo(oldVer) > 0 ); + } else { + // file doesn't exist or "forced" install + bInstall = PR_TRUE; + } + + if ( bInstall ) { + char *newJarSource = XP_Cat(jarSource, "/", matchingFiles[i]); + char *newSubDir; + if (subdir) { + newSubDir = XP_Cat(subdir, matchingFiles[i]); + } else { + newSubDir = XP_STRDUP(matchingFiles[i]); + } + ie = new nsInstallFile( this, + fullRegName, + version, + newJarSource, + (nsFolderSpec*) folderSpec, + newSubDir, + forceInstall, + errorMsg); + if (*errorMsg == NULL) { + ScheduleForInstall( ie ); + } + XP_FREEIF(newJarSource); + XP_FREEIF(newSubDir); + } + XP_FREEIF(fullRegName); + } + XP_FREEIF(subdir); + XP_FREEIF(qualified_name); + /* XXX: I think we should free nsInstallFile object */ + if (errorMsg != NULL) { + result = nsSoftUpdateError_UNEXPECTED_ERROR; + } + + saveError( result ); + return (result); } /* Uninstall */ -PRInt32 nsSoftwareUpdate::Uninstall(char* packageName) +PRInt32 nsSoftwareUpdate::Uninstall(char* packageName, char* *errorMsg) { - /* XXX: Fix it */ - return 0; + int errcode = nsSoftwareUpdate_SUCCESS; + +#ifdef XXX + /* XXX: Fix it, after having Uninstall object */ + nsUninstallObject* u = new nsUninstallObject( this, packageName, errorMsg ); + if (*errorMsg != NULL) { + errcode = nsSoftUpdateError_UNEXPECTED_ERROR; + } else { + ScheduleForInstall( u ); + } +#endif + + saveError( errcode ); + return errcode; } /******************************* @@ -895,24 +1082,40 @@ PRInt32 nsSoftwareUpdate::Uninstall(char* packageName) * 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::OpenProgressDialog(void) { + if ( !silent ) { + progwin = NativeOpenProgDlg( GetUserPackageName() ); + } } -void nsSoftwareUpdate::CloseProgressDialog() +void nsSoftwareUpdate::CloseProgressDialog(void) { + if ( progwin != NULL ) { + NativeCloseProgDlg( progwin ); + progwin = NULL; + } } void nsSoftwareUpdate::SetProgressDialogItem(char* message) { + if ( progwin != NULL ) { + NativeSetProgDlgItem( progwin, message ); + } } void nsSoftwareUpdate::SetProgressDialogRange(PRInt32 max) { + if ( progwin != NULL ) { + NativeSetProgDlgRange( progwin, max ); + } } void nsSoftwareUpdate::SetProgressDialogThermo(PRInt32 value) { + if ( progwin != NULL ) { + NativeSetProgDlgThermo( progwin, value ); + } } /* Private Methods */ @@ -920,10 +1123,39 @@ void nsSoftwareUpdate::SetProgressDialogThermo(PRInt32 value) /* * Reads in the installer certificate, and creates its principal */ -char* nsSoftwareUpdate::InitializeInstallerCertificate() +PRInt32 nsSoftwareUpdate::InitializeInstallerCertificate(char* *errorMsg) { - /* XXX: Fix it */ - return NULL; + PRInt32 errcode; + nsPrincipal *prin = NULL; + nsPrincipalArray* prinArray = (nsPrincipalArray*)getCertificates(zigPtr, installerJarName); + if ((prinArray == NULL) || (prinArray->GetSize() == 0)) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_NO_CERTIFICATE, + nsSoftUpdateError_NO_INSTALLER_CERTIFICATE); + errcode = nsSoftUpdateError_NO_INSTALLER_CERTIFICATE; + } else if (prinArray->GetSize() > 1) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_TOO_MANY_CERTIFICATES, + nsSoftUpdateError_TOO_MANY_CERTIFICATES); + errcode = nsSoftUpdateError_TOO_MANY_CERTIFICATES; + } else { + prin = (nsPrincipal *)prinArray->Get(0); + if (prin == NULL) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_NO_CERTIFICATE, + nsSoftUpdateError_NO_INSTALLER_CERTIFICATE); + errcode = nsSoftUpdateError_NO_INSTALLER_CERTIFICATE; + } + } + + if (prin != NULL) { + /* XXX: We should have Dup method on nsPrincipal object */ + nsPrincipalType prinType = prin->getType(); + void* key = prin->getKey(); + PRUint32 key_len = prin->getKeyLength(); + installPrincipal = new nsPrincipal(prinType, key, key_len); + } + + /* Free the allocated principals */ + freeCertificates(prinArray); + return saveError(errcode); } /* @@ -931,15 +1163,62 @@ char* nsSoftwareUpdate::InitializeInstallerCertificate() */ PRBool nsSoftwareUpdate::CheckSilentPrivileges() { - /* XXX: Fix it */ - return PR_FALSE; + PRBool ret_val = PR_FALSE; + + if (silent == PR_FALSE) { + return ret_val; + } + + /* Request impersonation privileges */ + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + + nsTarget* target = nsTarget::findTarget(SILENT_PRIV); + /* check the security permissions */ + if (target != NULL) { + ret_val = privMgr->enablePrivilege(target, GetPrincipal(), 1); + } + } + if (!ret_val) { + silent = PR_FALSE; + } + return ret_val; } /* Request the security privileges, so that the security dialogs * pop up */ -void nsSoftwareUpdate::RequestSecurityPrivileges() +PRInt32 nsSoftwareUpdate::RequestSecurityPrivileges(char* *errorMsg) { + PRBool ret_val = PR_FALSE; + /* Request impersonation privileges */ + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + + nsTarget* target = nsTarget::findTarget(INSTALL_PRIV); + /* check the security permissions */ + if (target != NULL) { + ret_val = privMgr->enablePrivilege(target, GetPrincipal(), 1); + } + } + + if (!ret_val) { + *errorMsg = "Permssion was denied"; + return nsSoftUpdateError_ACCESS_DENIED; + } else { + *errorMsg = NULL; + } + return nsSoftwareUpdate_SUCCESS; } /** @@ -947,8 +1226,9 @@ void nsSoftwareUpdate::RequestSecurityPrivileges() */ PRInt32 nsSoftwareUpdate::saveError(PRInt32 errcode) { - /* XXX: Fix it */ - return 0; + if ( errcode != nsSoftwareUpdate_SUCCESS ) + lastError = errcode; + return errcode; } /* @@ -960,6 +1240,9 @@ PRInt32 nsSoftwareUpdate::saveError(PRInt32 errcode) void nsSoftwareUpdate::CleanUp() { nsInstallObject* ie; + CloseJARFile(); + confdlg = NULL; + zigPtr = NULL; if ( installedFiles != NULL ) { PRUint32 i=0; for (; i < installedFiles->GetSize(); i++) { @@ -968,18 +1251,52 @@ void nsSoftwareUpdate::CleanUp() } installedFiles->RemoveAll(); } + installedFiles = NULL; + packageName = NULL; // used to see if StartInstall() has been called + + CloseProgressDialog(); } /** * GetQualifiedRegName * + * Allocates a new string and returns it. Caller is supposed to free it + * * 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; + + char *comm = "=COMM=/"; + PRUint32 comm_len = XP_STRLEN(comm); + PRBool starts_with_comm = PR_FALSE; + if ((XP_STRLEN(name)) >= comm_len) { + PRUint32 i; + for (i=0; ifURL->address, */ + jarData); + if ( err != 0 ) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_VERIFICATION_FAILED, err); + return err; + } + + /* Get the installer file name */ + installerJarName = NULL; + err = SOB_get_metainfo(jarData, NULL, INSTALLER_HEADER, + (void**)&installerJarName, &installerJarNameLength); + if (err != 0) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_MISSING_INSTALLER, err); + return err; + } + zigPtr = jarData; + return nsSoftwareUpdate_SUCCESS; } void nsSoftwareUpdate::CloseJARFile() { + ZIG* jarData = (ZIG*)zigPtr; + if (jarData != NULL) + SOB_destroy( jarData); + zigPtr = NULL; } /* getCertificates @@ -1015,64 +1395,295 @@ void* nsSoftwareUpdate::getCertificates(void* zigPtr, char* pathname) return nsPrincipal::getSigners(zigPtr, pathname); } +void nsSoftwareUpdate::freeCertificates(void* prins) +{ + nsPrincipalArray* prinArray = (nsPrincipalArray*)prins; + if ((prinArray == NULL) || (prinArray->GetSize() == 0)) + return; + + PRUint32 noOfPrins = prinArray->GetSize(); + /* Free all the objects */ + PRUint32 i; + for (i=0; i < noOfPrins; i++) { + nsPrincipal* prin = (nsPrincipal*)prinArray->Get(i); + delete prin; + prinArray->Set(i, NULL); + } + delete prinArray; +} + +#define APPLESINGLE_MAGIC_HACK 1 /* Hack to automatically detect applesingle files until we get tdell to do the right thing */ + + +/* Caller should free the returned string */ char* nsSoftwareUpdate::NativeExtractJARFile(char* inJarLocation, char* finalFile, char* *errorMsg) { - /* XXX: Fix it */ - return NULL; + char * tempName = NULL; + char * target = NULL; + char * ret_value = NULL; + int result; + ZIG * jar; + char * jarPath; + + /* Extract the file */ + jar = (ZIG *)zigPtr; + jarPath = (char*)inJarLocation; + if (jarPath == NULL) { + /* out-of-memory error already signaled */ + *errorMsg = SU_GetErrorMsg4(SU_ERROR_OUT_OF_MEMORY, nsSoftUpdateError_UNEXPECTED_ERROR); + return NULL; + } + + target = (char*)finalFile; + + if (target) { + char *fn; + char *end; + char *URLfile = XP_PlatformFileToURL(target); + + fn = URLfile+7; /* skip "file://" part */ + + if ((end = XP_STRRCHR(fn, '/')) != NULL ) + end[1] = 0; + + /* Create a temporary location */ + tempName = WH_TempName( xpURL, fn ); + XP_FREEIF(URLfile); + } else { +#ifdef XP_PC + char * extension = XP_STRRCHR(jarPath, '.'); + if (extension) + tempName = WH_TempFileName( xpURL, NULL, extension ); + else + tempName = WH_TempName( xpURL, NULL ); +#else + tempName = WH_TempName( xpURL, NULL ); +#endif + } + if (tempName == NULL) { + result = MK_OUT_OF_MEMORY; + goto done; + } + + + result = SOB_verified_extract( jar, jarPath, tempName); + + if ( result == 0 ) { + /* If we have an applesingle file + * decode it to a new file + */ + char * encodingName; + unsigned long encodingNameLength; + XP_Bool isApplesingle = FALSE; + result = SOB_get_metainfo( jar, NULL, CONTENT_ENCODING_HEADER, (void**)&encodingName, &encodingNameLength); + +#ifdef APPLESINGLE_MAGIC_HACK + if (result != 0) { + XP_File f; + uint32 magic; + f = XP_FileOpen(tempName, xpURL, XP_FILE_READ_BIN); + XP_FileRead( &magic, sizeof(magic), f); + XP_FileClose(f); + isApplesingle = (magic == 0x00051600 ); + result = 0; + } +#else + isApplesingle = (( result == 0 ) && + (XP_STRNCMP(APPLESINGLE_MIME_TYPE, encodingName, XP_STRLEN( APPLESINGLE_MIME_TYPE ) == 0))); +#endif + if ( isApplesingle ) { + /* We have an AppleSingle file */ + /* Extract it to the new AppleFile, and get the URL back */ + char * newTempName = NULL; +#ifdef XP_MAC + result = SU_DecodeAppleSingle(tempName, &newTempName); + if ( result == 0 ) { + XP_FileRemove( tempName, xpURL ); + XP_FREE(tempName); + tempName = newTempName; + } else { + XP_FileRemove( tempName, xpURL ); + } +#else + result = 0; +#endif + } + } + +done: + /* Create the return Java string if everything went OK */ + if (tempName && ( result == 0) ) { + ret_value = tempName; + } + + if ( (result != 0) || (ret_value == NULL) ) { + *errorMsg = SU_GetErrorMsg4(SU_ERROR_EXTRACT_FAILED, result); + return NULL; + } + + return ret_value; } -PRInt32 nsSoftwareUpdate::NativeMakeDirectory(char* path) +PRInt32 nsSoftwareUpdate::NativeMakeDirectory(char* dir) { - /* XXX: Fix it */ - return 0; + if ( !dir ) + return -1; + + return XP_MakeDirectoryR ( dir, xpURL ); } -long nsSoftwareUpdate::NativeDiskSpaceAvailable(char* path) +long nsSoftwareUpdate::NativeDiskSpaceAvailable(char* fileSystem) { - /* XXX: Fix it */ - return 0; + PRInt32 val = 0; + + if (fileSystem) { + val = FE_DiskSpaceAvailable(NULL, fileSystem); + } + return val; } -char* nsSoftwareUpdate::NativeFileURLToNative(char* dir, char* path) +/* Caller should free the returned string */ +char* nsSoftwareUpdate::NativeFileURLToNative(char* dir, char* pathNamePlatform) { - /* XXX: Fix it */ - return NULL; + char * newName = NULL; + + if (pathNamePlatform != NULL) { + newName = WH_FileName(pathNamePlatform, xpURL); + } + return newName; } -char** nsSoftwareUpdate::ExtractDirEntries(char* Dir) +char** nsSoftwareUpdate::ExtractDirEntries(char *Directory, int *length) { - /* XXX: Fix it */ - return NULL; + int size = 0; + int len = 0; + int dirlen; + char *pattern = NULL; + ZIG_Context *context; + SOBITEM *item; + char* *StrArray = NULL; + char *buff; + + if (!zigPtr) + goto bail; + + if (!Directory) + goto bail; + + dirlen = XP_STRLEN(Directory); + if ( (pattern = (char *)XP_ALLOC(dirlen + 3)) == NULL) + goto bail; + + XP_STRCPY(pattern, Directory); + XP_STRCPY(pattern+dirlen, "/*"); + + + /* it's either go through the JAR twice (first time just to get a count) + * or go through once and potentially use lots of memory saving all the + * strings. In deference to Win16 and potentially large installs we're + * going to loop through the JAR twice and take the performance hit; + * no one installs very often anyway. + */ + + if ((context = SOB_find ((ZIG*)zigPtr, pattern, ZIG_MF)) == NULL) + goto bail; + + while (SOB_find_next (context, &item) >= 0) + size++; + + SOB_find_end (context); + + StrArray = (char **)XP_CALLOC(size, sizeof(char *)); + if (StrArray == NULL) + goto bail; + + if ((context = SOB_find ((ZIG*)zigPtr, pattern, ZIG_MF)) == NULL) + goto bail; + + *length = size; + size = 0; + while (SOB_find_next (context, &item) >= 0) { + len = XP_STRLEN(item->pathname); + /* subtract length of target directory + slash */ + len = len - (dirlen+1); + if (( buff = (char*)XP_ALLOC (len+1)) != NULL ) { + /* Don't copy the search directory part */ + XP_STRCPY (buff, (item->pathname)+dirlen+1); + StrArray[size++] = buff; + } + } + SOB_find_end (context); + XP_FREEIF(pattern); + return StrArray; + +bail: + XP_FREEIF(pattern); + if (StrArray != NULL) { + size = *length; + for (int i=0; icompareTo( oldVer ) <= diffLevel); + else + needJar = (version->compareTo( oldVer ) >= diffLevel); + } + } + + if (needJar) + return StartSoftwareUpdate( url, flags ); + else + return PR_FALSE; +} + +PRBool +nsTrigger::ConditionalSoftwareUpdate(char* url, + char* componentName, + char* version) +{ + return ConditionalSoftwareUpdate( url, componentName, + BLD_DIFF, + new nsVersionInfo(version), + DEFAULT_MODE ); +} + +/** + * Validates existence and compares versions + * + * @param regName name of component in the registry to compare + * the version against. This doesn't have to be the + * registry name of an installed package but could + * instead be a sub-component. If the named item + * has a Path property the file must exist or a + * null version is used in the comparison. + * @param version The version to compare against + */ +PRInt32 nsTrigger::CompareVersion( char* regName, nsVersionInfo* version ) +{ + if (!UpdateEnabled()) + return EQUAL; + + nsVersionInfo* regVersion = GetVersionInfo( regName ); + + if ( regVersion == NULL || + nsVersionRegistry::validateComponent( regName ) == REGERR_NOFILE ) { + + regVersion = new nsVersionInfo(0,0,0,0,0); + } + + return regVersion->compareTo( version ); +} + +PRInt32 nsTrigger::CompareVersion( char* regName, char* version ) +{ + return CompareVersion( regName, new nsVersionInfo( version ) ); +} + +PRInt32 +nsTrigger::CompareVersion( char* regName, PRInt32 maj, + PRInt32 min, PRInt32 rel, + PRInt32 bld ) +{ + return CompareVersion( regName, new nsVersionInfo(maj, min, rel, bld, 0) ); +} PR_END_EXTERN_C diff --git a/mozilla/modules/softupdt/src/nsUninstallObject.cpp b/mozilla/modules/softupdt/src/nsUninstallObject.cpp new file mode 100644 index 00000000000..d935ba2e6d7 --- /dev/null +++ b/mozilla/modules/softupdt/src/nsUninstallObject.cpp @@ -0,0 +1,149 @@ +/* -*- 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 "nsUninstallObject.h" +#include "prmem.h" +#include "prmon.h" +#include "prlog.h" +#include "prprf.h" +#include "xp.h" +#include "NSReg.h" +#include "softupdt.h" +#include "nsVersionRegistry.h" +#include "nsPrivilegeManager.h" +#include "nsTarget.h" +#include "nsSUError.h" + +extern int SU_DETAILS_UNINSTALL; + +PR_BEGIN_EXTERN_C + +/* PUBLIC METHODS */ + +nsUninstallObject::nsUninstallObject(nsSoftwareUpdate* inSoftUpdate, + char* inRegName, + char* *errorMsg) : nsInstallObject(inSoftUpdate) +{ + regName = NULL; + userName = NULL; + if ( regName == NULL || XP_STRLEN(regName) == 0 ) { + *errorMsg = SU_GetErrorMsg3("RegName is NULL ", nsSoftUpdateError_INVALID_ARGUMENTS ); + return; + } + regName = XP_STRDUP(inRegName); + + /* Request impersonation privileges */ + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + nsTarget* target = NULL; + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + target = nsTarget::findTarget(INSTALL_PRIV); + if (target != NULL) { + if (!privMgr->enablePrivilege( target, softUpdate->GetPrincipal(), 1 )) { + *errorMsg = SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + return; + } + } + } + + userName = nsVersionRegistry::getUninstallUserName( regName ); + if ( userName == NULL ) { + char *msg = NULL; + msg = PR_sprintf_append(msg, "No such component %s", regName); + *errorMsg = SU_GetErrorMsg3(msg, nsSoftUpdateError_NO_SUCH_COMPONENT); + PR_FREEIF(msg); + return; + } +} + + +nsUninstallObject::~nsUninstallObject() +{ + XP_FREEIF(regName); + XP_FREEIF(userName); +} + + +/* Complete + * Uninstalls the package + */ +char* nsUninstallObject::Complete() +{ + nsTarget* execTarget = NULL; + + nsPrivilegeManager* privMgr = nsPrivilegeManager::getPrivilegeManager(); + nsTarget* impersonation = nsTarget::findTarget(IMPERSONATOR); + + if ((privMgr != NULL) && (impersonation != NULL)) { + /* XXX: We should get the SystemPrincipal and enablePrivilege on that. + * Or may be we should get rid of impersonation + */ + privMgr->enablePrivilege(impersonation, 1); + execTarget = nsTarget::findTarget(INSTALL_PRIV); + if (execTarget != NULL) { + if (!privMgr->enablePrivilege( execTarget, softUpdate->GetPrincipal(), 1 )) { + return SU_GetErrorMsg3("Permssion was denied", nsSoftUpdateError_ACCESS_DENIED); + } + } + } + + char *errorMsg = NativeComplete( regName ); + + if (execTarget != NULL) { + privMgr->revertPrivilege( execTarget, 1 ); + } + return errorMsg; +} + + +char* nsUninstallObject::Prepare() +{ + return NULL; +} + +void nsUninstallObject::Abort() +{ +} + +char* nsUninstallObject::toString() +{ + return SU_GetString1(SU_DETAILS_UNINSTALL, userName); // Needs I10n +} + + +/* PRIVATE METHODS */ + +char* nsUninstallObject::NativeComplete(char* regname) +{ + char* errorMsg = NULL; + if ( regname != NULL && *regname != '\0' ) { + int err = SU_Uninstall( regName ); + if (err != REGERR_OK) { + errorMsg = SU_GetErrorMsg3("Uninstall failed", err); + } + } + return errorMsg; +} + + +PR_END_EXTERN_C diff --git a/mozilla/modules/softupdt/src/nsVersionInfo.cpp b/mozilla/modules/softupdt/src/nsVersionInfo.cpp index 9ade1599a0c..d30d28352ac 100644 --- a/mozilla/modules/softupdt/src/nsVersionInfo.cpp +++ b/mozilla/modules/softupdt/src/nsVersionInfo.cpp @@ -117,22 +117,22 @@ nsVersionEnum nsVersionInfo::compareTo(nsVersionInfo* vi) else if ( build > vi->build ) diff = nsVersionEnum_BLD_DIFF; else - diff = -nsVersionEnum_BLD_DIFF; + diff = nsVersionEnum_BLD_DIFF_MINUS; } else if ( release > vi->release ) diff = nsVersionEnum_REL_DIFF; else - diff = -nsVersionEnum_REL_DIFF; + diff = nsVersionEnum_REL_DIFF_MINUS; } else if ( minor > vi->minor ) diff = nsVersionEnum_MINOR_DIFF; else - diff = -nsVersionEnum_MINOR_DIFF; + diff = nsVersionEnum_MINOR_DIFF_MINUS; } else if ( major > vi->major ) diff = nsVersionEnum_MAJOR_DIFF; else - diff = -nsVersionEnum_MAJOR_DIFF; + diff = nsVersionEnum_MAJOR_DIFF_MINUS; return diff; } diff --git a/mozilla/modules/softupdt/src/nsVersionRegistry.cpp b/mozilla/modules/softupdt/src/nsVersionRegistry.cpp index c9f23b35a56..c72d01206e8 100644 --- a/mozilla/modules/softupdt/src/nsVersionRegistry.cpp +++ b/mozilla/modules/softupdt/src/nsVersionRegistry.cpp @@ -17,8 +17,397 @@ */ #include "nsVersionRegistry.h" +#include "xp_mcom.h" +#include "NSReg.h" +#include "VerReg.h" +#include "prefapi.h" PR_BEGIN_EXTERN_C +/* PUBLIC METHODS */ + +/** + * Return the physical disk path for the specified component. + * @param component Registry path of the item to look up in the Registry + * @return The disk path for the specified component; NULL indicates error + * @see VersionRegistry#checkComponent + */ +char* nsVersionRegistry::componentPath( char* component ) +{ + char pathbuf[MAXREGPATHLEN]; + REGERR status; + char* ret_val = NULL; + + /* If conversion is successful */ + if ( component != NULL ) { + /* get component path from the registry */ + status = VR_GetPath( component, MAXREGPATHLEN, pathbuf ); + + /* if we get a path */ + if ( status == REGERR_OK ) { + ret_val = XP_STRDUP(pathbuf); + } + } + return ret_val; +} + +/** + * Return the version information for the specified component. + * @param component Registry path of the item to look up in the Registry + * @return A VersionInfo object for the specified component; NULL indicates error + * @see VersionRegistry#checkComponent + */ +nsVersionInfo* nsVersionRegistry::componentVersion( char* component ) +{ + REGERR status; + VERSION cVersion; + nsVersionInfo* verInfo = NULL; + + /* if conversion is successful */ + if ( component != NULL ) { + /* get component version from the registry */ + status = VR_GetVersion( component, &cVersion ); + + /* if we got the version */ + if ( status == REGERR_OK ) { + verInfo = new nsVersionInfo(cVersion.major, + cVersion.minor, + cVersion.release, + cVersion.build, + cVersion.check); + } + } + return verInfo; +} + +char* nsVersionRegistry::getDefaultDirectory( char* component ) +{ + char pathbuf[MAXREGPATHLEN]; + REGERR status; + char* ret_val = NULL; + + /* If conversion is successful */ + if ( component != NULL ) { + /* get component path from the registry */ + status = VR_GetDefaultDirectory( component, MAXREGPATHLEN, pathbuf ); + + /* if we get a path */ + if ( status == REGERR_OK ) { + ret_val = XP_STRDUP(pathbuf); + } + } + return ret_val; +} + +PRInt32 nsVersionRegistry::setDefaultDirectory( char* component, char* directory ) +{ + REGERR status = REGERR_FAIL; + + /* If conversion is successful */ + if ( component != NULL && directory != NULL ) { + /* get component path from the registry */ + status = VR_SetDefaultDirectory( component, directory ); + } + + return (status); +} + +PRInt32 nsVersionRegistry::installComponent( char* component, char* path, nsVersionInfo* version ) +{ + char * szVersion = NULL; + REGERR status = REGERR_FAIL; + + if (version != NULL) { + szVersion = version->toString(); + } + + if ( component != NULL ) { + /* call registry with converted data */ + /* XXX need to allow Directory installs also, change in Java */ + status = VR_Install( component, path, szVersion, 0 ); + } + + PR_FREEIF(szVersion); + return (status); +} + +PRInt32 nsVersionRegistry::installComponent( char* name, char* path, nsVersionInfo* version, PRInt32 refCount ) +{ + int err = installComponent( name, path, version ); + + if ( err == REGERR_OK ) + err = setRefCount( name, refCount ); + return err; +} + +/** + * Delete component and all sub-components. + * @param component Registry path of the item to delete + * @return Error code + */ +PRInt32 nsVersionRegistry::deleteComponent( char* component ) +{ + REGERR status = REGERR_FAIL; + + /* If conversion is successful */ + if ( component != NULL ) { + /* delete entry from registry */ + status = VR_Remove( component ); + } + /* return status */ + return (status); +} + +/** + * Check the status of a named components. + * @param component Registry path of the item to check + * @return Error code. REGERR_OK means the named component was found in + * the registry, the filepath referred to an existing file, and the + * checksum matched the physical file. Other error codes can be used to + * distinguish which of the above was not true. + */ +PRInt32 nsVersionRegistry::validateComponent( char* component ) +{ + if ( component == NULL ) { + return REGERR_FAIL; + } + + return ( VR_ValidateComponent( component ) ); +} + +/** + * verify that the named component is in the registry (light-weight + * version of validateComponent since it does no disk access). + * @param component Registry path of the item to verify + * @return Error code. REGERR_OK means it is in the registry. + * REGERR_NOFIND will usually be the result otherwise. + */ +PRInt32 nsVersionRegistry::inRegistry( char* component ) +{ + if ( component == NULL ) { + return REGERR_FAIL; + } + + return ( VR_InRegistry( component ) ); +} + +/** + * Closes the registry file. + * @return Error code + */ +PRInt32 nsVersionRegistry::close() +{ + return ( VR_Close() ); +} + +/** + * Returns an enumeration of the Version Registry contents. Use the + * enumeration methods of the returned object to fetch individual + * elements sequentially. + */ +void* nsVersionRegistry::elements() +{ + /* XXX: This method is not called anywhere. Who uses it? */ + PR_ASSERT(PR_FALSE); + return NULL; +} + +/** + * Set the refcount of a named component. + * @param component Registry path of the item to check + * @param refcount value to be set + * @return Error code + */ +PRInt32 nsVersionRegistry::setRefCount( char* component, PRInt32 refcount ) +{ + if ( component == NULL ) { + return REGERR_FAIL; + } + + return VR_SetRefCount( component, refcount ); +} + +/** + * Return the refcount of a named component. + * @param component Registry path of the item to check + * @return the value of refCount + */ +PRInt32 nsVersionRegistry::getRefCount( char* component ) +{ + REGERR status; + int cRefCount = 0; + + if ( component != NULL ) { + + status = VR_GetRefCount( component, &cRefCount ); + if ( status != REGERR_OK ) { + cRefCount = 0; + } + } + + return cRefCount; +} + +/** + * Creates a node for the item in the Uninstall list. + * @param regPackageName Registry name of the package we are installing + * @return userPackagename User-readable package name + * @return Error code + */ +PRInt32 nsVersionRegistry::uninstallCreate( char* regPackageName, char* userPackageName ) +{ + char* temp = convertPackageName(regPackageName); + regPackageName = temp; + PRInt32 ret_val = uninstallCreateNode(regPackageName, userPackageName); + XP_FREEIF(temp); + return ret_val; +} + +PRInt32 nsVersionRegistry::uninstallCreateNode( char* regPackageName, char* userPackageName ) +{ + if ( regPackageName == NULL ) { + return REGERR_FAIL; + } + + if ( userPackageName == NULL ) { + return REGERR_FAIL; + } + + return VR_UninstallCreateNode( regPackageName, userPackageName ); +} + +/** + * Adds the file as a property of the Shared Files node under the appropriate + * packageName node in the Uninstall list. + * @param regPackageName Registry name of the package installed + * @param vrName registry name of the shared file + * @return Error code + */ +PRInt32 nsVersionRegistry::uninstallAddFile( char* regPackageName, char* vrName ) +{ + char* temp = convertPackageName(regPackageName); + regPackageName = temp; + PRInt32 ret_val = uninstallAddFileToList(regPackageName, vrName); + XP_FREEIF(temp); + return ret_val; +} + +PRInt32 nsVersionRegistry::uninstallAddFileToList( char* regPackageName, char* vrName ) +{ + if ( regPackageName == NULL ) { + return REGERR_FAIL; + } + + if ( vrName == NULL ) { + return REGERR_FAIL; + } + + return VR_UninstallAddFileToList( regPackageName, vrName ); +} + +/** + * Checks if the shared file exists in the uninstall list of the package + * @param regPackageName Registry name of the package installed + * @param vrName registry name of the shared file + * @return true or false + */ +PRInt32 nsVersionRegistry::uninstallFileExists( char* regPackageName, char* vrName ) +{ + char* temp = convertPackageName(regPackageName); + regPackageName = temp; + PRInt32 ret_val = uninstallFileExistsInList(regPackageName, vrName); + XP_FREEIF(temp); + return ret_val; +} + +PRInt32 nsVersionRegistry::uninstallFileExistsInList( char* regPackageName, char* vrName ) +{ + if ( regPackageName == NULL ) { + return REGERR_FAIL; + } + + if ( vrName == NULL ) { + return REGERR_FAIL; + } + + return VR_UninstallFileExistsInList( regPackageName, vrName ); +} + +char* nsVersionRegistry::getUninstallUserName( char* regName ) +{ + REGERR status = REGERR_FAIL; + char buf[MAXREGNAMELEN]; + char* ret_val = NULL; + + if ( regName != NULL ) { + /* XXX: uncomment the following code, when we merge Nav 4.5 into 5.0 */ + //status = VR_GetUninstallUserName( regName, buf, sizeof(buf) ); + PR_ASSERT(PR_FALSE); + + if ( status == REGERR_OK ) + ret_val = XP_STRDUP(buf); + } + + return ret_val; +} + + +/* PRIVATE METHODS */ + +/** + * This class is simply static function wrappers; don't "new" one + */ +nsVersionRegistry::nsVersionRegistry() +{ +} + +/** + * Replaces all '/' with '_',in the given char*.If an '_' already exists in the + * given char*, it is escaped by adding another '_' to it. + * @param regPackageName Registry name of the package we are installing + * @return modified char* + */ +char* nsVersionRegistry::convertPackageName( char* regPackageName ) +{ + char* convertedPackageName; + PRBool bSharedUninstall = false; + PRUint32 i=0; + PRUint32 j= 0; + PRUint32 len = XP_STRLEN(regPackageName); + PRUint32 new_size; + + if (regPackageName[0] == '/') + bSharedUninstall = PR_TRUE; + + /* Count the number of '_' and then allocate that many extra characters */ + for (i=0; i < len; i++) { + if (regPackageName[i] == '_') + j++; + } + + new_size = len+j+1; + convertedPackageName = (char*)XP_CALLOC(new_size, sizeof(char)); + i = j = 0; + for (i=0; i < len; i++) { + PR_ASSERT(j < new_size); + char c = regPackageName[i]; + if (c == '/') + convertedPackageName[j] = '_'; + else + convertedPackageName[j] = c; + j++; + if (regPackageName[i] == '_') { + PR_ASSERT(j < new_size); + convertedPackageName[j++] = '_'; + } + } + PR_ASSERT(j == new_size); + + if (bSharedUninstall) { + convertedPackageName[0] = '/'; + } + return convertedPackageName; +} + PR_END_EXTERN_C