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
authorbenjamin@smedbergs.us
Fri, 20 Apr 2007 08:22:17 -0700
changeset 676 b92b640de096fbc3fa26ef3956906d46ef329189
parent 675 fec535cdc48344a173a1f942892ad7e9b422a6f7
child 677 00c8a925b0b8c54fec2e662bb2825df51a3db455
push idunknown
push userunknown
push dateunknown
reviewersrstrong
bugs375710
milestone1.9a4pre
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
browser/installer/windows/packages-static
toolkit/components/nsDefaultCLH.js
toolkit/mozapps/update/src/nsPostUpdateWin.js
toolkit/mozapps/update/src/nsUpdateService.js.in
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsAppRunner.h
toolkit/xre/nsXREDirProvider.cpp
toolkit/xre/nsXREDirProvider.h
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -211,16 +211,17 @@ bin/components/nsSessionStartup.js
 bin/components/nsSessionStore.js
 bin/components/sessionstore.xpt
 bin/components/nsURLFormatter.js
 bin/components/urlformatter.xpt
 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
 bin/components/safebrowsing.xpt
 bin/components/nsUrlClassifierListManager.js
 bin/components/nsUrlClassifierLib.js
 bin/components/nsUrlClassifierTable.js
 bin/components/url-classifier.xpt
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -219,16 +219,17 @@ bin\components\nsSessionStartup.js
 bin\components\nsSessionStore.js
 bin\components\sessionstore.xpt
 bin\components\nsURLFormatter.js
 bin\components\urlformatter.xpt
 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
 bin\components\safebrowsing.xpt
 bin\components\nsUrlClassifierListManager.js
 bin\components\nsUrlClassifierLib.js
 bin\components\nsUrlClassifierTable.js
 bin\components\url-classifier.xpt
--- a/toolkit/components/nsDefaultCLH.js
+++ b/toolkit/components/nsDefaultCLH.js
@@ -42,61 +42,102 @@ const nsICategoryManager       = Compone
 const nsIComponentRegistrar    = Components.interfaces.nsIComponentRegistrar;
 const nsICommandLine           = Components.interfaces.nsICommandLine;
 const nsICommandLineHandler    = Components.interfaces.nsICommandLineHandler;
 const nsIFactory               = Components.interfaces.nsIFactory;
 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.
  *
  * It opens the chrome window specified by the pref "toolkit.defaultChromeURI"
  * with the flags specified by the pref "toolkit.defaultChromeFeatures"
  * or "chrome,dialog=no,all" is it is not available.
  * The arguments passed to the window are the nsICommandLine instance.
  *
  * 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 */
 
   QueryInterface : function clh_QI(iid) {
     if (iid.equals(nsICommandLineHandler) ||
         iid.equals(nsIFactory) ||
         iid.equals(nsISupports))
       return this;
 
     throw Components.results.NS_ERROR_NO_INTERFACE;
   },
 
   /* 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 += "<Not Provided>";
+      }
+
+      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 += "<Not Provided>";
+      }
+
+      dump(out + "\n");
+      Components.utils.reportError(out);
+    }
+
     if (cmdLine.preventDefault)
-    return;
+      return;
 
     var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(nsIPrefBranch);
 
     try {
       var singletonWindowType =
                               prefs.getCharPref("toolkit.singletonWindowType");
       var windowMediator =
                 Components.classes["@mozilla.org/appshell/window-mediator;1"]
                           .getService(Components.interfaces.nsIWindowMediator);
 
       var win = windowMediator.getMostRecentWindow(singletonWindowType);
       if (win) {
         win.focus();
-    	  cmdLine.preventDefault = true;
-	      return;
+    	cmdLine.preventDefault = true;
+	  return;
       }
     }
     catch (e) { }
 
     // if the pref is missing, ignore the exception 
     try {
       var chromeURI = prefs.getCharPref("toolkit.defaultChromeURI");
 
--- a/toolkit/mozapps/update/src/nsPostUpdateWin.js
+++ b/toolkit/mozapps/update/src/nsPostUpdateWin.js
@@ -41,18 +41,17 @@
  * logs required to complete an update of the application.  This code is very
  * specific to the xpinstall wizard for windows.
  */
 
 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
 const PR_RDONLY      = 0x01;
 const PR_WRONLY      = 0x02;
 const PR_APPEND      = 0x10;
 
 const PERMS_FILE     = 0644;
@@ -182,27 +181,22 @@ InstallLogWriter.prototype = {
       if (file.exists())
         return file;
 
       return null;
     }
 
     // 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,
       // we will have to see also user app data (see bug 351949).
       if (!file)
         file = appendUpdateLogPath(getFile(KEY_UAPPDATA));
     }
 
--- a/toolkit/mozapps/update/src/nsUpdateService.js.in
+++ b/toolkit/mozapps/update/src/nsUpdateService.js.in
@@ -61,18 +61,17 @@ const PREF_PARTNER_BRANCH               
 const URI_UPDATE_PROMPT_DIALOG  = "chrome://mozapps/content/update/updates.xul";
 const URI_UPDATE_HISTORY_DIALOG = "chrome://mozapps/content/update/history.xul";
 const URI_BRAND_PROPERTIES      = "chrome://branding/locale/brand.properties";
 const URI_UPDATES_PROPERTIES    = "chrome://mozapps/locale/update/updates.properties";
 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
 
 const DIR_UPDATES         = "updates";
 const FILE_UPDATE_STATUS  = "update.status";
 const FILE_UPDATE_ARCHIVE = "update.mar";
 const FILE_UPDATE_LOG     = "update.log"
 const FILE_UPDATES_DB     = "updates.xml";
@@ -232,26 +231,22 @@ function getUpdateDir(pathArray) {
  * @param   update
  *          true if finding the update directory,
  *          false otherwise.
  * @return  nsIFile object for the location specified. 
  */
 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
   for (var i = 0; i < pathArray.length; ++i) {
     dir.append(pathArray[i]);
     if (shouldCreate && !dir.exists())
       dir.create(nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
   }
@@ -347,27 +342,23 @@ function getStatusTextFromCode(code, def
 function getUpdatesDir(key) {
   // Right now, we only support downloading one patch at a time, so we always
   // use the same target directory.
   var fileLocator =
       Components.classes["@mozilla.org/file/directory_service;1"].
       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
   }
   appDir.append(DIR_UPDATES);
   appDir.append("0");
   if (!appDir.exists() && !key)
     appDir.create(nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
   return appDir;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1413,37 +1413,16 @@ XRE_GetBinaryPath(const char* argv0, nsI
 #elif
 #error Oops, you need platform-specific code here
 #endif
 
   NS_ADDREF(*aResult = lf);
   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
 #include "nsWindowsRestart.cpp"
 #endif
 
 // If aBlankCommandLine is true, then the application will be launched with a
 // blank command line instead of being launched with the same command line that
@@ -2578,55 +2557,27 @@ XRE_main(int argc, char* argv[], const n
       // Try to remote the entire command line. If this fails, start up normally.
       if (RemoteCommandLine(desktopStartupIDPtr))
         return 0;
     }
 #endif
 
 #if defined(MOZ_UPDATER)
   // Check for and process any available updates
-  nsCOMPtr<nsIFile> updRoot = dirProvider.GetAppDir();
-  nsCOMPtr<nsILocalFile> updRootl(do_QueryInterface(updRoot));
-
-#ifdef XP_WIN
-  // Use <UserLocalDataDir>\updates\<relative path to app dir from
-  // Program Files> 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<nsILocalFile> 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<nsILocalFile> 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<nsIFile> 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
 
     nsCOMPtr<nsIProfileLock> profileLock;
     PRBool startOffline = PR_FALSE;
 
     rv = SelectProfile(getter_AddRefs(profileLock), nativeApp, &startOffline);
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -55,16 +55,26 @@
 #include "nscore.h"
 #include "nsXULAppAPI.h"
 
 // This directory service key is a lot like NS_APP_LOCALSTORE_50_FILE,
 // but it is always the "main" localstore file, even when we're in safe mode
 // 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\<User>\Local Settings\Application Data\
+ *          <Vendor>\<Application>\<relative path to app dir from Program Files>
+ * 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;
 
 class nsINativeAppSupport;
 class nsICmdLineService;
 class nsXREDirProvider;
 class nsIToolkitProfileService;
 class nsILocalFile;
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -122,23 +122,16 @@ nsXREDirProvider::Initialize(nsIFile *aX
   return NS_OK;
 }
 
 nsresult
 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);
   if (NS_FAILED(rv))
     return rv;
 
   rv = EnsureDirectoryExists(aLocalDir);
   if (NS_FAILED(rv))
@@ -237,16 +230,21 @@ nsXREDirProvider::GetFile(const char* aP
       if (NS_SUCCEEDED(rv))
         rv = file->AppendNative(NS_LITERAL_CSTRING("pref"));
     }
   }
   else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_DIR) ||
            !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))
       rv = file->AppendNative(NS_LITERAL_CSTRING(APP_REGISTRY_NAME));
   }
   else if (!strcmp(aProperty, NS_APP_USER_PROFILES_ROOT_DIR)) {
     rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file));
 
@@ -780,16 +778,64 @@ GetShellFolderPath(int folder, char resu
   } else {
     rv = NS_ERROR_NOT_AVAILABLE;
   }
 
   CoTaskMemFree(pItemIDList);
 
   return rv;
 }
+
+nsresult
+nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
+{
+  nsCOMPtr<nsIFile> 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 <UserLocalDataDir>\updates\<relative path to app dir from
+  // Program Files> 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<nsILocalFile> 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
 nsXREDirProvider::GetProfileStartupDir(nsIFile* *aResult)
 {
   if (mProfileDir)
     return mProfileDir->Clone(aResult);
 
--- a/toolkit/xre/nsXREDirProvider.h
+++ b/toolkit/xre/nsXREDirProvider.h
@@ -85,21 +85,28 @@ public:
   nsIFile* GetGREDir() { return mGREDir; }
   nsIFile* GetAppDir() { 
     if (mXULAppDir)
       return mXULAppDir;
     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
    * embedder-provided XPCOM directory provider. Only call this method
    * when XPCOM is initialized! aResult is a clone, it may be modified.
    */
   nsresult GetProfileDir(nsIFile* *aResult);