commit 62562804a469f1393ba6984ff5cffd1031c2410d
parent 00a2b13143d217d9bbccef3964c85e70bed46547
Author: Pier Angelo Vendrame <pierov@torproject.org>
Date: Fri, 27 Jan 2023 17:33:29 +0100
BB 9173: Change the default Firefox profile directory to be relative.
This commit makes Firefox look for the default profile directory in a
directory relative to the binary path.
The directory can be specified through the --with-relative-data-dir.
This is relative to the same directory as the firefox main binary for
Linux and Windows.
On macOS, we remove Contents/MacOS from it.
Or, in other words, the directory is relative to the application
bundle.
This behavior can be overriden at runtime, by placing a file called
system-install adjacent to the firefox main binary (also on macOS).
Diffstat:
10 files changed, 379 insertions(+), 18 deletions(-)
diff --git a/browser/config/mozconfigs/base-browser b/browser/config/mozconfigs/base-browser
@@ -47,3 +47,5 @@ ac_add_options --disable-legacy-profile-creation
if test -z "$WASI_SYSROOT"; then
ac_add_options --without-wasm-sandboxed-libraries
fi
+
+ac_add_options --with-relative-data-dir=BaseBrowser/Data/Browser
diff --git a/moz.configure b/moz.configure
@@ -953,6 +953,25 @@ with only_when(cross_compiling):
set_config("JS_BINARY", depends_if("JS_BINARY")(lambda value: value[0]))
option(
+ "--with-relative-data-dir",
+ nargs=1,
+ help="Sets the data directories to be relative to the application directory",
+)
+
+
+@depends("--with-relative-data-dir", target)
+@imports("json")
+def relative_data_dir(value, target):
+ if value and target.os == "Android":
+ die("--with-relative-data-dir is not supported on Android")
+ if value:
+ return json.dumps(value[0])
+
+
+set_define("RELATIVE_DATA_DIR", relative_data_dir)
+
+
+option(
"--with-base-browser-version",
nargs=1,
help="Set the Base Browser version, e.g., 7.0a1",
diff --git a/mozconfig-macos b/mozconfig-macos
@@ -10,3 +10,6 @@ ac_add_options --disable-update-agent
# Let's make sure no preference is enabling either Adobe's or Google's CDM.
ac_add_options --disable-eme
+
+# For base-browser we do not enable portable mode on macOS.
+ac_add_options --without-relative-data-dir
diff --git a/toolkit/xre/LauncherRegistryInfo.cpp b/toolkit/xre/LauncherRegistryInfo.cpp
@@ -16,6 +16,9 @@
#include <string>
#include <type_traits>
+// tor-browser#42163
+#include <filesystem>
+
// This is how long to wait after the last crash to try using the launcher
// process again. (bug 1846830) 45 days in 100-nanosecond intervals (FILETIME
// units)
@@ -679,6 +682,45 @@ LauncherResult<bool> LauncherRegistryInfo::ClearLauncherCrashTimestamp() {
LauncherResult<std::wstring>
LauncherRegistryInfo::BuildDefaultBlocklistFilename() {
+ // tor-browser#42163: Make the DLL blocklist obey portable mode
+ {
+ std::filesystem::path appDir;
+ {
+ mozilla::UniquePtr<wchar_t[]> appDirStr = GetFullBinaryPath();
+ if (!appDirStr) {
+ return LAUNCHER_ERROR_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ appDir = std::filesystem::path(appDirStr.get()).parent_path();
+ }
+ std::error_code ec;
+ const bool isPortable =
+ !std::filesystem::exists(appDir / L"system-install", ec);
+ if (ec) {
+ // exists is supposed not to set an error when a file does not exist
+ // (whereas other functions such as is_regular_file sets it).
+ // The standard is quite opaque about the meaning of the numeric codes.
+ // Moreover, we use libcxx on Windows, and it seems they created a sort of
+ // POSIX compatibility layer (e.g., for stat), see
+ // libcxx/src/filesystem/posix_compat.h.
+ // std::error_code has a message function, but all the various macro are
+ // specific to handle Windows errors, so we have to use the generic error.
+ // At least, at the moment the error is dropped eventually.
+ return LAUNCHER_ERROR_GENERIC();
+ }
+ if (isPortable) {
+ // RELATIVE_DATA_DIR must have forward slashes, but weakly_canonical
+ // already changes them to backslashes.
+ const std::filesystem::path blocklistPath =
+ std::filesystem::weakly_canonical(
+ appDir / L"" RELATIVE_DATA_DIR / L"blocklist", ec);
+ if (ec) {
+ return LAUNCHER_ERROR_GENERIC();
+ }
+ return blocklistPath.wstring();
+ }
+ // Normal installation, continue on Mozilla's path
+ }
+
// These flags are chosen to avoid I/O, see bug 1363398.
const DWORD flags =
KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_ALIAS;
@@ -711,6 +753,8 @@ LauncherRegistryInfo::BuildDefaultBlocklistFilename() {
}
LauncherResult<std::wstring> LauncherRegistryInfo::GetBlocklistFileName() {
+ // tor-browser#42163: Make the DLL blocklist obey portable mode
+#ifndef BASE_BROWSER_VERSION
LauncherResult<Disposition> disposition = Open();
if (disposition.isErr()) {
return disposition.propagateErr();
@@ -726,19 +770,19 @@ LauncherResult<std::wstring> LauncherRegistryInfo::GetBlocklistFileName() {
UniquePtr<wchar_t[]> buf = readResult.unwrap();
return std::wstring(buf.get());
}
-
+#endif
LauncherResult<std::wstring> defaultBlocklistPath =
BuildDefaultBlocklistFilename();
if (defaultBlocklistPath.isErr()) {
return defaultBlocklistPath.propagateErr();
}
-
+#ifndef BASE_BROWSER_VERSION
LauncherVoidResult writeResult = WriteRegistryValueString(
mRegKey, ResolveBlocklistValueName(), defaultBlocklistPath.inspect());
if (writeResult.isErr()) {
return writeResult.propagateErr();
}
-
+#endif
return defaultBlocklistPath;
}
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
@@ -2768,6 +2768,8 @@ static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) {
#endif // MOZ_WIDGET_ANDROID
}
+// If aUnlocker is NULL, it is also OK for the following arguments to be NULL:
+// aProfileDir, aProfileLocalDir, aResult.
static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
nsIFile* aProfileLocalDir,
nsIProfileUnlocker* aUnlocker,
@@ -2781,10 +2783,12 @@ static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
gStartupLock = nullptr;
#endif
- bool exists;
- aProfileDir->Exists(&exists);
- if (!exists) {
- return ProfileMissingDialog(aNative);
+ if (aProfileDir) {
+ bool exists;
+ aProfileDir->Exists(&exists);
+ if (!exists) {
+ return ProfileMissingDialog(aNative);
+ }
}
ScopedXPCOMStartup xpcom;
@@ -2794,7 +2798,7 @@ static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
#if defined(MOZ_TELEMETRY_REPORTING)
// We cannot check if telemetry has been disabled by the user, yet.
// So, rely on the build time settings, instead.
- mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
+ if (aProfileDir) mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
#endif
rv = xpcom.SetWindowCreator(aNative);
diff --git a/toolkit/xre/nsIXREDirProvider.idl b/toolkit/xre/nsIXREDirProvider.idl
@@ -20,4 +20,9 @@ interface nsIXREDirProvider : nsISupports
* Gets the hash for the current installation directory.
*/
AString getInstallHash();
+
+ /**
+ * Tells whether the browser has been started in portable mode.
+ */
+ readonly attribute boolean isPortableMode;
};
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
@@ -107,6 +107,10 @@ nsXREDirProvider::legacyOrXDGHomeTelemetry gXdgTelemetry =
nsXREDirProvider::legacyOrXDGHomeTelemetry::empty;
#endif // defined(MOZ_WIDGET_GTK)
+#if defined(RELATIVE_DATA_DIR)
+mozilla::Maybe<nsCOMPtr<nsIFile>> gDataDirPortable;
+#endif
+
// These are required to allow nsXREDirProvider to be usable in xpcshell tests.
// where gAppData is null.
#if defined(XP_MACOSX) || defined(XP_UNIX)
@@ -1118,11 +1122,125 @@ nsresult nsXREDirProvider::RestoreUserDataProfileDirectoryFromGTest(
return NS_OK;
}
+#if defined(RELATIVE_DATA_DIR)
+nsresult nsXREDirProvider::GetPortableDataDir(nsIFile** aFile,
+ bool& aIsPortable) {
+ if (gDataDirPortable) {
+ if (*gDataDirPortable) {
+ nsresult rv = (*gDataDirPortable)->Clone(aFile);
+ NS_ENSURE_SUCCESS(rv, rv);
+ aIsPortable = true;
+ } else {
+ aIsPortable = false;
+ }
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIFile> exeFile, exeDir;
+ bool persistent = false;
+ nsresult rv =
+ GetFile(XRE_EXECUTABLE_FILE, &persistent, getter_AddRefs(exeFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = exeFile->Normalize();
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = exeFile->GetParent(getter_AddRefs(exeDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+# if defined(XP_MACOSX)
+ nsAutoString exeDirPath;
+ rv = exeDir->GetPath(exeDirPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+ // When the browser is installed in /Applications, we never run in portable
+ // mode.
+ if (exeDirPath.LowerCaseFindASCII("/applications/") == 0) {
+ aIsPortable = false;
+ gDataDirPortable.emplace(nullptr);
+ return NS_OK;
+ }
+# endif
+
+# if defined(MOZ_WIDGET_GTK)
+ // On Linux, Firefox supports the is-packaged-app for the .deb distribution.
+ // We cannot use mozilla::widget::IsPackagedAppFileExists because it relies on
+ // this service to be initialized, but this function is called during the
+ // initialization. Therefore, we need to re-implement this check.
+ nsLiteralCString systemInstallNames[] = {"system-install"_ns,
+ "is-packaged-app"_ns};
+# else
+ nsLiteralCString systemInstallNames[] = {"system-install"_ns};
+# endif
+ for (const nsLiteralCString& fileName : systemInstallNames) {
+ nsCOMPtr<nsIFile> systemInstallFile;
+ rv = exeDir->Clone(getter_AddRefs(systemInstallFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = systemInstallFile->AppendNative(fileName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool exists = false;
+ rv = systemInstallFile->Exists(&exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (exists) {
+ gDataDirPortable.emplace(nullptr);
+ return NS_OK;
+ }
+ }
+
+ nsCOMPtr<nsIFile> localDir = exeDir;
+# if defined(XP_MACOSX)
+ rv = exeDir->GetParent(getter_AddRefs(localDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ exeDir = localDir;
+ rv = exeDir->GetParent(getter_AddRefs(localDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+# endif
+ rv = localDir->SetRelativePath(localDir.get(),
+ nsLiteralCString(RELATIVE_DATA_DIR));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+# if defined(XP_MACOSX)
+ // On macOS we try to create the directory immediately to switch to
+ // system-install mode if needed (e.g., when running from the DMG).
+ bool exists = false;
+ rv = localDir->Exists(&exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!exists) {
+ rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
+ if (NS_FAILED(rv)) {
+ aIsPortable = false;
+ gDataDirPortable.emplace(nullptr);
+ return NS_OK;
+ }
+ }
+# endif
+
+ gDataDirPortable.emplace(localDir);
+ rv = (*gDataDirPortable)->Clone(aFile);
+ NS_ENSURE_SUCCESS(rv, rv);
+ aIsPortable = true;
+ return rv;
+}
+#endif
+
+NS_IMETHODIMP nsXREDirProvider::GetIsPortableMode(bool* aIsPortableMode) {
+#ifdef RELATIVE_DATA_DIR
+ if (gDataDirPortable) {
+ *aIsPortableMode = *gDataDirPortable;
+ } else {
+ nsCOMPtr<nsIFile> dir;
+ GetPortableDataDir(getter_AddRefs(dir), *aIsPortableMode);
+ }
+#else
+ *aIsPortableMode = false;
+#endif
+ return NS_OK;
+}
+
// Return the home directory that will contain user data
nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
bool aLocal,
bool aForceLegacy) {
// Copied from nsAppFileLocationProvider (more or less)
+ NS_ENSURE_ARG_POINTER(aFile);
nsCOMPtr<nsIFile> localDir;
if (aLocal && gDataDirHomeLocal) {
@@ -1132,6 +1250,27 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
return gDataDirHome->Clone(aFile);
}
+#if defined(RELATIVE_DATA_DIR)
+ {
+ RefPtr<nsXREDirProvider> singleton = GetSingleton();
+ if (!singleton) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ bool isPortable = false;
+ nsresult rv =
+ singleton->GetPortableDataDir(getter_AddRefs(localDir), isPortable);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (isPortable) {
+ if (aLocal) {
+ rv = localDir->AppendNative("Caches"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ NS_IF_ADDREF(*aFile = localDir);
+ return rv;
+ }
+ }
+#endif
+
#if defined(XP_MACOSX)
FSRef fsRef;
OSType folderType;
@@ -1563,6 +1702,13 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
return NS_OK;
}
+#if defined(RELATIVE_DATA_DIR)
+ if (gDataDirPortable && *gDataDirPortable) {
+ // Do nothing in portable mode
+ return NS_OK;
+ }
+#endif
+
// Similar to nsXREDirProvider::AppendFromAppData.
// TODO: evaluate if refactoring might be required there in the future?
diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h
@@ -172,6 +172,14 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2,
void Append(nsIFile* aDirectory);
+#if defined(RELATIVE_DATA_DIR)
+ /**
+ * Get the path to the portable data dir, if the application is running in
+ * portable mode.
+ */
+ nsresult GetPortableDataDir(nsIFile** aFile, bool& aIsPortable);
+#endif
+
// On OSX, mGREDir points to .app/Contents/Resources
nsCOMPtr<nsIFile> mGREDir;
// On OSX, mGREBinDir points to .app/Contents/MacOS
diff --git a/widget/windows/WinTaskbar.cpp b/widget/windows/WinTaskbar.cpp
@@ -202,7 +202,21 @@ bool WinTaskbar::GenerateAppUserModelID(nsAString& aAppUserModelId,
bool aPrivateBrowsing) {
// If marked as such in prefs, use a hash of the profile path for the id
// instead of the install path hash setup by the installer.
- if (Preferences::GetBool("taskbar.grouping.useprofile", false)) {
+ bool useProfile = Preferences::GetBool("taskbar.grouping.useprofile", false);
+
+ {
+ // For portable mode, force the AUMID to be based on the profile directory
+ // instead of reading it from the registry.
+ bool isPortable = true;
+ // Do not even check if taskbar.grouping.useprofile is already true.
+ if (!useProfile &&
+ NS_SUCCEEDED(gDirServiceProvider->GetIsPortableMode(&isPortable)) &&
+ isPortable) {
+ useProfile = true;
+ }
+ }
+
+ if (useProfile) {
nsCOMPtr<nsIFile> profileDir;
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(profileDir));
diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp
@@ -164,14 +164,120 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) {
return NS_OK;
}
+#ifdef RELATIVE_DATA_DIR
+static nsresult SetupPortableMode(nsIFile** aDirectory, bool aLocal,
+ bool& aIsPortable) {
+ // This is almost the same as nsXREDirProvider::GetPortableDataDir.
+ // However, it seems that this is never called, at least during simple usage
+ // of the browser.
+
+ nsresult rv = NS_ERROR_UNEXPECTED;
+ nsCOMPtr<nsIProperties> directoryService(
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIFile> exeFile, exeDir;
+ rv = directoryService->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
+ getter_AddRefs(exeFile));
+ rv = exeFile->Normalize();
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = exeFile->GetParent(getter_AddRefs(exeDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+# if defined(XP_MACOSX)
+ nsAutoString exeDirPath;
+ rv = exeDir->GetPath(exeDirPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+ // When the browser is installed in /Applications, we never run in portable
+ // mode.
+ if (exeDirPath.LowerCaseFindASCII("/applications/") == 0) {
+ aIsPortable = false;
+ return NS_OK;
+ }
+# endif
+
+# if defined(MOZ_WIDGET_GTK)
+ // On Linux, Firefox supports the is-packaged-app for the .deb distribution.
+ nsLiteralCString systemInstallNames[] = {"system-install"_ns,
+ "is-packaged-app"_ns};
+# else
+ nsLiteralCString systemInstallNames[] = {"system-install"_ns};
+# endif
+ for (const nsLiteralCString& fileName : systemInstallNames) {
+ nsCOMPtr<nsIFile> systemInstallFile;
+ rv = exeDir->Clone(getter_AddRefs(systemInstallFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = systemInstallFile->AppendNative(fileName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool exists = false;
+ rv = systemInstallFile->Exists(&exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (exists) {
+ aIsPortable = false;
+ return NS_OK;
+ }
+ }
+
+ nsCOMPtr<nsIFile> localDir = exeDir;
+# if defined(XP_MACOSX)
+ rv = exeDir->GetParent(getter_AddRefs(localDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ exeDir = localDir;
+ rv = exeDir->GetParent(getter_AddRefs(localDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+# endif
+
+ rv = localDir->SetRelativePath(localDir.get(),
+ nsLiteralCString(RELATIVE_DATA_DIR));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (aLocal) {
+ rv = localDir->AppendNative("Caches"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ bool exists = false;
+ rv = localDir->Exists(&exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!exists) {
+ rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
+# if defined(XP_MACOSX)
+ if (NS_FAILED(rv)) {
+ // On macOS, we forgive this failure to allow running from the DMG.
+ aIsPortable = false;
+ return NS_OK;
+ }
+# else
+ NS_ENSURE_SUCCESS(rv, rv);
+# endif
+ }
+
+ localDir.forget(aDirectory);
+ aIsPortable = true;
+ return rv;
+}
+#endif
+
//----------------------------------------------------------------------------------------
// GetProductDirectory - Gets the directory which contains the application data
// folder
//
-// UNIX : ~/.mozilla/ or ${XDG_CONFIG_HOME:-~/.config}/mozilla
-// if env var MOZ_LEGACY_HOME is set to 1, then ~/.mozilla/ is used
-// WIN : <Application Data folder on user's machine>\Mozilla
-// Mac : :Documents:Mozilla:
+// If portable mode is enabled:
+// - aLocal == false: $APP_ROOT/$RELATIVE_DATA_DIR
+// - aLocal == true: $APP_ROOT/$RELATIVE_DATA_DIR/Caches
+// where $APP_ROOT is:
+// - the parent directory of the executable on Windows and Linux
+// - the root of the app bundle on macOS
+//
+// Otherwise:
+// - Windows:
+// - aLocal == false: %APPDATA%/$MOZ_USER_DIR
+// - aLocal == true: %LOCALAPPDATA%/$MOZ_USER_DIR
+// - macOS:
+// - aLocal == false: kDomainLibraryFolderType/$MOZ_USER_DIR
+// - aLocal == true: kCachedDataFolderType/$MOZ_USER_DIR
+// - Unix: ~/$MOZ_USER_DIR or ${XDG_CONFIG_HOME:-~/.config}/$MOZ_USER_DIR
+// if env var MOZ_LEGACY_HOME is set to 1, then ~/.$MOZ_USER_DIR/ is
+// used
//----------------------------------------------------------------------------------------
nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
bool aLocal) {
@@ -179,10 +285,20 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
return NS_ERROR_INVALID_ARG;
}
- nsresult rv;
+ nsresult rv = NS_ERROR_UNEXPECTED;
bool exists;
nsCOMPtr<nsIFile> localDir;
+#if defined(RELATIVE_DATA_DIR)
+ bool isPortable = false;
+ rv = SetupPortableMode(aLocalFile, aLocal, isPortable);
+ // If portable mode is enabled, we absolutely want it (e.g., to be sure there
+ // will not be disk leaks), so a failure is to be propagated.
+ if (NS_FAILED(rv) || isPortable) {
+ return rv;
+ }
+#endif
+
#if defined(MOZ_WIDGET_COCOA)
nsCOMPtr<nsILocalFileMac> localDirMac;
rv = NS_NewLocalFileWithCFURL(
@@ -265,10 +381,10 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
// GetDefaultUserProfileRoot - Gets the directory which contains each user
// profile dir
//
-// UNIX : ~/.mozilla/ or ${XDG_CONFIG_HOME:-~/.config}/mozilla
-// if env var MOZ_LEGACY_HOME is set to 1, then ~/.mozilla/ is used
-// WIN : <Application Data folder on user's machine>\Mozilla\Profiles
-// Mac : :Documents:Mozilla:Profiles:
+// - Windows and macOS: $PRODUCT_DIRECTORY/Profiles
+// - Unix: $PRODUCT_DIRECTORY
+// See also GetProductDirectory for instructions on how $PRODUCT_DIRECTORY is
+// generated.
//----------------------------------------------------------------------------------------
nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot(
nsIFile** aLocalFile, bool aLocal) {