From a3dfb7c083290bc4f01ac91dc7751b6e15882671 Mon Sep 17 00:00:00 2001 From: "benjamin@smedbergs.us" Date: Fri, 20 Apr 2007 08:22:17 -0700 Subject: [PATCH] Bug 375710 - Firefox 2.0.0.3 wants to downgrade to 2.0.0.2, patch by Masatoshi Kimura (:emk), reworked by me a bit, r=rstrong --- browser/installer/unix/packages-static | 1 + browser/installer/windows/packages-static | 1 + toolkit/components/nsDefaultCLH.js | 47 +++++++++++++- toolkit/mozapps/update/src/nsPostUpdateWin.js | 20 ++---- .../mozapps/update/src/nsUpdateService.js.in | 29 +++------ toolkit/xre/nsAppRunner.cpp | 65 +++---------------- toolkit/xre/nsAppRunner.h | 10 +++ toolkit/xre/nsXREDirProvider.cpp | 60 +++++++++++++++-- toolkit/xre/nsXREDirProvider.h | 9 ++- 9 files changed, 142 insertions(+), 100 deletions(-) diff --git a/browser/installer/unix/packages-static b/browser/installer/unix/packages-static index 4d17e6289f1..9d5f8c99eb1 100644 --- a/browser/installer/unix/packages-static +++ b/browser/installer/unix/packages-static @@ -216,6 +216,7 @@ bin/components/libbrowserdirprovider.so bin/components/libbrowsercomps.so bin/components/txEXSLTRegExFunctions.js bin/components/nsLivemarkService.js +bin/components/nsDefaultCLH.js ; Safe Browsing bin/components/nsSafebrowsingApplication.js diff --git a/browser/installer/windows/packages-static b/browser/installer/windows/packages-static index a6f9e94b37a..668395a9099 100644 --- a/browser/installer/windows/packages-static +++ b/browser/installer/windows/packages-static @@ -224,6 +224,7 @@ bin\components\browserdirprovider.dll bin\components\brwsrcmp.dll bin\components\txEXSLTRegExFunctions.js bin\components\nsLivemarkService.js +bin\components\nsDefaultCLH.js ; Safe Browsing bin\components\nsSafebrowsingApplication.js diff --git a/toolkit/components/nsDefaultCLH.js b/toolkit/components/nsDefaultCLH.js index 2ebd4b7ad54..d5770dc23da 100644 --- a/toolkit/components/nsDefaultCLH.js +++ b/toolkit/components/nsDefaultCLH.js @@ -47,6 +47,9 @@ const nsIModule = Components.interfaces.nsIModule; const nsIPrefBranch = Components.interfaces.nsIPrefBranch; const nsISupportsString = Components.interfaces.nsISupportsString; const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher; +const nsIProperties = Components.interfaces.nsIProperties; +const nsIFile = Components.interfaces.nsIFile; +const nsISimpleEnumerator = Components.interfaces.nsISimpleEnumerator; /** * This file provides a generic default command-line handler. @@ -59,6 +62,12 @@ const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher; * It doesn't do anything if the pref "toolkit.defaultChromeURI" is unset. */ +function getDirectoryService() +{ + return Components.classes["@mozilla.org/file/directory_service;1"] + .getService(nsIProperties); +} + var nsDefaultCLH = { /* nsISupports */ @@ -74,8 +83,40 @@ var nsDefaultCLH = { /* nsICommandLineHandler */ handle : function clh_handle(cmdLine) { + var printDir; + while (printDir = cmdLine.handleFlagWithParam("print-xpcom-dir", false)) { + var out = "print-xpcom-dir(\"" + printDir + "\"): "; + try { + out += getDirectoryService().get(printDir, nsIFile).path; + } + catch (e) { + out += ""; + } + + dump(out + "\n"); + Components.utils.reportError(out); + } + + var printDirList; + while (printDirList = cmdLine.handleFlagWithParam("print-xpcom-dirlist", + false)) { + out = "print-xpcom-dirlist(\"" + printDirList + "\"): "; + try { + var list = getDirectoryService().get(printDirList, + nsISimpleEnumerator); + while (list.hasMoreElements()) + out += list.getNext().QueryInterface(nsIFile).path + ";"; + } + catch (e) { + out += ""; + } + + dump(out + "\n"); + Components.utils.reportError(out); + } + if (cmdLine.preventDefault) - return; + return; var prefs = Components.classes["@mozilla.org/preferences-service;1"] .getService(nsIPrefBranch); @@ -90,8 +131,8 @@ var nsDefaultCLH = { var win = windowMediator.getMostRecentWindow(singletonWindowType); if (win) { win.focus(); - cmdLine.preventDefault = true; - return; + cmdLine.preventDefault = true; + return; } } catch (e) { } diff --git a/toolkit/mozapps/update/src/nsPostUpdateWin.js b/toolkit/mozapps/update/src/nsPostUpdateWin.js index 3355e613497..4dff8012222 100644 --- a/toolkit/mozapps/update/src/nsPostUpdateWin.js +++ b/toolkit/mozapps/update/src/nsPostUpdateWin.js @@ -46,8 +46,7 @@ const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties"; const KEY_APPDIR = "XCurProcD"; const KEY_TMPDIR = "TmpD"; -const KEY_LOCALDATA = "DefProfLRt"; -const KEY_PROGRAMFILES = "ProgF"; +const KEY_UPDROOT = "UpdRootD"; const KEY_UAPPDATA = "UAppData"; // see prio.h @@ -187,17 +186,12 @@ InstallLogWriter.prototype = { // See the local appdata first if app dir is under Program Files. var file = null; - var updRoot = getFile(KEY_APPDIR); - var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"] - .getService(Components.interfaces.nsIProperties); - var programFilesDir = fileLocator.get(KEY_PROGRAMFILES, - Components.interfaces.nsILocalFile); - if (programFilesDir.contains(updRoot, true)) { - var relativePath = updRoot.QueryInterface(Components.interfaces.nsILocalFile). - getRelativeDescriptor(programFilesDir); - var userLocalDir = fileLocator.get(KEY_LOCALDATA, - Components.interfaces.nsILocalFile).parent; - updRoot.setRelativeDescriptor(userLocalDir, relativePath); + var updRoot; + try { + updRoot = getFile(KEY_UPDROOT); + } catch (e) { + } + if (updRoot) { file = appendUpdateLogPath(updRoot); // When updating from Fx 2.0.0.1 to 2.0.0.3 (or later) on Vista, diff --git a/toolkit/mozapps/update/src/nsUpdateService.js.in b/toolkit/mozapps/update/src/nsUpdateService.js.in index c0dd5d93c5b..532425d3053 100644 --- a/toolkit/mozapps/update/src/nsUpdateService.js.in +++ b/toolkit/mozapps/update/src/nsUpdateService.js.in @@ -66,8 +66,7 @@ const URI_UPDATE_NS = "http://www.mozilla.org/2005/app-update"; const KEY_APPDIR = "XCurProcD"; #ifdef XP_WIN -const KEY_LOCALDATA = "DefProfLRt"; -const KEY_PROGRAMFILES = "ProgF"; +const KEY_UPDROOT = "UpdRootD"; const KEY_UAPPDATA = "UAppData"; #endif @@ -237,16 +236,12 @@ function getUpdateDir(pathArray) { function getDirInternal(key, pathArray, shouldCreate, update) { var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties); - var dir = fileLocator.get(key, Components.interfaces.nsILocalFile); + var dir = fileLocator.get(key, Components.interfaces.nsIFile); #ifdef XP_WIN if (update) { - var programFilesDir = fileLocator.get(KEY_PROGRAMFILES, - Components.interfaces.nsILocalFile); - if (programFilesDir.contains(dir, true)) { - var relativePath = dir.getRelativeDescriptor(programFilesDir); - var userLocalDir = fileLocator.get(KEY_LOCALDATA, - Components.interfaces.nsILocalFile).parent; - dir.setRelativeDescriptor(userLocalDir, relativePath); + try { + dir = fileLocator.get(KEY_UPDROOT, Components.interfaces.nsIFile); + } catch (e) { } } #endif @@ -352,17 +347,13 @@ function getUpdatesDir(key) { getService(Components.interfaces.nsIProperties); var appDir; if (key) - appDir = fileLocator.get(key, Components.interfaces.nsILocalFile); + appDir = fileLocator.get(key, Components.interfaces.nsIFile); else { - appDir = fileLocator.get(KEY_APPDIR, Components.interfaces.nsILocalFile); + appDir = fileLocator.get(KEY_APPDIR, Components.interfaces.nsIFile); #ifdef XP_WIN - var programFilesDir = fileLocator.get(KEY_PROGRAMFILES, - Components.interfaces.nsILocalFile); - if (programFilesDir.contains(appDir, true)) { - var relativePath = appDir.getRelativeDescriptor(programFilesDir); - var userLocalDir = fileLocator.get(KEY_LOCALDATA, - Components.interfaces.nsILocalFile).parent; - appDir.setRelativeDescriptor(userLocalDir, relativePath); + try { + appDir = fileLocator.get(KEY_UPDROOT, Components.interfaces.nsIFile); + } catch (e) { } #endif } diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 572d0bdc96c..584e4ae287f 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1418,27 +1418,6 @@ XRE_GetBinaryPath(const char* argv0, nsILocalFile* *aResult) return NS_OK; } -// copied from nsXREDirProvider.cpp -#ifdef XP_WIN -static nsresult -GetShellFolderPath(int folder, char result[MAXPATHLEN]) -{ - LPITEMIDLIST pItemIDList = NULL; - - nsresult rv; - if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)) && - SUCCEEDED(SHGetPathFromIDList(pItemIDList, result))) { - rv = NS_OK; - } else { - rv = NS_ERROR_NOT_AVAILABLE; - } - - CoTaskMemFree(pItemIDList); - - return rv; -} -#endif - #define NS_ERROR_LAUNCHED_CHILD_PROCESS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200) #ifdef XP_WIN @@ -2583,45 +2562,17 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) #if defined(MOZ_UPDATER) // Check for and process any available updates - nsCOMPtr updRoot = dirProvider.GetAppDir(); - nsCOMPtr updRootl(do_QueryInterface(updRoot)); - -#ifdef XP_WIN - // Use \updates\ if app dir is under Program Files to avoid the - // folder virtualization mess on Windows Vista - char path[MAXPATHLEN]; - rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, path); - NS_ENSURE_SUCCESS(rv, 1); - nsCOMPtr programFilesDir; - rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_FALSE, - getter_AddRefs(programFilesDir)); - NS_ENSURE_SUCCESS(rv, 1); - - PRBool descendant; - rv = programFilesDir->Contains(updRootl, PR_TRUE, &descendant); - NS_ENSURE_SUCCESS(rv, 1); - if (descendant) { - nsCAutoString relativePath; - rv = updRootl->GetRelativeDescriptor(programFilesDir, relativePath); - NS_ENSURE_SUCCESS(rv, 1); - - nsCOMPtr userLocalDir; - rv = dirProvider.GetUserLocalDataDirectory(getter_AddRefs(userLocalDir)); - NS_ENSURE_SUCCESS(rv, 1); - - rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, - getter_AddRefs(updRootl)); - NS_ENSURE_SUCCESS(rv, 1); - - rv = updRootl->SetRelativeDescriptor(userLocalDir, relativePath); - NS_ENSURE_SUCCESS(rv, 1); - } -#endif + nsCOMPtr updRoot; + PRBool persistent; + rv = dirProvider.GetFile(XRE_UPDATE_ROOT_DIR, &persistent, + getter_AddRefs(updRoot)); + // XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed + if (NS_FAILED(rv)) + updRoot = dirProvider.GetAppDir(); ProcessUpdates(dirProvider.GetGREDir(), dirProvider.GetAppDir(), - updRootl, + updRoot, gRestartArgc, gRestartArgv); #endif diff --git a/toolkit/xre/nsAppRunner.h b/toolkit/xre/nsAppRunner.h index 75436fd6e73..71f4fc09ee0 100644 --- a/toolkit/xre/nsAppRunner.h +++ b/toolkit/xre/nsAppRunner.h @@ -60,6 +60,16 @@ // and we load localstore from somewhere else. #define NS_LOCALSTORE_UNSAFE_FILE "LStoreS" +/** + * A directory service key which provides the update directory. + * At present this is supported only on Windows. + * Windows: Documents and Settings\\Local Settings\Application Data\ + * \\ + * If appDir is not under the Program Files, directory service will fail. + * Callers should fallback to appDir. + */ +#define XRE_UPDATE_ROOT_DIR "UpdRootD" + class nsACString; struct nsStaticModuleInfo; diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 5317cdc4076..5822c223a70 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -127,13 +127,6 @@ nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir) { NS_ASSERTION(aDir && aLocalDir, "We don't support no-profile apps yet!"); -#ifdef DEBUG_bsmedberg - nsCAutoString path, path2; - aDir->GetNativePath(path); - aLocalDir->GetNativePath(path2); - printf("nsXREDirProvider::SetProfile('%s', '%s')\n", path.get(), path2.get()); -#endif - nsresult rv; rv = EnsureDirectoryExists(aDir); @@ -242,6 +235,11 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent, !strcmp(aProperty, XRE_USER_APP_DATA_DIR)) { rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file)); } +#ifdef XP_WIN + else if (!strcmp(aProperty, XRE_UPDATE_ROOT_DIR)) { + rv = GetUpdateRootDir(getter_AddRefs(file)); + } +#endif else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_FILE)) { rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file)); if (NS_SUCCEEDED(rv)) @@ -785,6 +783,54 @@ GetShellFolderPath(int folder, char result[MAXPATHLEN]) return rv; } + +nsresult +nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) +{ + nsCOMPtr appDir = GetAppDir(); + nsCAutoString appPath; + nsresult rv = appDir->GetNativePath(appPath); + NS_ENSURE_SUCCESS(rv, rv); + + // AppDir may be a short path. Convert to long path to make sure + // the consistency of the update folder location + nsCString longPath; + char *buf; + longPath.GetMutableData(&buf, MAXPATHLEN); + DWORD len = GetLongPathName(appPath.get(), buf, MAXPATHLEN); + // Failing GetLongPathName() is not fatal. + if (len <= 0 || len >= MAXPATHLEN) + longPath.Assign(appPath); + else + longPath.SetLength(len); + + // Use \updates\ if app dir is under Program Files to avoid the + // folder virtualization mess on Windows Vista + char programFiles[MAXPATHLEN]; + rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, programFiles); + NS_ENSURE_SUCCESS(rv, rv); + + PRUint32 programFilesLen = strlen(programFiles); + programFiles[programFilesLen++] = '\\'; + programFiles[programFilesLen] = '\0'; + + if (longPath.Length() < programFilesLen) + return NS_ERROR_FAILURE; + + if (_strnicmp(programFiles, longPath.get(), programFilesLen) != 0) + return NS_ERROR_FAILURE; + + nsCOMPtr updRoot; + rv = GetUserLocalDataDirectory(getter_AddRefs(updRoot)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = updRoot->AppendRelativeNativePath(Substring(longPath, programFilesLen)); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ADDREF(*aResult = updRoot); + return NS_OK; +} #endif nsresult diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h index ba07501c407..47949eb3b72 100644 --- a/toolkit/xre/nsXREDirProvider.h +++ b/toolkit/xre/nsXREDirProvider.h @@ -89,12 +89,19 @@ public: return mGREDir; } + /** + * Get the directory under which update directory is created. + * This method may be called before XPCOM is started. aResult + * is a clone, it may be modified. + */ + nsresult GetUpdateRootDir(nsIFile* *aResult); + /** * Get the profile startup directory as determined by this class or by * mAppProvider. This method may be called before XPCOM is started. aResult * is a clone, it may be modified. */ - nsresult GetProfileStartupDir(nsIFile* *aResult); + nsresult GetProfileStartupDir(nsIFile* *aResult); /** * Get the profile directory as determined by this class or by an